TuttleOFX  1
CloudPointData.hpp
Go to the documentation of this file.
00001 #ifndef CLOUDPOINTDATA_HPP
00002 #define CLOUDPOINTDATA_HPP
00003 
00004 #include "ColorCubeViewerDefinitions.hpp"
00005 #include "GeodesicForm.hpp"
00006 #include "SelectionAverage.hpp"
00007 #include <tuttle/plugin/memory/OfxAllocator.hpp>
00008 
00009 #include <boost/gil/channel_algorithm.hpp>
00010 #include <terry/numeric/operations.hpp>
00011 #include <terry/numeric/assign.hpp>
00012 
00013 #include <boost/foreach.hpp>
00014 
00015 #include <vector>
00016 #include <set>
00017 
00018 namespace tuttle {
00019 namespace plugin {
00020 namespace colorCubeViewer {
00021 
00022 typedef std::vector<float, OfxAllocator<float> > DataVector;
00023 typedef boost::gil::rgba32f_view_t SView;
00024 typedef boost::gil::rgba32f_pixel_t SPixel;
00025         
00026 
00027 template <typename PixelRef1, // models pixel concept
00028           typename PixelRef2> // models pixel concept
00029 struct pixel_is_lesser_t
00030 {
00031         GIL_FORCEINLINE
00032     bool operator()( const PixelRef1& p1,
00033                      const PixelRef2& p2) const
00034         {
00035                 for( int v = 0; v < 3/*boost::gil::num_channels<Pixel>::type::value*/; ++v )
00036                 {
00037                         if( p1[v] < p2[v] )
00038                                 return true;
00039                         if( p1[v] > p2[v] )
00040                                 return false;
00041                 }
00042         return false;
00043     }
00044 };
00045 
00046 //Functor : copy image into a buffer (ignore alpha channel)
00047 struct Pixel_copy
00048 {
00049         //Arguments
00050     DataVector& _data; //buffer to fill up
00051         bool _isSelection; //is current operation on selection (only take good alpha pixels)
00052         
00053         //Constructor
00054         Pixel_copy(DataVector& data, bool isSelection = false)
00055         :_data( data ),
00056         _isSelection(isSelection)
00057         {
00058         }
00059         //Operator ()
00060         template< typename Pixel>
00061     Pixel operator()( const Pixel& p )
00062     {
00063         using namespace boost::gil;
00064                 //is current operation for selectionVBO
00065                 if(_isSelection) //test if current operation is to selection VBO
00066                 {
00067                         if(p[3] != 1) //if current pixel is not selected (alpha != 1)
00068                                 return p; //stop treatment
00069                 }
00070                 //recopy channels
00071                 for( int v = 0; v < 3 /*boost::gil::num_channels<Pixel>::type::value*/; ++v )
00072                 {
00073                         const float val = boost::gil::channel_convert<boost::gil::bits32f>( p[v] );             //capt channel (red, green or blue)
00074                         _data.push_back( val ); //add value to buffer data
00075                 }
00076         return p;
00077     }
00078 };
00079 
00080 //Functor copy image (with discretization)
00081 template< typename Pixel>
00082 struct Pixel_copy_discretization
00083 {
00084         typedef std::set< SPixel, tuttle::plugin::colorCubeViewer::pixel_is_lesser_t<SPixel,SPixel> > PixelSet;
00085         
00086         //Arguments
00087     DataVector& _data; //buffer to fill up
00088         int _nbStep;       // discretization step
00089         float _step;       // discretization value
00090         PixelSet _setData; //we use to set to prevent double same data many times
00091         bool _isSelection; //is current operation to selection VBO
00092                         
00093         //Constructor
00094         Pixel_copy_discretization(DataVector& data, int nbStep, bool isSelection = false):
00095         _data( data ),
00096         _nbStep(nbStep),
00097         _isSelection(isSelection)
00098         {
00099                 _step = (float)(1/(float)(nbStep-1));   //compute discretization value
00100         }
00101         
00102         //Operator ()   
00103     Pixel operator()( const Pixel& p )
00104     {
00105                 Pixel add;              //used to put data in the std::set
00106         using namespace boost::gil;     
00107                 //test if current operation is to selection VBO
00108                 if(_isSelection) //test
00109                 {
00110                         if(p[3] != 1) //if current pixel is not selected (alpha != 1)
00111                                 return p; //stop treatment
00112                 }
00113                 //recopy channels
00114                 for( int v = 0; v < 3 /*boost::gil::num_channels<Pixel>::type::value*/; ++v ) //We don't want work with alpha channel
00115                 {
00116                         double val = p[v];              //capt channel (red, green or blue)
00117                         
00118                         bool placedInVector = false;    //values is not in the vector yet
00119                         int iteration = 0;                              //initialize index to 0
00120                         while(!placedInVector)                  //place round value in the vector
00121                         {
00122                                 float previousValue = iteration*_step;
00123                                 float nextValue = (iteration+1)*_step;
00124                                 if(val <= previousValue)
00125                                 {
00126                                         add[v] = previousValue;                         //add value to pixel data
00127                                         placedInVector = true;                          // value is put in the vector
00128                                 }
00129                                 else if( val < nextValue)
00130                                 {
00131                                         add[v] = nextValue;                                     //add value to pixel data
00132                                         placedInVector = true;                          //value is put in the vector
00133                                 }
00134                                 ++iteration;    //increments indice
00135                         }
00136                 }
00137                 _setData.insert(add); //insert current pixel into the set (doubles are not allowed)
00138                 return p;
00139     }
00140         
00141         //Convert _setData values to _data values
00142         void convertSetDataToVectorData()
00143         {
00144                 //iterator creation
00145                 BOOST_FOREACH( const SPixel& p, _setData )      //iterator used to scan the set
00146                 {
00147                          _data.push_back(p[0]); //red channel copy into vector
00148                          _data.push_back(p[1]); //green channel copy into vector
00149                          _data.push_back(p[2]); //blue channel copy into vector
00150                 }
00151         }
00152 };
00153 
00154 class CloudPointData {
00155 
00156 protected:
00157         //VBO class (used to add an OpenGL VBO to scene)
00158         class VBO
00159         {
00160         public:
00161                 //VBO class (for create / remove / draw VBOs)
00162                 VBO( const void* data, int dataSize, GLenum usage ) : _id( 0 ), _size( 0 ), _color( 0 ), _colorDifferent(0) // Constructor
00163                 {
00164                         createVBO( data, dataSize, usage );
00165                 }
00166                 //Constructor
00167                 VBO( ) : _id( 0 ), _size( 0 ), _color( 0 ), _colorDifferent(0) { }
00168                 //Destructor
00169                 ~VBO( ) 
00170                 {
00171                         deleteVBO( );
00172                 }
00173 
00174         public:
00175                 unsigned int _id;                       //id of vertex array   
00176                 unsigned int _idColor;          //id of color array
00177                 unsigned int _size;                     //size of vertex/color array
00178                 bool _color;                            //display with colors
00179                 bool _colorDifferent;           //is color array the same than vertex array
00180 
00181                 void selfColor( bool c )
00182                 {
00183                         _color = c;
00184                 }
00185                 // VBO management
00186                 void createVBO( const void* data, int size, GLenum usage = GL_STATIC_DRAW, const void* dataColor = NULL);       //create a new VBO
00187                 void deleteVBO( );                                                                                                                                                                                      //delete the VBO
00188                 void genBuffer( unsigned int& id, const void* data, int size, GLenum target, GLenum usage );                            //generate VBO data
00189                 void genBufferColor( unsigned int& idColor, const void* data, int size, GLenum target, GLenum usage );          //generate VBO data
00190                 void draw( );                                                                                                                                                                                           //draw VBO on screen
00191         };
00192         
00193 public:
00194         //Class arguments
00195         OfxPointI _size;                                //size of source clip
00196         OfxTime _time;                                  //current time in sequence
00197         bool _isVBOBuilt;                               //if VBO is not built don't draw it on overlay
00198         bool _isSelectionVBOBuilt;              //if color selection VBO is not built don't draw it on overlay
00199         bool _isSpillSelectionVBOBuilt; //if spill selection VBO is not built don't draw it on overlay
00200                 
00201         //VBO to draw
00202         VBO _imgVBO;                            //VBO to display on overlay (cloud point VBO)
00203         VBO _selectionColorVBO;         //VBO to display on overlay (color selection in white)
00204         VBO _selectionSpillVBO;         //VBO to display on overlay (spill selection in silver)
00205         
00206         //Data recopy
00207         DataVector _imgCopy;                    //copy of the image needed to draw VB0
00208         DataVector _selectionCopy;              //copy of the selection image to draw VBO
00209         DataVector _spillCopy;                  //copy of the selection colors to draw VBO
00210         
00211         //Overlay data
00212         SelectionAverage _averageColor;                 //color clip selection average
00213         GeodesicForm    _geodesicFormColor;             //geodesic form color (overlay)
00214         GeodesicForm    _geodesicFormSpill;             //geodesic form spill (overlay)
00215         
00216 public:
00217         //Constructor
00218         CloudPointData(const OfxPointI& size, OfxTime time);
00219         
00220         //VBO management
00221         bool generateVBOData(OFX::Clip* clipSrc, const OfxPointD& renderScale, bool vboWithDiscretization, int discretizationStep);                             //create new VBO data (fill up buffer)
00222         bool generateColorSelectionVBO(OFX::Clip* clipColor, const OfxPointD& renderScale, bool vboWithDiscretization, int discretizationStep); //Change color of selected pixel (color clip)
00223         bool generateSpillSelectionVBO(OFX::Clip* clipSpill, const OfxPointD& renderScale, bool vboWithDiscretization, int discretizationStep); //Change color of selected pixel (spill clip)
00224         void updateVBO();                                                                                                                                                                                                                                               //create the VBO from VBO data (draw function)
00225         
00226 private:
00227         //VBO data management
00228         int generateAllPointsVBOData(SView srcView);                                                                                            //generate a VBO with all of the pixels
00229         int generateDiscretizedVBOData(SView srcView, const int& discretizationStep);                           //generate a  VBO with discretization
00230         //selection VBO data management
00231         int generateAllPointsSelectionVBOData(SView srcView);                                                                           //generate a VBO (and color) with all of the selected pixels
00232         int generateAllPointsSpillVBOData(SView srcView);                                                                                       //generate a VBO (and color) with all of the selected pixels
00233 };
00234 
00235 }
00236 }
00237 }
00238 #endif  /* CLOUDPOINTDATA_HPP */
00239