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