mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-11-01 18:11:37 -05:00
fix(cutting): keep Plan Cutting's lead and tab edits
Plan Cutting saved its settings only on a successful Apply, so a plate that would not plan lost them. Each open then laid the machine's leads back over the last parameters, and the cutting panel rebuilt parameters from scratch, dropping kerf and the machine/material/thickness stamp. Save the settings when the dialog is accepted, keep the panel's unexposed fields, and only apply the machine's leads when the last parameters were not already taken from that machine, material, grade and thickness. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
a9396ba065
commit
41460481d6
8 files changed
+108
-21
No files matched your search
@@ -73,6 +73,25 @@ public static class MachineCuttingDefaults
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether <paramref name="parameters"/> are stamped with the machine, material, grade and
|
||||
/// thickness <see cref="ApplyTo(CuttingParameters, MachineConfig?, Nest)"/> would record for
|
||||
/// the nest: they started from the machine's settings for it, and any lead edits since are
|
||||
/// the user's choice for that same job, which the machine's settings must not replace.
|
||||
/// </summary>
|
||||
public static bool IsRecordedFor(CuttingParameters parameters, MachineConfig? machine, Nest nest)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(parameters);
|
||||
ArgumentNullException.ThrowIfNull(nest);
|
||||
if (Find(machine, nest) == null)
|
||||
return false;
|
||||
var tolerance = ThicknessToleranceInches * Scale(Units.Inches, nest.Units);
|
||||
return string.Equals(parameters.MachineName, machine!.Name, StringComparison.Ordinal)
|
||||
&& string.Equals(parameters.MaterialName, nest.Material.Name, StringComparison.Ordinal)
|
||||
&& string.Equals(parameters.Grade ?? "", nest.Material.Grade ?? "", StringComparison.Ordinal)
|
||||
&& System.Math.Abs(parameters.Thickness - nest.Thickness) <= tolerance;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces the part clearance, overtravel, minimum segment and direction of
|
||||
/// <paramref name="settings"/> with the machine's for the nest; the head-lock choice is kept.
|
||||
|
||||
@@ -41,6 +41,19 @@ public class MachineCuttingDefaultsTests
|
||||
|
||||
private static readonly LeadConfig LineArc = new() { Type = "Line + Arc", Length = 0.125, Angle = 90, Radius = 0.0625 };
|
||||
|
||||
[Fact]
|
||||
public void IsRecordedFor_KeepsLeadsEditedAfterTheMachineSettingsWereTaken()
|
||||
{
|
||||
var parameters = new CuttingParameters();
|
||||
Assert.True(MachineCuttingDefaults.ApplyTo(parameters, Machine(LineArc), NestOf(0.25, "A36")));
|
||||
parameters.ExternalLeadOut = new NoLeadOut();
|
||||
|
||||
Assert.True(MachineCuttingDefaults.IsRecordedFor(parameters, Machine(LineArc), NestOf(0.2505, "A36")));
|
||||
Assert.False(MachineCuttingDefaults.IsRecordedFor(parameters, Machine(LineArc), NestOf(0.25, "A572")));
|
||||
Assert.False(MachineCuttingDefaults.IsRecordedFor(parameters, Machine(LineArc), NestOf(0.5, "A36")));
|
||||
Assert.False(MachineCuttingDefaults.IsRecordedFor(new CuttingParameters(), Machine(LineArc), NestOf(0.25, "A36")));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApplyTo_GivesEveryContourTheMachineLeadsAndStampsTheSource()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
using OpenNest.CNC.CuttingStrategy;
|
||||
using OpenNest.Controls;
|
||||
|
||||
namespace OpenNest.WinForms.Tests.Controls;
|
||||
|
||||
public class CuttingPanelTests
|
||||
{
|
||||
[Fact]
|
||||
public void BuildParameters_KeepsTheSettingsThePanelHasNoFieldFor()
|
||||
{
|
||||
StaTestThread.Run(() =>
|
||||
{
|
||||
using var panel = new CuttingPanel();
|
||||
panel.LoadFromParameters(new CuttingParameters
|
||||
{
|
||||
MachineName = "CL-980",
|
||||
MaterialName = "Stainless Steel",
|
||||
Grade = "304",
|
||||
Thickness = 0.075,
|
||||
Kerf = 0.008,
|
||||
ExternalLeadIn = new ArcLeadIn { Radius = 0.0625 },
|
||||
ExternalLeadOut = new NoLeadOut(),
|
||||
TabsEnabled = true,
|
||||
TabConfig = new NormalTab { Size = 0.25 },
|
||||
});
|
||||
|
||||
var built = panel.BuildParameters();
|
||||
|
||||
// Without the stamp, the machine's leads would replace these edits on the next open.
|
||||
Assert.Equal("CL-980", built.MachineName);
|
||||
Assert.Equal("Stainless Steel", built.MaterialName);
|
||||
Assert.Equal("304", built.Grade);
|
||||
Assert.Equal(0.075, built.Thickness);
|
||||
Assert.Equal(0.008, built.Kerf);
|
||||
Assert.IsType<NoLeadOut>(built.ExternalLeadOut);
|
||||
Assert.True(built.TabsEnabled);
|
||||
}, TimeSpan.FromSeconds(30), "The cutting panel did not build its parameters.");
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using OpenNest.CNC.CuttingStrategy;
|
||||
using OpenNest.IO;
|
||||
|
||||
namespace OpenNest.Controls
|
||||
{
|
||||
@@ -57,6 +58,8 @@ namespace OpenNest.Controls
|
||||
private readonly NumericUpDown nudPierceClearance;
|
||||
private readonly NumericUpDown nudPierceDiameter;
|
||||
|
||||
private CuttingParameters loaded;
|
||||
|
||||
private readonly CheckBox chkRoundLeadInAngles;
|
||||
private readonly NumericUpDown nudLeadInAngleIncrement;
|
||||
|
||||
@@ -294,30 +297,33 @@ namespace OpenNest.Controls
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
// Settings the panel has no field for (kerf, the machine/material/thickness stamp,
|
||||
// sequencing) come back unchanged from the parameters last loaded.
|
||||
public CuttingParameters BuildParameters()
|
||||
{
|
||||
return new CuttingParameters
|
||||
{
|
||||
ExternalLeadIn = BuildLeadIn(cboExternalLeadIn, pnlExternalLeadIn),
|
||||
ExternalLeadOut = BuildLeadOut(cboExternalLeadOut, pnlExternalLeadOut),
|
||||
InternalLeadIn = BuildLeadIn(cboInternalLeadIn, pnlInternalLeadIn),
|
||||
InternalLeadOut = BuildLeadOut(cboInternalLeadOut, pnlInternalLeadOut),
|
||||
TabsEnabled = chkTabsEnabled.Checked && rbTabAll.Checked,
|
||||
TabConfig = new NormalTab { Size = (double)nudTabWidth.Value },
|
||||
PierceClearance = (double)nudPierceClearance.Value,
|
||||
PierceDiameter = (double)nudPierceDiameter.Value,
|
||||
RoundLeadInAngles = chkRoundLeadInAngles.Checked,
|
||||
LeadInAngleIncrement = (double)nudLeadInAngleIncrement.Value,
|
||||
SupportTabs = chkTabsEnabled.Checked && rbSupportTab.Checked,
|
||||
NoBedTabMinWidth = (double)nudNoBedTabMin.Value,
|
||||
NoBedTabMaxWidth = (double)nudNoBedTabMax.Value,
|
||||
TabHeldMaxLength = (double)nudTabHeldMax.Value,
|
||||
};
|
||||
var parameters = loaded == null ? new CuttingParameters()
|
||||
: CuttingParametersSerializer.Deserialize(CuttingParametersSerializer.Serialize(loaded));
|
||||
parameters.ExternalLeadIn = BuildLeadIn(cboExternalLeadIn, pnlExternalLeadIn);
|
||||
parameters.ExternalLeadOut = BuildLeadOut(cboExternalLeadOut, pnlExternalLeadOut);
|
||||
parameters.InternalLeadIn = BuildLeadIn(cboInternalLeadIn, pnlInternalLeadIn);
|
||||
parameters.InternalLeadOut = BuildLeadOut(cboInternalLeadOut, pnlInternalLeadOut);
|
||||
parameters.TabsEnabled = chkTabsEnabled.Checked && rbTabAll.Checked;
|
||||
parameters.TabConfig = new NormalTab { Size = (double)nudTabWidth.Value };
|
||||
parameters.PierceClearance = (double)nudPierceClearance.Value;
|
||||
parameters.PierceDiameter = (double)nudPierceDiameter.Value;
|
||||
parameters.RoundLeadInAngles = chkRoundLeadInAngles.Checked;
|
||||
parameters.LeadInAngleIncrement = (double)nudLeadInAngleIncrement.Value;
|
||||
parameters.SupportTabs = chkTabsEnabled.Checked && rbSupportTab.Checked;
|
||||
parameters.NoBedTabMinWidth = (double)nudNoBedTabMin.Value;
|
||||
parameters.NoBedTabMaxWidth = (double)nudNoBedTabMax.Value;
|
||||
parameters.TabHeldMaxLength = (double)nudTabHeldMax.Value;
|
||||
return parameters;
|
||||
}
|
||||
|
||||
public void LoadFromParameters(CuttingParameters p)
|
||||
{
|
||||
suppressEvents = true;
|
||||
loaded = CuttingParametersSerializer.Deserialize(CuttingParametersSerializer.Serialize(p));
|
||||
|
||||
LoadLeadIn(cboExternalLeadIn, pnlExternalLeadIn, p.ExternalLeadIn);
|
||||
LoadLeadOut(cboExternalLeadOut, pnlExternalLeadOut, p.ExternalLeadOut);
|
||||
|
||||
@@ -1258,6 +1258,8 @@ internal sealed class CuttingInspectionPanel : UserControl
|
||||
dialog.LoadParameters(parameters);
|
||||
if (dialog.ShowDialog(this) != DialogResult.OK || closed || closeRequested) return;
|
||||
parameters = dialog.GetParameters();
|
||||
// Saved now, not only on Apply: a plate that will not plan must not lose the edit.
|
||||
EditNestForm.SaveCuttingParameters(parameters);
|
||||
ShowSettings();
|
||||
RestartPlanning();
|
||||
}
|
||||
|
||||
@@ -1356,7 +1356,7 @@ namespace OpenNest.Forms
|
||||
PlateView.SetAction(typeof(Actions.ActionLeadIn));
|
||||
}
|
||||
|
||||
private static void SaveCuttingParameters(CuttingParameters parameters)
|
||||
internal static void SaveCuttingParameters(CuttingParameters parameters)
|
||||
{
|
||||
var json = CuttingParametersSerializer.Serialize(parameters);
|
||||
Properties.Settings.Default.CuttingParametersJson = json;
|
||||
|
||||
@@ -198,12 +198,16 @@ namespace OpenNest.Forms
|
||||
/// <summary>
|
||||
/// The cutting parameters a plate of <paramref name="nest"/> without its own starts from:
|
||||
/// the last ones applied (or the built-in defaults), with the lead-ins, lead-outs and kerf
|
||||
/// of the nest's machine for its material and thickness when the machine has them.
|
||||
/// of the nest's machine for its material and thickness when the machine has them. Last
|
||||
/// parameters already taken from that machine, material and thickness keep the user's
|
||||
/// edits to them.
|
||||
/// </summary>
|
||||
public static CuttingParameters DefaultCuttingParameters(Nest nest)
|
||||
{
|
||||
var parameters = LastCuttingParameters();
|
||||
MachineCuttingDefaults.ApplyTo(parameters, FindMachine(nest.Machine), nest);
|
||||
var machine = FindMachine(nest.Machine);
|
||||
if (!MachineCuttingDefaults.IsRecordedFor(parameters, machine, nest))
|
||||
MachineCuttingDefaults.ApplyTo(parameters, machine, nest);
|
||||
return parameters;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,11 @@ machine's units to the nest's.
|
||||
|
||||
A plate with no cutting parameters of its own (Plan Cutting, Place Lead-in) starts from the
|
||||
last applied parameters, as before, with the machine's leads and kerf laid over them and the
|
||||
machine, material, grade and thickness recorded on the parameters. A plate that already has
|
||||
machine, material, grade and thickness recorded on the parameters. When the last parameters
|
||||
already record the same machine, material, grade and thickness, the machine's settings are not
|
||||
laid over them again, so lead and tab edits made for that job stick; the cutting panel keeps the
|
||||
record (and the kerf) through an edit. Plan Cutting saves its settings as the last parameters as
|
||||
soon as its settings dialog is accepted, not only on Apply. A plate that already has
|
||||
parameters keeps them: changing the machine, material or thickness does not rewrite leads
|
||||
the plate was planned with.
|
||||
|
||||
|
||||
Reference in new issue
Block a user