style: apply CSharpier formatting to all C# sources

Repo-wide sweep with the pinned CSharpier 1.3.0 tool. Whitespace and
line-wrapping only; OpenNest.Engine.Tests (109) and OpenNest.IO.Tests
pass after reformat, full solution builds 0 errors.

Added .csharpierignore so csproj/config XML keeps its existing layout
(CSharpier's XML wrapping churns attributes with zero benefit).

Formatting is now enforceable: dotnet csharpier check . passes.
This commit is contained in:
aj
2026-09-20 16:41:50 -04:00
parent 8e6fa677fb
commit aec0523062
476 changed files with 16592 additions and 7800 deletions
+18 -8
View File
@@ -44,7 +44,9 @@ public class EngineOverlapTests
var item = new NestItem { Drawing = drawing };
var success = engine.Fill(item);
_output.WriteLine($"Engine: {engine.Name}, Parts: {plate.Parts.Count}, Utilization: {plate.Utilization():P1}");
_output.WriteLine(
$"Engine: {engine.Name}, Parts: {plate.Parts.Count}, Utilization: {plate.Utilization():P1}"
);
if (engine is DefaultNestEngine defaultEngine)
{
@@ -54,8 +56,8 @@ public class EngineOverlapTests
}
// Show rotation distribution
var rotGroups = plate.Parts
.GroupBy(p => System.Math.Round(OpenNest.Math.Angle.ToDegrees(p.Rotation), 1))
var rotGroups = plate
.Parts.GroupBy(p => System.Math.Round(OpenNest.Math.Angle.ToDegrees(p.Rotation), 1))
.OrderBy(g => g.Key);
foreach (var g in rotGroups)
_output.WriteLine($" Rotation {g.Key:F1}°: {g.Count()} parts");
@@ -69,20 +71,28 @@ public class EngineOverlapTests
_output.WriteLine($" ({collisionPoints[i].X:F2}, {collisionPoints[i].Y:F2})");
}
Assert.False(hasOverlaps,
$"Engine '{engineName}' produced {collisionPoints.Count} collision point(s) with {plate.Parts.Count} parts");
Assert.False(
hasOverlaps,
$"Engine '{engineName}' produced {collisionPoints.Count} collision point(s) with {plate.Parts.Count} parts"
);
}
[Fact]
public void AdjacentParts_ShouldNotOverlap()
{
var plate = TestHelpers.MakePlate(60, 120,
var plate = TestHelpers.MakePlate(
60,
120,
TestHelpers.MakePartAt(0, 0, 10),
TestHelpers.MakePartAt(10, 0, 10));
TestHelpers.MakePartAt(10, 0, 10)
);
var hasOverlaps = plate.HasOverlappingParts(out var pts);
_output.WriteLine($"Adjacent squares: overlaps={hasOverlaps}, collision count={pts.Count}");
Assert.False(hasOverlaps, "Adjacent edge-touching parts should not be reported as overlapping");
Assert.False(
hasOverlaps,
"Adjacent edge-touching parts should not be reported as overlapping"
);
}
}
@@ -22,7 +22,12 @@ public class EngineRefactorSmokeTests
var engine = new DefaultNestEngine(plate);
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var parts = engine.Fill(item, plate.WorkArea(), null, System.Threading.CancellationToken.None);
var parts = engine.Fill(
item,
plate.WorkArea(),
null,
System.Threading.CancellationToken.None
);
Assert.True(parts.Count > 0, "DefaultNestEngine should fill parts");
}
@@ -35,7 +40,12 @@ public class EngineRefactorSmokeTests
var drawing = MakeRectDrawing(20, 10);
var groupParts = new List<Part> { new Part(drawing) };
var parts = engine.Fill(groupParts, plate.WorkArea(), null, System.Threading.CancellationToken.None);
var parts = engine.Fill(
groupParts,
plate.WorkArea(),
null,
System.Threading.CancellationToken.None
);
Assert.True(parts.Count > 0, "DefaultNestEngine group fill should produce parts");
}
@@ -48,7 +58,12 @@ public class EngineRefactorSmokeTests
engine.ForceFullAngleSweep = true;
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var parts = engine.Fill(item, plate.WorkArea(), null, System.Threading.CancellationToken.None);
var parts = engine.Fill(
item,
plate.WorkArea(),
null,
System.Threading.CancellationToken.None
);
Assert.True(parts.Count > 0, "ForceFullAngleSweep should still produce results");
}
@@ -91,7 +106,11 @@ public class EngineRefactorSmokeTests
var plate = new Plate(60, 120);
var drawing = MakeRectDrawing(20, 10);
var result = OpenNest.Engine.ML.BruteForceRunner.Run(drawing, plate, forceFullAngleSweep: true);
var result = OpenNest.Engine.ML.BruteForceRunner.Run(
drawing,
plate,
forceFullAngleSweep: true
);
Assert.NotNull(result);
Assert.True(result.PartCount > 0);
+173 -74
View File
@@ -1,10 +1,10 @@
using OpenNest.Geometry;
using OpenNest.IO;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using OpenNest.Geometry;
using OpenNest.IO;
using Xunit;
using Xunit.Abstractions;
@@ -18,6 +18,7 @@ public class MultiPlateNesterTests
{
_output = output;
}
private static Drawing MakeDrawing(string name, double width, double length)
{
var program = new OpenNest.CNC.Program();
@@ -33,11 +34,7 @@ public class MultiPlateNesterTests
private static NestItem MakeItem(string name, double width, double length, int qty = 1)
{
return new NestItem
{
Drawing = MakeDrawing(name, width, length),
Quantity = qty,
};
return new NestItem { Drawing = MakeDrawing(name, width, length), Quantity = qty };
}
[Fact]
@@ -62,9 +59,9 @@ public class MultiPlateNesterTests
{
var items = new List<NestItem>
{
MakeItem("short-wide", 50, 20), // longest = 50
MakeItem("tall-narrow", 10, 80), // longest = 80
MakeItem("square", 30, 30), // longest = 30
MakeItem("short-wide", 50, 20), // longest = 50
MakeItem("tall-narrow", 10, 80), // longest = 80
MakeItem("square", 30, 30), // longest = 30
};
var sorted = MultiPlateNester.SortItems(items, PartSortOrder.Size);
@@ -153,8 +150,10 @@ public class MultiPlateNesterTests
// All returned zones should have both dims < 12
foreach (var zone in scrap)
{
Assert.True(zone.Width < 12.0 && zone.Length < 12.0,
$"Zone {zone.Width:F1}x{zone.Length:F1} is not scrap — at least one dimension >= 12");
Assert.True(
zone.Width < 12.0 && zone.Length < 12.0,
$"Zone {zone.Width:F1}x{zone.Length:F1} is not scrap — at least one dimension >= 12"
);
}
}
@@ -164,7 +163,13 @@ public class MultiPlateNesterTests
public void CreatePlate_UsesTemplateWhenNoOptions()
{
var template = new Plate(96, 48) { PartSpacing = 0.25, Quadrant = 1 };
template.EdgeSpacing = new Spacing { Left = 1, Right = 1, Top = 1, Bottom = 1 };
template.EdgeSpacing = new Spacing
{
Left = 1,
Right = 1,
Top = 1,
Bottom = 1,
};
var plate = MultiPlateNester.CreatePlate(template, null, null);
@@ -178,13 +183,34 @@ public class MultiPlateNesterTests
public void CreatePlate_PicksSmallestFittingOption()
{
var template = new Plate(96, 48) { PartSpacing = 0.25, Quadrant = 1 };
template.EdgeSpacing = new Spacing { Left = 1, Right = 1, Top = 1, Bottom = 1 };
template.EdgeSpacing = new Spacing
{
Left = 1,
Right = 1,
Top = 1,
Bottom = 1,
};
var options = new List<PlateOption>
{
new() { Width = 48, Length = 96, Cost = 100 },
new() { Width = 60, Length = 120, Cost = 200 },
new() { Width = 72, Length = 144, Cost = 300 },
new()
{
Width = 48,
Length = 96,
Cost = 100,
},
new()
{
Width = 60,
Length = 120,
Cost = 200,
},
new()
{
Width = 72,
Length = 144,
Cost = 300,
},
};
// Part needs 50x50 work area — 48x96 (after edge spacing: 46x94) — 46 < 50, doesn't fit.
@@ -200,9 +226,24 @@ public class MultiPlateNesterTests
[Fact]
public void EvaluateUpgrade_PrefersCheaperOption()
{
var currentOption = new PlateOption { Width = 48, Length = 96, Cost = 100 };
var upgradeOption = new PlateOption { Width = 60, Length = 120, Cost = 160 };
var newPlateOption = new PlateOption { Width = 48, Length = 96, Cost = 100 };
var currentOption = new PlateOption
{
Width = 48,
Length = 96,
Cost = 100,
};
var upgradeOption = new PlateOption
{
Width = 60,
Length = 120,
Cost = 160,
};
var newPlateOption = new PlateOption
{
Width = 48,
Length = 96,
Cost = 100,
};
// Upgrade cost = 160 - 100 = 60
// New plate cost with 50% utilization, 50% salvage:
@@ -210,7 +251,12 @@ public class MultiPlateNesterTests
// netNewCost = 100 - 25 = 75
// Upgrade (60) < new plate (75), so upgrade wins
var decision = MultiPlateNester.EvaluateUpgradeVsNew(
currentOption, upgradeOption, newPlateOption, 0.5, 0.5);
currentOption,
upgradeOption,
newPlateOption,
0.5,
0.5
);
Assert.True(decision.ShouldUpgrade);
}
@@ -223,19 +269,17 @@ public class MultiPlateNesterTests
var template = new Plate(96, 48) { PartSpacing = 0.25, Quadrant = 1 };
template.EdgeSpacing = new Spacing();
var items = new List<NestItem>
{
MakeItem("big1", 80, 40, 1),
MakeItem("big2", 70, 35, 1),
};
var items = new List<NestItem> { MakeItem("big1", 80, 40, 1), MakeItem("big2", 70, 35, 1) };
var options = new MultiPlateNestOptions { Template = template };
var result = MultiPlateNester.Nest(items, options);
// Each large part should be on its own plate.
Assert.True(result.Plates.Count >= 2,
$"Expected at least 2 plates, got {result.Plates.Count}");
Assert.True(
result.Plates.Count >= 2,
$"Expected at least 2 plates, got {result.Plates.Count}"
);
}
[Fact]
@@ -260,8 +304,10 @@ public class MultiPlateNesterTests
// Both small drawing types should share space — not each on their own plate.
// With consolidation, they pack into remaining space alongside the big part.
Assert.True(result.Plates.Count <= 2,
$"Expected at most 2 plates (small parts consolidated), got {result.Plates.Count}");
Assert.True(
result.Plates.Count <= 2,
$"Expected at most 2 plates (small parts consolidated), got {result.Plates.Count}"
);
Assert.Equal(0, result.UnplacedItems.Count);
}
@@ -271,17 +317,9 @@ public class MultiPlateNesterTests
var template = new Plate(96, 48) { PartSpacing = 0.25, Quadrant = 1 };
template.EdgeSpacing = new Spacing();
var items = new List<NestItem>
{
MakeItem("big1", 80, 40, 1),
MakeItem("big2", 70, 35, 1),
};
var items = new List<NestItem> { MakeItem("big1", 80, 40, 1), MakeItem("big2", 70, 35, 1) };
var options = new MultiPlateNestOptions
{
Template = template,
AllowPlateCreation = false,
};
var options = new MultiPlateNestOptions { Template = template, AllowPlateCreation = false };
var result = MultiPlateNester.Nest(items, options);
@@ -303,15 +341,15 @@ public class MultiPlateNesterTests
// Plate WorkArea: Width=96, Length=48. Half: 48, 24.
// Part 24x22: Length=24 (not > 24), Width=22 (not > 48) — not Large.
// Area = 528 > 4608/9 = 512 — Medium.
var items = new List<NestItem>
{
MakeItem("medium", 24, 22, 1),
};
var items = new List<NestItem> { MakeItem("medium", 24, 22, 1) };
var options = new MultiPlateNestOptions { Template = template };
var result = MultiPlateNester.Nest(items, options,
existingPlates: new List<Plate> { existingPlate });
var result = MultiPlateNester.Nest(
items,
options,
existingPlates: new List<Plate> { existingPlate }
);
// Part should be placed on the existing plate, not a new one.
Assert.Single(result.Plates);
@@ -331,34 +369,43 @@ public class MultiPlateNesterTests
var nest = new NestReader(nestPath).Read();
var template = nest.PlateDefaults.CreateNew();
_output.WriteLine($"Plate: {template.Size.Width}x{template.Size.Length}, " +
$"spacing={template.PartSpacing}, edge=({template.EdgeSpacing.Left},{template.EdgeSpacing.Bottom},{template.EdgeSpacing.Right},{template.EdgeSpacing.Top})");
_output.WriteLine(
$"Plate: {template.Size.Width}x{template.Size.Length}, "
+ $"spacing={template.PartSpacing}, edge=({template.EdgeSpacing.Left},{template.EdgeSpacing.Bottom},{template.EdgeSpacing.Right},{template.EdgeSpacing.Top})"
);
var wa = template.WorkArea();
_output.WriteLine($"Work area: {wa.Width:F1}x{wa.Length:F1}");
_output.WriteLine($"Classification thresholds: Large if dim > {wa.Width / 2:F1} or {wa.Length / 2:F1}, " +
$"Medium if area > {wa.Width * wa.Length / 9:F0}");
_output.WriteLine(
$"Classification thresholds: Large if dim > {wa.Width / 2:F1} or {wa.Length / 2:F1}, "
+ $"Medium if area > {wa.Width * wa.Length / 9:F0}"
);
_output.WriteLine("---");
var items = new List<NestItem>();
foreach (var d in nest.Drawings)
{
var qty = d.Quantity.Required > 0 ? d.Quantity.Required : d.Quantity.Remaining;
if (qty <= 0) qty = 1;
if (qty <= 0)
qty = 1;
var bb = d.Program.BoundingBox();
var classification = MultiPlateNester.Classify(bb, wa);
_output.WriteLine($" {d.Name,-25} {bb.Width:F1}x{bb.Length:F1} (area={bb.Width * bb.Length:F0}) qty={qty} class={classification}");
_output.WriteLine(
$" {d.Name, -25} {bb.Width:F1}x{bb.Length:F1} (area={bb.Width * bb.Length:F0}) qty={qty} class={classification}"
);
items.Add(new NestItem
{
Drawing = d,
Quantity = qty,
StepAngle = d.Constraints.StepAngle,
RotationStart = d.Constraints.StartAngle,
RotationEnd = d.Constraints.EndAngle,
});
items.Add(
new NestItem
{
Drawing = d,
Quantity = qty,
StepAngle = d.Constraints.StepAngle,
RotationStart = d.Constraints.StartAngle,
RotationEnd = d.Constraints.EndAngle,
}
);
}
_output.WriteLine("---");
@@ -366,18 +413,65 @@ public class MultiPlateNesterTests
var plateOptions = new List<PlateOption>
{
new() { Width = 48, Length = 96, Cost = 0 },
new() { Width = 48, Length = 120, Cost = 0 },
new() { Width = 48, Length = 144, Cost = 0 },
new() { Width = 60, Length = 96, Cost = 0 },
new() { Width = 60, Length = 120, Cost = 0 },
new() { Width = 60, Length = 144, Cost = 0 },
new() { Width = 72, Length = 96, Cost = 0 },
new() { Width = 72, Length = 120, Cost = 0 },
new() { Width = 72, Length = 144, Cost = 0 },
new()
{
Width = 48,
Length = 96,
Cost = 0,
},
new()
{
Width = 48,
Length = 120,
Cost = 0,
},
new()
{
Width = 48,
Length = 144,
Cost = 0,
},
new()
{
Width = 60,
Length = 96,
Cost = 0,
},
new()
{
Width = 60,
Length = 120,
Cost = 0,
},
new()
{
Width = 60,
Length = 144,
Cost = 0,
},
new()
{
Width = 72,
Length = 96,
Cost = 0,
},
new()
{
Width = 72,
Length = 120,
Cost = 0,
},
new()
{
Width = 72,
Length = 144,
Cost = 0,
},
};
_output.WriteLine($"Plate options: {string.Join(", ", plateOptions.Select(o => $"{o.Width}x{o.Length}"))}");
_output.WriteLine(
$"Plate options: {string.Join(", ", plateOptions.Select(o => $"{o.Width}x{o.Length}"))}"
);
_output.WriteLine("");
var options = new MultiPlateNestOptions
@@ -393,16 +487,21 @@ public class MultiPlateNesterTests
for (var i = 0; i < result.Plates.Count; i++)
{
var pr = result.Plates[i];
var groups = pr.Parts.GroupBy(p => p.BaseDrawing.Name)
var groups = pr
.Parts.GroupBy(p => p.BaseDrawing.Name)
.Select(g => $"{g.Key} x{g.Count()}")
.ToList();
_output.WriteLine($" Plate {i + 1} ({pr.Plate.Size.Width}x{pr.Plate.Size.Length}): " +
$"{pr.Parts.Count} parts, util={pr.Plate.Utilization():P1} [{string.Join(", ", groups)}]");
_output.WriteLine(
$" Plate {i + 1} ({pr.Plate.Size.Width}x{pr.Plate.Size.Length}): "
+ $"{pr.Parts.Count} parts, util={pr.Plate.Utilization():P1} [{string.Join(", ", groups)}]"
);
}
if (result.UnplacedItems.Count > 0)
{
_output.WriteLine($" Unplaced: {string.Join(", ", result.UnplacedItems.Select(i => $"{i.Drawing.Name} x{i.Quantity}"))}");
_output.WriteLine(
$" Unplaced: {string.Join(", ", result.UnplacedItems.Select(i => $"{i.Drawing.Name} x{i.Quantity}"))}"
);
}
_output.WriteLine($"\nTotal parts placed: {result.Plates.Sum(p => p.Parts.Count)}");
+9 -7
View File
@@ -1,9 +1,9 @@
using System.Threading;
using OpenNest.CNC;
using OpenNest.Engine;
using OpenNest.Engine.BestFit;
using OpenNest.Geometry;
using OpenNest.Math;
using System.Threading;
namespace OpenNest.Tests.Engine;
@@ -31,18 +31,20 @@ public class NestInvarianceTests
return new Drawing("L", pgm);
}
private static Plate MakePlate() => new Plate(new Size(500, 500))
{
Quadrant = 1,
PartSpacing = 2,
};
private static Plate MakePlate() =>
new Plate(new Size(500, 500)) { Quadrant = 1, PartSpacing = 2 };
private static int RunFillCount(Drawing drawing, Plate plate)
{
BestFitCache.Clear();
var engine = new DefaultNestEngine(plate);
var item = new NestItem { Drawing = drawing };
var parts = engine.Fill(item, plate.WorkArea(), progress: null, token: CancellationToken.None);
var parts = engine.Fill(
item,
plate.WorkArea(),
progress: null,
token: CancellationToken.None
);
return parts?.Count ?? 0;
}
+33 -16
View File
@@ -30,15 +30,26 @@ public class PartClassifierTests
var result = PartClassifier.Classify(drawing);
Assert.Equal(PartType.Rectangle, result.Type);
Assert.True(result.Rectangularity >= 0.99, $"Expected rectangularity>=0.99, got {result.Rectangularity:F4}");
Assert.True(result.PerimeterRatio >= 0.99, $"Expected perimeterRatio>=0.99, got {result.PerimeterRatio:F4}");
Assert.True(
result.Rectangularity >= 0.99,
$"Expected rectangularity>=0.99, got {result.Rectangularity:F4}"
);
Assert.True(
result.PerimeterRatio >= 0.99,
$"Expected perimeterRatio>=0.99, got {result.PerimeterRatio:F4}"
);
}
[Fact]
public void Classify_RoundedRectangle_ReturnsRectangle()
{
// Use the built-in shape builder so arc geometry is constructed correctly.
var shape = new RoundedRectangleShape { Length = 100, Width = 50, Radius = 5 };
var shape = new RoundedRectangleShape
{
Length = 100,
Width = 50,
Radius = 5,
};
var drawing = shape.GetDrawing();
var result = PartClassifier.Classify(drawing);
@@ -54,14 +65,14 @@ public class PartClassifierTests
var pgm = new OpenNest.CNC.Program();
pgm.Codes.Add(new RapidMove(new Vector(0, 0)));
// Bottom edge left section -> notch -> bottom edge right section
pgm.Codes.Add(new LinearMove(new Vector(45, 0))); // along bottom to notch start
pgm.Codes.Add(new LinearMove(new Vector(45, 2))); // up into notch
pgm.Codes.Add(new LinearMove(new Vector(50, 2))); // across notch (5 wide)
pgm.Codes.Add(new LinearMove(new Vector(50, 0))); // back down
pgm.Codes.Add(new LinearMove(new Vector(100, 0))); // remainder of bottom edge
pgm.Codes.Add(new LinearMove(new Vector(45, 0))); // along bottom to notch start
pgm.Codes.Add(new LinearMove(new Vector(45, 2))); // up into notch
pgm.Codes.Add(new LinearMove(new Vector(50, 2))); // across notch (5 wide)
pgm.Codes.Add(new LinearMove(new Vector(50, 0))); // back down
pgm.Codes.Add(new LinearMove(new Vector(100, 0))); // remainder of bottom edge
pgm.Codes.Add(new LinearMove(new Vector(100, 50))); // right edge
pgm.Codes.Add(new LinearMove(new Vector(0, 50))); // top edge
pgm.Codes.Add(new LinearMove(new Vector(0, 0))); // left edge back to start
pgm.Codes.Add(new LinearMove(new Vector(0, 50))); // top edge
pgm.Codes.Add(new LinearMove(new Vector(0, 0))); // left edge back to start
var drawing = new Drawing("rect-notch", pgm);
var result = PartClassifier.Classify(drawing);
@@ -78,8 +89,10 @@ public class PartClassifierTests
var result = PartClassifier.Classify(drawing);
Assert.Equal(PartType.Circle, result.Type);
Assert.True(result.Circularity >= PartClassifier.CircularityThreshold,
$"Expected circularity>={PartClassifier.CircularityThreshold}, got {result.Circularity:F4}");
Assert.True(
result.Circularity >= PartClassifier.CircularityThreshold,
$"Expected circularity>={PartClassifier.CircularityThreshold}, got {result.Circularity:F4}"
);
}
[Fact]
@@ -151,8 +164,10 @@ public class PartClassifierTests
var result = PartClassifier.Classify(drawing);
Assert.Equal(PartType.Irregular, result.Type);
Assert.True(result.PerimeterRatio < PartClassifier.PerimeterRatioThreshold,
$"Expected perimeterRatio<{PartClassifier.PerimeterRatioThreshold}, got {result.PerimeterRatio:F4}");
Assert.True(
result.PerimeterRatio < PartClassifier.PerimeterRatioThreshold,
$"Expected perimeterRatio<{PartClassifier.PerimeterRatioThreshold}, got {result.PerimeterRatio:F4}"
);
}
[Fact]
@@ -186,8 +201,10 @@ public class PartClassifierTests
var result = PartClassifier.Classify(drawing);
// The MBR must be tilted — primary angle should be non-zero.
Assert.True(System.Math.Abs(result.PrimaryAngle) > 0.01,
$"Expected non-zero primary angle for 30°-tilted rect, got {result.PrimaryAngle:F4} rad");
Assert.True(
System.Math.Abs(result.PrimaryAngle) > 0.01,
$"Expected non-zero primary angle for 30°-tilted rect, got {result.PrimaryAngle:F4} rad"
);
}
[Fact]
+59 -14
View File
@@ -20,14 +20,24 @@ public class PlateOptimizerTests
{
var options = new List<PlateOption>
{
new() { Width = 20, Length = 20, Cost = 100 },
new() { Width = 40, Length = 40, Cost = 400 },
new()
{
Width = 20,
Length = 20,
Cost = 100,
},
new()
{
Width = 40,
Length = 40,
Cost = 400,
},
};
var templatePlate = new Plate(40, 40) { PartSpacing = 0 };
var items = new List<NestItem>
{
new() { Drawing = MakeRectDrawing(10, 10), Quantity = 1 }
new() { Drawing = MakeRectDrawing(10, 10), Quantity = 1 },
};
var result = PlateOptimizer.Optimize(items, options, 0.0, templatePlate);
@@ -42,14 +52,24 @@ public class PlateOptimizerTests
{
var options = new List<PlateOption>
{
new() { Width = 12, Length = 12, Cost = 50 },
new() { Width = 24, Length = 12, Cost = 100 },
new()
{
Width = 12,
Length = 12,
Cost = 50,
},
new()
{
Width = 24,
Length = 12,
Cost = 100,
},
};
var templatePlate = new Plate(24, 12) { PartSpacing = 0 };
var items = new List<NestItem>
{
new() { Drawing = MakeRectDrawing(10, 10), Quantity = 2 }
new() { Drawing = MakeRectDrawing(10, 10), Quantity = 2 },
};
var result = PlateOptimizer.Optimize(items, options, 0.0, templatePlate);
@@ -68,15 +88,25 @@ public class PlateOptimizerTests
// Net = 800 - 1500*(800/1600)*1.0 = 800-750 = 50
var options = new List<PlateOption>
{
new() { Width = 20, Length = 20, Cost = 400 },
new() { Width = 40, Length = 40, Cost = 800 },
new()
{
Width = 20,
Length = 20,
Cost = 400,
},
new()
{
Width = 40,
Length = 40,
Cost = 800,
},
};
var templatePlate = new Plate(40, 40) { PartSpacing = 0 };
templatePlate.EdgeSpacing = new Spacing();
var items = new List<NestItem>
{
new() { Drawing = MakeRectDrawing(10, 10), Quantity = 1 }
new() { Drawing = MakeRectDrawing(10, 10), Quantity = 1 },
};
var result = PlateOptimizer.Optimize(items, options, 1.0, templatePlate);
@@ -90,14 +120,24 @@ public class PlateOptimizerTests
{
var options = new List<PlateOption>
{
new() { Width = 20, Length = 20, Cost = 100 },
new() { Width = 40, Length = 40, Cost = 400 },
new()
{
Width = 20,
Length = 20,
Cost = 100,
},
new()
{
Width = 40,
Length = 40,
Cost = 400,
},
};
var templatePlate = new Plate(40, 40) { PartSpacing = 0 };
var items = new List<NestItem>
{
new() { Drawing = MakeRectDrawing(30, 30), Quantity = 1 }
new() { Drawing = MakeRectDrawing(30, 30), Quantity = 1 },
};
var result = PlateOptimizer.Optimize(items, options, 0.0, templatePlate);
@@ -111,13 +151,18 @@ public class PlateOptimizerTests
{
var options = new List<PlateOption>
{
new() { Width = 10, Length = 10, Cost = 50 },
new()
{
Width = 10,
Length = 10,
Cost = 50,
},
};
var templatePlate = new Plate(10, 10) { PartSpacing = 0 };
var items = new List<NestItem>
{
new() { Drawing = MakeRectDrawing(20, 20), Quantity = 1 }
new() { Drawing = MakeRectDrawing(20, 20), Quantity = 1 },
};
var result = PlateOptimizer.Optimize(items, options, 0.0, templatePlate);
+7 -10
View File
@@ -20,7 +20,7 @@ public class PlateProcessorTests
var processor = new PlateProcessor
{
Sequencer = new RightSideSequencer(),
RapidPlanner = new SafeHeightRapidPlanner()
RapidPlanner = new SafeHeightRapidPlanner(),
};
var result = processor.Process(plate);
@@ -40,7 +40,7 @@ public class PlateProcessorTests
var processor = new PlateProcessor
{
Sequencer = new RightSideSequencer(),
RapidPlanner = new SafeHeightRapidPlanner()
RapidPlanner = new SafeHeightRapidPlanner(),
};
var result = processor.Process(plate);
@@ -60,11 +60,8 @@ public class PlateProcessorTests
var processor = new PlateProcessor
{
Sequencer = new LeftSideSequencer(),
CuttingStrategy = new ContourCuttingStrategy
{
Parameters = new CuttingParameters()
},
RapidPlanner = new SafeHeightRapidPlanner()
CuttingStrategy = new ContourCuttingStrategy { Parameters = new CuttingParameters() },
RapidPlanner = new SafeHeightRapidPlanner(),
};
var result = processor.Process(plate);
@@ -83,7 +80,7 @@ public class PlateProcessorTests
var processor = new PlateProcessor
{
Sequencer = new LeftSideSequencer(),
RapidPlanner = new SafeHeightRapidPlanner()
RapidPlanner = new SafeHeightRapidPlanner(),
};
var result = processor.Process(plate);
@@ -101,7 +98,7 @@ public class PlateProcessorTests
var processor = new PlateProcessor
{
Sequencer = new LeftSideSequencer(),
RapidPlanner = new SafeHeightRapidPlanner()
RapidPlanner = new SafeHeightRapidPlanner(),
};
var result = processor.Process(plate);
@@ -117,7 +114,7 @@ public class PlateProcessorTests
var processor = new PlateProcessor
{
Sequencer = new LeftSideSequencer(),
RapidPlanner = new SafeHeightRapidPlanner()
RapidPlanner = new SafeHeightRapidPlanner(),
};
var result = processor.Process(plate);
+32 -8
View File
@@ -42,7 +42,12 @@ public class RemnantEngineTests
var engine = new VerticalRemnantEngine(plate);
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var parts = engine.Fill(item, plate.WorkArea(), null, System.Threading.CancellationToken.None);
var parts = engine.Fill(
item,
plate.WorkArea(),
null,
System.Threading.CancellationToken.None
);
Assert.True(parts.Count > 0, "VerticalRemnantEngine should fill parts");
}
@@ -54,7 +59,12 @@ public class RemnantEngineTests
var engine = new HorizontalRemnantEngine(plate);
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var parts = engine.Fill(item, plate.WorkArea(), null, System.Threading.CancellationToken.None);
var parts = engine.Fill(
item,
plate.WorkArea(),
null,
System.Threading.CancellationToken.None
);
Assert.True(parts.Count > 0, "HorizontalRemnantEngine should fill parts");
}
@@ -77,16 +87,30 @@ public class RemnantEngineTests
var defaultEngine = new DefaultNestEngine(plate);
var remnantEngine = new VerticalRemnantEngine(plate);
var defaultParts = defaultEngine.Fill(item, plate.WorkArea(), null, System.Threading.CancellationToken.None);
var remnantParts = remnantEngine.Fill(item, plate.WorkArea(), null, System.Threading.CancellationToken.None);
var defaultParts = defaultEngine.Fill(
item,
plate.WorkArea(),
null,
System.Threading.CancellationToken.None
);
var remnantParts = remnantEngine.Fill(
item,
plate.WorkArea(),
null,
System.Threading.CancellationToken.None
);
Assert.True(defaultParts.Count > 0);
Assert.True(remnantParts.Count > 0);
var defaultXExtent = defaultParts.Max(p => p.BoundingBox.Right) - defaultParts.Min(p => p.BoundingBox.Left);
var remnantXExtent = remnantParts.Max(p => p.BoundingBox.Right) - remnantParts.Min(p => p.BoundingBox.Left);
var defaultXExtent =
defaultParts.Max(p => p.BoundingBox.Right) - defaultParts.Min(p => p.BoundingBox.Left);
var remnantXExtent =
remnantParts.Max(p => p.BoundingBox.Right) - remnantParts.Min(p => p.BoundingBox.Left);
Assert.True(remnantXExtent <= defaultXExtent + 0.01,
$"Remnant X-extent ({remnantXExtent:F1}) should be <= default ({defaultXExtent:F1})");
Assert.True(
remnantXExtent <= defaultXExtent + 0.01,
$"Remnant X-extent ({remnantXExtent:F1}) should be <= default ({defaultXExtent:F1})"
);
}
}