TuttleOFX
1
|
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