Remove Degenerate Faces
Remove Degenerate Faces — the invisible cleanup that keeps geometry libraries from exploding
- mesh
- cleaned_mesh
- info
Some faces aren't really faces. A triangle with two identical vertex indices - [0, 1, 1] - has zero area and exists only to break whatever runs into it next. Same for sliver triangles so thin they're below any reasonable area threshold. This node finds those degenerate faces and strips them out, then prunes the now-unreferenced vertices. It's not glamorous, but it's the difference between a mesh that sails through the pack's remeshers, booleans, and CGAL ops and one that throws a cryptic error three nodes downstream.
You drop this node on the canvas yourself - it's a first-class repair node, not a hidden backend.
How it works
Three passes, in order of subtlety. First it removes faces with duplicate vertex indices (the [0,1,1] class - the pack's own docs note these appear when vertex merging collapses two corners of a triangle together). Then it removes zero-area faces via trimesh's built-in nondegenerate_faces() check. Finally, if you've set a min_area threshold, it removes faces below that area too - the sliver-triangle pass for CAD imports. Afterward it drops any vertices that nothing references anymore, so you don't leave corpse vertices behind.
Why this matters in practice: degenerate faces are a leading cause of "your mesh is broken" failures in downstream geometry code, and they're invisible in a viewer. The pack's comment blocks list the culprits directly - vertex merging, OCC meshing producing slivers at CAD face boundaries, sloppy importers. Run this and a bunch of "impossible" downstream errors just stop happening.
Inputs and outputs
- mesh (TRIMESH) - the mesh to clean.
- min_area (default 1e-10) - optional area threshold; faces below it are removed. The default is essentially "zero-area only." Raise it if you also want to purge pathological slivers - but go carefully, since legitimately small triangles (high-detail areas) will get caught too.
Outputs: cleaned_mesh (TRIMESH) and info (STRING). The info report is genuinely useful here: it counts how many faces were removed and whether any were found at all. If it reports zero, your mesh was already clean - cheap peace of mind.
Installing
Standard GeometryPack install - ComfyUI Manager → GeometryPack, 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. This node is pure trimesh - no heavy backend, so unlike the Blender/CGAL/GPU nodes there's nothing extra to download. It runs in the pack's base environment.
Where it fits in a workflow
Stick it right after any operation that can manufacture degenerate faces: a vertex-merge step, a CAD import, a boolean, or a decimation that collapsed edges into zero-area triangles. If you're about to feed a mesh into a remesher or the intersection-fix nodes and it's been through any of those, a quick pass through here first is cheap insurance. The pack's own repair philosophy is "clean before you process," and this is the first scrub.
Troubleshooting
- "No degenerate faces found" - good news, that's the point of the info line. If downstream errors persist, the problem is elsewhere.
- Lost detail after raising min_area - you set the threshold too high and ate real geometry. Drop it back toward the default.
- Vertex counts odd after - the node removes unreferenced vertices, so a vertex-count drop alongside the face removal is expected, not a bug.
- Pack-wide note: this is an actively developed pack, so if a saved workflow with it throws after an update, re-add the node rather than assuming you did something wrong.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| mesh | TRIMESH | — | |
| min_areaopt | FLOAT | 00–1 | Minimum face area threshold (faces below this are removed) |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| cleaned_mesh | TRIMESH | — |
| info | STRING | — |