Skip to content

feat: add image-blast-export skill (usdz, stl, fbx)#3

Open
mvanhorn wants to merge 1 commit into
neilsonnn:mainfrom
mvanhorn:feat/multi-format-export
Open

feat: add image-blast-export skill (usdz, stl, fbx)#3
mvanhorn wants to merge 1 commit into
neilsonnn:mainfrom
mvanhorn:feat/multi-format-export

Conversation

@mvanhorn
Copy link
Copy Markdown

Summary

A new image-blast-export skill converts generated .glb objects to USDZ (Apple AR / Vision Pro), STL (3D printing), and optionally FBX (Unity / Unreal, behind a --via blender flag).

Why this matters

The README markets image-blaster as embeddable in Unity, Unreal, Godot, Blender, Three.js, and Electron. Today the per-object output is .glb and .obj only. That covers Three.js and Godot but not Unity/Unreal (which want FBX), not Vision Pro / AR Quick Look (which wants USDZ), and not 3D printing (which wants STL). This skill closes that gap with a pure-JS path for USDZ + STL and an opt-in path for FBX.

Source Evidence
Meshy image-to-3D features page Meshy exports 7 formats including GLB, OBJ, FBX, STL, USDZ
Tripo3D multi-format export strategy FBX for Unity, USDZ for AR, USD for Vision Pro, GLB for web
Threedium: Export Image-To-3D for Unity Unity preferring FBX with PBR materials

Demo

Simulated demo (HyperFrames):

demo

The terminal scene shows the actual smoke test output: butterfly.glb (from app/public/butterfly/) converts to a 46.1 KB USDZ and a 15.5 KB STL.

Changes

  • .claude/skills/image-blast-export/SKILL.md plus matching image-blast-export.md agent
  • .claude/scripts/asset-pipeline/convert-mesh.mjs -- pure-Node converter using three-stdlib's GLTFLoader, USDZExporter, STLExporter against the local .glb
  • FBX is gated behind --via blender: when present and blender is on PATH, the script shells out via bpy.ops.import_scene.gltf + bpy.ops.export_scene.fbx. Without --via blender or without blender on PATH, FBX is skipped with a one-line warning (not a hard fail)
  • three and three-stdlib added to root devDependencies so the script runs from the repo root (versions match app/package.json)
  • Indexed file convention preserved: outputs are N-<slug>.usdz, N-<slug>.stl, with .N-<slug>-<fmt>-request.json provenance beside each
  • README Advanced section updated; .claude/settings.json allow-list refreshed for the new skill + script

Testing

Smoke-tested locally against app/public/butterfly/butterfly.glb:

$ node .claude/scripts/asset-pipeline/convert-mesh.mjs \
    --input app/public/butterfly/butterfly.glb \
    --output-dir /tmp/convert-smoke \
    --formats usdz,stl --asset-name butterfly
{
  "outputs": [
    { "format": "usdz", "path": "/tmp/convert-smoke/0-butterfly.usdz" },
    { "format": "stl",  "path": "/tmp/convert-smoke/0-butterfly.stl"  }
  ],
  "skipped": []
}

Result: 0-butterfly.usdz (46.1 KB) and 0-butterfly.stl (15.5 KB) plus matching .0-butterfly-<fmt>-request.json provenance files. node --check passes on convert-mesh.mjs. FBX gracefully skips when blender is not on PATH.

AI was used for assistance.

yugao-gaos added a commit to yugao-gaos/image-blaster that referenced this pull request May 28, 2026
Addresses 4 UX gaps in the cube-capture flow:

- Back to faces (neilsonnn#2): MaskPainter cancel now returns to the 6-face picker
  (setPhase 'picking') instead of reset(); a separate ✕ still closes the flow.
- Inpaint review (neilsonnn#3): new 'reviewing' phase + InpaintReview modal shows
  Original vs Inpainted side-by-side (plus a wipe slider) with Use / Re-mask /
  Discard — only "Use" records the result. MaskPainter routes inpaint success
  through reviewInpaint() instead of recording immediately.
- Persist + revisit capture position (neilsonnn#4): /__cube-capture writes a
  cube-capture-N.json sidecar with capturePosition; /__cube-captures returns it.
  CubeFacePicker gains a per-capture snap button + snaps on reopen.
  CameraSnapController (new) tweens the viewer camera back to a capture's
  vantage; works in Fly mode as-is and via a shared-ref teleport in FPS mode
  (cameraFocus.ts + CharacterController.tsx).
- WorldViewer mounts InpaintReview (DOM) + CameraSnapController (Canvas).

Store: inpaintedFaces map already existed; added pendingInpaint + reviewing
phase + cameraSnapTarget. Built via parallel sub-agent waves; whole app
tsc-clean, zero runtime console errors on fresh load. Live capture mechanics
unchanged from the prior validated fix; flux-fill inpaint model unchanged
(fal-ai/flux-pro/v1/fill).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant