CHARON 3D Auto Align
Your scan won't stand up straight. This node fixes that.
- aligned_mesh_file
- transform_json
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 (defaultcharon_mesh).save_transform_json- also writes a JSON witheuler_xyz_degto 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.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| mesh_path | STRING | Path to mesh file (.obj/.ply/.glb etc.) | |
| symmetry | BOOLEAN | false | Try to detect symmetry plane before alignment |
| ground_snap | BOOLEAN | true | Lift mesh so lowest point sits on Y=0 |
| filename_prefix | STRING | charon_mesh | Prefix for saved aligned mesh in ComfyUI output directory |
| save_transform_json | BOOLEAN | false | Also write transform JSON to output directory for debugging |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| aligned_mesh_file | FILE | — |
| transform_json | STRING | — |