public static IEnumerable <DB.Curve> ToCurveMany(this NurbsCurve value, double factor) { if (value.Degree == 1) { var curvePoints = value.Points; int pointCount = curvePoints.Count; if (pointCount > 1) { DB.XYZ end, start = curvePoints[0].Location.ToXYZ(factor); for (int p = 1; p < pointCount; start = end, ++p) { end = curvePoints[p].Location.ToXYZ(factor); yield return(DB.Line.CreateBound(start, end)); } } } else if (value.Degree == 2) { for (int s = 0; s < value.SpanCount; ++s) { var segment = value.Trim(value.SpanDomain(s)) as NurbsCurve; yield return(NurbsSplineEncoder.ToNurbsSpline(segment, factor)); } } else if (value.IsClosed(Revit.ShortCurveTolerance * 1.01)) { var segments = value.DuplicateSegments(); if (segments.Length == 1) { if ( value.NormalizedLengthParameter(0.5, out var mid) && value.Split(mid) is Curve[] half ) { yield return(NurbsSplineEncoder.ToNurbsSpline(half[0] as NurbsCurve, factor)); yield return(NurbsSplineEncoder.ToNurbsSpline(half[1] as NurbsCurve, factor)); } else { throw new ConversionException("Failed to Split closed Edge"); } } else { foreach (var segment in segments) { yield return(NurbsSplineEncoder.ToNurbsSpline(segment as NurbsCurve, factor)); } } } else { yield return(NurbsSplineEncoder.ToNurbsSpline(value, factor)); } }
public static DB.Curve ToCurve(this NurbsCurve value, double factor) { if (value.TryGetEllipse(out var ellipse, out var interval, Revit.VertexTolerance * factor)) { return(ellipse.ToCurve(interval, factor)); } var gap = Revit.ShortCurveTolerance * 1.01; if (value.IsClosed(gap * factor)) { var length = value.GetLength(); if ( length > gap && value.LengthParameter((gap / 2.0), out var t0) && value.LengthParameter(length - (gap / 2.0), out var t1) ) { var segments = value.Split(new double[] { t0, t1 }); value = segments[0] as NurbsCurve ?? value; } else { throw new ConversionException($"Failed to Split closed NurbsCurve, Length = {length}"); } } if (value.Degree < 3 && value.SpanCount > 1) { value = value.DuplicateCurve() as NurbsCurve; value.IncreaseDegree(3); } return(NurbsSplineEncoder.ToNurbsSpline(value, factor)); }