From 60033981b3ff768a1a28bbd3ad7f4b1091b26450 Mon Sep 17 00:00:00 2001 From: Petru Conduraru Date: Sat, 11 Jul 2026 07:48:52 +0300 Subject: [PATCH] Retry boolean CUT that OCCT reports done but subtracts no volume (#5630) An IfcOpeningElement voiding a dense tessellated first operand (an IfcGeographicElement terrain built from an IfcPolygonalFaceSet) is not cut: the opening solid overlaps the terrain, yet the result keeps the full volume. OCCT BRepAlgoAPI_Cut returns IsDone at the tight default fuzzy value but subtracts essentially nothing, and because it reports success the existing escalating-fuzziness retry never runs. At a higher fuzziness (still well under the min-edge ceiling) the section is computed correctly. After a CUT is deemed valid, and only while a higher-fuzziness retry is still permitted, compare the result volume to the first operand. If the removed fraction is negligible (< 1e-4 of operand A) treat the CUT as a failure so the escalation runs and finds a fuzzy value at which the cut actually happens. When no retry is left the result is accepted as before, so a genuinely tiny legitimate cut can never lose its outcome. New diagnostic GEO 156. Verified on OCC 7.9.2: the terrain goes from 7330.878 (no hole, 459 verts) to 6058.593 (real hole, 377 verts, still a closed manifold), removing the expected 1272 wedge. Regression: five currently-passing cut models (#619, #4118, #5473, #5186, #511) are byte-identical, and across the full 1447-object source file exactly one product (the terrain) changes. Co-Authored-By: Claude Opus 4.8 --- .../kernels/opencascade/boolean_utils.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/ifcgeom/kernels/opencascade/boolean_utils.cpp b/src/ifcgeom/kernels/opencascade/boolean_utils.cpp index 7695be65bc..e8b7a26ca2 100644 --- a/src/ifcgeom/kernels/opencascade/boolean_utils.cpp +++ b/src/ifcgeom/kernels/opencascade/boolean_utils.cpp @@ -1218,6 +1218,24 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To } } + // #5630 A solid-solid CUT whose tool operands survived the disjoint/ + // touching/narrow elimination above is expected to remove material. On + // dense tessellated first operands (e.g. IfcPolygonalFaceSet terrain) + // OCCT's BOP can silently return an essentially unchanged result at a + // tight fuzzy value, reporting IsDone yet subtracting ~nothing. Detect + // this near zero volume removal and, while a higher fuzziness retry is + // still permitted, treat it as a failure so the existing escalation can + // find a fuzzy value at which the section is actually computed. When no + // retry is left the result is accepted as is, preserving prior behaviour. + if (success && op == BOPAlgo_CUT && allow_retry) { + const double va = shape_volume(a); + const double vr = shape_volume(r); + if (va > 1.e-9 && (va - vr) < va * 1.e-4) { + success = false; + Logger::Root().Notice("GEO", 156, "Boolean subtraction removed no volume, retrying with higher fuzziness"); + } + } + if (success) { {