Commit Graph
341 Commits
Author SHA1 Message Date
ajandClaude Opus 5.5 4a1587d6bd feat(engine): fill cutouts first in every whole-job run
NestPipeline.Run now bundles parts that fit other parts' enclosed cutouts
into their frames before the selected engine, for desktop, Console, MCP and
API alike. A valid complete bundled trial is kept; a refused trial falls back
to the ordinary solve (reason on RefusedCutoutTrial), and an incomplete trial
is compared with it, keeping whichever valid proposal places more. An
incomplete but valid trial is now keepable like any incomplete result.
Expanded sheets list each frame's inserts before the frame, so the committed
order cuts every insert before the cutout that releases its slug.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 12:51:18 -04:00
ajandClaude Opus 5.5 6ac56c4a3f feat(core): pre-post checks for parts nested in cutouts
Posting review now proves containment exactly as the cutting planner does
(shared NestedPartContainment) and warns when a nested part is cut after its
host (NestedCutOrder) or when a host's hole lead or the nested part's lead
meets the other's material (NestedLead), including subprogram hole poses.
Ambiguous containment is incomplete, never clear; fixed-lead motions are not
reported twice. A committed cutout preview warns until Plan Cutting cuts the
insert first.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 12:09:55 -04:00
ajandClaude Opus 5.5 9816326429 fix(engine): legacy lead assignment respects pins
Assign Lead-ins (LeadInAssigner) now leaves every unlocked part with active
drawing pins unchanged and returns those parts, so it never overwrites a pin
with the plate's settings; the desktop names them ("N parts kept their
drawing lead-ins (plate P: parts ...); use Plan Cutting to apply their
drawing pins."). Parts without pins, with pins switched off, or locked are
assigned or skipped exactly as before.

The pre-post review now covers drawing pins. A part with active pins whose
placed program does not cut each pinned contour exactly as the pin's own
emission (re-emitted with the part's cutting settings and matched motion for
motion) warns "Drawing pins not applied", as do locked lead-ins overriding
pins and a pin that no longer matches the geometry; pins switched off are
not reported. The contours that are cut as pinned join locked programs in
the fixed-lead re-check against every part's clean material, and fixed
leads are now also checked against active clamps (Plan Cutting itself does
not model clamps).

AGENTS.md records the fixed-emission safeguard and the characterization
digests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 15:33:26 -04:00
ajandClaude Opus 5.5 a18f8c9b56 feat(engine): pinned contours use the fixed-lead warning path
A drawing-pinned contour is now a fixed emission like a locked program. A
regenerated placement maps its execution motions onto the emitted contour
choices (one group per choice after the program's scribes, opened by its
rapids) and owns as fixed the lead-in, cut, lead-out and tab of every pinned
contour; the rapids between contours, including the one into a pinned
contour, stay the planner's and strictly checked. If the motions do not
split cleanly into one group per choice, nothing is treated as fixed.

So a pinned lead that meets another part's material or its own part's no
longer rejects the candidate: the feasibility precheck accepts a pinned
entry as given, the search keeps it in place, and replay reports a FixedLead
warning naming the part, cutting contour, pin and the part hit, with the
advice to increase spacing or switch off drawing pins for the part. The
plate is UNVERIFIED and needs acceptance; the lead is never shortened and
the entry never moved. The unpinned control and the same plate with pins
off are Ready.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 15:33:25 -04:00
ajandClaude Opus 5.5 8d17cf8c59 feat(engine): capture and freshness for pins
Capture now honours a placement's pins only while they are active: a part
with DrawingPinsOff plans from the plate settings with no warning (D1's
per-part escape hatch), and Part.HasActiveDrawingPins is the shared test.
A pinned part is regenerated like any unlocked part whatever lead-ins or
settings it carried. A locked part with active pins keeps its exact program
and warns "Locked lead-ins override drawing pins on part N; Clear Lead-ins
to apply the pins." instead of being refused; an unlocked part a caller left
ineligible warns that its pins are not applied.

