refactor: rename Astra engine to Gpt6Astra

OpenAI reuses model codenames across generations (GPT-6 reused
GPT-5.6's Sol and Luna), so a bare codename like "Astra" can't
identify which model built the engine. Prefixing the model version
keeps engine names unambiguous as more runs are added. The CLR type
is now Gpt6AstraNestingEngine, so benchmark reports show the new name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
aj
2026-09-24 10:36:00 -04:00
co-authored by Claude Opus 5.5
parent 70ae0cc155
commit 755ea4d7f8
28 changed files with 63 additions and 63 deletions
@@ -2,7 +2,7 @@ using Clipper2Lib;
using OpenNest.Geometry;
using M = System.Math;
namespace OpenNest.Engine.Astra;
namespace OpenNest.Engine.Gpt6Astra;
/// <summary>Per-solve configuration-space cache, never a shared mutable geometry cache.</summary>
internal sealed class ContactGeometry
@@ -3,7 +3,7 @@ using OpenNest.Engine.Jobs;
using OpenNest.Geometry;
using M = System.Math;
namespace OpenNest.Engine.Astra;
namespace OpenNest.Engine.Gpt6Astra;
internal sealed record PackedShape(ShapeVariant Variant, double X, double Y);
internal sealed record SheetTrial(int StockIndex, int[] Counts, List<PackedShape> Shapes, double Area, double Span);
@@ -1,10 +1,10 @@
using OpenNest.Engine.Jobs;
using M = System.Math;
namespace OpenNest.Engine.Astra;
namespace OpenNest.Engine.Gpt6Astra;
/// <summary>Independent configuration-space contact packing with bounded stock-plan search.</summary>
public sealed class AstraNestingEngine : INestingEngine
public sealed class Gpt6AstraNestingEngine : INestingEngine
{
public NestJobResult Solve(NestJob job, IProgress<NestJobProgress>? progress = null,
CancellationToken token = default)
@@ -5,7 +5,7 @@ using OpenNest.Engine.Jobs.Adapters;
using OpenNest.Geometry;
using M = System.Math;
namespace OpenNest.Engine.Astra;
namespace OpenNest.Engine.Gpt6Astra;
internal sealed record PreparedPart(NestJobPart Requirement, double Area, ShapeVariant[] Variants);
@@ -1,11 +1,11 @@
# OpenNest.Engine.Astra
# OpenNest.Engine.Gpt6Astra
An independent, deterministic .NET 8 CNC nesting plugin. Its public parameterless
`AstraNestingEngine` implements `INestingEngine`. The project remains outside `OpenNest.sln`.
`Gpt6AstraNestingEngine` implements `INestingEngine`. The project remains outside `OpenNest.sln`.
## Placement algorithm
Astra searches configuration space: for each stationary/moving orientation pair, a no-fit
Gpt6Astra searches configuration space: for each stationary/moving orientation pair, a no-fit
polygon describes the translations that would overlap. Subtracting these regions from the
sheet's usable translation rectangle exposes contact positions where another part can fit.
This permits overlapping bounding rectangles, complementary triangle pairs, staggered circles,
@@ -46,9 +46,9 @@ concave interlocking, and insertion into straight-edged and curved holes.
and the contract's job-level stop reason. Cancellation throws without returning a partial job.
The engine never invokes another engine, registry, job runner, whole-plate nester or filler.
All order, stock, orientation, placement, search and stopping decisions belong to Astra.
All order, stock, orientation, placement, search and stopping decisions belong to Gpt6Astra.
Core geometry and Clipper are primitives, not alternative nesters. A shared Core collision fix
corrects curved-hole validation; the placement algorithm remains entirely in Astra.
corrects curved-hole validation; the placement algorithm remains entirely in Gpt6Astra.
## Precision and safety
@@ -70,7 +70,7 @@ is exercised separately through the benchmark's materialized geometry validator
## Structure
- `AstraNestingEngine.cs`: bounded stock-plan search, accounting, progress and result construction.
- `Gpt6AstraNestingEngine.cs`: bounded stock-plan search, accounting, progress and result construction.
- `PreparedGeometry.cs`: snapshots, allowed orientations, symmetry reduction and material regions.
- `ContactGeometry.cs`: cached no-fit polygons and rectangle specialization.
- `ContactPlacer.cs`: incremental available regions, contact/inside-hole search and collision checks.
@@ -78,22 +78,22 @@ is exercised separately through the benchmark's materialized geometry validator
- `benchmarks/`: standalone synthetic benchmark driver, reproducible repository-DXF manifests,
baseline/current CSV results and comparison notes. It is not compiled into the plugin.
`OpenNest.Engine.Astra.csproj` references Core explicitly and inherits Engine/net8.0 settings from
`OpenNest.Engine.Gpt6Astra.csproj` references Core explicitly and inherits Engine/net8.0 settings from
`../Directory.Build.props`. Test and benchmark sources are excluded from the plugin assembly.
## Build, test and deploy
```bash
dotnet build OpenNest.Engine.Astra/OpenNest.Engine.Astra.csproj -c Release
dotnet test OpenNest.Engine.Astra/tests/OpenNest.Engine.Astra.Tests.csproj -c Release
dotnet build OpenNest.Engine.Gpt6Astra/OpenNest.Engine.Gpt6Astra.csproj -c Release
dotnet test OpenNest.Engine.Gpt6Astra/tests/OpenNest.Engine.Gpt6Astra.Tests.csproj -c Release
dotnet build OpenNest.Benchmark/OpenNest.Benchmark.csproj -c Release
mkdir -p ../OpenNest/OpenNest.Benchmark/bin/Release/net8.0/Engines
cp OpenNest.Engine.Astra/bin/Release/net8.0/OpenNest.Engine.Astra.dll ../OpenNest/OpenNest.Benchmark/bin/Release/net8.0/Engines/
dotnet ../OpenNest/OpenNest.Benchmark/bin/Release/net8.0/OpenNest.Benchmark.dll OpenNest.Engine.Astra/benchmarks/dxf --engines AstraNestingEngine --parallel 1
cp OpenNest.Engine.Gpt6Astra/bin/Release/net8.0/OpenNest.Engine.Gpt6Astra.dll ../OpenNest/OpenNest.Benchmark/bin/Release/net8.0/Engines/
dotnet ../OpenNest/OpenNest.Benchmark/bin/Release/net8.0/OpenNest.Benchmark.dll OpenNest.Engine.Gpt6Astra/benchmarks/dxf --engines Gpt6AstraNestingEngine --parallel 1
```
The host supplies Core, Engine and their dependencies. Plugin discovery uses the CLR type name
`AstraNestingEngine`; no registry call exists in the plugin.
`Gpt6AstraNestingEngine`; no registry call exists in the plugin.
Rebuild the host with this checkout's `OpenNest.Core` as well: replacing only the plugin DLL
does not update the shared curved-hole collision fix.
@@ -105,7 +105,7 @@ orientations are sampled/pruned. Hole search uses anchor positions, not a comple
polygon solver. Small usable regions inside complex cutouts may be missed. The benchmark report
includes an isolated host-validator reproducer and its corrected outcomes.
Filling NFP interior voids can exclude unusual interlocking configurations.
Salvage-credit options and `PlacementStrategy` do not change Astra's objective; `MaxPlates` is
Salvage-credit options and `PlacementStrategy` do not change Gpt6Astra's objective; `MaxPlates` is
respected. Stock dimensions, all edge spacings, quadrants, priorities and rotation policies are
honored. No real `.nest` fixtures were available in this workspace.
@@ -6,7 +6,7 @@ using OpenNest.Shapes;
using CncProgram = OpenNest.CNC.Program;
using M = System.Math;
namespace OpenNest.Engine.Astra.Benchmarks;
namespace OpenNest.Engine.Gpt6Astra.Benchmarks;
internal static class GeneratedCases
{
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup><OutputType>Exe</OutputType><Nullable>disable</Nullable></PropertyGroup>
<ItemGroup>
<ProjectReference Include="../OpenNest.Engine.Astra.csproj" />
<ProjectReference Include="../OpenNest.Engine.Gpt6Astra.csproj" />
<Compile Include="$(OpenNestRoot)OpenNest.Benchmark/NestValidator.cs" Link="NestValidator.cs" />
</ItemGroup>
</Project>
@@ -38,8 +38,8 @@ if (args.Contains("--diagnose-ring"))
return;
}
var assembly = args.Length > 0 && args[0].EndsWith(".dll")
? new AssemblyLoadContext("benchmark-plugin", isCollectible: true).LoadFromAssemblyPath(Path.GetFullPath(args[0])) : Assembly.Load("OpenNest.Engine.Astra");
var engine = (INestingEngine)Activator.CreateInstance(assembly.GetType("OpenNest.Engine.Astra.AstraNestingEngine")!);
? new AssemblyLoadContext("benchmark-plugin", isCollectible: true).LoadFromAssemblyPath(Path.GetFullPath(args[0])) : Assembly.Load("OpenNest.Engine.Gpt6Astra");
var engine = (INestingEngine)Activator.CreateInstance(assembly.GetType("OpenNest.Engine.Gpt6Astra.Gpt6AstraNestingEngine")!);
var cases = new List<(string Name, NestJob Job)>();
var standard = new[] { new NestPlateStock("small", new Size(24, 48), partSpacing: 0.15),
new NestPlateStock("large", new Size(48, 96), partSpacing: 0.15) };
@@ -72,7 +72,7 @@ Add("tail", new[] { Part("rect", Rect(6, 4), 17) }, new[] {
new NestPlateStock("small", new Size(8, 12), partSpacing: 0.1), new NestPlateStock("large", new Size(20, 30), partSpacing: 0.1) });
Add("plate-cap", new[] { Part("r", Rect(5, 5), 10) }, new[] {
new NestPlateStock("small", new Size(10, 10)), new NestPlateStock("large", new Size(20, 20)) }, new NestJobOptions(maxPlates: 1));
cases.AddRange(OpenNest.Engine.Astra.Benchmarks.GeneratedCases.Create());
cases.AddRange(OpenNest.Engine.Gpt6Astra.Benchmarks.GeneratedCases.Create());
Console.WriteLine("case,valid,placed,requested,sheets,area,milliseconds");
foreach (var (name, job) in cases)
{
@@ -1,8 +1,8 @@
# Astra development benchmark report
# Gpt6Astra development benchmark report
Measured locally on Linux with .NET SDK 8.0.425, Release builds, 2026-09-23.
The shared-validator fix was verified on 2026-09-24; its results are recorded separately below.
The baseline is Astra's original independent guillotine/bounding-rectangle implementation,
The baseline is Gpt6Astra's original independent guillotine/bounding-rectangle implementation,
archived before the contact-search rewrite. These are not measurements against Opus or a
claim of performance on an unseen competition dataset.
@@ -71,7 +71,7 @@ triangulated collision check can report a violation with required spacing 0.175.
also changes with translations. Checking every candidate against that routine made a small
ring job take approximately 80–90 seconds.
Astra initially reserved curved cutouts as solid during placement, preserving the original
Gpt6Astra initially reserved curved cutouts as solid during placement, preserving the original
drawing in output. This workaround finished the ring/insert job in about 50 ms at the baseline
sheet cost. It has now been removed following a fix in `OpenNest.Core/Geometry/Collision.cs`.
@@ -87,8 +87,8 @@ oracle in the new tests, not a replacement per-pair validator.
The eight original translated reproductions all pass. Regression coverage also rejects real
spacing violations, checks both operand orders and windings, exercises all four quadrants,
and compares overlap areas against Clipper on 80 seeded pairs with multiple/concave holes.
The main suite passes 1,096 tests (12 font-fixture skips), Engine passes 170, and Astra passes
27. Astra's curved-hole tests now require a ring and insert to share stock whose usable area
The main suite passes 1,096 tests (12 font-fixture skips), Engine passes 170, and Gpt6Astra passes
27. Gpt6Astra's curved-hole tests now require a ring and insert to share stock whose usable area
fits only the ring, proving that insertion is enabled.
All 34 synthetic/generated jobs remain valid and complete with unchanged sheet-area costs.
@@ -101,7 +101,7 @@ their rerun is recorded in `results/validator-fixed-dxf.csv`.
The isolated reproduction does not invoke any nesting engine:
```bash
dotnet run --project OpenNest.Engine.Astra/benchmarks -c Release -- --diagnose-ring
dotnet run --project OpenNest.Engine.Gpt6Astra/benchmarks -c Release -- --diagnose-ring
```
`results/ring-validator-reproducer.txt` retains the original failures;
@@ -132,8 +132,8 @@ single case does not establish general superiority. There is no Opus result avai
## Local geometry optimizations
Apart from the shared Core collision fix described above, these optimizations are in Astra.
Astra caches NFPs and incrementally
Apart from the shared Core collision fix described above, these optimizations are in Gpt6Astra.
Gpt6Astra caches NFPs and incrementally
subtracts each newly placed part from available translation regions, avoiding repeated unions
of all previous obstacles. A four-vertex rectangle configuration-space specialization avoids
round-offset polygons and polygon collision work for exact axis-aligned rectangle contacts.
@@ -142,7 +142,7 @@ specialization. This is an end-to-end observation, not an isolated component mic
Precision regression tests cover exact clearances and rotated zero-spacing contacts. In the
latter case, the host's four-decimal polygon rounding and triangulated collision test can
reject a contact accepted by Clipper at six decimals. Astra now retains the original rotated
reject a contact accepted by Clipper at six decimals. Gpt6Astra now retains the original rotated
frame for that validation, checks zero-clearance contacts with Core's collision primitive,
and tries tiny nearby translations when exact contact is unsafe.
@@ -151,7 +151,7 @@ and tries tiny nearby translations when exact contact is unsafe.
Run from the repository root:
```bash
dotnet run --project OpenNest.Engine.Astra/benchmarks -c Release
dotnet run --project OpenNest.Engine.Gpt6Astra/benchmarks -c Release
```
Run only the extended generated suite with `-- current generated`; the first positional
@@ -161,7 +161,7 @@ and crashes make the driver exit with a nonzero status. Incompleteness is report
The standalone driver also accepts a prior plugin DLL and optional case-name filter:
```bash
dotnet run --project OpenNest.Engine.Astra/benchmarks -c Release -- /path/to/previous/OpenNest.Engine.Astra.dll triangles
dotnet run --project OpenNest.Engine.Gpt6Astra/benchmarks -c Release -- /path/to/previous/OpenNest.Engine.Gpt6Astra.dll triangles
```
An isolated assembly load context prevents .NET from silently substituting the currently
@@ -172,11 +172,11 @@ budget is a benchmark safeguard and is not an elapsed-time stopping rule inside
For real DXFs, build and deploy the plugin as described in the parent README, then:
```bash
dotnet ../OpenNest/OpenNest.Benchmark/bin/Release/net8.0/OpenNest.Benchmark.dll OpenNest.Engine.Astra/benchmarks/dxf --engines AstraNestingEngine --parallel 1 --csv /tmp/astra-dxf.csv
dotnet ../OpenNest/OpenNest.Benchmark/bin/Release/net8.0/OpenNest.Benchmark.dll OpenNest.Engine.Gpt6Astra/benchmarks/dxf --engines Gpt6AstraNestingEngine --parallel 1 --csv /tmp/astra-dxf.csv
```
The CSV files under `results/` retain the measured results. Tests run independently:
```bash
dotnet test OpenNest.Engine.Astra/tests/OpenNest.Engine.Astra.Tests.csproj -c Release
dotnet test OpenNest.Engine.Gpt6Astra/tests/OpenNest.Engine.Gpt6Astra.Tests.csproj -c Release
```
@@ -4,9 +4,9 @@ using OpenNest.Engine.Jobs;
using OpenNest.Engine.Jobs.Adapters;
using OpenNest.Geometry;
namespace OpenNest.Engine.Astra.Tests;
namespace OpenNest.Engine.Gpt6Astra.Tests;
public class AstraNestingEngineTests
public class Gpt6AstraNestingEngineTests
{
[Theory]
[InlineData(1)]
@@ -21,11 +21,11 @@ public class AstraNestingEngineTests
}, new[] { new NestPlateStock("stock", new Size(15, 20), 10, 0.25,
new Spacing(1, 2, 3, 1), quadrant) });
var before = job.Parts.Select(p => p.Geometry.Motions.ToArray()).ToArray();
var result = new AstraNestingEngine().Solve(job);
var result = new Gpt6AstraNestingEngine().Solve(job);
Assert.Equal(NestJobStatus.Complete, result.Status);
Validate(job, result);
for (var i = 0; i < job.Parts.Count; i++) Assert.Equal(before[i], job.Parts[i].Geometry.Motions);
var again = new AstraNestingEngine().Solve(job);
var again = new Gpt6AstraNestingEngine().Solve(job);
Assert.Equal(result.Plates.SelectMany(p => p.Placements), again.Plates.SelectMany(p => p.Placements));
Assert.Equal(result.Plates.Select(p => p.StockId), again.Plates.Select(p => p.StockId));
}
@@ -35,7 +35,7 @@ public class AstraNestingEngineTests
{
var job = new NestJob(new[] { Rectangle("p", 2, 2, 1) }, new[] {
new NestPlateStock("large", new Size(20, 20)), new NestPlateStock("small", new Size(2, 2)) });
var result = new AstraNestingEngine().Solve(job);
var result = new Gpt6AstraNestingEngine().Solve(job);
Assert.Equal("small", Assert.Single(result.Plates).StockId);
Validate(job, result);
}
@@ -47,7 +47,7 @@ public class AstraNestingEngineTests
{
var job = new NestJob(new[] { Rectangle("p", 2, 2, 3) },
new[] { new NestPlateStock("s", new Size(2, 2), quantity) }, new NestJobOptions(maxPlates: limit));
var result = new AstraNestingEngine().Solve(job);
var result = new Gpt6AstraNestingEngine().Solve(job);
Assert.Equal(reason, result.StopReason);
Assert.Equal(2, Assert.Single(result.Fulfillment).Unplaced);
Validate(job, result);
@@ -57,11 +57,11 @@ public class AstraNestingEngineTests
public void ImpossibleAndEmptyJobsTerminate()
{
var part = Rectangle("p", 10, 10, 1);
Assert.Equal(NestJobStopReason.NoPlacementFound, new AstraNestingEngine().Solve(
Assert.Equal(NestJobStopReason.NoPlacementFound, new Gpt6AstraNestingEngine().Solve(
new NestJob(new[] { part }, new[] { new NestPlateStock("s", new Size(2, 2)) })).StopReason);
Assert.Equal(NestJobStopReason.StockExhausted, new AstraNestingEngine().Solve(
Assert.Equal(NestJobStopReason.StockExhausted, new Gpt6AstraNestingEngine().Solve(
new NestJob(new[] { part }, Array.Empty<NestPlateStock>())).StopReason);
Assert.Equal(NestJobStatus.Complete, new AstraNestingEngine().Solve(
Assert.Equal(NestJobStatus.Complete, new Gpt6AstraNestingEngine().Solve(
new NestJob(Array.Empty<NestJobPart>(), Array.Empty<NestPlateStock>())).Status);
}
@@ -81,7 +81,7 @@ public class AstraNestingEngineTests
new NestJobPart("circle", PartGeometrySnapshot.FromProgram(circle), 5),
new NestJobPart("incremental", PartGeometrySnapshot.FromProgram(incremental), 5)
}, new[] { new NestPlateStock("s", new Size(20, 20), partSpacing: 0.4) });
var result = new AstraNestingEngine().Solve(job);
var result = new Gpt6AstraNestingEngine().Solve(job);
Assert.Equal(NestJobStatus.Complete, result.Status);
Validate(job, result);
}
@@ -93,9 +93,9 @@ public class AstraNestingEngineTests
new[] { new NestPlateStock("s", new Size(10, 10)) });
using var cts = new CancellationTokenSource();
cts.Cancel();
Assert.Throws<OperationCanceledException>(() => new AstraNestingEngine().Solve(job, token: cts.Token));
Assert.Throws<OperationCanceledException>(() => new Gpt6AstraNestingEngine().Solve(job, token: cts.Token));
using var during = new CancellationTokenSource();
Assert.Throws<OperationCanceledException>(() => new AstraNestingEngine().Solve(job,
Assert.Throws<OperationCanceledException>(() => new Gpt6AstraNestingEngine().Solve(job,
new CallbackProgress(_ => during.Cancel()), during.Token));
}
@@ -106,7 +106,7 @@ public class AstraNestingEngineTests
var high = new NestJobPart("high", low.Geometry, 1, priority: 9);
var job = new NestJob(new[] { low, high }, new[] { new NestPlateStock("s", new Size(2, 2), 1) });
var updates = new List<NestJobProgress>();
var result = new AstraNestingEngine().Solve(job, new CallbackProgress(updates.Add));
var result = new Gpt6AstraNestingEngine().Solve(job, new CallbackProgress(updates.Add));
Assert.Equal("high", Assert.Single(Assert.Single(result.Plates).Placements).PartId);
Assert.Equal(NestJobStage.PlateCommitted, updates.Last().Stage);
Assert.Equal(1, updates.Last().CommittedParts);
@@ -125,7 +125,7 @@ public class AstraNestingEngineTests
new NestJobPart("concave", PartGeometrySnapshot.FromProgram(l), 7),
new NestJobPart("hole", PartGeometrySnapshot.FromProgram(holed), 3)
}, new[] { new NestPlateStock("s", new Size(20, 30), partSpacing: 0.2) });
var result = new AstraNestingEngine().Solve(job);
var result = new Gpt6AstraNestingEngine().Solve(job);
Assert.Equal(NestJobStatus.Complete, result.Status);
Validate(job, result);
}
@@ -143,7 +143,7 @@ public class AstraNestingEngineTests
new NestPlateStock("small", new Size(15, 20), 1, 0.1),
new NestPlateStock("large", new Size(25, 30), partSpacing: 0.3)
});
var result = new AstraNestingEngine().Solve(job);
var result = new Gpt6AstraNestingEngine().Solve(job);
Assert.Equal(NestJobStatus.Complete, result.Status);
Validate(job, result);
}
@@ -156,7 +156,7 @@ public class AstraNestingEngineTests
triangle.LineTo(0, 10); triangle.LineTo(0, 0);
var job = new NestJob(new[] { new NestJobPart("t", PartGeometrySnapshot.FromProgram(triangle), 2) },
new[] { new NestPlateStock("s", new Size(10, 10), 1) });
var result = new AstraNestingEngine().Solve(job);
var result = new Gpt6AstraNestingEngine().Solve(job);
Assert.Equal(NestJobStatus.Complete, result.Status);
Assert.Single(result.Plates);
Validate(job, result);
@@ -170,7 +170,7 @@ public class AstraNestingEngineTests
frame.LineTo(9, 1); frame.LineTo(1, 1);
var job = new NestJob(new[] { new NestJobPart("frame", PartGeometrySnapshot.FromProgram(frame), 1),
Rectangle("insert", 7, 7, 1) }, new[] { new NestPlateStock("s", new Size(10, 10), 1, 0.25) });
var result = new AstraNestingEngine().Solve(job);
var result = new Gpt6AstraNestingEngine().Solve(job);
Assert.Equal(NestJobStatus.Complete, result.Status);
Assert.Single(result.Plates);
Validate(job, result);
@@ -182,7 +182,7 @@ public class AstraNestingEngineTests
var job = new NestJob(new[] { Rectangle("p", 5, 5, 10) }, new[] {
new NestPlateStock("small", new Size(10, 10)), new NestPlateStock("large", new Size(20, 20))
}, new NestJobOptions(maxPlates: 1));
var result = new AstraNestingEngine().Solve(job);
var result = new Gpt6AstraNestingEngine().Solve(job);
Assert.Equal(NestJobStatus.Complete, result.Status);
Assert.Equal("large", Assert.Single(result.Plates).StockId);
Validate(job, result);
@@ -193,7 +193,7 @@ public class AstraNestingEngineTests
{
var job = new NestJob(new[] { Rectangle("diagonal", 10, 1, 1, RotationPolicy.Automatic) },
new[] { new NestPlateStock("s", new Size(8, 8), 1) });
var result = new AstraNestingEngine().Solve(job);
var result = new Gpt6AstraNestingEngine().Solve(job);
Assert.Equal(NestJobStatus.Complete, result.Status);
Validate(job, result);
}
@@ -205,7 +205,7 @@ public class AstraNestingEngineTests
triangle.LineTo(0, 10); triangle.LineTo(0, 0);
var job = new NestJob(new[] { new NestJobPart("t", PartGeometrySnapshot.FromProgram(triangle), 20) },
new[] { new NestPlateStock("s", new Size(24, 48), partSpacing: 0.15) });
var result = new AstraNestingEngine().Solve(job);
var result = new Gpt6AstraNestingEngine().Solve(job);
Assert.Equal(NestJobStatus.Complete, result.Status);
Validate(job, result);
}
@@ -216,7 +216,7 @@ public class AstraNestingEngineTests
var job = new NestJob(new[] { Rectangle("p", 6, 4, 100, RotationPolicy.Automatic) }, new[] {
new NestPlateStock("small", new Size(8, 12), partSpacing: 0.1),
new NestPlateStock("large", new Size(20, 30), partSpacing: 0.1) });
var result = new AstraNestingEngine().Solve(job);
var result = new Gpt6AstraNestingEngine().Solve(job);
Assert.Equal(NestJobStatus.Complete, result.Status);
Assert.True(result.Plates.Sum(p => p.Stock.Size.Length * p.Stock.Size.Width) <= 3600);
Validate(job, result);
@@ -227,7 +227,7 @@ public class AstraNestingEngineTests
{
var job = new NestJob(new[] { Rectangle("p", 2, 2, 4) },
new[] { new NestPlateStock("s", new Size(4.25, 4.25), 1, 0.25) });
var result = new AstraNestingEngine().Solve(job);
var result = new Gpt6AstraNestingEngine().Solve(job);
Assert.Equal(NestJobStatus.Complete, result.Status);
Validate(job, result);
}
@@ -245,7 +245,7 @@ public class AstraNestingEngineTests
new NestJobPart("t", PartGeometrySnapshot.FromProgram(t), 7),
Rectangle("r", 3, 2, 5, RotationPolicy.Fixed(trial * System.Math.PI / 7))
}, new[] { new NestPlateStock("s", new Size(20, 25), partSpacing: spacing) });
var result = new AstraNestingEngine().Solve(job);
var result = new Gpt6AstraNestingEngine().Solve(job);
Assert.Equal(NestJobStatus.Complete, result.Status);
Validate(job, result);
}
@@ -265,7 +265,7 @@ public class AstraNestingEngineTests
new NestJobPart("insert", PartGeometrySnapshot.FromProgram(insert.Program), 1)
}, new[] { new NestPlateStock("s", new Size(10.8, 10.6), 1, partSpacing: 0.175,
edgeSpacing: new Spacing(0.2, 0.3, 0.4, 0.5), quadrant: quadrant) });
var result = new AstraNestingEngine().Solve(job);
var result = new Gpt6AstraNestingEngine().Solve(job);
Assert.Equal(NestJobStatus.Complete, result.Status);
Assert.Equal(2, Assert.Single(result.Plates).Placements.Count);
Validate(job, result);
@@ -281,7 +281,7 @@ public class AstraNestingEngineTests
new[] { new NestPlateStock("s", new Size(25, 43), 1, 0.25,
new Spacing(0.2, 0.3, 0.4, 0.5), 3) });
using var cancellation = new CancellationTokenSource(TimeSpan.FromSeconds(30));
var result = new AstraNestingEngine().Solve(job, token: cancellation.Token);
var result = new Gpt6AstraNestingEngine().Solve(job, token: cancellation.Token);
Assert.Equal(NestJobStatus.Complete, result.Status);
Assert.Single(result.Plates);
Validate(job, result);
@@ -11,6 +11,6 @@
<ItemGroup>
<Using Include="Xunit" />
<Compile Include="$(OpenNestRoot)OpenNest.Benchmark/NestValidator.cs" Link="NestValidator.cs" />
<ProjectReference Include="../OpenNest.Engine.Astra.csproj" />
<ProjectReference Include="../OpenNest.Engine.Gpt6Astra.csproj" />
</ItemGroup>
</Project>
+1 -1
View File
@@ -7,7 +7,7 @@ the OpenNest app or `OpenNest.Benchmark` build output.
| Engine | Approach |
|--------|----------|
| [Astra](OpenNest.Engine.Astra/) | Contact-based placement |
| [Gpt6Astra](OpenNest.Engine.Gpt6Astra/) | Contact-based placement |
| [Opus55](OpenNest.Engine.Opus55/) | Frontier-advance no-fit-polygon packing |
| [Qwen](OpenNest.Engine.Qwen/) | Scaffold — not yet implemented |