feat: replace Fill method with geometry-aware FillLinear algorithm
Fill(NestItem) now uses actual part geometry instead of bounding boxes. Also fixes Fill(NestItem, maxCount) which previously threw NotImplementedException. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -22,13 +22,49 @@ namespace OpenNest
|
|||||||
public bool Fill(NestItem item)
|
public bool Fill(NestItem item)
|
||||||
{
|
{
|
||||||
var workArea = Plate.WorkArea();
|
var workArea = Plate.WorkArea();
|
||||||
return FillArea(workArea, item);
|
var bestRotation = FindBestRotation(item);
|
||||||
|
|
||||||
|
var engine = new FillLinear(workArea, Plate.PartSpacing);
|
||||||
|
|
||||||
|
// Try 4 configurations: 2 rotations x 2 axes.
|
||||||
|
var configs = new[]
|
||||||
|
{
|
||||||
|
engine.Fill(item.Drawing, bestRotation, NestDirection.Horizontal),
|
||||||
|
engine.Fill(item.Drawing, bestRotation, NestDirection.Vertical),
|
||||||
|
engine.Fill(item.Drawing, bestRotation + Angle.HalfPI, NestDirection.Horizontal),
|
||||||
|
engine.Fill(item.Drawing, bestRotation + Angle.HalfPI, NestDirection.Vertical)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Pick the configuration with the most parts.
|
||||||
|
List<Part> best = null;
|
||||||
|
|
||||||
|
foreach (var config in configs)
|
||||||
|
{
|
||||||
|
if (best == null || config.Count > best.Count)
|
||||||
|
best = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (best == null || best.Count == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Limit to requested quantity if specified.
|
||||||
|
if (item.Quantity > 0 && best.Count > item.Quantity)
|
||||||
|
best = best.Take(item.Quantity).ToList();
|
||||||
|
|
||||||
|
Plate.Parts.AddRange(best);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Fill(NestItem item, int maxCount)
|
public bool Fill(NestItem item, int maxCount)
|
||||||
{
|
{
|
||||||
var workArea = Plate.WorkArea();
|
if (maxCount <= 0)
|
||||||
return FillArea(workArea, item, maxCount);
|
return false;
|
||||||
|
|
||||||
|
var savedQty = item.Quantity;
|
||||||
|
item.Quantity = maxCount;
|
||||||
|
var result = Fill(item);
|
||||||
|
item.Quantity = savedQty;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool FillArea(Box box, NestItem item)
|
public bool FillArea(Box box, NestItem item)
|
||||||
@@ -109,42 +145,6 @@ namespace OpenNest
|
|||||||
return parts.Count > 0;
|
return parts.Count > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool FillLinear(NestItem item)
|
|
||||||
{
|
|
||||||
var workArea = Plate.WorkArea();
|
|
||||||
var bestRotation = FindBestRotation(item);
|
|
||||||
|
|
||||||
var engine = new FillLinear(workArea, Plate.PartSpacing);
|
|
||||||
|
|
||||||
// Try 4 configurations: 2 rotations x 2 axes.
|
|
||||||
var configs = new[]
|
|
||||||
{
|
|
||||||
engine.Fill(item.Drawing, bestRotation, NestDirection.Horizontal),
|
|
||||||
engine.Fill(item.Drawing, bestRotation, NestDirection.Vertical),
|
|
||||||
engine.Fill(item.Drawing, bestRotation + Angle.HalfPI, NestDirection.Horizontal),
|
|
||||||
engine.Fill(item.Drawing, bestRotation + Angle.HalfPI, NestDirection.Vertical)
|
|
||||||
};
|
|
||||||
|
|
||||||
// Pick the configuration with the most parts.
|
|
||||||
List<Part> best = null;
|
|
||||||
|
|
||||||
foreach (var config in configs)
|
|
||||||
{
|
|
||||||
if (best == null || config.Count > best.Count)
|
|
||||||
best = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (best == null || best.Count == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Limit to requested quantity if specified.
|
|
||||||
if (item.Quantity > 0 && best.Count > item.Quantity)
|
|
||||||
best = best.Take(item.Quantity).ToList();
|
|
||||||
|
|
||||||
Plate.Parts.AddRange(best);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private double FindBestRotation(NestItem item)
|
private double FindBestRotation(NestItem item)
|
||||||
{
|
{
|
||||||
var entities = ConvertProgram.ToGeometry(item.Drawing.Program)
|
var entities = ConvertProgram.ToGeometry(item.Drawing.Program)
|
||||||
|
|||||||
Reference in New Issue
Block a user