void CleanUpMesh() { int numInvalidFaces = 0; int numInvalidEdges = 0; int numInvalidVertices = 0; int numInvalidHalfEdges = 0; List <HalfEdge> newHalfEdges = new List <HalfEdge>(); List <Face> newFaces = new List <Face>(); List <Edge> newEdges = new List <Edge>(); List <Vertex> newVertices = new List <Vertex>(); foreach (HalfEdge he in halfEdges) { if (he.Valid) { newHalfEdges.Add(he); } else { numInvalidHalfEdges++; } } foreach (Face f in faces) { if (f.Valid) { newFaces.Add(f); } else { numInvalidFaces++; } } foreach (Edge e in edges) { if (e.Valid) { newEdges.Add(e); } else { numInvalidEdges++; } } foreach (Vertex v in vertices) { if (v.Valid) { newVertices.Add(v); } else { numInvalidVertices++; } } halfEdges = newHalfEdges.ToArray(); faces = newFaces.ToArray(); edges = newEdges.ToArray(); vertices = newVertices.ToArray(); Debug.Log(numInvalidHalfEdges + " invalid half-edges, " + numInvalidVertices + " invalid vertices, " + numInvalidEdges + " invalid edges, " + numInvalidFaces + " invalid faces"); TagIndices(); Vector3[] positions = new Vector3[vertices.Length]; for (int i = 0; i < positions.Length; i++) { positions[i] = vertices[i].position; } Debug.Log(positions.Length + " vertices left"); int maxIndex = 0; List <int> triangles = new List <int>(); foreach (Face f in faces) { if (f.IsBoundary) { continue; } HalfEdge he = f.anyHalfEdge; for (int i = 0; i < 3; i++) { triangles.Add(he.tailVertex.Index); maxIndex = Mathf.Max(maxIndex, he.tailVertex.Index); he = he.next; } } Debug.Log("Max triangle index = " + maxIndex); targetMesh.mesh.triangles = triangles.ToArray(); targetMesh.mesh.vertices = positions; }
public void CollapseEdge(Edge e) { if (!e.Valid) { return; } HalfEdge nearSide = e.anyHalfEdge; HalfEdge farSide = nearSide.flip; // Assign all half-edge tails to one of the vertices. Vertex keepVertex = nearSide.tailVertex; Vertex discardVertex = farSide.tailVertex; HalfEdge start = discardVertex.anyHalfEdge; HalfEdge he = start; Debug.Log("Reassigning tails from " + discardVertex.Index + " (" + discardVertex.Valid + ") to " + keepVertex.Index + " (" + keepVertex.Valid + ")"); do { if (!he.Valid) { throw new System.Exception("Invalid half-edge reached"); } if (he.tailVertex != discardVertex) { throw new System.Exception("Tail vertex changed to " + he.tailVertex.Index); } he.tailVertex = keepVertex; he = he.flip.next; }while (he != start); // Reassign the vertex's half-edge pointer, because the current // one may become invalid if it is the collapsed edge. // Search for a half-edge not in either of the faces that will be collapsed. while (keepVertex.anyHalfEdge.face == nearSide.face || keepVertex.anyHalfEdge.face == farSide.face) { keepVertex.anyHalfEdge = keepVertex.anyHalfEdge.flip.next; if (keepVertex.anyHalfEdge == nearSide) { Debug.Log("Cycled around; no possible valid edges near vertex " + keepVertex.Index); } } // Add the merged vertex and all of its merged vertices to the // list of identified vertices. keepVertex.IdenticalVertices.AddRange(discardVertex.IdenticalVertices); keepVertex.IdenticalVertices.Add(discardVertex); // Invalidate the other vertex. discardVertex.Valid = false; Debug.Log("Collapsing triangles"); // Collapse triangles on both sides. CollapseTriangle(nearSide); CollapseTriangle(farSide); // Finally edit the positions of the merged vertices. Vector3 midpoint = (keepVertex.position + discardVertex.position) / 2; keepVertex.position = midpoint; discardVertex.position = midpoint; }