a48  2.0.2
include/mesht.hh
Go to the documentation of this file.
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 //=============================================================================
 All Classes Namespaces Files Functions Typedefs