Skip to content

levelset: cut cleanly where a 3D surface meets the box - #127

Merged
revarbat merged 1 commit into
mainfrom
levelset-clean-3d-boundary
Aug 27, 2026
Merged

levelset: cut cleanly where a 3D surface meets the box#127
revarbat merged 1 commit into
mainfrom
levelset-clean-3d-boundary

Conversation

@revarbat

Copy link
Copy Markdown
Member

Your gyroid found a real bug. Same script, before and after:

before after
voxel staircase along every edge where the sheet meets the box clean planar cuts

Cause

Manifold closes the mesh where the surface reaches the edge of the box it is given, and that closure follows the sample lattice. Anything touching the boundary gets a voxel staircase — and a gyroid touches it everywhere, which is why it showed up so starkly next to BOSL2's isosurface() of the same field.

Fix

Exactly what the 2D path already did: sample a box padded by 2 * edge, let the ragged closure happen out there, then intersect with a cube at the bounds actually requested. The cut becomes a plane.

The grid intake needed one more thing — its sampler now reads "outside" beyond the data rather than clamping, which would smear the boundary values outward and extend the surface instead of closing it.

Why the tests missed it

Every shape in them sat inside its box. The numeric form of the bug is sharp once you look for it — a half-space should be exactly half the box at any resolution:

edge=2     32000   (expect 32000)
edge=1     32000
edge=0.5   32000     err = 0 at every resolution

That is the 3D twin of the 2D half-plane test which caught this same class of bug a few hours ago. The 2D path got this fix first and I did not check 3D — worth recording, and CLAUDE.md now says so: a boundary bug found in one dimension is worth looking for in the other.

A sphere sitting well inside its box is unaffected (33487.2, unchanged), confirming the padding disturbs nothing that does not reach the boundary.

Three regression tests: the half-space at three resolutions, an interior sphere, and the grid intake cut at the box. 1078 pass under both engines.

Version 0.51.0 → 0.51.1.

🤖 Generated with Claude Code

Reported from a real model: a gyroid built with levelset() came out
visibly staircased along every edge where the sheet meets the bounding
box, next to a smooth one from BOSL2's isosurface() of the same field.

Manifold closes the mesh where the surface reaches the edge of the box
it is given, and that closure follows the sample lattice. Anything
touching the boundary gets a voxel staircase; a gyroid touches it
everywhere.

Fixed the way the 2D path already was: sample a box padded by 2*edge,
let the ragged closure happen out there, then intersect with a cube at
the bounds actually asked for, so the cut is a plane. The grid sampler
now reads "outside" beyond its data rather than clamping, which would
smear the boundary values outward and extend the surface instead of
closing it.

The tests did not catch this because every shape in them sat inside its
box. The numeric form of the bug is sharp once looked for: a half-space
should be exactly half the box at any resolution, and now is -- 32000
to the digit at edge 2, 1 and 0.5.

Worth recording: the 2D path got this exact fix first, and 3D was not
checked at the time. A boundary bug found in one dimension is worth
looking for in the other.

Three regression tests. 1078 passing under both engines.
@revarbat
revarbat merged commit 9a7f672 into main Aug 27, 2026
5 of 6 checks passed
@revarbat
revarbat deleted the levelset-clean-3d-boundary branch August 27, 2026 18:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant