private List <DisplacedVertex> FindDisplacedVertices(int maxWedges) { List <DisplacedVertex> displacedVertices = new List <DisplacedVertex>(); for (int i = m_initialWedges.Count - 1; i != maxWedges - 1; i--) { if (displacedVertices.Count == 0) //slight optim when list empty, no need to check if item already exists { displacedVertices.AddRange(m_initialWedges[i].m_displacedVertices); } else { for (int p = 0; p != m_initialWedges[i].m_displacedVertices.Count; p++) { DisplacedVertex vertex = m_initialWedges[i].m_displacedVertices[p]; //test if the vertex is already in the global list of displaced vertices bool bVertexAlreadyExists = false; for (int q = 0; q != displacedVertices.Count; q++) { if (displacedVertices[q].m_index == vertex.m_index) { bVertexAlreadyExists = true; displacedVertices[q] = vertex; //update the vertex position break; } } if (!bVertexAlreadyExists) { displacedVertices.Add(vertex); } } } } return(displacedVertices); }
/** * Collapse the wedge u onto the wedge v * **/ private void Collapse(Wedge u, Wedge v) { // Collapse the edge uv by moving vertex u onto v // Actually remove tris on uv, then update tris that // have u to have v, and then remove u. if (v == null) { // u is a vertex all by itself so just delete it u.Delete(); m_wedges.Remove(u); return; } //Find vertices that will collapse or be displaced for (int i = 0; i != u.Vertices.Count; i++) { Vertex vertex = u.Vertices[i]; Vertex collapseVertex = vertex.FindVertexToCollapseOn(v); //the vertex it will collapse on if it exists if (collapseVertex != null) { u.m_collapsedVertices.Add(vertex.ID, collapseVertex.ID); //no exception will be thrown as unique IDs are inserted into that dictionary //CollapsedVertex collapsedVertex = new CollapsedVertex(vertex.ID, collapseVertex.ID); //u.m_collapsedVertices.Add(collapsedVertex); } else { DisplacedVertex displacedVertex = new DisplacedVertex(); displacedVertex.m_index = vertex.ID; displacedVertex.m_targetPosition = v.m_position; u.m_displacedVertices.Add(displacedVertex); } } //delete triangles on edge[u - v] List <Triangle> sharedTriangles = u.GetSharedTrianglesWithWedge(v); for (int i = 0; i != sharedTriangles.Count; i++) { //delete the triangle sharedTriangles[i].Delete(); for (int j = 0; j != sharedTriangles[i].Vertices.Length; j++) { Vertex vertex = sharedTriangles[i].Vertices[j]; if (!u.HasVertex(vertex) && !v.HasVertex(vertex)) //the third wedge that is not u or v holds this vertex { if (vertex.AdjacentTriangles.Count == 0) //vertex is isolated, remove it { //find the wedge and remove the vertex from its internal list GetWedgeHoldingVertex(m_wedges, vertex).RemoveVertex(vertex); //add the vertex ID to the list of vertices deleted during the operation of collapsing u onto v u.m_deletedVertices.Add(vertex.ID); } } } } //perform the actual collapse u.CollapseOnWedge(v); //add u neighbors to v and add v as a new neighbor of u neighbors for (int i = 0; i != u.Neighbors.Count; i++) { if (u.Neighbors[i] != v) { v.AddNeighbor(u.Neighbors[i]); u.Neighbors[i].AddNeighbor(v); } } //neighbors of wedge u are likely to have lost one triangle through one of their vertex so invalidate them for (int i = 0; i != u.Neighbors.Count; i++) { u.Neighbors[i].InvalidateAdjacentTriangles(); } //delete the wedge and remove it from global list u.Delete(); m_wedges.Remove(u); // recompute the edge collapse costs for neighboring wedges for (int i = 0; i < u.Neighbors.Count; i++) { ComputeEdgeCostAtWedge(u.Neighbors[i]); } }