Repository navigation
roof(): voronoi method roofs unions of touching pieces - #268
Merged
Merged
Conversation
The default roof() gave nothing -- or ran away allocating -- for many unions of triangles/rectangles that touch along edges. Three causes: - Clipper returns pieces sharing an edge as outlines a hairline apart, which on the grid overlap or cross. Boost's Voronoi builder needs segments that meet only at their ends: the diagram came out wrong (no roof), or the builder never finished, growing without bound (16 of 6,000 corpus inputs; tens of GB). The outline is now welded and re-unioned first, as method="straight" already does, keeping the original outline (and so the identical roof) when welding changes nothing. - On a clean outline Boost still occasionally builds a wrong diagram where four sites are all but equidistant after rounding to the grid (a cell with no finite edges). The roof is retried on coarser grids (2^28..2^25) when the mesh does not come out a valid, non-empty solid. - An unused vertex -- the far end of a Voronoi edge outside the outline, up to 10^12 away -- stretched the bounding box Manifold sizes its tolerance by; its cleanup then collapsed the roof to nothing, or quietly dropped detail (old volumes off by up to 25% vs OpenSCAD). Such far vertices are now left out of the mesh. The weld's corner-vs-edge scan now only visits corners in each edge's x range, so the extra pass costs 2-10% of roof time at 1000-5000 corners. method="straight" output is byte-identical. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 8, 2026
Merged
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.
The default
roof()(method="voronoi") gave no roof (and on some inputs allocated without bound) for unions of pieces that touch along edges. On a seeded 6,000-input corpus it failed on 384 before, 16 of them runaways (one reached 36 GB); it now fails on none.Root causes
weldContours(weld, re-union, drop straight corners and spikes) first; an outline the weld leaves unchanged except for loop start/order is used as is, so its roof is identical.RoofMesh::builddrops unused vertices beyond 16× the mesh extent.The weld's corner-vs-edge scan now only checks corners in each edge's x range.
Verification
method="straight"is byte-identical on 1,600 inputs.tests/test_extrude_roof.cpp, all failing on the old code. Note: the runaway test allocates without bound on the old code, so beware when bisecting across this change. Full suite: 1468 passed.🤖 Generated with Claude Code