feat: add pierce point visualization and rename shape dimensions to Length/Width

Add toggleable pierce point drawing to PlateView that shows small red
filled circles at each rapid move endpoint (where cutting begins). Wire
through View menu, EditNestForm toggle, and MainForm handler.

Also rename RectangleShape/RoundedRectangleShape Width/Height to
Length/Width for consistency with CNC conventions, update MCP tools and
tests accordingly. Fix SplitDrawingForm designer layout ordering and
EntityView bend line selection styling.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-25 21:26:49 -04:00
parent 19001ea5be
commit f29f086080
14 changed files with 167 additions and 95 deletions

View File

@@ -194,9 +194,9 @@ namespace OpenNest.Controls
{
DashPattern = new float[] { 8, 6 }
};
using var selectedPen = new Pen(Color.Cyan, 2.5f)
using var glowPen = new Pen(Color.OrangeRed, 2.0f)
{
DashPattern = new float[] { 8, 6 }
DashPattern = new float[] { 6, 4 }
};
for (var i = 0; i < Bends.Count; i++)
@@ -204,7 +204,15 @@ namespace OpenNest.Controls
var bend = Bends[i];
var pt1 = PointWorldToGraph(bend.StartPoint);
var pt2 = PointWorldToGraph(bend.EndPoint);
g.DrawLine(i == SelectedBendIndex ? selectedPen : bendPen, pt1, pt2);
if (i == SelectedBendIndex)
{
g.DrawLine(glowPen, pt1, pt2);
}
else
{
g.DrawLine(bendPen, pt1, pt2);
}
}
}

View File

@@ -131,6 +131,8 @@ namespace OpenNest.Controls
public bool DrawRapid { get; set; }
public bool DrawPiercePoints { get; set; }
public bool DrawBounds { get; set; }
public bool DrawOffset { get; set; }
@@ -617,6 +619,9 @@ namespace OpenNest.Controls
if (DrawRapid)
DrawRapids(g);
if (DrawPiercePoints)
DrawAllPiercePoints(g);
}
private void DrawBendLines(Graphics g, Part part)
@@ -813,6 +818,54 @@ namespace OpenNest.Controls
}
}
private void DrawAllPiercePoints(Graphics g)
{
using var brush = new SolidBrush(Color.Red);
using var pen = new Pen(Color.DarkRed, 1f);
for (var i = 0; i < Plate.Parts.Count; ++i)
{
var part = Plate.Parts[i];
var pgm = part.Program;
var pos = part.Location;
DrawProgramPiercePoints(g, pgm, ref pos, brush, pen);
}
}
private void DrawProgramPiercePoints(Graphics g, Program pgm, ref Vector pos, Brush brush, Pen pen)
{
for (var i = 0; i < pgm.Length; ++i)
{
var code = pgm[i];
if (code.Type == CodeType.SubProgramCall)
{
var subpgm = (SubProgramCall)code;
if (subpgm.Program != null)
DrawProgramPiercePoints(g, subpgm.Program, ref pos, brush, pen);
}
else
{
var motion = code as Motion;
if (motion == null) continue;
var endpt = pgm.Mode == Mode.Incremental
? motion.EndPoint + pos
: motion.EndPoint;
if (code.Type == CodeType.RapidMove)
{
var pt = PointWorldToGraph(endpt);
var radius = 2f;
g.FillEllipse(brush, pt.X - radius, pt.Y - radius, radius * 2, radius * 2);
g.DrawEllipse(pen, pt.X - radius, pt.Y - radius, radius * 2, radius * 2);
}
pos = endpt;
}
}
}
private void DrawLine(Graphics g, Vector pt1, Vector pt2, Pen pen)
{
var point1 = PointWorldToGraph(pt1);

View File

@@ -473,6 +473,12 @@ namespace OpenNest.Forms
PlateView.Invalidate();
}
public void TogglePiercePoints()
{
PlateView.DrawPiercePoints = !PlateView.DrawPiercePoints;
PlateView.Invalidate();
}
public void ToggleDrawBounds()
{
PlateView.DrawBounds = !PlateView.DrawBounds;

View File

@@ -48,6 +48,7 @@
mnuEditSelectAll = new System.Windows.Forms.ToolStripMenuItem();
mnuView = new System.Windows.Forms.ToolStripMenuItem();
mnuViewDrawRapids = new System.Windows.Forms.ToolStripMenuItem();
mnuViewDrawPiercePoints = new System.Windows.Forms.ToolStripMenuItem();
mnuViewDrawBounds = new System.Windows.Forms.ToolStripMenuItem();
mnuViewDrawOffset = new System.Windows.Forms.ToolStripMenuItem();
toolStripMenuItem5 = new System.Windows.Forms.ToolStripSeparator();
@@ -297,7 +298,7 @@
//
// mnuView
//
mnuView.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { mnuViewDrawRapids, mnuViewDrawBounds, mnuViewDrawOffset, toolStripMenuItem5, mnuViewZoomTo, mnuViewZoomIn, mnuViewZoomOut });
mnuView.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { mnuViewDrawRapids, mnuViewDrawPiercePoints, mnuViewDrawBounds, mnuViewDrawOffset, toolStripMenuItem5, mnuViewZoomTo, mnuViewZoomIn, mnuViewZoomOut });
mnuView.Name = "mnuView";
mnuView.Size = new System.Drawing.Size(44, 20);
mnuView.Text = "&View";
@@ -308,7 +309,15 @@
mnuViewDrawRapids.Size = new System.Drawing.Size(222, 22);
mnuViewDrawRapids.Text = "Draw Rapids";
mnuViewDrawRapids.Click += ToggleDrawRapids_Click;
//
//
// mnuViewDrawPiercePoints
//
mnuViewDrawPiercePoints.CheckOnClick = true;
mnuViewDrawPiercePoints.Name = "mnuViewDrawPiercePoints";
mnuViewDrawPiercePoints.Size = new System.Drawing.Size(222, 22);
mnuViewDrawPiercePoints.Text = "Draw Pierce Points";
mnuViewDrawPiercePoints.Click += ToggleDrawPiercePoints_Click;
//
// mnuViewDrawBounds
//
mnuViewDrawBounds.CheckOnClick = true;
@@ -1131,6 +1140,7 @@
private System.Windows.Forms.ToolStripMenuItem mnuEditSelectAll;
private System.Windows.Forms.ToolStripMenuItem mnuView;
private System.Windows.Forms.ToolStripMenuItem mnuViewDrawRapids;
private System.Windows.Forms.ToolStripMenuItem mnuViewDrawPiercePoints;
private System.Windows.Forms.ToolStripMenuItem mnuViewDrawBounds;
private System.Windows.Forms.ToolStripMenuItem mnuViewDrawOffset;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem5;

