diff --git a/OpenNest.Engine.Tests/Fill/ExpanderCutoffDeltaTests.cs b/OpenNest.Engine.Tests/Fill/ExpanderCutoffDeltaTests.cs index 2d669327..aa70b095 100644 --- a/OpenNest.Engine.Tests/Fill/ExpanderCutoffDeltaTests.cs +++ b/OpenNest.Engine.Tests/Fill/ExpanderCutoffDeltaTests.cs @@ -1,6 +1,7 @@ using OpenNest.CNC; using OpenNest.Converters; using OpenNest.Engine.Fill; +using OpenNest.Engine.Tests.Jobs; using OpenNest.Geometry; using Xunit; @@ -10,16 +11,8 @@ public class ExpanderCutoffDeltaTests { private static Plate Sheet() => new(new Size(30, 30)) { EdgeSpacing = new Spacing(0, 0) }; - private static Program Rectangle(double width = 2, double height = 2) - { - var program = new Program(); - program.MoveTo(0, 0); - program.LineTo(width, 0); - program.LineTo(width, height); - program.LineTo(0, height); - program.LineTo(0, 0); - return program; - } + private static Program Rectangle(double width = 2, double height = 2) => + TestDrawingFactory.Rectangle(width, height); private static Part Add(Plate plate, Program program, double x, double y) { diff --git a/OpenNest.Engine.Tests/Fill/ExpanderCutoffQuadrantTests.cs b/OpenNest.Engine.Tests/Fill/ExpanderCutoffQuadrantTests.cs index 51cefcba..dbcd8d58 100644 --- a/OpenNest.Engine.Tests/Fill/ExpanderCutoffQuadrantTests.cs +++ b/OpenNest.Engine.Tests/Fill/ExpanderCutoffQuadrantTests.cs @@ -1,5 +1,6 @@ using OpenNest.CNC; using OpenNest.Engine.Fill; +using OpenNest.Engine.Tests.Jobs; using OpenNest.Geometry; using Xunit; @@ -7,17 +8,6 @@ namespace OpenNest.Engine.Tests.Fill; public class ExpanderCutoffQuadrantTests { - private static Program Square() - { - var program = new Program(); - program.MoveTo(0, 0); - program.LineTo(2, 0); - program.LineTo(2, 2); - program.LineTo(0, 2); - program.LineTo(0, 0); - return program; - } - public static IEnumerable Cases() { foreach (var quadrant in new[] { 1, 2, 3, 4 }) @@ -42,8 +32,9 @@ public class ExpanderCutoffQuadrantTests quadrant == 3 || quadrant == 4 ? -80 : 0); var anchorPose = origin + new Vector(30, 30); var moverPose = anchorPose + (verticalMotion ? new Vector(0, -3) : new Vector(-3, 0)); - var anchor = new Part(new Drawing("anchor", Square()), anchorPose); - var mover = new Part(new Drawing("mover", Square()), moverPose); + var anchor = new Part( + new Drawing("anchor", TestDrawingFactory.Rectangle(2, 2)), anchorPose); + var mover = new Part(new Drawing("mover", TestDrawingFactory.Rectangle(2, 2)), moverPose); plate.Parts.Add(anchor); plate.Parts.Add(mover); diff --git a/OpenNest.Engine.Tests/Fill/ExpanderFinalQualityTests.cs b/OpenNest.Engine.Tests/Fill/ExpanderFinalQualityTests.cs index 021dd796..44cc74cb 100644 --- a/OpenNest.Engine.Tests/Fill/ExpanderFinalQualityTests.cs +++ b/OpenNest.Engine.Tests/Fill/ExpanderFinalQualityTests.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using OpenNest.CNC; using OpenNest.Converters; using OpenNest.Engine.Fill; +using OpenNest.Engine.Tests.Jobs; using OpenNest.Geometry; using Xunit; @@ -14,17 +15,6 @@ public class ExpanderFinalQualityTests private static Program Disk(double radius) => ConvertGeometry.ToProgram(new List { new Circle(0, 0, radius) }); - private static Program Rectangle(double width, double height) - { - var program = new Program(); - program.MoveTo(0, 0); - program.LineTo(width, 0); - program.LineTo(width, height); - program.LineTo(0, height); - program.LineTo(0, 0); - return program; - } - private static Part Add(Plate plate, Program program, double x, double y) { var part = new Part(new Drawing("neutral", program), new Vector(x, y)); @@ -56,7 +46,7 @@ public class ExpanderFinalQualityTests { var plate = Sheet(); Add(plate, Disk(2), 10, 6); - var mover = Add(plate, Rectangle(1, 1), 12, 5.5); + var mover = Add(plate, TestDrawingFactory.Rectangle(1, 1), 12, 5.5); var result = Expander.Separate(new List { mover }, plate, spacing: 1); Assert.True(result.Converged, $"curved contact pinned: {result.Violations.Count} violations"); Assert.True(result.Positions[0].X >= 13 - 1e-3); @@ -79,7 +69,7 @@ public class ExpanderFinalQualityTests program.LineTo(0, 6 * k); program.LineTo(0, 0); Add(plate, program, 10, 5); - var mover = Add(plate, Rectangle(2 * k, 2 * k), 10 + k, 5 + 3 * k); + var mover = Add(plate, TestDrawingFactory.Rectangle(2 * k, 2 * k), 10 + k, 5 + 3 * k); // Left finger [10,10.0002] × [5.0002,5.0006] intersects the // mover [10.0001,10.0003] × [5.0003,5.0005] in positive area. var result = Expander.Separate(new List { mover }, plate, 0); @@ -92,8 +82,8 @@ public class ExpanderFinalQualityTests public void Expand_RemoteRegeneratedCutoff_MustNotPinUnrelatedGrowth() { var plate = Sheet(); - var anchor = Add(plate, Rectangle(2, 2), 1, 4); - var mover = Add(plate, Rectangle(2, 2), 4, 4); + var anchor = Add(plate, TestDrawingFactory.Rectangle(2, 2), 1, 4); + var mover = Add(plate, TestDrawingFactory.Rectangle(2, 2), 4, 4); plate.CutOffs.Add(new CutOff(new Vector(0, 10), CutOffAxis.Horizontal)); var settings = new CutOffSettings(); plate.RegenerateCutOffs(settings); @@ -114,8 +104,8 @@ public class ExpanderFinalQualityTests public void Expand_RegeneratedCutoffBlocksCrossingEvenWithClearFarEndpoint() { var plate = new Plate(new Size(20, 30)) { EdgeSpacing = new Spacing(0, 0) }; - var anchor = Add(plate, Rectangle(2, 2), 1, 1); - var mover = Add(plate, Rectangle(2, 2), 1, 6); + var anchor = Add(plate, TestDrawingFactory.Rectangle(2, 2), 1, 1); + var mover = Add(plate, TestDrawingFactory.Rectangle(2, 2), 1, 6); plate.CutOffs.Add(new CutOff(new Vector(0, 10), CutOffAxis.Horizontal)); var settings = new CutOffSettings(); plate.RegenerateCutOffs(settings); @@ -134,8 +124,8 @@ public class ExpanderFinalQualityTests public void Expand_OutsideUnchangedMover_MustNotReturnUnqualifiedSuccess() { var plate = Sheet(); - var anchor = Add(plate, Rectangle(2, 2), 1, 4); - var mover = Add(plate, Rectangle(2, 2), 35, 4); + var anchor = Add(plate, TestDrawingFactory.Rectangle(2, 2), 1, 4); + var mover = Add(plate, TestDrawingFactory.Rectangle(2, 2), 35, 4); var result = Expander.Expand(new List { anchor, mover }, plate, new Expander.Options { MaxSpacing = 3 }); diff --git a/OpenNest.Engine.Tests/Fill/ExpanderIntersectingOpenPathTests.cs b/OpenNest.Engine.Tests/Fill/ExpanderIntersectingOpenPathTests.cs index f1936da9..bb4ee921 100644 --- a/OpenNest.Engine.Tests/Fill/ExpanderIntersectingOpenPathTests.cs +++ b/OpenNest.Engine.Tests/Fill/ExpanderIntersectingOpenPathTests.cs @@ -1,5 +1,6 @@ using OpenNest.CNC; using OpenNest.Engine.Fill; +using OpenNest.Engine.Tests.Jobs; using OpenNest.Geometry; using Xunit; @@ -7,17 +8,6 @@ namespace OpenNest.Engine.Tests.Fill; public class ExpanderIntersectingOpenPathTests { - private static Program Square() - { - var program = new Program(); - program.MoveTo(0, 0); - program.LineTo(2, 0); - program.LineTo(2, 2); - program.LineTo(0, 2); - program.LineTo(0, 0); - return program; - } - public static IEnumerable Cases() { foreach (var quadrant in new[] { 1, 2, 3, 4 }) @@ -40,8 +30,8 @@ public class ExpanderIntersectingOpenPathTests }; var expectedA = origin + Swap(40, 40); var expectedB = origin + Swap(43, 40); - var anchor = new Part(new Drawing("anchor", Square()), expectedA); - var mover = new Part(new Drawing("mover", Square()), expectedB); + var anchor = new Part(new Drawing("anchor", TestDrawingFactory.Rectangle(2, 2)), expectedA); + var mover = new Part(new Drawing("mover", TestDrawingFactory.Rectangle(2, 2)), expectedB); plate.Parts.Add(anchor); plate.Parts.Add(mover); diff --git a/OpenNest.Engine.Tests/Fill/ExpanderQualityReviewTests.cs b/OpenNest.Engine.Tests/Fill/ExpanderQualityReviewTests.cs index 1acd79cb..bf14d39d 100644 --- a/OpenNest.Engine.Tests/Fill/ExpanderQualityReviewTests.cs +++ b/OpenNest.Engine.Tests/Fill/ExpanderQualityReviewTests.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using OpenNest.CNC; using OpenNest.Engine.Fill; +using OpenNest.Engine.Tests.Jobs; using OpenNest.Geometry; using Xunit; @@ -8,20 +9,10 @@ namespace OpenNest.Engine.Tests.Fill; public class ExpanderQualityReviewTests { - private static Program Rectangle(double width, double height) - { - var program = new Program(); - program.MoveTo(0, 0); - program.LineTo(width, 0); - program.LineTo(width, height); - program.LineTo(0, height); - program.LineTo(0, 0); - return program; - } - private static Part AddSquare(Plate plate, double x, double y, double size) { - var part = new Part(new Drawing("neutral", Rectangle(size, size)), new Vector(x, y)); + var part = new Part( + new Drawing("neutral", TestDrawingFactory.Rectangle(size, size)), new Vector(x, y)); plate.Parts.Add(part); return part; } @@ -54,7 +45,7 @@ public class ExpanderQualityReviewTests { var plate = MakePlate(30); plate.ClampZones.Add(new ClampZone("tiny", new Box(5, 5, 1e-5, 1e-5))); - var frameProgram = Rectangle(10, 10); + var frameProgram = TestDrawingFactory.Rectangle(10, 10); frameProgram.MoveTo(4, 4); frameProgram.LineTo(6, 4); frameProgram.LineTo(6, 6); diff --git a/OpenNest.Engine.Tests/Fill/ExpanderRemoteObliquePathTests.cs b/OpenNest.Engine.Tests/Fill/ExpanderRemoteObliquePathTests.cs index b1b04e9c..eaa446be 100644 --- a/OpenNest.Engine.Tests/Fill/ExpanderRemoteObliquePathTests.cs +++ b/OpenNest.Engine.Tests/Fill/ExpanderRemoteObliquePathTests.cs @@ -1,5 +1,6 @@ using OpenNest.CNC; using OpenNest.Engine.Fill; +using OpenNest.Engine.Tests.Jobs; using OpenNest.Geometry; using Xunit; @@ -7,17 +8,6 @@ namespace OpenNest.Engine.Tests.Fill; public class ExpanderRemoteObliquePathTests { - private static Program Square() - { - var program = new Program(); - program.MoveTo(0, 0); - program.LineTo(2, 0); - program.LineTo(2, 2); - program.LineTo(0, 2); - program.LineTo(0, 0); - return program; - } - public static IEnumerable Cases() { foreach (var quadrant in new[] { 1, 2, 3, 4 }) @@ -42,8 +32,9 @@ public class ExpanderRemoteObliquePathTests }; var anchorPose = origin + Swap(40, 40); var moverPose = origin + Swap(43, 40); - var anchor = new Part(new Drawing("anchor", Square()), anchorPose); - var mover = new Part(new Drawing("mover", Square()), moverPose); + var anchor = new Part( + new Drawing("anchor", TestDrawingFactory.Rectangle(2, 2)), anchorPose); + var mover = new Part(new Drawing("mover", TestDrawingFactory.Rectangle(2, 2)), moverPose); plate.Parts.Add(anchor); plate.Parts.Add(mover); if (cutoff) diff --git a/OpenNest.Engine.Tests/Fill/ExpanderTests.cs b/OpenNest.Engine.Tests/Fill/ExpanderTests.cs index b550edb1..1458bd5e 100644 --- a/OpenNest.Engine.Tests/Fill/ExpanderTests.cs +++ b/OpenNest.Engine.Tests/Fill/ExpanderTests.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Threading; using OpenNest.CNC; using OpenNest.Engine.Fill; +using OpenNest.Engine.Tests.Jobs; using OpenNest.Geometry; using Xunit; @@ -15,16 +16,8 @@ namespace OpenNest.Engine.Tests.Fill; /// public class ExpanderTests { - private static Program Rectangle(double width = 4, double length = 4) - { - var program = new Program(); - program.MoveTo(0, 0); - program.LineTo(width, 0); - program.LineTo(width, length); - program.LineTo(0, length); - program.LineTo(0, 0); - return program; - } + private static Program Rectangle(double width = 4, double length = 4) => + TestDrawingFactory.Rectangle(width, length); private static Part AddSquare(Plate plate, double x, double y, double size = 4) { diff --git a/OpenNest.Engine.Tests/Jobs/FillStackCharacterizationTests.cs b/OpenNest.Engine.Tests/Jobs/FillStackCharacterizationTests.cs index 8ca79e85..40d63fda 100644 --- a/OpenNest.Engine.Tests/Jobs/FillStackCharacterizationTests.cs +++ b/OpenNest.Engine.Tests/Jobs/FillStackCharacterizationTests.cs @@ -34,19 +34,6 @@ namespace OpenNest.Engine.Tests.Jobs; /// public class FillStackCharacterizationTests { - private static Program LShape() - { - var program = new Program(); - program.MoveTo(0, 0); - program.LineTo(6, 0); - program.LineTo(6, 4); - program.LineTo(3, 4); - program.LineTo(3, 2); - program.LineTo(0, 2); - program.LineTo(0, 0); - return program; - } - /// 6x4 block with a 2x2 notch cut into the middle of its top edge. private static Program Notched() { @@ -63,18 +50,6 @@ public class FillStackCharacterizationTests return program; } - /// D-shape: 3x5 block closed by a semicircular arc. - private static Program ArcPart() - { - var program = new Program(); - program.MoveTo(0, 0); - program.LineTo(3, 0); - program.ArcTo(3, 5, 3, 2.5, RotationType.CCW); - program.LineTo(0, 5); - program.LineTo(0, 0); - return program; - } - /// /// 46 x 3 bar with a stepped end: irregular, and too long for the 48 x 28 work area at all /// but the sweep angles near 0 and 180 degrees, so only those prove productive and get learned. @@ -112,9 +87,9 @@ public class FillStackCharacterizationTests private static Program Shape(string name) => name switch { - "lshape" => LShape(), + "lshape" => TestDrawingFactory.LShape(), "notched" => Notched(), - "arc" => ArcPart(), + "arc" => TestDrawingFactory.ArcPart(), "bar" => LongBar(), "chevron" => Chevron(), _ => TestDrawingFactory.Rectangle(4, 3), @@ -259,9 +234,9 @@ public class FillStackCharacterizationTests /// private static List MixedItems() => [ - new() { Drawing = new Drawing("lshape", LShape()), Quantity = 14 }, + new() { Drawing = new Drawing("lshape", TestDrawingFactory.LShape()), Quantity = 14 }, new() { Drawing = new Drawing("notched", Notched()), Quantity = 9 }, - new() { Drawing = new Drawing("arc", ArcPart()), Quantity = 11 }, + new() { Drawing = new Drawing("arc", TestDrawingFactory.ArcPart()), Quantity = 11 }, new() { Drawing = new Drawing("rect", TestDrawingFactory.Rectangle(4, 3)), Quantity = 1 }, ]; @@ -354,7 +329,11 @@ public class FillStackCharacterizationTests { var plate = MakeClampedPlate(); // A quantity close to a full sheet makes clamp-dropped copies trigger refills. - var item = new NestItem { Drawing = new Drawing("lshape", LShape()), Quantity = 40 }; + var item = new NestItem + { + Drawing = new Drawing("lshape", TestDrawingFactory.LShape()), + Quantity = 40, + }; return Layout( PlateFillService.FillItem( strategy, diff --git a/OpenNest.Engine.Tests/Jobs/FixedStrategyNestingEngineTests.cs b/OpenNest.Engine.Tests/Jobs/FixedStrategyNestingEngineTests.cs index af637e66..2c4483b0 100644 --- a/OpenNest.Engine.Tests/Jobs/FixedStrategyNestingEngineTests.cs +++ b/OpenNest.Engine.Tests/Jobs/FixedStrategyNestingEngineTests.cs @@ -58,19 +58,6 @@ public class FixedStrategyNestingEngineTests Assert.Throws(() => new FixedStrategyNestingEngine(" ")); } - private static Program LShape() - { - var program = new Program(); - program.MoveTo(0, 0); - program.LineTo(6, 0); - program.LineTo(6, 4); - program.LineTo(3, 4); - program.LineTo(3, 2); - program.LineTo(0, 2); - program.LineTo(0, 0); - return program; - } - public static TheoryData LockedRotationCases => new() { @@ -99,7 +86,7 @@ public class FixedStrategyNestingEngineTests "rect-6x4" => TestDrawingFactory.Rectangle(6, 4), "rect-20x3" => TestDrawingFactory.Rectangle(20, 3), "rect-3x20" => TestDrawingFactory.Rectangle(3, 20), - _ => LShape(), + _ => TestDrawingFactory.LShape(), }; var part = new NestJobPart( shape, diff --git a/OpenNest.Engine.Tests/Jobs/GoldenLayoutTests.cs b/OpenNest.Engine.Tests/Jobs/GoldenLayoutTests.cs index fbe7dc9f..35c09ce5 100644 --- a/OpenNest.Engine.Tests/Jobs/GoldenLayoutTests.cs +++ b/OpenNest.Engine.Tests/Jobs/GoldenLayoutTests.cs @@ -29,41 +29,6 @@ public class GoldenLayoutTests { private const double PoseTolerance = 1e-9; - private static Program Rect(double width, double length) - { - var program = new Program(); - program.MoveTo(0, 0); - program.LineTo(width, 0); - program.LineTo(width, length); - program.LineTo(0, length); - program.LineTo(0, 0); - return program; - } - - private static Program LShape() - { - var program = new Program(); - program.MoveTo(0, 0); - program.LineTo(6, 0); - program.LineTo(6, 4); - program.LineTo(3, 4); - program.LineTo(3, 2); - program.LineTo(0, 2); - program.LineTo(0, 0); - return program; - } - - private static Program ArcPart() - { - var program = new Program(); - program.MoveTo(0, 0); - program.LineTo(3, 0); - program.ArcTo(3, 5, 3, 2.5, RotationType.CCW); - program.LineTo(0, 5); - program.LineTo(0, 0); - return program; - } - private static NestJobPart Part(string id, Program program, int quantity) => new(id, PartGeometrySnapshot.FromProgram(program), quantity); @@ -72,10 +37,10 @@ public class GoldenLayoutTests new( new[] { - Part("rect-a", Rect(6, 4), 8), - Part("rect-b", Rect(4, 3), 6), - Part("lshape", LShape(), 3), - Part("arc", ArcPart(), 3), + Part("rect-a", TestDrawingFactory.Rectangle(6, 4), 8), + Part("rect-b", TestDrawingFactory.Rectangle(4, 3), 6), + Part("lshape", TestDrawingFactory.LShape(), 3), + Part("arc", TestDrawingFactory.ArcPart(), 3), }, new[] { new NestPlateStock("stock", new Size(30, 50), 5, 1, new Spacing(1, 1, 1, 1)) }, new NestJobOptions(strategy) @@ -86,9 +51,9 @@ public class GoldenLayoutTests new( new[] { - Part("rect-a", Rect(6, 4), 5), - Part("rect-b", Rect(4, 3), 4), - Part("rect-c", Rect(2, 7), 3), + Part("rect-a", TestDrawingFactory.Rectangle(6, 4), 5), + Part("rect-b", TestDrawingFactory.Rectangle(4, 3), 4), + Part("rect-c", TestDrawingFactory.Rectangle(2, 7), 3), }, new[] { new NestPlateStock("stock", new Size(30, 50), 4, 1, new Spacing(1, 1, 1, 1)) }, new NestJobOptions("Strip") @@ -339,7 +304,11 @@ public class GoldenLayoutTests private static NestJob ProgressJob() => new( - new[] { Part("a", Rect(6, 4), 5), Part("b", Rect(4, 3), 4) }, + new[] + { + Part("a", TestDrawingFactory.Rectangle(6, 4), 5), + Part("b", TestDrawingFactory.Rectangle(4, 3), 4), + }, new[] { new NestPlateStock("small", new Size(14, 14), 4, 1, new Spacing(1, 1, 1, 1)), diff --git a/OpenNest.Engine.Tests/Jobs/TestDrawingFactory.cs b/OpenNest.Engine.Tests/Jobs/TestDrawingFactory.cs index ddb5d510..f9012af6 100644 --- a/OpenNest.Engine.Tests/Jobs/TestDrawingFactory.cs +++ b/OpenNest.Engine.Tests/Jobs/TestDrawingFactory.cs @@ -14,4 +14,30 @@ internal static class TestDrawingFactory program.LineTo(0, 0); return program; } + + /// A 6 x 4 L: a 6 x 2 base with a 3 x 2 block on its right half. + public static Program LShape() + { + var program = new Program(); + program.MoveTo(0, 0); + program.LineTo(6, 0); + program.LineTo(6, 4); + program.LineTo(3, 4); + program.LineTo(3, 2); + program.LineTo(0, 2); + program.LineTo(0, 0); + return program; + } + + /// D-shape: a 3 x 5 block closed on the right by a semicircular arc. + public static Program ArcPart() + { + var program = new Program(); + program.MoveTo(0, 0); + program.LineTo(3, 0); + program.ArcTo(3, 5, 3, 2.5, RotationType.CCW); + program.LineTo(0, 5); + program.LineTo(0, 0); + return program; + } }