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