feat: add Plate.GetRemnants() for finding empty edge strips
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -473,5 +473,87 @@ namespace OpenNest
|
|||||||
|
|
||||||
return pts.Count > 0;
|
return pts.Count > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Finds rectangular remnant (empty) regions on the plate.
|
||||||
|
/// Returns strips along edges that are clear of parts.
|
||||||
|
/// </summary>
|
||||||
|
public List<Box> GetRemnants()
|
||||||
|
{
|
||||||
|
var work = WorkArea();
|
||||||
|
var results = new List<Box>();
|
||||||
|
|
||||||
|
if (Parts.Count == 0)
|
||||||
|
{
|
||||||
|
results.Add(work);
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
var obstacles = new List<Box>();
|
||||||
|
foreach (var part in Parts)
|
||||||
|
obstacles.Add(part.BoundingBox.Offset(PartSpacing));
|
||||||
|
|
||||||
|
// Right strip: from the rightmost part edge to the work area right edge
|
||||||
|
var maxRight = double.MinValue;
|
||||||
|
foreach (var box in obstacles)
|
||||||
|
{
|
||||||
|
if (box.Right > maxRight)
|
||||||
|
maxRight = box.Right;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxRight < work.Right)
|
||||||
|
{
|
||||||
|
var strip = new Box(maxRight, work.Bottom, work.Right - maxRight, work.Height);
|
||||||
|
if (strip.Area() > 1.0)
|
||||||
|
results.Add(strip);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Top strip: from the topmost part edge to the work area top edge
|
||||||
|
var maxTop = double.MinValue;
|
||||||
|
foreach (var box in obstacles)
|
||||||
|
{
|
||||||
|
if (box.Top > maxTop)
|
||||||
|
maxTop = box.Top;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxTop < work.Top)
|
||||||
|
{
|
||||||
|
var strip = new Box(work.Left, maxTop, work.Width, work.Top - maxTop);
|
||||||
|
if (strip.Area() > 1.0)
|
||||||
|
results.Add(strip);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bottom strip: from work area bottom to the lowest part edge
|
||||||
|
var minBottom = double.MaxValue;
|
||||||
|
foreach (var box in obstacles)
|
||||||
|
{
|
||||||
|
if (box.Bottom < minBottom)
|
||||||
|
minBottom = box.Bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (minBottom > work.Bottom)
|
||||||
|
{
|
||||||
|
var strip = new Box(work.Left, work.Bottom, work.Width, minBottom - work.Bottom);
|
||||||
|
if (strip.Area() > 1.0)
|
||||||
|
results.Add(strip);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Left strip: from work area left to the leftmost part edge
|
||||||
|
var minLeft = double.MaxValue;
|
||||||
|
foreach (var box in obstacles)
|
||||||
|
{
|
||||||
|
if (box.Left < minLeft)
|
||||||
|
minLeft = box.Left;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (minLeft > work.Left)
|
||||||
|
{
|
||||||
|
var strip = new Box(work.Left, work.Bottom, minLeft - work.Left, work.Height);
|
||||||
|
if (strip.Area() > 1.0)
|
||||||
|
results.Add(strip);
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user