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