Blender V5.0
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
8
10
11#include <cstdio>
12
13#include "DNA_object_types.h"
14
15#include "BKE_action.hh"
16
20
21namespace blender::deg {
22
23/* *********** */
24/* Outer Nodes */
25
26/* -------------------------------------------------------------------- */
29
31{
32 const std::string codebuf = std::to_string(int(opcode));
33 return "OperationIDKey(" + codebuf + ", " + name + ")";
34}
35
44
45void ComponentNode::init(const ID * /*id*/, const char * /*subdata*/)
46{
47 /* hook up eval context? */
48 /* XXX: maybe this needs a special API? */
49}
50
51/* Free 'component' node */
57
58std::string ComponentNode::identifier() const
59{
60 const std::string type_name = type_get_factory(type)->type_name();
61 const std::string name_part = name[0] ? (std::string(" '") + name + "'") : "";
62
63 return "[" + type_name + "]" + name_part + " : " +
64 "(affects_visible_id: " + (affects_visible_id ? "true" : "false") + ")";
65}
66
68{
69 OperationNode *node = nullptr;
70 if (operations_map != nullptr) {
71 node = operations_map->lookup_default(key, nullptr);
72 }
73 else {
74 for (OperationNode *op_node : operations) {
75 if (op_node->opcode == key.opcode && op_node->name_tag == key.name_tag &&
76 op_node->name == key.name)
77 {
78 node = op_node;
79 break;
80 }
81 }
82 }
83 return node;
84}
85
87 const StringRef name,
88 int name_tag) const
89{
90 OperationIDKey key(opcode, name, name_tag);
91 return find_operation(key);
92}
93
95{
96 OperationNode *node = find_operation(key);
97 if (node == nullptr) {
98 fprintf(stderr,
99 "%s: find_operation(%s) failed\n",
100 this->identifier().c_str(),
101 key.identifier().c_str());
102 BLI_assert_msg(0, "Request for non-existing operation, should not happen");
103 return nullptr;
104 }
105 return node;
106}
107
109 const StringRef name,
110 int name_tag) const
111{
112 OperationIDKey key(opcode, name, name_tag);
113 return get_operation(key);
114}
115
117{
118 return find_operation(key) != nullptr;
119}
120
121bool ComponentNode::has_operation(OperationCode opcode, const StringRef name, int name_tag) const
122{
123 OperationIDKey key(opcode, name, name_tag);
124 return has_operation(key);
125}
126
128 OperationCode opcode,
129 const StringRef name,
130 int name_tag)
131{
132 OperationNode *op_node = find_operation(opcode, name, name_tag);
133 if (!op_node) {
135 op_node = (OperationNode *)factory->create_node(this->owner->id_orig, "", name);
136
137 /* register opnode in this component's operation set */
138 OperationIDKey key(opcode, op_node->name, name_tag);
139 operations_map->add(key, op_node);
140
141 /* Set back-link. */
142 op_node->owner = this;
143 }
144 else {
145 fprintf(stderr,
146 "add_operation: Operation already exists - %s has %s at %p\n",
147 this->identifier().c_str(),
148 op_node->identifier().c_str(),
149 op_node);
150 BLI_assert_msg(0, "Should not happen!");
151 }
152
153 /* attach extra data */
154 op_node->evaluate = op;
155 op_node->opcode = opcode;
156 op_node->name = name;
157 op_node->name_tag = name_tag;
158
159 return op_node;
160}
161
163{
164 BLI_assert(entry_operation == nullptr);
165 entry_operation = op_node;
166}
167
169{
170 BLI_assert(exit_operation == nullptr);
171 exit_operation = op_node;
172}
173
175{
176 if (operations_map != nullptr) {
177 for (OperationNode *op_node : operations_map->values()) {
178 delete op_node;
179 }
180 operations_map->clear();
181 }
182 for (OperationNode *op_node : operations) {
183 delete op_node;
184 }
185 operations.clear();
186}
187
189{
190 /* Note that the node might already be tagged for an update due invisible state of the node
191 * during previous dependency evaluation. Here the node gets re-tagged, so we need to give
192 * the evaluated clues that evaluation needs to happen again. */
193 for (OperationNode *op_node : operations) {
194 op_node->tag_update(graph, source);
195 }
196 /* It is possible that tag happens before finalization. */
197 if (operations_map != nullptr) {
198 for (OperationNode *op_node : operations_map->values()) {
199 op_node->tag_update(graph, source);
200 }
201 }
202}
203
205{
206 if (entry_operation) {
207 return entry_operation;
208 }
209 if (operations_map != nullptr && operations_map->size() == 1) {
210 OperationNode *op_node = nullptr;
211 /* TODO(sergey): This is somewhat slow. */
212 for (OperationNode *tmp : operations_map->values()) {
213 op_node = tmp;
214 }
215 /* Cache for the subsequent usage. */
216 entry_operation = op_node;
217 return op_node;
218 }
219 if (operations.size() == 1) {
220 return operations[0];
221 }
222 return nullptr;
223}
224
226{
227 if (exit_operation) {
228 return exit_operation;
229 }
230 if (operations_map != nullptr && operations_map->size() == 1) {
231 OperationNode *op_node = nullptr;
232 /* TODO(sergey): This is somewhat slow. */
233 for (OperationNode *tmp : operations_map->values()) {
234 op_node = tmp;
235 }
236 /* Cache for the subsequent usage. */
237 exit_operation = op_node;
238 return op_node;
239 }
240 if (operations.size() == 1) {
241 return operations[0];
242 }
243 return nullptr;
244}
245
247{
248 operations.reserve(operations_map->size());
249 for (OperationNode *op_node : operations_map->values()) {
250 operations.append(op_node);
251 }
252 delete operations_map;
253 operations_map = nullptr;
254}
255
257
258/* -------------------------------------------------------------------- */
261
262void BoneComponentNode::init(const ID *id, const char *subdata)
263{
264 /* generic component-node... */
265 ComponentNode::init(id, subdata);
266
267 /* name of component comes is bone name */
268 /* TODO(sergey): This sets name to an empty string because subdata is
269 * empty. Is it a bug? */
270 // this->name = subdata;
271
272 /* bone-specific node data */
273 Object *object = (Object *)id;
274 this->pchan = BKE_pose_channel_find_name(object->pose, subdata);
275}
276
278
279/* -------------------------------------------------------------------- */
282
284/* TODO(sergey): Is this a correct tag? */
311
313
314/* -------------------------------------------------------------------- */
317
319{
320 register_node_typeinfo(&DNTI_ANIMATION);
321 register_node_typeinfo(&DNTI_BONE);
322 register_node_typeinfo(&DNTI_CACHE);
323 register_node_typeinfo(&DNTI_BATCH_CACHE);
324 register_node_typeinfo(&DNTI_COPY_ON_EVAL);
325 register_node_typeinfo(&DNTI_GEOMETRY);
326 register_node_typeinfo(&DNTI_LAYER_COLLECTIONS);
327 register_node_typeinfo(&DNTI_PARAMETERS);
328 register_node_typeinfo(&DNTI_PARTICLE_SYSTEM);
329 register_node_typeinfo(&DNTI_PARTICLE_SETTINGS);
330 register_node_typeinfo(&DNTI_POINT_CACHE);
331 register_node_typeinfo(&DNTI_IMAGE_ANIMATION);
332 register_node_typeinfo(&DNTI_EVAL_POSE);
333 register_node_typeinfo(&DNTI_SEQUENCER);
334 register_node_typeinfo(&DNTI_SHADING);
335 register_node_typeinfo(&DNTI_TRANSFORM);
336 register_node_typeinfo(&DNTI_OBJECT_FROM_LAYER);
337 register_node_typeinfo(&DNTI_HIERARCHY);
338 register_node_typeinfo(&DNTI_INSTANCING);
339 register_node_typeinfo(&DNTI_SYNCHRONIZATION);
340 register_node_typeinfo(&DNTI_AUDIO);
341 register_node_typeinfo(&DNTI_ARMATURE);
342 register_node_typeinfo(&DNTI_GENERIC_DATABLOCK);
343 register_node_typeinfo(&DNTI_SCENE);
344 register_node_typeinfo(&DNTI_VISIBILITY);
345 register_node_typeinfo(&DNTI_NTREE_OUTPUT);
346 register_node_typeinfo(&DNTI_NTREE_GEOMETRY_PREPROCESS);
347}
348
350
351} // 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:46
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
@ ID_RECALC_PARAMETERS
Definition DNA_ID.h:1138
@ ID_RECALC_TRANSFORM
Definition DNA_ID.h:1054
@ ID_RECALC_SHADING
Definition DNA_ID.h:1094
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1118
@ ID_RECALC_NTREE_OUTPUT
Definition DNA_ID.h:1155
@ ID_RECALC_ANIMATION
Definition DNA_ID.h:1077
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1074
Object is a sort of wrapper for general info.
#define DEG_COMPONENT_NODE_DEFINE(name, NAME, id_recalc_tag)
void register_node_typeinfo(DepsNodeFactory *factory)
void deg_register_component_depsnodes()
DepsNodeFactory * type_get_factory(const NodeType type)
std::function< void(::Depsgraph *)> DepsEvalOperationCb
Definition DNA_ID.h:414
struct bPose * pose
void init(const ID *id, const char *subdata) override
OperationNode * get_entry_operation() override
std::string identifier() const override
OperationNode * get_operation(OperationIDKey key) const
void init(const ID *id, const char *subdata) override
void tag_update(Depsgraph *graph, eUpdateSource source) override
Vector< OperationNode * > operations
OperationNode * find_operation(OperationIDKey key) const
OperationNode * add_operation(const DepsEvalOperationCb &op, OperationCode opcode, const StringRef name="", int name_tag=-1)
OperationNode * get_exit_operation() override
bool has_operation(OperationIDKey key) const
void set_exit_operation(OperationNode *op_node)
void finalize_build(Depsgraph *graph)
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, StringRef name) const =0
std::string name
Definition deg_node.hh:180
std::string identifier() const override