Skip to content

fix(boolean): recover coplanar boundary triangles dropped in normalization (#2111) - #2217

Merged
QuimMoya merged 1 commit into
mainfrom
pr-2111-coplanar-boundary
Sep 23, 2026
Merged

QuimMoya merged 1 commit into
mainfrom
pr-2111-coplanar-boundary

Conversation

@QuimMoya

Copy link
Copy Markdown
Contributor

Problem

TriangulatePlane (fuzzybools normalization) classifies each candidate triangle by casting a ray from its centre and testing containment in both operands. A coplanar face whose centre lies exactly on a face of an operand is classified as neither INSIDE nor BOUNDARY, so the triangle is dropped and the boolean result develops a hole — the "missing geometry" family (e.g. thin walls, slab tops), tracked in #2111.

Fix

Rescue such a triangle inside the normalization pipeline: if its centre lies on an original face of A and is not strictly inside B, mark it as an A boundary (recording that face's normal for correct winding) and keep it.

Recovering it here — rather than stitching afterwards — reuses the already-welded vertices, so no T-junctions or non-manifold edges are introduced by the recovery. The change is gated behind the existing "both operands non-boundary" drop condition, so only triangles that would otherwise be discarded are considered.

Verification (native geomquality A/B, main vs this branch)

No model that opened before hangs or crashes. Naked-edge / non-manifold totals:

model main fix
2111 279 / 7 270 / 7
540 29803 / 1172 29735 / 1148
1677 16245 / 81 16221 / 78
1256 14466 / 901 14403 / 905
219 158 / 103 158 / 103
Spacewell_Wall 1030 / 105 1030 / 105

Fixes #2111

…ation (#2111)

TriangulatePlane classifies each candidate triangle by casting a ray from its
centre and testing containment in both operands. A coplanar face whose centre
lies exactly on a face of an operand is classified as neither inside nor
boundary, so the triangle is dropped and the result develops a hole (the
"missing geometry" family, e.g. thin walls).

Rescue such a triangle inside the normalization pipeline: if its centre lies on
an original face of A and is not strictly inside B, mark it as an A boundary and
keep it. Recovering it here rather than stitching afterwards reuses the
already-welded vertices, so no T-junctions or non-manifold edges are introduced.

Fixes #2111
@QuimMoya
QuimMoya merged commit 98436dd into main Sep 23, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Missing geometry

1 participant