feat(engine): generalize Compactor.Push to support arbitrary angles and BB-only mode
Add Vector-based overloads to SpatialQuery (ray casting, edge distance, directional gap, perpendicular overlap) and PartGeometry (directional line filtering) to support pushing parts along any angle, not just cardinal directions. Add Compactor.PushBoundingBox for fast coarse positioning using only bounding box gaps. ActionClone shift+click now uses a two-phase strategy: BB push first to skip past irregular geometry snags, then geometry push to settle against actual contours. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -85,6 +85,73 @@ namespace OpenNest
|
||||
return lines;
|
||||
}
|
||||
|
||||
public static List<Line> GetPartLines(Part part, Vector facingDirection, double chordTolerance = 0.001)
|
||||
{
|
||||
var entities = ConvertProgram.ToGeometry(part.Program);
|
||||
var shapes = ShapeBuilder.GetShapes(entities.Where(e => e.Layer != SpecialLayers.Rapid));
|
||||
var lines = new List<Line>();
|
||||
|
||||
foreach (var shape in shapes)
|
||||
{
|
||||
var polygon = shape.ToPolygonWithTolerance(chordTolerance);
|
||||
polygon.Offset(part.Location);
|
||||
lines.AddRange(GetDirectionalLines(polygon, facingDirection));
|
||||
}
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
public static List<Line> GetOffsetPartLines(Part part, double spacing, Vector facingDirection, double chordTolerance = 0.001)
|
||||
{
|
||||
var entities = ConvertProgram.ToGeometry(part.Program);
|
||||
var shapes = ShapeBuilder.GetShapes(entities.Where(e => e.Layer != SpecialLayers.Rapid));
|
||||
var lines = new List<Line>();
|
||||
|
||||
foreach (var shape in shapes)
|
||||
{
|
||||
var offsetEntity = shape.OffsetEntity(spacing + chordTolerance, OffsetSide.Left) as Shape;
|
||||
|
||||
if (offsetEntity == null)
|
||||
continue;
|
||||
|
||||
var polygon = offsetEntity.ToPolygonWithTolerance(chordTolerance);
|
||||
polygon.RemoveSelfIntersections();
|
||||
polygon.Offset(part.Location);
|
||||
lines.AddRange(GetDirectionalLines(polygon, facingDirection));
|
||||
}
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns only polygon edges whose outward normal faces the specified direction vector.
|
||||
/// </summary>
|
||||
private static List<Line> GetDirectionalLines(Polygon polygon, Vector direction)
|
||||
{
|
||||
if (polygon.Vertices.Count < 3)
|
||||
return polygon.ToLines();
|
||||
|
||||
var sign = polygon.RotationDirection() == RotationType.CCW ? 1.0 : -1.0;
|
||||
var lines = new List<Line>();
|
||||
var last = polygon.Vertices[0];
|
||||
|
||||
for (var i = 1; i < polygon.Vertices.Count; i++)
|
||||
{
|
||||
var current = polygon.Vertices[i];
|
||||
var edx = current.X - last.X;
|
||||
var edy = current.Y - last.Y;
|
||||
|
||||
var keep = sign * (edy * direction.X - edx * direction.Y) > 0;
|
||||
|
||||
if (keep)
|
||||
lines.Add(new Line(last, current));
|
||||
|
||||
last = current;
|
||||
}
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns only polygon edges whose outward normal faces the specified direction.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user