/** * Simplifies a mesh, merging its faces. */ bool BOP_Merge::mergeFaces() { BOP_Indexs mergeVertices; BOP_Vertexs vertices = m_mesh->getVertexs(); BOP_IT_Vertexs v = vertices.begin(); const BOP_IT_Vertexs verticesEnd = vertices.end(); // Advance to first mergeable vertex advance(v,m_firstVertex); BOP_Index pos = m_firstVertex; // Add unbroken vertices to the list while(v!=verticesEnd) { if ((*v)->getTAG() != BROKEN) mergeVertices.push_back(pos); v++;pos++; } // Merge faces with that vertices return mergeFaces(mergeVertices); }
void clean_nonmanifold( BOP_Mesh *m ) { return; BOP_Edges nme; BOP_Edges e = m->getEdges(); for( BOP_IT_Edges it = e.begin(); it != e.end(); ++it ) { BOP_Indexs faces = (*it)->getFaces(); if( faces.size() & ~2 ) nme.push_back(*it); } if (nme.size() == 0) return; for( BOP_IT_Edges it = nme.begin(); it != nme.end(); ++it ) { if( (*it)->getFaces().size() > 1 ) { BOP_Indexs faces = (*it)->getFaces(); for( BOP_IT_Indexs face = faces.begin(); face != faces.end(); ++face ) { MT_Point3 vertex1 = m->getVertex(m->getFace(*face)->getVertex(0))->getPoint(); MT_Point3 vertex2 = m->getVertex(m->getFace(*face)->getVertex(1))->getPoint(); MT_Point3 vertex3 = m->getVertex(m->getFace(*face)->getVertex(2))->getPoint(); if (BOP_collinear(vertex1,vertex2,vertex3)) // collinear triangle deleteFace(m,m->getFace(*face)); } continue; } BOP_Face *oface1 = m->getFace((*it)->getFaces().front()); BOP_Face *oface2, *tmpface; BOP_Index first =(*it)->getVertex1(); BOP_Index next =(*it)->getVertex2(); BOP_Index last = first; unsigned short facecount = 0; bool found = false; BOP_Indexs vertList; #ifdef BOP_DEBUG cout << " first edge is " << (*it) << endl; #endif vertList.push_back(first); BOP_Edge *edge; while(true) { BOP_Vertex *vert = m->getVertex(next); BOP_Indexs edges = vert->getEdges(); edge = NULL; for( BOP_IT_Indexs eit = edges.begin(); eit != edges.end(); ++eit) { edge = m->getEdge(*eit); if( edge->getFaces().size() > 1) { edge = NULL; continue; } if( edge->getVertex1() == next && edge->getVertex2() != last ) { last = next; next = edge->getVertex2(); break; } if( edge->getVertex2() == next && edge->getVertex1() != last ) { last = next; next = edge->getVertex1(); break; } edge = NULL; } if( !edge ) break; #ifdef BOP_DEBUG cout << " next edge is " << edge << endl; #endif tmpface = m->getFace(edge->getFaces().front()); if( oface1->getOriginalFace() != tmpface->getOriginalFace() ) oface2 = tmpface; else ++facecount; vertList.push_back(last); if( vertList.size() > 3 ) break; if( next == first ) { found = true; break; } } if(found) { edge = *it; #ifdef BOP_DEBUG cout << " --> found a loop" << endl; #endif if( vertList.size() == 3 ) { BOP_Face3 *face = (BOP_Face3 *)m->getFace(edge->getFaces().front()); face->getNeighbours(first,last,next); } else if( vertList.size() == 4 ) { BOP_Face4 *face = (BOP_Face4 *)m->getFace(edge->getFaces().front()); face->getNeighbours(first,last,next,last); } else { #ifdef BOP_DEBUG cout << "loop has " << vertList.size() << "verts"; #endif continue; } if(facecount == 1) oface1 = oface2; next = vertList[1]; last = vertList[2]; if( edge->getVertex2() == next ) { BOP_Face3 *f = new BOP_Face3(next,first,last, oface1->getPlane(),oface1->getOriginalFace()); m->addFace( f ); #ifdef BOP_DEBUG cout << " face is backward: " << f << endl; #endif } else { BOP_Face3 *f = new BOP_Face3(last,first,next, oface1->getPlane(),oface1->getOriginalFace()); m->addFace( f ); #ifdef BOP_DEBUG cout << " face is forward: " << f << endl; #endif } } } }
/** * 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_Merge::mergeFaces(BOP_Indexs &mergeVertices) { // Check size > 0! if (mergeVertices.size() == 0) return false; // New faces added by merge BOP_Faces newFaces; // Old faces removed by merge BOP_Faces oldFaces; // Get the first vertex index and add it to // the current pending vertices to merge BOP_Index v = mergeVertices[0]; BOP_Indexs pendingVertices; pendingVertices.push_back(v); // Get faces with index v that come from the same original face BOP_LFaces facesByOriginalFace; getFaces(facesByOriginalFace,v); bool merged = true; // Check it has any unbroken face if (facesByOriginalFace.size()==0) { // v has not any unbroken face (so it's a new BROKEN vertex) (m_mesh->getVertex(v))->setTAG(BROKEN); merged = false; } // Merge vertex faces const BOP_IT_LFaces facesEnd = facesByOriginalFace.end(); for(BOP_IT_LFaces facesByOriginalFaceX = facesByOriginalFace.begin(); (facesByOriginalFaceX != facesEnd)&&merged; facesByOriginalFaceX++) { merged = mergeFaces((*facesByOriginalFaceX),oldFaces,newFaces,pendingVertices,v); } // Check if the are some pendingVertices to merge if (pendingVertices.size() > 1 && merged) { // There are pending vertices that we need to merge in order to merge v ... for(unsigned int i=1;i<pendingVertices.size() && merged;i++) merged = mergeFaces(oldFaces,newFaces,pendingVertices,pendingVertices[i]); } // If merge was succesful ... if (merged) { // Set old faces to BROKEN... const BOP_IT_Faces oldFacesEnd = oldFaces.end(); for(BOP_IT_Faces face=oldFaces.begin();face!=oldFacesEnd;face++) (*face)->setTAG(BROKEN); // ... and add merged faces (that are the new merged faces without pending vertices) const BOP_IT_Faces newFacesEnd = newFaces.end(); for(BOP_IT_Faces newFace=newFaces.begin();newFace!=newFacesEnd;newFace++) { m_mesh->addFace(*newFace); // Also, add new face vertices to the queue of vertices to merge if they weren't for(BOP_Index i = 0;i<(*newFace)->size();i++) { BOP_Index vertexIndex = (*newFace)->getVertex(i); if (vertexIndex >= m_firstVertex && !containsIndex(mergeVertices,vertexIndex)) mergeVertices.push_back(vertexIndex); } } // Set the merged vertices to BROKEN ... const BOP_IT_Indexs pendingEnd = pendingVertices.end(); for(BOP_IT_Indexs pendingVertex = pendingVertices.begin(); pendingVertex != pendingEnd;pendingVertex++) { BOP_Index pV = *pendingVertex; m_mesh->getVertex(pV)->setTAG(BROKEN); // ... and remove them from mergeVertices queue const BOP_IT_Indexs mergeEnd = mergeVertices.end(); for(BOP_IT_Indexs mergeVertex = mergeVertices.begin(); mergeVertex != mergeEnd;mergeVertex++) { BOP_Index mV = *mergeVertex; if (mV == pV) { mergeVertices.erase(mergeVertex); break; } } } } else { // The merge was not succesful, remove the vertex frome merge vertices queue mergeVertices.erase(mergeVertices.begin()); // free the not used newfaces const BOP_IT_Faces newFacesEnd = newFaces.end(); for(BOP_IT_Faces newFace=newFaces.begin();newFace!=newFacesEnd;newFace++) { delete (*newFace); } } // Invoke mergeFaces and return the merge result return (mergeFaces(mergeVertices) || merged); }