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