TuttleOFX
1
|
00001 #include "FloodFillPlugin.hpp" 00002 00003 #include <tuttle/plugin/ofxToGil/rect.hpp> 00004 #include <tuttle/plugin/ofxToGil/point.hpp> 00005 #include <tuttle/plugin/numeric/rectOp.hpp> 00006 #include <tuttle/plugin/memory/OfxAllocator.hpp> 00007 00008 #include <terry/globals.hpp> 00009 #include <terry/filter/floodFill.hpp> 00010 #include <terry/algorithm/transform_pixels_progress.hpp> 00011 #include <terry/draw/fill.hpp> 00012 00013 #include <terry/numeric/operations.hpp> 00014 #include <terry/numeric/minmax.hpp> 00015 #include <terry/channel_view.hpp> 00016 00017 namespace tuttle { 00018 namespace plugin { 00019 namespace floodFill { 00020 00021 template<class View> 00022 FloodFillProcess<View>::FloodFillProcess( FloodFillPlugin &effect ) 00023 : ImageGilFilterProcessor<View>( effect, eImageOrientationIndependant ) 00024 , _plugin( effect ) 00025 { 00026 this->setNoMultiThreading(); 00027 } 00028 00029 template<class View> 00030 void FloodFillProcess<View>::setup( const OFX::RenderArguments& args ) 00031 { 00032 ImageGilFilterProcessor<View>::setup( args ); 00033 00034 using namespace terry; 00035 using namespace terry::numeric; 00036 00037 _params = _plugin.getProcessParams( args.renderScale ); 00038 00039 if( _params._relativeMinMax ) 00040 { 00041 // typedef channel_view_type<red_t,View> LocalView; 00042 typedef kth_channel_view_type<0,View> LocalView; 00043 typename LocalView::type localView( LocalView::make(this->_srcView) ); 00044 pixel_minmax_by_channel_t<typename LocalView::type::value_type> minmax( localView(0,0) ); 00045 terry::algorithm::transform_pixels_progress( 00046 localView, 00047 minmax, 00048 *this ); 00049 00050 _isConstantImage = minmax.max[0] == minmax.min[0]; 00051 _lowerThres = (_params._lowerThres * (minmax.max[0]-minmax.min[0])) + minmax.min[0]; 00052 _upperThres = (_params._upperThres * (minmax.max[0]-minmax.min[0])) + minmax.min[0]; 00053 } 00054 else 00055 { 00056 _isConstantImage = false; 00057 _lowerThres = _params._lowerThres; 00058 _upperThres = _params._upperThres; 00059 } 00060 } 00061 00062 /** 00063 * @brief Function called by rendering thread each time a process must be done. 00064 * @param[in] procWindowRoW Processing window 00065 */ 00066 template<class View> 00067 void FloodFillProcess<View>::multiThreadProcessImages( const OfxRectI& procWindowRoW ) 00068 { 00069 using namespace boost::gil; 00070 using namespace terry; 00071 OfxRectI procWindowOutput = this->translateRoWToOutputClipCoordinates( procWindowRoW ); 00072 00073 static const unsigned int border = 1; 00074 const OfxRectI srcRodCrop = rectangleReduce( this->_srcPixelRod, border ); 00075 const OfxRectI procWindowRoWCrop = rectanglesIntersection( procWindowRoW, srcRodCrop ); 00076 00077 terry::draw::fill_pixels( this->_dstView, ofxToGil(procWindowOutput), get_black<Pixel>() ); 00078 00079 if( _isConstantImage ) 00080 return; 00081 00082 using namespace terry::filter::floodFill; 00083 00084 switch( _params._method ) 00085 { 00086 case eParamMethod4: 00087 { 00088 flood_fill<Connexity4, IsUpper<Scalar>, IsUpper<Scalar>, View, View, OfxAllocator>( 00089 this->_srcView, ofxToGil(this->_srcPixelRod), 00090 this->_dstView, ofxToGil(this->_dstPixelRod), 00091 ofxToGil(procWindowRoWCrop), 00092 IsUpper<Scalar>(_upperThres), 00093 IsUpper<Scalar>(_lowerThres) 00094 ); 00095 break; 00096 } 00097 case eParamMethod8: 00098 { 00099 flood_fill<Connexity8, IsUpper<Scalar>, IsUpper<Scalar>, View, View, OfxAllocator>( 00100 this->_srcView, ofxToGil(this->_srcPixelRod), 00101 this->_dstView, ofxToGil(this->_dstPixelRod), 00102 ofxToGil(procWindowRoWCrop), 00103 IsUpper<Scalar>(_upperThres), 00104 IsUpper<Scalar>(_lowerThres) 00105 ); 00106 break; 00107 } 00108 case eParamMethodBruteForce: // not in production 00109 { 00110 // flood_fill_bruteForce<IsUpper<Scalar>, IsUpper<Scalar>, View, View>( 00111 // this->_srcView, ofxToGil(this->_srcPixelRod), 00112 // this->_dstView, ofxToGil(this->_dstPixelRod), 00113 // ofxToGil(procWindowRoWCrop), 00114 // IsUpper<Scalar>(_upperThres), 00115 // IsUpper<Scalar>(_lowerThres) 00116 // ); 00117 break; 00118 } 00119 } 00120 } 00121 00122 } 00123 } 00124 }