Skip to content

fix(booleans): exact cylinder minus half-space cuboid with ellipse trims - #28

Merged
aka-blackboots merged 2 commits into
mainfrom
fix/plane-cylinder-ellipse-boolean
Oct 24, 2026
Merged

aka-blackboots merged 2 commits into
mainfrom
fix/plane-cylinder-ellipse-boolean

Conversation

@aka-blackboots

Copy link
Copy Markdown
Contributor

What

Exact Boolean for a full cylinder minus a half-space cuboid (one face plane cuts the cylinder).

Before, this cut failed when the plane was oblique to the cylinder axis (coverage gap), or parallel to a sloped axis (SSI support residual). Now the kept part is built directly:

  • the side, trimmed by the exact cut ellipse (parameter = cylinder angle), or by two rulings when the plane is parallel to the axis;
  • full or chord-clipped caps;
  • one planar cut face.

Aligned subtractions keep their existing builders.

Robustness

  • The chart is built from cross products, so near-perpendicular cuts keep an orthonormal frame.
  • The near-parallel guard is a rounding bound on the ellipse centre and amplitude, not an absolute value.
  • Only exact results and UnresolvedIntersection replace the original error; other failures keep the generic fallbacks.
  • Cuts within 1e-3 r of a side or rim (tessellation slivers) go to the other paths.

Tests

  • 9 new crate tests in analytic/booleans/cylinder_half_space.rs (oblique, perpendicular, parallel, sloped axis, near-rim probe families): all pass.
  • cargo test --release: 439 pass, 2 fail. The same 2 tests also fail on main at release: 2.0.18 without this change, so they are not caused by it:
    • analytic::tessellation::tests::a_trimmed_curved_face_keeps_its_triangle_set
    • analytic::wasm::tests::text_and_object_tessellation_give_the_pinned_triangles

Files

  • main/opengeometry/src/analytic/booleans.rs
  • main/opengeometry/src/analytic/booleans/cylinder_half_space.rs (new)

A full cylinder cut by one cuboid face plane failed when the plane was
oblique to the axis (coverage gap) or parallel to a sloped axis (SSI
support residual). Build the kept part directly: the side trimmed by
the cut ellipse (parameter = cylinder angle) or two rulings, full or
chord-clipped caps, and one planar cut face. Aligned subtractions keep
their existing builders.
- Build the chart from cross products so near-perpendicular cuts keep an
  orthonormal frame.
- Replace the absolute near-parallel guard with a rounding bound on the
  ellipse centre and amplitude.
- Only exact results and UnresolvedIntersection replace the original
  error; other failures keep the generic fallbacks.
- Leave cuts within 1e-3 r of a side or rim (tessellation slivers) to
  the other paths.
- Add the reviewer's probe families as crate tests.
@aka-blackboots
aka-blackboots merged commit 46de326 into main Oct 24, 2026
3 checks passed
@aka-blackboots aka-blackboots mentioned this pull request Oct 28, 2026
aka-blackboots added a commit that referenced this pull request Oct 28, 2026
Every file main changed is a 2.0 file that the 3.0 tree deletes or
replaces, so the 3.0 side is kept for each one.

- 533710f (2.0.17) and the 2D region fixes of cba5c0a are in geom2d
  (OPE-5, OPE-6); their tests moved into the crate.
- The memory work of cba5c0a is the memory module (OPE-16, OPE-17).
- The tessellation cache and accuracy rule of cba5c0a do not apply to
  the 3.0 tessellator.
- 46de326 (#28), the exact cylinder minus an oblique half-space cuboid,
  is not in 3.0 yet; tracked as OPE-33.
- The root package.json keeps the 3.0 workspace form; the version lives
  in main/package.json.
aka-blackboots added a commit that referenced this pull request Oct 30, 2026
The 2.0 kernel built a full cylinder minus a cuboid tilted against its
axis exactly (main 46de326, #28); 3.0 deleted that code, so the cut was a
CoverageGap at every tilt between 0 and 90 degrees.

A new oblique path inside cylinder_box_boolean runs only where 3.0 refused
before: the cylinder axis is aligned with no cuboid axis and exactly one
cuboid face plane crosses the cylinder. It builds the side trimmed by the
cut ellipse (or two rulings when the plane is parallel to the axis), full
or chord-clipped caps and one planar cut face, for cylinder minus cuboid
and the intersection in either order. Cuboid minus cylinder and the union
stay refused. 2.0's guards are kept: the rounding bound and the 1/1000 r
sliver limit at a side or rim, which give UnresolvedIntersection. Any other
failure falls back to today's ["cylinder", "oblique cuboid intersection"]
gap, so no input gets a worse error. The result reports
cylinder_box_boolean, so no attempted list moves.

Tests port 2.0's probe families with a closed-form kept volume; the STEP
check pins the face, ellipse and pcurve-less edge counts. Twenty new golden
keys booleans.cylinder-box.oblique-*; no existing key moves.
@aka-blackboots
aka-blackboots deleted the fix/plane-cylinder-ellipse-boolean branch October 31, 2026 13:17
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