diff options
Diffstat (limited to 'source/blender/nodes/intern/derived_node_tree.cc')
-rw-r--r-- | source/blender/nodes/intern/derived_node_tree.cc | 84 |
1 files changed, 83 insertions, 1 deletions
diff --git a/source/blender/nodes/intern/derived_node_tree.cc b/source/blender/nodes/intern/derived_node_tree.cc index 5a380897e3f..c693047ff40 100644 --- a/source/blender/nodes/intern/derived_node_tree.cc +++ b/source/blender/nodes/intern/derived_node_tree.cc @@ -41,6 +41,7 @@ DerivedNodeTree::DerivedNodeTree(bNodeTree *btree, NodeTreeRefMap &node_tree_ref this->insert_nodes_and_links_in_id_order(main_tree_ref, nullptr, all_nodes); this->expand_groups(all_nodes, all_group_inputs, all_parent_nodes, node_tree_refs); + this->relink_and_remove_muted_nodes(all_nodes); this->remove_expanded_group_interfaces(all_nodes); this->remove_unused_group_inputs(all_group_inputs); this->store_in_this_and_init_ids( @@ -120,7 +121,11 @@ BLI_NOINLINE void DerivedNodeTree::expand_groups(Vector<DNode *> &all_nodes, for (int i = 0; i < all_nodes.size(); i++) { DNode &node = *all_nodes[i]; if (node.node_ref_->is_group_node()) { - this->expand_group_node(node, all_nodes, all_group_inputs, all_parent_nodes, node_tree_refs); + /* Muted nodes are relinked in a separate step. */ + if (!node.node_ref_->is_muted()) { + this->expand_group_node( + node, all_nodes, all_group_inputs, all_parent_nodes, node_tree_refs); + } } } } @@ -301,6 +306,83 @@ BLI_NOINLINE void DerivedNodeTree::remove_unused_group_inputs( } } +BLI_NOINLINE void DerivedNodeTree::relink_and_remove_muted_nodes(Vector<DNode *> &all_nodes) +{ + int index = 0; + while (index < all_nodes.size()) { + DNode &node = *all_nodes[index]; + const NodeRef &node_ref = *node.node_ref_; + if (node_ref.is_muted()) { + this->relink_muted_node(node); + all_nodes.remove_and_reorder(index); + node.destruct_with_sockets(); + } + else { + index++; + } + } +} + +BLI_NOINLINE void DerivedNodeTree::relink_muted_node(DNode &node) +{ + const bNode &bnode = *node.bnode(); + LISTBASE_FOREACH (const bNodeLink *, internal_link, &bnode.internal_links) { + BLI_assert(internal_link->fromnode == &bnode); + BLI_assert(internal_link->tonode == &bnode); + bNodeSocket *input_bsocket = internal_link->fromsock; + bNodeSocket *output_bsocket = internal_link->tosock; + + /* Find internally linked sockets. */ + DInputSocket *input_socket = nullptr; + DOutputSocket *output_socket = nullptr; + for (DInputSocket *socket : node.inputs_) { + if (socket->bsocket() == input_bsocket) { + input_socket = socket; + break; + } + } + for (DOutputSocket *socket : node.outputs_) { + if (socket->bsocket() == output_bsocket) { + output_socket = socket; + break; + } + } + BLI_assert(input_socket != nullptr); + BLI_assert(output_socket != nullptr); + + /* Link sockets connected to the input to sockets that are connected to the internally linked + * output. */ + for (DInputSocket *to_socket : output_socket->linked_sockets_) { + for (DOutputSocket *from_socket : input_socket->linked_sockets_) { + from_socket->linked_sockets_.append_non_duplicates(to_socket); + to_socket->linked_sockets_.append_non_duplicates(from_socket); + } + for (DGroupInput *group_input : input_socket->linked_group_inputs_) { + group_input->linked_sockets_.append_non_duplicates(to_socket); + to_socket->linked_group_inputs_.append_non_duplicates(group_input); + } + } + } + + /* Remove remaining links from muted node. */ + for (DInputSocket *to_socket : node.inputs_) { + for (DOutputSocket *from_socket : to_socket->linked_sockets_) { + from_socket->linked_sockets_.remove_first_occurrence_and_reorder(to_socket); + } + for (DGroupInput *from_group_input : to_socket->linked_group_inputs_) { + from_group_input->linked_sockets_.remove_first_occurrence_and_reorder(to_socket); + } + to_socket->linked_sockets_.clear(); + to_socket->linked_group_inputs_.clear(); + } + for (DOutputSocket *from_socket : node.outputs_) { + for (DInputSocket *to_socket : from_socket->linked_sockets_) { + to_socket->linked_sockets_.remove_first_occurrence_and_reorder(from_socket); + } + from_socket->linked_sockets_.clear(); + } +} + void DNode::destruct_with_sockets() { for (DInputSocket *socket : inputs_) { |