# 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.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/` holds starter acceptance tests. Every layout is checked by the benchmark's own `NestValidator` (bounds, spacing, quantities, stock, rotation), so a passing test means the benchmark will accept the layout. They fail until `Solve()` is implemented. Keep them and add engine-specific tests next to them. ```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.Benchmark/OpenNest.Benchmark.csproj -c Release mkdir -p /OpenNest.Benchmark/bin/Release/net8.0/Engines cp OpenNest.Engine.__NAME__/bin/Release/net8.0/OpenNest.Engine.__NAME__.dll /OpenNest.Benchmark/bin/Release/net8.0/Engines/ dotnet /OpenNest.Benchmark/bin/Release/net8.0/OpenNest.Benchmark.dll --parallel 1 ``` `` 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.