img2threejs / README.md
Mike0021's picture
Increase reasoning-spec generation headroom
f074dc6 verified
|
Raw
History Blame Contribute Delete
9.6 kB
metadata
title: img2threejs
emoji: 🧊
colorFrom: indigo
colorTo: gray
sdk: docker
app_port: 7860
pinned: false
license: mit
short_description: Image to procedural Three.js with community gallery
tags:
  - threejs
  - image-to-3d
  - procedural-generation
  - code-generation
  - llm
startup_duration_timeout: 30m

img2threejs — image to procedural Three.js

Upload one object reference image. A vision-capable LLM authors an ObjectSculptSpec; deterministic validators enforce the upstream structural and strict-quality rules; and the vendored generator emits a TypeScript THREE.Group factory. The result renders in a sandboxed browser viewer and is downloadable as the original spec, TypeScript, an ESM bundle, and standalone HTML. Successful results are shared to the public community gallery by default; the clearly labelled upload-page toggle lets each user keep a result out of the gallery before generation begins.

This Docker Space adapts hoainho/img2threejs (MIT), synced to v1.3.0 commit 2c78038d315ec93086ef308c17ad2f1cd4cca683. It is reconstruction-by-code, not photogrammetry, mesh extraction, or a downloaded asset pack.

What the hosted workflow guarantees

image ──▶ byte/type/decompression guard + deterministic probe
      ──▶ vision LLM authors schema-2.1 ObjectSculptSpec
      ──▶ strict validator (errors return to the LLM, up to 3 repair rounds)
      ──▶ original spec saved locked and unreviewed
      ──▶ separate hosted-preview compile manifest (all supported parts)
      ──▶ vendored generator + esbuild ──▶ sandboxed viewer/downloads
      ──▶ optional persistent community publication (default on)

The hosted preview does not fabricate upstream review evidence. The downloaded spec.json retains an empty reviewHistory and its original locked pass order. A separate compile copy marks itself hosted-unreviewed-preview and combines the declared components into one preview pass. It contains no screenshot comparison, AI-vision score, reviewer, or continue decision.

The result is an approximate, stylized procedural reconstruction from a single image. Hidden sides are inferred rather than observed or measured. Structural strict validation is not visual approval; production approval requires running the upstream pass-by-pass render, comparison, and review loop outside this hosted preview. Unsupported geometry families and parent cycles are rejected instead of being replaced by placeholder boxes.

Community gallery and privacy

The upload page starts with Share this result to the community gallery enabled. The disclosure beside it states that publication includes the uploaded reference image and generated artifacts. Turn it off before choosing Generate to keep the job out of the gallery; opted-out and failed jobs are never copied to gallery storage. Opted-out job URLs are unlisted rather than access-controlled and expire with temporary job storage.

Published entries are written atomically to a private Hugging Face Bucket mounted at /data and are exposed only through the gallery API below. They survive app restarts, unlike the short-lived per-job files under /tmp. Gallery cards open the real generated bundle in the same sandboxed viewer and offer the same downloads. The viewer provides orbit, zoom, pan, wireframe, shadow, camera-reset, and screenshot controls.

Required Space Secrets

Conversion needs a vision-capable Anthropic Messages or OpenAI-compatible chat endpoint. Add these under Settings → Secrets:

Secret Required Example Purpose
LLM_API_KEY yes provider API key Credential; never logged or returned to the browser.
LLM_MODEL yes claude-sonnet-4-5, moonshotai/kimi-k3 Provider model identifier; it must accept images.
LLM_BASE_URL no https://api.anthropic.com Provider base URL; defaults to Anthropic.
LLM_API_STYLE no auto, anthropic, or openai auto tries Messages then falls back on HTTP 404.
LLM_MAX_TOKENS no 32768 Response budget for reasoning plus the structured spec.
LLM_TIMEOUT_S no 180 Per-request timeout in seconds.
LLM_MAX_RETRIES no 2 Transient provider retries.
LLM_REFERER, LLM_TITLE no provider-specific Optional attribution headers.

Set the public Space variable GALLERY_DIR=/data/gallery. The production Space mounts hf://buckets/Mike0021/img2threejs-gallery at /data; another deployment should mount its own Bucket at the same path.

Optional operational variables are JOB_TIMEOUT_S (default 1800, covering queue time through the completed browser bundle) and GALLERY_PUBLISH_TIMEOUT_S (default 120, bounding the isolated persistent Bucket copy). Long opaque stages report elapsed time every 25 seconds; the UI does not invent completion percentages.

