From ba4b7b43195c17436beaba95956087be4fb746a9 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 24 Dec 2021 12:34:04 +0100 Subject: Fix T94162: incorrect handling when there are multiple group outputs Typically a node group should only have a single Group Output node. However, currently Blender already supports having multiple group outputs, one of which is active. This wasn't handled correctly by geometry nodes. Differential Revision: https://developer.blender.org/D13611 --- source/blender/nodes/NOD_node_tree_ref.hh | 11 +++++++++++ source/blender/nodes/intern/derived_node_tree.cc | 3 +++ source/blender/nodes/intern/node_tree_ref.cc | 16 ++++++++++++++++ 3 files changed, 30 insertions(+) (limited to 'source/blender') diff --git a/source/blender/nodes/NOD_node_tree_ref.hh b/source/blender/nodes/NOD_node_tree_ref.hh index 65789069231..ebbec20a139 100644 --- a/source/blender/nodes/NOD_node_tree_ref.hh +++ b/source/blender/nodes/NOD_node_tree_ref.hh @@ -262,6 +262,7 @@ class NodeTreeRef : NonCopyable, NonMovable { Vector links_; MultiValueMap nodes_by_type_; Vector> owned_identifier_maps_; + const NodeRef *group_output_node_ = nullptr; public: NodeTreeRef(bNodeTree *btree); @@ -279,6 +280,11 @@ class NodeTreeRef : NonCopyable, NonMovable { const NodeRef *find_node(const bNode &bnode) const; + /** + * This is the active group output node if there are multiple. + */ + const NodeRef *group_output_node() const; + /** * \return True when there is a link cycle. Unavailable sockets are ignored. */ @@ -759,6 +765,11 @@ inline Span NodeTreeRef::links() const return links_; } +inline const NodeRef *NodeTreeRef::group_output_node() const +{ + return group_output_node_; +} + inline bNodeTree *NodeTreeRef::btree() const { return btree_; diff --git a/source/blender/nodes/intern/derived_node_tree.cc b/source/blender/nodes/intern/derived_node_tree.cc index dc223f07a26..449c6598307 100644 --- a/source/blender/nodes/intern/derived_node_tree.cc +++ b/source/blender/nodes/intern/derived_node_tree.cc @@ -270,6 +270,9 @@ void DOutputSocket::foreach_target_socket(ForeachTargetSocketFn target_fn, } } else if (linked_node->is_group_output_node()) { + if (linked_node.node_ref() != context_->tree().group_output_node()) { + continue; + } if (context_->is_root()) { /* This is a group output in the root node group. */ path_info.sockets.append(linked_socket); diff --git a/source/blender/nodes/intern/node_tree_ref.cc b/source/blender/nodes/intern/node_tree_ref.cc index ffe0edb9762..bc78533d45c 100644 --- a/source/blender/nodes/intern/node_tree_ref.cc +++ b/source/blender/nodes/intern/node_tree_ref.cc @@ -117,6 +117,22 @@ NodeTreeRef::NodeTreeRef(bNodeTree *btree) : btree_(btree) const bNodeType *nodetype = node->bnode_->typeinfo; nodes_by_type_.add(nodetype, node); } + + const Span group_output_nodes = this->nodes_by_type("NodeGroupOutput"); + if (group_output_nodes.is_empty()) { + group_output_node_ = nullptr; + } + else if (group_output_nodes.size() == 1) { + group_output_node_ = group_output_nodes.first(); + } + else { + for (const NodeRef *group_output : group_output_nodes) { + if (group_output->bnode_->flag & NODE_DO_OUTPUT) { + group_output_node_ = group_output; + break; + } + } + } } NodeTreeRef::~NodeTreeRef() -- cgit v1.2.3