Fix duplicate bend-note rendering in CAD converter
This commit is contained in:
@@ -26,6 +26,10 @@ namespace OpenNest.Bending
|
|||||||
[System.Text.Json.Serialization.JsonIgnore]
|
[System.Text.Json.Serialization.JsonIgnore]
|
||||||
public Entity SourceEntity { get; set; }
|
public Entity SourceEntity { get; set; }
|
||||||
|
|
||||||
|
// Import-only identity of the original CAD annotation (not nest metadata).
|
||||||
|
[System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
public ulong? SourceNoteHandle { get; set; }
|
||||||
|
|
||||||
public double Length => StartPoint.DistanceTo(EndPoint);
|
public double Length => StartPoint.DistanceTo(EndPoint);
|
||||||
|
|
||||||
public double AngleRadians => Angle.HasValue
|
public double AngleRadians => Angle.HasValue
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ namespace OpenNest.IO.Bending
|
|||||||
var noteText = StripMTextFormatting(note.Value);
|
var noteText = StripMTextFormatting(note.Value);
|
||||||
bend.Direction = GetBendDirection(noteText);
|
bend.Direction = GetBendDirection(noteText);
|
||||||
bend.NoteText = noteText;
|
bend.NoteText = noteText;
|
||||||
|
bend.SourceNoteHandle = note.Handle;
|
||||||
ParseBendNote(noteText, bend);
|
ParseBendNote(noteText, bend);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,6 +95,7 @@ namespace OpenNest.IO.Bending
|
|||||||
bend.Angle = other.Angle;
|
bend.Angle = other.Angle;
|
||||||
bend.Radius = other.Radius;
|
bend.Radius = other.Radius;
|
||||||
bend.NoteText = other.NoteText;
|
bend.NoteText = other.NoteText;
|
||||||
|
bend.SourceNoteHandle = other.SourceNoteHandle;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
using ACadSharp;
|
||||||
|
using ACadSharp.Entities;
|
||||||
|
using ACadSharp.Tables;
|
||||||
|
using CSMath;
|
||||||
|
using OpenNest.Bending;
|
||||||
|
using OpenNest.Controls;
|
||||||
|
using OpenNest.IO.Bending;
|
||||||
|
|
||||||
|
namespace OpenNest.Tests.Bending;
|
||||||
|
|
||||||
|
public class CadBendNoteTests
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void DetectedNote_HidesOnlyItsSourceText_AndReturnsWhenBendRemoved()
|
||||||
|
{
|
||||||
|
var doc = new CadDocument();
|
||||||
|
doc.Entities.Add(new Line(new XYZ(0, 0, 0), new XYZ(10, 0, 0))
|
||||||
|
{
|
||||||
|
Layer = new Layer("BEND"),
|
||||||
|
LineType = new LineType("CENTER")
|
||||||
|
});
|
||||||
|
var note = new MText { Value = "UP 90° R0.125", InsertPoint = new XYZ(5, 0.1, 0), Height = 0.2 };
|
||||||
|
doc.Entities.Add(note);
|
||||||
|
var unrelated = new MText { Value = note.Value, InsertPoint = new XYZ(50, 50, 0), Height = 0.2 };
|
||||||
|
doc.Entities.Add(unrelated);
|
||||||
|
|
||||||
|
var bends = new SolidWorksBendDetector().DetectBends(doc);
|
||||||
|
var bend = Assert.Single(bends);
|
||||||
|
Assert.Equal(note.Handle, bend.SourceNoteHandle);
|
||||||
|
var text = new CadText { SourceHandle = note.Handle, Value = note.Value };
|
||||||
|
Assert.True(text.IsReplacedByBendNote(bends));
|
||||||
|
Assert.False(new CadText { SourceHandle = unrelated.Handle, Value = note.Value }.IsReplacedByBendNote(bends));
|
||||||
|
|
||||||
|
bends.Clear();
|
||||||
|
Assert.False(text.IsReplacedByBendNote(bends));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void MissingSourceOrReplacement_DoesNotHideText()
|
||||||
|
{
|
||||||
|
var text = new CadText { SourceHandle = 42, Value = "UP 90° R0.125" };
|
||||||
|
Assert.False(text.IsReplacedByBendNote(null));
|
||||||
|
Assert.False(text.IsReplacedByBendNote(new[] { new Bend { NoteText = text.Value } }));
|
||||||
|
Assert.False(text.IsReplacedByBendNote(new[] { new Bend { SourceNoteHandle = 42 } }));
|
||||||
|
Assert.False(new CadText().IsReplacedByBendNote(new[] { new Bend { NoteText = text.Value } }));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -91,6 +91,9 @@ public class SolidWorksBendDetectorTests
|
|||||||
Assert.All(bends, b =>
|
Assert.All(bends, b =>
|
||||||
{
|
{
|
||||||
Assert.NotNull(b.NoteText);
|
Assert.NotNull(b.NoteText);
|
||||||
|
Assert.NotNull(b.SourceNoteHandle);
|
||||||
|
Assert.Contains(doc.Entities, e => e.Handle == b.SourceNoteHandle
|
||||||
|
&& e is ACadSharp.Entities.MText);
|
||||||
Assert.Equal(BendDirection.Up, b.Direction);
|
Assert.Equal(BendDirection.Up, b.Direction);
|
||||||
Assert.Equal(90.0, b.Angle);
|
Assert.Equal(90.0, b.Angle);
|
||||||
Assert.Equal(0.125, b.Radius);
|
Assert.Equal(0.125, b.Radius);
|
||||||
|
|||||||
@@ -1,10 +1,19 @@
|
|||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using OpenNest.Bending;
|
||||||
using OpenNest.Geometry;
|
using OpenNest.Geometry;
|
||||||
|
|
||||||
namespace OpenNest.Controls
|
namespace OpenNest.Controls
|
||||||
{
|
{
|
||||||
public class CadText
|
public class CadText
|
||||||
{
|
{
|
||||||
|
public ulong? SourceHandle { get; set; }
|
||||||
|
|
||||||
|
public bool IsReplacedByBendNote(IEnumerable<Bend> bends) =>
|
||||||
|
SourceHandle.HasValue && bends != null && bends.Any(b =>
|
||||||
|
b.SourceNoteHandle == SourceHandle && !string.IsNullOrEmpty(b.NoteText));
|
||||||
|
|
||||||
public Vector Position { get; set; }
|
public Vector Position { get; set; }
|
||||||
public string Value { get; set; }
|
public string Value { get; set; }
|
||||||
public double Height { get; set; }
|
public double Height { get; set; }
|
||||||
|
|||||||
@@ -346,7 +346,7 @@ namespace OpenNest.Controls
|
|||||||
|
|
||||||
foreach (var text in Texts)
|
foreach (var text in Texts)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(text.Value))
|
if (string.IsNullOrEmpty(text.Value) || text.IsReplacedByBendNote(Bends))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var estimatedWidth = text.Height * text.Value.Length * 0.6;
|
var estimatedWidth = text.Height * text.Value.Length * 0.6;
|
||||||
@@ -531,6 +531,9 @@ namespace OpenNest.Controls
|
|||||||
|
|
||||||
foreach (var text in Texts)
|
foreach (var text in Texts)
|
||||||
{
|
{
|
||||||
|
// The bend overlay already renders this source annotation.
|
||||||
|
if (text.IsReplacedByBendNote(Bends)) continue;
|
||||||
|
|
||||||
var pos = PointWorldToGraph(text.Position);
|
var pos = PointWorldToGraph(text.Position);
|
||||||
var fontSize = LengthWorldToGui(text.Height);
|
var fontSize = LengthWorldToGui(text.Height);
|
||||||
if (fontSize < 2f) continue;
|
if (fontSize < 2f) continue;
|
||||||
|
|||||||
@@ -929,6 +929,7 @@ namespace OpenNest.Forms
|
|||||||
var (mh, mv) = MapAttachmentPoint(mtext.AttachmentPoint);
|
var (mh, mv) = MapAttachmentPoint(mtext.AttachmentPoint);
|
||||||
texts.Add(new CadText
|
texts.Add(new CadText
|
||||||
{
|
{
|
||||||
|
SourceHandle = mtext.Handle,
|
||||||
Position = new Vector(mtext.InsertPoint.X, mtext.InsertPoint.Y),
|
Position = new Vector(mtext.InsertPoint.X, mtext.InsertPoint.Y),
|
||||||
Value = ReplaceControlCodes(StripMTextFormatting(mtext.Value)),
|
Value = ReplaceControlCodes(StripMTextFormatting(mtext.Value)),
|
||||||
Height = mtext.Height,
|
Height = mtext.Height,
|
||||||
@@ -958,6 +959,7 @@ namespace OpenNest.Forms
|
|||||||
};
|
};
|
||||||
texts.Add(new CadText
|
texts.Add(new CadText
|
||||||
{
|
{
|
||||||
|
SourceHandle = text.Handle,
|
||||||
Position = new Vector(pt.X, pt.Y),
|
Position = new Vector(pt.X, pt.Y),
|
||||||
Value = ReplaceControlCodes(text.Value),
|
Value = ReplaceControlCodes(text.Value),
|
||||||
Height = text.Height,
|
Height = text.Height,
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ Or open `OpenNest.sln` in Visual Studio and run the `OpenNest` project.
|
|||||||
|
|
||||||
### CAD Converter
|
### CAD Converter
|
||||||
|
|
||||||
The CAD Converter turns DXF/DWG files into nest-ready drawings. Toggle layers, colors, and linetypes to exclude construction geometry; review detected bend lines; and preview the generated cut program with contour ordering before accepting the drawing into the nest.
|
The CAD Converter turns DXF/DWG files into nest-ready drawings. Detected bend notes replace their original CAD annotations in the preview, avoiding duplicate labels without hiding unrelated text. Toggle layers, colors, and linetypes to exclude construction geometry; review detected bend lines; and preview the generated cut program with contour ordering before accepting the drawing into the nest.
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<a href="screenshots/screenshot-cad-converter-1.png"><img src="screenshots/screenshot-cad-converter-1.png" width="420" alt="CAD Converter — layer, color, and linetype filtering"></a>
|
<a href="screenshots/screenshot-cad-converter-1.png"><img src="screenshots/screenshot-cad-converter-1.png" width="420" alt="CAD Converter — layer, color, and linetype filtering"></a>
|
||||||
|
|||||||
Reference in New Issue
Block a user