View File

@@ -391,6 +391,7 @@ namespace OpenNest.Forms
activeForm.PlateView.PartAdded += PlateView_PartAdded;
activeForm.PlateView.PartRemoved += PlateView_PartRemoved;
mnuViewDrawRapids.Checked = activeForm.PlateView.DrawRapid;
mnuViewDrawPiercePoints.Checked = activeForm.PlateView.DrawPiercePoints;
mnuViewDrawBounds.Checked = activeForm.PlateView.DrawBounds;
statusLabel1.Text = activeForm.PlateView.Status;
}
@@ -553,6 +554,13 @@ namespace OpenNest.Forms
mnuViewDrawRapids.Checked = activeForm.PlateView.DrawRapid;
}
private void ToggleDrawPiercePoints_Click(object sender, EventArgs e)
{
if (activeForm == null) return;
activeForm.TogglePiercePoints();
mnuViewDrawPiercePoints.Checked = activeForm.PlateView.DrawPiercePoints;
}
private void ToggleDrawBounds_Click(object sender, EventArgs e)
{
if (activeForm == null) return;

View File

@@ -29,9 +29,6 @@ namespace OpenNest.Forms
private void InitializeComponent()
{
pnlSettings = new System.Windows.Forms.Panel();
pnlButtons = new System.Windows.Forms.Panel();
btnCancel = new System.Windows.Forms.Button();
btnOK = new System.Windows.Forms.Button();
grpSpikeParams = new System.Windows.Forms.GroupBox();
nudSpikePairCount = new System.Windows.Forms.NumericUpDown();
lblSpikePairCount = new System.Windows.Forms.Label();
@@ -70,6 +67,9 @@ namespace OpenNest.Forms
radByCount = new System.Windows.Forms.RadioButton();
radFitToPlate = new System.Windows.Forms.RadioButton();
radManual = new System.Windows.Forms.RadioButton();
pnlButtons = new System.Windows.Forms.Panel();
btnOK = new System.Windows.Forms.Button();
btnCancel = new System.Windows.Forms.Button();
pnlPreview = new SplitPreview();
toolStrip = new System.Windows.Forms.ToolStrip();
btnAddLine = new System.Windows.Forms.ToolStripButton();
@@ -96,6 +96,7 @@ namespace OpenNest.Forms
((System.ComponentModel.ISupportInitialize)nudPlateHeight).BeginInit();
((System.ComponentModel.ISupportInitialize)nudPlateWidth).BeginInit();
grpMethod.SuspendLayout();
pnlButtons.SuspendLayout();
toolStrip.SuspendLayout();
statusStrip.SuspendLayout();
SuspendLayout();
@@ -116,38 +117,6 @@ namespace OpenNest.Forms
pnlSettings.Padding = new System.Windows.Forms.Padding(6);
pnlSettings.Size = new System.Drawing.Size(220, 611);
pnlSettings.TabIndex = 2;
//
// pnlButtons
//
pnlButtons.Controls.Add(btnOK);
pnlButtons.Controls.Add(btnCancel);
pnlButtons.Dock = System.Windows.Forms.DockStyle.Bottom;
pnlButtons.Name = "pnlButtons";
pnlButtons.Size = new System.Drawing.Size(208, 40);
pnlButtons.TabIndex = 8;
//
// btnCancel
//
btnCancel.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right;
btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
btnCancel.Location = new System.Drawing.Point(110, 6);
btnCancel.Name = "btnCancel";
btnCancel.Size = new System.Drawing.Size(80, 28);
btnCancel.TabIndex = 7;
btnCancel.Text = "Cancel";
btnCancel.UseVisualStyleBackColor = true;
btnCancel.Click += OnCancel;
//
// btnOK
//
btnOK.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right;
btnOK.Location = new System.Drawing.Point(20, 6);
btnOK.Name = "btnOK";
btnOK.Size = new System.Drawing.Size(80, 28);
btnOK.TabIndex = 6;
btnOK.Text = "OK";
btnOK.UseVisualStyleBackColor = true;
btnOK.Click += OnOK;
//
// grpSpikeParams
//
@@ -216,7 +185,7 @@ namespace OpenNest.Forms
nudGrooveDepth.Name = "nudGrooveDepth";
nudGrooveDepth.Size = new System.Drawing.Size(88, 23);
nudGrooveDepth.TabIndex = 1;
nudGrooveDepth.Value = new decimal(new int[] { 625, 0, 0, 196608 });
nudGrooveDepth.Value = new decimal(new int[] { 125, 0, 0, 196608 });
nudGrooveDepth.ValueChanged += OnSpikeParamChanged;
//
// lblGrooveDepth
@@ -568,6 +537,39 @@ namespace OpenNest.Forms
radManual.Text = "Manual";
radManual.CheckedChanged += OnMethodChanged;
//
// pnlButtons
//
pnlButtons.Controls.Add(btnOK);
pnlButtons.Controls.Add(btnCancel);
pnlButtons.Dock = System.Windows.Forms.DockStyle.Bottom;
pnlButtons.Location = new System.Drawing.Point(6, 637);
pnlButtons.Name = "pnlButtons";
pnlButtons.Size = new System.Drawing.Size(191, 40);
pnlButtons.TabIndex = 8;
//
// btnOK
//
btnOK.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right;
btnOK.Location = new System.Drawing.Point(11, 6);
btnOK.Name = "btnOK";
btnOK.Size = new System.Drawing.Size(80, 28);
btnOK.TabIndex = 6;
btnOK.Text = "OK";
btnOK.UseVisualStyleBackColor = true;
btnOK.Click += OnOK;
//
// btnCancel
//
btnCancel.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right;
btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
btnCancel.Location = new System.Drawing.Point(101, 6);
btnCancel.Name = "btnCancel";
btnCancel.Size = new System.Drawing.Size(80, 28);
btnCancel.TabIndex = 7;
btnCancel.Text = "Cancel";
btnCancel.UseVisualStyleBackColor = true;
btnCancel.Click += OnCancel;
//
// pnlPreview
//
pnlPreview.BackColor = System.Drawing.Color.FromArgb(33, 40, 48);
@@ -667,6 +669,7 @@ namespace OpenNest.Forms
((System.ComponentModel.ISupportInitialize)nudPlateWidth).EndInit();
grpMethod.ResumeLayout(false);
grpMethod.PerformLayout();
pnlButtons.ResumeLayout(false);
toolStrip.ResumeLayout(false);
toolStrip.PerformLayout();
statusStrip.ResumeLayout(false);