public static ComponentProblem Add(ref ComponentProblems problems, BrepEdge edge, BrepTrim trim, string problem, ComponentProblemTypes type, object data = null) { var componentReal = new ComponentIndex(ComponentIndexType.BrepEdge, edge.EdgeIndex); var componentGUI = new ComponentIndex(ComponentIndexType.BrepEdge, trim.TrimIndex); return(Add(ref problems, componentReal, componentGUI, problem, type, data)); }
public static IEnumerable <DB.BRepBuilderEdgeGeometry> ToHost(BrepEdge edge) { var edgeCurve = edge.EdgeCurve.Trim(edge.Domain); if (edge.ProxyCurveIsReversed) { edgeCurve.Reverse(); } switch (edgeCurve) { case LineCurve line: yield return(DB.BRepBuilderEdgeGeometry.Create(ToHost(line))); yield break; case ArcCurve arc: yield return(DB.BRepBuilderEdgeGeometry.Create(ToHost(arc))); yield break; case NurbsCurve nurbs: yield return(DB.BRepBuilderEdgeGeometry.Create(ToHost(nurbs))); yield break; default: Debug.Fail($"{edgeCurve} is not supported as a Solid Edge"); yield break; } }
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); }
public static BrepVertex _GetEndVertex(this BrepEdge edge) { return(edge.EndVertex); var trim = edge._FindTrim(); var point = trim.Face.PointAt(trim.PointAtEnd.X, trim.PointAtEnd.Y); return(trim.Brep.Vertices[point._GetVertexIndex(trim.Brep.Vertices, 1, true)]); }
public static Edge ToTopologic(this BrepEdge brepEdge) { if (brepEdge == null) { return(null); } global::Rhino.Geometry.NurbsCurve nurbsCurve = brepEdge.ToNurbsCurve(); return(ToTopologic(nurbsCurve)); }
// check the location of edges, maxdistance to rd == 0 -> on that class road public static bool offsetValue(List <Line> a, BrepEdge edge) { foreach (Line rd in a) { if (rd.DistanceTo(edge.PointAtStart, true) < inter_tol && rd.DistanceTo(edge.PointAtEnd, true) < inter_tol) { // on this road return(true); } } // none return(false); }
private Topologic.Topology ByCurve(Curve ghCurve) { LineCurve ghLine = ghCurve as LineCurve; if (ghLine != null) { return(ByLine(ghLine.Line)); } Rhino.Geometry.NurbsCurve ghNurbsCurve = ghCurve as Rhino.Geometry.NurbsCurve; if (ghNurbsCurve != null) { return(ByNurbsCurve(ghNurbsCurve)); } ArcCurve ghArcCurve = ghCurve as ArcCurve; if (ghArcCurve != null) { return(ByArcCurve(ghArcCurve)); } BrepEdge ghBrepEdge = ghCurve as BrepEdge; if (ghBrepEdge != null) { return(ByBrepEdge(ghBrepEdge)); } //BrepTrim ghBrepTrim = ghCurve as BrepTrim; //if (ghBrepTrim != null) //{ // return ByBrepTrim(ghBrepTrim); //} PolylineCurve ghPolylineCurve = ghCurve as PolylineCurve; if (ghPolylineCurve != null) { return(ByPolylineCurve(ghPolylineCurve)); } PolyCurve ghPolyCurve = ghCurve as PolyCurve; if (ghPolyCurve != null) { return(ByPolyCurve(ghPolyCurve)); } throw new Exception("This type of curve is not yet supported."); }
public static Topology ToTopologic(this Curve curve) { if (curve == null) { return(null); } LineCurve lineCurve = curve as LineCurve; if (lineCurve != null) { return(lineCurve.Line.ToTopologic()); } Rhino.Geometry.NurbsCurve nurbsCurve = curve as Rhino.Geometry.NurbsCurve; if (nurbsCurve != null) { return(nurbsCurve.ToTopologic()); } ArcCurve arcCurve = curve as ArcCurve; if (arcCurve != null) { return(arcCurve.ToTopologic()); } BrepEdge brepEdge = curve as BrepEdge; if (brepEdge != null) { return(brepEdge.ToTopologic()); } PolylineCurve ghPolylineCurve = curve as PolylineCurve; if (ghPolylineCurve != null) { return(ghPolylineCurve.ToTopologic()); } PolyCurve ghPolyCurve = curve as PolyCurve; if (ghPolyCurve != null) { return(ghPolyCurve.ToTopologic()); } return(null); }
/// <summary> /// Create frames that are aligned with a Brep. The input curve does not /// necessarily have to lie on the Brep. /// </summary> /// <param name="curve">Input centreline of the glulam.</param> /// <param name="brep">Brep to align the glulam orientation to.</param> /// <param name="num_samples">Number of orientation frames to use for alignment.</param> /// <returns>New Glulam oriented to the brep.</returns> public static Plane[] FramesNormalToSurface(Curve curve, Brep brep, int num_samples = 20) { num_samples = Math.Max(num_samples, 2); double[] t = curve.DivideByCount(num_samples - 1, true); Plane[] planes = new Plane[num_samples]; Vector3d xaxis, yaxis, zaxis; Point3d pt; ComponentIndex ci; for (int i = 0; i < t.Length; ++i) { brep.ClosestPoint(curve.PointAt(t[i]), out pt, out ci, out double u, out double v, 0, out yaxis); // From: https://discourse.mcneel.com/t/brep-closestpoint-normal-is-not-normal/15147/8 // If the closest point is found on an edge, average the face normals if (ci.ComponentIndexType == ComponentIndexType.BrepEdge) { BrepEdge edge = brep.Edges[ci.Index]; int[] faces = edge.AdjacentFaces(); yaxis = Vector3d.Zero; for (int j = 0; j < faces.Length; ++j) { BrepFace bf = edge.Brep.Faces[j]; if (bf.ClosestPoint(pt, out u, out v)) { Vector3d faceNormal = bf.NormalAt(u, v); yaxis += faceNormal; } } yaxis.Unitize(); } zaxis = curve.TangentAt(t[i]); xaxis = Vector3d.CrossProduct(zaxis, yaxis); planes[i] = new Plane(pt, xaxis, yaxis); } return(planes); }
private Topologic.Edge ByBrepEdge(BrepEdge ghBrepEdge) { Rhino.Geometry.NurbsCurve ghNurbsCurve = ghBrepEdge.ToNurbsCurve(); return(ByNurbsCurve(ghNurbsCurve)); }
//internal static Brep ToRawBrep(/*const*/ Brep brep, double scaleFactor) //{ // brep = brep.DuplicateShallow() as Brep; // return EncodeRaw(ref brep, scaleFactor) ? brep : default; //} //internal static bool EncodeRaw(ref Brep brep, double scaleFactor) //{ // if (scaleFactor != 1.0 && !brep.Scale(scaleFactor)) // return default; // var bbox = brep.GetBoundingBox(false); // if (!bbox.IsValid || bbox.Diagonal.Length < Revit.ShortCurveTolerance) // return default; // return SplitFaces(ref brep); //} //static bool SplitFaces(ref Brep brep) //{ // Brep brepToSplit = null; // while (!ReferenceEquals(brepToSplit, brep)) // { // brepToSplit = brep; // foreach (var face in brepToSplit.Faces) // { // var splitters = new List<Curve>(); // var trimsBBox = BoundingBox.Empty; // foreach (var trim in face.OuterLoop.Trims) // trimsBBox.Union(trim.GetBoundingBox(true)); // var domainUV = new Interval[] // { // new Interval(trimsBBox.Min.X, trimsBBox.Max.X), // new Interval(trimsBBox.Min.Y, trimsBBox.Max.Y), // }; // // Compute splitters // var splittedUV = new bool[2] { false, false }; // for (int d = 0; d < 2; d++) // { // var domain = domainUV[d]; // var t = domain.Min; // while (face.GetNextDiscontinuity(d, Continuity.Gsmooth_continuous, t, domain.Max, out t)) // { // splitters.AddRange(face.TrimAwareIsoCurve(1 - d, t)); // splittedUV[d] = true; // } // } // var closedUV = new bool[2] { face.IsClosed(0), face.IsClosed(1) }; // if (!splittedUV[0] && closedUV[0]) // { // splitters.AddRange(face.TrimAwareIsoCurve(1, face.Domain(0).Mid)); // splittedUV[0] = true; // } // if (!splittedUV[1] && closedUV[1]) // { // splitters.AddRange(face.TrimAwareIsoCurve(0, face.Domain(1).Mid)); // splittedUV[1] = true; // } // if (splitters.Count > 0) // { // var surfaceIndex = face.SurfaceIndex; // var splitted = face.Split(splitters, Revit.ShortCurveTolerance); // if (splitted is null) // { // Debug.Fail("BrepFace.Split", "Failed to split a closed face."); // return false; // } // if (brepToSplit.Faces.Count == splitted.Faces.Count) // { // // Split was ok but for tolerance reasons no new faces were created. // // Too near from the limits. // } // else // { // foreach (var f in splitted.Faces) // { // if (f.SurfaceIndex != surfaceIndex) // continue; // if (splittedUV[0] && splittedUV[1]) // f.ShrinkFace(BrepFace.ShrinkDisableSide.ShrinkAllSides); // else if (splittedUV[0]) // f.ShrinkFace(BrepFace.ShrinkDisableSide.DoNotShrinkSouthSide | BrepFace.ShrinkDisableSide.DoNotShrinkNorthSide); // else if (splittedUV[1]) // f.ShrinkFace(BrepFace.ShrinkDisableSide.DoNotShrinkEastSide | BrepFace.ShrinkDisableSide.DoNotShrinkWestSide); // } // // Start again until no face is splitted // brep = splitted; // break; // } // } // } // } // return brep is object; //} #endregion #region Transfer /// <summary> /// Replaces <see cref="Raw.RawEncoder.ToHost(Brep)"/> to catch Revit Exceptions /// </summary> /// <param name="brep"></param> /// <returns></returns> public static NXOpen.Body ToSolid(/*const*/ Brep brep) { try { BodyStyle brepType; switch (brep.SolidOrientation) { case BrepSolidOrientation.Inward: brepType = BodyStyle.Sheet; break; case BrepSolidOrientation.Outward: brepType = BodyStyle.Solid; break; } List <NXOpen.Body> faceBodies = new List <NXOpen.Body>(); foreach (var face in brep.Faces) { using (var nurbSurface = face.ToNurbsSurface()) { List <(List <NXOpen.Curve> edgeCurves, List <int> directions)> boundaryEdgeCurves = new List <(List <NXOpen.Curve>, List <int>)>(); for (int i = 0; i < face.Loops.Count; i++) { List <NXOpen.Curve> currentEdgeCurves = new List <NXOpen.Curve>(); List <int> currentDirections = new List <int>(); var trims = face.Loops[i].Trims; for (int j = 0; j < trims.Count; j++) { if (trims[j].TrimType != BrepTrimType.Boundary && trims[j].TrimType != BrepTrimType.Mated) { continue; } BrepEdge edge = trims[j].Edge; if (edge is null) { continue; } var currentEdgeCurve = edge.Trim(edge.Domain).ToCurve(); currentEdgeCurves.Add(currentEdgeCurve); currentDirections.Add(edge.ProxyCurveIsReversed ? -1 : 1); } boundaryEdgeCurves.Add((currentEdgeCurves, currentDirections)); } if (nurbSurface.IsPlanar()) { // 使用有界平面创建 var boundaryCurves = boundaryEdgeCurves.SelectMany(obj => obj.edgeCurves).ToArray(); var boundedPlaneBody = _theSession.Parts.Work.Features.CreateBoundedPlane(boundaryCurves).GetBodies()[0]; boundedPlaneBody.RemoveParameter(); faceBodies.Add(boundedPlaneBody); //boundaryCurves.Delete(); //NXOpen.UF.StringList bplaneBoundaries = new NXOpen.UF.StringList() //{ // num = boundaryEdgeCurves.Count, // id = boundaryEdgeCurves.SelectMany(obj => obj.edgeCurveTags).ToArray(), // dir = boundaryEdgeCurves.SelectMany(obj => obj.directions).ToArray(), // _string = boundaryEdgeCurves.Select(obj => obj.edgeCurveTags.Count).ToArray() //}; //double[] tolerrances = new double[bplaneBoundaries.dir.Length]; //for (int i = 0; i < tolerrances.Length; i++) // tolerrances[i] = DistanceTolerance; //theUfSession.Modl.CreateBplane(ref bplaneBoundaries, tolerrances, out NXOpen.Tag body); //bplaneBoundaries.id.Select(obj => obj.GetTaggedObject() as NXOpen.NXObject).ToArray().Delete(); } else { var faceBody = RawEncoder.ToHost(nurbSurface); #region 找到一个位于面上的点 Point3d point3dOnFace = new Point3d(); bool findInteriorPoint = false; if (face.IsPointOnFace(face.Domain(0).Mid, face.Domain(1).Mid) == PointFaceRelation.Interior) { face.Evaluate(face.Domain(0).Mid, face.Domain(1).Mid, 0, out point3dOnFace, out _); findInteriorPoint = true; } else { var firstEdge = face.Loops.ElementAt(0).Trims.ElementAt(0).Edge; Point3d ptOnFirstEdge = firstEdge.PointAt(firstEdge.Domain.Mid); face.ClosestPoint(ptOnFirstEdge, out double u, out double v); double offsetValue = 0.02; u += offsetValue; v += offsetValue; if (face.IsPointOnFace(u, v) == PointFaceRelation.Interior) { face.Evaluate(u, v, 0, out point3dOnFace, out _); findInteriorPoint = true; } else { u -= 2 * offsetValue; v -= 2 * offsetValue; if (face.IsPointOnFace(u, v) == PointFaceRelation.Interior) { face.Evaluate(u, v, 0, out point3dOnFace, out _); findInteriorPoint = true; } } } if (!findInteriorPoint) { findInteriorPoint.ToString().ListingWindowWriteLine(); var copiedFaceBody = faceBody.CopyAndPaste()[0] as NXOpen.Body; copiedFaceBody.SetColor(216); } #endregion for (int i = 0; i < boundaryEdgeCurves.Count; i++) { NXOpen.UF.UFModl.TrimObject[] trimBoundaryObjects = new NXOpen.UF.UFModl.TrimObject[boundaryEdgeCurves[i].edgeCurves.Count]; for (int j = 0; j < trimBoundaryObjects.Length; j++) { trimBoundaryObjects[j] = new NXOpen.UF.UFModl.TrimObject { object_tag = boundaryEdgeCurves[i].edgeCurves[j].Tag, curve_project_method = boundaryEdgeCurves[i].directions[j] }; } _theUfSession.Modl.TrimSheet(faceBody.Tag, trimBoundaryObjects.Length, trimBoundaryObjects, null, 1, 1, point3dOnFace.ToXYZ().ToArray(), 0.01, out int numGapPoints, out double[] gapPoints); } faceBodies.Add(faceBody); } #if !DEBUG boundaryEdgeCurves.SelectMany(obj => obj.edgeCurves).ToArray().Delete(); #endif } } NXOpen.Body resultBody = null; if (faceBodies.Count > 1) { var sewFeature = WorkPart.Features.CreateSew(faceBodies.ToArray()); resultBody = sewFeature.GetBodies()[0]; #if !DEBUG resultBody.RemoveParameter(); #endif } else { resultBody = faceBodies[0]; } var brepArea = brep.GetArea(); var bodyArea = resultBody.GetArea(); resultBody.SetUserAttribute("Area", -1, bodyArea, NXOpen.Update.Option.Now); var error = Math.Abs(brepArea - bodyArea) / brepArea; resultBody.SetUserAttribute("Error", -1, error, NXOpen.Update.Option.Now); if (error > 0.001) { resultBody.SetColor(186); } } catch (NXOpen.NXException e) { Logger.Error(e.ToString()); } return(null); }
static void MakeTwistedCubeTrimmingLoop(ref Brep brep, ref BrepFace face, // Indices of corner vertices listed in SW, SE, NW, NE order int eSi, // index of edge on south side of surface int eS_dir, // orientation of edge with respect to surface trim int eEi, // index of edge on south side of surface int eE_dir, // orientation of edge with respect to surface trim int eNi, // index of edge on south side of surface int eN_dir, // orientation of edge with respect to surface trim int eWi, // index of edge on south side of surface int eW_dir // orientation of edge with respect to surface trim ) { Surface srf = brep.Surfaces[face.SurfaceIndex]; var loop = brep.Loops.Add(BrepLoopType.Outer, face); // Create trimming curves running counter clockwise around the surface's domain. // Start at the south side // side: 0=south, 1=east, 2=north, 3=west for (int side = 0; side < 4; side++) { Curve trimming_curve = TwistedCubeTrimmingCurve(srf, side); int curve_index = brep.Curves2D.Add(trimming_curve); int ei = 0; bool reverse = false; IsoStatus iso = IsoStatus.None; switch (side) { case 0: // south ei = eSi; reverse = (eS_dir == -1); iso = IsoStatus.South; break; case 1: // east ei = eEi; reverse = (eE_dir == -1); iso = IsoStatus.East; break; case 2: // north ei = eNi; reverse = (eN_dir == -1); iso = IsoStatus.North; break; case 3: // west ei = eWi; reverse = (eW_dir == -1); iso = IsoStatus.West; break; } BrepEdge edge = brep.Edges[ei]; BrepTrim trim = brep.Trims.Add(edge, reverse, loop, curve_index); trim.IsoStatus = iso; trim.TrimType = BrepTrimType.Mated; // This b-rep is closed, so all trims have mates. trim.SetTolerances(0, 0); // This simple example is exact - for models with // non-exact data, set tolerance as explained in // definition of BrepTrim. } }
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 List <BRepBuilderEdgeGeometry> BrepEdgeToNative(BrepEdge edge) { // TODO: Trim curve with domain. Unsure if this is necessary as all our curves are converted to NURBS on Rhino output. var nativeCurveArray = CurveToNative(edge.Curve); bool isTrimmed = edge.Curve.domain != null && edge.Domain != null && (edge.Curve.domain.start != edge.Domain.start || edge.Curve.domain.end != edge.Domain.end); if (nativeCurveArray.Size == 1) { var nativeCurve = nativeCurveArray.get_Item(0); if (edge.ProxyCurveIsReversed) { nativeCurve = nativeCurve.CreateReversed(); } if (nativeCurve == null) { return(new List <BRepBuilderEdgeGeometry>()); } if (isTrimmed) { nativeCurve.MakeBound(edge.Domain.start ?? 0, edge.Domain.end ?? 1); } if (!nativeCurve.IsBound) { nativeCurve.MakeBound(0, nativeCurve.Period); } var endPoint = nativeCurve.GetEndPoint(0); var source = nativeCurve.GetEndPoint(1); var distanceTo = endPoint.DistanceTo(source); var closed = distanceTo < 1E-6; if (closed) { // Revit does not like single curve loop edges, so we split them in two. var start = nativeCurve.GetEndParameter(0); var end = nativeCurve.GetEndParameter(1); var mid = (end - start) / 2; var a = nativeCurve.Clone(); a.MakeBound(start, mid); var b = nativeCurve.Clone(); b.MakeBound(mid, end); var halfEdgeA = BRepBuilderEdgeGeometry.Create(a); var halfEdgeB = BRepBuilderEdgeGeometry.Create(b); return(new List <BRepBuilderEdgeGeometry> { halfEdgeA, halfEdgeB }); } // TODO: Remove short segments if smaller than 'Revit.ShortCurveTolerance'. var fullEdge = BRepBuilderEdgeGeometry.Create(nativeCurve); return(new List <BRepBuilderEdgeGeometry> { fullEdge }); } var iterator = edge.ProxyCurveIsReversed ? nativeCurveArray.ReverseIterator() : nativeCurveArray.ForwardIterator(); var result = new List <BRepBuilderEdgeGeometry>(); while (iterator.MoveNext()) { var crv = iterator.Current as DB.Curve; if (edge.ProxyCurveIsReversed) { crv = crv.CreateReversed(); } result.Add(BRepBuilderEdgeGeometry.Create(crv)); } return(result); }
public static BrepTrim _FindTrim(this BrepEdge edge) { return(edge.Brep.Trims.First(o => o.Edge == edge)); }
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); }