I Built an Image to 3D Model App using LangGraph Meta Descr | Coderz Club

I Built an Image to 3D Model App using LangGraph Meta Description: How I built a full-stack image-to-3D pipeline using Gemini, Hunyuan3D-2, LangGraph, FastAPI, Trimesh, and WebGL. I wanted to experim

I Built an Image to 3D Model App using LangGraph Meta Description: How I built a full-stack image-to-3D pipeline using Gemini, Hunyuan3D-2, LangGraph, FastAPI, Trimesh, and WebGL. I wanted to experim

By Coderz Club · 2026-09-04 · Tags: ai, api

I Built an Image to 3D Model App using LangGraph

Meta Description: How I built a full-stack image-to-3D pipeline using Gemini, Hunyuan3D-2, LangGraph, FastAPI, Trimesh, and WebGL. I wanted to experiment with a problem that sounds simple: Can a single 2D image be turned into a usable 3D model? A single image gives us information about the visible surface, but says very little about the hidden geometry. The challenge isn't just generating a mesh; it is handling the entire pipeline around it. So I built Core3D, a system that takes a single image, preprocesses it, adds geometric context, generates a 3D mesh, repairs and validates the geometry, and finally lets the user inspect the resulting .GLB model directly in the browser. The end-to-end pipeline averages roughly 22 seconds in the project's benchmark. Architecture The application is split between a Next.js frontend and a FastAPI backend. ┌──────────────────────┐ │ Next.js Frontend │ │ WebGL Studio │ └──────────┬───────────┘ │ HTTP / GLB │ ┌──────────▼───────────┐ │ FastAPI API │ └──────────┬───────────┘ │ LangGraph Pipeline │ ┌──────────────────┼──────────────────┐ │ │ │ ▼ ▼ ▼ Preprocessing VLM Conditioning 3D Generation U2-Net Gemini Hunyuan3D-2 │ │ │ └──────────────────┼──────────────────┘ ▼ Mesh Processing Trimesh │ ▼ Final GLB The frontend uses Next.js, React, TypeScript, Tailwind CSS, and Google's <model-viewer>. The backend uses FastAPI, LangGraph, LangChain, and Pydantic. 1. Preprocessing the Image The first problem is background noise. If the input image contains a table, wall, floor, or other objects, the 3D reconstruction model has to distinguish the actual subject from everything else. I use rembg with U2-Net to isolate the foreground object. Input Image ↓ U2-Net / rembg ↓ Foreground Mask ↓ Bounding Box ↓ Center + Pad ↓ 1024 × 1024 RGBA After segmentation, the subject is cropped from its bounding box, scaled with approximately 15% padding, centered, and resized to 1024 × 1024. This gives the reconstruction model a much more consistent input regardless of how the original photograph was framed. 2. The Problem With a Single View A single image only exposes one side of an object. For example, a photograph of a chair might show the seat, front legs, and backrest while giving us no direct information about the rear structure. The model therefore has to infer: Hidden surfaces Object thickness Rear geometry Structural connections Overall volume Instead of relying only on the image, I added a multimodal conditioning step. 3. Using Gemini as a Geometric Conditioning Layer The preprocessed image is sent to Gemini 3.1 Flash-Lite. Gemini isn't responsible for generating the mesh. Instead, it produces a compact description of the object's 3D structure, including its volume, materials, shape, and likely hidden geometry. Image │ ▼ Gemini Vision Model │ ▼ Geometric Description │ ▼ 3D Reconstruction This makes the vision-language model act as a conditioning layer for the 3D model. For example, instead of giving the reconstruction model only: "chair" it can receive a more useful description such as: "Minimalist wooden chair with a rectangular seat, four tapered legs, solid rear support and smooth wooden surfaces." The implementation also has a fallback path so that if the multimodal request fails, the pipeline can continue using the user's prompt or a default description. 4. Generating the 3D Shape Once the image has been prepared and conditioned, it is sent to Hunyuan3D-2 through a Hugging Face ZeroGPU Space. The backend uses gradio_client to communicate with the remote inference service. The current configuration includes: Steps: 30 Guidance Scale: 5.5 Octree Resolution: 256 Num Chunks: 8000 The generated result is returned as a .GLB file. The interesting part here is that the expensive 3D inference doesn't have to run directly inside the FastAPI process. FastAPI │ ▼ Hugging Face ZeroGPU │ ▼ Hunyuan3D-2 │ ▼ Raw GLB This keeps the application backend relatively lightweight while still exposing the model through a normal API. 5. Why the Raw Mesh Isn't the Final Mesh A generated mesh isn't necessarily ready for rendering. It can contain: Incorrect normals Inverted faces Small holes Unnecessary geometry Excessive polygon counts So the generated GLB is passed through a separate mesh-processing stage using Trimesh. Raw GLB ↓ Load Geometry ↓ Fix Inversions ↓ Fix Normals ↓ Fill Holes ↓ Decimate if Necessary ↓ Validate ↓ Final GLB The pipeline uses Trimesh repair functions to fix inversions, normals, and holes. It also applies polygon reduction when the mesh exceeds 45,000 faces. This matters because a high-polygon model isn't necessarily a better model for an interactive browser application. 6. Validation and Retry Logic I didn't want to blindly trust whatever geometry the model generated. The pipeline tracks information such as: face_count is_valid retry_count max_retries After mesh processing, LangGraph determines whether the result is acceptable. ┌──────────────┐ │ M

View this page on Coderz Club