| |
| |
|
|
| #include "tfxattributes.h" |
| |
| |
| #include "toonz/tcolumnfx.h" |
| #include "toonz/txsheet.h" |
| #include "toonz/txshzeraryfxcolumn.h" |
| |
| #include "fxdata.h" |
| |
| |
| |
| |
| |
| namespace { |
| |
| void linkFxs(const QMap<TFx *, TFx *> &clonedFxs, |
| const QList<Link> &selectedLinks) { |
| int i; |
| for (i = 0; i < selectedLinks.size(); i++) { |
| TFx *outFx = selectedLinks[i].m_outputFx.getPointer(); |
| |
| TZeraryColumnFx *zerayFx = dynamic_cast<TZeraryColumnFx *>(outFx); |
| if (zerayFx) outFx = zerayFx->getZeraryFx(); |
| |
| TFx *inFx = selectedLinks[i].m_inputFx.getPointer(); |
| zerayFx = dynamic_cast<TZeraryColumnFx *>(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<TFx *, TFx *> &clonedFxs) { |
| QMap<TFx *, TFx *>::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<TLevelColumnFx *>(fx); |
| TPaletteColumnFx *pfx = dynamic_cast<TPaletteColumnFx *>(fx); |
| TXsheetFx *xfx = dynamic_cast<TXsheetFx *>(fx); |
| TOutputFx *ofx = dynamic_cast<TOutputFx *>(fx); |
| |
| return (!lcFx && !pfx && !xfx && !ofx); |
| } |
| |
| } |
| |
| |
| |
| |
| |
| FxsData::FxsData() : m_connected(false) {} |
| |
| |
| |
| void FxsData::setFxs(const QList<TFxP> &selectedFxs, |
| const QList<Link> &selectedLinks, |
| const QList<int> &columnIndexes, TXsheet *xsh) { |
| |
| QMap<TFx *, TFx *> clonedFxs; |
| for (int i = 0; i < selectedFxs.size(); i++) { |
| TFx *fx = selectedFxs[i].getPointer(); |
| if (!canCopyFx(fx)) continue; |
| TZeraryColumnFx *zerayFx = dynamic_cast<TZeraryColumnFx *>(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<int>::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<TFxP> &fxs, QMap<TFx *, int> &zeraryFxColumnSize, |
| QList<TXshColumnP> &columns) const { |
| QMap<TFx *, TFx *> 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<TXshColumnP>::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<TFx *, bool>::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; |
| } |
| |