Commit Graph
2187 Commits
Author SHA1 Message Date
ajandClaude Opus 5.5 d133f6879b fix(geometry): leave leads out of push and collision material
A part with lead-ins applied could not be pushed away once another part
touched it. PartGeometry kept LEADIN/LEADOUT entities as material, so the
leads chained onto the perimeter as open spurs and the spacing offset no
longer closed. The slide-contact classifier cannot tell the material side
of an unclosed boundary and blocks every contact, so parts resting against
it could not move up or right off it. Leads are cut into scrap, and the
spacing review, overlap analyzer and support checks already drop them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 09:44:43 -05:00
ajandClaude Opus 5.5 322a66c339 fix(planning): take back a pair swap that leaves the search stuck
The "cut those two the other way round" rule is a guess. On an interlocked
holed-parts plate it swapped a pair whose swapped order then blocked on that
same pair; no further rule could be learned, the full search ran the strict
budget out, and Plan Cutting fell back to the safest route (0 strict
expansions), failing ContourRecoveryFileTests' interlocked rows since
16bd9256.

When a round teaches nothing and a swap was learned, the newest swap is now
taken back, never re-learned, and the attempt that taught it learns the plain
"cut this part before those" rule instead, backing up from that attempt as
any learned rule does. The swap is chosen apart from the plain rules, so a
"departed part first" rule with the same pair is never taken for a swap.

Both interlocked rows plan Ready within budget again. The problem-nest corpus
keeps every status and expansion count; a 4000-layout random sweep of 3-5
locked-lead rectangles keeps every status.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 08:39:52 -05:00
ajandClaude Opus 5.5 52e421dcbe fix(cutting): center straight leads on a corner a tab wraps
A tab entered at a fillet joint trims back around the corner, so the cut
stops on one edge and starts on the other. Each straight lead took its own
edge's normal and the pair sat 150 degrees apart, reading as one bent line
through the corner. Both now take the bisector of the two ends' normals and
form the same V they form on a straight edge, falling back to their own
normals when either lead would not clear the part.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 22:08:18 -05:00
ajandClaude Opus 5.5 6ee81a3501 fix(cutting): keep rapids off cut parts no single tab can steady
A support-tabbed part that no single tab can hold level may tip once cut,
yet its tabbed outside was crossable like any retained part, so Plan
Cutting could rapid back across a row of long strips. Its outside is now a
rapid obstacle, closed across its tab gap, in the search, replay, cut-off
insertion and the safest route.

Its fallback entries are ranked toward the next cut rather than steadiest
first, so a long strip can be left toward the next part, and the "cut those
two the other way round" rule applies only when the approach crosses no
other part.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 22:07:28 -05:00
ajandClaude Opus 5.5 a0001f04ac chore(help): pin help v0.7.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 19:29:13 -05:00
ajandClaude Opus 5.5 91089820ee feat(engine): group like parts in Irregular's grouped variants
After its six variants and tail re-plan, Irregular decodes the job again
with each type of three or more copies packed as one group, in a searched
order, holding back up to four copies per group that would start a ragged
row and filling them into the gaps afterward. When everything fits, the
best candidates are re-packed in a strip ending just short of the front.

The pass runs after the ungrouped search, which is unchanged, and replaces
its result only by beating it. The help tutorial's parts now end at 34.9"
instead of 38.1" on 60 x 120.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 18:41:33 -05:00
ajandClaude Opus 5.5 a2966b9f86 test(cutting): post the tutorial nest with a clean CL review
With the CL post declaring placed order for nests it writes as planned,
the help tutorial's nest must reach posting with no findings at all.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 17:29:57 -05:00
aj 5da1e35e88 Merge branch 'refs/heads/claude/objective-yalow-6f6bde' into claude/help-docs-update-list-760b9c 2026-11-02 17:26:44 -05:00
ajandClaude Opus 5.5 72039a238b feat(post): declare placed order for CL nests that post in it
The Cincinnati CL post always drew an "incomplete final rapid sequence"
warning because it never declared IPostVerificationSupport. It writes etch
features before cuts, inserts or drops rapids, and with part sub-programs
rapids to each part's corner, so it cannot declare it unconditionally.

