/// <summary> /// Converts a <see cref="DB.CurveLoop"/> into a Rhino <see cref="Curve"/> /// </summary> public static Curve ToCurve(this DB.CurveLoop value) { if (value.NumberOfCurves() == 1) { return(value.First().ToCurve()); } var polycurve = new PolyCurve(); foreach (var curve in value) { polycurve.AppendSegment(curve.ToCurve()); } return(polycurve); }
public static PolyCurve ToNative(this SpecklePolycurve p) { PolyCurve myPolyc = new PolyCurve(); foreach (var segment in p.Segments) { try { myPolyc.AppendSegment(( Curve )Converter.Deserialise(segment)); } catch { } } myPolyc.UserDictionary.ReplaceContentsWith(p.Properties.ToNative()); if (p.Domain != null) { myPolyc.Domain = p.Domain.ToNative(); } return(myPolyc); }
/// <summary> /// Converts a <see cref="DB.CurveArrArray"/> into a <see cref="PolyCurve"/>[] /// </summary> /// <seealso cref="ToCurves(DB.CurveArrArray)"/> public static PolyCurve[] ToPolyCurves(this DB.CurveArrArray value) { var count = value.Size; var list = new PolyCurve[count]; int index = 0; foreach (var curveArray in value.Cast <DB.CurveArray>()) { var polycurve = new PolyCurve(); foreach (var curve in curveArray.Cast <DB.Curve>()) { polycurve.AppendSegment(curve.ToCurve()); } list[index++] = polycurve; } return(list); }
public PolyCurve PolycurveToNative(Polycurve p) { PolyCurve myPolyc = new PolyCurve(); foreach (var segment in p.segments) { try { //let the converter pick the best type of curve myPolyc.AppendSegment((RH.Curve)ConvertToNative((Base)segment)); } catch { } } if (p.domain != null) { myPolyc.Domain = IntervalToNative(p.domain); } return(myPolyc); }
static int AddSurface(Brep brep, Surface surface, Curve[] loops, out List <BrepBoundary>[] shells) { // Extract base surface if (surface is object) { double trimTolerance = Revit.VertexTolerance * 0.1; int si = brep.AddSurface(surface); if (surface is PlaneSurface) { var nurbs = surface.ToNurbsSurface(); nurbs.KnotsU.InsertKnot(surface.Domain(0).Mid); nurbs.KnotsV.InsertKnot(surface.Domain(1).Mid); surface = nurbs; } // Classify Loops var nesting = new int[loops.Length]; var edgeLoops = new BrepBoundary[loops.Length]; { var trims = new Curve[loops.Length]; int index = 0; foreach (var loop in loops) { if (loop is PolyCurve polycurve) { var trim = new PolyCurve(); for (int s = 0; s < polycurve.SegmentCount; s++) { var segment = polycurve.SegmentCurve(s); var trimSegment = surface.Pullback(segment, trimTolerance); trim.AppendSegment(trimSegment); } trims[index++] = trim; } else { trims[index++] = surface.Pullback(loop, trimTolerance); } } for (int i = 0; i < edgeLoops.Length; ++i) { for (int j = i + 1; j < edgeLoops.Length; ++j) { var containment = Curve.PlanarClosedCurveRelationship(trims[i], trims[j], Plane.WorldXY, Revit.VertexTolerance * Revit.ModelUnits); if (containment == RegionContainment.MutualIntersection) { edgeLoops[i].type = BrepLoopType.Outer; edgeLoops[j].type = BrepLoopType.Outer; } else if (containment == RegionContainment.AInsideB) { nesting[i]++; } else if (containment == RegionContainment.BInsideA) { nesting[j]++; } } } // Fix orientation if necessary index = 0; foreach (var loop in loops) { // Ignore intersecting loops if (edgeLoops[index].type == BrepLoopType.Unknown) { if (nesting[index] % 2 != 0) { edgeLoops[index].type = BrepLoopType.Inner; } else { edgeLoops[index].type = BrepLoopType.Outer; } } switch (trims[index].ClosedCurveOrientation()) { case CurveOrientation.Undefined: break; case CurveOrientation.CounterClockwise: if (edgeLoops[index].type == BrepLoopType.Inner) { loops[index].Reverse(); } break; case CurveOrientation.Clockwise: if (edgeLoops[index].type == BrepLoopType.Outer) { loops[index].Reverse(); } break; } ++index; } } // Create Brep Edges and compute trims { int index = 0; foreach (var edgeLoop in loops) { // Ignore unclasified loops if (edgeLoops[index].type == BrepLoopType.Unknown) { continue; } var kinks = new List <double>(); { var domain = edgeLoop.Domain; var t = domain.Min; while (edgeLoop.GetNextDiscontinuity(Continuity.C1_locus_continuous, t, domain.Max, out t)) { kinks.Add(t); } } var edges = kinks.Count > 0 ? edgeLoop.Split(kinks) : new Curve[] { edgeLoop }; edgeLoops[index].edges = new List <BrepEdge>(); edgeLoops[index].trims = new PolyCurve(); edgeLoops[index].orientation = new List <int>(); foreach (var edge in edges) { var brepEdge = default(BrepEdge); brepEdge = brep.Edges.Add(brep.AddEdgeCurve(edge)); edgeLoops[index].edges.Add(brepEdge); var segment = edge; edgeLoops[index].orientation.Add(segment.TangentAt(segment.Domain.Mid).IsParallelTo(brepEdge.TangentAt(brepEdge.Domain.Mid))); var trim = surface.Pullback(segment, trimTolerance); edgeLoops[index].trims.Append(trim); } edgeLoops[index].trims.MakeClosed(Revit.VertexTolerance); ++index; } } // Sort edgeLoops in nesting orther, shallow loops first Array.Sort(nesting, edgeLoops); var outerLoops = edgeLoops.Where(x => x.type == BrepLoopType.Outer); var innerLoops = edgeLoops.Where(x => x.type == BrepLoopType.Inner); // Group Edge loops in shells with the outer loop as the first one shells = outerLoops. Select(x => new List <BrepBoundary>() { x }). ToArray(); if (shells.Length == 1) { shells[0].AddRange(innerLoops); } else { // Iterate in reverse order to found deeper loops before others foreach (var innerLoop in innerLoops.Reverse()) { foreach (var shell in shells.Reverse()) { var containment = Curve.PlanarClosedCurveRelationship(innerLoop.trims, shell[0].trims, Plane.WorldXY, Revit.VertexTolerance); if (containment == RegionContainment.AInsideB) { shell.Add(innerLoop); break; } } } } return(si); } shells = default; return(-1); }