Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonz/fxdag.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzLib includes
Toshihiro Shimizu 890ddd
#include "toonz/tcolumnfxset.h"
Toshihiro Shimizu 890ddd
#include "toonz/tcolumnfx.h"
Toshihiro Shimizu 890ddd
#include "tw/stringtable.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzBase includes
Toshihiro Shimizu 890ddd
#include "tmacrofx.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
// tcg includes
Toshihiro Shimizu 890ddd
#include "tcg/function_types.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// STD includes
Toshihiro Shimizu 890ddd
//#include <cwctypes></cwctypes>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FxDag::FxDag()
Toshihiro Shimizu 890ddd
	: m_internalFxs(new TFxSet()), m_terminalFxs(new TFxSet()), m_groupIdCount(0), m_dagGridDimension(eSmall)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TXsheetFx *xsheetFx = new TXsheetFx;
Toshihiro Shimizu 890ddd
	xsheetFx->setFxDag(this);
Toshihiro Shimizu 890ddd
	m_xsheetFx = xsheetFx;
Toshihiro Shimizu 890ddd
	m_xsheetFx->addRef();
Toshihiro Shimizu 890ddd
	m_xsheetFx->setNewIdentifier();
Toshihiro Shimizu 890ddd
	addOutputFx();
Toshihiro Shimizu 890ddd
	m_outputFxs[0]->getInputPort(0)->setFx(m_xsheetFx);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FxDag::~FxDag()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	delete m_internalFxs;
Toshihiro Shimizu 890ddd
	delete m_terminalFxs;
Toshihiro Shimizu 890ddd
	m_xsheetFx->release();
Toshihiro Shimizu 890ddd
	int i;
Toshihiro Shimizu 890ddd
	for (i = 0; i < (int)m_outputFxs.size(); i++)
Toshihiro Shimizu 890ddd
		m_outputFxs[i]->release();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TOutputFx *FxDag::addOutputFx(TOutputFx *outputFx)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!outputFx)
Toshihiro Shimizu 890ddd
		outputFx = new TOutputFx();
Toshihiro Shimizu 890ddd
	outputFx->addRef();
Toshihiro Shimizu 890ddd
	m_xsheetFx->setNewIdentifier();
Toshihiro Shimizu 890ddd
	assert(outputFx->getInputPortCount() == 1);
Toshihiro Shimizu 890ddd
	m_outputFxs.push_back(outputFx);
Toshihiro Shimizu 890ddd
	return outputFx;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FxDag::removeOutputFx(TOutputFx *fx)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(fx);
Toshihiro Shimizu 890ddd
	if (m_outputFxs.size() == 1)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	if (std::find(m_outputFxs.begin(), m_outputFxs.end(), fx) == m_outputFxs.end())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	m_outputFxs.erase(
Toshihiro Shimizu 890ddd
		std::remove(m_outputFxs.begin(), m_outputFxs.end(), fx),
Toshihiro Shimizu 890ddd
		m_outputFxs.end());
Toshihiro Shimizu 890ddd
	fx->release();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TFxSet *FxDag::getInternalFxs() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_internalFxs;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FxDag::setCurrentOutputFx(TOutputFx *fx)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	std::vector<toutputfx *="">::iterator it;</toutputfx>
Toshihiro Shimizu 890ddd
	it = std::find(m_outputFxs.begin(), m_outputFxs.end(), fx);
Toshihiro Shimizu 890ddd
	if (it == m_outputFxs.end())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	if (it == m_outputFxs.begin())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	std::swap(*it, *m_outputFxs.begin());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TOutputFx *FxDag::getCurrentOutputFx() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(!m_outputFxs.empty());
Toshihiro Shimizu 890ddd
	return m_outputFxs[0];
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool FxDag::checkLoop(TFx *inputFx, TFx *fx)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (inputFx == fx)
Toshihiro Shimizu 890ddd
		return true;