IPostVerificationSupport gains a nest-aware PlacedProgramOrderChange(nest)
(null = preserved; otherwise the reason, shown in the warning). The CL post
answers it from its own writer: part sub-programs and smart rapids off, and
every part's and hole's posted motions exactly equal to its placed ones.
Plan Cutting cuts scribes first, so planned nests qualify. CNC output is
unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 17:21:25 -05:00
ajandClaude Opus 5.5 6771533e03 fix(cutting): leave the tab open on a round perimeter
A tabbed outside cut is trimmed short of its entry, but the trim only
handled lines and arcs: a round part's outline is one circle, so it was
cut whole. Plan Cutting counted it as tabbed and called the plan ready,
then the pre-post review found no tab and warned that the part may tip.
Cut a tabbed circle as an arc that stops the tab's chord short of its
entry, travelling the circle's own way.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 17:20:23 -05:00
ajandClaude Opus 5.5 c243830641 test(cutting): plan the help tutorial's first nest ready
The "Your first nest" layout (the help's sample parts, Auto Nested on a
60 x 120 sheet over a 2 inch support grid) must plan without warnings,
with support tabs on and off.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 16:54:59 -05:00
ajandClaude Opus 5.5 a0d6c7212b fix(cutting): raise the head for rapids into hole sub-programs
Round holes are cut as sub-programs, which are never marked because they
may be shared, so the safest-route fallback could not raise the head for
the rapid into a hole: on interlocked layouts every such crossing stayed
a finding and the plan stayed unverified. A HEAD RAISE marker may now sit
directly before a sub-program call, raising the call's arrival rapid.

- Motion reader: a marked call raises its first rapid; each sub-program
  motion records the part's own call that runs it.
- RaisedRapids marks the call when the crossing rapid is its arrival.
- Cincinnati CL keeps the marker with its hole call and writes M47 before
  it; part sub-program dedupe now tells marked programs apart.
- CI Fiber raises before the hole's first G0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 16:54:59 -05:00
ajandClaude Opus 5.5 8a282d53cf feat(cutting): let a tab alone hold parts up to 6 in new settings
Small parts on a coarse support grid (the help tutorial's 5 x 5 gussets
on a 2 inch grid) rest on one or two points, so no single tab could
steady them and every plan came back unverified. New cutting settings
now start "Tab alone holds parts up to" at 6; settings saved without the
field still read as 0, so existing settings keep their meaning.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 16:54:59 -05:00
ajandClaude Opus 5.5 bfc36d166c fix(support): measure a part the same however it is turned
A 5 x 5 right triangle fits both its legs' square and its hypotenuse's
7.07 x 3.54 box, each of area 25, and rotating calipers kept whichever
rounding found first, so the same gusset measured 5 long at one rotation
and 7.07 at another. Of rectangles tied for least area, measure the one
with the shorter long side, so length, width and the tab tie-break no
longer depend on placement.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 16:54:58 -05:00
ajandClaude Fable 5.1 ceddd8cf93 test(cutting): add an opt-in sweep over a folder of production nests
Plans every occupied plate of every .nest file in a local folder the way
Plan Cutting does after clearing lead-ins and cut-offs, and writes one
JSON line per plate with its outcome, warnings, fallbacks, expansions,
time and spacing pairs. It is how the reliability sweep found its
failure classes over 1,260 production plates; the nests and the report
stay outside the repository, and the test skips without the folder.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 14:31:46 -05:00
ajandClaude Fable 5.1 84a0fedac0 fix(cutting): sweep a part's holes even after its searched entries run out
Contour recovery tries each outside entry's hole-tour search first for a
part with at most 16 holes, and the reading-order sweeps after them; once
the searched entries had spent the recovery allowance it jumped straight
to the widened tries and never swept. A frame cut from inside its own
cutout, after the strips nested there, is often routed only by a sweep,
which leaves the cutout on its far side toward the outside entry beyond
it, so such plates fell back to the safest route with head raises or to
no plan at all. The sweeps now still get their few expansions per hole,
bounded by the whole budget. On the production corpus six plates went
from a safest-route or head-raise fallback to a strict plan, five kept
fewer raises, one blocked plate gained a safest route, and none got
worse; the problem-nest corpus is unchanged in every outcome and share.
No synthetic plate reproduced the exhausted allowance yet, so the corpus
guards this change.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 14:31:45 -05:00
ajandClaude Fable 5.1 96db154d9e perf(cutting): remember each contour's pierce-zone resolution per preparation
With a pierce diameter set, every internal contour whose configured
pierce is inside the zone is resolved by flattening the cutout, finding
its pole and eroding it, and the search emits a part's whole chain again
on every expansion, so on parts with dozens of such holes almost all of
the planning time went there: three 1,600-motion parts took 41 minutes
and timed out in production. The resolution is a pure function of the
hole, the entry, the configured lead-in, the zone and the turn, so each
preparation now keeps it by contour ordinal and reuses it, unchanged,
across its emissions and copies. The same plate plans in 148 s.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 14:31:45 -05:00
ajandClaude Fable 5.1 c122e64edd fix(verify): resolve adjacent curves before any native query runs
A fillet whose circle is tangent inside the arc it continues, as a
keyhole's slot ends are, gives the supporting-circle query of the pair
no real root: the circles' distance is the radii's difference up to
rounding, so the intersection comes back NaN, and the unfiltered check
that runs before any adjacency handling refused the whole part as
"nonfinite program coordinates". On the production corpus 17 plates
failed this way. Adjacent curves are now resolved from their shared
vertex before the native query would run, so no query runs for them.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 14:31:45 -05:00
ajandClaude Fable 5.1 60d235c8ce fix(verify): meet adjacent curves at their shared vertex exactly
Two curves that meet end to end share that vertex, but every contact
check asked the native intersection query about them, and it is
ill-conditioned there: two circles meeting at a shallow angle (a fillet
continuing into a larger arc) or a line meeting its fillet put their root
up to 1e-5 off the joint when the DXF arcs were rounded apart from their
neighbors by 1e-9. Material validation then refused the part as
self-touching, and the open-cut proof read a tabbed perimeter's fillet
joint as a loop, so with support tabs on every such part lost its
retention proof and its plate came back blocked. On a corpus of 1260
production plates this was the largest planner failure class: 61 of 67
NoSolutionWithinBudget plates, all planning once the joint is exact.

