refactor: use ShapeProfile perimeter for boundary and intersection
Replace shape-list iteration with ShapeProfile.Perimeter in both Part.Intersects and PartBoundary, simplifying the logic and ensuring only the outermost contour is used for collision detection. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -149,31 +149,25 @@ namespace OpenNest
|
|||||||
pts = new List<Vector>();
|
pts = new List<Vector>();
|
||||||
|
|
||||||
var entities1 = ConvertProgram.ToGeometry(Program)
|
var entities1 = ConvertProgram.ToGeometry(Program)
|
||||||
.Where(e => e.Layer != SpecialLayers.Rapid);
|
.Where(e => e.Layer != SpecialLayers.Rapid)
|
||||||
|
.ToList();
|
||||||
var entities2 = ConvertProgram.ToGeometry(part.Program)
|
var entities2 = ConvertProgram.ToGeometry(part.Program)
|
||||||
.Where(e => e.Layer != SpecialLayers.Rapid);
|
.Where(e => e.Layer != SpecialLayers.Rapid)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
var shapes1 = Helper.GetShapes(entities1);
|
if (entities1.Count == 0 || entities2.Count == 0)
|
||||||
var shapes2 = Helper.GetShapes(entities2);
|
return false;
|
||||||
|
|
||||||
shapes1.ForEach(shape => shape.Offset(Location));
|
var perimeter1 = new ShapeProfile(entities1).Perimeter;
|
||||||
shapes2.ForEach(shape => shape.Offset(part.Location));
|
var perimeter2 = new ShapeProfile(entities2).Perimeter;
|
||||||
|
|
||||||
for (int i = 0; i < shapes1.Count; i++)
|
if (perimeter1 == null || perimeter2 == null)
|
||||||
{
|
return false;
|
||||||
var shape1 = shapes1[i];
|
|
||||||
|
|
||||||
for (int j = 0; j < shapes2.Count; j++)
|
perimeter1.Offset(Location);
|
||||||
{
|
perimeter2.Offset(part.Location);
|
||||||
var shape2 = shapes2[j];
|
|
||||||
List<Vector> pts2;
|
|
||||||
|
|
||||||
if (shape1.Intersects(shape2, out pts2))
|
return perimeter1.Intersects(perimeter2, out pts);
|
||||||
pts.AddRange(pts2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return pts.Count > 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public double Left
|
public double Left
|
||||||
|
|||||||
@@ -23,22 +23,26 @@ namespace OpenNest
|
|||||||
|
|
||||||
public PartBoundary(Part part, double spacing)
|
public PartBoundary(Part part, double spacing)
|
||||||
{
|
{
|
||||||
var entities = ConvertProgram.ToGeometry(part.Program);
|
var entities = ConvertProgram.ToGeometry(part.Program)
|
||||||
var shapes = Helper.GetShapes(entities.Where(e => e.Layer != SpecialLayers.Rapid));
|
.Where(e => e.Layer != SpecialLayers.Rapid)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
var definedShape = new ShapeProfile(entities);
|
||||||
|
var perimeter = definedShape.Perimeter;
|
||||||
_polygons = new List<Polygon>();
|
_polygons = new List<Polygon>();
|
||||||
|
|
||||||
foreach (var shape in shapes)
|
if (perimeter != null)
|
||||||
{
|
{
|
||||||
var offsetEntity = shape.OffsetEntity(spacing, OffsetSide.Left) as Shape;
|
var offsetEntity = perimeter.OffsetEntity(spacing, OffsetSide.Left) as Shape;
|
||||||
|
|
||||||
if (offsetEntity == null)
|
if (offsetEntity != null)
|
||||||
continue;
|
{
|
||||||
|
// Circumscribe arcs so polygon vertices are always outside
|
||||||
// Circumscribe arcs so polygon vertices are always outside
|
// the true arc — guarantees the boundary never under-estimates.
|
||||||
// the true arc — guarantees the boundary never under-estimates.
|
var polygon = offsetEntity.ToPolygonWithTolerance(PolygonTolerance, circumscribe: true);
|
||||||
var polygon = offsetEntity.ToPolygonWithTolerance(PolygonTolerance, circumscribe: true);
|
polygon.RemoveSelfIntersections();
|
||||||
polygon.RemoveSelfIntersections();
|
_polygons.Add(polygon);
|
||||||
_polygons.Add(polygon);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PrecomputeDirectionalEdges(
|
PrecomputeDirectionalEdges(
|
||||||
|
|||||||
Reference in New Issue
Block a user