Пример #1
0
        static internal IEnumerable <Autodesk.Revit.DB.Curve> ToHost(this Rhino.Geometry.Curve curve, double curveTolerance = double.PositiveInfinity)
        {
            curveTolerance = Math.Min(Revit.ShortCurveTolerance, Math.Abs(curveTolerance));
            Debug.Assert(!curve.IsShort(curveTolerance));

            var simplifiedCurve = curve.Simplify(CurveSimplifyOptions.SplitAtFullyMultipleKnots, curveTolerance, Revit.AngleTolerance);

            if (simplifiedCurve != null)
            {
                curve = simplifiedCurve;
            }

            switch (curve)
            {
            case Rhino.Geometry.LineCurve line:

                yield return(Autodesk.Revit.DB.Line.CreateBound(line.PointAtStart.ToHost(), line.PointAtEnd.ToHost()));

                break;

            case Rhino.Geometry.PolylineCurve polyline:

                for (int p = 1; p < polyline.PointCount; ++p)
                {
                    yield return(Autodesk.Revit.DB.Line.CreateBound(polyline.Point(p - 1).ToHost(), polyline.Point(p).ToHost()));
                }
                break;

            case Rhino.Geometry.ArcCurve arc:

                if (arc.IsClosed)
                {
                    yield return(Autodesk.Revit.DB.Arc.Create(arc.Arc.Plane.ToHost(), arc.Arc.Radius, 0.0, (2.0 * Math.PI) - 2e-8));
                }
                else
                {
                    yield return(Autodesk.Revit.DB.Arc.Create(arc.Arc.StartPoint.ToHost(), arc.Arc.EndPoint.ToHost(), arc.Arc.MidPoint.ToHost()));
                }
                break;

            case Rhino.Geometry.PolyCurve polyCurve:

                polyCurve.RemoveNesting();
                polyCurve.RemoveShortSegments(curveTolerance);
                for (int s = 0; s < polyCurve.SegmentCount; ++s)
                {
                    foreach (var segment in polyCurve.SegmentCurve(s).ToHost())
                    {
                        yield return(segment);
                    }
                }
                break;

            case Rhino.Geometry.NurbsCurve nurbsCurve:

                if (nurbsCurve.IsLinear(Revit.VertexTolerance))
                {
                    yield return(Autodesk.Revit.DB.Line.CreateBound(nurbsCurve.PointAtStart.ToHost(), nurbsCurve.PointAtEnd.ToHost()));

                    yield break;
                }

                if (nurbsCurve.TryGetPolyline(out var polylineSegment))
                {
                    polylineSegment.ReduceSegments(curveTolerance);
                    foreach (var segment in polylineSegment.GetSegments())
                    {
                        yield return(Autodesk.Revit.DB.Line.CreateBound(segment.From.ToHost(), segment.To.ToHost()));
                    }

                    yield break;
                }

                if (nurbsCurve.TryGetArc(out var arcSegment, Revit.VertexTolerance))
                {
                    yield return(Autodesk.Revit.DB.Arc.Create(arcSegment.StartPoint.ToHost(), arcSegment.EndPoint.ToHost(), arcSegment.MidPoint.ToHost()));

                    yield break;
                }

                if (nurbsCurve.IsClosed)
                {
                    if (nurbsCurve.TryGetCircle(out var circle, Revit.VertexTolerance))
                    {
                        yield return(Autodesk.Revit.DB.Arc.Create(circle.Plane.ToHost(), circle.Radius, 0.0, 2.0 * (2.0 * Math.PI) - 2e-8));

                        yield break;
                    }

                    if (nurbsCurve.TryGetEllipse(out var ellipse, Revit.VertexTolerance))
                    {
                        yield return(Autodesk.Revit.DB.Ellipse.CreateCurve(ellipse.Plane.Origin.ToHost(), ellipse.Radius1, ellipse.Radius2, ellipse.Plane.XAxis.ToHost(), ellipse.Plane.YAxis.ToHost(), 0.0, (2.0 * Math.PI) - 2e-8));

                        yield break;
                    }

                    foreach (var segment in nurbsCurve.Split(nurbsCurve.Domain.Mid))
                    {
                        foreach (var c in segment.ToHost())
                        {
                            yield return(c);
                        }
                    }
                }
                else
                {
                    nurbsCurve.Knots.RemoveMultipleKnots(1, nurbsCurve.Degree, Revit.VertexTolerance);

                    var degree        = nurbsCurve.Degree;
                    var knots         = nurbsCurve.Knots.ToHost();
                    var controlPoints = nurbsCurve.Points.ToHost();

                    Debug.Assert(degree >= 1);
                    Debug.Assert(controlPoints.Count > nurbsCurve.Degree);
                    Debug.Assert(knots.Count == nurbsCurve.Degree + controlPoints.Count + 1);

                    Autodesk.Revit.DB.Curve nurbSpline = null;
                    try
                    {
                        if (nurbsCurve.IsRational)
                        {
                            var weights = new List <double>(controlPoints.Count);
                            foreach (var p in nurbsCurve.Points)
                            {
                                Debug.Assert(p.Weight > 0.0);
                                weights.Add(p.Weight);
                            }

                            Debug.Assert(weights.Count == controlPoints.Count);

                            nurbSpline = NurbSpline.CreateCurve(nurbsCurve.Degree, knots, controlPoints, weights);
                        }
                        else
                        {
                            nurbSpline = NurbSpline.CreateCurve(nurbsCurve.Degree, knots, controlPoints);
                        }
                    }
                    catch (Autodesk.Revit.Exceptions.ApplicationException e)
                    {
                        Debug.Fail(e.Source, e.Message);
                    }

                    yield return(nurbSpline);
                }
                break;

            default:
                foreach (var c in curve.ToNurbsCurve().ToHost())
                {
                    yield return(c);
                }
                break;
            }
        }