diff options
author | Jacques Lucke <jacques@blender.org> | 2022-05-30 13:54:07 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2022-05-30 13:54:07 +0300 |
commit | bb0fc675822f313c5546a2498a162472c2571ecb (patch) | |
tree | 2f4a7941a1a32d24260d3add53e92103506a8593 /source | |
parent | 2f77b2daaccfa00866f049e4c2fc1cdee41e8ae1 (diff) |
Nodes: add separately allocated run-time data for bNodeTree
`bNodeTree` has a lot of run-time embedded in it currently. Having a separately
allocated run-time struct has some benefits:
* Run-time data is not stored in files.
* Makes it easy to use c++ types as run-time data.
* More clear distinction between what data only exists at run-time and which doesn't.
This commit doesn't move all run-time data to the new struct yet, only the data where
I know for sure how it is used. The remaining data can be moved separately.
Differential Revision: https://developer.blender.org/D15033
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_node_runtime.hh | 40 | ||||
-rw-r--r-- | source/blender/blenkernel/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/node.cc | 18 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/node_tree_update.cc | 76 | ||||
-rw-r--r-- | source/blender/depsgraph/intern/builder/deg_builder_nodes.cc | 4 | ||||
-rw-r--r-- | source/blender/depsgraph/intern/builder/deg_builder_relations.cc | 4 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_node_types.h | 40 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_nodes.cc | 6 |
8 files changed, 109 insertions, 80 deletions
diff --git a/source/blender/blenkernel/BKE_node_runtime.hh b/source/blender/blenkernel/BKE_node_runtime.hh new file mode 100644 index 00000000000..c9c4577a2d4 --- /dev/null +++ b/source/blender/blenkernel/BKE_node_runtime.hh @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#pragma once + +#include <memory> + +#include "BLI_sys_types.h" +#include "BLI_utility_mixins.hh" + +namespace blender::nodes { +struct FieldInferencingInterface; +} + +namespace blender::bke { + +class bNodeTreeRuntime : NonCopyable, NonMovable { + public: + /** + * Keeps track of what changed in the node tree until the next update. + * Should not be changed directly, instead use the functions in `BKE_node_tree_update.h`. + * #eNodeTreeChangedFlag. + */ + uint32_t changed_flag = 0; + /** + * A hash of the topology of the node tree leading up to the outputs. This is used to determine + * of the node tree changed in a way that requires updating geometry nodes or shaders. + */ + uint32_t output_topology_hash = 0; + + /** + * Used to cache run-time information of the node tree. + * #eNodeTreeRuntimeFlag. + */ + uint8_t runtime_flag = 0; + + /** Information about how inputs and outputs of the node group interact with fields. */ + std::unique_ptr<nodes::FieldInferencingInterface> field_inferencing_interface; +}; + +} // namespace blender::bke diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 0b4f81df452..4edec268fe8 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -431,6 +431,7 @@ set(SRC BKE_multires.h BKE_nla.h BKE_node.h + BKE_node_runtime.hh BKE_node_tree_update.h BKE_object.h BKE_object_deform.h diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 4d96ba58d28..95a514ef474 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -60,6 +60,7 @@ #include "BKE_lib_query.h" #include "BKE_main.h" #include "BKE_node.h" +#include "BKE_node_runtime.hh" #include "BKE_node_tree_update.h" #include "RNA_access.h" @@ -94,6 +95,7 @@ using blender::Stack; using blender::StringRef; using blender::Vector; using blender::VectorSet; +using blender::bke::bNodeTreeRuntime; using blender::nodes::FieldInferencingInterface; using blender::nodes::InputSocketFieldType; using blender::nodes::NodeDeclaration; @@ -123,6 +125,7 @@ static void nodeMuteRerouteOutputLinks(struct bNodeTree *ntree, static void ntree_init_data(ID *id) { bNodeTree *ntree = (bNodeTree *)id; + ntree->runtime = MEM_new<bNodeTreeRuntime>(__func__); ntree_set_typeinfo(ntree, nullptr); } @@ -134,6 +137,8 @@ static void ntree_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, c /* We never handle usercount here for own data. */ const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT; + ntree_dst->runtime = MEM_new<bNodeTreeRuntime>(__func__); + /* in case a running nodetree is copied */ ntree_dst->execdata = nullptr; @@ -203,9 +208,9 @@ static void ntree_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, c /* node tree will generate its own interface type */ ntree_dst->interface_type = nullptr; - if (ntree_src->field_inferencing_interface) { - ntree_dst->field_inferencing_interface = new FieldInferencingInterface( - *ntree_src->field_inferencing_interface); + if (ntree_src->runtime->field_inferencing_interface) { + ntree_dst->runtime->field_inferencing_interface = std::make_unique<FieldInferencingInterface>( + *ntree_src->runtime->field_inferencing_interface); } if (flag & LIB_ID_COPY_NO_PREVIEW) { @@ -258,8 +263,6 @@ static void ntree_free_data(ID *id) MEM_freeN(sock); } - delete ntree->field_inferencing_interface; - /* free preview hash */ if (ntree->previews) { BKE_node_instance_hash_free(ntree->previews, (bNodeInstanceValueFP)BKE_node_preview_free); @@ -270,6 +273,7 @@ static void ntree_free_data(ID *id) } BKE_previewimg_free(&ntree->preview); + MEM_delete(ntree->runtime); } static void library_foreach_node_socket(LibraryForeachIDData *data, bNodeSocket *sock) @@ -670,9 +674,7 @@ void ntreeBlendReadData(BlendDataReader *reader, bNodeTree *ntree) ntree->progress = nullptr; ntree->execdata = nullptr; - ntree->runtime_flag = 0; - - ntree->field_inferencing_interface = nullptr; + ntree->runtime = MEM_new<bNodeTreeRuntime>(__func__); BKE_ntree_update_tag_missing_runtime_data(ntree); BLO_read_data_address(reader, &ntree->adt); diff --git a/source/blender/blenkernel/intern/node_tree_update.cc b/source/blender/blenkernel/intern/node_tree_update.cc index 68e4cccba00..d4b7f695ee1 100644 --- a/source/blender/blenkernel/intern/node_tree_update.cc +++ b/source/blender/blenkernel/intern/node_tree_update.cc @@ -15,6 +15,7 @@ #include "BKE_image.h" #include "BKE_main.h" #include "BKE_node.h" +#include "BKE_node_runtime.hh" #include "BKE_node_tree_update.h" #include "MOD_nodes.h" @@ -48,7 +49,7 @@ enum eNodeTreeChangedFlag { static void add_tree_tag(bNodeTree *ntree, const eNodeTreeChangedFlag flag) { - ntree->changed_flag |= flag; + ntree->runtime->changed_flag |= flag; } static void add_node_tag(bNodeTree *ntree, bNode *node, const eNodeTreeChangedFlag flag) @@ -172,11 +173,11 @@ static FieldInferencingInterface get_node_field_inferencing_interface(const Node /* This can happen when there is a linked node group that was not found (see T92799). */ return get_dummy_field_inferencing_interface(node); } - if (group->field_inferencing_interface == nullptr) { + if (!group->runtime->field_inferencing_interface) { /* This shouldn't happen because referenced node groups should always be updated first. */ BLI_assert_unreachable(); } - return *group->field_inferencing_interface; + return *group->runtime->field_inferencing_interface; } FieldInferencingInterface inferencing_interface; @@ -551,7 +552,8 @@ static bool update_field_inferencing(const NodeTreeRef &tree) bNodeTree &btree = *tree.btree(); /* Create new inferencing interface for this node group. */ - FieldInferencingInterface *new_inferencing_interface = new FieldInferencingInterface(); + std::unique_ptr<FieldInferencingInterface> new_inferencing_interface = + std::make_unique<FieldInferencingInterface>(); new_inferencing_interface->inputs.resize(BLI_listbase_count(&btree.inputs), InputSocketFieldType::IsSupported); new_inferencing_interface->outputs.resize(BLI_listbase_count(&btree.outputs), @@ -567,11 +569,10 @@ static bool update_field_inferencing(const NodeTreeRef &tree) update_socket_shapes(tree, field_state_by_socket_id); /* Update the previous group interface. */ - const bool group_interface_changed = btree.field_inferencing_interface == nullptr || - *btree.field_inferencing_interface != + const bool group_interface_changed = !btree.runtime->field_inferencing_interface || + *btree.runtime->field_inferencing_interface != *new_inferencing_interface; - delete btree.field_inferencing_interface; - btree.field_inferencing_interface = new_inferencing_interface; + btree.runtime->field_inferencing_interface = std::move(new_inferencing_interface); return group_interface_changed; } @@ -799,7 +800,7 @@ class NodeTreeMainUpdater { { Vector<bNodeTree *> changed_ntrees; FOREACH_NODETREE_BEGIN (bmain_, ntree, id) { - if (ntree->changed_flag != NTREE_CHANGED_NOTHING) { + if (ntree->runtime->changed_flag != NTREE_CHANGED_NOTHING) { changed_ntrees.append(ntree); } } @@ -817,7 +818,7 @@ class NodeTreeMainUpdater { if (root_ntrees.size() == 1) { bNodeTree *ntree = root_ntrees[0]; - if (ntree->changed_flag == NTREE_CHANGED_NOTHING) { + if (ntree->runtime->changed_flag == NTREE_CHANGED_NOTHING) { return; } const TreeUpdateResult result = this->update_tree(*ntree); @@ -830,7 +831,7 @@ class NodeTreeMainUpdater { if (!is_single_tree_update) { Vector<bNodeTree *> ntrees_in_order = this->get_tree_update_order(root_ntrees); for (bNodeTree *ntree : ntrees_in_order) { - if (ntree->changed_flag == NTREE_CHANGED_NOTHING) { + if (ntree->runtime->changed_flag == NTREE_CHANGED_NOTHING) { continue; } if (!update_result_by_tree_.contains(ntree)) { @@ -1002,7 +1003,8 @@ class NodeTreeMainUpdater { ntreeTexCheckCyclics(&ntree); } - if (ntree.changed_flag & NTREE_CHANGED_INTERFACE || ntree.changed_flag & NTREE_CHANGED_ANY) { + if (ntree.runtime->changed_flag & NTREE_CHANGED_INTERFACE || + ntree.runtime->changed_flag & NTREE_CHANGED_ANY) { result.interface_changed = true; } @@ -1057,18 +1059,18 @@ class NodeTreeMainUpdater { this->ensure_tree_ref(ntree, tree_ref); const NodeRef &node = *tree_ref->find_node(*bnode); if (this->should_update_individual_node(node)) { - const uint32_t old_changed_flag = ntree.changed_flag; - ntree.changed_flag = NTREE_CHANGED_NOTHING; + const uint32_t old_changed_flag = ntree.runtime->changed_flag; + ntree.runtime->changed_flag = NTREE_CHANGED_NOTHING; - /* This may set #ntree.changed_flag which is detected below. */ + /* This may set #ntree.runtime->changed_flag which is detected below. */ this->update_individual_node(node); - if (ntree.changed_flag != NTREE_CHANGED_NOTHING) { + if (ntree.runtime->changed_flag != NTREE_CHANGED_NOTHING) { /* The tree ref is outdated and needs to be rebuilt. Generally, only very few update * functions change the node. Typically zero or one nodes change after an update. */ tree_ref.reset(); } - ntree.changed_flag |= old_changed_flag; + ntree.runtime->changed_flag |= old_changed_flag; } } } @@ -1077,13 +1079,13 @@ class NodeTreeMainUpdater { { bNodeTree &ntree = *node.btree(); bNode &bnode = *node.bnode(); - if (ntree.changed_flag & NTREE_CHANGED_ANY) { + if (ntree.runtime->changed_flag & NTREE_CHANGED_ANY) { return true; } if (bnode.changed_flag & NTREE_CHANGED_NODE_PROPERTY) { return true; } - if (ntree.changed_flag & NTREE_CHANGED_LINK) { + if (ntree.runtime->changed_flag & NTREE_CHANGED_LINK) { /* 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.is_group_input_node()) { @@ -1101,7 +1103,7 @@ class NodeTreeMainUpdater { return true; } } - if (ntree.changed_flag & NTREE_CHANGED_INTERFACE) { + if (ntree.runtime->changed_flag & NTREE_CHANGED_INTERFACE) { if (node.is_group_input_node() || node.is_group_output_node()) { return true; } @@ -1232,16 +1234,16 @@ class NodeTreeMainUpdater { } /* Reset the changed_flag to allow detecting when the update callback changed the node tree. */ - const uint32_t old_changed_flag = ntree.changed_flag; - ntree.changed_flag = NTREE_CHANGED_NOTHING; + const uint32_t old_changed_flag = ntree.runtime->changed_flag; + ntree.runtime->changed_flag = NTREE_CHANGED_NOTHING; ntree.typeinfo->update(&ntree); - if (ntree.changed_flag != NTREE_CHANGED_NOTHING) { + if (ntree.runtime->changed_flag != NTREE_CHANGED_NOTHING) { /* The tree ref is outdated and needs to be rebuilt. */ tree_ref.reset(); } - ntree.changed_flag |= old_changed_flag; + ntree.runtime->changed_flag |= old_changed_flag; } void remove_unused_previews_when_necessary(bNodeTree &ntree) @@ -1250,7 +1252,7 @@ class NodeTreeMainUpdater { const uint32_t allowed_flags = NTREE_CHANGED_LINK | NTREE_CHANGED_SOCKET_PROPERTY | NTREE_CHANGED_NODE_PROPERTY | NTREE_CHANGED_NODE_OUTPUT | NTREE_CHANGED_INTERFACE; - if ((ntree.changed_flag & allowed_flags) == ntree.changed_flag) { + if ((ntree.runtime->changed_flag & allowed_flags) == ntree.runtime->changed_flag) { return; } BKE_node_preview_remove_unused(&ntree); @@ -1259,7 +1261,7 @@ class NodeTreeMainUpdater { void propagate_runtime_flags(const NodeTreeRef &tree_ref) { bNodeTree &ntree = *tree_ref.btree(); - ntree.runtime_flag = 0; + ntree.runtime->runtime_flag = 0; if (ntree.type != NTREE_SHADER) { return; } @@ -1268,7 +1270,7 @@ class NodeTreeMainUpdater { for (const NodeRef *group_node : tree_ref.nodes_by_type("NodeGroup")) { const bNodeTree *group = reinterpret_cast<bNodeTree *>(group_node->bnode()->id); if (group != nullptr) { - ntree.runtime_flag |= group->runtime_flag; + ntree.runtime->runtime_flag |= group->runtime->runtime_flag; } } /* Check if the tree itself has an animated image. */ @@ -1276,7 +1278,7 @@ class NodeTreeMainUpdater { for (const NodeRef *node : tree_ref.nodes_by_type(idname)) { Image *image = reinterpret_cast<Image *>(node->bnode()->id); if (image != nullptr && BKE_image_is_animated(image)) { - ntree.runtime_flag |= NTREE_RUNTIME_FLAG_HAS_IMAGE_ANIMATION; + ntree.runtime->runtime_flag |= NTREE_RUNTIME_FLAG_HAS_IMAGE_ANIMATION; break; } } @@ -1288,7 +1290,7 @@ class NodeTreeMainUpdater { "ShaderNodeOutputAOV"}) { const Span<const NodeRef *> nodes = tree_ref.nodes_by_type(idname); if (!nodes.is_empty()) { - ntree.runtime_flag |= NTREE_RUNTIME_FLAG_HAS_MATERIAL_OUTPUT; + ntree.runtime->runtime_flag |= NTREE_RUNTIME_FLAG_HAS_MATERIAL_OUTPUT; break; } } @@ -1323,12 +1325,12 @@ class NodeTreeMainUpdater { /* Compute a hash that represents the node topology connected to the output. This always has to * be updated even if it is not used to detect changes right now. Otherwise - * #btree.output_topology_hash will go out of date. */ + * #btree.runtime.output_topology_hash will go out of date. */ const Vector<const SocketRef *> tree_output_sockets = this->find_output_sockets(tree); - const uint32_t old_topology_hash = btree.output_topology_hash; + const uint32_t old_topology_hash = btree.runtime->output_topology_hash; const uint32_t new_topology_hash = this->get_combined_socket_topology_hash( tree, tree_output_sockets); - btree.output_topology_hash = new_topology_hash; + btree.runtime->output_topology_hash = new_topology_hash; if (const AnimData *adt = BKE_animdata_from_id(&btree.id)) { /* Drivers may copy values in the node tree around arbitrarily and may cause the output to @@ -1352,7 +1354,7 @@ class NodeTreeMainUpdater { } } - if (btree.changed_flag & NTREE_CHANGED_ANY) { + if (btree.runtime->changed_flag & NTREE_CHANGED_ANY) { return true; } @@ -1361,8 +1363,8 @@ class NodeTreeMainUpdater { } /* The topology hash can only be used when only topology-changing operations have been done. */ - if (btree.changed_flag == - (btree.changed_flag & (NTREE_CHANGED_LINK | NTREE_CHANGED_REMOVED_NODE))) { + if (btree.runtime->changed_flag == + (btree.runtime->changed_flag & (NTREE_CHANGED_LINK | NTREE_CHANGED_REMOVED_NODE))) { if (old_topology_hash == new_topology_hash) { return false; } @@ -1404,7 +1406,7 @@ class NodeTreeMainUpdater { if (bnode.type == NODE_GROUP) { const bNodeTree *node_group = reinterpret_cast<const bNodeTree *>(bnode.id); if (node_group != nullptr && - node_group->runtime_flag & NTREE_RUNTIME_FLAG_HAS_MATERIAL_OUTPUT) { + node_group->runtime->runtime_flag & NTREE_RUNTIME_FLAG_HAS_MATERIAL_OUTPUT) { return true; } } @@ -1591,7 +1593,7 @@ class NodeTreeMainUpdater { void reset_changed_flags(bNodeTree &ntree) { - ntree.changed_flag = NTREE_CHANGED_NOTHING; + ntree.runtime->changed_flag = NTREE_CHANGED_NOTHING; LISTBASE_FOREACH (bNode *, node, &ntree.nodes) { node->changed_flag = NTREE_CHANGED_NOTHING; node->update = 0; diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index c6fc3cd5d0b..657bc3eb25c 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -78,6 +78,7 @@ #include "BKE_modifier.h" #include "BKE_movieclip.h" #include "BKE_node.h" +#include "BKE_node_runtime.hh" #include "BKE_object.h" #include "BKE_particle.h" #include "BKE_pointcache.h" @@ -1083,7 +1084,8 @@ void DepsgraphNodeBuilder::build_animation_images(ID *id) bool has_image_animation = false; if (ELEM(GS(id->name), ID_MA, ID_WO)) { bNodeTree *ntree = *BKE_ntree_ptr_from_id(id); - if (ntree != nullptr && ntree->runtime_flag & NTREE_RUNTIME_FLAG_HAS_IMAGE_ANIMATION) { + if (ntree != nullptr && + ntree->runtime->runtime_flag & NTREE_RUNTIME_FLAG_HAS_IMAGE_ANIMATION) { has_image_animation = true; } } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 0d4f9103149..ae159373efd 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -71,6 +71,7 @@ #include "BKE_mball.h" #include "BKE_modifier.h" #include "BKE_node.h" +#include "BKE_node_runtime.hh" #include "BKE_object.h" #include "BKE_particle.h" #include "BKE_pointcache.h" @@ -1459,7 +1460,8 @@ void DepsgraphRelationBuilder::build_animation_images(ID *id) bool has_image_animation = false; if (ELEM(GS(id->name), ID_MA, ID_WO)) { bNodeTree *ntree = *BKE_ntree_ptr_from_id(id); - if (ntree != nullptr && ntree->runtime_flag & NTREE_RUNTIME_FLAG_HAS_IMAGE_ANIMATION) { + if (ntree != nullptr && + ntree->runtime->runtime_flag & NTREE_RUNTIME_FLAG_HAS_IMAGE_ANIMATION) { has_image_animation = true; } } diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 3be4f82ecb0..0ac61d7d062 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -71,11 +71,16 @@ namespace blender::nodes { class NodeDeclaration; class SocketDeclaration; } // namespace blender::nodes +namespace blender::bke { +class bNodeTreeRuntime; +} using NodeDeclarationHandle = blender::nodes::NodeDeclaration; using SocketDeclarationHandle = blender::nodes::SocketDeclaration; +using bNodeTreeRuntimeHandle = blender::bke::bNodeTreeRuntime; #else typedef struct NodeDeclarationHandle NodeDeclarationHandle; typedef struct SocketDeclarationHandle SocketDeclarationHandle; +typedef struct bNodeTreeRuntimeHandle bNodeTreeRuntimeHandle; #endif typedef struct bNodeSocket { @@ -462,16 +467,6 @@ typedef struct bNodeLink { #define NTREE_CHUNKSIZE_512 512 #define NTREE_CHUNKSIZE_1024 1024 -/** Workaround to forward-declare C++ type in C header. */ -#ifdef __cplusplus -namespace blender::nodes { -struct FieldInferencingInterface; -} -using FieldInferencingInterfaceHandle = blender::nodes::FieldInferencingInterface; -#else -typedef struct FieldInferencingInterfaceHandle FieldInferencingInterfaceHandle; -#endif - /* the basis for a Node tree, all links and nodes reside internal here */ /* only re-usable node trees are in the library though, * materials and textures allocate own tree struct */ @@ -494,31 +489,15 @@ typedef struct bNodeTree { float view_center[2]; ListBase nodes, links; - /** Information about how inputs and outputs of the node group interact with fields. */ - FieldInferencingInterfaceHandle *field_inferencing_interface; int type; /** - * Used to cache run-time information of the node tree. - * #eNodeTreeRuntimeFlag. - */ - uint8_t runtime_flag; - - char _pad1[3]; - - /** * Sockets in groups have unique identifiers, adding new sockets always * will increase this counter. */ int cur_index; int flag; - /** - * Keeps track of what changed in the node tree until the next update. - * Should not be changed directly, instead use the functions in `BKE_node_tree_update.h`. - * #eNodeTreeChangedFlag. - */ - uint32_t changed_flag; /** Flag to prevent re-entrant update calls. */ short is_updating; /** Generic temporary flag for recursion check (DFS/BFS). */ @@ -552,11 +531,8 @@ typedef struct bNodeTree { * in case multiple different editors are used and make context ambiguous. */ bNodeInstanceKey active_viewer_key; - /** - * A hash of the topology of the node tree leading up to the outputs. This is used to determine - * of the node tree changed in a way that requires updating geometry nodes or shaders. - */ - uint32_t output_topology_hash; + + char _pad[4]; /** Execution data. * @@ -579,6 +555,8 @@ typedef struct bNodeTree { /** Image representing what the node group does. */ struct PreviewImage *preview; + + bNodeTreeRuntimeHandle *runtime; } bNodeTree; /** #NodeTree.type, index */ diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index 0d8cef3e083..e0105e4962d 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -45,6 +45,7 @@ #include "BKE_main.h" #include "BKE_mesh.h" #include "BKE_modifier.h" +#include "BKE_node_runtime.hh" #include "BKE_node_tree_update.h" #include "BKE_object.h" #include "BKE_pointcloud.h" @@ -396,8 +397,9 @@ static bool socket_type_has_attribute_toggle(const bNodeSocket &socket) */ static bool input_has_attribute_toggle(const bNodeTree &node_tree, const int socket_index) { - BLI_assert(node_tree.field_inferencing_interface != nullptr); - const FieldInferencingInterface &field_interface = *node_tree.field_inferencing_interface; + BLI_assert(node_tree.runtime->field_inferencing_interface); + const FieldInferencingInterface &field_interface = + *node_tree.runtime->field_inferencing_interface; return field_interface.inputs[socket_index] != InputSocketFieldType::None; } |