Apply's freshness record now holds each drawing's pin list (reference and an
explicit StateFingerprint of every pin's point, leads and tab) and each
part's pins-off flag, so editing either after capture returns Stale. The
fingerprint writer is shared between settings and pins; a reflection test
pins ContourCutPin's public surface to what the fingerprint covers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 15:33:25 -04:00
ajandClaude Opus 5.5 7949d41b6d feat(core): pinned contour preparation
PreparedContours.Capture(program, parameters, pins) takes CutPinResolver
results for the same contours and fixes every resolved pin's contour: its
one and only entry is the pin's point, and it is emitted through the
existing emitter with the pin's own lead-in, lead-out and tab (angle
rounding off, so the entry never moves). Every catalogue returns the pinned
entry alone and emission refuses any other entry for that contour, so no
search path can relocate it. The certified tab size is the pinned outside's
own, so a pinned tab gap is genuine and replay certifies it. Unpinned
contours keep the shared settings and automatic selection; without pins the
existing preparation is untouched (5.1 digests unchanged).

Capture now resolves a regenerated part's drawing pins. A pin that does not
resolve (not on a contour, on several, sharing one, or unplaceable) is never
guessed: its contour stays automatic and the plate gets a FixedLead warning
naming the pin, making the proposal UNVERIFIED. A tab pinned on an internal
contour cannot be cut as pinned (only the outside is tabbed) and warns the
same way. Pins-off, locked parts with pins and freshness follow in 5.4.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 15:33:24 -04:00
ajandClaude Opus 5.5 d56f67a99a feat(engine): fixed-lead violations warn instead of refusing
D1a (user, 2026-10-14): one locked cutout must not refuse the whole layout.
With confirmed parameters a locked program is now a fixed emission, accepted
as given. The replay checker and the lead validator take a per-motion owner:
a violation inside the fixed emission (a lead meeting another part's or its
own material, a rapid inside the locked program crossing a cut contour, an
uncertifiable tab gap or a partial/reversed/retraced cut) is recorded apart
instead of failing the candidate. The search never rejects or learns an order
rule from them, so fixed emissions never steer it; the planner's rapid into
the locked program and every regenerated lead keep every strict check.

Replay turns those violations into typed FixedLead findings that name the
part, contour and the part hit. A plate whose only findings are these is
BestEffort with IndependentlyReplayed set: never Ready, applicable only with
the per-proposal acceptance, and CuttingPlanService.Apply still rejects it.
Overlap, unreadable programs, stale input and cancellation still block, and
unlocked programs a caller left ineligible and the no-parameter route keep
refusing as before.

Pre-post review now re-checks locked leads against every part's clean
material, so the same violations reappear before posting.

Existing tests that encoded the old locked refusal now assert the warning;
two batch tests that used a locked crossing as their hard block use an
overlap instead. The 5.1 digests are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 15:33:23 -04:00
ajandClaude Opus 5.5 0f06748f28 feat(io): persist pins and pins-off
Drawing cut pins and the per-placement pins-off flag now survive
save/reload and travel in drawing packages.

- `DrawingDto.cutPins` reuses the plate cutting-parameter lead and tab
  DTOs. Pins are read strictly per entry: an unknown lead or tab type is
  never replaced by a default, because a pin that cut differently from
  what was saved is worse than no pin. A bad entry is skipped with a
  reader warning naming the drawing and pin, and the rest load; a value
  that is not a list loads no pins, with a warning. A nest never fails to
  open over pins.
- `PartDto.drawingPinsOff` is written only when true. Anything other than
  a boolean loads as pins on (the drawing wins, D1) with a warning naming
  the plate and part, so an operator's override is never lost silently.
- Packages carry pins as drawing content, so pinning a drawing changes
  its package hash and the newer-revision notice can tell geometry/pins
  changes from detail-only ones.
- `Part.DrawingPinsOff` holds the flag; nothing plans with it yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 15:33:21 -04:00
ajandClaude Opus 5.5 2aecafb356 feat(desktop): Save to Drawing Library dialog
Operators can now save a nest drawing to the shared drawing library. Right-
click a drawing in the drawing list > Save to Drawing Library... opens a
dialog with name, customer, material (post materials suggested), grade,
thickness, cut type and notes, prefilled by the save model; units follow the
nest.

Whenever the details change, the dialog looks up library drawings with the
same details and offers Save as: the next revision of the match (the default
for one match or the linked drawing), a choice among several, or a separate
drawing. Save stays disabled until the lookup for the current details has
finished, so a choice can never apply to details it was not made for. A 409
is shown and the choices are refreshed; a save that could not be confirmed
tells the operator that saving again checks it and never stores it twice.

