Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/node_tree_update.cc
| Show All 16 Lines | |||||
| #include "BKE_main.h" | #include "BKE_main.h" | ||||
| #include "BKE_node.h" | #include "BKE_node.h" | ||||
| #include "BKE_node_runtime.hh" | #include "BKE_node_runtime.hh" | ||||
| #include "BKE_node_tree_update.h" | #include "BKE_node_tree_update.h" | ||||
| #include "MOD_nodes.h" | #include "MOD_nodes.h" | ||||
| #include "NOD_node_declaration.hh" | #include "NOD_node_declaration.hh" | ||||
| #include "NOD_socket.h" | |||||
| #include "NOD_texture.h" | #include "NOD_texture.h" | ||||
| #include "DEG_depsgraph_query.h" | #include "DEG_depsgraph_query.h" | ||||
| using namespace blender::nodes; | using namespace blender::nodes; | ||||
| /** | /** | ||||
| * These flags are used by the `changed_flag` field in #bNodeTree, #bNode and #bNodeSocket. | * These flags are used by the `changed_flag` field in #bNodeTree, #bNode and #bNodeSocket. | ||||
| ▲ Show 20 Lines • Show All 500 Lines • ▼ Show 20 Lines | for (bNodeSocket *socket : tree.all_sockets()) { | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| void update_individual_nodes(bNodeTree &ntree) | void update_individual_nodes(bNodeTree &ntree) | ||||
| { | { | ||||
| Vector<bNode *> group_inout_nodes; | |||||
| for (bNode *node : ntree.all_nodes()) { | for (bNode *node : ntree.all_nodes()) { | ||||
| nodeDeclarationEnsure(&ntree, node); | nodeDeclarationEnsure(&ntree, node); | ||||
| if (this->should_update_individual_node(ntree, *node)) { | if (this->should_update_individual_node(ntree, *node)) { | ||||
| bNodeType &ntype = *node->typeinfo; | bNodeType &ntype = *node->typeinfo; | ||||
| if (ntype.group_update_func) { | if (ntype.group_update_func) { | ||||
| ntype.group_update_func(&ntree, node); | ntype.group_update_func(&ntree, node); | ||||
| } | } | ||||
| if (ntype.updatefunc) { | if (ntype.updatefunc) { | ||||
| ntype.updatefunc(&ntree, node); | ntype.updatefunc(&ntree, node); | ||||
| } | } | ||||
| if (ntype.declare_dynamic) { | |||||
| nodes::update_node_declaration_and_sockets(ntree, *node); | |||||
| } | } | ||||
| if (ELEM(node->type, NODE_GROUP_INPUT, NODE_GROUP_OUTPUT)) { | |||||
| group_inout_nodes.append(node); | |||||
| } | |||||
| } | |||||
| /* The update function of group input/output nodes may add new interface sockets. When that | |||||
| * happens, all the input/output nodes have to be updated again. In the future it would be | |||||
| * better to move this functionality out of the node update function into the operator that's | |||||
| * supposed to create the new interface socket. */ | |||||
| if (ntree.runtime->changed_flag & NTREE_CHANGED_INTERFACE) { | |||||
| for (bNode *node : group_inout_nodes) { | |||||
| node->typeinfo->updatefunc(&ntree, node); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| bool should_update_individual_node(const bNodeTree &ntree, const bNode &node) | bool should_update_individual_node(const bNodeTree &ntree, const bNode &node) | ||||
| { | { | ||||
| if (ntree.runtime->changed_flag & NTREE_CHANGED_ANY) { | if (ntree.runtime->changed_flag & NTREE_CHANGED_ANY) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| if (node.runtime->changed_flag & NTREE_CHANGED_NODE_PROPERTY) { | if (node.runtime->changed_flag & NTREE_CHANGED_NODE_PROPERTY) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| if (ntree.runtime->changed_flag & NTREE_CHANGED_LINK) { | if (ntree.runtime->changed_flag & NTREE_CHANGED_LINK) { | ||||
| ntree.ensure_topology_cache(); | |||||
| /* Node groups currently always rebuilt their sockets when they are updated. | |||||
| * So avoid calling the update method when no new link was added to it. */ | |||||
| if (node.type == NODE_GROUP_INPUT) { | |||||
| if (node.output_sockets().last()->is_directly_linked()) { | |||||
| return true; | |||||
| } | |||||
| } | |||||
| else if (node.type == NODE_GROUP_OUTPUT) { | |||||
| if (node.input_sockets().last()->is_directly_linked()) { | |||||
| return true; | |||||
| } | |||||
| } | |||||
| else { | |||||
| /* Currently we have no way to tell if a node needs to be updated when a link changed. */ | /* Currently we have no way to tell if a node needs to be updated when a link changed. */ | ||||
JacquesLucke: Shouldn't call `ensure_topoogy_cache` if it's not used immediately afterwards. | |||||
| return true; | return true; | ||||
| } | } | ||||
| } | |||||
| if (ntree.runtime->changed_flag & NTREE_CHANGED_INTERFACE) { | if (ntree.runtime->changed_flag & NTREE_CHANGED_INTERFACE) { | ||||
| if (ELEM(node.type, NODE_GROUP_INPUT, NODE_GROUP_OUTPUT)) { | if (ELEM(node.type, NODE_GROUP_INPUT, NODE_GROUP_OUTPUT)) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 664 Lines • Show Last 20 Lines | |||||
Shouldn't call ensure_topoogy_cache if it's not used immediately afterwards.