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
+125
View File
@@ -0,0 +1,125 @@
# OpenNest.Engine.Gpt6Astra
An independent, deterministic .NET 8 CNC nesting plugin. Its public parameterless
`Gpt6AstraNestingEngine` implements `INestingEngine`. The project remains outside `OpenNest.sln`.
## Placement algorithm
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,
concave interlocking, and insertion into straight-edged and curved holes.
1. Validate immutable job input. Reconstruct owned analytic entities with `DrawingJobMapper`
and `ConvertProgram`. Closed contours define material; internal open marks do not become
holes. Preserve the snapshot's origin when converting normalized placements back to poses.
2. Prepare rotated outlines and material regions with holes, using conservative curve flattening.
Automatic angles combine 15-degree samples over a full turn with orientations aligned to the
longest straight edges. Symmetric duplicates are removed. Prefer up to 16 orientations whose
envelope area is within 8% of the minimum; retain additional orientations when needed to fit
a candidate stock. Fixed and bounded rotation policies remain enforced. Bounded sweeps use
up to 721 integer step indices, including permitted half-turn equivalents.
3. Process high-priority parts first, then parts fitting fewer available stock types, then larger
envelopes. Larger frames precede inserts. Search every retained orientation for each instance.
4. Build cached Minkowski/no-fit regions. Convex pairs use Core's linear convex NFP primitive;
concave pairs use Clipper's integer Minkowski sum. Arc-heavy concave contact outlines use
a coarser mesh with both approximation bounds added to clearance; fine material geometry
still checks every candidate. Positive outer boundaries are filled conservatively.
Axis-aligned rectangles have a four-vertex contact shortcut.
5. Maintain each orientation's available translation region incrementally as parts are added.
Search its boundary vertices, exact-fit contacts and hole anchors. Reject points inside solid
no-fit regions before expensive checks. Check surviving candidates against actual material
regions with holes and spacing offsets. Zero-clearance contacts also pass the shared triangulated
collision check, with tiny position adjustments when rounding makes an exact contact unsafe.
Hole contacts use the same check in the final sheet coordinate frame, with bounded caching.
Two directional objectives try bottom-up and left-to-right growth using the same contact algorithm.
6. Search stock plans with a beam of up to three states. Rank by observed delivery cost and
remaining material, while preserving a state with high placed area. This avoids starving
large-sheet plans in favor of cheap but inefficient small-sheet prefixes. A genuine material
area lower bound prunes plans only once a complete cheaper plan exists. After 24 evaluated
trials only one directional objective is used; after 64, beam width reduces to two.
Work counts, not elapsed time or randomness, control search breadth.
7. Select a complete plan with lowest purchased area, breaking equal-cost ties by sheet count.
If no complete plan is found, maximize fulfilled counts by priority, then minimize cost.
Emit committed-sheet progress, contiguous per-part instance indices, inventory, fulfillment
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 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 Gpt6Astra.
## Precision and safety
Analytic rotated bounds govern sheet containment. Material curves are conservatively flattened
at 0.001 job units. Positive configuration-space spacing includes 0.0003 extra units for non-rectangular
straight outlines; curved outlines reserve 0.003 extra units even at zero spacing, accounting for offset/chord error and the
benchmark validator's four-decimal grid. Axis-aligned rectangle contacts preserve exact requested
spacing. Actual material intersection checks backstop candidate construction. Both straight-edged
and curved holes are available for insertion. The shared collision routine now subtracts hole
triangles into disjoint fragments with consistent half-space clipping, resolving the reproduced
curved-hole false positive. See the benchmark report for regression results.
Concave contact outlines exceeding 64 vertices use a chord tolerance of the greater of 0.002
units or 0.2% of the smaller envelope dimension. The pair's two tolerances are added to the
NFP offset. This reduces Minkowski input size without coarsening the final material checks.
The broad phase is deliberately conservative. It can miss a valid close fit; output validation
is exercised separately through the benchmark's materialized geometry validator in tests.
## Structure
- `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.
- `tests/`: xUnit tests plus a linked copy of the existing benchmark validator source.
- `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.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.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.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
`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.
## Limitations
This is bounded heuristic search, not a proof of minimum sheet cost or infeasibility. Early part
order is not backtracked within a sheet, already placed parts are not moved, and available
orientations are sampled/pruned. Hole search uses anchor positions, not a complete inner-fit
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 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.
Complex concave outlines, dense bounded sweeps, many part types or very large quantities can
be expensive. NFP and trial cache entry counts are bounded, but individual geometry can be large.
Cancellation is checked throughout search and between geometry operations; shared validation and
individual Clipper calls are not interruptible. The v2 search costs more CPU than the original
bounding-rectangle baseline. See `benchmarks/README.md` for measured tradeoffs.
## Current validation
Release build succeeded with .NET SDK 8.0.425 on Linux. All 27 xUnit cases passed, including
independent benchmark validation of materialized results, exact positive/zero clearance,
non-cardinal rotations, hole insertion, automatic diagonal-only stock fits, all quadrants,
curves, incremental geometry, determinism, inventory, cancellation and stock-plan regressions.
All 34 synthetic/generated benchmark cases and all four repository-DXF cases were valid and complete.
Existing nullable warnings originate from the benchmark validator linked into the test project.