feat(io): persist part cutting programs and plate parameters
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
# 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.
|
||||
|
||||
## 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.
|
||||
Reference in New Issue
Block a user