Blender V2.61 - r43446
|
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 */