TFx *TMacroFx::clone(bool recursive) const { int n = m_fxs.size(); vector<TFxP> clones(n); std::map<TFx *, int> table; std::map<TFx *, int>::iterator it; int i, rootIndex = -1; // nodi for (i = 0; i < n; ++i) { TFx *fx = m_fxs[i].getPointer(); assert(fx); clones[i] = fx->clone(false); assert(table.count(fx) == 0); table[fx] = i; if (fx == m_root.getPointer()) rootIndex = i; TFx *linkedFx = fx->getLinkedFx(); if (linkedFx && table.find(linkedFx) != table.end()) clones[i]->linkParams(clones[table[linkedFx]].getPointer()); } assert(rootIndex >= 0); // connessioni for (i = 0; i < n; i++) { TFx *fx = m_fxs[i].getPointer(); for (int j = 0; j < fx->getInputPortCount(); j++) { TFxPort *port = fx->getInputPort(j); TFx *inputFx = port->getFx(); if (!inputFx) continue; it = table.find(inputFx); if (it == table.end()) { // il j-esimo input di fx e' esterno alla macro if (recursive) clones[i]->connect(fx->getInputPortName(j), inputFx->clone(true)); } else { // il j-esimo input di fx e' interno alla macro clones[i]->connect(fx->getInputPortName(j), clones[it->second].getPointer()); } } } //TFx *rootClone = // const_cast<TMacroFx*>(this)-> // clone(m_root.getPointer(), recursive, visited, clones); TMacroFx *clone = TMacroFx::create(clones); clone->setName(getName()); clone->setFxId(getFxId()); //Copy the index of the passive cache manager. clone->getAttributes()->passiveCacheDataIdx() = getAttributes()->passiveCacheDataIdx(); assert(clone->getRoot() == clones[rootIndex].getPointer()); return clone; }
void FxsData::setFxs(const QList<TFxP> &selectedFxs, const QList<Link> &selectedLinks, const QList<int> &columnIndexes, TXsheet *xsh) { // fx->clonedFx 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(); }
std::vector<TStageObjectId> StageObjectsData::restoreObjects(std::set<int> &columnIndices, std::list<int> &restoredSpline, TXsheet *xsh, int fxFlags, const TPointD &pos) const { bool doClone = (fxFlags & eDoClone); bool resetFxDagPositions = (fxFlags & eResetFxDagPositions); QMap<TStageObjectId, TStageObjectId> idTable; // Trace stored/restored id pairings std::map<TFx *, TFx *> fxTable; // Same for fxs here std::vector<TStageObjectId> restoredIds; std::set<int>::iterator idxt = columnIndices.begin(); int index = -1; // The actual column insertion index int i, elementsCount = m_elements.size(); for (i = 0; i < elementsCount; ++i) { TStageObjectDataElement *element = m_elements[i]; TCameraDataElement *cameraElement = dynamic_cast<TCameraDataElement *>(element); TColumnDataElement *columnElement = dynamic_cast<TColumnDataElement *>(element); // Restore the object depending on its specific type TStageObjectId restoredId = TStageObjectId::NoneId; if (!cameraElement && !columnElement) restoredId = element->restoreObject(xsh, pos != TConst::nowhere); else if (cameraElement) restoredId = cameraElement->restoreCamera(xsh, pos != TConst::nowhere); else if (columnElement) { // Build the column insertion index if (idxt != columnIndices.end()) index = *idxt++; else { ++index; columnIndices.insert(index); } // Restore the column element restoredId = columnElement->restoreColumn(xsh, index, fxFlags, pos != TConst::nowhere); FxDag *fxDag = xsh->getFxDag(); TXshColumn *column = columnElement->m_column.getPointer(); TXshColumn *pastedColumn = xsh->getColumn(index); TFx *fx = column->getFx(); TFx *pastedFx = pastedColumn->getFx(); if (fx && pastedFx) fxTable[fx] = pastedFx; // Enforce the correct terminality. Added columns are terminal by default. bool terminal = (fx && (m_terminalFxs.count(fx) > 0)); if (!terminal) fxDag->getTerminalFxs()->removeFx(pastedFx); // In case we've cloned a zerary fx column, update the actual fx's data if (TXshZeraryFxColumn *zc = dynamic_cast<TXshZeraryFxColumn *>(pastedColumn)) { TZeraryColumnFx *zfx = zc->getZeraryColumnFx(); TFx *zeraryFx = zfx->getZeraryFx(); if (zeraryFx && doClone) { std::wstring app = zeraryFx->getName(); fxDag->assignUniqueId(zeraryFx); zeraryFx->setName(app); } } } // Remember stored/restored stage object pairings idTable[element->m_params->m_id] = restoredId; restoredIds.push_back(restoredId); } // Apply stage object-parental relationships for (i = 0; i < elementsCount; ++i) { TStageObjectDataElement *element = m_elements[i]; TStageObjectId id = element->m_params->m_id; TStageObjectId parentId = element->m_params->m_parentId; TStageObjectId pastedId = idTable[id]; TStageObjectId pastedParentId = parentId; if (parentId.isColumn()) // Why discriminating for columns only ? { //Columns are redirected to table ids. If no redirected parent exists, store //a void value that will be avoided later QMap<TStageObjectId, TStageObjectId>::iterator it = idTable.find(parentId); pastedParentId = (it == idTable.end()) ? TStageObjectId::NoneId : it.value(); } if (pastedParentId != TStageObjectId::NoneId) { xsh->setStageObjectParent(pastedId, pastedParentId); TStageObject *pastedObj = xsh->getStageObject(pastedId); // Shouldn't these be done outside ? pastedObj->setHandle(element->m_params->m_handle); pastedObj->setParentHandle(element->m_params->m_parentHandle); } } // Iterate stored fxs std::set<TFx *>::const_iterator fxt, end = m_fxs.end(); for (fxt = m_fxs.begin(); fxt != end; ++fxt) { TFx *fxOrig = *fxt, *fx = fxOrig; // Only NOT COLUMN fxs - ie internal fxs if (fxTable.find(fxOrig) != fxTable.end()) continue; // Internal fxs if (doClone) { fx = fxOrig->clone(false); fx->setName(fxOrig->getName()); fx->getAttributes()->setId(fxOrig->getAttributes()->getId()); fx->getAttributes()->passiveCacheDataIdx() = -1; if (resetFxDagPositions) fx->getAttributes()->setDagNodePos(TConst::nowhere); xsh->getFxDag()->assignUniqueId(fx); } fxTable[fxOrig] = fx; // Insert the passed fx in the xsheet TOutputFx *outFx = dynamic_cast<TOutputFx *>(fx); if (!outFx) xsh->getFxDag()->getInternalFxs()->addFx(fx); else xsh->getFxDag()->addOutputFx(outFx); if (m_terminalFxs.count(fxOrig) > 0) xsh->getFxDag()->getTerminalFxs()->addFx(fx); if (!doClone) { // Err.... don't remember. Inquire further? :| int fxTypeCount = xsh->getFxDag()->getFxTypeCount(fx); int maxFxTypeId = std::max(fxTypeCount, fx->getAttributes()->getId()); xsh->getFxDag()->updateFxTypeTable(fx, maxFxTypeId); xsh->getFxDag()->updateFxIdTable(fx); } bool isLinked = (fxOrig->getLinkedFx() != fxOrig); if (isLinked) { if (m_fxs.find(fxOrig->getLinkedFx()) == m_fxs.end()) fx->linkParams(fxOrig->getLinkedFx()); else { TFx *linkedFx, *oldLinkedFx = fxOrig->getLinkedFx(); if (doClone) { // Clone the linked fx too linkedFx = fx->clone(false); linkedFx->linkParams(fx); linkedFx->setName(oldLinkedFx->getName()); linkedFx->getAttributes()->setId(oldLinkedFx->getAttributes()->getId()); linkedFx->getAttributes()->passiveCacheDataIdx() = -1; if (resetFxDagPositions) linkedFx->getAttributes()->setDagNodePos(TConst::nowhere); else linkedFx->getAttributes()->setDagNodePos(oldLinkedFx->getAttributes()->getDagNodePos()); xsh->getFxDag()->assignUniqueId(linkedFx); } else linkedFx = oldLinkedFx; fxTable[oldLinkedFx] = linkedFx; xsh->getFxDag()->getInternalFxs()->addFx(linkedFx); if (m_terminalFxs.count(oldLinkedFx) > 0) xsh->getFxDag()->getTerminalFxs()->addFx(linkedFx); if (!doClone) { int fxTypeCount = xsh->getFxDag()->getFxTypeCount(linkedFx); int maxFxTypeId = std::max(fxTypeCount, linkedFx->getAttributes()->getId()); xsh->getFxDag()->updateFxTypeTable(linkedFx, maxFxTypeId); xsh->getFxDag()->updateFxIdTable(linkedFx); } } } } // Update the link, like in functions above if (!fxTable.empty() && doClone) updateFxLinks(fxTable); // Paste any associated spline (not stored im m_splines) std::map<TStageObjectSpline *, TStageObjectSpline *> splines; for (i = 0; i < (int)restoredIds.size(); ++i) { TStageObjectId id = restoredIds[i]; TStageObject *obj = xsh->getStageObject(id); TStageObjectSpline *spline = obj->getSpline(); if (!spline) continue; TStageObjectTree *objTree = xsh->getStageObjectTree(); if (objTree->containsSpline(spline)) // No need to add it if it's already there continue; std::map<TStageObjectSpline *, TStageObjectSpline *>::iterator it = splines.find(spline); if (it != splines.end()) { // Seems that multiple objects can have the same spline... // BTW, shouldn't this case stop at the continue before ? obj->setSpline(it->second); continue; } // The spline was not found. Clone and add it to the xsheet TStageObjectSpline *newSpline = spline->clone(); // Not checking doClone ? objTree->assignUniqueSplineId(newSpline); objTree->insertSpline(newSpline); obj->setSpline(newSpline); splines[spline] = newSpline; } //paste stored path QList<TSplineDataElement *>::const_iterator splinIt; for (splinIt = m_splines.begin(); splinIt != m_splines.end(); ++splinIt) { TStageObjectTree *objTree = xsh->getStageObjectTree(); TSplineDataElement *splineEl = *splinIt; TStageObjectSpline *spline = splineEl->restoreSpline(fxFlags); if (doClone) objTree->assignUniqueSplineId(spline); objTree->insertSpline(spline); restoredSpline.push_back(spline->getId()); } xsh->updateFrameCount(); if (pos != TConst::nowhere) { // Update objects positions depending on the externally supplied pos TPointD middlePos; int count = 0; for (i = 0; i < (int)restoredIds.size(); ++i) { TStageObjectId id = restoredIds[i]; TStageObject *obj = xsh->getStageObject(id); TPointD oldPos = obj->getDagNodePos(); if (oldPos == TConst::nowhere) continue; middlePos += oldPos; ++count; } middlePos = TPointD(middlePos.x / count, middlePos.y / count); TPointD offset = pos - middlePos; for (i = 0; i < (int)restoredIds.size(); ++i) { TStageObjectId id = restoredIds[i]; TStageObject *obj = xsh->getStageObject(id); TPointD oldPos = obj->getDagNodePos(); if (oldPos == TConst::nowhere) continue; obj->setDagNodePos(oldPos + offset); } } return restoredIds; }
void StageObjectsData::storeColumnFxs(const std::set<int> &columnIndexes, TXsheet *xsh, int fxFlags) { bool doClone = (fxFlags & eDoClone); bool resetFxDagPositions = (fxFlags & eResetFxDagPositions); std::set<TFx *> internalFxs; xsh->getFxDag()->getInternalFxs()->getFxs(internalFxs); // Iterate internal fxs (note: columns NOT included) // NOTE: Could this be too heavy ? Shouldn't we travel upstream from given column fxs? std::set<TFx *>::iterator it; for (it = internalFxs.begin(); it != internalFxs.end(); ++it) { TFx *fxOrig = *it, *fx = fxOrig; if (m_fxTable.find(fx) != m_fxTable.end()) // If already treated continue; if (!canGenerate(m_originalColumnFxs, fx)) // If not completely in the upstream continue; if (doClone) { // Clone the fx if required fx = fxOrig->clone(false); fx->setName(fxOrig->getName()); fx->getAttributes()->setId(fxOrig->getAttributes()->getId()); fx->getAttributes()->passiveCacheDataIdx() = -1; if (resetFxDagPositions) fx->getAttributes()->setDagNodePos(TConst::nowhere); } m_fxTable[fxOrig] = fx; fx->addRef(); m_fxs.insert(fx); if (isColumnSelectionTerminalFx( fxOrig, xsh->getFxDag()->getTerminalFxs(), m_originalColumnFxs)) { fx->addRef(); m_terminalFxs.insert(fx); } if (fxOrig->getLinkedFx() != fxOrig) // Linked fx { if (!canGenerate(m_originalColumnFxs, fxOrig->getLinkedFx())) fx->linkParams(fxOrig->getLinkedFx()); else { // Insert the linked fx directly here TFx *linkedFx, *oldLinkedFx = fxOrig->getLinkedFx(); if (doClone) { linkedFx = fx->clone(false); // Not oldLinkedFx->clone() ? linkedFx->linkParams(fx); linkedFx->setName(oldLinkedFx->getName()); linkedFx->getAttributes()->setId(oldLinkedFx->getAttributes()->getId()); linkedFx->getAttributes()->passiveCacheDataIdx() = -1; if (resetFxDagPositions) fx->getAttributes()->setDagNodePos(TConst::nowhere); // Here too ? xsh->getFxDag()->assignUniqueId(linkedFx); } else linkedFx = oldLinkedFx; m_fxTable[oldLinkedFx] = linkedFx; linkedFx->addRef(); m_fxs.insert(linkedFx); if (xsh->getFxDag()->getTerminalFxs()->containsFx(fx->getLinkedFx())) // Here too - isATerminal ? { linkedFx->addRef(); m_terminalFxs.insert(linkedFx); } } } } // Like in the functions above, update links if (!m_fxTable.empty() && doClone) updateFxLinks(m_fxTable); }