Example #1
0
        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;
        }
Example #2
0
        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;
        }