feat(shapes): add pipe bore, clearance, and blind flag to PipeFlangeShape

Replaces NominalPipeSize (double) with PipeSize (string), PipeClearance (double), and Blind (bool). GetDrawing cuts a center bore at pipeOD + PipeClearance unless Blind is true or PipeSize is unknown/null.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-10 17:36:10 -04:00
parent 6adc5b0967
commit 92a57d33df
2 changed files with 93 additions and 3 deletions
+12 -2
View File
@@ -5,19 +5,23 @@ namespace OpenNest.Shapes
{ {
public class PipeFlangeShape : ShapeDefinition public class PipeFlangeShape : ShapeDefinition
{ {
public double NominalPipeSize { get; set; }
public double OD { get; set; } public double OD { get; set; }
public double HoleDiameter { get; set; } public double HoleDiameter { get; set; }
public double HolePatternDiameter { get; set; } public double HolePatternDiameter { get; set; }
public int HoleCount { get; set; } public int HoleCount { get; set; }
public string PipeSize { get; set; }
public double PipeClearance { get; set; }
public bool Blind { get; set; }
public override void SetPreviewDefaults() public override void SetPreviewDefaults()
{ {
NominalPipeSize = 2;
OD = 7.5; OD = 7.5;
HoleDiameter = 0.875; HoleDiameter = 0.875;
HolePatternDiameter = 5.5; HolePatternDiameter = 5.5;
HoleCount = 8; HoleCount = 8;
PipeSize = "2";
PipeClearance = 0.0625;
Blind = false;
} }
public override Drawing GetDrawing() public override Drawing GetDrawing()
@@ -38,6 +42,12 @@ namespace OpenNest.Shapes
entities.Add(new Circle(cx, cy, holeRadius)); entities.Add(new Circle(cx, cy, holeRadius));
} }
if (!Blind && !string.IsNullOrEmpty(PipeSize) && PipeSizes.TryGetOD(PipeSize, out var pipeOD))
{
var boreDiameter = pipeOD + PipeClearance;
entities.Add(new Circle(0, 0, boreDiameter / 2.0));
}
return CreateDrawing(entities); return CreateDrawing(entities);
} }
} }
+81 -1
View File
@@ -29,7 +29,8 @@ public class PipeFlangeShapeTests
OD = 10, OD = 10,
HoleDiameter = 1, HoleDiameter = 1,
HolePatternDiameter = 7, HolePatternDiameter = 7,
HoleCount = 4 HoleCount = 4,
Blind = true
}; };
var drawing = shape.GetDrawing(); var drawing = shape.GetDrawing();
@@ -51,4 +52,83 @@ public class PipeFlangeShapeTests
Assert.Equal("PipeFlange", drawing.Name); Assert.Equal("PipeFlange", drawing.Name);
} }
[Fact]
public void GetDrawing_WithPipeSize_CutsCenterBoreAtPipeODPlusClearance()
{
var shape = new PipeFlangeShape
{
OD = 10,
HoleDiameter = 1,
HolePatternDiameter = 7,
HoleCount = 4,
PipeSize = "2", // OD = 2.375
PipeClearance = 0.125,
Blind = false
};
var drawing = shape.GetDrawing();
// Expected bore diameter = 2.375 + 0.125 = 2.5
// Area = pi * (5^2 - 0.5^2 * 4 - 1.25^2) = pi * (25 - 1 - 1.5625) = pi * 22.4375
var expectedArea = System.Math.PI * 22.4375;
Assert.Equal(expectedArea, drawing.Area, 0.5);
}
[Fact]
public void GetDrawing_Blind_OmitsCenterBore()
{
var shape = new PipeFlangeShape
{
OD = 10,
HoleDiameter = 1,
HolePatternDiameter = 7,
HoleCount = 4,
PipeSize = "2",
PipeClearance = 0.125,
Blind = true
};
var drawing = shape.GetDrawing();
// With Blind=true, area = outer - 4 bolt holes = pi * (25 - 1) = pi * 24
var expectedArea = System.Math.PI * 24;
Assert.Equal(expectedArea, drawing.Area, 0.5);
}
[Fact]
public void GetDrawing_UnknownPipeSize_OmitsCenterBore()
{
var shape = new PipeFlangeShape
{
OD = 10,
HoleDiameter = 1,
HolePatternDiameter = 7,
HoleCount = 4,
PipeSize = "not-a-real-pipe",
PipeClearance = 0.125,
Blind = false
};
var drawing = shape.GetDrawing();
// Unknown pipe size → no bore, area matches blind case
var expectedArea = System.Math.PI * 24;
Assert.Equal(expectedArea, drawing.Area, 0.5);
}
[Fact]
public void GetDrawing_NullOrEmptyPipeSize_OmitsCenterBore()
{
var shape = new PipeFlangeShape
{
OD = 10,
HoleDiameter = 1,
HolePatternDiameter = 7,
HoleCount = 4,
PipeSize = null,
PipeClearance = 0.125
};
var drawing = shape.GetDrawing();
var expectedArea = System.Math.PI * 24;
Assert.Equal(expectedArea, drawing.Area, 0.5);
}
} }