Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_node_runtime.hh40
-rw-r--r--source/blender/blenkernel/CMakeLists.txt1
-rw-r--r--source/blender/blenkernel/intern/node.cc18
-rw-r--r--source/blender/blenkernel/intern/node_tree_update.cc76
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc4
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc4
-rw-r--r--source/blender/makesdna/DNA_node_types.h40
-rw-r--r--source/blender/modifiers/intern/MOD_nodes.cc6
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;
}