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
@@ -6,39 +6,43 @@ namespace OpenNest.Tests.Cincinnati;
public class CincinnatiFeatureWriterTests
{
private static CincinnatiPostConfig DefaultConfig() => new()
{
UseLineNumbers = true,
FeatureLineNumberStart = 1,
UseAntiDive = true,
KerfCompensation = KerfMode.ControllerSide,
DefaultKerfSide = KerfSide.Left,
ProcessParameterMode = G89Mode.LibraryFile,
InteriorM47 = M47Mode.Always,
ExteriorM47 = M47Mode.Always,
UseSpeedGas = false,
PostedAccuracy = 4,
SafetyHeadraiseDistance = 2000
};
private static FeatureContext SimpleContext(List<ICode>? codes = null) => new()
{
Codes = codes ?? new List<ICode>
private static CincinnatiPostConfig DefaultConfig() =>
new()
{
new RapidMove(13.401, 57.4895),
new LinearMove(14.0, 57.5) { Layer = LayerType.Leadin },
new LinearMove(20.0, 57.5) { Layer = LayerType.Cut }
},
FeatureNumber = 1,
PartName = "BRACKET",
IsFirstFeatureOfPart = true,
IsLastFeatureOnSheet = false,
IsSafetyHeadraise = false,
IsExteriorFeature = false,
LibraryFile = "MILD10",
CutDistance = 18.0,
SheetDiagonal = 30.0
};
UseLineNumbers = true,
FeatureLineNumberStart = 1,
UseAntiDive = true,
KerfCompensation = KerfMode.ControllerSide,
DefaultKerfSide = KerfSide.Left,
ProcessParameterMode = G89Mode.LibraryFile,
InteriorM47 = M47Mode.Always,
ExteriorM47 = M47Mode.Always,
UseSpeedGas = false,
PostedAccuracy = 4,
SafetyHeadraiseDistance = 2000,
};
private static FeatureContext SimpleContext(List<ICode>? codes = null) =>
new()
{
Codes =
codes
?? new List<ICode>
{
new RapidMove(13.401, 57.4895),
new LinearMove(14.0, 57.5) { Layer = LayerType.Leadin },
new LinearMove(20.0, 57.5) { Layer = LayerType.Cut },
},
FeatureNumber = 1,
PartName = "BRACKET",
IsFirstFeatureOfPart = true,
IsLastFeatureOnSheet = false,
IsSafetyHeadraise = false,
IsExteriorFeature = false,
LibraryFile = "MILD10",
CutDistance = 18.0,
SheetDiagonal = 30.0,
};
private static string WriteFeature(CincinnatiPostConfig config, FeatureContext ctx)
{
@@ -229,7 +233,10 @@ public class CincinnatiFeatureWriterTests
endPoint: new Vector(10.0, 20.0),
centerPoint: new Vector(15.0, 20.0),
rotation: RotationType.CW
) { Layer = LayerType.Cut }
)
{
Layer = LayerType.Cut,
},
};
var ctx = SimpleContext(codes);
@@ -247,12 +254,18 @@ public class CincinnatiFeatureWriterTests
var cwCodes = new List<ICode>
{
new RapidMove(10.0, 20.0),
new ArcMove(new Vector(20.0, 20.0), new Vector(15.0, 20.0), RotationType.CW) { Layer = LayerType.Cut }
new ArcMove(new Vector(20.0, 20.0), new Vector(15.0, 20.0), RotationType.CW)
{
Layer = LayerType.Cut,
},
};
var ccwCodes = new List<ICode>
{
new RapidMove(10.0, 20.0),
new ArcMove(new Vector(20.0, 20.0), new Vector(15.0, 20.0), RotationType.CCW) { Layer = LayerType.Cut }
new ArcMove(new Vector(20.0, 20.0), new Vector(15.0, 20.0), RotationType.CCW)
{
Layer = LayerType.Cut,
},
};
var cwOutput = WriteFeature(config, SimpleContext(cwCodes));
@@ -350,7 +363,7 @@ public class CincinnatiFeatureWriterTests
{
new RapidMove(1.0, 1.0),
new LinearMove(2.0, 1.0) { Layer = LayerType.Leadin },
new LinearMove(3.0, 1.0) { Layer = LayerType.Cut }
new LinearMove(3.0, 1.0) { Layer = LayerType.Cut },
};
var ctx = SimpleContext(codes);
ctx.IsEtch = true;
@@ -372,7 +385,7 @@ public class CincinnatiFeatureWriterTests
new RapidMove(1.0, 1.0),
new LinearMove(2.0, 1.0) { Layer = LayerType.Cut },
new LinearMove(3.0, 1.0) { Layer = LayerType.Cut },
new LinearMove(4.0, 1.0) { Layer = LayerType.Cut }
new LinearMove(4.0, 1.0) { Layer = LayerType.Cut },
};
var ctx = SimpleContext(codes);
var output = WriteFeature(config, ctx);
@@ -390,7 +403,7 @@ public class CincinnatiFeatureWriterTests
var codes = new List<ICode>
{
new RapidMove(1.0, 1.0),
new LinearMove(2.0, 1.0) { Layer = LayerType.Leadin }
new LinearMove(2.0, 1.0) { Layer = LayerType.Leadin },
};
var ctx = SimpleContext(codes);
var output = WriteFeature(config, ctx);
@@ -407,7 +420,10 @@ public class CincinnatiFeatureWriterTests
var codes = new List<ICode>
{
new RapidMove(10.0, 20.0),
new ArcMove(new Vector(10.0, 20.0), new Vector(15.0, 20.0), RotationType.CW) { Layer = LayerType.Cut }
new ArcMove(new Vector(10.0, 20.0), new Vector(15.0, 20.0), RotationType.CW)
{
Layer = LayerType.Cut,
},
};
var ctx = SimpleContext(codes);
var output = WriteFeature(config, ctx);
@@ -478,7 +494,7 @@ public class CincinnatiFeatureWriterTests
var codes = new List<ICode>
{
new RapidMove(1.0, 1.0),
new LinearMove(2.0, 1.0) { Layer = LayerType.Leadout }
new LinearMove(2.0, 1.0) { Layer = LayerType.Leadout },
};
var ctx = SimpleContext(codes);
var output = WriteFeature(config, ctx);
@@ -494,7 +510,10 @@ public class CincinnatiFeatureWriterTests
var codes = new List<ICode>
{
new RapidMove(10.0, 20.0),
new ArcMove(new Vector(12.0, 20.0), new Vector(11.0, 20.0), RotationType.CCW) { Layer = LayerType.Leadin }
new ArcMove(new Vector(12.0, 20.0), new Vector(11.0, 20.0), RotationType.CCW)
{
Layer = LayerType.Leadin,
},
};
var ctx = SimpleContext(codes);
var output = WriteFeature(config, ctx);
@@ -512,7 +531,10 @@ public class CincinnatiFeatureWriterTests
var codes = new List<ICode>
{
new RapidMove(10.0, 20.0),
new ArcMove(new Vector(11.0, 20.0), new Vector(10.5, 20.0), RotationType.CW) { Layer = LayerType.Cut }
new ArcMove(new Vector(11.0, 20.0), new Vector(10.5, 20.0), RotationType.CW)
{
Layer = LayerType.Cut,
},
};
var ctx = SimpleContext(codes);
var output = WriteFeature(config, ctx);
@@ -530,7 +552,10 @@ public class CincinnatiFeatureWriterTests
var codes = new List<ICode>
{
new RapidMove(10.0, 20.0),
new ArcMove(new Vector(10.2, 20.0), new Vector(10.1, 20.0), RotationType.CW) { Layer = LayerType.Cut }
new ArcMove(new Vector(10.2, 20.0), new Vector(10.1, 20.0), RotationType.CW)
{
Layer = LayerType.Cut,
},
};
var ctx = SimpleContext(codes);
var output = WriteFeature(config, ctx);
@@ -548,7 +573,10 @@ public class CincinnatiFeatureWriterTests
var codes = new List<ICode>
{
new RapidMove(0.0, 0.0),
new ArcMove(new Vector(20.0, 0.0), new Vector(10.0, 0.0), RotationType.CCW) { Layer = LayerType.Cut }
new ArcMove(new Vector(20.0, 0.0), new Vector(10.0, 0.0), RotationType.CCW)
{
Layer = LayerType.Cut,
},
};
var ctx = SimpleContext(codes);
var output = WriteFeature(config, ctx);
@@ -566,7 +594,10 @@ public class CincinnatiFeatureWriterTests
var codes = new List<ICode>
{
new RapidMove(10.0, 20.0),
new ArcMove(new Vector(10.2, 20.0), new Vector(10.1, 20.0), RotationType.CW) { Layer = LayerType.Cut }
new ArcMove(new Vector(10.2, 20.0), new Vector(10.1, 20.0), RotationType.CW)
{
Layer = LayerType.Cut,
},
};
var ctx = SimpleContext(codes);
var output = WriteFeature(config, ctx);
@@ -14,11 +14,7 @@ public class CincinnatiPostProcessorTests
public void Post_ProducesOutput_ForSinglePlateNest()
{
var nest = CreateTestNest();
var config = new CincinnatiPostConfig
{
ConfigurationName = "CL940",
PostedAccuracy = 4
};
var config = new CincinnatiPostConfig { ConfigurationName = "CL940", PostedAccuracy = 4 };
var post = new CincinnatiPostProcessor(config);
using var ms = new MemoryStream();
@@ -64,7 +60,7 @@ public class CincinnatiPostProcessorTests
var config = new CincinnatiPostConfig
{
PostedAccuracy = 4,
ArcFeedrate = ArcFeedrateMode.Variables
ArcFeedrate = ArcFeedrateMode.Variables,
};
var post = new CincinnatiPostProcessor(config);
@@ -84,7 +80,7 @@ public class CincinnatiPostProcessorTests
var config = new CincinnatiPostConfig
{
PostedAccuracy = 4,
ArcFeedrate = ArcFeedrateMode.None
ArcFeedrate = ArcFeedrateMode.None,
};
var post = new CincinnatiPostProcessor(config);
@@ -189,18 +185,24 @@ public class CincinnatiPostProcessorTests
UseAntiDive = true,
MaterialLibraries = new()
{
new MaterialLibraryEntry { Material = "Mild Steel", Thickness = 0.135, Gas = "N2", Library = "MS135N2PANEL.lib" }
new MaterialLibraryEntry
{
Material = "Mild Steel",
Thickness = 0.135,
Gas = "N2",
Library = "MS135N2PANEL.lib",
},
},
EtchLibraries = new()
{
new EtchLibraryEntry { Gas = "N2", Library = "EtchN2.lib" }
}
new EtchLibraryEntry { Gas = "N2", Library = "EtchN2.lib" },
},
};
var opts = new JsonSerializerOptions
{
WriteIndented = true,
Converters = { new JsonStringEnumConverter() }
Converters = { new JsonStringEnumConverter() },
};
var json = JsonSerializer.Serialize(config, opts);
var deserialized = JsonSerializer.Deserialize<CincinnatiPostConfig>(json, opts);
@@ -239,7 +241,7 @@ public class CincinnatiPostProcessorTests
{
PostedAccuracy = 4,
UsePartSubprograms = true,
PartSubprogramStart = 200
PartSubprogramStart = 200,
};
var post = new CincinnatiPostProcessor(config);
@@ -279,7 +281,7 @@ public class CincinnatiPostProcessorTests
{
PostedAccuracy = 4,
UsePartSubprograms = true,
PartSubprogramStart = 200
PartSubprogramStart = 200,
};
var post = new CincinnatiPostProcessor(config);
@@ -317,7 +319,7 @@ public class CincinnatiPostProcessorTests
{
PostedAccuracy = 4,
UsePartSubprograms = true,
PartSubprogramStart = 200
PartSubprogramStart = 200,
};
var post = new CincinnatiPostProcessor(config);
@@ -349,7 +351,7 @@ public class CincinnatiPostProcessorTests
{
PostedAccuracy = 4,
UsePartSubprograms = true,
PartSubprogramStart = 200
PartSubprogramStart = 200,
};
var post = new CincinnatiPostProcessor(config);
@@ -372,13 +374,13 @@ public class CincinnatiPostProcessorTests
var config = new CincinnatiPostConfig
{
UsePartSubprograms = true,
PartSubprogramStart = 300
PartSubprogramStart = 300,
};
var opts = new JsonSerializerOptions
{
WriteIndented = true,
Converters = { new JsonStringEnumConverter() }
Converters = { new JsonStringEnumConverter() },
};
var json = JsonSerializer.Serialize(config, opts);
var deserialized = JsonSerializer.Deserialize<CincinnatiPostConfig>(json, opts);
@@ -394,10 +396,10 @@ public class CincinnatiPostProcessorTests
// first segment in the CNC output because the feature writer uses
// the first LinearMove endpoint as the pierce point.
var pgm = new Program(Mode.Incremental);
pgm.Codes.Add(new LinearMove(0, 2)); // (0,0) → (0,2)
pgm.Codes.Add(new LinearMove(2, 0)); // (0,2) → (2,2)
pgm.Codes.Add(new LinearMove(0, -2)); // (2,2) → (2,0)
pgm.Codes.Add(new LinearMove(-2, 0)); // (2,0) → (0,0)
pgm.Codes.Add(new LinearMove(0, 2)); // (0,0) → (0,2)
pgm.Codes.Add(new LinearMove(2, 0)); // (0,2) → (2,2)
pgm.Codes.Add(new LinearMove(0, -2)); // (2,2) → (2,0)
pgm.Codes.Add(new LinearMove(-2, 0)); // (2,0) → (0,0)
var drawing = new Drawing("ClosedSquare", pgm);
var nest = new Nest("TestClosure");
@@ -406,11 +408,7 @@ public class CincinnatiPostProcessorTests
plate.Parts.Add(new Part(drawing, new Vector(1, 1)));
nest.Plates.Add(plate);
var config = new CincinnatiPostConfig
{
UsePartSubprograms = true,
PostedAccuracy = 4
};
var config = new CincinnatiPostConfig { UsePartSubprograms = true, PostedAccuracy = 4 };
var post = new CincinnatiPostProcessor(config);
using var ms = new MemoryStream();
@@ -14,7 +14,7 @@ public class CincinnatiPreambleWriterTests
var config = new CincinnatiPostConfig
{
ConfigurationName = "CL940",
PostedUnits = Units.Inches
PostedUnits = Units.Inches,
};
var sb = new StringBuilder();
using var sw = new StringWriter(sb);
@@ -152,7 +152,7 @@ public class CincinnatiPreambleWriterTests
{
new(48, 96) { Quantity = 5 },
new(72, 48) { Quantity = 2 },
new(36, 48) { Quantity = 1 }
new(36, 48) { Quantity = 1 },
};
writer.WriteMainProgram(sw, "Test", "", plates, "");
@@ -13,10 +13,7 @@ public class CincinnatiSheetWriterTests
[Fact]
public void WriteSheet_EmitsSheetHeader()
{
var config = new CincinnatiPostConfig
{
PostedAccuracy = 4
};
var config = new CincinnatiPostConfig { PostedAccuracy = 4 };
var plate = new Plate(48.0, 96.0);
plate.Parts.Add(new Part(new Drawing("TestPart", CreateSimpleProgram())));
@@ -42,7 +39,7 @@ public class CincinnatiSheetWriterTests
var config = new CincinnatiPostConfig
{
PalletExchange = PalletMode.EndOfSheet,
PostedAccuracy = 4
PostedAccuracy = 4,
};
var plate = new Plate(48.0, 96.0);
plate.Parts.Add(new Part(new Drawing("TestPart", CreateSimpleProgram())));
@@ -147,7 +144,7 @@ public class CincinnatiSheetWriterTests
var config = new CincinnatiPostConfig
{
PalletExchange = PalletMode.StartAndEnd,
PostedAccuracy = 4
PostedAccuracy = 4,
};
var plate = new Plate(48.0, 96.0);
plate.Parts.Add(new Part(new Drawing("TestPart", CreateSimpleProgram())));
@@ -168,7 +165,7 @@ public class CincinnatiSheetWriterTests
var config = new CincinnatiPostConfig
{
PalletExchange = PalletMode.None,
PostedAccuracy = 4
PostedAccuracy = 4,
};
var plate = new Plate(48.0, 96.0);
plate.Parts.Add(new Part(new Drawing("TestPart", CreateSimpleProgram())));
@@ -189,7 +186,7 @@ public class CincinnatiSheetWriterTests
var config = new CincinnatiPostConfig
{
PalletExchange = PalletMode.EndOfSheet,
PostedAccuracy = 4
PostedAccuracy = 4,
};
var plate = new Plate(48.0, 96.0);
plate.Parts.Add(new Part(new Drawing("TestPart", CreateSimpleProgram())));
@@ -234,7 +231,10 @@ public class CincinnatiSheetWriterTests
var codes = new List<ICode>
{
new RapidMove(10.0, 20.0),
new ArcMove(new Vector(10.0, 20.0), new Vector(15.0, 20.0), RotationType.CW) { Layer = LayerType.Cut }
new ArcMove(new Vector(10.0, 20.0), new Vector(15.0, 20.0), RotationType.CW)
{
Layer = LayerType.Cut,
},
};
var distance = FeatureUtils.ComputeCutDistance(codes);
@@ -249,7 +249,7 @@ public class CincinnatiSheetWriterTests
{
new RapidMove(0, 0),
new LinearMove(1, 0) { Layer = LayerType.Scribe },
new LinearMove(1, 1) { Layer = LayerType.Scribe }
new LinearMove(1, 1) { Layer = LayerType.Scribe },
};
Assert.True(FeatureUtils.IsEtch(codes));
@@ -262,7 +262,7 @@ public class CincinnatiSheetWriterTests
{
new RapidMove(0, 0),
new LinearMove(1, 0) { Layer = LayerType.Cut },
new LinearMove(1, 1) { Layer = LayerType.Cut }
new LinearMove(1, 1) { Layer = LayerType.Cut },
};
Assert.False(FeatureUtils.IsEtch(codes));
@@ -271,10 +271,7 @@ public class CincinnatiSheetWriterTests
[Fact]
public void IsFeatureEtch_ReturnsFalseForRapidsOnly()
{
var codes = new List<ICode>
{
new RapidMove(0, 0)
};
var codes = new List<ICode> { new RapidMove(0, 0) };
Assert.False(FeatureUtils.IsEtch(codes));
}
@@ -303,11 +300,11 @@ public class CincinnatiSheetWriterTests
var output = sb.ToString();
// Under G90, coordinates must be plate-absolute (part coords + part location)
Assert.Contains("G0 X10.5 Y5.25", output); // rapid to pierce
Assert.Contains("G1 X12.5 Y5.25", output); // (2,0) + (10.5,5.25)
Assert.Contains("G1 X12.5 Y7.25", output); // (2,2) + (10.5,5.25)
Assert.Contains("G1 X10.5 Y7.25", output); // (0,2) + (10.5,5.25)
Assert.Contains("G1 X10.5 Y5.25", output); // (0,0) + (10.5,5.25)
Assert.Contains("G0 X10.5 Y5.25", output); // rapid to pierce
Assert.Contains("G1 X12.5 Y5.25", output); // (2,0) + (10.5,5.25)
Assert.Contains("G1 X12.5 Y7.25", output); // (2,2) + (10.5,5.25)
Assert.Contains("G1 X10.5 Y7.25", output); // (0,2) + (10.5,5.25)
Assert.Contains("G1 X10.5 Y5.25", output); // (0,0) + (10.5,5.25)
}
[Fact]
@@ -4,24 +4,49 @@ namespace OpenNest.Tests.Cincinnati;
public class MaterialLibraryResolverTests
{
private static CincinnatiPostConfig ConfigWithLibraries() => new()
{
DefaultAssistGas = "O2",
DefaultEtchGas = "N2",
MaterialLibraries = new()
private static CincinnatiPostConfig ConfigWithLibraries() =>
new()
{
new MaterialLibraryEntry { Material = "Mild Steel", Thickness = 0.250, Gas = "O2", Library = "MS250O2.lib" },
new MaterialLibraryEntry { Material = "Mild Steel", Thickness = 0.250, Gas = "N2", Library = "MS250N2.lib" },
new MaterialLibraryEntry { Material = "Aluminum", Thickness = 0.125, Gas = "N2", Library = "AL125N2.lib" },
new MaterialLibraryEntry { Material = "Stainless Steel", Thickness = 0.375, Gas = "AIR", Library = "SS375AIR.lib" }
},
EtchLibraries = new()
{
new EtchLibraryEntry { Gas = "N2", Library = "EtchN2.lib" },
new EtchLibraryEntry { Gas = "O2", Library = "EtchO2.lib" },
new EtchLibraryEntry { Gas = "AIR", Library = "EtchAIR.lib" }
}
};
DefaultAssistGas = "O2",
DefaultEtchGas = "N2",
MaterialLibraries = new()
{
new MaterialLibraryEntry
{
Material = "Mild Steel",
Thickness = 0.250,
Gas = "O2",
Library = "MS250O2.lib",
},
new MaterialLibraryEntry
{
Material = "Mild Steel",
Thickness = 0.250,
Gas = "N2",
Library = "MS250N2.lib",
},
new MaterialLibraryEntry
{
Material = "Aluminum",
Thickness = 0.125,
Gas = "N2",
Library = "AL125N2.lib",
},
new MaterialLibraryEntry
{
Material = "Stainless Steel",
Thickness = 0.375,
Gas = "AIR",
Library = "SS375AIR.lib",
},
},
EtchLibraries = new()
{
new EtchLibraryEntry { Gas = "N2", Library = "EtchN2.lib" },
new EtchLibraryEntry { Gas = "O2", Library = "EtchO2.lib" },
new EtchLibraryEntry { Gas = "AIR", Library = "EtchAIR.lib" },
},
};
[Fact]
public void ResolveCutLibrary_ExactMatch()
@@ -9,7 +9,11 @@ public class SpeedClassifierTests
[InlineData(5.0, 10.0, "FAST")]
[InlineData(4.9, 10.0, "MEDIUM")]
[InlineData(0.5, 10.0, "SLOW")]
public void Classify_ReturnsExpectedClass(double contourLength, double sheetDiagonal, string expected)
public void Classify_ReturnsExpectedClass(
double contourLength,
double sheetDiagonal,
string expected
)
{
var classifier = new SpeedClassifier();
Assert.Equal(expected, classifier.Classify(contourLength, sheetDiagonal));
@@ -19,7 +23,11 @@ public class SpeedClassifierTests
[InlineData(0.8702, 3.927, "CutDist=.8702/3.927")]
[InlineData(18.9722, 3.927, "CutDist=18.9722/3.927")]
[InlineData(0.0, 10.0, "CutDist=0/10")]
public void FormatCutDist_IncludesLengthAndDiagonal(double contour, double diag, string expected)
public void FormatCutDist_IncludesLengthAndDiagonal(
double contour,
double diag,
string expected
)
{
var classifier = new SpeedClassifier();
Assert.Equal(expected, classifier.FormatCutDist(contour, diag));
@@ -67,7 +67,8 @@ public class UserVariablePostTests
var output = PostToString(post, nest);
// Both should use the same #200 — only one declaration
var declarationCount = output.Split('\n')
var declarationCount = output
.Split('\n')
.Count(l => l.Contains("#200=") && l.ToUpper().Contains("SHEET WIDTH"));
Assert.Equal(1, declarationCount);
}
@@ -112,7 +113,11 @@ public class UserVariablePostTests
public void CutOff_VerticalCut_UsesSheetWidthVariable()
{
// Create a plate with a vertical cutoff
var config = new CincinnatiPostConfig { SheetWidthVariable = 110, SheetLengthVariable = 111 };
var config = new CincinnatiPostConfig
{
SheetWidthVariable = 110,
SheetLengthVariable = 111,
};
var nest = new Nest { Name = "Test" };
var plate = new Plate(new Size(48, 96));
@@ -158,7 +163,7 @@ public class UserVariablePostTests
partPgm.Codes.Add(new LinearMove(0, 0));
var drawing = new Drawing("Part1", partPgm);
nest.Drawings.Add(drawing);
plate.Parts.Add(new Part(drawing, new Vector(15, 20))); // Part at Y=20-30, should create gap
plate.Parts.Add(new Part(drawing, new Vector(15, 20))); // Part at Y=20-30, should create gap
var cutoff = new CutOff(new Vector(20, 0), CutOffAxis.Vertical);
plate.CutOffs.Add(cutoff);