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:
4
OpenNest/Forms/CuttingParametersForm.Designer.cs
generated
4
OpenNest/Forms/CuttingParametersForm.Designer.cs
generated
@@ -114,7 +114,7 @@ namespace OpenNest.Forms
|
||||
this.bottomPanel.Controls.Add(this.acceptButton);
|
||||
this.bottomPanel.Controls.Add(this.cancelButton);
|
||||
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.Size = new System.Drawing.Size(380, 50);
|
||||
this.bottomPanel.TabIndex = 1;
|
||||
@@ -125,7 +125,7 @@ namespace OpenNest.Forms
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
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.bottomPanel);
|
||||
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 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()
|
||||
{
|
||||
@@ -54,9 +66,33 @@ namespace OpenNest.Forms
|
||||
protected override void OnLoad(EventArgs 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);
|
||||
}
|
||||
|
||||
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,
|
||||
out ComboBox leadInCombo, out Panel leadInPanel,
|
||||
out ComboBox leadOutCombo, out Panel leadOutPanel)
|
||||
@@ -164,6 +200,35 @@ namespace OpenNest.Forms
|
||||
grpTabs.Controls.Add(nudTabWidth);
|
||||
|
||||
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()
|
||||
@@ -305,6 +370,8 @@ namespace OpenNest.Forms
|
||||
chkTabsEnabled.Checked = p.TabsEnabled;
|
||||
if (p.TabConfig != null)
|
||||
nudTabWidth.Value = (decimal)p.TabConfig.Size;
|
||||
|
||||
nudPierceClearance.Value = (decimal)p.PierceClearance;
|
||||
}
|
||||
|
||||
private static void LoadLeadIn(ComboBox combo, Panel panel, LeadIn leadIn)
|
||||
@@ -379,7 +446,8 @@ namespace OpenNest.Forms
|
||||
ArcCircleLeadIn = BuildLeadIn(cboArcCircleLeadIn, pnlArcCircleLeadIn),
|
||||
ArcCircleLeadOut = BuildLeadOut(cboArcCircleLeadOut, pnlArcCircleLeadOut),
|
||||
TabsEnabled = chkTabsEnabled.Checked,
|
||||
TabConfig = new NormalTab { Size = (double)nudTabWidth.Value }
|
||||
TabConfig = new NormalTab { Size = (double)nudTabWidth.Value },
|
||||
PierceClearance = (double)nudPierceClearance.Value
|
||||
};
|
||||
return p;
|
||||
}
|
||||
|
||||
138
OpenNest/Forms/CuttingParametersSerializer.cs
Normal file
138
OpenNest/Forms/CuttingParametersSerializer.cs
Normal file
@@ -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; }
|
||||
}
|
||||
}
|
||||
}
|
||||
12
OpenNest/Properties/Settings.Designer.cs
generated
12
OpenNest/Properties/Settings.Designer.cs
generated
@@ -226,5 +226,17 @@ namespace OpenNest.Properties {
|
||||
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">
|
||||
<Value Profile="(Default)" />
|
||||
</Setting>
|
||||
<Setting Name="CuttingParametersJson" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)" />
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
||||
@@ -56,6 +56,9 @@
|
||||
<setting name="LastPierceTime" serializeAs="String">
|
||||
<value>0</value>
|
||||
</setting>
|
||||
<setting name="CuttingParametersJson" serializeAs="String">
|
||||
<value/>
|
||||
</setting>
|
||||
</OpenNest.Properties.Settings>
|
||||
<OpenNest.Resources.Settings>
|
||||
<setting name="MainFormLocation" serializeAs="String">
|
||||
|
||||
Reference in New Issue
Block a user