The Problem

Clients that need a web‑ready 3‑D representation of a product often receive heavy mesh files or rely on manual modeling. Those assets are large, version‑hard to audit, and costly to render on low‑bandwidth devices. A reproducible, code‑only model that can be generated from a single reference photo removes the download burden and guarantees that the geometry is derived from a deterministic pipeline.

What This Does

img2threejs takes one reference image and emits a TypeScript factory that builds a THREE.Group from primitives, procedural shaders and generated geometry. The core logic lives in the scripts/ folder:

  • scripts/append_sculpt_review.py – the primary entry point (main at line 201).
  • scripts/validate_sculpt_spec.py and scripts/generate_threejs_factory.py – validate the intermediate “sculpt spec” and turn it into the final Three.js source.
  • scripts/extract_reference_pbr.py, scripts/delight_reference.py, and scripts/build_detail_inventory.py – handle image analysis, colour‑space conversion and PNG/PNG‑filter utilities.

All generated models are animation‑ready and token‑efficient, as demonstrated by the animated GIFs in assets/.

How It Is Wired

Execution starts in scripts/append_sculpt_review.pymain (line 201). main calls a cascade of 170 functions across the repo; the most widely used helpers are:

  • run – invoked from 19 locations, driving the end‑to‑end pipeline.
  • is_number, validate_string_array, validate_unit_interval – numeric validation utilities used 17, 13 and 11 times respectively.
  • load_imageread_pngpaeth_predictor – the only path that touches the filesystem (reading PNG data).

File‑level responsibilities (ordered by impact):

FileCore dutiesExternal effect
scripts/validate_sculpt_spec.py48 functions: spec loading, numeric checks, score validationReads spec files
scripts/build_detail_inventory.pyPNG read/write, Paeth predictor, external command executionWrites PNG, runs external tool
scripts/extract_reference_pbr.pyColour distance, clamping, luma calculationsReads images
scripts/sculpt_pass_orchestrator.pyPass ordering, spec persistence, visual evidence generationReads/writes JSON spec
scripts/append_sculpt_review.pyItem splitting, spec loading, score clamping, remote path handlingReads spec, writes review output

No circular imports were detected, but several modules contain deep nesting (up to 10 levels) and oversized files (e.g., validate_sculpt_spec.py at 1 620 lines). The internal call graph shows 308 intra‑repo edges; the functions listed above have the broadest “blast radius” because many modules depend on them.

How To Use It

# Clone the repository
git clone https://github.com/moses-y/img2threejs.git
cd img2threejs

# Install Python dependencies (Python 3.10+ required)
pip install -r scripts/requirements.txt

The repository does not provide a documented CLI or configuration file. Based on the entry point, a typical invocation would be:

python scripts/append_sculpt_review.py <reference-image-path> <output-dir>

Replace <reference-image-path> and <output-dir> with the desired input image and destination for the generated TypeScript factory. If additional arguments are required, inspect append_sculpt_review.py for argparse usage (currently absent).

Real‑World Use

A product‑visualization service can embed this pipeline into its asset‑generation backend. After uploading a photo, the service runs the script above, stores the resulting .ts factory in a CDN, and serves the lightweight Three.js model to browsers, eliminating the need to host large GLB files.

# Example integration (pseudo‑code)
spec_path = generate_spec_from_image(uploaded_path)
factory_ts = run_pipeline(spec_path, out_dir="generated/")
cdn_url = upload_to_cdn(factory_ts)
render_in_browser(cdn_url)

Code Health & Issues

  • HIGH – No CI/CD – 16 source files, no workflow in .github/. Fix: add a GitHub Actions workflow that runs the build and tests on push/PR.
  • MEDIUM – No Dependabot – only scripts/requirements.txt exists, no update bot configured. Fix: add .github/dependabot.yml covering the Python ecosystem.
  • HIGH – Duplicated code blocks – 260 repeated 6‑line snippets across 14 files. Fix: extract shared helpers.
  • HIGH – Deep nesting – up to 10 indentation levels in several scripts. Fix: flatten with early returns or guard clauses.
  • HIGH – Oversized files – e.g., validate_sculpt_spec.py (1 620 lines). Fix: split by responsibility.
  • MEDIUM – High branching density – 510 branch points in two scripts. Fix: replace complex if/elif chains with strategy tables.

No tests are missing; a test suite exists under scripts/tests/, but without CI they are not automatically exercised.

The Bottom Line

img2threejs delivers a novel, code‑only pipeline for turning a single image into a Three.js model, which is valuable for bandwidth‑constrained web experiences. The implementation is functional but suffers from maintainability problems (large, duplicated, deeply nested scripts) and lacks automation (no CI, no dependency bot). Teams comfortable refactoring Python code and adding a CI layer can adopt it for internal asset generation; external users should be prepared to supply their own execution wrapper and validation.