feat(posts): CI Fiber one program per sheet, configurable pallet change

Multi-sheet nests previously went into one program with a single header
size and one M50 at the end, so sheet 2 would cut into sheet 1's
skeleton. New Sheets settings:

- One program per sheet (default on): JOB.cnc -> JOB-1.cnc, JOB-2.cnc,
  each a full program with its own size and pallet change (CL-series
  batch rule, EM-423 7.4). Single-sheet nests keep the chosen name.
- Off: one program, with /L "L0" + pallet change between sheets;
  mixed sheet sizes are rejected.
- Pallet change code (default M50, unconfirmed for multi-sheet CI Fiber
  runs; documented as a release blocker).

All sheets are validated and rendered before any file is written.
IMultiFilePostProcessor lets the desktop app confirm overwrites of every
target file and list what was saved, and the console print each file.
This commit is contained in:
aj
2026-09-28 18:22:36 -04:00
parent 32586149c6
commit c219ec4e66
10 changed files with 520 additions and 51 deletions
+26 -12
View File
@@ -19,11 +19,13 @@ uses the Cincinnati machine-sample convention, not a generic TF5200 laser API:
`V.E.X_SIZE`, `V.E.Y_SIZE`, and `V.E.UNIT`. Sheet weight is omitted by default.
- Startup: `G90`, `L PROGRAMSTART.NC`, then `P3=V.E.R3`, `$GOTO NP3:`, and `N0:`.
- Parts follow plate order. `V.E.R4` identifies the part within its sheet;
numbered contour labels and `V.E.R3` continue across sheets for restart lookup.
numbered contour labels and `V.E.R3` count up through the program for restart
lookup (they restart at 1 in each per-sheet program).
- Each contour: `/L "L0"`, restart number, rapid to pierce, then interior
`/L "L2"` with `G41` or exterior `/L "L4"` with `G42`; linear lead-in,
`/L "L6"`, cutting moves, and `/L "ZHSOFF"`.
- Tail: `/L "L0"`, `L PROGRAMEND.NC`, `M50`, `M30`, and `%`.
- Tail: `/L "L0"`, `L PROGRAMEND.NC`, the pallet-change code (`M50`), `M30`,
and `%`.
- Motion endpoints are sheet-absolute XY. Arc `I`/`J` are offsets from the arc
start, matching the G162 convention; the post does not explicitly emit G162.
- Sheet cut-offs post after every part on their sheet. Each segment is an open
@@ -42,9 +44,9 @@ uses the Cincinnati machine-sample convention, not a generic TF5200 laser API:
See [CIFiberPostConfig](../Posts/OpenNest.Posts.CincinnatiCIFiber/CIFiberPostConfig.cs)
for macro names, material mappings, unit codes, precision, and table limits.
The post is named for the machine family; table size belongs in configuration.
In the desktop app these settings open in a sectioned editor (Machine, Material,
Program output, Macros) with a material-code table; values are validated and
saved only when OK is pressed.
In the desktop app these settings open in a sectioned editor (Machine, Sheets,
Material, Program output, Macros) with a material-code table; values are
validated and saved only when OK is pressed.
- Assign linear lead-ins before posting, including circular holes. The writer
rejects missing or arc-first lead-ins. Its conservative rule cites the G238
@@ -56,19 +58,31 @@ saved only when OK is pressed.
- `InchUnitCode` defaults to `1`; `MetricUnitCode` defaults to `0` but remains
unconfirmed. Table limits compare directly with nest dimensions, without unit
conversion. Do not assume changing the unit code establishes metric support.
- Multiple nonempty plates are written sequentially, but dimensional header
values come only from the first plate and the pallet-change tail occurs once.
This is not proof of a qualified multi-sheet machine cycle.
- Validation can throw after output has started. Discard any output from a failed
post; it may be incomplete. Successful generation and tests do not establish
- Plates without parts are not posted. With **One program per sheet** (the
default) and more than one sheet, `JOB.cnc` is written as `JOB-1.cnc`,
`JOB-2.cnc`, ..., each a complete program with its own sheet size and pallet
change. This follows the CL-series batch rule (EM-423 §7.4: one sheet per
program; the operator sets repeats). A single-sheet nest keeps the chosen name.
Plate quantity is not written; repeat the program at the machine.
- With the option off, every sheet goes into one program: `/L "L0"` and the pallet
change separate sheets, and the header carries the first sheet's size. Sheets
of different sizes are rejected in this mode. Posting to a stream always
produces one program, so it rejects a multi-sheet nest in per-sheet mode.
- **Release blocker:** `PalletChangeCode` defaults to `M50`, taken from the
single-sheet machine sample and the CL-series manual (EM-423 §3.50). Neither the
pallet code nor the between-sheet sequence has been confirmed for multi-sheet CI
Fiber runs. Confirm both against a Cincinnati multi-sheet sample before release.
- All programs are generated and every sheet is validated before any file is
written, so a failed file post writes nothing. A failed stream post may leave
partial output; discard it. Successful generation and tests do not establish
that a program is safe to run on a particular machine.
## Verification
[Output-contract tests](../OpenNest.Tests/CincinnatiCIFiber/CIFiberPostProcessorTests.cs)
cover a square with a hole, coordinate transforms/formatting, lead-in rejection,
cut-off ordering and output,
table bounds, and suppression/scribe handling. Run:
cut-off ordering and output, table bounds, suppression/scribe handling, and
multi-sheet output in both modes. Run:
```sh
dotnet test OpenNest.Tests/OpenNest.Tests.csproj --filter FullyQualifiedName~CincinnatiCIFiber