pub fn difference_all(a: &[Tri], comps: &[&[Tri]]) -> Option<(Vec<Tri>, bool)>Expand description
a − (∪ comps) for PAIRWISE-DISJOINT, per-component-closed, OUTWARD-wound
cutter components, computed in ONE conforming arrangement (disjoint-cutter
batching).
Soundness: arrange only intersects A×B pairs, and disjoint B components
have no B×B intersections to miss; classification decomposes per component
(BComponents). The #2176 lesson is a PRECONDITION here: every component
must be closed and outward-wound on its own — the caller (mesh_bridge:: subtract_many) orients each component before concatenation, and the router
only admits per-component-watertight cutters to a batch.
vs. sequential per-cutter subtraction this avoids re-arranging the (growing) host once per cutter — each intermediate round-trip through f32 + the snap grid re-jitters carve vertices off shared planes, so cut N+1 re-cracks what cut N reconciled (many-void walls’ compounding open edges) — and is ~N× cheaper on N box cutters.
Returns (difference, changed), the same shape as union_all’s
(union, conforming). changed == false means no cutter reaches the solid
a bounds (every A sub-triangle kept, no B sub-triangle kept): the
triangles are a re-tessellated, not a cut.