public List <Line> MeshProfile(Mesh mesh) { Rhino.Geometry.Collections.MeshTopologyEdgeList el = mesh.TopologyEdges; List <MeshSimplify_Point> PointList = preDivide(mesh); List <Line> output = new List <Line>(); for (int i = 0; i < el.Count; i++) { int a = el.GetTopologyVertices(i).I; int b = el.GetTopologyVertices(i).J; if (PointList[a].order > 0 && PointList[b].order > 0) { output.Add(el.EdgeLine(i)); } } /* List<Point3d> output1 = new List<Point3d>(); * List<string> output2 = new List<string>(); * for(int i = 0;i < PointList.Count;i++){ * output1.Add(PointList[i].pos); * string str = PointList[i].order.ToString(); * if(PointList[i].order == 0)str = ""; * output2.Add(str); * }*/ return(output); }
public List <Rhino.Display.Text3d> foldsign(List <Mesh> x, List <Mesh> y) { List <Rhino.Display.Text3d> t3d1 = new List <Rhino.Display.Text3d>(); List <Point3d> pt = new List <Point3d>(); List <double> rad = new List <double>(); for (int i = 0; i < x.Count; i++) { Mesh mesh2 = y[i]; mc.MeshClean(ref mesh2, 0.01); x[i].UnifyNormals(); Rhino.Geometry.Collections.MeshTopologyEdgeList el = mesh2.TopologyEdges; x[i].FaceNormals.ComputeFaceNormals(); for (int k = 0; k < el.Count; k++) { if (el.GetConnectedFaces(k).Length != 2) { } else { MeshFace f1 = x[i].Faces[el.GetConnectedFaces(k)[0]]; MeshFace f2 = x[i].Faces[el.GetConnectedFaces(k)[1]]; pt.Add(el.EdgeLine(k).PointAt(0.5)); double t = mu.FoldAngle( x[i].Vertices[f1.A], x[i].Vertices[f1.B], x[i].Vertices[f1.C], x[i].Vertices[f2.A], x[i].Vertices[f2.B], x[i].Vertices[f2.C] ); t *= 180 / Math.PI; rad.Add(t); } } } for (int i = 0; i < pt.Count; i++) { double t1 = rad[i]; t1 = Math.Round(t1); int t2 = (int)t1; if (t2 < -180) { t2 = 0; } if (t2 > 180) { t2 = 0; } t2 *= -1; t3d1.Add(new Rhino.Display.Text3d(t2.ToString(), new Plane(pt[i], Vector3d.ZAxis), 1)); } return(t3d1); }
/// <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) { Mesh M = new Mesh(); if (!DA.GetData(0, ref M)) { return; } if (!M.IsValid || M == null) { return; } double A = 45.0; DA.GetData(1, ref A); double num = A / 57.2958; ConcurrentBag <Line> list = new ConcurrentBag <Line>(); ConcurrentBag <Line> list2 = new ConcurrentBag <Line>(); M.Normals.ComputeNormals(); Rhino.Geometry.Collections.MeshTopologyEdgeList topologyEdges = M.TopologyEdges; int num2 = topologyEdges.Count - 1; Parallel.For(0, topologyEdges.Count, i => //for (int i = 0; i <= num2; i++) { int[] connectedFaces = topologyEdges.GetConnectedFaces(i); if (connectedFaces.Length < 2) { list2.Add(topologyEdges.EdgeLine(i)); } if (connectedFaces.Length == 2) { Vector3f val2 = M.FaceNormals[connectedFaces[0]]; Vector3f val3 = M.FaceNormals[connectedFaces[1]]; double num3 = Vector3d.VectorAngle(new Vector3d((double)val2.X, (double)val2.Y, (double)val2.Z), new Vector3d((double)val3.X, (double)val3.Y, (double)val3.Z)); if (num3 > num) { list.Add(topologyEdges.EdgeLine(i)); } } }); DA.SetDataList(0, list); DA.SetDataList(1, list2); }
public List <Mesh> MeshSeperate(Mesh mesh) { Rhino.Geometry.Collections.MeshTopologyEdgeList el = mesh.TopologyEdges; List <MeshSimplify_Point> PointList = preDivide(mesh); List <MeshSimplify_Face> faces = new List <MeshSimplify_Face>(); for (int i = 0; i < mesh.Faces.Count; i++) { faces.Add(new MeshSimplify_Face(mesh.Faces[i])); } for (int i = 0; i < el.Count; i++) { int a = el.GetTopologyVertices(i).I; int b = el.GetTopologyVertices(i).J; if (PointList[a].order == 0 || PointList[b].order == 0) { int[] index = el.GetConnectedFaces(i); if (index.Length == 2) { faces[index[0]].reffaces.Add(faces[index[1]]); faces[index[1]].reffaces.Add(faces[index[0]]); } } } List <Mesh> outputMesh = new List <Mesh>(); List <List <MeshSimplify_Face> > outtemp = MeshSimplify_Face.Group(faces); for (int i = 0; i < outtemp.Count; i++) { Mesh meshout = new Mesh(); meshout.Vertices.AddVertices(mesh.Vertices); for (int j = 0; j < outtemp[i].Count; j++) { meshout.Faces.AddFace(outtemp[i][j].face); } meshout.Compact(); outputMesh.Add(meshout); } return(outputMesh); /* * List<Point3d> outpos = new List<Point3d>(); * List<string> outsign = new List<string>(); * for(int i = 0;i < faces.Count;i++){ * outpos.Add(faces[i].pos(mesh.Vertices)); * string str = i.ToString() + "/" + faces[i].reffaces.Count.ToString(); * outsign.Add(str); * } * B = outpos;C = outsign; */ }
public Gauss(Mesh input_mesh) { mesh = input_mesh; mesh.Compact(); mesh.UnifyNormals(); el = mesh.TopologyEdges; vs = mesh.TopologyVertices; ps = new List<VertexProperties>(); for (int i = 0; i < vs.Count; i++) { ps.Add(new VertexProperties (mesh.Normals[vs.MeshVertexIndices(i)[0]])); // outputs2.Add(new Vector3d()); } }
public List <Line> createProfile(Mesh x, double y) { mc.MeshClean(ref x, 0.01); Rhino.Geometry.Collections.MeshTopologyEdgeList el = x.TopologyEdges; List <Line> ls = new List <Line>(); for (int i = 0; i < el.Count; i++) { if (el.GetConnectedFaces(i).Length != 2) { ls.Add(el.EdgeLine(i)); } else { Line l = el.EdgeLine(i); Vector3d v = l.From - l.To; v.Unitize(); v *= (double)y; Point3d p1 = l.From - v; Point3d p2 = l.To + v; ls.Add(new Line(p1, p2)); } } return(ls); }
protected override Result RunCommand(RhinoDoc doc, RunMode mode) { Rhino.DocObjects.ObjRef objref; Result rc = Rhino.Input.RhinoGet.GetOneObject("Select mesh", false, ObjectType.Mesh, out objref); if (rc != Result.Success) { return(rc); } if (null == objref) { return(Result.Failure); } Rhino.Geometry.Mesh mesh = objref.Mesh(); if (null == mesh) { return(Result.Failure); } Rhino.Geometry.Collections.MeshTopologyEdgeList mesh_tope = mesh.TopologyEdges; for (int i = 0; i < mesh_tope.Count; i++) { // Find naked edges - edges with a single connecting face int[] mesh_topf = mesh_tope.GetConnectedFaces(i); if (null != mesh_topf && mesh_topf.Length == 1) { Guid id = doc.Objects.AddLine(mesh_tope.EdgeLine(i)); doc.Objects.Select(id); } } doc.Views.Redraw(); return(Result.Success); }
public string Mesh2Mesh(Mesh mesh, out Mesh s, double uscale, double vscale) { 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++) { //Print("j:" + j.ToString() + " k:" + k.ToString() + " energy: " + energy[index[k]].ToString());//////// energy[index[k]]++; } } //Print("///"); for (int j = 0; j < firstLoop1.Count; j++) { int[] index = vs.ConnectedTopologyVertices(firstLoop1[j]); for (int k = 0; k < index.Length; k++) { // Print("j:" + j.ToString() + " k:" + k.ToString() + " energy: " + energy[index[k]].ToString());//////// 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); } } List <Point3d> output1 = new List <Point3d>(); for (int i = 0; i < indexPt.Count; i++) { output1.Add(vs[indexPt[i]]); } // s = NurbsSurface.CreateFromPoints(output1, Column, firstLoop1.Count, 3, 3); s = mc.MeshFromPoints(output1, firstLoop1.Count, Column, uscale, vscale); return(str); }
public string Mesh2Topo(ref Mesh mesh, out Mesh mesh2, double length, double width, double mX, double mY, double maxX, double maxY) { // //construct a single bitmap but the edge is not fit well.The Vt has not been tested yet. // 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]; for (int i = 0; i < Column; i++) { for (int j = 0; j < firstLoop1.Count; j++) { output1.Add(vs[indexPt[iCount]]); int indexV = vs.MeshVertexIndices(indexPt[iCount])[0]; cl[iCount] = mesh.VertexColors[indexV]; iCount++; Point3d pt = new Point3d(length / MX * i, width / MY * (double)j, 0); output2.Add(pt); } } mesh2 = mc.MeshFromPoints(output2, firstLoop1.Count, Column); mesh = mc.MeshFromPoints(output1, firstLoop1.Count, Column); mesh2.Transform(Transform.Translation(mX, mY, 0)); mesh.VertexColors.Clear(); mesh.VertexColors.AppendColors(cl); mesh2.VertexColors.Clear(); mesh2.VertexColors.AppendColors(cl); iCount = 0; //Print(mesh.TextureCoordinates.Count.ToString());//unit=100 for (double i = 0; i < Column; i++) { for (double j = 0; j < firstLoop1.Count; j++) { //not tested mesh.TextureCoordinates.Add(new Point2f((Single)((i * length / MX + mX) / maxX), (Single)(j * width / MY + mY) / maxY)); mesh2.TextureCoordinates.Add(new Point2f((Single)((i * length / MX + mX) / maxX), (Single)(j * width / MY + mY) / maxY)); iCount++; } } return(str); }
/// 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); }
public Mesh Unfold(Mesh mesh) { List <face> Faces = new List <face>(); List <edge> Edges = new List <edge>(); mesh.Faces.ConvertQuadsToTriangles(); mesh.UnifyNormals(); mesh.Compact(); Rhino.Geometry.Collections.MeshTopologyEdgeList el = mesh.TopologyEdges; Rhino.Geometry.Collections.MeshTopologyVertexList vs = mesh.TopologyVertices; mesh.FaceNormals.ComputeFaceNormals(); //Print(mesh.FaceNormals.Count.ToString()); // Print(mesh.Vertices.Count.ToString()); for (int i = 0; i < mesh.Faces.Count; i++) { face f1 = new face( new Point3d(mesh.Vertices[mesh.Faces[i].A]), new Point3d(mesh.Vertices[mesh.Faces[i].B]), new Point3d(mesh.Vertices[mesh.Faces[i].C]), mesh.FaceNormals[i] ); Faces.Add(f1); } for (int i = 0; i < el.Count; i++) { int[] faceid = el.GetConnectedFaces(i); edge e1 = new edge(vs[el.GetTopologyVertices(i).I], vs[el.GetTopologyVertices(i).J]); if (faceid.Length == 1) { e1.Faces = new face[1]; e1.Faces[0] = Faces[faceid[0]]; } else if (faceid.Length > 1) { e1.Faces = new face[2]; e1.Faces[0] = Faces[faceid[0]]; e1.Faces[1] = Faces[faceid[1]]; } e1.ID = i; Edges.Add(e1); } for (int i = 0; i < mesh.Faces.Count; i++) { int[] edgeid = el.GetEdgesForFace(i); face f1 = Faces[i]; f1.edges[0] = Edges[edgeid[0]]; f1.edges[1] = Edges[edgeid[1]]; f1.edges[2] = Edges[edgeid[2]]; f1.ID = i; } /* List< Mesh> output2 = new List< Mesh>(); * for (int i = 0; i < Faces.Count; i++) * { * output2.Add(Faces[i].DrawFace()); * } * B = output2; */ face f = Faces[0]; f.AddTransform(Transform.PlaneToPlane(new Plane(f.Center(), -f.Normal), Plane.WorldXY)); FaceLoop(f); //Print(f.Pts[0].X.ToString() + "/" + f.Pts[0].Y.ToString() + "/" + f.Pts[0].Z.ToString()); Mesh output = new Mesh(); for (int i = 0; i < Faces.Count; i++) { output.Append(Faces[i].DrawFace()); } return(output); }
public void DrawViewportWires(GH_PreviewWireArgs args) { if (Value == null) { return; } //Draw lines if (Value.SolidMesh != null) { // Draw edges Rhino.Geometry.Collections.MeshTopologyEdgeList edges = Value.SolidMesh.TopologyEdges; if (Value.SolidMesh.FaceNormals.Count < Value.SolidMesh.Faces.Count) { Value.SolidMesh.FaceNormals.ComputeFaceNormals(); } if (Value.Member.IsDummy) { for (int i = 0; i < edges.Count; i++) { int[] faceID = edges.GetConnectedFaces(i); Vector3d vec1 = Value.SolidMesh.FaceNormals[faceID[0]]; Vector3d vec2 = Value.SolidMesh.FaceNormals[faceID[1]]; vec1.Unitize(); vec2.Unitize(); if (!vec1.Equals(vec2) || faceID.Length > 2) { if (args.Color == System.Drawing.Color.FromArgb(255, 150, 0, 0)) // this is a workaround to change colour between selected and not { Polyline hidden = new Polyline(); hidden.Add(edges.EdgeLine(i).PointAt(0)); hidden.Add(edges.EdgeLine(i).PointAt(1)); args.Pipeline.DrawDottedPolyline(hidden, UI.Colour.Dummy1D, false); } else { Polyline hidden = new Polyline(); hidden.Add(edges.EdgeLine(i).PointAt(0)); hidden.Add(edges.EdgeLine(i).PointAt(1)); args.Pipeline.DrawDottedPolyline(hidden, UI.Colour.Member2dEdgeSelected, false); } } else { } } } else { for (int i = 0; i < edges.Count; i++) { int[] faceID = edges.GetConnectedFaces(i); Vector3d vec1 = Value.SolidMesh.FaceNormals[faceID[0]]; Vector3d vec2 = Value.SolidMesh.FaceNormals[faceID[1]]; vec1.Unitize(); vec2.Unitize(); if (!vec1.Equals(vec2) || faceID.Length > 2) { if (args.Color == System.Drawing.Color.FromArgb(255, 150, 0, 0)) // this is a workaround to change colour between selected and not { if ((System.Drawing.Color)Value.Colour != System.Drawing.Color.FromArgb(0, 0, 0)) { args.Pipeline.DrawLine(edges.EdgeLine(i), (System.Drawing.Color)Value.Member.Colour, 2); } else { System.Drawing.Color col = UI.Colour.Member2dEdge; args.Pipeline.DrawLine(edges.EdgeLine(i), col, 2); } } else { args.Pipeline.DrawLine(edges.EdgeLine(i), UI.Colour.Element2dEdgeSelected, 2); } } else { Polyline hidden = new Polyline(); hidden.Add(edges.EdgeLine(i).PointAt(0)); hidden.Add(edges.EdgeLine(i).PointAt(1)); args.Pipeline.DrawDottedPolyline(hidden, UI.Colour.Dummy1D, false); } } } // draw points List <Point3d> pts = new List <Point3d>(Value.SolidMesh.Vertices.ToPoint3dArray()); for (int i = 0; i < pts.Count; i++) { if (args.Color == System.Drawing.Color.FromArgb(255, 150, 0, 0)) // this is a workaround to change colour between selected and not { args.Pipeline.DrawPoint(pts[i], Rhino.Display.PointStyle.RoundSimple, 2, (Value.Member.IsDummy) ? UI.Colour.Dummy1D : UI.Colour.Member1dNode); } else { args.Pipeline.DrawPoint(pts[i], Rhino.Display.PointStyle.RoundControlPoint, 3, UI.Colour.Member1dNodeSelected); } } } }
public Mesh Catmull_Clark(Mesh x) { Mesh mesh = new Mesh(); List <Point3d> pv = new List <Point3d>(); List <Point3d> pe = new List <Point3d>(); List <Point3d> pf = new List <Point3d>(); Rhino.Geometry.Collections.MeshTopologyVertexList vs = x.TopologyVertices; Rhino.Geometry.Collections.MeshTopologyEdgeList el = x.TopologyEdges; for (int i = 0; i < x.Faces.Count; i++) { int[] index = vs.IndicesFromFace(i); Point3d pf1 = new Point3d(); for (int j = 0; j < index.Length; j++) { pf1 += vs[index[j]]; } pf1 /= index.Length; pf.Add(pf1); } for (int i = 0; i < el.Count; i++) { IndexPair pair = el.GetTopologyVertices(i); Point3d pe1 = vs[pair.I] + vs[pair.J]; int[] index = el.GetConnectedFaces(i); if (index.Length == 2) { pe1 += pf[index[0]] + pf[index[1]]; pe1 /= 4.0; } else { pe1 = pe1 / 2.0; } pe.Add(pe1); } for (int i = 0; i < vs.Count; i++) { int[] index = vs.ConnectedEdges(i); int[] index2 = vs.ConnectedFaces(i); Point3d V = vs[i]; if (index.Length == index2.Length) { Point3d R = new Point3d(), Q = new Point3d(); for (int j = 0; j < index.Length; j++) { IndexPair pair = el.GetTopologyVertices(index[j]); Point3d pe1 = (vs[pair.I] + vs[pair.J]) * 0.5f; R += pe1; } R /= index.Length; for (int j = 0; j < index2.Length; j++) { Q += pf[index2[j]]; } Q /= index2.Length; int n = vs.ConnectedTopologyVertices(i).Length; V = Q + (R * 2) + V * (n - 3); V /= n; } else { Point3d R = new Point3d(); for (int j = 0; j < index.Length; j++) { if (el.GetConnectedFaces(index[j]).Length == 1) { IndexPair pair = el.GetTopologyVertices(index[j]); R += vs[pair.I] + vs[pair.J]; } } V = R * 0.125f + V * 0.5; } pv.Add(V); } mesh.Vertices.AddVertices(pv); mesh.Vertices.AddVertices(pe); mesh.Vertices.AddVertices(pf); for (int i = 0; i < x.Faces.Count; i++) { int[] index = vs.IndicesFromFace(i); if (x.Faces[i].IsQuad) { int pc = pv.Count + pe.Count + i; int p1 = index[0]; int p2 = index[1]; int p3 = index[2]; int p4 = index[3]; int p12 = el.GetEdgeIndex(p1, p2) + pv.Count; int p23 = el.GetEdgeIndex(p2, p3) + pv.Count; int p34 = el.GetEdgeIndex(p3, p4) + pv.Count; int p41 = el.GetEdgeIndex(p4, p1) + pv.Count; mesh.Faces.AddFace(p1, p12, pc, p41); mesh.Faces.AddFace(p12, p2, p23, pc); mesh.Faces.AddFace(pc, p23, p3, p34); mesh.Faces.AddFace(p41, pc, p34, p4); } else if (x.Faces[i].IsTriangle) { int pc = pv.Count + pe.Count + i; int p1 = index[0]; int p2 = index[1]; int p3 = index[2]; int p12 = el.GetEdgeIndex(p1, p2) + pv.Count; int p23 = el.GetEdgeIndex(p2, p3) + pv.Count; int p31 = el.GetEdgeIndex(p3, p1) + pv.Count; mesh.Faces.AddFace(p1, p12, pc, p31); mesh.Faces.AddFace(p12, p2, p23, pc); mesh.Faces.AddFace(pc, p23, p3, p31); } } mesh.UnifyNormals(); return(mesh); }
public Mesh Loop(Mesh x) { Mesh mesh = new Mesh(); x.Faces.ConvertQuadsToTriangles(); List <Point3d> pv = new List <Point3d>(); List <Point3d> pe = new List <Point3d>(); Rhino.Geometry.Collections.MeshTopologyVertexList vs = x.TopologyVertices; Rhino.Geometry.Collections.MeshTopologyEdgeList el = x.TopologyEdges; for (int i = 0; i < el.Count; i++) { IndexPair pair = el.GetTopologyVertices(i); Point3d pe1 = (vs[pair.I] + vs[pair.J]); int[] index = el.GetConnectedFaces(i); if (index.Length == 2) { int[] index1 = vs.IndicesFromFace(index[0]); int[] index2 = vs.IndicesFromFace(index[1]); pe1 += vs[index1[0]] + vs[index1[1]] + vs[index1[2]]; pe1 += vs[index2[0]] + vs[index2[1]] + vs[index2[2]]; pe1 /= 8.0; } else { pe1 = pe1 / 2.0; } pe.Add(pe1); } for (int i = 0; i < vs.Count; i++) { int[] index = vs.ConnectedEdges(i); int[] index2 = vs.ConnectedFaces(i); Point3d V = vs[i]; if (index.Length == index2.Length) { Point3d R = new Point3d(); double n = (double)index.Length; double u = Math.Pow(0.375 + 0.25 * Math.Cos(Math.PI * 2.0 / n), 2); u = (0.625 - u) / n; for (int j = 0; j < index.Length; j++) { IndexPair pair = el.GetTopologyVertices(index[j]); R += (vs[pair.I] + vs[pair.J] - V); } V = V * (1 - n * u) + R * u; } else { Point3d R = new Point3d(); for (int j = 0; j < index.Length; j++) { if (el.GetConnectedFaces(index[j]).Length == 1) { IndexPair pair = el.GetTopologyVertices(index[j]); R += vs[pair.I] + vs[pair.J]; } } V = R * 0.125f + V * 0.5; } pv.Add(V); } mesh.Vertices.AddVertices(pv); mesh.Vertices.AddVertices(pe); for (int i = 0; i < x.Faces.Count; i++) { int[] index = vs.IndicesFromFace(i); int p1 = index[0]; int p2 = index[1]; int p3 = index[2]; int p12 = el.GetEdgeIndex(p1, p2) + pv.Count; int p23 = el.GetEdgeIndex(p2, p3) + pv.Count; int p31 = el.GetEdgeIndex(p3, p1) + pv.Count; mesh.Faces.AddFace(p1, p12, p31); mesh.Faces.AddFace(p31, p12, p23); mesh.Faces.AddFace(p3, p31, p23); mesh.Faces.AddFace(p2, p23, p12); } mesh.UnifyNormals(); return(mesh); }
public List <Mesh> MeshBay(Mesh mesh, int step) { List <Rface> faces = new List <Rface>(); for (int i = 0; i < mesh.Faces.Count; i++) { faces.Add(new Rface()); } Rhino.Geometry.Collections.MeshTopologyEdgeList el = mesh.TopologyEdges; for (int i = 0; i < el.Count; i++) { int[] index = el.GetConnectedFaces(i); if (index.Length == 1) { faces[index[0]].age = 1; } if (index.Length == 2) { faces[index[1]]._CollectedFaceIndex.Add(index[0]); faces[index[0]]._CollectedFaceIndex.Add(index[1]); } } for (int k = 1; k < step + 1; k++) { for (int i = 0; i < faces.Count; i++) { if (faces[i].age == k) { for (int j = 0; j < faces[i]._CollectedFaceIndex.Count; j++) { int index2 = faces[i]._CollectedFaceIndex[j]; if (faces[index2].age == 0) { faces[index2].age = k + 1; } } } } } Mesh mesh1 = new Mesh(); Mesh mesh2 = new Mesh(); mesh1.Vertices.AddVertices(mesh.Vertices); mesh2.Vertices.AddVertices(mesh.Vertices); for (int i = 0; i < faces.Count; i++) { if (faces[i].age != 0) { mesh2.Faces.AddFace(mesh.Faces[i]); } else { mesh1.Faces.AddFace(mesh.Faces[i]); } } mesh1.Compact(); mesh1.UnifyNormals(); mesh2.Compact(); mesh2.UnifyNormals(); List <Mesh> output = new List <Mesh>(); output.Add(mesh1); output.Add(mesh2); return(output); }
public string FirstEdge(Mesh mesh, out List <int> firstLoop1) { Rhino.Geometry.Collections.MeshTopologyEdgeList el = mesh.TopologyEdges; Rhino.Geometry.Collections.MeshTopologyVertexList vs = mesh.TopologyVertices; firstLoop1 = new List <int>(); int firstPoint = -1; for (int i = 0; i < vs.Count; i++) { if (vs.ConnectedTopologyVertices(i).Length == 2) { firstPoint = i; break; } } if (firstPoint == -1) { return("can not find a 2 degree Vertex,Please check the mesh boundary"); } int SecondPoint = vs.ConnectedTopologyVertices(firstPoint)[0]; int ThirdPoint = vs.ConnectedTopologyVertices(firstPoint)[1]; int firstPoint1 = firstPoint; firstLoop1.Add(firstPoint); if (vs.ConnectedTopologyVertices(ThirdPoint).Length == 2) { firstLoop1.Add(ThirdPoint); } else if (vs.ConnectedTopologyVertices(SecondPoint).Length == 2) { firstLoop1.Add(SecondPoint); } else { firstLoop1.Add(SecondPoint); for (int i = 0; i < vs.Count; i++) { bool stop = false; int[] index = vs.ConnectedTopologyVertices(SecondPoint); for (int j = 0; j < index.Length; j++) { if (index[j] != firstPoint1) { if (vs.ConnectedTopologyVertices(index[j]).Length == 3) { firstPoint1 = SecondPoint; SecondPoint = index[j]; firstLoop1.Add(SecondPoint); break; }//if if (vs.ConnectedTopologyVertices(index[j]).Length == 2) { firstPoint1 = SecondPoint; SecondPoint = index[j]; firstLoop1.Add(SecondPoint); stop = true; break; }//if } } if (stop) { break; } } } return("Done"); }
/// <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) { double anchorThreshold = 0.01; double pointDuplicateThreshold = 0.01; bool isSheetMesh = false; GH_Structure <IGH_Goo> springTree = new GH_Structure <IGH_Goo>(); GH_Structure <GH_Vector> velTree = new GH_Structure <GH_Vector>(); GH_Structure <GH_Number> massTree = new GH_Structure <GH_Number>(); GH_Structure <GH_Number> lengthTree = new GH_Structure <GH_Number>(); GH_Structure <GH_Number> stiffnessTree = new GH_Structure <GH_Number>(); List <double> sheetStiffeningList = new List <double>(); GH_Structure <IGH_Goo> anchorTree = new GH_Structure <IGH_Goo>(); List <bool> selfCollisionList = new List <bool>(); List <int> groupIndexList = new List <int>(); List <SpringSystem> springSystems = new List <SpringSystem>(); DA.GetDataTree(0, out springTree); DA.GetDataTree(1, out velTree); DA.GetDataTree(2, out massTree); DA.GetDataTree(3, out lengthTree); DA.GetDataTree(4, out stiffnessTree); DA.GetDataList(5, sheetStiffeningList); DA.GetDataList(6, selfCollisionList); DA.GetDataTree(7, out anchorTree); DA.GetDataList(8, groupIndexList); #region simplify trees and if(branch.Count == 1) make sure everything sits in path {0} if (!springTree.IsEmpty) { springTree.Simplify(GH_SimplificationMode.CollapseAllOverlaps); } if (!velTree.IsEmpty) { velTree.Simplify(GH_SimplificationMode.CollapseAllOverlaps); } if (!massTree.IsEmpty) { massTree.Simplify(GH_SimplificationMode.CollapseAllOverlaps); } if (!lengthTree.IsEmpty) { lengthTree.Simplify(GH_SimplificationMode.CollapseAllOverlaps); } if (!stiffnessTree.IsEmpty) { stiffnessTree.Simplify(GH_SimplificationMode.CollapseAllOverlaps); } if (!anchorTree.IsEmpty) { anchorTree.Simplify(GH_SimplificationMode.CollapseAllOverlaps); } if (springTree.Branches.Count != groupIndexList.Count || springTree.Branches.Count != selfCollisionList.Count) { throw new Exception("Line tree doesn't fit either groupIndices count or selfCollision count!"); } if (springTree.Branches.Count == 1) { GH_Structure <IGH_Goo> lT = new GH_Structure <IGH_Goo>(); lT.AppendRange(springTree.Branches[0], new GH_Path(0)); springTree = lT; } if (velTree.Branches.Count == 1) { GH_Structure <GH_Vector> vT = new GH_Structure <GH_Vector>(); vT.AppendRange(velTree.Branches[0], new GH_Path(0)); velTree = vT; } if (massTree.Branches.Count == 1) { GH_Structure <GH_Number> mT = new GH_Structure <GH_Number>(); mT.AppendRange(massTree.Branches[0], new GH_Path(0)); massTree = mT; } if (lengthTree.Branches.Count == 1) { GH_Structure <GH_Number> leT = new GH_Structure <GH_Number>(); leT.AppendRange(lengthTree.Branches[0], new GH_Path(0)); lengthTree = leT; } if (stiffnessTree.Branches.Count == 1) { GH_Structure <GH_Number> sT = new GH_Structure <GH_Number>(); sT.AppendRange(stiffnessTree.Branches[0], new GH_Path(0)); stiffnessTree = sT; } if (anchorTree.Branches.Count == 1) { GH_Structure <IGH_Goo> aT = new GH_Structure <IGH_Goo>(); aT.AppendRange(anchorTree.Branches[0], new GH_Path(0)); anchorTree = aT; } #endregion for (int branchIndex = 0; branchIndex < springTree.Branches.Count; branchIndex++) { List <float> positions = new List <float>(); List <float> velocities = new List <float>(); List <float> invMasses = new List <float>(); List <int> springPairIndices = new List <int>(); List <float> targetLengths = new List <float>(); List <float> stiffnesses = new List <float>(); List <int> anchorIndices = new List <int>(); List <float> initialLengths = new List <float>(); //just for info GH_Path path = new GH_Path(branchIndex); List <Line> lines = new List <Line>(); Curve c; Line l; Mesh mesh = new Mesh(); foreach (IGH_Goo springObject in springTree.get_Branch(path)) { if (springObject.CastTo <Mesh>(out mesh)) { break; } else if (springObject.CastTo <Curve>(out c)) { if (c.IsPolyline()) { Polyline pl; c.TryGetPolyline(out pl); for (int i = 0; i < pl.SegmentCount; i++) { lines.Add(pl.SegmentAt(i)); } AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Polyline in branch " + branchIndex + " was split into its segments!"); } else { lines.Add(new Line(c.PointAtStart, c.PointAtEnd)); } } else if (springObject.CastTo <Line>(out l)) { lines.Add(l); } } #region isMesh if (mesh != null && mesh.IsValid) { mesh.Vertices.CombineIdentical(true, true); mesh.Weld(Math.PI); mesh.UnifyNormals(); Rhino.Geometry.Collections.MeshTopologyVertexList mv = mesh.TopologyVertices; Rhino.Geometry.Collections.MeshTopologyEdgeList me = mesh.TopologyEdges; //Add everything related to particles for (int i = 0; i < mv.Count; i++) { //add position positions.Add(mv[i].X); positions.Add(mv[i].Y); positions.Add(mv[i].Z); //add velocity Vector3d vel = new Vector3d(0.0, 0.0, 0.0); if (velTree.PathExists(path)) { if (velTree.get_Branch(path).Count > i) { vel = velTree.get_DataItem(path, i).Value; } else { vel = velTree.get_DataItem(path, 0).Value; } } velocities.Add((float)vel.X); velocities.Add((float)vel.Y); velocities.Add((float)vel.Z); //add inverse mass float invMass = 1.0f; if (massTree.PathExists(path)) { if (massTree.get_Branch(path).Count > i) { invMass = 1.0f / (float)massTree.get_DataItem(path, i).Value; } else { invMass = 1.0f / (float)massTree.get_DataItem(path, 0).Value; } } invMasses.Add(invMass); } //Add everything related to spring lines for (int i = 0; i < me.Count; i++) { springPairIndices.Add(me.GetTopologyVertices(i).I); springPairIndices.Add(me.GetTopologyVertices(i).J); //add length float length = (float)me.EdgeLine(i).Length; initialLengths.Add(length); if (lengthTree.PathExists(path)) { float temp = 0.0f; if (lengthTree.get_Branch(path).Count > i) { temp = (float)lengthTree.get_DataItem(path, i).Value; } else { temp = (float)lengthTree.get_DataItem(path, 0).Value; } if (temp < 0.0) { length *= -temp; } else { length = temp; } } targetLengths.Add(length); //add stiffness float stiffness = 1.0f; if (stiffnessTree.PathExists(path)) { if (stiffnessTree.get_Branch(path).Count > i) { stiffness = (float)stiffnessTree.get_DataItem(path, i).Value; } else { stiffness = (float)stiffnessTree.get_DataItem(path, 0).Value; } } stiffnesses.Add(stiffness); List <Line> f = new List <Line>(); if (sheetStiffeningList.Count > branchIndex && sheetStiffeningList[branchIndex] > 0.0) { isSheetMesh = true; int[] adjFaceInd = me.GetConnectedFaces(i); if (adjFaceInd.Length == 2) { f.Add(me.EdgeLine(i)); MeshFace faceA = mesh.Faces[adjFaceInd[0]]; MeshFace faceB = mesh.Faces[adjFaceInd[1]]; if (faceA.IsTriangle && faceB.IsTriangle) { List <int> allInds = new List <int> { faceA.A, faceA.B, faceA.C, faceB.A, faceB.B, faceB.C }; int[] uniques = new int[6] { 0, 0, 0, 0, 0, 0 }; for (int h = 0; h < 6; h++) { for (int g = 0; g < 6; g++) { if (allInds[h] == allInds[g]) { uniques[h]++; } } } for (int h = 0; h < 6; h++) { if (uniques[h] == 1) { springPairIndices.Add(mv.TopologyVertexIndex(allInds[h])); stiffnesses.Add((float)(stiffness * sheetStiffeningList[branchIndex])); } } float le = (float)mv[springPairIndices[springPairIndices.Count - 2]].DistanceTo(mv[springPairIndices[springPairIndices.Count - 1]]); targetLengths.Add(le); initialLengths.Add(le); f.Add(new Line(mesh.Vertices[mv.TopologyVertexIndex(springPairIndices[springPairIndices.Count - 1])], mesh.Vertices[mv.TopologyVertexIndex(springPairIndices[springPairIndices.Count - 2])])); } } } } } #endregion #region isLines else if (lines.Count != 0) { List <Line> cleanLineList = new List <Line>(); double ptDuplThrSquared = pointDuplicateThreshold * pointDuplicateThreshold; #region clean up line list List <Line> lHist = new List <Line>(); for (int j = 0; j < lines.Count; j++) { //Clean list from duplicate lines Line lCand = lines[j]; Point3d ptCandA = lCand.From; Point3d ptCandB = lCand.To; bool lineExistsAlready = false; foreach (Line lh in lHist) { Line tempL = new Line(lCand.From, lCand.To); if ((Util.SquareDistance(tempL.From, lh.From) < ptDuplThrSquared && Util.SquareDistance(tempL.To, lh.To) < ptDuplThrSquared) || (Util.SquareDistance(tempL.From, lh.To) < ptDuplThrSquared && Util.SquareDistance(tempL.To, lh.From) < ptDuplThrSquared)) { lineExistsAlready = true; } } //Clean list from too short lines if (!(Util.SquareDistance(ptCandA, ptCandB) < ptDuplThrSquared || lineExistsAlready)) { lHist.Add(lCand); cleanLineList.Add(lCand); } else { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Spring nr. " + j + " in branch " + branchIndex + " is either invalid (too short) or appeared for the second time. It is ignored."); } } #endregion //get velocity and mass for this branch (no mass / velo per particle allowed) List <float> branchDefaultVelocity = new List <float>() { 0.0f, 0.0f, 0.0f }; if (velTree.PathExists(path)) { branchDefaultVelocity = new List <float> { (float)velTree.get_DataItem(path, 0).Value.X, (float)velTree.get_DataItem(path, 0).Value.Y, (float)velTree.get_DataItem(path, 0).Value.Z } } ; float branchDefaultInvMass = 1.0f; if (massTree.PathExists(path)) { branchDefaultInvMass = 1.0f / (float)massTree.get_DataItem(path, 0).Value; } //find unique line start indices List <int> springStartIndices = new List <int>(); int advance = 0; for (int item = 0; item < cleanLineList.Count; item++) { Point3d ptCand = cleanLineList[item].From; int alreadyExistsAs = -1; for (int k = 0; k < positions.Count / 3; k++) { //simple squared distance if (Util.SquareDistance(new Point3d(positions[k * 3], positions[k * 3 + 1], positions[k * 3 + 2]), ptCand) < ptDuplThrSquared) { alreadyExistsAs = k; springStartIndices.Add(alreadyExistsAs); break; } } if (alreadyExistsAs == -1) { positions.Add((float)ptCand.X); positions.Add((float)ptCand.Y); positions.Add((float)ptCand.Z); velocities.AddRange(branchDefaultVelocity); invMasses.Add(branchDefaultInvMass); springStartIndices.Add(advance); advance++; } } //find unique line end indices List <int> springEndIndices = new List <int>(); for (int item = 0; item < cleanLineList.Count; item++) { Point3d ptCand = cleanLineList[item].To; int alreadyExistsAs = -1; for (int k = 0; k < positions.Count / 3; k++) { if (Util.SquareDistance(new Point3d(positions[3 * k], positions[3 * k + 1], positions[3 * k + 2]), ptCand) < ptDuplThrSquared) { alreadyExistsAs = k; springEndIndices.Add(alreadyExistsAs); break; } } if (alreadyExistsAs == -1) { positions.Add((float)ptCand.X); positions.Add((float)ptCand.Y); positions.Add((float)ptCand.Z); velocities.AddRange(branchDefaultVelocity); invMasses.Add(branchDefaultInvMass); springEndIndices.Add(advance); advance++; } } //weave spring start indices and spring end indices together for (int w = 0; w < springStartIndices.Count; w++) { springPairIndices.Add(springStartIndices[w]); springPairIndices.Add(springEndIndices[w]); } //Add everything spring line related... for (int i = 0; i < cleanLineList.Count; i++) { //add length float length = (float)cleanLineList[i].Length; initialLengths.Add(length); if (lengthTree.PathExists(path)) { float temp = 0.0f; if (lengthTree.get_Branch(path).Count > i) { temp = (float)lengthTree.get_DataItem(path, i).Value; } else { temp = (float)lengthTree.get_DataItem(path, 0).Value; } if (temp < 0.0) { length *= -temp; } else { length = temp; } } targetLengths.Add(length); //add stiffness float stiffness = 1.0f; if (stiffnessTree.PathExists(path)) { if (stiffnessTree.get_Branch(path).Count > i) { stiffness = (float)stiffnessTree.get_DataItem(path, i).Value; } else { stiffness = (float)stiffnessTree.get_DataItem(path, 0).Value; } } stiffnesses.Add(stiffness); } } #endregion else { throw new Exception("No valid spring input found in branch " + branchIndex); } //Add anchors if (anchorTree.PathExists(path)) { foreach (IGH_Goo anchorObj in anchorTree.get_Branch(path)) { string ass = ""; int ai = 0; Point3d ap = new Point3d(0.0, 0.0, 0.0); if (anchorObj.CastTo <string>(out ass)) { anchorIndices.Add(int.Parse(ass)); } else if (anchorObj.CastTo <int>(out ai)) { anchorIndices.Add(ai); } else if (anchorObj.CastTo <Point3d>(out ap)) { for (int i = 0; i < positions.Count / 3; i++) { if ((anchorThreshold * anchorThreshold) > Math.Pow((positions[3 * i] - ap.X), 2) + Math.Pow((positions[3 * i + 1] - ap.Y), 2) + Math.Pow((positions[3 * i + 2] - ap.Z), 2)) { anchorIndices.Add(i); } } } } } SpringSystem ss = new SpringSystem(positions.ToArray(), velocities.ToArray(), invMasses.ToArray(), springPairIndices.ToArray(), targetLengths.ToArray(), stiffnesses.ToArray(), selfCollisionList[branchIndex], anchorIndices.ToArray(), groupIndexList[branchIndex]); ss.Mesh = mesh; ss.IsSheetMesh = isSheetMesh; ss.InitialLengths = initialLengths.ToArray(); springSystems.Add(ss); } DA.SetDataList(0, springSystems); }
private List <MeshSimplify_Point> preDivide(Mesh mesh) { Rhino.Geometry.Collections.MeshTopologyEdgeList el = mesh.TopologyEdges; Rhino.Geometry.Collections.MeshTopologyVertexList vs = mesh.TopologyVertices; List <MeshSimplify_Point> PointList = new List <MeshSimplify_Point>(); for (int i = 0; i < vs.Count; i++) { MeshSimplify_Point pt = new MeshSimplify_Point(vs[i]); if (vs.MeshVertexIndices(i).Length > 0) { pt.N = mesh.Normals[vs.MeshVertexIndices(i)[0]]; } else { pt.computeNormal(mesh); } PointList.Add(pt); } for (int i = 0; i < vs.Count; i++) { int[] index = vs.ConnectedTopologyVertices(i); for (int j = 0; j < index.Length; j++) { PointList[i].refpoints.Add(PointList[index[j]]); } PointList[i].Sort(); } ///////////////////////////////////////////////////// for (int i = 0; i < vs.Count; i++) { PointList[i].order = 0; } for (int i = 0; i < el.Count; i++) { if (el.GetConnectedFaces(i).Length == 1) { PointList[el.GetTopologyVertices(i).I].order = 5; PointList[el.GetTopologyVertices(i).J].order = 5; } } for (int i = 0; i < vs.Count; i++) { if (PointList[i].order == 5) { if (PointList[i].refpoints.Count != 3) { PointList[i].order = 4; } } else { if (PointList[i].refpoints.Count != 4) { PointList[i].order = 4; } } } ////////////////////////////////////////////////////////// for (int k = 0; k < PointList.Count; k++) { bool sign = true; for (int i = 0; i < PointList.Count; i++) { if (PointList[i].order == 4) { sign = false; PointList[i].order++; if (PointList[i].refpoints.Count == 4) { if (PointList[i].refpoints[0].order == 5 && PointList[i].refpoints[2].order != 5) { PointList[i].refpoints[2].order = 1; } if (PointList[i].refpoints[1].order == 5 && PointList[i].refpoints[3].order != 5) { PointList[i].refpoints[3].order = 1; } if (PointList[i].refpoints[2].order == 5 && PointList[i].refpoints[0].order != 5) { PointList[i].refpoints[0].order = 1; } if (PointList[i].refpoints[3].order == 5 && PointList[i].refpoints[1].order != 5) { PointList[i].refpoints[1].order = 1; } } else { for (int j = 0; j < PointList[i].refpoints.Count; j++) { PointList[i].refpoints[j].order++; } } } } for (int i = 0; i < PointList.Count; i++) { if (PointList[i].order > 0 && PointList[i].order < 4) { PointList[i].order = 4; } } if (sign) { break; } } return(PointList); }