Add Optimize method that re-places parts using NFP-based BLF, keeping the result only if it improves density without losing parts. Fix perimeter inflation to use correct offset side. Add NfpNestEngine that wraps AutoNester for the registry. Register NFP engine. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
69 lines
2.3 KiB
C#
69 lines
2.3 KiB
C#
using OpenNest.Engine.Fill;
|
|
using OpenNest.Engine.Nfp;
|
|
using OpenNest.Geometry;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
|
|
namespace OpenNest
|
|
{
|
|
public class NfpNestEngine : NestEngineBase
|
|
{
|
|
public NfpNestEngine(Plate plate) : base(plate)
|
|
{
|
|
}
|
|
|
|
public override string Name => "NFP";
|
|
|
|
public override string Description => "NFP-based mixed-part nesting with simulated annealing";
|
|
|
|
public override List<Part> Fill(NestItem item, Box workArea,
|
|
IProgress<NestProgress> progress, CancellationToken token)
|
|
{
|
|
var inner = new DefaultNestEngine(Plate);
|
|
return inner.Fill(item, workArea, progress, token);
|
|
}
|
|
|
|
public override List<Part> Fill(List<Part> groupParts, Box workArea,
|
|
IProgress<NestProgress> progress, CancellationToken token)
|
|
{
|
|
var inner = new DefaultNestEngine(Plate);
|
|
return inner.Fill(groupParts, workArea, progress, token);
|
|
}
|
|
|
|
public override List<Part> PackArea(Box box, List<NestItem> items,
|
|
IProgress<NestProgress> progress, CancellationToken token)
|
|
{
|
|
var inner = new DefaultNestEngine(Plate);
|
|
return inner.PackArea(box, items, progress, token);
|
|
}
|
|
|
|
public override List<Part> Nest(List<NestItem> items,
|
|
IProgress<NestProgress> progress, CancellationToken token)
|
|
{
|
|
if (items == null || items.Count == 0)
|
|
return new List<Part>();
|
|
|
|
var parts = AutoNester.Nest(items, Plate, progress, token);
|
|
|
|
// Compact placed parts toward the origin to close gaps.
|
|
Compactor.Settle(parts, Plate.WorkArea(), Plate.PartSpacing);
|
|
|
|
// NFP optimization pass — re-place parts using geometry-aware BLF.
|
|
parts = AutoNester.Optimize(parts, Plate);
|
|
|
|
// Deduct placed quantities from original items.
|
|
foreach (var item in items)
|
|
{
|
|
if (item.Quantity <= 0)
|
|
continue;
|
|
|
|
var placed = parts.FindAll(p => p.BaseDrawing.Name == item.Drawing.Name).Count;
|
|
item.Quantity = System.Math.Max(0, item.Quantity - placed);
|
|
}
|
|
|
|
return parts;
|
|
}
|
|
}
|
|
}
|