57 #ifndef OPENMESH_SUBDIVIDER_UNIFORM_INTERP_SQRT3T_LABSIK_GREINER_HH 
   58 #define OPENMESH_SUBDIVIDER_UNIFORM_INTERP_SQRT3T_LABSIK_GREINER_HH 
   63 #include <OpenMesh/Core/Mesh/Handles.hh> 
   64 #include <OpenMesh/Core/System/config.hh> 
   67 #if defined(_DEBUG) || defined(DEBUG) 
   70 #  include <OpenMesh/Tools/Utils/MeshCheckerT.hh> 
   71 #  define ASSERT_CONSISTENCY( T, m ) \ 
   72      assert(OpenMesh::Utils::MeshCheckerT<T>(m).check()) 
   74 #  define ASSERT_CONSISTENCY( T, m ) 
   78 #if defined(OM_CC_MIPS) 
   90 namespace Subdivider { 
 
  105 template <
typename MeshType, 
typename RealType = 
double>
 
  110   typedef RealType                                real_t;
 
  111   typedef MeshType                                mesh_t;
 
  114   typedef std::vector< std::vector<real_t> >      weights_t;
 
  131   const char *
name()
 const override { 
return "Uniform Interpolating Sqrt3"; }
 
  136     weights_.resize(_max_valence);
 
  138     weights_[3].resize(4);
 
  139     weights_[3][0] = real_t(+4.0/27);
 
  140     weights_[3][1] = real_t(-5.0/27);
 
  141     weights_[3][2] = real_t(+4.0/27);
 
  142     weights_[3][3] = real_t(+8.0/9);
 
  144     weights_[4].resize(5);
 
  145     weights_[4][0] = real_t(+2.0/9);
 
  146     weights_[4][1] = real_t(-1.0/9);
 
  147     weights_[4][2] = real_t(-1.0/9);
 
  148     weights_[4][3] = real_t(+2.0/9);
 
  149     weights_[4][4] = real_t(+7.0/9);
 
  151     for(
unsigned int K=5; K<_max_valence; ++K)
 
  153         weights_[K].resize(K+1);
 
  154         double aH = 2.0*cos(M_PI/
static_cast<double>(K))/3.0;
 
  155         weights_[K][K] = 
static_cast<real_t
>(1.0 - aH*aH);
 
  156         for(
unsigned int i=0; i<K; ++i)
 
  159             weights_[K][i] = 
static_cast<real_t
>((aH*aH + 2.0*aH*cos(2.0*
static_cast<double>(i)*M_PI/
static_cast<double>(K) + M_PI/
static_cast<double>(K)) +
 
  160                                       2.0*aH*aH*cos(4.0*
static_cast<double>(i)*M_PI/
static_cast<double>(K) + 2.0*M_PI/
static_cast<double>(K)))/
static_cast<double>(K));
 
  165     weights_[6].resize(0);
 
  175     _m.request_edge_status();
 
  176     _m.add_property( fp_pos_ );
 
  177     _m.add_property( ep_nv_ );
 
  178     _m.add_property( mp_gen_ );
 
  179     _m.property( mp_gen_ ) = 0;
 
  181     return _m.has_edge_status() 
 
  188     _m.release_edge_status();
 
  189     _m.remove_property( fp_pos_ );
 
  190     _m.remove_property( ep_nv_ );
 
  191     _m.remove_property( mp_gen_ );
 
  196   bool subdivide( MeshType& _m, 
size_t _n , 
const bool _update_points = 
true)
 override 
  201     typename MeshType::VertexIter       vit;
 
  202     typename MeshType::VertexVertexIter vvit;
 
  203     typename MeshType::EdgeIter         eit;
 
  204     typename MeshType::FaceIter         fit;
 
  205     typename MeshType::FaceVertexIter   fvit;
 
  206     typename MeshType::FaceHalfedgeIter fheit;
 
  207     typename MeshType::VertexHandle     vh;
 
  208     typename MeshType::HalfedgeHandle   heh;
 
  209     typename MeshType::Point            pos(0,0,0), zero(0,0,0);
 
  210     size_t                              &gen = _m.property( mp_gen_ );
 
  212     for (
size_t l=0; l<_n; ++l)
 
  215       for (eit=_m.edges_begin(); eit != _m.edges_end();++eit)
 
  217         _m.status( *eit ).set_tagged( 
true );
 
  218         if ( (gen%2) && _m.is_boundary(*eit) )
 
  219           compute_new_boundary_points( _m, *eit ); 
 
  223       typename MeshType::FaceIter fend = _m.faces_end();
 
  224       for (fit = _m.faces_begin();fit != fend; ++fit)
 
  226         if (_m.is_boundary(*fit))
 
  229                 _m.property(fp_pos_, *fit).invalidate();
 
  233                 for( heh = _m.halfedge_handle(*fit); !_m.is_boundary( _m.opposite_halfedge_handle(heh) ); heh = _m.next_halfedge_handle(heh) )
 
  235                 assert(_m.is_boundary( _m.opposite_halfedge_handle(heh) ));
 
  238                 if( _m.is_boundary(_m.next_halfedge_handle(heh)) || _m.is_boundary(_m.prev_halfedge_handle(heh)) )
 
  240                     if(_m.is_boundary(_m.prev_halfedge_handle(heh)))
 
  241                         heh = _m.prev_halfedge_handle(heh); 
 
  243                     if(_m.is_boundary(_m.next_halfedge_handle(_m.next_halfedge_handle(heh))))
 
  246                         pos += real_t(1.0/3) * _m.point(_m.to_vertex_handle(heh));
 
  247                         pos += real_t(1.0/3) * _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(heh)));
 
  248                         pos += real_t(1.0/3) * _m.point(_m.to_vertex_handle(_m.prev_halfedge_handle(heh)));
 
  252 #ifdef MIRROR_TRIANGLES 
  254                         pos += real_t(2.0/9) * _m.point(_m.to_vertex_handle(heh));
 
  255                         pos += real_t(4.0/9) * _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(heh)));
 
  256                         pos += real_t(4.0/9) * _m.point(_m.to_vertex_handle(_m.prev_halfedge_handle(heh)));
 
  257                         pos += real_t(-1.0/9) * _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(_m.opposite_halfedge_handle(_m.prev_halfedge_handle(heh)))));
 
  259                         pos += real_t(7.0/24) * _m.point(_m.to_vertex_handle(heh));
 
  260                         pos += real_t(3.0/8) * _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(heh)));
 
  261                         pos += real_t(3.0/8) * _m.point(_m.to_vertex_handle(_m.prev_halfedge_handle(heh)));
 
  262                         pos += real_t(-1.0/24) * _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(_m.opposite_halfedge_handle(_m.prev_halfedge_handle(heh)))));
 
  268                     vh = _m.to_vertex_handle(_m.next_halfedge_handle(heh));
 
  270                     if((_m.valence(vh) == 6) || _m.is_boundary(vh))
 
  272 #ifdef MIRROR_TRIANGLES 
  274                         pos += real_t(5.0/9) * _m.point(vh);
 
  275                         pos += real_t(3.0/9) * _m.point(_m.to_vertex_handle(heh));
 
  276                         pos += real_t(3.0/9) * _m.point(_m.to_vertex_handle(_m.opposite_halfedge_handle(heh)));
 
  277                         pos += real_t(-1.0/9) * _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(_m.opposite_halfedge_handle(_m.next_halfedge_handle(heh)))));
 
  278                         pos += real_t(-1.0/9) * _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(_m.opposite_halfedge_handle(_m.prev_halfedge_handle(heh)))));
 
  281                         pos += real_t(1.0/9) * _m.point(vh);
 
  282                         pos += real_t(1.0/3) * _m.point(_m.to_vertex_handle(heh));
 
  283                         pos += real_t(1.0/3) * _m.point(_m.to_vertex_handle(_m.opposite_halfedge_handle(heh)));
 
  284                         pos += real_t(1.0/9) * _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(_m.opposite_halfedge_handle(_m.next_halfedge_handle(heh)))));
 
  285                         pos += real_t(1.0/9) * _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(_m.opposite_halfedge_handle(_m.prev_halfedge_handle(heh)))));
 
  287                         pos += real_t(1.0/2) * _m.point(vh);
 
  288                         pos += real_t(1.0/3) * _m.point(_m.to_vertex_handle(heh));
 
  289                         pos += real_t(1.0/3) * _m.point(_m.to_vertex_handle(_m.opposite_halfedge_handle(heh)));
 
  290                         pos += real_t(-1.0/12) * _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(_m.opposite_halfedge_handle(_m.next_halfedge_handle(heh)))));
 
  291                         pos += real_t(-1.0/12) * _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(_m.opposite_halfedge_handle(_m.prev_halfedge_handle(heh)))));
 
  298                         unsigned int K = _m.valence(vh);
 
  299                         pos += weights_[K][K]*_m.point(vh);
 
  300                         heh = _m.opposite_halfedge_handle( _m.next_halfedge_handle(heh) );
 
  301                         for(
unsigned int i = 0; i<K; ++i, heh = _m.opposite_halfedge_handle(_m.prev_halfedge_handle(heh)) )
 
  303                             pos += weights_[K][i]*_m.point(_m.to_vertex_handle(heh));
 
  307                 vh   = _m.add_vertex( pos );
 
  308                 _m.property(fp_pos_, *fit) = vh;
 
  317             for(fvit = _m.fv_iter( *fit ); fvit.is_valid(); ++fvit)
 
  318                 if( (_m.valence(*fvit)) == 6 || _m.is_boundary(*fvit) )
 
  323                 for(fheit = _m.fh_iter( *fit ); fheit.is_valid(); ++fheit)
 
  327                     assert(_m.to_vertex_handle(heh).is_valid());
 
  328                     pos += real_t(32.0/81) * _m.point(_m.to_vertex_handle(heh));
 
  330                     heh = _m.opposite_halfedge_handle(heh);
 
  331                     assert(heh.is_valid());
 
  332                     assert(_m.next_halfedge_handle(heh).is_valid());
 
  333                     assert(_m.to_vertex_handle(_m.next_halfedge_handle(heh)).is_valid());
 
  334                     pos -= real_t(1.0/81) * _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(heh)));
 
  336                     heh = _m.opposite_halfedge_handle(_m.prev_halfedge_handle(heh));
 
  337                     assert(heh.is_valid());
 
  338                     assert(_m.next_halfedge_handle(heh).is_valid());
 
  339                     assert(_m.to_vertex_handle(_m.next_halfedge_handle(heh)).is_valid());
 
  340                     pos -= real_t(2.0/81) * _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(heh)));
 
  341                     heh = _m.opposite_halfedge_handle(_m.prev_halfedge_handle(heh));
 
  342                     assert(heh.is_valid());
 
  343                     assert(_m.next_halfedge_handle(heh).is_valid());
 
  344                     assert(_m.to_vertex_handle(_m.next_halfedge_handle(heh)).is_valid());
 
  345                     pos -= real_t(2.0/81) * _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(heh)));
 
  351                 for(fheit = _m.fh_iter( *fit ); fheit.is_valid(); ++fheit)
 
  353                     vh = _m.to_vertex_handle(*fheit);
 
  354                     if( (_m.valence(vh) != 6) && (!_m.is_boundary(vh)) )
 
  356                         unsigned int K = _m.valence(vh);
 
  357                         pos += weights_[K][K]*_m.point(vh);
 
  358                         heh = _m.opposite_halfedge_handle( *fheit );
 
  359                         for(
unsigned int i = 0; i<K; ++i, heh = _m.opposite_halfedge_handle(_m.prev_halfedge_handle(heh)) )
 
  361                             pos += weights_[K][i]*_m.point(_m.to_vertex_handle(heh));
 
  365                 pos *= real_t(1.0/(3-nOrdinary));
 
  368             vh   = _m.add_vertex( pos );
 
  369             _m.property(fp_pos_, *fit) = vh;
 
  374       for (fit = _m.faces_begin();fit != fend; ++fit)
 
  376         if ( _m.is_boundary(*fit) && (gen%2))
 
  378                 boundary_split( _m, *fit );
 
  382             assert(_m.property(fp_pos_, *fit).is_valid());
 
  383             _m.split( *fit, _m.property(fp_pos_, *fit) );
 
  388       for (eit=_m.edges_begin(); eit != _m.edges_end(); ++eit)
 
  389         if ( _m.status( *eit ).tagged() && !_m.is_boundary( *eit ) )
 
  393       ASSERT_CONSISTENCY( MeshType, _m );
 
  405   void compute_new_boundary_points( MeshType& _m, 
 
  406                                     const typename MeshType::EdgeHandle& _eh)
 
  408     assert( _m.is_boundary(_eh) );
 
  410     typename MeshType::HalfedgeHandle heh;
 
  411     typename MeshType::VertexHandle   vh1, vh2, vh3, vh4, vhl, vhr;
 
  412     typename MeshType::Point          P1, P2, P3, P4;
 
  427     heh = _m.halfedge_handle(_eh, 
 
  428                              _m.is_boundary(_m.halfedge_handle(_eh,1)));
 
  430     assert( _m.is_boundary( _m.next_halfedge_handle( heh ) ) );
 
  431     assert( _m.is_boundary( _m.prev_halfedge_handle( heh ) ) );
 
  433     vh1 = _m.to_vertex_handle( _m.next_halfedge_handle( heh ) );
 
  434     vh2 = _m.to_vertex_handle( heh );
 
  435     vh3 = _m.from_vertex_handle( heh );
 
  436     vh4 = _m.from_vertex_handle( _m.prev_halfedge_handle( heh ));
 
  443     vhl = _m.add_vertex(real_t(-5.0/81)*P1 + real_t(20.0/27)*P2 + real_t(10.0/27)*P3 + real_t(-4.0/81)*P4);
 
  444     vhr = _m.add_vertex(real_t(-5.0/81)*P4 + real_t(20.0/27)*P3 + real_t(10.0/27)*P2 + real_t(-4.0/81)*P1);
 
  446     _m.property(ep_nv_, _eh).first  = vhl;
 
  447     _m.property(ep_nv_, _eh).second = vhr; 
 
  451   void boundary_split( MeshType& _m, 
const typename MeshType::FaceHandle& _fh )
 
  453     assert( _m.is_boundary(_fh) );
 
  455     typename MeshType::VertexHandle     vhl, vhr;
 
  456     typename MeshType::FaceEdgeIter     fe_it;
 
  457     typename MeshType::HalfedgeHandle   heh;
 
  460     for( fe_it=_m.fe_iter( _fh ); fe_it.is_valid() && !_m.is_boundary( *fe_it ); ++fe_it ) {};
 
  463     vhl = _m.property(ep_nv_, *fe_it).first;
 
  464     vhr = _m.property(ep_nv_, *fe_it).second;
 
  479     heh = _m.halfedge_handle(*fe_it, _m.is_boundary(_m.halfedge_handle(*fe_it,0)));
 
  481     typename MeshType::HalfedgeHandle pl_P3;
 
  484     boundary_split( _m, heh, vhl );         
 
  485     pl_P3 = _m.next_halfedge_handle( heh ); 
 
  486     boundary_split( _m, heh );              
 
  489     boundary_split( _m, pl_P3, vhr );
 
  490     boundary_split( _m, pl_P3 );
 
  492     assert( _m.is_boundary( vhl ) && _m.halfedge_handle(vhl).is_valid() );
 
  493     assert( _m.is_boundary( vhr ) && _m.halfedge_handle(vhr).is_valid() );
 
  496   void boundary_split(MeshType& _m, 
 
  497                       const typename MeshType::HalfedgeHandle& _heh,
 
  498                       const typename MeshType::VertexHandle& _vh)
 
  500     assert( _m.is_boundary( _m.edge_handle(_heh) ) );
 
  502     typename MeshType::HalfedgeHandle 
 
  504       opp_heh( _m.opposite_halfedge_handle(_heh) ),
 
  505       new_heh, opp_new_heh;
 
  506     typename MeshType::VertexHandle   to_vh(_m.to_vertex_handle(heh));
 
  507     typename MeshType::HalfedgeHandle t_heh;
 
  528         _m.next_halfedge_handle(t_heh) != opp_heh; 
 
  529         t_heh = _m.opposite_halfedge_handle(_m.next_halfedge_handle(t_heh)))
 
  532     assert( _m.is_boundary( t_heh ) );
 
  534     new_heh     = _m.new_edge( _vh, to_vh );
 
  535     opp_new_heh = _m.opposite_halfedge_handle(new_heh);
 
  538     _m.set_next_halfedge_handle(t_heh,   opp_new_heh);                  
 
  539     _m.set_next_halfedge_handle(new_heh, _m.next_halfedge_handle(heh)); 
 
  540     _m.set_next_halfedge_handle(heh,         new_heh);                  
 
  541     _m.set_next_halfedge_handle(opp_new_heh, opp_heh);                  
 
  544     _m.set_face_handle(opp_new_heh, _m.face_handle(opp_heh));
 
  547     _m.set_vertex_handle(heh, _vh); 
 
  550     _m.set_face_handle(new_heh, _m.face_handle(heh));
 
  554     _m.set_halfedge_handle( to_vh, opp_new_heh );
 
  557     _m.set_halfedge_handle( _vh, opp_heh );
 
  560   void boundary_split( MeshType& _m, 
 
  561                        const typename MeshType::HalfedgeHandle& _heh)
 
  563     assert( _m.is_boundary( _m.opposite_halfedge_handle( _heh ) ) );
 
  565     typename MeshType::HalfedgeHandle 
 
  567       n_heh(_m.next_halfedge_handle(heh));
 
  569     typename MeshType::VertexHandle   
 
  570       to_vh(_m.to_vertex_handle(heh));
 
  572     typename MeshType::HalfedgeHandle 
 
  573       heh2(_m.new_edge(to_vh,
 
  574                        _m.to_vertex_handle(_m.next_halfedge_handle(n_heh)))),
 
  575       heh3(_m.opposite_halfedge_handle(heh2));
 
  577     typename MeshType::FaceHandle
 
  578       new_fh(_m.new_face()),
 
  579       fh(_m.face_handle(heh));
 
  582     _m.set_face_handle(heh,  new_fh);
 
  583     _m.set_face_handle(heh2, new_fh);
 
  584     _m.set_next_halfedge_handle(heh2, _m.next_halfedge_handle(_m.next_halfedge_handle(n_heh)));
 
  585     _m.set_next_halfedge_handle(heh,  heh2);
 
  586     _m.set_face_handle( _m.next_halfedge_handle(heh2), new_fh);
 
  588     _m.set_next_halfedge_handle(heh3,                           n_heh);
 
  589     _m.set_next_halfedge_handle(_m.next_halfedge_handle(n_heh), heh3);
 
  590     _m.set_face_handle(heh3,  fh);
 
  592     _m.set_halfedge_handle(    fh, n_heh);
 
  593     _m.set_halfedge_handle(new_fh, heh);
 
  603                                      typename MeshType::VertexHandle> > ep_nv_;
 
