The Parametric Pseudo-Manifold (PPS) Library 1.0
ppssampler.h
Go to the documentation of this file.
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