public static bool _IsSameDirectionToEdge(this BrepTrim trim, Surface srf, Point3d trimT03d, Point3d trimT13d, Point3d edgeT03d, Point3d edgeT13d, bool validateTrimType = true) { if (validateTrimType) // speed optimization - avoiding call to UnsafeNativeMethods.ON_BrepTrim_Type { if (trim.TrimType == BrepTrimType.Singular) { return(false); } } return(_Vector3d._IsSameDirection(trimT03d, trimT13d, edgeT03d, edgeT13d)); // ON_BrepTrim& //ON_Brep::NewTrim( ON_BrepEdge& edge, ON_BOOL32 bRev3d, int c2i ) //{ // m_is_solid = 0; // ON_BrepTrim& trim = NewTrim( c2i ); // trim.m_ei = edge.m_edge_index; // edge.m_ti.Append(trim.m_trim_index); // trim.m_vi[0] = edge.m_vi[bRev3d?1:0]; // trim.m_vi[1] = edge.m_vi[bRev3d?0:1]; // trim.m_bRev3d = bRev3d?true:false; // return trim; //} }
/// <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); }
public static int _EndVertexIndex(this BrepTrim trim, double tol = 10, bool throwExceptionIfNotFound = true) { if (trim.Edge != null) { return(trim.Edge._GetEndVertex().VertexIndex); } var point = trim.Face.PointAt(trim.PointAtEnd.X, trim.PointAtEnd.Y); return(point._GetVertexIndex(trim.Brep.Vertices, tol, throwExceptionIfNotFound)); }
/// <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)"); }
/* OLD CODE * public static void _RecreateCurves(this BrepTrim trim, Surface srf, SurfaceSingulars ssingulars, bool reverseCurveDirection, bool fixDeformedEdges, double tol_tol_fixDeformedEdges, bool recreate3dCurves, out NurbsCurve crv3d, out NurbsCurve crv2d) * { * if (recreate3dCurves) * { * crv3d = trim._PullEdgeToSurface(srf, ssingulars, reverseCurveDirection, fixDeformedEdges, tol_tol_fixDeformedEdges); * * ////DEBUG * //foreach (var l in crv3d.Points) * //{ * // debugIndexEdge2++; * // string text = "#" + debugIndexEdge2; * // AddDebugPoint(Doc, text, l.Location, Color.Gold); //debug * //} * * // * // Create 2d curve (trim) from new edge (that is already projected on surface) * // High interpolation of 500 points makes mistakes almost unvisible * // * crv2d = srf._Convert3dCurveTo2d(crv3d, ssingulars, trim); * } * else * { * crv3d = trim.Edge._ToNurbsCurve(); * crv2d = trim._ToNurbsCurve(); * * if (reverseCurveDirection) * { * crv3d.Reverse(); * } * * // Reverse 2d crv if needed * var trimStartPoint = srf.PointAt(trim.PointAtStart.X, trim.PointAtStart.Y); * var trimEndPoint = srf.PointAt(trim.PointAtEnd.X, trim.PointAtEnd.Y); * if (crv3d.PointAtStart.DistanceTo(trimStartPoint) > crv3d.PointAtStart.DistanceTo(trimEndPoint)) * { * crv2d.Reverse(); * } * } * } * * public static NurbsCurve _PullEdgeToSurface(this BrepTrim trim, Surface srf, SurfaceSingulars ssingulars, bool reverseCurveDirection, bool fixDeformedEdges, double tol_tol_fixDeformedEdges) * { * // * // Project Edge to surface, and create new Edge from control points (edge devided by 100 points) * // * Curve edge = trim.Edge; * NurbsCurve crv3d = null; * * if (fixDeformedEdges) * { * NurbsCurve newedge; * if (edge._ZigZagDeformations_TryRemove_old(srf, tol_tol_fixDeformedEdges, out newedge)) * { * //log.temp("trim #{0} had zigzag ", trimIndex+1); * edge = newedge; * } * } * int DIVIDE_BY_COUNT_I = Math.Min(Math.Max(Convert.ToInt32(edge._GetLength_ThreadSafe() / 0.01), 10), 100); * if (edge.Degree == 1) * { * DIVIDE_BY_COUNT_I = 10; * } * * Point3d[] edgeDevidedPoints; * edge.DivideByCount(DIVIDE_BY_COUNT_I, true, out edgeDevidedPoints); * if (edgeDevidedPoints != null) * { * if (reverseCurveDirection) * { * edgeDevidedPoints = edgeDevidedPoints.Reverse().ToArray(); * } * var edgeDevidedUV = srf._ClosestPoints(edgeDevidedPoints); * * * //DEBUG * //Logger.log("+++"); * //foreach (var p in edgeDevidedUV) * //{ * // debugIndexEdge++; * // //bool inside = trim.Brep.IsPointInside(point, 0.000001,false); * // if (debugIndexEdge < debugIndexMAX) * // { * // string text = "#" + debugIndexEdge + ": " + String.Format("{0:0.00}", p.u) + " - " + String.Format("{0:0.00}", p.v); * // //string text = "#" + debugIndexEdge; * // AddDebugPoint(Doc, text, srf.PointAt(p.u, p.v), Color.Red); //debug * // Logger.log(text); * // } * //} * * // * // Fix U or V in singularities (in case where values are indentical at start of surface (like Point3d(u, v) == Point3d(u, v+100))); * // * var fixedSrf = srf._FixSurfacePoints(ref edgeDevidedUV, true, ssingulars, trim); * * // * // Contruct 3d curve on surface * // * var points2d = edgeDevidedUV.Select(o => new Point2d(o.u, o.v)).ToList(); * crv3d = srf.InterpolatedCurveOnSurfaceUV(points2d, 0.0000001); * * if (crv3d == null) * { * var point3d = edgeDevidedUV.Select(o => srf.PointAt(o.u, o.v)).ToList(); * crv3d = srf.InterpolatedCurveOnSurface(point3d, 0.0001); * //crv3d = crv3d; * //var doc = RhinoDoc.ActiveDoc; * //foreach (var p in point3d) * //{ * // debugIndexEdge2++; * // string text = "#" + debugIndexEdge2; * // AddDebugPoint(doc, text, p, Color.Gold); //debug * //} * } * } * * * * if (crv3d == null) * { * //log.error(g.IssueFixer, "Can't build crv3d from 2D points"); * throw new Exception("Can't rebuild " + trim._GUIEdgeName()); * } * * return crv3d; * } * * private static void AddDebugPoint(RhinoDoc doc, string text, Point3d point, Color color = default(Color)) * { * // return; * * color = (color == default(Color)) * ? Color.Aqua * : color; * * //doc.Objects.AddPoint(point, new ObjectAttributes() * //{ * // DisplayOrder = 12, * // LayerIndex = 0, * // Name = "temp", * // //Mode = ObjectMode.Locked, * // ColorSource = ObjectColorSource.ColorFromObject, * // ObjectColor = Color.Red, * // Visible = true * // //ObjectDecoration = ObjectDecoration.BothArrowhead, * //}); * Guid id = doc.Objects.AddTextDot(text, point, new ObjectAttributes() * { * DisplayOrder = 5, * LayerIndex = 0, * //Name = "DebugPoint " + text, * Name = text, * //Mode = ObjectMode.Locked, * ColorSource = ObjectColorSource.ColorFromObject, * ObjectColor = color, * Visible = true * }); * * * } * */ #endregion // /// <summary> /// Recalculated iso status. /// Works always compare to internal Rhino method 'srf.IsIsoparametric(trim)' /// </summary> /// <param name="trim"></param> /// <param name="ssingulars">provide it for speed optimization. otherwise it will be calculated automatically.</param> /// <returns></returns> public static IsoStatus _IsoStatus(this BrepTrim trim, SurfaceSingulars ssingulars = null) { // COMMENTED - just to show what is a internal Rhino method to detect isoStatus //return srf.IsIsoparametric(trim); - doesnt work always properly!!! // COMMENTED - we want to be very sure and lets recalculate isostaus always // Calculate ony if status is invalid //var trimIsoStatus = trim.IsoStatus; //var isValidIso = trimIsoStatus == IsoStatus.East // || trimIsoStatus == IsoStatus.North // || trimIsoStatus == IsoStatus.South // || trimIsoStatus == IsoStatus.West; //if (isValidIso) //{ // return trimIsoStatus; //} if (ssingulars == null) { var srf = trim._Srf(); ssingulars = new SurfaceSingulars(srf); } var T0 = trim.PointAtStart; var T1 = trim.PointAtEnd; var T0IsoStatus = ssingulars.GetIsoStatus(T0.X, T0.Y); var T1IsoStatus = ssingulars.GetIsoStatus(T1.X, T1.Y); if (T0IsoStatus == T1IsoStatus) { return(T0IsoStatus); } // show warnig message only both iso statuses are not 'None' - when we substitute surface with no singulars we will have such situation when all iso statuses became 'None' if ((T0IsoStatus != IsoStatus.None || T1IsoStatus != IsoStatus.None)) { if (ssingulars.Srf.IsAtSingularity(T0.X, T0.Y, true) || ssingulars.Srf.IsAtSingularity(T1.X, T1.Y, true)) { log.wrong("_BrepTrim._IsoStatus() Cannot detect proper IsoStatus: T0:{0}-T1:{1} T0=[{2:0.000},{3:0.000}] T1=[{4:0.000},{5:0.000}]", T0IsoStatus, T1IsoStatus, T0.X, T0.Y, T1.X, T1.Y); } else { var temp = 0; } } return(IsoStatus.None); }
/// <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 bool _IsSameDirectionToEdge(this BrepTrim trim) { if (trim.TrimType == BrepTrimType.Singular) { return(false); } var srf = trim._Srf(); var trimPointAtStart = trim.PointAtStart; var trimPointAtEnd = trim.PointAtEnd; var trimT0srf = srf.PointAt(trimPointAtStart.X, trimPointAtStart.Y); var trimT1srf = srf.PointAt(trimPointAtEnd.X, trimPointAtEnd.Y); var Crv3d = trim.Edge; var Domain = Crv3d.Domain; var edgeT03d = Crv3d.PointAt(Domain.T0); var edgeT13d = Crv3d.PointAt(Domain.T1); return(trim._IsSameDirectionToEdge(srf, trimT0srf, trimT1srf, edgeT03d, edgeT13d, false)); }
/// <summary> /// Fix control points of trim /// </summary> /// <param name="trim"></param> /// <param name="singulars"></param> /// <param name="roundStart">Round value of singular axis (if surface is singular on V - then round first value of V)</param> /// <param name="roundEnd">Round value of singular axis (if surface is singular on V - then round last value of V)</param> /// <returns></returns> public static NurbsCurve _FixContorlPoints(this BrepTrim trim, SurfaceSingulars singulars = null, bool roundStart = false, bool roundEnd = false) { var srf = trim._Srf(); var trimNurb = trim._ToNurbsCurve(); // v1 - full var res = trimNurb._Fix2dContorlPoints(srf, singulars, trim.Edge, roundStart, roundEnd); var newtrim = res._ZigZagDeformations_TryRemove(srf); //if (newtrim != null) //{ // res = newtrim; //} // v2 - only zigzag //var res = trimNurb; //var newtrim = trimNurb._ZigZagDeformations_TryRemove(srf); //if (newtrim != null) //{ // res = newtrim; //} //res = res._Fix2dContorlPoints(srf, singulars, trim.Edge, roundStart, roundEnd); return(res); }
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)); }
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 static string _GUIEdgeNum(this BrepTrim trim) { var num = Shared.GUIComponentNum(trim.TrimIndex); // in GUI we show starting from 1 or from 0 return(num._ToStringFastSharp()); }
public static string _GUIEdgeName(this BrepTrim trim) { return("Edge " + trim._GUIEdgeNum()); }
public static bool _NeedFixClosedCurve(this BrepTrim trim) { return(((Curve)trim)._NeedFixClosedCurve() || (trim.Edge != null && trim.Edge._NeedFixClosedCurve())); }
public static NurbsCurve _Simplify(this BrepTrim trim) { return(trim._Simplify(trim._Srf())); }
public static Surface _Srf(this BrepTrim trim) { return(trim.Brep.Surfaces[trim.Face.SurfaceIndex]); }
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 }