On success only the drawing's library link changes, and the chosen cut type
is remembered per PC. There is no nest dirty flag to set, so the operator
saves the nest to keep the new link. The item is Database mode only and is
shown only where the drawing list's host handles it (not the best-fit viewer).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 15:33:20 -04:00
ajandClaude Opus 5.5 a1bd44d0fa feat(desktop): Add from Drawing Library
Operators can now pull shared library drawings into a nest. Nest > Add from
Drawing Library... and a Library button above the drawing list open a paged
browser (name, customer, material, grade, thickness, cut type, revision, saved)
with a notes preview and a quantity. It starts filtered to the nest's material,
grade and thickness, with Show all to lift that.

Add downloads the listed revision's immutable package, not the current one, so
a revision saved meanwhile can never be what lands in the nest. The insert is
planned first and every warning or refusal is shown before the nest changes;
the dialog is modal, so the nest cannot move between plan and apply. The dialog
stays open for further adds and the drawing list refreshes on close.

Both entries are Database mode only: the library lives on the nest server, so
in File mode they are disabled with a "Database mode only" tooltip.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 15:33:19 -04:00
ajandClaude Opus 5.5 15654c0690 feat(core,io): drawing library link
A nest drawing copied from the drawing library has to remember exactly which
revision it is a copy of, so later slices can tell when the library moved on
(D2b) and so a save can target the right drawing. `Drawing.Library` holds the
server key, id, revision and a snapshot of that revision's cut type, thickness,
material, grade, units, notes and package hash. It is immutable, so copies can
share it.

`DrawingDto.library` is additive and omitted when null. It is read leniently:
anything that cannot be trusted as a link drops the link with a reader warning
and the drawing still loads, because a nest must never fail to open over
provenance. Enum names are checked as single names since Enum.TryParse would
accept numbers and comma lists.

Copy paths: converter edits update drawings in place and so keep the link;
canonical engine copies carry it; split pieces are new geometry and get none.
Packages strip it so linking never changes a drawing's package bytes or hash.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 15:33:17 -04:00
ajandClaude Opus 5.5 8b63c042b5 test(server): drawing library end to end
Proves Slice 1's contract through the production routes and the real client:
a code-built drawing is packaged, uploaded, found by cut type, material, grade
and thickness among decoys, downloaded and read back with identical program
text; a stale If-Match update raises a conflict and leaves the current
revision, its package hash and the history unchanged. Archive, restore,
metadata edits and duplicate ids are exercised the same way.

Documents the /api/drawings contract, schema v4 and the fact that the backup
manifest and restore check do not yet verify drawings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 15:33:03 -04:00
ajandClaude Opus 5.5 844f360732 docs: document saved best-fit entries and IO's Core-only dependency
The bestfits/ archive entry was undocumented. Describe its JSON shape,
that it is an optional cache readers may ignore, and that it is read or
written only when a caller supplies an IBestFitStore.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 14:54:45 -04:00
ajandClaude Opus 5.5 75195e8ba4 fix(cutoffs): continue strip lines into a tail too short to keep
When the end tail was shorter than the minimum tail to keep, the planner
dropped the separator but still stopped the strip grid at it, so the last
strip ran to the sheet end and could exceed the maximum spacing (e.g. a
39-inch strip from 105 to 144 with 35-inch spacing). The grid now spans the
whole sheet whenever the separator is skipped, keeping every strip within
the spacing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 10:40:04 -04:00
ajandClaude Opus 5.5 405a867a77 fix(desktop): draw planned cut-offs and issue markers on the plan preview
The proposal preview skipped the cut-off overlay: it carries cut-off parts but no
cut-off definitions, so planner cut-offs looked like thin black part outlines
instead of the orange-red dashes used everywhere else. The preview now draws each
cut-off part's own cutting moves in that style.

The same paint guard hid the validation overlay over a preview, so issue markers
for unverified plans were set but never drawn. The overlay now draws on proposals
too, with the marker's part numbers mapped to the preview's proposed order so the
right parts stay highlighted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 09:18:48 -04:00
ajandClaude Opus 5.5 c3fa8e79e0 feat(desktop): mark cut-plan issues on the plate and trim the inspection panel
Plan Cutting findings dropped the checker's geometry, so selecting one could only
zoom to part extents, and overlap-blocked plates (no preview) did nothing at all.
Findings now keep the check's world-coordinate witness (overlap regions, rapid,
contacts); selecting a row draws it with the Validate Nest overlay, on the proposal
or a blocked plate's live sheet. The witness is excluded from finding equality so
repeated search rejections still collapse to one finding.

