Files
OpenNest/OpenNest.Engine/RectanglePacking/RectFill.cs
T
ajandClaude Opus 5.5 12819198f9 feat(fill): search every spiral combination in rectangle best fit
The spiral used only the least-waste rows and columns. Those often make
one pair of blocks the larger on both axes, so it overlapped itself and
placed nothing, leaving Fill at two blocks. It now also tries every
four-block combination and takes one that holds more parts than both the
least-waste spiral and the two-block layout, so ties keep today's layout.

A 9 x 6.5 part on a 60 x 120 sheet goes from 109 to 112.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 23:42:25 -05:00

46 lines
1.8 KiB
C#

using OpenNest.Geometry;
namespace OpenNest.Engine.RectanglePacking
{
internal static class RectFill
{
public static void FillBest(Bin bin, Item item, int maxCount = int.MaxValue)
{
// Best fit runs first because a spiral other than the least-waste one must beat it.
var bestFitBin = bin.Clone() as Bin;
new FillBestFit(bestFitBin).Fill(item.Clone() as Item, maxCount);
var spiralBin = bin.Clone() as Bin;
var spiral = new FillSpiral(spiralBin) { AlternativeMustExceed = bestFitBin.Items.Count };
spiral.Fill(item, maxCount);
// Recursively fill the center remnant of the spiral
if (spiralBin.Items.Count > 0 && spiral.CenterRemnant != null)
{
var center = spiral.CenterRemnant;
var fitsNormal = item.Length <= center.Length && item.Width <= center.Width;
var fitsRotated = item.Width <= center.Length && item.Length <= center.Width;
if (fitsNormal || fitsRotated)
{
var remaining = maxCount - spiralBin.Items.Count;
FillBest(center.Location, center.Size, spiralBin, item, remaining);
}
}
var winner = spiralBin.Items.Count >= bestFitBin.Items.Count ? spiralBin : bestFitBin;
bin.Items.AddRange(winner.Items);
}
public static void FillBest(Vector location, Size size, Bin target, Item item, int maxCount)
{
if (size.Width <= 0 || size.Length <= 0 || maxCount <= 0)
return;
var bin = new Bin { Location = location, Size = size };
FillBest(bin, item, maxCount);
target.Items.AddRange(bin.Items);
}
}
}