TuttleOFX  1
ConvolutionPlugin.cpp
Go to the documentation of this file.
00001 #include "ConvolutionPlugin.hpp"
00002 #include "ConvolutionProcess.hpp"
00003 #include "ConvolutionDefinitions.hpp"
00004 
00005 #include <boost/gil/gil_all.hpp>
00006 
00007 #include <boost/numeric/conversion/cast.hpp>
00008 
00009 namespace tuttle {
00010 namespace plugin {
00011 namespace convolution {
00012 
00013 ConvolutionPlugin::ConvolutionPlugin( OfxImageEffectHandle handle )
00014         : ImageEffectGilPlugin( handle )
00015 {
00016         _paramSize = fetchInt2DParam( kParamSize );
00017         _paramBorder = fetchChoiceParam( kParamBorder );
00018 
00019         _paramCoef.resize( kParamSizeMax );
00020         for( unsigned int y = 0; y < kParamSizeMax; ++y )
00021         {
00022                 _paramCoef[y].resize( kParamSizeMax );
00023                 for( unsigned int x = 0; x < kParamSizeMax; ++x )
00024                 {
00025                         _paramCoef[y][x] = fetchDoubleParam( getCoefName( y, x ) );
00026                 }
00027         }
00028 }
00029 
00030 ConvolutionProcessParams ConvolutionPlugin::getProcessParams() const
00031 {
00032         using namespace terry::filter;
00033         
00034         ConvolutionProcessParams params;
00035 
00036         const OfxPointI size = _paramSize->getValue();
00037 
00038         params._size.x = boost::numeric_cast<unsigned int>( size.x );
00039         params._size.y = boost::numeric_cast<unsigned int>( size.y );
00040         
00041         params._boundary_option = convolve_option_extend_mirror;
00042         params._border = static_cast<EParamBorder>( _paramBorder->getValue() );
00043         
00044         switch( params._border )
00045         {
00046                 case eParamBorderMirror:
00047                         params._boundary_option = convolve_option_extend_mirror;
00048                         break;
00049                 case eParamBorderConstant:
00050                         params._boundary_option = convolve_option_extend_constant;
00051                         break;
00052                 case eParamBorderBlack:
00053                         params._boundary_option = convolve_option_extend_zero;
00054                         break;
00055                 case eParamBorderPadded:
00056                         params._boundary_option = convolve_option_extend_padded;
00057                         break;
00058         }
00059         params._convX.resize( params._size.x );
00060         params._convY.resize( params._size.y );
00061         for( unsigned int i = 0; i < params._size.x; ++i )
00062         {
00063                 params._convX[i] = _paramCoef[0][i]->getValue();
00064         }
00065         for( unsigned int i = 0; i < params._size.y; ++i )
00066         {
00067                 params._convY[i] = _paramCoef[1][i]->getValue();
00068         }
00069         /*
00070         params._convMatrix.resize( params._size.x, params._size.y );
00071         for( unsigned int y = 0; y < params._size.y; ++y )
00072         {
00073 //              unsigned int yy = y * params._size.x;
00074                 for( unsigned int x = 0; x < params._size.x; ++x )
00075                 {
00076                         params._convMatrix(x, y) = _paramCoef[y][x]->getValue();
00077                         TUTTLE_LOG_INFO( "coef[" << y << "][" << x << "] = " << params._convMatrix(x, y) );
00078                 }
00079         }
00080         */
00081         return params;
00082 }
00083 
00084 /**
00085  * @brief The overridden render function
00086  * @param[in]   args     Rendering parameters
00087  */
00088 void ConvolutionPlugin::render( const OFX::RenderArguments& args )
00089 {
00090         doGilRender<ConvolutionProcess>( *this, args );
00091 }
00092 
00093 bool ConvolutionPlugin::getRegionOfDefinition( const OFX::RegionOfDefinitionArguments& args, OfxRectD& rod )
00094 {
00095         const ConvolutionProcessParams params = getProcessParams();
00096         const OfxRectD srcRod = _clipSrc->getCanonicalRod( args.time );
00097         
00098         switch( params._border )
00099         {
00100                 case eParamBorderPadded:
00101                         rod.x1 = srcRod.x1 + params._convX.left_size();
00102                         rod.y1 = srcRod.y1 + params._convY.left_size();
00103                         rod.x2 = srcRod.x2 - params._convX.right_size();
00104                         rod.y2 = srcRod.y2 - params._convY.right_size();
00105                         return true;
00106                 default:
00107                         break;
00108         }
00109         return false;
00110 }
00111 
00112 void ConvolutionPlugin::getRegionsOfInterest( const OFX::RegionsOfInterestArguments& args, OFX::RegionOfInterestSetter& rois )
00113 {
00114         OfxRectD srcRoi = args.regionOfInterest;
00115         const OfxPointI size  = _paramSize->getValue();
00116         OfxPointD halfSize;
00117 
00118         halfSize.x = size.x * 0.5;
00119         halfSize.y = size.y * 0.5;
00120         srcRoi.x1 -= halfSize.x;
00121         srcRoi.x2 += halfSize.x;
00122         srcRoi.y1 -= halfSize.y;
00123         srcRoi.y2 += halfSize.y;
00124         rois.setRegionOfInterest( *_clipSrc, srcRoi );
00125 }
00126 
00127 bool ConvolutionPlugin::isIdentity( const OFX::RenderArguments& args, OFX::Clip*& identityClip, double& identityTime )
00128 {
00129         const OfxPointI size  = _paramSize->getValue();
00130         if( size.x != 0 || size.y != 0 )
00131                 return false;
00132 
00133         identityClip = _clipSrc;
00134         identityTime = args.time;
00135         return true;
00136 }
00137 
00138 void ConvolutionPlugin::changedParam( const OFX::InstanceChangedArgs& args, const std::string& paramName )
00139 {
00140         if( paramName == kParamSize && args.reason == OFX::eChangeUserEdit )
00141         {
00142                 const OfxPointI v = _paramSize->getValue();
00143                 OfxPointI oddNumber;
00144                 oddNumber.x = v.x | 1; // odd number
00145                 oddNumber.y = v.y | 1; // odd number
00146                 if( oddNumber != v )
00147                         _paramSize->setValue( oddNumber );
00148                 
00149                 // separable convolution
00150                 for( unsigned int x = 0; x < kParamSizeMax; ++x )
00151                 {
00152                         _paramCoef[0][x]->setIsSecretAndDisabled( static_cast<int>(x) >= v.x );
00153                         _paramCoef[1][x]->setIsSecretAndDisabled( static_cast<int>(x) >= v.y );
00154                 }
00155                 // disable other matrix values
00156                 for( unsigned int y = 2; y < kParamSizeMax; ++y )
00157                 {
00158                         for( unsigned int x = 0; x < kParamSizeMax; ++x )
00159                         {
00160                                 _paramCoef[y][x]->setIsSecretAndDisabled( true );
00161                         }
00162                 }
00163         }
00164 }
00165 
00166 }
00167 }
00168 }
00169