Img to 3d Generator Listing - #678
Open
lucaslyl wants to merge 17 commits into
Open
Conversation
…age field The working directory moves from img-to-3d-v2/ to img-to-3d-generator/ and every reference follows: module refs, sourceStudioId scoping on the archived rounds, render/upload URLs, and the demo instance (v2-test → nobita-house-demo). The v1 e8c3d5 modules and their orphaned instances are gone; one root-level instance migrated into the new directory (its relative links gaining the extra depth) and onto the `references` schema. Reference photos are one contains(MultiImageSourceField) — the sidebar is just that field's edit UI (hero preview, thumbnail strip with per-image remove, Link Image, paste-URL), so the studio's own photo gallery and its CSS are deleted. Also: - A Stop Refinement control: the current vision round finishes and is kept, then the loop exits instead of starting another. - History strip sorts round desc with a createdAt desc tiebreaker, so the newest round is always the leftmost tile. - The analyze prompt handles collage / character-sheet references: panels are views of ONE object, text and scene lighting are ignored, and colors sample from the object's own pixels in the flattest-lit panel. - Button labels are capitalized (+ New Sculpture, Regenerate, Generate Model, Export .glb, Stop Refinement). linear: https://linear.app/cardstack/issue/ECO-525/img-to-3d-studio-p1-mvp-photo-sculptspec-procedural-threejs-model-in-a
…ventions ## summary: The img-to-3D studio produced a different result on every run, and results regularly showed spurious parts, misplaced parts and misread object shapes. Three root causes: the generation requests left temperature and seed unpinned; the spec stage had no geometric post-processing to catch an implausible layout; and the two builders (studio preview and standalone .js export) had drifted apart, so the same spec rendered differently in each. ### Determinism - Pin SPEC_TEMPERATURE to 0 and derive the seed from the reference image URLs via FNV-1a (seedFromStrings), so one photo set reproduces one plan. - Cache the analysis by image-set signature and lock the structure, so a re-generate reuses the reviewed plan instead of re-rolling it. ### Spec post-processing (util/generation.gts) Add validation and repair passes: drop hairline parts, drop parts absent from the analysis plan, flag unrealized and overbuilt parts, enforce the attachments list numerically, ground support parts, resolve buried parts, detect instance collisions, repair primitive conventions and mirrored attachments, flag flat palettes and silhouette notches, separate coplanar layers. Scale reconciliation now applies cumulatively within a 0.4-2.5 band instead of compounding without limit. ### Builder parity Bring util/spec-interpreter.gts and util/code-export.gts back in sync: 45-degree orientation for 4-segment cones, the NEVER_INSET list, the plate aspect test before insetting, radial repeats centred on the attachment host, and final ground placement performed by the builder (the spec layer cannot know where the solvers will leave a part). Extract FINISH_PAINTER_SOURCES and FINISH_RUNTIME_SOURCES in util/finishes.gts so exported .js keeps its procedural finish textures. ### Reference image loading (util/realm-image.gts) A cross-origin image URL renders in an <img> but script cannot read its bytes, so fetch failed with "Failed to fetch" on pasted URLs. Fall back to SendRequestViaProxyCommand when the direct read is refused, and downscale to a 1568px long edge as WebP before sending, which also cuts the payload that made long multi-image requests likely to drop mid-flight. ### UI - Add i3d-popover.gts: a shared popover shell with a compact header, a close button and a 3px radius, replacing per-panel chrome. - History now runs a studio-scoped query and lists every round. - Targeted edits may resize and add parts; primitive stays frozen. ### Tests - util/generation.test.gts covers the passes. - util/audit-model.mjs is a browser-free audit harness (hairline geometry, outside-silhouette parts, parts above the body top, off-circle radial repeats, builder warnings) that exits non-zero on findings. ### Removals - util/mesh-service.gts, folded into util/spec-interpreter.gts. - Debug sculpture instances and demo studio JSON produced while testing.
…teness critic, and AI refinement - bone primitive (endpoint capsule) for reliable limbs; brighter viewer light rig + default clearcoat - centralised the deterministic repair chain in spec-passes/run-all; added face alignment + a face-part backstop, ring-collar seating, interior-cavity clamp, recess seating, and linear wheel-fusion repair - general completeness critic that adds parts the render is missing vs the reference (esp. glazing); glass/hollow-window handling; recolor via materialId reassignment - Refine-with-AI: conversational refinement through the AI Assistant (RefineSculptCommand + skill + studio button), editing the current round's spec in place, on Gemini Flash - SculptedModel keeps all reference views (MultiImageSourceField) and a revision counter for viewport cache-busting; runtime assets nest under img-to-3d/<studio-id>/ - analysis defaults to Gemini Flash; removed the dead runtime-interpreter render chain (model-viewer / spec-interpreter / three-loader)
… targeting - attachOrphans pass: give any part with no attachTo the nearest mass so the render's joint solver / contact backstop seat it instead of leaving it floating (assign-only, gap-capped, ties toward larger mass — no clump risk). Wired last in runStructurePasses; unit-tested. - RefineSculptCommand now edits the studio's CURRENT round (resolved via sourceStudioId -> selectedCreation/latestCreation), not the stale round the assistant room attached at open time. - Cap first generation to 2 AI correction passes via AUTO_VERIFY_ROUNDS.
Staging Submissions PreviewThis PR's content is pushed to the staging submissions realm: https://realms-staging.stack.cards/submissions/ Changed listings: Changed folders:
Updated at 2026-07-29 13:55:12 UTC for commit |
…form Its adoptsFrom now spells the module with the @cardstack/catalog alias and buildBackend is present, matching the round-1 instance.
lucaslyl
marked this pull request as ready for review
July 30, 2026 06:42
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Turn a product photo into an editable 3D model. Drop in a reference image and the studio analyzes the object, plans its parts, and rebuilds it as a procedural Three.js sculpture you can spin, export, and refine — no modeling skills needed. It works best on simple, regular geometry and hard-surface objects — bottles, cans, mugs, furniture, boxes, cylinders and revolved shapes — where a handful of primitives capture the form cleanly. It reproduces real labels and printed graphics from the photo (and tells a stuck-on sticker apart from a print applied straight onto the surface), saves every generation as an editable code file with full version history, and lets you fine-tune the result conversationally through the built-in AI assistant or export it as a .glb. Highly organic or precision-mechanical subjects (faces, figures, firearms) are harder and may only approximate.