Contains all the mesh ingredients like the polygonal mesh, the triangle mesh, different mesh kernels ...
Definition: MeshItems.hh:59
 
bool is_valid() const
The handle is valid iff the index is not negative.
Definition: Handles.hh:72
 
Handle representing an edge property.
Definition: Property.hh:447
 
Uniform Interpolating Sqrt3 subdivision algorithm
Definition: Sqrt3InterpolatingSubdividerLabsikGreinerT.hh:107
 
bool cleanup(MeshType &_m) override
Cleanup mesh after usage, e.g. remove added properties.
Definition: Sqrt3InterpolatingSubdividerLabsikGreinerT.hh:186
 
bool subdivide(MeshType &_m, size_t _n, const bool _update_points=true) override
Subdivide mesh _m _n times.
Definition: Sqrt3InterpolatingSubdividerLabsikGreinerT.hh:196
 
bool prepare(MeshType &_m) override
Prepare mesh, e.g. add properties.
Definition: Sqrt3InterpolatingSubdividerLabsikGreinerT.hh:173
 
void init_weights(size_t _max_valence=50)
Pre-compute weights.
Definition: Sqrt3InterpolatingSubdividerLabsikGreinerT.hh:134
 
const char * name() const override
Return name of subdivision algorithm.
Definition: Sqrt3InterpolatingSubdividerLabsikGreinerT.hh:131
 
Abstract base class for uniform subdivision algorithms.
Definition: SubdividerT.hh:89