using OpenNest.CNC; using OpenNest.Geometry; namespace OpenNest.Tests.CutOffs; /// /// A new Sheet Cut-Off line runs from its start edge, set by the cut direction, and stops at the /// first crossing line it meets, unless that would leave it too short. /// public class CutOffFirstCrossingTests { private static Plate PlateWithHorizontals(int quadrant, params double[] ys) { var plate = new Plate(48, 96) { Quadrant = quadrant }; foreach (var y in ys) plate.CutOffs.Add(new CutOff(new Vector(0, y), CutOffAxis.Horizontal)); return plate; } private static CutOffEdit Stop(Plate plate, CutOff line, CutDirection direction = CutDirection.AwayFromOrigin) { var edit = CutOffTrim.StopAtFirstCrossing(plate, line, new CutOffSettings { CutDirection = direction }); Assert.True(edit.Succeeded, edit.Refusal); edit.Apply(); return edit; } [Fact] public void AwayFromOrigin_StopsAtTheCrossingNearestTheOrigin() { var plate = PlateWithHorizontals(1, 30, 10); var line = new CutOff(new Vector(40, 25), CutOffAxis.Vertical); Stop(plate, line); Assert.Null(line.StartLimit); Assert.Equal(10, line.EndLimit); } [Fact] public void TowardOrigin_StopsAtTheCrossingNearestTheFarEdge() { var plate = PlateWithHorizontals(1, 30, 10); var line = new CutOff(new Vector(40, 25), CutOffAxis.Vertical); Stop(plate, line, CutDirection.TowardOrigin); Assert.Equal(30, line.StartLimit); Assert.Null(line.EndLimit); } [Fact] public void AwayFromOrigin_StartsAtTheOriginEdgeInAnyQuadrant() { var plate = PlateWithHorizontals(3, -30, -10); var line = new CutOff(new Vector(-40, -25), CutOffAxis.Vertical); Stop(plate, line); Assert.Equal(-10, line.StartLimit); Assert.Null(line.EndLimit); } [Fact] public void HorizontalLineStopsAtTheFirstVertical() { var plate = new Plate(48, 96); plate.CutOffs.Add(new CutOff(new Vector(60, 0), CutOffAxis.Vertical)); plate.CutOffs.Add(new CutOff(new Vector(20, 0), CutOffAxis.Vertical)); var line = new CutOff(new Vector(70, 12), CutOffAxis.Horizontal); Stop(plate, line); Assert.Null(line.StartLimit); Assert.Equal(20, line.EndLimit); } [Fact] public void StaysFullLengthWhenNothingCrossesIt() { var plate = new Plate(48, 96); plate.CutOffs.Add(new CutOff(new Vector(10, 0), CutOffAxis.Vertical)); var line = new CutOff(new Vector(40, 25), CutOffAxis.Vertical); Assert.Empty(Stop(plate, line).Changes); Assert.Null(line.StartLimit); Assert.Null(line.EndLimit); } [Fact] public void ALineStoppedShortOfItDoesNotCross() { var plate = new Plate(48, 96); plate.CutOffs.Add(new CutOff(new Vector(0, 10), CutOffAxis.Horizontal) { EndLimit = 30 }); var line = new CutOff(new Vector(40, 25), CutOffAxis.Vertical); Assert.Empty(Stop(plate, line).Changes); } [Fact] public void StaysFullLengthWhenTheLineLeftWouldBeTooShort() { var plate = PlateWithHorizontals(1, 0.03, 10); var line = new CutOff(new Vector(40, 25), CutOffAxis.Vertical); Assert.Empty(Stop(plate, line).Changes); Assert.Null(line.EndLimit); } [Fact] public void StoppingShortOfTheFarEdgeSaysTheOvercutIsOff() { var plate = PlateWithHorizontals(1, 10); var line = new CutOff(new Vector(40, 25), CutOffAxis.Vertical) { HeadLockOvercut = 1.5 }; Assert.Equal(CutOffTrim.OvercutOff, Stop(plate, line).Notice); } [Fact] public void ReachingTheFarEdgeKeepsTheOvercut() { var plate = PlateWithHorizontals(1, 10); var line = new CutOff(new Vector(40, 25), CutOffAxis.Vertical) { HeadLockOvercut = 1.5 }; Assert.Null(Stop(plate, line, CutDirection.TowardOrigin).Notice); } [Fact] public void TheRegeneratedLineEndsOnTheCrossing() { var plate = PlateWithHorizontals(1, 10); var line = new CutOff(new Vector(40, 25), CutOffAxis.Vertical); Stop(plate, line); plate.CutOffs.Add(line); plate.RegenerateCutOffs(new CutOffSettings()); var moves = line.Drawing.Program.Codes.OfType().ToList(); Assert.Equal(10, moves.Max(move => move.EndPoint.Y), 6); } }