00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00046
00047
00048
00049
00050
00051
00052 #ifndef OPENMESH_SUBDIVIDER_UNIFORM_SQRT3T_HH
00053 #define OPENMESH_SUBDIVIDER_UNIFORM_SQRT3T_HH
00054
00055
00056
00057
00058 #include <OpenMesh/Core/Mesh/Handles.hh>
00059 #include <OpenMesh/Core/System/config.hh>
00060 #include <OpenMesh/Tools/Subdivider/Uniform/SubdividerT.hh>
00061 #if defined(_DEBUG) || defined(DEBUG)
00062
00063
00064 # include <OpenMesh/Tools/Utils/MeshCheckerT.hh>
00065 # define ASSERT_CONSISTENCY( T, m ) \
00066 assert(OpenMesh::Utils::MeshCheckerT<T>(m).check())
00067 #else
00068 # define ASSERT_CONSISTENCY( T, m )
00069 #endif
00070
00071 #include <vector>
00072 #if defined(OM_CC_MIPS)
00073 # include <math.h>
00074 #else
00075 # include <cmath>
00076 #endif
00077
00078
00079
00080
00081 namespace OpenMesh {
00082 namespace Subdivider {
00083 namespace Uniform {
00084
00085
00086
00087
00088
00095 template <typename MeshType, typename RealType = float>
00096 class Sqrt3T : public SubdividerT< MeshType, RealType >
00097 {
00098 public:
00099
00100 typedef RealType real_t;
00101 typedef MeshType mesh_t;
00102 typedef SubdividerT< mesh_t, real_t > parent_t;
00103
00104 typedef std::pair< real_t, real_t > weight_t;
00105 typedef std::vector< std::pair<real_t,real_t> > weights_t;
00106
00107 public:
00108
00109
00110 Sqrt3T(void) : parent_t(), _1over3( 1.0/3.0 ), _1over27( 1.0/27.0 )
00111 { init_weights(); }
00112
00113 Sqrt3T(MeshType &_m) : parent_t(_m), _1over3( 1.0/3.0 ), _1over27( 1.0/27.0 )
00114 { init_weights(); }
00115
00116 virtual ~Sqrt3T() {}
00117
00118
00119 public:
00120
00121
00122 const char *name() const { return "Uniform Sqrt3"; }
00123
00124
00126 void init_weights(size_t _max_valence=50)
00127 {
00128 weights_.resize(_max_valence);
00129 std::generate(weights_.begin(), weights_.end(), compute_weight());
00130 }
00131
00132
00133 protected:
00134
00135
00136 bool prepare( MeshType& _m )
00137 {
00138 _m.request_edge_status();
00139 _m.add_property( vp_pos_ );
00140 _m.add_property( ep_nv_ );
00141 _m.add_property( mp_gen_ );
00142 _m.property( mp_gen_ ) = 0;
00143
00144 return _m.has_edge_status() && vp_pos_.is_valid()
00145 && ep_nv_.is_valid() && mp_gen_.is_valid();
00146 }
00147
00148
00149 bool cleanup( MeshType& _m )
00150 {
00151 _m.release_edge_status();
00152 _m.remove_property( vp_pos_ );
00153 _m.remove_property( ep_nv_ );
00154 _m.remove_property( mp_gen_ );
00155 return true;
00156 }
00157
00158
00159 bool subdivide( MeshType& _m, size_t _n )
00160 {
00161 typename MeshType::VertexIter vit;
00162 typename MeshType::VertexVertexIter vvit;
00163 typename MeshType::EdgeIter eit;
00164 typename MeshType::FaceIter fit;
00165 typename MeshType::FaceVertexIter fvit;
00166 typename MeshType::VertexHandle vh;
00167 typename MeshType::HalfedgeHandle heh;
00168 typename MeshType::Point pos(0,0,0), zero(0,0,0);
00169 size_t &gen = _m.property( mp_gen_ );
00170
00171 for (size_t l=0; l<_n; ++l)
00172 {
00173
00174 for (eit=_m.edges_begin(); eit != _m.edges_end();++eit)
00175 {
00176 _m.status( eit ).set_tagged( true );
00177 if ( (gen%2) && _m.is_boundary(eit) )
00178 compute_new_boundary_points( _m, eit );
00179 }
00180
00181
00182
00183 for (vit=_m.vertices_begin(); vit!=_m.vertices_end(); ++vit)
00184 {
00185 if ( _m.is_boundary(vit) )
00186 {
00187 if ( gen%2 )
00188 {
00189 heh = _m.halfedge_handle(vit);
00190 if (heh.is_valid())
00191 {
00192 typename OpenMesh::HalfedgeHandle
00193 prev_heh = _m.prev_halfedge_handle(heh);
00194
00195 assert( _m.is_boundary(heh ) );
00196 assert( _m.is_boundary(prev_heh) );
00197
00198 pos = _m.point(_m.to_vertex_handle(heh));
00199 pos += _m.point(_m.from_vertex_handle(prev_heh));
00200 pos *= real_t(4.0);
00201
00202 pos += real_t(19.0) * _m.point( vit );
00203 pos *= _1over27;
00204
00205 _m.property( vp_pos_, vit ) = pos;
00206 }
00207 }
00208 else
00209 _m.property( vp_pos_, vit ) = _m.point( vit );
00210 }
00211 else
00212 {
00213 size_t valence=0;
00214
00215 pos = zero;
00216 for ( vvit = _m.vv_iter(vit); vvit; ++vvit)
00217 {
00218 pos += _m.point( vvit );
00219 ++valence;
00220 }
00221 pos *= weights_[ valence ].second;
00222 pos += weights_[ valence ].first * _m.point(vit);
00223 _m.property( vp_pos_, vit ) = pos;
00224 }
00225 }
00226
00227
00228 typename MeshType::FaceIter fend = _m.faces_end();
00229 for (fit = _m.faces_begin();fit != fend; ++fit)
00230 {
00231 if ( (gen%2) && _m.is_boundary(fit))
00232 {
00233 boundary_split( _m, fit );
00234 }
00235 else
00236 {
00237 fvit = _m.fv_iter( fit );
00238 pos = _m.point( fvit);
00239 pos += _m.point(++fvit);
00240 pos += _m.point(++fvit);
00241 pos *= _1over3;
00242 vh = _m.add_vertex( zero );
00243 _m.property( vp_pos_, vh ) = pos;
00244 _m.split( fit, vh );
00245 }
00246 }
00247
00248
00249 for (vit=_m.vertices_begin();vit != _m.vertices_end(); ++vit)
00250 _m.set_point(vit, _m.property( vp_pos_, vit ) );
00251
00252
00253 for (eit=_m.edges_begin(); eit != _m.edges_end(); ++eit)
00254 if ( _m.status( eit ).tagged() && !_m.is_boundary( eit ) )
00255 _m.flip(eit);
00256
00257
00258 ASSERT_CONSISTENCY( MeshType, _m );
00259
00260
00261 ++gen;
00262 }
00263 return true;
00264 }
00265
00266 private:
00267
00270 struct compute_weight
00271 {
00272 compute_weight() : valence(-1) { }
00273 weight_t operator() (void)
00274 {
00275 #if !defined(OM_CC_MIPS)
00276 using std::cos;
00277 #endif
00278 if (++valence)
00279 {
00280 real_t alpha = (4.0-2.0*cos(2.0*M_PI / (double)valence))/9.0;
00281 return weight_t( real_t(1)-alpha, alpha/real_t(valence) );
00282 }
00283 return weight_t(0.0, 0.0);
00284 }
00285 int valence;
00286 };
00287
00288 private:
00289
00290
00291
00292 void compute_new_boundary_points( MeshType& _m,
00293 const typename MeshType::EdgeHandle& _eh)
00294 {
00295 assert( _m.is_boundary(_eh) );
00296
00297 typename MeshType::HalfedgeHandle heh;
00298 typename MeshType::VertexHandle vh1, vh2, vh3, vh4, vhl, vhr;
00299 typename MeshType::Point zero(0,0,0), P1, P2, P3, P4;
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314 heh = _m.halfedge_handle(_eh,
00315 _m.is_boundary(_m.halfedge_handle(_eh,1)));
00316
00317 assert( _m.is_boundary( _m.next_halfedge_handle( heh ) ) );
00318 assert( _m.is_boundary( _m.prev_halfedge_handle( heh ) ) );
00319
00320 vh1 = _m.to_vertex_handle( _m.next_halfedge_handle( heh ) );
00321 vh2 = _m.to_vertex_handle( heh );
00322 vh3 = _m.from_vertex_handle( heh );
00323 vh4 = _m.from_vertex_handle( _m.prev_halfedge_handle( heh ));
00324
00325 P1 = _m.point(vh1);
00326 P2 = _m.point(vh2);
00327 P3 = _m.point(vh3);
00328 P4 = _m.point(vh4);
00329
00330 vhl = _m.add_vertex(zero);
00331 vhr = _m.add_vertex(zero);
00332
00333 _m.property(vp_pos_, vhl ) = (P1 + real_t(16.0f) * P2 + real_t(10.0f) * P3) * _1over27;
00334 _m.property(vp_pos_, vhr ) = ( real_t(10.0f) * P2 + real_t(16.0f) * P3 + P4) * _1over27;
00335 _m.property(ep_nv_, _eh).first = vhl;
00336 _m.property(ep_nv_, _eh).second = vhr;
00337 }
00338
00339
00340 void boundary_split( MeshType& _m, const typename MeshType::FaceHandle& _fh )
00341 {
00342 assert( _m.is_boundary(_fh) );
00343
00344 typename MeshType::VertexHandle vhl, vhr;
00345 typename MeshType::FaceEdgeIter fe_it;
00346 typename MeshType::HalfedgeHandle heh;
00347
00348
00349 for( fe_it=_m.fe_iter( _fh ); fe_it && !_m.is_boundary( fe_it ); ++fe_it ) {};
00350
00351
00352 vhl = _m.property(ep_nv_, fe_it).first;
00353 vhr = _m.property(ep_nv_, fe_it).second;
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368 heh = _m.halfedge_handle(fe_it,
00369 _m.is_boundary(_m.halfedge_handle(fe_it,0)));
00370
00371 typename MeshType::HalfedgeHandle pl_P3;
00372
00373
00374 boundary_split( _m, heh, vhl );
00375 pl_P3 = _m.next_halfedge_handle( heh );
00376 boundary_split( _m, heh );
00377
00378
00379 boundary_split( _m, pl_P3, vhr );
00380 boundary_split( _m, pl_P3 );
00381
00382 assert( _m.is_boundary( vhl ) && _m.halfedge_handle(vhl).is_valid() );
00383 assert( _m.is_boundary( vhr ) && _m.halfedge_handle(vhr).is_valid() );
00384 }
00385
00386 void boundary_split(MeshType& _m,
00387 const typename MeshType::HalfedgeHandle& _heh,
00388 const typename MeshType::VertexHandle& _vh)
00389 {
00390 assert( _m.is_boundary( _m.edge_handle(_heh) ) );
00391
00392 typename MeshType::HalfedgeHandle
00393 heh(_heh),
00394 opp_heh( _m.opposite_halfedge_handle(_heh) ),
00395 new_heh, opp_new_heh;
00396 typename MeshType::VertexHandle to_vh(_m.to_vertex_handle(heh));
00397 typename MeshType::HalfedgeHandle t_heh;
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417 for(t_heh = heh;
00418 _m.next_halfedge_handle(t_heh) != opp_heh;
00419 t_heh = _m.opposite_halfedge_handle(_m.next_halfedge_handle(t_heh)))
00420 {}
00421
00422 assert( _m.is_boundary( t_heh ) );
00423
00424 new_heh = _m.new_edge( _vh, to_vh );
00425 opp_new_heh = _m.opposite_halfedge_handle(new_heh);
00426
00427
00428
00429 _m.set_next_halfedge_handle(t_heh, opp_new_heh);
00430
00431 _m.set_next_halfedge_handle(new_heh, _m.next_halfedge_handle(heh));
00432 _m.set_next_halfedge_handle(heh, new_heh);
00433 _m.set_next_halfedge_handle(opp_new_heh, opp_heh);
00434
00435
00436 _m.set_face_handle(opp_new_heh, _m.face_handle(opp_heh));
00437
00438
00439 _m.set_vertex_handle(heh, _vh);
00440
00441
00442 _m.set_face_handle(new_heh, _m.face_handle(heh));
00443
00444
00445
00446 _m.set_halfedge_handle( to_vh, opp_new_heh );
00447
00448
00449 _m.set_halfedge_handle( _vh, opp_heh );
00450 }
00451
00452 void boundary_split( MeshType& _m,
00453 const typename MeshType::HalfedgeHandle& _heh)
00454 {
00455 assert( _m.is_boundary( _m.opposite_halfedge_handle( _heh ) ) );
00456
00457 typename MeshType::HalfedgeHandle
00458 heh(_heh),
00459 n_heh(_m.next_halfedge_handle(heh));
00460
00461 typename MeshType::VertexHandle
00462 to_vh(_m.to_vertex_handle(heh));
00463
00464 typename MeshType::HalfedgeHandle
00465 heh2(_m.new_edge(to_vh,
00466 _m.to_vertex_handle(_m.next_halfedge_handle(n_heh)))),
00467 heh3(_m.opposite_halfedge_handle(heh2));
00468
00469 typename MeshType::FaceHandle
00470 new_fh(_m.new_face()),
00471 fh(_m.face_handle(heh));
00472
00473
00474
00475 #define set_next_heh set_next_halfedge_handle
00476 #define next_heh next_halfedge_handle
00477
00478 _m.set_face_handle(heh, new_fh);
00479 _m.set_face_handle(heh2, new_fh);
00480 _m.set_next_heh(heh2, _m.next_heh(_m.next_heh(n_heh)));
00481 _m.set_next_heh(heh, heh2);
00482 _m.set_face_handle( _m.next_heh(heh2), new_fh);
00483
00484
00485
00486 _m.set_next_heh(heh3, n_heh);
00487 _m.set_next_heh(_m.next_halfedge_handle(n_heh), heh3);
00488 _m.set_face_handle(heh3, fh);
00489
00490
00491 _m.set_halfedge_handle( fh, n_heh);
00492 _m.set_halfedge_handle(new_fh, heh);
00493
00494 #undef set_next_halfedge_handle
00495 #undef next_halfedge_handle
00496
00497 }
00498
00499 private:
00500
00501 weights_t weights_;
00502 OpenMesh::VPropHandleT< typename MeshType::Point > vp_pos_;
00503 OpenMesh::EPropHandleT< std::pair< typename MeshType::VertexHandle,
00504 typename MeshType::VertexHandle> > ep_nv_;
00505 OpenMesh::MPropHandleT< size_t > mp_gen_;
00506
00507 const real_t _1over3;
00508 const real_t _1over27;
00509 };
00510
00511
00512
00513 }
00514 }
00515 }
00516
00517 #endif // OPENMESH_SUBDIVIDER_UNIFORM_SQRT3T_HH
00518