Contacts now report an adjacent pair's shared vertex itself and derive
the pair's other intersection from it analytically (two circles meet
again at the vertex's mirror image across the line through their
centers; a line meets a circle again at the far end of its chord),
keeping it only on both finite spans. No tolerance grows: a genuine
second crossing beside the joint is still reported, and overlapping
spans still refuse.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 14:31:44 -05:00
ajandClaude Opus 5.5 81ec6a8125 feat(server): list, reopen and keep server nest jobs once
A server Auto Nest result could only be reviewed in the session that sent it,
and nothing stopped two desktops from keeping the same result. Phase 3 adds
My Server Jobs, so results that finished while OpenNest was closed are easy
to find, and records each review on the server.

- Server: GET /api/nest-jobs lists jobs newest first with state, engine,
  submitter, times, queue position, review and the worker's summary (parts,
  sheets, utilization, unplaced). It filters to active, finished or
  unreviewed jobs and to a submitter (a bare user name matches that user on
  any workstation). An ETag turns unchanged polls into 304s. Schema v17 adds
  nestId, review and summary columns, only where missing.
- Keep once: POST .../keep and .../discard take If-Match on the job revision
  and change an unreviewed result only once. A second desktop gets 409 with
  who kept it. DELETE removes finished jobs. A succeeded job keeps its
  package until it is reviewed, so a later session can rebuild the job.
- Retention: OPENNEST_JOB_RETENTION_DAYS (default 7) deletes finished jobs
  with their results. It runs on claims and list reads. A malformed value
  fails startup instead of deleting results early.
- Worker: reports the result's summary with the transcript. A job cancelled
  while its result arrived keeps no summary (found in the Docker smoke run).
- Desktop: Nest > My Server Jobs polls the list every 3 s; polling rather
  than per-job SSE because the list must show other desktops' jobs and
  removals. Open rebuilds the job from job.json against the open nest's own
  drawings. New per-drawing geometry fingerprints make the freshness check
  work across sessions. Cancel Job and Remove act on the selected job. A
  status-bar item counts this user's results waiting for review; there is
  no popup. Auto Nest's review now records Keep on the server before it
  commits, and records Discard too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 13:18:11 -05:00
