Blender V5.0
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"
64#include "BKE_grease_pencil.hh"
65#include "BKE_idprop.hh"
66#include "BKE_idtype.hh"
67#include "BKE_image.hh"
68#include "BKE_key.hh"
69#include "BKE_lattice.hh"
70#include "BKE_layer.hh"
71#include "BKE_lib_id.hh"
72#include "BKE_lib_query.hh"
73#include "BKE_light.h"
74#include "BKE_mask.h"
75#include "BKE_material.hh"
76#include "BKE_mball.hh"
77#include "BKE_mesh.hh"
78#include "BKE_modifier.hh"
79#include "BKE_movieclip.h"
80#include "BKE_nla.hh"
81#include "BKE_node.hh"
82#include "BKE_node_runtime.hh"
83#include "BKE_object.hh"
84#include "BKE_particle.h"
85#include "BKE_pointcache.h"
86#include "BKE_rigidbody.h"
87#include "BKE_scene.hh"
88#include "BKE_shader_fx.h"
89#include "BKE_sound.h"
90#include "BKE_tracking.h"
91#include "BKE_volume.hh"
92#include "BKE_world.h"
93
94#include "RNA_access.hh"
95#include "RNA_path.hh"
96#include "RNA_prototypes.hh"
97#include "RNA_types.hh"
98
99#include "DEG_depsgraph.hh"
100#include "DEG_depsgraph_build.hh"
101
102#include "SEQ_iterator.hh"
103#include "SEQ_sequencer.hh"
104
109#include "intern/depsgraph.hh"
119
120namespace blender::deg {
121
122/* ************ */
123/* Node Builder */
124
125/* **** General purpose functions **** */
126
137
139{
140 /* Cannot be in an IDInfo destructor, as these COW IDs do not belong to the IDInfo data. */
141 for (IDInfo &id_info : id_info_hash_.values()) {
142 if (id_info.id_cow != nullptr) {
143 deg_free_eval_copy_datablock(id_info.id_cow);
144 MEM_freeN(id_info.id_cow);
145 }
146 }
147}
148
150{
152
153 const ID_Type id_type = GS(id->name);
154 IDNode *id_node = nullptr;
155 ID *id_cow = nullptr;
156 IDComponentsMask previously_visible_components_mask = 0;
157 uint32_t previous_eval_flags = 0;
158 DEGCustomDataMeshMasks previous_customdata_masks;
159 IDInfo *id_info = id_info_hash_.lookup_ptr(id->session_uid);
160 if (id_info != nullptr) {
161 id_cow = id_info->id_cow;
162 previously_visible_components_mask = id_info->previously_visible_components_mask;
163 previous_eval_flags = id_info->previous_eval_flags;
164 previous_customdata_masks = id_info->previous_customdata_masks;
165 /* Tag ID info to not free the evaluated ID pointer. */
166 id_info->id_cow = nullptr;
167 }
168 id_node = graph_->add_id_node(id, id_cow);
169 id_node->previously_visible_components_mask = previously_visible_components_mask;
170 id_node->previous_eval_flags = previous_eval_flags;
171 id_node->previous_customdata_masks = previous_customdata_masks;
172
173 /* NOTE: Zero number of components indicates that ID node was just created. */
174 const bool is_newly_created = id_node->components.is_empty();
175
176 if (is_newly_created) {
177 if (deg_eval_copy_is_needed(id_type)) {
179 OperationNode *op_cow = comp_cow->add_operation(
180 [id_node](::Depsgraph *depsgraph) { deg_create_eval_copy(depsgraph, id_node); },
182 graph_->operations.append(op_cow);
183 }
184
185 ComponentNode *visibility_component = id_node->add_component(NodeType::VISIBILITY);
186 OperationNode *visibility_operation;
187
188 /* Optimization: currently only objects need a special visibility evaluation. For the rest ID
189 * types keep the node as a NO-OP so that relations can still be routed, but without penalty
190 * during the graph evaluation. */
191 if (id_type == ID_OB) {
192 visibility_operation = visibility_component->add_operation(
193 [id_node](::Depsgraph *depsgraph) {
195 },
197 }
198 else {
199 visibility_operation = visibility_component->add_operation(nullptr,
201 }
202
203 /* Pin the node so that it and its relations are preserved by the unused nodes/relations
204 * deletion. This is mainly to make it easier to debug visibility. */
205 visibility_operation->flag |= (OperationFlag::DEPSOP_FLAG_PINNED |
207 graph_->operations.append(visibility_operation);
208 }
209 return id_node;
210}
211
213{
214 return graph_->find_id_node(id);
215}
216
218{
219 return graph_->add_time_source();
220}
221
223 NodeType comp_type,
224 const char *comp_name)
225{
226 IDNode *id_node = add_id_node(id);
227 ComponentNode *comp_node = id_node->add_component(comp_type, comp_name);
228 comp_node->owner = id_node;
229 return comp_node;
230}
231
233 const NodeType comp_type,
234 const char *comp_name)
235{
236 IDNode *id_node = find_id_node(id);
237 if (id_node == nullptr) {
238 return nullptr;
239 }
240 return id_node->find_component(comp_type, comp_name);
241}
242
244 OperationCode opcode,
245 const DepsEvalOperationCb &op,
246 const char *name,
247 int name_tag)
248{
249 OperationNode *op_node = comp_node->find_operation(opcode, name, name_tag);
250 if (op_node == nullptr) {
251 op_node = comp_node->add_operation(op, opcode, name, name_tag);
252 graph_->operations.append(op_node);
253 }
254 else {
255 fprintf(stderr,
256 "add_operation: Operation already exists - %s has %s at %p\n",
257 comp_node->identifier().c_str(),
258 op_node->identifier().c_str(),
259 op_node);
260 BLI_assert_msg(0, "Should not happen!");
261 }
262 return op_node;
263}
264
266 NodeType comp_type,
267 const char *comp_name,
268 OperationCode opcode,
269 const DepsEvalOperationCb &op,
270 const char *name,
271 int name_tag)
272{
273 ComponentNode *comp_node = add_component_node(id, comp_type, comp_name);
274 return add_operation_node(comp_node, opcode, op, name, name_tag);
275}
276
278 NodeType comp_type,
279 OperationCode opcode,
280 const DepsEvalOperationCb &op,
281 const char *name,
282 int name_tag)
283{
284 return add_operation_node(id, comp_type, "", opcode, op, name, name_tag);
285}
286
288 NodeType comp_type,
289 const char *comp_name,
290 OperationCode opcode,
291 const DepsEvalOperationCb &op,
292 const char *name,
293 int name_tag)
294{
295 OperationNode *operation = find_operation_node(id, comp_type, comp_name, opcode, name, name_tag);
296 if (operation != nullptr) {
297 return operation;
298 }
299 return add_operation_node(id, comp_type, comp_name, opcode, op, name, name_tag);
300}
301
303 NodeType comp_type,
304 OperationCode opcode,
305 const DepsEvalOperationCb &op,
306 const char *name,
307 int name_tag)
308{
309 OperationNode *operation = find_operation_node(id, comp_type, opcode, name, name_tag);
310 if (operation != nullptr) {
311 return operation;
312 }
313 return add_operation_node(id, comp_type, opcode, op, name, name_tag);
314}
315
317 NodeType comp_type,
318 const char *comp_name,
319 OperationCode opcode,
320 const char *name,
321 int name_tag)
322{
323 return find_operation_node(id, comp_type, comp_name, opcode, name, name_tag) != nullptr;
324}
325
327 const NodeType comp_type,
328 const OperationCode opcode)
329{
330 return find_operation_node(id, comp_type, opcode) != nullptr;
331}
332
334 NodeType comp_type,
335 const char *comp_name,
336 OperationCode opcode,
337 const char *name,
338 int name_tag)
339{
340 ComponentNode *comp_node = find_component_node(id, comp_type, comp_name);
341 if (comp_node == nullptr) {
342 return nullptr;
343 }
344 return comp_node->find_operation(opcode, name, name_tag);
345}
346
348 const ID *id, NodeType comp_type, OperationCode opcode, const char *name, int name_tag)
349{
350 return find_operation_node(id, comp_type, "", opcode, name, name_tag);
351}
352
358
360{
361 return graph_->get_cow_id(id_orig);
362}
363
365{
366 if (id_orig->tag & ID_TAG_COPIED_ON_EVAL) {
367 /* ID is already remapped to copy-on-evaluation. */
368 return id_orig;
369 }
370 IDNode *id_node = add_id_node(id_orig);
371 return id_node->id_cow;
372}
373
374/* **** Build functions for entity nodes **** */
375
377{
378 /* Store existing evaluated versions of datablock, so we can re-use
379 * them for new ID nodes. */
380 for (IDNode *id_node : graph_->id_nodes) {
381 /* It is possible that the ID does not need to have evaluated version in which case id_cow is
382 * the same as id_orig. Additionally, such ID might have been removed, which makes the check
383 * for whether id_cow is expanded to access freed memory. In order to deal with this we
384 * check whether an evaluated copy is needed based on a scalar value which does not lead to
385 * access of possibly deleted memory. */
386 IDInfo id_info{};
387 if (deg_eval_copy_is_needed(id_node->id_type) && id_node->id_orig != id_node->id_cow) {
388 if (deg_eval_copy_is_expanded(id_node->id_cow)) {
389 id_info.id_cow = id_node->id_cow;
390 }
391 else {
392 /* This ID has not been expanded yet. Don't reuse it like already expanded IDs. */
393 MEM_SAFE_FREE(id_node->id_cow);
394 }
395 }
397 id_info.previous_eval_flags = id_node->eval_flags;
399 BLI_assert(!id_info_hash_.contains(id_node->id_orig_session_uid));
400 id_info_hash_.add_new(id_node->id_orig_session_uid, std::move(id_info));
401 id_node->id_cow = nullptr;
402 }
403
404 for (const OperationNode *op_node : graph_->entry_tags) {
405 saved_entry_tags_.append_as(op_node);
406 }
407
408 for (const OperationNode *op_node : graph_->operations) {
409 if (op_node->flag & DEPSOP_FLAG_NEEDS_UPDATE) {
410 needs_update_operations_.append_as(op_node);
411 }
412 }
413
414 /* Make sure graph has no nodes left from previous state. */
415 graph_->clear_all_nodes();
416 graph_->operations.clear();
417 graph_->entry_tags.clear();
418}
419
420/* Utility callbacks for `BKE_library_foreach_ID_link`, used to detect when an evaluated ID is
421 * using ID pointers that are either:
422 * - evaluated ID pointers that do not exist anymore in current depsgraph.
423 * - Orig ID pointers that do have now an evaluated version in current depsgraph.
424 * In both cases, it means the evaluated ID user needs to be flushed, to ensure its pointers are
425 * properly remapped.
426 *
427 * NOTE: This is split in two, a static function and a public method of the node builder, to allow
428 * the code to access the builder's data more easily. */
429
431 ID *id_pointer)
432{
433 if (id_pointer->orig_id == nullptr) {
434 /* `id_cow_self` uses a non-cow ID, if that ID has an evaluated copy in current depsgraph its
435 * owner needs to be remapped, i.e. copy-on-eval-flushed. */
436 IDNode *id_node = find_id_node(id_pointer);
437 if (id_node != nullptr && id_node->id_cow != nullptr) {
439 graph_,
440 id_cow_self->orig_id,
444 }
445 }
446 else {
447 /* `id_cow_self` uses an evaluated ID, if that evaluated copy is removed from current depsgraph
448 * its owner needs to be remapped, i.e. copy-on-eval-flushed. */
449 /* NOTE: at that stage, old existing evaluated copies that are to be removed from current state
450 * of evaluated depsgraph are still valid pointers, they are freed later (typically during
451 * destruction of the builder itself). */
452 IDNode *id_node = find_id_node(id_pointer->orig_id);
453 if (id_node == nullptr) {
455 graph_,
456 id_cow_self->orig_id,
460 }
461 }
462 return IDWALK_RET_NOP;
463}
464
466{
467 ID *id = *cb_data->id_pointer;
468 if (id == nullptr) {
469 return IDWALK_RET_NOP;
470 }
471 if (!ID_TYPE_USE_COPY_ON_EVAL(GS(id->name))) {
472 /* No need to go further if the id never had an evaluated copy in the depsgraph. This function
473 * is only concerned with keeping the mapping between original and evaluated IDs intact. */
474 return IDWALK_RET_NOP;
475 }
476
477 DepsgraphNodeBuilder *builder = static_cast<DepsgraphNodeBuilder *>(cb_data->user_data);
478 ID *id_cow_self = cb_data->self_id;
479
480 return builder->foreach_id_cow_detect_need_for_update_callback(id_cow_self, id);
481}
482
484{
485 /* NOTE: Currently the only ID types that depsgraph may decide to not evaluate/generate evaluated
486 * copies for, even though they are referenced by other data-blocks, are Collections and Objects
487 * (through their various visibility flags, and the ones from #LayerCollections too). However,
488 * this code is kept generic as it makes it more future-proof, and optimization here would give
489 * negligible performance improvements in typical cases.
490 *
491 * NOTE: This mechanism may also 'fix' some missing update tagging from non-depsgraph code in
492 * some cases. This is slightly unfortunate (as it may hide issues in other parts of Blender
493 * code), but cannot really be avoided currently. */
494
495 for (const IDNode *id_node : graph_->id_nodes) {
496 if (ELEM(id_node->id_cow, id_node->id_orig, nullptr)) {
497 /* Node/ID with no copy-on-eval data, no need to check it. */
498 continue;
499 }
500 if (!deg_eval_copy_is_expanded(id_node->id_cow)) {
501 /* Copy-on-eval data is not expanded yet, so this is a newly added node/ID that has not been
502 * evaluated yet. */
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
559{
560 graph_->light_linking_cache.end_build(*graph_->scene);
563}
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_SCR:
663 case ID_VF:
664 case ID_BR:
665 case ID_WM:
666 case ID_PAL:
667 case ID_PC:
668 case ID_WS:
671 break;
672 }
673}
674
676{
677 if (built_map_.check_is_built_and_tag(id)) {
678 return;
679 }
680
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_;
701 IDNode *id_node;
702 if (built_map_.check_is_built_and_tag(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);
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);
833 /* Build animation data,
834 *
835 * Do it now because it's possible object data will affect
836 * on object's level animation, for example in case of rebuilding
837 * pose for proxy. */
838 build_animdata(&object->id);
839 /* Particle systems. */
840 if (object->particlesystem.first != nullptr) {
841 build_particle_systems(object, is_visible);
842 }
843 /* Force field Texture. */
844 if ((object->pd != nullptr) && (object->pd->forcefield == PFIELD_TEXTURE) &&
845 (object->pd->tex != nullptr))
846 {
847 build_texture(object->pd->tex);
848 }
849
850 /* Object instancing. */
851 if (object->instance_collection != nullptr) {
852 build_object_instance_collection(object, is_visible);
853
854 OperationNode *instancer_node = add_operation_node(
856 instancer_node->flag |= OperationFlag::DEPSOP_FLAG_PINNED;
857 }
858 OperationNode *instance_node = add_operation_node(
860 instance_node->flag |= OperationFlag::DEPSOP_FLAG_PINNED;
861
862 OperationNode *instance_geometry_node = add_operation_node(
864 instance_geometry_node->flag |= OperationFlag::DEPSOP_FLAG_PINNED;
865
867
868 build_object_shading(object);
869
870 /* Synchronization back to original object. */
871 add_operation_node(&object->id,
874 [object_cow](::Depsgraph *depsgraph) {
875 BKE_object_sync_to_original(depsgraph, object_cow);
876 });
877}
878
880 Object *object,
881 eDepsNode_LinkedState_Type linked_state)
882{
883
884 OperationNode *entry_node = add_operation_node(
886 entry_node->set_as_entry();
889 exit_node->set_as_exit();
890
891 build_object_flags(base_index, object, linked_state);
892}
893
895 Object *object,
896 eDepsNode_LinkedState_Type linked_state)
897{
898 if (base_index == -1) {
899 return;
900 }
901 Scene *scene_cow = get_cow_datablock(scene_);
902 Object *object_cow = get_cow_datablock(object);
903 const bool is_from_set = (linked_state == DEG_ID_LINKED_VIA_SET);
904 /* TODO(sergey): Is this really best component to be used? */
906 &object->id,
909 [view_layer_index = view_layer_index_, scene_cow, object_cow, base_index, is_from_set](
911 BKE_object_eval_eval_base_flags(
912 depsgraph, scene_cow, view_layer_index, object_cow, base_index, is_from_set);
913 });
914}
915
917{
918 if (object->instance_collection == nullptr) {
919 return;
920 }
921 const bool is_current_parent_collection_visible = is_parent_collection_visible_;
922 is_parent_collection_visible_ = is_object_visible;
923 build_collection(nullptr, object->instance_collection);
924 is_parent_collection_visible_ = is_current_parent_collection_visible;
925}
926
928{
929 if (BLI_listbase_is_empty(&object->modifiers)) {
930 return;
931 }
932
933 const ModifierMode modifier_mode = (graph_->mode == DAG_EVAL_VIEWPORT) ? eModifierMode_Realtime :
935
936 IDNode *id_node = find_id_node(&object->id);
937
938 add_operation_node(&object->id,
941 [id_node](::Depsgraph *depsgraph) {
942 deg_evaluate_object_modifiers_mode_node_visibility(depsgraph, id_node);
943 });
944
945 int modifier_index;
946 LISTBASE_FOREACH_INDEX (ModifierData *, modifier, &object->modifiers, modifier_index) {
947 OperationNode *modifier_node = add_operation_node(
948 &object->id, NodeType::GEOMETRY, OperationCode::MODIFIER, nullptr, modifier->name);
949 if (modifier->type == eModifierType_Nodes) {
950 modifier_node->evaluate =
951 [id_node, modifier_index, modifier_node](::Depsgraph * /*depsgraph*/) {
952 Object *ob_eval = reinterpret_cast<Object *>(id_node->id_cow);
953 ModifierData *md_eval = reinterpret_cast<ModifierData *>(
954 BLI_findlink(&ob_eval->modifiers, modifier_index));
955 if (!md_eval) {
956 /* The modifiers may not be available on the evaluated object if the object has an
957 * error that turned it into an Empty. Modifiers are not copied on this object type.
958 * Also see #142290. */
959 return;
960 }
961 /* Set flag that the modifier can check when it is evaluated. */
962 const bool is_user_modified = modifier_node->flag & DEPSOP_FLAG_USER_MODIFIED;
963 SET_FLAG_FROM_TEST(md_eval->flag, is_user_modified, eModifierFlag_UserModified);
964 };
965 }
966
967 /* Mute modifier mode if the modifier is not enabled for the dependency graph mode.
968 * This handles static (non-animated) mode of the modifier. */
969 if ((modifier->mode & modifier_mode) == 0) {
970 modifier_node->flag |= DEPSOP_FLAG_MUTE;
971 }
972
974 graph_->has_animated_visibility = true;
975 }
976 }
977
979 data.builder = this;
980
981 /* Temporarily set the collection visibility to false, relying on the visibility flushing code
982 * to flush the visibility from a modifier into collections it depends on. */
983 const bool is_current_parent_collection_visible = is_parent_collection_visible_;
986 is_parent_collection_visible_ = is_current_parent_collection_visible;
987}
988
990{
991 if (object->data == nullptr) {
992 return;
993 }
994 /* type-specific data. */
995 switch (object->type) {
996 case OB_MESH:
997 case OB_CURVES_LEGACY:
998 case OB_FONT:
999 case OB_SURF:
1000 case OB_MBALL:
1001 case OB_LATTICE:
1002 case OB_CURVES:
1003 case OB_POINTCLOUD:
1004 case OB_VOLUME:
1006 break;
1007 case OB_GREASE_PENCIL:
1009 break;
1010 case OB_ARMATURE:
1011 build_rig(object);
1012 break;
1013 case OB_LAMP:
1015 break;
1016 case OB_CAMERA:
1018 break;
1019 case OB_LIGHTPROBE:
1021 break;
1022 case OB_SPEAKER:
1024 break;
1025 default: {
1026 ID *obdata = (ID *)object->data;
1027 if (!built_map_.check_is_built(obdata)) {
1028 build_animdata(obdata);
1029 }
1030 break;
1031 }
1032 }
1033 /* Materials. */
1034 Material ***materials_ptr = BKE_object_material_array_p(object);
1035 if (materials_ptr != nullptr) {
1036 short *num_materials_ptr = BKE_object_material_len_p(object);
1037 build_materials(*materials_ptr, *num_materials_ptr);
1038 }
1039}
1040
1042{
1043 Camera *camera = (Camera *)object->data;
1044 build_camera(camera);
1045}
1046
1048{
1049 Light *lamp = (Light *)object->data;
1050 build_light(lamp);
1051}
1052
1059
1061{
1062 GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object->data);
1063 /* Build the layer parents. */
1064 for (const bke::greasepencil::Layer *layer : grease_pencil.layers()) {
1065 Object *parent = layer->parent;
1066 if (parent == nullptr) {
1067 continue;
1068 }
1069 build_object(-1, parent, DEG_ID_LINKED_INDIRECTLY, false);
1070 }
1072}
1073
1080
1082{
1083 OperationNode *op_node;
1084 Object *ob_cow = get_cow_datablock(object);
1085 /* Transform entry operation. */
1087 op_node->set_as_entry();
1088 /* Local transforms (from transform channels - loc/rot/scale + deltas). */
1090 &object->id,
1093 [ob_cow](::Depsgraph *depsgraph) { BKE_object_eval_local_transform(depsgraph, ob_cow); });
1094 /* Object parent. */
1095 if (object->parent != nullptr) {
1097 &object->id,
1100 [ob_cow](::Depsgraph *depsgraph) { BKE_object_eval_parent(depsgraph, ob_cow); });
1101 }
1102 /* Object constraints. */
1103 if (object->constraints.first != nullptr) {
1105 }
1106 /* Rest of transformation update. */
1108 &object->id,
1111 [ob_cow](::Depsgraph *depsgraph) { BKE_object_eval_uber_transform(depsgraph, ob_cow); });
1112 /* Operation to take of rigid body simulation. soft bodies and other friends
1113 * in the context of point cache invalidation. */
1115 /* Object transform is done. */
1116 op_node = add_operation_node(
1117 &object->id,
1120 [ob_cow](::Depsgraph *depsgraph) { BKE_object_eval_transform_final(depsgraph, ob_cow); });
1121 op_node->set_as_exit();
1122}
1123
1142{
1143 /* create node for constraint stack */
1144 Scene *scene_cow = get_cow_datablock(scene_);
1145 Object *object_cow = get_cow_datablock(object);
1146 add_operation_node(&object->id,
1149 [scene_cow, object_cow](::Depsgraph *depsgraph) {
1150 BKE_object_eval_constraints(depsgraph, scene_cow, object_cow);
1151 });
1152}
1153
1155{
1156 if (!BKE_ptcache_object_has(scene_, object, 0)) {
1157 return;
1158 }
1159 Scene *scene_cow = get_cow_datablock(scene_);
1160 Object *object_cow = get_cow_datablock(object);
1161 add_operation_node(&object->id,
1164 [scene_cow, object_cow](::Depsgraph *depsgraph) {
1165 BKE_object_eval_ptcache_reset(depsgraph, scene_cow, object_cow);
1166 });
1167}
1168
1170{
1171 /* For objects put the light linking update callback to the same component as the base flags.
1172 * This way the light linking is updated on the view layer hierarchy change (which does not seem
1173 * to have a dedicated tag). */
1174 Object *object_cow = get_cow_datablock(object);
1175 add_operation_node(&object->id,
1178 [object_cow](::Depsgraph *depsgraph) {
1179 BKE_object_eval_light_linking(depsgraph, object_cow);
1180 });
1181
1182 graph_->light_linking_cache.add_emitter(*graph_->scene, *object);
1183
1184 if (object->light_linking) {
1187 }
1188}
1189
1191{
1192 if (collection == nullptr) {
1193 return;
1194 }
1195
1196 /* TODO(sergey): Support some sort of weak referencing, so that receiver objects which are
1197 * specified by this collection but not in the scene do not use extra memory.
1198 *
1199 * Until the better solution is implemented pull the objects indirectly, and keep them
1200 * invisible. This has penalty of higher memory usage, but not a performance penalty. */
1201
1202 const bool is_current_parent_collection_visible = is_parent_collection_visible_;
1204
1205 build_collection(nullptr, collection);
1206
1207 is_parent_collection_visible_ = is_current_parent_collection_visible;
1208
1209 /* Ensure the light linking component is created for the collection.
1210 *
1211 * Note that it is not possible to have early output check based on regular built flags because
1212 * the collection might have been first built for the non-light-linking purposes. */
1213 /* TODO(sergey): Can optimize this out by explicitly separating the different built tags. This
1214 * needs to be done in all places where the collection is built (is not something that can be
1215 * easily solved from just adding the light linking functionality). */
1216 if (!has_operation_node(
1218 {
1220 }
1221}
1222
1224{
1225 Object *object_cow = get_cow_datablock(object);
1227 &object->id,
1230 [object_cow](::Depsgraph *depsgraph) { BKE_object_eval_shading(depsgraph, object_cow); });
1231
1232 OperationNode *done_node = add_operation_node(
1234 done_node->set_as_exit();
1235}
1236
1238{
1239 /* Special handling for animated images/sequences. */
1241 /* Regular animation. */
1242 AnimData *adt = BKE_animdata_from_id(id);
1243 if (adt == nullptr) {
1244 return;
1245 }
1246 if (adt->action != nullptr) {
1247 build_action(adt->action);
1248 }
1249 /* Make sure ID node exists. */
1250 (void)add_id_node(id);
1251 ID *id_cow = get_cow_id(id);
1252 if (adt->action != nullptr || !BLI_listbase_is_empty(&adt->nla_tracks)) {
1253 OperationNode *operation_node;
1254 /* Explicit entry operation. */
1256 operation_node->set_as_entry();
1257 /* All the evaluation nodes. */
1261 });
1262 /* Explicit exit operation. */
1264 operation_node->set_as_exit();
1265 }
1266 /* NLA strips contain actions. */
1267 LISTBASE_FOREACH (NlaTrack *, nlt, &adt->nla_tracks) {
1268 if (!BKE_nlatrack_is_enabled(*adt, *nlt)) {
1269 continue;
1270 }
1271 build_animdata_nlastrip_targets(&nlt->strips);
1272 }
1273 /* Drivers. */
1274 build_animdata_drivers(id, adt);
1275}
1276
1278{
1279 LISTBASE_FOREACH (NlaStrip *, strip, strips) {
1280 if (strip->act != nullptr) {
1281 build_action(strip->act);
1282 }
1283 else if (strip->strips.first != nullptr) {
1284 build_animdata_nlastrip_targets(&strip->strips);
1285 }
1286 }
1287}
1288
1290{
1291 /* GPU materials might use an animated image. However, these materials have no been built yet so
1292 * we have to check if they might be created during evaluation. */
1293 bool has_image_animation = false;
1294 if (ELEM(GS(id->name), ID_MA, ID_WO)) {
1296 if (ntree != nullptr && ntree->runtime->runtime_flag & NTREE_RUNTIME_FLAG_HAS_IMAGE_ANIMATION)
1297 {
1298 has_image_animation = true;
1299 }
1300 }
1301
1302 if (has_image_animation || BKE_image_user_id_has_animation(id)) {
1303 ID *id_cow = get_cow_id(id);
1305 id,
1309 }
1310}
1311
1313{
1314 if (built_map_.check_is_built_and_tag(action)) {
1315 return;
1316 }
1317
1318 /* To make it possible to use animation data as a variable for drivers: */
1319 build_parameters(&action->id);
1320
1324}
1325
1327{
1328 bool needs_unshare = false;
1329
1330 /* Drivers. */
1331 int driver_index;
1332 LISTBASE_FOREACH_INDEX (FCurve *, fcu, &adt->drivers, driver_index) {
1333 build_driver(id, fcu, driver_index);
1334 needs_unshare = needs_unshare || data_path_maybe_shared(*id, fcu->rna_path);
1335 }
1336
1337 if (!needs_unshare) {
1338 return;
1339 }
1340
1341 ID *id_cow = get_cow_id(id);
1345 });
1346}
1347
1348void DepsgraphNodeBuilder::build_driver(ID *id, FCurve *fcurve, int driver_index)
1349{
1350 /* Create data node for this driver */
1351 ID *id_cow = get_cow_id(id);
1352
1353 /* TODO(sergey): ideally we could pass the copy-on-eval of fcu, but since it
1354 * has not yet been allocated at this point we can't. As a workaround
1355 * the animation systems allocates an array so we can do a fast lookup
1356 * with the driver index. */
1358 id,
1361 [id_cow, driver_index, fcurve](::Depsgraph *depsgraph) {
1362 BKE_animsys_eval_driver(depsgraph, id_cow, driver_index, fcurve);
1363 },
1364 fcurve->rna_path ? fcurve->rna_path : "",
1365 fcurve->array_index);
1366 build_driver_variables(id, fcurve);
1367}
1368
1370{
1371 PointerRNA id_ptr = RNA_id_pointer_create(id);
1372
1373 build_driver_id_property(id_ptr, fcurve->rna_path);
1374
1375 DriverTargetContext driver_target_context;
1376 driver_target_context.scene = graph_->scene;
1377 driver_target_context.view_layer = graph_->view_layer;
1378
1379 LISTBASE_FOREACH (DriverVar *, dvar, &fcurve->driver->variables) {
1381 PointerRNA target_prop;
1382 if (!driver_get_target_property(&driver_target_context, dvar, dtar, &target_prop)) {
1383 continue;
1384 }
1385
1386 /* Property is always expected to be resolved to a non-null RNA property, which is always
1387 * relative to some ID. */
1388 BLI_assert(target_prop.owner_id);
1389
1390 ID *target_id = target_prop.owner_id;
1391
1392 build_id(target_id);
1393 build_driver_id_property(target_prop, dtar->rna_path);
1394
1395 /* For rna_path based variables: */
1396 if ((dtar->flag & DTAR_FLAG_STRUCT_REF) == 0) {
1397 /* Handle all other cameras used by the scene timeline if applicable. */
1398 if (const char *camera_path = get_rna_path_relative_to_scene_camera(
1399 scene_, target_prop, dtar->rna_path))
1400 {
1402 }
1403 }
1404 }
1406 }
1407}
1408
1410 const char *camera_path)
1411{
1412 /* This skips scene->camera, which was already handled by the caller. */
1413 LISTBASE_FOREACH (TimeMarker *, marker, &scene->markers) {
1414 if (!ELEM(marker->camera, nullptr, scene->camera)) {
1415 PointerRNA camera_ptr = RNA_id_pointer_create(&marker->camera->id);
1416 build_driver_id_property(camera_ptr, camera_path);
1417 }
1418 }
1419}
1420
1422 const char *rna_path_from_target_prop)
1423{
1424 if (rna_path_from_target_prop == nullptr || rna_path_from_target_prop[0] == '\0') {
1425 return;
1426 }
1427
1429 PropertyRNA *prop;
1430 int index;
1431 if (!RNA_path_resolve_full(&target_prop, rna_path_from_target_prop, &ptr, &prop, &index)) {
1432 return;
1433 }
1434 if (prop == nullptr) {
1435 return;
1436 }
1438 return;
1439 }
1440 if (ptr.owner_id) {
1441 build_id(ptr.owner_id);
1442 }
1443 const char *prop_identifier = RNA_property_identifier(prop);
1444 /* Custom properties of bones are placed in their components to improve granularity. */
1445 if (RNA_struct_is_a(ptr.type, &RNA_PoseBone)) {
1446 const bPoseChannel *pchan = static_cast<const bPoseChannel *>(ptr.data);
1447 ensure_operation_node(ptr.owner_id,
1449 pchan->name,
1451 nullptr,
1452 prop_identifier);
1453 }
1454 else {
1456 ptr.owner_id, NodeType::PARAMETERS, OperationCode::ID_PROPERTY, nullptr, prop_identifier);
1457 }
1458}
1459
1461{
1462 (void)add_id_node(id);
1463 OperationNode *op_node;
1464 /* Explicit entry. */
1466 op_node->set_as_entry();
1467 /* Generic evaluation node. */
1468
1470 ID *id_cow = get_cow_id(id);
1472 id,
1475 [id_cow, id](::Depsgraph * /*depsgraph*/) { BKE_id_eval_properties_copy(id_cow, id); });
1476 }
1477 else {
1479 }
1480
1481 /* Explicit exit operation. */
1483 op_node->set_as_exit();
1484}
1485
1487{
1488 /* Object dimensions (bounding box) node. Will depend on both geometry and transform. */
1490}
1491
1493{
1494 if (built_map_.check_is_built_and_tag(world)) {
1495 return;
1496 }
1497 /* World itself. */
1498 add_id_node(&world->id);
1499 World *world_cow = get_cow_datablock(world);
1500 /* Shading update. */
1502 &world->id,
1505 [world_cow](::Depsgraph *depsgraph) { BKE_world_eval(depsgraph, world_cow); });
1508 /* Animation. */
1509 build_animdata(&world->id);
1510 build_parameters(&world->id);
1511 /* World's nodetree. */
1512 build_nodetree(world->nodetree);
1513}
1514
1515/* Rigidbody Simulation - Scene Level */
1517{
1518 RigidBodyWorld *rbw = scene->rigidbody_world;
1519 Scene *scene_cow = get_cow_datablock(scene);
1520
1535
1536 /* Create nodes --------------------------------------------------------- */
1537
1538 /* XXX: is this the right component, or do we want to use another one
1539 * instead? */
1540
1541 /* Init/rebuild operation. */
1543 &scene->id,
1546 [scene_cow](::Depsgraph *depsgraph) { BKE_rigidbody_rebuild_sim(depsgraph, scene_cow); });
1547 /* Do-sim operation. */
1548 OperationNode *sim_node = add_operation_node(&scene->id,
1551 [scene_cow](::Depsgraph *depsgraph) {
1552 BKE_rigidbody_eval_simulation(depsgraph,
1553 scene_cow);
1554 });
1555 sim_node->set_as_entry();
1556 sim_node->set_as_exit();
1557 sim_node->owner->entry_operation = sim_node;
1558 /* Objects - simulation participants. */
1559 if (rbw->group != nullptr) {
1560 build_collection(nullptr, rbw->group);
1562 if (object->type != OB_MESH) {
1563 continue;
1564 }
1565 if (object->rigidbody_object == nullptr) {
1566 continue;
1567 }
1568
1569 if (object->rigidbody_object->type == RBO_TYPE_PASSIVE) {
1570 continue;
1571 }
1572
1573 /* Create operation for flushing results. */
1574 /* Object's transform component - where the rigidbody operation
1575 * lives. */
1576 Object *object_cow = get_cow_datablock(object);
1577 add_operation_node(&object->id,
1580 [scene_cow, object_cow](::Depsgraph *depsgraph) {
1581 BKE_rigidbody_object_sync_transforms(depsgraph, scene_cow, object_cow);
1582 });
1583 }
1585 }
1586 /* Constraints. */
1587 if (rbw->constraints != nullptr) {
1589 RigidBodyCon *rbc = object->rigidbody_constraint;
1590 if (rbc == nullptr || rbc->ob1 == nullptr || rbc->ob2 == nullptr) {
1591 /* When either ob1 or ob2 is nullptr, the constraint doesn't work. */
1592 continue;
1593 }
1594 /* Make sure indirectly linked objects are fully built. */
1595 build_object(-1, object, DEG_ID_LINKED_INDIRECTLY, false);
1596 build_object(-1, rbc->ob1, DEG_ID_LINKED_INDIRECTLY, false);
1597 build_object(-1, rbc->ob2, DEG_ID_LINKED_INDIRECTLY, false);
1598 }
1600 }
1601}
1602
1603void DepsgraphNodeBuilder::build_particle_systems(Object *object, bool is_object_visible)
1604{
1618 /* Component for all particle systems. */
1620
1621 Object *ob_cow = get_cow_datablock(object);
1622 OperationNode *op_node;
1623 op_node = add_operation_node(
1626 });
1627 op_node->set_as_entry();
1628 /* Build all particle systems. */
1629 LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) {
1630 ParticleSettings *part = psys->part;
1631 /* Build particle settings operations.
1632 *
1633 * NOTE: The call itself ensures settings are only build once. */
1635 /* Particle system evaluation. */
1636 add_operation_node(psys_comp, OperationCode::PARTICLE_SYSTEM_EVAL, nullptr, psys->name);
1637 /* Keyed particle targets. */
1639 LISTBASE_FOREACH (ParticleTarget *, particle_target, &psys->targets) {
1640 if (ELEM(particle_target->ob, nullptr, object)) {
1641 continue;
1642 }
1643 build_object(-1, particle_target->ob, DEG_ID_LINKED_INDIRECTLY, is_object_visible);
1644 }
1645 }
1646 /* Visualization of particle system. */
1647 switch (part->ren_as) {
1648 case PART_DRAW_OB:
1649 if (part->instance_object != nullptr) {
1650 build_object(-1, part->instance_object, DEG_ID_LINKED_INDIRECTLY, is_object_visible);
1651 }
1652 break;
1653 case PART_DRAW_GR:
1654 if (part->instance_collection != nullptr) {
1655 build_collection(nullptr, part->instance_collection);
1656 }
1657 break;
1658 }
1659 }
1661 op_node->set_as_exit();
1662}
1663
1665{
1666 if (built_map_.check_is_built_and_tag(particle_settings)) {
1667 return;
1668 }
1669 /* Make sure we've got proper copied ID pointer. */
1670 add_id_node(&particle_settings->id);
1671 ParticleSettings *particle_settings_cow = get_cow_datablock(particle_settings);
1672 /* Animation data. */
1673 build_animdata(&particle_settings->id);
1674 build_parameters(&particle_settings->id);
1675 /* Parameters change. */
1676 OperationNode *op_node;
1677 op_node = add_operation_node(
1679 op_node->set_as_entry();
1680 add_operation_node(&particle_settings->id,
1683 [particle_settings_cow](::Depsgraph *depsgraph) {
1684 BKE_particle_settings_eval_reset(depsgraph, particle_settings_cow);
1685 });
1686 op_node = add_operation_node(
1688 op_node->set_as_exit();
1689 /* Texture slots. */
1690 for (MTex *mtex : particle_settings->mtex) {
1691 if (mtex == nullptr || mtex->tex == nullptr) {
1692 continue;
1693 }
1694 build_texture(mtex->tex);
1695 }
1696}
1697
1699{
1700 if (built_map_.check_is_built_and_tag(key)) {
1701 return;
1702 }
1705 build_animdata(&key->id);
1706 build_parameters(&key->id);
1707 /* This is an exit operation for the entire key datablock, is what is used
1708 * as dependency for modifiers evaluation. */
1710 /* Create per-key block properties, allowing tricky inter-dependencies for
1711 * drivers evaluation. */
1712 LISTBASE_FOREACH (KeyBlock *, key_block, &key->block) {
1714 &key->id, NodeType::PARAMETERS, OperationCode::PARAMETERS_EVAL, nullptr, key_block->name);
1715 }
1716}
1717
1718/* ObData Geometry Evaluation */
1719/* XXX: what happens if the datablock is shared! */
1721{
1722 OperationNode *op_node;
1723 Scene *scene_cow = get_cow_datablock(scene_);
1724 Object *object_cow = get_cow_datablock(object);
1725 /* Entry operation, takes care of initialization, and some other
1726 * relations which needs to be run prior actual geometry evaluation. */
1728 op_node->set_as_entry();
1729 /* Geometry evaluation. */
1730 op_node = add_operation_node(&object->id,
1733 [scene_cow, object_cow](::Depsgraph *depsgraph) {
1734 BKE_object_eval_uber_data(depsgraph, scene_cow, object_cow);
1735 });
1736 op_node->set_as_exit();
1737 /* Materials. */
1738 build_materials(object->mat, object->totcol);
1739 /* Point caches. */
1741 /* Geometry. */
1743 build_dimensions(object);
1744 /* Batch cache. */
1746 &object->id,
1749 [object_cow](::Depsgraph *depsgraph) { BKE_object_select_update(depsgraph, object_cow); });
1750}
1751
1753{
1754 if (built_map_.check_is_built_and_tag(obdata)) {
1755 return;
1756 }
1757 OperationNode *op_node;
1758 /* Make sure we've got an ID node before requesting evaluated pointer. */
1759 (void)add_id_node(obdata);
1760 ID *obdata_cow = get_cow_id(obdata);
1763 /* Animation. */
1764 build_animdata(obdata);
1765 /* ShapeKeys */
1766 Key *key = BKE_key_from_id(obdata);
1767 if (key) {
1768 build_shapekeys(key);
1769 }
1770 /* Nodes for result of obdata's evaluation, and geometry
1771 * evaluation on object. */
1772 const ID_Type id_type = GS(obdata->name);
1773 switch (id_type) {
1774 case ID_ME: {
1775 op_node = add_operation_node(obdata,
1778 [obdata_cow](::Depsgraph *depsgraph) {
1779 BKE_mesh_eval_geometry(depsgraph, (Mesh *)obdata_cow);
1780 });
1781 op_node->set_as_entry();
1782 break;
1783 }
1784 case ID_MB: {
1786 op_node->set_as_entry();
1787 break;
1788 }
1789 case ID_CU_LEGACY: {
1790 op_node = add_operation_node(obdata,
1793 [obdata_cow](::Depsgraph *depsgraph) {
1794 BKE_curve_eval_geometry(depsgraph, (Curve *)obdata_cow);
1795 });
1796 op_node->set_as_entry();
1797 Curve *cu = (Curve *)obdata;
1798 if (cu->bevobj != nullptr) {
1800 }
1801 if (cu->taperobj != nullptr) {
1803 }
1804 if (cu->textoncurve != nullptr) {
1806 }
1807 break;
1808 }
1809 case ID_LT: {
1810 op_node = add_operation_node(obdata,
1813 [obdata_cow](::Depsgraph *depsgraph) {
1815 });
1816 op_node->set_as_entry();
1817 break;
1818 }
1819
1820 case ID_CV: {
1821 Curves *curves_id = reinterpret_cast<Curves *>(obdata);
1822
1824 op_node->set_as_entry();
1825
1826 if (curves_id->surface != nullptr) {
1827 build_object(-1, curves_id->surface, DEG_ID_LINKED_INDIRECTLY, false);
1828 }
1829 break;
1830 }
1831 case ID_PT: {
1833 op_node->set_as_entry();
1834 break;
1835 }
1836 case ID_VO: {
1837 /* Volume frame update. */
1838 op_node = add_operation_node(obdata,
1841 [obdata_cow](::Depsgraph *depsgraph) {
1843 });
1844 op_node->set_as_entry();
1845 break;
1846 }
1847 case ID_GP: {
1848 op_node = add_operation_node(obdata,
1851 [obdata_cow](::Depsgraph *depsgraph) {
1853 depsgraph, reinterpret_cast<GreasePencil *>(obdata_cow));
1854 });
1855 op_node->set_as_entry();
1856 break;
1857 }
1858 default:
1859 BLI_assert_msg(0, "Should not happen");
1860 break;
1861 }
1863 op_node->set_as_exit();
1864 /* Parameters for driver sources. */
1865 build_parameters(obdata);
1866 /* Batch cache. */
1867 add_operation_node(obdata,
1870 [obdata_cow](::Depsgraph *depsgraph) {
1872 });
1873 /* Shading (No-Op).
1874 * Needed to allow the Material shading updates reach the Object. */
1876}
1877
1879{
1880 if (built_map_.check_is_built_and_tag(armature)) {
1881 return;
1882 }
1883 build_idproperties(armature->id.properties);
1885 build_animdata(&armature->id);
1886 build_parameters(&armature->id);
1887 /* This operation is no longer necessary, as it was updating things with the bone layers (which
1888 * got replaced by bone collections). However, it's still used by other depsgraph components as a
1889 * dependency, so for now the node itself is kept as a no-op.
1890 * TODO: remove this node & the references to it, if eventually it turns out we really don't need
1891 * this.
1892 */
1895 build_armature_bones(&armature->bonebase);
1896 build_armature_bone_collections(armature->collections_span());
1897}
1898
1900{
1901 LISTBASE_FOREACH (Bone *, bone, bones) {
1902 build_idproperties(bone->prop);
1903 build_idproperties(bone->system_properties);
1904 build_armature_bones(&bone->childbase);
1905 }
1906}
1907
1910{
1911 for (BoneCollection *bcoll : collections) {
1912 build_idproperties(bcoll->prop);
1913 build_idproperties(bcoll->system_properties);
1914 }
1915}
1916
1918{
1919 if (built_map_.check_is_built_and_tag(camera)) {
1920 return;
1921 }
1924 build_animdata(&camera->id);
1925 build_parameters(&camera->id);
1926 if (camera->dof.focus_object != nullptr) {
1928 }
1929}
1930
1932{
1933 if (built_map_.check_is_built_and_tag(lamp)) {
1934 return;
1935 }
1938 build_animdata(&lamp->id);
1939 build_parameters(&lamp->id);
1940 /* light's nodetree */
1941 build_nodetree(lamp->nodetree);
1942
1943 Light *lamp_cow = get_cow_datablock(lamp);
1944 add_operation_node(&lamp->id,
1947 [lamp_cow](::Depsgraph *depsgraph) { BKE_light_eval(depsgraph, lamp_cow); });
1948}
1949
1951{
1952 build_idproperties(socket->prop);
1953
1954 if (socket->type == SOCK_OBJECT) {
1955 build_id((ID *)((bNodeSocketValueObject *)socket->default_value)->value);
1956 }
1957 else if (socket->type == SOCK_IMAGE) {
1958 build_id((ID *)((bNodeSocketValueImage *)socket->default_value)->value);
1959 }
1960 else if (socket->type == SOCK_COLLECTION) {
1961 build_id((ID *)((bNodeSocketValueCollection *)socket->default_value)->value);
1962 }
1963 else if (socket->type == SOCK_TEXTURE) {
1964 build_id((ID *)((bNodeSocketValueTexture *)socket->default_value)->value);
1965 }
1966 else if (socket->type == SOCK_MATERIAL) {
1967 build_id((ID *)((bNodeSocketValueMaterial *)socket->default_value)->value);
1968 }
1969}
1970
1972{
1973 if (ntree == nullptr) {
1974 return;
1975 }
1976 if (built_map_.check_is_built_and_tag(ntree)) {
1977 return;
1978 }
1979 /* nodetree itself */
1980 add_id_node(&ntree->id);
1981 /* General parameters. */
1982 build_parameters(&ntree->id);
1985 /* Animation, */
1986 build_animdata(&ntree->id);
1987 /* Output update. */
1989 if (ntree->type == NTREE_GEOMETRY) {
1990 ID *id_cow = get_cow_id(&ntree->id);
1991 add_operation_node(&ntree->id,
1994 [id_cow](::Depsgraph * /*depsgraph*/) {
1995 bNodeTree *ntree_cow = reinterpret_cast<bNodeTree *>(id_cow);
1996 bke::node_tree_runtime::preprocess_geometry_node_tree_for_evaluation(
1997 *ntree_cow);
1998 });
1999 }
2000
2001 /* nodetree's nodes... */
2002 for (bNode *bnode : ntree->all_nodes()) {
2003 build_idproperties(bnode->prop);
2004 LISTBASE_FOREACH (bNodeSocket *, socket, &bnode->inputs) {
2005 build_nodetree_socket(socket);
2006 }
2007 LISTBASE_FOREACH (bNodeSocket *, socket, &bnode->outputs) {
2008 build_nodetree_socket(socket);
2009 }
2010
2011 ID *id = bnode->id;
2012 if (id == nullptr) {
2013 continue;
2014 }
2015 ID_Type id_type = GS(id->name);
2016 if (id_type == ID_MA) {
2017 build_material((Material *)id);
2018 }
2019 else if (id_type == ID_TE) {
2020 build_texture((Tex *)id);
2021 }
2022 else if (id_type == ID_IM) {
2023 build_image((Image *)id);
2024 }
2025 else if (id_type == ID_OB) {
2026 /* TODO(sergey): Use visibility of owner of the node tree. */
2028 }
2029 else if (id_type == ID_SCE) {
2030 Scene *node_scene = (Scene *)id;
2031 build_scene_parameters(node_scene);
2032 /* Camera is used by defocus node.
2033 *
2034 * On the one hand it's annoying to always pull it in, but on another hand it's also annoying
2035 * to have hardcoded node-type exception here. */
2036 if (node_scene->camera != nullptr) {
2037 /* TODO(sergey): Use visibility of owner of the node tree. */
2038 build_object(-1, node_scene->camera, DEG_ID_LINKED_INDIRECTLY, true);
2039 }
2040 }
2041 else if (id_type == ID_TXT) {
2042 /* Ignore script nodes. */
2043 }
2044 else if (id_type == ID_MSK) {
2045 build_mask((Mask *)id);
2046 }
2047 else if (id_type == ID_MC) {
2049 }
2050 else if (id_type == ID_VF) {
2051 build_vfont((VFont *)id);
2052 }
2053 else if (id_type == ID_GR) {
2054 build_collection(nullptr, reinterpret_cast<Collection *>(id));
2055 }
2056 else if (bnode->is_group()) {
2057 bNodeTree *group_ntree = (bNodeTree *)id;
2058 build_nodetree(group_ntree);
2059 }
2060 else {
2061 /* Ignore this case. It can happen when the node type is not known currently. Either because
2062 * it belongs to an add-on or because it comes from a different Blender version that does
2063 * support the ID type here already. */
2064 }
2065 }
2066
2067 /* Needed for interface cache. */
2068 ntree->ensure_interface_cache();
2069 for (bNodeTreeInterfaceSocket *socket : ntree->interface_inputs()) {
2070 build_idproperties(socket->properties);
2071 }
2072 for (bNodeTreeInterfaceSocket *socket : ntree->interface_outputs()) {
2073 build_idproperties(socket->properties);
2074 }
2075
2076 /* TODO: link from nodetree to owner_component? */
2077}
2078
2080{
2081 if (built_map_.check_is_built_and_tag(material)) {
2082 return;
2083 }
2084 /* Material itself. */
2085 add_id_node(&material->id);
2086 Material *material_cow = get_cow_datablock(material);
2087 /* Shading update. */
2089 &material->id,
2092 [material_cow](::Depsgraph *depsgraph) { BKE_material_eval(depsgraph, material_cow); });
2093 build_idproperties(material->id.properties);
2095 /* Material animation. */
2096 build_animdata(&material->id);
2097 build_parameters(&material->id);
2098 /* Material's nodetree. */
2099 build_nodetree(material->nodetree);
2100}
2101
2102void DepsgraphNodeBuilder::build_materials(Material **materials, int num_materials)
2103{
2104 for (int i = 0; i < num_materials; i++) {
2105 if (materials[i] == nullptr) {
2106 continue;
2107 }
2108 build_material(materials[i]);
2109 }
2110}
2111
2113{
2114 if (built_map_.check_is_built_and_tag(texture)) {
2115 return;
2116 }
2117 /* Texture itself. */
2118 add_id_node(&texture->id);
2119 Tex *texture_cow = get_cow_datablock(texture);
2120 build_idproperties(texture->id.properties);
2121 build_idproperties(texture->id.system_properties);
2122 build_animdata(&texture->id);
2124 /* Texture's nodetree. */
2125 build_nodetree(texture->nodetree);
2126 /* Special cases for different IDs which texture uses. */
2127 if (texture->type == TEX_IMAGE) {
2128 if (texture->ima != nullptr) {
2129 build_image(texture->ima);
2130 }
2131 }
2135 [texture_cow](::Depsgraph *depsgraph) {
2136 texture_cow->runtime.last_update = DEG_get_update_count(depsgraph);
2137 });
2138}
2139
2141{
2142 if (built_map_.check_is_built_and_tag(image)) {
2143 return;
2144 }
2145 build_parameters(&image->id);
2150}
2151
2153{
2154 if (built_map_.check_is_built_and_tag(cache_file)) {
2155 return;
2156 }
2157 ID *cache_file_id = &cache_file->id;
2158 add_id_node(cache_file_id);
2159 CacheFile *cache_file_cow = get_cow_datablock(cache_file);
2160 build_idproperties(cache_file_id->properties);
2161 build_idproperties(cache_file_id->system_properties);
2162 /* Animation, */
2163 build_animdata(cache_file_id);
2164 build_parameters(cache_file_id);
2165 /* Cache evaluation itself. */
2166 add_operation_node(cache_file_id,
2169 [bmain = bmain_, cache_file_cow](::Depsgraph *depsgraph) {
2170 BKE_cachefile_eval(bmain, depsgraph, cache_file_cow);
2171 });
2172}
2173
2175{
2176 if (built_map_.check_is_built_and_tag(mask)) {
2177 return;
2178 }
2179 ID *mask_id = &mask->id;
2180 Mask *mask_cow = (Mask *)ensure_cow_id(mask_id);
2181 build_idproperties(mask->id.properties);
2182 build_idproperties(mask->id.system_properties);
2183 /* F-Curve based animation. */
2184 build_animdata(mask_id);
2185 build_parameters(mask_id);
2186 /* Animation based on mask's shapes. */
2188 mask_id,
2191 [mask_cow](::Depsgraph *depsgraph) { BKE_mask_eval_animation(depsgraph, mask_cow); });
2192 /* Final mask evaluation. */
2196 });
2197 /* Build parents. */
2198 LISTBASE_FOREACH (MaskLayer *, mask_layer, &mask->masklayers) {
2199 LISTBASE_FOREACH (MaskSpline *, spline, &mask_layer->splines) {
2200 for (int i = 0; i < spline->tot_point; i++) {
2201 MaskSplinePoint *point = &spline->points[i];
2202 MaskParent *parent = &point->parent;
2203 if (parent == nullptr || parent->id == nullptr) {
2204 continue;
2205 }
2206 build_id(parent->id);
2207 }
2208 }
2209 }
2210}
2211
2213{
2214 if (built_map_.check_is_built_and_tag(linestyle)) {
2215 return;
2216 }
2217
2218 ID *linestyle_id = &linestyle->id;
2219 build_parameters(linestyle_id);
2220 build_idproperties(linestyle->id.properties);
2222 build_animdata(linestyle_id);
2223 build_nodetree(linestyle->nodetree);
2224}
2225
2227{
2228 if (built_map_.check_is_built_and_tag(clip)) {
2229 return;
2230 }
2231 ID *clip_id = &clip->id;
2232 MovieClip *clip_cow = (MovieClip *)ensure_cow_id(clip_id);
2235 /* Animation. */
2236 build_animdata(clip_id);
2237 build_parameters(clip_id);
2238 /* Movie clip evaluation. */
2239 add_operation_node(clip_id,
2242 [bmain = bmain_, clip_cow](::Depsgraph *depsgraph) {
2243 BKE_movieclip_eval_update(depsgraph, bmain, clip_cow);
2244 });
2245}
2246
2248{
2249 if (built_map_.check_is_built_and_tag(probe)) {
2250 return;
2251 }
2252 /* Placeholder so we can add relations and tag ID node for update. */
2256 build_animdata(&probe->id);
2257 build_parameters(&probe->id);
2258}
2259
2261{
2262 if (built_map_.check_is_built_and_tag(speaker)) {
2263 return;
2264 }
2265 /* Placeholder so we can add relations and tag ID node for update. */
2269 build_animdata(&speaker->id);
2270 build_parameters(&speaker->id);
2271 if (speaker->sound != nullptr) {
2272 build_sound(speaker->sound);
2273 }
2274}
2275
2277{
2278 if (built_map_.check_is_built_and_tag(sound)) {
2279 return;
2280 }
2281 add_id_node(&sound->id);
2282 bSound *sound_cow = get_cow_datablock(sound);
2283 add_operation_node(&sound->id,
2286 [bmain = bmain_, sound_cow](::Depsgraph *depsgraph) {
2287 BKE_sound_evaluate(depsgraph, bmain, sound_cow);
2288 });
2291 build_animdata(&sound->id);
2292 build_parameters(&sound->id);
2293}
2294
2296{
2297 if (built_map_.check_is_built_and_tag(vfont)) {
2298 return;
2299 }
2300 build_parameters(&vfont->id);
2305}
2306
2307static bool strip_node_build_cb(Strip *strip, void *user_data)
2308{
2309 DepsgraphNodeBuilder *nb = (DepsgraphNodeBuilder *)user_data;
2310 nb->build_idproperties(strip->prop);
2312 if (strip->sound != nullptr) {
2313 nb->build_sound(strip->sound);
2314 }
2315 if (strip->scene != nullptr) {
2316 nb->build_scene_parameters(strip->scene);
2317 }
2318 if (strip->type == STRIP_TYPE_SCENE && strip->scene != nullptr) {
2319 if (strip->flag & SEQ_SCENE_STRIPS) {
2320 nb->build_scene_sequencer(strip->scene);
2321 }
2322 ViewLayer *sequence_view_layer = BKE_view_layer_default_render(strip->scene);
2323 nb->build_scene_speakers(strip->scene, sequence_view_layer);
2324 }
2327 continue;
2328 }
2329
2330 const SequencerCompositorModifierData *modifier_data =
2331 reinterpret_cast<SequencerCompositorModifierData *>(modifier);
2332 if (!modifier_data->node_group) {
2333 continue;
2334 }
2335 nb->build_nodetree(modifier_data->node_group);
2336 }
2337 /* TODO(sergey): Movie clip, scene, camera, mask. */
2338 return true;
2339}
2340
2342{
2343 if (scene->ed == nullptr) {
2344 return;
2345 }
2346 if (built_map_.check_is_built_and_tag(scene, BuilderMap::TAG_SCENE_SEQUENCER)) {
2347 return;
2348 }
2349 build_scene_audio(scene);
2350 Scene *scene_cow = get_cow_datablock(scene);
2351 add_operation_node(&scene->id,
2354 [scene_cow](::Depsgraph *depsgraph) {
2355 seq::eval_strips(depsgraph, scene_cow, &scene_cow->ed->seqbase);
2356 });
2357 /* Make sure data for sequences is in the graph. */
2359}
2360
2362{
2363 if (built_map_.check_is_built_and_tag(scene, BuilderMap::TAG_SCENE_AUDIO)) {
2364 return;
2365 }
2366
2367 OperationNode *audio_entry_node = add_operation_node(
2369 audio_entry_node->set_as_entry();
2370
2372
2373 Scene *scene_cow = get_cow_datablock(scene);
2374 add_operation_node(&scene->id,
2377 [scene_cow](::Depsgraph *depsgraph) {
2378 BKE_scene_update_tag_audio_volume(depsgraph, scene_cow);
2379 });
2380}
2381
2383{
2384 BKE_view_layer_synced_ensure(scene, view_layer);
2386 Object *object = base->object;
2387 if (object->type != OB_SPEAKER || !need_pull_base_into_graph(base)) {
2388 continue;
2389 }
2390 /* NOTE: Can not use base because it does not belong to a current view layer. */
2391 build_object(-1, base->object, DEG_ID_LINKED_INDIRECTLY, true);
2392 }
2393}
2394
2395/* **** ID traversal callbacks functions **** */
2396
2398 Object * /*object*/,
2399 ID **idpoin,
2400 LibraryForeachIDCallbackFlag /*cb_flag*/)
2401{
2403 ID *id = *idpoin;
2404 if (id == nullptr) {
2405 return;
2406 }
2407 switch (GS(id->name)) {
2408 case ID_OB:
2409 data->builder->build_object(-1, (Object *)id, DEG_ID_LINKED_INDIRECTLY, false);
2410 break;
2411 default:
2412 data->builder->build_id(id);
2413 break;
2414 }
2415}
2416
2418 ID **idpoin,
2419 bool /*is_reference*/,
2420 void *user_data)
2421{
2423 ID *id = *idpoin;
2424 if (id == nullptr) {
2425 return;
2426 }
2427 switch (GS(id->name)) {
2428 case ID_OB:
2429 data->builder->build_object(-1, (Object *)id, DEG_ID_LINKED_INDIRECTLY, false);
2430 break;
2431 default:
2432 data->builder->build_id(id);
2433 break;
2434 }
2435}
2436
2437} // namespace blender::deg
Blender kernel action and pose functionality.
AnimData * BKE_animdata_from_id(const ID *id)
Definition anim_data.cc:83
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:329
#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:5483
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:1771
void BKE_lattice_eval_geometry(Depsgraph *depsgraph, Lattice *latt)
Definition lattice.cc:697
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
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_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_TAG_COPIED_ON_EVAL
Definition DNA_ID.h:997
#define ID_TYPE_USE_COPY_ON_EVAL(_id_type)
Definition DNA_ID.h:740
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1118
#define ID_TYPE_SUPPORTS_PARAMS_WITHOUT_COW(id_type)
Definition DNA_ID.h:745
@ ID_FLAG_EMBEDDED_DATA
Definition DNA_ID.h:774
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_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
@ eSeqModifierType_Compositor
@ STRIP_TYPE_SCENE
@ SEQ_SCENE_STRIPS
@ TEX_IMAGE
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
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)
#define GS(x)
TEX_TEMPLATE DataVec texture(T, FltCoord, float=0.0f) RET
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:4543
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 foreach_strip(ListBase *seqbase, ForEachFunc callback, void *user_data)
Definition iterator.cc:59
const char * name
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:142
IDPropertyData data
Definition DNA_ID.h:169
Definition DNA_ID.h:414
unsigned int recalc
Definition DNA_ID.h:445
int tag
Definition DNA_ID.h:442
char name[258]
Definition DNA_ID.h:432
IDProperty * system_properties
Definition DNA_ID.h:489
IDProperty * properties
Definition DNA_ID.h:480
struct ID * orig_id
Definition DNA_ID.h:501
short flag
Definition DNA_ID.h:438
unsigned int session_uid
Definition DNA_ID.h:462
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 IDProperty * system_properties
ListBase modifiers
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:4238