TuttleOFX
1
|
00001 #include "WarpAlgorithm.hpp" 00002 #include "WarpPlugin.hpp" 00003 00004 #include <terry/sampler/resample_progress.hpp> 00005 #include <terry/algorithm/transform_pixels_progress.hpp> 00006 #include <tuttle/plugin/exceptions.hpp> 00007 00008 #include <terry/globals.hpp> 00009 00010 namespace tuttle { 00011 namespace plugin { 00012 namespace warp { 00013 00014 template<class View> 00015 WarpProcess<View>::WarpProcess( WarpPlugin &effect ) 00016 : ImageGilFilterProcessor<View>( effect, eImageOrientationFromTopToBottom ) 00017 , _plugin( effect ) 00018 { 00019 _clipSrcB = effect.fetchClip( kClipSourceB ); 00020 } 00021 00022 template<class View> 00023 void WarpProcess<View>::setup( const OFX::RenderArguments& args ) 00024 { 00025 ImageGilFilterProcessor<View>::setup( args ); 00026 _params = _plugin.getProcessParams( args.renderScale ); 00027 00028 if( this->_clipSrcB->isConnected( ) ) 00029 { 00030 // srcB initialization 00031 this->_srcB.reset( _clipSrcB->fetchImage( args.time ) ); 00032 if( !this->_srcB.get( ) ) 00033 { 00034 BOOST_THROW_EXCEPTION( exception::ImageNotReady( ) ); 00035 } 00036 00037 // Commented because of a build error : 00038 // getRowBytes( ) is not a method of OFX::Image 00039 // TODO: Fix this 00040 // if( this->_srcB->getRowBytes( ) == 0 ) 00041 // { 00042 // BOOST_THROW_EXCEPTION( exception::WrongRowBytes( ) ); 00043 // } 00044 00045 // _srcBPixelRod = _srcB->getRegionOfDefinition(); // bug in nuke, returns bounds 00046 _srcBPixelRod = _clipSrcB->getPixelRod( args.time, args.renderScale ); 00047 this->_srcBView = this->getView( this->_srcB.get( ), _srcBPixelRod ); 00048 _tpsB.setup( _params._bezierOut, _params._bezierIn, _params._rigiditeTPS, _params._activateWarp, this->_srcBPixelRod.x2 - this->_srcBPixelRod.x1, this->_srcBPixelRod.y2 - this->_srcBPixelRod.y1, ( 1.0 - _params._transition ) ); 00049 } 00050 //TPS_Morpher<Scalar> tps( _params._inPoints, _params._outPoints , _params._rigiditeTPS); 00051 _tpsA.setup( _params._bezierIn, _params._bezierOut, _params._rigiditeTPS, _params._activateWarp, this->_srcPixelRod.x2 - this->_srcPixelRod.x1, this->_srcPixelRod.y2 - this->_srcPixelRod.y1, _params._transition ); 00052 //TUTTLE_TCOUT_VAR( _params._rigiditeTPS ); 00053 //TUTTLE_TCOUT_VAR( _params._activateWarp ); 00054 } 00055 00056 /** 00057 * @brief Function called by rendering thread each time a process must be done. 00058 * @param[in] procWindowRoW Processing window 00059 */ 00060 template<class View> 00061 void WarpProcess<View>::multiThreadProcessImages( const OfxRectI& procWindowRoW ) 00062 { 00063 using namespace boost::gil; 00064 using namespace terry::sampler; 00065 using namespace terry::algorithm; 00066 const OfxRectI procWindowOutput = translateRegion( procWindowRoW, this->_dstPixelRod ); 00067 const OfxRectI procWindowSrcA = translateRegion( procWindowRoW, this->_srcPixelRod ); 00068 const OfxRectI procWindowSrcB = translateRegion( procWindowRoW, this->_srcBPixelRod ); 00069 00070 OfxPointI procWindowSize = { procWindowRoW.x2 - procWindowRoW.x1, 00071 procWindowRoW.y2 - procWindowRoW.y1 }; 00072 00073 const EParamFilterOutOfImage outOfImageProcess = eParamFilterOutBlack; /// @todo expose as parameter 00074 00075 if( this->_clipSrcB->isConnected( ) ) 00076 { 00077 Image imgA( procWindowSize.x, procWindowSize.y ); 00078 Image imgB( procWindowSize.x, procWindowSize.y ); 00079 View viewA = subimage_view( 00080 view(imgA), 00081 this->_srcPixelRod.x1-procWindowRoW.x1, this->_srcPixelRod.y1-procWindowRoW.y1, 00082 this->_srcView.width(), this->_srcView.height() ); 00083 View viewB = subimage_view( 00084 view(imgB), 00085 this->_srcBPixelRod.x1-procWindowRoW.x1, this->_srcBPixelRod.y1-procWindowRoW.y1, 00086 this->_srcBView.width(), this->_srcBView.height() ); 00087 00088 resample_pixels_progress<terry::sampler::bilinear_sampler>( this->_srcView, viewA, _tpsA, procWindowSrcA, outOfImageProcess, this->getOfxProgress() ); 00089 resample_pixels_progress<terry::sampler::bilinear_sampler>( this->_srcBView, viewB, _tpsB, procWindowSrcB, outOfImageProcess, this->getOfxProgress() ); 00090 00091 //fondu entre imgA et imgB = this->_dstView FAITEALAMAIN 00092 View dst = subimage_view( this->_dstView, procWindowOutput.x1, procWindowOutput.y1, 00093 procWindowSize.x, procWindowSize.y ); 00094 transform_pixels_progress( 00095 view( imgA ), 00096 view( imgB ), 00097 dst, 00098 pixel_merge_t<Pixel > ( _params._transition ), 00099 this->getOfxProgress() ); 00100 } 00101 else 00102 { 00103 View dst = subimage_view( 00104 this->_dstView, 00105 this->_srcPixelRod.x1-this->_dstPixelRod.x1, this->_srcPixelRod.y1-this->_dstPixelRod.y1, 00106 this->_srcView.width(), this->_srcView.height() ); 00107 resample_pixels_progress<terry::sampler::bilinear_sampler > ( this->_srcView, dst, _tpsA, procWindowSrcA, outOfImageProcess, this->getOfxProgress() ); 00108 } 00109 } 00110 00111 } 00112 } 00113 }