mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-11-13 03:31:09 -05:00
feat(engine): squeeze the Rectangles sheet that finishes the job
Auto Nest left N26-2A5 (14 door stops, 14 lock plates on a clamped 26x26 sheet) 8.0 high, while the shop's hand layout holds all 28 under 7.5 and leaves a half-inch-deeper drop. Every MaxRects fit rule packs into the whole sheet, so with room to spare it spreads the parts out and never looks for the shortest strip. When a rule places all the remaining demand, Rectangles now repacks it into shorter and narrower bins, every rule and mode per probe, and offers the tightest complete layout per axis to the stock loop, which still picks by cost and offcut. Fit is not monotonic in bin size (7.5 packs, 7.62 and 7.74 do not), so probes walk down through stack heights (sums of spaced part sides from the bin edge or a reached clamp) instead of bisecting. A placement budget skips sheets finishing ~2000+ parts. Benchmark, Rectangles on 80 recent production nests with salvage credit: 11 cheaper, 0 worse, all valid, total time 14.7 s -> 13.2 s. The zero-clamp hash is re-captured (the squeezed layout is narrower); the far-clamp test now compares poses, since the clamp can reorder an identical layout. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
7dc471bbf8
commit
9273a44258
6 files changed
+362
-13
No files matched your search
@@ -64,14 +64,29 @@ public sealed class RectanglesNestingEngine : INestingEngine
|
||||
{
|
||||
// Both private MaxRects modes return only after their normal demand/no-fit search;
|
||||
// neither returns partial/budget-limited output. This is not a geometric impossibility proof.
|
||||
var plans = PackAll(stock, left, null, null);
|
||||
foreach (var plan in plans)
|
||||
yield return Layout(plan);
|
||||
// A sheet that finishes the job is also tried squeezed into a shorter or narrower bin.
|
||||
foreach (var plan in SheetSqueeze.Run(types, left, stock, plans,
|
||||
(width, height) => PackAll(stock, left, width, height), token))
|
||||
yield return Layout(plan);
|
||||
}
|
||||
|
||||
IReadOnlyList<SheetPlan> PackAll(NestPlateStock stock, IReadOnlyList<int> left, double? width, double? height)
|
||||
{
|
||||
var plans = new List<SheetPlan>(Modes.Length * Rules.Length);
|
||||
foreach (var mode in Modes)
|
||||
foreach (var rule in Rules)
|
||||
{
|
||||
var plan = SheetPacker.Pack(types, left, stock, rule, mode, token);
|
||||
plans.Add(SheetPacker.Pack(types, left, stock, rule, mode, token, width, height));
|
||||
SheetPacked?.Invoke(mode);
|
||||
yield return new SheetLayout(stock, plan.Poses().ToArray(), plan.MaterialArea, plan.Envelope);
|
||||
}
|
||||
return plans;
|
||||
}
|
||||
|
||||
static SheetLayout Layout(SheetPlan plan) =>
|
||||
new(plan.Stock, plan.Poses().ToArray(), plan.MaterialArea, plan.Envelope);
|
||||
}
|
||||
|
||||
private static bool FitsStock(NestPlateStock stock, BoxOrientation o)
|
||||
|
||||
Reference in new issue
Block a user