static internal IEnumerable <GeometryObject> ToHost(this Rhino.Geometry.Brep brep) { Solid solid = null; // MakeValidForV2 converts everything inside brep to NURBS if (brep.MakeValidForV2()) { var splittedBrep = SplitClosedFaces(brep); if (splittedBrep != null) { brep = splittedBrep; //RhinoDoc.ActiveDoc.Objects.Add(brep); try { var builder = new BRepBuilder(brep.IsSolid ? BRepType.Solid : BRepType.OpenShell); builder.AllowRemovalOfProblematicFaces(); builder.SetAllowShortEdges(); var brepEdges = new List <BRepBuilderGeometryId> [brep.Edges.Count]; foreach (var face in brep.Faces) { var faceId = builder.AddFace(face.ToHost(), face.OrientationIsReversed); builder.SetFaceMaterialId(faceId, GraphicAttributes.Peek.MaterialId); foreach (var loop in face.Loops) { var loopId = builder.AddLoop(faceId); foreach (var trim in loop.Trims) { if (trim.TrimType != BrepTrimType.Boundary && trim.TrimType != BrepTrimType.Mated) { continue; } var edge = trim.Edge; if (edge == null) { continue; } var edgeIds = brepEdges[edge.EdgeIndex]; if (edgeIds == null) { edgeIds = brepEdges[edge.EdgeIndex] = new List <BRepBuilderGeometryId>(); foreach (var e in edge.ToHost()) { edgeIds.Add(builder.AddEdge(BRepBuilderEdgeGeometry.Create(e))); } } if (trim.IsReversed()) { for (int e = edgeIds.Count - 1; e >= 0; --e) { builder.AddCoEdge(loopId, edgeIds[e], true); } } else { for (int e = 0; e < edgeIds.Count; ++e) { builder.AddCoEdge(loopId, edgeIds[e], false); } } } builder.FinishLoop(loopId); } builder.FinishFace(faceId); } builder.Finish(); if (builder.IsResultAvailable()) { solid = builder.GetResult(); } } catch (Autodesk.Revit.Exceptions.ApplicationException e) { // TODO: Fix cases with singularities and uncomment this line //Debug.Fail(e.Source, e.Message); Debug.WriteLine(e.Message, e.Source); } } else { Debug.Fail("SplitClosedFaces", "SplitClosedFaces failed to split a closed surface."); } } if (solid != null) { yield return(solid); } else { // Emergency result as a mesh var mp = MeshingParameters.Default; mp.MinimumEdgeLength = Revit.VertexTolerance; mp.ClosedObjectPostProcess = true; mp.JaggedSeams = false; var brepMesh = new Rhino.Geometry.Mesh(); brepMesh.Append(Rhino.Geometry.Mesh.CreateFromBrep(brep, mp)); foreach (var g in brepMesh.ToHost()) { yield return(g); } } }
public Solid BrepToNative(Brep brep) { var bRepType = BRepType.OpenShell; switch (brep.Orientation) { case BrepOrientation.Inward: bRepType = BRepType.Void; break; case BrepOrientation.Outward: bRepType = BRepType.Solid; break; } using var builder = new BRepBuilder(bRepType); builder.SetAllowShortEdges(); builder.AllowRemovalOfProblematicFaces(); var brepEdges = new List <DB.BRepBuilderGeometryId> [brep.Edges.Count]; foreach (var face in brep.Faces) { var faceId = builder.AddFace(BrepFaceToNative(face), face.OrientationReversed); foreach (var loop in face.Loops) { var loopId = builder.AddLoop(faceId); if (face.OrientationReversed) { loop.TrimIndices.Reverse(); } foreach (var trim in loop.Trims) { if (trim.TrimType != BrepTrimType.Boundary && trim.TrimType != BrepTrimType.Mated) { continue; } if (trim.Edge == null) { continue; } var edgeIds = brepEdges[trim.EdgeIndex]; if (edgeIds == null) { // First time we see this edge, convert it and add edgeIds = brepEdges[trim.EdgeIndex] = new List <BRepBuilderGeometryId>(); var bRepBuilderGeometryIds = BrepEdgeToNative(trim.Edge).Select(edge => builder.AddEdge(edge)); edgeIds.AddRange(bRepBuilderGeometryIds); } var trimReversed = face.OrientationReversed ? !trim.IsReversed : trim.IsReversed; if (trimReversed) { for (int e = edgeIds.Count - 1; e >= 0; --e) { if (builder.IsValidEdgeId(edgeIds[e])) { builder.AddCoEdge(loopId, edgeIds[e], true); } } } else { for (int e = 0; e < edgeIds.Count; ++e) { if (builder.IsValidEdgeId(edgeIds[e])) { builder.AddCoEdge(loopId, edgeIds[e], false); } } } } builder.FinishLoop(loopId); } builder.FinishFace(faceId); } var removedFace = builder.RemovedSomeFaces(); var bRepBuilderOutcome = builder.Finish(); if (bRepBuilderOutcome == BRepBuilderOutcome.Failure) { return(null); } var isResultAvailable = builder.IsResultAvailable(); if (!isResultAvailable) { return(null); } var result = builder.GetResult(); return(result); }