From 823320e9828a285ee2d2ef551c6ef20e0b46de5a Mon Sep 17 00:00:00 2001 From: AJ Isaacs Date: Sun, 15 Mar 2026 17:29:29 -0400 Subject: [PATCH] fix(engine): use reverse-gap check in Compactor to handle irregular shapes The forward bounding-box gap check (gap < 0) incorrectly skipped obstacles for irregular shapes like SULLYS-003 whose narrow handle extends past an adjacent part's BB edge while the wide body still needs contact detection. Replaced with a reverse-direction gap check that only skips obstacles the moving part has entirely cleared. Also fixed edge distance check to prevent overshooting the work area boundary when already at the limit. Co-Authored-By: Claude Opus 4.6 (1M context) --- OpenNest.Engine/Compactor.cs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/OpenNest.Engine/Compactor.cs b/OpenNest.Engine/Compactor.cs index 4a4f781..89f4018 100644 --- a/OpenNest.Engine/Compactor.cs +++ b/OpenNest.Engine/Compactor.cs @@ -93,10 +93,15 @@ namespace OpenNest var workArea = plate.WorkArea(); var distance = double.MaxValue; + // BB gap at which offset geometries are expected to be touching. + var contactGap = (halfSpacing + ChordTolerance) * 2; + foreach (var moving in movingParts) { var edgeDist = Helper.EdgeDistance(moving.BoundingBox, workArea, direction); - if (edgeDist > 0 && edgeDist < distance) + if (edgeDist <= 0) + distance = 0; + else if (edgeDist < distance) distance = edgeDist; var movingBox = moving.BoundingBox; @@ -104,8 +109,16 @@ namespace OpenNest for (var i = 0; i < obstacleBoxes.Length; i++) { + // Use the reverse-direction gap to check if the obstacle is entirely + // behind the moving part. The forward gap (gap < 0) is unreliable for + // irregular shapes whose bounding boxes overlap even when the actual + // geometry still has a valid contact in the push direction. + var reverseGap = Helper.DirectionalGap(movingBox, obstacleBoxes[i], opposite); + if (reverseGap > 0) + continue; + var gap = Helper.DirectionalGap(movingBox, obstacleBoxes[i], direction); - if (gap < 0 || gap >= distance) + if (gap >= distance) continue; var perpOverlap = isHorizontal