diff --git a/AGENTS.md b/AGENTS.md index 6eb6bce1..55daf12c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -37,7 +37,7 @@ Releases: follow [the release procedure](docs/releasing.md) and `scripts/Publish - `OpenNest.Core`: domain (`Nest -> Plate -> Part -> Drawing -> CNC.Program`), geometry, cutting strategies and diagnostics. Angles are radians; use `Tolerance.Epsilon` for geometry comparisons. `OpenNest.Math` shadows `System.Math`, so qualify the latter. - `OpenNest.Engine`: whole-job API in `Jobs/`, interactive proposals via `PlateFillService`, fill strategies, best-fit pairs, packing, sequencing and rapid planning. `INestingEngine.Solve(NestJob)` returns stock IDs/poses; boundary adapters map drawings and materialize results. `NestJobRunner` validates its candidates before committing demand/stock accounting. Do not assume arbitrary plug-in output or interactive paths received that validation. Job identity is reference-based, not drawing-name-based. - Built-in whole-job engines live in `OpenNest.Engine/NestingEngines//`, named for the jobs they suit; see [nesting engines](docs/nesting-engines.md). A change must beat that engine's current benchmark result with every layout valid. External plug-ins implement `INestingEngine` with a public parameterless constructor and load from `Engines/` beside the host; keep their projects out of this solution. -- `OpenNest.IO`: ACadSharp import/export and ZIP-based `.nest` persistence. All DXF-to-Drawing conversion goes through `CadImporter`: `Import` + `BuildDrawing` for editable/reporting flows, `ImportDrawing` for headless callers. Preserve source offsets, entity IDs, suppressed entities and bends. Bend repair is opt-in, requires explicit source units and may not alter cut geometry or unrelated marks. +- `OpenNest.IO`: ACadSharp import/export and ZIP-based `.nest` persistence; depends on Core only (an IO.Tests guard enforces it). Best fits persist only when callers pass `BestFitCacheStore.Shared` as `NestReader`/`NestWriter.BestFitStore`. All DXF-to-Drawing conversion goes through `CadImporter`: `Import` + `BuildDrawing` for editable/reporting flows, `ImportDrawing` for headless callers. Preserve source offsets, entity IDs, suppressed entities and bends. Bend repair is opt-in, requires explicit source units and may not alter cut geometry or unrelated marks. - `OpenNest`: WinForms UI (`Forms/`, `Controls/PlateView`, `Actions/`). `OpenNest.Data` holds cross-platform persistence; new-nest defaults live in `%APPDATA%\OpenNest\defaults.json`. Posts live in `Posts/OpenNest.Posts./` and deploy to the desktop output's `Posts/` directory. - `OpenNest.Console`, `OpenNest.Mcp`, `OpenNest.Api`: front ends; `OpenNest.Benchmark`: whole-job engine comparisons; `OpenNest.Gpu`: GPU evaluators; `OpenNest.Training`: ML data collection. Benchmark timing comparisons require `--parallel 1`; validate layouts and fulfillment, not just elapsed time. diff --git a/docs/nest-file-format.md b/docs/nest-file-format.md index d7a5bb13..0682fbef 100644 --- a/docs/nest-file-format.md +++ b/docs/nest-file-format.md @@ -125,6 +125,26 @@ 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. +## Saved best-fit pairs (cache only) + +Optional `bestfits/bestfit-N` entries hold drawing N's cached best-fit pair +results: a JSON array of sets, each with `plateWidth`, `plateHeight` and +`spacing` (the plate size and part spacing it was filtered for) and `results`. +Each result has `part1Rotation`, `part2Rotation`, `part2OffsetX`, +`part2OffsetY`, `strategyType`, `testNumber`, `candidateSpacing`, +`rotatedArea`, `boundingWidth`, `boundingHeight`, `optimalRotation`, `keep`, +`reason`, `trueArea` and `hullAngles`. Angles are radians; pair geometry is in +the drawing's canonical frame. + +The entries are only a cache: readers may ignore them and writers may omit +them, at the cost of recomputing pairs. Writers save only sets whose +(width, length, spacing) matches a plate in the nest, and only kept results; a +drawing without such a set gets no entry. `NestReader` and `NestWriter` touch +these entries only when given an `IBestFitStore` through `BestFitStore`; +without one, a reader skips them unparsed and a writer writes none. The front +ends pass the engine's `BestFitCacheStore.Shared`, which adds loaded sets to +the process-wide `BestFitCache` without replacing sets already computed. + ## Verification and limits The automated tests cover save/reopen/re-save, rotated/manual/locked parts,