diff --git a/OpenNest.Engine.Qwen/OpenNest.Engine.Qwen.csproj b/OpenNest.Engine.Qwen/OpenNest.Engine.Qwen.csproj
new file mode 100644
index 0000000..bb15a22
--- /dev/null
+++ b/OpenNest.Engine.Qwen/OpenNest.Engine.Qwen.csproj
@@ -0,0 +1,13 @@
+
+
+ net8.0
+ OpenNest.Engine.Qwen
+ OpenNest.Engine.Qwen
+ enable
+ enable
+
+
+
+
+
+
diff --git a/OpenNest.Engine.Qwen/QwenNestingEngine.cs b/OpenNest.Engine.Qwen/QwenNestingEngine.cs
new file mode 100644
index 0000000..a3ed1b4
--- /dev/null
+++ b/OpenNest.Engine.Qwen/QwenNestingEngine.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Threading;
+using OpenNest.Engine.Jobs;
+
+namespace OpenNest.Engine.Qwen;
+
+///
+/// TODO: name and describe the actual placement strategy here (e.g. "skyline packer with
+/// greedy shelf assignment", "NFP-based sliding placement with simulated-annealing order
+/// search", etc). This must be an independently designed algorithm — see README.md.
+///
+public sealed class QwenNestingEngine : INestingEngine
+{
+ public NestJobResult Solve(
+ NestJob job,
+ IProgress? progress = null,
+ CancellationToken token = default
+ )
+ {
+ ArgumentNullException.ThrowIfNull(job);
+
+ // TODO: implement independent placement logic here.
+ //
+ // Do NOT call NestingEngineRegistry.Create(...), PlateNesterFactory, or any
+ // FixedStrategyNestingEngine / StockLadderNestingEngine instance from inside this
+ // method. Decide placements yourself using OpenNest.Core / OpenNest.Geometry
+ // primitives (Polygon, NoFitPolygon, Collision, ConvexHull, RotatingCalipers, etc).
+ //
+ // job.Parts -> requested parts (PartGeometrySnapshot geometry, quantity, priority, rotation policy)
+ // job.Plates -> candidate stock sheets (size, spacing, quadrant, quantity)
+ // job.Options -> job-wide options
+ //
+ // Return a NestJobResult built from NestJobPlateResult (one per used sheet, holding
+ // ordered NestJobPlacement values), PartFulfillment (requested vs placed per part id),
+ // and StockUsage (sheets used per stock id).
+
+ throw new NotImplementedException(
+ "Qwen nesting engine placement logic not yet implemented."
+ );
+ }
+}
diff --git a/OpenNest.Engine.Qwen/README.md b/OpenNest.Engine.Qwen/README.md
new file mode 100644
index 0000000..9c401d5
--- /dev/null
+++ b/OpenNest.Engine.Qwen/README.md
@@ -0,0 +1,57 @@
+# OpenNest.Engine.Qwen
+
+An independent `INestingEngine` implementation — **not** a wrapper, ensemble, or
+selector over OpenNest's built-in engines (`StockLadderNestingEngine`,
+`FixedStrategyNestingEngine` "Default"/"Strip"/"Vertical Remnant"/"Horizontal Remnant`,
+or anything reachable through `PlateNesterFactory`/`NestingEngineRegistry`).
+`Solve()` must never call, instantiate, or otherwise delegate a placement decision
+to one of those.
+
+## Allowed building blocks
+
+Low-level geometry/data-structure primitives are fair game — they are not nesting
+strategies:
+
+- `OpenNest.Core` geometry: `Polygon`, `Shape`, `BoundingBox`, `Vector`, `Box`,
+ `ConvexHull`, `ConvexDecomposition`, `RotatingCalipers`, `Collision` (overlap/spacing
+ checks), `NoFitPolygon`, `ShapeProfile`, `SpatialQuery`.
+- `OpenNest.Engine` support types if useful: `PartBoundary`, `RotationAnalysis`,
+ `AngleCandidateBuilder` — the *decision logic* using them must be your own (don't just
+ call `BestFitFinder`/`PairEvaluator`/`RotationSlideStrategy`, which are the existing
+ best-fit engine's internals).
+
+## What to fill in
+
+`QwenNestingEngine.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.
+
+## Build
+
+```bash
+dotnet build OpenNest.Engine.Qwen/OpenNest.Engine.Qwen.csproj
+```
+
+This project is intentionally **outside** `OpenNest.sln` (same pattern as the
+`OpenNest.Engine.Aurora` plugin) — it's discovered at runtime as a plugin, not built
+as part of the main solution.
+
+## Try it out with the benchmark
+
+`OpenNest.Benchmark` auto-loads plugin engines from an `Engines/` folder next to its
+own build output:
+
+```bash
+dotnet build OpenNest.Engine.Qwen/OpenNest.Engine.Qwen.csproj -c Release
+dotnet build OpenNest.Benchmark/OpenNest.Benchmark.csproj -c Release
+
+mkdir -p OpenNest.Benchmark/bin/Release/net8.0/Engines
+cp OpenNest.Engine.Qwen/bin/Release/net8.0/OpenNest.Engine.Qwen.dll OpenNest.Benchmark/bin/Release/net8.0/Engines/
+
+dotnet OpenNest.Benchmark/bin/Release/net8.0/OpenNest.Benchmark.dll
+```
+
+Your engine will show up in the report under its CLR type name (`QwenNestingEngine`),
+competing on equal footing against the built-in engines.
diff --git a/OpenNest.Engine.Qwen/tests/OpenNest.Engine.Qwen.Tests.csproj b/OpenNest.Engine.Qwen/tests/OpenNest.Engine.Qwen.Tests.csproj
new file mode 100644
index 0000000..e3f0be9
--- /dev/null
+++ b/OpenNest.Engine.Qwen/tests/OpenNest.Engine.Qwen.Tests.csproj
@@ -0,0 +1,19 @@
+
+
+ net8.0
+ enable
+ enable
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OpenNest.Engine.Qwen/tests/QwenNestingEngineTests.cs b/OpenNest.Engine.Qwen/tests/QwenNestingEngineTests.cs
new file mode 100644
index 0000000..4043aee
--- /dev/null
+++ b/OpenNest.Engine.Qwen/tests/QwenNestingEngineTests.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using OpenNest.Engine.Jobs;
+using OpenNest.Geometry;
+
+namespace OpenNest.Engine.Qwen.Tests;
+
+public class QwenNestingEngineTests
+{
+ [Fact]
+ public void SolveReturnsAResultForASingleSimplePart()
+ {
+ // TODO: replace with a real fixture once Solve() is implemented — this only
+ // proves the plumbing (project reference, constructor, interface) is wired up.
+ var engine = new QwenNestingEngine();
+
+ Assert.NotNull(engine);
+ Assert.IsAssignableFrom(engine);
+ }
+}
diff --git a/OpenNest.Engine.Sonnet5/OpenNest.Engine.Sonnet5.csproj b/OpenNest.Engine.Sonnet5/OpenNest.Engine.Sonnet5.csproj
new file mode 100644
index 0000000..0ffbe7b
--- /dev/null
+++ b/OpenNest.Engine.Sonnet5/OpenNest.Engine.Sonnet5.csproj
@@ -0,0 +1,13 @@
+
+
+ net8.0
+ OpenNest.Engine.Sonnet5
+ OpenNest.Engine.Sonnet5
+ enable
+ enable
+
+
+
+
+
+
diff --git a/OpenNest.Engine.Sonnet5/README.md b/OpenNest.Engine.Sonnet5/README.md
new file mode 100644
index 0000000..ba2ffbb
--- /dev/null
+++ b/OpenNest.Engine.Sonnet5/README.md
@@ -0,0 +1,57 @@
+# OpenNest.Engine.Sonnet5
+
+An independent `INestingEngine` implementation — **not** a wrapper, ensemble, or
+selector over OpenNest's built-in engines (`StockLadderNestingEngine`,
+`FixedStrategyNestingEngine` "Default"/"Strip"/"Vertical Remnant"/"Horizontal Remnant`,
+or anything reachable through `PlateNesterFactory`/`NestingEngineRegistry`).
+`Solve()` must never call, instantiate, or otherwise delegate a placement decision
+to one of those.
+
+## Allowed building blocks
+
+Low-level geometry/data-structure primitives are fair game — they are not nesting
+strategies:
+
+- `OpenNest.Core` geometry: `Polygon`, `Shape`, `BoundingBox`, `Vector`, `Box`,
+ `ConvexHull`, `ConvexDecomposition`, `RotatingCalipers`, `Collision` (overlap/spacing
+ checks), `NoFitPolygon`, `ShapeProfile`, `SpatialQuery`.
+- `OpenNest.Engine` support types if useful: `PartBoundary`, `RotationAnalysis`,
+ `AngleCandidateBuilder` — the *decision logic* using them must be your own (don't just
+ call `BestFitFinder`/`PairEvaluator`/`RotationSlideStrategy`, which are the existing
+ best-fit engine's internals).
+
+## What to fill in
+
+`Sonnet5NestingEngine.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.
+
+## Build
+
+```bash
+dotnet build OpenNest.Engine.Sonnet5/OpenNest.Engine.Sonnet5.csproj
+```
+
+This project is intentionally **outside** `OpenNest.sln` (same pattern as the
+`OpenNest.Engine.Aurora` plugin) — it's discovered at runtime as a plugin, not built
+as part of the main solution.
+
+## Try it out with the benchmark
+
+`OpenNest.Benchmark` auto-loads plugin engines from an `Engines/` folder next to its
+own build output:
+
+```bash
+dotnet build OpenNest.Engine.Sonnet5/OpenNest.Engine.Sonnet5.csproj -c Release
+dotnet build OpenNest.Benchmark/OpenNest.Benchmark.csproj -c Release
+
+mkdir -p OpenNest.Benchmark/bin/Release/net8.0/Engines
+cp OpenNest.Engine.Sonnet5/bin/Release/net8.0/OpenNest.Engine.Sonnet5.dll OpenNest.Benchmark/bin/Release/net8.0/Engines/
+
+dotnet OpenNest.Benchmark/bin/Release/net8.0/OpenNest.Benchmark.dll
+```
+
+Your engine will show up in the report under its CLR type name (`Sonnet5NestingEngine`),
+competing on equal footing against the built-in engines.
diff --git a/OpenNest.Engine.Sonnet5/Sonnet5NestingEngine.cs b/OpenNest.Engine.Sonnet5/Sonnet5NestingEngine.cs
new file mode 100644
index 0000000..c0958be
--- /dev/null
+++ b/OpenNest.Engine.Sonnet5/Sonnet5NestingEngine.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Threading;
+using OpenNest.Engine.Jobs;
+
+namespace OpenNest.Engine.Sonnet5;
+
+///
+/// TODO: name and describe the actual placement strategy here (e.g. "skyline packer with
+/// greedy shelf assignment", "NFP-based sliding placement with simulated-annealing order
+/// search", etc). This must be an independently designed algorithm — see README.md.
+///
+public sealed class Sonnet5NestingEngine : INestingEngine
+{
+ public NestJobResult Solve(
+ NestJob job,
+ IProgress? progress = null,
+ CancellationToken token = default
+ )
+ {
+ ArgumentNullException.ThrowIfNull(job);
+
+ // TODO: implement independent placement logic here.
+ //
+ // Do NOT call NestingEngineRegistry.Create(...), PlateNesterFactory, or any
+ // FixedStrategyNestingEngine / StockLadderNestingEngine instance from inside this
+ // method. Decide placements yourself using OpenNest.Core / OpenNest.Geometry
+ // primitives (Polygon, NoFitPolygon, Collision, ConvexHull, RotatingCalipers, etc).
+ //
+ // job.Parts -> requested parts (PartGeometrySnapshot geometry, quantity, priority, rotation policy)
+ // job.Plates -> candidate stock sheets (size, spacing, quadrant, quantity)
+ // job.Options -> job-wide options
+ //
+ // Return a NestJobResult built from NestJobPlateResult (one per used sheet, holding
+ // ordered NestJobPlacement values), PartFulfillment (requested vs placed per part id),
+ // and StockUsage (sheets used per stock id).
+
+ throw new NotImplementedException(
+ "Sonnet5 nesting engine placement logic not yet implemented."
+ );
+ }
+}
diff --git a/OpenNest.Engine.Sonnet5/tests/OpenNest.Engine.Sonnet5.Tests.csproj b/OpenNest.Engine.Sonnet5/tests/OpenNest.Engine.Sonnet5.Tests.csproj
new file mode 100644
index 0000000..ee0d1ae
--- /dev/null
+++ b/OpenNest.Engine.Sonnet5/tests/OpenNest.Engine.Sonnet5.Tests.csproj
@@ -0,0 +1,19 @@
+
+
+ net8.0
+ enable
+ enable
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OpenNest.Engine.Sonnet5/tests/Sonnet5NestingEngineTests.cs b/OpenNest.Engine.Sonnet5/tests/Sonnet5NestingEngineTests.cs
new file mode 100644
index 0000000..158af80
--- /dev/null
+++ b/OpenNest.Engine.Sonnet5/tests/Sonnet5NestingEngineTests.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using OpenNest.Engine.Jobs;
+using OpenNest.Geometry;
+
+namespace OpenNest.Engine.Sonnet5.Tests;
+
+public class Sonnet5NestingEngineTests
+{
+ [Fact]
+ public void SolveReturnsAResultForASingleSimplePart()
+ {
+ // TODO: replace with a real fixture once Solve() is implemented — this only
+ // proves the plumbing (project reference, constructor, interface) is wired up.
+ var engine = new Sonnet5NestingEngine();
+
+ Assert.NotNull(engine);
+ Assert.IsAssignableFrom(engine);
+ }
+}
diff --git a/OpenNest.Engine.Terra/OpenNest.Engine.Terra.csproj b/OpenNest.Engine.Terra/OpenNest.Engine.Terra.csproj
new file mode 100644
index 0000000..0f958a2
--- /dev/null
+++ b/OpenNest.Engine.Terra/OpenNest.Engine.Terra.csproj
@@ -0,0 +1,13 @@
+
+
+ net8.0
+ OpenNest.Engine.Terra
+ OpenNest.Engine.Terra
+ enable
+ enable
+
+
+
+
+
+
diff --git a/OpenNest.Engine.Terra/README.md b/OpenNest.Engine.Terra/README.md
new file mode 100644
index 0000000..b8551ab
--- /dev/null
+++ b/OpenNest.Engine.Terra/README.md
@@ -0,0 +1,57 @@
+# OpenNest.Engine.Terra
+
+An independent `INestingEngine` implementation — **not** a wrapper, ensemble, or
+selector over OpenNest's built-in engines (`StockLadderNestingEngine`,
+`FixedStrategyNestingEngine` "Default"/"Strip"/"Vertical Remnant"/"Horizontal Remnant`,
+or anything reachable through `PlateNesterFactory`/`NestingEngineRegistry`).
+`Solve()` must never call, instantiate, or otherwise delegate a placement decision
+to one of those.
+
+## Allowed building blocks
+
+Low-level geometry/data-structure primitives are fair game — they are not nesting
+strategies:
+
+- `OpenNest.Core` geometry: `Polygon`, `Shape`, `BoundingBox`, `Vector`, `Box`,
+ `ConvexHull`, `ConvexDecomposition`, `RotatingCalipers`, `Collision` (overlap/spacing
+ checks), `NoFitPolygon`, `ShapeProfile`, `SpatialQuery`.
+- `OpenNest.Engine` support types if useful: `PartBoundary`, `RotationAnalysis`,
+ `AngleCandidateBuilder` — the *decision logic* using them must be your own (don't just
+ call `BestFitFinder`/`PairEvaluator`/`RotationSlideStrategy`, which are the existing
+ best-fit engine's internals).
+
+## What to fill in
+
+`TerraNestingEngine.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.
+
+## Build
+
+```bash
+dotnet build OpenNest.Engine.Terra/OpenNest.Engine.Terra.csproj
+```
+
+This project is intentionally **outside** `OpenNest.sln` (same pattern as the
+`OpenNest.Engine.Aurora` plugin) — it's discovered at runtime as a plugin, not built
+as part of the main solution.
+
+## Try it out with the benchmark
+
+`OpenNest.Benchmark` auto-loads plugin engines from an `Engines/` folder next to its
+own build output:
+
+```bash
+dotnet build OpenNest.Engine.Terra/OpenNest.Engine.Terra.csproj -c Release
+dotnet build OpenNest.Benchmark/OpenNest.Benchmark.csproj -c Release
+
+mkdir -p OpenNest.Benchmark/bin/Release/net8.0/Engines
+cp OpenNest.Engine.Terra/bin/Release/net8.0/OpenNest.Engine.Terra.dll OpenNest.Benchmark/bin/Release/net8.0/Engines/
+
+dotnet OpenNest.Benchmark/bin/Release/net8.0/OpenNest.Benchmark.dll
+```
+
+Your engine will show up in the report under its CLR type name (`TerraNestingEngine`),
+competing on equal footing against the built-in engines.
diff --git a/OpenNest.Engine.Terra/TerraNestingEngine.cs b/OpenNest.Engine.Terra/TerraNestingEngine.cs
new file mode 100644
index 0000000..897f3e1
--- /dev/null
+++ b/OpenNest.Engine.Terra/TerraNestingEngine.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Threading;
+using OpenNest.Engine.Jobs;
+
+namespace OpenNest.Engine.Terra;
+
+///
+/// TODO: name and describe the actual placement strategy here (e.g. "skyline packer with
+/// greedy shelf assignment", "NFP-based sliding placement with simulated-annealing order
+/// search", etc). This must be an independently designed algorithm — see README.md.
+///
+public sealed class TerraNestingEngine : INestingEngine
+{
+ public NestJobResult Solve(
+ NestJob job,
+ IProgress? progress = null,
+ CancellationToken token = default
+ )
+ {
+ ArgumentNullException.ThrowIfNull(job);
+
+ // TODO: implement independent placement logic here.
+ //
+ // Do NOT call NestingEngineRegistry.Create(...), PlateNesterFactory, or any
+ // FixedStrategyNestingEngine / StockLadderNestingEngine instance from inside this
+ // method. Decide placements yourself using OpenNest.Core / OpenNest.Geometry
+ // primitives (Polygon, NoFitPolygon, Collision, ConvexHull, RotatingCalipers, etc).
+ //
+ // job.Parts -> requested parts (PartGeometrySnapshot geometry, quantity, priority, rotation policy)
+ // job.Plates -> candidate stock sheets (size, spacing, quadrant, quantity)
+ // job.Options -> job-wide options
+ //
+ // Return a NestJobResult built from NestJobPlateResult (one per used sheet, holding
+ // ordered NestJobPlacement values), PartFulfillment (requested vs placed per part id),
+ // and StockUsage (sheets used per stock id).
+
+ throw new NotImplementedException(
+ "Terra nesting engine placement logic not yet implemented."
+ );
+ }
+}
diff --git a/OpenNest.Engine.Terra/tests/OpenNest.Engine.Terra.Tests.csproj b/OpenNest.Engine.Terra/tests/OpenNest.Engine.Terra.Tests.csproj
new file mode 100644
index 0000000..6f9ab72
--- /dev/null
+++ b/OpenNest.Engine.Terra/tests/OpenNest.Engine.Terra.Tests.csproj
@@ -0,0 +1,19 @@
+
+
+ net8.0
+ enable
+ enable
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OpenNest.Engine.Terra/tests/TerraNestingEngineTests.cs b/OpenNest.Engine.Terra/tests/TerraNestingEngineTests.cs
new file mode 100644
index 0000000..c917b9d
--- /dev/null
+++ b/OpenNest.Engine.Terra/tests/TerraNestingEngineTests.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using OpenNest.Engine.Jobs;
+using OpenNest.Geometry;
+
+namespace OpenNest.Engine.Terra.Tests;
+
+public class TerraNestingEngineTests
+{
+ [Fact]
+ public void SolveReturnsAResultForASingleSimplePart()
+ {
+ // TODO: replace with a real fixture once Solve() is implemented — this only
+ // proves the plumbing (project reference, constructor, interface) is wired up.
+ var engine = new TerraNestingEngine();
+
+ Assert.NotNull(engine);
+ Assert.IsAssignableFrom(engine);
+ }
+}