public static BrepTrimList Trims_ThreadSafe(this BrepLoop loop) { var res = loop.Trims; res._InitThreadSafe(); return(res); }
private Face ByBrepFace(BrepFace ghBrepFace) { Rhino.Geometry.Surface ghSurface = ghBrepFace.UnderlyingSurface(); Face untrimmedFace = BySurface(ghSurface); BrepLoop ghOuterLoop = ghBrepFace.OuterLoop; Wire outerWire = null; BrepLoopList ghLoops = ghBrepFace.Loops; List <Wire> innerWires = new List <Wire>(); foreach (BrepLoop ghLoop in ghLoops) { BrepTrimList ghTrims = ghLoop.Trims; List <Edge> trimmingEdges = new List <Edge>(); foreach (BrepTrim ghTrim in ghTrims) { BrepEdge ghEdge = ghTrim.Edge; if (ghEdge == null) { continue; //throw new Exception("An invalid Rhino edge is encountered."); } Topology topology = ByCurve(ghEdge.DuplicateCurve()); // Edge or Wire? Edge trimmingEdge = topology as Edge; if (trimmingEdge != null) { trimmingEdges.Add(trimmingEdge); } Wire partialTrimmingWire = topology as Wire; if (partialTrimmingWire != null) { List <Edge> partialTrimmingEdges = partialTrimmingWire.Edges; trimmingEdges.AddRange(partialTrimmingEdges); } } Wire trimmingWire = Wire.ByEdges(trimmingEdges); List <Vertex> trimmingVertices = trimmingWire.Vertices; if (ghLoop == ghOuterLoop) { outerWire = trimmingWire; } else { innerWires.Add(trimmingWire); } } Face outerTrimmedFace = Topologic.Utilities.FaceUtility.TrimByWire(untrimmedFace, outerWire, true); Face finalFace = outerTrimmedFace.AddInternalBoundaries(innerWires); return(finalFace); }
/// <summary> /// Get middle point of edges in 3d space. /// </summary> /// <param name="loop"></param> /// <param name="accurate">Accurate takes more time but have great precision.</param> /// <returns></returns> public static Point3d _GetCentroid(this BrepLoop loop, bool accurate) { if (loop == null) { log.wrong("_BrepLoop._GetCentroid - loop is null"); return(Point3d.Origin); } var loopEdges = loop._Trims_ThreadSafe() .Where(o => o.Edge != null) .Select(o => (Curve)o.Edge).ToArray(); return(loop.Face._Srf()._GetCentroid(loopEdges, accurate)); }
public static double _GetLength3d(this BrepLoop loop) { double res = 0; foreach (var trim in loop.Trims_ThreadSafe()) { if (trim.TrimType == BrepTrimType.Singular) { continue; } res += trim.Edge._GetLength_ThreadSafe(); } return(res); }
public static Curve[] _GetJoinedEdges(this BrepLoop loop, double tol = 1) { var crvs = new List <Curve>(); foreach (var trim in loop.Trims_ThreadSafe()) { if (trim.TrimType == BrepTrimType.Singular) { continue; } var crv3d = trim.Edge._Complexify(100); crvs.Add(crv3d); } var res = Curve.JoinCurves(crvs, tol); return(res); }
public static Curve[] _GetJoinedTrims3d(this BrepLoop loop, double tol = 1) { var crvs = new List <Curve>(); foreach (var trim in loop.Trims_ThreadSafe()) { if (trim.TrimType == BrepTrimType.Singular) { continue; } //var crv3d = Srf._Convert2dCurveTo3d(trim.Crv); var crv3d = trim._2dTo3d(trim._Srf())._Complexify(100); crvs.Add(crv3d); } var res = Curve.JoinCurves(crvs, tol); return(res); }
/// <summary> /// Return index of vertexes used by this loop /// </summary> /// <param name="loop"></param> /// <param name="indexesCircular">each index that will be in this list point to circular vertexes: crv start and end points are same - zero length or cirvular or wrong defined points</param> /// <returns></returns> public static List <int> _GetVertexesIndex(this BrepLoop loop, out List <int> indexesCircular) { var vertices = loop.Brep.Vertices; var indexes = new List <int>(); indexesCircular = new List <int>(); //crv start and end points are same - zero length or cirvular or wrong defined points foreach (var t in loop.Trims_ThreadSafe()) { //check for supported trim types switch (t.TrimType) { case BrepTrimType.Boundary: case BrepTrimType.Mated: case BrepTrimType.Seam: case BrepTrimType.Singular: break; default: throw new Exception("Exception: class _BrepLoop._GetVertexesIndex - Not supported type in trims: " + t.ObjectType); } int indexBegin = t._StartVertexIndex(); if (!indexes.Contains(indexBegin)) { indexes.Add(indexBegin); } int indexEnd = t._EndVertexIndex(); if (!indexes.Contains(indexEnd)) { indexes.Add(indexEnd); } if (indexBegin == indexEnd && t.TrimType != BrepTrimType.Singular) { indexesCircular.Add(indexBegin); } } indexes.Sort(); return(indexes); }
public static BrepTrimList _Trims_ThreadSafe(this BrepLoop loop) { return(Trims_ThreadSafe(loop)); }
public Brep BrepToSpeckle(Solid solid) { #if REVIT2021 // TODO: Incomplete implementation!! var brep = new Brep(); brep.units = ModelUnits; if (solid is null || solid.Faces.IsEmpty) { return(null); } var faceIndex = 0; var edgeIndex = 0; var curve2dIndex = 0; var curve3dIndex = 0; var loopIndex = 0; var trimIndex = 0; var surfaceIndex = 0; var speckleFaces = new Dictionary <Face, BrepFace>(); var speckleEdges = new Dictionary <Edge, BrepEdge>(); var speckleEdgeIndexes = new Dictionary <Edge, int>(); var speckle3dCurves = new ICurve[solid.Edges.Size]; var speckle2dCurves = new List <ICurve>(); var speckleLoops = new List <BrepLoop>(); var speckleTrims = new List <BrepTrim>(); foreach (var face in solid.Faces.Cast <Face>()) { var surface = FaceToSpeckle(face, out bool orientation, 0.0); var iterator = face.EdgeLoops.ForwardIterator(); var loopIndices = new List <int>(); while (iterator.MoveNext()) { var loop = iterator.Current as EdgeArray; var loopTrimIndices = new List <int>(); // Loop through the edges in the loop. var loopIterator = loop.ForwardIterator(); while (loopIterator.MoveNext()) { // Each edge should create a 2d curve, a 3d curve, a BrepTrim and a BrepEdge. var edge = loopIterator.Current as Edge; var faceA = edge.GetFace(0); // Determine what face side are we currently on. var edgeSide = face == faceA ? 0 : 1; // Get curve, create trim and save index var trim = edge.GetCurveUV(edgeSide); var sTrim = new BrepTrim(brep, edgeIndex, faceIndex, loopIndex, curve2dIndex, 0, BrepTrimType.Boundary, edge.IsFlippedOnFace(edgeSide), -1, -1); var sTrimIndex = trimIndex; loopTrimIndices.Add(sTrimIndex); // Add curve and trim, increase index counters. speckle2dCurves.Add(CurveToSpeckle(trim.As3DCurveInXYPlane())); speckleTrims.Add(sTrim); curve2dIndex++; trimIndex++; // Check if we have visited this edge before. if (!speckleEdges.ContainsKey(edge)) { // First time we visit this edge, add 3d curve and create new BrepEdge. var edgeCurve = edge.AsCurve(); speckle3dCurves[curve3dIndex] = CurveToSpeckle(edgeCurve); var sCurveIndex = curve3dIndex; curve3dIndex++; // Create a trim with just one of the trimIndices set, the second one will be set on the opposite condition. var sEdge = new BrepEdge(brep, sCurveIndex, new[] { sTrimIndex }, -1, -1, edge.IsFlippedOnFace(face), null); speckleEdges.Add(edge, sEdge); speckleEdgeIndexes.Add(edge, edgeIndex); edgeIndex++; } else { // Already visited this edge, skip curve 3d var sEdge = speckleEdges[edge]; var sEdgeIndex = speckleEdgeIndexes[edge]; sTrim.EdgeIndex = sEdgeIndex; // Update trim indices with new item. // TODO: Make this better. var trimIndices = sEdge.TrimIndices.ToList(); trimIndices.Append(sTrimIndex); sEdge.TrimIndices = trimIndices.ToArray(); } } var speckleLoop = new BrepLoop(brep, faceIndex, loopTrimIndices, BrepLoopType.Outer); speckleLoops.Add(speckleLoop); var sLoopIndex = loopIndex; loopIndex++; loopIndices.Add(sLoopIndex); } speckleFaces.Add(face, new BrepFace(brep, surfaceIndex, loopIndices, loopIndices[0], !face.OrientationMatchesSurfaceOrientation)); faceIndex++; brep.Surfaces.Add(surface); surfaceIndex++; } var mesh = new Mesh(); (mesh.faces, mesh.vertices) = GetFaceVertexArrFromSolids(new List <Solid> { solid }); mesh.units = ModelUnits; // TODO: Revit has no brep vertices. Must call 'brep.SetVertices()' in rhino when provenance is revit. // TODO: Set tolerances and flags in rhino when provenance is revit. brep.Faces = speckleFaces.Values.ToList(); brep.Curve2D = speckle2dCurves; brep.Curve3D = speckle3dCurves.ToList(); brep.Trims = speckleTrims; brep.Edges = speckleEdges.Values.ToList(); brep.Loops = speckleLoops; brep.displayValue = mesh; return(brep); #else throw new Exception("Converting BREPs to Speckle is currently only supported in Revit 2021."); #endif }
public static global::Topologic.Face ToTopologic(this BrepFace brepFace) { global::Rhino.Geometry.Surface ghSurface = brepFace?.UnderlyingSurface(); if (ghSurface == null) { return(null); } global::Topologic.Face untrimmedFace = ghSurface.ToTopologic(); BrepLoop ghOuterLoop = brepFace.OuterLoop; Wire outerWire = null; BrepLoopList ghLoops = brepFace.Loops; List <Wire> innerWires = new List <Wire>(); foreach (BrepLoop ghLoop in ghLoops) { BrepTrimList ghTrims = ghLoop.Trims; List <Edge> trimmingEdges = new List <Edge>(); foreach (BrepTrim ghTrim in ghTrims) { BrepEdge ghEdge = ghTrim.Edge; if (ghEdge == null) { continue; //throw new Exception("An invalid Rhino edge is encountered."); } Topology topology = ghEdge.DuplicateCurve().ToTopologic(); if (topology == null) { continue; } // Edge or Wire? Edge trimmingEdge = topology as Edge; if (trimmingEdge != null) { trimmingEdges.Add(trimmingEdge); } Wire partialTrimmingWire = topology as Wire; if (partialTrimmingWire != null) { IList <Edge> partialTrimmingEdges = partialTrimmingWire.Edges; trimmingEdges.AddRange(partialTrimmingEdges); } } Wire trimmingWire = Wire.ByEdges(trimmingEdges); if (ghLoop == ghOuterLoop) { outerWire = trimmingWire; } else { innerWires.Add(trimmingWire); } } global::Topologic.Face outerTrimmedFace = global::Topologic.Utilities.FaceUtility.TrimByWire(untrimmedFace, outerWire, true); global::Topologic.Face finalFace = outerTrimmedFace.AddInternalBoundaries(innerWires); return(finalFace); }