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 <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; */ }
/// <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); }
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 CaculateAm() { for (int i = 0; i < mesh.Faces.Count; i++) { int[] f = vs.IndicesFromFace(i); Point3d p1 = vs[f[0]]; Point3d p2 = vs[f[1]]; Point3d p3 = vs[f[2]]; Circle circle = new Circle(p1, p2, p3); double a = p1.DistanceTo(p2); double b = p1.DistanceTo(p3); double c = p2.DistanceTo(p3); // Print(f.Length.ToString()); // Print(a.ToString() + "/" + b.ToString() + "/" + c.ToString()); Point3d ci = new Point3d(); int sign = 0; if (c >= a && c >= b) { if ((c * c) < (a * a + b * b)) { ci = circle.Center; } else { ci = (p2 + p3) / 2; sign = 1; } } else if (a >= c && a >= b) { if ((a * a) < (c * c + b * b)) { ci = circle.Center; } else { ci = (p2 + p1) / 2; sign = 2; } } else if (b >= a && b >= c) { if ((b * b) < (a * a + c * c)) { ci = circle.Center; } else { ci = (p1 + p3) / 2; sign = 3; } } else { //Print("error"); } Point3d p1p2 = (p1 + p2) / 2; Point3d p1p3 = (p1 + p3) / 2; Point3d p2p3 = (p3 + p2) / 2; if (sign == 0) { ps[f[0]].Am += areaTri(ci, p1, p1p2) + areaTri(ci, p1, p1p3); ps[f[1]].Am += areaTri(ci, p2, p1p2) + areaTri(ci, p2, p2p3); ps[f[2]].Am += areaTri(ci, p3, p1p3) + areaTri(ci, p3, p2p3); } else if (sign == 1) { ps[f[1]].Am += areaTri(ci, p2, p1p2); ps[f[2]].Am += areaTri(ci, p3, p1p3); ps[f[0]].Am += areaTri(ci, p1, p1p2) + areaTri(ci, p1, p1p3); } else if (sign == 2) { ps[f[1]].Am += areaTri(ci, p2, p2p3); ps[f[0]].Am += areaTri(ci, p1, p1p3); ps[f[2]].Am += areaTri(ci, p3, p1p3) + areaTri(ci, p3, p2p3); } else if (sign == 3) { ps[f[0]].Am += areaTri(ci, p1, p1p2); ps[f[2]].Am += areaTri(ci, p3, p2p3); ps[f[1]].Am += areaTri(ci, p2, p1p2) + areaTri(ci, p2, p2p3); } else {// Print("error"); } ////////////////// ps[f[0]].KG += Vector3d.VectorAngle(p2 - p1, p3 - p1); ps[f[1]].KG += Vector3d.VectorAngle(p1 - p2, p3 - p2); ps[f[2]].KG += Vector3d.VectorAngle(p2 - p3, p1 - p3); ///////////////// } for (int i = 0; i < el.Count; i++) { int[] f = el.GetConnectedFaces(i); if (f.Length == 2) { /////////////// int pi1 = el.GetTopologyVertices(i).I; int pi2 = el.GetTopologyVertices(i).J; int pf1 = 0; int pf2 = 0; int[] vi1 = vs.IndicesFromFace(f[0]); for (int j = 0; j < 3; j++) { if (vi1[j] != pi1 && vi1[j] != pi2) { pf1 = vi1[j]; break; } } int[] vi2 = vs.IndicesFromFace(f[1]); for (int j = 0; j < 3; j++) { if (vi2[j] != pi1 && vi2[j] != pi2) { pf2 = vi2[j]; break; } } double ang1 = Vector3d.VectorAngle(vs[pi1] - vs[pf1], vs[pi2] - vs[pf1]); double ang2 = Vector3d.VectorAngle(vs[pi1] - vs[pf2], vs[pi2] - vs[pf2]); if (ang1 == Math.PI / 2) { ang1 = 0; } else { ang1 = 1 / Math.Tan(ang1); } if (ang2 == Math.PI / 2) { ang2 = 0; } else { ang2 = 1 / Math.Tan(ang2); } double total = ang1 + ang2; double t1 = Vector3d.Multiply(ps[pi1].n, (vs[pi1] - vs[pi2])); double t2 = Vector3d.Multiply(ps[pi2].n, (vs[pi2] - vs[pi1])); ps[pi1].KH += t1 * total; ps[pi2].KH += t2 * total; //////////////// } } }
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); }
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); }