a48
2.0.2
|
00001 00008 #ifndef A48_MESHT_HH 00009 #define A48_MESHT_HH 00010 00011 //== INCLUDES ================================================================= 00012 00013 #include <set> 00014 #include <map> 00015 #include <vector> 00016 00017 #include <vertext.hh> 00018 #include <halfedget.hh> 00019 #include <facet.hh> 00020 00021 //== NAMESPACES =============================================================== 00022 00023 namespace a48 { 00024 00025 //== CLASS DEFINITION ========================================================= 00026 00035 class DefaultTraits { 00036 public: 00037 typedef VertexT< DefaultTraits > vertex_type; 00038 typedef HalfedgeT< DefaultTraits > halfedge_type; 00039 typedef FaceT< DefaultTraits > face_type; 00040 }; 00047 //== CLASS DEFINITION ========================================================= 00048 00058 template< class Traits = DefaultTraits > 00059 class BaseItemsPolicy { 00060 00061 typedef typename Traits::vertex_type vertex_type; 00062 typedef typename Traits::halfedge_type halfedge_type; 00063 typedef typename Traits::face_type face_type; 00064 00065 public: 00066 00071 virtual void set_vertex_attributes( vertex_type *v1, const vertex_type *v0 ) = 0; 00072 00082 virtual void set_vertex_attributes( const unsigned int& i, vertex_type *v ) = 0; 00083 00088 virtual void set_halfedge_attributes( halfedge_type *h1, const halfedge_type *h0 ) = 0; 00089 00094 virtual void set_halfedge_attributes( halfedge_type *h, halfedge_type *o ) = 0; 00095 00106 virtual void set_halfedge_attributes( const unsigned int& i, const unsigned int& j, const unsigned int& hi, halfedge_type *h ) = 0; 00107 00112 virtual void set_face_attributes( face_type *f1, const face_type *f0 ) = 0; 00113 00123 virtual void set_face_attributes( const unsigned int& i, face_type *f ) = 0; 00124 00125 }; 00132 //== CLASS DEFINITION ========================================================= 00133 00150 template< class Traits = DefaultTraits > 00151 class MeshT { 00152 00153 public: 00154 00155 typedef BaseItemsPolicy< Traits > items_policy; 00156 00157 typedef typename Traits::vertex_type vertex_type; 00158 typedef typename Traits::halfedge_type halfedge_type; 00159 typedef typename Traits::face_type face_type; 00160 00161 typedef typename halfedge_type::edge_type edge_type; 00162 00163 typedef typename std::set< vertex_type* > vertex_container; 00164 typedef typename std::set< halfedge_type* > halfedge_container; 00165 typedef typename std::set< face_type* > face_container; 00166 00167 typedef typename vertex_container::iterator vertex_iterator; 00168 typedef typename vertex_container::const_iterator vertex_const_iterator; 00169 00170 typedef typename halfedge_container::iterator halfedge_iterator; 00171 typedef typename halfedge_container::const_iterator halfedge_const_iterator; 00172 00173 typedef typename face_container::iterator face_iterator; 00174 typedef typename face_container::const_iterator face_const_iterator; 00175 00177 MeshT() : vc(), hc(), fc(), ip(0) { } 00178 00183 MeshT( items_policy *_ip ) : vc(), hc(), fc(), ip(_ip) { } 00184 00188 MeshT( const MeshT< Traits >& _m ) { *this = _m; } 00189 00191 ~MeshT() { this->clear(); } 00192 00194 void clear( void ) { 00195 for (vertex_iterator vit = vc.begin(); vit != vc.end(); ++vit) delete *vit; 00196 for (halfedge_iterator hit = hc.begin(); hit != hc.end(); ++hit) delete *hit; 00197 for (face_iterator fit = fc.begin(); fit != fc.end(); ++fit) delete *fit; 00198 vc.clear(); hc.clear(); fc.clear(); 00199 } 00200 00205 MeshT< Traits >& operator = ( const MeshT< Traits >& _m ) { 00206 this->ip = _m.get_items_policy(); 00207 std::map< vertex_type*, vertex_type* > vmap; // vertex map 00208 std::map< halfedge_type*, halfedge_type* > hmap; // halfedge map 00209 std::map< face_type*, face_type* > fmap; // face map 00210 this->clear(); // clear this mesh 00211 // Map copy mesh to this mesh 00212 for (vertex_iterator vit = _m.vertices_begin(); vit != _m.vertices_end(); ++vit) { 00213 vertex_type *v = this->add_vertex(); 00214 // Verify if the vertex type is adaptive and has a level value 00215 if( AdaptiveVertexT< Traits > *av = dynamic_cast< AdaptiveVertexT< Traits >* >(v) ) 00216 av->set_level( (*vit)->level() ); 00217 vmap[ *vit ] = v; 00218 } 00219 for (halfedge_iterator hit = _m.halfedges_begin(); hit != _m.halfedges_end(); ++hit) 00220 hmap[ *hit ] = this->add_halfedge(); 00221 for (face_iterator fit = _m.faces_begin(); fit != _m.faces_end(); ++fit) 00222 fmap[ *fit ] = this->add_face(); 00223 // Build this mesh filtering copy mesh inner structure 00224 for (vertex_iterator vit = _m.vertices_begin(); vit != _m.vertices_end(); ++vit) 00225 vmap[ *vit ]->set_halfedge( hmap[ (*vit)->halfedge() ] ); 00226 for (halfedge_iterator hit = _m.halfedges_begin(); hit != _m.halfedges_end(); ++hit) 00227 hmap[ *hit ]->set( vmap[ (*hit)->vertex() ], hmap[ (*hit)->next() ], 00228 hmap[ (*hit)->opposite() ], fmap[ (*hit)->face() ] ); 00229 for (face_iterator fit = _m.faces_begin(); fit != _m.faces_end(); ++fit) 00230 fmap[ *fit ]->set_halfedge( hmap[ (*fit)->halfedge() ] ); 00231 if( this->ip ) { // Set data structure attributes 00232 for (vertex_iterator vit = _m.vertices_begin(); vit != _m.vertices_end(); ++vit) 00233 this->ip->set_vertex_attributes( vmap[ *vit ], *vit ); 00234 for (halfedge_iterator hit = _m.halfedges_begin(); hit != _m.halfedges_end(); ++hit) 00235 this->ip->set_halfedge_attributes( hmap[ *hit ], *hit ); 00236 for (face_iterator fit = _m.faces_begin(); fit != _m.faces_end(); ++fit) 00237 this->ip->set_face_attributes( fmap[ *fit ], *fit ); 00238 } 00239 return *this; 00240 } 00241 00248 void fix_vertices_stars( void ) { 00249 for (halfedge_iterator hit = hc.begin(); hit != hc.end(); ++hit) 00250 if( (*hit)->is_boundary() ) 00251 (*hit)->vertex()->set_halfedge( *hit ); 00252 } 00253 00254 // @name Basic add and delete functions 00256 00260 vertex_type* add_vertex( void ) { return *vc.insert( new vertex_type() ).first; } 00261 00265 halfedge_type* add_halfedge( void ) { return *hc.insert( new halfedge_type() ).first; } 00266 00270 face_type* add_face( void ) { return *fc.insert( new face_type() ).first; } 00271 00275 void delete_vertex( vertex_type *_v ) { vc.erase( _v ); delete _v; } 00276 00280 void delete_halfedge( halfedge_type *_h ) { hc.erase( _h ); delete _h; } 00281 00285 void delete_face( face_type *_f ) { fc.erase( _f ); delete _f; } 00286 00288 00289 // @name Query functions 00291 00295 bool is_closed( void ) const { 00296 for (halfedge_const_iterator hit = hc.begin(); hit != hc.end(); ++hit) 00297 if( (*hit)->is_boundary() ) return false; 00298 return true; 00299 } 00300 00304 bool is_consistent( void ) const { 00305 for (halfedge_const_iterator hit = hc.begin(); hit != hc.end(); ++hit) 00306 if( !(*hit)->is_consistent() ) return false; 00307 return true; 00308 } 00309 00313 bool is_manifold( void ) const { 00314 // First, verifies if there is an isolated vertex not 00315 // connected to any face 00316 for (vertex_const_iterator vit = vc.begin(); vit != vc.end(); ++vit) 00317 if( !(*vit)->on_manifold() ) return false; 00318 // Second, verifies if there is more than two 00319 // halfedges representing the same edge 00320 std::map< edge_type, std::vector< halfedge_type* > > emap; // edge map 00321 edge_type e; // edge 00322 for (halfedge_const_iterator hit = hc.begin(); hit != hc.end(); ++hit) { 00323 (*hit)->edge(e); 00324 emap[e].push_back( *hit ); 00325 if( emap[e].size() > 2 ) return false; 00326 } 00327 emap.clear(); 00328 // Third, vertifies if there is a face juxtaposed with 00329 // another face 00330 std::map< edge_type, halfedge_type* > hmap; // halfedge map 00331 std::vector< vertex_type* > fv, hv; // face and halfedges vertices 00332 halfedge_type *h, *oh; // current and other halfedge 00333 bool eq; // equal flag (true if there is two faces juxtaposed) 00334 for (face_const_iterator fit = fc.begin(); fit != fc.end(); ++fit) { 00335 h = (*fit)->halfedge(); 00336 do { 00337 fv.push_back( h->vertex() ); 00338 h = h->next(); 00339 } while( h != (*fit)->halfedge() ); 00340 std::sort( fv.begin(), fv.end() ); 00341 h = (*fit)->halfedge(); 00342 do { 00343 h->edge(e); 00344 if( hmap.find( e ) == hmap.end() ) hmap[e] = h; 00345 else { 00346 oh = hmap[e]; 00347 do { 00348 hv.push_back( oh->vertex() ); 00349 oh = oh->next(); 00350 } while( oh != hmap[e] ); 00351 std::sort( hv.begin(), hv.end() ); 00352 eq = true; 00353 for (unsigned int i = 0; i < hv.size() or i < fv.size(); ++i) 00354 eq &= (hv[i] == fv[i]); 00355 if( eq ) return false; 00356 hv.clear(); 00357 } 00358 h = h->next(); 00359 } while( h != (*fit)->halfedge() ); 00360 fv.clear(); 00361 } 00362 hmap.clear(); 00363 return true; 00364 } 00365 00373 bool is_valid( void ) const { 00374 // First, verify for each vertex if it has a halfedge 00375 // and all subsequent points to it 00376 halfedge_type *fhe, *che; 00377 unsigned int n; 00378 for (vertex_const_iterator vit = vc.begin(); vit != vc.end(); ++vit) { 00379 che = fhe = (*vit)->halfedge(); 00380 n = 0; 00381 do { 00382 ++n; 00383 if( !che ) return false; 00384 if( che->vertex() != (*vit) ) return false; 00385 if( che->next()->is_boundary() ) break; 00386 if( n >= hc.size() ) return false; 00387 che = che->next()->opposite(); 00388 } while( che != fhe ); 00389 } 00390 // Second, verify for each halfedge if the next ones 00391 // and opposite return to it 00392 for (halfedge_const_iterator hit = hc.begin(); hit != hc.end(); ++hit) { 00393 che = fhe = (*hit); 00394 n = 0; 00395 do { 00396 ++n; 00397 if( !che->is_boundary() and che->opposite()->opposite() != che ) return false; 00398 if( n >= hc.size() ) return false; 00399 che = che->next(); 00400 } while( che != fhe ); 00401 } 00402 // Third, verify for each face, if all interior 00403 // halfedges point to it 00404 for (face_const_iterator fit = fc.begin(); fit != fc.end(); ++fit) { 00405 che = fhe = (*fit)->halfedge(); 00406 do { 00407 if( che->face() != (*fit) ) return false; 00408 che = che->next(); 00409 } while( che != fhe ); 00410 } 00411 return true; 00412 } 00413 00415 00416 // @name Set functions 00418 00437 void set_base( const unsigned int& nv, 00438 const unsigned int& nf, 00439 const unsigned int *conn, 00440 const unsigned int& nvf = 3 ) { 00441 this->clear(); // Clear all containers 00442 unsigned int i = 0; // Generic index i 00443 vertex_type **tvc = new vertex_type*[ nv ]; // Temporary vertex containter 00444 for (i = 0; i < nv; ++i) { // For each mesh vertex 00445 // The order inside vc is not guaranteed to complain 00446 // with the input order set by the conn array 00447 tvc[i] = this->add_vertex(); // Create new vertex 00448 if( ip ) ip->set_vertex_attributes( i, tvc[i] ); // @see BaseItemsPolicy 00449 } 00450 this->set_base( tvc, conn, nf, nvf ); 00451 delete [] tvc; // Clear temporary vertex container 00452 } 00453 00465 void set_base( vertex_type **verts, 00466 const unsigned int *conn, 00467 const unsigned int& nf, 00468 const unsigned int& nvf = 3 ) { 00469 unsigned int i, j, nj, hi; // Generic index i, j, next j and halfedge i 00470 halfedge_type *fhe, *che, *nhe; // Halfedge pointers: first, current and next 00471 face_type *f; // Face pointer 00472 typedef typename std::pair< unsigned int, unsigned int > edge_uint; 00473 std::map< edge_uint, halfedge_type* > hmap; // Halfedge map (B+-tree) 00474 edge_uint e; // Edge is two ordered vertex indices 00475 for (i = 0; i < nf; ++i) { // For each mesh face 00476 hi = i * nvf; // First halfedge index 00477 fhe = this->add_halfedge(); // Create first halfedge 00478 f = this->add_face(); // Create face 00479 if( ip ) ip->set_face_attributes( i, f ); // @see BaseItemsPolicy 00480 f->set_halfedge(fhe); // The face's halfedge is the first 00481 nhe = fhe; // Initialize the next halfedge as the first 00482 for (j = 0; j < nvf; ++j) { // For each halfedge of the current face 00483 nj = (j < (nvf-1) ? j+1 : 0); // Next j index 00484 che = nhe; // Update current halfedge as next halfedge 00485 if( j == nvf-1 ) nhe = fhe; // In the last iteration the next halfedge is the first 00486 else nhe = this->add_halfedge(); // Create next halfedge 00487 verts[ conn[hi+nj] ]->set_halfedge( che ); // The next vertex is pointed by the current halfedge 00488 // Set halfedge properties 00489 che->set_vertex( verts[ conn[hi+nj] ] ); 00490 che->set_next( nhe ); 00491 che->set_face( f ); 00492 // Find the other-side halfedge 00493 if( conn[hi+j] < conn[hi+nj] ) e = std::make_pair( conn[hi+j], conn[hi+nj] ); 00494 else e = std::make_pair( conn[hi+nj], conn[hi+j] ); 00495 if( hmap.find( e ) == hmap.end() ) { 00496 // If not found insert it in the B+-tree 00497 hmap[e] = che; 00498 if( ip ) ip->set_halfedge_attributes( conn[hi+j], conn[hi+nj], j, che ); // @see BaseItemsPolicy 00499 } else { // If found set both opposite halfedges 00500 che->set_opposite( hmap[e] ); 00501 hmap[e]->set_opposite( che ); 00502 if( ip ) { 00503 ip->set_halfedge_attributes( conn[hi+j], conn[hi+nj], j, che ); // @see BaseItemsPolicy 00504 ip->set_halfedge_attributes( che, hmap[e] ); // @see BaseItemsPolicy 00505 } 00506 } 00507 } 00508 // If all faces are given in the same 00509 // orientation there is no need to check if 00510 // two opposed halfedges are going in the same 00511 // direction @see is_consistent 00512 } 00513 this->fix_vertices_stars(); 00514 } 00515 00520 void set_items_policy( items_policy *_ip ) { ip = _ip; } 00521 00523 00524 // @name Get functions 00526 00530 unsigned int size_of_vertices( void ) const { return vc.size(); } 00531 00535 unsigned int size_of_halfedges( void ) const { return hc.size(); } 00536 00540 unsigned int size_of_faces( void ) const { return fc.size(); } 00541 00545 const vertex_container& set_of_vertices( void ) const { return vc; } 00546 00550 const halfedge_container& set_of_halfedges( void ) const { return hc; } 00551 00555 const face_container& set_of_faces( void ) const { return fc; } 00556 00561 items_policy* get_items_policy( void ) { return ip; } 00562 00566 const items_policy* get_items_policy( void ) const { return ip; } 00567 00569 00570 // @name Iterators to access mesh vertices, halfedges and faces 00572 00574 vertex_iterator vertices_begin( void ) { return vc.begin(); } 00576 vertex_const_iterator vertices_begin( void ) const { return vc.begin(); } 00577 00579 vertex_iterator vertices_end( void ) { return vc.end(); } 00581 vertex_const_iterator vertices_end( void ) const { return vc.end(); } 00582 00584 halfedge_iterator halfedges_begin( void ) { return hc.begin(); } 00586 halfedge_const_iterator halfedges_begin( void ) const { return hc.begin(); } 00587 00589 halfedge_iterator halfedges_end( void ) { return hc.end(); } 00591 halfedge_const_iterator halfedges_end( void ) const { return hc.end(); } 00592 00594 face_iterator faces_begin( void ) { return fc.begin(); } 00596 face_const_iterator faces_begin( void ) const { return fc.begin(); } 00597 00599 face_iterator faces_end( void ) { return fc.end(); } 00601 face_const_iterator faces_end( void ) const { return fc.end(); } 00602 00604 00605 private: 00606 00607 vertex_container vc; 00608 halfedge_container hc; 00609 face_container fc; 00610 items_policy *ip; 00611 00612 }; 00619 //============================================================================= 00620 } // namespace a48 00621 //============================================================================= 00622 #endif // A48_MESHT_HH 00623 //=============================================================================