ajandClaude Opus 5.5 b0cdbb3e81 feat(server): stream server nest progress and notify when a job ends
A server Auto Nest showed only "Nesting on the nest server" for however long
the job took, and Stop could take a whole 20-second heartbeat to reach the
worker. Now the desktop shows the same Best plan so far strip a local run
does, and a job that ends while OpenNest is in the background says so.

- Worker: RecordingNestingEngine taps each solve's progress. NestJobReporter
  stores only the latest stage and plan, at most once every two seconds, so a
  chatty engine cannot flood SQLite. Each round also reads the cancel flag,
  so Stop reaches the worker within one interval (about 2 s in the Docker
  smoke test).
- Server: schema v16 adds per-job revision, progress, plan and planRevision
  columns, which the upgrade adds only where missing. PUT .../progress and
  .../plan renew the lease like a heartbeat. GET .../events is Server-Sent
  Events, woken by an in-process change signal: plan and job events with
  revision ids, keep-alives, Last-Event-ID resume, and the final state always
  sent before the stream ends. GET .../plan serves the polling fallback.
  Progress goes over HTTP because the worker never opens the database
  (another host, NFS).
- Desktop: NestJobWatch follows the stream. When the stream drops it polls
  once and reconnects, and it polls throughout when the server has no stream.
  RemoteNestPlanPreview draws worker plans from the client's own request,
  including cutout-trial frame proxies. ServerNestNotice shows a tray balloon
  (a toast on Windows 10/11) when the job ends while OpenNest is not in
  front. A real toast would need an AUMID shortcut that Velopack does not
  promise. Clicking the balloon brings the review forward; nothing is kept
  without Keep.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 13:18:10 -05:00
ajandClaude Opus 5.5 54ad7ee84d feat(server): nest Auto Nest jobs on the server's worker
Large nests tie up the workstation that runs them. In Database mode, Auto Nest
can now queue the job on the nest server, where a worker container solves one
job at a time under its own CPU and memory limits. The job has no time limit,
so a throttled worker finds the same nest a fast one does, only later.

- Server: /api/nest-jobs queue (schema v15). The worker holds a job on a
  heartbeat lease. When the lease lapses, the job goes back to the queue,
  or fails after three attempts. Only one job runs at a time. Packages and
  results are opaque to the HTTP server, which stays off Engine and IO.
- Worker: OpenNest.Server.Worker in the same image (OPENNEST_ROLE=worker),
  reaching the server over HTTP only. It records each engine answer with
  RecordingNestingEngine and gives its job back on shutdown.
- Desktop: "Nest on the server" in the Auto Nest dialog, for built-in
  engines only. The client replays the recorded answers with
  RemoteNestSubmission, so validation, the review and Keep run locally
  against the client's own drawings, exactly as after a local run. A
  drawing edited after sending refuses the result. If the server cannot
  take the job, the user may nest locally instead.
- compose.server.yaml adds the throttled worker service. The Dockerfile,
  .dockerignore, CI paths and the deploy script now include the worker's
  projects.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 13:18:09 -05:00
ajandClaude Opus 5.5 d29f919aa2 fix(io): save nests safely and reopen them with their cut-off settings
Reopening a nest regenerated its cut-offs with built-in defaults (no
overtravel, a different minimum segment) rather than the machine's
settings it was made with, so a nest saved, reopened and posted could
cut scrap that never separates. Plates now record the settings their
cut-offs were last generated with, and files carry them; older files
still load with the defaults.

Saving over a nest file truncated it before writing, so any failure
part way lost the only good copy, and the error reached the user as an
unhandled exception after the save path had already changed. Nest and
settings files are now written beside the target and swapped in, and a
failed save is reported with the old file left intact.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 09:51:11 -05:00
ajandClaude Opus 5.5 e8c52a354d fix(posts): refuse wrong-process output and keep settings across updates
Ahead of the new laser schedule, three ways a post could silently cut
with the wrong process, and one way its settings silently reset:

- Cincinnati CL wrote no G89 when no cut library matched the nest's
  material, thickness and gas (or no etch library for etch features),
  so the controller cut with whatever library it loaded last. It now
  refuses, unless the new "Require libraries" setting is turned off.
- Cincinnati CL declared G20/G21 from its own setting without comparing
  the nest's units, so a metric nest posted 25.4x too large. It now
  refuses a mismatch.
