feat: render lead-in/lead-out codes in yellow, skip suppressed codes

Add GetGraphicsPaths/AddProgramSplit to GraphicsHelper that builds separate
GraphicsPath objects for cut vs lead-in/lead-out codes, skipping suppressed
codes. Update LayoutPart to use split paths when HasManualLeadIns is set,
drawing lead-in geometry in yellow regardless of selection state.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-30 13:32:43 -04:00
parent c9b5ee1918
commit ab4f806820
2 changed files with 94 additions and 2 deletions

View File

@@ -85,6 +85,74 @@ namespace OpenNest
return img;
}
public static void GetGraphicsPaths(this Program pgm, Vector origin,
out GraphicsPath cutPath, out GraphicsPath leadPath)
{
cutPath = new GraphicsPath();
leadPath = new GraphicsPath();
var curpos = origin;
AddProgramSplit(cutPath, leadPath, pgm, pgm.Mode, ref curpos);
}
private static void AddProgramSplit(GraphicsPath cutPath, GraphicsPath leadPath,
Program pgm, Mode mode, ref Vector curpos)
{
mode = pgm.Mode;
for (var i = 0; i < pgm.Length; ++i)
{
var code = pgm[i];
switch (code.Type)
{
case CodeType.ArcMove:
var arc = (ArcMove)code;
if (arc.Suppressed)
{
var endpt = arc.EndPoint;
if (mode == Mode.Incremental) endpt += curpos;
curpos = endpt;
break;
}
var arcPath = (arc.Layer == LayerType.Leadin || arc.Layer == LayerType.Leadout)
? leadPath : cutPath;
AddArc(arcPath, arc, mode, ref curpos);
break;
case CodeType.LinearMove:
var line = (LinearMove)code;
if (line.Suppressed)
{
var endpt = line.EndPoint;
if (mode == Mode.Incremental) endpt += curpos;
curpos = endpt;
break;
}
var linePath = (line.Layer == LayerType.Leadin || line.Layer == LayerType.Leadout)
? leadPath : cutPath;
AddLine(linePath, line, mode, ref curpos);
break;
case CodeType.RapidMove:
AddLine(cutPath, (RapidMove)code, mode, ref curpos);
break;
case CodeType.SubProgramCall:
var tmpmode = mode;
var subpgm = (SubProgramCall)code;
if (subpgm.Program != null)
{
cutPath.StartFigure();
leadPath.StartFigure();
AddProgramSplit(cutPath, leadPath, subpgm.Program, mode, ref curpos);
}
mode = tmpmode;
break;
}
}
}
private static void AddArc(GraphicsPath path, ArcMove arc, Mode mode, ref Vector curpos)
{
var endpt = arc.EndPoint;

View File

@@ -15,6 +15,7 @@ namespace OpenNest
private static Color selectedColor;
private static Pen selectedPen;
private static Brush selectedBrush;
private static Pen leadInPen;
private Color color;
private Brush brush;
@@ -34,6 +35,7 @@ namespace OpenNest
{
programIdFont = new Font(SystemFonts.DefaultFont, FontStyle.Bold | FontStyle.Underline);
SelectedColor = Color.FromArgb(90, 150, 200, 255);
leadInPen = new Pen(Color.Yellow, 1.5f);
}
private LayoutPart(Part part)
@@ -52,6 +54,8 @@ namespace OpenNest
public GraphicsPath Path { get; private set; }
public GraphicsPath LeadInPath { get; private set; }
public Color Color
{
get { return color; }
@@ -83,6 +87,9 @@ namespace OpenNest
g.FillPath(brush, Path);
g.DrawPath(pen, Path);
}
if (LeadInPath != null)
g.DrawPath(leadInPen, LeadInPath);
}
public void Draw(Graphics g, string id)
@@ -98,6 +105,9 @@ namespace OpenNest
g.DrawPath(pen, Path);
}
if (LeadInPath != null)
g.DrawPath(leadInPen, LeadInPath);
using var sf = new StringFormat
{
Alignment = StringAlignment.Center,
@@ -138,8 +148,22 @@ namespace OpenNest
public void Update(DrawControl plateView)
{
Path = GraphicsHelper.GetGraphicsPath(BasePart.Program, BasePart.Location);
Path.Transform(plateView.Matrix);
if (BasePart.HasManualLeadIns)
{
BasePart.Program.GetGraphicsPaths(BasePart.Location, out var cutPath, out var leadPath);
cutPath.Transform(plateView.Matrix);
leadPath.Transform(plateView.Matrix);
Path = cutPath;
LeadInPath?.Dispose();
LeadInPath = leadPath;
}
else
{
Path = GraphicsHelper.GetGraphicsPath(BasePart.Program, BasePart.Location);
Path.Transform(plateView.Matrix);
LeadInPath?.Dispose();
LeadInPath = null;
}
_labelPoint ??= ComputeLabelPoint();
var rotatedLabel = _labelPoint.Value.Rotate(BasePart.Rotation);