A cut built slab by slab (the exact prism boolean) sewed the result from horizontal
slabs and only joins merged the coplanar pieces back. So a floor vent cut through the
Raspberry Pi case split the long wall into strips at the ports' tops and bottoms
(87 faces instead of 79 at 32 mm), and at 24 mm the end opening split the end wall.
- Prism booleans merge coplanar neighbours for every operation (faces only: edges,
curves and surfaces stay exact), keeping each face's construction source where all
its pieces share it, Split Face lines and regularization protection. Painted or
protected operands keep their authored pieces as before.
- The prism history now tells apart a wall's several edges with its caps (a wall
with openings meets each opening's floor), so cuts beside existing openings keep
exact history and faces keep their names.
- Tests: the Pi case's faces pinned after every feature at 24, at 24 changed to 32,
and built at 32 (each outer side one face); random openings and bosses on a
shelled case never split another side; every corpus design rebuilds a parameter
edit like a fresh build and reverts exactly.
- Action matrix baseline: demo/pi-case re-blessed (fewer, merged faces; no
regressions), demo/pi-case-0.8 recorded, and 88 new passes on
regressions/lid_ribs_flush_with_window.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A cut of stepped prisms sews a wall over one segment through successive
slabs as one face, and the generated planar walls are then joined on
their common supports. Until now such a piece carried no history.
- prism_lineage: a sewn wall records what it is over in each slab it
spans (Spec::Wall { levels, slabs }), so a coalesced wall comes from
the operand walls under it in every slab
- the sewn piece's history is attached before the joining and carried
through it (Built::Traced); planar_regularize composes the history of
the body it joins with the join itself
- a composed face is Split only where record::mark_shared_split finds an
origin under several faces; an inner Split alone no longer makes one
- Body::same ignores history: an operation that leaves a body as it is
gives the same body, carrying that operation's history
The two boolean history tests that waited for this run again, and the
coalesced and regularized step cuts are covered.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J53sR6gEaVt56soFDpTck8
EdgeOrigin::Meet now names each side as a Side: the sorted, de-duplicated
origins of the face there. substitute maps a side to the union of the inner
faces' origins, so a meeting with a face an inner operation merged keeps its
lineage; meeting() derives sides from whole faces. Fillets after box cuts
that leave coplanar pieces now report exact history. Prism lineage meets a
cap of several origins and resolves wall junctions away from shared
vertices by the operand's one edge between the walls. bore_union's recut
reports history only for a one-face bore (pieces of a two-arc bore's recut
wall were given both arcs).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J53sR6gEaVt56soFDpTck8
Fillets (local, loop, rolling ball, corner, variable, chord), chamfers
(cutters, local corners, loops, two sides), shell, draft, offset faces,
split face/body, delete face, patch/copy/stitch/trim/extend and
transforms record their history over [body] while they build: faces
rebuilt from the body's, blends in place of edges (corner patches in
place of the edges at the corner), shell walls as offsets, edges as
pieces of the body's or where two faces meet. Multi-step operations
compose each step. The push-face offset fallback now has history, and
the bore union composes its narrowed tool.
A reflection reorders a body's edges, so transforms now match edges by
identity (mirrored copies reported the wrong edges).
Refs #136
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J53sR6gEaVt56soFDpTck8
ops::boolean's result carries its history over [a, b] whichever path made
it, recorded by the code that builds the faces:
- truck path (incl. jitter retries): shapeops history mapped through the
order-preserving copies and the cut's turned tool, then through healing
- heal records which input faces each healed face merges and which input
edges each joined or exact edge replaces (HealMap); opt-in, so heal_keep
callers pay nothing
- trivial shortcuts, the void, glue, faces pushed apart (push_faces records
its own history; the slab cut back on a union maps to the operands'
faces in that plane), the nudged retry, by_lumps and join composition
- prism booleans: section segments carry tags (operand cap edge, the wall
beside it, its vertices) through the 2D boolean; walls, caps and edges of
the extruded or sewn result follow from them
- planar and faceted polygon booleans: polygons carry their operand face;
faces join the pieces across edges, edges come from the pieces either side
History gains renumber/over (and consuming forms) for composition;
record gains regions/traced/build helpers. truck-shapeops
*_with_history now return the solid with an Option history. Paths that
cannot report (bore narrowing via offset, inexpressible lineage) leave the
result without history. Boolean results, tolerances and fallback order are
unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J53sR6gEaVt56soFDpTck8