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): none yet. 00026 * 00027 * ***** END GPL LICENSE BLOCK ***** 00028 */ 00029 00035 #include "BOP_Mesh.h" 00036 #include "BOP_MathUtils.h" 00037 #include <iostream> 00038 #include <fstream> 00039 00040 #include "MEM_guardedalloc.h" 00041 #include "BLI_blenlib.h" 00042 00043 BOP_Mesh::BOP_Mesh() 00044 { 00045 #ifdef HASH 00046 #ifdef HASH_PRINTF_DEBUG 00047 printf ("has hashing\n"); 00048 #endif 00049 hash = NULL; 00050 hashsize = 0; 00051 #endif 00052 } 00053 00057 BOP_Mesh::~BOP_Mesh() 00058 { 00059 const BOP_IT_Vertexs vertexsEnd = m_vertexs.end(); 00060 for(BOP_IT_Vertexs itv=m_vertexs.begin();itv!=vertexsEnd;itv++){ 00061 delete *itv; 00062 } 00063 m_vertexs.clear(); 00064 00065 const BOP_IT_Edges edgesEnd = m_edges.end(); 00066 for(BOP_IT_Edges ite=m_edges.begin();ite!=edgesEnd;ite++){ 00067 delete *ite; 00068 } 00069 m_edges.clear(); 00070 00071 const BOP_IT_Faces facesEnd = m_faces.end(); 00072 for(BOP_IT_Faces itf=m_faces.begin();itf!=facesEnd;itf++){ 00073 delete *itf; 00074 } 00075 m_faces.clear(); 00076 00077 #ifdef HASH 00078 while( hashsize ) { 00079 --hashsize; 00080 BLI_freelistN( &hash[hashsize] ); 00081 } 00082 MEM_freeN( hash ); 00083 hash = NULL; 00084 #endif 00085 } 00086 00092 BOP_Index BOP_Mesh::addVertex(MT_Point3 p) 00093 { 00094 m_vertexs.push_back(new BOP_Vertex(p)); 00095 return m_vertexs.size()-1; 00096 } 00097 00104 BOP_Index BOP_Mesh::addEdge(BOP_Index v1, BOP_Index v2) 00105 { 00106 #ifdef HASH 00107 /* prepare a new hash entry for the edge */ 00108 int minv; 00109 EdgeEntry *h = (EdgeEntry *)MEM_callocN( sizeof( EdgeEntry ), "edgehash" ); 00110 00111 /* store sorted, smallest vert first */ 00112 if( v1 < v2 ) { 00113 minv = HASH(v1); 00114 h->v1 = v1; 00115 h->v2 = v2; 00116 } else { 00117 minv = HASH(v2); 00118 h->v1 = v2; 00119 h->v2 = v1; 00120 } 00121 h->index = m_edges.size(); 00122 00123 /* if hash index larger than hash list, extend the list */ 00124 if( minv >= hashsize ) { 00125 int newsize = (minv + 8) & ~7; 00126 ListBase *nhash = (ListBase *)MEM_mallocN( 00127 newsize * sizeof( ListBase ), 00128 "edgehashtable" ); 00129 /* copy old entries */ 00130 memcpy( nhash, hash, sizeof( ListBase ) * hashsize ); 00131 /* clear new ones */ 00132 while( hashsize < newsize ) { 00133 nhash[hashsize].first = nhash[hashsize].last = NULL; 00134 ++hashsize; 00135 } 00136 if( hash ) 00137 MEM_freeN( hash ); 00138 hash = nhash; 00139 } 00140 00141 /* add the entry to tail of the right hash list */ 00142 BLI_addtail( &hash[minv], h ); 00143 #endif 00144 m_edges.push_back(new BOP_Edge(v1,v2)); 00145 return m_edges.size()-1; 00146 } 00147 00148 #ifdef HASH 00149 00155 void BOP_Mesh::rehashVertex(BOP_Index o, BOP_Index n, BOP_Index x) 00156 { 00157 EdgeEntry *edge; 00158 int minv = HASH(o); 00159 BOP_Index v1, v2; 00160 00161 /* figure out where and what to look for */ 00162 if( o < x ) { 00163 minv = HASH(o); 00164 v1 = o; v2 = x; 00165 } else { 00166 minv = HASH(x); 00167 v1 = x; v2 = o; 00168 } 00169 00170 /* if hash is valid, search for the match */ 00171 if( minv < hashsize ) { 00172 for(edge = (EdgeEntry *)hash[minv].first; 00173 edge; edge = edge->next ) { 00174 if(edge->v1 == v1 && edge->v2 == v2) 00175 break; 00176 } 00177 00178 /* NULL edge == no match */ 00179 if(!edge) { 00180 #ifdef HASH_PRINTF_DEBUG 00181 printf ("OOPS! didn't find edge (%d %d)\n",v1,v2); 00182 #endif 00183 return; 00184 } 00185 #ifdef HASH_PRINTF_DEBUG 00186 printf ("found edge (%d %d)\n",v1,v2); 00187 #endif 00188 /* remove the edge from the old hash list */ 00189 BLI_remlink( &hash[minv], edge ); 00190 00191 /* decide where the new edge should go */ 00192 if( n < x ) { 00193 minv = HASH(n); 00194 v1 = n; v2 = x; 00195 } else { 00196 minv = HASH(x); 00197 edge->v1 = x; edge->v2 = n; 00198 } 00199 00200 /* if necessary, extend the hash list */ 00201 if( minv >= hashsize ) { 00202 #ifdef HASH_PRINTF_DEBUG 00203 printf ("OOPS! new vertex too large! (%d->%d)\n",o,n); 00204 #endif 00205 int newsize = (minv + 8) & ~7; 00206 ListBase *nhash = (ListBase *)MEM_mallocN( 00207 newsize * sizeof( ListBase ), 00208 "edgehashtable" ); 00209 memcpy( nhash, hash, sizeof( ListBase ) * hashsize ); 00210 while( hashsize < newsize ) { 00211 nhash[hashsize].first = nhash[hashsize].last = NULL; 00212 ++hashsize; 00213 } 00214 if( hash ) 00215 MEM_freeN( hash ); 00216 hash = nhash; 00217 } 00218 00219 /* add the entry to tail of the right hash list */ 00220 BLI_addtail( &hash[minv], edge ); 00221 } else { 00222 #ifdef HASH_PRINTF_DEBUG 00223 printf ("OOPS! hash not large enough for (%d %d)\n",minv,hashsize); 00224 #endif 00225 } 00226 } 00227 #endif 00228 00234 BOP_Index BOP_Mesh::addFace(BOP_Face *face) 00235 { 00236 if (face->size()==3) 00237 return addFace((BOP_Face3 *)face); 00238 else 00239 return addFace((BOP_Face4 *)face); 00240 } 00241 00247 BOP_Index BOP_Mesh::addFace(BOP_Face3 *face) 00248 { 00249 BOP_Index indexface = m_faces.size(); 00250 00251 BOP_Index index1 = face->getVertex(0); 00252 BOP_Index index2 = face->getVertex(1); 00253 BOP_Index index3 = face->getVertex(2); 00254 00255 m_faces.push_back((BOP_Face *)face); 00256 00257 BOP_Index edge; 00258 00259 if (!getIndexEdge(index1,index2,edge)) { 00260 edge = addEdge(index1,index2); 00261 getVertex(index1)->addEdge(edge); 00262 getVertex(index2)->addEdge(edge); 00263 } 00264 00265 getEdge(edge)->addFace(indexface); 00266 00267 if (!getIndexEdge(index2,index3,edge)) { 00268 edge = addEdge(index2,index3); 00269 getVertex(index2)->addEdge(edge); 00270 getVertex(index3)->addEdge(edge); 00271 } 00272 00273 getEdge(edge)->addFace(indexface); 00274 00275 if (!getIndexEdge(index3,index1,edge)) { 00276 edge = addEdge(index3,index1); 00277 getVertex(index3)->addEdge(edge); 00278 getVertex(index1)->addEdge(edge); 00279 } 00280 00281 getEdge(edge)->addFace(indexface); 00282 00283 if ((index1 == index2) || (index1 == index3) || (index2 == index3)) 00284 face->setTAG(BROKEN); 00285 00286 return indexface; 00287 } 00288 00294 BOP_Index BOP_Mesh::addFace(BOP_Face4 *face) 00295 { 00296 m_faces.push_back((BOP_Face *)face); 00297 BOP_Index indexface = m_faces.size()-1; 00298 00299 BOP_Index index1 = face->getVertex(0); 00300 BOP_Index index2 = face->getVertex(1); 00301 BOP_Index index3 = face->getVertex(2); 00302 BOP_Index index4 = face->getVertex(3); 00303 00304 BOP_Index edge; 00305 00306 if (!getIndexEdge(index1,index2,edge)) { 00307 edge = addEdge(index1,index2); 00308 getVertex(index1)->addEdge(edge); 00309 getVertex(index2)->addEdge(edge); 00310 } 00311 00312 getEdge(edge)->addFace(indexface); 00313 00314 if (!getIndexEdge(index2,index3,edge)) { 00315 edge = addEdge(index2,index3); 00316 getVertex(index2)->addEdge(edge); 00317 getVertex(index3)->addEdge(edge); 00318 } 00319 00320 getEdge(edge)->addFace(indexface); 00321 00322 if (!getIndexEdge(index3,index4,edge)) { 00323 edge = addEdge(index3,index4); 00324 getVertex(index3)->addEdge(edge); 00325 getVertex(index4)->addEdge(edge); 00326 } 00327 00328 getEdge(edge)->addFace(indexface); 00329 00330 if (!getIndexEdge(index4,index1,edge)) { 00331 edge = addEdge(index4,index1); 00332 getVertex(index4)->addEdge(edge); 00333 getVertex(index1)->addEdge(edge); 00334 } 00335 00336 getEdge(edge)->addFace(indexface); 00337 00338 if ((index1 == index2) || (index1 == index3) || (index1 == index4) || 00339 (index2 == index3) || (index2 == index4) || (index3 == index4)) 00340 face->setTAG(BROKEN); 00341 00342 return m_faces.size()-1; 00343 } 00344 00351 bool BOP_Mesh::containsFace(BOP_Faces *faces, BOP_Face *face) 00352 { 00353 const BOP_IT_Faces facesEnd = faces->end(); 00354 for(BOP_IT_Faces it = faces->begin();it!=facesEnd;it++) { 00355 if (face == *it) 00356 return true; 00357 } 00358 00359 return false; 00360 } 00367 BOP_Edge* BOP_Mesh::getEdge(BOP_Indexs edges, BOP_Index v) 00368 { 00369 const BOP_IT_Indexs edgesEnd = edges.end(); 00370 for(BOP_IT_Indexs it=edges.begin();it!=edgesEnd;it++){ 00371 BOP_Edge *edge = m_edges[*it]; 00372 if ((edge->getVertex1() == v) || (edge->getVertex2() == v)) 00373 return edge; 00374 } 00375 return NULL; 00376 } 00377 00384 BOP_Edge* BOP_Mesh::getEdge(BOP_Index v1, BOP_Index v2) 00385 { 00386 #ifdef HASH 00387 int minv; 00388 EdgeEntry *edge; 00389 00390 /* figure out where and what to search for */ 00391 if( v1 < v2 ) { 00392 minv = HASH(v1); 00393 } else { 00394 minv = HASH(v2); 00395 BOP_Index tmp = v1; 00396 v1 = v2; 00397 v2 = tmp; 00398 } 00399 00400 /* if hash index valid, search the list and return match if found */ 00401 if( minv < hashsize ) { 00402 for(edge = (EdgeEntry *)hash[minv].first; 00403 edge; edge = edge->next ) { 00404 if(edge->v1 == v1 && edge->v2 == v2) 00405 return m_edges[edge->index]; 00406 } 00407 } 00408 #else 00409 const BOP_IT_Edges edgesEnd = m_edges.end(); 00410 for(BOP_IT_Edges edge=m_edges.begin();edge!=edgesEnd;edge++) { 00411 if (((*edge)->getVertex1() == v1 && (*edge)->getVertex2() == v2) || 00412 ((*edge)->getVertex1() == v2 && (*edge)->getVertex2() == v1)) 00413 return *edge; 00414 } 00415 #endif 00416 return NULL; 00417 } 00418 00426 bool BOP_Mesh::getIndexEdge(BOP_Index v1, BOP_Index v2, BOP_Index &e) 00427 { 00428 #ifdef HASH 00429 int minv; 00430 EdgeEntry *edge; 00431 00432 /* figure out what and where to look */ 00433 if( v1 < v2 ) { 00434 minv = HASH(v1); 00435 } else { 00436 minv = HASH(v2); 00437 BOP_Index tmp = v1; 00438 v1 = v2; 00439 v2 = tmp; 00440 } 00441 00442 /* if hash index is valid, look for a match */ 00443 if( minv < hashsize ) { 00444 for(edge = (EdgeEntry *)hash[minv].first; 00445 edge; edge = edge->next ) { 00446 if(edge->v1 == v1 && edge->v2 == v2) 00447 break; 00448 } 00449 00450 /* edge != NULL means match */ 00451 if(edge) { 00452 #ifdef HASH_PRINTF_DEBUG 00453 printf ("found edge (%d %d)\n",v1,v2); 00454 #endif 00455 e = edge->index; 00456 #ifdef BOP_NEW_MERGE 00457 if( m_edges[e]->getUsed() == false ) { 00458 m_edges[e]->setUsed(true); 00459 m_vertexs[v1]->addEdge(e); 00460 m_vertexs[v2]->addEdge(e); 00461 } 00462 #endif 00463 return true; 00464 } 00465 #ifdef HASH_PRINTF_DEBUG 00466 else 00467 printf ("didn't find edge (%d %d)\n",v1,v2); 00468 #endif 00469 } 00470 #else 00471 BOP_Index pos=0; 00472 const BOP_IT_Edges edgesEnd = m_edges.end(); 00473 for(BOP_IT_Edges edge=m_edges.begin();edge!=edgesEnd;edge++,pos++) { 00474 if (((*edge)->getVertex1() == v1 && (*edge)->getVertex2() == v2) || 00475 ((*edge)->getVertex1() == v2 && (*edge)->getVertex2() == v1)){ 00476 e = pos; 00477 return true; 00478 } 00479 } 00480 #endif 00481 return false; 00482 } 00483 00490 BOP_Edge* BOP_Mesh::getEdge(BOP_Face *face, unsigned int edge) 00491 { 00492 if (face->size()==3) 00493 return getEdge((BOP_Face3 *)face,edge); 00494 else 00495 return getEdge((BOP_Face4 *)face,edge); 00496 } 00497 00504 BOP_Edge* BOP_Mesh::getEdge(BOP_Face3 *face, unsigned int edge) 00505 { 00506 switch(edge){ 00507 case 1: 00508 return getEdge(m_vertexs[face->getVertex(0)]->getEdges(),face->getVertex(1)); 00509 case 2: 00510 return getEdge(m_vertexs[face->getVertex(1)]->getEdges(),face->getVertex(2)); 00511 case 3: 00512 return getEdge(m_vertexs[face->getVertex(2)]->getEdges(),face->getVertex(0)); 00513 }; 00514 00515 return NULL; 00516 } 00517 00524 BOP_Edge * BOP_Mesh::getEdge(BOP_Face4 *face, unsigned int edge) 00525 { 00526 switch(edge){ 00527 case 1: 00528 return getEdge(m_vertexs[face->getVertex(0)]->getEdges(),face->getVertex(1)); 00529 case 2: 00530 return getEdge(m_vertexs[face->getVertex(1)]->getEdges(),face->getVertex(2)); 00531 case 3: 00532 return getEdge(m_vertexs[face->getVertex(2)]->getEdges(),face->getVertex(3)); 00533 case 4: 00534 return getEdge(m_vertexs[face->getVertex(3)]->getEdges(),face->getVertex(0)); 00535 }; 00536 00537 return NULL; 00538 } 00539 00547 BOP_Face* BOP_Mesh::getFace(BOP_Index v1, BOP_Index v2, BOP_Index v3) 00548 { 00549 const BOP_IT_Faces facesEnd = m_faces.end(); 00550 for(BOP_IT_Faces face=m_faces.begin();face!=facesEnd;face++) { 00551 if ((*face)->containsVertex(v1) && (*face)->containsVertex(v2) && 00552 (*face)->containsVertex(v3)) 00553 return (*face); 00554 } 00555 return NULL; 00556 } 00557 00566 bool BOP_Mesh::getIndexFace(BOP_Index v1, BOP_Index v2, BOP_Index v3, BOP_Index &f) 00567 { 00568 BOP_Index pos=0; 00569 const BOP_IT_Faces facesEnd = m_faces.end(); 00570 for(BOP_IT_Faces face=m_faces.begin();face!=facesEnd;face++,pos++) { 00571 if ((*face)->containsVertex(v1) && (*face)->containsVertex(v2) && 00572 (*face)->containsVertex(v3)){ 00573 f = pos; 00574 return true; 00575 } 00576 } 00577 return false; 00578 } 00579 00584 BOP_Vertexs &BOP_Mesh::getVertexs() 00585 { 00586 return m_vertexs; 00587 } 00588 00593 BOP_Edges &BOP_Mesh::getEdges() 00594 { 00595 return m_edges; 00596 } 00597 00602 BOP_Faces &BOP_Mesh::getFaces() 00603 { 00604 return m_faces; 00605 } 00606 00612 BOP_Vertex* BOP_Mesh::getVertex(BOP_Index i) 00613 { 00614 return m_vertexs[i]; 00615 } 00616 00622 BOP_Edge* BOP_Mesh::getEdge(BOP_Index i) 00623 { 00624 return m_edges[i]; 00625 } 00626 00632 BOP_Face* BOP_Mesh::getFace(BOP_Index i) 00633 { 00634 return m_faces[i]; 00635 } 00636 00641 unsigned int BOP_Mesh::getNumVertexs() 00642 { 00643 return m_vertexs.size(); 00644 } 00645 00650 unsigned int BOP_Mesh::getNumEdges() 00651 { 00652 return m_edges.size(); 00653 } 00654 00659 unsigned int BOP_Mesh::getNumFaces() 00660 { 00661 return m_faces.size(); 00662 } 00663 00668 unsigned int BOP_Mesh::getNumVertexs(BOP_TAG tag) 00669 { 00670 unsigned int count = 0; 00671 const BOP_IT_Vertexs vertexsEnd = m_vertexs.end(); 00672 for(BOP_IT_Vertexs vertex=m_vertexs.begin();vertex!=vertexsEnd;vertex++) { 00673 if ((*vertex)->getTAG() == tag) count++; 00674 } 00675 return count; 00676 } 00681 unsigned int BOP_Mesh::getNumFaces(BOP_TAG tag) 00682 { 00683 unsigned int count = 0; 00684 const BOP_IT_Faces facesEnd = m_faces.end(); 00685 for(BOP_IT_Faces face=m_faces.begin();face!=facesEnd;face++) { 00686 if ((*face)->getTAG() == tag) count++; 00687 } 00688 return count; 00689 } 00690 00697 static void removeBrokenFaces( BOP_Edge *edge, BOP_Mesh *mesh ) 00698 { 00699 BOP_Faces m_faces = mesh->getFaces(); 00700 00701 BOP_Indexs edgeFaces = edge->getFaces(); 00702 const BOP_IT_Indexs edgeFacesEnd = edgeFaces.end(); 00703 for(BOP_IT_Indexs idxFace=edgeFaces.begin();idxFace!=edgeFacesEnd; 00704 idxFace++) 00705 m_faces[*idxFace]->setTAG(BROKEN); 00706 } 00707 00713 BOP_Index BOP_Mesh::replaceVertexIndex(BOP_Index oldIndex, BOP_Index newIndex) 00714 { 00715 BOP_IT_Indexs oldEdgeIndex; 00716 if (oldIndex==newIndex) return newIndex; 00717 00718 // Update faces, edges and vertices 00719 BOP_Vertex *oldVertex = m_vertexs[oldIndex]; 00720 BOP_Vertex *newVertex = m_vertexs[newIndex]; 00721 BOP_Indexs oldEdges = oldVertex->getEdges(); 00722 00723 // Update faces to the newIndex 00724 BOP_IT_Indexs oldEdgesEnd = oldEdges.end(); 00725 for(oldEdgeIndex=oldEdges.begin();oldEdgeIndex!=oldEdgesEnd; 00726 oldEdgeIndex++) { 00727 BOP_Edge *edge = m_edges[*oldEdgeIndex]; 00728 if ((edge->getVertex1()==oldIndex && edge->getVertex2()==newIndex) || 00729 (edge->getVertex2()==oldIndex && edge->getVertex1()==newIndex)) { 00730 // Remove old edge ==> set edge faces to BROKEN 00731 removeBrokenFaces( edge, this ); 00732 oldVertex->removeEdge(*oldEdgeIndex); 00733 newVertex->removeEdge(*oldEdgeIndex); 00734 } 00735 else { 00736 BOP_Indexs faces = edge->getFaces(); 00737 const BOP_IT_Indexs facesEnd = faces.end(); 00738 for(BOP_IT_Indexs face=faces.begin();face!=facesEnd;face++) { 00739 if (m_faces[*face]->getTAG()!=BROKEN) 00740 m_faces[*face]->replaceVertexIndex(oldIndex,newIndex); 00741 } 00742 } 00743 } 00744 00745 oldEdgesEnd = oldEdges.end(); 00746 for(oldEdgeIndex=oldEdges.begin();oldEdgeIndex!=oldEdgesEnd; 00747 oldEdgeIndex++) { 00748 BOP_Edge * edge = m_edges[*oldEdgeIndex]; 00749 BOP_Edge * edge2; 00750 BOP_Index v1 = edge->getVertex1(); 00751 00752 v1 = (v1==oldIndex?edge->getVertex2():v1); 00753 if ((edge2 = getEdge(newIndex,v1)) == NULL) { 00754 edge->replaceVertexIndex(oldIndex,newIndex); 00755 if ( edge->getVertex1() == edge->getVertex2() ) { 00756 removeBrokenFaces( edge, this ); 00757 oldVertex->removeEdge(*oldEdgeIndex); 00758 } 00759 #ifdef HASH 00760 rehashVertex(oldIndex,newIndex,v1); 00761 #endif 00762 newVertex->addEdge(*oldEdgeIndex); 00763 } 00764 else { 00765 BOP_Indexs faces = edge->getFaces(); 00766 const BOP_IT_Indexs facesEnd = faces.end(); 00767 for(BOP_IT_Indexs f=faces.begin();f!=facesEnd;f++) { 00768 if (m_faces[*f]->getTAG()!=BROKEN) 00769 edge2->addFace(*f); 00770 } 00771 BOP_Vertex *oppositeVertex = m_vertexs[v1]; 00772 oppositeVertex->removeEdge(*oldEdgeIndex); 00773 edge->replaceVertexIndex(oldIndex,newIndex); 00774 if ( edge->getVertex1() == edge->getVertex2() ) { 00775 removeBrokenFaces( edge, this ); 00776 oldVertex->removeEdge(*oldEdgeIndex); 00777 newVertex->removeEdge(*oldEdgeIndex); 00778 } 00779 #ifdef HASH 00780 rehashVertex(oldIndex,newIndex,v1); 00781 #endif 00782 } 00783 } 00784 oldVertex->setTAG(BROKEN); 00785 00786 return newIndex; 00787 } 00788 00789 bool BOP_Mesh::isClosedMesh() 00790 { 00791 for(unsigned int i=0; i<m_edges.size(); i++) { 00792 BOP_Edge *edge = m_edges[i]; 00793 BOP_Indexs faces = edge->getFaces(); 00794 unsigned int count = 0; 00795 const BOP_IT_Indexs facesEnd = faces.end(); 00796 for(BOP_IT_Indexs it = faces.begin();it!=facesEnd;it++) { 00797 if (m_faces[*it]->getTAG()!=BROKEN) 00798 count++; 00799 } 00800 00801 if ((count%2)!=0) return false; 00802 } 00803 00804 return true; 00805 } 00806 00807 00808 #ifdef BOP_DEBUG 00809 /****************************************************************************** 00810 * DEBUG METHODS * 00811 * This functions are used to test the mesh state and debug program errors. * 00812 ******************************************************************************/ 00813 00817 void BOP_Mesh::print() 00818 { 00819 unsigned int i; 00820 cout << "--Faces--" << endl; 00821 for(i=0;i<m_faces.size();i++){ 00822 cout << "Face " << i << ": " << m_faces[i] << endl; 00823 } 00824 00825 cout << "--Vertices--" << endl; 00826 for(i=0;i<m_vertexs.size();i++){ 00827 cout << "Point " << i << ": " << m_vertexs[i]->getPoint() << endl; 00828 } 00829 } 00830 00834 void BOP_Mesh::printFormat(BOP_Faces *faces) 00835 { 00836 if (faces->size()) { 00837 for(unsigned int it=1;it<faces->size();it++) { 00838 if ((*faces)[it]->getTAG()!=BROKEN) { 00839 cout << m_vertexs[(*faces)[it]->getVertex(0)]->getPoint() << " "; 00840 cout << m_vertexs[(*faces)[it]->getVertex(1)]->getPoint() << " "; 00841 cout << m_vertexs[(*faces)[it]->getVertex(2)]->getPoint() << endl; 00842 } 00843 } 00844 } 00845 } 00846 00850 void BOP_Mesh::saveFormat(BOP_Faces *faces,char *filename) 00851 { 00852 ofstream fout(filename); 00853 00854 if (!fout.is_open()) { 00855 cerr << "BOP_Mesh::saveFormat Error: Could not create file." << endl; 00856 return; 00857 } 00858 00859 unsigned int count = 0; 00860 if (faces->size()) { 00861 for(unsigned int it=0;it<faces->size();it++) { 00862 if ((*faces)[it]->getTAG()!=BROKEN) { 00863 count++; 00864 } 00865 } 00866 } 00867 00868 fout << count << endl; 00869 if (faces->size()) { 00870 for(unsigned int it=0;it<faces->size();it++) { 00871 if ((*faces)[it]->getTAG()!=BROKEN){ 00872 fout << m_vertexs[(*faces)[it]->getVertex(0)]->getPoint() << " "; 00873 fout << m_vertexs[(*faces)[it]->getVertex(1)]->getPoint() << " "; 00874 fout << m_vertexs[(*faces)[it]->getVertex(2)]->getPoint() << endl; 00875 } 00876 } 00877 } 00878 00879 fout.close(); 00880 } 00881 00885 void BOP_Mesh::printFormat() 00886 { 00887 cout << "--Vertices--" << endl; 00888 if (m_vertexs.size()>0) { 00889 cout << "{" << m_vertexs[0]->getPoint().x() << ","; 00890 cout << m_vertexs[0]->getPoint().y() << ","; 00891 cout << m_vertexs[0]->getPoint().z() << "}"; 00892 for(unsigned int i=1;i<m_vertexs.size();i++) { 00893 cout << ",{" << m_vertexs[i]->getPoint().x() << ","; 00894 cout << m_vertexs[i]->getPoint().y() << ","; 00895 cout << m_vertexs[i]->getPoint().z() << "}"; 00896 } 00897 cout << endl; 00898 } 00899 00900 cout << "--Faces--" << endl; 00901 if (m_faces.size()>0) { 00902 cout << "{" << m_faces[0]->getVertex(0) << ","; 00903 cout << m_faces[0]->getVertex(1) << "," << m_faces[0]->getVertex(2) << "}"; 00904 for(unsigned int i=1;i<m_faces.size();i++) { 00905 cout << ",{" << m_faces[i]->getVertex(0) << ","; 00906 cout << m_faces[i]->getVertex(1) << "," << m_faces[i]->getVertex(2) << "}"; 00907 } 00908 cout << endl; 00909 } 00910 } 00911 00915 void BOP_Mesh::printFace(BOP_Face *face, int col) 00916 { 00917 cout << "--Face" << endl; 00918 cout << m_vertexs[face->getVertex(0)]->getPoint(); 00919 cout << " " << m_vertexs[face->getVertex(1)]->getPoint(); 00920 cout << " " << m_vertexs[face->getVertex(2)]->getPoint(); 00921 if (face->size()==4) 00922 cout << " " << m_vertexs[face->getVertex(3)]->getPoint(); 00923 cout << " " << col << endl; 00924 } 00925 00929 void BOP_Mesh::testMesh() 00930 { 00931 00932 BOP_Face* cares[10]; 00933 unsigned int nedges=0,i; 00934 for(i=0;i<m_edges.size();i++) { 00935 BOP_Edge *edge = m_edges[i]; 00936 BOP_Indexs faces = edge->getFaces(); 00937 unsigned int count = 0; 00938 const BOP_IT_Indexs facesEnd = faces.end(); 00939 for(BOP_IT_Indexs it = faces.begin();it!=facesEnd;it++) { 00940 if (m_faces[*it]->getTAG()!=BROKEN) { 00941 cares[count] = m_faces[*it]; 00942 count++; 00943 00944 } 00945 } 00946 00947 if ((count%2)!=0) nedges++; 00948 } 00949 if (nedges) 00950 cout << nedges << " wrong edges." << endl; 00951 else 00952 cout << "well edges." << endl; 00953 00954 unsigned int duplFaces = 0; 00955 unsigned int wrongFaces = 0; 00956 for(i=0;i<m_faces.size();i++){ 00957 BOP_Face *faceI = m_faces[i]; 00958 if (faceI->getTAG()==BROKEN) 00959 continue; 00960 00961 if (testFace(faceI)){ 00962 wrongFaces++; 00963 cout << "Wrong Face: " << faceI << endl; 00964 } 00965 00966 for(unsigned int j=i+1;j<m_faces.size();j++){ 00967 BOP_Face *faceJ = m_faces[j]; 00968 00969 if (faceJ->getTAG()==BROKEN) 00970 continue; 00971 00972 if (testFaces(faceI,faceJ)){ 00973 duplFaces++; 00974 cout << "Duplicate FaceI: " << faceI << endl; 00975 cout << "Duplicate FaceJ: " << faceJ << endl; 00976 } 00977 } 00978 } 00979 00980 cout << duplFaces << " duplicate faces." << endl; 00981 cout << wrongFaces << " wrong faces." << endl; 00982 } 00983 00987 bool BOP_Mesh::testFace(BOP_Face *face){ 00988 00989 for(unsigned int i=0;i<face->size();i++){ 00990 for(unsigned int j=i+1;j<face->size();j++){ 00991 if (face->getVertex(i)==face->getVertex(j)) 00992 return true; 00993 } 00994 } 00995 00996 return false; 00997 } 00998 01002 bool BOP_Mesh::testFaces(BOP_Face *faceI, BOP_Face *faceJ){ 01003 01004 if (faceI->size()<faceJ->size()){ 01005 for(unsigned int i=0;i<faceI->size();i++){ 01006 if (!faceJ->containsVertex(faceI->getVertex(i))) 01007 return false; 01008 } 01009 //faceI->setTAG(BROKEN); 01010 } 01011 else{ 01012 for(unsigned int i=0;i<faceJ->size();i++){ 01013 if (!faceI->containsVertex(faceJ->getVertex(i))) 01014 return false; 01015 } 01016 //faceJ->setTAG(BROKEN); 01017 } 01018 01019 return true; 01020 } 01021 01025 void BOP_Mesh::testPlane(BOP_Face *face) 01026 { 01027 MT_Plane3 plane1(m_vertexs[face->getVertex(0)]->getPoint(), 01028 m_vertexs[face->getVertex(1)]->getPoint(), 01029 m_vertexs[face->getVertex(2)]->getPoint()); 01030 01031 if (BOP_orientation(plane1,face->getPlane()) < 0) { 01032 cout << "Test Plane " << face << " v1: "; 01033 cout << m_vertexs[face->getVertex(0)]->getPoint() << " v2: "; 01034 cout << m_vertexs[face->getVertex(1)]->getPoint() << " v3: "; 01035 cout << m_vertexs[face->getVertex(2)]->getPoint() << " plane: "; 01036 cout << face->getPlane() << endl; 01037 cout << "Incorrect vertices order!!! plane1: " << plane1 << " ("; 01038 cout << BOP_orientation(plane1,face->getPlane()) << ") " << " invert "; 01039 cout << MT_Plane3(m_vertexs[face->getVertex(2)]->getPoint(), 01040 m_vertexs[face->getVertex(1)]->getPoint(), 01041 m_vertexs[face->getVertex(0)]->getPoint()) << endl; 01042 if (BOP_collinear(m_vertexs[face->getVertex(0)]->getPoint(), 01043 m_vertexs[face->getVertex(1)]->getPoint(), 01044 m_vertexs[face->getVertex(2)]->getPoint())) { 01045 cout << " COLLINEAR!!!" << endl; 01046 } 01047 else { 01048 cout << endl; 01049 } 01050 } 01051 } 01052 01056 bool BOP_Mesh::testEdges(BOP_Faces *facesObj) 01057 { 01058 for(unsigned int i=0;i<m_edges.size();i++) { 01059 BOP_Edge *edge = m_edges[i]; 01060 BOP_Indexs faces = edge->getFaces(); 01061 unsigned int count = 0; 01062 const BOP_IT_Indexs facesEnd = faces.end(); 01063 for(BOP_IT_Indexs it = faces.begin();it!=facesEnd;it++) { 01064 if ((m_faces[*it]->getTAG()!=BROKEN) && containsFace(facesObj,m_faces[*it])) 01065 count++; 01066 } 01067 if ((count%2)!=0) { 01068 return false; 01069 } 01070 } 01071 01072 return true; 01073 } 01074 01078 void BOP_Mesh::updatePlanes() 01079 { 01080 const BOP_IT_Faces facesEnd = m_faces.end(); 01081 for(BOP_IT_Faces it = m_faces.begin();it!=facesEnd;it++) { 01082 BOP_Face *face = *it; 01083 MT_Plane3 plane(m_vertexs[face->getVertex(0)]->getPoint(), 01084 m_vertexs[face->getVertex(1)]->getPoint(), 01085 m_vertexs[face->getVertex(2)]->getPoint()); 01086 face->setPlane(plane); 01087 } 01088 } 01089 01090 #endif