The release dialog's Add a set box was a pure type-ahead: it queried the
server only after typing paused, so opening it, or clicking its arrow with
nothing typed, showed an empty list. From Drawing Sets > Release that was
easy to miss, but New Release starts with nothing listed, and an empty
dropdown there reads as a missing server connection. The dialog now reads
the first active sets by name when it is shown, and again when the list is
opened while still empty, without dropping the list open on its own; typing
narrows it as before.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Releases could only be reached through one set or one library drawing, so
seeing what the shop released lately meant knowing which set to open first.
File > Releases shows every release on the server, newest first, naming what
each one had ("Kit A ×2, Kit B; Bracket ×4") in place of the per-set
revision and kits, with the same nest list and Undo Release. New Release
opens the release dialog empty, so a release can start from the list rather
than from a set; the plan builder now accepts no lines as an empty plan,
and the dialog's Release button stays disabled until a group is listed.
The list re-reads from the newest page once the dialog records a release.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
After adding library drawings the operator had to close the dialog to see what
the nest now needed, and fixing a quantity meant leaving it for Edit Drawing
one part at a time. The new In This Nest tab lists the nest's drawings (cutoffs
excluded) with their library revision and required, nested and remaining
quantities, refreshes after each add, and edits Required in place.
An edit applies to the nest immediately, like an add, and the nest window
refreshes its drawing list when the dialog closes. Out-of-range values are
refused both when the cell is validated and when they are applied, because
DataGridView only validates on leaving the cell and EndEdit commits without it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Release dialog lists sets and drawings in one grid (with a type
column; Kits / Qty is a set's kits or a drawing's quantity, up to
100,000). Add Drawings... browses the library as the set editor's pane
does and stays open for several adds; listed drawings are greyed and
skipped, archived ones refused. The Drawings tab gains Release... (when
opened from a nest) to start a release from one drawing, and
Releases... so a release of drawings alone can still be found and
undone, since it belongs to no set's history.
docs/nest-storage.md describes the desktop flow, the `drawings` wire
field, null item setId, the drawingId query/probe and schema v11.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Plates with staged automatic scrap cut-offs could not be planned: P260810-01
plate 1 ran out of budget even at 10x effort, while the same plate plans
Ready in 3.6k expansions without the lines. A cut-off was one fixed program
cut whole before every part its line passes through, which dragged the tour
to the middle of the sheet and left the head at the far edge of the line;
and cutting every line first (the rejected alternative) weakens the sheet
and breaks the containment operators rely on when they fast-forward a
changed program.
A cut-off stays one definition, but Plate.RegenerateCutOffs now makes one
part per trimmed segment, each with its own place in the cut sequence.
CutOffSegments gives each segment the span of the nominal line it stands
for (end of the segment before it to start of the one after), and the
dependency rules of the planner and Part Sequencing use that span, so a
segment precedes only the parts beside it. The free-order search plans the
parts as if the segments were not there, so adding lines no longer changes
a plate's route, then CutOffInsertion slides each segment into the latest
gap before its first part where the rapid into its pierce and the rapid
from its end cross nothing cut before; only when one fits nowhere is the
plate searched with the segments among the parts. The search looks through
segments wherever they sit (entries face the next part, hole routes rank
from the pre-segment position, rapids are still checked from the segment's
end), so an applied plan replanned with the order kept replays Ready.
Segments saved out of consecutive order are recorded per segment in the
.nest file (`segments`); older readers load them consecutively.
P260810-01 plate 1 now plans Ready in 3639 expansions with every check
passing; rapid travel 1836 against 1547 without the lines. Plates without
cut-offs keep their PlanningCharacterizationTests digests, and the
problem-nest corpus has no plate below its baseline.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Cut planning should rank routes safest first, then fastest, but a plate whose
strict search hit its expansion budget was simply refused ("no plan found
within the search limit"), even when a route with a few reviewable rapid
crossings existed. Scrap cut-offs make this common: their trimmed segments
can wall off a column of parts, and rapids are straight.
When both the free-order and current-order searches stop at the limit, the
batch now walks a greedy safest route from each input, replays it with fresh
checks, and keeps the one with fewer violations (material first, then rapid
crossings, then the rest), then less rapid travel. A route that passes every
check is an ordinary Ready plan; otherwise it is an unverified BestEffort
that lists every violation and applies only with explicit acceptance. Routes
with any motion into material are never offered, so the strict refusal and
its lead-in advice stand.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Releasing a set creates new nests or merges into draft ones, so tying the
set browser to the Drawing Library dialog (which needs an open nest) put it
behind a document it never uses. File > Drawing Sets... (Database mode)
now opens a standalone window with the set browser and Release, opening
released nests in their own tabs. The library dialog loses its Sets tab
but keeps Used in Sets and Add to Set on a drawing's menu.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The library browser showed only a grid and a notes box, so picking the right
part meant reading names and guessing at the shape, and the add controls sat in
a crowded row with the pager. The Drawings tab now splits into the list (with
its pager underneath) and a details pane: a geometry preview, the drawing's
name, customer, material, thickness, cutting and revision, its notes, and the
quantity with a prominent Add to Nest button.
The preview downloads the listed revision's package after the selection settles
for 150 ms, shares a request already loading that revision, and caches drawings
per revision for the dialog's lifetime. It colors the drawing from the record's
settings without advancing the nest's part palette. It is best-effort: any
failure shows "Preview unavailable" and the dialog keeps working, and the UI
update is marshalled explicitly because an STA thread without a WinForms
synchronization context resumes the await on the thread pool.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Steel is "Carbon Steel" in OpenNest, matching the Cincinnati post's cut
libraries. The CI Fiber material-code table only listed "Mild Steel", so a
Carbon Steel nest reached MSN only by falling through to the default code.
List "Carbon Steel" explicitly in the shipped JSON and the built-in
default, and keep "Mild Steel" for nests that already use it.
Tests check both names against the shipped config and the built-in
default; the Carbon Steel rows failed before this change. Posted output
is unchanged, since the default code was already MSN.
With every part drawn the same, it was hard to see which parts the drawn
lines had not reached yet. Parts no line reaches are now drawn muted, and
update live while dragging. Clicking a part adds it as a one-point line, so
a stray part can be picked without drawing a line to it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every part was claimed by its nearest line even when the line never reached
it, so a part beyond a line's start projected to distance 0 along it and was
cut near the front. Parts now belong only to lines crossing their bounding
box; uncrossed parts follow all the others, ordered by their nearest line.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fill only tried 0 and 90 degrees for parts classified as rectangles, so a long
part filling a 60 x 120 plate four high at 90 degrees left a 55 x 59 strip empty
although two more fit tilted about 33 degrees (a reported nest: 4 placed, 6 fit).
The second tilted part only fits with its corner tucked beside the grid, in the
strip the grid's slack leaves, so a plain rectangular remnant fill finds one.
TiltedRemnant runs after the other strategies. It moves the best layout flush to
one end so leftover room becomes one remnant, and to either end of the other axis
so its slack forms one strip; then tiles the part at the most upright angles that
fit the remnant's height and keeps only copies at least the part spacing from the
layout. It is skipped when the part fits the remnant upright, for circles, for an
explicit rotation range and once the requested quantity is placed.
Fill benchmark (--parallel 1): the synthetic set is unchanged (all valid, same
cost and plates). The reported part needs 1 sheet instead of 2 for 6 parts and
2 instead of 3 for 12.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Nests, drawings and releases store material and grade as free text, so
there was no canonical list for clients to suggest from or to fix
spelling against. Schema v10 adds materials and material_grades keyed by
SharedListNames.Key, with GET/POST /api/materials. Adding is idempotent
by key and keeps the first spelling.
The tables start empty: the materials already stored did not import
cleanly, so the list is filled through the API instead. Existing
free-text columns are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A release now ends in nests ready to cut rather than empty drafts, and a
merge no longer leaves the draft it cleared waiting for someone to run Auto
Nest. "Nest after release" (on by default) runs Auto Nest headless on every
released group, new or merged, before anything is uploaded.
NestRenest removes every plate and nests each drawing's required quantity
onto sheets from the nest's plate defaults and plate-size options. It keeps
a layout only when it is valid and keepable, so an invalid result never
reaches the server; the nest is saved without sheets and the operator is
told to run Auto Nest. Unplaced copies stay as remaining quantity, and the
status column lists sheets, utilization and what did not fit. A new Nesting
progress stage reports each group, and cancelling while nesting saves
nothing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The release dialog now lists the sets to release instead of one set with a
multiplier. More are added by typing a name (the matching active sets fill
the list as you type) and each set has its own kit count. Its groups span
all the sets, and each group can make a new Draft nest or merge into a Draft
nest of the same material, grade and thickness, listed with its sheet count.
The status column says that a merge discards the draft's layout and that
Undo Release restores it.
A draft open in a tab of this desktop is refused, because nest tabs do not
track unsaved edits and the merge would leave them behind. The main window
tells the dialog which server nests are open.
The release history shows what each release did to each nest (created, or
merged from one revision to another, and what undo did) and gains Undo
Release. When nests changed after the release, it names them and offers to
undo the others, leaving those as they are.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The release plan now takes several sets, each with its own kit count. A
drawing listed by more than one set becomes one item with the quantities
summed and each set's share kept, so the release can record what every kit
put into every nest. FindDraftsAsync lists the Draft nests of a group's
material through the new nest query filters.
The session can merge a group into a chosen draft instead of making a new
nest. It downloads the draft at the revision it was chosen at, refuses it
unless it is still a Draft of the group's material, thickness, units and cut
type, adds the items, and removes every plate so the whole demand is nested
again. The save is guarded by that revision, so a draft someone saved
meanwhile fails its group instead of being overwritten. An optional renest
step, run before anything is uploaded, will back "Nest after release"; if it
throws, the nest is still released without a layout.
The release record now carries every set line, merged nests with their
revisions before and after, and each set's drawing quantities.
SetReleaseText.UndoRefusal words a refused undo for the release history.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A release that merges into an existing draft needs the drafts of the same
material group. The nest query can now filter exactly on status, material,
grade and thickness. Material and grade compare like the shared material
lists (case and spacing ignored) through a SQLite function, so no key columns
or backfill are needed; a blank grade asks for nests without one, and
thickness matches at the four decimals drawings are stored with.
The client sends the filters only when set, so plain browsing keeps working
against servers that do not know them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A release can now cover several sets, each with its own kit count, so parts
from different kits share sheets. It can also merge into an existing draft
nest instead of always creating one. Schema v9 replaces the single-set
release tables: releases, their set lines, their nests (created or merged,
with the nest revision before and after) and the drawing quantities each set
added to each nest, so a kit stays traceable once kits share a nest. The v8
migration turns each existing release into one set line with created nests.
Undo runs on the server in one transaction: created nests are soft-deleted
and merged nests restored to their pre-merge revision, but only while each
still holds what the release wrote. Otherwise nothing changes and the
changed nests are listed, so the operator can skip them. A nest restored to
that revision counts as unchanged, which lets releases sharing a nest be
undone newest first.
The old /api/sets/{id}/releases and /api/nests/{id}/release routes are
replaced by /api/releases; no tagged desktop used them. The desktop still
releases one set at a time until the release dialog is reworked.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adding drawings to a set meant opening the library dialog, then the set
editor, then a second copy of the library in pick mode, then backing out
again. The set editor now has the library as its left pane (unfiltered,
searchable, sortable, paged): select drawings and Add to Set, double-click
or press Enter. Members already in the set are greyed. The library
dialog's pick mode had no other caller and is removed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The server stored whatever plate count, part count, material and
thickness the client claimed, so a record could disagree with its own
archive, and a bulk importer had to read each written .nest back in full
just to describe it (about a quarter of the PEP archive import's time).
Uploads (POST and PUT /file) now read only the archive's nest.json -
never programs or geometry, and without referencing OpenNest.IO - and
overwrite those fields, following NestReader's fallbacks for thickness,
material, parts with a missing drawing and the trailing new-plate slot.
A file without a readable nest.json is 400 and stores nothing, so the
server can guarantee the record describes the bytes; nest.json
decompression stops at 64 MB. A metadata-only PUT keeps the stored
counts because the archive is unchanged; material and thickness stay
editable there, since the desktop applies the record's values on open.
Server tests that uploaded placeholder bytes now upload small
deterministic archives, and the container smoke's near-limit probe is a
padded real archive. New tests pin the server's values to a full
NestReader read of the same archive.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Plan Cutting is now the only automatic lead-in assignment, and parts the
support grid cannot hold level are reported wherever they lack a
steadying tab.
- Remove Assign Lead-ins (plate and nest), LeadInAssigner, the lead-in
tool's Auto-Assign button and the Auto Tab size range; old settings
with autoTab sizes still load
- Manual Place Lead-in tabs the clicked entry when support tabs are on
and the grid cannot hold the part (SupportTabSettings)
- New PartSupport finding: Plan Cutting replay and best-effort plans
warn when a drawing pin, a lead-in that does not fit or no single tab
leaves a part unsteady; the pre-post review checks each placed
program's outside tab gap. These warnings replace the advisory
weak-tab notes; only the inside-corner tab note stays advisory, and
never for a pin
- Pinned perimeters keep their pin but carry the support analysis
- Draw grid points as pixel-snapped squares without anti-aliasing
- Post fixtures build lead-ins through a test-only TestLeadIns helper
- Docs: support tabs, pre-post verification and planner notes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A tab cannot lift a part's margin past its contacts' own hull edges, so a
whole stretch of outline often ties for the best tab point, and the first
sample found won, leaving the tab off-center. Keep the full outline search
for the margin, then among samples within Tolerance.Epsilon of the best,
pick the one nearest the line through the center of gravity across the
long side of the outline's minimum-area bounding rectangle. A part held
only near one end is still tabbed at the far end.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Nest records gain a materialGrade field (server schema v8, blank for existing
rows) that is searched, sorted and versioned like the other metadata. The
Nest Info dialog gets a grade picker listing the machine configs' grades for
the chosen material; density survives only an unchanged name and grade. A
blank recorded grade keeps the archive's grade while the name matches, so
records saved before v8 do not lose it on open. Saved Nests shows a Grade column.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Saved best-fit pairs are in the drawing's canonical frame, but the canonical
angle is recomputed on load and was not saved with the set. When that
computation changes (RotatingCalipers checking every hull edge, marks no
longer counted as material), old pairs were replayed in a turned frame and
could overlap.
Each saved set now records canonicalAngle, and BestFitCacheStore.Import
skips sets whose angle no longer matches the recomputed one (1e-9 rad,
modulo a full turn). Sets from older files have no angle and are dropped;
their pairs are recomputed when next needed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
While a Sequence by Path line is being dragged, the plate view shows the
numbers the finished line would give, without reordering the plate, so
reorder listeners (drawing list, overlap overlay, simulator) are not hit
on every mouse move. The plate is reordered once on release.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Plate > Sequence Parts > Sequence by Path: each left-drag adds a line,
cut in drawing order; the jump between lines is a rapid and claims no
parts. Each part belongs to the line passing closest to its center and
is ordered by where that nearest point falls along the line. Cut-first
parts stay ahead and cutoff dependency rules still apply. A small window
offers Undo Line, Clear (restores the starting order) and Done.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The best tab point used to land in inside corners: equally good points
run along a straight edge, vertices were tried first and the first tie
won. Operators cannot grind a nub flush there.
- SupportAnalyzer finds inside corners (inward-turning vertex runs of at
least 30 degrees, so chorded fillets count) and keeps tab points a
clearance from them; of equally good points it picks the one farthest
from an inside corner. Plan Cutting and the overlay use twice the tab
size; AcceptsTabAt rejects closer points
- When no steadying entry has a lead-in that fits, the search falls back
to entries clear of inside corners, then to every entry, each ordered
by how well the tab steadies the part, keeping only the steadiest that
fit
- Replay notes parts whose planned tab cannot hold them level or sits in
an inside corner; the notes are advisory and leave a Ready plan Ready
- Console/MCP plate summaries print a ready plan's notes
- docs/support-tabs.md and cutting-planner notes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Model the machine's support bed as a grid of contact points measured
from the plate origin, and check each part's center of gravity against
the convex hull of the grid points under its material. The bed is
extensible so straight and CAD-imported curved slats can follow.
- Core: SupportBed/SupportGrid, SupportMaterial and SupportAnalyzer
(margin with registration tolerance, best single tab point)
- Nest-wide support bed that every plate follows, saved in
plateDefaults.supportBed; machine defaults in support-grid.json
- CuttingParameters.SupportTabs: Plan Cutting tabs only unsupported
parts and limits their perimeter entries to points where the tab
steadies the part, falling back to any fitting entry
- Desktop: Nest > Support Grid..., View > Draw Support overlay and a
"Tab parts the support grid cannot hold level" tab option
- docs/support-tabs.md, nest file format and planner notes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Operators often build a nest first and only then want it kept as a
reusable kit. The drawing list's new "Add Library Drawings to Set..."
takes every drawing copied from this server's library, sums copies of
one library drawing, and opens the set editor on a chosen or new set
for review and Save. Unlinked, other-server and zero-quantity drawings
are named as skipped instead of silently dropped.
Members the set already lists keep the set's quantity: a nest released
from a set carries its kit multiplier, so copying its quantities back
would scale the kit on every round trip. Members are added at the
library's latest revision (S1), with a note when the nest holds an
older one or the drawing is archived.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A set is only useful on the floor once it becomes nests. Release on the
Sets tab previews one row per material group with a kit multiplier, an
archived-drawing toggle and a tick per group, then builds each ticked
group's nest as File > New would, in the group's units, uploads it as a
Draft, opens it in its own tab bound to the server record and records the
release. Every group's outcome stays on screen, and a release whose
nests exist but whose record failed can be recorded again.
Releases shows each release's nests and how far they have got ("2 of 3
cut"), and Nest Info names the release a nest came from, so a kit run can
be followed across its nests. Plate defaults convert between inches and
millimeters so a group drawn in other units still gets sensible plates.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Operators need to build kits from library drawings before they can be
released. The Drawing Library dialog gains a Sets tab beside Drawings,
so sets live where their drawings are browsed: list, search, archive,
restore, history, and an editor whose Add Drawings reuses the library in
a multi-select pick mode. The Drawings tab's menu shows which sets use a
drawing and adds it to a chosen or new set.
DrawingSetEditSession keeps a new set's id across a save whose reply was
lost, so a retry adopts the stored set instead of creating it twice, and
guards existing-set saves with the revision they were read at.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The desktop needs a cross-platform way to read and save sets and to turn
one into nests before any UI is built on it. RemoteDrawingSetStore covers
every /api/sets route with the library client's checks and conflict
handling. SetReleasePlan groups a set by material, grade, thickness, units
and cut type without I/O, so the release dialog can preview refusals
(duplicate names, drawings without material) before anything is created.
SetReleaseSession builds every group's nest through LibraryDrawingInsert
before uploading any, so a refusal leaves nothing on the server; uploads
then never cancel mid-flight, a lost reply is reconciled by the nest's
client-allocated id, and the release is posted only when every chosen
nest exists, with a same-id retry when that post fails.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Releasing a drawing set makes one nest per material group, so a kit run
spans several nests. The server now records which set revision was
released, the multiplier and the nests it made, so a run can be tracked
across its nests and a nest can say where it came from.
The client uploads every nest first and posts the release last: a failure
part-way leaves ordinary nests and no release, never a release pointing at
missing nests. For the same reason a release is accepted for an older set
revision or an archived set, since the nests already exist by then. The
release id is client-allocated and a nest belongs to at most one release,
so a retried post gets 409 with the release that already holds it.
Releases are append-only and read joined to each nest's current metadata,
so status and deletion are always current. The tables join schema v7, as
the set tables have not shipped yet.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A drawing set is a named list of library drawings with quantities (a kit,
an assembly, a recurring order) that will later be released into one nest
per material. This is the server half: sets get the same revision,
If-Match and archive contract as /api/drawings so the client and tests
follow a known shape.
Schema v7 adds drawing_sets, drawing_set_revisions and
drawing_set_members. Members reference drawings by id and mean each
drawing's current revision, so reads join the current drawing record:
the client can group members by material without one request per drawing,
and the joined record is ignored on save so a read record can be sent
back unchanged. Every change keeps its own member list, and
/api/drawings/{id}/sets answers "used in" from current revisions only.
The drawing query's enum, integer and history-paging parsing is now shared
so both APIs refuse bad input identically.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Nests released from drawing sets need a state before Quote: created but not
yet nested or checked. Draft is appended to NestStatus (value 3) because the
server still accepts integer statuses from existing callers, so existing
numbers must not shift; NestStatuses.WorkflowOrder puts it first wherever the
operator picks a status.
Older desktops read Draft as Quote (the documented unknown-status fallback),
and an older server refuses "draft", so the server must be upgraded before
desktops that can set it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The pallet-change setting and post doc said M50 moves the cut sheet out,
borrowed from the CL-series manual. Cincinnati's CNC Codes Handbook calls
M50 "Table In" and M51 "Table Out". On the CI Fiber shuttle, Table In brings
the waiting pallet into the laser, which sends the cut one out, so M50 is
still the swap. Say that, note that it expects the waiting pallet to be
loaded, and note that newer Cincinnati samples end without a pallet code.
Default (M50) and posted output are unchanged.
The sample regression fixture now carries each part's pierce, lead-in and
cut moves from the Cincinnati machine program as its saved cutting program.
A new test posts those saved programs without reassigning lead-ins and
requires the program body to equal the sample exactly: L2/L4 macro, G41/G42
side, lead-ins and every cut move (21,911 lines).
Mutation checks: dropping the largest-contour perimeter rule from the kerf
fix fails it at the first perimeter (L4 posted as L2), and forcing G41 fails
it at the first perimeter's G42. The existing tests still replace the saved
programs with OpenNest's own lead-ins first; their comment now says so
instead of describing the sample's leads wrongly.
The CI Fiber post selected G42 for every perimeter. Cincinnati's CNC Codes
Handbook defines G42 as "product remains on the left", and imported
perimeters run clockwise with the part on the right, so the controller
offset every outside edge into the part: parts came out a kerf undersize.
Cincinnati's LaserNST samples only use G42 because they cut perimeters
counter-clockwise.
Winding is normalized only at DXF import, so the post can't assume a
direction either. It now takes the largest contour as the perimeter (as
ShapeProfile does) and picks G41 or G42 from each contour's actual winding.
That also stops a reversed drawing from swapping the L2/L4 lead-in macros.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The safety raise (M47 P<SafetyHeadraiseDistance>) used to fire only when
the next part had a different drawing name, which has nothing to do with
crash risk: a long rapid between copies of the same part got a plain M47,
while a short hop between neighbouring different drawings got the full
raise. Sheets are rarely flat (5/8" plate can be ~1.5" out of flat within
supplier tolerance), and longer rapids cross more of that bow.
Add SafetyHeadraiseRapidDistance (program units, default 12"): any rapid to
the next pierce longer than it takes the safety raise, regardless of
drawing. Unknown travel never does.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Console --plan-cutting and MCP plan_cutting run the planner at the default
effort; only the desktop exposes the setting. Adding a corpus nest must keep
the corpus server selected until the save, and the command is Nest > Edit.
Tools > Options > Cut planning effort (default 1.0, 0.5-10) multiplies the
desktop cut planner's per-plate expansion budget for both the free-order
search and the current-order retry. The budget counts expansions, not time,
so the setting is how faster hardware can be spent on hard plates.
The panel reads the setting on the UI thread and passes it to
CuttingPlanBatch.Capture; the worker never reads settings. The 1,000-
expansion first pass stays fixed: it is a cheap probe for easy plates, so a
higher effort only adds work where the full search runs. A plate refused
at the search limit now says the effort can be raised, without promising a
plan. The default keeps today's budgets and characterization digests.
Console, MCP and API do not run the cut planner, so they get no option.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Plans every nest on a dedicated OpenNest server (OPENNEST_PROBLEM_NESTS_SERVER)
plate by plate, with a per-plate time limit, and fails when a plate ranks
below the "planning: 1=... 2=..." baseline in the nest's comments. Customer
nests and baselines stay on the server, never in the repository. Refuses a
server holding more than 200 nests, so a production archive is not planned
by mistake.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Console --plan-cutting and MCP plan_cutting/apply_cutting_plan run the
desktop's CuttingPlanBatch: capture, plan, then an all-or-nothing apply.
Settings come from an explicit JSON file or the plates' identical saved
settings, never defaults. Unverified plans need per-call acceptance,
which is not posting consent. Console --no-fill plans a loaded nest as
is; a blocked plan exits 2 and saves nothing. Scrap cut-offs stay
desktop-only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An attempt along a part order stopped backtracking after 8 x entries x
contours expansions without progress, with contours taken as the most of
any part on the plate. One many-holed part therefore let every blocked
part, even a two-contour tab, replay its predecessors' entries for the
whole of that allowance; a plate whose rounds each stalled that long
ran out of budget before the recovery pass that would have finished it.
Along an order the stall now uses the larger contour count of the blocked
part and of the part cut just before it, whose departure a retry changes,
capped by the old limit. The sequence-free recovery pass keeps the plate
maximum. Planning characterization digests are unchanged.
The optional private-fixture test now also runs RecoveryCuttingNestPath
with default lead-ins, and requires that file's plates to plan within
60% of their budget.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The cut planner's directed-contour recovery pass gave up on plates the
full search could solve, so they ended "no plan found within the search
limit":
- Each hole was checked as an isolated probe that repeats the part's
scribes, so every hole-to-hole hop was checked as a detour through
the scribe start. Scribes and other open cuts are now checked once
from the arrival, and each hole as a direct hop from the one before.
- Hole entries were ranked only by pierce distance, so the departure
often ran back across the hole just cut. The nearest hole is still
tried first, but its entries that leave toward the holes still to
cut come first.
- The first-ranked outside entry could spend the whole recovery
allowance. Each outside entry now gets a share of what is left.
The optional private-fixture test now takes its config key, adding
RecoveryCuttingNestPath; it fails on the old search and passes now.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A plate of at least 200 parts with no cutoffs or prerequisites, whose
part centres bin into rows and columns within a quarter of the smallest
part extent, is toured line by line in alternating directions. Each row
and column gap must be wider than that tolerance, each cell may hold
only one part, and at least a quarter of the cells must be filled
(interleaved rows fill half). The route runs along whichever axis, from
whichever corner, is shortest from the start point.
This replaces the travelling-salesman 2-opt/Or-opt passes, which took
about 8 s on 5,742 parts. It is still only a proposal: the joint search
checks every rapid and lead, and replans after a learned rule use the
general order. Smaller plates, and the characterization fixtures, keep
their order unchanged.
The washer nest's plate 1 now plans Ready in about 44 s (was 54 s), with
86k expansions against 91k.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A lead check scanned every other part's material with native contact
queries. On the 5,742-washer plate that was about 80% of planning and
it never finished inside 120 s.
The earlier extent filter (reverted in ea1270e1) used a fixed 0.001 gap,
which native line/circle rounding can exceed for long leads beside small
circles. This skip adds 1e-6 times the span of both extents. The
discriminant's rounding is bounded by about 1e-7 times that span, and
about 2e-9 is seen. So a skipped material has no native contact, and the
900000-long lead beside a small circle is still checked. Each skipped
scan is charged to the native query budget as if it ran. Ray parity is
still asked natively unless the lead's midpoint is outside the
material's Y range. The pierce zone skips only material farther than its
radius by the same gap.
A randomized test checks that skipped material never has a native
contact. It fails with the span allowance at zero and passes with it as
low as 1e-8. Plate 1 of the washer nest now plans Ready in about 54 s.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With no lead-out the tool leaves a hole where it entered it. A tiny corner
arc's midpoint lies on both facing sides of its hole, so the ranker scored it
as an ideal two-side corner, but the tool leaves it along its 45-degree
tangent: a shallow rapid to a nearby next hole re-entered the corner and
crossed the hole just cut. Every outside endpoint's preferred hole chain
then failed the same way, and the reorder search spent its budget on full
backtracking. A 31-part plate of such parts needed 31,959 expansions
against a default budget of 20,000.
Hole entries whose straight rapid to the next pierce clears the hole itself
now rank first, in the preferred chain and in the full search. This is a
stable reorder only: no entry is dropped, and every emitted rapid is still
checked. That plate now plans Ready on its first preferred pass, using 7,781
expansions; the budget is unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PEP-converted incremental programs round every move, so a long contour
can end 1-1.4e-6 off its start. Material capture refused it as open
("blocked: unsupported geometry"), and a gap right at the 1e-6 boundary
could pass material capture yet fail preparation.
On the planner's owned clean copy only, close incremental contours whose
gap exceeds 1e-8 but stays within what their rounded moves could
accumulate (capped at Tolerance.Epsilon); the next motion absorbs the
correction so nothing later moves. Absolute programs, larger gaps and
the drawing itself are untouched.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Pinned-lead and locked-lead warnings named a Drawing Pins Off command and a
Clear Lead-ins command that the desktop does not have; name Plate > Remove
Lead-ins and spacing instead. Closing Plan Cutting no longer claims nothing
changed after lead-ins or cut-offs were cleared, the no-stock reason no
longer says the part is larger than every sheet when only the usable area at
the checked rotations is too small, and the console says whole-job engines.