Files
OpenNest-Engines/_Template/README.md
T
33cc2ee810 docs(engines): template on shared services and a determinism rule
New engines start from the shared test kit (the template's tests are a
one-line EngineContractTests subclass) and the host APIs, so they don't
re-derive geometry reading, work areas or validator tolerances.
BENCH-RULES.md now forbids clocks, unseeded randomness and environment
variables from influencing placement (budgets count work; wall time only
through the host's cancellation token) and lists the kit as read-only.
Build-Engines.ps1 deploys only OpenNest.Engine.* folders, and
New-Engine.ps1 -IncludeBuildFiles copies the kit.

Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 09:29:28 -04:00

82 lines
4.3 KiB
Markdown

# OpenNest.Engine.__NAME__
An independent `INestingEngine` implementation. It must not be a wrapper, ensemble, or
selector over OpenNest's built-in engines. `Solve()` must not call, instantiate, or
delegate to any existing `INestingEngine` (`StockLadderNestingEngine`,
`FixedStrategyNestingEngine`), `NestingEngineRegistry`, `NestJobRunner`, or the whole-plate
nesters/fillers behind `PlateNesterFactory` (`DefaultPlateNester`, `StripPlateNester`,
`RemnantPlateNester`, `PlateFillService`, `DefaultPlateFiller`, ...). It must also never run
several of them and keep the best result.
The decisions that make it an engine must be yours: which sheet(s) to use, which parts go
where and in what order, which pattern/strategy to apply to which region, and when to stop.
**Read `BENCH-RULES.md` before starting.** It covers your workspace, version control, the
real-part drawing archive, tests and your final report.
## Allowed building blocks
Reuse is encouraged. These are tools you drive, composed by your own decision logic:
- `OpenNest.Engine.Jobs`: `JobPartGeometry`, stock `WorkArea`/`Area`/`Fits`,
`RotationPolicy.EnumerateAngles`, `RotationCandidates`, `NestJobCost`, `NestTolerances`,
`NestLayoutCheck`, and `NestJobResultBuilder`. These prepare geometry, check and account
for decisions made by your algorithm; they do not choose placements.
- `OpenNest.Core` geometry: `Polygon`, `Shape`, `BoundingBox`, `Vector`, `Box`, `ConvexHull`,
`ConvexDecomposition`, `RotatingCalipers`, `Collision`, `NoFitPolygon`, `ShapeProfile`,
`SpatialQuery`.
- Fill and pattern components in `OpenNest.Engine.Fill`: `FillLinear`, `FillExtents`,
`PairFiller`, `ShrinkFiller`, `RemnantFiller`/`RemnantFinder`, `Compactor`, `FillScore`,
`Pattern`/`PatternTiler`, `PartBoundary`, `RotationAnalysis`, `AngleCandidateBuilder`,
`BestCombination`.
- `OpenNest.Engine.BestFit` (`BestFitFinder`, `PairEvaluator`, ...), `RectanglePacking`,
`CirclePacking`.
If you find a faster or better way to do something a shared component already does (for
example linear patterning), implement it inside this engine's own project and leave the
shared code untouched. Do not edit `OpenNest.Core`, `OpenNest.Engine`, or
`OpenNest.Benchmark`. Call it out in your report (what it replaces, why it is better,
measured numbers) so it can be generalized and upstreamed for every engine later.
## What to fill in
- `__NAME__NestingEngine.cs` — implement `Solve()`. Pick and document an actual placement
strategy (NFP-based sliding placement, skyline/shelf packer, simulated-annealing/genetic
layout search, guillotine-cut packer, physics/gravity-settling, etc). It's fine to be
simpler or worse than the built-in engines to start; it must not be the same algorithm
re-derived through indirection.
- This README — replace this section with a description of the algorithm, its trade-offs,
and benchmark results.
## Tests
`tests/` references the read-only `../Engine.Testing` kit and subclasses
`EngineContractTests<TEngine>`. `LayoutAssert.Valid` uses `NestLayoutCheck.Violations`,
the benchmark's shared validation primitive, plus strict bounds and accounting checks.
The acceptance tests fail until `Solve()` is implemented. Keep them and add engine-specific
tests next to them. No clocks, unseeded randomness or environment variables may influence
placement; count work for budgets and honor the host cancellation token for wall time.
```bash
dotnet test OpenNest.Engine.__NAME__/tests/OpenNest.Engine.__NAME__.Tests.csproj
```
## Build and benchmark
The project is a plugin outside `OpenNest.sln`. `OpenNest.Benchmark` loads plugin engines
from an `Engines/` folder next to its own build output:
```bash
dotnet build OpenNest.Engine.__NAME__/OpenNest.Engine.__NAME__.csproj -c Release
dotnet build <OpenNest>/OpenNest.Benchmark/OpenNest.Benchmark.csproj -c Release
mkdir -p <OpenNest>/OpenNest.Benchmark/bin/Release/net8.0/Engines
cp OpenNest.Engine.__NAME__/bin/Release/net8.0/OpenNest.Engine.__NAME__.dll <OpenNest>/OpenNest.Benchmark/bin/Release/net8.0/Engines/
dotnet <OpenNest>/OpenNest.Benchmark/bin/Release/net8.0/OpenNest.Benchmark.dll <path-to-.nest-or-folder> --parallel 1
```
`<OpenNest>` is the OpenNest checkout root. Your engine shows up in the report under its
CLR type name (`__NAME__NestingEngine`), competing on equal footing against the built-in
engines.