//-------------------------------------------------------------------------------------------------- void _ImportSplineWithFitPoints(DxfDomSpline dxfSpline) { // Copy points var pointCount = dxfSpline.FitPoints.Length; var points = new TColgp_HArray1OfPnt2d(1, pointCount); for (int i = 0; i < pointCount; i++) { points.SetValue(i + 1, dxfSpline.FitPoints[i]); } // Interpolate var algo = new Geom2dAPI_Interpolate(points, false, 0.001); if (dxfSpline.HasTangents) { algo.Load(dxfSpline.StartTangent, dxfSpline.EndTangent); } algo.Perform(); if (!algo.IsDone()) { Messages.Warning("DxfImporter: Cannot create spline through fit points."); return; } _AddBSplineCurve(algo.Curve()); }
//-------------------------------------------------------------------------------------------------- void _AddBezierSegment(SketchSegmentBezier bezierSegment) { if (_Document.Flags.HasFlag(DxfFlags.ExportSplineAsPolygon)) { var curve = bezierSegment.MakeCurve(_Sketch.Points); if (curve == null) { Messages.Error($"Cannot make curve for converting bezier segment to polyline."); return; } _AddPolygonCurve(curve); } else { var pointCount = bezierSegment.Points.Length; var knots = new double[pointCount * 2]; knots.Fill(0, pointCount, 0.0); knots.Fill(pointCount, pointCount, 1.0); var points = bezierSegment.Points.Select(idx => _Sketch.Points[idx]).ToArray(); var entity = new DxfDomSpline("0", pointCount - 1, knots, points, null, DxfDomSpline.SplineFlags.None); _Document.Entities.Add(entity); } }
//-------------------------------------------------------------------------------------------------- void _AddBSplineCurve(Geom2d_BSplineCurve bspline, double first, double last) { // Cut spline bspline = Geom2dConvert.SplitBSplineCurve(bspline, first, last, 0.00001); if (_Document.Flags.HasFlag(DxfFlags.ExportSplineAsPolygon)) { _AddPolygonCurve(bspline); return; } if (bspline.Degree() > 3) { // Try to reduce the order of the curve var continuity = bspline.Continuity(); if (continuity != GeomAbs_Shape.GeomAbs_C0) { continuity = GeomAbs_Shape.GeomAbs_C1; } var converter = new Geom2dConvert_ApproxCurve(bspline, _Precision * 10.0, continuity, 100, 3); if (!(converter.IsDone() && converter.HasResult())) { Messages.Warning("DxfExporter: BSpline curve has an undecreasable degree of " + bspline.Degree() + "."); return; } bspline = converter.Curve(); } var knotSource = bspline.KnotSequence(); var knots = new double[knotSource.Length()]; int sourceStart = knotSource.Lower(); for (int i = 0; i < knots.Length; i++) { knots[i] = knotSource.Value(sourceStart + i); } var points = new Pnt2d[bspline.NbPoles()]; var weights = new double[points.Length]; for (int i = 0; i < bspline.NbPoles(); i++) { points[i] = bspline.Pole(i + 1); weights[i] = bspline.Weight(i + 1); } var flags = DxfDomSpline.SplineFlags.None; if (bspline.IsRational()) { flags = flags.Added(DxfDomSpline.SplineFlags.IsRational); } var entity = new DxfDomSpline(_CurrentLayer, bspline.Degree(), knots, points, weights, flags); _Document.Entities.Add(entity); }
//-------------------------------------------------------------------------------------------------- void _ImportSpline(DxfDomSpline dxfSpline) { if (dxfSpline.ControlPoints.Length > 0 && dxfSpline.Knots.Length > 0) { _ImportSplineWithControlPoints(dxfSpline); } else if (dxfSpline.FitPoints.Length > 0) { _ImportSplineWithFitPoints(dxfSpline); } }
//-------------------------------------------------------------------------------------------------- void _ImportSplineWithControlPoints(DxfDomSpline dxfSpline) { // Copy control points var poleCount = dxfSpline.ControlPoints.Length; var poles = new TColgp_Array1OfPnt2d(1, poleCount); var weights = dxfSpline.Weights != null ? new TColStd_Array1OfReal(1, poleCount) : null; for (int i = 0; i < poleCount; i++) { poles.SetValue(i + 1, dxfSpline.ControlPoints[i]); weights?.SetValue(i + 1, dxfSpline.Weights[i]); } // Count multiplicities and compact knot list var knotList = new List <double>(); var multList = new List <int>(); var lastKnot = double.NaN; foreach (var knot in dxfSpline.Knots) { if (lastKnot != knot) { knotList.Add(knot); lastKnot = knot; multList.Add(1); } else { multList[multList.Count - 1]++; } } // Copy knots and multiplicities var knotCount = knotList.Count; var knots = new TColStd_Array1OfReal(1, knotCount); var mults = new TColStd_Array1OfInteger(1, knotCount); for (int i = 0; i < knotCount; i++) { knots.SetValue(i + 1, knotList[i]); mults.SetValue(i + 1, multList[i]); } // Create spline var spline = weights != null ? new Geom2d_BSplineCurve(poles, weights, knots, mults, dxfSpline.Degree, dxfSpline.Flags.Has(DxfDomSpline.SplineFlags.IsClosed)) : new Geom2d_BSplineCurve(poles, knots, mults, dxfSpline.Degree, dxfSpline.Flags.Has(DxfDomSpline.SplineFlags.IsClosed)); _AddBSplineCurve(spline); }
//-------------------------------------------------------------------------------------------------- void _ReadEntities(DxfReader reader) { while (reader.GroupCode >= 0) { if (reader.GroupCode != 0) { reader.Skip(); continue; } var type = reader.ReadString()?.ToUpper(); if (type == null) { continue; } DxfDomEntity entity = null; switch (type) { case "ENDSEC": return; case "LINE": entity = new DxfDomLine(); break; case "CIRCLE": case "ARC": entity = new DxfDomCircle(); break; case "ELLIPSE": entity = new DxfDomEllipse(); break; case "LWPOLYLINE": entity = new DxfDomLwPolyline(); break; case "POLYLINE": entity = new DxfDomPolyline(); break; case "SPLINE": entity = new DxfDomSpline(); break; } if (entity == null) { continue; } if (entity.Read(reader)) { Entities.Add(entity); } else { Messages.Error($"DxfReader: Incomplete entity description at line {reader.Line}."); } } }