Blender V5.0
geometry_nodes_dependencies.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
6
7#include "DNA_ID.h"
8#include "DNA_object_types.h"
9
11#include "BKE_node_runtime.hh"
12
13namespace blender::nodes {
14
16{
17 if (!id) {
18 return;
19 }
20 this->ids.add(id->session_uid, id);
21}
22
24{
25 if (!id) {
26 return;
27 }
28 if (GS(id->name) == ID_OB) {
29 this->add_object(reinterpret_cast<Object *>(id));
30 }
31 else {
32 this->add_generic_id(id);
33 }
34}
35
37 const ObjectDependencyInfo &object_deps)
38{
39 if (!object) {
40 return;
41 }
42 this->add_generic_id(&object->id);
43 ObjectDependencyInfo &deps = this->objects_info.lookup_or_add(object->id.session_uid,
44 object_deps);
45 deps.geometry |= object_deps.geometry;
46 deps.transform |= object_deps.transform;
47 deps.camera_parameters |= object_deps.camera_parameters;
48}
49
51{
52 for (ID *id : other.ids.values()) {
53 this->add_generic_id(id);
54 }
55 for (const auto &&item : other.objects_info.items()) {
56 ID *id = other.ids.lookup(item.key);
57 BLI_assert(GS(id->name) == ID_OB);
58 this->add_object(reinterpret_cast<Object *>(id), item.value);
59 }
63 this->time_dependent |= other.time_dependent;
64}
65
68{
69 if (socket.is_input()) {
70 if (socket.is_logically_linked()) {
71 /* The input value is unused. */
72 return;
73 }
74 }
75 switch (socket.type) {
76 case SOCK_OBJECT: {
77 if (Object *object = static_cast<bNodeSocketValueObject *>(socket.default_value)->value) {
78 deps.add_object(object);
79 }
80 break;
81 }
82 case SOCK_COLLECTION: {
83 if (Collection *collection =
84 static_cast<bNodeSocketValueCollection *>(socket.default_value)->value)
85 {
86 deps.add_generic_id(reinterpret_cast<ID *>(collection));
87 }
88 break;
89 }
90 case SOCK_MATERIAL: {
91 if (Material *material =
92 static_cast<bNodeSocketValueMaterial *>(socket.default_value)->value)
93 {
94 deps.add_generic_id(reinterpret_cast<ID *>(material));
95 }
96 break;
97 }
98 case SOCK_TEXTURE: {
99 if (Tex *texture = static_cast<bNodeSocketValueTexture *>(socket.default_value)->value) {
100 deps.add_generic_id(reinterpret_cast<ID *>(texture));
101 }
102 break;
103 }
104 case SOCK_IMAGE: {
105 if (Image *image = static_cast<bNodeSocketValueImage *>(socket.default_value)->value) {
106 deps.add_generic_id(reinterpret_cast<ID *>(image));
107 }
108 break;
109 }
110 }
111}
112
115{
116 for (const bNode *node : tree.nodes_by_type("GeometryNodeInputObject")) {
117 if (node->is_muted()) {
118 continue;
119 }
120 deps.add_object(reinterpret_cast<Object *>(node->id));
121 }
122 for (const bNode *node : tree.nodes_by_type("GeometryNodeInputCollection")) {
123 if (node->is_muted()) {
124 continue;
125 }
126 deps.add_generic_id(node->id);
127 }
128}
129
131 const blender::StringRefNull type_idname)
132{
133 for (const bNode *node : tree.nodes_by_type(type_idname)) {
134 if (!node->is_muted()) {
135 return true;
136 }
137 }
138 return false;
139}
140
143{
144 bool needs_own_transform = false;
145
146 needs_own_transform |= has_enabled_nodes_of_type(tree, "GeometryNodeSelfObject");
147 needs_own_transform |= has_enabled_nodes_of_type(tree, "GeometryNodeDeformCurvesOnSurface");
148
149 for (const bNode *node : tree.nodes_by_type("GeometryNodeCollectionInfo")) {
150 if (node->is_muted()) {
151 continue;
152 }
153 const NodeGeometryCollectionInfo &storage = *static_cast<const NodeGeometryCollectionInfo *>(
154 node->storage);
155 needs_own_transform |= storage.transform_space == GEO_NODE_TRANSFORM_SPACE_RELATIVE;
156 }
157
158 for (const bNode *node : tree.nodes_by_type("GeometryNodeObjectInfo")) {
159 if (node->is_muted()) {
160 continue;
161 }
162 const NodeGeometryObjectInfo &storage = *static_cast<const NodeGeometryObjectInfo *>(
163 node->storage);
164 needs_own_transform |= storage.transform_space == GEO_NODE_TRANSFORM_SPACE_RELATIVE;
165 }
166
167 deps.needs_own_transform |= needs_own_transform;
168}
169
170static bool needs_scene_render_params(const bNodeTree &ntree)
171{
172 for (const bNode *node : ntree.nodes_by_type("GeometryNodeCameraInfo")) {
173 if (node->is_muted()) {
174 continue;
175 }
176 const bNodeSocket &projection_matrix_socket = *node->output_by_identifier("Projection Matrix");
177 if (projection_matrix_socket.is_logically_linked()) {
178 return true;
179 }
180 }
181 return false;
182}
183
185 const bNodeTree &ntree,
187 FunctionRef<const GeometryNodesEvalDependencies *(const bNodeTree &group)> get_group_deps)
188{
189 ntree.ensure_topology_cache();
190 for (const bNodeSocket *socket : ntree.all_sockets()) {
192 }
193 deps.needs_active_camera |= has_enabled_nodes_of_type(ntree, "GeometryNodeInputActiveCamera");
195 deps.time_dependent |= has_enabled_nodes_of_type(ntree, "GeometryNodeSimulationInput") ||
196 has_enabled_nodes_of_type(ntree, "GeometryNodeInputSceneTime");
197
200
201 for (const bNode *node : ntree.group_nodes()) {
202 if (!node->id) {
203 continue;
204 }
205 const bNodeTree &group = *reinterpret_cast<const bNodeTree *>(node->id);
206 if (const GeometryNodesEvalDependencies *group_deps = get_group_deps(group)) {
207 deps.merge(*group_deps);
208 }
209 }
210}
211
213 const bNodeTree &ntree)
214{
216 gather_geometry_nodes_eval_dependencies(ntree, deps, [](const bNodeTree &group) {
217 return group.runtime->geometry_nodes_eval_dependencies.get();
218 });
219 return deps;
220}
221
224{
225 if (deps_by_tree.contains(&ntree)) {
226 return;
227 }
229 gather_geometry_nodes_eval_dependencies(ntree, new_deps, [&](const bNodeTree &group) {
231 return &deps_by_tree.lookup(&group);
232 });
233 deps_by_tree.add(&ntree, std::move(new_deps));
234}
235
243
244} // namespace blender::nodes
#define BLI_assert(a)
Definition BLI_assert.h:46
ID and Library types, which are fundamental for SDNA.
@ ID_OB
@ SOCK_TEXTURE
@ SOCK_MATERIAL
@ SOCK_IMAGE
@ SOCK_COLLECTION
@ SOCK_OBJECT
@ GEO_NODE_TRANSFORM_SPACE_RELATIVE
Object is a sort of wrapper for general info.
ValueIterator values() const &
Definition BLI_map.hh:884
const Value & lookup(const Key &key) const
Definition BLI_map.hh:545
bool add(const Key &key, const Value &value)
Definition BLI_map.hh:295
const Value & lookup(const Key &key) const
Definition BLI_map.hh:545
bool contains(const Key &key) const
Definition BLI_map.hh:353
KDTree_3d * tree
#define GS(x)
TEX_TEMPLATE DataVec texture(T, FltCoord, float=0.0f) RET
GeometryNodesEvalDependencies gather_geometry_nodes_eval_dependencies_with_cache(const bNodeTree &ntree)
static void gather_geometry_nodes_eval_dependencies_recursive_impl(const bNodeTree &ntree, Map< const bNodeTree *, GeometryNodesEvalDependencies > &deps_by_tree)
static bool needs_scene_render_params(const bNodeTree &ntree)
static void add_eval_dependencies_from_socket(const bNodeSocket &socket, GeometryNodesEvalDependencies &deps)
static bool has_enabled_nodes_of_type(const bNodeTree &tree, const blender::StringRefNull type_idname)
static void add_own_transform_dependencies(const bNodeTree &tree, GeometryNodesEvalDependencies &deps)
static void gather_geometry_nodes_eval_dependencies(const bNodeTree &ntree, GeometryNodesEvalDependencies &deps, FunctionRef< const GeometryNodesEvalDependencies *(const bNodeTree &group)> get_group_deps)
GeometryNodesEvalDependencies gather_geometry_nodes_eval_dependencies_recursive(const bNodeTree &ntree)
static void add_eval_dependencies_from_node_data(const bNodeTree &tree, GeometryNodesEvalDependencies &deps)
Definition DNA_ID.h:414
char name[258]
Definition DNA_ID.h:432
unsigned int session_uid
Definition DNA_ID.h:462
struct Collection * value
void * default_value
bNodeTreeRuntimeHandle * runtime
void add_object(Object *object, const ObjectDependencyInfo &object_deps=all_object_deps)
void merge(const GeometryNodesEvalDependencies &other)