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