a48
2.0.2
|
00001 00008 #ifndef A48_STELLARMESHT_HH 00009 #define A48_STELLARMESHT_HH 00010 00011 //== INCLUDES ================================================================= 00012 00013 #include <mesht.hh> 00014 00015 //== NAMESPACES =============================================================== 00016 00017 namespace a48 { 00018 00019 //== CLASS DEFINITION ========================================================= 00020 00030 template< class Traits = DefaultTraits > 00031 class BaseStellarPolicy { 00032 00033 typedef typename Traits::vertex_type vertex_type; 00034 typedef typename Traits::halfedge_type halfedge_type; 00035 typedef typename Traits::face_type face_type; 00036 00037 public: 00038 00043 virtual void sample_vertex( const face_type *f, vertex_type *v ) = 0; 00044 00052 virtual void sample_vertex( const halfedge_type *h, vertex_type *v ) = 0; 00053 00058 virtual void remove_vertex( const face_type *f, const vertex_type *v ) = 0; 00059 00067 virtual void remove_vertex( const halfedge_type *h, const vertex_type *v ) = 0; 00068 00075 virtual void flip_halfedge( const halfedge_type *h ) = 0; 00076 00077 }; 00084 //== CLASS DEFINITION ========================================================= 00085 00102 template< class Traits = DefaultTraits > 00103 class StellarMeshT : public MeshT< Traits > { 00104 00105 public: 00106 00107 typedef BaseItemsPolicy< Traits > items_policy; 00108 typedef BaseStellarPolicy< Traits > stellar_policy; 00109 00110 typedef typename Traits::vertex_type vertex_type; 00111 typedef typename Traits::halfedge_type halfedge_type; 00112 typedef typename Traits::face_type face_type; 00113 00115 StellarMeshT() : MeshT< Traits >(), sp(0) { } 00116 00121 StellarMeshT( stellar_policy *_sp ) : 00122 MeshT< Traits >(), sp(_sp) { } 00123 00130 StellarMeshT( items_policy *_ip, 00131 stellar_policy *_sp = 0 ) : 00132 MeshT< Traits >(_ip), sp(_sp) { } 00133 00137 StellarMeshT( const StellarMeshT< Traits >& _m ) { *this = _m; } 00138 00143 StellarMeshT< Traits >& operator = ( const StellarMeshT< Traits >& _m ) { 00144 this->sp = _m.get_stellar_policy(); 00145 MeshT< Traits >::operator = ( _m ); 00146 return *this; 00147 } 00148 00149 // @name Query functions 00151 00155 bool is_tri( void ) const { 00156 for (typename MeshT< Traits >::face_iterator fit = this->faces_begin(); fit != this->faces_end(); ++fit) 00157 if( !(*fit)->is_triangle() ) return false; 00158 return true; 00159 } 00160 00162 00163 // @name Set functions 00165 00170 void set_stellar_policy( stellar_policy *_sp ) { sp = _sp; } 00171 00173 00174 // @name Get functions 00176 00181 stellar_policy* get_stellar_policy( void ) { return sp; } 00182 00186 const stellar_policy* get_stellar_policy( void ) const { return sp; } 00187 00189 00190 // @name Stellar operators for a triangulated mesh 00192 00208 void edge_weld( halfedge_type *h1, halfedge_type *h2 ) { 00209 if( h1->is_boundary() and h2->is_boundary() ) { 00210 // Remove vertex attributes at the base halfedge 00211 if( sp ) sp->remove_vertex( h1, h1->vertex() ); // @see BaseStellarPolicy 00212 delete_vertex( h1->vertex() ); // After saving base halfedge it can be deleted 00213 half_weld( h1 ); // Half weld using base halfedge (unfolding two faces in one) 00214 } else if( h1->vertex()->degree() == 4 ) { weld( h1->vertex() ); } 00215 } 00216 00230 void face_weld( halfedge_type *h1, halfedge_type *h2, halfedge_type *h3 ) { 00231 if( h1->vertex()->degree() == 3 and h1->vertex() == h2->vertex() == h3->vertex() ) 00232 weld( h1->vertex() ); 00233 } 00234 00249 void edge_split( halfedge_type *h ) { split( h ); } 00250 00262 void face_split( face_type *f ) { split( f ); } 00263 00277 void flip( halfedge_type *h ) { 00278 if( h->is_boundary() ) return; 00279 if( !h->is_flip_ok() ) return; // Verify if the halfedge can be flipped 00280 // inform policy of the incoming flip 00281 if( sp ) sp->flip_halfedge( h ); // @see BaseStellarPolicy 00282 halfedge_type *ph = h->previous(); 00283 halfedge_type *nh = h->next(); 00284 ph->set_next( h->opposite()->next() ); 00285 nh->set_next( h->opposite() ); 00286 if( h->vertex()->halfedge() == h ) 00287 h->vertex()->set_halfedge( h->opposite()->previous() ); 00288 if( h->opposite()->vertex()->halfedge() == h->opposite() ) 00289 h->opposite()->vertex()->set_halfedge( ph ); 00290 h->set_vertex( h->next()->vertex() ); 00291 h->set_next( ph ); 00292 if( h->face()->halfedge() == nh ) 00293 h->face()->set_halfedge( h ); 00294 ph = h->opposite()->previous(); 00295 ph->set_next( nh ); 00296 h->opposite()->next()->set_next( h ); 00297 h->opposite()->next()->set_face( h->face() ); 00298 if( h->opposite()->face()->halfedge() == h->opposite()->next() ) 00299 h->opposite()->face()->set_halfedge( h->opposite() ); 00300 nh->set_face( h->opposite()->face() ); 00301 h->opposite()->set_vertex( h->previous()->vertex() ); 00302 h->opposite()->set_next( ph ); 00303 } 00304 00318 void unflip( halfedge_type *h ) { 00319 if( h->is_boundary() ) return; 00320 if( !h->is_flip_ok() ) return; // Verify if the halfedge can be flipped 00321 // inform policy of the incoming flip 00322 if( sp ) sp->flip_halfedge( h ); // @see BaseStellarPolicy 00323 halfedge_type *ph = h->previous(); 00324 halfedge_type *nh = h->next(); 00325 ph->set_next( h->opposite()->next() ); 00326 ph->set_face( h->opposite()->face() ); 00327 if( h->vertex()->halfedge() == h ) 00328 h->vertex()->set_halfedge( h->opposite()->previous() ); 00329 if( h->opposite()->vertex()->halfedge() == h->opposite() ) 00330 h->opposite()->vertex()->set_halfedge( ph ); 00331 h->set_vertex( h->opposite()->next()->vertex() ); 00332 h->set_next( h->opposite()->previous() ); 00333 if( h->face()->halfedge() == ph ) 00334 h->face()->set_halfedge( h ); 00335 ph = h->opposite()->previous(); 00336 ph->set_next( nh ); 00337 ph->set_face( h->face() ); 00338 h->opposite()->next()->set_next( h->opposite() ); 00339 if( h->opposite()->face()->halfedge() == ph ) 00340 h->opposite()->face()->set_halfedge( h->opposite() ); 00341 h->opposite()->set_vertex( nh->vertex() ); 00342 h->opposite()->set_next( nh->next() ); 00343 nh->set_next( h ); 00344 } 00345 00355 void weld( vertex_type *v ) { 00356 if( !v->is_weld_ok() ) return; // Verify if the vertex can be welded 00357 unsigned int nf = v->incident_faces(); // Number of incident faces 00358 halfedge_type *bh = v->halfedge(); // Base halfedge 00359 halfedge_type *oh; // Opposed halfedge 00360 if( sp and ( nf == 2 or nf == 4 ) ) sp->remove_vertex( bh, v ); // @see BaseStellarPolicy 00361 if( sp and nf == 3 ) sp->remove_vertex( bh->face(), v ); // @see BaseStellarPolicy 00362 delete_vertex( v ); // After saving base halfedge it can be deleted 00363 half_weld( bh ); // Half weld using base halfedge (unfolding two faces in one) 00364 if( nf == 2 ) return; // It is done if there is only two faces incident 00365 else if( nf == 3 ) { // Delete third face below the unfold face 00366 // The opposed halfedge to bh outside third face 00367 oh = bh->opposite()->next()->opposite(); 00368 // Set proper halfedges for vertices in the base halfedge 00369 if( bh->vertex()->halfedge() == bh->opposite()->next() ) 00370 bh->vertex()->set_halfedge( bh ); 00371 if( bh->opposite()->vertex()->halfedge() == bh->opposite() ) 00372 bh->opposite()->vertex()->set_halfedge( bh->previous() ); 00373 // Delete third face and its halfedges 00374 delete_face( bh->opposite()->face() ); 00375 delete_halfedge( bh->opposite()->previous() ); 00376 delete_halfedge( bh->opposite()->next() ); 00377 delete_halfedge( bh->opposite() ); 00378 // Set opposite halfedges of the base edge properly 00379 bh->set_opposite( oh ); 00380 if( oh ) oh->set_opposite( bh ); 00381 } else if( nf == 4 ) { 00382 // The opposed halfedge to bh pointing to the weld vertex 00383 oh = bh->opposite()->previous()->opposite()->previous(); 00384 // Half weld using opposed halfedge (unfolding two faces in one) 00385 half_weld( oh ); 00386 // Set opposite halfedge of the base edge properly 00387 bh->set_opposite( oh ); 00388 oh->set_opposite( bh ); 00389 } 00390 } 00391 00401 void split( halfedge_type *h ) { 00402 unsigned int nf = h->adjacent_faces(); // Number of adjacent faces 00403 vertex_type *v = this->add_vertex(); // Common middle vertex to create 00404 v->set_halfedge( h ); 00405 if( sp ) sp->sample_vertex( h, v ); // @see BaseStellarPolicy 00406 half_split( h, v ); // Half split using input halfedge (folding one face in two) 00407 if( nf == 1 ) return; // It is done if there is only one adjacent face 00408 halfedge_type *oh = h->opposite(); // The other-side halfedge 00409 half_split( oh, v ); // Half split the opposite input halfedge 00410 // Fix pointers of the four splitted halfedges 00411 h->next()->opposite()->next()->set_opposite( oh ); 00412 oh->set_opposite( h->next()->opposite()->next() ); 00413 oh->next()->opposite()->next()->set_opposite( h ); 00414 h->set_opposite( oh->next()->opposite()->next() ); 00415 } 00416 00428 void split( face_type *f0 ) { 00429 halfedge_type *h00 = f0->halfedge(); 00430 halfedge_type *h10 = h00->next(); 00431 halfedge_type *h20 = h10->next(); 00432 // Add new mesh elements 00433 vertex_type *v = this->add_vertex(); 00434 if( sp ) sp->sample_vertex( f0, v ); // @see BaseStellarPolicy 00435 halfedge_type *h01 = this->add_halfedge(); 00436 halfedge_type *h02 = this->add_halfedge(); 00437 halfedge_type *h11 = this->add_halfedge(); 00438 halfedge_type *h12 = this->add_halfedge(); 00439 halfedge_type *h21 = this->add_halfedge(); 00440 halfedge_type *h22 = this->add_halfedge(); 00441 face_type *f1 = this->add_face(); 00442 face_type *f2 = this->add_face(); 00443 // Set proper pointers of new elements 00444 f1->set_halfedge( h10 ); 00445 f2->set_halfedge( h20 ); 00446 h01->set( v, h02, h12, f0 ); h02->set( h20->vertex(), h00, h21, f0 ); 00447 h11->set( v, h12, h22, f1 ); h12->set( h00->vertex(), h10, h01, f1 ); 00448 h21->set( v, h22, h02, f2 ); h22->set( h10->vertex(), h20, h11, f2 ); 00449 v->set_halfedge( h01 ); 00450 // Fix pointers of reused elements 00451 h00->set_next( h01 ); 00452 h10->set( h11, f1 ); 00453 h20->set( h21, f2 ); 00454 } 00455 00457 00458 private: 00459 00472 void half_weld( halfedge_type *h ) { 00473 // Previous and next halfedge and opposed vertex (see figure above) 00474 halfedge_type *ph = h->previous(); 00475 halfedge_type *nh = h->next()->opposite()->previous(); 00476 vertex_type *ov = h->next()->opposite()->next()->vertex(); 00477 // Set proper halfedges for pointed vertices 00478 if( ov->halfedge() == h->next()->opposite()->next() ) 00479 ov->set_halfedge( h ); 00480 if( h->next()->vertex()->halfedge() == h->next() ) 00481 h->next()->vertex()->set_halfedge( nh ); 00482 // Set proper halfedge for reused face 00483 h->face()->set_halfedge( h ); 00484 // Delete second face and its halfedges (unfolding two faces in one) 00485 delete_face( h->next()->opposite()->face() ); 00486 delete_halfedge( h->next()->opposite()->next() ); 00487 delete_halfedge( h->next()->opposite() ); 00488 delete_halfedge( h->next() ); 00489 // Fix pointers of reused halfedges 00490 nh->set_face( h->face() ); 00491 nh->set_next( ph ); 00492 h->set_next( nh ); 00493 h->set_vertex( ov ); 00494 } 00495 00509 void half_split( halfedge_type *h, vertex_type *v ) { 00510 halfedge_type *nh = h->next(); 00511 vertex_type *ov = h->vertex(); 00512 // Add new mesh elements 00513 face_type *f = this->add_face(); 00514 halfedge_type *h1 = this->add_halfedge(); 00515 halfedge_type *h2 = this->add_halfedge(); 00516 halfedge_type *h3 = this->add_halfedge(); 00517 // Set proper pointers of new elements 00518 f->set_halfedge( nh ); 00519 h1->set( ov, nh, f ); 00520 h2->set( v, h1, h3, f ); 00521 h3->set( nh->vertex(), h->previous(), h2, h->face() ); 00522 // Fix pointers of reused elements 00523 if( ov->halfedge() == h ) ov->set_halfedge( h1 ); 00524 h->face()->set_halfedge( h->previous() ); 00525 h->set( v, h3 ); 00526 nh->set( h2, f ); 00527 } 00528 00529 stellar_policy *sp; 00530 00531 }; 00538 //============================================================================= 00539 } // namespace a48 00540 //============================================================================= 00541 #endif // A48_STELLARMESHT_HH 00542 //=============================================================================