This commit is contained in:
aj committed 2026-10-10 12:38:50 -04:00
commit ef6ca80e6d
38 files changed
+2896 -186

No files matched your search

+2
View File
@@ -36,6 +36,8 @@ For a 120-by-81-inch sheet whose parts extend through 80 inches, the nominal ske
## Part sequencing
For **Plate > Sequence Parts > Manual Sequence**, choose the one-based sequence number and hover a part on the sheet; only the part under the pointer is outlined. Click it to place it at that exact position, then the number advances up to the last part. Clicking empty sheet space changes nothing. Use **Done**, the window close button, right-click on the sheet, or Escape to leave the tool. Manual reordering changes neither geometry nor quantities.
After adding cutoffs, apply **Part Sequencing** to the current plate or all plates. Each cutoff is moved earlier as needed so it is cut before every part its nominal line passes through. Ordinary parts retain their relative order from the chosen sequencing route; a tail separator that crosses no parts keeps its normal route position rather than being forced to the front. Cutoff geometry, clearance, part programs, placements, and quantities are unchanged.
The dependency check uses the nominal horizontal/vertical line and its start/end limits, not the trimmed cutting segments, which intentionally skip the parts. It conservatively checks placed part bounds (including edge contacts), so a cutoff through a concave recess can also move ahead of that part. Definitions are matched by drawing identity, not their displayed names. A cutoff part with no matching definition is conservatively ordered before all ordinary parts.
+38 -7
View File
@@ -146,11 +146,24 @@ other curve already touches, while a contact anywhere else on the line still ref
Source parts rank by modeled travel (material-centre distance at a holed-part
boundary); within a part, preferred contour order and facing-entry rank precede
travel. Ties use stable source/contour/entry ordinals. Hash values and drawing names are not tie breakers. The expansion budget
counts rejected candidates and frontier ranking as well as accepted moves, before
emission; it is not a wall-clock timeout. Callers can cancel. Exhaustion may occur
before already-generated siblings are traversed; it returns a refusal, not an
unranked fallback or a proof of geometric impossibility.
travel. Ties use stable source/contour/entry ordinals. Hash values and drawing names
are not tie breakers.
When the next whole part is fixed by the tour or a part is already active, the
search generates and checks contour alternatives on demand in contour/entry rank
order. It does not emit every sibling before trying the first. Backtracking still
visits the remaining alternatives when needed; none is pruned. The free whole-part
fallback still evaluates all ready sources before ranking their travel distances.
The expansion budget counts evaluated candidates and frontier ranking, including
rejections, before emission; it is not a wall-clock timeout. An unvisited sibling
consumes no additional DFS-prefix emission work or per-sibling expansion charge;
entry-catalogue prechecks still emit isolated contours and consume budget.
Consequently a bounded search can
reach a different frontier and report different rejected approaches than eager
expansion did. All visited candidates retain their lead/rapid checks, and a selected
plan still receives fresh independent replay. Callers can cancel. Exhaustion returns
a refusal, not an unranked fallback or proof of geometric impossibility.
## Automatic outside entries and look-ahead
@@ -306,6 +319,14 @@ plans every plate that has parts. Both open one dialog built on
obstruct it, spacing the parts farther apart. These are suggestions, not guaranteed
fixes: replanning runs the same strict checks; an unverified fallback requires
separate warning acceptance and is not approval to post or cut.
- The desktop free-order batch first tries up to eight entries per contour for at most
1,000 expansions. Only a Ready proposal that passes independent replay is used;
otherwise it runs the original 16-entry search with its entire plate budget.
Cancellation stops both attempts. This short pass can choose a different valid
route, and a hard plate can take up to 1,000 extra expansions before the full
attempt. The current-order retry still uses its original 16-entry budget.
Returned expansion counts describe the retained attempt, not a discarded
short pass plus its full-cap retry.
- Every plate is captured on the UI thread and checked and planned on a worker. Clean part
material is checked for overlaps with the pre-post overlap analyzer; known overlapping parts
still block that plate whatever its route. Incomplete checks remain visible warnings, never
@@ -313,9 +334,19 @@ plans every plate that has parts. Both open one dialog built on
`NoSolutionWithinBudget` is retried once with the current part order, and the summary
says the order was kept. Both are allowed 400 expansions per part (at least the
default 20000), because both still plan contour order and entries for every part.
- The dialog uses an owner-monitor-sized window (approximately 90% of the working area), like
the database browser. The right panel keeps the batch outcome and plate headings above a
read-only, unsorted warning grid with Plate, source Part, With, and full finding text. Every
overlap issue/pair and every planner finding has its own selectable row, including findings
hidden by the compact blocked-plate summary. Selecting a row switches to that plate's
detached preview and zooms to the affected part extent (or both parts for a pair), mapping
source positions to the proposed cutting order. This is not an exact contact marker: most
findings do not carry a geometric witness. If a plate cannot produce a current, supported
preview, no geometry is cloned or focused; the row still identifies its source part in the
editor. Replanning, cancellation and stale Apply clear old warning targets.
- The summary lists every plate: ready plates with part counts and rapid travel, others
with their status and findings. Unverified proposals show every overlap and route
warning in the scrollable summary before the acceptance checkbox is used; they do
with their status and findings. Unverified proposals retain every overlap and route
warning in the selectable grid before the acceptance checkbox is used; they do
not truncate later parts' warnings. Finding part numbers are the plate's current order, as the
editor numbers them. The preview shows the active plate detached from the nest (quantity
zero, so drawing quantities do not change) in the proposed order with the proposed
+4
View File
@@ -241,6 +241,10 @@ curl --fail http://<bind-address>:<port>/healthz # {"status":"ok"}
In the desktop app choose **File > Storage Mode...**, Database, and enter the base
URL `http://<bind-address>:<port>`, without `/healthz` or `/api/nests`.
To set or change just the saved server address without changing File/Database mode,
use **Tools > Options > Nest server URL > Set / Change Server**. This saves the URL
immediately, independently of the Options Save button; it does not migrate nests
or enable Database mode. Canceling Options afterward does not undo that address.
### Backup, restore, and upgrade
+37 -2
View File
@@ -70,8 +70,9 @@ remain separate sequencer/verification work.
## Filling cutouts (not yet in production)
Placing parts inside another part's enclosed cutout is being built as a step that runs before any
engine, so every engine benefits. Nothing calls it yet: a part inside a cutout must be cut before
the cutout's contour, and the sequencer does not enforce that order.
engine, so every engine benefits. Only an internal test-only pipeline preview calls it: a part
inside a cutout must be cut before the cutout's contour, and the cutting/post safety gates are
not complete. Ordinary whole-job calls do not enable this path.
`CutoutLatticeFill` (`OpenNest.Engine/Jobs/Cutouts/`) fills one closed cutout with copies of one
part. It runs Fill over the cutout's bounds plus one part step on every side, then shifts
@@ -83,6 +84,40 @@ layout check uses. The method suits many small copies in a large cutout; a few l
meant for no-fit-polygon placement. Fill can return different, equally scored lattices on repeated
calls for some parts, so results are not yet guaranteed identical between runs.
The internal `CutoutRouter` can propose copies from the shifted lattice, then search bounded
inner-fit/NFP sample points for remaining copies and other insert requirements. It keeps
original requirement IDs, reindexes accepted copies and checks clearance against the frame
and every previously accepted insert. Lattice shifts account for occupied poses before
quantity trimming; a pre-fill work limit declines giant grids and lets bounded NFP sampling
try instead. A null NFP proposal is not proof of geometric impossibility. No material-area
ratio cutoff rejects a possible placement: the measured 0.10 and 0.35 ratios guide
search order only. Below 0.10 it starts with Fill for three or more copies; between
0.10 and 0.35 it compares Fill-plus-NFP with NFP-only counts; above 0.35 it tries
NFP first, then Fill if demand remains, taking the higher-count valid proposal.
An 0.20 NFP-only rule would lose a second 4-inch square in a 10-inch round hole.
Six geometry-only, anonymized real-job probes and neutral ring fixtures informed
the search-order hints; these limited cases are not a global density guarantee.
The internal `NestPipeline.RunCutoutPreview` builds quantity-one proxy instances for eligible
closed-cutout frames. It considers legal frame rotations without outer-perimeter symmetry
reduction, shifts insert rotation policies into the local frame, and reserves certified router
poses by original requirement ID. It can fill multiple holes and repeated/different frame
requirements; inserts with a different priority or their own cutouts stay independent, so
bundles remain flat. It uses the largest offered spacing for every bundle because the current
job contract cannot condition insert demand on the stock selected later. Remaining demand is
offered to the selected engine once. Only actually placed proxies expand to original frame and
insert identities. An unplaced proxy's reservations return to the original unplaced demand;
they cannot be packed retroactively in that same solve. Engine indices and metadata are checked,
then every physical pose, stock, rotation, quantity and fulfillment is independently validated
before binding caller drawings. Incomplete, forged or geometrically invalid composites return
no bindable plates even with invalid-result consent. Candidate evaluation progress is forwarded
with unverified proxy commitment counts zeroed; transformed proxy commits are hidden. Physical
commits are reported only after physical validation. Preparation is bounded to 32 bundles
and 16 base sweep-angle samples per frame (automatic quarter-turns are all retained);
remaining copies stay ordinary requirements. Fixed legal proxy orientations are a
conservative search choice, not full engine choice among all legal orientations; unsupported
bundles remain ordinary independent requirements. This is an internal pipeline path, not a
production setting or cut-ready nest. Cutting/post safety remains pending before enablement.
## Renamed engines
The registry maps names used by earlier releases (the first two shipped as plug-ins) so saved
@@ -0,0 +1,26 @@
# Cutting-planner native curve reuse
The opt-in 144-part synthetic grid probe measures only `CuttingPlanService.Plan`, not build,
fixture creation, assertions, desktop rendering or posting:
```sh
OPENNEST_RUN_CUTTING_PERF=1 dotnet test OpenNest.Tests/OpenNest.Tests.csproj -c Release \
--filter 'FullyQualifiedName~ReorderSearchTests.DenseGrid144_PerformanceProbe' \
--logger 'console;verbosity=detailed'
```
Run separate fresh processes on the same machine with build and filesystem caches warm;
there is no in-process plan/JIT warmup, so these are first-call measurements. Compare
`Cutting144 elapsedMs`, `expansions`, `status` and `executionSha256`. The hash covers
expanded owned motions (including called hole programs), their layers, rapid flags,
exact coordinate bits, curve type and arc/circle parameters in source order; it does
not claim byte-identical authored G-code flags or post output. The test also requires
a Ready, independently replayed result and exact source-part conservation. Without
the environment flag it skips. Timing is diagnostic, not a deadline assertion.
The native curve wrapper now lazily owns one private native `Entity` for repeated
contact/containment queries. `ToEntity()` still makes a fresh object for other callers.
No lead or rapid check is skipped: long-lead/tiny-circle numerical contacts make a
fixed-extent material prefilter unsafe. Retest the cutting-planner and native-contact
regressions, especially near tangencies, repeated/concurrent queries and incomplete
material; do not infer posted NC or machine acceptance from this probe.