From d6247078b4483f42c39f6e6319be218294bebe1c Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Fri, 6 Dec 2019 03:42:53 +1100 Subject: [PATCH] improved various functions to support nodeinputarrays --- app/node/input.cpp | 24 +++++++++--- app/node/input.h | 2 + app/node/inputarray.cpp | 17 ++++---- app/node/inputarray.h | 4 ++ app/node/node.cpp | 87 ++++++++++++++++++++++++++++------------- app/node/node.h | 4 ++ 6 files changed, 98 insertions(+), 40 deletions(-) diff --git a/app/node/input.cpp b/app/node/input.cpp index 569af1dde..b86dea364 100644 --- a/app/node/input.cpp +++ b/app/node/input.cpp @@ -23,6 +23,7 @@ #include "common/lerp.h" #include "node.h" #include "output.h" +#include "inputarray.h" NodeInput::NodeInput(const QString& id) : NodeParam(id), @@ -35,6 +36,11 @@ NodeInput::NodeInput(const QString& id) : keyframes_.append(NodeKeyframe()); } +bool NodeInput::IsArray() +{ + return false; +} + NodeParam::Type NodeInput::type() { return kInput; @@ -279,8 +285,7 @@ void NodeInput::set_maximum(const QVariant &max) void NodeInput::CopyValues(NodeInput *source, NodeInput *dest, bool include_connections) { - source->parentNode()->LockUserInput(); - dest->parentNode()->LockUserInput(); + Q_ASSERT(source->id() == dest->id()); // Copy values dest->keyframes_ = source->keyframes_; @@ -288,11 +293,20 @@ void NodeInput::CopyValues(NodeInput *source, NodeInput *dest, bool include_conn // Copy keyframing state dest->set_is_keyframing(source->is_keyframing()); - source->parentNode()->UnlockUserInput(); - dest->parentNode()->UnlockUserInput(); - // Copy connections if (include_connections && source->get_connected_output() != nullptr) { ConnectEdge(source->get_connected_output(), dest); } + + // If these inputs are an array, copy the subparams too + if (dest->IsArray()) { + NodeInputArray* src_array = static_cast(source); + NodeInputArray* dst_array = static_cast(dest); + + dst_array->SetSize(src_array->GetSize()); + + for (int i=0;iGetSize();i++) { + CopyValues(src_array->ParamAt(i), dst_array->ParamAt(i), include_connections); + } + } } diff --git a/app/node/input.h b/app/node/input.h index a5307a762..a9db08aa6 100644 --- a/app/node/input.h +++ b/app/node/input.h @@ -42,6 +42,8 @@ public: */ NodeInput(const QString &id); + virtual bool IsArray(); + /** * @brief Returns kInput */ diff --git a/app/node/inputarray.cpp b/app/node/inputarray.cpp index e6ed231d5..5e19e3693 100644 --- a/app/node/inputarray.cpp +++ b/app/node/inputarray.cpp @@ -5,7 +5,11 @@ NodeInputArray::NodeInputArray(const QString &id) : NodeInput(id) { +} +bool NodeInputArray::IsArray() +{ + return true; } int NodeInputArray::GetSize() const @@ -66,10 +70,13 @@ NodeInput *NodeInputArray::ParamAt(int index) const return sub_params_.at(index); } +const QVector &NodeInputArray::sub_params() +{ + return sub_params_; +} + void NodeInputArray::InsertAt(int index) { - qDebug() << "Inserted at"; - // Add another input at the end Append(); @@ -99,22 +106,16 @@ void NodeInputArray::InsertAt(int index) void NodeInputArray::Append() { - qDebug() << "Appended"; - SetSize(GetSize() + 1); } void NodeInputArray::RemoveLast() { - qDebug() << "Removed last"; - SetSize(GetSize() - 1); } void NodeInputArray::RemoveAt(int index) { - qDebug() << "Removed at"; - int limit = sub_params_.size() - 1; // Shift all connections from index down diff --git a/app/node/inputarray.h b/app/node/inputarray.h index 924deacc0..756d8e86a 100644 --- a/app/node/inputarray.h +++ b/app/node/inputarray.h @@ -9,6 +9,8 @@ class NodeInputArray : public NodeInput public: NodeInputArray(const QString &id); + virtual bool IsArray() override; + int GetSize() const; void Prepend(); @@ -22,6 +24,8 @@ public: NodeInput* ParamAt(int index) const; + const QVector& sub_params(); + signals: void SizeChanged(int size); diff --git a/app/node/node.cpp b/app/node/node.cpp index cfc21f0b3..2a97df553 100644 --- a/app/node/node.cpp +++ b/app/node/node.cpp @@ -167,6 +167,9 @@ void Node::CopyInputs(Node *source, Node *destination, bool include_connections) { Q_ASSERT(source->id() == destination->id()); + source->LockUserInput(); + destination->LockUserInput(); + const QList& src_param = source->params_; const QList& dst_param = destination->params_; @@ -183,6 +186,37 @@ void Node::CopyInputs(Node *source, Node *destination, bool include_connections) } } } + + source->UnlockUserInput(); + destination->UnlockUserInput(); +} + +void DuplicateConnectionsBetweenListsInternal(const QList &source, const QList &destination, NodeInput* source_input, NodeInput* dest_input) +{ + if (source_input->IsConnected()) { + // Get this input's connected outputs + NodeOutput* source_output = source_input->get_connected_output(); + Node* source_output_node = source_output->parentNode(); + + // Find equivalent in destination list + Node* dest_output_node = destination.at(source.indexOf(source_output_node)); + + Q_ASSERT(dest_output_node->id() == source_output_node->id()); + + NodeOutput* dest_output = static_cast(dest_output_node->GetParameterWithID(source_output->id())); + + NodeParam::ConnectEdge(dest_output, dest_input); + } + + // If inputs are arrays, duplicate their connections too + if (source_input->IsArray()) { + NodeInputArray* source_array = static_cast(source_input); + NodeInputArray* dest_array = static_cast(dest_input); + + for (int i=0;iGetSize();i++) { + DuplicateConnectionsBetweenListsInternal(source, destination, source_array->ParamAt(i), dest_array->ParamAt(i)); + } + } } void Node::DuplicateConnectionsBetweenLists(const QList &source, const QList &destination) @@ -198,22 +232,11 @@ void Node::DuplicateConnectionsBetweenLists(const QList &source, const Q for (int j=0;jparams_.size();j++) { NodeParam* source_param = source_input_node->params_.at(j); - if (source_param->type() == NodeInput::kInput && source_param->IsConnected()) { + if (source_param->type() == NodeInput::kInput) { NodeInput* source_input = static_cast(source_param); NodeInput* dest_input = static_cast(dest_input_node->params_.at(j)); - // Get this input's connected outputs - NodeOutput* source_output = source_input->get_connected_output(); - Node* source_output_node = source_output->parentNode(); - - // Find equivalent in destination list - Node* dest_output_node = destination.at(source.indexOf(source_output_node)); - - Q_ASSERT(dest_output_node->id() == source_output_node->id()); - - NodeOutput* dest_output = static_cast(dest_output_node->GetParameterWithID(source_output->id())); - - NodeParam::ConnectEdge(dest_output, dest_input); + DuplicateConnectionsBetweenListsInternal(source, destination, source_input, dest_input); } } } @@ -249,6 +272,26 @@ int Node::IndexOfParameter(NodeParam *param) const return params_.indexOf(param); } +void Node::TraverseInputInternal(QList& list, NodeInput* input, bool traverse) { + Node* connected = input->get_connected_node(); + + if (connected != nullptr && !list.contains(connected)) { + list.append(connected); + + if (traverse) { + GetDependenciesInternal(connected, list, traverse); + } + } + + if (input->IsArray()) { + NodeInputArray* input_array = static_cast(input); + + for (int i=0;iGetSize();i++) { + TraverseInputInternal(list, input_array->ParamAt(i), traverse); + } + } +} + /** * @brief Recursively collects dependencies of Node `n` and appends them to QList `list` * @@ -257,18 +300,12 @@ int Node::IndexOfParameter(NodeParam *param) const * TRUE to recursively traverse each node for a complete dependency graph. FALSE to return only the immediate * dependencies. */ -void GetDependenciesInternal(const Node* n, QList& list, bool traverse) { +void Node::GetDependenciesInternal(const Node* n, QList& list, bool traverse) { foreach (NodeParam* p, n->parameters()) { if (p->type() == NodeParam::kInput) { - Node* connected = static_cast(p)->get_connected_node(); + NodeInput* input = static_cast(p); - if (connected != nullptr && !list.contains(connected)) { - list.append(connected); - - if (traverse) { - GetDependenciesInternal(connected, list, traverse); - } - } + TraverseInputInternal(list, input, traverse); } } } @@ -295,11 +332,7 @@ QList Node::GetExclusiveDependencies() const NodeParam* p = params.at(j); if (p->type() == NodeParam::kOutput) { - QVector edges = p->edges(); - - for (int k=0;kedges()) { // If any edge goes to from an output here to an input of a Node that isn't in this dep list, it's NOT an // exclusive dependency if (deps.contains(edge->input()->parentNode())) { diff --git a/app/node/node.h b/app/node/node.h index 50db300e1..86b86bf1f 100644 --- a/app/node/node.h +++ b/app/node/node.h @@ -310,6 +310,10 @@ private: void DisconnectInput(NodeInput* input); + static void TraverseInputInternal(QList& list, NodeInput* input, bool traverse); + + static void GetDependenciesInternal(const Node* n, QList& list, bool traverse); + QList params_; /**