feat: add option to round lead-in angles for circle holes
Snaps lead-in angles on ArcCircle contours to a configurable increment (default 5°), reducing unique hole variations from infinite to 72 max. Rounding happens upstream in EmitContour so the PlateView and post output stay in sync. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -255,7 +255,23 @@ namespace OpenNest.CNC.CuttingStrategy
|
|||||||
var leadOut = SelectLeadOut(contourType);
|
var leadOut = SelectLeadOut(contourType);
|
||||||
|
|
||||||
if (contourType == ContourType.ArcCircle && entity is Circle circle)
|
if (contourType == ContourType.ArcCircle && entity is Circle circle)
|
||||||
|
{
|
||||||
|
if (Parameters.RoundLeadInAngles && Parameters.LeadInAngleIncrement > 0)
|
||||||
|
{
|
||||||
|
var increment = Angle.ToRadians(Parameters.LeadInAngleIncrement);
|
||||||
|
normal = System.Math.Round(normal / increment) * increment;
|
||||||
|
normal = Angle.NormalizeRad(normal);
|
||||||
|
|
||||||
|
// Recompute contour start point on the circle at the rounded angle.
|
||||||
|
// For ArcCircle, normal points inward (toward center), so outward = normal - PI.
|
||||||
|
var outwardAngle = normal - System.Math.PI;
|
||||||
|
point = new Vector(
|
||||||
|
circle.Center.X + circle.Radius * System.Math.Cos(outwardAngle),
|
||||||
|
circle.Center.Y + circle.Radius * System.Math.Sin(outwardAngle));
|
||||||
|
}
|
||||||
|
|
||||||
leadIn = ClampLeadInForCircle(leadIn, circle, point, normal);
|
leadIn = ClampLeadInForCircle(leadIn, circle, point, normal);
|
||||||
|
}
|
||||||
|
|
||||||
program.Codes.AddRange(leadIn.Generate(point, normal, winding));
|
program.Codes.AddRange(leadIn.Generate(point, normal, winding));
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,9 @@ namespace OpenNest.CNC.CuttingStrategy
|
|||||||
|
|
||||||
public double PierceClearance { get; set; } = 0.0625;
|
public double PierceClearance { get; set; } = 0.0625;
|
||||||
|
|
||||||
|
public bool RoundLeadInAngles { get; set; }
|
||||||
|
public double LeadInAngleIncrement { get; set; } = 5.0;
|
||||||
|
|
||||||
public double AutoTabMinSize { get; set; }
|
public double AutoTabMinSize { get; set; }
|
||||||
public double AutoTabMaxSize { get; set; }
|
public double AutoTabMaxSize { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,9 @@ namespace OpenNest.Controls
|
|||||||
private readonly NumericUpDown nudAutoTabMax;
|
private readonly NumericUpDown nudAutoTabMax;
|
||||||
private readonly NumericUpDown nudPierceClearance;
|
private readonly NumericUpDown nudPierceClearance;
|
||||||
|
|
||||||
|
private readonly CheckBox chkRoundLeadInAngles;
|
||||||
|
private readonly NumericUpDown nudLeadInAngleIncrement;
|
||||||
|
|
||||||
private readonly Button btnAutoAssign;
|
private readonly Button btnAutoAssign;
|
||||||
|
|
||||||
private bool suppressEvents;
|
private bool suppressEvents;
|
||||||
@@ -162,7 +165,7 @@ namespace OpenNest.Controls
|
|||||||
{
|
{
|
||||||
HeaderText = "Pierce",
|
HeaderText = "Pierce",
|
||||||
Dock = DockStyle.Top,
|
Dock = DockStyle.Top,
|
||||||
ExpandedHeight = 60,
|
ExpandedHeight = 90,
|
||||||
IsExpanded = true
|
IsExpanded = true
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -176,6 +179,34 @@ namespace OpenNest.Controls
|
|||||||
nudPierceClearance = CreateNumeric(130, 3, 0.0625, 0.0625);
|
nudPierceClearance = CreateNumeric(130, 3, 0.0625, 0.0625);
|
||||||
piercePanel.ContentPanel.Controls.Add(nudPierceClearance);
|
piercePanel.ContentPanel.Controls.Add(nudPierceClearance);
|
||||||
|
|
||||||
|
chkRoundLeadInAngles = new CheckBox
|
||||||
|
{
|
||||||
|
Text = "Round Lead-In Angles",
|
||||||
|
Location = new Point(12, 32),
|
||||||
|
AutoSize = true
|
||||||
|
};
|
||||||
|
chkRoundLeadInAngles.CheckedChanged += (s, e) =>
|
||||||
|
{
|
||||||
|
nudLeadInAngleIncrement.Enabled = chkRoundLeadInAngles.Checked;
|
||||||
|
OnParametersChanged();
|
||||||
|
};
|
||||||
|
piercePanel.ContentPanel.Controls.Add(chkRoundLeadInAngles);
|
||||||
|
|
||||||
|
piercePanel.ContentPanel.Controls.Add(new Label
|
||||||
|
{
|
||||||
|
Text = "Increment:",
|
||||||
|
Location = new Point(175, 34),
|
||||||
|
AutoSize = true
|
||||||
|
});
|
||||||
|
|
||||||
|
nudLeadInAngleIncrement = CreateNumeric(245, 31, 5, 1);
|
||||||
|
nudLeadInAngleIncrement.DecimalPlaces = 0;
|
||||||
|
nudLeadInAngleIncrement.Minimum = 1;
|
||||||
|
nudLeadInAngleIncrement.Maximum = 90;
|
||||||
|
nudLeadInAngleIncrement.Enabled = false;
|
||||||
|
nudLeadInAngleIncrement.ValueChanged += (s, e) => OnParametersChanged();
|
||||||
|
piercePanel.ContentPanel.Controls.Add(nudLeadInAngleIncrement);
|
||||||
|
|
||||||
// Auto-Assign button — wrapped in a panel for Dock.Top with padding
|
// Auto-Assign button — wrapped in a panel for Dock.Top with padding
|
||||||
btnAutoAssign = new Button
|
btnAutoAssign = new Button
|
||||||
{
|
{
|
||||||
@@ -218,6 +249,8 @@ namespace OpenNest.Controls
|
|||||||
TabsEnabled = chkTabsEnabled.Checked,
|
TabsEnabled = chkTabsEnabled.Checked,
|
||||||
TabConfig = new NormalTab { Size = (double)nudTabWidth.Value },
|
TabConfig = new NormalTab { Size = (double)nudTabWidth.Value },
|
||||||
PierceClearance = (double)nudPierceClearance.Value,
|
PierceClearance = (double)nudPierceClearance.Value,
|
||||||
|
RoundLeadInAngles = chkRoundLeadInAngles.Checked,
|
||||||
|
LeadInAngleIncrement = (double)nudLeadInAngleIncrement.Value,
|
||||||
AutoTabMinSize = (double)nudAutoTabMin.Value,
|
AutoTabMinSize = (double)nudAutoTabMin.Value,
|
||||||
AutoTabMaxSize = (double)nudAutoTabMax.Value
|
AutoTabMaxSize = (double)nudAutoTabMax.Value
|
||||||
};
|
};
|
||||||
@@ -238,6 +271,9 @@ namespace OpenNest.Controls
|
|||||||
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;
|
nudPierceClearance.Value = (decimal)p.PierceClearance;
|
||||||
|
chkRoundLeadInAngles.Checked = p.RoundLeadInAngles;
|
||||||
|
nudLeadInAngleIncrement.Value = (decimal)p.LeadInAngleIncrement;
|
||||||
|
nudLeadInAngleIncrement.Enabled = p.RoundLeadInAngles;
|
||||||
nudAutoTabMin.Value = (decimal)p.AutoTabMinSize;
|
nudAutoTabMin.Value = (decimal)p.AutoTabMinSize;
|
||||||
nudAutoTabMax.Value = (decimal)p.AutoTabMaxSize;
|
nudAutoTabMax.Value = (decimal)p.AutoTabMaxSize;
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ namespace OpenNest.Forms
|
|||||||
TabsEnabled = p.TabsEnabled,
|
TabsEnabled = p.TabsEnabled,
|
||||||
TabWidth = p.TabConfig?.Size ?? 0.25,
|
TabWidth = p.TabConfig?.Size ?? 0.25,
|
||||||
PierceClearance = p.PierceClearance,
|
PierceClearance = p.PierceClearance,
|
||||||
|
RoundLeadInAngles = p.RoundLeadInAngles,
|
||||||
|
LeadInAngleIncrement = p.LeadInAngleIncrement,
|
||||||
AutoTabMinSize = p.AutoTabMinSize,
|
AutoTabMinSize = p.AutoTabMinSize,
|
||||||
AutoTabMaxSize = p.AutoTabMaxSize
|
AutoTabMaxSize = p.AutoTabMaxSize
|
||||||
};
|
};
|
||||||
@@ -47,6 +49,8 @@ namespace OpenNest.Forms
|
|||||||
TabsEnabled = dto.TabsEnabled,
|
TabsEnabled = dto.TabsEnabled,
|
||||||
TabConfig = new NormalTab { Size = dto.TabWidth },
|
TabConfig = new NormalTab { Size = dto.TabWidth },
|
||||||
PierceClearance = dto.PierceClearance,
|
PierceClearance = dto.PierceClearance,
|
||||||
|
RoundLeadInAngles = dto.RoundLeadInAngles,
|
||||||
|
LeadInAngleIncrement = dto.LeadInAngleIncrement > 0 ? dto.LeadInAngleIncrement : 5.0,
|
||||||
AutoTabMinSize = dto.AutoTabMinSize,
|
AutoTabMinSize = dto.AutoTabMinSize,
|
||||||
AutoTabMaxSize = dto.AutoTabMaxSize
|
AutoTabMaxSize = dto.AutoTabMaxSize
|
||||||
};
|
};
|
||||||
@@ -111,6 +115,8 @@ namespace OpenNest.Forms
|
|||||||
public bool TabsEnabled { get; set; }
|
public bool TabsEnabled { get; set; }
|
||||||
public double TabWidth { get; set; }
|
public double TabWidth { get; set; }
|
||||||
public double PierceClearance { get; set; }
|
public double PierceClearance { get; set; }
|
||||||
|
public bool RoundLeadInAngles { get; set; }
|
||||||
|
public double LeadInAngleIncrement { get; set; }
|
||||||
public double AutoTabMinSize { get; set; }
|
public double AutoTabMinSize { get; set; }
|
||||||
public double AutoTabMaxSize { get; set; }
|
public double AutoTabMaxSize { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user