/// <summary> /// Loft operation: /// This insets each face by 1/4 of its diagonal and adds a center face /// </summary> /// <param name="pMesh"></param> /// <returns></returns> public static PlanktonMesh Loft(this PlanktonMesh pMesh) { var lMesh = new PlanktonMesh(); // iterate over faces for (int i = 0; i < pMesh.Faces.Count; i++) { // get face center var center = pMesh.Faces.GetFaceCenter(i).ToPoint3d(); // get vertices for face var vIndices = pMesh.Faces.GetFaceVertices(i); var vertices = (from index in vIndices select pMesh.Vertices[index].ToPoint3d()).ToArray(); // get face vertex count int vertexCount = vIndices.Length; // calculate mid-Point between each face vertex and face center Point3d[] midPoints = new Point3d[vertexCount]; for (int j = 0; j < vertexCount; j++) { midPoints[j] = new Line(center, vertices[j]).PointAt(0.5); } // Add original face vertices to new mesh for (int j = 0; j < vertexCount; j++) { lMesh.Vertices.Add(vertices[j]); } // Add new face vertices to mesh for (int j = 0; j < vertexCount; j++) { lMesh.Vertices.Add(midPoints[j]); } // Add new inset faces int allVerticesCount = lMesh.Vertices.Count; int startIndex = allVerticesCount - vertexCount * 2; for (int j = 0; j < vertexCount; j++) { int a = j + startIndex; int b = (j + 1) % vertexCount + startIndex; int c = (j + 1) % vertexCount + startIndex + vertexCount; int d = j + startIndex + vertexCount; lMesh.Faces.AddFace(a, b, c, d); } // Add center face of inset lMesh.Faces.AddFace(Enumerable.Range(startIndex + vertexCount, vertexCount)); } // combine identical vertices, // this is necessary because we added vertices by face // ugly hack :( lMesh = lMesh.CombineIdenticalVertices(); return(lMesh); }
public static PlanktonMesh Quinto(this PlanktonMesh pMesh) { // new mesh to hold quinto result var qMesh = new PlanktonMesh(); // iterate over faces for (int i = 0; i < pMesh.Faces.Count; i++) { // get face vertices var oldVertices = (from index in pMesh.Faces.GetFaceVertices(i) select pMesh.Vertices[index].ToPoint3d()).ToArray(); var oldVertexCount = oldVertices.Length; // empty array to hold all new face vertices var vertexCount = oldVertices.Length * 3; var vertices = new Point3d[vertexCount]; // add old vertices for (int j = 0; j < oldVertexCount; j++) { vertices[j] = oldVertices[j]; } // get mid points of face edges for (int j = 0; j < oldVertexCount; j++) { int upperIndex = (j + 1) % oldVertexCount; var midPoint = new Line(oldVertices[j], oldVertices[upperIndex]).PointAt(0.5); // add to vertex array vertices[j + oldVertexCount] = midPoint; } // get face center var ptCenter = pMesh.Faces.GetFaceCenter(i).ToPoint3d(); // get mid point from edge mid-point to face center for (int j = 0; j < oldVertexCount; j++) { var midPoint = new Line(vertices[j + oldVertexCount], ptCenter).PointAt(0.5); // add to vertex array vertices[j + 2 * oldVertexCount] = midPoint; } // Add vertices to new mesh for (int j = 0; j < vertexCount; j++) { qMesh.Vertices.Add(vertices[j]); } // Add faces int startIndex = qMesh.Vertices.Count - vertexCount; for (int j = 0; j < oldVertexCount; j++) { int a = startIndex + j; int b = startIndex + j + oldVertexCount; int c = startIndex + j + 2 * oldVertexCount; // don't know a sexy math formula for this behaviour right now :/ int d; int e; if (j == 0) { d = startIndex + vertexCount - 1; e = startIndex + 2 * oldVertexCount - 1; } else { d = startIndex + j + 2 * oldVertexCount - 1; e = startIndex + j + oldVertexCount - 1; } qMesh.Faces.AddFace(new[] { a, b, c, d, e }); } // Add center face of inset qMesh.Faces.AddFace(Enumerable.Range(startIndex + 2 * oldVertexCount, oldVertexCount)); } // remove identical vertices which exist because we added by face qMesh = qMesh.CombineIdenticalVertices(); // return return(qMesh); }