Nodes/ComfyUI-Charon/CHARON 3D Auto Align
ComfyUI Node

CHARON 3D Auto Align

Your scan won't stand up straight. This node fixes that.

By keghoang·Created 9 months ago·Updated 9 months ago· 0
CHARON 3D Auto Align
    • aligned_mesh_file
    • transform_json
    mesh_path
    symmetryfalse
    ground_snaptrue
    filename_prefixcharon_mesh
    save_transform_jsonfalse

    Reconstructed meshes come out of capture pipelines in arbitrary orientations. The floor is tilted 20 degrees, the model faces a random direction, and nothing lines up with your scene's axes. Normally that means loading the mesh into Blender and hand-rotating until it looks right. CHARON_3D_Auto_Align does it in one shot: point it at a mesh file, and it works out the dominant axes, rotates the mesh to align with world X/Y/Z, and optionally snaps the lowest point to the ground.

    The mechanism is more interesting than a PCA-based auto-centering. It runs a RANSAC loop (200 iterations) over face normals weighted by face area, building an orthonormal basis from the surface's dominant directions. Then it refines that basis with iterative median-axis passes, and finally tries the candidate flips to pick the orientation that best matches the +X/+Y/+Z axes. The symmetry option does a separate pass first: it hunts for a symmetry plane (sampling up to 10,000 faces, bucketing candidate planes, and taking the median) and locks that plane's normal as the fixed axis. That's a big win for characters and symmetric artifacts - a mirrored object can otherwise end up rotated in a way that's "correct" but useless.

    The inputs that matter:

    • mesh_path - a path to your mesh (.obj/.ply/.glb and friends; trimesh decides what's loadable). It's a string, so paste the absolute path.
    • symmetry - off by default, and it costs time. Turn it on for symmetric objects.
    • ground_snap - on by default. Lifts the mesh so the lowest vertex sits on Y=0.
    • filename_prefix - prefix for the saved mesh (default charon_mesh).
    • save_transform_json - also writes a JSON with euler_xyz_deg to the output folder for debugging.

    The node saves the aligned mesh into ComfyUI's output directory (keeping the original file extension, with a random suffix) and returns two outputs: aligned_mesh_file (the path) and transform_json (a JSON string with a 3×3 rotation and an xyz translation). It also publishes the mesh via the ui.meshes block, so it appears in Comfy's history and downloads like an image would. The real payoff is wiring transform_json into CHARON_Camera_From_DA3 - that moves the captured cameras to match the aligned mesh, which is the whole point of this pack.

    Honest caveats. The RANSAC is stochastic - no fixed seed - so re-running can land on a different-but-valid orientation, occasionally a 180° flip on an axis. If it picks the "wrong" hemisphere, just run it again. Large meshes get subsampled to 10k faces for the fitting, so a 5-million-face scan won't hang forever, but fine noisy detail can confuse the result; symmetry helps. And this is an orientation tool, not a repair tool - if your mesh has no clear dominant planes, it will still rotate it somewhere, just maybe not where you hoped.

    Common issues are straightforward: mesh_path empty or mistyped gives "mesh_path is required" or "Mesh not found"; a file with no geometry gives "Mesh has no geometry". The only real dependency is trimesh - if imports fail, that's why.

    Install (shared with the whole pack):

    cd ComfyUI/custom_nodes
    git clone https://github.com/keghoang/ComfyUI-Charon
    cd ComfyUI-Charon
    pip install -r requirements.txt   # just trimesh>=4.0; NumPy comes with ComfyUI
    

    Restart ComfyUI and you'll find both nodes under CHARON/3D. ComfyUI Manager works too - search "ComfyUI-Charon". No model files, no keys, nothing heavy. This is a small, single-purpose pack that does one job well: making your scans face the right way.

    CategoryCHARON/3D

    Inputs (5)

    NameTypeDefaultDescription
    mesh_pathSTRINGPath to mesh file (.obj/.ply/.glb etc.)
    symmetryBOOLEANfalseTry to detect symmetry plane before alignment
    ground_snapBOOLEANtrueLift mesh so lowest point sits on Y=0
    filename_prefixSTRINGcharon_meshPrefix for saved aligned mesh in ComfyUI output directory
    save_transform_jsonBOOLEANfalseAlso write transform JSON to output directory for debugging

    Outputs (2)

    NameTypeDescription
    aligned_mesh_fileFILE
    transform_jsonSTRING