* test: reproduce #260 (Targeted cut deletes another body that the tool fully covers)
* Primitives honour `targets` for join/cut/intersect (#260)
solid.box/cylinder/sphere/torus had no targets field, so a `targets` list was
ignored and every body of the component took part: a targeted cut also cut a
non-target body, and deleted one it covered fully. Their `targets` now become
the feature's participants.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
---------
Co-authored-by: bherbruck <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
* test: reproduce #259 (Join with explicit `targets` also merges a non-target body that the tool touches)
* Primitives honour `targets` for join/cut/intersect (#259)
solid.box/cylinder/sphere/torus had no targets field, so a `targets` list was
ignored and every body of the component took part: a join also merged a touched
non-target body, a cut also cut (or deleted) one. Their `targets` now become the
feature's participants.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
---------
Co-authored-by: bherbruck <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
* test: reproduce #267 (timeline.delete of a sketch leaves later features that use its body by name)
* fix: timeline.delete reports features that newly fail (#267)
A later feature that names a deleted body (a combine targeting a deleted extrude's body) is
listed under failing: [{feature, error}] in the reply instead of failing silently.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT
---------
Co-authored-by: bherbruck <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
* test: reproduce #266 (Multi-profile solid.extrude with body_name names only the first body)
* fix: name every body of a multi-body feature after body_name (#266)
A new-body feature that makes more bodies than it was given names now stores Ribs (2),
Ribs (3)... for the rest instead of falling back to generic BodyN names. Command-time only:
saved designs keep their names.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT
* fix: keep body_name list for the multi-body naming step (#266)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT
---------
Co-authored-by: bherbruck <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
* test: reproduce #264 (Sheet metal: collinear tabs cannot be folded or flanged together)
* fix(sheet): fold and flange tabs that sit side by side on one line (#264)
A fold's bend zone and a flange's setback were cut with an infinite line, so
a second tab on the same line blocked a fold ('slanted or curved edge') and
two tab-end flanges in one feature shared one trimmed edge (nonmanifold).
When the zone falls apart into pieces, fold only the pieces the fold points
span, each as its own bend; trim a flange's setback only from the material
along its own edge, and attach each flange to the edge it was picked on.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT
---------
Co-authored-by: bherbruck <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
* test: reproduce #261 (Rectangular pattern of a hole cut scales super-linearly)
* Patterns of many hole cuts scale near-linearly (#261)
Two quadratic costs:
- Meshing a face tested every point against every segment of every boundary
loop, so a plate face with hundreds of holes meshed in quadratic time. The
vendored truck-meshalgo inside test now skips loops whose parameter box is
clear of the point (they wind zero times around it).
- A pattern cut each copy in turn, rebuilding and re-checking an ever more
complex target per copy. Copies whose boxes are clear of each other are now
one tool of many pieces (kernel::union_apart, no intersection work), cut once.
512 holes now take ~7 s instead of not finishing. The test's volume tolerance is
widened from 1e-6 relative to 0.1 % of each hole: the measure meshes the bores
and reads each hole ~0.06 % small, on main too.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Hole-pattern test: a budget CI can meet; coarser apart-box meshes (#261)
CI runs every test binary at once and is about ten times slower than a
machine running this test alone (15 tests passed 60 s in the last run), so the
512-hole pattern (about 6 s alone) hit the 60 s timeout there. The budget now
only has to tell linear from the quadratic hang: 300 s timeout, 120 s budget.
union_apart meshes each copy coarsely (2 % of its size, box grown by twice that).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Hole-pattern test checks the scaling, not a wall-clock time (#261)
CI runs every test binary at once: the 512-hole pattern (about 6 s alone, 10 s
CPU single-threaded) took 177 s there, so no fixed time is reliable. The test
now patterns 128 and then 512 holes and requires the second to take under 8x
the first (linear is 4x, measured 3.5-4.2x here; the old quadratic cost was 16x
or more), each with the volume check and a 900 s hang guard.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
---------
Co-authored-by: bherbruck <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
* test: reproduce #268 (Panic from truck-topology lib.rs:186 when joining struts that end on a bore wall)
* Sew refuses edges whose ends weld to one vertex (#268)
The sewer welds vertices on a 1e-6 grid but only rejected edges shorter than
1e-9, so a sliver edge between the two welded its ends into one vertex and
truck-topology panicked ("Two same vertices cannot construct an edge") inside
the guard. Such an edge is now a degenerate-edge error before any truck call,
and the boolean takes its usual fallback.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
---------
Co-authored-by: bherbruck <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
* test: reproduce #265 (Renaming a pattern copy renumbers the remaining copies)
* fix: renaming a body keeps its sibling bodies' names (#265)
body.rename pinned only the names of the feature's bodies before the renamed one, so unpinned
pattern copies after it were renumbered into the freed name. Pin every sibling's current name.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT
---------
Co-authored-by: bherbruck <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
* test: reproduce #263 (sheet.fold accepts a fixed point that is not on the sheet)
* fix(sheet): refuse a fold's fixed point that lies off the sheet's material (#263)
A fixed point inside a cut-out or outside the base outline (in the panel's
thickness) silently picked a side. Refuse it with an error that names the
point; side-face picks and points on other panels keep working.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT
---------
Co-authored-by: bherbruck <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
* test: reproduce #262 (sheet.fold: bend zone reaching the blank outline is reported as a slanted or curved edge)
* fix(sheet): name the bend zone reaching an outline corner instead of blaming a slanted edge (#262)
A fold whose bend zone contains a corner of the panel outline (a fold at a
tab's root) was reported as crossing a slanted or curved edge. Name the
corner and how far to move the fold line to clear it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT
---------
Co-authored-by: bherbruck <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>