The side panel's scrolling report was a wall of text operators skipped. It is now
a colored outcome line, one line for the shown plate, and one remedy or marker
hint above the issue grid, with secondary detail moved to tooltips.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 09:11:13 -04:00
aj 697b6492c7 fix(browser): integrate metadata-safe nest information edits 2026-10-16 06:52:33 -04:00
ajandClaude Opus 5.5 f05533f69c merge: integrate inspection-view navigation lock with live header zoom
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 06:46:12 -04:00
ajandClaude Opus 5.5 7d254ce18d feat(desktop): remove or restore a clamp by right-click
Operators sometimes pull a clamp for a manual layout, but only Auto Nest's
last-resort search could take clamps off a sheet. Right-clicking a clamp in
Select mode now offers to remove it from that sheet or put it back, reusing
the existing per-sheet RemovedClamps, so the zones, cut-time charge, display
and .nest persistence all behave as they do for Auto Nest removals.

The change is refused while a nest run or fill may be reading the clamps,
sharing the guard the Clamps dialog already used.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 06:20:30 -04:00
aj 9f0d4f37ce feat(browser): edit nest information without opening the nest 2026-10-16 00:03:32 -04:00
aj 1672b62717 docs(diagnostics): state the tiny-clamp and grid-threshold marker limits
The spec review found two places where the marker and threshold
contract does not hold.

A clamp narrower than the chord tolerance is still judged
tolerance-free against finely re-read material and reported as the
whole clamp rectangle. That existing safety policy is kept, so its
marker is the clamp's centre: within half the clamp's size (under
0.0005) of the material, though not necessarily on it. Document this
on PlateOverlapPair.Marker and in the overlap docs, and lock it in the
tiny-clamp region test.

Also document that 1e-8 grid rounding can move an area within
rounding error of the 1e-5 threshold to either side of it.
2026-10-15 23:31:14 -04:00
aj 80d01839bd feat(diagnostics): place overlap markers on the shared material
The overlap crosshair sat on the pair's area centroid. For a split,
holed or concave overlap, that point can be off the red material:
between two patches, in a hole, or inside a curve.

PlateOverlapPair.Marker is a point inside the pair's largest island.
It is the island's pole of inaccessibility (PolyLabel), searched to a
tenth of the island's area/perimeter within a 4096-cell budget. If
that bounded search does not land inside (a long thin sliver), the
marker falls back to the midpoint of the widest interior run of a
horizontal scan line placed between vertex heights.

The overlay crosshair, marker hit testing, hover coordinates
("Marker:") and the cutting-inspection ring now use the marker.
Centroid stays the true area centroid. View > Overlap Check > Display
> Centroids is now labelled Markers.

Before the marker existed, its call sites used the centroid. Two
patches, a covered frame, a half annulus and a thin crescent then put
it off the material; now all four land on it. Disabling the scan-line
fallback fails its test. On the 389-plate corpus, markers add about
0.4 ms per overlapping pair; pair and area results are unchanged.
2026-10-15 23:31:14 -04:00
aj f04d9f298b perf(diagnostics): compute overlap areas with Clipper2
The material-overlap diagnostic clipped every triangle of one part
against every triangle of the other, then carved each fragment by
every hole triangle. Curved overlaps produced thousands of fragments,
and a part sitting inside another part's cutout was slow even when
clear.

PlateOverlapAnalyzer now intersects each candidate pair's hole-aware
material once with Clipper2, in part-local coordinates on a 1e-8 grid.
Each operand is its outline minus the union of its holes (positive
fill rule). Regions become connected islands: a counterclockwise
outline plus clockwise Holes, including an island that both parts'
holes enclose together. PolygonAreaMoments.TrySubtract gives each
island's net moments. A pair is reported when its total shared area
exceeds Tolerance.Epsilon. Out-of-range or nonfinite coordinates make
the pair incomplete rather than clear. The overlay and the cutting
inspection highlight fill outlines with their holes.

