예제 #1
0
        //--------------------------------------------------------------------------------------------------

        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);
            }
        }
예제 #3
0
        //--------------------------------------------------------------------------------------------------

        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);
        }
예제 #4
0
        //--------------------------------------------------------------------------------------------------

        void _ImportSpline(DxfDomSpline dxfSpline)
        {
            if (dxfSpline.ControlPoints.Length > 0 && dxfSpline.Knots.Length > 0)
            {
                _ImportSplineWithControlPoints(dxfSpline);
            }
            else if (dxfSpline.FitPoints.Length > 0)
            {
                _ImportSplineWithFitPoints(dxfSpline);
            }
        }
예제 #5
0
        //--------------------------------------------------------------------------------------------------

        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);
        }
예제 #6
0
        //--------------------------------------------------------------------------------------------------

        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}.");
                }
            }
        }