TuttleOFX  1
INode.hpp
Go to the documentation of this file.
00001 #ifndef _TUTTLE_HOST_INODE_HPP_
00002 #define _TUTTLE_HOST_INODE_HPP_
00003 
00004 #include <tuttle/host/exceptions.hpp>
00005 
00006 #include <ofxCore.h>
00007 #include <ofxAttribute.h>
00008 
00009 #include <boost/noncopyable.hpp>
00010 
00011 #include <iostream>
00012 #include <string>
00013 #include <vector>
00014 #include <set>
00015 #include <map>
00016 
00017 namespace tuttle {
00018 namespace host {
00019 
00020 namespace ofx {
00021 namespace attribute {
00022 class OfxhParam;
00023 class OfxhParamSet;
00024 class OfxhClipImageSet;
00025 }
00026 namespace property{
00027 class OfxhSet;
00028 }
00029 }
00030 namespace attribute {
00031 class Attribute;
00032 class Clip;
00033 class ClipImage;
00034 }
00035 namespace graph {
00036 class ProcessVertexAtTimeData;
00037 class ProcessVertexData;
00038 class ProcessVertexAtTimeInfo;
00039 }
00040 
00041 class ImageEffectNode;
00042 
00043 
00044 class INode : private boost::noncopyable
00045 {
00046 public:
00047         typedef INode This;
00048         
00049         typedef std::set<OfxTime> TimesSet;
00050         typedef std::map<std::string, TimesSet> ClipTimesSetMap;
00051         
00052         enum ENodeType
00053         {
00054                 eNodeTypeUnknown,
00055                 eNodeTypeImageEffect,
00056                 eNodeTypeParam,
00057                 eNodeTypeGraph,
00058                 eNodeTypeBuffer,
00059         };
00060         
00061 public:
00062         INode() {}
00063         INode( const INode& e ) {}
00064         
00065         virtual ~INode() = 0;
00066         virtual INode* clone() const = 0;
00067         virtual bool operator==( const INode& ) const = 0;
00068         
00069         virtual const std::string& getName() const = 0;
00070         virtual void setName( const std::string& name ) = 0;
00071         virtual const ENodeType    getNodeType() const = 0;
00072 
00073         ImageEffectNode& asImageEffectNode();
00074         const ImageEffectNode& asImageEffectNode() const;
00075 
00076         virtual std::vector<int> getVersion() const = 0;
00077         std::string getVersionStr() const;
00078         
00079         virtual std::string getLabel() const = 0;
00080 
00081         virtual const ofx::property::OfxhSet& getProperties() const = 0;
00082         virtual ofx::property::OfxhSet&       getEditableProperties() = 0;
00083 
00084         virtual attribute::Attribute& getAttribute( const std::string& name ) = 0;
00085         const attribute::Attribute& getAttribute( const std::string& name ) const { return const_cast<INode*>(this)->getAttribute( name ); }
00086         virtual attribute::Attribute&       getSingleInputAttribute()       = 0;
00087         virtual const attribute::Attribute& getSingleInputAttribute() const = 0;
00088         
00089         virtual std::size_t getNbParams() const = 0;
00090         virtual const ofx::attribute::OfxhParam& getParam( const std::string& name ) const = 0;
00091         virtual ofx::attribute::OfxhParam&       getParam( const std::string& name ) = 0;
00092         virtual const ofx::attribute::OfxhParam& getParamByScriptName( const std::string& name, const bool acceptPartialName = false ) const = 0;
00093         virtual ofx::attribute::OfxhParam&       getParamByScriptName( const std::string& name, const bool acceptPartialName = false ) = 0;
00094         virtual const ofx::attribute::OfxhParam& getParam( const std::size_t  index ) const = 0;
00095         virtual ofx::attribute::OfxhParam&       getParam( const std::size_t  index ) = 0;
00096 
00097         virtual attribute::ClipImage&       getClip( const std::string& name, const bool acceptPartialName = false ) = 0;
00098         virtual const attribute::ClipImage& getClip( const std::string& name, const bool acceptPartialName = false ) const = 0;
00099 
00100         attribute::ClipImage&       getOutputClip()       { return getClip( kOfxImageEffectOutputClipName ); }
00101         const attribute::ClipImage& getOutputClip() const { return getClip( kOfxImageEffectOutputClipName ); }
00102 
00103         virtual ofx::attribute::OfxhParamSet& getParamSet() = 0;
00104         virtual const ofx::attribute::OfxhParamSet& getParamSet() const = 0;
00105 
00106         virtual ofx::attribute::OfxhClipImageSet& getClipImageSet() = 0;
00107         virtual const ofx::attribute::OfxhClipImageSet& getClipImageSet() const = 0;
00108 
00109         virtual std::size_t getLocalHashAtTime( const OfxTime time ) const = 0;
00110 
00111 #ifndef SWIG
00112         virtual void connect( const INode&, attribute::Attribute& ) = 0;
00113 
00114         virtual void setup1() = 0;
00115         virtual void setup2_reverse() = 0;
00116         virtual void setup3() = 0;
00117         
00118         virtual OfxRangeD computeTimeDomain() = 0;
00119 
00120 //      virtual OfxTime mapInputTime( const OfxTime time ) const = 0;
00121         
00122         virtual OfxRangeD getTimeDomain() const = 0;
00123         
00124         /**
00125          * @brief Begin of the a new frame range to process. Initilize this node.
00126          * @param[in] processData
00127          * @remark called on each node without predefined order.
00128          */
00129         virtual void beginSequence( graph::ProcessVertexData& processData ) = 0;
00130 
00131         /**
00132          * @brief Asks the plugin all times it needs for each of it's input clips.
00133          * @param[in] time
00134          */
00135         virtual ClipTimesSetMap getTimesNeeded( const OfxTime time ) const = 0;
00136 
00137         /**
00138          * @brief Initialization pass to propagate informations from inputs to outputs.
00139          * @param[in] processData
00140          * @remark Called on each node in a depth first search order. So you have the guarantee that it has been called on each input nodes before.
00141          */
00142         virtual void preProcess1( graph::ProcessVertexAtTimeData& processData ) {}
00143         
00144         /**
00145          * @brief Initialization pass to propagate informations from outputs to inputs.
00146          * @param[in] processData
00147          * @remark Called on each node in a REVERSE depth first search order. So you have the guarantee that it has been called on each output nodes before. Output nodes are those who used the result of the current node.
00148          */
00149         virtual void preProcess2_reverse( graph::ProcessVertexAtTimeData& processData ) {}
00150 
00151         /**
00152          * @brief The node can declare to be an identity operation.
00153          * In this case, the node is not processed and the rendering engine direcly use the indicated input clip at a particular time.
00154          *
00155          * @param[in] processData
00156          * @param[out] clip the input clip to use as identity
00157          * @param[out] time the time to use as identity
00158          * @return if the node is an identity operation
00159          */
00160         virtual bool isIdentity( const graph::ProcessVertexAtTimeData& processData, std::string& clip, OfxTime& time ) const = 0;
00161         
00162         /**
00163          * @brief Fill ProcessInfo to compute statistics for the current process,
00164          *        like memory used by this node, by all input nodes, etc.
00165          * @param[in] processData
00166          * @remark Called on each node in a depth first search order. So you have the guarantee that it has been called on each input nodes before.
00167          */
00168         virtual void preProcess_infos( const graph::ProcessVertexAtTimeData& processData, const OfxTime time, graph::ProcessVertexAtTimeInfo& nodeInfos ) const = 0;
00169 
00170         /**
00171          * @brief Process this node. All inputs are compute.
00172          * @param[in] processData
00173          * @remark Called on each node in a depth first search order. So you have the guarantee that it has been called on each input nodes before.
00174          */
00175         virtual void process( graph::ProcessVertexAtTimeData& processData ) = 0;
00176 
00177         /**
00178          * @brief The process of all nodes is done for one frame, now finalize this node.
00179          * @param[in] processData
00180          * @remark Called on each node in a depth first search order. So you have the guarantee that it has been called on each input nodes before.
00181          */
00182         virtual void postProcess( graph::ProcessVertexAtTimeData& processData ) = 0;
00183 
00184         /**
00185          * @brief End of the whole frame range process, now finalize this node.
00186          * @param[in] processData
00187          * @remark called on each node without predefined order.
00188          */
00189         virtual void endSequence( graph::ProcessVertexData& processData ) = 0;
00190 #endif
00191 
00192         virtual std::ostream& print( std::ostream& os ) const = 0;
00193 
00194         friend std::ostream& operator<<( std::ostream& os, const This& v );
00195 
00196 #ifndef SWIG
00197 protected:
00198         typedef graph::ProcessVertexData Data;
00199         typedef graph::ProcessVertexAtTimeData DataAtTime;
00200         typedef std::map<OfxTime,DataAtTime*> DataAtTimeMap;
00201 
00202         Data* _data; ///< link to external datas
00203         DataAtTimeMap _dataAtTime; ///< link to external datas at each time
00204 
00205 public:
00206         void setProcessData( Data* data );
00207         void setProcessDataAtTime( DataAtTime* dataAtTime );
00208         void clearProcessDataAtTime();
00209         
00210         Data& getData();
00211         const Data& getData() const;
00212         
00213         bool hasData( const OfxTime time ) const;
00214         const DataAtTime& getData( const OfxTime time ) const;
00215         const DataAtTime& getFirstData() const;
00216         const DataAtTime& getLastData() const; 
00217         DataAtTime& getData( const OfxTime time );
00218         DataAtTime& getFirstData();
00219         DataAtTime& getLastData();
00220 #endif
00221 };
00222 
00223 
00224 #ifndef SWIG
00225 /**
00226  * @brief to make clonable for use in boost::ptr_container.
00227  */
00228 inline INode* new_clone( const INode& a )
00229 {
00230         return a.clone();
00231 }
00232 
00233 #endif
00234 
00235 inline std::string mapNodeTypeEnumToString( const INode::ENodeType e )
00236 {
00237         switch( e )
00238         {
00239                 case INode::eNodeTypeUnknown:
00240                         return "Unknown";
00241                 case INode::eNodeTypeImageEffect:
00242                         return "ImageEffect";
00243                 case INode::eNodeTypeParam:
00244                         return "Param";
00245                 case INode::eNodeTypeGraph:
00246                         return "Graph";
00247                 case INode::eNodeTypeBuffer:
00248                         return "Buffer";
00249         }
00250         BOOST_THROW_EXCEPTION( exception::Bug()
00251                 << exception::dev() + "Unrecognized ENodeType enum. (" + e + ")." );
00252 }
00253 
00254 
00255 }
00256 }
00257 
00258 #endif
00259