From f568308d1a444b4bf3cf2b65a26ad0cad0d95799 Mon Sep 17 00:00:00 2001 From: AJ Isaacs Date: Mon, 16 Mar 2026 00:32:35 -0400 Subject: [PATCH] feat: add EdgeStartSequencer Co-Authored-By: Claude Sonnet 4.6 --- .../Sequencing/EdgeStartSequencer.cs | 36 +++++++++++++++++++ .../Sequencing/EdgeStartSequencerTests.cs | 31 ++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 OpenNest.Engine/Sequencing/EdgeStartSequencer.cs create mode 100644 OpenNest.Tests/Sequencing/EdgeStartSequencerTests.cs diff --git a/OpenNest.Engine/Sequencing/EdgeStartSequencer.cs b/OpenNest.Engine/Sequencing/EdgeStartSequencer.cs new file mode 100644 index 0000000..187a599 --- /dev/null +++ b/OpenNest.Engine/Sequencing/EdgeStartSequencer.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; +using System.Linq; + +namespace OpenNest.Engine.Sequencing +{ + public class EdgeStartSequencer : IPartSequencer + { + public List Sequence(IReadOnlyList parts, Plate plate) + { + // Plate(width, length) stores Size with Width/Length swapped internally. + // Reconstruct the logical plate box using the BoundingBox origin and the + // corrected extents: Size.Length = X-extent, Size.Width = Y-extent. + var origin = plate.BoundingBox(false); + var plateBox = new OpenNest.Geometry.Box( + origin.X, origin.Y, + plate.Size.Length, + plate.Size.Width); + + return parts + .OrderBy(p => MinEdgeDistance(p.BoundingBox.Center, plateBox)) + .ThenBy(p => p.Location.X) + .Select(p => new SequencedPart { Part = p }) + .ToList(); + } + + private static double MinEdgeDistance(OpenNest.Geometry.Vector center, OpenNest.Geometry.Box plateBox) + { + var distLeft = center.X - plateBox.Left; + var distRight = plateBox.Right - center.X; + var distBottom = center.Y - plateBox.Bottom; + var distTop = plateBox.Top - center.Y; + + return System.Math.Min(System.Math.Min(distLeft, distRight), System.Math.Min(distBottom, distTop)); + } + } +} diff --git a/OpenNest.Tests/Sequencing/EdgeStartSequencerTests.cs b/OpenNest.Tests/Sequencing/EdgeStartSequencerTests.cs new file mode 100644 index 0000000..3f002de --- /dev/null +++ b/OpenNest.Tests/Sequencing/EdgeStartSequencerTests.cs @@ -0,0 +1,31 @@ +using System.Collections.Generic; +using OpenNest.CNC; +using OpenNest.Engine.Sequencing; +using OpenNest.Geometry; +using Xunit; + +namespace OpenNest.Tests.Sequencing; + +public class EdgeStartSequencerTests +{ + private static Part MakePartAt(double x, double y) => TestHelpers.MakePartAt(x, y); + + [Fact] + public void SortsByDistanceFromNearestEdge() + { + var plate = new Plate(60, 120); + var edgePart = MakePartAt(1, 1); + var centerPart = MakePartAt(25, 55); + var midPart = MakePartAt(10, 10); + plate.Parts.Add(edgePart); + plate.Parts.Add(centerPart); + plate.Parts.Add(midPart); + + var sequencer = new EdgeStartSequencer(); + var result = sequencer.Sequence(plate.Parts.ToList(), plate); + + Assert.Same(edgePart, result[0].Part); + Assert.Same(midPart, result[1].Part); + Assert.Same(centerPart, result[2].Part); + } +}