refactor(core): remove Plate.HasOverlappingParts

Its last callers were four strategy tests; they now use
PartOverlapChecker.FindOverlappingPairs, which also reports
contained and stacked parts.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
This commit is contained in:
ajandClaude Fable 5.2 committed 2026-11-12 19:11:37 -05:00
1 parent e5d4337681
commit 9b893c7a09
3 files changed
+7 -41

No files matched your search

-35
View File
@@ -1153,40 +1153,5 @@ namespace OpenNest
return Parts.Where(p => !p.BaseDrawing.IsCutOff).Sum(part => part.BaseDrawing.Area)
/ Area();
}
public bool HasOverlappingParts(out List<Vector> pts)
{
pts = new List<Vector>();
var realParts = Parts.Where(p => !p.BaseDrawing.IsCutOff).ToList();
for (var i = 0; i < realParts.Count; i++)
{
var part1 = realParts[i];
var b1 = part1.BoundingBox;
for (var j = i + 1; j < realParts.Count; j++)
{
var part2 = realParts[j];
var b2 = part2.BoundingBox;
// Skip pairs whose bounding boxes don't meaningfully overlap.
// Floating-point rounding can produce sub-epsilon overlaps for
// parts that are merely edge-touching, so require the overlap
// region to exceed Epsilon in both dimensions.
var overlapX =
System.Math.Min(b1.Right, b2.Right) - System.Math.Max(b1.Left, b2.Left);
var overlapY =
System.Math.Min(b1.Top, b2.Top) - System.Math.Max(b1.Bottom, b2.Bottom);
if (overlapX <= Math.Tolerance.Epsilon || overlapY <= Math.Tolerance.Epsilon)
continue;
if (part1.Intersects(part2, out var pts2))
pts.AddRange(pts2);
}
}
return pts.Count > 0;
}
}
}
@@ -85,13 +85,14 @@ public class StrategyOverlapTests
foreach (var g in rotGroups)
_output.WriteLine($" Rotation {g.Key:F1}°: {g.Count()} parts");
var hasOverlaps = plate.HasOverlappingParts(out var pts);
_output.WriteLine($" Overlaps: {hasOverlaps} ({pts.Count} collision pts)");
var pairs = PartOverlapChecker.FindOverlappingPairs(plate.Parts);
var hasOverlaps = pairs.Count > 0;
_output.WriteLine($" Overlaps: {hasOverlaps} ({pairs.Count} overlapping pairs)");
if (hasOverlaps)
{
failures.Add(
$"{strategy.GetType().Name} ({strategy.Phase}): {pts.Count} collision pts, {count} parts"
$"{strategy.GetType().Name} ({strategy.Phase}): {pairs.Count} overlapping pairs, {count} parts"
);
// Show overlapping pair details
@@ -178,7 +178,7 @@ public class StripeFillerTests
if (parts.Count > 0)
{
plate.Parts.AddRange(parts);
var hasOverlaps = plate.HasOverlappingParts(out _);
var hasOverlaps = PartOverlapChecker.FindOverlappingPairs(plate.Parts).Count > 0;
Assert.False(hasOverlaps, "Stripe fill should not produce overlapping parts");
}
}
@@ -211,7 +211,7 @@ public class StripeFillerTests
if (parts.Count > 0)
{
plate.Parts.AddRange(parts);
var hasOverlaps = plate.HasOverlappingParts(out _);
var hasOverlaps = PartOverlapChecker.FindOverlappingPairs(plate.Parts).Count > 0;
Assert.False(hasOverlaps, "Column fill should not produce overlapping parts");
}
}
@@ -244,7 +244,7 @@ public class StripeFillerTests
Assert.InRange(capped.Count, 6, full.Count - 1);
var plate = new Plate(60, 120) { PartSpacing = 0.5 };
plate.Parts.AddRange(capped);
Assert.False(plate.HasOverlappingParts(out _), "Capped stripe fill overlaps");
Assert.Empty(PartOverlapChecker.FindOverlappingPairs(plate.Parts));
}
[Fact]