Qwen3.8-Flash-Next's final version after a 14.5-hour optimization run (its commit 7d7fca3): cost-first sheet trials, largest-area-first demand order, and a cached-triangulation exact gate that brought a 219-part production job from timeout to ~106 s. 13/13 tests pass against OpenNest master. README cleaned for publishing: the model-facing template rules are replaced by a one-line independence statement, the production job is described generically instead of by its PEP job/file name (also in a JobSolver comment), results show both sheet pools as re-measured here (the 9-size claim in its report didn't reproduce: it grabs 96x240 and under-fills them), and the stale StockLadder-crash note is gone now that core leaves etch marks out of nesting. Also drops a stale Aurora plugin reference from Opus55's README and lists the engine in the repo README. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
OpenNest.Engine.Qwen38FlashNext
An independent whole-job INestingEngine built by Qwen3.8-Flash-Next: bottom-left greedy
insertion over convex no-fit polygons with an exact clearance gate. It does not call, wrap,
or select over any built-in engine, nester, filler, or runner.
Algorithm
Bottom-left greedy insertion over convex No-Fit-Polygons, with an exact material-clearance
gate, driven sheet by sheet by a greedy demand scheduler. All geometry math is the engine's
own (Engine/); it calls no built-in nester, filler, or runner.
PartPreparationrebuilds each snapshot into a closed contour topology (perimeter + cutouts; rapids/scribe marks dropped), flattens it circumscribed (the collision polygon always contains the true material), and caches per-(part, angle, spacing) geometry: bounds, convex hull, and the spacing-inflated outline rotated into that orientation's frame (offset commutes with rotation; an unrotated inflation tests the candidate against the material of a different angle - this was a real overlap bug, caught byRotatedConcavePartsKeepSpacingAtFixedAngles). Candidate angles are the policy angles, or 0/90/180/270 plus the rotating-calipers minimum-bounding-rectangle angle for automatic rotation.SheetPackerplaces one part instance at a time. Per already-placed part it builds a convex NFP asplacedHull (+) disk(spacing) (+) reflect(candidateHull)via its own Minkowski edge-merge (Convex.cs; the merge picks the more-clockwise frontier edge, an inverted comparison here corrupts every non-parallel sum into a self-intersecting contour), then enumerates corner-point candidates: anchor work-box corners, NFP vertices, and NFP-edge/box-line slides, tried in ascending bottom-left order. Because the NFP is hull-based it only certifies clearance when both parts are convex solids with uncapped hulls; everything else falls through to the exact gate - placed material inflated by the spacing (holes shrunk, closed holes treated solid) versus the candidate's raw material with holes subtracted, the same inflation rule the benchmark validator uses, so interlocking concave parts are placed legally where the convex NFP alone would reject them. A uniform spatial grid keeps the pair tests near-constant as the sheet fills, and an overlap memo keyed by world pose collapses repeated clipper work across stock trials.FastPoly/CachedCollision(TriSet) make the exact gate cheap. Each orientation caches flat-array triangulations of its raw material and its spacing-inflated gate material; a candidate-vs-placed pair then runs the built-in clipper algorithm on plain double arrays with the anchor offsets as translations - noPolygonclones, no per-check re-triangulation, no LINQ. A uniform edge grid on the gate outlines certifies disjoint shell pairs (clear) and convex-solid crossings (overlap) before any clip work; the certification is three-state (touch and collinear contact defer to the clip, containment is decided by sampled interior tests) so it can never report a false clear - cross-validated againstCollision.HasOverlapover ~2.5M decisions per job run with zero verdict mismatches, and hole-clipping overflow falls back to the exactPolygongate (0.2% of checks on the production job below).JobSolverwalks demands in its own order (priority, then largest material area - big parts first lay down the sheet skeleton the small parts fill against; measured 12% lower job cost than smallest-extent-first on the production job below) and drains each greedily, then a time-boxed gap-fill pass. For the next sheet it trials every available stock size independently and commits the trial delivering the cheapest plate area per unit of part area placed (the benchmark's cost function), breaking ties by priority coverage, instance count, then plate area; lost trials change no job state. The job stops on met demand, exhausted stock, no further placement, or the plate cap. Deterministic: identical input, identical layout.
Trade-offs: greedy BLFG insertion leaves some of the density interlocking-pair and compaction pipelines find on regular jobs, and every stock size is trialled per sheet (O(sheets x stocks x fill)); on the 69-drawing/219-part production job below that costs ~110 s against the benchmark's 5-minute per-solve timeout. In exchange it places arcs, concaves, and holed parts under one uniform gate with no per-shape-class special cases.
Benchmark results
A real laser-cutting production job: 69 drawings, 219 parts, 3/16 mild steel, spacing 0.3,
--parallel 1, same OpenNest build for every engine.
| Sheet sizes offered | Result | Sheets | Utilization | Cost | Time |
|---|---|---|---|---|---|
| The job's own 4 sizes (60x96, 60x120, 72x120, 48x144) | valid, 219/219 | 28 | 78.4% | 219,744 | ~106 s |
| OpenNest's standard 9-size catalog | valid, 219/219 | 14 | 56.6% | 304,128 | ~132 s |
It uses the fewest sheets of any engine tested, but not the least material. The shop's original hand layout used 29 sheets (191,232 sq in). Known weakness: sheet choice is greedy one sheet at a time, so with large stock available it grabs 96x240 sheets and under-fills them.
Optimization history on this job (all valid, 219/219): count-first trial scoring and span-first demand order cost 258048/39 plates; cost-first trial scoring brought it to 249696 (39); area-first demand order to 219744 (28). Wall time went from timeout (>400 s) to ~110 s via the cached-triangulation exact gate and the fast shell prefilter.
Tests
tests/ holds acceptance tests whose layouts are checked by the benchmark's own
NestValidator (bounds, spacing, quantities, stock, rotation), plus NFP geometry tests and a
rotated-concave spacing regression test.
dotnet test OpenNest.Engine.Qwen38FlashNext/tests/OpenNest.Engine.Qwen38FlashNext.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:
dotnet build OpenNest.Engine.Qwen38FlashNext/OpenNest.Engine.Qwen38FlashNext.csproj -c Release
dotnet build <OpenNest>/OpenNest.Benchmark/OpenNest.Benchmark.csproj -c Release
mkdir -p <OpenNest>/OpenNest.Benchmark/bin/Release/net8.0/Engines
cp OpenNest.Engine.Qwen38FlashNext/bin/Release/net8.0/OpenNest.Engine.Qwen38FlashNext.dll <OpenNest>/OpenNest.Benchmark/bin/Release/net8.0/Engines/
dotnet <OpenNest>/OpenNest.Benchmark/bin/Release/net8.0/OpenNest.Benchmark.dll <path-to-.nest-or-folder> --parallel 1
<OpenNest> is the OpenNest checkout root. Or build and deploy in one step with
./Build-Engines.ps1 -Engines Qwen38FlashNext. The engine appears in reports as
Qwen38FlashNextNestingEngine.