mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-11-03 18:11:36 -05:00
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>
46 lines
1.8 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|