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