/** * Simplifies a mesh, merging the faces with the specified vertices. * @param mergeVertices vertices to test * @return true if a face merge was performed */ bool BOP_Merge2::mergeFaces(BOP_Indexs &mergeVertices) { // Check size > 0! if (mergeVertices.size() == 0) return false; bool didMerge = false; for( BOP_Index i = 0; i < mergeVertices.size(); ++i ) { BOP_LFaces facesByOriginalFace; BOP_Index v = mergeVertices[i]; BOP_Vertex *vert = m_mesh->getVertex(v); #ifdef BOP_DEBUG cout << "i = " << i << ", v = " << v << ", vert = " << vert << endl; if (v==48) cout << "found vert 48" << endl; #endif if ( vert->getTAG() != BROKEN ) { getFaces(facesByOriginalFace,v); switch (facesByOriginalFace.size()) { case 0: // v has no unbroken faces (so it's a new BROKEN vertex) freeVerts( v, vert ); vert->setTAG(BROKEN); break; case 2: { #ifdef BOP_DEBUG cout << "size of fBOF = " << facesByOriginalFace.size() << endl; #endif BOP_Faces ff = facesByOriginalFace.front(); BOP_Faces fb = facesByOriginalFace.back(); BOP_Index eindexs[2]; int ecount = 0; // look for two edges adjacent to v which contain both ofaces BOP_Indexs edges = vert->getEdges(); #ifdef BOP_DEBUG cout << " ff has " << ff.size() << " faces" << endl; cout << " fb has " << fb.size() << " faces" << endl; cout << " v has " << edges.size() << " edges" << endl; #endif for(BOP_IT_Indexs it = edges.begin(); it != edges.end(); ++it ) { BOP_Edge *edge = m_mesh->getEdge(*it); BOP_Indexs faces = edge->getFaces(); #ifdef BOP_DEBUG cout << " " << edge << " has " << edge->getFaces().size() << " faces" << endl; #endif if( faces.size() == 2 ) { BOP_Face *f0 = m_mesh->getFace(faces[0]); BOP_Face *f1 = m_mesh->getFace(faces[1]); if( f0->getOriginalFace() != f1->getOriginalFace() ) { #ifdef BOP_DEBUG cout << " " << f0 << endl; cout << " " << f1 << endl; #endif eindexs[ecount++] = (*it); } } } if(ecount == 2) { #ifdef BOP_DEBUG cout << " edge indexes are " << eindexs[0]; cout << " and " << eindexs[1] << endl; #endif BOP_Edge *edge = m_mesh->getEdge(eindexs[0]); BOP_Index N = edge->getVertex1(); if(N == v) N = edge->getVertex2(); #ifdef BOP_DEBUG cout << " ## OK, replace "<<v<<" with "<<N << endl; #endif mergeVertex(ff , v, N ); mergeVertex(fb , v, N ); // now remove v and its edges vert->setTAG(BROKEN); for(BOP_IT_Indexs it = edges.begin(); it != edges.end(); ++it ) { BOP_Edge *tedge = m_mesh->getEdge(*it); tedge->setUsed(false); } didMerge = true; } #ifdef BOP_DEBUG else { cout << " HUH: ecount was " << ecount << endl; } #endif } break; default: break; } } } return didMerge; }
/** * Replaces a vertex index. * @param oldIndex old vertex index * @param newIndex new vertex index */ BOP_Index BOP_Mesh::replaceVertexIndex(BOP_Index oldIndex, BOP_Index newIndex) { BOP_IT_Indexs oldEdgeIndex; if (oldIndex==newIndex) return newIndex; // Update faces, edges and vertices BOP_Vertex *oldVertex = m_vertexs[oldIndex]; BOP_Vertex *newVertex = m_vertexs[newIndex]; BOP_Indexs oldEdges = oldVertex->getEdges(); // Update faces to the newIndex BOP_IT_Indexs oldEdgesEnd = oldEdges.end(); for(oldEdgeIndex=oldEdges.begin();oldEdgeIndex!=oldEdgesEnd; oldEdgeIndex++) { BOP_Edge *edge = m_edges[*oldEdgeIndex]; if ((edge->getVertex1()==oldIndex && edge->getVertex2()==newIndex) || (edge->getVertex2()==oldIndex && edge->getVertex1()==newIndex)) { // Remove old edge ==> set edge faces to BROKEN removeBrokenFaces( edge, this ); oldVertex->removeEdge(*oldEdgeIndex); newVertex->removeEdge(*oldEdgeIndex); } else { BOP_Indexs faces = edge->getFaces(); const BOP_IT_Indexs facesEnd = faces.end(); for(BOP_IT_Indexs face=faces.begin();face!=facesEnd;face++) { if (m_faces[*face]->getTAG()!=BROKEN) m_faces[*face]->replaceVertexIndex(oldIndex,newIndex); } } } oldEdgesEnd = oldEdges.end(); for(oldEdgeIndex=oldEdges.begin();oldEdgeIndex!=oldEdgesEnd; oldEdgeIndex++) { BOP_Edge * edge = m_edges[*oldEdgeIndex]; BOP_Edge * edge2; BOP_Index v1 = edge->getVertex1(); v1 = (v1==oldIndex?edge->getVertex2():v1); if ((edge2 = getEdge(newIndex,v1)) == NULL) { edge->replaceVertexIndex(oldIndex,newIndex); if ( edge->getVertex1() == edge->getVertex2() ) { removeBrokenFaces( edge, this ); oldVertex->removeEdge(*oldEdgeIndex); } #ifdef HASH rehashVertex(oldIndex,newIndex,v1); #endif newVertex->addEdge(*oldEdgeIndex); } else { BOP_Indexs faces = edge->getFaces(); const BOP_IT_Indexs facesEnd = faces.end(); for(BOP_IT_Indexs f=faces.begin();f!=facesEnd;f++) { if (m_faces[*f]->getTAG()!=BROKEN) edge2->addFace(*f); } BOP_Vertex *oppositeVertex = m_vertexs[v1]; oppositeVertex->removeEdge(*oldEdgeIndex); edge->replaceVertexIndex(oldIndex,newIndex); if ( edge->getVertex1() == edge->getVertex2() ) { removeBrokenFaces( edge, this ); oldVertex->removeEdge(*oldEdgeIndex); newVertex->removeEdge(*oldEdgeIndex); } #ifdef HASH rehashVertex(oldIndex,newIndex,v1); #endif } } oldVertex->setTAG(BROKEN); return newIndex; }