tahoma2d/toonz/sources/include/tfx.h

569 lines
16 KiB
C
Raw Normal View History

2016-05-17 03:04:11 +12:00
#pragma once
2016-03-19 06:57:51 +13:00
#ifndef TFX_INCLUDED
#define TFX_INCLUDED
2016-04-14 22:15:09 +12:00
#include <memory>
2016-03-19 06:57:51 +13:00
// TnzCore includes
#include "tsmartpointer.h"
#include "tpersist.h"
#include "texception.h"
#include "ttile.h"
#include "tgeometry.h"
// TnzBase includes
#include "tparamchange.h"
#undef DVAPI
#undef DVVAR
#ifdef TFX_EXPORTS
#define DVAPI DV_EXPORT_API
#define DVVAR DV_EXPORT_VAR
#else
#define DVAPI DV_IMPORT_API
#define DVVAR DV_IMPORT_VAR
#endif
//===================================================================
// Forward declarations
class TFxImp;
class TFx;
class TParam;
class TFxAttributes;
class TParamContainer;
class TParamVar;
class TRenderSettings;
class TParamUIConcept;
//===================================================================
2016-06-15 18:43:10 +12:00
class DVAPI TFxPort {
friend class TFx;
2016-03-19 06:57:51 +13:00
protected:
2016-06-15 18:43:10 +12:00
TFx *m_owner; //!< This is an input port of m_owner
int m_groupIdx; //!< Dynamic group index this belongs to in m_owner (-1 if
2016-06-20 14:23:05 +12:00
//! none)
2016-06-15 18:43:10 +12:00
bool m_isControl;
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
TFxPort(bool isControl)
: m_owner(0), m_groupIdx(-1), m_isControl(isControl) {}
virtual ~TFxPort() {}
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
virtual TFx *getFx() const = 0;
virtual void setFx(TFx *) = 0;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
bool isConnected() const { return getFx() != 0; }
bool isaControlPort() const { return m_isControl; }
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
int getGroupIndex() const { return m_groupIdx; }
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
TFx *getOwnerFx() const { return m_owner; }
void setOwnerFx(TFx *fx) { m_owner = fx; }
2016-03-19 06:57:51 +13:00
private:
2016-06-15 18:43:10 +12:00
// Not copiable
TFxPort(const TFxPort &);
TFxPort &operator=(const TFxPort &);
2016-03-19 06:57:51 +13:00
};
//-------------------------------------------------------------------
template <class T>
2016-06-15 18:43:10 +12:00
class TFxPortT : public TFxPort {
friend class TFx;
2016-03-19 06:57:51 +13:00
protected:
2016-06-15 18:43:10 +12:00
T *m_fx;
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
TFxPortT(bool isControl = false) : TFxPort(isControl), m_fx(0) {}
~TFxPortT() {
if (m_fx) {
m_fx->removeOutputConnection(this);
m_fx->release();
}
}
2016-06-19 20:06:29 +12:00
TFx *getFx() const override { return m_fx; }
2016-06-15 18:43:10 +12:00
2016-06-19 20:06:29 +12:00
void setFx(TFx *fx) override {
2016-06-15 18:43:10 +12:00
if (m_fx) m_fx->removeOutputConnection(this);
if (fx == 0) {
if (m_fx) m_fx->release();
m_fx = 0;
} else {
T *fxt = dynamic_cast<T *>(fx);
if (!fxt) throw TException("Fx: port type mismatch");
fxt->addRef();
if (m_fx) m_fx->release();
m_fx = fxt;
m_fx->addOutputConnection(this);
}
}
T *operator->() {
assert(m_fx);
return m_fx;
}
2016-03-19 06:57:51 +13:00
};
//===================================================================
/*
\brief A TFxPortDynamicGroup represents a group of fx ports with the
same name prefix whose ports that are added or removed dynamically by
Toonz on user request.
\sa The TFx::dynamicPortsGroup() method.
*/
2016-06-15 18:43:10 +12:00
class DVAPI TFxPortDynamicGroup {
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
typedef std::vector<TFxPort *> PortsContainer;
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
TFxPortDynamicGroup(const std::string &portsPrefix, int minPortsCount = 1);
~TFxPortDynamicGroup();
//! Returns the group's displayed ports prefix (ports added to the group \b
//! must
//! have this prefix).
const std::string &portsPrefix() const { return m_portsPrefix; }
//! Returns the minimal number of ports to be displayed in the group. The
//! group
//! <B> must not <\B> be initialized in an fx implementation with more ports
//! than
//! this number.
int minPortsCount() const { return m_minPortsCount; }
//! Returns the list of ports currently in the group (may contain empty
//! ports).
const PortsContainer &ports() const { return m_ports; }
//! Equivalent to checking the portName prefix against the stored one.
bool contains(const std::string &portName) const {
return (strncmp(m_portsPrefix.c_str(), portName.c_str(),
m_portsPrefix.size()) == 0);
}
2016-03-19 06:57:51 +13:00
private:
2016-06-15 18:43:10 +12:00
std::string m_portsPrefix; //!< Name prefix of each stored port
int m_minPortsCount; //!< Ports count \a should not be smaller
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
std::vector<TFxPort *> m_ports; //!< \b Owned ports (deleted on destruction)
2016-03-19 06:57:51 +13:00
private:
2016-06-15 18:43:10 +12:00
friend class TFx;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// Not copyable
TFxPortDynamicGroup(const TFxPortDynamicGroup &);
TFxPortDynamicGroup &operator=(const TFxPortDynamicGroup &);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
void addPort(TFxPort *port);
void removePort(
TFxPort *port); //!< Removes <I> and deletes <\I> the specified port
void clear();
2016-03-19 06:57:51 +13:00
};
typedef TFxPortDynamicGroup TFxPortDG;
//===================================================================
2016-06-15 18:43:10 +12:00
class DVAPI TFxTimeRegion {
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
TFxTimeRegion();
TFxTimeRegion(double start, double end);
static TFxTimeRegion createUnlimited();
TFxTimeRegion &operator+=(const TFxTimeRegion &rhs) {
m_start = std::min(m_start, rhs.m_start);
m_end = std::max(m_end, rhs.m_end);
return *this;
}
TFxTimeRegion &operator+=(double shift) {
m_start += shift;
m_end += shift;
return *this;
}
TFxTimeRegion &operator-=(double shift) { return operator+=(-shift); }
bool contains(double time) const;
bool isUnlimited() const;
bool isEmpty() const;
bool getFrameCount(int &count) const;
int getFirstFrame() const;
int getLastFrame() const;
double m_start;
double m_end;
2016-03-19 06:57:51 +13:00
};
inline TFxTimeRegion operator+(const TFxTimeRegion &tr1,
const TFxTimeRegion &tr2) {
2016-06-15 18:43:10 +12:00
return TFxTimeRegion(tr1) += tr2;
2016-03-19 06:57:51 +13:00
}
inline TFxTimeRegion operator+(const TFxTimeRegion &tr1, double shift) {
2016-06-15 18:43:10 +12:00
return TFxTimeRegion(tr1) += shift;
2016-03-19 06:57:51 +13:00
}
inline TFxTimeRegion operator-(const TFxTimeRegion &tr1, double shift) {
2016-06-15 18:43:10 +12:00
return TFxTimeRegion(tr1) -= shift;
2016-03-19 06:57:51 +13:00
}
//===================================================================
2016-06-15 18:43:10 +12:00
class DVAPI TFxChange {
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
TFx *m_fx;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
double m_firstAffectedFrame;
double m_lastAffectedFrame;
bool m_dragging;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
static double m_minFrame;
static double m_maxFrame;
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
TFxChange(TFx *fx, double firstAffectedFrame, double lastAffectedFrame,
bool dragging)
: m_fx(fx)
, m_firstAffectedFrame(firstAffectedFrame)
, m_lastAffectedFrame(lastAffectedFrame)
, m_dragging(dragging) {}
2016-03-19 06:57:51 +13:00
private:
2016-06-15 18:43:10 +12:00
TFxChange();
2016-03-19 06:57:51 +13:00
};
//------------------------------------------------------------------------------
class TFxParamChange final : public TFxChange {
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
TFxParamChange(TFx *fx, double firstAffectedFrame, double lastAffectedFrame,
bool dragging);
TFxParamChange(TFx *fx, const TParamChange &src);
2016-03-19 06:57:51 +13:00
};
//------------------------------------------------------------------------------
class TFxPortAdded final : public TFxChange {
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
TFxPortAdded(TFx *fx) : TFxChange(fx, m_minFrame, m_maxFrame, false) {}
~TFxPortAdded() {}
2016-03-19 06:57:51 +13:00
};
//------------------------------------------------------------------------------
class TFxPortRemoved final : public TFxChange {
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
TFxPortRemoved(TFx *fx) : TFxChange(fx, m_minFrame, m_maxFrame, false) {}
~TFxPortRemoved() {}
2016-03-19 06:57:51 +13:00
};
//------------------------------------------------------------------------------
class TFxParamAdded final : public TFxChange {
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
TFxParamAdded(TFx *fx) : TFxChange(fx, m_minFrame, m_maxFrame, false) {}
~TFxParamAdded() {}
2016-03-19 06:57:51 +13:00
};
//------------------------------------------------------------------------------
class TFxParamRemoved final : public TFxChange {
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
TFxParamRemoved(TFx *fx) : TFxChange(fx, m_minFrame, m_maxFrame, false) {}
~TFxParamRemoved() {}
2016-03-19 06:57:51 +13:00
};
//------------------------------------------------------------------------------
class TFxParamsUnlinked final : public TFxChange {
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
TFxParamsUnlinked(TFx *fx) : TFxChange(fx, m_minFrame, m_maxFrame, false) {}
~TFxParamsUnlinked() {}
2016-03-19 06:57:51 +13:00
};
//===================================================================
2016-06-15 18:43:10 +12:00
class DVAPI TFxObserver {
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
TFxObserver() {}
virtual ~TFxObserver() {}
virtual void onChange(const TFxChange &change) = 0;
virtual void onChange(const TFxPortAdded &change) {
onChange(static_cast<const TFxChange &>(change));
}
virtual void onChange(const TFxPortRemoved &change) {
onChange(static_cast<const TFxChange &>(change));
}
virtual void onChange(const TFxParamAdded &change) {
onChange(static_cast<const TFxChange &>(change));
}
virtual void onChange(const TFxParamRemoved &change) {
onChange(static_cast<const TFxChange &>(change));
}
virtual void onChange(const TFxParamsUnlinked &change) {
onChange(static_cast<const TFxChange &>(change));
}
2016-03-19 06:57:51 +13:00
};
//===================================================================
2016-06-15 18:43:10 +12:00
class TFxInfo {
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
std::string m_name;
bool m_isHidden;
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
TFxInfo() {}
TFxInfo(const std::string &name, bool isHidden)
: m_name(name), m_isHidden(isHidden) {}
2016-03-19 06:57:51 +13:00
};
//===================================================================
2016-04-15 17:11:23 +12:00
#ifdef _WIN32
2016-03-19 06:57:51 +13:00
template class DVAPI TSmartPointerT<TFx>;
#endif
typedef TSmartPointerT<TFx> TFxP;
//===================================================================
2016-06-15 18:43:10 +12:00
class DVAPI TFx : public TSmartObject, public TPersist, public TParamObserver {
DECLARE_CLASS_CODE
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
TFxImp *m_imp;
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
typedef TFx *CreateProc();
TFx();
virtual ~TFx();
virtual std::wstring getName() const;
void setName(std::wstring name);
std::wstring getFxId() const;
void setFxId(std::wstring id);
TParamContainer *getParams();
const TParamContainer *getParams() const;
void addParamVar(TParamVar *var);
virtual TFx *clone(bool recursive = true) const;
TFx *clone(TFx *fx, bool recursive) const;
void unlinkParams();
2019-08-22 22:08:37 +12:00
virtual void linkParams(TFx *src);
2016-06-15 18:43:10 +12:00
TFx *getLinkedFx() const;
bool addInputPort(const std::string &name, TFxPort &p); //!< Adds a port with
2016-06-20 14:23:05 +12:00
//! given name,
//! returns false on
//! duplicate names.
2016-06-15 18:43:10 +12:00
//! Ownership of the port belongs to derived implementations of TFx.
bool addInputPort(const std::string &name, TFxPort *p,
int groupIndex); //!< Adds a port with given name to the
2016-06-20 14:23:05 +12:00
//! specified dynamic group,
2016-06-15 18:43:10 +12:00
//! returns false on duplicate names. Ownership is transferred to the group.
bool removeInputPort(const std::string &name); //!< Removes the port with
2016-06-20 14:23:05 +12:00
//! given name, returns false
//! if not found.
2016-06-15 18:43:10 +12:00
bool renamePort(const std::string &oldName, const std::string &newName);
bool connect(
const std::string &name,
TFx *other); //!< Equivalent to getInputPort(name)->setFx(other).
bool disconnect(const std::string
&name); //!< Equivalent to getInputPort(name)->setFx(0).
int getInputPortCount() const;
TFxPort *getInputPort(int index) const;
TFxPort *getInputPort(const std::string &name) const;
std::string getInputPortName(int index) const;
virtual int dynamicPortGroupsCount() const { return 0; }
virtual const TFxPortDG *dynamicPortGroup(int g) const { return 0; }
bool hasDynamicPortGroups() const { return (dynamicPortGroupsCount() > 0); }
void clearDynamicPortGroup(
int g); //!< \warning Users must ensure that the group's minimal
//! ports count is respected - this method does \b not.
bool addOutputConnection(TFxPort *port);
bool removeOutputConnection(TFxPort *port);
static void listFxs(std::vector<TFxInfo> &fxInfos);
static TFxInfo getFxInfo(const std::string &fxIdentifier); //!< Returns info
2016-06-20 14:23:05 +12:00
//! associated to
//! an fx
//! identifier, or
//! an
2016-06-15 18:43:10 +12:00
//! unnamed one if none was found.
virtual bool isZerary() const { return getInputPortCount() == 0; }
// returns the column index that provides reference frame for the FX.
// (TColumnFx and Zerary fxs return their column indexes, n-ary FXs return
// the reference column index of their first argument)
// note: it returns -1 if the column is undefined (e.g. a n-ary FX with
// arguments undefined yet)
virtual int getReferenceColumnIndex() const;
// se getXsheetPort() != 0 e la porta non e' connessa la si considera connessa
// a tutte le colonne precedenti a quella corrente.
// cfr. AddFx
virtual TFxPort *getXsheetPort() const { return 0; }
int getOutputConnectionCount() const;
TFxPort *getOutputConnection(int i) const;
virtual TFxTimeRegion getTimeRegion(bool ignoreImplicit = false) const;
2016-06-15 18:43:10 +12:00
void setActiveTimeRegion(const TFxTimeRegion &tr);
TFxTimeRegion getActiveTimeRegion() const;
virtual bool checkActiveTimeRegion() const { return true; }
void disconnectAll();
//! Returns a list of User Interface Concepts to be displayed when editing the
//! fx parameters.
//! \note Ownership of the returned array allocated with new[] is passed to
//! callers.
virtual void getParamUIs(TParamUIConcept *&params, int &length) {
params = 0, length = 0;
}
inline std::string getFxType() const;
virtual std::string getPluginId() const = 0;
static TFx *create(std::string name);
// TParamObserver-related methods
2016-06-19 20:06:29 +12:00
void onChange(const TParamChange &c) override;
2016-06-15 18:43:10 +12:00
void addObserver(TFxObserver *);
void removeObserver(TFxObserver *);
void notify(const TFxChange &change);
void notify(const TFxPortAdded &change);
void notify(const TFxPortRemoved &change);
void notify(const TFxParamAdded &change);
void notify(const TFxParamRemoved &change);
2016-06-19 20:06:29 +12:00
void loadData(TIStream &is) override;
void saveData(TOStream &os) override;
2016-06-15 18:43:10 +12:00
void loadPreset(TIStream &is); // solleva un eccezione se il preset non
// corrisponde all'effetto
void savePreset(TOStream &os);
TFxAttributes *getAttributes() const;
virtual std::string getAlias(double frame,
const TRenderSettings &info) const {
return "";
}
//! Compatibility function - used to translate a port name from older Toonz
//! versions into its current form.
virtual void compatibilityTranslatePort(int majorVersion, int minorVersion,
std::string &portName) {}
/*-- InputPort used when the Rendering (eye) button is OFF --*/
2016-06-15 18:43:10 +12:00
virtual int getPreferredInputPort() { return 0; }
/* Virtual function for RasterFxPluginHost */
2016-06-15 18:43:10 +12:00
virtual void callStartRenderHandler() {}
virtual void callEndRenderHandler() {}
virtual void callStartRenderFrameHandler(const TRenderSettings *rs,
double frame) {}
virtual void callEndRenderFrameHandler(const TRenderSettings *rs,
double frame) {}
2016-03-19 06:57:51 +13:00
// This function will be called in TFx::loadData whenever the obsolete
// parameter is loaded. Do nothing by default.
virtual void onObsoleteParamLoaded(const std::string &paramName) {}
void setFxVersion(int);
int getFxVersion() const;
virtual void onFxVersionSet() {}
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
// Id-related functions
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
unsigned long getIdentifier() const;
void setIdentifier(unsigned long id);
void setNewIdentifier();
2016-03-19 06:57:51 +13:00
private:
2016-06-15 18:43:10 +12:00
// not implemented
TFx(const TFx &);
TFx &operator=(const TFx &);
2016-03-19 06:57:51 +13:00
};
//===================================================================
DVAPI TIStream &operator>>(TIStream &in, TFxP &p);
//===================================================================
//===================================================================
2016-06-15 18:43:10 +12:00
class DVAPI TFxDeclaration : public TPersistDeclaration {
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
TFxDeclaration(const TFxInfo &info);
2016-03-19 06:57:51 +13:00
};
template <class T>
class TFxDeclarationT final : public TFxDeclaration {
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
TFxDeclarationT(const TFxInfo &info) : TFxDeclaration(info) {}
2016-06-19 20:06:29 +12:00
TPersist *create() const override { return new T; }
2016-03-19 06:57:51 +13:00
};
//-------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
inline std::string TFx::getFxType() const { return getDeclaration()->getId(); }
2016-03-19 06:57:51 +13:00
//-------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
#define FX_DECLARATION(T) \
2019-08-22 22:08:37 +12:00
\
2016-06-15 18:43:10 +12:00
public: \
2016-06-23 22:02:33 +12:00
const TPersistDeclaration *getDeclaration() const override;
2016-06-15 18:43:10 +12:00
#define FX_IDENTIFIER(T, I) \
namespace { \
TFxDeclarationT<T> info##T(TFxInfo(I, false)); \
} \
const TPersistDeclaration *T::getDeclaration() const { return &info##T; }
#define FX_IDENTIFIER_IS_HIDDEN(T, I) \
namespace { \
TFxDeclarationT<T> info##T(TFxInfo(I, true)); \
} \
const TPersistDeclaration *T::getDeclaration() const { return &info##T; }
2016-03-19 06:57:51 +13:00
//===================================================================
#endif