Toshihiro Shimizu 890ddd
	if (dynamic_cast<txsheetfx *="">(inputFx)) {</txsheetfx>
Toshihiro Shimizu 890ddd
		TFxSet *terminals = getTerminalFxs();
Toshihiro Shimizu 890ddd
		for (int i = 0; i < terminals->getFxCount(); i++) {
Toshihiro Shimizu 890ddd
			TFx *tfx = terminals->getFx(i);
Toshihiro Shimizu 890ddd
			if (tfx && checkLoop(tfx, fx))
Toshihiro Shimizu 890ddd
				return true;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		if (TZeraryColumnFx *zerary = dynamic_cast<tzerarycolumnfx *="">(inputFx))</tzerarycolumnfx>
Toshihiro Shimizu 890ddd
			inputFx = zerary->getZeraryFx();
Toshihiro Shimizu 890ddd
		for (int i = 0; i < inputFx->getInputPortCount(); i++) {
Toshihiro Shimizu 890ddd
			TFx *ifx = inputFx->getInputPort(i)->getFx();
Toshihiro Shimizu 890ddd
			if (ifx && checkLoop(ifx, fx))
Toshihiro Shimizu 890ddd
				return true;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TFxSet *FxDag::getTerminalFxs() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_terminalFxs;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FxDag::addToXsheet(TFx *fx)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_terminalFxs->addFx(fx);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FxDag::removeFromXsheet(TFx *fx)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_terminalFxs->removeFx(fx);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
struct NotAlnum {
Toshihiro Shimizu 890ddd
	bool operator()(wint_t val) const { return !iswalnum(val); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
} // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FxDag::assignUniqueId(TFx *fx)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	struct locals {
Toshihiro Shimizu 890ddd
		static void eraseNonAlnums(std::wstring &str)
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			str.erase(std::remove_if(str.begin(), str.end(), NotAlnum()), str.end());
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}; // locals
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	string type = fx->getFxType();
Toshihiro Shimizu 890ddd
	int count = ++m_typeTable[type];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	fx->getAttributes()->setId(count);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	wstring name = TStringTable::translate(type);
Toshihiro Shimizu 890ddd
	locals::eraseNonAlnums(name); // fx ids are used as XML tag names - thus, we'll restrict
Toshihiro Shimizu 890ddd
								  // the char set to alnums. Specifically, '/' must be ruled out.
Toshihiro Shimizu 890ddd
								  // E.g.: "Erode/Dilate 1" must become "ErodeDilate1"
Toshihiro Shimizu 890ddd
	name = name + QString::number(count).rightJustified(2, '0').toStdWString();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (fx->getName() == L"")
Toshihiro Shimizu 890ddd
		fx->setName(name);
Toshihiro Shimizu 890ddd
	fx->setFxId(name);
Toshihiro Shimizu 890ddd
	m_idTable[toLower(name)] = fx;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TFx *FxDag::getFxById(wstring id) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	std::map<wstring, *="" tfx="">::const_iterator it = m_idTable.find(id);</wstring,>
Toshihiro Shimizu 890ddd
	if (it == m_idTable.end())
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		return it->second;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FxDag::updateFxTypeTable(TFx *fx, int value)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	string type = fx->getFxType();
Toshihiro Shimizu 890ddd
	m_typeTable[type] = value;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FxDag::updateFxIdTable(TFx *fx)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_idTable[toLower(fx->getFxId())] = fx;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int FxDag::getFxTypeCount(TFx *fx)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	string type = fx->getFxType();
Toshihiro Shimizu 890ddd
	std::map<string, int="">::iterator it = m_typeTable.find(type);</string,>
Toshihiro Shimizu 890ddd
	if (it == m_typeTable.end())
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
	return it->second;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FxDag::getFxs(vector<tfx *=""> &fxs) const</tfx>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	std::set<tfx *=""> fxSet;</tfx>
Toshihiro Shimizu 890ddd
	getInternalFxs()->getFxs(fxSet);
Toshihiro Shimizu 890ddd
	fxs.insert(fxs.end(), fxSet.begin(), fxSet.end());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool FxDag::isRendered(TFx *fx) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_terminalFxs->containsFx(fx))
Toshihiro Shimizu 890ddd
		return true;
Toshihiro Shimizu 890ddd
	if (dynamic_cast<toutputfx *="">(fx))</toutputfx>
Toshihiro Shimizu 890ddd
		return true;
Toshihiro Shimizu 890ddd
	int i;
Toshihiro Shimizu 890ddd
	for (i = 0; i < fx->getOutputConnectionCount(); i++) {
Toshihiro Shimizu 890ddd
		TFx *outFx = fx->getOutputConnection(i)->getOwnerFx();
Toshihiro Shimizu 890ddd
		if (outFx && isRendered(outFx))
Toshihiro Shimizu 890ddd
			return true;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool FxDag::isControl(TFx *fx) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_terminalFxs->containsFx(fx))
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	if (dynamic_cast<toutputfx *="">(fx))</toutputfx>
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	int i;
Toshihiro Shimizu 890ddd
	for (i = 0; i < fx->getOutputConnectionCount(); i++) {
Toshihiro Shimizu 890ddd
		TFxPort *port = fx->getOutputConnection(i);
Toshihiro Shimizu 890ddd
		TFx *outFx = port->getOwnerFx();
Toshihiro Shimizu 890ddd
		if (outFx) {
Toshihiro Shimizu 890ddd
			if (outFx->getInputPort(0) != port)
Toshihiro Shimizu 890ddd
				return true;
Toshihiro Shimizu 890ddd
			if (isControl(outFx))
Toshihiro Shimizu 890ddd
				return true;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
TFx *search(const std::map<tfx *="" *,="" tfx=""> &table, TFx *fx)</tfx>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	std::map<tfx *="" *,="" tfx="">::const_iterator it = table.find(fx);</tfx>
Toshihiro Shimizu 890ddd
	return it == table.end() ? 0 : it->second;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FxDag::saveData(TOStream &os, int occupiedColumnCount)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (getInternalFxs()->getFxCount() > 0) {
Toshihiro Shimizu 890ddd
		os.openChild("internal");
Toshihiro Shimizu 890ddd
		getInternalFxs()->saveData(os, occupiedColumnCount);
Toshihiro Shimizu 890ddd
		os.closeChild();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (getTerminalFxs()->getFxCount() > 0) {
Toshihiro Shimizu 890ddd
		os.openChild("terminal");
Toshihiro Shimizu 890ddd
		getTerminalFxs()->saveData(os, occupiedColumnCount);
Toshihiro Shimizu 890ddd
		os.closeChild();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	os.child("xsheet") << m_xsheetFx;
Toshihiro Shimizu 890ddd
	int k;
Toshihiro Shimizu 890ddd
	for (k = 0; k < (int)m_outputFxs.size(); k++)
Toshihiro Shimizu 890ddd
		os.child("output") << m_outputFxs[k];
Toshihiro Shimizu 890ddd
	os.child("grid_dimension") << (int)m_dagGridDimension;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FxDag::loadData(TIStream &is)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	VersionNumber tnzVersion = is.getVersion();
Toshihiro Shimizu 890ddd
	int k;
Toshihiro Shimizu 890ddd
	for (k = 0; k < (int)m_outputFxs.size(); k++)
Toshihiro Shimizu 890ddd
		m_outputFxs[k]->release();
Toshihiro Shimizu 890ddd
	m_outputFxs.clear();
Toshihiro Shimizu 890ddd
	string tagName;
Toshihiro Shimizu 890ddd
	while (is.openChild(tagName)) {
Toshihiro Shimizu 890ddd
		if (tagName == "terminal") {
Toshihiro Shimizu 890ddd
			TFxSet *fxSet = getTerminalFxs();
Toshihiro Shimizu 890ddd
			fxSet->loadData(is);
Toshihiro Shimizu 890ddd
			int i;
Toshihiro Shimizu 890ddd
			for (i = 0; i < fxSet->getFxCount(); i++) {
Toshihiro Shimizu 890ddd
				TFx *fx = fxSet->getFx(i);
Toshihiro Shimizu 890ddd
				if (fx->getAttributes()->isGrouped() && m_groupIdCount < fx->getAttributes()->getGroupId())
Toshihiro Shimizu 890ddd
					m_groupIdCount = fx->getAttributes()->getGroupId();
Toshihiro Shimizu 890ddd
				if (TZeraryColumnFx *zfx = dynamic_cast<tzerarycolumnfx *="">(fx))</tzerarycolumnfx>
Toshihiro Shimizu 890ddd
					fx = zfx->getZeraryFx();
Toshihiro Shimizu 890ddd
				if (tnzVersion < VersionNumber(1, 16)) {
Toshihiro Shimizu 890ddd
					wstring app = fx->getName();
Toshihiro Shimizu 890ddd
					assignUniqueId(fx);
Toshihiro Shimizu 890ddd
					fx->setName(app);
Toshihiro Shimizu 890ddd
					continue;
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
				int fxTypeCount = getFxTypeCount(fx);
Toshihiro Shimizu 890ddd
				int maxFxTypeId = tmax(fxTypeCount, fx->getAttributes()->getId());
Toshihiro Shimizu 890ddd
				updateFxTypeTable(fx, maxFxTypeId);
Toshihiro Shimizu 890ddd
				TMacroFx *macroFx = dynamic_cast<tmacrofx *="">(fx);</tmacrofx>
Toshihiro Shimizu 890ddd
				if (macroFx) {
Toshihiro Shimizu 890ddd
					vector<tfxp> fxs = macroFx->getFxs();</tfxp>
Toshihiro Shimizu 890ddd
					int j;
Toshihiro Shimizu 890ddd
					for (j = 0; j < (int)fxs.size(); j++) {
Toshihiro Shimizu 890ddd
						TFxP inMacroFx = fxs[j];
Toshihiro Shimizu 890ddd
						fxTypeCount = getFxTypeCount(inMacroFx.getPointer());
Toshihiro Shimizu 890ddd
						maxFxTypeId = tmax(fxTypeCount, inMacroFx->getAttributes()->getId());
Toshihiro Shimizu 890ddd
						updateFxTypeTable(inMacroFx.getPointer(), maxFxTypeId);
Toshihiro Shimizu 890ddd
						m_idTable[toLower(inMacroFx->getFxId())] = inMacroFx.getPointer();
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		} else if (tagName == "internal") {
Toshihiro Shimizu 890ddd
			TFxSet *fxSet = getInternalFxs();
Toshihiro Shimizu 890ddd
			fxSet->loadData(is);
Toshihiro Shimizu 890ddd
			int i;
Toshihiro Shimizu 890ddd
			for (i = 0; i < fxSet->getFxCount(); i++) {
Toshihiro Shimizu 890ddd
				TFx *fx = fxSet->getFx(i);
Toshihiro Shimizu 890ddd
				if (fx->getAttributes()->isGrouped() && m_groupIdCount < fx->getAttributes()->getGroupId())
Toshihiro Shimizu 890ddd
					m_groupIdCount = fx->getAttributes()->getGroupId();
Toshihiro Shimizu 890ddd
				if (TZeraryColumnFx *zfx = dynamic_cast<tzerarycolumnfx *="">(fx))</tzerarycolumnfx>
Toshihiro Shimizu 890ddd
					fx = zfx->getZeraryFx();
Toshihiro Shimizu 890ddd
				if (tnzVersion < VersionNumber(1, 16)) {
Toshihiro Shimizu 890ddd
					wstring app = fx->getName();
Toshihiro Shimizu 890ddd
					assignUniqueId(fx);
Toshihiro Shimizu 890ddd
					fx->setName(app);
Toshihiro Shimizu 890ddd
					continue;
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
				int fxTypeCount = getFxTypeCount(fx);
Toshihiro Shimizu 890ddd
				int maxFxTypeId = tmax(fxTypeCount, fx->getAttributes()->getId());
Toshihiro Shimizu 890ddd
				updateFxTypeTable(fx, maxFxTypeId);
Toshihiro Shimizu 890ddd
				m_idTable[toLower(fx->getFxId())] = fx;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		} else if (tagName == "xsheet" || tagName == "output") {
Toshihiro Shimizu 890ddd
			TPersist *p = 0;
Toshihiro Shimizu 890ddd
			is >> p;
Toshihiro Shimizu 890ddd
			TFx *fx = dynamic_cast<tfx *="">(p);</tfx>
Toshihiro Shimizu 890ddd
			if (!fx)
Toshihiro Shimizu 890ddd
				throw TException("FxDag. unexpeced Fx");
Toshihiro Shimizu 890ddd
			fx->addRef();
Toshihiro Shimizu 890ddd
			fx->setNewIdentifier();
Toshihiro Shimizu 890ddd
			if (tagName == "xsheet") {
Toshihiro Shimizu 890ddd
				m_xsheetFx->release();
Toshihiro Shimizu 890ddd
				m_xsheetFx = fx;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				TXsheetFx *xsheetFx = dynamic_cast<txsheetfx *="">(fx);</txsheetfx>
Toshihiro Shimizu 890ddd
				if (xsheetFx)
Toshihiro Shimizu 890ddd
					xsheetFx->setFxDag(this);
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				TOutputFx *outputFx = dynamic_cast<toutputfx *="">(fx);</toutputfx>
Toshihiro Shimizu 890ddd
				if (outputFx)
Toshihiro Shimizu 890ddd
					m_outputFxs.push_back(outputFx);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		} else if (tagName == "grid_dimension") {
Toshihiro Shimizu 890ddd
			is >> m_dagGridDimension;
Toshihiro Shimizu 890ddd
		} else
Toshihiro Shimizu 890ddd
			throw TException("FxDag. unexpeced tag: " + tagName);
Toshihiro Shimizu 890ddd
		is.closeChild();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}