// TnzBase includes #include "tfxattributes.h" // TnzLib includes #include "toonz/tcolumnfx.h" #include "toonz/txsheet.h" #include "toonz/txshzeraryfxcolumn.h" #include "fxdata.h" //****************************************************************** // Local namespace stuff //****************************************************************** namespace { void linkFxs(const QMap &clonedFxs, const QList &selectedLinks) { int i; for (i = 0; i < selectedLinks.size(); i++) { TFx *outFx = selectedLinks[i].m_outputFx.getPointer(); TZeraryColumnFx *zerayFx = dynamic_cast(outFx); if (zerayFx) outFx = zerayFx->getZeraryFx(); TFx *inFx = selectedLinks[i].m_inputFx.getPointer(); zerayFx = dynamic_cast(inFx); if (zerayFx) inFx = zerayFx->getZeraryFx(); if (!clonedFxs.contains(outFx) || !clonedFxs.contains(inFx)) continue; TFx *clonedOutFx = clonedFxs[outFx]; TFx *clonedInFx = clonedFxs[inFx]; assert(clonedOutFx && clonedInFx); clonedOutFx->getInputPort(selectedLinks[i].m_index)->setFx(clonedInFx); } } //------------------------------------------------------- void linkFxs(const QMap &clonedFxs) { QMap::const_iterator it; for (it = clonedFxs.begin(); it != clonedFxs.end(); it++) { TFx *fx = it.key(); int j, portCount = fx->getInputPortCount(); for (j = 0; j < portCount; j++) { TFx *inputFx = fx->getInputPort(j)->getFx(); if (!clonedFxs.contains(inputFx)) continue; TFx *clonedFx = clonedFxs[fx]; TFx *inputClonedFx = clonedFxs[inputFx]; assert(clonedFx && inputClonedFx); clonedFx->getInputPort(j)->setFx(inputClonedFx); } } } //------------------------------------------------------- bool canCopyFx(TFx *fx) { TLevelColumnFx *lcFx = dynamic_cast(fx); TPaletteColumnFx *pfx = dynamic_cast(fx); TXsheetFx *xfx = dynamic_cast(fx); TOutputFx *ofx = dynamic_cast(fx); return (!lcFx && !pfx && !xfx && !ofx); } } // namespace //****************************************************************** // FxsData implementation //****************************************************************** FxsData::FxsData() : m_connected(false) {} //------------------------------------------------------- void FxsData::setFxs(const QList &selectedFxs, const QList &selectedLinks, const QList &columnIndexes, TXsheet *xsh) { // fx->clonedFx QMap clonedFxs; for (int i = 0; i < selectedFxs.size(); i++) { TFx *fx = selectedFxs[i].getPointer(); if (!canCopyFx(fx)) continue; TZeraryColumnFx *zerayFx = dynamic_cast(fx); if (zerayFx) fx = zerayFx->getZeraryFx(); TFx *clonedFx = fx->clone(false); TPointD pos; if (zerayFx) pos = zerayFx->getAttributes()->getDagNodePos(); else pos = fx->getAttributes()->getDagNodePos(); clonedFx->getAttributes()->setDagNodePos(pos); m_fxs.append(clonedFx); if (zerayFx) m_zeraryFxColumnSize[clonedFx] = zerayFx->getColumn()->getRowCount(); m_visitedFxs[clonedFx] = false; clonedFxs[fx] = clonedFx; TFx *linkedFx = fx->getLinkedFx(); if (linkedFx && clonedFxs.contains(linkedFx)) clonedFx->linkParams(clonedFxs[linkedFx]); } QList::const_iterator it; for (it = columnIndexes.begin(); it != columnIndexes.end(); it++) { TXshColumn *col = xsh->getColumn(*it); TXshColumn *newCol = col->clone(); newCol->getFx()->getAttributes()->setDagNodePos( col->getFx()->getAttributes()->getDagNodePos()); m_columns.append(newCol); clonedFxs[col->getFx()] = newCol->getFx(); } linkFxs(clonedFxs, selectedLinks); checkConnectivity(); } //------------------------------------------------------- void FxsData::getFxs(QList &fxs, QMap &zeraryFxColumnSize, QList &columns) const { QMap clonedFxs; for (int i = 0; i < m_fxs.size(); i++) { TFx *clonedFx = m_fxs[i]->clone(false); TPointD pos = m_fxs[i]->getAttributes()->getDagNodePos(); clonedFx->getAttributes()->setDagNodePos(pos); clonedFx->getAttributes()->removeFromAllGroup(); fxs.append(clonedFx); if (m_fxs[i]->isZerary()) zeraryFxColumnSize[clonedFx] = m_zeraryFxColumnSize[m_fxs[i].getPointer()]; clonedFxs[m_fxs[i].getPointer()] = clonedFx; TFx *linkedFx = m_fxs[i]->getLinkedFx(); if (linkedFx && clonedFxs.contains(linkedFx)) clonedFx->linkParams(clonedFxs[linkedFx]); } QList::const_iterator it; for (it = m_columns.begin(); it != m_columns.end(); it++) { TXshColumn *col = it->getPointer(); TXshColumn *newCol = col->clone(); newCol->getFx()->getAttributes()->setDagNodePos( col->getFx()->getAttributes()->getDagNodePos()); columns.append(newCol); clonedFxs[col->getFx()] = newCol->getFx(); } linkFxs(clonedFxs); } //------------------------------------------------------- FxsData *FxsData::clone() const { FxsData *data = new FxsData; getFxs(data->m_fxs, data->m_zeraryFxColumnSize, data->m_columns); return data; } //------------------------------------------------------- void FxsData::checkConnectivity() { if (m_fxs.isEmpty()) return; visitFx(m_fxs.at(0).getPointer()); m_connected = true; QMap::const_iterator it; for (it = m_visitedFxs.begin(); it != m_visitedFxs.end(); it++) m_connected = m_connected && it.value(); } //------------------------------------------------------- void FxsData::visitFx(TFx *fx) { if (m_visitedFxs.value(fx)) return; m_visitedFxs[fx] = true; int i; for (i = 0; i < fx->getInputPortCount(); i++) { TFx *inputFx = fx->getInputPort(i)->getFx(); if (m_visitedFxs.contains(inputFx) && areLinked(fx, inputFx)) visitFx(inputFx); } for (i = 0; i < fx->getOutputConnectionCount(); i++) { TFx *outputFx = fx->getOutputConnection(i)->getOwnerFx(); if (m_visitedFxs.contains(outputFx) && areLinked(outputFx, fx)) visitFx(outputFx); } } //--------------------------------------------------------- bool FxsData::areLinked(TFx *outFx, TFx *inFx) { for (int i = 0; i < outFx->getInputPortCount(); i++) { TFx *inputFx = outFx->getInputPort(i)->getFx(); if (inFx == inputFx) return true; } return false; }