From 127e411f41bdc7dea414f1ae13f8da95fd816118 Mon Sep 17 00:00:00 2001 From: Rodney Date: Jul 28 2021 13:17:28 +0000 Subject: Merge pull request #4025 from shun-iwasawa/g/fxschematic_node_placement Fx schematic node placement fix --- diff --git a/toonz/sources/include/toonzqt/fxschematicscene.h b/toonz/sources/include/toonzqt/fxschematicscene.h index 4fc5ce1..75a1bbc 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 cb1c8a0..ac3e1aa 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 2707d59..af3eb71 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