From 1d5bc2d81609af0d3b5ec279bc9b92debee442ba Mon Sep 17 00:00:00 2001 From: shun-iwasawa Date: Tue, 27 Jul 2021 17:13:22 +0900 Subject: [PATCH] fx schematic node placement fix --- .../include/toonzqt/fxschematicscene.h | 2 + toonz/sources/toonzlib/fxcommand.cpp | 6 +++ toonz/sources/toonzqt/fxschematicscene.cpp | 49 ++++++++++++++++++- 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/toonz/sources/include/toonzqt/fxschematicscene.h b/toonz/sources/include/toonzqt/fxschematicscene.h index 1907db2c..3547a35a 100644 --- a/toonz/sources/include/toonzqt/fxschematicscene.h +++ b/toonz/sources/include/toonzqt/fxschematicscene.h @@ -184,6 +184,8 @@ private: void updatePositionOnResize(TFx *fx, bool maximizedNode); void removeRetroLinks(TFx *fx, double &maxX); + bool isAnEmptyZone_withParentFx(const QRectF &rect, const TFx *parent); + signals: void showPreview(TFxP); void cacheFx(TFxP); diff --git a/toonz/sources/toonzlib/fxcommand.cpp b/toonz/sources/toonzlib/fxcommand.cpp index 9c16a6bd..00768e2a 100644 --- a/toonz/sources/toonzlib/fxcommand.cpp +++ b/toonz/sources/toonzlib/fxcommand.cpp @@ -1011,6 +1011,12 @@ void DuplicateFxUndo::initialize() { m_dupFx = fx; } + + // place duplicated nodes lower-right position from the original ones + if (fx->getAttributes()->getDagNodePos() != TConst::nowhere) { + TPointD dupFxPos = fx->getAttributes()->getDagNodePos() + TPointD(50, 50); + m_dupFx->getAttributes()->setDagNodePos(dupFxPos); + } } //------------------------------------------------------------- diff --git a/toonz/sources/toonzqt/fxschematicscene.cpp b/toonz/sources/toonzqt/fxschematicscene.cpp index 2707d593..af3eb71e 100644 --- a/toonz/sources/toonzqt/fxschematicscene.cpp +++ b/toonz/sources/toonzqt/fxschematicscene.cpp @@ -164,6 +164,18 @@ QList getRoots(const QList &fxs, TFxSet *terminals) { bool resizingNodes = false; bool updatingScene = false; + +bool nodePosDefined(const TFx *fx1, const TFx *fx2) { + bool isPosDefined[2] = { + fx1->getAttributes()->getDagNodePos() != TConst::nowhere, + fx2->getAttributes()->getDagNodePos() != TConst::nowhere}; + + if (isPosDefined[0] == isPosDefined[1]) + return fx1->getIdentifier() < fx2->getIdentifier(); + else + return isPosDefined[0]; +} + } // namespace //================================================================== @@ -425,6 +437,7 @@ void FxSchematicScene::updateScene() { } // Add normalFx + QList fxsToBePlaced; for (i = 0; i < fxSet->getFxCount(); i++) { TFx *fx = fxSet->getFx(i); TMacroFx *macro = dynamic_cast(fx); @@ -444,9 +457,17 @@ void FxSchematicScene::updateScene() { } continue; } + fxsToBePlaced.append(fx); + } + + // sorting fxs so that fxs with specified positions are placed first + qSort(fxsToBePlaced.begin(), fxsToBePlaced.end(), nodePosDefined); + + for (auto fx : fxsToBePlaced) { SchematicNode *node = addFxSchematicNode(fx); if (fx->getAttributes()->isGrouped()) editedGroup[fx->getAttributes()->getEditingGroupId()].append(node); + TMacroFx *macro = dynamic_cast(fx); // If adding an unedited macro and nodes are not yet set, let's position the // internal nodes now if (macro) { @@ -763,7 +784,9 @@ void FxSchematicScene::placeNode(FxSchematicNode *node) { inputFx->getAttributes()->getDagNodePos() + TPointD(150, 0); pos = QPointF(dagPos.x, dagPos.y); nodeRect.moveTopLeft(pos); - while (!isAnEmptyZone(nodeRect)) nodeRect.translate(0, -step); + + while (!isAnEmptyZone_withParentFx(nodeRect, inputFx)) + nodeRect.translate(0, -step); pos = nodeRect.topLeft(); } else { m_nodesToPlace[inputFx].append(node); @@ -2135,3 +2158,27 @@ void FxSchematicScene::onNodeChangedSize() { if (resizingNodes) return; updateScene(); } + +//------------------------------------------------------------------ + +bool FxSchematicScene::isAnEmptyZone_withParentFx(const QRectF &rect, + const TFx *parent) { + QList allItems = items(); + for (auto const level : allItems) { + SchematicNode *node = dynamic_cast(level); + if (!node) continue; + FxSchematicNode *fxNode = dynamic_cast(node); + if (fxNode && fxNode->isA(eXSheetFx)) continue; + // check only the fxs sharing the same parent + if (!fxNode) continue; + for (int p = 0; p < fxNode->getInputPortCount(); p++) { + if (parent == fxNode->getFx()->getInputPort(p)->getFx()) { + if (node->boundingRect().translated(node->scenePos()).intersects(rect)) + return false; + else + break; + } + } + } + return true; +} \ No newline at end of file