//---------------------------------------------------------------------------- bool MTMesh::Remove (int label0, int label1, int label2) { TIter iter = mTMap.find(MTITriangle(label0, label1, label2)); if (iter == mTMap.end()) { // The triangle does not exist. return false; } int t = iter->second; MTTriangle& triangle = mTriangles[t]; // Detach triangle from edges. int e0 = triangle.Edge(0); int e1 = triangle.Edge(1); int e2 = triangle.Edge(2); MTEdge& edge0 = mEdges[e0]; MTEdge& edge1 = mEdges[e1]; MTEdge& edge2 = mEdges[e2]; DetachTriangleFromEdge(t, triangle, 0, e0, edge0); DetachTriangleFromEdge(t, triangle, 1, e1, edge1); DetachTriangleFromEdge(t, triangle, 2, e2, edge2); // Detach triangle from vertices. int v0 = triangle.Vertex(0); MTVertex& vertex0 = mVertices[v0]; vertex0.RemoveTriangle(t); int v1 = triangle.Vertex(1); MTVertex& vertex1 = mVertices[v1]; vertex1.RemoveTriangle(t); int v2 = triangle.Vertex(2); MTVertex& vertex2 = mVertices[v2]; vertex2.RemoveTriangle(t); // Detach edges from vertices (only if last edge to reference vertex). bool e0Destroy = (edge0.Triangle(0) == -1); if (e0Destroy) { vertex0.RemoveEdge(e0); vertex1.RemoveEdge(e0); } bool e1Destroy = (edge1.Triangle(0) == -1); if (e1Destroy) { vertex1.RemoveEdge(e1); vertex2.RemoveEdge(e1); } bool e2Destroy = (edge2.Triangle(0) == -1); if (e2Destroy) { vertex0.RemoveEdge(e2); vertex2.RemoveEdge(e2); } // Removal of components from the sets and maps starts here. Be careful // using set indices, component references, and map iterators since // deletion has side effects. Deletion of a component might cause another // component to be moved within the corresponding set or map. bool v0Destroy = (vertex0.GetNumEdges() == 0); bool v1Destroy = (vertex1.GetNumEdges() == 0); bool v2Destroy = (vertex2.GetNumEdges() == 0); // Remove edges if no longer used. if (e0Destroy) { RemoveEdge(label0, label1); } if (e1Destroy) { RemoveEdge(label1, label2); } if (e2Destroy) { RemoveEdge(label2, label0); } // Remove vertices if no longer used. if (v0Destroy) { RemoveVertex(label0); } if (v1Destroy) { RemoveVertex(label1); } if (v2Destroy) { RemoveVertex(label2); } // Remove triangle (definitely no longer used). RemoveTriangle(label0, label1, label2); return true; }
void CMesh::CollapseEdge(TEdge *pEdge, bool bRemoveSecond) { TVertex *p2Remain, *p2Remove; CArray<TVertex *> arrInvalVerts; TEdgeHash hashEvaluatedEdges; int i, iTri; ASSERT(pEdge); p2Remain = pEdge->m_pVertices[!bRemoveSecond]; p2Remove = pEdge->m_pVertices[bRemoveSecond]; for (i = 0; i < p2Remove->m_pTriangles->m_iCount; i++) { TVertex *pOther0, *pOther1; p2Remove->m_pTriangles->At(i)->GetOtherVertices(p2Remove, pOther0, pOther1); arrInvalVerts.Append(pOther0); arrInvalVerts.Append(pOther1); } ASSERT(pEdge->m_pTriangles[0]); // Order of removal is important, if we remove the first one first and it's the only one left, // the edge will get deleted and the attempt to remove the other one will crash RemoveTriangle(pEdge->m_pTriangles[1]); RemoveTriangle(pEdge->m_pTriangles[0]); ASSERT(!GetEdge(p2Remain, p2Remove)); /* #ifdef _DEBUG { for (int i = 0; i < p2Remove->m_pTriangles->m_iCount; i++) { TVertex *pVert0, *pVert1; TTriangle *pTri = p2Remove->m_pTriangles->At(i); pTri->GetOtherVertices(p2Remove, pVert0, pVert1); TTriangle kTestTri(p2Remain, pVert0, pVert1); TTriangleHash::TIter it = m_hashTriangles.Find(&kTestTri); ASSERT(!it); if (it) TEdge *pE = GetEdge(pVert0, pVert1); } } #endif */ while (p2Remove->m_pTriangles->m_iCount > 0) { TVertex *pVert0, *pVert1; TTriangle *pTri = p2Remove->m_pTriangles->At(p2Remove->m_pTriangles->m_iCount - 1); pTri->GetOtherVertices(p2Remove, pVert0, pVert1); int iTriIndex = pTri->m_iIndex; RemoveTriangle(pTri); AddTriangle(p2Remain, pVert0, pVert1, iTriIndex); } m_hashVertices.RemoveValue(p2Remove); delete p2Remove; for (i = 0; i < arrInvalVerts.m_iCount; i++) { for (iTri = 0; iTri < arrInvalVerts[i]->m_pTriangles->m_iCount; iTri++) { TVertex *pOther[2]; TEdge *pEdge; int iVert; arrInvalVerts[i]->m_pTriangles->At(iTri)->GetOtherVertices(arrInvalVerts[i], pOther[0], pOther[1]); for (iVert = 0; iVert < 2; iVert++) { pEdge = GetEdge(arrInvalVerts[i], pOther[iVert]); if (hashEvaluatedEdges.Find(pEdge)) continue; EvaluateEdge(pEdge, false); EvaluateEdge(pEdge, true); hashEvaluatedEdges.Add(pEdge); } } } }