From a7f897272262458de8eb6635c63ab8d77978c1bd Mon Sep 17 00:00:00 2001 From: AJ Isaacs Date: Tue, 24 Mar 2026 20:39:29 -0400 Subject: [PATCH] feat: add bend line rendering and grain warning in PlateView Co-Authored-By: Claude Opus 4.6 (1M context) --- OpenNest/Controls/PlateView.cs | 73 ++++++++++++++++++++++++++++++++++ OpenNest/Forms/EditNestForm.cs | 6 +++ 2 files changed, 79 insertions(+) diff --git a/OpenNest/Controls/PlateView.cs b/OpenNest/Controls/PlateView.cs index 42c80b5..fcf585f 100644 --- a/OpenNest/Controls/PlateView.cs +++ b/OpenNest/Controls/PlateView.cs @@ -1,4 +1,5 @@ using OpenNest.Actions; +using OpenNest.Bending; using OpenNest.CNC; using OpenNest.Collections; using OpenNest.Engine.Fill; @@ -134,6 +135,8 @@ namespace OpenNest.Controls public bool DrawOffset { get; set; } + public bool ShowBendLines { get; set; } + public double OffsetTolerance { get; set; } = 0.001; public bool FillParts { get; set; } @@ -578,6 +581,8 @@ namespace OpenNest.Controls continue; part.Draw(g, (i + 1).ToString()); + DrawBendLines(g, part.BasePart); + DrawGrainWarning(g, part.BasePart); } // Draw preview parts — active (current strategy) takes precedence @@ -614,6 +619,74 @@ namespace OpenNest.Controls DrawRapids(g); } + private void DrawBendLines(Graphics g, Part part) + { + if (!ShowBendLines || part.BaseDrawing.Bends == null || part.BaseDrawing.Bends.Count == 0) + return; + + using var bendPen = new Pen(Color.Yellow, 1.5f) + { + DashStyle = System.Drawing.Drawing2D.DashStyle.Dash + }; + + foreach (var bend in part.BaseDrawing.Bends) + { + var start = bend.StartPoint; + var end = bend.EndPoint; + + // Apply part rotation + if (part.Rotation != 0) + { + start = start.Rotate(part.Rotation); + end = end.Rotate(part.Rotation); + } + + // Apply part offset + start = start + part.Location; + end = end + part.Location; + + var pt1 = PointWorldToGraph(start); + var pt2 = PointWorldToGraph(end); + + g.DrawLine(bendPen, pt1, pt2); + } + } + + private void DrawGrainWarning(Graphics g, Part part) + { + if (!ShowBendLines || Plate == null || part.BaseDrawing.Bends == null || part.BaseDrawing.Bends.Count == 0) + return; + + var grainAngle = Plate.GrainAngle; + var tolerance = Angle.ToRadians(5); + + foreach (var bend in part.BaseDrawing.Bends) + { + var bendAngle = bend.LineAngle + part.Rotation; + bendAngle = bendAngle % System.Math.PI; + if (bendAngle < 0) bendAngle += System.Math.PI; + + var grainNormalized = grainAngle % System.Math.PI; + if (grainNormalized < 0) grainNormalized += System.Math.PI; + + var diff = System.Math.Abs(bendAngle - grainNormalized); + diff = System.Math.Min(diff, System.Math.PI - diff); + + if (diff > tolerance) + { + var box = part.BaseDrawing.Program.BoundingBox(); + var location = part.Location; + var pt1 = PointWorldToGraph(location); + var pt2 = PointWorldToGraph(new Vector( + location.X + box.Width, location.Y + box.Length)); + using var warnPen = new Pen(Color.FromArgb(180, 255, 140, 0), 2f); + g.DrawRectangle(warnPen, pt1.X, pt2.Y, + System.Math.Abs(pt2.X - pt1.X), System.Math.Abs(pt2.Y - pt1.Y)); + return; + } + } + } + private void DrawCutOffs(Graphics g) { if (Plate?.CutOffs == null || Plate.CutOffs.Count == 0) diff --git a/OpenNest/Forms/EditNestForm.cs b/OpenNest/Forms/EditNestForm.cs index 0645fb7..26b5a99 100644 --- a/OpenNest/Forms/EditNestForm.cs +++ b/OpenNest/Forms/EditNestForm.cs @@ -479,6 +479,12 @@ namespace OpenNest.Forms PlateView.Invalidate(); } + public void ToggleBendLines() + { + PlateView.ShowBendLines = !PlateView.ShowBendLines; + PlateView.Invalidate(); + } + public void ToggleDrawOffset() { PlateView.DrawOffset = !PlateView.DrawOffset;