//-------------------------------------------------------------------------------------------------- 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); }
//-------------------------------------------------------------------------------------------------- protected void AddBezierCurve(Geom2d_BezierCurve geom2DBezier, double first, double last, bool reverse) { if (geom2DBezier.Degree() > 3) { // Try to reduce the order of the curve var continuity = geom2DBezier.Continuity(); if (continuity != GeomAbs_Shape.GeomAbs_C0) { continuity = GeomAbs_Shape.GeomAbs_C1; } var converter = new Geom2dConvert_ApproxCurve(geom2DBezier, 0.001 /*Precision.Confusion() * 10*/, continuity, 1000, 3); if (!(converter.IsDone() && converter.HasResult())) { Messages.Warning("SvgExporter: Bezier curve has an undecreasable order of " + geom2DBezier.Degree() + "."); return; } AddBSplineCurve(converter.Curve(), first, last, reverse); return; } // Create segment, SVG path does not support UV geom2DBezier.Segment(first, last); Pnt2d c1, c2; var start = reverse ? geom2DBezier.EndPoint() : geom2DBezier.StartPoint(); var end = reverse ? geom2DBezier.StartPoint() : geom2DBezier.EndPoint(); BoundingBox?.Add(start); BoundingBox?.Add(end); switch (geom2DBezier.Degree()) { case 1: AddToPath(new SvgPathSegLineto(start, end)); break; case 2: c1 = geom2DBezier.Pole(2); BoundingBox?.Add(c1); AddToPath(new SvgPathSegCurvetoQuadratic(start, c1, end)); break; case 3: c1 = geom2DBezier.Pole(reverse ? 3 : 2); c2 = geom2DBezier.Pole(reverse ? 2 : 3); BoundingBox?.Add(c1); BoundingBox?.Add(c2); AddToPath(new SvgPathSegCurvetoCubic(start, c1, c2, end)); break; default: Messages.Warning("SvgExporter: Bezier curve has an unsupported order of " + geom2DBezier.Degree() + "."); break; } }
//-------------------------------------------------------------------------------------------------- void _AddBezierCurve(Geom2d_BezierCurve geom2DBezier, double firstParameter, double lastParameter) { int p1, p2, p3, p4; switch (geom2DBezier.Degree()) { case 1: p1 = _AddPoint(geom2DBezier.StartPoint()); p2 = _AddPoint(geom2DBezier.EndPoint()); _Segments.Add(new SketchSegmentLine(p1, p2)); break; case 2: p1 = _AddPoint(geom2DBezier.StartPoint()); p2 = _AddPoint(geom2DBezier.Pole(2), false); p3 = _AddPoint(geom2DBezier.EndPoint()); _Segments.Add(new SketchSegmentBezier(p1, p2, p3)); break; case 3: p1 = _AddPoint(geom2DBezier.StartPoint()); p2 = _AddPoint(geom2DBezier.Pole(2), false); p3 = _AddPoint(geom2DBezier.Pole(3), false); p4 = _AddPoint(geom2DBezier.EndPoint()); _Segments.Add(new SketchSegmentBezier(p1, p2, p3, p4)); break; default: // Try to reduce the order of the curve var continuity = geom2DBezier.Continuity(); if (continuity != GeomAbs_Shape.GeomAbs_C0) { continuity = GeomAbs_Shape.GeomAbs_C1; } var trimmedCurve = new Geom2d_TrimmedCurve(geom2DBezier, firstParameter, lastParameter); var converter = new Geom2dConvert_ApproxCurve(trimmedCurve, 0.001 /*Precision.Confusion() * 10*/, continuity, 1000, 3); if (!(converter.IsDone() && converter.HasResult())) { Messages.Warning("DxfImporter: Bezier curve has an undecreasable order of " + geom2DBezier.Degree() + "."); return; } _AddBSplineCurve(converter.Curve()); break; } }
//-------------------------------------------------------------------------------------------------- void _AddPolygonCurve(Geom2d_Curve curve) { var converter = new Geom2dConvert_ApproxCurve(curve, _Precision, GeomAbs_Shape.GeomAbs_C0, 500, 1); if (!(converter.IsDone() && converter.HasResult())) { Messages.Error($"Cannot tesselate curve to polyline."); return; } var approx = converter.Curve(); var points = new Pnt2d[approx.NbPoles()]; for (int i = 0; i < points.Length; i++) { points[i] = approx.Pole(i + 1); } var entity = new DxfDomLwPolyline("0", points); _Document.Entities.Add(entity); }
//-------------------------------------------------------------------------------------------------- public static bool RenderBezierCurve(IDrawingRenderer renderer, Geom2d_BezierCurve bezier, double first, double last, bool reverse) { if (renderer.Capabilities.BezierCurveMaxDegree > 0) { var maxDegree = Math.Min(3, renderer.Capabilities.BezierCurveMaxDegree); if (bezier.Degree() > maxDegree) { // Try to reduce the order of the curve var continuity = bezier.Continuity(); if (continuity != GeomAbs_Shape.GeomAbs_C0) { continuity = GeomAbs_Shape.GeomAbs_C1; } var converter = new Geom2dConvert_ApproxCurve(bezier, 0.0001, continuity, 1000, maxDegree); if (!(converter.IsDone() && converter.HasResult())) { Messages.Warning("BrepRenderHelper: Bezier curve has an undecreasable order of " + bezier.Degree() + "."); return(false); } return(RenderBSplineCurve(renderer, converter.Curve(), first, last, reverse)); } bezier.Segment(first, last); Pnt2d c1, c2; var start = reverse ? bezier.EndPoint() : bezier.StartPoint(); var end = reverse ? bezier.StartPoint() : bezier.EndPoint(); switch (bezier.Degree()) { case 1: renderer.Line(start, end); return(true); case 2: c1 = bezier.Pole(2); renderer.BezierCurve(new[] { start, c1, end }); return(true); case 3: c1 = bezier.Pole(reverse ? 3 : 2); c2 = bezier.Pole(reverse ? 2 : 3); renderer.BezierCurve(new[] { start, c1, c2, end }); return(true); default: Messages.Warning("BrepRenderHelper: Bezier curve has an unsupported order of " + bezier.Degree() + "."); break; } return(false); } else { // Try to create B-Spline curve var bsplineCurve = ShapeConstruct.ConvertCurveToBSpline(bezier, first, last, 0.0001, bezier.Continuity(), 10000, 3); if (bsplineCurve != null) { return(RenderBSplineCurve(renderer, bsplineCurve, first, last, reverse)); } Messages.Warning("BrepRenderHelper: Bezier curve is not supported by exporter and conversion to BSpline failed."); return(false); } }
//-------------------------------------------------------------------------------------------------- public static bool RenderBSplineCurve(IDrawingRenderer renderer, Geom2d_BSplineCurve bspline, double first, double last, bool reverse) { if (renderer.Capabilities.BSplineCurveMaxDegree > 0) { bspline = Geom2dConvert.SplitBSplineCurve(bspline, first, last, 0.00001); if (bspline.Degree() > renderer.Capabilities.BSplineCurveMaxDegree) { // 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, 0.0001, continuity, 100, 3); if (!(converter.IsDone() && converter.HasResult())) { Messages.Warning("BrepRenderHelper: BSpline curve has an undecreasable degree of " + bspline.Degree() + "."); return(false); } 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); } renderer.BSplineCurve(bspline.Degree(), knots, points, weights, bspline.IsRational()); return(true); } else { // Cannot render BSpline, Try bezier var converter = new Geom2dConvert_BSplineCurveToBezierCurve(bspline, first, last, 0.001 /*Precision.PConfusion() * 10*/); bool result = true; if (reverse) { for (int i = converter.NbArcs(); i >= 1; i -= 1) { var arc = converter.Arc(i); result &= RenderBezierCurve(renderer, arc, arc.FirstParameter(), arc.LastParameter(), true); } } else { for (int i = 1; i <= converter.NbArcs(); i += 1) { var arc = converter.Arc(i); result &= RenderBezierCurve(renderer, arc, arc.FirstParameter(), arc.LastParameter(), false); } } return(result); } }