Files
OpenNest/docs/nest-file-format.md
T
aj ef2f9aa714 feat(core,io): persist nest status and made-by in nest files
Add NestStatus (Quote/ToBeCut/HasBeenCut) plus MadeBy on Nest, written as
additive camelCase nest.json fields with PascalCase enum strings matching
the units convention. Legacy files and unknown status values fall back to
Quote. The nest info dialog gains a Status dropdown and Made By box.
2026-09-29 16:21:17 -04:00

87 lines
5.1 KiB
Markdown

# Nest file format and saved cutting state
`.nest` is a ZIP archive with additive version-2 JSON metadata in `nest.json`.
Old files remain readable. Older applications ignore the new cutting-state fields;
opening and saving with an older application loses that state.
## Job metadata
`nest.json` carries the workflow fields shown in the nest info dialog:
`name`, `customer`, `dateCreated`, `dateLastModified`, `notes`, `material`,
`thickness`, plus `status` (`"Quote"`, `"ToBeCut"`, `"HasBeenCut"`) and `madeBy`.
Status and made-by are additive: files written before them load as Quote with an
empty maker, and an unrecognized status value likewise falls back to Quote.
## Programs and placements
- `programs/program-N` is drawing N's clean G-code program; optional
`programs/program-N-subs` contains its hole sub-programs.
- Each serialized plate has a one-based `id`. Its `parts` array excludes cut-offs;
each placement retains `drawingId`, `x`, `y`, and `rotation` (radians).
- A placement with `HasManualLeadIns` also writes `parts/plate-P/part-K`, and
`parts/plate-P/part-K-subs` when it has hole sub-programs. P is the serialized
plate ID; K is the zero-based index in that plate's serialized parts array.
Empty plates and cut-offs do not consume these part indices.
- The placement's `program` field references that ZIP entry. Its G-code is saved
in the already-rotated local part frame, with the placed origin at `(x, y)`.
Existing `:LEADIN`, `:LEADOUT`, and other layer tags, tab gaps, and G65 calls
are retained rather than regenerated by a cutting strategy during load.
Hole IDs may be negative: they are identifiers, not validity sentinels.
- `drawingHash` protects against restoring obsolete cutting paths after an
externally edited drawing. It is uppercase SHA-256 of UTF-8 text composed of
the main text's decimal UTF-16 character count, `:`, main text, and sub-program
text (empty when absent). The hash includes both drawing entries so changing a
hole alone invalidates the placed cutting program. Text is read without a BOM;
otherwise whitespace and line endings participate in the hash.
The reader constructs and places a clean part first, then installs its saved
program without rotating it again. The drawing reference remains authoritative
for Remove Lead-ins: removing them restores the clean drawing at the saved pose.
Successful restoration marks the part as carrying lead-ins and restores its
`leadInsLocked` flag. The per-part `CuttingParameters` reference remains null;
the saved program, not strategy regeneration, determines the cutting geometry.
Missing `program` references in legacy files load clean and silently, even when
old transient flags were true. A missing or mismatched drawing hash likewise
loads clean silently. A referenced but missing, unparseable, or motionless part
program, or an unresolved/empty hole sub-program, leaves that part clean and
unlocked without discarding the rest of the nest. `NestReader.Warnings` identifies
the plate, zero-based part index, and entry; File > Open displays these warnings.
The program reader is not a general G-code or geometric safety validator; the
saved cutting geometry is not validated against the drawing.
## Plate cutting parameters
Each plate's optional `cuttingParameters` stores the settings used by Assign
Lead-ins and Place Lead-in. Missing settings stay null, preserving the old default
selection behavior. `OpenNest.IO.CuttingParametersSerializer` owns the shared
cross-platform DTO mapping; the desktop settings serializer delegates to it so
existing saved settings keep their JSON contract. Settings are independent of
the saved part programs: restoring settings never regenerates those programs.
## Drawing edits
`DrawingProgramSnapshot` captures serialized main and hole-program text before
the converter is loaded. After an accepted edit, only parts referencing drawings
whose program text changed are rebuilt (lead-ins, tabs, and locks cleared); their
location and rotation remain unchanged. Reference identity, not editable names,
keys this comparison. The desktop invalidates the affected layout graphics.
Name, quantity, and color edits leave placed programs alone. The properties
editor previously called `LayoutPart.Update`, a color refresh, not `Part.Update`;
it now explicitly refreshes only the edited drawing's layout colors.
## Verification and limits
The automated tests cover save/reopen/re-save, rotated/manual/locked parts,
lead-outs and tab gaps, hole binding, clean removal, stale drawings, damaged
entries isolated from other parts, plate settings, and CI Fiber posting before
and after reload. Drawing-change decision logic runs on Linux; desktop rendering,
dialog values, and clicks require Windows acceptance.
Known separate issue: the cutting strategy currently labels contour cuts
`Display`. CI Fiber includes them, but GravographIS skips Display. Saving restores
the existing layers; this change does not alter the strategy or either post.
Future hardening: make numeric G-code serialization/parsing culture-invariant
as a coordinated compatibility change; do not change just one side. Program
content deduplication is optional and must not change per-part ownership.