private static int CompareDinosByLength2(IndexPair x, IndexPair y) { if(Pmin(x) > Pmin(y))return 1; if (Pmin(x) < Pmin(y)) return -1; if(Pmin(x) == Pmin(y)){ if(Pmax(x) > Pmax(y))return 1; if (Pmax(x) < Pmax(y)) return -1; return 0; } else return 0; }
public static void GrowHull(ref Mesh Msh, Point3d Pt) { double Tol = RhinoDoc.ActiveDoc.ModelAbsoluteTolerance * 0.1;//RhinoDoc.ActiveDoc.ModelAngleToleranceRadians; double AngleTest = (Math.PI * 0.5) - ((0.1 / 360) * (Math.PI * 2.0)); MeshPoint CP = Msh.ClosestMeshPoint(Pt, 0); if (CP.Point.DistanceTo(Pt) < Tol) { int[] EdgeIndices = Msh.TopologyEdges.GetEdgesForFace(CP.FaceIndex); Msh.Faces.RemoveAt(CP.FaceIndex); Msh.Vertices.Add(Pt); List <MeshFace> AddFaces = new List <MeshFace>(); for (int EdgeIdx = 0; EdgeIdx < EdgeIndices.Length; EdgeIdx++) { Rhino.IndexPair VertexPair = Msh.TopologyEdges.GetTopologyVertices(EdgeIndices[EdgeIdx]); AddFaces.Add(new MeshFace(Msh.TopologyVertices.MeshVertexIndices(VertexPair.I)[0], Msh.TopologyVertices.MeshVertexIndices(VertexPair.J)[0], Msh.Vertices.Count - 1)); } Msh.Faces.AddFaces(AddFaces); return; } else if (Msh.IsPointInside(Pt, Tol, true)) { return; } else { Msh.FaceNormals.ComputeFaceNormals(); List <int> DeleteFaces = new List <int>(); for (int FaceIdx = 0; FaceIdx < Msh.Faces.Count; FaceIdx++) { Vector3d VecTest = new Vector3d(Msh.Faces.GetFaceCenter(FaceIdx) - Pt); Plane PlaneTest = new Plane(Msh.Faces.GetFaceCenter(FaceIdx), Msh.FaceNormals[FaceIdx]); if (Vector3d.VectorAngle(PlaneTest.ZAxis, VecTest) > AngleTest || Math.Abs(PlaneTest.DistanceTo(Pt)) < Tol) { DeleteFaces.Add(FaceIdx); } } Msh.Faces.DeleteFaces(DeleteFaces); Msh.Vertices.Add(Pt); List <MeshFace> AddFaces = new List <MeshFace>(); for (int EdgeIdx = 0; EdgeIdx < Msh.TopologyEdges.Count; EdgeIdx++) { if (!Msh.TopologyEdges.IsSwappableEdge(EdgeIdx)) { IndexPair VertexPair = Msh.TopologyEdges.GetTopologyVertices(EdgeIdx); AddFaces.Add(new MeshFace(Msh.TopologyVertices.MeshVertexIndices(VertexPair.I)[0], Msh.TopologyVertices.MeshVertexIndices(VertexPair.J)[0], Msh.Vertices.Count - 1)); } } Msh.Faces.AddFaces(AddFaces); return; } }
/// <summary> /// Instace constructor based on a list of curves (i.e. a lattice). /// </summary> public ExoMesh(List<Curve> struts) { m_hulls = new List<ExoHull>(); m_sleeves = new List<ExoSleeve>(); m_plates = new List<ExoPlate>(); m_mesh = new Mesh(); double tol = RhinoDoc.ActiveDoc.ModelAbsoluteTolerance; // First, we convert the struts to a list of unique nodes and node pairs // We use the following lists to extract valid data from the input list var nodeList = new Point3dList(); // List of unique nodes var nodePairList = new List<IndexPair>(); // List of struts, as node index pairs struts = FrameTools.CleanNetwork(struts, tol, out nodeList, out nodePairList); // Set hull locations foreach (Point3d node in nodeList) { m_hulls.Add(new ExoHull(node)); } // Create sleeves, plates and relational indices for (int i = 0; i < struts.Count; i++) { m_sleeves.Add(new ExoSleeve(struts[i], nodePairList[i])); // Construct plates m_plates.Add(new ExoPlate(nodePairList[i].I, struts[i].TangentAtStart)); m_plates.Add(new ExoPlate(nodePairList[i].J, -struts[i].TangentAtEnd)); // Set sleeve relational parameters IndexPair platePair = new IndexPair(m_plates.Count - 2, m_plates.Count - 1); m_sleeves[i].PlatePair = platePair; // Set hull relational parameters m_hulls[nodePairList[i].I].SleeveIndices.Add(i); m_hulls[nodePairList[i].J].SleeveIndices.Add(i); m_hulls[nodePairList[i].I].PlateIndices.Add(platePair.I); m_hulls[nodePairList[i].J].PlateIndices.Add(platePair.J); } }
/// <summary> /// Formats the line input into the UnitCell object. It converts the list of lines into /// a list of unique nodes and unique node pairs, ignoring duplicates. /// </summary> private void ExtractTopology(List<Line> lines) { double tol = RhinoDoc.ActiveDoc.ModelAbsoluteTolerance; CellTools.FixIntersections(ref lines); // Iterate through list of lines foreach (Line line in lines) { // Get line, and it's endpoints Point3d[] pts = new Point3d[] { line.From, line.To }; List<int> nodeIndices = new List<int>(); // Loop over end points, being sure to not create the same node twice foreach (Point3d pt in pts) { int closestIndex = this.Nodes.ClosestIndex(pt); // find closest node to current pt // If node already exists if (this.Nodes.Count != 0 && this.Nodes[closestIndex].EpsilonEquals(pt, tol)) { nodeIndices.Add(closestIndex); } // If it doesn't exist, add it else { this.Nodes.Add(pt); nodeIndices.Add(this.Nodes.Count - 1); } } IndexPair nodePair = new IndexPair(nodeIndices[0], nodeIndices[1]); // If not duplicate strut, save it if (this.NodePairs.Count == 0 || !NodePairs.Contains(nodePair)) { this.NodePairs.Add(nodePair); } } }
static int Pmin(IndexPair pair) { if(pair.I > pair.J)return pair.J; else return pair.I; }
/// 2Nurbs /// public string Mesh2Topo(ref Mesh mesh, out Mesh mesh2, int edge, out IndexPair data) { Rhino.Geometry.Collections.MeshTopologyEdgeList el = mesh.TopologyEdges; Rhino.Geometry.Collections.MeshTopologyVertexList vs = mesh.TopologyVertices; string str = ""; List<int> firstLoop1; str += FirstEdge(mesh, out firstLoop1); double column = (double)vs.Count / (double)firstLoop1.Count; int Column = (int)column; if (column - Column != 0) str += "Points Count error,Please confirm the topo to be quad style"; int[] energy = new int[vs.Count]; List<int> indexPt = new List<int>(); indexPt.AddRange(firstLoop1); for (int i = 0; i < firstLoop1.Count; i++) { energy[firstLoop1[i]] = 1; } for (int i = 0; i < Column - 1; i++) { bool sign = true; for (int j = 0; j < firstLoop1.Count; j++) { int[] index = vs.ConnectedTopologyVertices(firstLoop1[j]); for (int k = 0; k < index.Length; k++) { energy[index[k]]++; } } for (int j = 0; j < firstLoop1.Count; j++) { int[] index = vs.ConnectedTopologyVertices(firstLoop1[j]); for (int k = 0; k < index.Length; k++) { if (energy[index[k]] == 1) { firstLoop1[j] = index[k]; sign = false; break; } } } if (sign) { str += " Loop false,Not quad topo Or To the end"; } else { indexPt.AddRange(firstLoop1); } } /// ///******* double MX = (double)Column - 1; double MY = (double)firstLoop1.Count - 1; List<Point3d> output1 = new List<Point3d>(); List<Point3d> output2 = new List<Point3d>(); int iCount = 0; Color[] cl = new Color[mesh.Vertices.Count]; //edge List<int> pl1 = new List<int>(); List<int> pl2 = new List<int>(); List<int> pl3 = new List<int>(); List<int> pl4 = new List<int>(); int edge1 = 0, edge2 = 0, edge3 = 0, edge4 = 0; ////////// for (int i = 0; i < Column; i++) { for (int j = 0; j < firstLoop1.Count; j++) { if (i == 0) pl1.Add(iCount); if (i == column - 1) pl3.Add(iCount); if (j == 0) pl2.Add(iCount); if (j == firstLoop1.Count - 1) pl4.Add(iCount); if (i == 0 && j == 0) edge1 = iCount; if (i == 0 && j == firstLoop1.Count - 1) edge2 = iCount; if (i == column - 1 && j == firstLoop1.Count - 1) edge3 = iCount; if (i == column - 1 && j == 0) edge4 = iCount; output1.Add(vs[indexPt[iCount]]); int indexV = vs.MeshVertexIndices(indexPt[iCount])[0]; cl[iCount] = mesh.VertexColors[indexV]; iCount++; Point3d pt = new Point3d(edge * i, edge * j, 0); output2.Add(pt); } } mesh2 = mc.MeshFromPoints(output2, firstLoop1.Count, Column); mesh = mc.MeshFromPoints(output1, firstLoop1.Count, Column); mesh.VertexColors.Clear(); mesh.VertexColors.AppendColors(cl); mesh2.VertexColors.Clear(); mesh2.VertexColors.AppendColors(cl); ///edge List<Point3d> pts; ///////////////////////////////////////////////////////// Color[] cl1 = new Color[pl1.Count * 2]; pts = new List<Point3d>(); for (int i = 0; i < pl1.Count; i++) { pts.Add(new Point3d(mesh2.Vertices[pl1[i]])); pts.Add((Point3d)mesh2.Vertices[pl1[i]] + new Vector3d(-edge, 0, 0)); cl1[i * 2] = mesh2.VertexColors[pl1[i]]; cl1[i * 2 + 1] = mesh2.VertexColors[pl1[i]]; } Mesh mesh3 = mc.MeshFromPoints(pts, 2, pl1.Count); mesh3.VertexColors.AppendColors(cl1); mesh2.Append(mesh3); ///////////////////////////////////////////////////////// Color[] cl2 = new Color[pl2.Count * 2]; pts = new List<Point3d>(); for (int i = 0; i < pl2.Count; i++) { pts.Add(new Point3d(mesh2.Vertices[pl2[i]])); pts.Add((Point3d)mesh2.Vertices[pl2[i]] + new Vector3d(0, -edge, 0)); cl2[i * 2] = mesh2.VertexColors[pl2[i]]; cl2[i * 2 + 1] = mesh2.VertexColors[pl2[i]]; } mesh3 = mc.MeshFromPoints(pts, 2, pl2.Count); mesh3.VertexColors.AppendColors(cl2); mesh2.Append(mesh3); ///////////////////////////////////////////////////////// Color[] cl3 = new Color[pl3.Count * 2]; pts = new List<Point3d>(); for (int i = 0; i < pl3.Count; i++) { pts.Add(new Point3d(mesh2.Vertices[pl3[i]])); pts.Add((Point3d)mesh2.Vertices[pl3[i]] + new Vector3d(edge, 0, 0)); cl3[i * 2] = mesh2.VertexColors[pl3[i]]; cl3[i * 2 + 1] = mesh2.VertexColors[pl3[i]]; } mesh3 = mc.MeshFromPoints(pts, 2, pl3.Count); mesh3.VertexColors.AppendColors(cl3); mesh2.Append(mesh3); ///////////////////////////////////////////////////////// Color[] cl4 = new Color[pl4.Count * 2]; pts = new List<Point3d>(); for (int i = 0; i < pl4.Count; i++) { pts.Add(new Point3d(mesh2.Vertices[pl4[i]])); pts.Add((Point3d)mesh2.Vertices[pl4[i]] + new Vector3d(0, edge, 0)); cl4[i * 2] = mesh2.VertexColors[pl4[i]]; cl4[i * 2 + 1] = mesh2.VertexColors[pl4[i]]; } mesh3 = mc.MeshFromPoints(pts, 2, pl4.Count); mesh3.VertexColors.AppendColors(cl4); mesh2.Append(mesh3); ///////////////////////////////////////////////////////// Point3d ept = (Point3d)mesh2.Vertices[edge1]; mesh3 = mc.MeshFromPoints(ept, ept + new Vector3d(-edge, 0, 0), ept + new Vector3d(-edge, -edge, 0), ept + new Vector3d(0, -edge, 0)); mesh3.VertexColors.Add(mesh2.VertexColors[edge1]); mesh3.VertexColors.Add(mesh2.VertexColors[edge1]); mesh3.VertexColors.Add(mesh2.VertexColors[edge1]); mesh3.VertexColors.Add(mesh2.VertexColors[edge1]); mesh2.Append(mesh3); ept = (Point3d)mesh2.Vertices[edge2]; mesh3 = mc.MeshFromPoints(ept, ept + new Vector3d(-edge, 0, 0), ept + new Vector3d(-edge, edge, 0), ept + new Vector3d(0, edge, 0)); mesh3.VertexColors.Add(mesh2.VertexColors[edge2]); mesh3.VertexColors.Add(mesh2.VertexColors[edge2]); mesh3.VertexColors.Add(mesh2.VertexColors[edge2]); mesh3.VertexColors.Add(mesh2.VertexColors[edge2]); mesh2.Append(mesh3); ept = (Point3d)mesh2.Vertices[edge3]; mesh3 = mc.MeshFromPoints(ept, ept + new Vector3d(edge, 0, 0), ept + new Vector3d(edge, edge, 0), ept + new Vector3d(0, edge, 0)); mesh3.VertexColors.Add(mesh2.VertexColors[edge3]); mesh3.VertexColors.Add(mesh2.VertexColors[edge3]); mesh3.VertexColors.Add(mesh2.VertexColors[edge3]); mesh3.VertexColors.Add(mesh2.VertexColors[edge3]); mesh2.Append(mesh3); ept = (Point3d)mesh2.Vertices[edge4]; mesh3 = mc.MeshFromPoints(ept, ept + new Vector3d(edge, 0, 0), ept + new Vector3d(edge, -edge, 0), ept + new Vector3d(0, -edge, 0)); mesh3.VertexColors.Add(mesh2.VertexColors[edge4]); mesh3.VertexColors.Add(mesh2.VertexColors[edge4]); mesh3.VertexColors.Add(mesh2.VertexColors[edge4]); mesh3.VertexColors.Add(mesh2.VertexColors[edge4]); mesh2.Append(mesh3); ////////////////////////////////////////////////////// for (double i = 1; i <= Column; i++) { for (double j = 1; j <= firstLoop1.Count; j++) { mesh.TextureCoordinates.Add(i / (Column + 1), j / (firstLoop1.Count + 1)); } } data = new IndexPair((Column + 1) * edge, (firstLoop1.Count + 1) * edge); return str; }
/// <summary> /// Removes duplicate/invalid/tiny curves and outputs the cleaned list, a list of unique nodes and a list of node pairs. /// </summary> public static List<Curve> CleanNetwork(List<Curve> inputStruts, double tol, out Point3dList nodes, out List<IndexPair> nodePairs) { nodes = new Point3dList(); nodePairs = new List<IndexPair>(); var struts = new List<Curve>(); // Loop over list of struts for (int i = 0; i < inputStruts.Count; i++) { Curve strut = inputStruts[i]; // Unitize domain strut.Domain = new Interval(0, 1); // Minimum strut length (if user defined very small tolerance, use 100*rhinotolerance) double minLength = Math.Max(tol, 100*RhinoDoc.ActiveDoc.ModelAbsoluteTolerance); // If strut is invalid, ignore it if (strut == null || !strut.IsValid || strut.IsShort(minLength)) { continue; } Point3d[] pts = new Point3d[2] { strut.PointAtStart, strut.PointAtEnd }; List<int> nodeIndices = new List<int>(); // Loop over end points of strut // Check if node is already in nodes list, if so, we find its index instead of creating a new node for (int j = 0; j < 2; j++) { Point3d pt = pts[j]; // Find closest node to current pt int closestIndex = nodes.ClosestIndex(pt); // If node already exists (within tolerance), set the index if (nodes.Count != 0 && pt.EpsilonEquals(nodes[closestIndex], tol)) { nodeIndices.Add(closestIndex); } // If node doesn't exist else { // Update lookup list nodes.Add(pt); nodeIndices.Add(nodes.Count - 1); } } // We must ignore duplicate struts bool isDuplicate = false; IndexPair nodePair = new IndexPair(nodeIndices[0], nodeIndices[1]); int dupIndex = nodePairs.IndexOf(nodePair); // dupIndex equals -1 if nodePair not found, i.e. if it doesn't equal -1, a match was found if (nodePairs.Count != 0 && dupIndex != -1) { // Check the curve midpoint to make sure it's a duplicate Curve testStrut = struts[dupIndex]; Point3d ptA = strut.PointAt(0.5); Point3d ptB = testStrut.PointAt(0.5); if (ptA.EpsilonEquals(ptB, tol)) isDuplicate = true; } // So we only create the strut if it doesn't exist yet (check nodePairLookup list) if (!isDuplicate) { // Update the lookup list nodePairs.Add(nodePair); strut.Domain = new Interval(0, 1); struts.Add(strut); } } return struts; }
private static int CompareDinosByLength(IndexPair x, IndexPair y) { if (x.J > y.J) return 1; if (x.J == y.J) return 0; if (x.J < y.J) return -1; else return 0; }
/// <summary> /// Instance constuctor based on the underlying curve and hull pair for this sleeve. /// </summary> public ExoSleeve(Curve curve, IndexPair hullPair) { m_curve = curve; m_hullPair = hullPair; m_platePair = new IndexPair(); m_startRadius = 0.0; m_endRadius = 0.0; }
/// <summary> /// Default constructor. /// </summary> public ExoSleeve() { m_curve = null; m_hullPair = new IndexPair(); m_platePair = new IndexPair(); m_startRadius = 0.0; m_endRadius = 0.0; }
public static DataTree <Polyline> ReciprocalFrame(this Mesh mesh, double angle = 10, double dist = 0.25, double width = 0.1) { DataTree <Polyline> polylines = new DataTree <Polyline>(); try { var display = new List <Line>(); double thickness = width; int[][] tv = mesh.GetNGonsTopoBoundaries(); HashSet <int> tvAll = mesh.GetAllNGonsTopoVertices(); HashSet <int> e = mesh.GetAllNGonEdges(tv); Line[] lines = mesh.GetAllNGonEdgesLines(e); Line[] lines1 = mesh.GetAllNGonEdgesLines(e); bool[] nakedV = mesh.GetNakedEdgePointStatus(); int[][] fe = mesh.GetNGonFacesEdges(tv); Plane[] planes = new Plane[lines.Length]; Vector3d[] vecs = new Vector3d[mesh.TopologyEdges.Count]; int j = 0; foreach (int i in e) { Line l = mesh.TopologyEdges.EdgeLine(i); Rhino.IndexPair ip = mesh.TopologyEdges.GetTopologyVertices(i); int v0 = mesh.TopologyVertices.MeshVertexIndices(ip.I)[0]; int v1 = mesh.TopologyVertices.MeshVertexIndices(ip.J)[0]; Vector3d vec = new Vector3d( (mesh.Normals[v0].X + mesh.Normals[v1].X) * 0.5, (mesh.Normals[v0].Y + mesh.Normals[v1].Y) * 0.5, (mesh.Normals[v0].Z + mesh.Normals[v1].Z) * 0.5 ); vec.Unitize(); vecs[j] = vec; if (mesh.TopologyEdges.GetConnectedFaces(i).Length == 2) { l.Transform(Transform.Rotation(Rhino.RhinoMath.ToRadians(angle), vec, l.PointAt(0.5))); } Vector3d cross = Vector3d.CrossProduct(l.Direction, vec); planes[j] = new Plane(l.PointAt(0.5), cross); cross.Unitize(); l.Transform(Transform.Translation(cross * thickness)); lines[j] = l; l.Transform(Transform.Translation(-cross * 2 * thickness)); lines1[j++] = l; } //ngon vertex edges int[][] connectedE = mesh.GetConnectedNGonEdgesToNGonTopologyVertices(tvAll, e); int[] allEArray = e.ToArray(); int[] allvArray = tvAll.ToArray(); Line[] linesCopy = new Line[lines.Length]; Line[] linesCopy1 = new Line[lines.Length]; Line[] linesCopyM = new Line[lines.Length]; Line[] linesCopyM1 = new Line[lines.Length]; // Line[] linesCopyMoved = new Line[lines.Length]; for (int i = 0; i < lines.Length; i++) { linesCopy[i] = new Line(lines[i].From, lines[i].To); linesCopy1[i] = new Line(lines1[i].From, lines1[i].To); linesCopyM[i] = new Line(lines[i].From + vecs[i] * dist, lines[i].To + vecs[i] * dist); linesCopyM1[i] = new Line(lines1[i].From + vecs[i] * dist, lines1[i].To + vecs[i] * dist); } for (int i = 0; i < connectedE.Length; i++) { //Defines planes int total = connectedE[i].Length; Plane[] projectionPlanes = new Plane[total]; int start = total - 1; for (j = start; j < start + total; j++) { int currentEdge = connectedE[i][j % total]; int localID = Array.IndexOf(allEArray, currentEdge); projectionPlanes[j - start] = planes[localID]; } //Intersect lines for (j = 0; j < connectedE[i].Length; j++) { int currentEdge = connectedE[i][j]; if (mesh.TopologyEdges.GetConnectedFaces(currentEdge).Length == 1) { continue; } int localID = Array.IndexOf(allEArray, currentEdge); Line currentLine = linesCopy[localID]; Line currentLine1 = linesCopy1[localID]; Line currentLineM = linesCopyM[localID]; Line currentLineM1 = linesCopyM1[localID]; IndexPair pair = mesh.TopologyEdges.GetTopologyVertices(currentEdge); double lineT, lineT1; Plane currentPlane = new Plane(projectionPlanes[j]); double flag = 1; //Check length Plane tempPlane = new Plane(currentPlane); Line temp2 = new Line(currentLine.From, currentLine.To); tempPlane.Origin += tempPlane.ZAxis * (thickness); Line temp = new Line(currentLine.From, currentLine.To); double tt; Rhino.Geometry.Intersect.Intersection.LinePlane(temp2, tempPlane, out tt); if (allvArray[i] == pair.I) { temp.From = temp2.PointAt(tt); } else { temp.To = temp2.PointAt(tt); } double lineLen0 = temp.Length; tempPlane = new Plane(currentPlane); temp2 = new Line(currentLine.From, currentLine.To); tempPlane.Origin += tempPlane.ZAxis * (-thickness); temp = new Line(currentLine.From, currentLine.To); Rhino.Geometry.Intersect.Intersection.LinePlane(temp2, tempPlane, out tt); if (allvArray[i] == pair.I) { temp.From = temp2.PointAt(tt); } else { temp.To = temp2.PointAt(tt); } double lineLen1 = temp.Length; //End Check Length if (lineLen1 < lineLen0) { flag = -1; } currentPlane.Origin += currentPlane.ZAxis * (flag * thickness); Rhino.Geometry.Intersect.Intersection.LinePlane(currentLine, currentPlane, out lineT); Rhino.Geometry.Intersect.Intersection.LinePlane(currentLine1, currentPlane, out lineT1); Rhino.Geometry.Intersect.Intersection.LinePlane(currentLineM, currentPlane, out lineT); Rhino.Geometry.Intersect.Intersection.LinePlane(currentLineM1, currentPlane, out lineT1); if (allvArray[i] == pair.I) { currentLine.From = currentLine.PointAt(lineT); currentLine1.From = currentLine1.PointAt(lineT1); currentLineM.From = currentLineM.PointAt(lineT); currentLineM1.From = currentLineM1.PointAt(lineT1); } else { currentLine.To = currentLine.PointAt(lineT); currentLine1.To = currentLine1.PointAt(lineT1); currentLineM.To = currentLineM.PointAt(lineT); currentLineM1.To = currentLineM1.PointAt(lineT1); } linesCopy[localID] = currentLine; linesCopy1[localID] = currentLine1; linesCopyM[localID] = currentLineM; linesCopyM1[localID] = currentLineM1; } } for (int i = 0; i < linesCopy.Length; i++) { if (mesh.TopologyEdges.GetConnectedFaces(allEArray[i]).Length == 1) { continue; } polylines.AddRange(new Polyline[] { new Polyline(new Point3d[] { linesCopy[i].From, linesCopy[i].To, linesCopy1[i].To, linesCopy1[i].From, linesCopy[i].From }), new Polyline(new Point3d[] { linesCopyM[i].From, linesCopyM[i].To, linesCopyM1[i].To, linesCopyM1[i].From, linesCopyM[i].From }) }, new GH_Path(i)); } //A = linesCopy; //B = linesCopy1; //C = linesCopyM; //D = linesCopyM1; //E = polylines; } catch (Exception e) { Rhino.RhinoApp.WriteLine(e.ToString()); } return(polylines); }
protected override void SolveInstance(IGH_DataAccess DA) { Mesh m = DA.Fetch <Mesh>("Mesh"); bool fixEdges = DA.Fetch <bool>("FixEdges"); double l = DA.Fetch <double>("EdgeLength"); int iterations = DA.Fetch <int>("Iterations"); List <Point3d> fixPt = DA.FetchList <Point3d>("FixPt"); bool project = DA.Fetch <bool>("Project"); bool loops = DA.Fetch <bool>("Loops"); Mesh mesh = m.DuplicateMesh(); mesh.Faces.ConvertQuadsToTriangles(); double len = (l == 0) ? mesh.GetBoundingBox(false).Diagonal.Length * 0.1 : l; //r.PreventNormalFlips = true; List <int> ids = new List <int>(); Point3d[] pts = mesh.Vertices.ToPoint3dArray(); foreach (Point3d p in fixPt) { ids.Add(NGonsCore.PointUtil.ClosestPoint(p, pts)); } DMesh3 dmesh = mesh.ToDMesh3(); Remesher r = new Remesher(dmesh); r.Precompute(); r.SetTargetEdgeLength(len); r.SmoothSpeedT = 0.5; if (project) { r.SetProjectionTarget(MeshProjectionTarget.Auto(dmesh)); } r.EnableFlips = r.EnableSplits = r.EnableCollapses = true; r.EnableSmoothing = true; MeshConstraints cons = new MeshConstraints(); if (ids.Count > 0) { foreach (int id in ids) { //cons.SetOrUpdateVertexConstraint(id, new VertexConstraint(true, 1)); cons.SetOrUpdateVertexConstraint(id, VertexConstraint.Pinned); } } r.SetExternalConstraints(cons); r.Precompute(); if (fixEdges) { //r.SetExternalConstraints(new MeshConstraints()); MeshConstraintUtil.FixAllBoundaryEdges(r); MeshConstraintUtil.FixAllBoundaryEdges_AllowSplit(cons, dmesh, 0); //MeshConstraintUtil.FixAllBoundaryEdges_AllowCollapse(cons, dmesh, 0); } if (loops) { MeshConstraintUtil.PreserveBoundaryLoops(r); //project to edge //MeshConstraintUtil.PreserveBoundaryLoops(cons,dmesh);//project to edge } r.SetExternalConstraints(cons); for (int k = 0; k < iterations; ++k) { r.BasicRemeshPass(); } //output if (ids.Count > 0 && !fixEdges) { this.Message = "Vertices"; } else if (ids.Count == 0 && fixEdges) { this.Message = "Edges"; } else if (ids.Count > 0 && fixEdges) { this.Message = "Vertices + Edges"; } else { this.Message = ""; } dmesh = new DMesh3(dmesh, true); Mesh rmesh = dmesh.ToRhinoMesh(); if (loops) { Mesh mesh_ = rmesh.DuplicateMesh(); Rhino.IndexPair[] closestEdges = new Rhino.IndexPair[fixPt.Count]; int counter = 0; foreach (Point3d p in fixPt) { double[] d = new double[rmesh.TopologyEdges.Count]; int[] eid = new int[rmesh.TopologyEdges.Count]; for (int i = 0; i < rmesh.TopologyEdges.Count; i++) { if (rmesh.TopologyEdges.GetConnectedFaces(i).Length == 1) { Line line = rmesh.TopologyEdges.EdgeLine(i); line.ClosestPoint(p, true); d[i] = line.ClosestPoint(p, true).DistanceToSquared(p); //line.From.DistanceToSquared(p) + line.To.DistanceToSquared(p); } else { d[i] = 99999; } eid[i] = i; } Array.Sort(d, eid); closestEdges[counter++] = rmesh.TopologyEdges.GetTopologyVertices(eid[0]); } for (int i = 0; i < fixPt.Count; i++) { mesh_.Vertices.Add(fixPt[i]); mesh_.Faces.AddFace(rmesh.Vertices.Count + i, closestEdges[i].I, closestEdges[i].J); } rmesh = mesh_; } rmesh.UnifyNormals(); rmesh.RebuildNormals(); // rmesh.UnifyNormals(); DA.SetData(0, rmesh); }