feat: persist cutting parameters and add pierce clearance UI
Save/restore cutting parameters as JSON in user settings so values survive between sessions. Add pierce clearance numeric input to the CuttingParametersForm. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
+2
-2
@@ -114,7 +114,7 @@ namespace OpenNest.Forms
|
|||||||
this.bottomPanel.Controls.Add(this.acceptButton);
|
this.bottomPanel.Controls.Add(this.acceptButton);
|
||||||
this.bottomPanel.Controls.Add(this.cancelButton);
|
this.bottomPanel.Controls.Add(this.cancelButton);
|
||||||
this.bottomPanel.Dock = System.Windows.Forms.DockStyle.Bottom;
|
this.bottomPanel.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||||
this.bottomPanel.Location = new System.Drawing.Point(0, 406);
|
this.bottomPanel.Location = new System.Drawing.Point(0, 466);
|
||||||
this.bottomPanel.Name = "bottomPanel";
|
this.bottomPanel.Name = "bottomPanel";
|
||||||
this.bottomPanel.Size = new System.Drawing.Size(380, 50);
|
this.bottomPanel.Size = new System.Drawing.Size(380, 50);
|
||||||
this.bottomPanel.TabIndex = 1;
|
this.bottomPanel.TabIndex = 1;
|
||||||
@@ -125,7 +125,7 @@ namespace OpenNest.Forms
|
|||||||
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
|
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
|
||||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
this.CancelButton = this.cancelButton;
|
this.CancelButton = this.cancelButton;
|
||||||
this.ClientSize = new System.Drawing.Size(380, 456);
|
this.ClientSize = new System.Drawing.Size(380, 516);
|
||||||
this.Controls.Add(this.tabControl);
|
this.Controls.Add(this.tabControl);
|
||||||
this.Controls.Add(this.bottomPanel);
|
this.Controls.Add(this.bottomPanel);
|
||||||
this.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
this.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||||
|
|||||||
@@ -22,8 +22,20 @@ namespace OpenNest.Forms
|
|||||||
|
|
||||||
private CheckBox chkTabsEnabled;
|
private CheckBox chkTabsEnabled;
|
||||||
private NumericUpDown nudTabWidth;
|
private NumericUpDown nudTabWidth;
|
||||||
|
private NumericUpDown nudPierceClearance;
|
||||||
|
|
||||||
public CuttingParameters Parameters { get; set; } = new CuttingParameters();
|
private bool hasCustomParameters;
|
||||||
|
private CuttingParameters parameters = new CuttingParameters();
|
||||||
|
|
||||||
|
public CuttingParameters Parameters
|
||||||
|
{
|
||||||
|
get => parameters;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
parameters = value;
|
||||||
|
hasCustomParameters = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public CuttingParametersForm()
|
public CuttingParametersForm()
|
||||||
{
|
{
|
||||||
@@ -54,9 +66,33 @@ namespace OpenNest.Forms
|
|||||||
protected override void OnLoad(EventArgs e)
|
protected override void OnLoad(EventArgs e)
|
||||||
{
|
{
|
||||||
base.OnLoad(e);
|
base.OnLoad(e);
|
||||||
|
|
||||||
|
// If caller didn't provide custom parameters, try loading saved ones
|
||||||
|
if (!hasCustomParameters)
|
||||||
|
{
|
||||||
|
var json = Properties.Settings.Default.CuttingParametersJson;
|
||||||
|
if (!string.IsNullOrEmpty(json))
|
||||||
|
{
|
||||||
|
try { Parameters = CuttingParametersSerializer.Deserialize(json); }
|
||||||
|
catch { /* use defaults on corrupt data */ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LoadFromParameters(Parameters);
|
LoadFromParameters(Parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void OnFormClosing(FormClosingEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnFormClosing(e);
|
||||||
|
|
||||||
|
if (DialogResult == System.Windows.Forms.DialogResult.OK)
|
||||||
|
{
|
||||||
|
var json = CuttingParametersSerializer.Serialize(BuildParameters());
|
||||||
|
Properties.Settings.Default.CuttingParametersJson = json;
|
||||||
|
Properties.Settings.Default.Save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void SetupTab(TabPage tab,
|
private static void SetupTab(TabPage tab,
|
||||||
out ComboBox leadInCombo, out Panel leadInPanel,
|
out ComboBox leadInCombo, out Panel leadInPanel,
|
||||||
out ComboBox leadOutCombo, out Panel leadOutPanel)
|
out ComboBox leadOutCombo, out Panel leadOutPanel)
|
||||||
@@ -164,6 +200,35 @@ namespace OpenNest.Forms
|
|||||||
grpTabs.Controls.Add(nudTabWidth);
|
grpTabs.Controls.Add(nudTabWidth);
|
||||||
|
|
||||||
Controls.Add(grpTabs);
|
Controls.Add(grpTabs);
|
||||||
|
|
||||||
|
var grpPierce = new GroupBox
|
||||||
|
{
|
||||||
|
Text = "Pierce",
|
||||||
|
Location = new System.Drawing.Point(4, 410),
|
||||||
|
Size = new System.Drawing.Size(372, 55),
|
||||||
|
Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right
|
||||||
|
};
|
||||||
|
|
||||||
|
grpPierce.Controls.Add(new Label
|
||||||
|
{
|
||||||
|
Text = "Pierce Clearance:",
|
||||||
|
Location = new System.Drawing.Point(12, 23),
|
||||||
|
AutoSize = true
|
||||||
|
});
|
||||||
|
|
||||||
|
nudPierceClearance = new NumericUpDown
|
||||||
|
{
|
||||||
|
Location = new System.Drawing.Point(130, 20),
|
||||||
|
Size = new System.Drawing.Size(100, 22),
|
||||||
|
DecimalPlaces = 4,
|
||||||
|
Increment = 0.0625m,
|
||||||
|
Minimum = 0,
|
||||||
|
Maximum = 9999,
|
||||||
|
Value = 0.0625m
|
||||||
|
};
|
||||||
|
grpPierce.Controls.Add(nudPierceClearance);
|
||||||
|
|
||||||
|
Controls.Add(grpPierce);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PopulateDropdowns()
|
private void PopulateDropdowns()
|
||||||
@@ -305,6 +370,8 @@ namespace OpenNest.Forms
|
|||||||
chkTabsEnabled.Checked = p.TabsEnabled;
|
chkTabsEnabled.Checked = p.TabsEnabled;
|
||||||
if (p.TabConfig != null)
|
if (p.TabConfig != null)
|
||||||
nudTabWidth.Value = (decimal)p.TabConfig.Size;
|
nudTabWidth.Value = (decimal)p.TabConfig.Size;
|
||||||
|
|
||||||
|
nudPierceClearance.Value = (decimal)p.PierceClearance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void LoadLeadIn(ComboBox combo, Panel panel, LeadIn leadIn)
|
private static void LoadLeadIn(ComboBox combo, Panel panel, LeadIn leadIn)
|
||||||
@@ -379,7 +446,8 @@ namespace OpenNest.Forms
|
|||||||
ArcCircleLeadIn = BuildLeadIn(cboArcCircleLeadIn, pnlArcCircleLeadIn),
|
ArcCircleLeadIn = BuildLeadIn(cboArcCircleLeadIn, pnlArcCircleLeadIn),
|
||||||
ArcCircleLeadOut = BuildLeadOut(cboArcCircleLeadOut, pnlArcCircleLeadOut),
|
ArcCircleLeadOut = BuildLeadOut(cboArcCircleLeadOut, pnlArcCircleLeadOut),
|
||||||
TabsEnabled = chkTabsEnabled.Checked,
|
TabsEnabled = chkTabsEnabled.Checked,
|
||||||
TabConfig = new NormalTab { Size = (double)nudTabWidth.Value }
|
TabConfig = new NormalTab { Size = (double)nudTabWidth.Value },
|
||||||
|
PierceClearance = (double)nudPierceClearance.Value
|
||||||
};
|
};
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,138 @@
|
|||||||
|
using OpenNest.CNC.CuttingStrategy;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
|
namespace OpenNest.Forms
|
||||||
|
{
|
||||||
|
internal static class CuttingParametersSerializer
|
||||||
|
{
|
||||||
|
private static readonly JsonSerializerOptions JsonOptions = new()
|
||||||
|
{
|
||||||
|
WriteIndented = false,
|
||||||
|
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
|
||||||
|
};
|
||||||
|
|
||||||
|
public static string Serialize(CuttingParameters p)
|
||||||
|
{
|
||||||
|
var dto = new CuttingParametersDto
|
||||||
|
{
|
||||||
|
ExternalLeadIn = ToDto(p.ExternalLeadIn),
|
||||||
|
ExternalLeadOut = ToLeadOutDto(p.ExternalLeadOut),
|
||||||
|
InternalLeadIn = ToDto(p.InternalLeadIn),
|
||||||
|
InternalLeadOut = ToLeadOutDto(p.InternalLeadOut),
|
||||||
|
ArcCircleLeadIn = ToDto(p.ArcCircleLeadIn),
|
||||||
|
ArcCircleLeadOut = ToLeadOutDto(p.ArcCircleLeadOut),
|
||||||
|
TabsEnabled = p.TabsEnabled,
|
||||||
|
TabWidth = p.TabConfig?.Size ?? 0.25,
|
||||||
|
PierceClearance = p.PierceClearance
|
||||||
|
};
|
||||||
|
return JsonSerializer.Serialize(dto, JsonOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CuttingParameters Deserialize(string json)
|
||||||
|
{
|
||||||
|
var dto = JsonSerializer.Deserialize<CuttingParametersDto>(json, JsonOptions);
|
||||||
|
if (dto == null)
|
||||||
|
return new CuttingParameters();
|
||||||
|
|
||||||
|
return new CuttingParameters
|
||||||
|
{
|
||||||
|
ExternalLeadIn = FromDto(dto.ExternalLeadIn),
|
||||||
|
ExternalLeadOut = FromLeadOutDto(dto.ExternalLeadOut),
|
||||||
|
InternalLeadIn = FromDto(dto.InternalLeadIn),
|
||||||
|
InternalLeadOut = FromLeadOutDto(dto.InternalLeadOut),
|
||||||
|
ArcCircleLeadIn = FromDto(dto.ArcCircleLeadIn),
|
||||||
|
ArcCircleLeadOut = FromLeadOutDto(dto.ArcCircleLeadOut),
|
||||||
|
TabsEnabled = dto.TabsEnabled,
|
||||||
|
TabConfig = new NormalTab { Size = dto.TabWidth },
|
||||||
|
PierceClearance = dto.PierceClearance
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static LeadInDto ToDto(LeadIn leadIn)
|
||||||
|
{
|
||||||
|
return leadIn switch
|
||||||
|
{
|
||||||
|
LineLeadIn line => new LeadInDto { Type = "Line", Length = line.Length, ApproachAngle = line.ApproachAngle },
|
||||||
|
ArcLeadIn arc => new LeadInDto { Type = "Arc", Radius = arc.Radius },
|
||||||
|
LineArcLeadIn la => new LeadInDto { Type = "LineArc", LineLength = la.LineLength, ArcRadius = la.ArcRadius, ApproachAngle = la.ApproachAngle },
|
||||||
|
CleanHoleLeadIn ch => new LeadInDto { Type = "CleanHole", LineLength = ch.LineLength, ArcRadius = ch.ArcRadius, Kerf = ch.Kerf },
|
||||||
|
LineLineLeadIn ll => new LeadInDto { Type = "LineLine", Length1 = ll.Length1, Angle1 = ll.ApproachAngle1, Length2 = ll.Length2, Angle2 = ll.ApproachAngle2 },
|
||||||
|
_ => new LeadInDto { Type = "None" }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static LeadIn FromDto(LeadInDto dto)
|
||||||
|
{
|
||||||
|
if (dto == null) return new NoLeadIn();
|
||||||
|
return dto.Type switch
|
||||||
|
{
|
||||||
|
"Line" => new LineLeadIn { Length = dto.Length, ApproachAngle = dto.ApproachAngle },
|
||||||
|
"Arc" => new ArcLeadIn { Radius = dto.Radius },
|
||||||
|
"LineArc" => new LineArcLeadIn { LineLength = dto.LineLength, ArcRadius = dto.ArcRadius, ApproachAngle = dto.ApproachAngle },
|
||||||
|
"CleanHole" => new CleanHoleLeadIn { LineLength = dto.LineLength, ArcRadius = dto.ArcRadius, Kerf = dto.Kerf },
|
||||||
|
"LineLine" => new LineLineLeadIn { Length1 = dto.Length1, ApproachAngle1 = dto.Angle1, Length2 = dto.Length2, ApproachAngle2 = dto.Angle2 },
|
||||||
|
_ => new NoLeadIn()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static LeadOutDto ToLeadOutDto(LeadOut leadOut)
|
||||||
|
{
|
||||||
|
return leadOut switch
|
||||||
|
{
|
||||||
|
LineLeadOut line => new LeadOutDto { Type = "Line", Length = line.Length, ApproachAngle = line.ApproachAngle },
|
||||||
|
ArcLeadOut arc => new LeadOutDto { Type = "Arc", Radius = arc.Radius },
|
||||||
|
MicrotabLeadOut mt => new LeadOutDto { Type = "Microtab", GapSize = mt.GapSize },
|
||||||
|
_ => new LeadOutDto { Type = "None" }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static LeadOut FromLeadOutDto(LeadOutDto dto)
|
||||||
|
{
|
||||||
|
if (dto == null) return new NoLeadOut();
|
||||||
|
return dto.Type switch
|
||||||
|
{
|
||||||
|
"Line" => new LineLeadOut { Length = dto.Length, ApproachAngle = dto.ApproachAngle },
|
||||||
|
"Arc" => new ArcLeadOut { Radius = dto.Radius },
|
||||||
|
"Microtab" => new MicrotabLeadOut { GapSize = dto.GapSize },
|
||||||
|
_ => new NoLeadOut()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private class CuttingParametersDto
|
||||||
|
{
|
||||||
|
public LeadInDto ExternalLeadIn { get; set; }
|
||||||
|
public LeadOutDto ExternalLeadOut { get; set; }
|
||||||
|
public LeadInDto InternalLeadIn { get; set; }
|
||||||
|
public LeadOutDto InternalLeadOut { get; set; }
|
||||||
|
public LeadInDto ArcCircleLeadIn { get; set; }
|
||||||
|
public LeadOutDto ArcCircleLeadOut { get; set; }
|
||||||
|
public bool TabsEnabled { get; set; }
|
||||||
|
public double TabWidth { get; set; }
|
||||||
|
public double PierceClearance { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private class LeadInDto
|
||||||
|
{
|
||||||
|
public string Type { get; set; } = "None";
|
||||||
|
public double Length { get; set; }
|
||||||
|
public double ApproachAngle { get; set; }
|
||||||
|
public double Radius { get; set; }
|
||||||
|
public double LineLength { get; set; }
|
||||||
|
public double ArcRadius { get; set; }
|
||||||
|
public double Kerf { get; set; }
|
||||||
|
public double Length1 { get; set; }
|
||||||
|
public double Angle1 { get; set; }
|
||||||
|
public double Length2 { get; set; }
|
||||||
|
public double Angle2 { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private class LeadOutDto
|
||||||
|
{
|
||||||
|
public string Type { get; set; } = "None";
|
||||||
|
public double Length { get; set; }
|
||||||
|
public double ApproachAngle { get; set; }
|
||||||
|
public double Radius { get; set; }
|
||||||
|
public double GapSize { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Generated
+12
@@ -226,5 +226,17 @@ namespace OpenNest.Properties {
|
|||||||
this["DisabledStrategies"] = value;
|
this["DisabledStrategies"] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||||
|
public string CuttingParametersJson {
|
||||||
|
get {
|
||||||
|
return ((string)(this["CuttingParametersJson"]));
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
this["CuttingParametersJson"] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,5 +53,8 @@
|
|||||||
<Setting Name="DisabledStrategies" Type="System.String" Scope="User">
|
<Setting Name="DisabledStrategies" Type="System.String" Scope="User">
|
||||||
<Value Profile="(Default)" />
|
<Value Profile="(Default)" />
|
||||||
</Setting>
|
</Setting>
|
||||||
|
<Setting Name="CuttingParametersJson" Type="System.String" Scope="User">
|
||||||
|
<Value Profile="(Default)" />
|
||||||
|
</Setting>
|
||||||
</Settings>
|
</Settings>
|
||||||
</SettingsFile>
|
</SettingsFile>
|
||||||
@@ -56,6 +56,9 @@
|
|||||||
<setting name="LastPierceTime" serializeAs="String">
|
<setting name="LastPierceTime" serializeAs="String">
|
||||||
<value>0</value>
|
<value>0</value>
|
||||||
</setting>
|
</setting>
|
||||||
|
<setting name="CuttingParametersJson" serializeAs="String">
|
||||||
|
<value/>
|
||||||
|
</setting>
|
||||||
</OpenNest.Properties.Settings>
|
</OpenNest.Properties.Settings>
|
||||||
<OpenNest.Resources.Settings>
|
<OpenNest.Resources.Settings>
|
||||||
<setting name="MainFormLocation" serializeAs="String">
|
<setting name="MainFormLocation" serializeAs="String">
|
||||||
|
|||||||
Reference in New Issue
Block a user