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_Merge2.h" 00036 00037 #ifdef BOP_NEW_MERGE 00038 00039 static void deleteFace(BOP_Mesh *m, BOP_Face *face); 00040 00044 BOP_Merge2 BOP_Merge2::SINGLETON; 00045 00046 #ifdef BOP_DEBUG 00047 void dumpmesh ( BOP_Mesh *m, bool force ) 00048 { 00049 unsigned int nonmanifold = 0; 00050 { 00051 BOP_Edges edges = m->getEdges(); 00052 int count = 0; 00053 for (BOP_IT_Edges edge = edges.begin(); edge != edges.end(); 00054 ++count, ++edge) { 00055 if (!(*edge)->getUsed() && (*edge)->getFaces().size() == 0 ) continue; 00056 BOP_Vertex * v1 = m->getVertex((*edge)->getVertex1()); 00057 BOP_Vertex * v2 = m->getVertex((*edge)->getVertex2()); 00058 00059 if(v1->getTAG()!= BROKEN || v2->getTAG()!= BROKEN ) { 00060 int fcount = 0; 00061 BOP_Indexs faces = (*edge)->getFaces(); 00062 for (BOP_IT_Indexs face = faces.begin(); face != faces.end(); face++) { 00063 BOP_Face *f = m->getFace(*face); 00064 if(f->getTAG()== UNCLASSIFIED) ++fcount; 00065 } 00066 00067 00068 if(fcount !=0 && fcount !=2 ) { 00069 ++nonmanifold; 00070 } 00071 } 00072 } 00073 if (!force && nonmanifold == 0) return; 00074 } 00075 if( nonmanifold ) 00076 cout << nonmanifold << " edges detected" << endl; 00077 #ifdef BOP_DEBUG 00078 cout << "---------------------------" << endl; 00079 00080 BOP_Edges edges = m->getEdges(); 00081 int count = 0; 00082 for (BOP_IT_Edges edge = edges.begin(); edge != edges.end(); 00083 ++count, ++edge) { 00084 BOP_Vertex * v1 = m->getVertex((*edge)->getVertex1()); 00085 BOP_Vertex * v2 = m->getVertex((*edge)->getVertex2()); 00086 00087 if(v1->getTAG()!= BROKEN || v2->getTAG()!= BROKEN ) { 00088 int fcount = 0; 00089 BOP_Indexs faces = (*edge)->getFaces(); 00090 cout << count << ", " << (*edge) << ", " << faces.size() << endl; 00091 for (BOP_IT_Indexs face = faces.begin(); face != faces.end(); face++) { 00092 BOP_Face *f = m->getFace(*face); 00093 if(f->getTAG()== UNCLASSIFIED) ++fcount; 00094 cout << " face " << f << endl; 00095 } 00096 00097 00098 if(fcount !=0 && fcount !=2 ) 00099 cout << " NON-MANIFOLD" << endl; 00100 } 00101 } 00102 00103 BOP_Faces faces = m->getFaces(); 00104 count = 0; 00105 for (BOP_IT_Faces face = faces.begin(); face != faces.end(); face++) { 00106 if( count < 12*2 || (*face)->getTAG() != BROKEN ) { 00107 cout << count << ", " << *face << endl; 00108 } 00109 ++count; 00110 } 00111 00112 BOP_Vertexs verts = m->getVertexs(); 00113 count = 0; 00114 for (BOP_IT_Vertexs vert = verts.begin(); vert != verts.end(); vert++) { 00115 cout << count++ << ", " << *vert << " " << (*vert)->getNumEdges() << endl; 00116 BOP_Indexs edges = (*vert)->getEdges(); 00117 for( BOP_IT_Indexs it = edges.begin(); it != edges.end(); ++it) { 00118 BOP_Edge *edge = m->getEdge(*it); 00119 cout << " " << edge << endl; 00120 } 00121 } 00122 cout << "===========================" << endl; 00123 #endif 00124 } 00125 #endif 00126 00133 void BOP_Merge2::mergeFaces(BOP_Mesh *m, BOP_Index v) 00134 { 00135 m_mesh = m; 00136 00137 #ifdef BOP_DEBUG 00138 cout << "##############################" << endl; 00139 #endif 00140 cleanup( ); 00141 00142 m_firstVertex = v; 00143 bool cont = false; 00144 00145 // Merge faces 00146 mergeFaces(); 00147 00148 do { 00149 // Add quads ... 00150 cont = createQuads(); 00151 // ... and merge new faces 00152 if( cont ) cont = mergeFaces(); 00153 00154 #ifdef BOP_DEBUG 00155 cout << "called mergeFaces " << cont << endl; 00156 #endif 00157 // ... until the merge is not succesful 00158 } while(cont); 00159 } 00160 00161 void clean_nonmanifold( BOP_Mesh *m ) 00162 { 00163 return; 00164 00165 BOP_Edges nme; 00166 BOP_Edges e = m->getEdges(); 00167 for( BOP_IT_Edges it = e.begin(); it != e.end(); ++it ) { 00168 BOP_Indexs faces = (*it)->getFaces(); 00169 if( faces.size() & ~2 ) 00170 nme.push_back(*it); 00171 } 00172 if (nme.size() == 0) return; 00173 for( BOP_IT_Edges it = nme.begin(); it != nme.end(); ++it ) { 00174 if( (*it)->getFaces().size() > 1 ) { 00175 BOP_Indexs faces = (*it)->getFaces(); 00176 for( BOP_IT_Indexs face = faces.begin(); face != faces.end(); ++face ) { 00177 MT_Point3 vertex1 = m->getVertex(m->getFace(*face)->getVertex(0))->getPoint(); 00178 MT_Point3 vertex2 = m->getVertex(m->getFace(*face)->getVertex(1))->getPoint(); 00179 MT_Point3 vertex3 = m->getVertex(m->getFace(*face)->getVertex(2))->getPoint(); 00180 if (BOP_collinear(vertex1,vertex2,vertex3)) // collinear triangle 00181 deleteFace(m,m->getFace(*face)); 00182 } 00183 continue; 00184 } 00185 BOP_Face *oface1 = m->getFace((*it)->getFaces().front()); 00186 BOP_Face *oface2, *tmpface; 00187 BOP_Index first =(*it)->getVertex1(); 00188 BOP_Index next =(*it)->getVertex2(); 00189 BOP_Index last = first; 00190 unsigned short facecount = 0; 00191 bool found = false; 00192 BOP_Indexs vertList; 00193 #ifdef BOP_DEBUG 00194 cout << " first edge is " << (*it) << endl; 00195 #endif 00196 vertList.push_back(first); 00197 BOP_Edge *edge; 00198 while(true) { 00199 BOP_Vertex *vert = m->getVertex(next); 00200 BOP_Indexs edges = vert->getEdges(); 00201 edge = NULL; 00202 for( BOP_IT_Indexs eit = edges.begin(); eit != edges.end(); ++eit) { 00203 edge = m->getEdge(*eit); 00204 if( edge->getFaces().size() > 1) { 00205 edge = NULL; 00206 continue; 00207 } 00208 if( edge->getVertex1() == next && edge->getVertex2() != last ) { 00209 last = next; 00210 next = edge->getVertex2(); 00211 break; 00212 } 00213 if( edge->getVertex2() == next && edge->getVertex1() != last ) { 00214 last = next; 00215 next = edge->getVertex1(); 00216 break; 00217 } 00218 edge = NULL; 00219 } 00220 if( !edge ) break; 00221 #ifdef BOP_DEBUG 00222 cout << " next edge is " << edge << endl; 00223 #endif 00224 tmpface = m->getFace(edge->getFaces().front()); 00225 if( oface1->getOriginalFace() != tmpface->getOriginalFace() ) 00226 oface2 = tmpface; 00227 else 00228 ++facecount; 00229 vertList.push_back(last); 00230 if( vertList.size() > 3 ) break; 00231 if( next == first ) { 00232 found = true; 00233 break; 00234 } 00235 } 00236 if(found) { 00237 edge = *it; 00238 #ifdef BOP_DEBUG 00239 cout << " --> found a loop" << endl; 00240 #endif 00241 if( vertList.size() == 3 ) { 00242 BOP_Face3 *face = (BOP_Face3 *)m->getFace(edge->getFaces().front()); 00243 face->getNeighbours(first,last,next); 00244 } else if( vertList.size() == 4 ) { 00245 BOP_Face4 *face = (BOP_Face4 *)m->getFace(edge->getFaces().front()); 00246 face->getNeighbours(first,last,next,last); 00247 } else { 00248 #ifdef BOP_DEBUG 00249 cout << "loop has " << vertList.size() << "verts"; 00250 #endif 00251 continue; 00252 } 00253 if(facecount == 1) oface1 = oface2; 00254 next = vertList[1]; 00255 last = vertList[2]; 00256 if( edge->getVertex2() == next ) { 00257 BOP_Face3 *f = new BOP_Face3(next,first,last, 00258 oface1->getPlane(),oface1->getOriginalFace()); 00259 m->addFace( f ); 00260 #ifdef BOP_DEBUG 00261 cout << " face is backward: " << f << endl; 00262 #endif 00263 00264 } else { 00265 BOP_Face3 *f = new BOP_Face3(last,first,next, 00266 oface1->getPlane(),oface1->getOriginalFace()); 00267 m->addFace( f ); 00268 #ifdef BOP_DEBUG 00269 cout << " face is forward: " << f << endl; 00270 #endif 00271 } 00272 } 00273 } 00274 } 00275 00285 void BOP_Merge2::cleanup( void ) 00286 { 00287 BOP_Edges edges = m_mesh->getEdges(); 00288 for (BOP_IT_Edges edge = edges.begin(); edge != edges.end(); ++edge) { 00289 BOP_Indexs faces = (*edge)->getFaces(); 00290 for (BOP_IT_Indexs face = faces.begin(); face != faces.end(); ++face) { 00291 BOP_Face *f = m_mesh->getFace(*face); 00292 if(f->getTAG()== UNCLASSIFIED) ; 00293 else (*edge)->removeFace(*face); 00294 } 00295 if( (*edge)->getFaces().size() == 0) (*edge)->setUsed(false); 00296 } 00297 00298 BOP_Vertexs v = m_mesh->getVertexs(); 00299 for( BOP_IT_Vertexs it = v.begin(); it != v.end(); ++it ) { 00300 if( (*it)->getTAG() != BROKEN) { 00301 BOP_Indexs iedges = (*it)->getEdges(); 00302 for(BOP_IT_Indexs i = iedges.begin();i!=iedges.end();i++) 00303 if( m_mesh->getEdge((*i))->getUsed( ) == false) (*it)->removeEdge( *i ); 00304 if( (*it)->getEdges().size() == 0 ) (*it)->setTAG(BROKEN); 00305 } 00306 } 00307 // clean_nonmanifold( m_mesh ); 00308 } 00309 00313 bool BOP_Merge2::mergeFaces() 00314 { 00315 BOP_Indexs mergeVertices; 00316 BOP_Vertexs vertices = m_mesh->getVertexs(); 00317 BOP_IT_Vertexs v = vertices.begin(); 00318 const BOP_IT_Vertexs verticesEnd = vertices.end(); 00319 00320 // Advance to first mergeable vertex 00321 advance(v,m_firstVertex); 00322 BOP_Index pos = m_firstVertex; 00323 00324 // Add unbroken vertices to the list 00325 while(v!=verticesEnd) { 00326 if ((*v)->getTAG() != BROKEN) { 00327 mergeVertices.push_back(pos); 00328 } 00329 00330 v++; 00331 pos++; 00332 } 00333 00334 // Merge faces with that vertices 00335 return mergeFaces(mergeVertices); 00336 } 00337 00341 void BOP_Merge2::freeVerts(BOP_Index v, BOP_Vertex *vert) 00342 { 00343 BOP_Indexs edges = vert->getEdges(); 00344 BOP_Vertex *other; 00345 00346 for( BOP_IT_Indexs it = edges.begin(); it != edges.end(); ++it) { 00347 BOP_Edge *edge = m_mesh->getEdge(*it); 00348 BOP_Indexs edges2; 00349 if( edge->getVertex1() != v ) 00350 other = m_mesh->getVertex( edge->getVertex1() ); 00351 else 00352 other = m_mesh->getVertex( edge->getVertex2() ); 00353 other->removeEdge(*it); 00354 vert->removeEdge(*it); 00355 } 00356 } 00357 00363 bool BOP_Merge2::mergeFaces(BOP_Indexs &mergeVertices) 00364 { 00365 // Check size > 0! 00366 if (mergeVertices.size() == 0) return false; 00367 bool didMerge = false; 00368 00369 for( BOP_Index i = 0; i < mergeVertices.size(); ++i ) { 00370 BOP_LFaces facesByOriginalFace; 00371 BOP_Index v = mergeVertices[i]; 00372 BOP_Vertex *vert = m_mesh->getVertex(v); 00373 #ifdef BOP_DEBUG 00374 cout << "i = " << i << ", v = " << v << ", vert = " << vert << endl; 00375 if (v==48) 00376 cout << "found vert 48" << endl; 00377 #endif 00378 if ( vert->getTAG() != BROKEN ) { 00379 getFaces(facesByOriginalFace,v); 00380 00381 switch (facesByOriginalFace.size()) { 00382 case 0: 00383 // v has no unbroken faces (so it's a new BROKEN vertex) 00384 freeVerts( v, vert ); 00385 vert->setTAG(BROKEN); 00386 break; 00387 case 2: { 00388 #ifdef BOP_DEBUG 00389 cout << "size of fBOF = " << facesByOriginalFace.size() << endl; 00390 #endif 00391 BOP_Faces ff = facesByOriginalFace.front(); 00392 BOP_Faces fb = facesByOriginalFace.back(); 00393 BOP_Index eindexs[2]; 00394 int ecount = 0; 00395 00396 // look for two edges adjacent to v which contain both ofaces 00397 BOP_Indexs edges = vert->getEdges(); 00398 #ifdef BOP_DEBUG 00399 cout << " ff has " << ff.size() << " faces" << endl; 00400 cout << " fb has " << fb.size() << " faces" << endl; 00401 cout << " v has " << edges.size() << " edges" << endl; 00402 #endif 00403 for(BOP_IT_Indexs it = edges.begin(); it != edges.end(); 00404 ++it ) { 00405 BOP_Edge *edge = m_mesh->getEdge(*it); 00406 BOP_Indexs faces = edge->getFaces(); 00407 #ifdef BOP_DEBUG 00408 cout << " " << edge << " has " << edge->getFaces().size() << " faces" << endl; 00409 #endif 00410 if( faces.size() == 2 ) { 00411 BOP_Face *f0 = m_mesh->getFace(faces[0]); 00412 BOP_Face *f1 = m_mesh->getFace(faces[1]); 00413 if( f0->getOriginalFace() != f1->getOriginalFace() ) { 00414 #ifdef BOP_DEBUG 00415 cout << " " << f0 << endl; 00416 cout << " " << f1 << endl; 00417 #endif 00418 eindexs[ecount++] = (*it); 00419 } 00420 } 00421 } 00422 if(ecount == 2) { 00423 #ifdef BOP_DEBUG 00424 cout << " edge indexes are " << eindexs[0]; 00425 cout << " and " << eindexs[1] << endl; 00426 #endif 00427 BOP_Edge *edge = m_mesh->getEdge(eindexs[0]); 00428 BOP_Index N = edge->getVertex1(); 00429 if(N == v) N = edge->getVertex2(); 00430 #ifdef BOP_DEBUG 00431 cout << " ## OK, replace "<<v<<" with "<<N << endl; 00432 #endif 00433 mergeVertex(ff , v, N ); 00434 mergeVertex(fb , v, N ); 00435 // now remove v and its edges 00436 vert->setTAG(BROKEN); 00437 for(BOP_IT_Indexs it = edges.begin(); it != edges.end(); 00438 ++it ) { 00439 BOP_Edge *tedge = m_mesh->getEdge(*it); 00440 tedge->setUsed(false); 00441 } 00442 didMerge = true; 00443 } 00444 #ifdef BOP_DEBUG 00445 else { 00446 cout << " HUH: ecount was " << ecount << endl; 00447 } 00448 #endif 00449 } 00450 break; 00451 default: 00452 break; 00453 } 00454 } 00455 } 00456 00457 return didMerge; 00458 } 00459 00460 void BOP_Merge2::mergeVertex(BOP_Faces &faces, BOP_Index v1, BOP_Index v2) 00461 { 00462 for(BOP_IT_Faces face=faces.begin();face!=faces.end();face++) { 00463 if( (*face)->size() == 3) 00464 mergeVertex((BOP_Face3 *) *face, v1, v2); 00465 else 00466 mergeVertex((BOP_Face4 *) *face, v1, v2); 00467 (*face)->setTAG(BROKEN); 00468 #ifdef BOP_DEBUG 00469 cout << " breaking " << (*face) << endl; 00470 #endif 00471 } 00472 } 00473 00474 /* 00475 * Remove a face from the mesh and from each edges's face list 00476 */ 00477 00478 static void deleteFace(BOP_Mesh *m, BOP_Face *face) 00479 { 00480 BOP_Index l2 = face->getVertex(0); 00481 BOP_Faces faces = m->getFaces(); 00482 for(int i = face->size(); i-- ; ) { 00483 BOP_Indexs edges = m->getVertex(l2)->getEdges(); 00484 BOP_Index l1 = face->getVertex(i); 00485 for(BOP_IT_Indexs it1 = edges.begin(); it1 != edges.end(); ++it1 ) { 00486 BOP_Edge *edge = m->getEdge(*it1); 00487 if( ( edge->getVertex1() == l1 && edge->getVertex2() == l2 ) || 00488 ( edge->getVertex1() == l2 && edge->getVertex2() == l1 ) ) { 00489 BOP_Indexs ef = edge->getFaces(); 00490 for(BOP_IT_Indexs it = ef.begin(); it != ef.end(); ++it ) { 00491 if( m->getFace(*it) == face) { 00492 edge->removeFace(*it); 00493 break; 00494 } 00495 } 00496 break; 00497 } 00498 } 00499 l2 = l1; 00500 } 00501 face->setTAG(BROKEN); 00502 } 00503 00504 void BOP_Merge2::mergeVertex(BOP_Face3 *face, BOP_Index v1, BOP_Index v2) 00505 { 00506 BOP_Index next, prev; 00507 face->getNeighbours(v1,prev,next); 00508 00509 // if new vertex is not already in the tri, make a new tri 00510 if( prev != v2 && next != v2 ) { 00511 m_mesh->addFace( new BOP_Face3(prev,v2,next, 00512 face->getPlane(),face->getOriginalFace()) ); 00513 #ifdef BOP_DEBUG 00514 cout << "mv3: add " << prev << "," << v2 << "," << next << endl; 00515 } else { 00516 cout << "mv3: vertex already in tri: doing nothing" << endl; 00517 #endif 00518 } 00519 deleteFace(m_mesh, face); 00520 } 00521 00522 void BOP_Merge2::mergeVertex(BOP_Face4 *face, BOP_Index v1, BOP_Index v2) 00523 { 00524 BOP_Index next, prev, opp; 00525 face->getNeighbours(v1,prev,next,opp); 00526 00527 // if new vertex is already in the quad, replace quad with new tri 00528 if( prev == v2 || next == v2 ) { 00529 m_mesh->addFace( new BOP_Face3(prev,next,opp, 00530 face->getPlane(),face->getOriginalFace()) ); 00531 #ifdef BOP_DEBUG 00532 cout << "mv4a: add " << prev << "," << next << "," << opp << endl; 00533 #endif 00534 } 00535 // otherwise make a new quad 00536 else { 00537 m_mesh->addFace( new BOP_Face4(prev,v2,next,opp, 00538 face->getPlane(),face->getOriginalFace()) ); 00539 #ifdef BOP_DEBUG 00540 cout << "mv4b: add "<<prev<<","<<v2<<","<<next<<","<<opp<<endl; 00541 #endif 00542 } 00543 deleteFace(m_mesh, face); 00544 } 00545 00546 // #define OLD_QUAD 00547 00553 bool BOP_Merge2::createQuads() 00554 { 00555 00556 BOP_Faces quads; 00557 00558 // Get mesh faces 00559 BOP_Faces faces = m_mesh->getFaces(); 00560 00561 // Merge mesh triangles 00562 const BOP_IT_Faces facesIEnd = (faces.end()-1); 00563 const BOP_IT_Faces facesJEnd = faces.end(); 00564 for(BOP_IT_Faces faceI=faces.begin();faceI!=facesIEnd;faceI++) { 00565 #ifdef OLD_QUAD 00566 if ((*faceI)->getTAG() == BROKEN || (*faceI)->size() != 3) continue; 00567 for(BOP_IT_Faces faceJ=(faceI+1);faceJ!=facesJEnd;faceJ++) { 00568 if ((*faceJ)->getTAG() == BROKEN || (*faceJ)->size() != 3 || 00569 (*faceJ)->getOriginalFace() != (*faceI)->getOriginalFace()) continue; 00570 00571 00572 BOP_Face *faceK = createQuad((BOP_Face3*)*faceI,(BOP_Face3*)*faceJ); 00573 if (faceK != NULL) { 00574 // Set triangles to BROKEN 00575 deleteFace(m_mesh, *faceI); 00576 deleteFace(m_mesh, *faceJ); 00577 #ifdef BOP_DEBUG 00578 cout << "createQuad: del " << *faceI << endl; 00579 cout << "createQuad: del " << *faceJ << endl; 00580 cout << "createQuad: add " << faceK << endl; 00581 #endif 00582 quads.push_back(faceK); 00583 break; 00584 } 00585 } 00586 #else 00587 if ((*faceI)->getTAG() == BROKEN ) continue; 00588 for(BOP_IT_Faces faceJ=(faceI+1);faceJ!=facesJEnd;faceJ++) { 00589 if ((*faceJ)->getTAG() == BROKEN || 00590 (*faceJ)->getOriginalFace() != (*faceI)->getOriginalFace()) continue; 00591 00592 BOP_Face *faceK = NULL; 00593 if((*faceI)->size() == 3) { 00594 if((*faceJ)->size() == 3) 00595 faceK = createQuad((BOP_Face3*)*faceI,(BOP_Face3*)*faceJ); 00596 else 00597 faceK = createQuad((BOP_Face3*)*faceI,(BOP_Face4*)*faceJ); 00598 } else { 00599 if((*faceJ)->size() == 3) 00600 faceK = createQuad((BOP_Face3*)*faceJ,(BOP_Face4*)*faceI); 00601 else 00602 faceK = createQuad((BOP_Face4*)*faceI,(BOP_Face4*)*faceJ); 00603 } 00604 00605 if (faceK != NULL) { 00606 // Set triangles to BROKEN 00607 deleteFace(m_mesh, *faceI); 00608 deleteFace(m_mesh, *faceJ); 00609 #ifdef BOP_DEBUG 00610 cout << "createQuad: del " << *faceI << endl; 00611 cout << "createQuad: del " << *faceJ << endl; 00612 cout << "createQuad: add " << faceK << endl; 00613 #endif 00614 quads.push_back(faceK); 00615 break; 00616 } 00617 } 00618 #endif 00619 } 00620 00621 // Add quads to mesh 00622 const BOP_IT_Faces quadsEnd = quads.end(); 00623 for(BOP_IT_Faces quad=quads.begin();quad!=quadsEnd;quad++) m_mesh->addFace(*quad); 00624 return (quads.size() > 0); 00625 } 00626 00635 BOP_Face* BOP_Merge2::createQuad(BOP_Face3 *faceI, BOP_Face3 *faceJ) 00636 { 00637 // Test if both triangles share a vertex index 00638 BOP_Index v; 00639 unsigned int i; 00640 for(i=0;i<3 ;i++) { 00641 v = faceI->getVertex(i); 00642 if( faceJ->containsVertex(v) ) break; 00643 } 00644 if (i == 3) return NULL; 00645 00646 BOP_Face *faceK = NULL; 00647 00648 // Get faces data 00649 BOP_Index prevI, nextI, prevJ, nextJ; 00650 faceI->getNeighbours(v,prevI,nextI); 00651 faceJ->getNeighbours(v,prevJ,nextJ); 00652 MT_Point3 vertex = m_mesh->getVertex(v)->getPoint(); 00653 MT_Point3 vPrevI = m_mesh->getVertex(prevI)->getPoint(); 00654 MT_Point3 vNextI = m_mesh->getVertex(nextI)->getPoint(); 00655 MT_Point3 vPrevJ = m_mesh->getVertex(prevJ)->getPoint(); 00656 MT_Point3 vNextJ = m_mesh->getVertex(nextJ)->getPoint(); 00657 00658 // Quad test 00659 if (prevI == nextJ) { 00660 if (!BOP_collinear(vNextI,vertex,vPrevJ) && !BOP_collinear(vNextI,vPrevI,vPrevJ) && 00661 BOP_convex(vertex,vNextI,vPrevI,vPrevJ)) { 00662 faceK = new BOP_Face4(v,nextI,prevI,prevJ,faceI->getPlane(),faceI->getOriginalFace()); 00663 faceK->setTAG(faceI->getTAG()); 00664 BOP_Index edge; 00665 m_mesh->getIndexEdge(v,prevI,edge); 00666 m_mesh->getVertex(v)->removeEdge(edge); 00667 m_mesh->getVertex(prevI)->removeEdge(edge); 00668 } 00669 } 00670 else if (nextI == prevJ) { 00671 if (!BOP_collinear(vPrevI,vertex,vNextJ) && !BOP_collinear(vPrevI,vNextI,vNextJ) && 00672 BOP_convex(vertex,vNextJ,vNextI,vPrevI)) { 00673 faceK = new BOP_Face4(v,nextJ,nextI,prevI,faceI->getPlane(),faceI->getOriginalFace()); 00674 faceK->setTAG(faceI->getTAG()); 00675 BOP_Index edge; 00676 m_mesh->getIndexEdge(v,nextI,edge); 00677 m_mesh->getVertex(v)->removeEdge(edge); 00678 m_mesh->getVertex(nextI)->removeEdge(edge); 00679 } 00680 } 00681 return faceK; 00682 } 00683 00692 BOP_Face* BOP_Merge2::createQuad(BOP_Face3 *faceI, BOP_Face4 *faceJ) 00693 { 00694 // Test if triangle and quad share a vertex index 00695 BOP_Index v; 00696 unsigned int i; 00697 for(i=0;i<3 ;i++) { 00698 v = faceI->getVertex(i); 00699 if( faceJ->containsVertex(v) ) break; 00700 } 00701 if (i == 3) return NULL; 00702 00703 BOP_Face *faceK = NULL; 00704 00705 // Get faces data 00706 BOP_Index prevI, nextI, prevJ, nextJ, oppJ; 00707 faceI->getNeighbours(v,prevI,nextI); 00708 faceJ->getNeighbours(v,prevJ,nextJ,oppJ); 00709 00710 // Quad test 00711 BOP_Index edge; 00712 if (nextI == prevJ) { 00713 if (prevI == nextJ) { // v is in center 00714 faceK = new BOP_Face3(nextJ,oppJ,prevJ,faceI->getPlane(),faceI->getOriginalFace()); 00715 faceK->setTAG(faceI->getTAG()); 00716 m_mesh->getIndexEdge(v,prevI,edge); 00717 m_mesh->getVertex(v)->removeEdge(edge); 00718 m_mesh->getVertex(prevI)->removeEdge(edge); 00719 m_mesh->getIndexEdge(v,nextI,edge); 00720 m_mesh->getVertex(v)->removeEdge(edge); 00721 m_mesh->getVertex(nextI)->removeEdge(edge); 00722 freeVerts(v, m_mesh->getVertex(v)); 00723 } else if (prevI == oppJ) { // nextI is in center 00724 faceK = new BOP_Face3(v,nextJ,oppJ,faceI->getPlane(),faceI->getOriginalFace()); 00725 faceK->setTAG(faceI->getTAG()); 00726 m_mesh->getIndexEdge(v,nextI,edge); 00727 m_mesh->getVertex(v)->removeEdge(edge); 00728 m_mesh->getVertex(nextI)->removeEdge(edge); 00729 m_mesh->getIndexEdge(prevI,nextI,edge); 00730 m_mesh->getVertex(prevI)->removeEdge(edge); 00731 m_mesh->getVertex(nextI)->removeEdge(edge); 00732 freeVerts(nextI, m_mesh->getVertex(nextI)); 00733 } 00734 } else if (nextI == oppJ && prevI == nextJ ) { // prevI is in center 00735 faceK = new BOP_Face3(prevJ,v,oppJ,faceI->getPlane(),faceI->getOriginalFace()); 00736 faceK->setTAG(faceI->getTAG()); 00737 m_mesh->getIndexEdge(v,prevI,edge); 00738 m_mesh->getVertex(v)->removeEdge(edge); 00739 m_mesh->getVertex(prevI)->removeEdge(edge); 00740 m_mesh->getIndexEdge(nextI,prevI,edge); 00741 m_mesh->getVertex(nextI)->removeEdge(edge); 00742 m_mesh->getVertex(prevI)->removeEdge(edge); 00743 freeVerts(prevI, m_mesh->getVertex(prevI)); 00744 } 00745 return faceK; 00746 } 00747 00756 BOP_Face* BOP_Merge2::createQuad(BOP_Face4 *faceI, BOP_Face4 *faceJ) 00757 { 00758 BOP_Face *faceK = NULL; 00759 // 00760 // Test if both quads share a vertex index 00761 // 00762 BOP_Index v; 00763 unsigned int i; 00764 for(i=0;i<4 ;i++) { 00765 v = faceI->getVertex(i); 00766 if( faceJ->containsVertex(v) ) break; 00767 } 00768 if (i == 3) return NULL; 00769 00770 00771 // Get faces data 00772 BOP_Index prevI, nextI, oppI, prevJ, nextJ, oppJ; 00773 faceI->getNeighbours(v,prevI,nextI,oppI); 00774 faceJ->getNeighbours(v,prevJ,nextJ,oppJ); 00775 00776 // Quad test 00777 BOP_Index edge; 00778 if (nextI == prevJ) { 00779 if (prevI == nextJ) { // v is in center 00780 faceK = new BOP_Face4(nextI,oppI,nextJ,oppJ,faceI->getPlane(),faceI->getOriginalFace()); 00781 faceK->setTAG(faceI->getTAG()); 00782 m_mesh->getIndexEdge(v,prevI,edge); 00783 m_mesh->getVertex(v)->removeEdge(edge); 00784 m_mesh->getVertex(prevI)->removeEdge(edge); 00785 m_mesh->getIndexEdge(v,nextI,edge); 00786 m_mesh->getVertex(v)->removeEdge(edge); 00787 m_mesh->getVertex(nextI)->removeEdge(edge); 00788 freeVerts(v, m_mesh->getVertex(v)); 00789 } else if (oppI == oppJ) { // nextI is in center 00790 faceK = new BOP_Face4(v,nextJ,oppJ,prevI,faceI->getPlane(),faceI->getOriginalFace()); 00791 faceK->setTAG(faceI->getTAG()); 00792 m_mesh->getIndexEdge(v,nextI,edge); 00793 m_mesh->getVertex(v)->removeEdge(edge); 00794 m_mesh->getVertex(nextI)->removeEdge(edge); 00795 m_mesh->getIndexEdge(prevI,nextI,edge); 00796 m_mesh->getVertex(prevI)->removeEdge(edge); 00797 m_mesh->getVertex(nextI)->removeEdge(edge); 00798 freeVerts(nextI, m_mesh->getVertex(nextI)); 00799 } 00800 } else if (prevI == nextJ && oppI == oppJ) { // prevI is in center 00801 faceK = new BOP_Face4(v,nextI,oppJ,prevJ,faceI->getPlane(),faceI->getOriginalFace()); 00802 faceK->setTAG(faceI->getTAG()); 00803 m_mesh->getIndexEdge(v,prevI,edge); 00804 m_mesh->getVertex(v)->removeEdge(edge); 00805 m_mesh->getVertex(prevI)->removeEdge(edge); 00806 m_mesh->getIndexEdge(nextI,prevI,edge); 00807 m_mesh->getVertex(nextI)->removeEdge(edge); 00808 m_mesh->getVertex(prevI)->removeEdge(edge); 00809 freeVerts(prevI, m_mesh->getVertex(prevI)); 00810 } 00811 return faceK; 00812 } 00813 00820 bool BOP_Merge2::containsIndex(BOP_Indexs indexs, BOP_Index i) 00821 { 00822 const BOP_IT_Indexs indexsEnd = indexs.end(); 00823 for(BOP_IT_Indexs it=indexs.begin();it!=indexsEnd;it++) { 00824 if (*it == i) return true; 00825 } 00826 return false; 00827 } 00828 00835 void BOP_Merge2::getFaces(BOP_LFaces &facesByOriginalFace, BOP_Index v) 00836 { 00837 // Get edges with vertex v 00838 00839 BOP_Indexs edgeIndexs = m_mesh->getVertex(v)->getEdges(); 00840 const BOP_IT_Indexs edgeEnd = edgeIndexs.end(); 00841 for(BOP_IT_Indexs edgeIndex = edgeIndexs.begin();edgeIndex != edgeEnd;edgeIndex++) { 00842 // For each edge, add its no broken faces to the output list 00843 BOP_Edge* edge = m_mesh->getEdge(*edgeIndex); 00844 BOP_Indexs faceIndexs = edge->getFaces(); 00845 const BOP_IT_Indexs faceEnd = faceIndexs.end(); 00846 for(BOP_IT_Indexs faceIndex=faceIndexs.begin();faceIndex!=faceEnd;faceIndex++) { 00847 BOP_Face* face = m_mesh->getFace(*faceIndex); 00848 if (face->getTAG() != BROKEN) { 00849 bool found = false; 00850 // Search if we already have created a list for the 00851 // faces that come from the same original face 00852 const BOP_IT_LFaces lfEnd = facesByOriginalFace.end(); 00853 for(BOP_IT_LFaces facesByOriginalFaceX=facesByOriginalFace.begin(); 00854 facesByOriginalFaceX!=lfEnd; facesByOriginalFaceX++) { 00855 if (((*facesByOriginalFaceX)[0])->getOriginalFace() == face->getOriginalFace()) { 00856 // Search that the face has not been added to the list before 00857 for(unsigned int i = 0;i<(*facesByOriginalFaceX).size();i++) { 00858 if ((*facesByOriginalFaceX)[i] == face) { 00859 found = true; 00860 break; 00861 } 00862 } 00863 if (!found) { 00864 // Add the face to the list 00865 if (face->getTAG()==OVERLAPPED) facesByOriginalFaceX->insert(facesByOriginalFaceX->begin(),face); 00866 else facesByOriginalFaceX->push_back(face); 00867 found = true; 00868 } 00869 break; 00870 } 00871 } 00872 if (!found) { 00873 // Create a new list and add the current face 00874 BOP_Faces facesByOriginalFaceX; 00875 facesByOriginalFaceX.push_back(face); 00876 facesByOriginalFace.push_back(facesByOriginalFaceX); 00877 } 00878 } 00879 } 00880 } 00881 } 00882 00891 void BOP_Merge2::getFaces(BOP_LFaces &facesByOriginalFace, BOP_Indexs vertices, BOP_Index v) 00892 { 00893 // Get edges with vertex v 00894 BOP_Indexs edgeIndexs = m_mesh->getVertex(v)->getEdges(); 00895 const BOP_IT_Indexs edgeEnd = edgeIndexs.end(); 00896 for(BOP_IT_Indexs edgeIndex = edgeIndexs.begin();edgeIndex != edgeEnd;edgeIndex++) { 00897 // Foreach edge, add its no broken faces to the output list 00898 BOP_Edge* edge = m_mesh->getEdge(*edgeIndex); 00899 BOP_Indexs faceIndexs = edge->getFaces(); 00900 const BOP_IT_Indexs faceEnd = faceIndexs.end(); 00901 for(BOP_IT_Indexs faceIndex=faceIndexs.begin();faceIndex!=faceEnd;faceIndex++) { 00902 BOP_Face* face = m_mesh->getFace(*faceIndex); 00903 if (face->getTAG() != BROKEN) { 00904 // Search if the face contains any of the forbidden vertices 00905 bool found = false; 00906 for(BOP_IT_Indexs vertex = vertices.begin();*vertex!= v;vertex++) { 00907 if (face->containsVertex(*vertex)) { 00908 // face contains a forbidden vertex! 00909 found = true; 00910 break; 00911 } 00912 } 00913 if (!found) { 00914 // Search if we already have created a list with the 00915 // faces that come from the same original face 00916 const BOP_IT_LFaces lfEnd = facesByOriginalFace.end(); 00917 for(BOP_IT_LFaces facesByOriginalFaceX=facesByOriginalFace.begin(); 00918 facesByOriginalFaceX!=lfEnd; facesByOriginalFaceX++) { 00919 if (((*facesByOriginalFaceX)[0])->getOriginalFace() == face->getOriginalFace()) { 00920 // Search that the face has not been added to the list before 00921 for(unsigned int i = 0;i<(*facesByOriginalFaceX).size();i++) { 00922 if ((*facesByOriginalFaceX)[i] == face) { 00923 found = true; 00924 break; 00925 } 00926 } 00927 if (!found) { 00928 // Add face to the list 00929 if (face->getTAG()==OVERLAPPED) facesByOriginalFaceX->insert(facesByOriginalFaceX->begin(),face); 00930 else facesByOriginalFaceX->push_back(face); 00931 found = true; 00932 } 00933 break; 00934 } 00935 } 00936 if (!found) { 00937 // Create a new list and add the current face 00938 BOP_Faces facesByOriginalFaceX; 00939 facesByOriginalFaceX.push_back(face); 00940 facesByOriginalFace.push_back(facesByOriginalFaceX); 00941 } 00942 } 00943 } 00944 } 00945 } 00946 } 00947 00948 #endif /* BOP_NEW_MERGE */