Gpt6Astra reverse-engineered the validator: hand-tuned paddings and a copied check sequence (ValidationOverlap) to match its rounding. It now reads parts with JobPartGeometry, takes clearance from NestTolerances, checks candidates with NestLayoutCheck.Clears, and assembles results with NestJobResultBuilder and NestJobCost; its tests use the shared kit. Its contact search, beam search and extra Automatic angles are unchanged. Synthetic benchmark (5 jobs, salvage 0.5): all valid, 2 sheets each, cost 5574.07 -> 5470.07; time 1871 -> 2400 ms from the stricter shared check on arc-heavy jobs. Co-Authored-By: Codex <noreply@openai.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
138 lines
9.7 KiB
Markdown
138 lines
9.7 KiB
Markdown
# 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. Read owned analytic material with `JobPartGeometry.Read`. 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 extend `RotationCandidates.ForShape` with 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 720 base samples through `RotationPolicy.EnumerateAngles`, including permitted half-turn equivalents.
|
|
3. Process high-priority parts first (a lower `Priority` number ranks higher, as in the host),
|
|
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 `NestJobCost.NetSheetArea` including salvage, 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 `NestTolerances.ValidationOutline`. Contact generation and material halos both use
|
|
`SafeClearanceMargin` so proposed contacts pass the same clearance gate. Axis-aligned
|
|
rectangle contacts preserve exact requested spacing. `NestLayoutCheck.Clears` replaces
|
|
the copied validator construction and collision sequence, with world-pose caching.
|
|
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.
|
|
|
|
## Shared services migration
|
|
|
|
Stock bounds and fit checks use the host stock primitives; committed results and progress
|
|
use `NestJobResultBuilder`. The test project shares `Engine.Testing` and no longer links
|
|
benchmark source. The synthetic console also validates through `NestLayoutCheck` and
|
|
reports `NestJobCost.Evaluate`. Automatic 15-degree/edge sampling, beam search, contact
|
|
placement, exact rectangle handling, and full-material symmetry signatures for holed
|
|
parts remain engine-owned. The host symmetry helper compares only perimeters.
|
|
|
|
The five salvage benchmarks stayed valid and complete. Cost fell from 5574.07 to
|
|
5470.07 overall (no job worsened at report precision); see [PR 5 results](../MIGRATION-PR5.md).
|