TuttleOFX  1
LensDistortOverlayInteract.cpp
Go to the documentation of this file.
00001 #include "LensDistortOverlayInteract.hpp"
00002 #include "lensDistortDefinitions.hpp"
00003 #include "LensDistortPlugin.hpp"
00004 #include "lensDistortAlgorithm.hpp"
00005 #include <tuttle/plugin/opengl/gl.h>
00006 #include <tuttle/plugin/interact/interact.hpp>
00007 #include <tuttle/plugin/interact/overlay.hpp>
00008 #include <tuttle/plugin/interact/ParamPoint.hpp>
00009 #include <tuttle/plugin/interact/ParamPointRelativePoint.hpp>
00010 #include <tuttle/plugin/interact/ParamPoint.hpp>
00011 #include <tuttle/plugin/ofxToGil/point.hpp>
00012 
00013 #include <ofxsImageEffect.h>
00014 #include <ofxsInteract.h>
00015 #include <boost/gil/gil_all.hpp>
00016 
00017 #include <vector>
00018 
00019 namespace tuttle {
00020 namespace plugin {
00021 namespace lens {
00022 
00023 /**
00024  * @brief create a list of points which represents a grid in image coordinates
00025  * @param imgSize image size (in pixels)
00026  * @param nbTiles number of tiles
00027  * @param scale scale of the grid (normalized value)
00028  * @param center shift to apply on the image (normalized value)
00029  */
00030 template<typename Point2>
00031 std::vector<std::vector<Point2> > createGrid( const OfxRectD& rod, const unsigned int nbTiles, const Point2& scale, const Point2& center, const unsigned int steps = 50 )
00032 {
00033         //      Point2 rodCorner( rod.x1, rod.y1 );
00034         Point2 rodSize( rod.x2 - rod.x1, rod.y2 - rod.y1 );
00035         const unsigned int size = nbTiles + 1; // number of lines
00036         const double stepSize   = rodSize.x / (double) steps;
00037         const double tileSize   = rodSize.x / (double) nbTiles;
00038         const double halfSize   = rodSize.x / 2.0;
00039         const double yShift     = ( rodSize.x - rodSize.y ) / 2.0; // vertical shift (because it's a squared grid)
00040         const Point2 pixCenter  = ( center * rodSize.x ); // center in pixel coordinates
00041 
00042         std::vector<std::vector<Point2> > lines;
00043         lines.reserve( 2 * size );
00044         for( unsigned int i = 0; i < size; ++i )
00045         {
00046                 std::vector<Point2> horizontal, vertical;
00047                 horizontal.reserve( steps );
00048                 vertical.reserve( steps );
00049                 for( unsigned int j = 0; j <= steps; ++j )
00050                 {
00051                         double si = ( i * tileSize ) - halfSize;
00052                         Point2 diagonal( si * scale.x + halfSize + pixCenter.x, si * scale.y + halfSize + pixCenter.y - yShift );
00053                         double sj = ( j * stepSize ) - halfSize;
00054                         horizontal.push_back( Point2( sj * scale.x + halfSize + pixCenter.x, diagonal.y ) );
00055                         vertical.push_back( Point2( diagonal.x, sj * scale.y + halfSize + pixCenter.y - yShift ) );
00056                 }
00057                 lines.push_back( horizontal );
00058                 lines.push_back( vertical );
00059         }
00060         return lines;
00061 }
00062 
00063 template<typename Point2>
00064 void shiftGrid( std::vector<std::vector<Point2> >& grid, const Point2& shift )
00065 {
00066         for( typename std::vector<std::vector<Point2> >::iterator itv = grid.begin(), itvEnd = grid.end();
00067              itv != itvEnd;
00068              ++itv )
00069         {
00070                 for( typename std::vector<Point2>::iterator it = itv->begin(), itEnd = itv->end();
00071                      it != itEnd;
00072                      ++it  )
00073                 {
00074                         *it += shift;
00075                 }
00076         }
00077 }
00078 
00079 LensDistortOverlayInteract::LensDistortOverlayInteract( OfxInteractHandle handle, OFX::ImageEffect* effect )
00080         : OFX::OverlayInteract( handle )
00081         , _infos( effect )
00082         , _interactScene( *effect, _infos )
00083 {
00084         _effect = effect;
00085         _plugin = static_cast<LensDistortPlugin*>( _effect );
00086 
00087         const interact::FrameOptionalClip frame( _plugin->_srcRefClip, _plugin->_clipSrc );
00088         interact::PointInteract* centerPoint = new interact::ParamPoint<interact::FrameOptionalClip, eCoordinateSystemXXcn>( _infos, _plugin->_center, frame );
00089         _interactScene.push_back( new interact::ParamPointRelativePoint<interact::FrameOptionalClip, eCoordinateSystemXXcn>( _infos, _plugin->_gridCenter, frame, centerPoint ), new interact::IsActiveBooleanParamFunctor<>( _plugin->_gridCenterOverlay ) );
00090         _interactScene.push_back( centerPoint, new interact::IsActiveBooleanParamFunctor<>( _plugin->_centerOverlay ) );
00091 }
00092 
00093 bool LensDistortOverlayInteract::draw( const OFX::DrawArgs& args )
00094 {
00095         typedef boost::gil::point2<Scalar> Point2;
00096         static const float lineWidth = 2.0;
00097         bool displaySomething        = false;
00098 
00099         // debug drawing
00100         if( _plugin->_debugDisplayRoi->getValue() )
00101         {
00102                 glLineWidth( lineWidth );
00103                 displaySomething = true;
00104 
00105                 glColor3f( 1.0f, 0.0f, 0.0f );
00106                 overlay::displayRect( _plugin->_dstRoi, -1 );
00107 
00108                 glColor3f( 0.0f, 1.0f, 0.0f );
00109                 overlay::displayRect( _plugin->_srcRoi, 1 );
00110 
00111                 glColor3f( 0.0f, 0.0f, 1.0f );
00112                 overlay::displayRect( _plugin->_srcRealRoi, 1 );
00113         }
00114 
00115         displaySomething |= _interactScene.draw( args );
00116 
00117         // drawing
00118         if( _plugin->_gridOverlay->getValue() && _plugin->_clipSrc->isConnected() )
00119         {
00120                 displaySomething = true;
00121                 static const unsigned int steps = 10;
00122 
00123                 // get the project size
00124                 OfxRectD srcRod = _plugin->_clipSrc->getCanonicalRod( args.time );
00125                 if( _plugin->_srcRefClip->isConnected() )
00126                         srcRod = _plugin->_srcRefClip->getCanonicalRod( args.time );
00127 
00128                 const Point2 imgSize( srcRod.x2 - srcRod.x1, srcRod.y2 - srcRod.y1 );
00129 //              const OfxRectD outputRod = _plugin->_clipDst->getCanonicalRod( args.time );
00130                 //parameters
00131                 const Point2 gridCenter( ofxToGil( _plugin->_gridCenter->getValue() ) );
00132                 const Point2 gridScale( ofxToGil( _plugin->_gridScale->getValue() ) );
00133                 std::vector<std::vector<Point2> > grid = createGrid( srcRod, steps, gridScale, gridCenter );
00134                 if( !_plugin->_displaySource->getValue() )
00135                 {
00136                         LensDistortProcessParams<Scalar> params;
00137                         static const double pixelAspectRatio = 1.0; // here the pixel aspect ratio is 1.0 because we work in canonical coordinates
00138                         params = _plugin->getProcessParams( srcRod, srcRod, pixelAspectRatio, true );
00139                         // work in output clip coordinates
00140                         transformValuesApply( _plugin->getLensType(), params, grid );
00141                 }
00142                 Point2 rodCorner( srcRod.x1, srcRod.y1 );
00143                 shiftGrid( grid, rodCorner ); // to move in RoW coordinates
00144 
00145                 glLineWidth( lineWidth );
00146                 glColor3f( 1.0f, 1.0f, 0.0f );
00147                 overlay::drawCurves( grid );
00148         }
00149         return displaySomething;
00150 }
00151 
00152 bool LensDistortOverlayInteract::penMotion( const OFX::PenArgs& args )
00153 {
00154         return _interactScene.penMotion( args );
00155 }
00156 
00157 bool LensDistortOverlayInteract::penDown( const OFX::PenArgs& args )
00158 {
00159         return _interactScene.penDown( args );
00160 }
00161 
00162 bool LensDistortOverlayInteract::penUp( const OFX::PenArgs& args )
00163 {
00164         return _interactScene.penUp( args );
00165 }
00166 
00167 }
00168 }
00169 }