On 389 real PEP-converted plates the pair, clamp-finding and issue
sets are identical to the previous kernel. Pair areas are equal or up
to 0.0002 larger: the kernel drops fragments below its area threshold.
With material prepared, the per-plate clipping maximum fell from
2.6 s to 52 ms (total 5.0 s to 0.5 s).

Engine and validation checks still use Collision.
2026-10-15 23:31:14 -04:00
aj 04c9f748f9 Merge remote-tracking branch 'github/master' into feat/inspection-view-navigation 2026-10-15 07:42:46 -04:00
aj 1db0ef04f0 fix(desktop): refuse Expand Spacing while a nest or fill is running
Expand now reads the plate on a worker while its Cancel window pumps
messages, so a still-running fill could commit parts into the plate the
search is enumerating (InvalidOperationException: collection modified).
Refuse the command while whole-job nesting, a NestProgressForm or a fill
on any view of the nest is active. The usual plate-action guard is not
reused: ActionSelect reports busy whenever parts are selected, which
Expand requires.
2026-10-14 20:52:52 -04:00
aj 855d686a6a docs(expand): describe cancelling a long Expand Spacing search 2026-10-14 20:39:58 -04:00
aj f9e3c361b4 fix(cutoffs): trim lines through clearance-outline vertices to the part
A cut-off line passing exactly through a vertex of the clearance outline
got duplicate intersection hits and fell back to the part's bounding box.
Automatic strip lines sit on a 0.05 lattice that often lands on such
vertices, and the strip search preferred them because the box fallback
measured as less cutting, so planned cut-offs looked box-trimmed while a
slightly moved manual line was trimmed correctly.

Slice the polygonal clearance outline exactly with half-open edges:
crossing vertices count once, touching vertices zero or twice, edges on
the line are excluded whole. Zero clearance and non-polygon outlines keep
the existing path and its conservative fallback.
2026-10-14 20:18:32 -04:00
aj 21d38beb53 fix(desktop): select cut-offs with plate windows 2026-10-14 14:10:39 -04:00
aj 29f48789dd Merge remote-tracking branch 'github/master' into feat/inspection-view-navigation 2026-10-14 10:21:03 -04:00
ajandClaude Opus 5.5 5180ce1506 feat(inspection): keep header zoom live while plate navigation is locked
Validation inspection disabled the whole plate header, so the zoom buttons
and Ctrl+Plus/Ctrl+Minus stopped working even though wheel zoom and fit stay
available. Group the plate navigation buttons into their own container so the
inspection scope can lock them while leaving the viewport-only zoom controls
and shortcuts live.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 10:20:57 -04:00
aj 74f32f0516 fix(nests): keep etch marks when clearing lead-ins of PEP nests
PEP-converted nests stored etch marks only in each placed part's locked
cutting program; the drawing program held the contour cuts alone. Because
Remove Lead-ins rebuilds a part from its drawing, clearing lead-ins also
erased the marks from every part.

Recover the marks while reading the nest: when a drawing has no scribe
moves and every placement that kept its saved program carries the same
marks, add them to the drawing in its own frame and refresh that drawing's
clean placements. Saved programs are never rewritten, drawings that already
have marks are untouched, and drawings whose saved programs disagree are
left alone rather than guessed at.
2026-10-14 06:58:24 -04:00
aj 6424512e8c fix(expand): distinguish open-path material entry from bounds 2026-10-13 22:34:21 -04:00
aj 27f8c9799b fix(expand): measure open cutoff segments and refuse uncertain curved gaps 2026-10-13 22:11:12 -04:00
aj 775ece5d21 fix(expand): certify disk and cutoff paths and report invalid input 2026-10-13 21:49:28 -04:00
aj 4183af4142 fix(expand): retain convex exits and report tiny clamp overlap 2026-10-13 21:31:57 -04:00
aj fdc6f074ee fix(expand): distinguish part blockers from plate edges 2026-10-13 21:31:57 -04:00
aj dc4b07ddf5 fix(expand): separate parts touching cutout walls 2026-10-13 21:31:57 -04:00
aj 6c76617905 fix(expand): clip translations against material along their path 2026-10-13 21:31:57 -04:00
aj 43e08965b9 fix(expand): preserve entry clearances and retry blocked pairs 2026-10-13 21:31:57 -04:00
aj ddd1e422be feat(cutoffs): cut sheet-separating cut-offs after every part 2026-10-13 21:09:35 -04:00
aj b9a387b517 feat(desktop): choose cutting-planner cut-off settings in the automatic cut-off dialog 2026-10-13 20:55:24 -04:00
aj 9f2ece37ed feat(desktop): add automatic cut-offs, existing-work banner and clear button to the cutting planner 2026-10-13 20:39:43 -04:00
aj 57450ecea8 fix(cutoffs): honor candidate budget and truthful cut-length ties
Reserve nominal-line slots in the candidate lattice, compare rounded lengths in exact micro-units before pierce ties, and report real fixed-grid cut length. Per-line notices name local increases instead of negative savings. Failing-first regressions cover dense spacing, decimal ties and the legacy summary.
2026-10-13 20:01:48 -04:00
aj f63fee7392 feat(desktop): add minimum strip and cut-length summary to automatic cutoffs 2026-10-13 19:34:02 -04:00
aj 1bcead4b3a fix(io): write empty clamp sheets whose spacing differs from the defaults
The writer omitted an empty rail sheet when its size, quadrant and zones
matched the defaults, ignoring spacing, so a sheet left at the old part or
edge spacing after a defaults change (configured stock under C17) was
dropped on save. The comparison now includes edge and part spacing.