ANTHROPIC_API_KEY/ANTHROPIC_AUTH_TOKEN, ANTHROPIC_BASE_URL, and ANTHROPIC_MODEL are accepted as server-side aliases. Without a key and model, the app still starts, /health reports llm_configured: false, and job creation returns 503 llm_not_configured; no model or placeholder is emitted.

HTTP API

curl https://<space-host>/health
curl -F "file=@object.png" https://<space-host>/api/jobs
curl -N https://<space-host>/api/jobs/<job-id>/events
curl https://<space-host>/api/jobs/<job-id>/artifacts/spec.json
curl https://<space-host>/api/jobs/<job-id>/artifacts/factory.ts
curl https://<space-host>/api/jobs/<job-id>/artifacts/model.bundle.js
curl https://<space-host>/api/jobs/<job-id>/artifacts/standalone.html
curl 'https://<space-host>/api/gallery?offset=0&limit=24'
curl https://<space-host>/api/gallery/<gallery-id>
curl https://<space-host>/api/gallery/<gallery-id>/artifacts/standalone.html

Uploads are limited to PNG, JPEG, WebP, GIF, or BMP, 10 MiB, and 40 MP by default. SVG is rejected. Images are orientation-normalized, metadata-stripped, and downscaled to at most 1024 px before processing. Defaults permit 10 jobs per hour per client, 2 active conversions, and 8 queued/running jobs total. In the multipart job request, share defaults to true; send share=false to opt out.

Run and test locally

Python 3.12 and Node 22 are the tested versions.

python3 -m pip install -r requirements.txt
npm ci
pytest -q
python3 forge/tests/test_pipeline.py

LLM_API_KEY=... LLM_MODEL=... LLM_BASE_URL=... python3 -m app.main
# http://127.0.0.1:7860

Build and verify the same target architecture used by Hugging Face:

docker build --platform=linux/amd64 -t img2threejs .
docker run --rm -p 7860:7860 \
  -e LLM_API_KEY -e LLM_MODEL -e LLM_BASE_URL img2threejs

scripts/verify_docker.sh

The Docker build regenerates a fixture factory through the real strict gate and hosted-preview compiler, bundles it with esbuild, and executes the bundle headlessly in Node. The final runtime image contains only runtime dependencies, app/, the required forge/ source, and the license—not tests, scripts, rollouts, virtual environments, caches, or the upstream comparison clone.

Deploy and verify

The helper uses the currently authenticated local hf CLI account; an HF_TOKEN environment variable is not required. --dry-run performs no Hub mutation and prints the exact deterministic upload allowlist.

hf auth whoami
hf buckets create Mike0021/img2threejs-gallery --private --exist-ok
hf spaces volumes set Mike0021/img2threejs \
  --volume hf://buckets/Mike0021/img2threejs-gallery:/data
hf spaces variables add Mike0021/img2threejs --env GALLERY_DIR=/data/gallery
python3 scripts/deploy_space.py --dry-run
python3 scripts/deploy_space.py                 # sets present LLM_* aliases as Secrets
# or: python3 scripts/deploy_space.py --no-secrets

hf spaces logs Mike0021/img2threejs --build --follow
hf spaces logs Mike0021/img2threejs --follow

python3 scripts/verify_space.py                 # wait/info/logs + GET-only probes
python3 scripts/verify_space.py \
  --e2e tests/fixtures/mug_photo.png            # real SSE job + artifact/node smoke

The deploy helper stages only its allowlist and issues one sanitized hf upload. Secret values are passed in a temporary mode-0600 secrets file; only secret names are printed. The live verifier never submits a job unless an explicit --e2e IMAGE is supplied.

Repository layout

Path Purpose
app/ FastAPI service, LLM client, pipeline adapter, SPA, and sandboxed viewer
forge/ Vendored upstream v1.3 pipeline with targeted runtime generator/safety fixes
grimoire/, SKILL.md Upstream rubrics and complete agent workflow
UPSTREAM_REVISION Exact upstream version and commit provenance
tests/ Unit, HTTP, pipeline, manifest, and render smoke tests
scripts/ Fixture builder, Node smoke, Docker verifier, deployer, live verifier
docs/SECURITY.md Threat model, controls, and accepted limitations

The targeted forge/ changes preserve declared component dimensions without scaling child pivots, avoid misinterpreting non-axis attachments, detect parent cycles, and retain explicit hosted-preview honesty labels. The Space supports the v1.3 advanced primitive set instead of replacing unknown geometry with boxes. The adapter is therefore intentionally not a byte-for-byte upstream tree.

License and attribution

MIT — © 2026 hoainho (upstream) and this Space's contributors. See LICENSE. three.js is MIT © the three.js authors.