fix: assign colors to SpecialLayers and ConvertProgram entities
ConvertProgram.ToGeometry() created entities without setting Color,
defaulting to Color.Empty (alpha=0). After ededc7b switched from
Pens.White to per-entity colors, these rendered fully transparent.
- Add explicit colors to all SpecialLayers (Cut=White, Rapid=Gray, etc.)
- Set entity Color from layer in ConvertProgram for lines, arcs, circles
- Add GetEntityPen fallback: treat Empty/alpha-0 as White
- Add bend line rendering and selection in EntityView/CadConverterForm
- Fix SolidWorksBendDetector MText formatting strip for bend notes
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -59,9 +59,11 @@ namespace OpenNest.Converters
|
|||||||
if (mode == Mode.Incremental)
|
if (mode == Mode.Incremental)
|
||||||
pt += curpos;
|
pt += curpos;
|
||||||
|
|
||||||
|
var layer = ConvertLayer(linearMove.Layer);
|
||||||
var line = new Line(curpos, pt)
|
var line = new Line(curpos, pt)
|
||||||
{
|
{
|
||||||
Layer = ConvertLayer(linearMove.Layer)
|
Layer = layer,
|
||||||
|
Color = layer.Color
|
||||||
};
|
};
|
||||||
geometry.Add(line);
|
geometry.Add(line);
|
||||||
curpos = pt;
|
curpos = pt;
|
||||||
@@ -76,7 +78,8 @@ namespace OpenNest.Converters
|
|||||||
|
|
||||||
var line = new Line(curpos, pt)
|
var line = new Line(curpos, pt)
|
||||||
{
|
{
|
||||||
Layer = SpecialLayers.Rapid
|
Layer = SpecialLayers.Rapid,
|
||||||
|
Color = SpecialLayers.Rapid.Color
|
||||||
};
|
};
|
||||||
geometry.Add(line);
|
geometry.Add(line);
|
||||||
curpos = pt;
|
curpos = pt;
|
||||||
@@ -103,9 +106,9 @@ namespace OpenNest.Converters
|
|||||||
var layer = ConvertLayer(arcMove.Layer);
|
var layer = ConvertLayer(arcMove.Layer);
|
||||||
|
|
||||||
if (startAngle.IsEqualTo(endAngle))
|
if (startAngle.IsEqualTo(endAngle))
|
||||||
geometry.Add(new Circle(center, radius) { Layer = layer });
|
geometry.Add(new Circle(center, radius) { Layer = layer, Color = layer.Color });
|
||||||
else
|
else
|
||||||
geometry.Add(new Arc(center, radius, startAngle, endAngle, arcMove.Rotation == RotationType.CW) { Layer = layer });
|
geometry.Add(new Arc(center, radius, startAngle, endAngle, arcMove.Rotation == RotationType.CW) { Layer = layer, Color = layer.Color });
|
||||||
|
|
||||||
curpos = endpt;
|
curpos = endpt;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,22 @@
|
|||||||
using OpenNest.Geometry;
|
using System.Drawing;
|
||||||
|
using OpenNest.Geometry;
|
||||||
|
|
||||||
namespace OpenNest
|
namespace OpenNest
|
||||||
{
|
{
|
||||||
public static class SpecialLayers
|
public static class SpecialLayers
|
||||||
{
|
{
|
||||||
public static readonly Layer Default = new Layer("0");
|
public static readonly Layer Default = new Layer("0") { Color = Color.White };
|
||||||
|
|
||||||
public static readonly Layer Cut = new Layer("CUT");
|
public static readonly Layer Cut = new Layer("CUT") { Color = Color.White };
|
||||||
|
|
||||||
public static readonly Layer Rapid = new Layer("RAPID");
|
public static readonly Layer Rapid = new Layer("RAPID") { Color = Color.Gray };
|
||||||
|
|
||||||
public static readonly Layer Display = new Layer("DISPLAY");
|
public static readonly Layer Display = new Layer("DISPLAY") { Color = Color.Cyan };
|
||||||
|
|
||||||
public static readonly Layer Leadin = new Layer("LEADIN");
|
public static readonly Layer Leadin = new Layer("LEADIN") { Color = Color.Yellow };
|
||||||
|
|
||||||
public static readonly Layer Leadout = new Layer("LEADOUT");
|
public static readonly Layer Leadout = new Layer("LEADOUT") { Color = Color.Yellow };
|
||||||
|
|
||||||
public static readonly Layer Scribe = new Layer("SCRIBE");
|
public static readonly Layer Scribe = new Layer("SCRIBE") { Color = Color.Magenta };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,9 +17,13 @@ namespace OpenNest.IO.Bending
|
|||||||
public double MaxBendRadius { get; set; } = 4.0;
|
public double MaxBendRadius { get; set; } = 4.0;
|
||||||
|
|
||||||
private static readonly Regex BendNoteRegex = new Regex(
|
private static readonly Regex BendNoteRegex = new Regex(
|
||||||
@"\b(?<direction>UP|DOWN|DN)\s+(?<angle>\d+(\.\d+)?)°?\s*R\s*(?<radius>\d+(\.\d+)?)\b",
|
@"(?<direction>UP|DOWN|DN)\s+(?<angle>\d+(\.\d+)?)[^A-Z\d]*R\s*(?<radius>\d+(\.\d+)?)",
|
||||||
RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||||
|
|
||||||
|
private static readonly Regex MTextFormatRegex = new Regex(
|
||||||
|
@"\\[fHCTQWASpOoLlKk][^;]*;|\\P|[{}]|%%[dDpPcC]",
|
||||||
|
RegexOptions.Compiled);
|
||||||
|
|
||||||
public List<Bend> DetectBends(CadDocument document)
|
public List<Bend> DetectBends(CadDocument document)
|
||||||
{
|
{
|
||||||
var bendLines = FindBendLines(document);
|
var bendLines = FindBendLines(document);
|
||||||
@@ -45,9 +49,10 @@ namespace OpenNest.IO.Bending
|
|||||||
var note = FindClosestBendNote(line, bendNotes);
|
var note = FindClosestBendNote(line, bendNotes);
|
||||||
if (note != null)
|
if (note != null)
|
||||||
{
|
{
|
||||||
bend.Direction = GetBendDirection(note.Value);
|
var noteText = StripMTextFormatting(note.Value);
|
||||||
bend.NoteText = note.Value;
|
bend.Direction = GetBendDirection(noteText);
|
||||||
ParseBendNote(note.Value, bend);
|
bend.NoteText = noteText;
|
||||||
|
ParseBendNote(noteText, bend);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bend.Radius.HasValue || bend.Radius.Value <= MaxBendRadius)
|
if (!bend.Radius.HasValue || bend.Radius.Value <= MaxBendRadius)
|
||||||
@@ -106,6 +111,24 @@ namespace OpenNest.IO.Bending
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string StripMTextFormatting(string text)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(text))
|
||||||
|
return text;
|
||||||
|
|
||||||
|
// Replace known DXF special characters
|
||||||
|
var result = text
|
||||||
|
.Replace("%%d", "°").Replace("%%D", "°")
|
||||||
|
.Replace("%%p", "±").Replace("%%P", "±")
|
||||||
|
.Replace("%%c", "⌀").Replace("%%C", "⌀");
|
||||||
|
|
||||||
|
// Strip MText formatting codes and braces
|
||||||
|
result = MTextFormatRegex.Replace(result, " ");
|
||||||
|
|
||||||
|
// Collapse multiple spaces
|
||||||
|
return Regex.Replace(result.Trim(), @"\s+", " ");
|
||||||
|
}
|
||||||
|
|
||||||
private MText FindClosestBendNote(ACadSharp.Entities.Line bendLine, List<MText> notes)
|
private MText FindClosestBendNote(ACadSharp.Entities.Line bendLine, List<MText> notes)
|
||||||
{
|
{
|
||||||
if (notes.Count == 0) return null;
|
if (notes.Count == 0) return null;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using OpenNest.Geometry;
|
using OpenNest.Bending;
|
||||||
|
using OpenNest.Geometry;
|
||||||
using OpenNest.Math;
|
using OpenNest.Math;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
@@ -10,6 +11,8 @@ namespace OpenNest.Controls
|
|||||||
public class EntityView : DrawControl
|
public class EntityView : DrawControl
|
||||||
{
|
{
|
||||||
public List<Entity> Entities;
|
public List<Entity> Entities;
|
||||||
|
public List<Bend> Bends = new List<Bend>();
|
||||||
|
public int SelectedBendIndex = -1;
|
||||||
|
|
||||||
private readonly Pen gridPen = new Pen(Color.FromArgb(70, 70, 70));
|
private readonly Pen gridPen = new Pen(Color.FromArgb(70, 70, 70));
|
||||||
private readonly Dictionary<int, Pen> penCache = new Dictionary<int, Pen>();
|
private readonly Dictionary<int, Pen> penCache = new Dictionary<int, Pen>();
|
||||||
@@ -49,6 +52,8 @@ namespace OpenNest.Controls
|
|||||||
DrawEntity(e.Graphics, entity, pen);
|
DrawEntity(e.Graphics, entity, pen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DrawBendLines(e.Graphics);
|
||||||
|
|
||||||
#if DRAW_OFFSET
|
#if DRAW_OFFSET
|
||||||
|
|
||||||
var offsetShape = new Shape();
|
var offsetShape = new Shape();
|
||||||
@@ -106,6 +111,9 @@ namespace OpenNest.Controls
|
|||||||
|
|
||||||
private Pen GetEntityPen(Color color)
|
private Pen GetEntityPen(Color color)
|
||||||
{
|
{
|
||||||
|
if (color.IsEmpty || color.A == 0)
|
||||||
|
color = Color.White;
|
||||||
|
|
||||||
// Clamp dark colors to ensure visibility on dark background
|
// Clamp dark colors to ensure visibility on dark background
|
||||||
var brightness = (color.R * 299 + color.G * 587 + color.B * 114) / 1000;
|
var brightness = (color.R * 299 + color.G * 587 + color.B * 114) / 1000;
|
||||||
if (brightness < 80)
|
if (brightness < 80)
|
||||||
@@ -130,6 +138,29 @@ namespace OpenNest.Controls
|
|||||||
penCache.Clear();
|
penCache.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void DrawBendLines(Graphics g)
|
||||||
|
{
|
||||||
|
if (Bends == null || Bends.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
using var bendPen = new Pen(Color.Yellow, 1.5f)
|
||||||
|
{
|
||||||
|
DashStyle = DashStyle.Dash
|
||||||
|
};
|
||||||
|
using var selectedPen = new Pen(Color.Cyan, 2.5f)
|
||||||
|
{
|
||||||
|
DashStyle = DashStyle.Dash
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var i = 0; i < Bends.Count; i++)
|
||||||
|
{
|
||||||
|
var bend = Bends[i];
|
||||||
|
var pt1 = PointWorldToGraph(bend.StartPoint);
|
||||||
|
var pt2 = PointWorldToGraph(bend.EndPoint);
|
||||||
|
g.DrawLine(i == SelectedBendIndex ? selectedPen : bendPen, pt1, pt2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected override void Dispose(bool disposing)
|
protected override void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (disposing)
|
if (disposing)
|
||||||
|
|||||||
@@ -134,6 +134,7 @@ namespace OpenNest.Forms
|
|||||||
entityView1.ClearPenCache();
|
entityView1.ClearPenCache();
|
||||||
entityView1.Entities.Clear();
|
entityView1.Entities.Clear();
|
||||||
entityView1.Entities.AddRange(item.Entities);
|
entityView1.Entities.AddRange(item.Entities);
|
||||||
|
entityView1.Bends = item.Bends ?? new List<Bend>();
|
||||||
|
|
||||||
item.Entities.ForEach(e => e.IsVisible = true);
|
item.Entities.ForEach(e => e.IsVisible = true);
|
||||||
if (item.Entities.Any(e => e.Layer != null))
|
if (item.Entities.Any(e => e.Layer != null))
|
||||||
@@ -174,7 +175,7 @@ namespace OpenNest.Forms
|
|||||||
|
|
||||||
private void OnBendLineSelected(object sender, int index)
|
private void OnBendLineSelected(object sender, int index)
|
||||||
{
|
{
|
||||||
// TODO: Highlight bend line in EntityView
|
entityView1.SelectedBendIndex = index;
|
||||||
entityView1.Invalidate();
|
entityView1.Invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,6 +185,8 @@ namespace OpenNest.Forms
|
|||||||
if (item == null || index < 0 || index >= item.Bends.Count) return;
|
if (item == null || index < 0 || index >= item.Bends.Count) return;
|
||||||
|
|
||||||
item.Bends.RemoveAt(index);
|
item.Bends.RemoveAt(index);
|
||||||
|
entityView1.Bends = item.Bends;
|
||||||
|
entityView1.SelectedBendIndex = -1;
|
||||||
filterPanel.LoadItem(item.Entities, item.Bends);
|
filterPanel.LoadItem(item.Entities, item.Bends);
|
||||||
entityView1.Invalidate();
|
entityView1.Invalidate();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user