Files
OpenNest/OpenNest.IO/Extensions.cs
AJ Isaacs e92208b8c0 fix: remove import spline precision setting entirely
Spline import now uses SplineConverter (arc-based) so the configurable
precision parameter is obsolete. Removed the setting from the options
dialog, DxfImporter property, Settings files, and all callsites.
Hardcoded 200 as the sampling density for the intermediate point
evaluation that feeds into SplineConverter.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 08:05:33 -04:00

260 lines
8.3 KiB
C#

using ACadSharp.Entities;
using CSMath;
using OpenNest.Geometry;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
namespace OpenNest.IO
{
internal static class Extensions
{
public static Vector ToOpenNest(this XY v)
{
return new Vector(v.X, v.Y);
}
public static Vector ToOpenNest(this XYZ v)
{
return new Vector(v.X, v.Y);
}
public static Geometry.Arc ToOpenNest(this ACadSharp.Entities.Arc arc)
{
var result = new Geometry.Arc(
arc.Center.X, arc.Center.Y, arc.Radius,
arc.StartAngle,
arc.EndAngle)
{
Layer = arc.Layer.ToOpenNest()
};
result.ApplyDxfProperties(arc);
return result;
}
public static Geometry.Circle ToOpenNest(this ACadSharp.Entities.Circle circle)
{
var result = new Geometry.Circle(
circle.Center.X, circle.Center.Y,
circle.Radius)
{
Layer = circle.Layer.ToOpenNest()
};
result.ApplyDxfProperties(circle);
return result;
}
public static Geometry.Line ToOpenNest(this ACadSharp.Entities.Line line)
{
var result = new Geometry.Line(
line.StartPoint.X, line.StartPoint.Y,
line.EndPoint.X, line.EndPoint.Y)
{
Layer = line.Layer.ToOpenNest()
};
result.ApplyDxfProperties(line);
return result;
}
public static List<Geometry.Entity> ToOpenNest(this Spline spline)
{
var layer = spline.Layer.ToOpenNest();
var color = spline.ResolveColor();
var lineTypeName = spline.ResolveLineTypeName();
// Evaluate actual points on the spline curve (not control points)
List<XYZ> curvePoints;
try
{
curvePoints = spline.PolygonalVertexes(200);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"Spline curve evaluation failed: {ex.Message}");
curvePoints = null;
}
if (curvePoints == null || curvePoints.Count < 2)
{
// Fallback: use control points if evaluation fails
curvePoints = new List<XYZ>(spline.ControlPoints);
if (curvePoints.Count < 2)
return new List<Geometry.Entity>();
}
var points = new List<Vector>(curvePoints.Count);
foreach (var pt in curvePoints)
points.Add(pt.ToOpenNest());
var entities = SplineConverter.Convert(points, spline.IsClosed, tolerance: 0.001);
foreach (var entity in entities)
{
entity.Layer = layer;
entity.Color = color;
entity.LineTypeName = lineTypeName;
}
return entities;
}
public static List<Geometry.Line> ToOpenNest(this Polyline polyline)
{
var lines = new List<Geometry.Line>();
if (polyline.Vertices.Count == 0)
return lines;
var layer = polyline.Layer.ToOpenNest();
var color = polyline.ResolveColor();
var lineTypeName = polyline.ResolveLineTypeName();
var lastPoint = polyline.Vertices[0].Location.ToOpenNest();
for (var i = 1; i < polyline.Vertices.Count; i++)
{
var nextPoint = polyline.Vertices[i].Location.ToOpenNest();
lines.Add(new Geometry.Line(lastPoint, nextPoint)
{
Layer = layer,
Color = color,
LineTypeName = lineTypeName
});
lastPoint = nextPoint;
}
var isClosed = (polyline.Flags & PolylineFlags.ClosedPolylineOrClosedPolygonMeshInM) != 0;
if (isClosed)
lines.Add(new Geometry.Line(lastPoint, polyline.Vertices[0].Location.ToOpenNest())
{
Layer = layer,
Color = color,
LineTypeName = lineTypeName
});
return lines;
}
public static List<Geometry.Line> ToOpenNest(this LwPolyline polyline)
{
var lines = new List<Geometry.Line>();
if (polyline.Vertices.Count == 0)
return lines;
var layer = polyline.Layer.ToOpenNest();
var color = polyline.ResolveColor();
var lineTypeName = polyline.ResolveLineTypeName();
var lastPoint = polyline.Vertices[0].ToOpenNest();
for (var i = 1; i < polyline.Vertices.Count; i++)
{
var nextPoint = polyline.Vertices[i].ToOpenNest();
lines.Add(new Geometry.Line(lastPoint, nextPoint)
{
Layer = layer,
Color = color,
LineTypeName = lineTypeName
});
lastPoint = nextPoint;
}
var isClosed = (polyline.Flags & LwPolylineFlags.Closed) != 0;
if (isClosed)
lines.Add(new Geometry.Line(lastPoint, polyline.Vertices[0].ToOpenNest())
{
Layer = layer,
Color = color,
LineTypeName = lineTypeName
});
return lines;
}
public static List<Geometry.Entity> ToOpenNest(this ACadSharp.Entities.Ellipse ellipse, double tolerance = 0.001)
{
var center = new Vector(ellipse.Center.X, ellipse.Center.Y);
var majorAxis = new Vector(ellipse.MajorAxisEndPoint.X, ellipse.MajorAxisEndPoint.Y);
var semiMajor = System.Math.Sqrt(majorAxis.X * majorAxis.X + majorAxis.Y * majorAxis.Y);
var semiMinor = semiMajor * ellipse.RadiusRatio;
var rotation = System.Math.Atan2(majorAxis.Y, majorAxis.X);
var startParam = ellipse.StartParameter;
var endParam = ellipse.EndParameter;
var layer = ellipse.Layer.ToOpenNest();
var color = ellipse.ResolveColor();
var lineTypeName = ellipse.ResolveLineTypeName();
var entities = EllipseConverter.Convert(center, semiMajor, semiMinor, rotation,
startParam, endParam, tolerance);
foreach (var entity in entities)
{
entity.Layer = layer;
entity.Color = color;
entity.LineTypeName = lineTypeName;
}
return entities;
}
public static Geometry.Layer ToOpenNest(this ACadSharp.Tables.Layer layer)
{
return new Geometry.Layer(layer.Name)
{
Color = Color.FromArgb(layer.Color.R, layer.Color.G, layer.Color.B),
IsVisible = layer.IsOn,
LineTypeName = layer.LineType?.Name
};
}
public static Color ResolveColor(this ACadSharp.Entities.Entity entity)
{
var color = entity.Color;
if (color.IsByLayer)
color = entity.Layer.Color;
return Color.FromArgb(color.R, color.G, color.B);
}
public static string ResolveLineTypeName(this ACadSharp.Entities.Entity entity)
{
var lt = entity.LineType;
if (lt == null || string.Equals(lt.Name, "ByLayer", System.StringComparison.OrdinalIgnoreCase))
return entity.Layer.LineType?.Name ?? "Continuous";
return lt.Name;
}
public static void ApplyDxfProperties(this Geometry.Entity target, ACadSharp.Entities.Entity source)
{
target.Color = source.ResolveColor();
target.LineTypeName = source.ResolveLineTypeName();
}
public static Vector ToOpenNest(this LwPolyline.Vertex v)
{
return new Vector(v.Location.X, v.Location.Y);
}
public static XY ToAcad(this Vector v)
{
return new XY(v.X, v.Y);
}
public static XYZ ToAcadXYZ(this Vector v)
{
return new XYZ(v.X, v.Y, 0);
}
}
}