Qwen3.8-Flash-Next reached a working engine and is now optimizing it. Optimization passes can regress, so this preserves the first version that passes all acceptance tests (13/13 against OpenNest master, including the model's own rotated-spacing regression test) for comparison and rollback. Snapshot taken 2026-09-24 12:00 from hermes.lan:/home/aj/src/Qwen38FlashNext; the run is still in progress, so this stays off master until it finishes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
49 lines
2.2 KiB
C#
49 lines
2.2 KiB
C#
using System;
|
|
using System.Threading;
|
|
using OpenNest.Engine.Jobs;
|
|
using OpenNest.Engine.Qwen38FlashNext.Engine;
|
|
|
|
namespace OpenNest.Engine.Qwen38FlashNext;
|
|
|
|
/// <summary>
|
|
/// Independent whole-job nesting engine: bottom-left-first placement over convex
|
|
/// No-Fit-Polygons with an exact material-clearance gate, driven sheet by sheet by a
|
|
/// greedy demand scheduler.
|
|
/// <para>
|
|
/// Per sheet, parts are demanded in the engine's own order (priority, then the part
|
|
/// with the thinnest worst-case orientation extent, then area, then id) and each
|
|
/// requirement is drained greedily. For a part instance the engine enumerates its
|
|
/// legal orientations (policy angles, or 0/90/180/270 plus the rotating-calipers
|
|
/// minimum bounding rectangle for automatic rotation), builds for every placed part a
|
|
/// convex NFP as placedHull (+) disk(spacing) (+) reflect(candidateHull) via its own
|
|
/// Minkowski edge-merge, generates the corner-point feasible-region candidates (anchor
|
|
/// box corners, NFP vertices, NFP-edge/box-line slides), and places the instance at the
|
|
/// lowest-leftmost candidate whose exact material clearance the engine's collision gate
|
|
/// accepts. Which stock the next sheet uses is chosen by re-packing each available size
|
|
/// and committing the trial that places the most instances on the smallest sheet; the
|
|
/// job stops when demand is met, stock runs out, nothing further can be placed, or the
|
|
/// plate cap is hit. See Engine/ for the placement core and README.md for the design
|
|
/// write-up.
|
|
/// </para>
|
|
/// <para>
|
|
/// The engine is self-contained: it calls no built-in <see cref="INestingEngine"/>,
|
|
/// nester, filler, or runner, and is deterministic - identical input, identical layout.
|
|
/// </para>
|
|
/// </summary>
|
|
public sealed class Qwen38FlashNextNestingEngine : INestingEngine
|
|
{
|
|
public NestJobResult Solve(
|
|
NestJob job,
|
|
IProgress<NestJobProgress>? progress = null,
|
|
CancellationToken token = default
|
|
)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(job);
|
|
token.ThrowIfCancellationRequested();
|
|
|
|
var preparation = new PartPreparation(job.Parts);
|
|
var solver = new JobSolver(job, preparation);
|
|
return solver.Solve(progress, token);
|
|
}
|
|
}
|