From 96d8a6874fa0c2689ce5284d3787993e5f4d2d7c Mon Sep 17 00:00:00 2001 From: AJ Isaacs Date: Mon, 26 Oct 2026 07:05:38 -0400 Subject: [PATCH] fix(autonest): show part rotation limits in degrees The Rot Start, Rot End and Step columns showed the drawing's radian constraints as-is, so users had to type 1.5708 for 90 degrees. The grid now shows and accepts degrees; rows keep the radian values, so an unedited row passes the drawing's limits to the engine without a conversion round trip. Co-Authored-By: Claude Opus 5.5 --- .../Forms/AutoNestFormRotationTests.cs | 53 +++++++++++++++++++ OpenNest/Forms/AutoNestForm.cs | 40 ++++++++++---- 2 files changed, 84 insertions(+), 9 deletions(-) create mode 100644 OpenNest.WinForms.Tests/Forms/AutoNestFormRotationTests.cs diff --git a/OpenNest.WinForms.Tests/Forms/AutoNestFormRotationTests.cs b/OpenNest.WinForms.Tests/Forms/AutoNestFormRotationTests.cs new file mode 100644 index 00000000..58f1d673 --- /dev/null +++ b/OpenNest.WinForms.Tests/Forms/AutoNestFormRotationTests.cs @@ -0,0 +1,53 @@ +using System.Windows.Forms; +using OpenNest.CNC; +using OpenNest.Forms; + +namespace OpenNest.WinForms.Tests.Forms; + +public class AutoNestFormRotationTests +{ + [Fact] + public void RotationColumnsShowDegreesAndNestItemsKeepRadians() + { + RunSta(() => + { + var drawing = new Drawing("grain", new Program()) { Quantity = { Required = 2 } }; + drawing.Constraints.StartAngle = 0; + drawing.Constraints.EndAngle = System.Math.PI / 2; + drawing.Constraints.StepAngle = System.Math.PI / 2; + var nest = new Nest(); + nest.Drawings.Add(drawing); + + using var form = new AutoNestForm(nest); + var grid = GetGrid(form); + Assert.Equal(0.0, grid.Rows[0].Cells[Column(grid, "RotationStart")].Value); + Assert.Equal(90.0, grid.Rows[0].Cells[Column(grid, "RotationEnd")].Value); + Assert.Equal(90.0, grid.Rows[0].Cells[Column(grid, "StepAngle")].Value); + + var item = Assert.Single(form.GetNestItems()); + Assert.Equal(System.Math.PI / 2, item.RotationEnd); + Assert.Equal(System.Math.PI / 2, item.StepAngle); + + grid.Rows[0].Cells[Column(grid, "RotationEnd")].Value = 180.0; + grid.Rows[0].Cells[Column(grid, "StepAngle")].Value = 45.0; + item = Assert.Single(form.GetNestItems()); + Assert.Equal(System.Math.PI, item.RotationEnd, 12); + Assert.Equal(System.Math.PI / 4, item.StepAngle, 12); + }); + } + + private static DataGridView GetGrid(AutoNestForm form) + { + // Binding needs a context even when the test does not show the form. + form.BindingContext = new BindingContext(); + var grid = Assert.IsType(form.Controls.Find("partsGrid", true).Single()); + grid.CreateControl(); + return grid; + } + + private static int Column(DataGridView grid, string property) => + grid.Columns.Cast().Single(c => c.DataPropertyName == property).Index; + + private static void RunSta(Action action) => + StaTestThread.Run(action, TimeSpan.FromSeconds(15), "The STA test did not complete."); +} diff --git a/OpenNest/Forms/AutoNestForm.cs b/OpenNest/Forms/AutoNestForm.cs index 5f419d06..d09bbe6d 100644 --- a/OpenNest/Forms/AutoNestForm.cs +++ b/OpenNest/Forms/AutoNestForm.cs @@ -11,6 +11,7 @@ using OpenNest.Data.MaterialLedger; using OpenNest.Engine; using OpenNest.Geometry; using OpenNest.Help; +using OpenNest.Math; namespace OpenNest.Forms { @@ -257,9 +258,9 @@ namespace OpenNest.Forms nestItem.Drawing = gridItem.RefDrawing; nestItem.Priority = gridItem.Priority; nestItem.Quantity = gridItem.Quantity; - nestItem.RotationEnd = gridItem.RotationEnd; - nestItem.RotationStart = gridItem.RotationStart; - nestItem.StepAngle = gridItem.StepAngle; + nestItem.RotationEnd = gridItem.RotationEndRadians; + nestItem.RotationStart = gridItem.RotationStartRadians; + nestItem.StepAngle = gridItem.StepAngleRadians; nestItems.Add(nestItem); } @@ -880,9 +881,9 @@ namespace OpenNest.Forms item.RefDrawing = dwg; item.Quantity = dwg.Quantity.Remaining > 0 ? dwg.Quantity.Remaining : 0; item.Priority = dwg.Priority; - item.RotationStart = dwg.Constraints.StartAngle; - item.RotationEnd = dwg.Constraints.EndAngle; - item.StepAngle = dwg.Constraints.StepAngle; + item.RotationStartRadians = dwg.Constraints.StartAngle; + item.RotationEndRadians = dwg.Constraints.EndAngle; + item.StepAngleRadians = dwg.Constraints.StepAngle; return item; } @@ -903,14 +904,35 @@ namespace OpenNest.Forms public int Priority { get; set; } + // Rotations are kept in radians and shown in degrees, so an unedited row passes + // the drawing's limits through without a conversion round trip. + internal double RotationStartRadians { get; set; } + internal double RotationEndRadians { get; set; } + internal double StepAngleRadians { get; set; } + [DisplayName("Rot Start")] - public double RotationStart { get; set; } + public double RotationStart + { + get => ToDisplayDegrees(RotationStartRadians); + set => RotationStartRadians = Angle.ToRadians(value); + } [DisplayName("Rot End")] - public double RotationEnd { get; set; } + public double RotationEnd + { + get => ToDisplayDegrees(RotationEndRadians); + set => RotationEndRadians = Angle.ToRadians(value); + } [DisplayName("Step")] - public double StepAngle { get; set; } + public double StepAngle + { + get => ToDisplayDegrees(StepAngleRadians); + set => StepAngleRadians = Angle.ToRadians(value); + } + + private static double ToDisplayDegrees(double radians) => + System.Math.Round(Angle.ToDegrees(radians), 4); } private class PlateOptionItem