- CI Fiber posted any material missing from its table as the default
  code (MSN), so stainless or aluminum ran with mild-steel technology.
  A named, unmapped material is now refused; the default code covers
  only nests with no material.
- Posts saved their settings beside their DLL, inside the install
  folder a Velopack update replaces, so every update reset them to the
  shipped defaults. Saves now go to %APPDATA%\OpenNest\Posts and the
  shipped JSON only seeds them; constructing a post no longer writes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 09:51:11 -05:00
ajandClaude Opus 5.5 82d54aec87 fix(post-review): list part-support warnings in the post review
PartSupport findings counted toward the headline and the Post Anyway
checkbox but had no tile or list group, so an operator saw "1 warning"
with nothing to read and was likely to tick through a part that may tip
once cut free. A test now fails if any finding kind is left unlisted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 09:51:10 -05:00
ajandClaude Opus 5.5 b2cc796e4a fix(cutting): let a part no tab can steady leave from another entry
A support-tabbed part that no single tab can hold level was limited to its
one steadiest entry. Two strips stacked in a frame's cutout then blocked
the plate: from the upper strip's only entry, every route to the lower one
crossed holes already cut. Its other entries clear of inside corners now
follow the steadiest, in the search and in contour recovery; the part is
still tabbed and still warned about. Parts a tab can hold keep their
steadying entries.

