Skip to content

feat(booleans): subtract a slanted planar cutter from arc-edged extrusions, with exact ellipse ends - #59

Merged
aka-blackboots merged 6 commits into
mainfrom
task/planar-cut-of-arc-extrusions
Nov 15, 2026
Merged

aka-blackboots merged 6 commits into
mainfrom
task/planar-cut-of-arc-extrusions

Conversation

@aka-blackboots

@aka-blackboots aka-blackboots commented Nov 15, 2026 •

Copy link
Copy Markdown
Contributor

What

Solid.operate(OG_OPERATION_SUBTRACT, { tools }) now subtracts a slanted planar cutter from an extrusion whose profile has arcs (handler subtract_half_space_from_arc_extrusion):

  • The extrusion can mix lines and arcs in its profile (half-round, full-round, ogee) or be an OG_PRIMITIVE_CYLINDER.
  • The cutter can be a cuboid or any convex prism, for example a mitre parallelogram.
  • The cut end is an exact ellipse (Ellipse edges on the B-rep), and the cylinder faces stay Cylinder.
  • Mitres at both ends work in one call: tools: [mitre0, mitre1].
  • The reverse order also works: a cuboid or convex prism minus a slanted rod or gutter gives a blind or through hole with ellipse rims.

Conditions

  • The cut plane must cross the whole extrusion strictly between its two ends.
  • In the reverse order, the box face must not also cut the rod's end discs, and the profile must have no holes.
  • Any other case still returns CoverageGap, as before.

Why

Floorkit draws two gutters that meet at a roof corner with a mitre on the corner bisector. Before this change, the cut failed with CoverageGap {generic analytic solid, intersecting analytic solid}.

Tests

Note

This PR and #58 both start from main. They conflict in boolean/dispatch/table.rs and in the golden fixture tests/fixtures/golden/aarch64-apple-darwin.json. The second one to merge needs those two files resolved and the golden fixture regenerated.

Half-round, full-round and ogee extrusions and a primitive cylinder lying on their side, cut by a slanted cuboid or parallelogram prism at 30, 45 and 60 degrees in plan, and two gutters mitred on a corner bisector, singly and as a two-cutter batch. Each result must be closed and valid, keep its cylinder faces analytic and carry an exact ellipse trim. Today every case is a coverage gap.
A planar cutter that crosses an extrusion of lines and arcs at an angle to its axis fell through every handler as a coverage gap, so gutters and rods could not be mitred. The new handler reads the host as a straight prism from its two caps, finds the one convex-cutter face that crosses every generator strictly between the caps while the cutter holds all of the removed end, and rebuilds the prism with that face as its new cap: cylinder sides stay analytic and each arc gets an exact ellipse trim. A batch of such cutters replaces one cap per cutter, so a gutter mitred at both ends is one result.

It sits right after the vertical arc-extrusion handler, so the stored half-space ring case (a cube with a round bore under the section clipper) now takes this handler instead of prismatic_curved_boolean, with the same eight faces, a valid solid and the same half volume. Every other change to recorded results is the new name in attempt lists: the half-space torus and revolved-bowl outcomes, the rail-minus-wall gap in the acceptance session, and the golden handler coverage lists.
Drawings take the cut end from the B-rep's ellipse edges, so the end face itself must be bounded by ellipse arcs that lie on both the bisector plane and the gutter cylinders and cover the whole half-round. Red on the code before the half-space handler (a coverage gap), green after.
A slanted cuboid minus a rod must keep a blind round hole with an ellipse rim, a slanted slab minus a rod a through hole with two rims, and a slanted prism minus a half-round gutter a gutter-shaped pocket, each valid and closed with analytic cylinder walls and the right removed volume. Today each is a coverage gap. The tilted cuboid minus cylinder case leaves the coverage-gap test, which now holds only for their union.
The reverse order of the half-space cut, a cuboid or prism minus a rod or gutter lying across one of its faces at a slant, was still a coverage gap. The prism model is trimmed by every face of the convex host it crosses cleanly, until each remaining face holds the trimmed piece inside it. The host is then copied with the trimmed piece's ends as holes in the faces it enters through. The piece's walls are reversed into the host, and an end of the rod that stays inside becomes the floor of a blind hole. Rims are exact ellipses and walls stay analytic cylinders. Holes square to the axis are left to the existing handlers, and so is a face that also cuts the rod's end discs.

It shares the half-space handler's dispatch entry, so no attempt list moves. The golden cylinder-box oblique-20 and oblique-45 reversed subtractions, recorded as coverage gaps, now return a nine-face result; oblique-70 stays a gap because that face reaches past both ends of the cylinder.
…c-extrusions

# Conflicts:
#	main/opengeometry/src/operations/modifying/boolean/dispatch/table.rs
#	main/opengeometry/tests/fixtures/golden/aarch64-apple-darwin.json
@aka-blackboots
aka-blackboots merged commit 50da168 into main Nov 15, 2026
0 of 4 checks passed
@aka-blackboots
aka-blackboots deleted the task/planar-cut-of-arc-extrusions branch November 15, 2026 00:24
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