From 2d67b375a15f8bb96233fc56a40be8cf545d08df Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Mon, 23 May 2022 09:03:33 +0200 Subject: Fix T98231: missing update when material output is in group Differential Revision: https://developer.blender.org/D14998 --- .../blender/blenkernel/intern/node_tree_update.cc | 37 ++++++++++++++-------- source/blender/makesdna/DNA_node_types.h | 2 ++ 2 files changed, 26 insertions(+), 13 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/intern/node_tree_update.cc b/source/blender/blenkernel/intern/node_tree_update.cc index 8afe7ce7520..68e4cccba00 100644 --- a/source/blender/blenkernel/intern/node_tree_update.cc +++ b/source/blender/blenkernel/intern/node_tree_update.cc @@ -985,7 +985,7 @@ class NodeTreeMainUpdater { this->remove_unused_previews_when_necessary(ntree); this->ensure_tree_ref(ntree, tree_ref); - this->update_has_image_animation(*tree_ref); + this->propagate_runtime_flags(*tree_ref); if (ntree.type == NTREE_GEOMETRY) { if (node_field_inferencing::update_field_inferencing(*tree_ref)) { result.interface_changed = true; @@ -1256,10 +1256,10 @@ class NodeTreeMainUpdater { BKE_node_preview_remove_unused(&ntree); } - void update_has_image_animation(const NodeTreeRef &tree_ref) + void propagate_runtime_flags(const NodeTreeRef &tree_ref) { bNodeTree &ntree = *tree_ref.btree(); - ntree.runtime_flag &= ~NTREE_RUNTIME_FLAG_HAS_IMAGE_ANIMATION; + ntree.runtime_flag = 0; if (ntree.type != NTREE_SHADER) { return; } @@ -1268,21 +1268,30 @@ class NodeTreeMainUpdater { for (const NodeRef *group_node : tree_ref.nodes_by_type("NodeGroup")) { const bNodeTree *group = reinterpret_cast(group_node->bnode()->id); if (group != nullptr) { - if (group->runtime_flag & NTREE_RUNTIME_FLAG_HAS_IMAGE_ANIMATION) { - ntree.runtime_flag |= NTREE_RUNTIME_FLAG_HAS_IMAGE_ANIMATION; - return; - } + ntree.runtime_flag |= group->runtime_flag; } } /* Check if the tree itself has an animated image. */ - for (const StringRefNull idname : {"ShaderNodeTexImage", "ShaderNodeTexEnvironment"}) + for (const StringRefNull idname : {"ShaderNodeTexImage", "ShaderNodeTexEnvironment"}) { for (const NodeRef *node : tree_ref.nodes_by_type(idname)) { Image *image = reinterpret_cast(node->bnode()->id); if (image != nullptr && BKE_image_is_animated(image)) { ntree.runtime_flag |= NTREE_RUNTIME_FLAG_HAS_IMAGE_ANIMATION; - return; + break; } } + } + /* Check if the tree has a material output. */ + for (const StringRefNull idname : {"ShaderNodeOutputMaterial", + "ShaderNodeOutputLight", + "ShaderNodeOutputWorld", + "ShaderNodeOutputAOV"}) { + const Span nodes = tree_ref.nodes_by_type(idname); + if (!nodes.is_empty()) { + ntree.runtime_flag |= NTREE_RUNTIME_FLAG_HAS_MATERIAL_OUTPUT; + break; + } + } } void update_node_levels(bNodeTree &ntree) @@ -1392,10 +1401,12 @@ class NodeTreeMainUpdater { return true; } /* Assume node groups without output sockets are outputs. */ - /* TODO: Store whether a node group contains a top-level output node (e.g. Material Output) in - * run-time information on the node group itself. */ - if (bnode.type == NODE_GROUP && node.outputs().is_empty()) { - return true; + if (bnode.type == NODE_GROUP) { + const bNodeTree *node_group = reinterpret_cast(bnode.id); + if (node_group != nullptr && + node_group->runtime_flag & NTREE_RUNTIME_FLAG_HAS_MATERIAL_OUTPUT) { + return true; + } } return false; } diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index e9c12e52bce..3be4f82ecb0 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -610,6 +610,8 @@ typedef enum eNodeTreeExecutionMode { typedef enum eNodeTreeRuntimeFlag { /** There is a node that references an image with animation. */ NTREE_RUNTIME_FLAG_HAS_IMAGE_ANIMATION = 1 << 0, + /** There is a material output node in the group. */ + NTREE_RUNTIME_FLAG_HAS_MATERIAL_OUTPUT = 1 << 1, } eNodeTreeRuntimeFlag; /* socket value structs for input buttons -- cgit v1.2.3