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
00051
00052
00053
00054
00055
00056
00057 #ifndef OPENMESH_SUBDIVIDER_UNIFORM_INTERP_SQRT3T_LABSIK_GREINER_HH
00058 #define OPENMESH_SUBDIVIDER_UNIFORM_INTERP_SQRT3T_LABSIK_GREINER_HH
00059
00060
00061
00062
00063 #include <OpenMesh/Core/Mesh/Handles.hh>
00064 #include <OpenMesh/Core/System/config.hh>
00065 #include <OpenMesh/Tools/Subdivider/Uniform/SubdividerT.hh>
00066
00067 #if defined(_DEBUG) || defined(DEBUG)
00068
00069
00070 # include <OpenMesh/Tools/Utils/MeshCheckerT.hh>
00071 # define ASSERT_CONSISTENCY( T, m ) \
00072 assert(OpenMesh::Utils::MeshCheckerT<T>(m).check())
00073 #else
00074 # define ASSERT_CONSISTENCY( T, m )
00075 #endif
00076
00077 #include <vector>
00078 #if defined(OM_CC_MIPS)
00079 # include <math.h>
00080 #else
00081 # include <cmath>
00082 #endif
00083
00084
00085
00086
00087
00088
00089 namespace OpenMesh {
00090 namespace Subdivider {
00091 namespace Uniform {
00092
00093
00094
00095
00096
00105 template <typename MeshType, typename RealType = float>
00106 class InterpolatingSqrt3LGT : public SubdividerT< MeshType, RealType >
00107 {
00108 public:
00109
00110 typedef RealType real_t;
00111 typedef MeshType mesh_t;
00112 typedef SubdividerT< mesh_t, real_t > parent_t;
00113
00114 typedef std::vector< std::vector<real_t> > weights_t;
00115
00116 public:
00117
00118
00119 InterpolatingSqrt3LGT(void) : parent_t()
00120 { init_weights(); }
00121
00122 InterpolatingSqrt3LGT(MeshType &_m) : parent_t(_m)
00123 { init_weights(); }
00124
00125 virtual ~InterpolatingSqrt3LGT() {}
00126
00127
00128 public:
00129
00130
00131 const char *name() const { return "Uniform Interpolating Sqrt3"; }
00132
00134 void init_weights(size_t _max_valence=50)
00135 {
00136 weights_.resize(_max_valence);
00137
00138 weights_[3].resize(4);
00139 weights_[3][0] = +4.0/27;
00140 weights_[3][1] = -5.0/27;
00141 weights_[3][2] = +4.0/27;
00142 weights_[3][3] = +8.0/9;
00143
00144 weights_[4].resize(5);
00145 weights_[4][0] = +2.0/9;
00146 weights_[4][1] = -1.0/9;
00147 weights_[4][2] = -1.0/9;
00148 weights_[4][3] = +2.0/9;
00149 weights_[4][4] = +7.0/9 ;
00150
00151 for(unsigned int K=5; K<_max_valence; ++K)
00152 {
00153 weights_[K].resize(K+1);
00154 double aH = 2.0*cos(M_PI/K)/3.0;
00155 weights_[K][K] = 1.0 - aH*aH;
00156 for(unsigned int i=0; i<K; ++i)
00157 {
00158 weights_[K][i] = (aH*aH + 2.0*aH*cos(2.0*i*M_PI/K + M_PI/K) + 2.0*aH*aH*cos(4.0*i*M_PI/K + 2.0*M_PI/K))/K;
00159 }
00160 }
00161
00162
00163 weights_[6].resize(0);
00164
00165 }
00166
00167
00168 protected:
00169
00170
00171 bool prepare( MeshType& _m )
00172 {
00173 _m.request_edge_status();
00174 _m.add_property( fp_pos_ );
00175 _m.add_property( ep_nv_ );
00176 _m.add_property( mp_gen_ );
00177 _m.property( mp_gen_ ) = 0;
00178
00179 return _m.has_edge_status()
00180 && ep_nv_.is_valid() && mp_gen_.is_valid();
00181 }
00182
00183
00184 bool cleanup( MeshType& _m )
00185 {
00186 _m.release_edge_status();
00187 _m.remove_property( fp_pos_ );
00188 _m.remove_property( ep_nv_ );
00189 _m.remove_property( mp_gen_ );
00190 return true;
00191 }
00192
00193
00194 bool subdivide( MeshType& _m, size_t _n )
00195 {
00196 typename MeshType::VertexIter vit;
00197 typename MeshType::VertexVertexIter vvit;
00198 typename MeshType::EdgeIter eit;
00199 typename MeshType::FaceIter fit;
00200 typename MeshType::FaceVertexIter fvit;
00201 typename MeshType::FaceHalfedgeIter fheit;
00202 typename MeshType::VertexHandle vh;
00203 typename MeshType::HalfedgeHandle heh;
00204 typename MeshType::Point pos(0,0,0), zero(0,0,0);
00205 size_t &gen = _m.property( mp_gen_ );
00206
00207 for (size_t l=0; l<_n; ++l)
00208 {
00209
00210 for (eit=_m.edges_begin(); eit != _m.edges_end();++eit)
00211 {
00212 _m.status( eit ).set_tagged( true );
00213 if ( (gen%2) && _m.is_boundary(eit) )
00214 compute_new_boundary_points( _m, eit );
00215 }
00216
00217
00218 typename MeshType::FaceIter fend = _m.faces_end();
00219 for (fit = _m.faces_begin();fit != fend; ++fit)
00220 {
00221 if (_m.is_boundary(fit))
00222 {
00223 if(gen%2)
00224 _m.property(fp_pos_, fit.handle()).invalidate();
00225 else
00226 {
00227
00228 for( heh = _m.halfedge_handle(fit.handle()); !_m.is_boundary( _m.opposite_halfedge_handle(heh) ); heh = _m.next_halfedge_handle(heh) )
00229 ;
00230 assert(_m.is_boundary( _m.opposite_halfedge_handle(heh) ));
00231 pos = zero;
00232
00233 if( _m.is_boundary(_m.next_halfedge_handle(heh)) || _m.is_boundary(_m.prev_halfedge_handle(heh)) )
00234 {
00235 if(_m.is_boundary(_m.prev_halfedge_handle(heh)))
00236 heh = _m.prev_halfedge_handle(heh);
00237
00238 if(_m.is_boundary(_m.next_halfedge_handle(_m.next_halfedge_handle(heh))))
00239 {
00240
00241 pos += real_t(1.0/3) * _m.point(_m.to_vertex_handle(heh));
00242 pos += real_t(1.0/3) * _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(heh)));
00243 pos += real_t(1.0/3) * _m.point(_m.to_vertex_handle(_m.prev_halfedge_handle(heh)));
00244 }
00245 else
00246 {
00247 #ifdef MIRROR_TRIANGLES
00248
00249 pos += real_t(2.0/9) * _m.point(_m.to_vertex_handle(heh));
00250 pos += real_t(4.0/9) * _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(heh)));
00251 pos += real_t(4.0/9) * _m.point(_m.to_vertex_handle(_m.prev_halfedge_handle(heh)));
00252 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)))));
00253 #else
00254 pos += real_t(7.0/24) * _m.point(_m.to_vertex_handle(heh));
00255 pos += real_t(3.0/8) * _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(heh)));
00256 pos += real_t(3.0/8) * _m.point(_m.to_vertex_handle(_m.prev_halfedge_handle(heh)));
00257 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)))));
00258 #endif
00259 }
00260 }
00261 else
00262 {
00263 vh = _m.to_vertex_handle(_m.next_halfedge_handle(heh));
00264
00265 if((_m.valence(vh) == 6) || _m.is_boundary(vh))
00266 {
00267 #ifdef MIRROR_TRIANGLES
00268
00269 pos += real_t(5.0/9) * _m.point(vh);
00270 pos += real_t(3.0/9) * _m.point(_m.to_vertex_handle(heh));
00271 pos += real_t(3.0/9) * _m.point(_m.to_vertex_handle(_m.opposite_halfedge_handle(heh)));
00272 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)))));
00273 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)))));
00274 #else
00275 #ifdef MIN_NORM
00276 pos += real_t(1.0/9) * _m.point(vh);
00277 pos += real_t(1.0/3) * _m.point(_m.to_vertex_handle(heh));
00278 pos += real_t(1.0/3) * _m.point(_m.to_vertex_handle(_m.opposite_halfedge_handle(heh)));
00279 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)))));
00280 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)))));
00281 #else
00282 pos += real_t(1.0/2) * _m.point(vh);
00283 pos += real_t(1.0/3) * _m.point(_m.to_vertex_handle(heh));
00284 pos += real_t(1.0/3) * _m.point(_m.to_vertex_handle(_m.opposite_halfedge_handle(heh)));
00285 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)))));
00286 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)))));
00287 #endif
00288 #endif
00289 }
00290 else
00291 {
00292
00293 unsigned int K = _m.valence(vh);
00294 pos += weights_[K][K]*_m.point(vh);
00295 heh = _m.opposite_halfedge_handle( _m.next_halfedge_handle(heh) );
00296 for(unsigned int i = 0; i<K; ++i, heh = _m.opposite_halfedge_handle(_m.prev_halfedge_handle(heh)) )
00297 {
00298 pos += weights_[K][i]*_m.point(_m.to_vertex_handle(heh));
00299 }
00300 }
00301 }
00302 vh = _m.add_vertex( pos );
00303 _m.property(fp_pos_, fit.handle()) = vh;
00304 }
00305 }
00306 else
00307 {
00308 pos = zero;
00309 int nOrdinary = 0;
00310
00311
00312 for(fvit = _m.fv_iter( fit ); fvit; ++fvit)
00313 if( (_m.valence(fvit.handle())) == 6 || _m.is_boundary(fvit.handle()) )
00314 ++nOrdinary;
00315
00316 if(nOrdinary==3)
00317 {
00318 for(fheit = _m.fh_iter( fit ); fheit; ++fheit)
00319 {
00320
00321 heh = fheit.handle();
00322 assert(_m.to_vertex_handle(heh).is_valid());
00323 pos += real_t(32.0/81) * _m.point(_m.to_vertex_handle(heh));
00324
00325 heh = _m.opposite_halfedge_handle(heh);
00326 assert(heh.is_valid());
00327 assert(_m.next_halfedge_handle(heh).is_valid());
00328 assert(_m.to_vertex_handle(_m.next_halfedge_handle(heh)).is_valid());
00329 pos -= real_t(1.0/81) * _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(heh)));
00330
00331 heh = _m.opposite_halfedge_handle(_m.prev_halfedge_handle(heh));
00332 assert(heh.is_valid());
00333 assert(_m.next_halfedge_handle(heh).is_valid());
00334 assert(_m.to_vertex_handle(_m.next_halfedge_handle(heh)).is_valid());
00335 pos -= real_t(2.0/81) * _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(heh)));
00336 heh = _m.opposite_halfedge_handle(_m.prev_halfedge_handle(heh));
00337 assert(heh.is_valid());
00338 assert(_m.next_halfedge_handle(heh).is_valid());
00339 assert(_m.to_vertex_handle(_m.next_halfedge_handle(heh)).is_valid());
00340 pos -= real_t(2.0/81) * _m.point(_m.to_vertex_handle(_m.next_halfedge_handle(heh)));
00341 }
00342 }
00343 else
00344 {
00345
00346 for(fheit = _m.fh_iter( fit ); fheit; ++fheit)
00347 {
00348 vh = _m.to_vertex_handle(fheit);
00349 if( (_m.valence(vh) != 6) && (!_m.is_boundary(vh)) )
00350 {
00351 unsigned int K = _m.valence(vh);
00352 pos += weights_[K][K]*_m.point(vh);
00353 heh = _m.opposite_halfedge_handle( fheit.handle() );
00354 for(unsigned int i = 0; i<K; ++i, heh = _m.opposite_halfedge_handle(_m.prev_halfedge_handle(heh)) )
00355 {
00356 pos += weights_[K][i]*_m.point(_m.to_vertex_handle(heh));
00357 }
00358 }
00359 }
00360 pos *= real_t(1.0/(3-nOrdinary));
00361 }
00362
00363 vh = _m.add_vertex( pos );
00364 _m.property(fp_pos_, fit.handle()) = vh;
00365 }
00366 }
00367
00368
00369 for (fit = _m.faces_begin();fit != fend; ++fit)
00370 {
00371 if ( _m.is_boundary(fit) && (gen%2))
00372 {
00373 boundary_split( _m, fit );
00374 }
00375 else
00376 {
00377 assert(_m.property(fp_pos_, fit.handle()).is_valid());
00378 _m.split( fit, _m.property(fp_pos_, fit.handle()) );
00379 }
00380 }
00381
00382
00383 for (eit=_m.edges_begin(); eit != _m.edges_end(); ++eit)
00384 if ( _m.status( eit ).tagged() && !_m.is_boundary( eit ) )
00385 _m.flip(eit);
00386
00387
00388 ASSERT_CONSISTENCY( MeshType, _m );
00389
00390
00391 ++gen;
00392 }
00393 return true;
00394 }
00395
00396 private:
00397
00398
00399
00400 void compute_new_boundary_points( MeshType& _m,
00401 const typename MeshType::EdgeHandle& _eh)
00402 {
00403 assert( _m.is_boundary(_eh) );
00404
00405 typename MeshType::HalfedgeHandle heh;
00406 typename MeshType::VertexHandle vh1, vh2, vh3, vh4, vhl, vhr;
00407 typename MeshType::Point zero(0,0,0), P1, P2, P3, P4;
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422 heh = _m.halfedge_handle(_eh,
00423 _m.is_boundary(_m.halfedge_handle(_eh,1)));
00424
00425 assert( _m.is_boundary( _m.next_halfedge_handle( heh ) ) );
00426 assert( _m.is_boundary( _m.prev_halfedge_handle( heh ) ) );
00427
00428 vh1 = _m.to_vertex_handle( _m.next_halfedge_handle( heh ) );
00429 vh2 = _m.to_vertex_handle( heh );
00430 vh3 = _m.from_vertex_handle( heh );
00431 vh4 = _m.from_vertex_handle( _m.prev_halfedge_handle( heh ));
00432
00433 P1 = _m.point(vh1);
00434 P2 = _m.point(vh2);
00435 P3 = _m.point(vh3);
00436 P4 = _m.point(vh4);
00437
00438 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);
00439 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);
00440
00441 _m.property(ep_nv_, _eh).first = vhl;
00442 _m.property(ep_nv_, _eh).second = vhr;
00443 }
00444
00445
00446 void boundary_split( MeshType& _m, const typename MeshType::FaceHandle& _fh )
00447 {
00448 assert( _m.is_boundary(_fh) );
00449
00450 typename MeshType::VertexHandle vhl, vhr;
00451 typename MeshType::FaceEdgeIter fe_it;
00452 typename MeshType::HalfedgeHandle heh;
00453
00454
00455 for( fe_it=_m.fe_iter( _fh ); fe_it && !_m.is_boundary( fe_it ); ++fe_it ) {};
00456
00457
00458 vhl = _m.property(ep_nv_, fe_it).first;
00459 vhr = _m.property(ep_nv_, fe_it).second;
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474 heh = _m.halfedge_handle(fe_it,
00475 _m.is_boundary(_m.halfedge_handle(fe_it,0)));
00476
00477 typename MeshType::HalfedgeHandle pl_P3;
00478
00479
00480 boundary_split( _m, heh, vhl );
00481 pl_P3 = _m.next_halfedge_handle( heh );
00482 boundary_split( _m, heh );
00483
00484
00485 boundary_split( _m, pl_P3, vhr );
00486 boundary_split( _m, pl_P3 );
00487
00488 assert( _m.is_boundary( vhl ) && _m.halfedge_handle(vhl).is_valid() );
00489 assert( _m.is_boundary( vhr ) && _m.halfedge_handle(vhr).is_valid() );
00490 }
00491
00492 void boundary_split(MeshType& _m,
00493 const typename MeshType::HalfedgeHandle& _heh,
00494 const typename MeshType::VertexHandle& _vh)
00495 {
00496 assert( _m.is_boundary( _m.edge_handle(_heh) ) );
00497
00498 typename MeshType::HalfedgeHandle
00499 heh(_heh),
00500 opp_heh( _m.opposite_halfedge_handle(_heh) ),
00501 new_heh, opp_new_heh;
00502 typename MeshType::VertexHandle to_vh(_m.to_vertex_handle(heh));
00503 typename MeshType::HalfedgeHandle t_heh;
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523 for(t_heh = heh;
00524 _m.next_halfedge_handle(t_heh) != opp_heh;
00525 t_heh = _m.opposite_halfedge_handle(_m.next_halfedge_handle(t_heh)))
00526 {}
00527
00528 assert( _m.is_boundary( t_heh ) );
00529
00530 new_heh = _m.new_edge( _vh, to_vh );
00531 opp_new_heh = _m.opposite_halfedge_handle(new_heh);
00532
00533
00534 _m.set_next_halfedge_handle(t_heh, opp_new_heh);
00535 _m.set_next_halfedge_handle(new_heh, _m.next_halfedge_handle(heh));
00536 _m.set_next_halfedge_handle(heh, new_heh);
00537 _m.set_next_halfedge_handle(opp_new_heh, opp_heh);
00538
00539
00540 _m.set_face_handle(opp_new_heh, _m.face_handle(opp_heh));
00541
00542
00543 _m.set_vertex_handle(heh, _vh);
00544
00545
00546 _m.set_face_handle(new_heh, _m.face_handle(heh));
00547
00548
00549
00550 _m.set_halfedge_handle( to_vh, opp_new_heh );
00551
00552
00553 _m.set_halfedge_handle( _vh, opp_heh );
00554 }
00555
00556 void boundary_split( MeshType& _m,
00557 const typename MeshType::HalfedgeHandle& _heh)
00558 {
00559 assert( _m.is_boundary( _m.opposite_halfedge_handle( _heh ) ) );
00560
00561 typename MeshType::HalfedgeHandle
00562 heh(_heh),
00563 n_heh(_m.next_halfedge_handle(heh));
00564
00565 typename MeshType::VertexHandle
00566 to_vh(_m.to_vertex_handle(heh));
00567
00568 typename MeshType::HalfedgeHandle
00569 heh2(_m.new_edge(to_vh,
00570 _m.to_vertex_handle(_m.next_halfedge_handle(n_heh)))),
00571 heh3(_m.opposite_halfedge_handle(heh2));
00572
00573 typename MeshType::FaceHandle
00574 new_fh(_m.new_face()),
00575 fh(_m.face_handle(heh));
00576
00577
00578 _m.set_face_handle(heh, new_fh);
00579 _m.set_face_handle(heh2, new_fh);
00580 _m.set_next_halfedge_handle(heh2, _m.next_halfedge_handle(_m.next_halfedge_handle(n_heh)));
00581 _m.set_next_halfedge_handle(heh, heh2);
00582 _m.set_face_handle( _m.next_halfedge_handle(heh2), new_fh);
00583
00584 _m.set_next_halfedge_handle(heh3, n_heh);
00585 _m.set_next_halfedge_handle(_m.next_halfedge_handle(n_heh), heh3);
00586 _m.set_face_handle(heh3, fh);
00587
00588 _m.set_halfedge_handle( fh, n_heh);
00589 _m.set_halfedge_handle(new_fh, heh);
00590
00591
00592 }
00593
00594 private:
00595
00596 weights_t weights_;
00597 OpenMesh::FPropHandleT< typename MeshType::VertexHandle > fp_pos_;
00598 OpenMesh::EPropHandleT< std::pair< typename MeshType::VertexHandle,
00599 typename MeshType::VertexHandle> > ep_nv_;
00600 OpenMesh::MPropHandleT< size_t > mp_gen_;
00601 };
00602
00603
00604
00605 }
00606 }
00607 }
00608
00609 #endif // OPENMESH_SUBDIVIDER_UNIFORM_SQRT3T_HH
00610