a48  2.0.2
include/adaptivemesht.hh
Go to the documentation of this file.
00001 
00008 #ifndef A48_ADAPTIVEMESHT_HH
00009 #define A48_ADAPTIVEMESHT_HH
00010 
00011 //== INCLUDES =================================================================
00012 
00013 #include <stellarmesht.hh>
00014 
00015 //== NAMESPACES ===============================================================
00016 
00017 namespace a48 {
00018 
00019 //== CLASS DEFINITION =========================================================
00020 
00029 class DefaultAdaptiveTraits {
00030 public:
00031     typedef AdaptiveVertexT< DefaultAdaptiveTraits > vertex_type; 
00032     typedef AdaptiveHalfedgeT< DefaultAdaptiveTraits > halfedge_type; 
00033     typedef AdaptiveFaceT< DefaultAdaptiveTraits > face_type; 
00034 };
00041 //== CLASS DEFINITION =========================================================
00042 
00052 template< class Traits = DefaultAdaptiveTraits >
00053 class BaseAdaptivePolicy {
00054 
00055     typedef typename Traits::vertex_type vertex_type; 
00056     typedef typename Traits::halfedge_type halfedge_type; 
00057     typedef typename Traits::face_type face_type; 
00058 
00059 public:
00060 
00064     virtual void update_simplification( vertex_type *v ) = 0;
00065 
00069     virtual void update_simplification( halfedge_type *h ) = 0;
00070 
00081     virtual void update_simplification( void ) = 0;
00082 
00086     virtual void update_refinement( halfedge_type *h ) = 0;
00087 
00091     virtual void update_refinement( vertex_type *v ) = 0;
00092 
00103     virtual void update_refinement( void ) = 0;
00104 
00113     virtual vertex_type* next_simplify_vertex( void ) = 0;
00114 
00123     virtual halfedge_type* next_refine_halfedge( void ) = 0;
00124 
00125 };
00132 //== CLASS DEFINITION =========================================================
00133 
00158 template< class Traits = DefaultAdaptiveTraits >
00159 class AdaptiveMeshT : public StellarMeshT< Traits > {
00160 
00161 public:
00162 
00163     typedef BaseItemsPolicy< Traits > items_policy; 
00164     typedef BaseStellarPolicy< Traits > stellar_policy; 
00165     typedef BaseAdaptivePolicy< Traits > adaptive_policy; 
00166 
00167     typedef typename Traits::vertex_type vertex_type; 
00168     typedef typename Traits::halfedge_type halfedge_type; 
00169     typedef typename Traits::face_type face_type; 
00170 
00172     AdaptiveMeshT() : StellarMeshT< Traits >(), ap(0) { }
00173 
00178     AdaptiveMeshT( adaptive_policy *_ap ) : StellarMeshT< Traits >(), ap(_ap) { }
00179 
00188     AdaptiveMeshT( items_policy *_ip,
00189                    stellar_policy *_sp = 0,
00190                    adaptive_policy *_ap = 0 ) :
00191         StellarMeshT< Traits >(_ip,_sp), ap(_ap) { }
00192 
00196     AdaptiveMeshT( const AdaptiveMeshT< Traits >& _m ) { *this = _m; }
00197 
00202     AdaptiveMeshT< Traits >& operator = ( const AdaptiveMeshT< Traits >& _m ) {
00203         this->ap = _m.get_adaptive_policy();
00204         StellarMeshT< Traits >::operator = ( _m );
00205         return *this;
00206     }
00207 
00208     // @name Query functions
00210 
00220     bool is_triquad( void ) const {
00221         unsigned int she = 0; 
00222         for (typename StellarMeshT< Traits >::halfedge_const_iterator
00223                  hit = this->halfedges_begin(); hit != this->halfedges_end(); ++hit)
00224             if( (*hit)->is_split() and ( (*hit)->is_boundary() or (*hit)->opposite()->is_split() ) )
00225                 ++she;
00226         // Boundary faces are considered to have a matching
00227         // null face so their corresponding split halfedge can
00228         // be at the boundary
00229         if( she != this->size_of_faces() ) return false;
00230         return true;
00231     }
00232 
00234 
00235     // @name Set functions
00237 
00242     void set_adaptive_policy( adaptive_policy *_ap ) { ap = _ap; }
00243 
00245 
00246     // @name Get functions
00248 
00253     adaptive_policy* get_adaptive_policy( void ) { return ap; }
00254 
00258     const adaptive_policy* get_adaptive_policy( void ) const { return ap; }
00259 
00261 
00262     // @name Adaptation methods for a stellar mesh
00264 
00269     void simplify( vertex_type *v ) {
00270         if( v->level() == 0 ) return;
00271         unsigned int d = v->degree(), weld_deg = v->is_boundary() ? 3 : 4;
00272         unsigned int max_level;
00273         vertex_type *vneigh, *vmax;
00274         halfedge_type *hcurr;
00275         do {
00276             max_level = v->level();
00277             vmax = 0;
00278             hcurr = v->halfedge();
00279             do { // Trying to find a max-level neighbor vertex
00280                 vneigh = hcurr->next()->vertex();
00281                 hcurr = hcurr->next()->opposite();
00282                 if( vneigh->level() > max_level ) {
00283                     max_level = vneigh->level();
00284                     vmax = vneigh;
00285                 }
00286             } while( hcurr and hcurr != v->halfedge() );
00287             if( vmax ) // If there is such a vertex
00288                 simplify( vmax ); // Simplify it
00289             else break; // If not, leave
00290             d = v->degree(); // degree may change in recursion
00291         } while( d > weld_deg );
00292         if( !v->is_weld() ) return; // verify if this vertex may be welded
00293         hcurr = v->halfedge();
00294         if( ap ) ap->update_simplification( v ); // @see BaseAdaptivePolicy
00295         this->weld( v );
00296         if( ap ) ap->update_simplification( hcurr ); // @see BaseAdaptivePolicy
00297     }
00298 
00303     void refine( halfedge_type *h ) {
00304         halfedge_type *h0 = h->face()->split_halfedge();
00305         halfedge_type *h1 = ( h->is_boundary() ) ? 0 :
00306             h->opposite()->face()->split_halfedge();
00307         if( h0 != h ) refine( h0 );
00308         if( h1 and h1 != h->opposite() ) refine( h1 );
00309         if( ap ) ap->update_refinement( h ); // @see BaseAdaptivePolicy
00310         unsigned int l0 = h->face()->level(),
00311             l1 = ( h->is_boundary() ) ? 0 : h->opposite()->face()->level();
00312         this->split( h );
00313         h->vertex()->set_level( std::max( l0, l1 ) + 1 );
00314         if( ap ) ap->update_refinement( h->vertex() ); // @see BaseAdaptivePolicy
00315     }
00316 
00320     void adapt_simplify( void ) {
00321         if( !ap ) return; // @see BaseAdaptivePolicy
00322         ap->update_simplification();
00323         vertex_type *v = ap->next_simplify_vertex();
00324         while( v ) {
00325             this->simplify( v );
00326             v = ap->next_simplify_vertex();
00327         }
00328     }
00329 
00333     void adapt_refine( void ) {
00334         if( !ap ) return; // @see BaseAdaptivePolicy
00335         ap->update_refinement();
00336         halfedge_type *h = ap->next_refine_halfedge();
00337         while( h ) {
00338             this->refine( h );
00339             h = ap->next_refine_halfedge();
00340         }
00341     }
00342 
00344 
00345 private:
00346 
00347     adaptive_policy *ap; 
00348 
00349 };
00356 //=============================================================================
00357 } // namespace a48
00358 //=============================================================================
00359 #endif // A48_ADAPTIVEMESHT_HH
00360 //=============================================================================
 All Classes Namespaces Files Functions Typedefs