mirror of
https://github.com/mudler/LocalAI.git
synced 2026-07-31 18:38:23 -04:00
* feat(3d): add Generate3D RPC, FLAG_3D capability, and /v1/3d/generations endpoint Adds the plumbing for image-conditioned 3D asset generation (binary glTF / GLB output), modeled on the video generation path: - backend.proto: Generate3D RPC + Generate3DRequest (staged image src, glb dst, seed/step/cfg_scale/texture_steps, quality and background enums, params map for backend-specific extras) - pkg/grpc: thread Generate3D through client, server, embed, base and the backend interfaces; connection-evicting and distributed-node wrappers (in-flight tracking + file staging) included - core/config: FLAG_3D usecase (guessed only for the trellis2cpp backend), '3d' canonical usecase string mapped to the Generate3D method, and a '3d' output modality - REST: POST /v1/3d/generations (+ unversioned alias) returning OpenAIResponse with a /generated-3d URL or b64_json; conditioning image accepted as URL, base64, or data URI; quality/background validated at the edge; .glb served as model/gltf-binary - auth: '3d' route feature (default ON); /api/instructions entry Assisted-by: Claude:claude-fable-5 [Claude Code] Signed-off-by: Richard Palethorpe <io@richiejp.com> * feat(trellis2cpp): add the trellis2.cpp image-to-3D backend Wraps localai-org/trellis2cpp (C++/GGML port of Microsoft TRELLIS.2, pbr-textures branch) as a Go+purego backend, following the stablediffusion-ggml pattern: - backend/go/trellis2cpp: purego bindings to the flat C ABI (v9, asserted at startup), eager pipeline load with model-set validation (refuses non-trellis GGUFs; degrades coarse/geometry-only/textured exactly like the upstream demo), Generate3D via t2_generate + t2_bake_glb writing a binary glTF to dst. Weight-free unit tests cover resolution/validation/param mapping — CI never downloads the multi-GB GGUF set or runs inference. - CPU SIMD variants build into per-variant directories (the shared libggml sonames collide across variants, unlike sd-ggml's flat renamed-.so scheme); run.sh picks one via /proc/cpuinfo. - CI wiring: backend-matrix entries (cpu, cuda12/13, vulkan amd64+arm64, l4t, l4t-cuda13, darwin metal), index.yaml meta + latest/master image entries, bump_deps tracking of the pbr-textures branch, changed-backends.js mapping, top-level Makefile targets. - Importer: auto-detects trellis GGUF repos/URIs (registered before llama-cpp so the .gguf match isn't stolen) and expands any trellis URI to the full 10-file component set spanning the three LocalAI-io HF repos. - Gallery: trellis2-4b (full PBR + 1024 cascade) and trellis2-4b-geometry (512 untextured) with verified sha256s. Assisted-by: Claude:claude-fable-5 [Claude Code] Signed-off-by: Richard Palethorpe <io@richiejp.com> * feat(ui): 3D generation page with native GLB viewer and IndexedDB history Adds a Studio tab + /app/3d page for the new image-to-3D endpoint: - GlbViewer ports the trellis2cpp demo's dependency-free WebGL2 renderer (quaternion trackball, metallic-roughness PBR, ACES, hidden-line wireframe with a bounded index budget) and pairs it with a minimal GLB parser for the two forms t2_bake_glb emits — dense vertex-PBR (linear COLOR_0 + _METALLIC_ROUGHNESS, uploaded as normalized integers) and the opt-in UV-atlas textured form. Parsing happens before any GL so stats and errors render without WebGL2. - use3DHistory stores past generations (params, input thumbnail, and the GLB blob itself) in IndexedDB with keep-newest-20 eviction — GLBs are multi-MB binaries localStorage can't hold — and the page offers a download button for the active GLB. - Wiring: CAP_3D capability constant (FLAG_3D — the exact string /api/models/capabilities serves), threeDApi, router entries, Studio tab, vite dev proxy, en locale keys. - e2e: render-smoke entry plus a focused spec that feeds a real one-triangle vertex-PBR GLB through the parser/viewer and exercises IndexedDB persistence, selection, deletion, and API errors. Assisted-by: Claude:claude-fable-5 [Claude Code] Signed-off-by: Richard Palethorpe <io@richiejp.com> * fix(3d): address API correctness and UX issues Keep 3D generation on the LocalAI-specific /3d/generations route and ensure authentication and permissions cover it. Propagate distributed transfer failures, publish a portable ARM64 backend image, honor importer overrides, and align discovery, upload validation, and touch controls. Assisted-by: Codex:gpt-5 Signed-off-by: Richard Palethorpe <io@richiejp.com> * feat(3d): add previewable print remeshing Add a single-detail CGAL Alpha Wrap workflow for existing Trellis GLBs, including PBR reprojection, API documentation, tracing, and an in-browser preview before download. Allow the remesh route to enforce its 512 MiB upload cap independently of the smaller global default so generated high-resolution meshes can be processed. Assisted-by: Codex:gpt-5 Signed-off-by: Richard Palethorpe <io@richiejp.com> * build(trellis2cpp): centralize remesh dependency pins Assisted-by: Codex:GPT-5 [apply_patch] [exec_command] Signed-off-by: Richard Palethorpe <io@richiejp.com> * fix(kokoros): implement Generate3D stub for new proto RPC The Generate3D RPC added to backend.proto for the trellis2cpp backend made tonic's generated Backend trait require generate3_d, breaking the kokoros-grpc build. Return unimplemented like the other unsupported modalities. Assisted-by: Claude Code:claude-fable-5 Signed-off-by: Richard Palethorpe <io@richiejp.com> --------- Signed-off-by: Richard Palethorpe <io@richiejp.com> Co-authored-by: localai-org-maint-bot <bot-opensource@localaisrl.com>
123 lines
7.2 KiB
Markdown
123 lines
7.2 KiB
Markdown
+++
|
||
disableToc = false
|
||
title = "3D Generation"
|
||
weight = 19
|
||
url = "/features/3d-generation/"
|
||
+++
|
||
|
||
LocalAI can generate textured 3D meshes from a single conditioning image via the `/3d/generations` endpoint, powered by the `trellis2cpp` backend — a C++/GGML port of [Microsoft TRELLIS.2](https://github.com/microsoft/TRELLIS.2) ([trellis2.cpp](https://github.com/localai-org/trellis2cpp)). The output is a binary glTF (`.glb`) asset with PBR materials.
|
||
|
||
Generation is image-conditioned only — there is no text-prompt path. Provide a photo or rendering of a single object (ideally on a plain background) and TRELLIS.2 reconstructs a full 3D mesh from it.
|
||
|
||
## Setup
|
||
|
||
Install a model from the gallery:
|
||
|
||
```bash
|
||
local-ai run trellis2-4b # full pipeline: 1024³ cascade + PBR textures (~18 GB)
|
||
# or
|
||
local-ai run trellis2-4b-geometry # 512³ untextured geometry only (~7 GB)
|
||
```
|
||
|
||
The backend detects which component GGUFs are present and degrades gracefully: without the texture models it produces untextured geometry, and without the fine-flow models it falls back to a coarse marching-cubes preview.
|
||
|
||
## API
|
||
|
||
- **Method:** `POST`
|
||
- **Endpoint:** `/3d/generations`
|
||
|
||
### Request
|
||
|
||
The request body is JSON with the following fields:
|
||
|
||
| Parameter | Type | Required | Default | Description |
|
||
|-------------------|----------|----------|---------|--------------------------------------------------------------------|
|
||
| `model` | `string` | Yes | | Model name to use |
|
||
| `image` | `string` | Yes | | Conditioning image as base64, a data URI, or a public URL |
|
||
| `quality` | `string` | No | `auto` | Mesh pipeline: `auto`, `coarse`, `512`, or `1024` |
|
||
| `background` | `string` | No | `auto` | Background handling: `auto`, `keep`, `black`, or `white` |
|
||
| `step` | `int` | No | 12 | Flow sampling steps for the shape |
|
||
| `texture_steps` | `int` | No | 12 | Flow sampling steps for the PBR material |
|
||
| `cfg_scale` | `float` | No | 7.5 | Classifier-free guidance scale |
|
||
| `seed` | `int` | No | random | Random seed for reproducibility |
|
||
| `response_format` | `string` | No | `url` | `url` to return a file URL, `b64_json` for base64 output |
|
||
| `params` | `object` | No | | Backend-specific string parameters (`texture_size`, `components`) |
|
||
|
||
`quality` selects the mesh resolution: `coarse` is a fast marching-cubes preview, `512` the fine dual-grid mesh, `1024` the high-resolution cascade (slow — several minutes, roughly 10 GB VRAM), and `auto` picks the best pipeline the installed model set supports.
|
||
|
||
`background` controls solid-background removal on the conditioning image before generation: `auto` detects border-connected near-black/near-white, `keep` preserves the image alpha exactly, and `black`/`white` force removal of that colour.
|
||
|
||
Backend-specific `params`: `texture_size` (UV-atlas resolution hint when atlas baking is enabled) and `components` (`tiny` removes small islands, `largest` keeps only the biggest connected component, `all` — the default — keeps everything).
|
||
|
||
### Response
|
||
|
||
Returns a JSON response using LocalAI's OpenAI-style generation envelope:
|
||
|
||
| Field | Type | Description |
|
||
|-------------------|----------|----------------------------------------------------------------|
|
||
| `created` | `int` | Unix timestamp of generation |
|
||
| `id` | `string` | Unique identifier (UUID) |
|
||
| `data` | `array` | Array with the generated asset |
|
||
| `data[].url` | `string` | URL path to the `.glb` under `/generated-3d` (if `url`) |
|
||
| `data[].b64_json` | `string` | Base64-encoded GLB (if `response_format` is `b64_json`) |
|
||
|
||
### Watertight print remeshing
|
||
|
||
`POST /3d/remesh` applies the same post-generation CGAL Alpha Wrap workflow as the trellis2.cpp demo. It accepts `multipart/form-data` and returns the remeshed GLB directly as `model/gltf-binary`:
|
||
|
||
| Field | Type | Required | Default | Description |
|
||
|----------|----------|----------|---------|-------------|
|
||
| `model` | `string` | Yes | | Installed TRELLIS.2 model name |
|
||
| `mesh` | `file` | Yes | | Source GLB produced by TRELLIS.2 |
|
||
| `detail` | `float` | No | `0.5` | Smallest preserved detail as a percentage of the source bounding-box diagonal (`0.35`–`2.5`) |
|
||
|
||
There is intentionally no independent offset control. The enclosing offset follows the trellis2.cpp demo and is derived as `detail / 30`; independent tuning tends to produce puffy or degenerate wraps. Lower detail percentages retain finer features but take longer and generally produce more triangles. The output is watertight, oriented, intersection-free, and 2-manifold. For textured sources, LocalAI unwraps the replacement mesh and reprojects its PBR material onto a new UV atlas.
|
||
|
||
Source GLBs may be up to 512 MiB. This route uses its own upload limit because fine TRELLIS.2 meshes commonly exceed LocalAI's default `--upload-limit`.
|
||
|
||
```bash
|
||
curl http://localhost:8080/3d/remesh \
|
||
-F model=trellis2-4b \
|
||
-F mesh=@generated.glb \
|
||
-F detail=0.5 \
|
||
--output printable.glb
|
||
```
|
||
|
||
## Usage
|
||
|
||
### Generate a 3D model from an image
|
||
|
||
```bash
|
||
curl http://localhost:8080/3d/generations \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"model": "trellis2-4b",
|
||
"image": "https://example.com/photo-of-a-chair.png",
|
||
"quality": "512"
|
||
}'
|
||
```
|
||
|
||
The response contains a URL such as `/generated-3d/b64123456789.glb`; fetch it from the same server. The GLB is standard glTF 2.0 and opens in Blender, three.js, `<model-viewer>`, and most engines.
|
||
|
||
### Base64 input and output
|
||
|
||
```bash
|
||
curl http://localhost:8080/3d/generations \
|
||
-H "Content-Type: application/json" \
|
||
-d "{
|
||
\"model\": \"trellis2-4b\",
|
||
\"image\": \"$(base64 -w0 chair.png)\",
|
||
\"response_format\": \"b64_json\"
|
||
}" | jq -r '.data[0].b64_json' | base64 -d > chair.glb
|
||
```
|
||
|
||
## WebUI
|
||
|
||
The React UI includes a 3D tab in the Studio (and a `/3d` page) with an interactive PBR viewer: upload an image, pick the quality, and preview the generated mesh with orbit/pan/zoom and a wireframe toggle. Past generations are kept in the browser (IndexedDB). After generation, a single Detail slider and **Apply remeshing** button replace the preview with the exact watertight model that the GLB download exports; **Show original** switches back without regenerating.
|
||
|
||
## Notes
|
||
|
||
- The 512³ pipeline takes roughly two minutes on a modern GPU; the 1024³ cascade takes around five minutes and needs about 10 GB VRAM plus a temporary host-RAM spike.
|
||
- `TRELLIS2_DEVICE=cpu` forces CPU inference (slow; mainly for debugging).
|
||
- The generated mesh has unoriented winding (faithful to TRELLIS.2) and is exported Y-up with vertex-PBR materials; a UV-atlas texture bake can be enabled in the backend via the `T2GLB_XATLAS` environment variable.
|