Point to Mesh Distance
Stamp a signed distance field onto your point cloud
- target_mesh
- pointcloud
- pointcloud
- info
A point cloud is just a bag of coordinates until you know how each point relates to the surface it was scanned from. Point to Mesh Distance computes exactly that: for every point in your cloud, how far is it from a target mesh - and optionally which side it's on, inside or outside. The output is your point cloud back again with a per-point distance field attached, ready to colorize, filter, or feed into a reconstruction.
It's part of ComfyUI-GeometryPack ("ComfyUI libigl") by Andrea Pozzetti, and it's one of the pack's two distance nodes - this one is point-centric, its sibling Mesh to Mesh Distance is about whole-surface error.
How it works
You give it a target_mesh (the surface to measure against) and a pointcloud (which the code happily accepts even if it's actually a full mesh - it just uses the vertices). Two modes via distance_type:
unsigned- every point gets the distance to the nearest surface point. Uses trimesh'sclosest_pointquery. Fast, robust, no assumptions about the target being closed.signed- points also get a sign: negative inside the mesh, positive outside. This is libigl'ssigned_distance, and it's the powerful one - signed distance is what SDF-based reconstruction and many sculpting/boolean pipelines want.
The sign_method combo only matters for signed mode and is where the fine control lives: default (fast and robust, libigl's choice), winding_number (accurate, handles non-watertight targets), fast_winding_number (the same but faster, slightly less exact), pseudonormal (the legacy test), and unsigned (which forces unsigned behavior even in signed mode). If your target mesh has holes, winding_number is the honest option; default can misclassify points near broken geometry.
The outputs are the pointcloud back (with the distance field added as a vertex attribute) and an info string summarizing the computation.
What you'd actually do with it
- Colorize and inspect - the distance field drops into the pack's field-aware preview nodes, so you can literally see how well a point cloud fits its target surface. Areas of high distance are your scan errors.
- Filter outliers - a point cloud where most points hug the surface but a few float far off? Threshold on the field to flag or drop them.
- Prep for reconstruction - signed distances to a reference are the standard input for making a clean SDF-derived surface.
Install and gotchas
Pack standard: search "GeometryPack" in ComfyUI Manager, or:
cd ComfyUI/custom_nodes
git clone https://github.com/PozzettiAndrea/ComfyUI-GeometryPack.git
cd ComfyUI-GeometryPack
pip install -r requirements.txt --upgrade
python install.py
Restart after. The pack installs via the experimental comfy-env + pixi route with a heavy isolated environment; libigl arrives with it, but signed mode will throw a clear "install libigl" error if it's ever missing.
The traps are conceptual more than technical. Signed distance assumes your target is a reasonably closed surface - against a half-open shell, the sign near the opening is unreliable, which is exactly the case winding_number exists for. And the two meshes must share a coordinate frame; if your point cloud is in scan space and the target in world space, the "distances" are nonsense and won't look obviously wrong. Normalize both, or don't normalize either.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| target_mesh | TRIMESH | — | |
| pointcloud | TRIMESH | — | |
| distance_type | COMBO | 2 options: unsigned, signed | |
| sign_method | COMBO | 5 options: default, winding_number, fast_winding_number, pseudonormal, unsigned |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| pointcloud | TRIMESH | — |
| info | STRING | — |