Blender V4.3
deg_node_component.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2013 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
10
11#include <cstdio>
12#include <cstring> /* required for STREQ later on. */
13
14#include "BLI_ghash.h"
15#include "BLI_hash.hh"
16#include "BLI_utildefines.h"
17
18#include "DNA_object_types.h"
19
20#include "BKE_action.hh"
21
25
26namespace blender::deg {
27
28/* *********** */
29/* Outer Nodes */
30
31/* -------------------------------------------------------------------- */
36 : opcode(OperationCode::OPERATION), name(""), name_tag(-1)
37{
38}
39
41 : opcode(opcode), name(""), name_tag(-1)
42{
43}
44
45ComponentNode::OperationIDKey::OperationIDKey(OperationCode opcode, const char *name, int name_tag)
46 : opcode(opcode), name(name), name_tag(name_tag)
47{
48}
49
51{
52 const string codebuf = to_string(int(opcode));
53 return "OperationIDKey(" + codebuf + ", " + name + ")";
54}
55
57{
58 return (opcode == other.opcode) && STREQ(name, other.name) && (name_tag == other.name_tag);
59}
60
62{
63 const int opcode_as_int = int(opcode);
65 name_tag,
68}
69
78
79void ComponentNode::init(const ID * /*id*/, const char * /*subdata*/)
80{
81 /* hook up eval context? */
82 /* XXX: maybe this needs a special API? */
83}
84
85/* Free 'component' node */
91
93{
94 const string type_name = type_get_factory(type)->type_name();
95 const string name_part = name[0] ? (string(" '") + name + "'") : "";
96
97 return "[" + type_name + "]" + name_part + " : " +
98 "(affects_visible_id: " + (affects_visible_id ? "true" : "false") + ")";
99}
100
102{
103 OperationNode *node = nullptr;
104 if (operations_map != nullptr) {
105 node = operations_map->lookup_default(key, nullptr);
106 }
107 else {
108 for (OperationNode *op_node : operations) {
109 if (op_node->opcode == key.opcode && op_node->name_tag == key.name_tag &&
110 STREQ(op_node->name.c_str(), key.name))
111 {
112 node = op_node;
113 break;
114 }
115 }
116 }
117 return node;
118}
119
121 const char *name,
122 int name_tag) const
123{
124 OperationIDKey key(opcode, name, name_tag);
125 return find_operation(key);
126}
127
129{
130 OperationNode *node = find_operation(key);
131 if (node == nullptr) {
132 fprintf(stderr,
133 "%s: find_operation(%s) failed\n",
134 this->identifier().c_str(),
135 key.identifier().c_str());
136 BLI_assert_msg(0, "Request for non-existing operation, should not happen");
137 return nullptr;
138 }
139 return node;
140}
141
143 const char *name,
144 int name_tag) const
145{
146 OperationIDKey key(opcode, name, name_tag);
147 return get_operation(key);
148}
149
151{
152 return find_operation(key) != nullptr;
153}
154
155bool ComponentNode::has_operation(OperationCode opcode, const char *name, int name_tag) const
156{
157 OperationIDKey key(opcode, name, name_tag);
158 return has_operation(key);
159}
160
162 OperationCode opcode,
163 const char *name,
164 int name_tag)
165{
166 OperationNode *op_node = find_operation(opcode, name, name_tag);
167 if (!op_node) {
169 op_node = (OperationNode *)factory->create_node(this->owner->id_orig, "", name);
170
171 /* register opnode in this component's operation set */
172 OperationIDKey key(opcode, op_node->name.c_str(), name_tag);
173 operations_map->add(key, op_node);
174
175 /* Set back-link. */
176 op_node->owner = this;
177 }
178 else {
179 fprintf(stderr,
180 "add_operation: Operation already exists - %s has %s at %p\n",
181 this->identifier().c_str(),
182 op_node->identifier().c_str(),
183 op_node);
184 BLI_assert_msg(0, "Should not happen!");
185 }
186
187 /* attach extra data */
188 op_node->evaluate = op;
189 op_node->opcode = opcode;
190 op_node->name = name;
191 op_node->name_tag = name_tag;
192
193 return op_node;
194}
195
197{
198 BLI_assert(entry_operation == nullptr);
199 entry_operation = op_node;
200}
201
203{
204 BLI_assert(exit_operation == nullptr);
205 exit_operation = op_node;
206}
207
209{
210 if (operations_map != nullptr) {
211 for (OperationNode *op_node : operations_map->values()) {
212 delete op_node;
213 }
214 operations_map->clear();
215 }
216 for (OperationNode *op_node : operations) {
217 delete op_node;
218 }
219 operations.clear();
220}
221
223{
224 /* Note that the node might already be tagged for an update due invisible state of the node
225 * during previous dependency evaluation. Here the node gets re-tagged, so we need to give
226 * the evaluated clues that evaluation needs to happen again. */
227 for (OperationNode *op_node : operations) {
228 op_node->tag_update(graph, source);
229 }
230 /* It is possible that tag happens before finalization. */
231 if (operations_map != nullptr) {
232 for (OperationNode *op_node : operations_map->values()) {
233 op_node->tag_update(graph, source);
234 }
235 }
236}
237
239{
240 if (entry_operation) {
241 return entry_operation;
242 }
243 if (operations_map != nullptr && operations_map->size() == 1) {
244 OperationNode *op_node = nullptr;
245 /* TODO(sergey): This is somewhat slow. */
246 for (OperationNode *tmp : operations_map->values()) {
247 op_node = tmp;
248 }
249 /* Cache for the subsequent usage. */
250 entry_operation = op_node;
251 return op_node;
252 }
253 if (operations.size() == 1) {
254 return operations[0];
255 }
256 return nullptr;
257}
258
260{
261 if (exit_operation) {
262 return exit_operation;
263 }
264 if (operations_map != nullptr && operations_map->size() == 1) {
265 OperationNode *op_node = nullptr;
266 /* TODO(sergey): This is somewhat slow. */
267 for (OperationNode *tmp : operations_map->values()) {
268 op_node = tmp;
269 }
270 /* Cache for the subsequent usage. */
271 exit_operation = op_node;
272 return op_node;
273 }
274 if (operations.size() == 1) {
275 return operations[0];
276 }
277 return nullptr;
278}
279
281{
282 operations.reserve(operations_map->size());
283 for (OperationNode *op_node : operations_map->values()) {
284 operations.append(op_node);
285 }
286 delete operations_map;
287 operations_map = nullptr;
288}
289
292/* -------------------------------------------------------------------- */
296void BoneComponentNode::init(const ID *id, const char *subdata)
297{
298 /* generic component-node... */
299 ComponentNode::init(id, subdata);
300
301 /* name of component comes is bone name */
302 /* TODO(sergey): This sets name to an empty string because subdata is
303 * empty. Is it a bug? */
304 // this->name = subdata;
305
306 /* bone-specific node data */
307 Object *object = (Object *)id;
308 this->pchan = BKE_pose_channel_find_name(object->pose, subdata);
309}
310
313/* -------------------------------------------------------------------- */
318/* TODO(sergey): Is this a correct tag? */
345
348/* -------------------------------------------------------------------- */
353{
354 register_node_typeinfo(&DNTI_ANIMATION);
355 register_node_typeinfo(&DNTI_BONE);
356 register_node_typeinfo(&DNTI_CACHE);
357 register_node_typeinfo(&DNTI_BATCH_CACHE);
358 register_node_typeinfo(&DNTI_COPY_ON_EVAL);
359 register_node_typeinfo(&DNTI_GEOMETRY);
360 register_node_typeinfo(&DNTI_LAYER_COLLECTIONS);
361 register_node_typeinfo(&DNTI_PARAMETERS);
362 register_node_typeinfo(&DNTI_PARTICLE_SYSTEM);
363 register_node_typeinfo(&DNTI_PARTICLE_SETTINGS);
364 register_node_typeinfo(&DNTI_POINT_CACHE);
365 register_node_typeinfo(&DNTI_IMAGE_ANIMATION);
366 register_node_typeinfo(&DNTI_EVAL_POSE);
367 register_node_typeinfo(&DNTI_SEQUENCER);
368 register_node_typeinfo(&DNTI_SHADING);
369 register_node_typeinfo(&DNTI_TRANSFORM);
370 register_node_typeinfo(&DNTI_OBJECT_FROM_LAYER);
371 register_node_typeinfo(&DNTI_HIERARCHY);
372 register_node_typeinfo(&DNTI_INSTANCING);
373 register_node_typeinfo(&DNTI_SYNCHRONIZATION);
374 register_node_typeinfo(&DNTI_AUDIO);
375 register_node_typeinfo(&DNTI_ARMATURE);
376 register_node_typeinfo(&DNTI_GENERIC_DATABLOCK);
377 register_node_typeinfo(&DNTI_SCENE);
378 register_node_typeinfo(&DNTI_VISIBILITY);
379 register_node_typeinfo(&DNTI_NTREE_OUTPUT);
380 register_node_typeinfo(&DNTI_NTREE_GEOMETRY_PREPROCESS);
381}
382
385} // namespace blender::deg
Blender kernel action and pose functionality.
bPoseChannel * BKE_pose_channel_find_name(const bPose *pose, const char *name)
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:57
size_t BLI_ghashutil_combine_hash(size_t hash_a, size_t hash_b)
unsigned int BLI_ghashutil_uinthash(unsigned int key)
unsigned int BLI_ghashutil_strhash_p(const void *ptr)
#define STREQ(a, b)
@ ID_RECALC_PARAMETERS
Definition DNA_ID.h:1105
@ ID_RECALC_TRANSFORM
Definition DNA_ID.h:1021
@ ID_RECALC_SHADING
Definition DNA_ID.h:1061
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1085
@ ID_RECALC_NTREE_OUTPUT
Definition DNA_ID.h:1122
@ ID_RECALC_ANIMATION
Definition DNA_ID.h:1044
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1041
Object is a sort of wrapper for general info.
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Map
OperationNode * node
#define DEG_COMPONENT_NODE_DEFINE(name, NAME, id_recalc_tag)
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
static const char * to_string(const Interpolation &interp)
Definition gl_shader.cc:82
void register_node_typeinfo(DepsNodeFactory *factory)
void deg_register_component_depsnodes()
function< void(::Depsgraph *)> DepsEvalOperationCb
DepsNodeFactory * type_get_factory(const NodeType type)
unsigned __int64 uint64_t
Definition stdint.h:90
Definition DNA_ID.h:413
struct bPose * pose
void init(const ID *id, const char *subdata)
bool operator==(const OperationIDKey &other) const
virtual OperationNode * get_entry_operation() override
OperationNode * get_operation(OperationIDKey key) const
void init(const ID *id, const char *subdata) override
virtual void tag_update(Depsgraph *graph, eUpdateSource source) override
Vector< OperationNode * > operations
OperationNode * find_operation(OperationIDKey key) const
virtual OperationNode * get_exit_operation() override
OperationNode * add_operation(const DepsEvalOperationCb &op, OperationCode opcode, const char *name="", int name_tag=-1)
bool has_operation(OperationIDKey key) const
void set_exit_operation(OperationNode *op_node)
void finalize_build(Depsgraph *graph)
virtual string identifier() const override
Map< ComponentNode::OperationIDKey, OperationNode * > * operations_map
void set_entry_operation(OperationNode *op_node)
virtual const char * type_name() const =0
virtual Node * create_node(const ID *id, const char *subdata, const char *name) const =0
virtual void tag_update(Depsgraph *graph, eUpdateSource source) override
virtual string identifier() const override