From 92a57d33dfbe74c93b0378f12d645b362f2cb80a Mon Sep 17 00:00:00 2001 From: AJ Isaacs Date: Fri, 10 Apr 2026 17:36:10 -0400 Subject: [PATCH] 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 --- OpenNest.Core/Shapes/PipeFlangeShape.cs | 14 +++- OpenNest.Tests/Shapes/PipeFlangeShapeTests.cs | 82 ++++++++++++++++++- 2 files changed, 93 insertions(+), 3 deletions(-) diff --git a/OpenNest.Core/Shapes/PipeFlangeShape.cs b/OpenNest.Core/Shapes/PipeFlangeShape.cs index f4be59d..7c5de3d 100644 --- a/OpenNest.Core/Shapes/PipeFlangeShape.cs +++ b/OpenNest.Core/Shapes/PipeFlangeShape.cs @@ -5,19 +5,23 @@ namespace OpenNest.Shapes { public class PipeFlangeShape : ShapeDefinition { - public double NominalPipeSize { get; set; } public double OD { get; set; } public double HoleDiameter { get; set; } public double HolePatternDiameter { 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() { - NominalPipeSize = 2; OD = 7.5; HoleDiameter = 0.875; HolePatternDiameter = 5.5; HoleCount = 8; + PipeSize = "2"; + PipeClearance = 0.0625; + Blind = false; } public override Drawing GetDrawing() @@ -38,6 +42,12 @@ namespace OpenNest.Shapes 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); } } diff --git a/OpenNest.Tests/Shapes/PipeFlangeShapeTests.cs b/OpenNest.Tests/Shapes/PipeFlangeShapeTests.cs index 3ba47e5..f8aafdf 100644 --- a/OpenNest.Tests/Shapes/PipeFlangeShapeTests.cs +++ b/OpenNest.Tests/Shapes/PipeFlangeShapeTests.cs @@ -29,7 +29,8 @@ public class PipeFlangeShapeTests OD = 10, HoleDiameter = 1, HolePatternDiameter = 7, - HoleCount = 4 + HoleCount = 4, + Blind = true }; var drawing = shape.GetDrawing(); @@ -51,4 +52,83 @@ public class PipeFlangeShapeTests 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); + } }