public static OFFMesh Refine(OFFMesh mesh) { List <Vector3> newVertices = new List <Vector3>(); List <OFFMesh.Triangle> newTriangles = new List <OFFMesh.Triangle>(); int verticesCpt = 0; foreach (OFFMesh.Triangle t in mesh.triangles) { Vector3 AB = (mesh.vertices[t.A] + mesh.vertices[t.B]) / 2f; Vector3 BC = (mesh.vertices[t.B] + mesh.vertices[t.C]) / 2f; Vector3 CA = (mesh.vertices[t.C] + mesh.vertices[t.A]) / 2f; newVertices.Add(AB); newVertices.Add(mesh.vertices[t.B]); newVertices.Add(BC); newVertices.Add(mesh.vertices[t.C]); newVertices.Add(CA); newVertices.Add(mesh.vertices[t.A]); newTriangles.Add(new OFFMesh.Triangle(verticesCpt, verticesCpt + 1, verticesCpt + 2)); newTriangles.Add(new OFFMesh.Triangle(verticesCpt + 2, verticesCpt + 3, verticesCpt + 4)); newTriangles.Add(new OFFMesh.Triangle(verticesCpt + 4, verticesCpt + 5, verticesCpt + 0)); newTriangles.Add(new OFFMesh.Triangle(verticesCpt + 0, verticesCpt + 2, verticesCpt + 4)); verticesCpt += 6; } OFFMesh newMesh = new OFFMesh(); newMesh.vertices = newVertices; newMesh.triangles = newTriangles; return(MeshFilter.Clean(newMesh)); }
public static OFFMesh Clean(OFFMesh mesh) { List <Vector3> newVertices = new List <Vector3>(); List <OFFMesh.Triangle> newTriangles = new List <OFFMesh.Triangle>(mesh.triangles.ToArray()); int newVerticesCount = 0; List <int> newIndices = new List <int>(); for (int i = 0; i < mesh.vertices.Count; i++) { int newIndex = newVertices.IndexOf(mesh.vertices[i]); if (newIndex < 0) { newVertices.Add(mesh.vertices[i]); newIndices.Add(newVerticesCount++); } else { newIndices.Add(newIndex); } } foreach (OFFMesh.Triangle t in newTriangles) { t.A = newIndices[t.A]; t.B = newIndices[t.B]; t.C = newIndices[t.C]; } OFFMesh newMesh = new OFFMesh(); newMesh.vertices = newVertices; newMesh.triangles = newTriangles; return(newMesh); }
/*public static OFFMesh Cube (float a, int m) * { * OFFMesh mesh = new OFFMesh(); * * float step = a / (float)m; * for (int x = 0; x < m; x++) * { * for (int y = 0; y < m; y++) * { * mesh.vertices.Add(new Vector3(x*step - a/2f, y*step - a/2f, a/2f)); * } * } * * return mesh; * } */ public static OFFMesh Cylinder(float h, float r, int m) { OFFMesh mesh = new OFFMesh(); float angStep = 2 * MathF.PI / (float)m; for (int n = 0; n < m; n++) { float a = (float)n * angStep; mesh.vertices.Add(new Vector3(r * MathF.Cos(a), r * MathF.Sin(a), h / 2f)); mesh.vertices.Add(new Vector3(r * MathF.Cos(a), r * MathF.Sin(a), -h / 2f)); } mesh.vertices.Add(new Vector3(0f, 0f, h / 2f)); mesh.vertices.Add(new Vector3(0f, 0f, -h / 2f)); for (int n = 0; n < 2 * m; n += 2) { Triangle[] tQuad = Quad2Triangles(n, (n + 1) % (2 * m), (n + 3) % (2 * m), (n + 2) % (2 * m)); mesh.triangles.Add(tQuad[0]); mesh.triangles.Add(tQuad[1]); mesh.triangles.Add(new Triangle(m, n, (n + 2) % (2 * m))); mesh.triangles.Add(new Triangle(m + 1, (n + 3) % (2 * m), (n + 1) % (2 * m))); } return(mesh); }
public static OFFMesh VertexClustering(OFFMesh mesh, float clusterSize) { // Grouping vertices in clusters List <Cluster> clusters = new List <Cluster>(); foreach (Vector3 vertex in mesh.vertices) { Vector3 floor = vertex / clusterSize; floor = new Vector3(MathF.Floor(floor.X), MathF.Floor(floor.Y), MathF.Floor(floor.Z)) * clusterSize; Cluster cluster = clusters.Find(x => x.floorCoordinates == floor); if (cluster == null) { cluster = new Cluster(floor); clusters.Add(cluster); } cluster.vertices.Add(vertex); } // Building new vertices list from averages by cluster List <Vector3> averageVertices = new List <Vector3>(); foreach (Cluster cluster in clusters) { averageVertices.Add(cluster.AverageVertex); } // Building new triangle list by merging old triangles List <OFFMesh.Triangle> averageTriangles = new List <OFFMesh.Triangle>(); foreach (OFFMesh.Triangle triangle in mesh.triangles) { // A triangle of clusters Cluster clusterA = clusters.Find(c => c.vertices.Contains(mesh.vertices[triangle.A])); Cluster clusterB = clusters.Find(c => c.vertices.Contains(mesh.vertices[triangle.B])); Cluster clusterC = clusters.Find(c => c.vertices.Contains(mesh.vertices[triangle.C])); // A triangle of new vertices int averageA = averageVertices.IndexOf(clusterA.AverageVertex); int averageB = averageVertices.IndexOf(clusterB.AverageVertex); int averageC = averageVertices.IndexOf(clusterC.AverageVertex); OFFMesh.Triangle averageTriangle = new OFFMesh.Triangle(averageA, averageB, averageC); // Ignore flat triangles (if two or more vertices are in the same cluster) and avoid doubles if (averageA != averageB && averageB != averageC && averageC != averageA && averageTriangles.Find(t => t.Equals(averageTriangle)) == null) { averageTriangles.Add(averageTriangle); } } // Output mesh OFFMesh filteredMesh = new OFFMesh(); filteredMesh.vertices = averageVertices; filteredMesh.triangles = averageTriangles; return(filteredMesh); }
static void Main(string[] args) { string folder = "D:/TPOutputs"; OFFMesh mesh = OFFMesh.Sphere(5f, 10, 10); //OFFMesh mesh = OFFMesh.Cylinder (5f, 1f, 100); //OFFMesh mesh = OFFMesh.Cone(5f, 1f, 100); //OFFMesh filterdMesh = MeshFilter.VertexClustering(mesh, 2f); OFFMesh filterdMesh = MeshFilter.Refine(mesh); mesh.SaveFile(folder + "/filter_before.off"); filterdMesh.SaveFile(folder + "/filter_after.off"); }
public static OFFMesh Sphere(float r, int m, int p) { OFFMesh mesh = new OFFMesh(); float mStep = 2 * MathF.PI / (float)m; float pStep = MathF.PI / (float)(p + 1); for (int q = 1; q < p + 1; q++) { float ap = (float)q * pStep; float yp = r * MathF.Cos(ap); float rp = r * MathF.Sin(ap); for (int n = 0; n < m; n++) { float am = (float)n * mStep; mesh.vertices.Add(new Vector3(rp * MathF.Cos(am), rp * MathF.Sin(am), yp)); } } for (int q = 0; q < p - 1; q++) { for (int n = 0; n < m; n++) { Triangle[] tQuad = Quad2Triangles(q * m + n, q * m + (n + 1) % m, (q + 1) % p * m + (n + 1) % m, (q + 1) % p * m + n); tQuad[0].Flip(); tQuad[1].Flip(); mesh.triangles.Add(tQuad[0]); mesh.triangles.Add(tQuad[1]); } } mesh.vertices.Add(new Vector3(0f, 0f, r)); mesh.vertices.Add(new Vector3(0f, 0f, -r)); for (int n = 0; n < m; n++) { mesh.triangles.Add(new Triangle(p * m + 1, ((p - 1) * m) + (n + 1) % m, (p - 1) * m + n)); mesh.triangles.Add(new Triangle((n + 1) % m, p * m, n)); } return(mesh); }
public static OFFMesh Cone(float h, float r, int m) { OFFMesh mesh = new OFFMesh(); float angStep = 2 * MathF.PI / (float)m; for (int n = 0; n < m; n++) { float a = (float)n * angStep; mesh.vertices.Add(new Vector3(r * MathF.Cos(a), r * MathF.Sin(a), -h / 2f)); } mesh.vertices.Add(new Vector3(0f, 0f, h / 2f)); mesh.vertices.Add(new Vector3(0f, 0f, -h / 2f)); for (int n = 0; n < m; n++) { mesh.triangles.Add(new Triangle(n, (n + 1) % m, m)); mesh.triangles.Add(new Triangle(n, m + 1, (n + 1) % m)); } return(mesh); }