Spaces:
Running
Download README.md from townbox/projection-texturing: direct link, hf CLI and curl.
- Browser
- Download file 6.47 kB
-
https://huggingface.co/spaces/townbox/projection-texturing/resolve/main/README.md
- Command line
-
hf download hf://spaces/townbox/projection-texturing/README.md
-
curl -L -o README.md https://huggingface.co/spaces/townbox/projection-texturing/resolve/main/README.md
title: projtex · Projection Texturing API
emoji: 🎨
colorFrom: green
colorTo: yellow
sdk: docker
app_port: 7860
pinned: false
license: mit
short_description: Agent-first API to texture 3D meshes with Qwen-Image / Fibo
models:
- Qwen/Qwen-Image-2.1-Turbo
- Qwen/Qwen-Image-2.1
- briaai/Fibo-2.0-edit-turbo
tags:
- 3d
- texturing
- mcp-server
- agents
- image-editing
projtex: projection texturing API (agent-first)
Send a 3D mesh and a prompt; get back the mesh with a baked colour texture (GLB). The service:
- generates images from virtual cameras, each conditioned on what is already painted;
- checks every image against the geometry;
- projects the images onto the mesh and blends them in texture space;
- bakes the result into the mesh's UVs.
Three image models are available, through Hugging Face Spaces:
- Qwen-Image-2.1-Turbo (8 steps) via hugging-apps/qwen-qwen-image-2-1-turbo (default: fastest, least GPU quota);
- Qwen-Image-2.1 (full model, 40 steps) via the official Qwen/Qwen-Image-2.1 (
"backend": "qwen-space"); - Bria Fibo 2.0 Edit Turbo via briaai/Fibo-2.0-editing (
"backend": "fibo-space").
Designed for agents:
- Asynchronous jobs.
POST /api/jobsreturns at once. PollGET /api/jobs/{id}; every status includesprogress, qualitysummary, file URLs and anextlist of concrete follow-up calls. - Three equivalent interfaces:
- Inputs agents can produce: a local file uploaded as raw bytes (
POST /api/uploads->upload_id, then a plain JSON job),mesh_base64, a publicmesh_url, or a built-insample. GLB from Blender or three.js (GLTFExporter), glTF with embedded data, OBJ, PLY, STL or a zip. - Outputs that drop back into your scene: the GLB keeps your objects (names, transforms), materials (names, metallic/roughness/alpha) and orientation; every material's base colour uses one baked texture. When your UVs are kept, the albedo PNG also fits your original model. Inside-out surfaces are detected and flipped.
- Honest progress and quality: queue position and ETA while waiting; a
verdict(good / usable / needs work) with coverage measured over what cameras can see (the underside is reported apart). - A quality loop as API calls: regenerate views, disable views, fill gaps, local retouch (repair / replace / upscale), pick 3D points from pixels, and re-bake.
- Free dry runs with
"backend": "mock", and bring-your-own images with"backend": "external". - Flat errors
{"error", "hint"}.
Quick start
BASE=https://townbox-projection-texturing.hf.space
curl -s --data-binary @house.glb -H 'content-type: model/gltf-binary' $BASE/api/uploads
# -> {"upload_id": "up_...", ...}
curl -s -X POST $BASE/api/jobs -H 'content-type: application/json' -H "X-HF-Token: $HF_TOKEN" \
-d '{"upload_id":"up_...","prompt":"white clapboard siding, grey shingle roof; dark green door"}'
# -> {"job_id": "...", "state": "queued", "poll_after_seconds": 15, "next": [...]}
curl -s $BASE/api/jobs/<job_id>
# when "state" is "done": files.textured_glb, files.contact_sheet, summary.verdict, output, next
Try it without a mesh: {"sample": "lantern", "prompt": "black wrought iron, weathered oak post, warm glass"}.
Terrain and ground: POST /api/terrain {"upload_id": "up_...", "prompt": "an alpine valley in early summer"} (or a
heightmap, and your own layers) returns files.terrain_glb (the ground with a top-down colour map) and
files.bundle_zip (splat maps, seamless detail textures, blender_terrain.py, three_terrain.js). See the
"Terrain and ground" section of /llms.txt.
PBR materials: add "pbr": true to a texture job (or POST /api/jobs/{id}/pbr afterwards) for
files.textured_pbr_glb with a de-lit base colour and a metallicRoughness texture (roughness, metallic maps from a
LoRA on Qwen-Image-Edit-2511, run on the caller's ZeroGPU quota).
MCP client configuration:
{"mcpServers": {"projtex": {"type": "http", "url": "https://townbox-projection-texturing.hf.space/mcp",
"headers": {"X-HF-Token": "hf_..."}}}}
Tools:
texture_mesh,texture_terrain,get_job(with a preview image) andview_image;- the quality loop:
regenerate_views,disable_views,fill_gaps,retouch,undo_retouch,bake,pick_point; submit_view_image(bring your own images);service_infoandguide.
Quota: who pays for generation
Image generation runs on ZeroGPU Spaces and spends the caller's daily GPU quota, about 30 s per view.
- Your token: send it as
X-HF-Token(or thehf_tokenfield) so your own quota is used. It stays in memory for that job only and is never written to disk, logged or returned. - No token: the job runs as the visitor identity the Hub forwards, if present, otherwise as the shared
anonymous quota (about 2 GPU-minutes per day).
GET /api/identityshows which applies to your requests. - No quota needed: the
mockandexternalbackends.
What runs here
The CPU part of projtex runs in this container, with software OpenGL:
- mesh import and UV repair;
- camera planning (objects, characters with face close-ups, 360° environment probes);
- validation of every generated view (rejects re-framed outputs);
- texel-space fusion weighted by angle and depth;
- push-pull hole filling, leave-one-out consistency checks, local retouch layers;
- GLB export.
Limits:
- meshes: 60 MB, 600k triangles;
- texture size: 1024, 2048 or 4096;
- 8 operations run at once (the CPU-heavy parts share 2 CPU slots), the rest are queued;
- jobs expire after 12 h or when the Space restarts.
Licences
- Code: MIT.
- Qwen-Image-2.1 and Qwen-Image-2.1-Turbo outputs: Qwen research licence.
- Fibo 2.0 Edit Turbo outputs: CC BY-NC 4.0 (non-commercial).
- Samples: Avocado and Lantern are CC0 (Khronos glTF-Sample-Assets). The head is the Lee Perry-Smith scan, CC-BY 3.0, by Infinite-Realities.
Inspired by the projection-texturing workflow shown by @alexfredo87. This is an independent implementation.