Blender V4.3
depsgraph_tag.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
12
13#include <cstdio>
14#include <cstring> /* required for memset */
15#include <queue>
16
17#include "BLI_index_range.hh"
18#include "BLI_math_bits.h"
19#include "BLI_task.h"
20#include "BLI_utildefines.h"
21
22#include "DNA_anim_types.h"
23#include "DNA_curve_types.h"
24#include "DNA_key_types.h"
25#include "DNA_lattice_types.h"
26#include "DNA_mesh_types.h"
27#include "DNA_object_types.h"
28#include "DNA_particle_types.h"
29#include "DNA_screen_types.h"
31
32#include "BKE_anim_data.hh"
33#include "BKE_global.hh"
34#include "BKE_idtype.hh"
35#include "BKE_lib_override.hh"
36#include "BKE_node.hh"
37#include "BKE_scene.hh"
38#include "BKE_screen.hh"
39#include "BKE_workspace.hh"
40
41#include "DEG_depsgraph.hh"
44
46#include "intern/depsgraph.hh"
57
58namespace deg = blender::deg;
59
60/* *********************** */
61/* Update Tagging/Flushing */
62
63namespace blender::deg {
64
65namespace {
66
67void depsgraph_geometry_tag_to_component(const ID *id, NodeType *component_type)
68{
69 const NodeType result = geometry_tag_to_component(id);
70 if (result != NodeType::UNDEFINED) {
71 *component_type = result;
72 }
73}
74
75bool is_selectable_data_id_type(const ID_Type id_type)
76{
78}
79
80void depsgraph_select_tag_to_component_opcode(const ID *id,
81 NodeType *component_type,
82 OperationCode *operation_code)
83{
84 const ID_Type id_type = GS(id->name);
85 if (id_type == ID_SCE) {
86 /* We need to flush base flags to all objects in a scene since we
87 * don't know which ones changed. However, we don't want to update
88 * the whole scene, so pick up some operation which will do as less
89 * as possible.
90 *
91 * TODO(sergey): We can introduce explicit exit operation which
92 * does nothing and which is only used to cascade flush down the
93 * road. */
94 *component_type = NodeType::LAYER_COLLECTIONS;
95 *operation_code = OperationCode::VIEW_LAYER_EVAL;
96 }
97 else if (id_type == ID_OB) {
98 *component_type = NodeType::OBJECT_FROM_LAYER;
100 }
101 else if (is_selectable_data_id_type(id_type)) {
102 *component_type = NodeType::BATCH_CACHE;
104 }
105 else {
106 *component_type = NodeType::COPY_ON_EVAL;
107 *operation_code = OperationCode::COPY_ON_EVAL;
108 }
109}
110
111void depsgraph_base_flags_tag_to_component_opcode(const ID *id,
112 NodeType *component_type,
113 OperationCode *operation_code)
114{
115 const ID_Type id_type = GS(id->name);
116 if (id_type == ID_SCE) {
117 *component_type = NodeType::LAYER_COLLECTIONS;
118 *operation_code = OperationCode::VIEW_LAYER_EVAL;
119 }
120 else if (id_type == ID_OB) {
121 *component_type = NodeType::OBJECT_FROM_LAYER;
122 *operation_code = OperationCode::OBJECT_BASE_FLAGS;
123 }
124}
125
126OperationCode psysTagToOperationCode(IDRecalcFlag tag)
127{
128 if (tag == ID_RECALC_PSYS_RESET) {
130 }
132}
133
134void depsgraph_tag_to_component_opcode(const ID *id,
135 IDRecalcFlag tag,
136 NodeType *component_type,
137 OperationCode *operation_code)
138{
139 const ID_Type id_type = GS(id->name);
140 *component_type = NodeType::UNDEFINED;
141 *operation_code = OperationCode::OPERATION;
142 /* Special case for now, in the future we should get rid of this. */
143 if (tag == 0) {
144 *component_type = NodeType::ID_REF;
145 *operation_code = OperationCode::OPERATION;
146 return;
147 }
148 switch (tag) {
150 *component_type = NodeType::TRANSFORM;
151 break;
153 depsgraph_geometry_tag_to_component(id, component_type);
154 break;
156 *component_type = NodeType::ANIMATION;
157 break;
162 if (id_type == ID_PA) {
163 /* NOTES:
164 * - For particle settings node we need to use different
165 * component. Will be nice to get this unified with object,
166 * but we can survive for now with single exception here.
167 * Particles needs reconsideration anyway, */
168 *component_type = NodeType::PARTICLE_SETTINGS;
169 *operation_code = psysTagToOperationCode(tag);
170 }
171 else {
172 *component_type = NodeType::PARTICLE_SYSTEM;
173 }
174 break;
176 *component_type = NodeType::COPY_ON_EVAL;
177 break;
179 *component_type = NodeType::SHADING;
180 break;
181 case ID_RECALC_SELECT:
182 depsgraph_select_tag_to_component_opcode(id, component_type, operation_code);
183 break;
185 depsgraph_base_flags_tag_to_component_opcode(id, component_type, operation_code);
186 break;
188 *component_type = NodeType::POINT_CACHE;
189 break;
191 /* There is no such node in depsgraph, this tag is to be handled
192 * separately. */
193 break;
195 *component_type = NodeType::SEQUENCER;
196 break;
202 case ID_RECALC_AUDIO:
203 *component_type = NodeType::AUDIO;
204 break;
206 *component_type = NodeType::PARAMETERS;
207 break;
208 case ID_RECALC_SOURCE:
209 *component_type = NodeType::PARAMETERS;
210 break;
212 case ID_RECALC_ALL:
214 BLI_assert_msg(0, "Should not happen");
215 break;
217 break; /* Must be ignored by depsgraph. */
219 *component_type = NodeType::NTREE_OUTPUT;
220 *operation_code = OperationCode::NTREE_OUTPUT;
221 break;
222
224 *component_type = NodeType::HIERARCHY;
225 *operation_code = OperationCode::HIERARCHY;
226 break;
227
233 /* Silently ignore.
234 * The bits might be passed here from ID_RECALC_ALL. This is not a code-mistake, but just the
235 * way how the recalc flags are handled. */
236 break;
237 }
238}
239
240void id_tag_update_ntree_special(
241 Main *bmain, Depsgraph *graph, ID *id, uint flags, eUpdateSource update_source)
242{
244 if (ntree == nullptr) {
245 return;
246 }
247 graph_id_tag_update(bmain, graph, &ntree->id, flags, update_source);
248}
249
250void depsgraph_update_editors_tag(Main *bmain, Depsgraph *graph, ID *id)
251{
252 /* NOTE: We handle this immediately, without delaying anything, to be
253 * sure we don't cause threading issues with OpenGL. */
254 /* TODO(sergey): Make sure this works for evaluated data-blocks as well. */
255 DEGEditorUpdateContext update_ctx = {nullptr};
256 update_ctx.bmain = bmain;
257 update_ctx.depsgraph = (::Depsgraph *)graph;
258 update_ctx.scene = graph->scene;
259 update_ctx.view_layer = graph->view_layer;
260 deg_editors_id_update(&update_ctx, id);
261}
262
263void depsgraph_id_tag_copy_on_write(Depsgraph *graph, IDNode *id_node, eUpdateSource update_source)
264{
265 ComponentNode *cow_comp = id_node->find_component(NodeType::COPY_ON_EVAL);
266 if (cow_comp == nullptr) {
268 return;
269 }
270 cow_comp->tag_update(graph, update_source);
271}
272
273void depsgraph_tag_component(Depsgraph *graph,
274 IDNode *id_node,
275 NodeType component_type,
276 OperationCode operation_code,
277 eUpdateSource update_source)
278{
279 ComponentNode *component_node = id_node->find_component(component_type);
280 /* NOTE: Animation component might not be existing yet (which happens when adding new driver or
281 * adding a new keyframe), so the required copy-on-evaluation tag needs to be taken care
282 * explicitly here. */
283 if (component_node == nullptr) {
284 if (component_type == NodeType::ANIMATION) {
286 depsgraph_id_tag_copy_on_write(graph, id_node, update_source);
287 }
288 return;
289 }
290 if (operation_code == OperationCode::OPERATION) {
291 component_node->tag_update(graph, update_source);
292 }
293 else {
294 OperationNode *operation_node = component_node->find_operation(operation_code);
295 if (operation_node != nullptr) {
296 operation_node->tag_update(graph, update_source);
297 }
298 }
299 /* If component depends on copy-on-evaluation, tag it as well. */
300 if (component_node->need_tag_cow_before_update(IDRecalcFlag(id_node->id_cow->recalc))) {
301 depsgraph_id_tag_copy_on_write(graph, id_node, update_source);
302 }
303 if (component_type == NodeType::COPY_ON_EVAL) {
305 }
306}
307
308/* This is a tag compatibility with legacy code.
309 *
310 * Mainly, old code was tagging object with ID_RECALC_GEOMETRY tag to inform
311 * that object's data data-block changed. Now API expects that ID is given
312 * explicitly, but not all areas are aware of this yet. */
313void deg_graph_id_tag_legacy_compat(
314 Main *bmain, Depsgraph *depsgraph, ID *id, IDRecalcFlag tag, eUpdateSource update_source)
315{
316 if (ELEM(tag, ID_RECALC_GEOMETRY, 0)) {
317 switch (GS(id->name)) {
318 case ID_OB: {
319 Object *object = (Object *)id;
320 ID *data_id = (ID *)object->data;
321 if (data_id != nullptr) {
322 graph_id_tag_update(bmain, depsgraph, data_id, 0, update_source);
323 }
324 break;
325 }
326 /* TODO(sergey): Shape keys are annoying, maybe we should find a
327 * way to chain geometry evaluation to them, so we don't need extra
328 * tagging here. */
329 case ID_ME: {
330 Mesh *mesh = (Mesh *)id;
331 if (mesh->key != nullptr) {
332 ID *key_id = &mesh->key->id;
333 if (key_id != nullptr) {
334 graph_id_tag_update(bmain, depsgraph, key_id, 0, update_source);
335 }
336 }
337 break;
338 }
339 case ID_LT: {
340 Lattice *lattice = (Lattice *)id;
341 if (lattice->key != nullptr) {
342 ID *key_id = &lattice->key->id;
343 if (key_id != nullptr) {
344 graph_id_tag_update(bmain, depsgraph, key_id, 0, update_source);
345 }
346 }
347 break;
348 }
349 case ID_CU_LEGACY: {
350 Curve *curve = (Curve *)id;
351 if (curve->key != nullptr) {
352 ID *key_id = &curve->key->id;
353 if (key_id != nullptr) {
354 graph_id_tag_update(bmain, depsgraph, key_id, 0, update_source);
355 }
356 }
357 break;
358 }
359 default:
360 break;
361 }
362 }
363}
364
365void graph_id_tag_update_single_flag(Main *bmain,
366 Depsgraph *graph,
367 ID *id,
368 IDNode *id_node,
369 IDRecalcFlag tag,
370 eUpdateSource update_source)
371{
372 if (tag == ID_RECALC_EDITORS) {
373 if (graph != nullptr && graph->is_active) {
374 depsgraph_update_editors_tag(bmain, graph, id);
375 }
376 return;
377 }
378 /* Get description of what is to be tagged. */
379 NodeType component_type;
380 OperationCode operation_code;
381 depsgraph_tag_to_component_opcode(id, tag, &component_type, &operation_code);
382 /* Check whether we've got something to tag. */
383 if (component_type == NodeType::UNDEFINED) {
384 /* Given ID does not support tag. */
385 /* TODO(sergey): Shall we raise some panic here? */
386 return;
387 }
388 /* Some sanity checks before moving forward. */
389 if (id_node == nullptr) {
390 /* Happens when object is tagged for update and not yet in the
391 * dependency graph (but will be after relations update). */
392 return;
393 }
394 /* Tag ID recalc flag. */
395 DepsNodeFactory *factory = type_get_factory(component_type);
396 BLI_assert(factory != nullptr);
397 id_node->id_cow->recalc |= factory->id_recalc_tag();
398 /* Tag corresponding dependency graph operation for update. */
399 if (component_type == NodeType::ID_REF) {
400 id_node->tag_update(graph, update_source);
401 }
402 else {
403 depsgraph_tag_component(graph, id_node, component_type, operation_code, update_source);
404 }
405 /* TODO(sergey): Get rid of this once all areas are using proper data ID
406 * for tagging. */
407 deg_graph_id_tag_legacy_compat(bmain, graph, id, tag, update_source);
408}
409
410string stringify_append_bit(const string &str, IDRecalcFlag tag)
411{
412 const char *tag_name = DEG_update_tag_as_string(tag);
413 if (tag_name == nullptr) {
414 return str;
415 }
416 string result = str;
417 if (!result.empty()) {
418 result += ", ";
419 }
420 result += tag_name;
421 return result;
422}
423
424string stringify_update_bitfield(uint flags)
425{
426 if (flags == 0) {
427 return "LEGACY_0";
428 }
429 string result;
430 uint current_flag = flags;
431 /* Special cases to avoid ALL flags form being split into
432 * individual bits. */
433 if ((current_flag & ID_RECALC_PSYS_ALL) == ID_RECALC_PSYS_ALL) {
434 result = stringify_append_bit(result, ID_RECALC_PSYS_ALL);
435 }
436 /* Handle all the rest of the flags. */
437 while (current_flag != 0) {
438 IDRecalcFlag tag = (IDRecalcFlag)(1 << bitscan_forward_clear_uint(&current_flag));
439 result = stringify_append_bit(result, tag);
440 }
441 return result;
442}
443
444const char *update_source_as_string(eUpdateSource source)
445{
446 switch (source) {
448 return "TIME";
450 return "USER_EDIT";
452 return "RELATIONS";
454 return "VISIBILITY";
456 return "SIDE_EFFECT_REQUEST";
457 }
458 BLI_assert_msg(0, "Should never happen.");
459 return "UNKNOWN";
460}
461
462int deg_recalc_flags_for_legacy_zero()
463{
466}
467
468int deg_recalc_flags_effective(Depsgraph *graph, uint flags)
469{
470 if (graph != nullptr) {
471 if (!graph->is_active) {
472 return 0;
473 }
474 }
475 if (flags == 0) {
476 return deg_recalc_flags_for_legacy_zero();
477 }
478 return flags;
479}
480
481/* Special tag function which tags all components which needs to be tagged
482 * for update flag=0.
483 *
484 * TODO(sergey): This is something to be avoid in the future, make it more
485 * explicit and granular for users to tag what they really need. */
486void deg_graph_node_tag_zero(Main *bmain,
487 Depsgraph *graph,
488 IDNode *id_node,
489 eUpdateSource update_source)
490{
491 if (id_node == nullptr) {
492 return;
493 }
494 ID *id = id_node->id_orig;
495 /* TODO(sergey): Which recalc flags to set here? */
496 id_node->id_cow->recalc |= deg_recalc_flags_for_legacy_zero();
497
498 for (ComponentNode *comp_node : id_node->components.values()) {
499 if (comp_node->type == NodeType::ANIMATION) {
500 continue;
501 }
502 if (comp_node->type == NodeType::COPY_ON_EVAL) {
504 }
505
506 comp_node->tag_update(graph, update_source);
507 }
508 deg_graph_id_tag_legacy_compat(bmain, graph, id, (IDRecalcFlag)0, update_source);
509}
510
511/* Implicit tagging of the parameters component on other changes.
512 *
513 * This takes care of ensuring that if a change made in C side on parameters which affect,
514 * say, geometry and explicit tag only done for geometry, parameters are also tagged to give
515 * drivers a chance to re-evaluate for the new values. */
516void deg_graph_tag_parameters_if_needed(Main *bmain,
517 Depsgraph *graph,
518 ID *id,
519 IDNode *id_node,
520 const uint flags,
521 const eUpdateSource update_source)
522{
523 if (flags == 0) {
524 /* Tagging for 0 flags is handled in deg_graph_node_tag_zero(), and parameters are handled
525 * there as well. */
526 return;
527 }
528
529 if (flags & ID_RECALC_PARAMETERS) {
530 /* Parameters are already tagged for update explicitly, no need to run extra logic here. */
531 return;
532 }
533
534 /* Clear flags which are known to not affect parameters usable by drivers. */
535 const uint clean_flags = flags &
538 /* While drivers may use the current-frame, this value is assigned
539 * explicitly and doesn't require a the scene to be copied again. */
541
542 if (clean_flags == 0) {
543 /* Changes are limited to only things which are not usable by drivers. */
544 return;
545 }
546
547 graph_id_tag_update_single_flag(bmain, graph, id, id_node, ID_RECALC_PARAMETERS, update_source);
548}
549
550void graph_tag_on_visible_update(Depsgraph *graph, const bool do_time)
551{
552 graph->need_tag_id_on_graph_visibility_update = true;
553 graph->need_tag_id_on_graph_visibility_time_update |= do_time;
554}
555
556} /* namespace */
557
559{
560 if (!graph->need_tag_id_on_graph_visibility_update) {
561 return;
562 }
563
564 const bool do_time = graph->need_tag_id_on_graph_visibility_time_update;
565 Main *bmain = graph->bmain;
566
567 /* NOTE: It is possible to have this function called with `do_time=false` first and later (prior
568 * to evaluation though) with `do_time=true`. This means early output checks should be aware of
569 * this. */
570 for (deg::IDNode *id_node : graph->id_nodes) {
571 const ID_Type id_type = GS(id_node->id_orig->name);
572
574 /* ID has no components which affects anything visible.
575 * No need bother with it to tag or anything. */
576 continue;
577 }
578 uint flags = 0;
580 flags |= ID_RECALC_SYNC_TO_EVAL;
581 if (do_time) {
582 if (BKE_animdata_from_id(id_node->id_orig) != nullptr) {
583 flags |= ID_RECALC_ANIMATION;
584 }
585 }
586 }
587 else {
589 /* The ID was already visible and evaluated, all the subsequent
590 * updates and tags are to be done explicitly. */
591 continue;
592 }
593 }
594 /* We only tag components which needs an update. Tagging everything is
595 * not a good idea because that might reset particles cache (or any
596 * other type of cache).
597 *
598 * TODO(sergey): Need to generalize this somehow. */
599 if (id_type == ID_OB) {
601 }
602 /* For non-copy-on-eval datablocks like images, there is no need to update when
603 * they just got added to the depsgraph and there is no flag indicating
604 * a specific change that was made to them. Unlike evaluated datablocks which
605 * have just been copied.
606 * This helps preserve cached image draw data for the compositor. */
607 if (ID_TYPE_USE_COPY_ON_EVAL(id_type) || flags != 0) {
609 }
610 if (id_type == ID_SCE) {
611 /* Make sure collection properties are up to date. */
613 }
614 /* Now when ID is updated to the new visibility state, prevent it from
615 * being re-tagged again. Simplest way to do so is to pretend that it
616 * was already updated by the "previous" dependency graph.
617 *
618 * NOTE: Even if the on_visible_update() is called from the state when
619 * dependency graph is tagged for relations update, it will be fine:
620 * since dependency graph builder re-schedules entry tags, all the
621 * tags we request from here will be applied in the updated state of
622 * dependency graph. */
624 }
625
626 graph->need_tag_id_on_graph_visibility_update = false;
627 graph->need_tag_id_on_graph_visibility_time_update = false;
628}
629
631{
632 const ID_Type id_type = GS(id->name);
633 switch (id_type) {
634 case ID_OB: {
635 const Object *object = (Object *)id;
636 switch (object->type) {
637 case OB_MESH:
638 case OB_CURVES_LEGACY:
639 case OB_SURF:
640 case OB_FONT:
641 case OB_LATTICE:
642 case OB_MBALL:
644 case OB_CURVES:
645 case OB_POINTCLOUD:
646 case OB_VOLUME:
647 case OB_GREASE_PENCIL:
648 return NodeType::GEOMETRY;
649 case OB_ARMATURE:
650 return NodeType::EVAL_POSE;
651 /* TODO(sergey): More cases here? */
652 }
653 break;
654 }
655 case ID_ME:
656 case ID_CU_LEGACY:
657 case ID_LT:
658 case ID_MB:
659 case ID_CV:
660 case ID_PT:
661 case ID_VO:
662 case ID_GR:
663 return NodeType::GEOMETRY;
664 case ID_PA: /* Particles */
665 return NodeType::UNDEFINED;
666 case ID_LP:
668 case ID_GD_LEGACY:
669 return NodeType::GEOMETRY;
670 case ID_PAL: /* Palettes */
672 case ID_MSK:
674 case ID_GP:
675 return NodeType::GEOMETRY;
676 default:
677 break;
678 }
679 return NodeType::UNDEFINED;
680}
681
682void id_tag_update(Main *bmain, ID *id, uint flags, eUpdateSource update_source)
683{
684 graph_id_tag_update(bmain, nullptr, id, flags, update_source);
686 graph_id_tag_update(bmain, depsgraph, id, flags, update_source);
687 }
688
689 if (update_source & DEG_UPDATE_SOURCE_USER_EDIT) {
691 }
692
693 /* Accumulate all tags for an ID between two undo steps, so they can be
694 * replayed for undo. */
695 id->recalc_after_undo_push |= deg_recalc_flags_effective(nullptr, flags);
696}
697
699 Main *bmain, Depsgraph *graph, ID *id, uint flags, eUpdateSource update_source)
700{
701 const int debug_flags = (graph != nullptr) ? DEG_debug_flags_get((::Depsgraph *)graph) : G.debug;
702 if (graph != nullptr && graph->is_evaluating) {
703 if (debug_flags & G_DEBUG_DEPSGRAPH_TAG) {
704 printf("ID tagged for update during dependency graph evaluation.\n");
705 }
706 return;
707 }
708 if (debug_flags & G_DEBUG_DEPSGRAPH_TAG) {
709 printf("%s: id=%s flags=%s source=%s\n",
710 __func__,
711 id->name,
712 stringify_update_bitfield(flags).c_str(),
713 update_source_as_string(update_source));
714 }
715 IDNode *id_node = (graph != nullptr) ? graph->find_id_node(id) : nullptr;
716 if (graph != nullptr) {
717 DEG_graph_id_type_tag(reinterpret_cast<::Depsgraph *>(graph), GS(id->name));
718 }
719 if (flags == 0) {
720 deg_graph_node_tag_zero(bmain, graph, id_node, update_source);
721 }
722 /* Store original flag in the ID.
723 * Allows to have more granularity than a node-factory based flags. */
724 if (id_node != nullptr) {
725 id_node->id_cow->recalc |= flags;
726 }
727 /* When ID is tagged for update based on an user edits store the recalc flags in the original ID.
728 * This way IDs in the undo steps will have this flag preserved, making it possible to restore
729 * all needed tags when new dependency graph is created on redo.
730 * This is the only way to ensure modifications to animation data (such as keyframes i.e.)
731 * properly triggers animation update for the newly constructed dependency graph on redo (while
732 * usually newly created dependency graph skips animation update to avoid loss of unkeyed
733 * changes). */
734 if (update_source == DEG_UPDATE_SOURCE_USER_EDIT) {
735 id->recalc |= deg_recalc_flags_effective(graph, flags);
736 }
737 uint current_flag = flags;
738 while (current_flag != 0) {
739 IDRecalcFlag tag = (IDRecalcFlag)(1 << bitscan_forward_clear_uint(&current_flag));
740 graph_id_tag_update_single_flag(bmain, graph, id, id_node, tag, update_source);
741 }
742 /* Special case for nested node tree data-blocks. */
743 id_tag_update_ntree_special(bmain, graph, id, flags, update_source);
744 /* Direct update tags means that something outside of simulated/cached
745 * physics did change and that cache is to be invalidated.
746 * This is only needed if data changes. If it's just a drawing, we keep the
747 * point cache. */
748 if (update_source == DEG_UPDATE_SOURCE_USER_EDIT && flags != ID_RECALC_SHADING) {
749 graph_id_tag_update_single_flag(
750 bmain, graph, id, id_node, ID_RECALC_POINT_CACHE, update_source);
751 }
752 deg_graph_tag_parameters_if_needed(bmain, graph, id, id_node, flags, update_source);
753}
754
755} // namespace blender::deg
756
758{
759 switch (flag) {
761 return "TRANSFORM";
763 return "GEOMETRY";
765 return "GEOMETRY_ALL_MODES";
767 return "ANIMATION";
769 return "PSYS_REDO";
771 return "PSYS_RESET";
773 return "PSYS_CHILD";
775 return "PSYS_PHYS";
777 return "PSYS_ALL";
779 return "COPY_ON_EVAL";
781 return "SHADING";
782 case ID_RECALC_SELECT:
783 return "SELECT";
785 return "BASE_FLAGS";
787 return "POINT_CACHE";
789 return "EDITORS";
791 return "SEQUENCER_STRIPS";
793 return "FRAME_CHANGE";
795 return "AUDIO_FPS";
797 return "AUDIO_VOLUME";
799 return "AUDIO_MUTE";
801 return "AUDIO_LISTENER";
802 case ID_RECALC_AUDIO:
803 return "AUDIO";
805 return "PARAMETERS";
806 case ID_RECALC_SOURCE:
807 return "SOURCE";
808 case ID_RECALC_ALL:
809 return "ALL";
811 return "TAG_FOR_UNDO";
813 return "ID_RECALC_NTREE_OUTPUT";
814
816 return "ID_RECALC_HIERARCHY";
817
823 /* Silently return nullptr, indicating that there is no string representation.
824 *
825 * This is needed due to the way how logging for ID_RECALC_ALL works: it iterates over all
826 * bits and converts then to string. */
827 return nullptr;
828 }
829 return nullptr;
830}
831
832/* Data-Based Tagging. */
833
834void DEG_id_tag_update(ID *id, uint flags)
835{
836 DEG_id_tag_update_ex(G.main, id, flags);
837}
838
839void DEG_id_tag_update_ex(Main *bmain, ID *id, uint flags)
840{
841 if (id == nullptr) {
842 /* Ideally should not happen, but old depsgraph allowed this. */
843 return;
844 }
846}
847
849{
850 BLI_assert(depsgraph != nullptr);
851 BLI_assert(id != nullptr);
853 Main *bmain = DEG_get_bmain(depsgraph);
855}
856
857void DEG_graph_id_tag_update(Main *bmain, Depsgraph *depsgraph, ID *id, uint flags)
858{
861}
862
864{
866 DEG_graph_time_tag_update(reinterpret_cast<::Depsgraph *>(depsgraph));
867 }
868}
869
871{
872 deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(depsgraph);
873 deg_graph->tag_time_source();
874}
875
876void DEG_graph_id_type_tag(Depsgraph *depsgraph, short id_type)
877{
878 if (id_type == ID_NT) {
879 /* Stupid workaround so parent data-blocks of nested node-tree get looped
880 * over when we loop over tagged data-block types. */
886 }
887 const int id_type_index = BKE_idtype_idcode_to_index(id_type);
888 deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(depsgraph);
889 deg_graph->id_type_updated[id_type_index] = 1;
890}
891
892void DEG_id_type_tag(Main *bmain, short id_type)
893{
895 DEG_graph_id_type_tag(reinterpret_cast<::Depsgraph *>(depsgraph), id_type);
896 }
897}
898
899void DEG_graph_tag_on_visible_update(Depsgraph *depsgraph, const bool do_time)
900{
902 deg::graph_tag_on_visible_update(graph, do_time);
903}
904
905void DEG_tag_on_visible_update(Main *bmain, const bool do_time)
906{
908 deg::graph_tag_on_visible_update(depsgraph, do_time);
909 }
910}
911
913{
915 graph->use_editors_update = true;
916}
917
918void DEG_editors_update(Depsgraph *depsgraph, bool time)
919{
921 if (!graph->use_editors_update) {
922 return;
923 }
924
927 Main *bmain = DEG_get_bmain(depsgraph);
928 bool updated = time || DEG_id_type_any_updated(depsgraph);
929
930 DEGEditorUpdateContext update_ctx = {nullptr};
931 update_ctx.bmain = bmain;
932 update_ctx.depsgraph = depsgraph;
933 update_ctx.scene = scene;
934 update_ctx.view_layer = view_layer;
935 deg::deg_editors_scene_update(&update_ctx, updated);
936}
937
939{
940 id->recalc &= ~ID_RECALC_ALL;
942 /* Clear embedded node trees too. */
943 if (ntree) {
944 ntree->id.recalc &= ~ID_RECALC_ALL;
945 }
946 /* XXX And what about scene's master collection here? */
947}
948
949void DEG_ids_clear_recalc(Depsgraph *depsgraph, const bool backup)
950{
951 deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(depsgraph);
952 /* TODO(sergey): Re-implement POST_UPDATE_HANDLER_WORKAROUND using entry_tags
953 * and id_tags storage from the new dependency graph. */
955 return;
956 }
957 /* Go over all ID nodes, clearing tags. */
958 for (deg::IDNode *id_node : deg_graph->id_nodes) {
959 if (backup) {
960 id_node->id_cow_recalc_backup |= id_node->id_cow->recalc;
961 }
962 /* TODO: we clear original ID recalc flags here, but this may not work
963 * correctly when there are multiple depsgraph with others still using
964 * the recalc flag. */
965 id_node->is_user_modified = false;
966 id_node->is_cow_explicitly_tagged = false;
968 if (deg_graph->is_active) {
970 }
971 }
972
973 if (backup) {
974 for (const int64_t i : blender::IndexRange(INDEX_ID_MAX)) {
975 if (deg_graph->id_type_updated[i] != 0) {
976 deg_graph->id_type_updated_backup[i] = 1;
977 }
978 }
979 }
980 memset(deg_graph->id_type_updated, 0, sizeof(deg_graph->id_type_updated));
981}
982
984{
985 deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(depsgraph);
986
987 for (deg::IDNode *id_node : deg_graph->id_nodes) {
988 id_node->id_cow->recalc |= id_node->id_cow_recalc_backup;
989 id_node->id_cow_recalc_backup = 0;
990 }
991
992 for (const int64_t i : blender::IndexRange(INDEX_ID_MAX)) {
993 if (deg_graph->id_type_updated_backup[i] != 0) {
994 deg_graph->id_type_updated[i] = 1;
995 }
996 }
997 memset(deg_graph->id_type_updated_backup, 0, sizeof(deg_graph->id_type_updated_backup));
998}
AnimData * BKE_animdata_from_id(const ID *id)
Definition anim_data.cc:89
@ G_DEBUG_DEPSGRAPH_TAG
int BKE_idtype_idcode_to_index(short idcode)
Definition idtype.cc:232
void BKE_lib_override_id_tag_on_deg_tag_from_user(ID *id)
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:57
MINLINE unsigned int bitscan_forward_clear_uint(unsigned int *a)
unsigned int uint
#define ELEM(...)
void DEG_graph_id_type_tag(Depsgraph *depsgraph, short id_type)
const char * DEG_update_tag_as_string(IDRecalcFlag flag)
int DEG_debug_flags_get(const Depsgraph *depsgraph)
ViewLayer * DEG_get_input_view_layer(const Depsgraph *graph)
Main * DEG_get_bmain(const Depsgraph *graph)
bool DEG_id_type_any_updated(const Depsgraph *depsgraph)
Scene * DEG_get_input_scene(const Depsgraph *graph)
#define ID_TYPE_USE_COPY_ON_EVAL(_id_type)
Definition DNA_ID.h:693
IDRecalcFlag
Definition DNA_ID.h:1016
@ ID_RECALC_PARAMETERS
Definition DNA_ID.h:1105
@ ID_RECALC_AUDIO_FPS
Definition DNA_ID.h:1094
@ ID_RECALC_PSYS_PHYS
Definition DNA_ID.h:1054
@ ID_RECALC_AUDIO_LISTENER
Definition DNA_ID.h:1097
@ ID_RECALC_TRANSFORM
Definition DNA_ID.h:1021
@ ID_RECALC_PROVISION_29
Definition DNA_ID.h:1133
@ ID_RECALC_SHADING
Definition DNA_ID.h:1061
@ ID_RECALC_PROVISION_30
Definition DNA_ID.h:1134
@ ID_RECALC_FRAME_CHANGE
Definition DNA_ID.h:1092
@ ID_RECALC_AUDIO
Definition DNA_ID.h:1099
@ ID_RECALC_POINT_CACHE
Definition DNA_ID.h:1072
@ ID_RECALC_SELECT
Definition DNA_ID.h:1068
@ ID_RECALC_PSYS_REDO
Definition DNA_ID.h:1048
@ ID_RECALC_PROVISION_31
Definition DNA_ID.h:1135
@ ID_RECALC_PSYS_CHILD
Definition DNA_ID.h:1052
@ ID_RECALC_HIERARCHY
Definition DNA_ID.h:1125
@ ID_RECALC_PROVISION_27
Definition DNA_ID.h:1131
@ ID_RECALC_SOURCE
Definition DNA_ID.h:1110
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1085
@ ID_RECALC_EDITORS
Definition DNA_ID.h:1078
@ ID_RECALC_GEOMETRY_ALL_MODES
Definition DNA_ID.h:1148
@ ID_RECALC_PSYS_ALL
Definition DNA_ID.h:1158
@ ID_RECALC_AUDIO_MUTE
Definition DNA_ID.h:1096
@ ID_RECALC_SEQUENCER_STRIPS
Definition DNA_ID.h:1089
@ ID_RECALC_TAG_FOR_UNDO
Definition DNA_ID.h:1119
@ ID_RECALC_NTREE_OUTPUT
Definition DNA_ID.h:1122
@ ID_RECALC_PSYS_RESET
Definition DNA_ID.h:1050
@ ID_RECALC_ANIMATION
Definition DNA_ID.h:1044
@ ID_RECALC_PROVISION_28
Definition DNA_ID.h:1132
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1041
@ ID_RECALC_ALL
Definition DNA_ID.h:1155
@ ID_RECALC_AUDIO_VOLUME
Definition DNA_ID.h:1095
@ ID_RECALC_BASE_FLAGS
Definition DNA_ID.h:1071
#define INDEX_ID_MAX
Definition DNA_ID.h:1328
ID_Type
@ ID_TE
@ ID_VO
@ ID_NT
@ ID_LA
@ ID_SCE
@ ID_MSK
@ ID_CV
@ ID_PAL
@ ID_LP
@ ID_WO
@ ID_MA
@ ID_CU_LEGACY
@ ID_GD_LEGACY
@ ID_ME
@ ID_GR
@ ID_MB
@ ID_LT
@ ID_OB
@ ID_GP
@ ID_PA
@ ID_PT
Object is a sort of wrapper for general info.
@ OB_LATTICE
@ OB_MBALL
@ OB_SURF
@ OB_FONT
@ OB_GREASE_PENCIL
@ OB_ARMATURE
@ OB_MESH
@ OB_POINTCLOUD
@ OB_VOLUME
@ OB_CURVES_LEGACY
@ OB_GPENCIL_LEGACY
@ OB_CURVES
#define printf
Depsgraph * graph
const IDNode * id_node
const Depsgraph * depsgraph
Lattice lattice
void DEG_graph_time_tag_update(Depsgraph *depsgraph)
void DEG_id_type_tag(Main *bmain, short id_type)
void DEG_editors_update(Depsgraph *depsgraph, bool time)
void DEG_id_tag_update_ex(Main *bmain, ID *id, uint flags)
void DEG_enable_editors_update(Depsgraph *depsgraph)
void DEG_ids_clear_recalc(Depsgraph *depsgraph, const bool backup)
void DEG_time_tag_update(Main *bmain)
void DEG_tag_on_visible_update(Main *bmain, const bool do_time)
void DEG_id_tag_update(ID *id, uint flags)
void DEG_graph_id_tag_update(Main *bmain, Depsgraph *depsgraph, ID *id, uint flags)
void DEG_graph_tag_on_visible_update(Depsgraph *depsgraph, const bool do_time)
void DEG_id_tag_update_for_side_effect_request(Depsgraph *depsgraph, ID *id, uint flags)
void DEG_graph_id_type_tag(Depsgraph *depsgraph, short id_type)
const char * DEG_update_tag_as_string(IDRecalcFlag flag)
void DEG_ids_restore_recalc(Depsgraph *depsgraph)
static void deg_graph_clear_id_recalc_flags(ID *id)
#define str(s)
#define GS(x)
Definition iris.cc:202
#define G(x, y, z)
bNodeTree * node_tree_from_id(ID *id)
Definition node.cc:3732
Span< Depsgraph * > get_all_registered_graphs(Main *bmain)
NodeType geometry_tag_to_component(const ID *id)
void deg_editors_id_update(const DEGEditorUpdateContext *update_ctx, ID *id)
void deg_editors_scene_update(const DEGEditorUpdateContext *update_ctx, bool updated)
void graph_tag_ids_for_visible_update(Depsgraph *graph)
bool deg_eval_copy_is_expanded(const ID *id_cow)
bool deg_eval_copy_is_needed(const ID *id_orig)
DepsNodeFactory * type_get_factory(const NodeType type)
void id_tag_update(Main *bmain, ID *id, uint flags, eUpdateSource update_source)
void graph_id_tag_update(Main *bmain, Depsgraph *graph, ID *id, uint flags, eUpdateSource update_source)
@ DEG_UPDATE_SOURCE_SIDE_EFFECT_REQUEST
__int64 int64_t
Definition stdint.h:89
Definition DNA_ID.h:413
unsigned int recalc
Definition DNA_ID.h:437
char name[66]
Definition DNA_ID.h:425
struct Key * key
char id_type_updated[INDEX_ID_MAX]
Definition depsgraph.hh:110
char id_type_updated_backup[INDEX_ID_MAX]
Definition depsgraph.hh:112
IDComponentsMask previously_visible_components_mask
IDComponentsMask visible_components_mask
ComponentNode * find_component(NodeType type, const char *name="") const
virtual void tag_update(Depsgraph *graph, eUpdateSource source) override
uint8_t flag
Definition wm_window.cc:138