fix: stop push at contact boundary and filter edges by direction

RayEdgeDistance returned double.MaxValue for touching vertices (dist ≈ 0),
causing rays from other vertices to hit the far side of stationary parts
and allow movement through obstacles. Now returns 0 when touching so the
distance > 0 check in PushSelected correctly prevents further movement.

Added directional edge filtering using outward normals to discard
back-facing edges before ray checks, reducing line count by ~2/3.
DirectionalDistance now checks both StartPoint and EndPoint per line
to preserve vertices at filtered edge boundaries.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-06 21:42:40 -05:00
parent 49cc65903d
commit 08b31d0797
2 changed files with 100 additions and 9 deletions

View File

@@ -792,9 +792,11 @@ namespace OpenNest.Controls
var stationaryLines = new List<List<Line>>(stationaryParts.Count);
var stationaryBoxes = new List<Box>(stationaryParts.Count);
var opposite = Helper.OppositeDirection(direction);
foreach (var part in stationaryParts)
{
stationaryLines.Add(Helper.GetPartLines(part.BasePart));
stationaryLines.Add(Helper.GetPartLines(part.BasePart, opposite));
stationaryBoxes.Add(part.BoundingBox);
}
@@ -805,8 +807,8 @@ namespace OpenNest.Controls
{
// Get offset lines for the moving part.
var movingLines = Plate.PartSpacing > 0
? Helper.GetOffsetPartLines(selected.BasePart, Plate.PartSpacing)
: Helper.GetPartLines(selected.BasePart);
? Helper.GetOffsetPartLines(selected.BasePart, Plate.PartSpacing, direction)
: Helper.GetPartLines(selected.BasePart, direction);
var movingBox = selected.BoundingBox;