a48
2.0.2
|
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 //=============================================================================