|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "tmacrofx.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzBase includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tparamcontainer.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tfxattributes.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzCore includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tstream.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class MatchesFx {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
MatchesFx(const TFxP &fx) : m_fx(fx) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool operator()(const TFxP &fx) {
|
|
Shinya Kitaoka |
120a6e |
return m_fx.getPointer() == fx.getPointer();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TFxP m_fx;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void pushParents(const TFxP &root, std::vector<tfxp> &fxs,</tfxp>
|
|
Shinya Kitaoka |
120a6e |
const std::vector<tfxp> &selectedFxs) {</tfxp>
|
|
Shinya Kitaoka |
120a6e |
int i, count = root->getInputPortCount();
|
|
Shinya Kitaoka |
120a6e |
if (count == 0) {
|
|
Shinya Kitaoka |
120a6e |
std::vector<tfxp>::const_iterator found =</tfxp>
|
|
Shinya Kitaoka |
120a6e |
std::find_if(fxs.begin(), fxs.end(), MatchesFx(root));
|
|
Shinya Kitaoka |
120a6e |
if (found == fxs.end()) fxs.push_back(root);
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < count; i++) {
|
|
Shinya Kitaoka |
120a6e |
TFxP inutFx = root->getInputPort(i)->getFx();
|
|
Shinya Kitaoka |
120a6e |
std::vector<tfxp>::const_iterator found =</tfxp>
|
|
Shinya Kitaoka |
120a6e |
std::find_if(selectedFxs.begin(), selectedFxs.end(), MatchesFx(inutFx));
|
|
Shinya Kitaoka |
120a6e |
if (found != selectedFxs.end()) pushParents(inutFx, fxs, selectedFxs);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
std::vector<tfxp>::const_iterator found =</tfxp>
|
|
Shinya Kitaoka |
120a6e |
std::find_if(fxs.begin(), fxs.end(), MatchesFx(root));
|
|
Shinya Kitaoka |
120a6e |
if (found == fxs.end()) fxs.push_back(root);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::vector<tfxp> sortFxs(const std::vector<tfxp> &fxs) {</tfxp></tfxp>
|
|
Shinya Kitaoka |
120a6e |
std::vector<tfxp> app;</tfxp>
|
|
Shinya Kitaoka |
120a6e |
std::vector<tfxp> roots;</tfxp>
|
|
Shinya Kitaoka |
120a6e |
// find fxs that could be in back of the vector.
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < (int)fxs.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
TFxP fx = fxs[i];
|
|
Shinya Kitaoka |
120a6e |
int j, count = (int)fx->getOutputConnectionCount();
|
|
Shinya Kitaoka |
120a6e |
if (count == 0) {
|
|
Shinya Kitaoka |
120a6e |
roots.push_back(fx);
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
for (j = 0; j < count; j++) {
|
|
Shinya Kitaoka |
120a6e |
TFxP connectedFx = fx->getOutputConnection(j)->getOwnerFx();
|
|
Shinya Kitaoka |
120a6e |
std::vector<tfxp>::const_iterator found =</tfxp>
|
|
Shinya Kitaoka |
120a6e |
std::find_if(fxs.begin(), fxs.end(), MatchesFx(connectedFx));
|
|
Shinya Kitaoka |
120a6e |
if (found == fxs.end()) {
|
|
Shinya Kitaoka |
120a6e |
roots.push_back(fx);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < (int)roots.size(); i++) pushParents(roots[i], app, fxs);
|
|
Shinya Kitaoka |
120a6e |
assert(fxs.size() == app.size());
|
|
Shinya Kitaoka |
120a6e |
return app;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// raccoglie tutti i parametri dai vari TFx e li assegna anche alla macro
|
|
Shinya Kitaoka |
120a6e |
void collectParams(TMacroFx *macroFx) {
|
|
Shinya Kitaoka |
120a6e |
int k;
|
|
Shinya Kitaoka |
120a6e |
for (k = 0; k < (int)macroFx->m_fxs.size(); k++) {
|
|
Shinya Kitaoka |
120a6e |
TFxP fx = macroFx->m_fxs[k];
|
|
Shinya Kitaoka |
120a6e |
int j;
|
|
Shinya Kitaoka |
120a6e |
for (j = 0; j < fx->getParams()->getParamCount(); j++)
|
|
Shinya Kitaoka |
120a6e |
macroFx->getParams()->add(fx->getParams()->getParamVar(j)->clone());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // anonymous namespace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TMacroFx::analyze(const std::vector<tfxp> &fxs, TFxP &root,</tfxp>
|
|
Shinya Kitaoka |
120a6e |
std::vector<tfxp> &roots, std::vector<tfxp> &leafs) {</tfxp></tfxp>
|
|
Shinya Kitaoka |
120a6e |
if (fxs.size() == 1)
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
leafs.clear();
|
|
Shinya Kitaoka |
120a6e |
roots.clear();
|
|
Shinya Kitaoka |
120a6e |
std::vector<tfxp>::const_iterator it = fxs.begin();</tfxp>
|
|
Shinya Kitaoka |
120a6e |
for (; it != fxs.end(); ++it) {
|
|
Shinya Kitaoka |
120a6e |
TFxP fx = *it;
|
|
Shinya Kitaoka |
120a6e |
int inputInternalConnection = 0;
|
|
Shinya Kitaoka |
120a6e |
int inputExternalConnection = 0;
|
|
Shinya Kitaoka |
120a6e |
int outputInternalConnection = 0;
|
|
Shinya Kitaoka |
120a6e |
int outputExternalConnection = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// calcola se ci sono connessioni in input dall'esterno
|
|
Shinya Kitaoka |
120a6e |
// verso l'interno e/o internamente a orderedFxs
|
|
Shinya Kitaoka |
120a6e |
int inputPortCount = fx->getInputPortCount();
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < inputPortCount; ++i) {
|
|
Shinya Kitaoka |
120a6e |
TFxPort *inputPort = fx->getInputPort(i);
|
|
Shinya Kitaoka |
120a6e |
TFx *inputPortFx = inputPort->getFx();
|
|
Shinya Kitaoka |
120a6e |
if (inputPortFx) {
|
|
Shinya Kitaoka |
120a6e |
if (std::find_if(fxs.begin(), fxs.end(), MatchesFx(inputPortFx)) !=
|
|
Shinya Kitaoka |
120a6e |
fxs.end())
|
|
Shinya Kitaoka |
120a6e |
++inputInternalConnection;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
++inputExternalConnection;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// calcola se ci sono connessioni in output dall'interno
|
|
Shinya Kitaoka |
120a6e |
// verso l'esterno e/o internamente a orderedFxs
|
|
Shinya Kitaoka |
120a6e |
int outputPortCount = fx->getOutputConnectionCount();
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < outputPortCount; ++i) {
|
|
Shinya Kitaoka |
120a6e |
TFxPort *outputPort = fx->getOutputConnection(i);
|
|
Shinya Kitaoka |
120a6e |
TFx *outputFx = outputPort->getOwnerFx();
|
|
Shinya Kitaoka |
120a6e |
if (outputFx) {
|
|
Shinya Kitaoka |
120a6e |
if (std::find_if(fxs.begin(), fxs.end(), MatchesFx(outputFx)) !=
|
|
Shinya Kitaoka |
120a6e |
fxs.end())
|
|
Shinya Kitaoka |
120a6e |
++outputInternalConnection;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
++outputExternalConnection;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// se fx e' una radice
|
|
Shinya Kitaoka |
120a6e |
if ((outputExternalConnection > 0) ||
|
|
Shinya Kitaoka |
120a6e |
(outputExternalConnection == 0 && outputInternalConnection == 0)) {
|
|
Shinya Kitaoka |
120a6e |
root = fx;
|
|
Shinya Kitaoka |
120a6e |
roots.push_back(fx);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// se fx e' una foglia
|
|
Shinya Kitaoka |
120a6e |
if (inputExternalConnection > 0 || fx->getInputPortCount() == 0 ||
|
|
Shinya Kitaoka |
120a6e |
(inputExternalConnection == 0 &&
|
|
Shinya Kitaoka |
120a6e |
inputInternalConnection < fx->getInputPortCount())) {
|
|
Shinya Kitaoka |
120a6e |
leafs.push_back(fx);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (roots.size() != 1)
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
if (leafs.size() == 0) return false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TMacroFx::analyze(const std::vector<tfxp> &fxs) {</tfxp>
|
|
Shinya Kitaoka |
120a6e |
TFxP root = 0;
|
|
Shinya Kitaoka |
120a6e |
std::vector<tfxp> leafs;</tfxp>
|
|
Shinya Kitaoka |
120a6e |
std::vector<tfxp> roots;</tfxp>
|
|
Shinya Kitaoka |
120a6e |
return analyze(fxs, root, roots, leafs);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TMacroFx::isaLeaf(TFx *fx) const {
|
|
Shinya Kitaoka |
120a6e |
int count = fx->getInputPortCount();
|
|
Shinya Kitaoka |
120a6e |
if (count == 0) return true;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < count; ++i) {
|
|
Shinya Kitaoka |
120a6e |
TFxPort *port = fx->getInputPort(i);
|
|
Shinya Kitaoka |
120a6e |
TFx *inputFx = port->getFx();
|
|
Shinya Kitaoka |
120a6e |
if (inputFx) {
|
|
Shinya Kitaoka |
120a6e |
if (std::find_if(m_fxs.begin(), m_fxs.end(), MatchesFx(inputFx)) ==
|
|
Shinya Kitaoka |
120a6e |
m_fxs.end()) {
|
|
Shinya Kitaoka |
120a6e |
// il nodo di input non appartiene al macroFx
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
// la porta di input non e' connessa
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// tutte le porte di input sono connesse verso nodi appartenenti al macroFx
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TMacroFx::TMacroFx() : m_isEditing(false) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TMacroFx::~TMacroFx() {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TFx *TMacroFx::clone(bool recursive) const {
|
|
Shinya Kitaoka |
120a6e |
int n = m_fxs.size();
|
|
Shinya Kitaoka |
120a6e |
std::vector<tfxp> clones(n);</tfxp>
|
|
Shinya Kitaoka |
120a6e |
std::map<tfx *,="" int=""> table;</tfx>
|
|
Shinya Kitaoka |
120a6e |
std::map<tfx *,="" int="">::iterator it;</tfx>
|
|
Shinya Kitaoka |
120a6e |
int i, rootIndex = -1;
|
|
Shinya Kitaoka |
120a6e |
// nodi
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < n; ++i) {
|
|
Shinya Kitaoka |
120a6e |
TFx *fx = m_fxs[i].getPointer();
|
|
Shinya Kitaoka |
120a6e |
assert(fx);
|
|
Shinya Kitaoka |
120a6e |
clones[i] = fx->clone(false);
|
|
Shinya Kitaoka |
120a6e |
assert(table.count(fx) == 0);
|
|
Shinya Kitaoka |
120a6e |
table[fx] = i;
|
|
Shinya Kitaoka |
120a6e |
if (fx == m_root.getPointer()) rootIndex = i;
|
|
Shinya Kitaoka |
120a6e |
TFx *linkedFx = fx->getLinkedFx();
|
|
Shinya Kitaoka |
120a6e |
if (linkedFx && table.find(linkedFx) != table.end())
|
|
Shinya Kitaoka |
120a6e |
clones[i]->linkParams(clones[table[linkedFx]].getPointer());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
assert(rootIndex >= 0);
|
|
Shinya Kitaoka |
120a6e |
// connessioni
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < n; i++) {
|
|
Shinya Kitaoka |
120a6e |
TFx *fx = m_fxs[i].getPointer();
|
|
Shinya Kitaoka |
120a6e |
for (int j = 0; j < fx->getInputPortCount(); j++) {
|
|
Shinya Kitaoka |
120a6e |
TFxPort *port = fx->getInputPort(j);
|
|
Shinya Kitaoka |
120a6e |
TFx *inputFx = port->getFx();
|
|
Shinya Kitaoka |
120a6e |
if (!inputFx) continue;
|
|
Shinya Kitaoka |
120a6e |
it = table.find(inputFx);
|
|
Shinya Kitaoka |
120a6e |
if (it == table.end()) {
|
|
Shinya Kitaoka |
120a6e |
// il j-esimo input di fx e' esterno alla macro
|
|
Shinya Kitaoka |
120a6e |
if (recursive)
|
|
Shinya Kitaoka |
120a6e |
clones[i]->connect(fx->getInputPortName(j), inputFx->clone(true));
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
// il j-esimo input di fx e' interno alla macro
|
|
Shinya Kitaoka |
120a6e |
clones[i]->connect(fx->getInputPortName(j),
|
|
Shinya Kitaoka |
120a6e |
clones[it->second].getPointer());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// TFx *rootClone =
|
|
Shinya Kitaoka |
120a6e |
// const_cast<tmacrofx*>(this)-></tmacrofx*>
|
|
Shinya Kitaoka |
120a6e |
// clone(m_root.getPointer(), recursive, visited, clones);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TMacroFx *clone = TMacroFx::create(clones);
|
|
Shinya Kitaoka |
120a6e |
clone->setName(getName());
|
|
Shinya Kitaoka |
120a6e |
clone->setFxId(getFxId());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Copy the index of the passive cache manager.
|
|
Shinya Kitaoka |
120a6e |
clone->getAttributes()->passiveCacheDataIdx() =
|
|
Shinya Kitaoka |
120a6e |
getAttributes()->passiveCacheDataIdx();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(clone->getRoot() == clones[rootIndex].getPointer());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return clone;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TMacroFx::doGetBBox(double frame, TRectD &bBox,
|
|
Shinya Kitaoka |
120a6e |
const TRenderSettings &info) {
|
|
Shinya Kitaoka |
120a6e |
return m_root->doGetBBox(frame, bBox, info);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TMacroFx::doDryCompute(TRectD &rect, double frame,
|
|
Shinya Kitaoka |
120a6e |
const TRenderSettings &info) {
|
|
Shinya Kitaoka |
120a6e |
assert(m_root);
|
|
Shinya Kitaoka |
120a6e |
m_root->dryCompute(rect, frame, info);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TMacroFx::doCompute(TTile &tile, double frame, const TRenderSettings &ri) {
|
|
Shinya Kitaoka |
120a6e |
assert(m_root);
|
|
Shinya Kitaoka |
120a6e |
m_root->compute(tile, frame, ri);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TFxTimeRegion TMacroFx::getTimeRegion() const {
|
|
Shinya Kitaoka |
120a6e |
return m_root->getTimeRegion();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::string TMacroFx::getPluginId() const { return "Base"; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TMacroFx::setRoot(TFx *root) {
|
|
Shinya Kitaoka |
120a6e |
m_root = root;
|
|
Shinya Kitaoka |
120a6e |
// TFx::m_imp->m_outputPort = root->m_imp->m_outputPort;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TFx *TMacroFx::getRoot() const { return m_root.getPointer(); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TFx *TMacroFx::getFxById(const std::wstring &id) const {
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < (int)m_fxs.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
TFx *fx = m_fxs[i].getPointer();
|
|
Shinya Kitaoka |
120a6e |
if (fx->getFxId() == id) return fx;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const std::vector<tfxp> &TMacroFx::getFxs() const { return m_fxs; }</tfxp>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::string TMacroFx::getMacroFxType() const {
|
|
Shinya Kitaoka |
120a6e |
std::string name = getFxType() + "(";
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < (int)m_fxs.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
if (i > 0) name += ",";
|
|
Shinya Kitaoka |
120a6e |
if (TMacroFx *childMacro = dynamic_cast<tmacrofx *="">(m_fxs[i].getPointer()))</tmacrofx>
|
|
Shinya Kitaoka |
120a6e |
name += childMacro->getMacroFxType();
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
name += m_fxs[i]->getFxType();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return name + ")";
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TMacroFx *TMacroFx::create(const std::vector<tfxp> &fxs) {</tfxp>
|
|
Shinya Kitaoka |
120a6e |
std::vector<tfxp> leafs;</tfxp>
|
|
Shinya Kitaoka |
120a6e |
std::vector<tfxp> roots;</tfxp>
|
|
Shinya Kitaoka |
120a6e |
TFxP root = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::vector<tfxp> orederedFxs = sortFxs(fxs);</tfxp>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// verifica che gli effetti selezionati siano idonei ad essere raccolti
|
|
Shinya Kitaoka |
120a6e |
// in una macro. Ci deve essere un solo nodo terminale
|
|
Shinya Kitaoka |
120a6e |
// (roots.size()==1, roots[0] == root) e uno o piu' nodi di ingresso
|
|
Shinya Kitaoka |
120a6e |
// (assert leafs.size()>0)
|
|
Shinya Kitaoka |
120a6e |
if (!analyze(orederedFxs, root, roots, leafs)) return 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// -----------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TMacroFx *macroFx = new TMacroFx;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// tutti i nodi vengono spostati (e non copiati) nella macro stessa
|
|
Shinya Kitaoka |
120a6e |
std::vector<tfxp>::const_iterator it = orederedFxs.begin();</tfxp>
|
|
Shinya Kitaoka |
120a6e |
for (; it != orederedFxs.end(); ++it) macroFx->m_fxs.push_back(*it);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// i nodi di ingresso vengono messi in collegamento con le
|
|
Shinya Kitaoka |
120a6e |
// porte di ingresso della macro
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < (int)leafs.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
TFxP fx = leafs[i];
|
|
Shinya Kitaoka |
120a6e |
int k = 0;
|
|
Shinya Kitaoka |
120a6e |
int count = fx->getInputPortCount();
|
|
Shinya Kitaoka |
120a6e |
for (; k < count; k++) {
|
|
Shinya Kitaoka |
120a6e |
TFxPort *port = fx->getInputPort(k);
|
|
Shinya Kitaoka |
120a6e |
std::string portName = fx->getInputPortName(k);
|
|
Shinya Kitaoka |
120a6e |
std::string fxId = ::to_string(fx->getFxId());
|
|
Shinya Kitaoka |
120a6e |
portName +=
|
|
Shinya Kitaoka |
120a6e |
"_" + std::to_string(macroFx->getInputPortCount()) + "_" + fxId;
|
|
Shinya Kitaoka |
120a6e |
TFx *portFx = port->getFx();
|
|
Shinya Kitaoka |
120a6e |
if (portFx) {
|
|
Shinya Kitaoka |
120a6e |
// se la porta k-esima del nodo di ingresso i-esimo e' collegata
|
|
Shinya Kitaoka |
120a6e |
// ad un effetto, la porta viene inserita solo se l'effetto non fa
|
|
Shinya Kitaoka |
120a6e |
// gia' parte della macro
|
|
Shinya Kitaoka |
120a6e |
if (std::find_if(orederedFxs.begin(), orederedFxs.end(),
|
|
Shinya Kitaoka |
120a6e |
MatchesFx(portFx)) == orederedFxs.end())
|
|
Shinya Kitaoka |
120a6e |
macroFx->addInputPort(portName, *port);
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
macroFx->addInputPort(portName, *port);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// le porte di uscita di root diventano le porte di uscita della macro
|
|
Shinya Kitaoka |
120a6e |
int count = root->getOutputConnectionCount();
|
|
Shinya Kitaoka |
120a6e |
int k = count - 1;
|
|
Shinya Kitaoka |
120a6e |
for (; k >= 0; --k) {
|
|
Shinya Kitaoka |
120a6e |
TFxPort *port = root->getOutputConnection(k);
|
|
Shinya Kitaoka |
120a6e |
port->setFx(macroFx);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
macroFx->setRoot(root.getPointer());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// tutti i parametri delle funzioni figlie diventano parametri della macro
|
|
Shinya Kitaoka |
120a6e |
collectParams(macroFx);
|
|
Shinya Kitaoka |
120a6e |
return macroFx;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TMacroFx::canHandle(const TRenderSettings &info, double frame) {
|
|
Shinya Kitaoka |
120a6e |
return m_root->canHandle(info, frame);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::string TMacroFx::getAlias(double frame,
|
|
Shinya Kitaoka |
120a6e |
const TRenderSettings &info) const {
|
|
Shinya Kitaoka |
120a6e |
std::string alias = getFxType();
|
|
Shinya Kitaoka |
120a6e |
alias += "[";
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// alias degli effetti connessi alle porte di input separati da virgole
|
|
Shinya Kitaoka |
120a6e |
// una porta non connessa da luogo a un alias vuoto (stringa vuota)
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < getInputPortCount(); i++) {
|
|
Shinya Kitaoka |
120a6e |
TFxPort *port = getInputPort(i);
|
|
Shinya Kitaoka |
120a6e |
if (port->isConnected()) {
|
|
Shinya Kitaoka |
120a6e |
TRasterFxP ifx = port->getFx();
|
|
Shinya Kitaoka |
120a6e |
assert(ifx);
|
|
Shinya Kitaoka |
120a6e |
alias += ifx->getAlias(frame, info);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
alias += ",";
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// alias dei valori dei parametri dell'effetto al frame dato
|
|
Shinya Kitaoka |
120a6e |
for (int j = 0; j < (int)m_fxs.size(); j++) {
|
|
Shinya Kitaoka |
120a6e |
alias += (j == 0) ? "(" : ",(";
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_fxs[j]->getParams()->getParamCount(); i++) {
|
|
Shinya Kitaoka |
120a6e |
if (i > 0) alias += ",";
|
|
Shinya Kitaoka |
120a6e |
TParam *param = m_fxs[j]->getParams()->getParam(i);
|
|
Shinya Kitaoka |
120a6e |
alias += param->getName() + "=" + param->getValueAlias(frame, 2);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
alias += ")";
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
alias += "]";
|
|
Shinya Kitaoka |
120a6e |
return alias;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TMacroFx::compatibilityTranslatePort(int major, int minor,
|
|
Shinya Kitaoka |
120a6e |
std::string &portName) {
|
|
Shinya Kitaoka |
120a6e |
// Reroute translation to the actual fx associated to the port
|
|
Shinya Kitaoka |
120a6e |
const std::string &fxId =
|
|
Shinya Kitaoka |
120a6e |
portName.substr(portName.find_last_of('_') + 1, std::string::npos);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (TFx *fx = getFxById(::to_wstring(fxId))) {
|
|
Shinya Kitaoka |
120a6e |
size_t opnEnd = portName.find_first_of('_');
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::string originalPortName = portName.substr(0, opnEnd);
|
|
Shinya Kitaoka |
120a6e |
fx->compatibilityTranslatePort(major, minor, originalPortName);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
portName.replace(0, opnEnd, originalPortName);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Seems that at a certain point, the port name got extended...
|
|
Shinya Kitaoka |
120a6e |
if (VersionNumber(major, minor) == VersionNumber(1, 16)) {
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < getInputPortCount(); ++i) {
|
|
Shinya Kitaoka |
120a6e |
const std::string &name = getInputPortName(i);
|
|
Shinya Kitaoka |
120a6e |
if (name.find(portName) != std::string::npos) {
|
|
Shinya Kitaoka |
120a6e |
portName = name;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TMacroFx::loadData(TIStream &is) {
|
|
Shinya Kitaoka |
120a6e |
VersionNumber tnzVersion = is.getVersion();
|
|
Shinya Kitaoka |
120a6e |
std::string tagName;
|
|
Shinya Kitaoka |
120a6e |
while (is.openChild(tagName)) {
|
|
Shinya Kitaoka |
120a6e |
if (tagName == "root") {
|
|
Shinya Kitaoka |
120a6e |
TPersist *p = 0;
|
|
Shinya Kitaoka |
120a6e |
is >> p;
|
|
Shinya Kitaoka |
120a6e |
m_root = dynamic_cast<tfx *="">(p);</tfx>
|
|
Shinya Kitaoka |
120a6e |
} else if (tagName == "nodes") {
|
|
Shinya Kitaoka |
120a6e |
while (!is.eos()) {
|
|
Shinya Kitaoka |
120a6e |
TPersist *p = 0;
|
|
Shinya Kitaoka |
120a6e |
is >> p;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// NOTE: In current implementation p is sharedly owned by is - it's
|
|
Shinya Kitaoka |
120a6e |
// automatically
|
|
Shinya Kitaoka |
120a6e |
// released upon stream destruction if the below assignment fails
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (TFx *fx = dynamic_cast<tfx *="">(p)) {</tfx>
|
|
Shinya Kitaoka |
120a6e |
m_fxs.push_back(fx);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else if (tagName == "ports") {
|
|
Shinya Kitaoka |
120a6e |
int i = 0;
|
|
Shinya Kitaoka |
120a6e |
while (is.matchTag(tagName)) {
|
|
Shinya Kitaoka |
120a6e |
if (tagName == "port") {
|
|
Shinya Kitaoka |
120a6e |
std::string name = is.getTagAttribute("name");
|
|
Shinya Kitaoka |
120a6e |
if (tnzVersion < VersionNumber(1, 16) && name != "") {
|
|
Shinya Kitaoka |
120a6e |
TRasterFxPort *port = new TRasterFxPort();
|
|
Shinya Kitaoka |
120a6e |
addInputPort(name, *port);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
name = is.getTagAttribute("name_inFx");
|
|
Shinya Kitaoka |
120a6e |
if (tnzVersion < VersionNumber(1, 17) &&
|
|
Shinya Kitaoka |
120a6e |
tnzVersion != VersionNumber(0, 0))
|
|
Shinya Kitaoka |
120a6e |
name.insert(name.find("_"), "_" + std::to_string(i));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
compatibilityTranslatePort(tnzVersion.first, tnzVersion.second,
|
|
Shinya Kitaoka |
120a6e |
name);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::string inPortName = name;
|
|
Shinya Kitaoka |
120a6e |
inPortName.erase(inPortName.find("_"), inPortName.size() - 1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::string inFxId = name;
|
|
Shinya Kitaoka |
120a6e |
inFxId.erase(0, inFxId.find_last_of("_") + 1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < (int)m_fxs.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
std::wstring fxId = m_fxs[i]->getFxId();
|
|
Shinya Kitaoka |
120a6e |
if (fxId == ::to_wstring(inFxId)) {
|
|
Shinya Kitaoka |
120a6e |
if (TFxPort *port = m_fxs[i]->getInputPort(inPortName))
|
|
Shinya Kitaoka |
120a6e |
addInputPort(name, *port);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
i++;
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
throw TException("unexpected tag " + tagName);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else if (tagName == "super") {
|
|
Shinya Kitaoka |
120a6e |
TRasterFx::loadData(is);
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
throw TException("unexpected tag " + tagName);
|
|
Shinya Kitaoka |
120a6e |
is.closeChild();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
collectParams(this);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TMacroFx::saveData(TOStream &os) {
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
os.openChild("root");
|
|
Shinya Kitaoka |
120a6e |
TPersist *p = m_root.getPointer();
|
|
Shinya Kitaoka |
120a6e |
os << p;
|
|
Shinya Kitaoka |
120a6e |
os.closeChild();
|
|
Shinya Kitaoka |
120a6e |
os.openChild("nodes");
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < (int)m_fxs.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
TFxP fx = m_fxs[i];
|
|
Shinya Kitaoka |
120a6e |
TPersist *p = fx.getPointer();
|
|
Shinya Kitaoka |
120a6e |
os << p;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
os.closeChild();
|
|
Shinya Kitaoka |
120a6e |
os.openChild("ports");
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < getInputPortCount(); i++) {
|
|
Shinya Kitaoka |
120a6e |
std::string portName = getInputPortName(i);
|
|
Shinya Kitaoka |
120a6e |
std::map<std::string, std::string=""> attr;</std::string,>
|
|
Shinya Kitaoka |
120a6e |
attr["name_inFx"] = portName;
|
|
Shinya Kitaoka |
120a6e |
os.openCloseChild("port", attr);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
os.closeChild();
|
|
Shinya Kitaoka |
120a6e |
os.openChild("super");
|
|
Shinya Kitaoka |
120a6e |
TRasterFx::saveData(os);
|
|
Shinya Kitaoka |
120a6e |
os.closeChild();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
FX_IDENTIFIER(TMacroFx, "macroFx")
|
|
Shinya Kitaoka |
120a6e |
// FX_IDENTIFIER_IS_HIDDEN(TMacroFx, "macroFx")
|