diff --git a/OpenNest.IO/CadImporter.cs b/OpenNest.IO/CadImporter.cs index aa2ed4a..921ab1b 100644 --- a/OpenNest.IO/CadImporter.cs +++ b/OpenNest.IO/CadImporter.cs @@ -5,6 +5,7 @@ using OpenNest.Bending; using OpenNest.Converters; using OpenNest.Geometry; using OpenNest.IO.Bending; +using OpenNest.Math; namespace OpenNest.IO { @@ -25,6 +26,8 @@ namespace OpenNest.IO var dxf = Dxf.Import(path); + RemoveDuplicateArcs(dxf.Entities); + var bends = new List(); if (options.DetectBends && dxf.Document != null) { @@ -136,5 +139,33 @@ namespace OpenNest.IO return drawing; } + + internal static void RemoveDuplicateArcs(List entities) + { + var circles = entities.OfType().ToList(); + var arcs = entities.OfType().ToList(); + var arcsToRemove = new List(); + + foreach (var arc in arcs) + { + foreach (var circle in circles) + { + if (arc.Layer?.Name != circle.Layer?.Name) + continue; + + if (!arc.Center.DistanceTo(circle.Center).IsEqualTo(0)) + continue; + + if (!arc.Radius.IsEqualTo(circle.Radius)) + continue; + + arcsToRemove.Add(arc); + break; + } + } + + foreach (var arc in arcsToRemove) + entities.Remove(arc); + } } } diff --git a/OpenNest.Tests/IO/RemoveDuplicateArcsTests.cs b/OpenNest.Tests/IO/RemoveDuplicateArcsTests.cs new file mode 100644 index 0000000..3c5436e --- /dev/null +++ b/OpenNest.Tests/IO/RemoveDuplicateArcsTests.cs @@ -0,0 +1,96 @@ +using System.Collections.Generic; +using System.Linq; +using OpenNest.Geometry; +using OpenNest.IO; +using OpenNest.Math; +using Xunit; + +namespace OpenNest.Tests.IO; + +public class RemoveDuplicateArcsTests +{ + [Fact] + public void RemoveDuplicateArcs_RemovesArcMatchingCircle_SameLayer() + { + var layer = new Layer("0"); + var circle = new Circle(10, 10, 5) { Layer = layer }; + var arc = new Arc(10, 10, 5, 0, Angle.ToRadians(90)) { Layer = layer }; + var line = new Line(0, 0, 10, 0) { Layer = layer }; + var entities = new List { circle, arc, line }; + + CadImporter.RemoveDuplicateArcs(entities); + + Assert.Equal(2, entities.Count); + Assert.Contains(circle, entities); + Assert.Contains(line, entities); + Assert.DoesNotContain(arc, entities); + } + + [Fact] + public void RemoveDuplicateArcs_KeepsArcOnDifferentLayer() + { + var layer1 = new Layer("cut"); + var layer2 = new Layer("etch"); + var circle = new Circle(10, 10, 5) { Layer = layer1 }; + var arc = new Arc(10, 10, 5, 0, Angle.ToRadians(90)) { Layer = layer2 }; + var entities = new List { circle, arc }; + + CadImporter.RemoveDuplicateArcs(entities); + + Assert.Equal(2, entities.Count); + Assert.Contains(arc, entities); + } + + [Fact] + public void RemoveDuplicateArcs_KeepsArcWithDifferentRadius() + { + var layer = new Layer("0"); + var circle = new Circle(10, 10, 5) { Layer = layer }; + var arc = new Arc(10, 10, 3, 0, Angle.ToRadians(90)) { Layer = layer }; + var entities = new List { circle, arc }; + + CadImporter.RemoveDuplicateArcs(entities); + + Assert.Equal(2, entities.Count); + } + + [Fact] + public void RemoveDuplicateArcs_KeepsArcWithDifferentCenter() + { + var layer = new Layer("0"); + var circle = new Circle(10, 10, 5) { Layer = layer }; + var arc = new Arc(20, 20, 5, 0, Angle.ToRadians(90)) { Layer = layer }; + var entities = new List { circle, arc }; + + CadImporter.RemoveDuplicateArcs(entities); + + Assert.Equal(2, entities.Count); + } + + [Fact] + public void RemoveDuplicateArcs_NoCircles_NoChange() + { + var arc = new Arc(10, 10, 5, 0, Angle.ToRadians(90)); + var line = new Line(0, 0, 10, 0); + var entities = new List { arc, line }; + + CadImporter.RemoveDuplicateArcs(entities); + + Assert.Equal(2, entities.Count); + } + + [Fact] + public void RemoveDuplicateArcs_MultipleArcsMatchOneCircle_RemovesAll() + { + var layer = new Layer("0"); + var circle = new Circle(10, 10, 5) { Layer = layer }; + var arc1 = new Arc(10, 10, 5, 0, Angle.ToRadians(90)) { Layer = layer }; + var arc2 = new Arc(10, 10, 5, Angle.ToRadians(90), Angle.ToRadians(180)) { Layer = layer }; + var entities = new List { circle, arc1, arc2 }; + + CadImporter.RemoveDuplicateArcs(entities); + + Assert.Single(entities); + Assert.Contains(circle, entities); + } +}