The Parametric Pseudo-Manifold (PPS) Library 1.0
|
00001 00027 #ifndef PPSSAMPLER_H 00028 #define PPSSAMPLER_H 00029 00030 #include <vector> // std::vector 00031 #include <map> // std::map 00032 #include <cassert> // assert 00033 00034 #include "pps.h" // pps::PPS 00035 00036 00051 namespace pps { 00052 00053 00063 template < typename Mesh > 00064 class PPSsampler { 00065 public: 00066 // --------------------------------------------------------------- 00067 // 00068 // Type definitions 00069 // 00070 // --------------------------------------------------------------- 00071 00077 typedef typename Mesh::Vertex Vertex ; 00078 00079 00085 typedef typename Mesh::Halfedge Halfedge ; 00086 00087 00093 typedef typename Mesh::Face Face ; 00094 00095 00101 typedef typename Mesh::VertexIterator VertexIterator ; 00102 00103 00109 typedef typename Mesh::FaceIterator FaceIterator ; 00110 00111 00112 // --------------------------------------------------------------- 00113 // 00114 // Public methods 00115 // 00116 // --------------------------------------------------------------- 00117 00126 PPSsampler( PPS< Mesh >* pps ) : _pps( pps ) 00127 {} 00128 00129 00135 virtual ~PPSsampler() 00136 {} 00137 00138 00154 void sample( 00155 unsigned lod , 00156 unsigned& numpts , 00157 double*& lvpps , 00158 double*& lvmsh , 00159 unsigned& numfaces , 00160 unsigned*& lfaces 00161 ) ; 00162 00163 00164 private: 00165 // --------------------------------------------------------------- 00166 // 00167 // Private methods 00168 // 00169 // --------------------------------------------------------------- 00170 00180 void midpointsub( 00181 unsigned lod , 00182 unsigned& vcount , 00183 Face* face 00184 ) ; 00185 00186 00202 void midpointsub( 00203 unsigned lod , 00204 unsigned& vcount , 00205 Face* face , 00206 unsigned v1 , 00207 unsigned v2 , 00208 unsigned v3 , 00209 double c1[ 3 ] , 00210 double c2[ 3 ] , 00211 double c3[ 3 ] 00212 ) ; 00213 00214 00215 00216 // --------------------------------------------------------------- 00217 // 00218 // Private data members 00219 // 00220 // --------------------------------------------------------------- 00221 00222 pps::PPS< Mesh >* _pps ; 00223 00224 std::vector< double > _lv1 ; 00225 00226 std::vector< double > _lv2 ; 00227 00228 std::vector< unsigned > _lf ; 00229 00230 00231 std::map< Vertex* , unsigned > _vnt ; 00232 00233 00234 std::map< std::pair< unsigned , unsigned > , unsigned > _vpa; 00235 00236 } ; 00237 00238 00239 // ----------------------------------------------------------------- 00240 // 00241 // Implementation of public methods 00242 // 00243 // ----------------------------------------------------------------- 00244 00259 template < typename Mesh > 00260 void 00261 PPSsampler< Mesh >::sample( 00262 unsigned lod , 00263 unsigned& numpts , 00264 double*& lvpps , 00265 double*& lvmsh , 00266 unsigned& numfaces , 00267 unsigned*& lfaces 00268 ) 00269 { 00270 unsigned i = 0; 00271 00272 for ( VertexIterator vit = _pps->vertices_begin() ; 00273 !_pps->is_done( vit ) ; _pps->move_forward( vit ) ) { 00274 00275 Vertex* vertex = *vit ; 00276 00277 _vnt.insert( std::make_pair( vertex , i ) ) ; 00278 00283 double pt1[ 3 ] ; 00284 double pt2[ 3 ] ; 00285 00286 Halfedge* he = vertex->get_halfedge() ; 00287 00288 Face* face = he->get_face() ; 00289 00290 if ( he == face->get_halfedge() ) { 00291 _pps->eval_pps( face , 1 , 0 , 0 , pt1[ 0 ] , pt1[ 1 ] , pt1[ 2 ] ) ; 00292 _pps->eval_surface( face , 1 , 0 , 0 , pt2[ 0 ] , pt2[ 1 ] , pt2[ 2 ] ) ; 00293 } 00294 else if ( he->get_next() == face->get_halfedge() ) { 00295 _pps->eval_pps( face , 0 , 0 , 1 , pt1[ 0 ] , pt1[ 1 ] , pt1[ 2 ] ) ; 00296 _pps->eval_surface( face , 0 , 0 , 1 , pt2[ 0 ] , pt2[ 1 ] , pt2[ 2 ] ) ; 00297 } 00298 else { 00299 _pps->eval_pps( face , 0 , 1 , 0 , pt1[ 0 ] , pt1[ 1 ] , pt1[ 2 ] ) ; 00300 _pps->eval_surface( face , 0 , 1 , 0 , pt2[ 0 ] , pt2[ 1 ] , pt2[ 2 ] ) ; 00301 } 00302 00306 _lv1.push_back( pt1[ 0 ] ) ; 00307 _lv1.push_back( pt1[ 1 ] ) ; 00308 _lv1.push_back( pt1[ 2 ] ) ; 00309 00310 // Store the vertex in the set of vertices. 00311 _lv2.push_back( pt2[ 0 ] ) ; 00312 _lv2.push_back( pt2[ 1 ] ) ; 00313 _lv2.push_back( pt2[ 2 ] ) ; 00314 00315 ++i ; 00316 } 00317 00323 for ( FaceIterator fit = _pps->faces_begin() ; 00324 !_pps->is_done( fit ) ; _pps->move_forward( fit ) ) { 00325 midpointsub( lod , i , *fit ) ; 00326 } 00327 00328 assert( _lv1.size() == _lv2.size() ) ; 00329 00330 numpts = _lv1.size() ; 00331 numfaces = _lf.size() ; 00332 00333 lvpps = new double[ numpts ] ; 00334 lvmsh = new double[ numpts ] ; 00335 lfaces = new unsigned[ numfaces ] ; 00336 00337 for ( i = 0 ; i < numpts ; i++ ) { 00338 lvpps[ i ] = _lv1[ i ] ; 00339 lvmsh[ i ] = _lv2[ i ] ; 00340 } 00341 00342 for ( i = 0 ; i < numfaces ; i++ ) lfaces[ i ] = _lf[ i ] ; 00343 00344 _lv1.clear() ; 00345 _lv2.clear() ; 00346 00347 _lf.clear() ; 00348 00349 _vnt.clear(); 00350 _vpa.clear(); 00351 00352 return ; 00353 } 00354 00355 00365 template < typename Mesh > 00366 void 00367 PPSsampler< Mesh >::midpointsub( 00368 unsigned lod , 00369 unsigned& vcount , 00370 Face* face 00371 ) 00372 { 00376 Vertex* v1 = face->get_halfedge()->get_origin() ; 00377 Vertex* v2 = face->get_halfedge()->get_next()->get_origin() ; 00378 Vertex* v3 = face->get_halfedge()->get_prev()->get_origin() ; 00379 00383 unsigned id1 = _vnt.find( v1 )->second ; 00384 unsigned id2 = _vnt.find( v2 )->second ; 00385 unsigned id3 = _vnt.find( v3 )->second ; 00386 00391 if ( lod == 0 ) { 00392 _lf.push_back( id1 ) ; 00393 _lf.push_back( id2 ) ; 00394 _lf.push_back( id3 ) ; 00395 } 00396 else { 00397 double c1[ 3 ] = { 1 , 0 , 0 } ; 00398 double c2[ 3 ] = { 0 , 1 , 0 } ; 00399 double c3[ 3 ] = { 0 , 0 , 1 } ; 00400 00401 midpointsub( lod - 1 , vcount , face , id1 , id2 , id3 , 00402 c1 , c2 , c3 ) ; 00403 } 00404 00405 return ; 00406 } 00407 00408 00424 template < typename Mesh > 00425 void 00426 PPSsampler< Mesh >::midpointsub( 00427 unsigned lod , 00428 unsigned& vcount , 00429 Face* face , 00430 unsigned v1 , 00431 unsigned v2 , 00432 unsigned v3 , 00433 double c1[ 3 ] , 00434 double c2[ 3 ] , 00435 double c3[ 3 ] 00436 ) 00437 { 00441 double c12[ 3 ] ; 00442 double c23[ 3 ] ; 00443 double c31[ 3 ] ; 00444 00445 for ( unsigned i = 0 ; i < 3 ; i++ ) { 00446 c12[ i ] = 0.5 * ( c1[ i ] + c2[ i ] ) ; 00447 c23[ i ] = 0.5 * ( c2[ i ] + c3[ i ] ) ; 00448 c31[ i ] = 0.5 * ( c3[ i ] + c1[ i ] ) ; 00449 } 00450 00451 std::map< std::pair< unsigned , unsigned > , unsigned >::iterator pit = 00452 _vpa.find( std::make_pair( v1 , v2 ) ) ; 00453 00454 unsigned v12; 00455 if ( pit != _vpa.end() ) { 00456 v12 = pit->second ; 00457 } 00458 else { 00459 double pt1[ 3 ] ; 00460 double pt2[ 3 ] ; 00461 00462 _pps->eval_pps( face , c12[ 0 ] , c12[ 1 ] , c12[ 2 ] , pt1[ 0 ] , 00463 pt1[ 1 ] , pt1[ 2 ] ) ; 00464 _pps->eval_surface( face , c12[ 0 ] , c12[ 1 ] , c12[ 2 ] , 00465 pt2[ 0 ] , pt2[ 1 ] , pt2[ 2 ] ) ; 00466 00467 _lv1.push_back( pt1[ 0 ] ) ; 00468 _lv1.push_back( pt1[ 1 ] ) ; 00469 _lv1.push_back( pt1[ 2 ] ) ; 00470 00471 _lv2.push_back( pt2[ 0 ] ) ; 00472 _lv2.push_back( pt2[ 1 ] ) ; 00473 _lv2.push_back( pt2[ 2 ] ) ; 00474 00475 v12 = vcount; 00476 _vpa.insert( std::make_pair( std::make_pair( v2 , v1 ) , v12 ) ) ; 00477 ++vcount ; 00478 } 00479 00480 pit = _vpa.find( std::make_pair( v2 , v3 ) ) ; 00481 00482 unsigned v23 ; 00483 if ( pit != _vpa.end() ) { 00484 v23 = pit->second ; 00485 } 00486 else { 00487 double pt1[ 3 ] ; 00488 double pt2[ 3 ] ; 00489 00490 _pps->eval_pps( face , c23[ 0 ] , c23[ 1 ] , c23[ 2 ] , 00491 pt1[ 0 ] , pt1[ 1 ] , pt1[ 2 ] ) ; 00492 _pps->eval_surface( face , c23[ 0 ] , c23[ 1 ] , c23[ 2 ] , 00493 pt2[ 0 ] , pt2[ 1 ] , pt2[ 2 ] ) ; 00494 00495 _lv1.push_back( pt1[ 0 ] ) ; 00496 _lv1.push_back( pt1[ 1 ] ) ; 00497 _lv1.push_back( pt1[ 2 ] ) ; 00498 00499 _lv2.push_back( pt2[ 0 ] ) ; 00500 _lv2.push_back( pt2[ 1 ] ) ; 00501 _lv2.push_back( pt2[ 2 ] ) ; 00502 00503 v23 = vcount ; 00504 _vpa.insert( std::make_pair( std::make_pair( v3 , v2 ) , v23 ) ) ; 00505 ++vcount ; 00506 } 00507 00508 pit = _vpa.find( std::make_pair( v3 , v1 ) ) ; 00509 00510 unsigned v31 ; 00511 if ( pit != _vpa.end() ) { 00512 v31 = pit->second ; 00513 } 00514 else { 00515 double pt1[ 3 ] ; 00516 double pt2[ 3 ] ; 00517 00518 _pps->eval_pps( face , c31[ 0 ] , c31[ 1 ] , c31[ 2 ] , pt1[ 0 ] , 00519 pt1[ 1 ] , pt1[ 2 ] ) ; 00520 _pps->eval_surface( face , c31[ 0 ] , c31[ 1 ] , c31[ 2 ] , 00521 pt2[ 0 ] , pt2[ 1 ] , pt2[ 2 ] ) ; 00522 00523 _lv1.push_back( pt1[ 0 ] ) ; 00524 _lv1.push_back( pt1[ 1 ] ) ; 00525 _lv1.push_back( pt1[ 2 ] ) ; 00526 00527 _lv2.push_back( pt2[ 0 ] ) ; 00528 _lv2.push_back( pt2[ 1 ] ) ; 00529 _lv2.push_back( pt2[ 2 ] ) ; 00530 00531 v31 = vcount ; 00532 _vpa.insert( std::make_pair( std::make_pair( v1 , v3 ) , v31 ) ) ; 00533 ++vcount ; 00534 } 00535 00536 if (lod == 0) { 00537 _lf.push_back( v1 ) ; 00538 _lf.push_back( v12 ) ; 00539 _lf.push_back( v31 ) ; 00540 00541 _lf.push_back( v12 ) ; 00542 _lf.push_back( v2 ) ; 00543 _lf.push_back( v23 ) ; 00544 00545 _lf.push_back( v31 ) ; 00546 _lf.push_back( v23 ) ; 00547 _lf.push_back( v3 ) ; 00548 00549 _lf.push_back( v12 ) ; 00550 _lf.push_back( v23 ) ; 00551 _lf.push_back( v31 ) ; 00552 } 00553 else { 00554 midpointsub( lod - 1 , vcount , face , v1 , v12 , v31 , 00555 c1 , c12 , c31 ) ; 00556 midpointsub( lod - 1 , vcount , face , v12 , v2 , v23 , 00557 c12, c2 , c23 ) ; 00558 midpointsub( lod - 1 , vcount , face , v31 , v23 , v3 , 00559 c31 , c23 , c3 ) ; 00560 midpointsub( lod - 1 , vcount , face , v12 , v23 , v31 , 00561 c12 , c23 , c31 ) ; 00562 } 00563 00564 return ; 00565 } 00566 00567 } 00568 //end of group class. 00570 00571 #endif // PPSSAMPLER_H