The unverified headline also named fixed lead-ins when the only warning
was a part that may tip; it now says what needs review.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 09:34:00 -05:00
ajandClaude Opus 5.5 e0bc97a719 fix(cutting): plan support-tabbed perimeters that have a lead-out
Every part the support grid could not hold level got a tabbed perimeter
with the outside lead-out after its tab, and planning refused any lead-out
after its own open cut, so with a lead-out configured no such part could
be planned. Pre-post review already proves such cuts release nothing (the
lead-out stays out of the tab gap); planning now runs the same proof, so
planning and review agree and a lead-out that reaches into the tab is
still refused.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 09:33:57 -05:00
ajandClaude Opus 5.5 af9886c355 chore(ui): take Drawing Library Grid off the File menu
The grid was added to check the whole library for drawings that freeze
a preview; it is a testing tool, not an operator feature. The form and
its test stay for future library checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 08:45:50 -05:00
ajandClaude Opus 5.5 3d728b000e fix(bestfit): never hold a pair to a tighter aspect than one part
The best-fit filter rejected pairs over a 5:1 aspect (or the plate's)
unless 75% utilized. A long part such as U251-DET3 (27.4 x 3.5, aspect
7.7) is past that alone, so its tightest interlocked pairs (5.1:1) were
all dropped even though they are less elongated than the part itself.
On the 60 x 120 sheet that cost 12 parts: 66 placed instead of 78.

The limit now widens to the part's own bounding-box aspect, so
side-by-side pairs survive while end-to-end pairs of compact parts are
still rejected.

The learned-angle characterization nests re-captured: their 46 x 3 bar
now nests as an interlocked pair, which left the Fill nest identical to
a full sweep, so the notched quantity drops from 6 to 4 to keep the
fixture sensitive to learned angles.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 07:58:31 -05:00
ajandClaude Opus 5.5 1a46d9896f perf(geometry): speed up labels and shape chaining on many-hole parts
The Drawing Library Grid check found seven drawings with 1,000-1,700
holes (90-6138-26/27, Reeves bakery vent pans, 4938 A15) that took
0.5-3.6 s to preview, all of it in the part label point.

- PolyLabel skips a hole's containment test outside its bounds and its
  edge distances when its bounds are farther than the nearest edge so
  far. Both skips leave the result exactly as before; label points on
  all seven drawings are unchanged and the search is 4-35x faster.
- ShapeBuilder.GetShapes rescanned every remaining entity at each
  chaining step. An endpoint grid now finds the candidates, tested in
  list order with the same checks, so chosen entities, reversals and
  shapes are identical (compared against the old loop on the library
  drawings and 300 random entity soups). 90-6138: 700 ms -> 40 ms.
- The label builds its shapes once: ShapeProfile.FromShapes reuses the
  ones it already chained instead of chaining them again.

Previews of all seven now take 57-166 ms.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 07:50:06 -05:00
ajandClaude Opus 5.5 b703abe8dc feat(library): add a Drawing Library Grid that checks every drawing
File > Drawing Library Grid shows a page of library drawings side by
side. Check All Pages walks every page, downloading each drawing, timing
its label search without the paint's cell budget on a worker with a
10 s limit, then timing its paint, and lists drawings that fail, run
slow or would freeze a preview. It was added to confirm no other library
drawing hangs on load the way the twin-outline drawing did: a run over
all 40,757 drawings on the work server found no hangs or failures.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 07:50:06 -05:00
ajandClaude Opus 5.5 f9b718e890 fix(preview): stop part labels hanging on twin-outline drawings
A drawing of two equal, separate outlines (RC-204441A23 PT13) froze the
drawing library preview. ShapeProfile takes one outline as the perimeter
and the other as a cutout, so the net area is rounding noise and
ThicknessPrecision fell to 1e-9. A rectangle's pole is a whole ridge, so
the label search refined it into billions of cells on the UI thread.

Net area negligible next to the outline now falls back to the outline's
own width, and the paint-time label search has a cell budget so no shape
can stall painting.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 07:50:06 -05:00
ajandClaude Opus 5.5 d4e622271a feat(ui): show each drawing's count on the current plate
The drawing list only showed nest-wide totals, so seeing how many of a
drawing a layout holds meant counting parts by eye. Prefix the nested
line with the current plate's count, e.g. "[78] 144 of 1 nested".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 07:28:44 -05:00
ajandClaude Opus 5.5 f597b06024 fix(console): autonest each drawing's required quantity by default
--autonest without --quantity nested one copy of each drawing, so a
118-part job of 67 drawings solved as 67 parts and reported success.
Default to the required quantity less copies on other plates, which the
run keeps; drawings without one are left out, as on the desktop, unless
no drawing has one. --quantity still overrides.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 23:43:04 -05:00
ajandClaude Opus 5.5 3ca23e9474 test(cutouts): allow float rounding at the exact wall clearance
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 23:42:26 -05:00
ajandClaude Opus 5.5 b1a03c1796 feat(engine): solve rectangular cutouts as a knapsack of boxes
Search insert selections as boxes with a counted beam search over maximal
free rectangles, pair low-density parts with their half turn, then gap-fill
with the frontier packer. The router takes it on seated outline area.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 23:42:26 -05:00
ajandClaude Opus 5.5 62e5410cdb fix(cutouts): maximize material seated in cutouts, not copies
Compare cutout proposals, frame angles and bundles by insert outline area,
and add bounded largest-first packer candidates so big parts get the first
move in an empty hole. On the real job the four frames go from 54-70% to
77-81% filled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 23:42:26 -05:00
ajandClaude Opus 5.5 12819198f9 feat(fill): search every spiral combination in rectangle best fit
The spiral used only the least-waste rows and columns. Those often make
one pair of blocks the larger on both axes, so it overlapped itself and
placed nothing, leaving Fill at two blocks. It now also tries every
four-block combination and takes one that holds more parts than both the
least-waste spiral and the two-block layout, so ties keep today's layout.

A 9 x 6.5 part on a 60 x 120 sheet goes from 109 to 112.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 23:42:25 -05:00
ajandClaude Opus 5.5 763e2a1d4a fix(ui): scale the fill time in the status bar
Long fills read as thousands of milliseconds. Keep milliseconds under
a second, then show seconds and minutes so the time stays readable.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 23:42:25 -05:00
ajandClaude Opus 5.5 0a0da50006 feat(ui): show the layout check in the status bar
An empty canvas corner gave no sign of whether a check was still running,
which matters on large nests. A Layout section beside utilization now
follows the automatic check: checking, OK, or findings in red, with the
full wording in its tooltip. It has its own label so rechecks never
replace the last command's status text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 23:42:25 -05:00
ajandClaude Opus 5.5 ac7ee41801 feat(ui): leave the overlap corner empty unless something is wrong
Drop the check mark: a clear result, and an automatic recheck after one,
now draw nothing. Findings and failed, canceled or incomplete checks keep
their text, and views without automatic rechecks keep their pending text.
The status bar still reports a manual check's result.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 23:42:25 -05:00
ajandClaude Opus 5.5 fd37cbffef feat(ui): keep the overlap corner quiet during rechecks
A pending or running recheck no longer swaps the green check for status
text. A clear result stays as a gray check, and earlier findings stay as
dimmed text, neither of which claims anything about the edited layout.
Views without automatic rechecks still ask for a manual check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 23:42:25 -05:00
ajandClaude Opus 5.5 c0cd7c6aff feat(ui): validate part spacing in the plate view overlay
The overlap check now runs the pre-post part spacing scan on its snapshot,
so the canvas label and posting agree. Too-close pairs are counted in the
label and marked with an orange ring showing the gap, with hover details.
A fully checked plate with no findings draws a green check instead of
text; the status bar keeps the wording. Changing the plate's part spacing
now stales the report, and repeated parts share one offset outline so
automatic rechecks stay fast.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 23:42:25 -05:00
ajandClaude Opus 5.5 c8883bbd1e fix(ci): follow the Lattice test rename in Windows acceptance
The Fill engine rename changed McpFillToolsWithoutAnEngineUseFill to
...UseLattice, so the acceptance check failed on a missing test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 23:24:44 -05:00
ajandClaude Opus 5.5 44372d129e feat(ui): rename the Fill engine to Lattice and describe engines
"Fill" said nothing about what the engine does, since every engine fills.
It is now Lattice, and Fill stays an alias, so saved selections, scripts
and API requests keep working. Engine descriptions are rewritten in plain
language and shown beside each name in the desktop engine lists; the main
toolbar's tooltip also says when Fill Area falls back to Lattice.

Docs also cover the leftover placement from the previous commit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 21:17:16 -05:00
ajandClaude Opus 5.5 4b2aba83bb feat(fill): keep interlocked pairs whole and place leftovers as pairs
A quantity-limited fill trimmed the parts farthest along the trim axis,
which could take one half from each of two pairs. TrimToCount now finds
interlocked pairs and keeps or drops them whole (from d1d68a91), so the
spare space stays one usable cell.

After a fill, leftovers now run in two orders, pack-first and pairs-first,
and the strategy's comparer keeps the better whole layout, so its ranking
of this step cannot get worse. Even quantities go in as best-fit pairs,
may turn a quarter when unrestricted, are tried in every remnant and are
ranked with the layout around them. Each placed pair slides left and down
against true outlines to take the space its bounding box could not.

On compare.nest Vertical Remnant goes from 6665.1 to 5862.6 and Lattice
from 7200 to 5915.8. Nine characterization pins change from the trim with
counts unchanged; the fill pins now also check layout validity. Vertical
Remnant's golden layout shortens from 28 to 26.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 21:17:15 -05:00
ajandClaude Opus 5.5 be4886f876 fix(ui): remove the F1 hotkey for help
F1 opening help kept taking over from placing a part. Help stays on
the Help menu and F1 belongs to the Clone tool alone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 18:25:56 -05:00
ajandClaude Opus 5.5 e7499f14c2 fix(ui): return to Select after one Zoom To Area
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 17:17:49 -05:00
ajandClaude Opus 5.5 10a4128187 fix(engine): keep full-sheet fills on clamped jobs
Whole-job fills treated clamps as occupied space, so a clamped edge cost
a row: 8.25in circles stopped at 96 on a sheet the plate fill packs with
102. When one drawing still has unmet demand, also fill the sheet as if
the clamps were absent, drop the parts on them and keep the better
layout.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 17:13:37 -05:00
aj 4e92d0e8f3 fix(planning): route a cut-off from its start to its far end
A cut-off always runs away from its fixed edge: the origin side, the only
edge guaranteed to be a real sheet edge. The part order is proposed as a
traveling-salesman path over one point per placement, and a cut-off's
point was the middle of its line. The route did not know the tool must
arrive at the line's start and leaves at its far end, so the parts
before a sheet-splitting line finished level with its middle, and the
rapid down to its start crossed parts already cut.

Each placement now has an entry and an exit point; they differ only for
cut-offs (start and departure). Nearest neighbor and Or-opt go on from
each part's exit, and 2-opt costs a reversed run along its own directed
legs; with no cut-off on the plate the exits are not passed and the
symmetric route is unchanged. The part cut before a cut-off faces its
start.

Cut-off direction is not chosen here: the order reads each cut-off's start
and end from its program as given, and the joint search may still reverse a
head-locked far-edge segment.
2026-11-01 16:51:09 -05:00