Blender V2.61 - r43446

BOP_Merge.cpp

Go to the documentation of this file.
00001 /*
00002  *
00003  *
00004  * ***** BEGIN GPL LICENSE BLOCK *****
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  *
00020  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00021  * All rights reserved.
00022  *
00023  * The Original Code is: all of this file.
00024  *
00025  * Contributor(s): Marc Freixas, Ken Hughes
00026  *
00027  * ***** END GPL LICENSE BLOCK *****
00028  */
00029 
00035 #include "BOP_Merge.h"
00036 
00037 #ifdef BOP_ORIG_MERGE
00038 
00039 #ifdef _MSC_VER
00040 #if _MSC_VER < 1300
00041 #include <list>
00042 #endif
00043 #endif
00044 
00048 BOP_Merge BOP_Merge::SINGLETON;
00049 
00055 void BOP_Merge::mergeFaces(BOP_Mesh *m, BOP_Index v)
00056 {
00057     m_mesh = m;
00058     m_firstVertex = v;
00059 
00060     bool cont = false;
00061 
00062     // Merge faces
00063     mergeFaces();
00064 
00065     do {
00066         // Add quads ...
00067         cont = createQuads();
00068         if (cont) {
00069             // ... and merge new faces
00070             cont = mergeFaces();
00071         }
00072         // ... until the merge is not succesful
00073     } while(cont);
00074 }
00075 
00079 bool BOP_Merge::mergeFaces()
00080 {
00081     BOP_Indexs mergeVertices;
00082     BOP_Vertexs vertices = m_mesh->getVertexs();
00083     BOP_IT_Vertexs v = vertices.begin();
00084     const BOP_IT_Vertexs verticesEnd = vertices.end();
00085 
00086     // Advance to first mergeable vertex
00087     advance(v,m_firstVertex);
00088     BOP_Index pos = m_firstVertex;
00089 
00090     // Add unbroken vertices to the list
00091     while(v!=verticesEnd) {
00092         if ((*v)->getTAG() != BROKEN) mergeVertices.push_back(pos);
00093         v++;pos++;
00094     }
00095 
00096     // Merge faces with that vertices
00097     return mergeFaces(mergeVertices);
00098 }
00099 
00100 
00106 bool BOP_Merge::mergeFaces(BOP_Indexs &mergeVertices)
00107 {
00108     // Check size > 0!
00109     if (mergeVertices.size() == 0) return false;
00110 
00111     // New faces added by merge
00112     BOP_Faces newFaces;
00113 
00114     // Old faces removed by merge
00115     BOP_Faces oldFaces;
00116 
00117     // Get the first vertex index and add it to 
00118     // the current pending vertices to merge
00119     BOP_Index v = mergeVertices[0];
00120     BOP_Indexs pendingVertices;
00121     pendingVertices.push_back(v);
00122 
00123     // Get faces with index v that come from the same original face
00124     BOP_LFaces facesByOriginalFace;
00125     getFaces(facesByOriginalFace,v);
00126 
00127     bool merged = true;
00128 
00129     // Check it has any unbroken face
00130     if (facesByOriginalFace.size()==0) {
00131         // v has not any unbroken face (so it's a new BROKEN vertex)
00132         (m_mesh->getVertex(v))->setTAG(BROKEN);
00133         merged = false;
00134     }
00135 
00136     // Merge vertex faces   
00137     const BOP_IT_LFaces facesEnd = facesByOriginalFace.end();
00138     
00139     for(BOP_IT_LFaces facesByOriginalFaceX = facesByOriginalFace.begin();
00140         (facesByOriginalFaceX != facesEnd)&&merged;
00141         facesByOriginalFaceX++) {       
00142             merged = mergeFaces((*facesByOriginalFaceX),oldFaces,newFaces,pendingVertices,v);
00143     }
00144 
00145     // Check if the are some pendingVertices to merge
00146     if (pendingVertices.size() > 1 && merged) {
00147         // There are pending vertices that we need to merge in order to merge v ...
00148         for(unsigned int i=1;i<pendingVertices.size() && merged;i++) 
00149             merged = mergeFaces(oldFaces,newFaces,pendingVertices,pendingVertices[i]);
00150     }
00151 
00152     // If merge was succesful ...
00153     if (merged) {
00154         // Set old faces to BROKEN...
00155       const BOP_IT_Faces oldFacesEnd = oldFaces.end();
00156         for(BOP_IT_Faces face=oldFaces.begin();face!=oldFacesEnd;face++) 
00157             (*face)->setTAG(BROKEN);
00158 
00159         // ... and add merged faces (that are the new merged faces without pending vertices)
00160         const BOP_IT_Faces newFacesEnd = newFaces.end();
00161         for(BOP_IT_Faces newFace=newFaces.begin();newFace!=newFacesEnd;newFace++) {
00162             m_mesh->addFace(*newFace);
00163             // Also, add new face vertices to the queue of vertices to merge if they weren't
00164             for(BOP_Index i = 0;i<(*newFace)->size();i++) {
00165                 BOP_Index vertexIndex = (*newFace)->getVertex(i);
00166                 if (vertexIndex >= m_firstVertex && !containsIndex(mergeVertices,vertexIndex))
00167                     mergeVertices.push_back(vertexIndex);
00168             }
00169         }
00170         // Set the merged vertices to BROKEN ...
00171         const BOP_IT_Indexs pendingEnd = pendingVertices.end();
00172         for(BOP_IT_Indexs pendingVertex = pendingVertices.begin(); pendingVertex != pendingEnd;pendingVertex++) {
00173             BOP_Index pV = *pendingVertex;
00174             m_mesh->getVertex(pV)->setTAG(BROKEN);
00175             // ... and remove them from mergeVertices queue
00176             const BOP_IT_Indexs mergeEnd = mergeVertices.end();
00177             for(BOP_IT_Indexs mergeVertex = mergeVertices.begin(); mergeVertex != mergeEnd;mergeVertex++) {
00178                 BOP_Index mV = *mergeVertex;
00179                 if (mV == pV) {
00180                     mergeVertices.erase(mergeVertex);
00181                     break;
00182                 }
00183             }
00184         }
00185     }
00186     else {
00187         // The merge  was not succesful, remove the vertex frome merge vertices queue
00188         mergeVertices.erase(mergeVertices.begin());
00189         
00190         // free the not used newfaces
00191         const BOP_IT_Faces newFacesEnd = newFaces.end();
00192         for(BOP_IT_Faces newFace=newFaces.begin();newFace!=newFacesEnd;newFace++) {
00193             delete (*newFace);
00194         }
00195     }
00196 
00197     // Invoke mergeFaces and return the merge result
00198     return (mergeFaces(mergeVertices) || merged);
00199 }
00200 
00201 
00214 bool BOP_Merge::mergeFaces(BOP_Faces &oldFaces, BOP_Faces &newFaces, BOP_Indexs &vertices, BOP_Index v) {
00215 
00216     bool merged = true;
00217 
00218     // Get faces with v that come from the same original face, (without the already 'merged' from vertices)
00219     BOP_LFaces facesByOriginalFace;
00220     getFaces(facesByOriginalFace,vertices,v);
00221   
00222     if (facesByOriginalFace.size()==0) {
00223         // All the faces with this vertex were already merged!!!
00224         return true;
00225     }
00226     else {
00227         // Merge faces
00228       const BOP_IT_LFaces facesEnd = facesByOriginalFace.end();
00229         for(BOP_IT_LFaces facesByOriginalFaceX = facesByOriginalFace.begin();
00230             (facesByOriginalFaceX != facesEnd)&&merged;
00231             facesByOriginalFaceX++) {
00232                 merged = mergeFaces((*facesByOriginalFaceX),oldFaces,newFaces,vertices,v);
00233         }
00234     }
00235     return merged;
00236 }
00237 
00238 
00252 bool BOP_Merge::mergeFaces(BOP_Faces &faces, BOP_Faces &oldFaces, BOP_Faces &newFaces, BOP_Indexs &vertices, BOP_Index v)
00253 {
00254 
00255     bool merged = false;
00256 
00257     if (faces.size() == 2) {
00258         // Merge a pair of faces into a new face without v
00259         BOP_Face *faceI = faces[0];
00260         BOP_Face *faceJ = faces[1];
00261         BOP_Face *faceK = mergeFaces(faceI,faceJ,vertices,v);
00262         if (faceK != NULL) {
00263             newFaces.push_back(faceK);
00264             oldFaces.push_back(faceI);
00265             oldFaces.push_back(faceJ);
00266             merged = true;
00267         } 
00268         else merged = false;
00269     }
00270     else if (faces.size() == 4) {
00271         // Merge two pair of faces into a new pair without v
00272         // First we try to perform a simplify merge to avoid more pending vertices
00273         // (for example, if we have two triangles and two quads it will be better
00274         // to do 3+4 and 3+4 than 3+3 and 4+4)
00275         BOP_Face *oldFace1 = faces[0];
00276         BOP_Face *oldFace2, *newFace1;
00277         unsigned int indexJ = 1;
00278         while (indexJ < faces.size() && !merged) {
00279             oldFace2 = faces[indexJ];
00280             newFace1 = mergeFaces(oldFace1,oldFace2,v);
00281             if (newFace1 != NULL) merged = true;
00282             else indexJ++;
00283         }
00284         if (merged) {
00285             // Merge the other pair of faces 
00286             unsigned int indexK, indexL;
00287             if (indexJ == 1) {indexK = 2;indexL = 3;}
00288             else if (indexJ == 2) {indexK = 1;indexL = 3;}
00289             else {indexK = 1;indexL = 2;}
00290             BOP_Face *oldFace3 = faces[indexK];
00291             BOP_Face *oldFace4 = faces[indexL];
00292             unsigned int oldSize = vertices.size();
00293             BOP_Face *newFace2 = mergeFaces(oldFace3,oldFace4,vertices,v);
00294             if (newFace2 != NULL) {
00295                 newFaces.push_back(newFace1);
00296                 newFaces.push_back(newFace2);
00297                 oldFaces.push_back(oldFace1);
00298                 oldFaces.push_back(oldFace2);
00299                 oldFaces.push_back(oldFace3);
00300                 oldFaces.push_back(oldFace4);
00301                 merged = true;
00302             }
00303             else {
00304                 // Undo all changes
00305                 delete newFace1;
00306                 merged = false;
00307                 unsigned int count = vertices.size() - oldSize;
00308                 if (count != 0)
00309                     vertices.erase(vertices.end() - count, vertices.end());
00310             }
00311         }       
00312         if (!merged) {
00313             // Try a complete merge
00314             merged = true;
00315             while (faces.size()>0 && merged) {
00316                 indexJ = 1;
00317                 BOP_Face *faceI = faces[0];
00318                 merged = false;
00319                 while (indexJ < faces.size()) {
00320                     BOP_Face *faceJ = faces[indexJ];
00321                     BOP_Face *faceK = mergeFaces(faceI,faceJ,vertices,v);
00322                     if (faceK != NULL) {
00323                         // faceK = faceI + faceJ and it does not include v!
00324                         faces.erase(faces.begin()+indexJ,faces.begin()+(indexJ+1));
00325                         faces.erase(faces.begin(),faces.begin()+1);
00326                         newFaces.push_back(faceK);
00327                         oldFaces.push_back(faceI);
00328                         oldFaces.push_back(faceJ);
00329                         merged = true;
00330                         break;
00331                     }
00332                     else indexJ++;
00333                 }
00334             }
00335         }
00336     }
00337     else merged = false; // there are N=1 or N=3 or N>4 faces!
00338 
00339     // Return merge result
00340     return merged;
00341 }
00342 
00351 BOP_Face* BOP_Merge::mergeFaces(BOP_Face *faceI, BOP_Face *faceJ, BOP_Index v)
00352 {
00353     if (faceI->size() == 3) {
00354         if (faceJ->size() == 4)
00355             return mergeFaces((BOP_Face4*)faceJ,(BOP_Face3*)faceI,v);
00356     }
00357     else if (faceI->size() == 4) {
00358         if (faceJ->size() == 3)
00359             return mergeFaces((BOP_Face4*)faceI,(BOP_Face3*)faceJ,v);
00360     }
00361     return NULL;
00362 }
00363 
00376 BOP_Face* BOP_Merge::mergeFaces(BOP_Face *faceI, BOP_Face *faceJ, BOP_Indexs &pending, BOP_Index v)
00377 {
00378     if (faceI->size() == 3) {
00379         if (faceJ->size() == 3)
00380             return mergeFaces((BOP_Face3*)faceI,(BOP_Face3*)faceJ,v);
00381         else if (faceJ->size() == 4)
00382             return mergeFaces((BOP_Face4*)faceJ,(BOP_Face3*)faceI,pending,v);
00383     }
00384     else if (faceI->size() == 4) {
00385         if (faceJ->size() == 3)
00386             return mergeFaces((BOP_Face4*)faceI,(BOP_Face3*)faceJ,pending,v);
00387         else if (faceJ->size() == 4)
00388             return mergeFaces((BOP_Face4*)faceI,(BOP_Face4*)faceJ,pending,v);
00389     }
00390     return NULL;
00391 }
00392 
00401 BOP_Face* BOP_Merge::mergeFaces(BOP_Face3 *faceI, BOP_Face3 *faceJ, BOP_Index v)
00402 {
00403     BOP_Face *faceK = NULL;
00404 
00405     // Get faces data
00406     BOP_Index prevI, nextI, prevJ, nextJ;   
00407     faceI->getNeighbours(v,prevI,nextI);
00408     faceJ->getNeighbours(v,prevJ,nextJ);
00409     MT_Point3 vertex = m_mesh->getVertex(v)->getPoint();
00410     MT_Point3 vPrevI = m_mesh->getVertex(prevI)->getPoint();
00411     MT_Point3 vNextI = m_mesh->getVertex(nextI)->getPoint();
00412     MT_Point3 vPrevJ = m_mesh->getVertex(prevJ)->getPoint();
00413     MT_Point3 vNextJ = m_mesh->getVertex(nextJ)->getPoint();
00414 
00415     // Merge test
00416     if (prevI == nextJ) {
00417         // Both faces share the edge (prevI,v) == (v,nextJ)
00418         if (BOP_between(vertex,vNextI,vPrevJ)) {
00419             faceK = new BOP_Face3(prevI,prevJ,nextI,faceI->getPlane(),faceI->getOriginalFace());
00420             faceK->setTAG(faceI->getTAG());
00421         }
00422     }
00423     else if (nextI == prevJ) {
00424         // Both faces share the edge (v,nextI) == (prevJ,v)
00425         if (BOP_between(vertex,vPrevI,vNextJ)) {
00426             faceK = new BOP_Face3(prevI,nextJ,nextI,faceI->getPlane(),faceI->getOriginalFace());
00427             faceK->setTAG(faceI->getTAG());
00428         }
00429     }
00430     return faceK;
00431 }
00432 
00441 BOP_Face* BOP_Merge::mergeFaces(BOP_Face4 *faceI, BOP_Face3 *faceJ, BOP_Index v)
00442 {
00443     BOP_Face *faceK = NULL;
00444 
00445     // Get faces data
00446     BOP_Index prevI, nextI, opp, prevJ, nextJ;
00447     faceI->getNeighbours(v,prevI,nextI,opp);
00448     faceJ->getNeighbours(v,prevJ,nextJ);
00449     MT_Point3 vertex = m_mesh->getVertex(v)->getPoint();
00450     MT_Point3 vOpp = m_mesh->getVertex(opp)->getPoint();
00451     MT_Point3 vPrevI = m_mesh->getVertex(prevI)->getPoint();
00452     MT_Point3 vNextI = m_mesh->getVertex(nextI)->getPoint();
00453     MT_Point3 vPrevJ = m_mesh->getVertex(prevJ)->getPoint();
00454     MT_Point3 vNextJ = m_mesh->getVertex(nextJ)->getPoint();
00455 
00456     // Merge test
00457     if (prevI == nextJ) {
00458         if (BOP_between(vertex,vNextI,vPrevJ) && !BOP_collinear(vPrevJ,vPrevI,vOpp)
00459             && BOP_convex(vOpp,vPrevI,vPrevJ,vNextI)) {
00460             faceK = new BOP_Face4(opp,prevI,prevJ,nextI,faceI->getPlane(),faceI->getOriginalFace());
00461             faceK->setTAG(faceI->getTAG());
00462         }
00463     }
00464     else if (nextI == prevJ) {
00465         if (BOP_between(vertex,vPrevI,vNextJ) && !BOP_collinear(vNextJ,vNextI,vOpp)
00466             && BOP_convex(vOpp,vPrevI,vNextJ,vNextI)) {
00467             faceK = new BOP_Face4(opp,prevI,nextJ,nextI,faceI->getPlane(),faceI->getOriginalFace());
00468             faceK->setTAG(faceI->getTAG());
00469         }
00470     }
00471     return faceK;
00472 }
00473 
00485 BOP_Face* BOP_Merge::mergeFaces(BOP_Face4 *faceI, BOP_Face3 *faceJ, BOP_Indexs &pending, BOP_Index v)
00486 {
00487     BOP_Face *faceK = NULL;
00488 
00489     // Get faces data
00490     BOP_Index prevI, nextI, opp, prevJ, nextJ;
00491     faceI->getNeighbours(v,prevI,nextI,opp);
00492     faceJ->getNeighbours(v,prevJ,nextJ);
00493     MT_Point3 vertex = m_mesh->getVertex(v)->getPoint();
00494     MT_Point3 vOpp = m_mesh->getVertex(opp)->getPoint();
00495     MT_Point3 vPrevI = m_mesh->getVertex(prevI)->getPoint();
00496     MT_Point3 vNextI = m_mesh->getVertex(nextI)->getPoint();
00497     MT_Point3 vPrevJ = m_mesh->getVertex(prevJ)->getPoint();
00498     MT_Point3 vNextJ = m_mesh->getVertex(nextJ)->getPoint();
00499 
00500     // Merge test
00501     if (prevI == nextJ) {
00502         if (BOP_between(vertex,vNextI,vPrevJ)) {
00503             if (!BOP_collinear(vPrevJ,vPrevI,vOpp) && BOP_convex(vOpp,vPrevI,vPrevJ,vNextI)) {
00504                 // The result is a new quad
00505                 faceK = new BOP_Face4(opp,prevI,prevJ,nextI,faceI->getPlane(),faceI->getOriginalFace());
00506                 faceK->setTAG(faceI->getTAG());
00507             }
00508             else if (BOP_between(vPrevI,vPrevJ,vOpp)) {
00509                 // The result is a triangle (only if prevI can be merged)
00510                 if (prevI < m_firstVertex) return NULL; // It can't be merged
00511                 faceK = new BOP_Face3(nextI,opp,prevJ,faceI->getPlane(),faceI->getOriginalFace());
00512                 faceK->setTAG(faceI->getTAG());
00513                 if (!containsIndex(pending, prevI)) pending.push_back(prevI);
00514             }
00515         }
00516     }
00517     else if (nextI == prevJ) {
00518         if (BOP_between(vertex,vPrevI,vNextJ)) {
00519             if (!BOP_collinear(vNextJ,vNextI,vOpp) && BOP_convex(vOpp,vPrevI,vNextJ,vNextI)) {
00520                 // The result is a new quad
00521                 faceK = new BOP_Face4(opp,prevI,nextJ,nextI,faceI->getPlane(),faceI->getOriginalFace());
00522                 faceK->setTAG(faceI->getTAG());
00523             }
00524             else if (BOP_between(vNextI,vOpp,vNextJ)) {
00525                 // The result is a triangle (only if nextI can be merged)
00526                 if (nextI < m_firstVertex) return NULL;
00527                 faceK = new BOP_Face3(prevI,nextJ,opp,faceI->getPlane(),faceI->getOriginalFace());
00528                 faceK->setTAG(faceI->getTAG());
00529                 if (!containsIndex(pending, nextI)) pending.push_back(nextI);
00530             }
00531         }
00532     }
00533     return faceK;
00534 }
00535 
00547 BOP_Face* BOP_Merge::mergeFaces(BOP_Face4 *faceI, BOP_Face4 *faceJ, BOP_Indexs &pending, BOP_Index v)
00548 {
00549     BOP_Face *faceK = NULL;
00550 
00551     // Get faces data
00552     BOP_Index prevI, nextI, oppI, prevJ, nextJ, oppJ;
00553     faceI->getNeighbours(v,prevI,nextI,oppI);
00554     faceJ->getNeighbours(v,prevJ,nextJ,oppJ);
00555     MT_Point3 vertex = m_mesh->getVertex(v)->getPoint();
00556     MT_Point3 vPrevI = m_mesh->getVertex(prevI)->getPoint();
00557     MT_Point3 vNextI = m_mesh->getVertex(nextI)->getPoint();
00558     MT_Point3 vOppI = m_mesh->getVertex(oppI)->getPoint();
00559     MT_Point3 vPrevJ = m_mesh->getVertex(prevJ)->getPoint();
00560     MT_Point3 vNextJ = m_mesh->getVertex(nextJ)->getPoint();
00561     MT_Point3 vOppJ = m_mesh->getVertex(oppJ)->getPoint();
00562 
00563     // Merge test
00564     if (prevI == nextJ) {
00565         // prevI/nextJ will be a new vertex required to merge
00566         if (prevI < m_firstVertex) return NULL; // It can't be merged
00567         if (BOP_between(vertex,vPrevJ,vNextI) && BOP_between(vNextJ,vOppJ,vOppI)) {
00568             faceK = new BOP_Face4(oppJ,prevJ,nextI,oppI,faceI->getPlane(),faceI->getOriginalFace());
00569             faceK->setTAG(faceI->getTAG());
00570             // We add prevI to the pending list if it wasn't yet
00571             if (!containsIndex(pending, prevI)) pending.push_back(prevI);
00572         }
00573     }
00574     else if (nextI == prevJ) {
00575         // nextI/prevJ will be a new vertex required to merge
00576         if (nextI < m_firstVertex) return NULL; // It can't be merged
00577         if (BOP_between(vertex,vPrevI,vNextJ) && BOP_between(vNextI,vOppI,vOppJ)) {
00578             faceK = new BOP_Face4(oppI,prevI,nextJ,oppJ,faceI->getPlane(),faceI->getOriginalFace());
00579             faceK->setTAG(faceI->getTAG());
00580             // Add nextI to the pending list if it wasn't yet
00581             if (!containsIndex(pending, nextI)) pending.push_back(nextI);
00582         }
00583     }
00584     return faceK;
00585 }
00586 
00587 
00593 bool BOP_Merge::createQuads()
00594 {
00595   
00596     BOP_Faces quads;
00597     
00598     // Get mesh faces
00599     BOP_Faces faces = m_mesh->getFaces();
00600 
00601     
00602     // Merge mesh triangles
00603     const BOP_IT_Faces facesIEnd = (faces.end()-1);
00604     const BOP_IT_Faces facesJEnd = faces.end();
00605     for(BOP_IT_Faces faceI=faces.begin();faceI!=facesIEnd;faceI++) {
00606         if ((*faceI)->getTAG() == BROKEN || (*faceI)->size() != 3) continue;
00607         for(BOP_IT_Faces faceJ=(faceI+1);faceJ!=facesJEnd;faceJ++) {
00608             if ((*faceJ)->getTAG() == BROKEN || (*faceJ)->size() != 3 ||
00609                 (*faceJ)->getOriginalFace() != (*faceI)->getOriginalFace()) continue;
00610 
00611             // Test if both triangles share a vertex index
00612             BOP_Index v;
00613             bool found = false;
00614             for(unsigned int i=0;i<3 && !found;i++) {
00615                 v = (*faceI)->getVertex(i);
00616                 found = (*faceJ)->containsVertex(v);
00617                 
00618             }
00619             if (!found) continue;
00620 
00621             BOP_Face *faceK = createQuad((BOP_Face3*)*faceI,(BOP_Face3*)*faceJ,v);
00622             if (faceK != NULL) {
00623                 // Set triangles to BROKEN
00624                 (*faceI)->setTAG(BROKEN);
00625                 (*faceJ)->setTAG(BROKEN);
00626                 quads.push_back(faceK);
00627                 break;
00628             }
00629         }
00630     }
00631 
00632     // Add quads to mesh
00633     const BOP_IT_Faces quadsEnd = quads.end();
00634     for(BOP_IT_Faces quad=quads.begin();quad!=quadsEnd;quad++) m_mesh->addFace(*quad);
00635     return (quads.size() > 0);
00636 }
00637 
00646 BOP_Face* BOP_Merge::createQuad(BOP_Face3 *faceI, BOP_Face3 *faceJ, BOP_Index v)
00647 {
00648     BOP_Face *faceK = NULL;
00649 
00650     // Get faces data
00651     BOP_Index prevI, nextI, prevJ, nextJ;
00652     faceI->getNeighbours(v,prevI,nextI);
00653     faceJ->getNeighbours(v,prevJ,nextJ);
00654     MT_Point3 vertex = m_mesh->getVertex(v)->getPoint();
00655     MT_Point3 vPrevI = m_mesh->getVertex(prevI)->getPoint();
00656     MT_Point3 vNextI = m_mesh->getVertex(nextI)->getPoint();
00657     MT_Point3 vPrevJ = m_mesh->getVertex(prevJ)->getPoint();
00658     MT_Point3 vNextJ = m_mesh->getVertex(nextJ)->getPoint();
00659 
00660     // Quad test
00661     if (prevI == nextJ) {
00662         if (!BOP_collinear(vNextI,vertex,vPrevJ) && !BOP_collinear(vNextI,vPrevI,vPrevJ) &&
00663             BOP_convex(vertex,vNextI,vPrevI,vPrevJ)) {
00664                 faceK = new BOP_Face4(v,nextI,prevI,prevJ,faceI->getPlane(),faceI->getOriginalFace());
00665                 faceK->setTAG(faceI->getTAG());
00666         }
00667     }
00668     else if (nextI == prevJ) {
00669         if (!BOP_collinear(vPrevI,vertex,vNextJ) && !BOP_collinear(vPrevI,vNextI,vNextJ) &&
00670             BOP_convex(vertex,vNextJ,vNextI,vPrevI)) {
00671                 faceK = new BOP_Face4(v,nextJ,nextI,prevI,faceI->getPlane(),faceI->getOriginalFace());
00672                 faceK->setTAG(faceI->getTAG());
00673             }
00674     }
00675     return faceK;
00676 }
00677 
00684 bool BOP_Merge::containsIndex(BOP_Indexs indexs, BOP_Index i)
00685 {
00686   const BOP_IT_Indexs indexsEnd = indexs.end();
00687     for(BOP_IT_Indexs it=indexs.begin();it!=indexsEnd;it++) {
00688         if (*it == i) return true;
00689     }
00690     return false;
00691 }
00692 
00699 void BOP_Merge::getFaces(BOP_LFaces &facesByOriginalFace, BOP_Index v)
00700 {
00701     // Get edges with vertex v
00702     BOP_Indexs edgeIndexs = m_mesh->getVertex(v)->getEdges();
00703     const BOP_IT_Indexs edgeEnd = edgeIndexs.end();
00704     for(BOP_IT_Indexs edgeIndex = edgeIndexs.begin();edgeIndex != edgeEnd;edgeIndex++) {    
00705         // Foreach edge, add its no broken faces to the output list
00706         BOP_Edge* edge = m_mesh->getEdge(*edgeIndex);
00707         BOP_Indexs faceIndexs = edge->getFaces();
00708         const BOP_IT_Indexs faceEnd = faceIndexs.end();
00709         for(BOP_IT_Indexs faceIndex=faceIndexs.begin();faceIndex!=faceEnd;faceIndex++) {
00710             BOP_Face* face = m_mesh->getFace(*faceIndex);
00711             if (face->getTAG() != BROKEN) {
00712                 bool found = false;
00713                 // Search if we already have created a list for the 
00714                 // faces that come from the same original face
00715                 const BOP_IT_LFaces lfEnd = facesByOriginalFace.end();
00716                 for(BOP_IT_LFaces facesByOriginalFaceX=facesByOriginalFace.begin();
00717                 facesByOriginalFaceX!=lfEnd; facesByOriginalFaceX++) {
00718                     if (((*facesByOriginalFaceX)[0])->getOriginalFace() == face->getOriginalFace()) {
00719                         // Search that the face has not been added to the list before
00720                         for(unsigned int i = 0;i<(*facesByOriginalFaceX).size();i++) {
00721                             if ((*facesByOriginalFaceX)[i] == face) {
00722                                 found = true;
00723                                 break;
00724                             }
00725                         }
00726                         if (!found) {
00727                             // Add the face to the list
00728                           if (face->getTAG()==OVERLAPPED) facesByOriginalFaceX->insert(facesByOriginalFaceX->begin(),face);
00729                           else facesByOriginalFaceX->push_back(face);
00730                           found = true;
00731                         }
00732                         break;
00733                     }
00734                 }
00735                 if (!found) {
00736                     // Create a new list and add the current face
00737                     BOP_Faces facesByOriginalFaceX;
00738                     facesByOriginalFaceX.push_back(face);
00739                     facesByOriginalFace.push_back(facesByOriginalFaceX);
00740                 }
00741             }
00742         }
00743     }
00744 }
00745 
00754 void BOP_Merge::getFaces(BOP_LFaces &facesByOriginalFace, BOP_Indexs vertices, BOP_Index v)
00755 {
00756     // Get edges with vertex v
00757     BOP_Indexs edgeIndexs = m_mesh->getVertex(v)->getEdges();
00758     const BOP_IT_Indexs edgeEnd = edgeIndexs.end();
00759     for(BOP_IT_Indexs edgeIndex = edgeIndexs.begin();edgeIndex != edgeEnd;edgeIndex++) {    
00760         // Foreach edge, add its no broken faces to the output list
00761         BOP_Edge* edge = m_mesh->getEdge(*edgeIndex);
00762         BOP_Indexs faceIndexs = edge->getFaces();
00763         const BOP_IT_Indexs faceEnd = faceIndexs.end();
00764         for(BOP_IT_Indexs faceIndex=faceIndexs.begin();faceIndex!=faceEnd;faceIndex++) {
00765             BOP_Face* face = m_mesh->getFace(*faceIndex);
00766             if (face->getTAG() != BROKEN) {
00767                 // Search if the face contains any of the forbidden vertices
00768                 bool found = false;
00769                 for(BOP_IT_Indexs vertex = vertices.begin();*vertex!= v;vertex++) {
00770                     if (face->containsVertex(*vertex)) {
00771                         // face contains a forbidden vertex!
00772                         found = true;
00773                         break;
00774                 }
00775             }
00776             if (!found) {
00777                 // Search if we already have created a list with the 
00778                 // faces that come from the same original face
00779               const BOP_IT_LFaces lfEnd = facesByOriginalFace.end();
00780                 for(BOP_IT_LFaces facesByOriginalFaceX=facesByOriginalFace.begin();
00781                     facesByOriginalFaceX!=lfEnd; facesByOriginalFaceX++) {
00782                     if (((*facesByOriginalFaceX)[0])->getOriginalFace() == face->getOriginalFace()) {
00783                         // Search that the face has not been added to the list before
00784                         for(unsigned int i = 0;i<(*facesByOriginalFaceX).size();i++) {
00785                             if ((*facesByOriginalFaceX)[i] == face) {
00786                                 found = true;
00787                                 break;
00788                             }
00789                         }
00790                         if (!found) {
00791                           // Add face to the list
00792                           if (face->getTAG()==OVERLAPPED) facesByOriginalFaceX->insert(facesByOriginalFaceX->begin(),face);
00793                           else facesByOriginalFaceX->push_back(face);
00794                           found = true;
00795                         }
00796                         break;
00797                     }
00798                 }
00799                 if (!found) {
00800                     // Create a new list and add the current face
00801                     BOP_Faces facesByOriginalFaceX;
00802                     facesByOriginalFaceX.push_back(face);
00803                     facesByOriginalFace.push_back(facesByOriginalFaceX);
00804                 }
00805             }
00806         }
00807     }
00808     }
00809 }
00810 
00811 #endif  /* BOP_ORIG_MERGE */