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 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 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); }