mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-11 10:06:47 +00:00
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 <noreply@anthropic.com>
This commit is contained in:
@@ -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) {
|
||||
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user