diff --git a/OpenNest.Core/Geometry/Arc.cs b/OpenNest.Core/Geometry/Arc.cs index 8a677ec..e556ffe 100644 --- a/OpenNest.Core/Geometry/Arc.cs +++ b/OpenNest.Core/Geometry/Arc.cs @@ -93,6 +93,9 @@ namespace OpenNest.Geometry } } + public bool IsFullCircle() => + SweepAngle() >= Angle.TwoPI - Tolerance.Epsilon; + /// /// Angle in radians between start and end angles. /// diff --git a/OpenNest.Core/Geometry/GeometryOptimizer.cs b/OpenNest.Core/Geometry/GeometryOptimizer.cs index 0243e51..97595f9 100644 --- a/OpenNest.Core/Geometry/GeometryOptimizer.cs +++ b/OpenNest.Core/Geometry/GeometryOptimizer.cs @@ -17,6 +17,38 @@ namespace OpenNest.Geometry (list, item, i) => list.GetCollinearLines(item, i), (Line a, Line b, out Line joined) => TryJoinLines(a, b, out joined)); + public static void Deduplicate(IList circles) + { + for (var i = circles.Count - 1; i >= 1; i--) + { + for (var j = i - 1; j >= 0; j--) + { + if (circles[i].Center.DistanceTo(circles[j].Center) <= Tolerance.Epsilon + && circles[i].Radius.IsEqualTo(circles[j].Radius)) + { + circles.RemoveAt(i); + break; + } + } + } + } + + public static void Deduplicate(IList circles, IList arcs) + { + for (var i = circles.Count - 1; i >= 0; i--) + { + for (var j = arcs.Count - 1; j >= 0; j--) + { + if (arcs[j].Center.DistanceTo(circles[i].Center) <= Tolerance.Epsilon + && arcs[j].Radius.IsEqualTo(circles[i].Radius) + && arcs[j].IsFullCircle()) + { + arcs.RemoveAt(j); + } + } + } + } + private delegate bool TryJoin(T a, T b, out T joined); private static void MergePass(IList items, diff --git a/OpenNest.IO/Dxf.cs b/OpenNest.IO/Dxf.cs index 5c2548c..9187206 100644 --- a/OpenNest.IO/Dxf.cs +++ b/OpenNest.IO/Dxf.cs @@ -133,6 +133,7 @@ namespace OpenNest.IO var entities = new List(); var lines = new List(); var arcs = new List(); + var circles = new List(); foreach (var entity in doc.Entities) { @@ -150,7 +151,7 @@ namespace OpenNest.IO break; case ACadSharp.Entities.Circle circle: - entities.Add(circle.ToOpenNest()); + circles.Add(circle.ToOpenNest()); break; case ACadSharp.Entities.Spline spline: @@ -181,7 +182,10 @@ namespace OpenNest.IO GeometryOptimizer.Optimize(lines); GeometryOptimizer.Optimize(arcs); + GeometryOptimizer.Deduplicate(circles); + GeometryOptimizer.Deduplicate(circles, arcs); + entities.AddRange(circles); entities.AddRange(lines); entities.AddRange(arcs);