TuttleOFX  1
TuttleOFX/libraries/tuttle/src/tuttle/host/ComputeOptions.hpp
Go to the documentation of this file.
00001 #ifndef _TUTTLE_HOST_CORE_COMPUTEOPTIONS_HPP_
00002 #define _TUTTLE_HOST_CORE_COMPUTEOPTIONS_HPP_
00003 
00004 #include <tuttle/common/utils/global.hpp>
00005 
00006 #include <ofxCore.h>
00007 
00008 #include <tuttle/common/utils/Formatter.hpp>
00009 
00010 #include <tuttle/common/atomic.hpp>
00011 #include <boost/shared_ptr.hpp>
00012 
00013 #include <limits>
00014 #include <list>
00015 
00016 namespace tuttle {
00017 namespace host {
00018 
00019 class IProgressHandle
00020 {
00021 public:
00022         virtual ~IProgressHandle() = 0;
00023 
00024         virtual void beginSequence() {}
00025         virtual void beginFrame() {}
00026         virtual void setupAtTime() {}
00027         virtual void processAtTime() {}
00028         virtual void endFrame() {}
00029         virtual void endSequence() {}
00030 };
00031 
00032 struct TimeRange
00033 {
00034         TimeRange()
00035                 : _begin( std::numeric_limits<int>::min() )
00036                 , _end  ( std::numeric_limits<int>::max() )
00037                 , _step ( 1 )
00038         {}
00039         TimeRange( const int frame )
00040                 : _begin( frame )
00041                 , _end  ( frame )
00042                 , _step ( 1 )
00043         {}
00044         TimeRange( const int begin, const int end, const int step = 1 )
00045                 : _begin( begin )
00046                 , _end  ( end )
00047                 , _step ( step )
00048         {}
00049         TimeRange( const OfxRangeD& range, const int step = 1 );
00050         
00051         int _begin;
00052         int _end;
00053         int _step;
00054 };
00055 
00056 enum EVerboseLevel
00057 {
00058         eVerboseLevelTrace   = boost::log::trivial::trace,
00059         eVerboseLevelDebug   = boost::log::trivial::debug,
00060         eVerboseLevelInfo    = boost::log::trivial::info,
00061         eVerboseLevelWarning = boost::log::trivial::warning,
00062         eVerboseLevelError   = boost::log::trivial::error,
00063         eVerboseLevelFatal   = boost::log::trivial::fatal
00064 };
00065 
00066 class ComputeOptions
00067 {
00068 public:
00069         typedef ComputeOptions This;
00070         
00071         ComputeOptions()
00072         : _begin    ( std::numeric_limits<int>::min() )
00073         , _end      ( std::numeric_limits<int>::max() )
00074         , _abort    ( false )
00075         {
00076                 init();
00077         }
00078         
00079         explicit
00080         ComputeOptions( const int frame )
00081         : _begin    ( std::numeric_limits<int>::min() )
00082         , _end      ( std::numeric_limits<int>::max() )
00083         , _abort    ( false )
00084         {
00085                 init();
00086                 _timeRanges.push_back( TimeRange( frame, frame ) );
00087         }
00088         
00089         ComputeOptions( const int begin, const int end, const int step = 1 )
00090         : _begin    ( std::numeric_limits<int>::min() )
00091         , _end      ( std::numeric_limits<int>::max() )
00092         , _abort    ( false )
00093         {
00094                 init();
00095                 _timeRanges.push_back( TimeRange( begin, end, step ) );
00096         }
00097         
00098         ComputeOptions( const ComputeOptions& options )
00099         : _begin    ( std::numeric_limits<int>::min() )
00100         , _end      ( std::numeric_limits<int>::max() )
00101         , _abort    ( false )
00102         {
00103                 *this = options;
00104         }
00105         
00106         ComputeOptions& operator=( const ComputeOptions& other )
00107         {
00108                 _timeRanges = other._timeRanges;
00109 
00110                 _begin = other._begin;
00111                 _end = other._end;
00112                 _renderScale = other._renderScale;
00113                 _continueOnError = other._continueOnError;
00114                 _continueOnMissingFile = other._continueOnMissingFile;
00115                 _forceIdentityNodesProcess = other._forceIdentityNodesProcess;
00116                 _returnBuffers = other._returnBuffers;
00117                 _isInteractive = other._isInteractive;
00118 
00119                 // don't modify the abort status?
00120                 //_abort.store( false, boost::memory_order_relaxed );
00121                 
00122                 return *this;
00123         }
00124         
00125 private:
00126         void init()
00127         {
00128                 setRenderScale( 1.0, 1.0 );
00129                 setVerboseLevel( eVerboseLevelWarning );
00130                 setReturnBuffers            ( true  );
00131                 setContinueOnError          ( false );
00132                 setContinueOnMissingFile    ( false );
00133                 setColorEnable              ( false );
00134                 setIsInteractive            ( false );
00135                 setForceIdentityNodesProcess( false );
00136         }
00137         
00138 public:
00139         const std::list<TimeRange>& getTimeRanges() const { return _timeRanges; }
00140         
00141         int getBegin( ) const { return _begin; }
00142         int getEnd  ( ) const { return _end; }
00143         
00144         This& setTimeRange( const int begin, const int end, const int step = 1 )
00145         {
00146                 _timeRanges.clear();
00147                 addTimeRange( begin, end, step );
00148                 return *this;
00149         }
00150         This& setTimeRange( const TimeRange& timeRange )
00151         {
00152                 _timeRanges.clear();
00153                 _timeRanges.push_back( timeRange );
00154                 return *this;
00155         }
00156         This& addTimeRange( const int begin, const int end, const int step = 1 )
00157         {
00158                 addTimeRange( TimeRange(begin, end, step) );
00159                 return *this;
00160         }
00161         This& addTimeRange( const TimeRange& timeRange )
00162         {
00163                 _timeRanges.push_back( timeRange );
00164                 return *this;
00165         }
00166         
00167         This& setBegin( const int& beginTime )
00168         {
00169                 _begin = beginTime;
00170                 return *this;
00171         }
00172         
00173         This& setEnd( const int& endTime )
00174         {
00175                 _end = endTime;
00176                 return *this;
00177         }
00178         
00179         /**
00180          * @brief To get a preview of the result, you could set a renderscale.
00181          */
00182         This& setRenderScale( const double x, const double y )
00183         {
00184                 _renderScale.x = x;
00185                 _renderScale.y = y;
00186                 return *this;
00187         }
00188         const OfxPointD& getRenderScale() const { return _renderScale; }
00189         
00190         /**
00191          * @brief Continue as much as possible after an error.
00192          * If an image file inside an image sequence failed to be loaded, we continue to process other images of the sequence.
00193          */
00194         This& setContinueOnError( const bool v = true )
00195         {
00196                 _continueOnError = v;
00197                 return *this;
00198         }
00199         bool getContinueOnError() const { return _continueOnError; }
00200         
00201         /**
00202          * @brief Continue as much as possible after an error.
00203          * If an image file inside an image sequence failed to be loaded, we continue to process other images of the sequence.
00204          */
00205         This& setContinueOnMissingFile( const bool v = true )
00206         {
00207                 _continueOnMissingFile = v;
00208                 return *this;
00209         }
00210         bool getContinueOnMissingFile() const { return _continueOnMissingFile; }
00211         
00212         /**
00213          * @brief To get output buffer of all output nodes.
00214          */
00215         This& setReturnBuffers( const bool v = true )
00216         {
00217                 _returnBuffers = v;
00218                 return *this;
00219         }
00220         bool getReturnBuffers() const { return _returnBuffers; }
00221         
00222         /**
00223          * @brief Set the verbose level of the process.
00224          */
00225         This& setVerboseLevel( const EVerboseLevel level )
00226         {
00227                 tuttle::common::Formatter::get()->setLogLevel( static_cast<boost::log::trivial::severity_level>( level ) );
00228                 return *this;
00229         }
00230         
00231         /**
00232          * @brief Set the output color enabled or not.
00233          */
00234         This& setColorEnable( const bool enable = true )
00235         {
00236                 enable ?
00237                         tuttle::common::Color::get()->enable() :
00238                         tuttle::common::Color::get()->disable();
00239                 return *this;
00240         }
00241         
00242         /**
00243          * @brief Inform plugins about the kind of process: batch or interactive.
00244          */
00245         This& setIsInteractive( const bool v = true )
00246         {
00247                 _isInteractive = v;
00248                 return *this;
00249         }
00250         bool getIsInteractive() const { return _isInteractive; }
00251         
00252         /**
00253          * @brief For debug puposes only, you could force to call the process on all identity nodes.
00254          * This case should never happens to the plugin, so it may fail to do it.
00255          */
00256         This& setForceIdentityNodesProcess( const bool v = true )
00257         {
00258                 _forceIdentityNodesProcess = v;
00259                 return *this;
00260         }
00261         bool getForceIdentityNodesProcess() const { return _forceIdentityNodesProcess; }
00262         
00263         /**
00264          * @brief The application would like to abort the process (from another thread).
00265          */
00266         void abort()
00267         {
00268                 _abort.store( true, boost::memory_order_relaxed );
00269         }
00270         /**
00271          * @brief Has someone asked to abort the process?
00272          */
00273         bool getAbort() const { return _abort.load( boost::memory_order_relaxed ); }
00274 
00275         /**
00276         * @brief A handle to follow the progress (start, end...) of the compute
00277         */
00278         void setProgressHandle( boost::shared_ptr<IProgressHandle> progressHandle)
00279         {
00280                 _progressHandle = progressHandle;
00281         }
00282         bool isProgressHandleSet() const
00283         {
00284                 return _progressHandle.get() != NULL;
00285         }
00286         void beginSequenceHandle() const
00287         {
00288                 if( isProgressHandleSet() )
00289                         _progressHandle->beginSequence();
00290         }
00291         void beginFrameHandle() const
00292         {
00293                 if( isProgressHandleSet() )
00294                         _progressHandle->beginFrame();
00295         }
00296         void setupAtTimeHandle() const
00297         {
00298                 if( isProgressHandleSet() )
00299                         _progressHandle->setupAtTime();
00300         }
00301         void processAtTimeHandle() const
00302         {
00303                 if( isProgressHandleSet() )
00304                         _progressHandle->processAtTime();
00305         }
00306         void endFrameHandle() const
00307         {
00308                 if( isProgressHandleSet() )
00309                         _progressHandle->endFrame();
00310         }
00311         void endSequenceHandle() const
00312         {
00313                 if( isProgressHandleSet() )
00314                         _progressHandle->endSequence();
00315         }
00316 
00317 private:
00318         std::list<TimeRange> _timeRanges;
00319         
00320         OfxPointD _renderScale;
00321         // different to range
00322         int _begin;
00323         int _end;
00324         
00325         bool _continueOnError;
00326         bool _continueOnMissingFile;
00327         bool _forceIdentityNodesProcess;
00328         bool _returnBuffers;
00329         bool _isInteractive;
00330         
00331         boost::atomic_bool _abort;
00332 
00333         boost::shared_ptr<IProgressHandle> _progressHandle;
00334 };
00335 
00336 }
00337 }
00338 
00339 #endif