Skip to content

Standard primitives: slot prism, rounded box, pipe segment, polysolid and three wires - #54

Merged
aka-blackboots merged 6 commits into
mainfrom
feature/standard-primitives
Nov 10, 2026
Merged

aka-blackboots merged 6 commits into
mainfrom
feature/standard-primitives

Conversation

@aka-blackboots

Copy link
Copy Markdown
Contributor

Summary

Adds the standard primitives that pass the full bar today: subtract, union and intersect with a box tool and a cylinder tool, shell, STEP export, valid and closed, exact volume. Each ships with its SDK constant, typed parameters, docs and an example page. All changes are additive; no existing kind, field, default or golden key changes.

Solids

  • OG_PRIMITIVE_SLOT_PRISM { length, width, height }: a stadium outline extruded along the normal.
  • OG_PRIMITIVE_ROUNDED_BOX { width, height, depth, radius }: a cuboid with its four upright edges rounded.
  • OG_PRIMITIVE_PIPE_SEGMENT { outerRadius, innerRadius, height, startAngle, sweepAngle }: a ring sector, placed and angled like the cylinder sector.
  • OG_PRIMITIVE_POLYSOLID { path, width, height, justify? }: a wall of constant width and height along a path of straight legs and tangent arcs. Justify 'centre', 'left' or 'right'. Straight corners are mitred, bevelled above a mitre limit of 4. A closed path makes a ring wall.

Wires

  • OG_PRIMITIVE_REGULAR_POLYGON { sides, radius }: 3 to 1024 corners on a circle, the first on +u.
  • OG_PRIMITIVE_SLOT { length, width } and OG_PRIMITIVE_ROUNDED_RECTANGLE { width, breadth, radius }: the outlines of the slot prism and rounded box, so each extrudes into the matching solid.

Bad values return InvalidParameter naming the value. A polysolid joint where an arc meets a segment at an angle, a wall that overlaps itself, or a leg folded back by its mitre is refused and the message names the segments.

Also in this PR

  • The primitive dispatch is split by body type (kind.rs, solids.rs, wires.rs, sizes.rs) so new solid and wire kinds land in separate files. No behaviour change.
  • The migration docs name the 3.0 replacements for the wedge (a five-face polyhedron or an extruded triangle) and the 2.0 Curve (a polyline wire through its points).

Commits

One commit per change, in merge order:

  1. Split primitive dispatch by body type
  2. Name the 3.0 replacements for wedges and the 2.0 curve
  3. Add slot prism, rounded box and pipe segment solid primitives
  4. Add the Polysolid primitive with straight legs
  5. Add regular polygon, slot and rounded rectangle wire primitives
  6. Build polysolid paths with tangent arcs

Verification

  • npm run check green after every commit; npm run check:full (with both browser suites) green after commits 3 to 6.
  • Kernel snapshot: 10 new keys, none changed. Public API: new lines only.
  • Each new solid built by kind name through the built package: every subtract, union and intersect cell with a box and a cylinder tool, shell at 0.03, one STEP solid with no edge missing its surface curve, and the exact volume within the measure bound.
  • The five example pages (shapes/slot-prism, rounded-box, pipe-segment, polysolid, wire-kinds) and the docs pages load in a browser with no console errors.

Known limit

The straight-leg polysolid keeps collinear split faces from the stroke (the L wall has 10 faces rather than 8). Merging them would move golden values, so it is left for a follow-up.

The primitive module was at 589 of 600 lines and build_primitive at 77 of
80, with seven new kinds about to land from two lanes. Solid builders move
to solids.rs, wire builders and their checks to a new wires.rs, the shared
check_arc to sizes.rs, and the Primitive enum with its body_type to kind.rs
so the children do not import their parent. build_primitive now picks
build_solid or build_wire by body type, so new solid and wire arms land in
different files. No behaviour change.
The documents said wedges and curves other than lines, circles and arcs
have no replacement in 3.0. A wedge builds today as a five-face
polyhedron or an extruded triangle, and the 2.0 Curve was a polyline
through its control points, which OG_PRIMITIVE_POLYLINE makes. The
elliptical arc has no replacement, and 3.0 has no spline, ellipse or
elliptical arc; the text keeps saying so.

The migration page gains a checked example for each replacement, the 2.5
guide moves Wedge and Curve to "Partly replaced", and the variable
holding a cylinder sector is no longer called wedge.
Each kind extrudes an outline of lines and arcs with the arc-edged
extrusion, standing on its plane like the cuboid (the pipe segment placed
and angled like the cylinder sector). The outlines are pure functions so
the wire kinds can reuse them. Bad sizes, a corner radius at or past half
the width or depth, a sweep of zero or a full turn, and an inner radius at
or past the outer one return InvalidParameter naming the value.

The SDK gains the three kind constants, params helpers and types; the docs,
examples, changelog and README list them; the golden file gains the three
new builder keys only.

A slot width too narrow for its end arcs is refused as a bad width too.
A polysolid is a wall of constant width and height along a path in the
plane. The builder strokes the path with the mitred polyline offset and
extrudes the single region it gives, with the hole of a closed loop.
Justify left or right shifts the path by half the width first. Arc
segments, short or zero-length legs, a crossing path and a stroke that
is not one region are refused with InvalidParameter, so the stroke never
drops points without telling the user. The SDK gets the kind constant,
its params helper and type, with docs, an example page and changelog
lines.

Left and right justify bevel the shifted path at the stroke's mitre limit, so a sharp corner cannot push the wall past it. Path checks return InvalidParameter; errors from the stroke and the extrusion pass through as they are.
The regular polygon is a closed polyline of 3 to 1024 corners on a circle,
the first on +u. The slot and rounded rectangle are closed profile wires
built from the slot prism and rounded box outlines, so each extrudes into
the matching solid. Bad sides, sizes and corner radii return
InvalidParameter naming the value. The SDK gains the constants, helpers and
types; the docs, an example page, the changelog and README list them; the
golden file gains the three new wire keys only.
A polysolid path may now hold arc segments. Each joint that involves an
arc must be tangent; a line that does not continue an arc, or an arc
that does not continue the segment before it, is refused with
InvalidParameter naming the joint. Paths with arcs are built from a
direct offset outline: lines offset to parallel lines, arcs to
concentric arcs, straight corners mitred or bevelled at the stroke's
limit, then extruded with its hole for a closed path. The 2D curved
union of the stroke cannot do this today.

The path checks run in the builder, shared by both routes. A wall that
overlaps itself, a leg folded back by its mitre and an offset radius at
or below the tolerance are refused with InvalidParameter naming the
segments. Straight paths keep the stroke route unchanged. The guide,
the example page, the changelog and the README describe arc paths; the
golden file gains two new keys only.
@aka-blackboots
aka-blackboots merged commit a31cbe6 into main Nov 10, 2026
1 of 5 checks passed
@aka-blackboots
aka-blackboots deleted the feature/standard-primitives branch November 10, 2026 19:58
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