TuttleOFX  1
SelectionAverage.cpp
Go to the documentation of this file.
00001 #include "SelectionAverage.hpp"
00002 
00003 #include <tuttle/plugin/opengl/gl.h>
00004 
00005 #include <terry/algorithm/transform_pixels.hpp>
00006 
00007 
00008 namespace tuttle {
00009 namespace plugin {
00010 namespace colorCubeViewer {
00011         
00012 //Constructor
00013 SelectionAverage::SelectionAverage(OfxTime time)
00014 {
00015         //initialize averageValue to 0
00016         _averageValue.x = _averageValue.y = _averageValue.z = 0;
00017         _time = time;   //get current time
00018 }
00019 
00020 
00021 /**
00022  * Draw average on screen (cross)
00023  */
00024 void SelectionAverage::draw()
00025 {
00026         float kCrossSize = 0.05f;
00027         //compute complementary color
00028         float complementaryColor[3]; 
00029         complementaryColor[0] = 1-_averageValue.x;      //complementary red
00030         complementaryColor[1] = 1-_averageValue.y;      //complementary green
00031         complementaryColor[2] = 1-_averageValue.z;      //complementary blue
00032         
00033         //compute values on X axis
00034         float xBefore = _averageValue.x-kCrossSize;     //compute before value (X axis)
00035         float xAfter = _averageValue.x + kCrossSize;    //compute after value (X axis)
00036         
00037         //compute values on Y axis
00038         float yBefore = _averageValue.y-kCrossSize;     //compute before value (Y axis)
00039         float yAfter = _averageValue.y + kCrossSize;    //compute after value (Y axis)
00040         
00041         //compute values on Z axis
00042         float zBefore = _averageValue.z-kCrossSize;     //compute before value (Z axis)
00043         float zAfter = _averageValue.z+kCrossSize;      //compute after value (Z axis)
00044         
00045         //drawing average mark
00046         glBegin(GL_LINES);
00047         glColor3f(complementaryColor[0],complementaryColor[1],complementaryColor[2]);                                                           //color : complementary to average
00048         glVertex3f(xBefore,_averageValue.y,_averageValue.z); glVertex3f(xAfter,_averageValue.y,_averageValue.z);        //X axis
00049         glVertex3f(_averageValue.x,yBefore,_averageValue.z); glVertex3f(_averageValue.x,yAfter,_averageValue.z);        //Y axis
00050         glVertex3f(_averageValue.x,_averageValue.y,zBefore); glVertex3f(_averageValue.x,_averageValue.y,zAfter);        //Z axis
00051         glEnd();
00052 }
00053 
00054 /*
00055  *Generate average from color selection clip
00056  */
00057 bool SelectionAverage::computeAverageSelection(OFX::Clip* clipColor, const OfxPointD& renderScale)
00058 {
00059         // connection test
00060         if( ! clipColor->isConnected() )
00061         {       
00062                 return false;
00063         }
00064         boost::scoped_ptr<OFX::Image> src( clipColor->fetchImage(_time, clipColor->getCanonicalRod(_time)) );   //scoped pointer of current source clip
00065 
00066         // Compatibility tests
00067         if( !src.get() ) // source isn't accessible
00068         {
00069                 std::cout << "color src is not accessible (average)" << std::endl;
00070                 return false;
00071         }
00072 
00073         if( src->getRowDistanceBytes() == 0 )//if source is wrong
00074         {
00075                 BOOST_THROW_EXCEPTION( exception::WrongRowBytes() );
00076                 return false;
00077         }
00078 
00079         const OfxRectI srcPixelRod = clipColor->getPixelRod( _time, renderScale ); //get current RoD
00080         if( (clipColor->getPixelDepth() != OFX::eBitDepthFloat) ||
00081                 (!clipColor->getPixelComponents()) )
00082         {
00083                 BOOST_THROW_EXCEPTION( exception::Unsupported() << exception::user() + "Can't compute histogram data with the actual input clip format." );
00084         return false;
00085         }
00086 
00087         //TUTTLE_TLOG_VAR( TUTTLE_INFO, src->getBounds());
00088         //TUTTLE_TLOG_VAR( TUTTLE_INFO, src->getRegionOfDefinition() );
00089 
00090         if( srcPixelRod != src->getBounds() )// the host does bad things !
00091         {
00092                 // remove overlay... but do not crash.
00093                 TUTTLE_LOG_WARNING( "Image RoD and image bounds are not the same (rod=" << srcPixelRod << " , bounds:" << src->getBounds() << ")." );
00094                 return false;
00095         }
00096 
00097         // Compute if source is OK
00098         SView colorView = tuttle::plugin::getGilView<SView>( src.get(), srcPixelRod, eImageOrientationIndependant );            // get current view from color clip
00099         ComputeAverage<SView>::CPixel average = ComputeAverage<SView>()( colorView );   // compute color clip average
00100         
00101         //copy computed average into average stock variable
00102         _averageValue.x = average[0]; //red channel value
00103         _averageValue.y = average[1]; //green channel value
00104         _averageValue.z = average[2]; //blue channel values
00105         
00106         return true; //average has been computed
00107 }
00108 
00109 /*
00110  * Extend a geodesicForm using the selection
00111  */
00112 void SelectionAverage::extendGeodesicForm(OFX::Clip* clipColor, const OfxPointD& renderScale, GeodesicForm& geodesicForm)
00113 {
00114         // connection test
00115         if( ! clipColor->isConnected() )
00116         {       
00117                 return;
00118         }
00119 
00120         boost::scoped_ptr<OFX::Image> src( clipColor->fetchImage(_time, clipColor->getCanonicalRod(_time)) );   //scoped pointer of current source clip
00121         
00122         //TUTTLE_TLOG_VAR( TUTTLE_INFO, clipColor->getPixelRod(_time,renderScale)); 
00123         //TUTTLE_TLOG_VAR( TUTTLE_INFO, clipColor->getCanonicalRod(_time, renderScale));
00124 
00125         // Compatibility tests
00126         if( !src.get() ) // source isn't accessible
00127         {
00128                 std::cout << "src is not accessible (color clip)" << std::endl;
00129                 return;
00130         }
00131 
00132         if( src->getRowDistanceBytes() == 0 )//if source is wrong
00133         {
00134                 BOOST_THROW_EXCEPTION( exception::WrongRowBytes() );
00135                 return;
00136         }
00137 
00138         const OfxRectI srcPixelRod = clipColor->getPixelRod( _time, renderScale ); //get current RoD
00139         if( (clipColor->getPixelDepth() != OFX::eBitDepthFloat) ||
00140                 (!clipColor->getPixelComponents()) )
00141         {
00142                 BOOST_THROW_EXCEPTION( exception::Unsupported() << exception::user() + "Can't compute histogram data with the actual input clip format." );
00143         return;
00144         }
00145 
00146         if( srcPixelRod != src->getBounds() )// the host does bad things !
00147         {
00148                 // remove overlay... but do not crash.
00149                 TUTTLE_LOG_WARNING( "Image RoD and image bounds are not the same (rod=" << srcPixelRod << " , bounds:" << src->getBounds() << ")." );
00150                 return;
00151         }
00152 
00153         // Compute if source is OK
00154         SView colorView = tuttle::plugin::getGilView<SView>( src.get(), srcPixelRod, eImageOrientationIndependant );            // get current view from color clip
00155         Pixel_extend_GeodesicForm funct(geodesicForm);  //functor declaration                   //initialize functor
00156         terry::algorithm::transform_pixels(colorView, funct);                                                                   //with functor reference;
00157 }
00158 
00159 }
00160 }
00161 }
00162