Files
OpenNest/OpenNest.Engine/RectanglePacking/PackBottomLeft.cs
AJ Isaacs b738d4c72c refactor: clean up NestEngine — collapse overloads, extract helper, remove dead code
- Fill(NestItem) and Fill(List<Part>) now delegate to their Box overloads
- Add Part.CreateAtOrigin() to replace repeated 4-line build-at-origin pattern
  used in NestEngine, RotationSlideStrategy, and PairEvaluator
- Remove dead code: FillArea overloads, Fill(NestItem, int), FillWithPairs(NestItem),
  ConvertTileResultToParts, PackBottomLeft.FindPointHorizontal, Pattern.GetLines/GetOffsetLines,
  unused count variable in FillNoRotation
- Simplify IsBetterValidFill to delegate to IsBetterFill after overlap check

NestEngine reduced from 717 to 484 lines.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 21:31:15 -05:00

93 lines
2.2 KiB
C#

using System.Collections.Generic;
using System.Linq;
using OpenNest.Geometry;
using OpenNest.Math;
namespace OpenNest.RectanglePacking
{
internal class PackBottomLeft : PackEngine
{
private List<Vector> points;
public PackBottomLeft(Bin bin)
: base(bin)
{
points = new List<Vector>();
}
public override void Pack(List<Item> items)
{
items = items.OrderBy(i => -i.Area()).ToList();
points.Add(Bin.Location);
var skip = new List<int>();
for (int i = 0; i < items.Count; i++)
{
var item = items[i];
if (skip.Contains(item.Id))
continue;
var pt = FindPointVertical(item);
if (pt == null)
{
skip.Add(item.Id);
continue;
}
item.Location = pt.Value;
points.Remove(pt.Value);
points.Add(new Vector(item.Left, item.Top));
points.Add(new Vector(item.Right, item.Bottom));
Bin.Items.Add(item);
}
points.Clear();
}
private Vector? FindPointVertical(Item item)
{
var pt = new Vector(double.MaxValue, double.MaxValue);
for (int i = 0; i < points.Count; i++)
{
var point = points[i];
item.Location = point;
if (!IsValid(item))
continue;
if (point.X < pt.X)
pt = point;
else if (point.X.IsEqualTo(pt.X) && point.Y < pt.Y)
pt = point;
}
if (pt.X != double.MaxValue && pt.Y != double.MaxValue)
return pt;
return null;
}
private bool IsValid(Item item)
{
if (!Bin.Contains(item))
return false;
foreach (var it in Bin.Items)
{
if (item.Intersects(it))
return false;
}
return true;
}
}
}