/// <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); }
/// <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); }