Blender V4.3
deg_builder_nodes.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 <cstdlib>
15
16#include "MEM_guardedalloc.h"
17
18#include "BLI_blenlib.h"
19#include "BLI_span.hh"
20#include "BLI_string.h"
21#include "BLI_utildefines.h"
22
23#include "DNA_action_types.h"
24#include "DNA_anim_types.h"
25#include "DNA_armature_types.h"
26#include "DNA_cachefile_types.h"
27#include "DNA_camera_types.h"
30#include "DNA_curve_types.h"
31#include "DNA_curves_types.h"
32#include "DNA_effect_types.h"
34#include "DNA_key_types.h"
35#include "DNA_light_types.h"
37#include "DNA_linestyle_types.h"
38#include "DNA_mask_types.h"
39#include "DNA_material_types.h"
40#include "DNA_mesh_types.h"
41#include "DNA_meta_types.h"
42#include "DNA_movieclip_types.h"
43#include "DNA_node_types.h"
44#include "DNA_object_types.h"
45#include "DNA_particle_types.h"
46#include "DNA_rigidbody_types.h"
47#include "DNA_scene_types.h"
48#include "DNA_sequence_types.h"
49#include "DNA_sound_types.h"
50#include "DNA_speaker_types.h"
51#include "DNA_texture_types.h"
52#include "DNA_vfont_types.h"
53#include "DNA_world_types.h"
54
55#include "BKE_action.hh"
56#include "BKE_anim_data.hh"
57#include "BKE_animsys.h"
58#include "BKE_armature.hh"
60#include "BKE_cachefile.hh"
61#include "BKE_collection.hh"
62#include "BKE_constraint.h"
63#include "BKE_curve.hh"
64#include "BKE_effect.h"
65#include "BKE_fcurve_driver.h"
66#include "BKE_gpencil_legacy.h"
68#include "BKE_grease_pencil.hh"
69#include "BKE_idprop.hh"
70#include "BKE_idtype.hh"
71#include "BKE_image.hh"
72#include "BKE_key.hh"
73#include "BKE_lattice.hh"
74#include "BKE_layer.hh"
75#include "BKE_lib_id.hh"
76#include "BKE_lib_query.hh"
77#include "BKE_light.h"
78#include "BKE_mask.h"
79#include "BKE_material.h"
80#include "BKE_mball.hh"
81#include "BKE_mesh.hh"
82#include "BKE_modifier.hh"
83#include "BKE_movieclip.h"
84#include "BKE_node.hh"
85#include "BKE_node_runtime.hh"
86#include "BKE_object.hh"
87#include "BKE_particle.h"
88#include "BKE_pointcache.h"
89#include "BKE_rigidbody.h"
90#include "BKE_scene.hh"
91#include "BKE_shader_fx.h"
92#include "BKE_sound.h"
93#include "BKE_tracking.h"
94#include "BKE_volume.hh"
95#include "BKE_world.h"
96
97#include "RNA_access.hh"
98#include "RNA_path.hh"
99#include "RNA_prototypes.hh"
100#include "RNA_types.hh"
101
102#include "DEG_depsgraph.hh"
103#include "DEG_depsgraph_build.hh"
104
105#include "SEQ_iterator.hh"
106#include "SEQ_sequencer.hh"
107
111#include "intern/depsgraph.hh"
121
122namespace blender::deg {
123
124/* ************ */
125/* Node Builder */
126
127/* **** General purpose functions **** */
128
130 Depsgraph *graph,
132 : DepsgraphBuilder(bmain, graph, cache),
133 scene_(nullptr),
134 view_layer_(nullptr),
135 view_layer_index_(-1),
136 is_parent_collection_visible_(true)
137{
138}
139
141{
142 for (IDInfo *id_info : id_info_hash_.values()) {
143 if (id_info->id_cow != nullptr) {
144 deg_free_eval_copy_datablock(id_info->id_cow);
145 MEM_freeN(id_info->id_cow);
146 }
147 MEM_freeN(id_info);
148 }
149}
150
152{
153 BLI_assert(id->session_uid != MAIN_ID_SESSION_UID_UNSET);
154
155 const ID_Type id_type = GS(id->name);
156 IDNode *id_node = nullptr;
157 ID *id_cow = nullptr;
158 IDComponentsMask previously_visible_components_mask = 0;
159 uint32_t previous_eval_flags = 0;
160 DEGCustomDataMeshMasks previous_customdata_masks;
161 IDInfo *id_info = id_info_hash_.lookup_default(id->session_uid, nullptr);
162 if (id_info != nullptr) {
163 id_cow = id_info->id_cow;
164 previously_visible_components_mask = id_info->previously_visible_components_mask;
165 previous_eval_flags = id_info->previous_eval_flags;
166 previous_customdata_masks = id_info->previous_customdata_masks;
167 /* Tag ID info to not free the evaluated ID pointer. */
168 id_info->id_cow = nullptr;
169 }
170 id_node = graph_->add_id_node(id, id_cow);
171 id_node->previously_visible_components_mask = previously_visible_components_mask;
172 id_node->previous_eval_flags = previous_eval_flags;
173 id_node->previous_customdata_masks = previous_customdata_masks;
174
175 /* NOTE: Zero number of components indicates that ID node was just created. */
176 const bool is_newly_created = id_node->components.is_empty();
177
178 if (is_newly_created) {
179 if (deg_eval_copy_is_needed(id_type)) {
180 ComponentNode *comp_cow = id_node->add_component(NodeType::COPY_ON_EVAL);
181 OperationNode *op_cow = comp_cow->add_operation(
184 graph_->operations.append(op_cow);
185 }
186
187 ComponentNode *visibility_component = id_node->add_component(NodeType::VISIBILITY);
188 OperationNode *visibility_operation;
189
190 /* Optimization: currently only objects need a special visibility evaluation. For the rest ID
191 * types keep the node as a NO-OP so that relations can still be routed, but without penalty
192 * during the graph evaluation. */
193 if (id_type == ID_OB) {
194 visibility_operation = visibility_component->add_operation(
195 [id_node](::Depsgraph *depsgraph) {
197 },
199 }
200 else {
201 visibility_operation = visibility_component->add_operation(nullptr,
203 }
204
205 /* Pin the node so that it and its relations are preserved by the unused nodes/relations
206 * deletion. This is mainly to make it easier to debug visibility. */
207 visibility_operation->flag |= (OperationFlag::DEPSOP_FLAG_PINNED |
209 graph_->operations.append(visibility_operation);
210 }
211 return id_node;
212}
213
215{
216 return graph_->find_id_node(id);
217}
218
223
225 NodeType comp_type,
226 const char *comp_name)
227{
229 ComponentNode *comp_node = id_node->add_component(comp_type, comp_name);
230 comp_node->owner = id_node;
231 return comp_node;
232}
233
235 const NodeType comp_type,
236 const char *comp_name)
237{
239 if (id_node == nullptr) {
240 return nullptr;
241 }
242 return id_node->find_component(comp_type, comp_name);
243}
244
246 OperationCode opcode,
247 const DepsEvalOperationCb &op,
248 const char *name,
249 int name_tag)
250{
251 OperationNode *op_node = comp_node->find_operation(opcode, name, name_tag);
252 if (op_node == nullptr) {
253 op_node = comp_node->add_operation(op, opcode, name, name_tag);
254 graph_->operations.append(op_node);
255 }
256 else {
257 fprintf(stderr,
258 "add_operation: Operation already exists - %s has %s at %p\n",
259 comp_node->identifier().c_str(),
260 op_node->identifier().c_str(),
261 op_node);
262 BLI_assert_msg(0, "Should not happen!");
263 }
264 return op_node;
265}
266
268 NodeType comp_type,
269 const char *comp_name,
270 OperationCode opcode,
271 const DepsEvalOperationCb &op,
272 const char *name,
273 int name_tag)
274{
275 ComponentNode *comp_node = add_component_node(id, comp_type, comp_name);
276 return add_operation_node(comp_node, opcode, op, name, name_tag);
277}
278
280 NodeType comp_type,
281 OperationCode opcode,
282 const DepsEvalOperationCb &op,
283 const char *name,
284 int name_tag)
285{
286 return add_operation_node(id, comp_type, "", opcode, op, name, name_tag);
287}
288
290 NodeType comp_type,
291 const char *comp_name,
292 OperationCode opcode,
293 const DepsEvalOperationCb &op,
294 const char *name,
295 int name_tag)
296{
297 OperationNode *operation = find_operation_node(id, comp_type, comp_name, opcode, name, name_tag);
298 if (operation != nullptr) {
299 return operation;
300 }
301 return add_operation_node(id, comp_type, comp_name, opcode, op, name, name_tag);
302}
303
305 NodeType comp_type,
306 OperationCode opcode,
307 const DepsEvalOperationCb &op,
308 const char *name,
309 int name_tag)
310{
311 OperationNode *operation = find_operation_node(id, comp_type, opcode, name, name_tag);
312 if (operation != nullptr) {
313 return operation;
314 }
315 return add_operation_node(id, comp_type, opcode, op, name, name_tag);
316}
317
319 NodeType comp_type,
320 const char *comp_name,
321 OperationCode opcode,
322 const char *name,
323 int name_tag)
324{
325 return find_operation_node(id, comp_type, comp_name, opcode, name, name_tag) != nullptr;
326}
327
329 const NodeType comp_type,
330 const OperationCode opcode)
331{
332 return find_operation_node(id, comp_type, opcode) != nullptr;
333}
334
336 NodeType comp_type,
337 const char *comp_name,
338 OperationCode opcode,
339 const char *name,
340 int name_tag)
341{
342 ComponentNode *comp_node = find_component_node(id, comp_type, comp_name);
343 if (comp_node == nullptr) {
344 return nullptr;
345 }
346 return comp_node->find_operation(opcode, name, name_tag);
347}
348
350 const ID *id, NodeType comp_type, OperationCode opcode, const char *name, int name_tag)
351{
352 return find_operation_node(id, comp_type, "", opcode, name, name_tag);
353}
354
360
362{
363 return graph_->get_cow_id(id_orig);
364}
365
367{
368 if (id_orig->tag & ID_TAG_COPIED_ON_EVAL) {
369 /* ID is already remapped to copy-on-evaluation. */
370 return id_orig;
371 }
372 IDNode *id_node = add_id_node(id_orig);
373 return id_node->id_cow;
374}
375
376/* **** Build functions for entity nodes **** */
377
379{
380 /* Store existing evaluated versions of datablock, so we can re-use
381 * them for new ID nodes. */
382 for (IDNode *id_node : graph_->id_nodes) {
383 /* It is possible that the ID does not need to have evaluated version in which case id_cow is
384 * the same as id_orig. Additionally, such ID might have been removed, which makes the check
385 * for whether id_cow is expanded to access freed memory. In order to deal with this we
386 * check whether an evaluated copy is needed based on a scalar value which does not lead to
387 * access of possibly deleted memory. */
388 IDInfo *id_info = (IDInfo *)MEM_mallocN(sizeof(IDInfo), "depsgraph id info");
390 id_node->id_orig != id_node->id_cow)
391 {
392 id_info->id_cow = id_node->id_cow;
393 }
394 else {
395 id_info->id_cow = nullptr;
396 }
397 id_info->previously_visible_components_mask = id_node->visible_components_mask;
398 id_info->previous_eval_flags = id_node->eval_flags;
399 id_info->previous_customdata_masks = id_node->customdata_masks;
400 BLI_assert(!id_info_hash_.contains(id_node->id_orig_session_uid));
401 id_info_hash_.add_new(id_node->id_orig_session_uid, id_info);
402 id_node->id_cow = nullptr;
403 }
404
405 for (const OperationNode *op_node : graph_->entry_tags) {
406 saved_entry_tags_.append_as(op_node);
407 }
408
409 for (const OperationNode *op_node : graph_->operations) {
410 if (op_node->flag & DEPSOP_FLAG_NEEDS_UPDATE) {
411 needs_update_operations_.append_as(op_node);
412 }
413 }
414
415 /* Make sure graph has no nodes left from previous state. */
418 graph_->entry_tags.clear();
419}
420
421/* Util callbacks for `BKE_library_foreach_ID_link`, used to detect when an evaluated ID is using
422 * ID pointers that are either:
423 * - evaluated ID pointers that do not exist anymore in current depsgraph.
424 * - Orig ID pointers that do have now an evaluated version in current depsgraph.
425 * In both cases, it means the evaluated ID user needs to be flushed, to ensure its pointers are
426 * properly remapped.
427 *
428 * NOTE: This is split in two, a static function and a public method of the node builder, to allow
429 * the code to access the builder's data more easily. */
430
432 ID *id_pointer)
433{
434 if (id_pointer->orig_id == nullptr) {
435 /* `id_cow_self` uses a non-cow ID, if that ID has an evaluated copy in current depsgraph its
436 * owner needs to be remapped, i.e. copy-on-eval-flushed. */
437 IDNode *id_node = find_id_node(id_pointer);
438 if (id_node != nullptr && id_node->id_cow != nullptr) {
440 graph_,
441 id_cow_self->orig_id,
445 }
446 }
447 else {
448 /* `id_cow_self` uses an evaluated ID, if that evaluated copy is removed from current depsgraph
449 * its owner needs to be remapped, i.e. copy-on-eval-flushed. */
450 /* NOTE: at that stage, old existing evaluated copies that are to be removed from current state
451 * of evaluated depsgraph are still valid pointers, they are freed later (typically during
452 * destruction of the builder itself). */
453 IDNode *id_node = find_id_node(id_pointer->orig_id);
454 if (id_node == nullptr) {
456 graph_,
457 id_cow_self->orig_id,
461 }
462 }
463 return IDWALK_RET_NOP;
464}
465
467{
468 ID *id = *cb_data->id_pointer;
469 if (id == nullptr) {
470 return IDWALK_RET_NOP;
471 }
472 if (!ID_TYPE_USE_COPY_ON_EVAL(GS(id->name))) {
473 /* No need to go further if the id never had an evaluated copy in the depsgraph. This function
474 * is only concerned with keeping the mapping between original and evaluated IDs intact. */
475 return IDWALK_RET_NOP;
476 }
477
478 DepsgraphNodeBuilder *builder = static_cast<DepsgraphNodeBuilder *>(cb_data->user_data);
479 ID *id_cow_self = cb_data->self_id;
480
481 return builder->foreach_id_cow_detect_need_for_update_callback(id_cow_self, id);
482}
483
485{
486 /* NOTE: Currently the only ID types that depsgraph may decide to not evaluate/generate evaluated
487 * copies for, even though they are referenced by other data-blocks, are Collections and Objects
488 * (through their various visibility flags, and the ones from #LayerCollections too). However,
489 * this code is kept generic as it makes it more future-proof, and optimization here would give
490 * negligible performance improvements in typical cases.
491 *
492 * NOTE: This mechanism may also 'fix' some missing update tagging from non-depsgraph code in
493 * some cases. This is slightly unfortunate (as it may hide issues in other parts of Blender
494 * code), but cannot really be avoided currently. */
495
496 for (const IDNode *id_node : graph_->id_nodes) {
497 if (id_node->previously_visible_components_mask == 0) {
498 /* Newly added node/ID, no need to check it. */
499 continue;
500 }
501 if (ELEM(id_node->id_cow, id_node->id_orig, nullptr)) {
502 /* Node/ID with no copy-on-eval data, no need to check it. */
503 continue;
504 }
505 if ((id_node->id_cow->recalc & ID_RECALC_SYNC_TO_EVAL) != 0) {
506 /* Node/ID already tagged for copy-on-eval flush, no need to check it. */
507 continue;
508 }
509 if ((id_node->id_cow->flag & ID_FLAG_EMBEDDED_DATA) != 0) {
510 /* For now, we assume embedded data are managed by their owner IDs and do not need to be
511 * checked here.
512 *
513 * NOTE: This exception somewhat weak, and ideally should not be needed. Currently however,
514 * embedded data are handled as full local (private) data of their owner IDs in part of
515 * Blender (like read/write code, including undo/redo), while depsgraph generally treat them
516 * as regular independent IDs. This leads to inconsistencies that can lead to bad level
517 * memory accesses.
518 *
519 * E.g. when undoing creation/deletion of a collection directly child of a scene's master
520 * collection, the scene itself is re-read in place, but its master collection becomes a
521 * completely new different pointer, and the existing copy-on-eval of the old master
522 * collection in the matching deg node is therefore pointing to fully invalid (freed) memory.
523 */
524 continue;
525 }
527 id_node->id_cow,
529 this,
531 }
532}
533
535{
536 for (const OperationKey &operation_key : saved_entry_tags_) {
537 OperationNode *operation_node = find_operation_node(operation_key);
538 if (operation_node == nullptr) {
539 continue;
540 }
541
542 /* Since the tag is coming from a saved copy of entry tags, this means
543 * that originally node was explicitly tagged for user update. */
545 }
546
547 /* Restore needs-update flags since the previous state of the dependency graph, ensuring the
548 * previously-skipped operations are properly re-evaluated when needed. */
549 for (const OperationKey &operation_key : needs_update_operations_) {
550 OperationNode *operation_node = find_operation_node(operation_key);
551 if (operation_node == nullptr) {
552 continue;
553 }
554 operation_node->flag |= DEPSOP_FLAG_NEEDS_UPDATE;
555 }
556}
557
564
565void DepsgraphNodeBuilder::build_id(ID *id, const bool force_be_visible)
566{
567 if (id == nullptr) {
568 return;
569 }
570
571 const ID_Type id_type = GS(id->name);
572 switch (id_type) {
573 case ID_AC:
574 build_action((bAction *)id);
575 break;
576 case ID_AR:
578 break;
579 case ID_CA:
580 build_camera((Camera *)id);
581 break;
582 case ID_GR:
583 build_collection(nullptr, (Collection *)id);
584 break;
585 case ID_OB:
586 /* TODO(sergey): Get visibility from a "parent" somehow.
587 *
588 * NOTE: Using `false` visibility here should be fine, since if this
589 * driver affects on something invisible we don't really care if the
590 * driver gets evaluated (and even don't want this to force object
591 * to become visible).
592 *
593 * If this happened to be affecting visible object, then it is up to
594 * deg_graph_build_flush_visibility() to ensure visibility of the
595 * object is true. */
596 build_object(-1, (Object *)id, DEG_ID_LINKED_INDIRECTLY, force_be_visible);
597 break;
598 case ID_KE:
599 build_shapekeys((Key *)id);
600 break;
601 case ID_LA:
602 build_light((Light *)id);
603 break;
604 case ID_LP:
606 break;
607 case ID_NT:
609 break;
610 case ID_MA:
612 break;
613 case ID_TE:
614 build_texture((Tex *)id);
615 break;
616 case ID_IM:
617 build_image((Image *)id);
618 break;
619 case ID_WO:
620 build_world((World *)id);
621 break;
622 case ID_MSK:
623 build_mask((Mask *)id);
624 break;
625 case ID_LS:
627 break;
628 case ID_MC:
630 break;
631 case ID_ME:
632 case ID_MB:
633 case ID_CU_LEGACY:
634 case ID_LT:
635 case ID_GD_LEGACY:
636 case ID_CV:
637 case ID_PT:
638 case ID_VO:
639 case ID_GP:
641 break;
642 case ID_SPK:
643 build_speaker((Speaker *)id);
644 break;
645 case ID_SO:
646 build_sound((bSound *)id);
647 break;
648 case ID_TXT:
649 /* Not a part of dependency graph. */
650 break;
651 case ID_CF:
653 break;
654 case ID_SCE:
656 break;
657 case ID_PA:
659 break;
660
661 case ID_LI:
662 case ID_IP:
663 case ID_SCR:
664 case ID_VF:
665 case ID_BR:
666 case ID_WM:
667 case ID_PAL:
668 case ID_PC:
669 case ID_WS:
672 break;
673 }
674}
675
677{
679 return;
680 }
681
682 build_idproperties(id->properties);
683 build_animdata(id);
685}
686
688{
689 IDP_foreach_property(id_property, IDP_TYPE_FILTER_ID, [&](IDProperty *id_property) {
690 this->build_id(static_cast<ID *>(id_property->data.pointer));
691 });
692}
693
695 Collection *collection)
696{
697 const int visibility_flag = (graph_->mode == DAG_EVAL_VIEWPORT) ? COLLECTION_HIDE_VIEWPORT :
699 const bool is_collection_restricted = (collection->flag & visibility_flag);
700 const bool is_collection_visible = !is_collection_restricted && is_parent_collection_visible_;
702 if (built_map_.checkIsBuiltAndTag(collection)) {
703 id_node = find_id_node(&collection->id);
704 if (is_collection_visible && id_node->is_visible_on_build == false &&
705 id_node->is_collection_fully_expanded == true)
706 {
707 /* Collection became visible, make sure nested collections and
708 * objects are poked with the new visibility flag, since they
709 * might become visible too. */
710 }
711 else if (from_layer_collection == nullptr && !id_node->is_collection_fully_expanded) {
712 /* Initially collection was built from layer now, and was requested
713 * to not recurse into object. But now it's asked to recurse into all objects. */
714 }
715 else {
716 return;
717 }
718 }
719 else {
720 /* Collection itself. */
721 id_node = add_id_node(&collection->id);
722 id_node->is_visible_on_build = is_collection_visible;
723
725
726 build_idproperties(collection->id.properties);
727 build_parameters(&collection->id);
729 }
730 if (from_layer_collection != nullptr) {
731 /* If we came from layer collection we don't go deeper, view layer
732 * builder takes care of going deeper. */
733 return;
734 }
735 /* Backup state. */
736 const bool is_current_parent_collection_visible = is_parent_collection_visible_;
737 /* Modify state as we've entered new collection/ */
738 is_parent_collection_visible_ = is_collection_visible;
739 /* Build collection objects. */
740 LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) {
741 build_object(-1, cob->ob, DEG_ID_LINKED_INDIRECTLY, is_collection_visible);
742 }
743 /* Build child collections. */
744 LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
745 build_collection(nullptr, child->collection);
746 }
747 /* Restore state. */
748 is_parent_collection_visible_ = is_current_parent_collection_visible;
749 id_node->is_collection_fully_expanded = true;
750}
751
753 Object *object,
754 eDepsNode_LinkedState_Type linked_state,
755 bool is_visible)
756{
757 const bool has_object = built_map_.checkIsBuiltAndTag(object);
758
759 /* When there is already object in the dependency graph accumulate visibility an linked state
760 * flags. Only do it on the object itself (apart from very special cases) and leave dealing with
761 * visibility of dependencies to the visibility flush step which happens at the end of the build
762 * process. */
763 if (has_object) {
764 IDNode *id_node = find_id_node(&object->id);
765 if (id_node->linked_state == DEG_ID_LINKED_INDIRECTLY) {
766 build_object_flags(base_index, object, linked_state);
767 }
768 id_node->linked_state = max(id_node->linked_state, linked_state);
769 id_node->is_visible_on_build |= is_visible;
770 id_node->has_base |= (base_index != -1);
771
772 /* There is no relation path which will connect current object with all the ones which come
773 * via the instanced collection, so build the collection again. Note that it will do check
774 * whether visibility update is needed on its own. */
775 build_object_instance_collection(object, is_visible);
776
777 return;
778 }
779
780 /* Create ID node for object and begin init. */
781 IDNode *id_node = add_id_node(&object->id);
782 Object *object_cow = get_cow_datablock(object);
783 id_node->linked_state = linked_state;
784 /* NOTE: Scene is nullptr when building dependency graph for render pipeline.
785 * Probably need to assign that to something non-nullptr, but then the logic here will still be
786 * somewhat weird. */
787 if (scene_ != nullptr && object == scene_->camera) {
788 id_node->is_visible_on_build = true;
789 }
790 else {
791 id_node->is_visible_on_build = is_visible;
792 }
793 id_node->has_base |= (base_index != -1);
794
796
797 /* Various flags, flushing from bases/collections. */
798 build_object_from_layer(base_index, object, linked_state);
799 /* Transform. */
801 /* Parent. */
802 if (object->parent != nullptr) {
803 build_object(-1, object->parent, DEG_ID_LINKED_INDIRECTLY, is_visible);
804 }
805 /* Modifiers. */
807 /* Grease Pencil Modifiers. */
808 if (object->greasepencil_modifiers.first != nullptr) {
810 data.builder = this;
812 }
813 /* Shader FX. */
814 if (object->shader_fx.first != nullptr) {
816 data.builder = this;
818 }
819 /* Constraints. */
820 if (object->constraints.first != nullptr) {
822 data.builder = this;
823 BKE_constraints_id_loop(&object->constraints, constraint_walk, IDWALK_NOP, &data);
824 }
825 /* Object data. */
826 build_object_data(object);
827 /* Parameters, used by both drivers/animation and also to inform dependency
828 * from object's data. */
829 build_parameters(&object->id);
830 build_idproperties(object->id.properties);
831 /* Build animation data,
832 *
833 * Do it now because it's possible object data will affect
834 * on object's level animation, for example in case of rebuilding
835 * pose for proxy. */
836 build_animdata(&object->id);
837 /* Particle systems. */
838 if (object->particlesystem.first != nullptr) {
839 build_particle_systems(object, is_visible);
840 }
841 /* Force field Texture. */
842 if ((object->pd != nullptr) && (object->pd->forcefield == PFIELD_TEXTURE) &&
843 (object->pd->tex != nullptr))
844 {
845 build_texture(object->pd->tex);
846 }
847
848 /* Object instancing. */
849 if (object->instance_collection != nullptr) {
850 build_object_instance_collection(object, is_visible);
851
852 OperationNode *instancer_node = add_operation_node(
854 instancer_node->flag |= OperationFlag::DEPSOP_FLAG_PINNED;
855 }
856 OperationNode *instance_node = add_operation_node(
858 instance_node->flag |= OperationFlag::DEPSOP_FLAG_PINNED;
859
860 OperationNode *instance_geometry_node = add_operation_node(
862 instance_geometry_node->flag |= OperationFlag::DEPSOP_FLAG_PINNED;
863
865
866 build_object_shading(object);
867
868 /* Synchronization back to original object. */
869 add_operation_node(&object->id,
872 [object_cow](::Depsgraph *depsgraph) {
873 BKE_object_sync_to_original(depsgraph, object_cow);
874 });
875}
876
878 Object *object,
879 eDepsNode_LinkedState_Type linked_state)
880{
881
882 OperationNode *entry_node = add_operation_node(
884 entry_node->set_as_entry();
887 exit_node->set_as_exit();
888
889 build_object_flags(base_index, object, linked_state);
890}
891
893 Object *object,
894 eDepsNode_LinkedState_Type linked_state)
895{
896 if (base_index == -1) {
897 return;
898 }
899 Scene *scene_cow = get_cow_datablock(scene_);
900 Object *object_cow = get_cow_datablock(object);
901 const bool is_from_set = (linked_state == DEG_ID_LINKED_VIA_SET);
902 /* TODO(sergey): Is this really best component to be used? */
904 &object->id,
907 [view_layer_index = view_layer_index_, scene_cow, object_cow, base_index, is_from_set](
908 ::Depsgraph *depsgraph) {
909 BKE_object_eval_eval_base_flags(
910 depsgraph, scene_cow, view_layer_index, object_cow, base_index, is_from_set);
911 });
912}
913
915{
916 if (object->instance_collection == nullptr) {
917 return;
918 }
919 const bool is_current_parent_collection_visible = is_parent_collection_visible_;
920 is_parent_collection_visible_ = is_object_visible;
921 build_collection(nullptr, object->instance_collection);
922 is_parent_collection_visible_ = is_current_parent_collection_visible;
923}
924
926{
927 if (BLI_listbase_is_empty(&object->modifiers)) {
928 return;
929 }
930
931 const ModifierMode modifier_mode = (graph_->mode == DAG_EVAL_VIEWPORT) ? eModifierMode_Realtime :
933
934 IDNode *id_node = find_id_node(&object->id);
935
936 add_operation_node(&object->id,
939 [id_node](::Depsgraph *depsgraph) {
940 deg_evaluate_object_modifiers_mode_node_visibility(depsgraph, id_node);
941 });
942
943 int modifier_index;
944 LISTBASE_FOREACH_INDEX (ModifierData *, modifier, &object->modifiers, modifier_index) {
945 OperationNode *modifier_node = add_operation_node(
946 &object->id, NodeType::GEOMETRY, OperationCode::MODIFIER, nullptr, modifier->name);
947 if (modifier->type == eModifierType_Nodes) {
948 modifier_node->evaluate =
949 [id_node, modifier_index, modifier_node](::Depsgraph * /*depsgraph*/) {
950 Object *ob_eval = reinterpret_cast<Object *>(id_node->id_cow);
951 ModifierData *md_eval = reinterpret_cast<ModifierData *>(
952 BLI_findlink(&ob_eval->modifiers, modifier_index));
953 /* Set flag that the modifier can check when it is evaluated. */
954 const bool is_user_modified = modifier_node->flag & DEPSOP_FLAG_USER_MODIFIED;
955 SET_FLAG_FROM_TEST(md_eval->flag, is_user_modified, eModifierFlag_UserModified);
956 };
957 }
958
959 /* Mute modifier mode if the modifier is not enabled for the dependency graph mode.
960 * This handles static (non-animated) mode of the modifier. */
961 if ((modifier->mode & modifier_mode) == 0) {
962 modifier_node->flag |= DEPSOP_FLAG_MUTE;
963 }
964
965 if (is_modifier_visibility_animated(object, modifier)) {
967 }
968 }
969
971 data.builder = this;
972
973 /* Temporarily set the collection visibility to false, relying on the visibility flushing code
974 * to flush the visibility from a modifier into collections it depends on. */
975 const bool is_current_parent_collection_visible = is_parent_collection_visible_;
978 is_parent_collection_visible_ = is_current_parent_collection_visible;
979}
980
982{
983 if (object->data == nullptr) {
984 return;
985 }
986 /* type-specific data. */
987 switch (object->type) {
988 case OB_MESH:
989 case OB_CURVES_LEGACY:
990 case OB_FONT:
991 case OB_SURF:
992 case OB_MBALL:
993 case OB_LATTICE:
995 case OB_CURVES:
996 case OB_POINTCLOUD:
997 case OB_VOLUME:
999 break;
1000 case OB_GREASE_PENCIL:
1002 break;
1003 case OB_ARMATURE:
1004 build_rig(object);
1005 break;
1006 case OB_LAMP:
1008 break;
1009 case OB_CAMERA:
1011 break;
1012 case OB_LIGHTPROBE:
1014 break;
1015 case OB_SPEAKER:
1017 break;
1018 default: {
1019 ID *obdata = (ID *)object->data;
1020 if (!built_map_.checkIsBuilt(obdata)) {
1021 build_animdata(obdata);
1022 }
1023 break;
1024 }
1025 }
1026 /* Materials. */
1027 Material ***materials_ptr = BKE_object_material_array_p(object);
1028 if (materials_ptr != nullptr) {
1029 short *num_materials_ptr = BKE_object_material_len_p(object);
1030 build_materials(*materials_ptr, *num_materials_ptr);
1031 }
1032}
1033
1035{
1036 Camera *camera = (Camera *)object->data;
1037 build_camera(camera);
1038}
1039
1041{
1042 Light *lamp = (Light *)object->data;
1044}
1045
1052
1054{
1055 GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object->data);
1056 /* Build the layer parents. */
1057 for (const bke::greasepencil::Layer *layer : grease_pencil.layers()) {
1058 Object *parent = layer->parent;
1059 if (parent == nullptr) {
1060 continue;
1061 }
1062 build_object(-1, parent, DEG_ID_LINKED_INDIRECTLY, false);
1063 }
1065}
1066
1068{
1069 Speaker *speaker = (Speaker *)object->data;
1070 build_speaker(speaker);
1072}
1073
1075{
1076 OperationNode *op_node;
1077 Object *ob_cow = get_cow_datablock(object);
1078 /* Transform entry operation. */
1080 op_node->set_as_entry();
1081 /* Local transforms (from transform channels - loc/rot/scale + deltas). */
1083 &object->id,
1086 [ob_cow](::Depsgraph *depsgraph) { BKE_object_eval_local_transform(depsgraph, ob_cow); });
1087 /* Object parent. */
1088 if (object->parent != nullptr) {
1090 &object->id,
1093 [ob_cow](::Depsgraph *depsgraph) { BKE_object_eval_parent(depsgraph, ob_cow); });
1094 }
1095 /* Object constraints. */
1096 if (object->constraints.first != nullptr) {
1098 }
1099 /* Rest of transformation update. */
1101 &object->id,
1104 [ob_cow](::Depsgraph *depsgraph) { BKE_object_eval_uber_transform(depsgraph, ob_cow); });
1105 /* Operation to take of rigid body simulation. soft bodies and other friends
1106 * in the context of point cache invalidation. */
1108 /* Object transform is done. */
1109 op_node = add_operation_node(
1110 &object->id,
1113 [ob_cow](::Depsgraph *depsgraph) { BKE_object_eval_transform_final(depsgraph, ob_cow); });
1114 op_node->set_as_exit();
1115}
1116
1135{
1136 /* create node for constraint stack */
1137 Scene *scene_cow = get_cow_datablock(scene_);
1138 Object *object_cow = get_cow_datablock(object);
1139 add_operation_node(&object->id,
1142 [scene_cow, object_cow](::Depsgraph *depsgraph) {
1143 BKE_object_eval_constraints(depsgraph, scene_cow, object_cow);
1144 });
1145}
1146
1148{
1149 if (!BKE_ptcache_object_has(scene_, object, 0)) {
1150 return;
1151 }
1152 Scene *scene_cow = get_cow_datablock(scene_);
1153 Object *object_cow = get_cow_datablock(object);
1154 add_operation_node(&object->id,
1157 [scene_cow, object_cow](::Depsgraph *depsgraph) {
1158 BKE_object_eval_ptcache_reset(depsgraph, scene_cow, object_cow);
1159 });
1160}
1161
1163{
1164 /* For objects put the light linking update callback to the same component as the base flags.
1165 * This way the light linking is updated on the view layer hierarchy change (which does not seem
1166 * to have a dedicated tag). */
1167 Object *object_cow = get_cow_datablock(object);
1168 add_operation_node(&object->id,
1171 [object_cow](::Depsgraph *depsgraph) {
1172 BKE_object_eval_light_linking(depsgraph, object_cow);
1173 });
1174
1176
1177 if (object->light_linking) {
1178 build_light_linking_collection(object->light_linking->receiver_collection);
1179 build_light_linking_collection(object->light_linking->blocker_collection);
1180 }
1181}
1182
1184{
1185 if (collection == nullptr) {
1186 return;
1187 }
1188
1189 /* TODO(sergey): Support some sort of weak referencing, so that receiver objects which are
1190 * specified by this collection but not in the scene do not use extra memory.
1191 *
1192 * Until the better solution is implemented pull the objects indirectly, and keep them
1193 * invisible. This has penalty of higher memory usage, but not a performance penalty. */
1194
1195 const bool is_current_parent_collection_visible = is_parent_collection_visible_;
1197
1198 build_collection(nullptr, collection);
1199
1200 is_parent_collection_visible_ = is_current_parent_collection_visible;
1201
1202 /* Ensure the light linking component is created for the collection.
1203 *
1204 * Note that it is not possible to have early output check based on regular built flags because
1205 * the collection might have been first built for the non-light-linking purposes. */
1206 /* TODO(sergey): Can optimize this out by explicitly separating the different built tags. This
1207 * needs to be done in all places where the collection is built (is not something that can be
1208 * easily solved from just adding the light linking functionality). */
1209 if (!has_operation_node(
1211 {
1213 }
1214}
1215
1217{
1218 Object *object_cow = get_cow_datablock(object);
1220 &object->id,
1223 [object_cow](::Depsgraph *depsgraph) { BKE_object_eval_shading(depsgraph, object_cow); });
1224
1225 OperationNode *done_node = add_operation_node(
1227 done_node->set_as_exit();
1228}
1229
1231{
1232 /* Special handling for animated images/sequences. */
1234 /* Regular animation. */
1235 AnimData *adt = BKE_animdata_from_id(id);
1236 if (adt == nullptr) {
1237 return;
1238 }
1239 if (adt->action != nullptr) {
1240 build_action(adt->action);
1241 }
1242 /* Make sure ID node exists. */
1243 (void)add_id_node(id);
1244 ID *id_cow = get_cow_id(id);
1245 if (adt->action != nullptr || !BLI_listbase_is_empty(&adt->nla_tracks)) {
1246 OperationNode *operation_node;
1247 /* Explicit entry operation. */
1249 operation_node->set_as_entry();
1250 /* All the evaluation nodes. */
1252 id, NodeType::ANIMATION, OperationCode::ANIMATION_EVAL, [id_cow](::Depsgraph *depsgraph) {
1254 });
1255 /* Explicit exit operation. */
1257 operation_node->set_as_exit();
1258 }
1259 /* NLA strips contain actions. */
1260 LISTBASE_FOREACH (NlaTrack *, nlt, &adt->nla_tracks) {
1261 build_animdata_nlastrip_targets(&nlt->strips);
1262 }
1263 /* Drivers. */
1264 int driver_index = 0;
1265 LISTBASE_FOREACH (FCurve *, fcu, &adt->drivers) {
1266 /* create driver */
1267 build_driver(id, fcu, driver_index++);
1268 }
1269}
1270
1272{
1273 LISTBASE_FOREACH (NlaStrip *, strip, strips) {
1274 if (strip->act != nullptr) {
1275 build_action(strip->act);
1276 }
1277 else if (strip->strips.first != nullptr) {
1278 build_animdata_nlastrip_targets(&strip->strips);
1279 }
1280 }
1281}
1282
1284{
1285 /* GPU materials might use an animated image. However, these materials have no been built yet so
1286 * we have to check if they might be created during evaluation. */
1287 bool has_image_animation = false;
1288 if (ELEM(GS(id->name), ID_MA, ID_WO)) {
1290 if (ntree != nullptr && ntree->runtime->runtime_flag & NTREE_RUNTIME_FLAG_HAS_IMAGE_ANIMATION)
1291 {
1292 has_image_animation = true;
1293 }
1294 }
1295
1296 if (has_image_animation || BKE_image_user_id_has_animation(id)) {
1297 ID *id_cow = get_cow_id(id);
1299 id,
1302 [id_cow](::Depsgraph *depsgraph) { BKE_image_user_id_eval_animation(depsgraph, id_cow); });
1303 }
1304}
1305
1314
1315void DepsgraphNodeBuilder::build_driver(ID *id, FCurve *fcurve, int driver_index)
1316{
1317 /* Create data node for this driver */
1318 ID *id_cow = get_cow_id(id);
1319
1320 /* TODO(sergey): ideally we could pass the copy-on-eval of fcu, but since it
1321 * has not yet been allocated at this point we can't. As a workaround
1322 * the animation systems allocates an array so we can do a fast lookup
1323 * with the driver index. */
1325 id,
1328 [id_cow, driver_index, fcurve](::Depsgraph *depsgraph) {
1329 BKE_animsys_eval_driver(depsgraph, id_cow, driver_index, fcurve);
1330 },
1331 fcurve->rna_path ? fcurve->rna_path : "",
1332 fcurve->array_index);
1333 build_driver_variables(id, fcurve);
1334}
1335
1337{
1338 PointerRNA id_ptr = RNA_id_pointer_create(id);
1339
1340 build_driver_id_property(id_ptr, fcurve->rna_path);
1341
1342 DriverTargetContext driver_target_context;
1343 driver_target_context.scene = graph_->scene;
1344 driver_target_context.view_layer = graph_->view_layer;
1345
1346 LISTBASE_FOREACH (DriverVar *, dvar, &fcurve->driver->variables) {
1348 PointerRNA target_prop;
1349 if (!driver_get_target_property(&driver_target_context, dvar, dtar, &target_prop)) {
1350 continue;
1351 }
1352
1353 /* Property is always expected to be resolved to a non-null RNA property, which is always
1354 * relative to some ID. */
1355 BLI_assert(target_prop.owner_id);
1356
1357 ID *target_id = target_prop.owner_id;
1358
1359 build_id(target_id);
1360 build_driver_id_property(target_prop, dtar->rna_path);
1361
1362 /* For rna_path based variables: */
1363 if ((dtar->flag & DTAR_FLAG_STRUCT_REF) == 0) {
1364 /* Handle all other cameras used by the scene timeline if applicable. */
1365 if (const char *camera_path = get_rna_path_relative_to_scene_camera(
1366 scene_, target_prop, dtar->rna_path))
1367 {
1369 }
1370 }
1371 }
1373 }
1374}
1375
1377 const char *camera_path)
1378{
1379 /* This skips scene->camera, which was already handled by the caller. */
1380 LISTBASE_FOREACH (TimeMarker *, marker, &scene->markers) {
1381 if (!ELEM(marker->camera, nullptr, scene->camera)) {
1382 PointerRNA camera_ptr = RNA_id_pointer_create(&marker->camera->id);
1383 build_driver_id_property(camera_ptr, camera_path);
1384 }
1385 }
1386}
1387
1389 const char *rna_path_from_target_prop)
1390{
1391 if (rna_path_from_target_prop == nullptr || rna_path_from_target_prop[0] == '\0') {
1392 return;
1393 }
1394
1396 PropertyRNA *prop;
1397 int index;
1398 if (!RNA_path_resolve_full(&target_prop, rna_path_from_target_prop, &ptr, &prop, &index)) {
1399 return;
1400 }
1401 if (prop == nullptr) {
1402 return;
1403 }
1405 return;
1406 }
1407 if (ptr.owner_id) {
1409 }
1410 const char *prop_identifier = RNA_property_identifier((PropertyRNA *)prop);
1411 /* Custom properties of bones are placed in their components to improve granularity. */
1412 if (RNA_struct_is_a(ptr.type, &RNA_PoseBone)) {
1413 const bPoseChannel *pchan = static_cast<const bPoseChannel *>(ptr.data);
1416 pchan->name,
1418 nullptr,
1419 prop_identifier);
1420 }
1421 else {
1423 ptr.owner_id, NodeType::PARAMETERS, OperationCode::ID_PROPERTY, nullptr, prop_identifier);
1424 }
1425}
1426
1428{
1429 (void)add_id_node(id);
1430 OperationNode *op_node;
1431 /* Explicit entry. */
1433 op_node->set_as_entry();
1434 /* Generic evaluation node. */
1435
1436 if (ID_TYPE_SUPPORTS_PARAMS_WITHOUT_COW(GS(id->name))) {
1437 ID *id_cow = get_cow_id(id);
1439 id,
1442 [id_cow, id](::Depsgraph * /*depsgraph*/) { BKE_id_eval_properties_copy(id_cow, id); });
1443 }
1444 else {
1446 }
1447
1448 /* Explicit exit operation. */
1450 op_node->set_as_exit();
1451}
1452
1454{
1455 /* Object dimensions (bounding box) node. Will depend on both geometry and transform. */
1457}
1458
1460{
1461 if (built_map_.checkIsBuiltAndTag(world)) {
1462 return;
1463 }
1464 /* World itself. */
1465 add_id_node(&world->id);
1466 World *world_cow = get_cow_datablock(world);
1467 /* Shading update. */
1469 &world->id,
1472 [world_cow](::Depsgraph *depsgraph) { BKE_world_eval(depsgraph, world_cow); });
1473 build_idproperties(world->id.properties);
1474 /* Animation. */
1475 build_animdata(&world->id);
1476 build_parameters(&world->id);
1477 /* World's nodetree. */
1478 build_nodetree(world->nodetree);
1479}
1480
1481/* Rigidbody Simulation - Scene Level */
1483{
1484 RigidBodyWorld *rbw = scene->rigidbody_world;
1485 Scene *scene_cow = get_cow_datablock(scene);
1486
1502 /* Create nodes --------------------------------------------------------- */
1503
1504 /* XXX: is this the right component, or do we want to use another one
1505 * instead? */
1506
1507 /* Init/rebuild operation. */
1509 &scene->id,
1512 [scene_cow](::Depsgraph *depsgraph) { BKE_rigidbody_rebuild_sim(depsgraph, scene_cow); });
1513 /* Do-sim operation. */
1514 OperationNode *sim_node = add_operation_node(&scene->id,
1517 [scene_cow](::Depsgraph *depsgraph) {
1518 BKE_rigidbody_eval_simulation(depsgraph,
1519 scene_cow);
1520 });
1521 sim_node->set_as_entry();
1522 sim_node->set_as_exit();
1523 sim_node->owner->entry_operation = sim_node;
1524 /* Objects - simulation participants. */
1525 if (rbw->group != nullptr) {
1526 build_collection(nullptr, rbw->group);
1528 if (object->type != OB_MESH) {
1529 continue;
1530 }
1531 if (object->rigidbody_object == nullptr) {
1532 continue;
1533 }
1534
1535 if (object->rigidbody_object->type == RBO_TYPE_PASSIVE) {
1536 continue;
1537 }
1538
1539 /* Create operation for flushing results. */
1540 /* Object's transform component - where the rigidbody operation
1541 * lives. */
1542 Object *object_cow = get_cow_datablock(object);
1543 add_operation_node(&object->id,
1546 [scene_cow, object_cow](::Depsgraph *depsgraph) {
1547 BKE_rigidbody_object_sync_transforms(depsgraph, scene_cow, object_cow);
1548 });
1549 }
1551 }
1552 /* Constraints. */
1553 if (rbw->constraints != nullptr) {
1555 RigidBodyCon *rbc = object->rigidbody_constraint;
1556 if (rbc == nullptr || rbc->ob1 == nullptr || rbc->ob2 == nullptr) {
1557 /* When either ob1 or ob2 is nullptr, the constraint doesn't work. */
1558 continue;
1559 }
1560 /* Make sure indirectly linked objects are fully built. */
1561 build_object(-1, object, DEG_ID_LINKED_INDIRECTLY, false);
1562 build_object(-1, rbc->ob1, DEG_ID_LINKED_INDIRECTLY, false);
1563 build_object(-1, rbc->ob2, DEG_ID_LINKED_INDIRECTLY, false);
1564 }
1566 }
1567}
1568
1569void DepsgraphNodeBuilder::build_particle_systems(Object *object, bool is_object_visible)
1570{
1584 /* Component for all particle systems. */
1586
1587 Object *ob_cow = get_cow_datablock(object);
1588 OperationNode *op_node;
1589 op_node = add_operation_node(
1590 psys_comp, OperationCode::PARTICLE_SYSTEM_INIT, [ob_cow](::Depsgraph *depsgraph) {
1592 });
1593 op_node->set_as_entry();
1594 /* Build all particle systems. */
1595 LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) {
1596 ParticleSettings *part = psys->part;
1597 /* Build particle settings operations.
1598 *
1599 * NOTE: The call itself ensures settings are only build once. */
1601 /* Particle system evaluation. */
1603 /* Keyed particle targets. */
1604 if (ELEM(part->phystype, PART_PHYS_KEYED, PART_PHYS_BOIDS)) {
1605 LISTBASE_FOREACH (ParticleTarget *, particle_target, &psys->targets) {
1606 if (ELEM(particle_target->ob, nullptr, object)) {
1607 continue;
1608 }
1609 build_object(-1, particle_target->ob, DEG_ID_LINKED_INDIRECTLY, is_object_visible);
1610 }
1611 }
1612 /* Visualization of particle system. */
1613 switch (part->ren_as) {
1614 case PART_DRAW_OB:
1615 if (part->instance_object != nullptr) {
1616 build_object(-1, part->instance_object, DEG_ID_LINKED_INDIRECTLY, is_object_visible);
1617 }
1618 break;
1619 case PART_DRAW_GR:
1620 if (part->instance_collection != nullptr) {
1621 build_collection(nullptr, part->instance_collection);
1622 }
1623 break;
1624 }
1625 }
1627 op_node->set_as_exit();
1628}
1629
1631{
1632 if (built_map_.checkIsBuiltAndTag(particle_settings)) {
1633 return;
1634 }
1635 /* Make sure we've got proper copied ID pointer. */
1636 add_id_node(&particle_settings->id);
1637 ParticleSettings *particle_settings_cow = get_cow_datablock(particle_settings);
1638 /* Animation data. */
1639 build_animdata(&particle_settings->id);
1640 build_parameters(&particle_settings->id);
1641 /* Parameters change. */
1642 OperationNode *op_node;
1643 op_node = add_operation_node(
1645 op_node->set_as_entry();
1646 add_operation_node(&particle_settings->id,
1649 [particle_settings_cow](::Depsgraph *depsgraph) {
1650 BKE_particle_settings_eval_reset(depsgraph, particle_settings_cow);
1651 });
1652 op_node = add_operation_node(
1654 op_node->set_as_exit();
1655 /* Texture slots. */
1656 for (MTex *mtex : particle_settings->mtex) {
1657 if (mtex == nullptr || mtex->tex == nullptr) {
1658 continue;
1659 }
1660 build_texture(mtex->tex);
1661 }
1662}
1663
1665{
1666 if (built_map_.checkIsBuiltAndTag(key)) {
1667 return;
1668 }
1670 build_animdata(&key->id);
1671 build_parameters(&key->id);
1672 /* This is an exit operation for the entire key datablock, is what is used
1673 * as dependency for modifiers evaluation. */
1675 /* Create per-key block properties, allowing tricky inter-dependencies for
1676 * drivers evaluation. */
1677 LISTBASE_FOREACH (KeyBlock *, key_block, &key->block) {
1679 &key->id, NodeType::PARAMETERS, OperationCode::PARAMETERS_EVAL, nullptr, key_block->name);
1680 }
1681}
1682
1683/* ObData Geometry Evaluation */
1684/* XXX: what happens if the datablock is shared! */
1686{
1687 OperationNode *op_node;
1688 Scene *scene_cow = get_cow_datablock(scene_);
1689 Object *object_cow = get_cow_datablock(object);
1690 /* Entry operation, takes care of initialization, and some other
1691 * relations which needs to be run prior actual geometry evaluation. */
1693 op_node->set_as_entry();
1694 /* Geometry evaluation. */
1695 op_node = add_operation_node(&object->id,
1698 [scene_cow, object_cow](::Depsgraph *depsgraph) {
1699 BKE_object_eval_uber_data(depsgraph, scene_cow, object_cow);
1700 });
1701 op_node->set_as_exit();
1702 /* Materials. */
1703 build_materials(object->mat, object->totcol);
1704 /* Point caches. */
1706 /* Geometry. */
1708 build_dimensions(object);
1709 /* Batch cache. */
1711 &object->id,
1714 [object_cow](::Depsgraph *depsgraph) { BKE_object_select_update(depsgraph, object_cow); });
1715}
1716
1718{
1719 if (built_map_.checkIsBuiltAndTag(obdata)) {
1720 return;
1721 }
1722 OperationNode *op_node;
1723 /* Make sure we've got an ID node before requesting evaluated pointer. */
1724 (void)add_id_node((ID *)obdata);
1725 ID *obdata_cow = get_cow_id(obdata);
1727 /* Animation. */
1728 build_animdata(obdata);
1729 /* ShapeKeys */
1730 Key *key = BKE_key_from_id(obdata);
1731 if (key) {
1732 build_shapekeys(key);
1733 }
1734 /* Nodes for result of obdata's evaluation, and geometry
1735 * evaluation on object. */
1736 const ID_Type id_type = GS(obdata->name);
1737 switch (id_type) {
1738 case ID_ME: {
1739 op_node = add_operation_node(obdata,
1742 [obdata_cow](::Depsgraph *depsgraph) {
1743 BKE_mesh_eval_geometry(depsgraph, (Mesh *)obdata_cow);
1744 });
1745 op_node->set_as_entry();
1746 break;
1747 }
1748 case ID_MB: {
1750 op_node->set_as_entry();
1751 break;
1752 }
1753 case ID_CU_LEGACY: {
1754 op_node = add_operation_node(obdata,
1757 [obdata_cow](::Depsgraph *depsgraph) {
1758 BKE_curve_eval_geometry(depsgraph, (Curve *)obdata_cow);
1759 });
1760 op_node->set_as_entry();
1761 Curve *cu = (Curve *)obdata;
1762 if (cu->bevobj != nullptr) {
1764 }
1765 if (cu->taperobj != nullptr) {
1767 }
1768 if (cu->textoncurve != nullptr) {
1770 }
1771 break;
1772 }
1773 case ID_LT: {
1774 op_node = add_operation_node(obdata,
1777 [obdata_cow](::Depsgraph *depsgraph) {
1779 });
1780 op_node->set_as_entry();
1781 break;
1782 }
1783
1784 case ID_CV: {
1785 Curves *curves_id = reinterpret_cast<Curves *>(obdata);
1786
1788 op_node->set_as_entry();
1789
1790 if (curves_id->surface != nullptr) {
1791 build_object(-1, curves_id->surface, DEG_ID_LINKED_INDIRECTLY, false);
1792 }
1793 break;
1794 }
1795 case ID_PT: {
1797 op_node->set_as_entry();
1798 break;
1799 }
1800 case ID_VO: {
1801 /* Volume frame update. */
1802 op_node = add_operation_node(obdata,
1805 [obdata_cow](::Depsgraph *depsgraph) {
1807 });
1808 op_node->set_as_entry();
1809 break;
1810 }
1811 case ID_GP: {
1813 op_node->set_as_entry();
1814 break;
1815 }
1816 default:
1817 BLI_assert_msg(0, "Should not happen");
1818 break;
1819 }
1821 op_node->set_as_exit();
1822 /* Parameters for driver sources. */
1823 build_parameters(obdata);
1824 /* Batch cache. */
1825 add_operation_node(obdata,
1828 [obdata_cow](::Depsgraph *depsgraph) {
1830 });
1831 /* Shading (No-Op).
1832 * Needed to allow the Material shading updates reach the Object. */
1834}
1835
1837{
1838 if (built_map_.checkIsBuiltAndTag(armature)) {
1839 return;
1840 }
1841 build_idproperties(armature->id.properties);
1842 build_animdata(&armature->id);
1843 build_parameters(&armature->id);
1844 /* This operation is no longer necessary, as it was updating things with the bone layers (which
1845 * got replaced by bone collections). However, it's still used by other depsgraph components as a
1846 * dependency, so for now the node itself is kept as a no-op.
1847 * TODO: remove this node & the references to it, if eventually it turns out we really don't need
1848 * this.
1849 */
1851 &armature->id, NodeType::ARMATURE, OperationCode::ARMATURE_EVAL, [](::Depsgraph *) {});
1852 build_armature_bones(&armature->bonebase);
1853 build_armature_bone_collections(armature->collections_span());
1854}
1855
1857{
1858 LISTBASE_FOREACH (Bone *, bone, bones) {
1859 build_idproperties(bone->prop);
1860 build_armature_bones(&bone->childbase);
1861 }
1862}
1863
1866{
1867 for (BoneCollection *bcoll : collections) {
1868 build_idproperties(bcoll->prop);
1869 }
1870}
1871
1873{
1874 if (built_map_.checkIsBuiltAndTag(camera)) {
1875 return;
1876 }
1877 build_idproperties(camera->id.properties);
1878 build_animdata(&camera->id);
1879 build_parameters(&camera->id);
1880 if (camera->dof.focus_object != nullptr) {
1881 build_object(-1, camera->dof.focus_object, DEG_ID_LINKED_INDIRECTLY, false);
1882 }
1883}
1884
1886{
1888 return;
1889 }
1893 /* light's nodetree */
1895
1896 Light *lamp_cow = get_cow_datablock(lamp);
1900 [lamp_cow](::Depsgraph *depsgraph) { BKE_light_eval(depsgraph, lamp_cow); });
1901}
1902
1904{
1905 build_idproperties(socket->prop);
1906
1907 if (socket->type == SOCK_OBJECT) {
1908 build_id((ID *)((bNodeSocketValueObject *)socket->default_value)->value);
1909 }
1910 else if (socket->type == SOCK_IMAGE) {
1911 build_id((ID *)((bNodeSocketValueImage *)socket->default_value)->value);
1912 }
1913 else if (socket->type == SOCK_COLLECTION) {
1914 build_id((ID *)((bNodeSocketValueCollection *)socket->default_value)->value);
1915 }
1916 else if (socket->type == SOCK_TEXTURE) {
1917 build_id((ID *)((bNodeSocketValueTexture *)socket->default_value)->value);
1918 }
1919 else if (socket->type == SOCK_MATERIAL) {
1920 build_id((ID *)((bNodeSocketValueMaterial *)socket->default_value)->value);
1921 }
1922}
1923
1925{
1926 if (ntree == nullptr) {
1927 return;
1928 }
1929 if (built_map_.checkIsBuiltAndTag(ntree)) {
1930 return;
1931 }
1932 /* nodetree itself */
1933 add_id_node(&ntree->id);
1934 /* General parameters. */
1935 build_parameters(&ntree->id);
1937 /* Animation, */
1938 build_animdata(&ntree->id);
1939 /* Output update. */
1941 if (ntree->type == NTREE_GEOMETRY) {
1942 ID *id_cow = get_cow_id(&ntree->id);
1943 add_operation_node(&ntree->id,
1946 [id_cow](::Depsgraph * /*depsgraph*/) {
1947 bNodeTree *ntree_cow = reinterpret_cast<bNodeTree *>(id_cow);
1948 bke::node_tree_runtime::preprocess_geometry_node_tree_for_evaluation(
1949 *ntree_cow);
1950 });
1951 }
1952
1953 /* nodetree's nodes... */
1954 for (bNode *bnode : ntree->all_nodes()) {
1955 build_idproperties(bnode->prop);
1956 LISTBASE_FOREACH (bNodeSocket *, socket, &bnode->inputs) {
1957 build_nodetree_socket(socket);
1958 }
1959 LISTBASE_FOREACH (bNodeSocket *, socket, &bnode->outputs) {
1960 build_nodetree_socket(socket);
1961 }
1962
1963 ID *id = bnode->id;
1964 if (id == nullptr) {
1965 continue;
1966 }
1967 ID_Type id_type = GS(id->name);
1968 if (id_type == ID_MA) {
1969 build_material((Material *)id);
1970 }
1971 else if (id_type == ID_TE) {
1972 build_texture((Tex *)id);
1973 }
1974 else if (id_type == ID_IM) {
1975 build_image((Image *)id);
1976 }
1977 else if (id_type == ID_OB) {
1978 /* TODO(sergey): Use visibility of owner of the node tree. */
1980 }
1981 else if (id_type == ID_SCE) {
1982 Scene *node_scene = (Scene *)id;
1983 build_scene_parameters(node_scene);
1984 /* Camera is used by defocus node.
1985 *
1986 * On the one hand it's annoying to always pull it in, but on another hand it's also annoying
1987 * to have hardcoded node-type exception here. */
1988 if (node_scene->camera != nullptr) {
1989 /* TODO(sergey): Use visibility of owner of the node tree. */
1990 build_object(-1, node_scene->camera, DEG_ID_LINKED_INDIRECTLY, true);
1991 }
1992 }
1993 else if (id_type == ID_TXT) {
1994 /* Ignore script nodes. */
1995 }
1996 else if (id_type == ID_MSK) {
1997 build_mask((Mask *)id);
1998 }
1999 else if (id_type == ID_MC) {
2001 }
2002 else if (id_type == ID_VF) {
2003 build_vfont((VFont *)id);
2004 }
2005 else if (ELEM(bnode->type, NODE_GROUP, NODE_CUSTOM_GROUP)) {
2006 bNodeTree *group_ntree = (bNodeTree *)id;
2007 build_nodetree(group_ntree);
2008 }
2009 else {
2010 /* Ignore this case. It can happen when the node type is not known currently. Either because
2011 * it belongs to an add-on or because it comes from a different Blender version that does
2012 * support the ID type here already. */
2013 }
2014 }
2015
2016 /* Needed for interface cache. */
2017 ntree->ensure_interface_cache();
2018 for (bNodeTreeInterfaceSocket *socket : ntree->interface_inputs()) {
2019 build_idproperties(socket->properties);
2020 }
2021 for (bNodeTreeInterfaceSocket *socket : ntree->interface_outputs()) {
2022 build_idproperties(socket->properties);
2023 }
2024
2025 /* TODO: link from nodetree to owner_component? */
2026}
2027
2029{
2030 if (built_map_.checkIsBuiltAndTag(material)) {
2031 return;
2032 }
2033 /* Material itself. */
2034 add_id_node(&material->id);
2035 Material *material_cow = get_cow_datablock(material);
2036 /* Shading update. */
2038 &material->id,
2041 [material_cow](::Depsgraph *depsgraph) { BKE_material_eval(depsgraph, material_cow); });
2042 build_idproperties(material->id.properties);
2043 /* Material animation. */
2044 build_animdata(&material->id);
2045 build_parameters(&material->id);
2046 /* Material's nodetree. */
2047 build_nodetree(material->nodetree);
2048}
2049
2050void DepsgraphNodeBuilder::build_materials(Material **materials, int num_materials)
2051{
2052 for (int i = 0; i < num_materials; i++) {
2053 if (materials[i] == nullptr) {
2054 continue;
2055 }
2056 build_material(materials[i]);
2057 }
2058}
2059
2061{
2062 if (built_map_.checkIsBuiltAndTag(texture)) {
2063 return;
2064 }
2065 /* Texture itself. */
2066 add_id_node(&texture->id);
2067 build_idproperties(texture->id.properties);
2068 build_animdata(&texture->id);
2069 build_parameters(&texture->id);
2070 /* Texture's nodetree. */
2071 build_nodetree(texture->nodetree);
2072 /* Special cases for different IDs which texture uses. */
2073 if (texture->type == TEX_IMAGE) {
2074 if (texture->ima != nullptr) {
2075 build_image(texture->ima);
2076 }
2077 }
2080}
2081
2083{
2084 if (built_map_.checkIsBuiltAndTag(image)) {
2085 return;
2086 }
2087 build_parameters(&image->id);
2088 build_idproperties(image->id.properties);
2091}
2092
2094{
2095 if (built_map_.checkIsBuiltAndTag(cache_file)) {
2096 return;
2097 }
2098 ID *cache_file_id = &cache_file->id;
2099 add_id_node(cache_file_id);
2100 CacheFile *cache_file_cow = get_cow_datablock(cache_file);
2101 build_idproperties(cache_file_id->properties);
2102 /* Animation, */
2103 build_animdata(cache_file_id);
2104 build_parameters(cache_file_id);
2105 /* Cache evaluation itself. */
2106 add_operation_node(cache_file_id,
2109 [bmain = bmain_, cache_file_cow](::Depsgraph *depsgraph) {
2110 BKE_cachefile_eval(bmain, depsgraph, cache_file_cow);
2111 });
2112}
2113
2115{
2116 if (built_map_.checkIsBuiltAndTag(mask)) {
2117 return;
2118 }
2119 ID *mask_id = &mask->id;
2120 Mask *mask_cow = (Mask *)ensure_cow_id(mask_id);
2121 build_idproperties(mask->id.properties);
2122 /* F-Curve based animation. */
2123 build_animdata(mask_id);
2124 build_parameters(mask_id);
2125 /* Animation based on mask's shapes. */
2127 mask_id,
2130 [mask_cow](::Depsgraph *depsgraph) { BKE_mask_eval_animation(depsgraph, mask_cow); });
2131 /* Final mask evaluation. */
2133 mask_id, NodeType::PARAMETERS, OperationCode::MASK_EVAL, [mask_cow](::Depsgraph *depsgraph) {
2135 });
2136 /* Build parents. */
2137 LISTBASE_FOREACH (MaskLayer *, mask_layer, &mask->masklayers) {
2138 LISTBASE_FOREACH (MaskSpline *, spline, &mask_layer->splines) {
2139 for (int i = 0; i < spline->tot_point; i++) {
2140 MaskSplinePoint *point = &spline->points[i];
2141 MaskParent *parent = &point->parent;
2142 if (parent == nullptr || parent->id == nullptr) {
2143 continue;
2144 }
2145 build_id(parent->id);
2146 }
2147 }
2148 }
2149}
2150
2152{
2154 return;
2155 }
2156
2157 ID *linestyle_id = &linestyle->id;
2158 build_parameters(linestyle_id);
2160 build_animdata(linestyle_id);
2162}
2163
2165{
2166 if (built_map_.checkIsBuiltAndTag(clip)) {
2167 return;
2168 }
2169 ID *clip_id = &clip->id;
2170 MovieClip *clip_cow = (MovieClip *)ensure_cow_id(clip_id);
2172 /* Animation. */
2173 build_animdata(clip_id);
2174 build_parameters(clip_id);
2175 /* Movie clip evaluation. */
2176 add_operation_node(clip_id,
2179 [bmain = bmain_, clip_cow](::Depsgraph *depsgraph) {
2180 BKE_movieclip_eval_update(depsgraph, bmain, clip_cow);
2181 });
2182}
2183
2185{
2186 if (built_map_.checkIsBuiltAndTag(probe)) {
2187 return;
2188 }
2189 /* Placeholder so we can add relations and tag ID node for update. */
2192 build_animdata(&probe->id);
2193 build_parameters(&probe->id);
2194}
2195
2197{
2198 if (built_map_.checkIsBuiltAndTag(speaker)) {
2199 return;
2200 }
2201 /* Placeholder so we can add relations and tag ID node for update. */
2204 build_animdata(&speaker->id);
2205 build_parameters(&speaker->id);
2206 if (speaker->sound != nullptr) {
2207 build_sound(speaker->sound);
2208 }
2209}
2210
2212{
2213 if (built_map_.checkIsBuiltAndTag(sound)) {
2214 return;
2215 }
2216 add_id_node(&sound->id);
2217 bSound *sound_cow = get_cow_datablock(sound);
2218 add_operation_node(&sound->id,
2221 [bmain = bmain_, sound_cow](::Depsgraph *depsgraph) {
2222 BKE_sound_evaluate(depsgraph, bmain, sound_cow);
2223 });
2225 build_animdata(&sound->id);
2226 build_parameters(&sound->id);
2227}
2228
2239
2240static bool seq_node_build_cb(Sequence *seq, void *user_data)
2241{
2242 DepsgraphNodeBuilder *nb = (DepsgraphNodeBuilder *)user_data;
2243 nb->build_idproperties(seq->prop);
2244 if (seq->sound != nullptr) {
2245 nb->build_sound(seq->sound);
2246 }
2247 if (seq->scene != nullptr) {
2248 nb->build_scene_parameters(seq->scene);
2249 }
2250 if (seq->type == SEQ_TYPE_SCENE && seq->scene != nullptr) {
2251 if (seq->flag & SEQ_SCENE_STRIPS) {
2252 nb->build_scene_sequencer(seq->scene);
2253 }
2254 ViewLayer *sequence_view_layer = BKE_view_layer_default_render(seq->scene);
2255 nb->build_scene_speakers(seq->scene, sequence_view_layer);
2256 }
2257 /* TODO(sergey): Movie clip, scene, camera, mask. */
2258 return true;
2259}
2260
2262{
2263 if (scene->ed == nullptr) {
2264 return;
2265 }
2267 return;
2268 }
2269 build_scene_audio(scene);
2270 Scene *scene_cow = get_cow_datablock(scene);
2271 add_operation_node(&scene->id,
2274 [scene_cow](::Depsgraph *depsgraph) {
2275 SEQ_eval_sequences(depsgraph, scene_cow, &scene_cow->ed->seqbase);
2276 });
2277 /* Make sure data for sequences is in the graph. */
2278 SEQ_for_each_callback(&scene->ed->seqbase, seq_node_build_cb, this);
2279}
2280
2282{
2284 return;
2285 }
2286
2287 OperationNode *audio_entry_node = add_operation_node(
2289 audio_entry_node->set_as_entry();
2290
2292
2293 Scene *scene_cow = get_cow_datablock(scene);
2294 add_operation_node(&scene->id,
2297 [scene_cow](::Depsgraph *depsgraph) {
2298 BKE_scene_update_tag_audio_volume(depsgraph, scene_cow);
2299 });
2300}
2301
2303{
2304 BKE_view_layer_synced_ensure(scene, view_layer);
2306 Object *object = base->object;
2307 if (object->type != OB_SPEAKER || !need_pull_base_into_graph(base)) {
2308 continue;
2309 }
2310 /* NOTE: Can not use base because it does not belong to a current view layer. */
2311 build_object(-1, base->object, DEG_ID_LINKED_INDIRECTLY, true);
2312 }
2313}
2314
2315/* **** ID traversal callbacks functions **** */
2316
2318 Object * /*object*/,
2319 ID **idpoin,
2320 int /*cb_flag*/)
2321{
2322 BuilderWalkUserData *data = (BuilderWalkUserData *)user_data;
2323 ID *id = *idpoin;
2324 if (id == nullptr) {
2325 return;
2326 }
2327 switch (GS(id->name)) {
2328 case ID_OB:
2329 data->builder->build_object(-1, (Object *)id, DEG_ID_LINKED_INDIRECTLY, false);
2330 break;
2331 default:
2332 data->builder->build_id(id);
2333 break;
2334 }
2335}
2336
2338 ID **idpoin,
2339 bool /*is_reference*/,
2340 void *user_data)
2341{
2342 BuilderWalkUserData *data = (BuilderWalkUserData *)user_data;
2343 ID *id = *idpoin;
2344 if (id == nullptr) {
2345 return;
2346 }
2347 switch (GS(id->name)) {
2348 case ID_OB:
2349 data->builder->build_object(-1, (Object *)id, DEG_ID_LINKED_INDIRECTLY, false);
2350 break;
2351 default:
2352 data->builder->build_id(id);
2353 break;
2354 }
2355}
2356
2357} // namespace blender::deg
Blender kernel action and pose functionality.
AnimData * BKE_animdata_from_id(const ID *id)
Definition anim_data.cc:89
void BKE_animsys_eval_animdata(struct Depsgraph *depsgraph, struct ID *id)
Definition anim_sys.cc:4187
void BKE_animsys_eval_driver(struct Depsgraph *depsgraph, struct ID *id, int driver_index, struct FCurve *fcu_orig)
Definition anim_sys.cc:4222
void BKE_cachefile_eval(Main *bmain, Depsgraph *depsgraph, CacheFile *cache_file)
Definition cachefile.cc:336
#define FOREACH_COLLECTION_OBJECT_RECURSIVE_END
#define FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(_collection, _object)
void BKE_constraints_id_loop(struct ListBase *list, ConstraintIDFunc func, const int flag, void *userdata)
void BKE_curve_eval_geometry(Depsgraph *depsgraph, Curve *curve)
Definition curve.cc:5492
bool driver_get_target_property(const DriverTargetContext *driver_target_context, struct DriverVar *dvar, struct DriverTarget *dtar, struct PointerRNA *r_prop)
#define DRIVER_TARGETS_USED_LOOPER_BEGIN(dvar)
#define DRIVER_TARGETS_LOOPER_END
void BKE_gpencil_modifiers_foreach_ID_link(struct Object *ob, GreasePencilIDWalkFunc walk, void *user_data)
Low-level operations for grease pencil.
void IDP_foreach_property(IDProperty *id_property_root, int type_filter, blender::FunctionRef< void(IDProperty *id_property)> callback)
bool BKE_image_user_id_has_animation(ID *id)
void BKE_image_user_id_eval_animation(Depsgraph *depsgraph, ID *id)
Key * BKE_key_from_id(ID *id)
Definition key.cc:1800
void BKE_lattice_eval_geometry(Depsgraph *depsgraph, Lattice *latt)
Definition lattice.cc:703
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
ViewLayer * BKE_view_layer_default_render(const Scene *scene)
ListBase * BKE_view_layer_object_bases_get(ViewLayer *view_layer)
#define MAIN_ID_SESSION_UID_UNSET
void BKE_id_eval_properties_copy(ID *id_cow, ID *id)
@ IDWALK_RET_STOP_ITER
@ IDWALK_RET_NOP
void BKE_library_foreach_ID_link(Main *bmain, ID *id, blender::FunctionRef< LibraryIDLinkCallback > callback, void *user_data, int flag)
Definition lib_query.cc:416
@ IDWALK_NOP
@ IDWALK_READONLY
@ IDWALK_IGNORE_EMBEDDED_ID
General operations, lookup, etc. for blender lights.
void BKE_mask_eval_update(struct Depsgraph *depsgraph, struct Mask *mask)
void BKE_mask_eval_animation(struct Depsgraph *depsgraph, struct Mask *mask)
General operations, lookup, etc. for materials.
short * BKE_object_material_len_p(struct Object *ob)
struct Material *** BKE_object_material_array_p(struct Object *ob)
void BKE_mesh_eval_geometry(Depsgraph *depsgraph, Mesh *mesh)
void void void BKE_modifiers_foreach_ID_link(Object *ob, IDWalkFunc walk, void *user_data)
void BKE_movieclip_eval_update(struct Depsgraph *depsgraph, struct Main *bmain, struct MovieClip *clip)
#define NODE_CUSTOM_GROUP
Definition BKE_node.hh:807
#define NODE_GROUP
Definition BKE_node.hh:800
General operations, lookup, etc. for blender objects.
void BKE_object_data_select_update(Depsgraph *depsgraph, ID *object_data)
void BKE_particle_system_eval_init(struct Depsgraph *depsgraph, struct Object *object)
bool BKE_ptcache_object_has(struct Scene *scene, struct Object *ob, int duplis)
API for Blender-side Rigid Body stuff.
void BKE_shaderfx_foreach_ID_link(struct Object *ob, ShaderFxIDWalkFunc walk, void *user_data)
Definition shader_fx.cc:240
Volume data-block.
void BKE_volume_eval_geometry(Depsgraph *depsgraph, Volume *volume)
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:57
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
#define LISTBASE_FOREACH(type, var, list)
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define LISTBASE_FOREACH_INDEX(type, var, list, index_var)
#define SET_FLAG_FROM_TEST(value, test, flag)
#define ELEM(...)
@ DAG_EVAL_VIEWPORT
#define ID_TYPE_USE_COPY_ON_EVAL(_id_type)
Definition DNA_ID.h:693
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1085
#define ID_TYPE_SUPPORTS_PARAMS_WITHOUT_COW(id_type)
Definition DNA_ID.h:698
@ ID_FLAG_EMBEDDED_DATA
Definition DNA_ID.h:725
@ ID_TAG_COPIED_ON_EVAL
Definition DNA_ID.h:964
ID_Type
@ ID_WM
@ ID_CA
@ ID_AR
@ ID_MC
@ ID_CF
@ ID_LI
@ ID_TE
@ ID_IM
@ ID_VO
@ ID_WS
@ ID_NT
@ ID_LA
@ ID_KE
@ ID_TXT
@ ID_SO
@ ID_SCE
@ ID_LS
@ ID_MSK
@ ID_CV
@ ID_PAL
@ ID_BR
@ ID_LP
@ ID_WO
@ ID_MA
@ ID_AC
@ ID_SCR
@ ID_CU_LEGACY
@ ID_GD_LEGACY
@ ID_VF
@ ID_ME
@ ID_IP
@ ID_GR
@ ID_SPK
@ ID_MB
@ ID_LT
@ ID_OB
@ ID_GP
@ ID_PA
@ ID_PT
@ ID_PC
@ IDP_TYPE_FILTER_ID
@ DTAR_FLAG_STRUCT_REF
Object groups, one object can be in many groups at once.
@ COLLECTION_HIDE_RENDER
@ COLLECTION_HIDE_VIEWPORT
@ eModifierFlag_UserModified
@ eModifierMode_Render
@ eModifierMode_Realtime
@ eModifierType_Nodes
@ NTREE_GEOMETRY
@ NTREE_RUNTIME_FLAG_HAS_IMAGE_ANIMATION
@ SOCK_TEXTURE
@ SOCK_MATERIAL
@ SOCK_IMAGE
@ SOCK_COLLECTION
@ SOCK_OBJECT
Object is a sort of wrapper for general info.
@ OB_SPEAKER
@ OB_LATTICE
@ OB_MBALL
@ OB_SURF
@ OB_CAMERA
@ OB_FONT
@ OB_GREASE_PENCIL
@ OB_ARMATURE
@ OB_LAMP
@ OB_MESH
@ OB_POINTCLOUD
@ OB_VOLUME
@ OB_CURVES_LEGACY
@ OB_GPENCIL_LEGACY
@ OB_CURVES
@ OB_LIGHTPROBE
@ PART_DRAW_GR
@ PART_DRAW_OB
@ PART_PHYS_KEYED
@ PART_PHYS_BOIDS
Types and defines for representing Rigid Body entities.
@ RBO_TYPE_PASSIVE
@ SEQ_TYPE_SCENE
@ SEQ_SCENE_STRIPS
@ TEX_IMAGE
Read Guarded memory(de)allocation.
void append(const T &value)
bool checkIsBuiltAndTag(ID *id, int tag=TAG_COMPLETE)
bool checkIsBuilt(ID *id, int tag=TAG_COMPLETE) const
virtual bool need_pull_base_into_graph(const Base *base)
static const char * get_rna_path_relative_to_scene_camera(const Scene *scene, const PointerRNA &target_prop, const char *rna_path)
virtual bool is_modifier_visibility_animated(const Object *object, const ModifierData *modifier)
ComponentNode * find_component_node(const ID *id, NodeType comp_type, const char *comp_name="")
virtual void build_scene_parameters(Scene *scene)
virtual void build_scene_sequencer(Scene *scene)
virtual void build_object_data_camera(Object *object)
virtual void build_object_data_geometry(Object *object)
virtual void build_object_pointcache(Object *object)
static void modifier_walk(void *user_data, struct Object *object, struct ID **idpoin, int cb_flag)
virtual void build_world(World *world)
virtual void build_object(int base_index, Object *object, eDepsNode_LinkedState_Type linked_state, bool is_visible)
OperationNode * ensure_operation_node(ID *id, NodeType comp_type, const char *comp_name, OperationCode opcode, const DepsEvalOperationCb &op=nullptr, const char *name="", int name_tag=-1)
virtual void build_id(ID *id, bool force_be_visible=false)
virtual void build_freestyle_linestyle(FreestyleLineStyle *linestyle)
virtual void build_scene_speakers(Scene *scene, ViewLayer *view_layer)
virtual void build_cachefile(CacheFile *cache_file)
virtual void build_object_instance_collection(Object *object, bool is_object_visible)
virtual void build_object_data_speaker(Object *object)
OperationNode * add_operation_node(ComponentNode *comp_node, OperationCode opcode, const DepsEvalOperationCb &op=nullptr, const char *name="", int name_tag=-1)
virtual void build_vfont(VFont *vfont)
OperationNode * find_operation_node(const ID *id, NodeType comp_type, const char *comp_name, OperationCode opcode, const char *name="", int name_tag=-1)
virtual void build_object_data(Object *object)
virtual void build_particle_settings(ParticleSettings *part)
static void constraint_walk(bConstraint *constraint, ID **idpoin, bool is_reference, void *user_data)
virtual void build_driver_id_property(const PointerRNA &target_prop, const char *rna_path_from_target_prop)
virtual void build_particle_systems(Object *object, bool is_object_visible)
virtual void build_dimensions(Object *object)
virtual void build_armature(bArmature *armature)
virtual void build_scene_audio(Scene *scene)
ComponentNode * add_component_node(ID *id, NodeType comp_type, const char *comp_name="")
virtual void build_driver_variables(ID *id, FCurve *fcurve)
virtual void build_action(bAction *action)
virtual void build_driver_scene_camera_variable(Scene *scene, const char *camera_path)
virtual void build_animdata_nlastrip_targets(ListBase *strips)
virtual void build_material(Material *ma)
virtual void build_materials(Material **materials, int num_materials)
virtual void build_collection(LayerCollection *from_layer_collection, Collection *collection)
virtual void build_rigidbody(Scene *scene)
virtual void build_object_transform(Object *object)
virtual void build_light_linking_collection(Collection *collection)
virtual void build_movieclip(MovieClip *clip)
T * get_cow_datablock(const T *orig) const
virtual void build_object_data_light(Object *object)
virtual void build_image(Image *image)
virtual void build_speaker(Speaker *speaker)
virtual void build_sound(bSound *sound)
Vector< PersistentOperationKey > needs_update_operations_
virtual void build_object_data_geometry_datablock(ID *obdata)
DepsgraphNodeBuilder(Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache)
Vector< PersistentOperationKey > saved_entry_tags_
virtual void build_object_flags(int base_index, Object *object, eDepsNode_LinkedState_Type linked_state)
ID * get_cow_id(const ID *id_orig) const
virtual void build_rig(Object *object)
virtual void build_lightprobe(LightProbe *probe)
int foreach_id_cow_detect_need_for_update_callback(ID *id_cow_self, ID *id_pointer)
virtual void build_nodetree(bNodeTree *ntree)
virtual void build_idproperties(IDProperty *id_property)
virtual void build_camera(Camera *camera)
virtual void build_light(Light *lamp)
virtual void build_armature_bones(ListBase *bones)
virtual void build_driver(ID *id, FCurve *fcurve, int driver_index)
virtual void build_object_light_linking(Object *object)
bool has_operation_node(ID *id, NodeType comp_type, const char *comp_name, OperationCode opcode, const char *name="", int name_tag=-1)
virtual void build_nodetree_socket(bNodeSocket *socket)
virtual void build_armature_bone_collections(blender::Span< BoneCollection * > collections)
virtual void build_object_data_lightprobe(Object *object)
virtual void build_object_data_grease_pencil(Object *object)
virtual void build_object_constraints(Object *object)
virtual void build_object_shading(Object *object)
virtual void build_object_modifiers(Object *object)
virtual void build_object_from_layer(int base_index, Object *object, eDepsNode_LinkedState_Type linked_state)
void add_emitter(const Scene &scene, const Object &emitter)
const IDNode * id_node
FreestyleLineStyle linestyle
const Depsgraph * depsgraph
#define GS(x)
Definition iris.cc:202
void SEQ_for_each_callback(ListBase *seqbase, SeqForEachFunc callback, void *user_data)
Definition iterator.cc:43
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
bNodeTree ** node_tree_ptr_from_id(ID *id)
Definition node.cc:3712
static bool seq_node_build_cb(Sequence *seq, void *user_data)
uint64_t IDComponentsMask
bool rna_prop_affects_parameters_node(const PointerRNA *ptr, const PropertyRNA *prop)
function< void(::Depsgraph *)> DepsEvalOperationCb
void deg_evaluate_object_node_visibility(::Depsgraph *depsgraph, IDNode *id_node)
void deg_create_eval_copy(::Depsgraph *graph, const IDNode *id_node)
bool deg_eval_copy_is_expanded(const ID *id_cow)
void deg_free_eval_copy_datablock(ID *id_cow)
bool deg_eval_copy_is_needed(const ID *id_orig)
@ DEG_ID_LINKED_INDIRECTLY
static int foreach_id_cow_detect_need_for_update_callback(LibraryIDLinkCallbackData *cb_data)
void graph_id_tag_update(Main *bmain, Depsgraph *graph, ID *id, uint flags, eUpdateSource update_source)
bool RNA_struct_is_a(const StructRNA *type, const StructRNA *srna)
const char * RNA_property_identifier(const PropertyRNA *prop)
PointerRNA RNA_id_pointer_create(ID *id)
bool RNA_path_resolve_full(const PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index)
Definition rna_path.cc:537
unsigned int uint32_t
Definition stdint.h:80
bAction * action
ListBase drivers
ListBase nla_tracks
struct Object * bevobj
struct Object * textoncurve
struct Object * taperobj
struct Object * surface
struct ViewLayer * view_layer
char * rna_path
ChannelDriver * driver
int array_index
struct bNodeTree * nodetree
void * pointer
Definition DNA_ID.h:145
IDPropertyData data
Definition DNA_ID.h:168
Definition DNA_ID.h:413
int tag
Definition DNA_ID.h:434
IDProperty * properties
Definition DNA_ID.h:456
struct ID * orig_id
Definition DNA_ID.h:466
char name[66]
Definition DNA_ID.h:425
ListBase block
struct bNodeTree * nodetree
char parent[64]
ListBase modifiers
struct Object * parent
struct MTex * mtex[18]
ID * owner_id
Definition RNA_types.hh:40
StructRNA * type
Definition RNA_types.hh:41
void * data
Definition RNA_types.hh:42
struct Object * ob1
struct Object * ob2
struct Collection * constraints
struct Collection * group
struct Object * camera
struct Scene * scene
struct bSound * sound
struct IDProperty * prop
struct bSound * sound
IDProperty * prop
void * default_value
bNodeTreeRuntimeHandle * runtime
OperationNode * find_operation(OperationIDKey key) const
OperationNode * add_operation(const DepsEvalOperationCb &op, OperationCode opcode, const char *name="", int name_tag=-1)
virtual string identifier() const override
ID * get_cow_id(const ID *id_orig) const
Definition depsgraph.cc:242
IDNode * find_id_node(const ID *id) const
Definition depsgraph.cc:105
light_linking::Cache light_linking_cache
Definition depsgraph.hh:176
IDNode * add_id_node(ID *id, ID *id_cow_hint=nullptr)
Definition depsgraph.cc:110
OperationNodes operations
Definition depsgraph.hh:126
eEvaluationMode mode
Definition depsgraph.hh:136
TimeSourceNode * add_time_source()
Definition depsgraph.cc:86
Set< OperationNode * > entry_tags
Definition depsgraph.hh:120
IDComponentsMask previously_visible_components_mask
virtual void tag_update(Depsgraph *graph, eUpdateSource source) override
virtual string identifier() const override
float max
PointerRNA * ptr
Definition wm_files.cc:4126