Blender V4.5
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
10
12
13#include <algorithm>
14#include <cstdio>
15#include <cstdlib>
16
17#include "MEM_guardedalloc.h"
18
19#include "BLI_listbase.h"
20#include "BLI_span.hh"
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_key_types.h"
33#include "DNA_light_types.h"
35#include "DNA_linestyle_types.h"
36#include "DNA_mask_types.h"
37#include "DNA_material_types.h"
38#include "DNA_mesh_types.h"
39#include "DNA_movieclip_types.h"
40#include "DNA_node_types.h"
41#include "DNA_object_types.h"
42#include "DNA_particle_types.h"
43#include "DNA_rigidbody_types.h"
44#include "DNA_scene_types.h"
45#include "DNA_sequence_types.h"
46#include "DNA_sound_types.h"
47#include "DNA_speaker_types.h"
48#include "DNA_texture_types.h"
49#include "DNA_vfont_types.h"
50#include "DNA_world_types.h"
51
52#include "BKE_action.hh"
53#include "BKE_anim_data.hh"
54#include "BKE_animsys.h"
55#include "BKE_armature.hh"
57#include "BKE_cachefile.hh"
58#include "BKE_collection.hh"
59#include "BKE_constraint.h"
60#include "BKE_curve.hh"
61#include "BKE_effect.h"
62#include "BKE_fcurve_driver.h"
63#include "BKE_gpencil_legacy.h"
65#include "BKE_grease_pencil.hh"
66#include "BKE_idprop.hh"
67#include "BKE_idtype.hh"
68#include "BKE_image.hh"
69#include "BKE_key.hh"
70#include "BKE_lattice.hh"
71#include "BKE_layer.hh"
72#include "BKE_lib_id.hh"
73#include "BKE_lib_query.hh"
74#include "BKE_light.h"
75#include "BKE_mask.h"
76#include "BKE_material.hh"
77#include "BKE_mball.hh"
78#include "BKE_mesh.hh"
79#include "BKE_modifier.hh"
80#include "BKE_movieclip.h"
81#include "BKE_nla.hh"
82#include "BKE_node.hh"
83#include "BKE_node_runtime.hh"
84#include "BKE_object.hh"
85#include "BKE_particle.h"
86#include "BKE_pointcache.h"
87#include "BKE_rigidbody.h"
88#include "BKE_scene.hh"
89#include "BKE_shader_fx.h"
90#include "BKE_sound.h"
91#include "BKE_tracking.h"
92#include "BKE_volume.hh"
93#include "BKE_world.h"
94
95#include "RNA_access.hh"
96#include "RNA_path.hh"
97#include "RNA_prototypes.hh"
98#include "RNA_types.hh"
99
100#include "DEG_depsgraph.hh"
101#include "DEG_depsgraph_build.hh"
102
103#include "SEQ_iterator.hh"
104#include "SEQ_sequencer.hh"
105
110#include "intern/depsgraph.hh"
120
121namespace blender::deg {
122
123/* ************ */
124/* Node Builder */
125
126/* **** General purpose functions **** */
127
138
140{
141 /* Cannot be in an IDInfo destructor, as these COW IDs do not belong to the IDInfo data. */
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 }
148}
149
151{
153
154 const ID_Type id_type = GS(id->name);
155 IDNode *id_node = nullptr;
156 ID *id_cow = nullptr;
157 IDComponentsMask previously_visible_components_mask = 0;
158 uint32_t previous_eval_flags = 0;
159 DEGCustomDataMeshMasks previous_customdata_masks;
160 IDInfo *id_info = id_info_hash_.lookup_ptr(id->session_uid);
161 if (id_info != nullptr) {
162 id_cow = id_info->id_cow;
163 previously_visible_components_mask = id_info->previously_visible_components_mask;
164 previous_eval_flags = id_info->previous_eval_flags;
165 previous_customdata_masks = id_info->previous_customdata_masks;
166 /* Tag ID info to not free the evaluated ID pointer. */
167 id_info->id_cow = nullptr;
168 }
169 id_node = graph_->add_id_node(id, id_cow);
170 id_node->previously_visible_components_mask = previously_visible_components_mask;
171 id_node->previous_eval_flags = previous_eval_flags;
172 id_node->previous_customdata_masks = previous_customdata_masks;
173
174 /* NOTE: Zero number of components indicates that ID node was just created. */
175 const bool is_newly_created = id_node->components.is_empty();
176
177 if (is_newly_created) {
178 if (deg_eval_copy_is_needed(id_type)) {
180 OperationNode *op_cow = comp_cow->add_operation(
181 [id_node](::Depsgraph *depsgraph) { deg_create_eval_copy(depsgraph, id_node); },
183 graph_->operations.append(op_cow);
184 }
185
186 ComponentNode *visibility_component = id_node->add_component(NodeType::VISIBILITY);
187 OperationNode *visibility_operation;
188
189 /* Optimization: currently only objects need a special visibility evaluation. For the rest ID
190 * types keep the node as a NO-OP so that relations can still be routed, but without penalty
191 * during the graph evaluation. */
192 if (id_type == ID_OB) {
193 visibility_operation = visibility_component->add_operation(
194 [id_node](::Depsgraph *depsgraph) {
196 },
198 }
199 else {
200 visibility_operation = visibility_component->add_operation(nullptr,
202 }
203
204 /* Pin the node so that it and its relations are preserved by the unused nodes/relations
205 * deletion. This is mainly to make it easier to debug visibility. */
206 visibility_operation->flag |= (OperationFlag::DEPSOP_FLAG_PINNED |
208 graph_->operations.append(visibility_operation);
209 }
210 return id_node;
211}
212
214{
215 return graph_->find_id_node(id);
216}
217
219{
220 return graph_->add_time_source();
221}
222
224 NodeType comp_type,
225 const char *comp_name)
226{
227 IDNode *id_node = add_id_node(id);
228 ComponentNode *comp_node = id_node->add_component(comp_type, comp_name);
229 comp_node->owner = id_node;
230 return comp_node;
231}
232
234 const NodeType comp_type,
235 const char *comp_name)
236{
237 IDNode *id_node = find_id_node(id);
238 if (id_node == nullptr) {
239 return nullptr;
240 }
241 return id_node->find_component(comp_type, comp_name);
242}
243
245 OperationCode opcode,
246 const DepsEvalOperationCb &op,
247 const char *name,
248 int name_tag)
249{
250 OperationNode *op_node = comp_node->find_operation(opcode, name, name_tag);
251 if (op_node == nullptr) {
252 op_node = comp_node->add_operation(op, opcode, name, name_tag);
253 graph_->operations.append(op_node);
254 }
255 else {
256 fprintf(stderr,
257 "add_operation: Operation already exists - %s has %s at %p\n",
258 comp_node->identifier().c_str(),
259 op_node->identifier().c_str(),
260 op_node);
261 BLI_assert_msg(0, "Should not happen!");
262 }
263 return op_node;
264}
265
267 NodeType comp_type,
268 const char *comp_name,
269 OperationCode opcode,
270 const DepsEvalOperationCb &op,
271 const char *name,
272 int name_tag)
273{
274 ComponentNode *comp_node = add_component_node(id, comp_type, comp_name);
275 return add_operation_node(comp_node, opcode, op, name, name_tag);
276}
277
279 NodeType comp_type,
280 OperationCode opcode,
281 const DepsEvalOperationCb &op,
282 const char *name,
283 int name_tag)
284{
285 return add_operation_node(id, comp_type, "", opcode, op, name, name_tag);
286}
287
289 NodeType comp_type,
290 const char *comp_name,
291 OperationCode opcode,
292 const DepsEvalOperationCb &op,
293 const char *name,
294 int name_tag)
295{
296 OperationNode *operation = find_operation_node(id, comp_type, comp_name, opcode, name, name_tag);
297 if (operation != nullptr) {
298 return operation;
299 }
300 return add_operation_node(id, comp_type, comp_name, opcode, op, name, name_tag);
301}
302
304 NodeType comp_type,
305 OperationCode opcode,
306 const DepsEvalOperationCb &op,
307 const char *name,
308 int name_tag)
309{
310 OperationNode *operation = find_operation_node(id, comp_type, opcode, name, name_tag);
311 if (operation != nullptr) {
312 return operation;
313 }
314 return add_operation_node(id, comp_type, opcode, op, name, name_tag);
315}
316
318 NodeType comp_type,
319 const char *comp_name,
320 OperationCode opcode,
321 const char *name,
322 int name_tag)
323{
324 return find_operation_node(id, comp_type, comp_name, opcode, name, name_tag) != nullptr;
325}
326
328 const NodeType comp_type,
329 const OperationCode opcode)
330{
331 return find_operation_node(id, comp_type, opcode) != nullptr;
332}
333
335 NodeType comp_type,
336 const char *comp_name,
337 OperationCode opcode,
338 const char *name,
339 int name_tag)
340{
341 ComponentNode *comp_node = find_component_node(id, comp_type, comp_name);
342 if (comp_node == nullptr) {
343 return nullptr;
344 }
345 return comp_node->find_operation(opcode, name, name_tag);
346}
347
349 const ID *id, NodeType comp_type, OperationCode opcode, const char *name, int name_tag)
350{
351 return find_operation_node(id, comp_type, "", opcode, name, name_tag);
352}
353
359
361{
362 return graph_->get_cow_id(id_orig);
363}
364
366{
367 if (id_orig->tag & ID_TAG_COPIED_ON_EVAL) {
368 /* ID is already remapped to copy-on-evaluation. */
369 return id_orig;
370 }
371 IDNode *id_node = add_id_node(id_orig);
372 return id_node->id_cow;
373}
374
375/* **** Build functions for entity nodes **** */
376
378{
379 /* Store existing evaluated versions of datablock, so we can re-use
380 * them for new ID nodes. */
381 for (IDNode *id_node : graph_->id_nodes) {
382 /* It is possible that the ID does not need to have evaluated version in which case id_cow is
383 * the same as id_orig. Additionally, such ID might have been removed, which makes the check
384 * for whether id_cow is expanded to access freed memory. In order to deal with this we
385 * check whether an evaluated copy is needed based on a scalar value which does not lead to
386 * access of possibly deleted memory. */
387 IDInfo id_info{};
388 if (deg_eval_copy_is_needed(id_node->id_type) && id_node->id_orig != id_node->id_cow) {
389 if (deg_eval_copy_is_expanded(id_node->id_cow)) {
390 id_info.id_cow = id_node->id_cow;
391 }
392 else {
393 /* This ID has not been expanded yet. Don't reuse it like already expanded IDs. */
394 MEM_SAFE_FREE(id_node->id_cow);
395 }
396 }
398 id_info.previous_eval_flags = id_node->eval_flags;
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, std::move(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. */
416 graph_->clear_all_nodes();
417 graph_->operations.clear();
418 graph_->entry_tags.clear();
419}
420
421/* Utility callbacks for `BKE_library_foreach_ID_link`, used to detect when an evaluated ID is
422 * using 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 (ELEM(id_node->id_cow, id_node->id_orig, nullptr)) {
498 /* Node/ID with no copy-on-eval data, no need to check it. */
499 continue;
500 }
501 if (!deg_eval_copy_is_expanded(id_node->id_cow)) {
502 /* Copy-on-eval data is not expanded yet, so this is a newly added node/ID that has not been
503 * evaluated yet. */
504 continue;
505 }
506 if ((id_node->id_cow->recalc & ID_RECALC_SYNC_TO_EVAL) != 0) {
507 /* Node/ID already tagged for copy-on-eval flush, no need to check it. */
508 continue;
509 }
510 if ((id_node->id_cow->flag & ID_FLAG_EMBEDDED_DATA) != 0) {
511 /* For now, we assume embedded data are managed by their owner IDs and do not need to be
512 * checked here.
513 *
514 * NOTE: This exception somewhat weak, and ideally should not be needed. Currently however,
515 * embedded data are handled as full local (private) data of their owner IDs in part of
516 * Blender (like read/write code, including undo/redo), while depsgraph generally treat them
517 * as regular independent IDs. This leads to inconsistencies that can lead to bad level
518 * memory accesses.
519 *
520 * E.g. when undoing creation/deletion of a collection directly child of a scene's master
521 * collection, the scene itself is re-read in place, but its master collection becomes a
522 * completely new different pointer, and the existing copy-on-eval of the old master
523 * collection in the matching deg node is therefore pointing to fully invalid (freed) memory.
524 */
525 continue;
526 }
528 id_node->id_cow,
530 this,
532 }
533}
534
536{
537 for (const OperationKey &operation_key : saved_entry_tags_) {
538 OperationNode *operation_node = find_operation_node(operation_key);
539 if (operation_node == nullptr) {
540 continue;
541 }
542
543 /* Since the tag is coming from a saved copy of entry tags, this means
544 * that originally node was explicitly tagged for user update. */
546 }
547
548 /* Restore needs-update flags since the previous state of the dependency graph, ensuring the
549 * previously-skipped operations are properly re-evaluated when needed. */
550 for (const OperationKey &operation_key : needs_update_operations_) {
551 OperationNode *operation_node = find_operation_node(operation_key);
552 if (operation_node == nullptr) {
553 continue;
554 }
555 operation_node->flag |= DEPSOP_FLAG_NEEDS_UPDATE;
556 }
557}
558
560{
561 graph_->light_linking_cache.end_build(*graph_->scene);
564}
565
566void DepsgraphNodeBuilder::build_id(ID *id, const bool force_be_visible)
567{
568 if (id == nullptr) {
569 return;
570 }
571
572 const ID_Type id_type = GS(id->name);
573 switch (id_type) {
574 case ID_AC:
575 build_action((bAction *)id);
576 break;
577 case ID_AR:
579 break;
580 case ID_CA:
581 build_camera((Camera *)id);
582 break;
583 case ID_GR:
584 build_collection(nullptr, (Collection *)id);
585 break;
586 case ID_OB:
587 /* TODO(sergey): Get visibility from a "parent" somehow.
588 *
589 * NOTE: Using `false` visibility here should be fine, since if this
590 * driver affects on something invisible we don't really care if the
591 * driver gets evaluated (and even don't want this to force object
592 * to become visible).
593 *
594 * If this happened to be affecting visible object, then it is up to
595 * deg_graph_build_flush_visibility() to ensure visibility of the
596 * object is true. */
597 build_object(-1, (Object *)id, DEG_ID_LINKED_INDIRECTLY, force_be_visible);
598 break;
599 case ID_KE:
600 build_shapekeys((Key *)id);
601 break;
602 case ID_LA:
603 build_light((Light *)id);
604 break;
605 case ID_LP:
607 break;
608 case ID_NT:
610 break;
611 case ID_MA:
613 break;
614 case ID_TE:
615 build_texture((Tex *)id);
616 break;
617 case ID_IM:
618 build_image((Image *)id);
619 break;
620 case ID_WO:
621 build_world((World *)id);
622 break;
623 case ID_MSK:
624 build_mask((Mask *)id);
625 break;
626 case ID_LS:
628 break;
629 case ID_MC:
631 break;
632 case ID_ME:
633 case ID_MB:
634 case ID_CU_LEGACY:
635 case ID_LT:
636 case ID_GD_LEGACY:
637 case ID_CV:
638 case ID_PT:
639 case ID_VO:
640 case ID_GP:
642 break;
643 case ID_SPK:
644 build_speaker((Speaker *)id);
645 break;
646 case ID_SO:
647 build_sound((bSound *)id);
648 break;
649 case ID_TXT:
650 /* Not a part of dependency graph. */
651 break;
652 case ID_CF:
654 break;
655 case ID_SCE:
657 break;
658 case ID_PA:
660 break;
661
662 case ID_LI:
663 case ID_IP:
664 case ID_SCR:
665 case ID_VF:
666 case ID_BR:
667 case ID_WM:
668 case ID_PAL:
669 case ID_PC:
670 case ID_WS:
673 break;
674 }
675}
676
678{
679 if (built_map_.check_is_built_and_tag(id)) {
680 return;
681 }
682
684 build_animdata(id);
686}
687
689{
690 IDP_foreach_property(id_property, IDP_TYPE_FILTER_ID, [&](IDProperty *id_property) {
691 this->build_id(static_cast<ID *>(id_property->data.pointer));
692 });
693}
694
696 Collection *collection)
697{
698 const int visibility_flag = (graph_->mode == DAG_EVAL_VIEWPORT) ? COLLECTION_HIDE_VIEWPORT :
700 const bool is_collection_restricted = (collection->flag & visibility_flag);
701 const bool is_collection_visible = !is_collection_restricted && is_parent_collection_visible_;
702 IDNode *id_node;
703 if (built_map_.check_is_built_and_tag(collection)) {
704 id_node = find_id_node(&collection->id);
705 if (is_collection_visible && id_node->is_visible_on_build == false &&
706 id_node->is_collection_fully_expanded == true)
707 {
708 /* Collection became visible, make sure nested collections and
709 * objects are poked with the new visibility flag, since they
710 * might become visible too. */
711 }
712 else if (from_layer_collection == nullptr && !id_node->is_collection_fully_expanded) {
713 /* Initially collection was built from layer now, and was requested
714 * to not recurse into object. But now it's asked to recurse into all objects. */
715 }
716 else {
717 return;
718 }
719 }
720 else {
721 /* Collection itself. */
722 id_node = add_id_node(&collection->id);
723 id_node->is_visible_on_build = is_collection_visible;
724
726
727 build_idproperties(collection->id.properties);
728 build_parameters(&collection->id);
730 }
731 if (from_layer_collection != nullptr) {
732 /* If we came from layer collection we don't go deeper, view layer
733 * builder takes care of going deeper. */
734 return;
735 }
736 /* Backup state. */
737 const bool is_current_parent_collection_visible = is_parent_collection_visible_;
738 /* Modify state as we've entered new collection/ */
739 is_parent_collection_visible_ = is_collection_visible;
740 /* Build collection objects. */
741 LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) {
742 build_object(-1, cob->ob, DEG_ID_LINKED_INDIRECTLY, is_collection_visible);
743 }
744 /* Build child collections. */
745 LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
746 build_collection(nullptr, child->collection);
747 }
748 /* Restore state. */
749 is_parent_collection_visible_ = is_current_parent_collection_visible;
750 id_node->is_collection_fully_expanded = true;
751}
752
754 Object *object,
755 eDepsNode_LinkedState_Type linked_state,
756 bool is_visible)
757{
758 const bool has_object = built_map_.check_is_built_and_tag(object);
759
760 /* When there is already object in the dependency graph accumulate visibility an linked state
761 * flags. Only do it on the object itself (apart from very special cases) and leave dealing with
762 * visibility of dependencies to the visibility flush step which happens at the end of the build
763 * process. */
764 if (has_object) {
765 IDNode *id_node = find_id_node(&object->id);
766 if (id_node->linked_state == DEG_ID_LINKED_INDIRECTLY) {
767 build_object_flags(base_index, object, linked_state);
768 }
769 id_node->linked_state = std::max(id_node->linked_state, linked_state);
770 id_node->is_visible_on_build |= is_visible;
771 id_node->has_base |= (base_index != -1);
772
773 /* There is no relation path which will connect current object with all the ones which come
774 * via the instanced collection, so build the collection again. Note that it will do check
775 * whether visibility update is needed on its own. */
776 build_object_instance_collection(object, is_visible);
777
778 return;
779 }
780
781 /* Create ID node for object and begin init. */
782 IDNode *id_node = add_id_node(&object->id);
783 Object *object_cow = get_cow_datablock(object);
784 id_node->linked_state = linked_state;
785 /* NOTE: Scene is nullptr when building dependency graph for render pipeline.
786 * Probably need to assign that to something non-nullptr, but then the logic here will still be
787 * somewhat weird. */
788 if (scene_ != nullptr && object == scene_->camera) {
789 id_node->is_visible_on_build = true;
790 }
791 else {
792 id_node->is_visible_on_build = is_visible;
793 }
794 id_node->has_base |= (base_index != -1);
795
797
798 /* Various flags, flushing from bases/collections. */
799 build_object_from_layer(base_index, object, linked_state);
800 /* Transform. */
802 /* Parent. */
803 if (object->parent != nullptr) {
804 build_object(-1, object->parent, DEG_ID_LINKED_INDIRECTLY, is_visible);
805 }
806 /* Modifiers. */
808 /* Grease Pencil Modifiers. */
809 if (object->greasepencil_modifiers.first != nullptr) {
811 data.builder = this;
813 }
814 /* Shader FX. */
815 if (object->shader_fx.first != nullptr) {
817 data.builder = this;
819 }
820 /* Constraints. */
821 if (object->constraints.first != nullptr) {
823 data.builder = this;
825 }
826 /* Object data. */
827 build_object_data(object);
828 /* Parameters, used by both drivers/animation and also to inform dependency
829 * from object's data. */
830 build_parameters(&object->id);
832 /* Build animation data,
833 *
834 * Do it now because it's possible object data will affect
835 * on object's level animation, for example in case of rebuilding
836 * pose for proxy. */
837 build_animdata(&object->id);
838 /* Particle systems. */
839 if (object->particlesystem.first != nullptr) {
840 build_particle_systems(object, is_visible);
841 }
842 /* Force field Texture. */
843 if ((object->pd != nullptr) && (object->pd->forcefield == PFIELD_TEXTURE) &&
844 (object->pd->tex != nullptr))
845 {
846 build_texture(object->pd->tex);
847 }
848
849 /* Object instancing. */
850 if (object->instance_collection != nullptr) {
851 build_object_instance_collection(object, is_visible);
852
853 OperationNode *instancer_node = add_operation_node(
855 instancer_node->flag |= OperationFlag::DEPSOP_FLAG_PINNED;
856 }
857 OperationNode *instance_node = add_operation_node(
859 instance_node->flag |= OperationFlag::DEPSOP_FLAG_PINNED;
860
861 OperationNode *instance_geometry_node = add_operation_node(
863 instance_geometry_node->flag |= OperationFlag::DEPSOP_FLAG_PINNED;
864
866
867 build_object_shading(object);
868
869 /* Synchronization back to original object. */
870 add_operation_node(&object->id,
873 [object_cow](::Depsgraph *depsgraph) {
874 BKE_object_sync_to_original(depsgraph, object_cow);
875 });
876}
877
879 Object *object,
880 eDepsNode_LinkedState_Type linked_state)
881{
882
883 OperationNode *entry_node = add_operation_node(
885 entry_node->set_as_entry();
888 exit_node->set_as_exit();
889
890 build_object_flags(base_index, object, linked_state);
891}
892
894 Object *object,
895 eDepsNode_LinkedState_Type linked_state)
896{
897 if (base_index == -1) {
898 return;
899 }
900 Scene *scene_cow = get_cow_datablock(scene_);
901 Object *object_cow = get_cow_datablock(object);
902 const bool is_from_set = (linked_state == DEG_ID_LINKED_VIA_SET);
903 /* TODO(sergey): Is this really best component to be used? */
905 &object->id,
908 [view_layer_index = view_layer_index_, scene_cow, object_cow, base_index, is_from_set](
910 BKE_object_eval_eval_base_flags(
911 depsgraph, scene_cow, view_layer_index, object_cow, base_index, is_from_set);
912 });
913}
914
916{
917 if (object->instance_collection == nullptr) {
918 return;
919 }
920 const bool is_current_parent_collection_visible = is_parent_collection_visible_;
921 is_parent_collection_visible_ = is_object_visible;
922 build_collection(nullptr, object->instance_collection);
923 is_parent_collection_visible_ = is_current_parent_collection_visible;
924}
925
927{
928 if (BLI_listbase_is_empty(&object->modifiers)) {
929 return;
930 }
931
932 const ModifierMode modifier_mode = (graph_->mode == DAG_EVAL_VIEWPORT) ? eModifierMode_Realtime :
934
935 IDNode *id_node = find_id_node(&object->id);
936
937 add_operation_node(&object->id,
940 [id_node](::Depsgraph *depsgraph) {
941 deg_evaluate_object_modifiers_mode_node_visibility(depsgraph, id_node);
942 });
943
944 int modifier_index;
945 LISTBASE_FOREACH_INDEX (ModifierData *, modifier, &object->modifiers, modifier_index) {
946 OperationNode *modifier_node = add_operation_node(
947 &object->id, NodeType::GEOMETRY, OperationCode::MODIFIER, nullptr, modifier->name);
948 if (modifier->type == eModifierType_Nodes) {
949 modifier_node->evaluate =
950 [id_node, modifier_index, modifier_node](::Depsgraph * /*depsgraph*/) {
951 Object *ob_eval = reinterpret_cast<Object *>(id_node->id_cow);
952 ModifierData *md_eval = reinterpret_cast<ModifierData *>(
953 BLI_findlink(&ob_eval->modifiers, modifier_index));
954 /* Set flag that the modifier can check when it is evaluated. */
955 const bool is_user_modified = modifier_node->flag & DEPSOP_FLAG_USER_MODIFIED;
956 SET_FLAG_FROM_TEST(md_eval->flag, is_user_modified, eModifierFlag_UserModified);
957 };
958 }
959
960 /* Mute modifier mode if the modifier is not enabled for the dependency graph mode.
961 * This handles static (non-animated) mode of the modifier. */
962 if ((modifier->mode & modifier_mode) == 0) {
963 modifier_node->flag |= DEPSOP_FLAG_MUTE;
964 }
965
967 graph_->has_animated_visibility = true;
968 }
969 }
970
972 data.builder = this;
973
974 /* Temporarily set the collection visibility to false, relying on the visibility flushing code
975 * to flush the visibility from a modifier into collections it depends on. */
976 const bool is_current_parent_collection_visible = is_parent_collection_visible_;
979 is_parent_collection_visible_ = is_current_parent_collection_visible;
980}
981
983{
984 if (object->data == nullptr) {
985 return;
986 }
987 /* type-specific data. */
988 switch (object->type) {
989 case OB_MESH:
990 case OB_CURVES_LEGACY:
991 case OB_FONT:
992 case OB_SURF:
993 case OB_MBALL:
994 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_.check_is_built(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;
1043 build_light(lamp);
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
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
1175 graph_->light_linking_cache.add_emitter(*graph_->scene, *object);
1176
1177 if (object->light_linking) {
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. */
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 if (!BKE_nlatrack_is_enabled(*adt, *nlt)) {
1262 continue;
1263 }
1264 build_animdata_nlastrip_targets(&nlt->strips);
1265 }
1266 /* Drivers. */
1267 build_animdata_drivers(id, adt);
1268}
1269
1271{
1272 LISTBASE_FOREACH (NlaStrip *, strip, strips) {
1273 if (strip->act != nullptr) {
1274 build_action(strip->act);
1275 }
1276 else if (strip->strips.first != nullptr) {
1277 build_animdata_nlastrip_targets(&strip->strips);
1278 }
1279 }
1280}
1281
1283{
1284 /* GPU materials might use an animated image. However, these materials have no been built yet so
1285 * we have to check if they might be created during evaluation. */
1286 bool has_image_animation = false;
1287 if (ELEM(GS(id->name), ID_MA, ID_WO)) {
1289 if (ntree != nullptr && ntree->runtime->runtime_flag & NTREE_RUNTIME_FLAG_HAS_IMAGE_ANIMATION)
1290 {
1291 has_image_animation = true;
1292 }
1293 }
1294
1295 if (has_image_animation || BKE_image_user_id_has_animation(id)) {
1296 ID *id_cow = get_cow_id(id);
1298 id,
1302 }
1303}
1304
1306{
1307 if (built_map_.check_is_built_and_tag(action)) {
1308 return;
1309 }
1310
1311 /* To make it possible to use animation data as a variable for drivers: */
1312 build_parameters(&action->id);
1313
1316}
1317
1319{
1320 bool needs_unshare = false;
1321
1322 /* Drivers. */
1323 int driver_index;
1324 LISTBASE_FOREACH_INDEX (FCurve *, fcu, &adt->drivers, driver_index) {
1325 build_driver(id, fcu, driver_index);
1326 needs_unshare = needs_unshare || data_path_maybe_shared(*id, fcu->rna_path);
1327 }
1328
1329 if (!needs_unshare) {
1330 return;
1331 }
1332
1333 ID *id_cow = get_cow_id(id);
1337 });
1338}
1339
1340void DepsgraphNodeBuilder::build_driver(ID *id, FCurve *fcurve, int driver_index)
1341{
1342 /* Create data node for this driver */
1343 ID *id_cow = get_cow_id(id);
1344
1345 /* TODO(sergey): ideally we could pass the copy-on-eval of fcu, but since it
1346 * has not yet been allocated at this point we can't. As a workaround
1347 * the animation systems allocates an array so we can do a fast lookup
1348 * with the driver index. */
1350 id,
1353 [id_cow, driver_index, fcurve](::Depsgraph *depsgraph) {
1354 BKE_animsys_eval_driver(depsgraph, id_cow, driver_index, fcurve);
1355 },
1356 fcurve->rna_path ? fcurve->rna_path : "",
1357 fcurve->array_index);
1358 build_driver_variables(id, fcurve);
1359}
1360
1362{
1363 PointerRNA id_ptr = RNA_id_pointer_create(id);
1364
1365 build_driver_id_property(id_ptr, fcurve->rna_path);
1366
1367 DriverTargetContext driver_target_context;
1368 driver_target_context.scene = graph_->scene;
1369 driver_target_context.view_layer = graph_->view_layer;
1370
1371 LISTBASE_FOREACH (DriverVar *, dvar, &fcurve->driver->variables) {
1373 PointerRNA target_prop;
1374 if (!driver_get_target_property(&driver_target_context, dvar, dtar, &target_prop)) {
1375 continue;
1376 }
1377
1378 /* Property is always expected to be resolved to a non-null RNA property, which is always
1379 * relative to some ID. */
1380 BLI_assert(target_prop.owner_id);
1381
1382 ID *target_id = target_prop.owner_id;
1383
1384 build_id(target_id);
1385 build_driver_id_property(target_prop, dtar->rna_path);
1386
1387 /* For rna_path based variables: */
1388 if ((dtar->flag & DTAR_FLAG_STRUCT_REF) == 0) {
1389 /* Handle all other cameras used by the scene timeline if applicable. */
1390 if (const char *camera_path = get_rna_path_relative_to_scene_camera(
1391 scene_, target_prop, dtar->rna_path))
1392 {
1394 }
1395 }
1396 }
1398 }
1399}
1400
1402 const char *camera_path)
1403{
1404 /* This skips scene->camera, which was already handled by the caller. */
1405 LISTBASE_FOREACH (TimeMarker *, marker, &scene->markers) {
1406 if (!ELEM(marker->camera, nullptr, scene->camera)) {
1407 PointerRNA camera_ptr = RNA_id_pointer_create(&marker->camera->id);
1408 build_driver_id_property(camera_ptr, camera_path);
1409 }
1410 }
1411}
1412
1414 const char *rna_path_from_target_prop)
1415{
1416 if (rna_path_from_target_prop == nullptr || rna_path_from_target_prop[0] == '\0') {
1417 return;
1418 }
1419
1421 PropertyRNA *prop;
1422 int index;
1423 if (!RNA_path_resolve_full(&target_prop, rna_path_from_target_prop, &ptr, &prop, &index)) {
1424 return;
1425 }
1426 if (prop == nullptr) {
1427 return;
1428 }
1430 return;
1431 }
1432 if (ptr.owner_id) {
1433 build_id(ptr.owner_id);
1434 }
1435 const char *prop_identifier = RNA_property_identifier(prop);
1436 /* Custom properties of bones are placed in their components to improve granularity. */
1437 if (RNA_struct_is_a(ptr.type, &RNA_PoseBone)) {
1438 const bPoseChannel *pchan = static_cast<const bPoseChannel *>(ptr.data);
1439 ensure_operation_node(ptr.owner_id,
1441 pchan->name,
1443 nullptr,
1444 prop_identifier);
1445 }
1446 else {
1448 ptr.owner_id, NodeType::PARAMETERS, OperationCode::ID_PROPERTY, nullptr, prop_identifier);
1449 }
1450}
1451
1453{
1454 (void)add_id_node(id);
1455 OperationNode *op_node;
1456 /* Explicit entry. */
1458 op_node->set_as_entry();
1459 /* Generic evaluation node. */
1460
1462 ID *id_cow = get_cow_id(id);
1464 id,
1467 [id_cow, id](::Depsgraph * /*depsgraph*/) { BKE_id_eval_properties_copy(id_cow, id); });
1468 }
1469 else {
1471 }
1472
1473 /* Explicit exit operation. */
1475 op_node->set_as_exit();
1476}
1477
1479{
1480 /* Object dimensions (bounding box) node. Will depend on both geometry and transform. */
1482}
1483
1485{
1486 if (built_map_.check_is_built_and_tag(world)) {
1487 return;
1488 }
1489 /* World itself. */
1490 add_id_node(&world->id);
1491 World *world_cow = get_cow_datablock(world);
1492 /* Shading update. */
1494 &world->id,
1497 [world_cow](::Depsgraph *depsgraph) { BKE_world_eval(depsgraph, world_cow); });
1499 /* Animation. */
1500 build_animdata(&world->id);
1501 build_parameters(&world->id);
1502 /* World's nodetree. */
1503 build_nodetree(world->nodetree);
1504}
1505
1506/* Rigidbody Simulation - Scene Level */
1508{
1509 RigidBodyWorld *rbw = scene->rigidbody_world;
1510 Scene *scene_cow = get_cow_datablock(scene);
1511
1526
1527 /* Create nodes --------------------------------------------------------- */
1528
1529 /* XXX: is this the right component, or do we want to use another one
1530 * instead? */
1531
1532 /* Init/rebuild operation. */
1534 &scene->id,
1537 [scene_cow](::Depsgraph *depsgraph) { BKE_rigidbody_rebuild_sim(depsgraph, scene_cow); });
1538 /* Do-sim operation. */
1539 OperationNode *sim_node = add_operation_node(&scene->id,
1542 [scene_cow](::Depsgraph *depsgraph) {
1543 BKE_rigidbody_eval_simulation(depsgraph,
1544 scene_cow);
1545 });
1546 sim_node->set_as_entry();
1547 sim_node->set_as_exit();
1548 sim_node->owner->entry_operation = sim_node;
1549 /* Objects - simulation participants. */
1550 if (rbw->group != nullptr) {
1551 build_collection(nullptr, rbw->group);
1553 if (object->type != OB_MESH) {
1554 continue;
1555 }
1556 if (object->rigidbody_object == nullptr) {
1557 continue;
1558 }
1559
1560 if (object->rigidbody_object->type == RBO_TYPE_PASSIVE) {
1561 continue;
1562 }
1563
1564 /* Create operation for flushing results. */
1565 /* Object's transform component - where the rigidbody operation
1566 * lives. */
1567 Object *object_cow = get_cow_datablock(object);
1568 add_operation_node(&object->id,
1571 [scene_cow, object_cow](::Depsgraph *depsgraph) {
1572 BKE_rigidbody_object_sync_transforms(depsgraph, scene_cow, object_cow);
1573 });
1574 }
1576 }
1577 /* Constraints. */
1578 if (rbw->constraints != nullptr) {
1580 RigidBodyCon *rbc = object->rigidbody_constraint;
1581 if (rbc == nullptr || rbc->ob1 == nullptr || rbc->ob2 == nullptr) {
1582 /* When either ob1 or ob2 is nullptr, the constraint doesn't work. */
1583 continue;
1584 }
1585 /* Make sure indirectly linked objects are fully built. */
1586 build_object(-1, object, DEG_ID_LINKED_INDIRECTLY, false);
1587 build_object(-1, rbc->ob1, DEG_ID_LINKED_INDIRECTLY, false);
1588 build_object(-1, rbc->ob2, DEG_ID_LINKED_INDIRECTLY, false);
1589 }
1591 }
1592}
1593
1594void DepsgraphNodeBuilder::build_particle_systems(Object *object, bool is_object_visible)
1595{
1609 /* Component for all particle systems. */
1611
1612 Object *ob_cow = get_cow_datablock(object);
1613 OperationNode *op_node;
1614 op_node = add_operation_node(
1617 });
1618 op_node->set_as_entry();
1619 /* Build all particle systems. */
1620 LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) {
1621 ParticleSettings *part = psys->part;
1622 /* Build particle settings operations.
1623 *
1624 * NOTE: The call itself ensures settings are only build once. */
1626 /* Particle system evaluation. */
1627 add_operation_node(psys_comp, OperationCode::PARTICLE_SYSTEM_EVAL, nullptr, psys->name);
1628 /* Keyed particle targets. */
1630 LISTBASE_FOREACH (ParticleTarget *, particle_target, &psys->targets) {
1631 if (ELEM(particle_target->ob, nullptr, object)) {
1632 continue;
1633 }
1634 build_object(-1, particle_target->ob, DEG_ID_LINKED_INDIRECTLY, is_object_visible);
1635 }
1636 }
1637 /* Visualization of particle system. */
1638 switch (part->ren_as) {
1639 case PART_DRAW_OB:
1640 if (part->instance_object != nullptr) {
1641 build_object(-1, part->instance_object, DEG_ID_LINKED_INDIRECTLY, is_object_visible);
1642 }
1643 break;
1644 case PART_DRAW_GR:
1645 if (part->instance_collection != nullptr) {
1646 build_collection(nullptr, part->instance_collection);
1647 }
1648 break;
1649 }
1650 }
1652 op_node->set_as_exit();
1653}
1654
1656{
1657 if (built_map_.check_is_built_and_tag(particle_settings)) {
1658 return;
1659 }
1660 /* Make sure we've got proper copied ID pointer. */
1661 add_id_node(&particle_settings->id);
1662 ParticleSettings *particle_settings_cow = get_cow_datablock(particle_settings);
1663 /* Animation data. */
1664 build_animdata(&particle_settings->id);
1665 build_parameters(&particle_settings->id);
1666 /* Parameters change. */
1667 OperationNode *op_node;
1668 op_node = add_operation_node(
1670 op_node->set_as_entry();
1671 add_operation_node(&particle_settings->id,
1674 [particle_settings_cow](::Depsgraph *depsgraph) {
1675 BKE_particle_settings_eval_reset(depsgraph, particle_settings_cow);
1676 });
1677 op_node = add_operation_node(
1679 op_node->set_as_exit();
1680 /* Texture slots. */
1681 for (MTex *mtex : particle_settings->mtex) {
1682 if (mtex == nullptr || mtex->tex == nullptr) {
1683 continue;
1684 }
1685 build_texture(mtex->tex);
1686 }
1687}
1688
1690{
1691 if (built_map_.check_is_built_and_tag(key)) {
1692 return;
1693 }
1695 build_animdata(&key->id);
1696 build_parameters(&key->id);
1697 /* This is an exit operation for the entire key datablock, is what is used
1698 * as dependency for modifiers evaluation. */
1700 /* Create per-key block properties, allowing tricky inter-dependencies for
1701 * drivers evaluation. */
1702 LISTBASE_FOREACH (KeyBlock *, key_block, &key->block) {
1704 &key->id, NodeType::PARAMETERS, OperationCode::PARAMETERS_EVAL, nullptr, key_block->name);
1705 }
1706}
1707
1708/* ObData Geometry Evaluation */
1709/* XXX: what happens if the datablock is shared! */
1711{
1712 OperationNode *op_node;
1713 Scene *scene_cow = get_cow_datablock(scene_);
1714 Object *object_cow = get_cow_datablock(object);
1715 /* Entry operation, takes care of initialization, and some other
1716 * relations which needs to be run prior actual geometry evaluation. */
1718 op_node->set_as_entry();
1719 /* Geometry evaluation. */
1720 op_node = add_operation_node(&object->id,
1723 [scene_cow, object_cow](::Depsgraph *depsgraph) {
1724 BKE_object_eval_uber_data(depsgraph, scene_cow, object_cow);
1725 });
1726 op_node->set_as_exit();
1727 /* Materials. */
1728 build_materials(object->mat, object->totcol);
1729 /* Point caches. */
1731 /* Geometry. */
1733 build_dimensions(object);
1734 /* Batch cache. */
1736 &object->id,
1739 [object_cow](::Depsgraph *depsgraph) { BKE_object_select_update(depsgraph, object_cow); });
1740}
1741
1743{
1744 if (built_map_.check_is_built_and_tag(obdata)) {
1745 return;
1746 }
1747 OperationNode *op_node;
1748 /* Make sure we've got an ID node before requesting evaluated pointer. */
1749 (void)add_id_node(obdata);
1750 ID *obdata_cow = get_cow_id(obdata);
1752 /* Animation. */
1753 build_animdata(obdata);
1754 /* ShapeKeys */
1755 Key *key = BKE_key_from_id(obdata);
1756 if (key) {
1757 build_shapekeys(key);
1758 }
1759 /* Nodes for result of obdata's evaluation, and geometry
1760 * evaluation on object. */
1761 const ID_Type id_type = GS(obdata->name);
1762 switch (id_type) {
1763 case ID_ME: {
1764 op_node = add_operation_node(obdata,
1767 [obdata_cow](::Depsgraph *depsgraph) {
1768 BKE_mesh_eval_geometry(depsgraph, (Mesh *)obdata_cow);
1769 });
1770 op_node->set_as_entry();
1771 break;
1772 }
1773 case ID_MB: {
1775 op_node->set_as_entry();
1776 break;
1777 }
1778 case ID_CU_LEGACY: {
1779 op_node = add_operation_node(obdata,
1782 [obdata_cow](::Depsgraph *depsgraph) {
1783 BKE_curve_eval_geometry(depsgraph, (Curve *)obdata_cow);
1784 });
1785 op_node->set_as_entry();
1786 Curve *cu = (Curve *)obdata;
1787 if (cu->bevobj != nullptr) {
1789 }
1790 if (cu->taperobj != nullptr) {
1792 }
1793 if (cu->textoncurve != nullptr) {
1795 }
1796 break;
1797 }
1798 case ID_LT: {
1799 op_node = add_operation_node(obdata,
1802 [obdata_cow](::Depsgraph *depsgraph) {
1804 });
1805 op_node->set_as_entry();
1806 break;
1807 }
1808
1809 case ID_CV: {
1810 Curves *curves_id = reinterpret_cast<Curves *>(obdata);
1811
1813 op_node->set_as_entry();
1814
1815 if (curves_id->surface != nullptr) {
1816 build_object(-1, curves_id->surface, DEG_ID_LINKED_INDIRECTLY, false);
1817 }
1818 break;
1819 }
1820 case ID_PT: {
1822 op_node->set_as_entry();
1823 break;
1824 }
1825 case ID_VO: {
1826 /* Volume frame update. */
1827 op_node = add_operation_node(obdata,
1830 [obdata_cow](::Depsgraph *depsgraph) {
1832 });
1833 op_node->set_as_entry();
1834 break;
1835 }
1836 case ID_GP: {
1837 op_node = add_operation_node(obdata,
1840 [obdata_cow](::Depsgraph *depsgraph) {
1842 depsgraph, reinterpret_cast<GreasePencil *>(obdata_cow));
1843 });
1844 op_node->set_as_entry();
1845 break;
1846 }
1847 default:
1848 BLI_assert_msg(0, "Should not happen");
1849 break;
1850 }
1852 op_node->set_as_exit();
1853 /* Parameters for driver sources. */
1854 build_parameters(obdata);
1855 /* Batch cache. */
1856 add_operation_node(obdata,
1859 [obdata_cow](::Depsgraph *depsgraph) {
1861 });
1862 /* Shading (No-Op).
1863 * Needed to allow the Material shading updates reach the Object. */
1865}
1866
1868{
1869 if (built_map_.check_is_built_and_tag(armature)) {
1870 return;
1871 }
1872 build_idproperties(armature->id.properties);
1873 build_animdata(&armature->id);
1874 build_parameters(&armature->id);
1875 /* This operation is no longer necessary, as it was updating things with the bone layers (which
1876 * got replaced by bone collections). However, it's still used by other depsgraph components as a
1877 * dependency, so for now the node itself is kept as a no-op.
1878 * TODO: remove this node & the references to it, if eventually it turns out we really don't need
1879 * this.
1880 */
1883 build_armature_bones(&armature->bonebase);
1884 build_armature_bone_collections(armature->collections_span());
1885}
1886
1888{
1889 LISTBASE_FOREACH (Bone *, bone, bones) {
1890 build_idproperties(bone->prop);
1891 build_armature_bones(&bone->childbase);
1892 }
1893}
1894
1897{
1898 for (BoneCollection *bcoll : collections) {
1899 build_idproperties(bcoll->prop);
1900 }
1901}
1902
1904{
1905 if (built_map_.check_is_built_and_tag(camera)) {
1906 return;
1907 }
1909 build_animdata(&camera->id);
1910 build_parameters(&camera->id);
1911 if (camera->dof.focus_object != nullptr) {
1913 }
1914}
1915
1917{
1918 if (built_map_.check_is_built_and_tag(lamp)) {
1919 return;
1920 }
1922 build_animdata(&lamp->id);
1923 build_parameters(&lamp->id);
1924 /* light's nodetree */
1925 build_nodetree(lamp->nodetree);
1926
1927 Light *lamp_cow = get_cow_datablock(lamp);
1928 add_operation_node(&lamp->id,
1931 [lamp_cow](::Depsgraph *depsgraph) { BKE_light_eval(depsgraph, lamp_cow); });
1932}
1933
1935{
1936 build_idproperties(socket->prop);
1937
1938 if (socket->type == SOCK_OBJECT) {
1939 build_id((ID *)((bNodeSocketValueObject *)socket->default_value)->value);
1940 }
1941 else if (socket->type == SOCK_IMAGE) {
1942 build_id((ID *)((bNodeSocketValueImage *)socket->default_value)->value);
1943 }
1944 else if (socket->type == SOCK_COLLECTION) {
1945 build_id((ID *)((bNodeSocketValueCollection *)socket->default_value)->value);
1946 }
1947 else if (socket->type == SOCK_TEXTURE) {
1948 build_id((ID *)((bNodeSocketValueTexture *)socket->default_value)->value);
1949 }
1950 else if (socket->type == SOCK_MATERIAL) {
1951 build_id((ID *)((bNodeSocketValueMaterial *)socket->default_value)->value);
1952 }
1953}
1954
1956{
1957 if (ntree == nullptr) {
1958 return;
1959 }
1960 if (built_map_.check_is_built_and_tag(ntree)) {
1961 return;
1962 }
1963 /* nodetree itself */
1964 add_id_node(&ntree->id);
1965 /* General parameters. */
1966 build_parameters(&ntree->id);
1968 /* Animation, */
1969 build_animdata(&ntree->id);
1970 /* Output update. */
1972 if (ntree->type == NTREE_GEOMETRY) {
1973 ID *id_cow = get_cow_id(&ntree->id);
1974 add_operation_node(&ntree->id,
1977 [id_cow](::Depsgraph * /*depsgraph*/) {
1978 bNodeTree *ntree_cow = reinterpret_cast<bNodeTree *>(id_cow);
1979 bke::node_tree_runtime::preprocess_geometry_node_tree_for_evaluation(
1980 *ntree_cow);
1981 });
1982 }
1983
1984 /* nodetree's nodes... */
1985 for (bNode *bnode : ntree->all_nodes()) {
1986 build_idproperties(bnode->prop);
1987 LISTBASE_FOREACH (bNodeSocket *, socket, &bnode->inputs) {
1988 build_nodetree_socket(socket);
1989 }
1990 LISTBASE_FOREACH (bNodeSocket *, socket, &bnode->outputs) {
1991 build_nodetree_socket(socket);
1992 }
1993
1994 ID *id = bnode->id;
1995 if (id == nullptr) {
1996 continue;
1997 }
1998 ID_Type id_type = GS(id->name);
1999 if (id_type == ID_MA) {
2000 build_material((Material *)id);
2001 }
2002 else if (id_type == ID_TE) {
2003 build_texture((Tex *)id);
2004 }
2005 else if (id_type == ID_IM) {
2006 build_image((Image *)id);
2007 }
2008 else if (id_type == ID_OB) {
2009 /* TODO(sergey): Use visibility of owner of the node tree. */
2011 }
2012 else if (id_type == ID_SCE) {
2013 Scene *node_scene = (Scene *)id;
2014 build_scene_parameters(node_scene);
2015 /* Camera is used by defocus node.
2016 *
2017 * On the one hand it's annoying to always pull it in, but on another hand it's also annoying
2018 * to have hardcoded node-type exception here. */
2019 if (node_scene->camera != nullptr) {
2020 /* TODO(sergey): Use visibility of owner of the node tree. */
2021 build_object(-1, node_scene->camera, DEG_ID_LINKED_INDIRECTLY, true);
2022 }
2023 }
2024 else if (id_type == ID_TXT) {
2025 /* Ignore script nodes. */
2026 }
2027 else if (id_type == ID_MSK) {
2028 build_mask((Mask *)id);
2029 }
2030 else if (id_type == ID_MC) {
2032 }
2033 else if (id_type == ID_VF) {
2034 build_vfont((VFont *)id);
2035 }
2036 else if (id_type == ID_GR) {
2037 build_collection(nullptr, reinterpret_cast<Collection *>(id));
2038 }
2039 else if (bnode->is_group()) {
2040 bNodeTree *group_ntree = (bNodeTree *)id;
2041 build_nodetree(group_ntree);
2042 }
2043 else {
2044 /* Ignore this case. It can happen when the node type is not known currently. Either because
2045 * it belongs to an add-on or because it comes from a different Blender version that does
2046 * support the ID type here already. */
2047 }
2048 }
2049
2050 /* Needed for interface cache. */
2051 ntree->ensure_interface_cache();
2052 for (bNodeTreeInterfaceSocket *socket : ntree->interface_inputs()) {
2053 build_idproperties(socket->properties);
2054 }
2055 for (bNodeTreeInterfaceSocket *socket : ntree->interface_outputs()) {
2056 build_idproperties(socket->properties);
2057 }
2058
2059 /* TODO: link from nodetree to owner_component? */
2060}
2061
2063{
2064 if (built_map_.check_is_built_and_tag(material)) {
2065 return;
2066 }
2067 /* Material itself. */
2068 add_id_node(&material->id);
2069 Material *material_cow = get_cow_datablock(material);
2070 /* Shading update. */
2072 &material->id,
2075 [material_cow](::Depsgraph *depsgraph) { BKE_material_eval(depsgraph, material_cow); });
2076 build_idproperties(material->id.properties);
2077 /* Material animation. */
2078 build_animdata(&material->id);
2079 build_parameters(&material->id);
2080 /* Material's nodetree. */
2081 build_nodetree(material->nodetree);
2082}
2083
2084void DepsgraphNodeBuilder::build_materials(Material **materials, int num_materials)
2085{
2086 for (int i = 0; i < num_materials; i++) {
2087 if (materials[i] == nullptr) {
2088 continue;
2089 }
2090 build_material(materials[i]);
2091 }
2092}
2093
2095{
2096 if (built_map_.check_is_built_and_tag(texture)) {
2097 return;
2098 }
2099 /* Texture itself. */
2100 add_id_node(&texture->id);
2101 Tex *texture_cow = get_cow_datablock(texture);
2102 build_idproperties(texture->id.properties);
2103 build_animdata(&texture->id);
2105 /* Texture's nodetree. */
2106 build_nodetree(texture->nodetree);
2107 /* Special cases for different IDs which texture uses. */
2108 if (texture->type == TEX_IMAGE) {
2109 if (texture->ima != nullptr) {
2110 build_image(texture->ima);
2111 }
2112 }
2116 [texture_cow](::Depsgraph *depsgraph) {
2117 texture_cow->runtime.last_update = DEG_get_update_count(depsgraph);
2118 });
2119}
2120
2122{
2123 if (built_map_.check_is_built_and_tag(image)) {
2124 return;
2125 }
2126 build_parameters(&image->id);
2130}
2131
2133{
2134 if (built_map_.check_is_built_and_tag(cache_file)) {
2135 return;
2136 }
2137 ID *cache_file_id = &cache_file->id;
2138 add_id_node(cache_file_id);
2139 CacheFile *cache_file_cow = get_cow_datablock(cache_file);
2140 build_idproperties(cache_file_id->properties);
2141 /* Animation, */
2142 build_animdata(cache_file_id);
2143 build_parameters(cache_file_id);
2144 /* Cache evaluation itself. */
2145 add_operation_node(cache_file_id,
2148 [bmain = bmain_, cache_file_cow](::Depsgraph *depsgraph) {
2149 BKE_cachefile_eval(bmain, depsgraph, cache_file_cow);
2150 });
2151}
2152
2154{
2155 if (built_map_.check_is_built_and_tag(mask)) {
2156 return;
2157 }
2158 ID *mask_id = &mask->id;
2159 Mask *mask_cow = (Mask *)ensure_cow_id(mask_id);
2160 build_idproperties(mask->id.properties);
2161 /* F-Curve based animation. */
2162 build_animdata(mask_id);
2163 build_parameters(mask_id);
2164 /* Animation based on mask's shapes. */
2166 mask_id,
2169 [mask_cow](::Depsgraph *depsgraph) { BKE_mask_eval_animation(depsgraph, mask_cow); });
2170 /* Final mask evaluation. */
2174 });
2175 /* Build parents. */
2176 LISTBASE_FOREACH (MaskLayer *, mask_layer, &mask->masklayers) {
2177 LISTBASE_FOREACH (MaskSpline *, spline, &mask_layer->splines) {
2178 for (int i = 0; i < spline->tot_point; i++) {
2179 MaskSplinePoint *point = &spline->points[i];
2180 MaskParent *parent = &point->parent;
2181 if (parent == nullptr || parent->id == nullptr) {
2182 continue;
2183 }
2184 build_id(parent->id);
2185 }
2186 }
2187 }
2188}
2189
2191{
2192 if (built_map_.check_is_built_and_tag(linestyle)) {
2193 return;
2194 }
2195
2196 ID *linestyle_id = &linestyle->id;
2197 build_parameters(linestyle_id);
2198 build_idproperties(linestyle->id.properties);
2199 build_animdata(linestyle_id);
2200 build_nodetree(linestyle->nodetree);
2201}
2202
2204{
2205 if (built_map_.check_is_built_and_tag(clip)) {
2206 return;
2207 }
2208 ID *clip_id = &clip->id;
2209 MovieClip *clip_cow = (MovieClip *)ensure_cow_id(clip_id);
2211 /* Animation. */
2212 build_animdata(clip_id);
2213 build_parameters(clip_id);
2214 /* Movie clip evaluation. */
2215 add_operation_node(clip_id,
2218 [bmain = bmain_, clip_cow](::Depsgraph *depsgraph) {
2219 BKE_movieclip_eval_update(depsgraph, bmain, clip_cow);
2220 });
2221}
2222
2224{
2225 if (built_map_.check_is_built_and_tag(probe)) {
2226 return;
2227 }
2228 /* Placeholder so we can add relations and tag ID node for update. */
2231 build_animdata(&probe->id);
2232 build_parameters(&probe->id);
2233}
2234
2236{
2237 if (built_map_.check_is_built_and_tag(speaker)) {
2238 return;
2239 }
2240 /* Placeholder so we can add relations and tag ID node for update. */
2243 build_animdata(&speaker->id);
2244 build_parameters(&speaker->id);
2245 if (speaker->sound != nullptr) {
2246 build_sound(speaker->sound);
2247 }
2248}
2249
2251{
2252 if (built_map_.check_is_built_and_tag(sound)) {
2253 return;
2254 }
2255 add_id_node(&sound->id);
2256 bSound *sound_cow = get_cow_datablock(sound);
2257 add_operation_node(&sound->id,
2260 [bmain = bmain_, sound_cow](::Depsgraph *depsgraph) {
2261 BKE_sound_evaluate(depsgraph, bmain, sound_cow);
2262 });
2264 build_animdata(&sound->id);
2265 build_parameters(&sound->id);
2266}
2267
2269{
2270 if (built_map_.check_is_built_and_tag(vfont)) {
2271 return;
2272 }
2273 build_parameters(&vfont->id);
2277}
2278
2279static bool strip_node_build_cb(Strip *strip, void *user_data)
2280{
2281 DepsgraphNodeBuilder *nb = (DepsgraphNodeBuilder *)user_data;
2282 nb->build_idproperties(strip->prop);
2283 if (strip->sound != nullptr) {
2284 nb->build_sound(strip->sound);
2285 }
2286 if (strip->scene != nullptr) {
2287 nb->build_scene_parameters(strip->scene);
2288 }
2289 if (strip->type == STRIP_TYPE_SCENE && strip->scene != nullptr) {
2290 if (strip->flag & SEQ_SCENE_STRIPS) {
2291 nb->build_scene_sequencer(strip->scene);
2292 }
2293 ViewLayer *sequence_view_layer = BKE_view_layer_default_render(strip->scene);
2294 nb->build_scene_speakers(strip->scene, sequence_view_layer);
2295 }
2296 /* TODO(sergey): Movie clip, scene, camera, mask. */
2297 return true;
2298}
2299
2301{
2302 if (scene->ed == nullptr) {
2303 return;
2304 }
2305 if (built_map_.check_is_built_and_tag(scene, BuilderMap::TAG_SCENE_SEQUENCER)) {
2306 return;
2307 }
2308 build_scene_audio(scene);
2309 Scene *scene_cow = get_cow_datablock(scene);
2310 add_operation_node(&scene->id,
2313 [scene_cow](::Depsgraph *depsgraph) {
2314 seq::eval_strips(depsgraph, scene_cow, &scene_cow->ed->seqbase);
2315 });
2316 /* Make sure data for sequences is in the graph. */
2318}
2319
2321{
2322 if (built_map_.check_is_built_and_tag(scene, BuilderMap::TAG_SCENE_AUDIO)) {
2323 return;
2324 }
2325
2326 OperationNode *audio_entry_node = add_operation_node(
2328 audio_entry_node->set_as_entry();
2329
2331
2332 Scene *scene_cow = get_cow_datablock(scene);
2333 add_operation_node(&scene->id,
2336 [scene_cow](::Depsgraph *depsgraph) {
2337 BKE_scene_update_tag_audio_volume(depsgraph, scene_cow);
2338 });
2339}
2340
2342{
2343 BKE_view_layer_synced_ensure(scene, view_layer);
2345 Object *object = base->object;
2346 if (object->type != OB_SPEAKER || !need_pull_base_into_graph(base)) {
2347 continue;
2348 }
2349 /* NOTE: Can not use base because it does not belong to a current view layer. */
2350 build_object(-1, base->object, DEG_ID_LINKED_INDIRECTLY, true);
2351 }
2352}
2353
2354/* **** ID traversal callbacks functions **** */
2355
2357 Object * /*object*/,
2358 ID **idpoin,
2359 LibraryForeachIDCallbackFlag /*cb_flag*/)
2360{
2362 ID *id = *idpoin;
2363 if (id == nullptr) {
2364 return;
2365 }
2366 switch (GS(id->name)) {
2367 case ID_OB:
2368 data->builder->build_object(-1, (Object *)id, DEG_ID_LINKED_INDIRECTLY, false);
2369 break;
2370 default:
2371 data->builder->build_id(id);
2372 break;
2373 }
2374}
2375
2377 ID **idpoin,
2378 bool /*is_reference*/,
2379 void *user_data)
2380{
2382 ID *id = *idpoin;
2383 if (id == nullptr) {
2384 return;
2385 }
2386 switch (GS(id->name)) {
2387 case ID_OB:
2388 data->builder->build_object(-1, (Object *)id, DEG_ID_LINKED_INDIRECTLY, false);
2389 break;
2390 default:
2391 data->builder->build_id(id);
2392 break;
2393 }
2394}
2395
2396} // namespace blender::deg
Blender kernel action and pose functionality.
AnimData * BKE_animdata_from_id(const ID *id)
Definition anim_data.cc:82
void BKE_animsys_eval_driver_unshare(Depsgraph *depsgraph, ID *id)
Definition anim_sys.cc:4192
void BKE_animsys_eval_animdata(struct Depsgraph *depsgraph, struct ID *id)
Definition anim_sys.cc:4158
void BKE_animsys_eval_driver(struct Depsgraph *depsgraph, struct ID *id, int driver_index, struct FCurve *fcu_orig)
Definition anim_sys.cc:4223
void BKE_cachefile_eval(Main *bmain, Depsgraph *depsgraph, CacheFile *cache_file)
Definition cachefile.cc:326
#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:5494
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 BKE_grease_pencil_eval_geometry(Depsgraph *depsgraph, GreasePencil *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:1804
void BKE_lattice_eval_geometry(Depsgraph *depsgraph, Lattice *latt)
Definition lattice.cc:702
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)
LibraryForeachIDCallbackFlag
void BKE_library_foreach_ID_link(Main *bmain, ID *id, blender::FunctionRef< LibraryIDLinkCallback > callback, void *user_data, LibraryForeachIDFlag flag)
Definition lib_query.cc:431
@ IDWALK_RET_STOP_ITER
@ IDWALK_RET_NOP
@ 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(Object *ob)
Material *** BKE_object_material_array_p(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)
bool BKE_nlatrack_is_enabled(const AnimData &adt, const NlaTrack &nlt)
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:46
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
void * BLI_findlink(const ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:534
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
#define LISTBASE_FOREACH_INDEX(type, var, list, index_var)
#define SET_FLAG_FROM_TEST(value, test, flag)
#define ELEM(...)
@ DAG_EVAL_VIEWPORT
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1026
@ ID_TAG_COPIED_ON_EVAL
Definition DNA_ID.h:905
@ ID_FLAG_EMBEDDED_DATA
Definition DNA_ID.h:687
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_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_SCENE_STRIPS
@ STRIP_TYPE_SCENE
@ TEX_IMAGE
Read Guarded memory(de)allocation.
BMesh const char void * data
return true
BPy_StructRNA * depsgraph
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)
DepsgraphBuilder(Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache)
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)
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)
static void modifier_walk(void *user_data, struct Object *object, struct ID **idpoin, LibraryForeachIDCallbackFlag cb_flag)
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_animdata_drivers(ID *id, AnimData *adt)
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)
TEX_TEMPLATE DataVec texture(T, FltCoord, float=0.0f) RET
#define ID_TYPE_USE_COPY_ON_EVAL(_id_type)
#define MEM_SAFE_FREE(v)
#define ID_TYPE_SUPPORTS_PARAMS_WITHOUT_COW(id_type)
#define GS(a)
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
bNodeTree ** node_tree_ptr_from_id(ID *id)
Definition node.cc:4816
uint64_t IDComponentsMask
bool rna_prop_affects_parameters_node(const PointerRNA *ptr, const PropertyRNA *prop)
void deg_evaluate_object_node_visibility(::Depsgraph *depsgraph, IDNode *id_node)
void deg_create_eval_copy(::Depsgraph *graph, const IDNode *id_node)
static bool strip_node_build_cb(Strip *strip, void *user_data)
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)
std::function< void(::Depsgraph *)> DepsEvalOperationCb
bool data_path_maybe_shared(const ID &id, const StringRef data_path)
@ 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)
void for_each_callback(ListBase *seqbase, ForEachFunc callback, void *user_data)
Definition iterator.cc:59
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:544
bAction * action
ListBase drivers
ListBase nla_tracks
struct Object * focus_object
struct CameraDOFSettings dof
struct Object * bevobj
struct Object * textoncurve
struct Object * taperobj
struct Object * surface
struct ViewLayer * view_layer
ListBase seqbase
char * rna_path
ChannelDriver * driver
int array_index
struct bNodeTree * nodetree
void * pointer
Definition DNA_ID.h:137
IDPropertyData data
Definition DNA_ID.h:159
Definition DNA_ID.h:404
unsigned int recalc
Definition DNA_ID.h:427
int tag
Definition DNA_ID.h:424
IDProperty * properties
Definition DNA_ID.h:446
struct ID * orig_id
Definition DNA_ID.h:466
short flag
Definition DNA_ID.h:420
char name[66]
Definition DNA_ID.h:415
unsigned int session_uid
Definition DNA_ID.h:444
ListBase block
struct Collection * blocker_collection
struct Collection * receiver_collection
struct bNodeTree * nodetree
void * first
struct Tex * tex
MaskParent parent
struct bNodeTree * nodetree
ListBase particlesystem
ListBase constraints
struct Collection * instance_collection
ListBase modifiers
ListBase greasepencil_modifiers
struct Material ** mat
struct PartDeflect * pd
ListBase shader_fx
LightLinking * light_linking
struct Object * parent
struct Collection * instance_collection
struct MTex * mtex[18]
struct Object * instance_object
ID * owner_id
Definition RNA_types.hh:51
struct Object * ob1
struct Object * ob2
struct Collection * constraints
struct Collection * group
struct RigidBodyWorld * rigidbody_world
struct Editing * ed
struct Object * camera
ListBase markers
struct bSound * sound
struct IDProperty * prop
struct Scene * scene
struct bSound * sound
struct bNodeTree * nodetree
IDProperty * prop
void * default_value
bNodeTreeRuntimeHandle * runtime
std::string identifier() const override
OperationNode * find_operation(OperationIDKey key) const
OperationNode * add_operation(const DepsEvalOperationCb &op, OperationCode opcode, const StringRef name="", int name_tag=-1)
IDComponentsMask previously_visible_components_mask
DEGCustomDataMeshMasks customdata_masks
DEGCustomDataMeshMasks previous_customdata_masks
ComponentNode * add_component(NodeType type, StringRef name="")
IDComponentsMask visible_components_mask
Map< ComponentIDKey, ComponentNode * > components
eDepsNode_LinkedState_Type linked_state
ComponentNode * find_component(NodeType type, StringRef name="") const
uint32_t previous_eval_flags
void tag_update(Depsgraph *graph, eUpdateSource source) override
std::string identifier() const override
i
Definition text_draw.cc:230
PointerRNA * ptr
Definition wm_files.cc:4227