PM 455f6763-f0aa-40da-b9ad-11de4b2ea95b
2026-10-13 18:15:50 -04:00
aj d9273c889f fix(io): keep a sheet's own clamp rail and its removals through save and reload
Commit can attach the stock's rail to a sheet whose nest has no (or another)
default rail, but only the default rail was saved and the reader re-attached
sheets only to it, so the removed clamp and its time vanished on reload. A
sheet following a rail other than the default now saves it in an optional
per-plate clampRail (read leniently, omitted otherwise), and the reader
re-attaches the sheet to it.

PM 22daec3d-dabb-4aae-95f7-c1d090d5dcdf
2026-10-13 18:15:50 -04:00
aj 4226c0f902 fix(engine): find the fewest clamps to remove, not only neighbouring runs
Recovery only tried contiguous runs of clamps, so a part with a notch over
a middle clamp had all three clamps removed although the two outer ones
were enough (D8: 'the fewest clamps that let it fit'). One probe per clamp
now finds the clamps every removal must include (a part that cannot fit with
only that clamp left needs it off; removal is monotone), and the search
tries every set by size, mandatory clamps plus the optional ones nearest the
origin first. Full-sheet parts resolve with one probe per clamp.

PM 3df03af2-35a6-49c2-9082-fc6208f5b708
2026-10-13 18:15:50 -04:00
aj e38980e54b docs(clamps): describe last-resort clamp removal and current clamp coverage
automatic-nesting.md still said interactive fill/push, the overlap check and
cutoffs ignore clamps, and nesting-engines.md listed the large-spacing and
tiny-zone defects fixed in this slice. Both now describe current behaviour,
and the new last-resort removal section states its limits (1000-probe budget,
sub-grid clearance) as settled with the user (plan D12-D15).
2026-10-13 18:15:50 -04:00
aj 6fc1a0ebdc fix(core): move an untouched trailing sheet to new nest defaults
Changing the nest defaults (Nest Info, Set as default, Edit Plate on an
empty sheet) left the editor's trailing empty sheet on the old size and
quadrant, so the writer's clamp-preserving empty-sheet rule saved it as a
stale extra sheet. PlateManager.ChangePlateDefaults wraps a defaults edit:
a trailing empty, cutoff-free sheet that exactly matched the old defaults
(and followed their rail with no removed clamps or explicit zones) takes the
new defaults; every other empty sheet keeps its configuration and is still
written.

PM cade6901-5f4a-4503-85bf-0ea681d9ca7f
2026-10-13 18:15:50 -04:00
aj 04d538b0a4 fix(io): omit removedClamps from sheets without a removal
Every plate was written with "removedClamps": [], so files without the
feature changed. The key is now omitted unless a clamp was removed, like
the other additive sections; nest-file-format.md documents removedClamps
and removalMinutes and their lenient reading.

PM 6ded8ac4-84fd-4e8b-9a3b-6f41e494542c item (c)
2026-10-13 18:15:50 -04:00