Repository navigation
fix: snap cutter faces lying just off a parallel operand face before differences - #2282
Merged
beachtom merged 2 commits intoOct 21, 2026
Merged
Conversation
…differences Openings exported a tenth of a millimetre off the wall faces and tilted by about 1e-5 rad straddle the 1e-4 coplanarity tolerance: some vertices of the opening's face count as on the wall's plane, others as off it. The difference then comes out open, caps the hole with the opening's flipped face, or skips the cut altogether. Before each difference, cutter faces within twice the plane deviation tolerance of a parallel operand face are moved exactly onto that plane: - cutter positions are welded first so every copy of a vertex moves together - a vertex on faces snapped to several planes goes to the closest point on all of them - the stored vertex normals follow the face, since buildPlanes prefers them and would otherwise tilt the face back - a face within reach of parallel planes at different offsets (an operand sliver thinner than the snap distance) is left alone - open cutters are left alone, and the snapped cutter is used only if it is still closed once its planes are fitted Adds three synthetic metre-unit walls with misaligned extruded and faceted brep openings to the boolean robustness tests.
Matches how file-local helpers are declared elsewhere in web-ifc. No functional change; the built WASM is byte-identical.
beachtom
approved these changes
Oct 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes the walls still broken in #2269.
Revit exports in #2269 place openings 0.02–0.14 mm off the wall faces and tilt them by about 1.8e-5 rad. Because of the tilt, the distance between an opening face and the wall face varies along the face, for example 0.998e-4 … 1.38e-4 m, which straddles the 1e-4 coplanarity tolerance. Some vertices of the face count as lying on the wall plane and others don't. Depending on the wall, the difference comes out open, keeps the opening's flipped face as a cap across the hole, or skips the cut. One wall fails with offsets of 0.02–0.07 mm, fully inside the tolerance, because the tilted face is still classified inconsistently.
Before each difference, this PR moves cutter faces that lie within 2×
TOLERANCE_PLANE_DEVIATIONof a parallel operand face exactly onto that face's plane (SnapToOperandPlanesinIfcGeometryProcessor.cpp):buildPlanesprefers them over the triangle normal and would otherwise tilt the face back.Validation (element by element, with and without the change, against IfcOpenShell 0.8.5):
The reduced model from [Bug]: Incorrect boolean subtraction creates triangular surfaces across wall openings #2269, on
maindd44aa7 withCOORDINATE_TO_ORIGINon and off:mainThe other 48 elements are unchanged.
tests/ifcfiles/public: 8 files change, and 11 elements get better:ISSUE_159_kleine_Wohnung_R22.ifc(open mesh → closed, 2.4275 m³) and 6 inS_Office_Integrated Design Archi.ifc;AC20-FZK-Haus.ifc(also inISSUE_005_haus.ifc) and 2 more in S_Office.The rest change triangulation only. One S_Office element (#396617) turns from open to closed with the same volume; IfcOpenShell differs from both by 2.6 m³ and 20 m².
Six larger models, mostly private, with about 135,000 elements: 25 elements change. Seven are better: five now match IfcOpenShell and two are closer. The rest change triangulation only or by less than 0.01 %. None got worse.
tests/functional/BooleanRobustness.spec.jsgets three synthetic metre-unit walls with misaligned extruded and faceted brep openings. All three fail onmainand pass here. The expected values are the nominal sizes, because IfcOpenShell keeps a skin for two of them.Jest: all 324 tests pass on this branch's freshly built Node WASM.
npm run regression: all 30 models pass.Cost: about +3 % total geometry time on a 640 MB model.
Build environment: Node 24.20.0, Emscripten 4.0.23.
Notes for review:
TOLERANCE_PLANE_DEVIATIONto a parallel operand face (0.2 mm in metre models) now ends exactly on that face, so skins thinner than that are no longer kept.