private BrepTrim GetClosetBrepTrim(BrepTrimList TrimList, Curve Crv) { foreach (BrepTrim item in TrimList) { // //item.TrimCurve 会出现问题, //关于TrimCurve官方的解释如下 //Gets the Brep.Curves2D 2d curve geometry used by this trim, or null. //item.Edge is an 2D Curve // //这里只对两根线是否相等进行了简单的判断,如果起始点相等,那么就相等,否则不相等 Curve EdgeCrv = item.Edge.EdgeCurve; Point3d TrimSPt = EdgeCrv.PointAtStart; Point3d TrimEPt = EdgeCrv.PointAtEnd; bool IsMeetEnd = (TrimSPt.EpsilonEquals(Crv.PointAtStart, 10) && TrimEPt.EpsilonEquals(Crv.PointAtEnd, 10)) || (TrimSPt.EpsilonEquals(Crv.PointAtEnd, 10) && TrimEPt.EpsilonEquals(Crv.PointAtStart, 10)); if (IsMeetEnd) { return(item); } } return(null); }
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> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { Surface Srf = default(Surface); List <Curve> Crvs = new List <Curve>(); List <BrepTrim> TrimsList = new List <BrepTrim>(); double Length = 2; bool IsSmooth = true; if (!DA.GetData(0, ref Srf)) { return; } if (!DA.GetDataList <Curve>(1, Crvs)) { return; } if (!DA.GetData(2, ref Length)) { return; } if (!DA.GetData(3, ref IsSmooth)) { return; } Brep TempBrep = Srf.ToBrep(); if (!TempBrep.IsSurface || TempBrep == null) { this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Unable to extend trimmed surfaces.:line 67"); return; } //BrepTrimList is an reference object BrepTrimList BrepTrimList = TempBrep.Trims; for (int Index = 0; Index < Crvs.Count; Index++) { BrepTrim TrimItem = this.GetClosetBrepTrim(BrepTrimList, Crvs[Index]); TrimsList.Add(TrimItem); } var TempList = TrimsList.Where(item => item == null || item.TrimType == BrepTrimType.Seam).ToList(); if (TempList.Count != 0) { this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Unable to extend trimmed surfaces. line 81"); } ///<summary> ///如果输入的Surface为UntrimSurface,那么Extend会对Surface进行延伸,如果输入的Surface为Untrim Surface,Extend ///方法就会先对Surface 执行‘untrim’操作,然后再对面进行延伸 /// </summary> for (int Index = 0; Index < TrimsList.Count; Index++) { Srf = Srf.Extend(TrimsList[Index].IsoStatus, Length, IsSmooth); } DA.SetData(0, Srf); }
internal static void _InitThreadSafe(this BrepTrimList trims) { lock (trims) { var count = trims.Count; if (count > 0) { // we take last element and thus init all list - this make our list threadsafe var last = trims[count - 1]; } } }
/// <summary> /// Get index of trim in loop to which it belongs. /// Dont use TrimIndex, since it is global index: index of trim in all trims from Brep. /// </summary> /// <param name="trim"></param> /// <param name="loopTrims"></param> /// <returns></returns> public static int _IndexInLoop(this BrepTrim trim, BrepTrimList loopTrims = null) { var trims = loopTrims ?? trim.Loop.Trims_ThreadSafe(); for (int i = 0; i < trims.Count; i++) { if (trims[i].TrimIndex == trim.TrimIndex) { return(i); } } throw new Exception("Cannot find trimindex in mehod: _BrepTrim._IndexInLoop(trim)"); }
public static List <Point3d[]> _GetTrimControlPoints(this BrepTrimList loopTrims) { loopTrims._InitThreadSafe(); var res = new List <Point3d[]>(); foreach (var trim in loopTrims) { var points = trim.TrimType == BrepTrimType.Singular ? new[] { trim.PointAtStart, trim.PointAtEnd } : trim._ToNurbsCurve().Points.Select(o => o.Location).ToArray(); res.Add(points); } return(res); }
public static List <BrepTrim> _SelectNonSingularTrims(this BrepTrimList trims) { trims._InitThreadSafe(); var res = new List <BrepTrim>(); foreach (var trim in trims) { switch (trim.TrimType) { case BrepTrimType.Boundary: case BrepTrimType.Mated: case BrepTrimType.Seam: res.Add(trim); //var edgeLength = trim.Edge.GetLength(); //var trimLength = trim.GetLength(); //if (edgeLength < 0.0001) //{ // var nothing = 0; // // do not add very small edges //} //else //{ // trimsUnsorted.Add(trim); //} break; case BrepTrimType.Singular: // nothing - dont copy singular trims int i = 0; break; default: throw new Exception("Exception: class Object_BrepLoop - Not supported type in trims: " + trim.ObjectType); } } return(res); }
public static List <BrepTrim> _SortByCrvs3d(this BrepTrimList trims, out List <bool> trimsReversedFlag, out bool crvs3dHasReversedDirection) { var reversedDirectionCount = 0; trimsReversedFlag = new List <bool>(); var trimsUnsorted = trims._SelectNonSingularTrims(); var trimsSorted = new List <BrepTrim>(); var searchForIndex = -1; //var debugIndexes = new List<int>(); //var debugIs = new List<int>(); while (trimsUnsorted.Count > 0) { bool found = false; int foundIndex = 0; for (var i = 0; i < trimsUnsorted.Count; i++) { var trim = trimsUnsorted[i]; //var indexStart = trim.Edge.PointAtStart._GetVertexIndex(trim.Brep.Vertices); //var indexEnd = trim.Edge.PointAtEnd._GetVertexIndex(trim.Brep.Vertices); var indexStart = trim.Edge._GetStartVertex().VertexIndex; var indexEnd = trim.Edge._GetEndVertex().VertexIndex; if (searchForIndex == -1) { searchForIndex = indexStart; } if (!found && (indexStart == searchForIndex || indexEnd == searchForIndex)) { found = true; foundIndex = i; // continue to search for circular crvs - that PointStart == PointEnd } if (indexStart == searchForIndex && indexStart == indexEnd) { found = true; foundIndex = i; break; //if found circular crv stop search - circular crvs have the highest priority } } if (found) { var trim = trimsUnsorted[foundIndex]; var indexStart = trim.Edge._GetStartVertex().VertexIndex; var indexEnd = trim.Edge._GetEndVertex().VertexIndex; var distToStart = trim.Edge.PointAtStart._DistanceTo(trim.Face.PointAt(trim.PointAtStart.X, trim.PointAtStart.Y)); var distToEnd = trim.Edge.PointAtStart._DistanceTo(trim.Face.PointAt(trim.PointAtEnd.X, trim.PointAtEnd.Y)); if (distToStart < distToEnd) { reversedDirectionCount--; } if (distToStart > distToEnd) { reversedDirectionCount++; } //debugIndexes.Add(indexStart); //debugIndexes.Add(indexEnd); trimsUnsorted.RemoveAt(foundIndex); //debugIs.Add(foundIndex); trimsSorted.Add(trim); // Detect reversed flag: a) end->start - straight connection b)end->end - reversed connection var straightConnection = (indexStart == searchForIndex); // for circular crvs simple detection if connection is staight doesnt work - so lets do precision calculation if (indexStart == indexEnd) { } if (straightConnection) { trimsReversedFlag.Add(false); searchForIndex = indexEnd; } else { trimsReversedFlag.Add(true); searchForIndex = indexStart; } } if (!found) { throw new Exception( "Exception: Cannot find next trim! (Issue_SurfaceBad_BadTrim_Singular.SortTrims)"); } } crvs3dHasReversedDirection = reversedDirectionCount > 0; return(trimsSorted); }
/// <summary> /// Find prev and next trim in same loop. /// /// </summary> /// <param name="trim"></param> /// <param name="prevTrim"></param> /// <param name="nextTrim"></param> /// <param name="loopTrims">Provide this parameter is possible. Speed optimization. If it is not provided - will be calculcated, what takes some time.</param> public static void _GetPrevNextTrims(this BrepTrim trim, out BrepTrim prevTrim, out BrepTrim nextTrim, BrepTrimList loopTrims = null) { var trims = loopTrims ?? trim.Loop.Trims_ThreadSafe(); for (int i = 0; i < trims.Count; i++) { if (trims[i].TrimIndex == trim.TrimIndex) { var iPrev = (i != 0) ? i - 1 : trims.Count - 1; var iNext = (i != trims.Count - 1) ? i + 1 : 0; prevTrim = trims[iPrev]; nextTrim = trims[iNext]; return; } } throw new Exception("Cannot find trimindex in mehod: _BrepTrim._GetPrevNextTrims(trim, out prevTrim, out nextTrim)"); }
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); }