diff --git a/toonz/sources/toonzlib/fxcommand.cpp b/toonz/sources/toonzlib/fxcommand.cpp index 97c7c26..0ea8a78 100644 --- a/toonz/sources/toonzlib/fxcommand.cpp +++ b/toonz/sources/toonzlib/fxcommand.cpp @@ -1608,7 +1608,8 @@ private: else { TOutputFx *currentOutputFx = xsh->getFxDag()->getCurrentOutputFx(); const TPointD &pos = currentOutputFx->getAttributes()->getDagNodePos(); - outputFx->getAttributes()->setDagNodePos(pos + TPointD(20, 20)); + if (pos != TConst::nowhere) + outputFx->getAttributes()->setDagNodePos(pos + TPointD(20, 20)); } } }; @@ -2647,7 +2648,8 @@ void UndoPasteFxs::initialize(const std::map &zeraryFxColumnSize, TFx *fx = *ft; const TPointD &fxPos = fx->getAttributes()->getDagNodePos(); - fx->getAttributes()->setDagNodePos(fxPos + offset); + if (fxPos != TConst::nowhere) + fx->getAttributes()->setDagNodePos(fxPos + offset); } } } diff --git a/toonz/sources/toonzqt/fxschematicnode.cpp b/toonz/sources/toonzqt/fxschematicnode.cpp index 1cee27c..8b21ec0 100644 --- a/toonz/sources/toonzqt/fxschematicnode.cpp +++ b/toonz/sources/toonzqt/fxschematicnode.cpp @@ -1884,15 +1884,18 @@ void FxSchematicNode::setSchematicNodePos(const QPointF &pos) const { TPointD p(pos.x(), pos.y()); if (!m_fx->getAttributes()->isGrouped() || m_fx->getAttributes()->isGroupEditing()) { + TPointD oldFxPos = m_fx->getAttributes()->getDagNodePos(); m_fx->getAttributes()->setDagNodePos(p); TMacroFx *macro = dynamic_cast(m_fx.getPointer()); if (macro) { - TPointD delta = p - macro->getRoot()->getAttributes()->getDagNodePos(); + TPointD delta = + p - (oldFxPos != TConst::nowhere ? oldFxPos : TPointD(0, 0)); std::vector fxs = macro->getFxs(); int i; for (i = 0; i < (int)fxs.size(); i++) { TPointD oldPos = fxs[i]->getAttributes()->getDagNodePos(); - fxs[i]->getAttributes()->setDagNodePos(oldPos + delta); + if (oldPos != TConst::nowhere) + fxs[i]->getAttributes()->setDagNodePos(oldPos + delta); } } } else { @@ -3461,16 +3464,17 @@ void FxGroupNode::updateFxsDagPosition(const TPointD &pos) const { // placeNode() function. // if (m_groupedFxs[i]->getAttributes()->getDagNodePos() != TConst::nowhere) { - m_groupedFxs[i]->getAttributes()->setDagNodePos( - m_groupedFxs[i]->getAttributes()->getDagNodePos() + delta); + TPointD groupPos = m_groupedFxs[i]->getAttributes()->getDagNodePos(); + if (groupPos != TConst::nowhere) + m_groupedFxs[i]->getAttributes()->setDagNodePos(groupPos + delta); TMacroFx *macro = dynamic_cast(m_groupedFxs[i].getPointer()); if (macro) { std::vector fxs = macro->getFxs(); int i; for (i = 0; i < (int)fxs.size(); i++) { TPointD oldP = fxs[i]->getAttributes()->getDagNodePos(); - // if (oldP != TConst::nowhere) - fxs[i]->getAttributes()->setDagNodePos(oldP + delta); + if (oldP != TConst::nowhere) + fxs[i]->getAttributes()->setDagNodePos(oldP + delta); } } } diff --git a/toonz/sources/toonzqt/fxschematicscene.cpp b/toonz/sources/toonzqt/fxschematicscene.cpp index 71e10f0..e16c8ab 100644 --- a/toonz/sources/toonzqt/fxschematicscene.cpp +++ b/toonz/sources/toonzqt/fxschematicscene.cpp @@ -447,6 +447,23 @@ void FxSchematicScene::updateScene() { SchematicNode *node = addFxSchematicNode(fx); if (fx->getAttributes()->isGrouped()) editedGroup[fx->getAttributes()->getEditingGroupId()].append(node); + // If adding an unedited macro and nodes are not yet set, let's position the + // internal nodes now + if (macro) { + double minY = macro->getAttributes()->getDagNodePos().y; + double maxX = macro->getAttributes()->getDagNodePos().x; + double y = minY; + double x = maxX; + std::vector fxs = macro->getFxs(); + for (int j = 0; j < (int)fxs.size(); j++) { + TFx *macroFx = fxs[j].getPointer(); + if (macroFx && !m_placedFxs.contains(macroFx)) { + placeNodeAndParents(macroFx, x, maxX, minY); + y -= (m_gridDimension == eLarge ? 100 : 50); + minY = std::min(y, minY); + } + } + } } // grouped node @@ -690,9 +707,44 @@ void FxSchematicScene::placeNode(FxSchematicNode *node) { node->getFx()->getAttributes()->setDagNodePos(TPointD(pos.x(), pos.y())); node->setPos(pos); return; - } else if (node->isA(eMacroFx) || node->isA(eNormalFx) || - node->isA(eNormalLayerBlendingFx) || node->isA(eNormalMatteFx) || - node->isA(eNormalImageAdjustFx)) { + } else if (node->isA(eMacroFx)) { + double minX = TConst::nowhere.x, minY = TConst::nowhere.y, maxY; + QPointF pos; + TMacroFx *macroFx = dynamic_cast(node->getFx()); + std::vector fxs = macroFx->getFxs(); + int k; + for (k = 0; k < (int)fxs.size(); k++) { + TFx *fx = fxs[k].getPointer(); + if (fx->getAttributes()->getDagNodePos() == TConst::nowhere) continue; + if (QPointF(minX, minY) == + QPointF(TConst::nowhere.x, TConst::nowhere.y)) { + minX = fx->getAttributes()->getDagNodePos().x; + minY = maxY = fx->getAttributes()->getDagNodePos().y; + continue; + } + minX = std::min(fx->getAttributes()->getDagNodePos().x, minX); + minY = std::min(fx->getAttributes()->getDagNodePos().y, minY); + maxY = std::max(fx->getAttributes()->getDagNodePos().y, maxY); + } + if (QPointF(minX, minY) == QPointF(TConst::nowhere.x, TConst::nowhere.y)) { + pos = sceneRect().center(); + nodeRect.moveTopLeft(pos); + while (!isAnEmptyZone(nodeRect)) nodeRect.translate(0, -step); + pos = nodeRect.topLeft(); + } else { + pos.setX(minX); + pos.setY((maxY + minY) / 2); + } + node->getFx()->getAttributes()->setDagNodePos(TPointD(pos.x(), pos.y())); + node->setPos(QPointF(pos)); + if (m_nodesToPlace.contains(node->getFx())) { + QList nodes = m_nodesToPlace[node->getFx()]; + int i; + for (i = 0; i < nodes.size(); i++) placeNode(nodes[i]); + } + return; + } else if (node->isA(eNormalFx) || node->isA(eNormalLayerBlendingFx) || + node->isA(eNormalMatteFx) || node->isA(eNormalImageAdjustFx)) { // I'm placing an effect or a macro TFx *inputFx = node->getFx()->getInputPort(0)->getFx(); QPointF pos; @@ -1126,6 +1178,40 @@ void FxSchematicScene::reorderScene() { TXsheet *xsh = m_xshHandle->getXsheet(); int i = 0; + + FxDag *fxDag = xsh->getFxDag(); + TFxSet *fxSet = fxDag->getInternalFxs(); + + // Let's reset every position to nowhere first + fxDag->getXsheetFx()->getAttributes()->setDagNodePos(TConst::nowhere); + + for (i = 0; i < fxDag->getOutputFxCount(); i++) { + TOutputFx *fx = fxDag->getOutputFx(i); + if (!fx) continue; + fx->getAttributes()->setDagNodePos(TConst::nowhere); + } + + for (i = 0; i < xsh->getColumnCount(); i++) { + TXshColumn *column = xsh->getColumn(i); + TFx *fx = column->getFx(); + if (!fx) continue; + fx->getAttributes()->setDagNodePos(TConst::nowhere); + } + + for (i = 0; i < fxSet->getFxCount(); i++) { + TFx *fx = fxSet->getFx(i); + fx->getAttributes()->setDagNodePos(TConst::nowhere); + TMacroFx *macro = dynamic_cast(fx); + if (macro && macro->isEditing()) { + std::vector fxs = macro->getFxs(); + int j; + for (j = 0; j < (int)fxs.size(); j++) { + fxs[j]->getAttributes()->setDagNodePos(TConst::nowhere); + } + } + } + + // Let's start placing them now for (i = 0; i < xsh->getColumnCount(); i++) { TXshColumn *column = xsh->getColumn(i); TFx *fx = column->getFx(); @@ -1168,15 +1254,16 @@ void FxSchematicScene::reorderScene() { double middleY = (sceneCenter.y() + minY + step) * 0.5; placeNodeAndParents(xsh->getFxDag()->getXsheetFx(), maxX, maxX, middleY); + y -= step; + minY = std::min(y, minY); - FxDag *fxDag = xsh->getFxDag(); - TFxSet *fxSet = fxDag->getInternalFxs(); for (i = 0; i < fxSet->getFxCount(); i++) { TFx *fx = fxSet->getFx(i); if (m_placedFxs.contains(fx)) continue; - fx->getAttributes()->setDagNodePos(TPointD(sceneCenter.x() + 120, minY)); - minY -= step; + placeNodeAndParents(fx, (sceneCenter.x() + 120), maxX, minY); + y -= step; + minY = std::min(y, minY); } updateScene(); } @@ -1190,7 +1277,8 @@ void FxSchematicScene::removeRetroLinks(TFx *fx, double &maxX) { if (!inFx) continue; TPointD inFxPos = inFx->getAttributes()->getDagNodePos(); TPointD fxPos = fx->getAttributes()->getDagNodePos(); - if (fxPos.x <= inFxPos.x) { + if (inFxPos != TConst::nowhere && fxPos != TConst::nowhere && + fxPos.x <= inFxPos.x) { while (fxPos.x <= inFxPos.x) fxPos.x += 150; maxX = std::max(fxPos.x + 150, maxX); fx->getAttributes()->setDagNodePos(fxPos); @@ -1222,8 +1310,23 @@ void FxSchematicScene::placeNodeAndParents(TFx *fx, double x, double &maxX, } } } - double y = minY; - fx->getAttributes()->setDagNodePos(TPointD(x, y)); + double y = minY; + TMacroFx *macro = dynamic_cast(fx); + if (macro) { + int tmpY = y; + std::vector fxs = macro->getFxs(); + for (int j = 0; j < (int)fxs.size(); j++) { + TFx *macroFx = fxs[j].getPointer(); + if (macroFx && !m_placedFxs.contains(macroFx)) { + placeNodeAndParents(macroFx, x, maxX, minY); + y -= step; + minY = std::min(y, minY); + } + } + tmpY = (minY + tmpY + step) * 0.5; + fx->getAttributes()->setDagNodePos(TPointD(x, tmpY)); + } else + fx->getAttributes()->setDagNodePos(TPointD(x, y)); if (fx->getOutputConnectionCount() == 0) minY -= step; x += 120; maxX = std::max(maxX, x); @@ -2008,6 +2111,7 @@ void FxSchematicScene::resizeNodes(bool maximizedNode) { void FxSchematicScene::updatePositionOnResize(TFx *fx, bool maximizedNode) { TPointD oldPos = fx->getAttributes()->getDagNodePos(); + if (oldPos == TConst::nowhere) return; double oldPosY = oldPos.y - 25000; double newPosY = maximizedNode ? oldPosY * 2 : oldPosY * 0.5; fx->getAttributes()->setDagNodePos(TPointD(oldPos.x, newPosY + 25000)); diff --git a/toonz/sources/toonzqt/schematicgroupeditor.cpp b/toonz/sources/toonzqt/schematicgroupeditor.cpp index aed9748..d2f3fff 100644 --- a/toonz/sources/toonzqt/schematicgroupeditor.cpp +++ b/toonz/sources/toonzqt/schematicgroupeditor.cpp @@ -411,11 +411,14 @@ void FxSchematicMacroEditor::setGroupedNodeZValue(int zValue) { //--------------------------------------------------------------- void FxSchematicMacroEditor::mouseMoveEvent(QGraphicsSceneMouseEvent *e) { + QPointF prevPos = pos(); SchematicWindowEditor::mouseMoveEvent(e); if (m_button == Qt::LeftButton) { - TFx *root = m_macro->getRoot(); - TPointD pos = root->getAttributes()->getDagNodePos(); - m_macro->getAttributes()->setDagNodePos(pos); + QPointF delta = pos() - prevPos; + TFx *root = m_macro->getRoot(); + TPointD oldPos = m_macro->getAttributes()->getDagNodePos(); + m_macro->getAttributes()->setDagNodePos(oldPos + + TPointD(delta.x(), delta.y())); } } diff --git a/toonz/sources/toonzqt/stageschematicscene.cpp b/toonz/sources/toonzqt/stageschematicscene.cpp index 00d230e..8718f81 100644 --- a/toonz/sources/toonzqt/stageschematicscene.cpp +++ b/toonz/sources/toonzqt/stageschematicscene.cpp @@ -593,6 +593,7 @@ void StageSchematicScene::resizeNodes(bool maximizedNode) { void StageSchematicScene::updatePositionOnResize(TStageObject *obj, bool maximizedNode) { TPointD oldPos = obj->getDagNodePos(); + if (oldPos == TConst::nowhere) return; double oldPosY = oldPos.y - 25500; double newPosY = maximizedNode ? oldPosY * 2 : oldPosY * 0.5; obj->setDagNodePos(TPointD(oldPos.x, newPosY + 25500)); @@ -603,6 +604,7 @@ void StageSchematicScene::updatePositionOnResize(TStageObject *obj, void StageSchematicScene::updateSplinePositionOnResize(TStageObjectSpline *spl, bool maximizedNode) { TPointD oldPos = spl->getDagNodePos(); + if (oldPos == TConst::nowhere) return; double oldPosY = oldPos.y - 25500; double newPosY = maximizedNode ? oldPosY * 2 : oldPosY * 0.5; spl->setDagNodePos(TPointD(oldPos.x, newPosY + 25500));