// TODO: See above. We're no longer creating new extrusions. This is here just for backwards compatibility. public RH.Extrusion ExtrusionToNative(Extrusion extrusion) { RH.Curve outerProfile = CurveToNative((Curve)extrusion.profile); RH.Curve innerProfile = null; if (extrusion.profiles.Count == 2) { innerProfile = CurveToNative((Curve)extrusion.profiles[1]); } try { var IsClosed = extrusion.profile.GetType().GetProperty("IsClosed").GetValue(extrusion.profile, null) as bool?; if (IsClosed != true) { outerProfile.Reverse(); } } catch { } var myExtrusion = RH.Extrusion.Create(outerProfile.ToNurbsCurve(), (double)extrusion.length, (bool)extrusion.capped); if (innerProfile != null) { myExtrusion.AddInnerProfile(innerProfile); } return(myExtrusion); }
public ICurve CurveToSpeckle(RH.Curve curve, string units = null) { var u = units ?? ModelUnits; var tolerance = RhinoDoc.ActiveDoc.ModelAbsoluteTolerance; Rhino.Geometry.Plane pln = Rhino.Geometry.Plane.Unset; curve.TryGetPlane(out pln, tolerance); if (curve is PolyCurve polyCurve) { return(PolycurveToSpeckle(polyCurve, u)); } if (curve.IsCircle(tolerance) && curve.IsClosed) { curve.TryGetCircle(out var getObj, tolerance); var cir = CircleToSpeckle(getObj, u); cir.domain = IntervalToSpeckle(curve.Domain); return(cir); } if (curve.IsArc(tolerance)) { curve.TryGetArc(out var getObj, tolerance); var arc = ArcToSpeckle(getObj, u); arc.domain = IntervalToSpeckle(curve.Domain); return(arc); } if (curve.IsEllipse(tolerance) && curve.IsClosed) { curve.TryGetEllipse(pln, out var getObj, tolerance); var ellipse = EllipseToSpeckle(getObj, u); ellipse.domain = IntervalToSpeckle(curve.Domain); } if (curve.IsLinear(tolerance) || curve.IsPolyline()) // defaults to polyline { curve.TryGetPolyline(out var getObj); if (null != getObj) { return(PolylineToSpeckle(getObj, IntervalToSpeckle(curve.Domain), u)); } } return(NurbsToSpeckle(curve.ToNurbsCurve(), u)); }
/// <summary> /// Converts a Rhino <see cref="Rhino.Geometry.Brep"/> instance to a Speckle <see cref="Brep"/> /// </summary> /// <param name="brep">BREP to be converted.</param> /// <returns></returns> public Brep BrepToSpeckle(RH.Brep brep, string units = null) { var tol = RhinoDoc.ActiveDoc.ModelAbsoluteTolerance; //tol = 0; var u = units ?? ModelUnits; brep.Repair(tol); //should maybe use ModelAbsoluteTolerance ? // foreach (var f in brep.Faces) // { // f.RebuildEdges(tol, false, false); // } // Create complex var joinedMesh = new RH.Mesh(); var mySettings = MeshingParameters.Minimal; joinedMesh.Append(RH.Mesh.CreateFromBrep(brep, mySettings)); joinedMesh.Weld(Math.PI); joinedMesh.Vertices.CombineIdentical(true, true); joinedMesh.Compact(); var spcklBrep = new Brep(displayValue: MeshToSpeckle(joinedMesh, u), provenance: Applications.Rhino, units: u); // Vertices, uv curves, 3d curves and surfaces spcklBrep.Vertices = brep.Vertices .Select(vertex => PointToSpeckle(vertex, u)).ToList(); spcklBrep.Curve3D = brep.Curves3D .Select(curve3d => { Rhino.Geometry.Curve crv = curve3d; if (crv is NurbsCurve nurbsCurve) { // Nurbs curves of degree 2 have weird support in Revit, so we up everything to degree 3. if (nurbsCurve.Degree < 3) { nurbsCurve.IncreaseDegree(3); } // Check for invalid multiplicity in the curves. This is also to better support Revit. var invalid = HasInvalidMultiplicity(nurbsCurve); // If the curve has invalid multiplicity and is not closed, rebuild with same number of points and degree. // TODO: Figure out why closed curves don't like this hack? if (invalid) { nurbsCurve = nurbsCurve.Rebuild(nurbsCurve.Points.Count * 3, nurbsCurve.Degree, true);; var in1 = HasInvalidMultiplicity(nurbsCurve); Console.WriteLine(in1); } nurbsCurve.Domain = curve3d.Domain; crv = nurbsCurve; } var icrv = ConvertToSpeckle(crv) as ICurve; return(icrv); // And finally convert to speckle }).ToList(); spcklBrep.Curve2D = brep.Curves2D.ToList().Select(c => { var curve = c; if (c is NurbsCurve nurbsCurve) { var invalid = HasInvalidMultiplicity(nurbsCurve); if (invalid) { //nurbsCurve = nurbsCurve.Fit(nurbsCurve.Degree, 0, 0).ToNurbsCurve(); nurbsCurve = nurbsCurve.Rebuild(nurbsCurve.Points.Count * 3, nurbsCurve.Degree, true); var in1 = HasInvalidMultiplicity(nurbsCurve); } curve = nurbsCurve; } var crv = CurveToSpeckle(c, Units.None); return(crv); }).ToList(); spcklBrep.Surfaces = brep.Surfaces .Select(srf => SurfaceToSpeckle(srf.ToNurbsSurface(), u)).ToList(); spcklBrep.IsClosed = brep.IsSolid; spcklBrep.Orientation = (BrepOrientation)brep.SolidOrientation; // Faces spcklBrep.Faces = brep.Faces .Select(f => new BrepFace( spcklBrep, f.SurfaceIndex, f.Loops.Select(l => l.LoopIndex).ToList(), f.OuterLoop.LoopIndex, f.OrientationIsReversed )).ToList(); // Edges spcklBrep.Edges = brep.Edges .Select(edge => new BrepEdge( spcklBrep, edge.EdgeCurveIndex, edge.TrimIndices(), edge.StartVertex?.VertexIndex ?? -1, edge.EndVertex?.VertexIndex ?? -1, edge.ProxyCurveIsReversed, IntervalToSpeckle(edge.Domain) )).ToList(); // Loops spcklBrep.Loops = brep.Loops .Select(loop => new BrepLoop( spcklBrep, loop.Face.FaceIndex, loop.Trims.Select(t => t.TrimIndex).ToList(), (BrepLoopType)loop.LoopType )).ToList(); // Trims spcklBrep.Trims = brep.Trims .Select(trim => { var t = new BrepTrim( spcklBrep, trim.Edge?.EdgeIndex ?? -1, trim.Face.FaceIndex, trim.Loop.LoopIndex, trim.TrimCurveIndex, (int)trim.IsoStatus, (BrepTrimType)trim.TrimType, trim.IsReversed(), trim.StartVertex.VertexIndex, trim.EndVertex.VertexIndex ); t.Domain = IntervalToSpeckle(trim.Domain); return(t); }) .ToList(); spcklBrep.volume = brep.GetVolume(); spcklBrep.bbox = BoxToSpeckle(new RH.Box(brep.GetBoundingBox(true)), u); spcklBrep.area = brep.GetArea(); return(spcklBrep); }
// Proper explosion of polycurves: // (C) The Rutten David https://www.grasshopper3d.com/forum/topics/explode-closed-planar-curve-using-rhinocommon public bool CurveSegments(List <RH.Curve> L, RH.Curve crv, bool recursive) { if (crv == null) { return(false); } PolyCurve polycurve = crv as PolyCurve; if (polycurve != null) { if (recursive) { polycurve.RemoveNesting(); } RH.Curve[] segments = polycurve.Explode(); if (segments == null) { return(false); } if (segments.Length == 0) { return(false); } if (recursive) { foreach (RH.Curve S in segments) { CurveSegments(L, S, recursive); } } else { foreach (RH.Curve S in segments) { L.Add(S.DuplicateShallow() as RH.Curve); } } return(true); } //Nothing else worked, lets assume it's a nurbs curve and go from there... var nurbs = crv.ToNurbsCurve(); if (nurbs == null) { return(false); } double t0 = nurbs.Domain.Min; double t1 = nurbs.Domain.Max; double t; int LN = L.Count; do { if (!nurbs.GetNextDiscontinuity(Continuity.C1_locus_continuous, t0, t1, out t)) { break; } var trim = new RH.Interval(t0, t); if (trim.Length < 1e-10) { t0 = t; continue; } var M = nurbs.DuplicateCurve(); M = M.Trim(trim); if (M.IsValid) { L.Add(M); } t0 = t; } while (true); if (L.Count == LN) { L.Add(nurbs); } return(true); }
/// <summary> /// Converts a Rhino <see cref="Rhino.Geometry.Brep"/> instance to a Speckle <see cref="Brep"/> /// </summary> /// <param name="brep">BREP to be converted.</param> /// <returns></returns> public Brep BrepToSpeckle(RH.Brep brep) { //brep.Repair(0.0); //should maybe use ModelAbsoluteTolerance ? var joinedMesh = new RH.Mesh(); var mySettings = new MeshingParameters(0); //brep.Compact(); brep.Trims.MatchEnds(); RH.Mesh.CreateFromBrep(brep, mySettings).All(meshPart => { joinedMesh.Append(meshPart); return(true); }); var spcklBrep = new Brep(displayValue: MeshToSpeckle(joinedMesh), provenance: Speckle.Core.Kits.Applications.Rhino, units: ModelUnits); // Vertices, uv curves, 3d curves and surfaces spcklBrep.Vertices = brep.Vertices .Select(vertex => PointToSpeckle(vertex)).ToList(); spcklBrep.Curve3D = brep.Curves3D .Select(curve3d => { Rhino.Geometry.Curve crv = curve3d; if (crv is NurbsCurve nurbsCurve) { // Nurbs curves of degree 2 have weird support in Revit, so we up everything to degree 3. if (nurbsCurve.Degree < 3) { nurbsCurve.IncreaseDegree(3); } // Check for invalid multiplicity in the curves. This is also to better support Revit. var invalid = HasInvalidMultiplicity(nurbsCurve); // If the curve has invalid multiplicity and is not closed, rebuild with same number of points and degree. // TODO: Figure out why closed curves don't like this hack? if (invalid && !nurbsCurve.IsClosed) { nurbsCurve = nurbsCurve.Rebuild(nurbsCurve.Points.Count, nurbsCurve.Degree, true); } nurbsCurve.Domain = curve3d.Domain; crv = nurbsCurve; } var icrv = ConvertToSpeckle(crv) as ICurve; return(icrv); // And finally convert to speckle }).ToList(); spcklBrep.Curve2D = brep.Curves2D.ToList().Select(c => { var nurbsCurve = c.ToNurbsCurve(); //nurbsCurve.Knots.RemoveMultipleKnots(1, nurbsCurve.Degree, Doc.ModelAbsoluteTolerance ); var rebuild = nurbsCurve.Rebuild(nurbsCurve.Points.Count, nurbsCurve.Degree, true); var crv = CurveToSpeckle(rebuild); return(crv); }).ToList(); spcklBrep.Surfaces = brep.Surfaces .Select(srf => SurfaceToSpeckle(srf.ToNurbsSurface())).ToList(); spcklBrep.IsClosed = brep.IsSolid; spcklBrep.Orientation = (BrepOrientation)brep.SolidOrientation; // Faces spcklBrep.Faces = brep.Faces .Select(f => new BrepFace( spcklBrep, f.SurfaceIndex, f.Loops.Select(l => l.LoopIndex).ToList(), f.OuterLoop.LoopIndex, f.OrientationIsReversed )).ToList(); // Edges spcklBrep.Edges = brep.Edges .Select(edge => new BrepEdge( spcklBrep, edge.EdgeCurveIndex, edge.TrimIndices(), edge.StartVertex.VertexIndex, edge.EndVertex.VertexIndex, edge.ProxyCurveIsReversed, IntervalToSpeckle(edge.Domain) )).ToList(); // Loops spcklBrep.Loops = brep.Loops .Select(loop => new BrepLoop( spcklBrep, loop.Face.FaceIndex, loop.Trims.Select(t => t.TrimIndex).ToList(), (BrepLoopType)loop.LoopType )).ToList(); // Trims spcklBrep.Trims = brep.Trims .Select(trim => { var t = new BrepTrim( spcklBrep, trim.Edge?.EdgeIndex ?? -1, trim.Face.FaceIndex, trim.Loop.LoopIndex, trim.TrimCurveIndex, (int)trim.IsoStatus, (BrepTrimType)trim.TrimType, trim.IsReversed(), trim.StartVertex.VertexIndex, trim.EndVertex.VertexIndex ); t.Domain = IntervalToSpeckle(trim.Domain); return(t); }) .ToList(); return(spcklBrep); }