feat: mirror axis simplifier, bend note propagation, ellipse fixes
Geometry Simplifier: - Replace least-squares circle fitting with mirror axis algorithm that constrains center to perpendicular bisector of chord, guaranteeing zero-gap endpoint connectivity by construction - Golden section search optimizes center position along the axis - Increase default tolerance from 0.005 to 0.5 for practical CNC use - Support existing arcs in simplification runs (sample arc points to find larger replacement arcs spanning lines + arcs together) - Add tolerance zone visualization (offset original geometry ±tolerance) - Show original geometry overlay with orange dashed lines in preview - Add "Original" checkbox to CadConverter for comparing old vs new - Store OriginalEntities on FileListItem to prevent tolerance creep when re-running simplifier with different settings Bend Detection: - Propagate bend notes to collinear bend lines split by cutouts using infinite-line perpendicular distance check - Add bend note text rendering in EntityView at bend line midpoints DXF Import: - Fix trimmed ellipse closing chord: only close when sweep ≈ 2π, preventing phantom lines through slot cutouts Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -25,6 +25,9 @@ namespace OpenNest.Controls
|
||||
}
|
||||
|
||||
public Arc SimplifierPreview { get; set; }
|
||||
public List<Entity> SimplifierToleranceLeft { get; set; }
|
||||
public List<Entity> SimplifierToleranceRight { get; set; }
|
||||
public List<Entity> OriginalEntities { get; set; }
|
||||
|
||||
private readonly Pen gridPen = new Pen(Color.FromArgb(70, 70, 70));
|
||||
private readonly Dictionary<int, Pen> penCache = new Dictionary<int, Pen>();
|
||||
@@ -79,6 +82,17 @@ namespace OpenNest.Controls
|
||||
|
||||
e.Graphics.TranslateTransform(origin.X, origin.Y);
|
||||
|
||||
// Draw original geometry overlay (faded, behind current)
|
||||
if (OriginalEntities != null)
|
||||
{
|
||||
using var origPen = new Pen(Color.FromArgb(50, 255, 140, 40));
|
||||
foreach (var entity in OriginalEntities)
|
||||
{
|
||||
if (!IsEtchLayer(entity.Layer))
|
||||
DrawEntity(e.Graphics, entity, origPen);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var entity in Entities)
|
||||
{
|
||||
if (IsEtchLayer(entity.Layer)) continue;
|
||||
@@ -102,6 +116,25 @@ namespace OpenNest.Controls
|
||||
|
||||
if (SimplifierPreview != null)
|
||||
{
|
||||
// Draw tolerance zone (offset lines each side of original geometry)
|
||||
if (SimplifierToleranceLeft != null)
|
||||
{
|
||||
using var zonePen = new Pen(Color.FromArgb(40, 100, 200, 100));
|
||||
foreach (var entity in SimplifierToleranceLeft)
|
||||
DrawEntity(e.Graphics, entity, zonePen);
|
||||
foreach (var entity in SimplifierToleranceRight)
|
||||
DrawEntity(e.Graphics, entity, zonePen);
|
||||
}
|
||||
|
||||
// Draw old geometry (highlighted lines) in orange dashed
|
||||
if (simplifierHighlightSet != null)
|
||||
{
|
||||
using var oldPen = new Pen(Color.FromArgb(180, 255, 160, 50), 1f / ViewScale) { DashPattern = new float[] { 6, 3 } };
|
||||
foreach (var entity in simplifierHighlightSet)
|
||||
DrawEntity(e.Graphics, entity, oldPen);
|
||||
}
|
||||
|
||||
// Draw the new arc in bright green
|
||||
using var previewPen = new Pen(Color.FromArgb(0, 200, 80), 2f / ViewScale);
|
||||
DrawArc(e.Graphics, SimplifierPreview, previewPen);
|
||||
}
|
||||
@@ -260,20 +293,26 @@ namespace OpenNest.Controls
|
||||
{
|
||||
DashPattern = new float[] { 6, 4 }
|
||||
};
|
||||
using var noteFont = new Font("Segoe UI", 9f);
|
||||
using var noteBrush = new SolidBrush(Color.FromArgb(220, 255, 255, 200));
|
||||
using var selectedNoteBrush = new SolidBrush(Color.FromArgb(220, 255, 180, 100));
|
||||
|
||||
for (var i = 0; i < Bends.Count; i++)
|
||||
{
|
||||
var bend = Bends[i];
|
||||
var pt1 = PointWorldToGraph(bend.StartPoint);
|
||||
var pt2 = PointWorldToGraph(bend.EndPoint);
|
||||
var isSelected = i == SelectedBendIndex;
|
||||
|
||||
if (i == SelectedBendIndex)
|
||||
{
|
||||
if (isSelected)
|
||||
g.DrawLine(glowPen, pt1, pt2);
|
||||
}
|
||||
else
|
||||
{
|
||||
g.DrawLine(bendPen, pt1, pt2);
|
||||
|
||||
if (!string.IsNullOrEmpty(bend.NoteText))
|
||||
{
|
||||
var mid = new PointF((pt1.X + pt2.X) / 2f, (pt1.Y + pt2.Y) / 2f);
|
||||
g.DrawString(bend.NoteText, noteFont, isSelected ? selectedNoteBrush : noteBrush, mid.X + 4, mid.Y + 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -424,6 +463,8 @@ namespace OpenNest.Controls
|
||||
{
|
||||
SimplifierHighlight = null;
|
||||
SimplifierPreview = null;
|
||||
SimplifierToleranceLeft = null;
|
||||
SimplifierToleranceRight = null;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user