Blender  V3.3
deg_builder_relations.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2013 Blender Foundation. All rights reserved. */
3 
11 
12 #include <cstdio>
13 #include <cstdlib>
14 #include <cstring> /* required for STREQ later on. */
15 
16 #include "MEM_guardedalloc.h"
17 
18 #include "BLI_blenlib.h"
19 #include "BLI_utildefines.h"
20 
21 #include "DNA_action_types.h"
22 #include "DNA_anim_types.h"
23 #include "DNA_armature_types.h"
24 #include "DNA_cachefile_types.h"
25 #include "DNA_camera_types.h"
26 #include "DNA_cloth_types.h"
27 #include "DNA_collection_types.h"
28 #include "DNA_constraint_types.h"
29 #include "DNA_curve_types.h"
30 #include "DNA_curves_types.h"
31 #include "DNA_effect_types.h"
32 #include "DNA_gpencil_types.h"
33 #include "DNA_key_types.h"
34 #include "DNA_light_types.h"
35 #include "DNA_lightprobe_types.h"
36 #include "DNA_linestyle_types.h"
37 #include "DNA_mask_types.h"
38 #include "DNA_material_types.h"
39 #include "DNA_mesh_types.h"
40 #include "DNA_meta_types.h"
41 #include "DNA_movieclip_types.h"
42 #include "DNA_node_types.h"
43 #include "DNA_object_force_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_simulation_types.h"
50 #include "DNA_sound_types.h"
51 #include "DNA_speaker_types.h"
52 #include "DNA_texture_types.h"
53 #include "DNA_vfont_types.h"
54 #include "DNA_volume_types.h"
55 #include "DNA_world_types.h"
56 
57 #include "BKE_action.h"
58 #include "BKE_anim_data.h"
59 #include "BKE_armature.h"
60 #include "BKE_collection.h"
61 #include "BKE_collision.h"
62 #include "BKE_constraint.h"
63 #include "BKE_curve.h"
64 #include "BKE_effect.h"
65 #include "BKE_fcurve_driver.h"
66 #include "BKE_gpencil_modifier.h"
67 #include "BKE_idprop.h"
68 #include "BKE_image.h"
69 #include "BKE_key.h"
70 #include "BKE_layer.h"
71 #include "BKE_material.h"
72 #include "BKE_mball.h"
73 #include "BKE_modifier.h"
74 #include "BKE_node.h"
75 #include "BKE_node_runtime.hh"
76 #include "BKE_object.h"
77 #include "BKE_particle.h"
78 #include "BKE_pointcache.h"
79 #include "BKE_rigidbody.h"
80 #include "BKE_shader_fx.h"
81 #include "BKE_shrinkwrap.h"
82 #include "BKE_sound.h"
83 #include "BKE_tracking.h"
84 #include "BKE_world.h"
85 
86 #include "RNA_access.h"
87 #include "RNA_prototypes.h"
88 #include "RNA_types.h"
89 
90 #include "SEQ_iterator.h"
91 
92 #include "DEG_depsgraph.h"
93 #include "DEG_depsgraph_build.h"
94 
98 #include "intern/debug/deg_debug.h"
100 #include "intern/depsgraph_tag.h"
102 
103 #include "intern/node/deg_node.h"
105 #include "intern/node/deg_node_id.h"
108 
109 #include "intern/depsgraph.h"
111 #include "intern/depsgraph_type.h"
112 
113 namespace blender::deg {
114 
115 /* ***************** */
116 /* Relations Builder */
117 
118 namespace {
119 
120 bool driver_target_depends_on_time(const DriverTarget *target)
121 {
122  if (target->idtype == ID_SCE &&
123  (target->rna_path != nullptr && STREQ(target->rna_path, "frame_current"))) {
124  return true;
125  }
126  return false;
127 }
128 
129 bool driver_variable_depends_on_time(const DriverVar *variable)
130 {
131  for (int i = 0; i < variable->num_targets; ++i) {
132  if (driver_target_depends_on_time(&variable->targets[i])) {
133  return true;
134  }
135  }
136  return false;
137 }
138 
139 bool driver_variables_depends_on_time(const ListBase *variables)
140 {
141  LISTBASE_FOREACH (const DriverVar *, variable, variables) {
142  if (driver_variable_depends_on_time(variable)) {
143  return true;
144  }
145  }
146  return false;
147 }
148 
149 bool driver_depends_on_time(ChannelDriver *driver)
150 {
152  return true;
153  }
154  if (driver_variables_depends_on_time(&driver->variables)) {
155  return true;
156  }
157  return false;
158 }
159 
160 bool particle_system_depends_on_time(ParticleSystem *psys)
161 {
162  ParticleSettings *part = psys->part;
163  /* Non-hair particles we always consider dependent on time. */
164  if (part->type != PART_HAIR) {
165  return true;
166  }
167  /* Dynamics always depends on time. */
168  if (psys->flag & PSYS_HAIR_DYNAMICS) {
169  return true;
170  }
171  /* TODO(sergey): Check what else makes hair dependent on time. */
172  return false;
173 }
174 
175 bool object_particles_depends_on_time(Object *object)
176 {
177  if (object->type != OB_MESH) {
178  return false;
179  }
180  LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) {
181  if (particle_system_depends_on_time(psys)) {
182  return true;
183  }
184  }
185  return false;
186 }
187 
188 bool check_id_has_anim_component(ID *id)
189 {
190  AnimData *adt = BKE_animdata_from_id(id);
191  if (adt == nullptr) {
192  return false;
193  }
194  return (adt->action != nullptr) || (!BLI_listbase_is_empty(&adt->nla_tracks));
195 }
196 
197 bool check_id_has_driver_component(ID *id)
198 {
199  AnimData *adt = BKE_animdata_from_id(id);
200  if (adt == nullptr) {
201  return false;
202  }
203  return !BLI_listbase_is_empty(&adt->drivers);
204 }
205 
206 OperationCode bone_target_opcode(ID *target,
207  const char *subtarget,
208  ID *id,
209  const char *component_subdata,
210  RootPChanMap *root_map)
211 {
212  /* Same armature. */
213  if (target == id) {
214  /* Using "done" here breaks in-chain deps, while using
215  * "ready" here breaks most production rigs instead.
216  * So, we do a compromise here, and only do this when an
217  * IK chain conflict may occur. */
218  if (root_map->has_common_root(component_subdata, subtarget)) {
220  }
221  }
223 }
224 
225 bool object_have_geometry_component(const Object *object)
226 {
227  return ELEM(
229 }
230 
231 } // namespace
232 
233 /* **** General purpose functions **** */
234 
236  Depsgraph *graph,
237  DepsgraphBuilderCache *cache)
238  : DepsgraphBuilder(bmain, graph, cache), scene_(nullptr), rna_node_query_(graph, this)
239 {
240 }
241 
243 {
244  if (key.id) {
245  /* XXX TODO */
246  return nullptr;
247  }
248 
249  return graph_->time_source;
250 }
251 
253 {
255  if (!id_node) {
256  fprintf(stderr,
257  "find_node component: Could not find ID %s\n",
258  (key.id != nullptr) ? key.id->name : "<null>");
259  return nullptr;
260  }
261 
262  ComponentNode *node = id_node->find_component(key.type, key.name);
263  return node;
264 }
265 
267 {
268  OperationNode *op_node = find_node(key);
269  if (op_node == nullptr) {
270  fprintf(stderr,
271  "find_node_operation: Failed for (%s, '%s')\n",
273  key.name);
274  }
275  return op_node;
276 }
277 
279 {
280  return rna_node_query_.find_node(&key.ptr, key.prop, key.source);
281 }
282 
284 {
286  if (!id_node) {
287  return nullptr;
288  }
289  ComponentNode *comp_node = id_node->find_component(key.component_type, key.component_name);
290  if (!comp_node) {
291  return nullptr;
292  }
293  return comp_node->find_operation(key.opcode, key.name, key.name_tag);
294 }
295 
297 {
298  return find_node(key) != nullptr;
299 }
300 
302  const char *description)
303 {
304  IDNode *id_node = handle->node->owner->owner;
305  ID *id = id_node->id_orig;
306  ComponentKey geometry_key(id, NodeType::GEOMETRY);
307  /* Wire up the actual relation. */
308  add_depends_on_transform_relation(id, geometry_key, description);
309 }
310 
312  const DEGCustomDataMeshMasks &customdata_masks)
313 {
314  if (customdata_masks != DEGCustomDataMeshMasks() && object != nullptr &&
315  object->type == OB_MESH) {
316  IDNode *id_node = graph_->find_id_node(&object->id);
317 
318  if (id_node == nullptr) {
319  BLI_assert_msg(0, "ID should always be valid");
320  }
321  else {
322  id_node->customdata_masks |= customdata_masks;
323  }
324  }
325 }
326 
328 {
330  if (id_node == nullptr) {
331  BLI_assert_msg(0, "ID should always be valid");
332  }
333  else {
334  id_node->eval_flags |= flag;
335  }
336 }
337 
339  Node *node_to,
340  const char *description,
341  int flags)
342 {
343  if (timesrc && node_to) {
344  return graph_->add_new_relation(timesrc, node_to, description, flags);
345  }
346 
348  BUILD,
349  "add_time_relation(%p = %s, %p = %s, %s) Failed\n",
350  timesrc,
351  (timesrc) ? timesrc->identifier().c_str() : "<None>",
352  node_to,
353  (node_to) ? node_to->identifier().c_str() : "<None>",
354  description);
355 
356  return nullptr;
357 }
358 
360 {
361  ComponentKey from_key(id_from, NodeType::VISIBILITY);
362  ComponentKey to_key(id_to, NodeType::VISIBILITY);
363  add_relation(from_key, to_key, "visibility");
364 }
365 
367  OperationNode *node_to,
368  const char *description,
369  int flags)
370 {
371  if (node_from && node_to) {
372  return graph_->add_new_relation(node_from, node_to, description, flags);
373  }
374 
376  BUILD,
377  "add_operation_relation(%p = %s, %p = %s, %s) Failed\n",
378  node_from,
379  (node_from) ? node_from->identifier().c_str() : "<None>",
380  node_to,
381  (node_to) ? node_to->identifier().c_str() : "<None>",
382  description);
383 
384  return nullptr;
385 }
386 
388  Object *object,
389  Collection *collection,
390  const char *name)
391 {
393 
394  LISTBASE_FOREACH (CollisionRelation *, relation, relations) {
395  if (relation->ob != object) {
396  ComponentKey trf_key(&relation->ob->id, NodeType::TRANSFORM);
397  add_relation(trf_key, key, name);
398 
399  ComponentKey coll_key(&relation->ob->id, NodeType::GEOMETRY);
400  add_relation(coll_key, key, name);
401  }
402  }
403 }
404 
406  Object *object,
407  ParticleSystem *psys,
408  EffectorWeights *eff,
409  bool add_absorption,
410  const char *name)
411 {
412  ListBase *relations = build_effector_relations(graph_, eff->group);
413 
414  /* Make sure physics effects like wind are properly re-evaluating the modifier stack. */
415  if (!BLI_listbase_is_empty(relations)) {
416  TimeSourceKey time_src_key;
417  ComponentKey geometry_key(&object->id, NodeType::GEOMETRY);
418  add_relation(
419  time_src_key, geometry_key, "Effector Time -> Particle", RELATION_CHECK_BEFORE_ADD);
420  }
421 
422  LISTBASE_FOREACH (EffectorRelation *, relation, relations) {
423  if (relation->ob != object) {
424  /* Relation to forcefield object, optionally including geometry. */
425  ComponentKey eff_key(&relation->ob->id, NodeType::TRANSFORM);
426  add_relation(eff_key, key, name);
427 
428  if (ELEM(relation->pd->shape, PFIELD_SHAPE_SURFACE, PFIELD_SHAPE_POINTS) ||
429  relation->pd->forcefield == PFIELD_GUIDE) {
430  ComponentKey mod_key(&relation->ob->id, NodeType::GEOMETRY);
431  add_relation(mod_key, key, name);
432  }
433 
434  /* Force field Texture. */
435  if ((relation->pd != nullptr) && (relation->pd->forcefield == PFIELD_TEXTURE) &&
436  (relation->pd->tex != nullptr)) {
437  ComponentKey tex_key(&relation->pd->tex->id, NodeType::GENERIC_DATABLOCK);
438  add_relation(tex_key, key, "Force field Texture");
439  }
440 
441  /* Smoke flow relations. */
442  if (relation->pd->forcefield == PFIELD_FLUIDFLOW && relation->pd->f_source) {
443  ComponentKey trf_key(&relation->pd->f_source->id, NodeType::TRANSFORM);
444  add_relation(trf_key, key, "Smoke Force Domain");
445  ComponentKey eff_key(&relation->pd->f_source->id, NodeType::GEOMETRY);
446  add_relation(eff_key, key, "Smoke Force Domain");
447  }
448 
449  /* Absorption forces need collision relation. */
450  if (add_absorption && (relation->pd->flag & PFIELD_VISIBILITY)) {
451  add_particle_collision_relations(key, object, nullptr, "Force Absorption");
452  }
453  }
454 
455  if (relation->psys) {
456  if (relation->ob != object) {
457  ComponentKey eff_key(&relation->ob->id, NodeType::PARTICLE_SYSTEM);
458  add_relation(eff_key, key, name);
459  /* TODO: remove this when/if EVAL_PARTICLES is sufficient
460  * for up to date particles. */
461  ComponentKey mod_key(&relation->ob->id, NodeType::GEOMETRY);
462  add_relation(mod_key, key, name);
463  }
464  else if (relation->psys != psys) {
465  OperationKey eff_key(&relation->ob->id,
468  relation->psys->name);
469  add_relation(eff_key, key, name);
470  }
471  }
472  }
473 }
474 
476 {
477  return graph_;
478 }
479 
480 /* **** Functions to build relations between entities **** */
481 
483 {
484 }
485 
487 {
488  if (id == nullptr) {
489  return;
490  }
491 
492  const ID_Type id_type = GS(id->name);
493  switch (id_type) {
494  case ID_AC:
495  build_action((bAction *)id);
496  break;
497  case ID_AR:
498  build_armature((bArmature *)id);
499  break;
500  case ID_CA:
501  build_camera((Camera *)id);
502  break;
503  case ID_GR:
504  build_collection(nullptr, nullptr, (Collection *)id);
505  break;
506  case ID_OB:
507  build_object((Object *)id);
508  break;
509  case ID_KE:
510  build_shapekeys((Key *)id);
511  break;
512  case ID_LA:
513  build_light((Light *)id);
514  break;
515  case ID_LP:
517  break;
518  case ID_NT:
519  build_nodetree((bNodeTree *)id);
520  break;
521  case ID_MA:
522  build_material((Material *)id);
523  break;
524  case ID_TE:
525  build_texture((Tex *)id);
526  break;
527  case ID_IM:
528  build_image((Image *)id);
529  break;
530  case ID_WO:
531  build_world((World *)id);
532  break;
533  case ID_MSK:
534  build_mask((Mask *)id);
535  break;
536  case ID_LS:
538  break;
539  case ID_MC:
540  build_movieclip((MovieClip *)id);
541  break;
542  case ID_ME:
543  case ID_MB:
544  case ID_CU_LEGACY:
545  case ID_LT:
546  case ID_CV:
547  case ID_PT:
548  case ID_VO:
549  case ID_GD:
551  break;
552  case ID_SPK:
553  build_speaker((Speaker *)id);
554  break;
555  case ID_SO:
556  build_sound((bSound *)id);
557  break;
558  case ID_TXT:
559  /* Not a part of dependency graph. */
560  break;
561  case ID_CF:
562  build_cachefile((CacheFile *)id);
563  break;
564  case ID_SCE:
566  break;
567  case ID_SIM:
569  break;
570  case ID_PA:
572  break;
573 
574  case ID_LI:
575  case ID_IP:
576  case ID_SCR:
577  case ID_VF:
578  case ID_BR:
579  case ID_WM:
580  case ID_PAL:
581  case ID_PC:
582  case ID_WS:
584  build_generic_id(id);
585  break;
586  }
587 }
588 
590 {
591  if (built_map_.checkIsBuiltAndTag(id)) {
592  return;
593  }
594 
595  const BuilderStack::ScopedEntry stack_entry = stack_.trace(*id);
596 
598  build_animdata(id);
599  build_parameters(id);
600 }
601 
602 static void build_idproperties_callback(IDProperty *id_property, void *user_data)
603 {
604  DepsgraphRelationBuilder *builder = reinterpret_cast<DepsgraphRelationBuilder *>(user_data);
605  BLI_assert(id_property->type == IDP_ID);
606  builder->build_id(reinterpret_cast<ID *>(id_property->data.pointer));
607 }
608 
610 {
612 }
613 
615  Object *object,
616  Collection *collection)
617 {
618  if (from_layer_collection != nullptr) {
619  /* If we came from layer collection we don't go deeper, view layer
620  * builder takes care of going deeper.
621  *
622  * NOTE: Do early output before tagging build as done, so possible
623  * subsequent builds from outside of the layer collection properly
624  * recurses into all the nested objects and collections. */
625  return;
626  }
627 
628  const BuilderStack::ScopedEntry stack_entry = stack_.trace(collection->id);
629 
630  const bool group_done = built_map_.checkIsBuiltAndTag(collection);
631  OperationKey object_transform_final_key(object != nullptr ? &object->id : nullptr,
634  ComponentKey duplicator_key(object != nullptr ? &object->id : nullptr, NodeType::DUPLI);
635  if (!group_done) {
636  build_idproperties(collection->id.properties);
637  OperationKey collection_geometry_key{
639  LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) {
640  build_object(cob->ob);
641 
642  /* The geometry of a collection depends on the positions of the elements in it. */
643  OperationKey object_transform_key{
645  add_relation(object_transform_key, collection_geometry_key, "Collection Geometry");
646 
647  /* Only create geometry relations to child objects, if they have a geometry component. */
648  OperationKey object_geometry_key{
650  if (find_node(object_geometry_key) != nullptr) {
651  add_relation(object_geometry_key, collection_geometry_key, "Collection Geometry");
652  }
653 
654  /* An instance is part of the geometry of the collection. */
655  if (cob->ob->type == OB_EMPTY) {
656  Collection *collection_instance = cob->ob->instance_collection;
657  if (collection_instance != nullptr) {
658  OperationKey collection_instance_key{
660  add_relation(collection_instance_key, collection_geometry_key, "Collection Geometry");
661  }
662  }
663  }
664  LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
665  build_collection(nullptr, nullptr, child->collection);
666  OperationKey child_collection_geometry_key{
668  add_relation(child_collection_geometry_key, collection_geometry_key, "Collection Geometry");
669  }
670  }
671  if (object != nullptr) {
673  ComponentKey dupli_transform_key(&ob->id, NodeType::TRANSFORM);
674  add_relation(dupli_transform_key, object_transform_final_key, "Dupligroup");
675  /* Hook to special component, to ensure proper visibility/evaluation
676  * optimizations. */
677  add_relation(dupli_transform_key, duplicator_key, "Dupligroup");
678  const NodeType dupli_geometry_component_type = geometry_tag_to_component(&ob->id);
679  if (dupli_geometry_component_type != NodeType::UNDEFINED) {
680  ComponentKey dupli_geometry_component_key(&ob->id, dupli_geometry_component_type);
681  add_relation(dupli_geometry_component_key, duplicator_key, "Dupligroup");
682  }
683  }
685  }
686 }
687 
689 {
690  if (built_map_.checkIsBuiltAndTag(object)) {
691  return;
692  }
693 
694  const BuilderStack::ScopedEntry stack_entry = stack_.trace(object->id);
695 
696  /* Object Transforms. */
697  OperationCode base_op = (object->parent) ? OperationCode::TRANSFORM_PARENT :
699  OperationKey base_op_key(&object->id, NodeType::TRANSFORM, base_op);
700  OperationKey init_transform_key(&object->id, NodeType::TRANSFORM, OperationCode::TRANSFORM_INIT);
701  OperationKey local_transform_key(
703  OperationKey parent_transform_key(
705  OperationKey transform_eval_key(&object->id, NodeType::TRANSFORM, OperationCode::TRANSFORM_EVAL);
706  OperationKey final_transform_key(
709 
710  add_relation(init_transform_key, local_transform_key, "Transform Init");
711 
712  /* Various flags, flushing from bases/collections. */
714 
715  /* Parenting. */
716  if (object->parent != nullptr) {
717  /* Make sure parent object's relations are built. */
718  build_object(object->parent);
719  /* Parent relationship. */
720  build_object_parent(object);
721  /* Local -> parent. */
722  add_relation(local_transform_key, parent_transform_key, "ObLocal -> ObParent");
723  }
724 
725  /* Modifiers. */
726  if (object->modifiers.first != nullptr) {
727  BuilderWalkUserData data;
728  data.builder = this;
729  BKE_modifiers_foreach_ID_link(object, modifier_walk, &data);
730  }
731 
732  /* Grease Pencil Modifiers. */
733  if (object->greasepencil_modifiers.first != nullptr) {
734  BuilderWalkUserData data;
735  data.builder = this;
736  BKE_gpencil_modifiers_foreach_ID_link(object, modifier_walk, &data);
737  }
738 
739  /* Shader FX. */
740  if (object->shader_fx.first != nullptr) {
741  BuilderWalkUserData data;
742  data.builder = this;
743  BKE_shaderfx_foreach_ID_link(object, modifier_walk, &data);
744  }
745 
746  /* Constraints. */
747  if (object->constraints.first != nullptr) {
748  BuilderWalkUserData data;
749  data.builder = this;
750  BKE_constraints_id_loop(&object->constraints, constraint_walk, &data);
751  }
752 
753  /* Object constraints. */
754  OperationKey object_transform_simulation_init_key(
756  if (object->constraints.first != nullptr) {
757  OperationKey constraint_key(
759  /* Constraint relations. */
760  build_constraints(&object->id, NodeType::TRANSFORM, "", &object->constraints, nullptr);
761  /* operation order */
762  add_relation(base_op_key, constraint_key, "ObBase-> Constraint Stack");
763  add_relation(constraint_key, final_transform_key, "ObConstraints -> Done");
764  add_relation(constraint_key, ob_eval_key, "Constraint -> Transform Eval");
765  add_relation(
766  ob_eval_key, object_transform_simulation_init_key, "Transform Eval -> Simulation Init");
767  add_relation(object_transform_simulation_init_key,
768  final_transform_key,
769  "Simulation -> Final Transform");
770  }
771  else {
772  add_relation(base_op_key, ob_eval_key, "Eval");
773  add_relation(
774  ob_eval_key, object_transform_simulation_init_key, "Transform Eval -> Simulation Init");
775  add_relation(object_transform_simulation_init_key,
776  final_transform_key,
777  "Simulation -> Final Transform");
778  }
779 
781 
782  /* Animation data */
783  build_animdata(&object->id);
784 
785  /* Object data. */
786  build_object_data(object);
787 
788  /* Particle systems. */
789  if (object->particlesystem.first != nullptr) {
790  build_particle_systems(object);
791  }
792 
793  /* Force field Texture. */
794  if ((object->pd != nullptr) && (object->pd->forcefield == PFIELD_TEXTURE) &&
795  (object->pd->tex != nullptr)) {
796  build_texture(object->pd->tex);
797  }
798 
799  /* Object dupligroup. */
800  if (object->instance_collection != nullptr) {
801  build_collection(nullptr, object, object->instance_collection);
802  }
803 
804  /* Point caches. */
805  build_object_pointcache(object);
806 
807  /* Synchronization back to original object. */
808  OperationKey synchronize_key(
810  add_relation(final_transform_key, synchronize_key, "Synchronize to Original");
811 
812  /* Parameters. */
813  build_parameters(&object->id);
814 
815  /* Visibility.
816  * Evaluate visibility node after the object's base_flags has been updated to the current state
817  * of collections restrict and object's restrict flags. */
818  const ComponentKey object_from_layer_entry_key(&object->id, NodeType::OBJECT_FROM_LAYER);
819  const ComponentKey visibility_key(&object->id, NodeType::VISIBILITY);
820  add_relation(object_from_layer_entry_key, visibility_key, "Object Visibility");
821 }
822 
823 /* NOTE: Implies that the object has base in the current view layer. */
825 {
826  /* It is possible to have situation when an object is pulled into the dependency graph in a
827  * few different ways:
828  *
829  * - Indirect driver dependency, which doesn't have a Base (or, Base is unknown).
830  * - Via a base from a view layer (view layer of the graph, or view layer of a set scene).
831  * - Possibly other ways, which are not important for decision making here.
832  *
833  * There needs to be a relation from view layer which has a base with the object so that the
834  * order of flags evaluation is correct (object-level base flags evaluation requires view layer
835  * to be evaluated first).
836  *
837  * This build call handles situation when object comes from a view layer, hence has a base, and
838  * needs a relation from the view layer. Do the relation prior to check of whether the object
839  * relations are built so that the relation is created from every view layer which has a base
840  * with this object. */
841 
842  OperationKey view_layer_done_key(
844  OperationKey object_from_layer_entry_key(
846 
847  add_relation(view_layer_done_key, object_from_layer_entry_key, "View Layer flags to Object");
848 
849  /* Regular object building. */
850  build_object(object);
851 }
852 
854 {
855  OperationKey object_from_layer_entry_key(
857  OperationKey object_from_layer_exit_key(
859  OperationKey object_flags_key(
861 
862  if (!has_node(object_flags_key)) {
863  /* Just connect Entry -> Exit if there is no OBJECT_BASE_FLAGS node. */
864  add_relation(object_from_layer_entry_key, object_from_layer_exit_key, "Object from Layer");
865  return;
866  }
867 
868  /* Entry -> OBJECT_BASE_FLAGS -> Exit */
869  add_relation(object_from_layer_entry_key, object_flags_key, "Base flags flush Entry");
870  add_relation(object_flags_key, object_from_layer_exit_key, "Base flags flush Exit");
871 
872  /* Synchronization back to original object. */
873  OperationKey synchronize_key(
875  add_relation(object_from_layer_exit_key, synchronize_key, "Synchronize to Original");
876 }
877 
879 {
880  if (object->data == nullptr) {
881  return;
882  }
883  ID *obdata_id = (ID *)object->data;
884  /* Object data animation. */
885  if (!built_map_.checkIsBuilt(obdata_id)) {
886  build_animdata(obdata_id);
887  }
888  /* type-specific data. */
889  switch (object->type) {
890  case OB_MESH:
891  case OB_CURVES_LEGACY:
892  case OB_FONT:
893  case OB_SURF:
894  case OB_MBALL:
895  case OB_LATTICE:
896  case OB_GPENCIL:
897  case OB_CURVES:
898  case OB_POINTCLOUD:
899  case OB_VOLUME: {
901  /* TODO(sergey): Only for until we support granular
902  * update of curves. */
903  if (object->type == OB_FONT) {
904  Curve *curve = (Curve *)object->data;
905  if (curve->textoncurve) {
906  ComponentKey geometry_key((ID *)object->data, NodeType::GEOMETRY);
907  ComponentKey transform_key(&object->id, NodeType::TRANSFORM);
908  add_relation(transform_key, geometry_key, "Text on Curve own Transform");
910  }
911  }
912  break;
913  }
914  case OB_ARMATURE:
915  build_rig(object);
916  break;
917  case OB_LAMP:
918  build_object_data_light(object);
919  break;
920  case OB_CAMERA:
921  build_object_data_camera(object);
922  break;
923  case OB_LIGHTPROBE:
925  break;
926  case OB_SPEAKER:
928  break;
929  }
930  Key *key = BKE_key_from_object(object);
931  if (key != nullptr) {
932  ComponentKey geometry_key((ID *)object->data, NodeType::GEOMETRY);
933  ComponentKey key_key(&key->id, NodeType::GEOMETRY);
934  add_relation(key_key, geometry_key, "Shapekeys");
935  build_nested_shapekey(&object->id, key);
936  }
937  /* Materials. */
938  Material ***materials_ptr = BKE_object_material_array_p(object);
939  if (materials_ptr != nullptr) {
940  short *num_materials_ptr = BKE_object_material_len_p(object);
941  build_materials(*materials_ptr, *num_materials_ptr);
942  }
943 }
944 
946 {
947  Camera *camera = (Camera *)object->data;
949  ComponentKey object_parameters_key(&object->id, NodeType::PARAMETERS);
950  ComponentKey camera_parameters_key(&camera->id, NodeType::PARAMETERS);
951  add_relation(camera_parameters_key, object_parameters_key, "Camera -> Object");
952 }
953 
955 {
956  Light *lamp = (Light *)object->data;
957  build_light(lamp);
958  ComponentKey lamp_parameters_key(&lamp->id, NodeType::PARAMETERS);
959  ComponentKey object_parameters_key(&object->id, NodeType::PARAMETERS);
960  add_relation(lamp_parameters_key, object_parameters_key, "Light -> Object");
961 }
962 
964 {
965  LightProbe *probe = (LightProbe *)object->data;
966  build_lightprobe(probe);
969  add_relation(probe_key, object_key, "LightProbe Update");
970 }
971 
973 {
974  Speaker *speaker = (Speaker *)object->data;
975  build_speaker(speaker);
976  ComponentKey speaker_key(&speaker->id, NodeType::AUDIO);
977  ComponentKey object_key(&object->id, NodeType::AUDIO);
978  add_relation(speaker_key, object_key, "Speaker Update");
979 }
980 
982 {
983  Object *parent = object->parent;
984  ID *parent_id = &object->parent->id;
985  ComponentKey object_transform_key(&object->id, NodeType::TRANSFORM);
986  /* Type-specific links. */
987  switch (object->partype) {
988  /* Armature Deform (Virtual Modifier) */
989  case PARSKEL: {
990  ComponentKey parent_transform_key(parent_id, NodeType::TRANSFORM);
991  add_relation(parent_transform_key, object_transform_key, "Parent Armature Transform");
992 
993  if (parent->type == OB_ARMATURE) {
994  ComponentKey object_geometry_key(&object->id, NodeType::GEOMETRY);
995  ComponentKey parent_pose_key(parent_id, NodeType::EVAL_POSE);
996  add_relation(
997  parent_transform_key, object_geometry_key, "Parent Armature Transform -> Geometry");
998  add_relation(parent_pose_key, object_geometry_key, "Parent Armature Pose -> Geometry");
999 
1001  &object->id, object_geometry_key, "Virtual Armature Modifier");
1002  }
1003 
1004  break;
1005  }
1006 
1007  /* Vertex Parent */
1008  case PARVERT1:
1009  case PARVERT3: {
1010  ComponentKey parent_key(parent_id, NodeType::GEOMETRY);
1011  add_relation(parent_key, object_transform_key, "Vertex Parent");
1012  /* Original index is used for optimizations of lookups for subdiv
1013  * only meshes.
1014  * TODO(sergey): This optimization got lost at 2.8, so either verify
1015  * we can get rid of this mask here, or bring the optimization
1016  * back. */
1017  add_customdata_mask(object->parent,
1022  ComponentKey transform_key(parent_id, NodeType::TRANSFORM);
1023  add_relation(transform_key, object_transform_key, "Vertex Parent TFM");
1024  break;
1025  }
1026 
1027  /* Bone Parent */
1028  case PARBONE: {
1029  if (object->parsubstr[0] != '\0') {
1030  ComponentKey parent_bone_key(parent_id, NodeType::BONE, object->parsubstr);
1031  OperationKey parent_transform_key(
1033  add_relation(parent_bone_key, object_transform_key, "Bone Parent");
1034  add_relation(parent_transform_key, object_transform_key, "Armature Parent");
1035  }
1036  break;
1037  }
1038 
1039  default: {
1040  if (object->parent->type == OB_LATTICE) {
1041  /* Lattice Deform Parent - Virtual Modifier. */
1042  ComponentKey parent_key(parent_id, NodeType::TRANSFORM);
1043  ComponentKey geom_key(parent_id, NodeType::GEOMETRY);
1044  add_relation(parent_key, object_transform_key, "Lattice Deform Parent");
1045  add_relation(geom_key, object_transform_key, "Lattice Deform Parent Geom");
1046  }
1047  else if (object->parent->type == OB_CURVES_LEGACY) {
1048  Curve *cu = (Curve *)object->parent->data;
1049 
1050  if (cu->flag & CU_PATH) {
1051  /* Follow Path. */
1052  ComponentKey parent_key(parent_id, NodeType::GEOMETRY);
1053  add_relation(parent_key, object_transform_key, "Curve Follow Parent");
1054  ComponentKey transform_key(parent_id, NodeType::TRANSFORM);
1055  add_relation(transform_key, object_transform_key, "Curve Follow TFM");
1056  }
1057  else {
1058  /* Standard Parent. */
1059  ComponentKey parent_key(parent_id, NodeType::TRANSFORM);
1060  add_relation(parent_key, object_transform_key, "Curve Parent");
1061  }
1062  }
1063  else {
1064  /* Standard Parent. */
1065  ComponentKey parent_key(parent_id, NodeType::TRANSFORM);
1066  add_relation(parent_key, object_transform_key, "Parent");
1067  }
1068  break;
1069  }
1070  }
1071  /* Meta-balls are the odd balls here (no pun intended): they will request
1072  * instance-list (formerly known as dupli-list) during evaluation. This is
1073  * their way of interacting with all instanced surfaces, making a nice
1074  * effect when is used form particle system. */
1075  if (object->type == OB_MBALL && parent->transflag & OB_DUPLI) {
1076  ComponentKey parent_geometry_key(parent_id, NodeType::GEOMETRY);
1077  /* NOTE: Meta-balls are evaluating geometry only after their transform,
1078  * so we only hook up to transform channel here. */
1079  add_relation(parent_geometry_key, object_transform_key, "Parent");
1080  }
1081 
1082  /* Dupliverts uses original vertex index. */
1083  if (parent->transflag & OB_DUPLIVERTS) {
1085  }
1086 }
1087 
1089 {
1090  ComponentKey point_cache_key(&object->id, NodeType::POINT_CACHE);
1091  /* Different point caches are affecting different aspects of life of the
1092  * object. We keep track of those aspects and avoid duplicate relations. */
1093  enum {
1094  FLAG_TRANSFORM = (1 << 0),
1095  FLAG_GEOMETRY = (1 << 1),
1096  FLAG_ALL = (FLAG_TRANSFORM | FLAG_GEOMETRY),
1097  };
1098  ListBase ptcache_id_list;
1099  BKE_ptcache_ids_from_object(&ptcache_id_list, object, scene_, 0);
1100  int handled_components = 0;
1101  LISTBASE_FOREACH (PTCacheID *, ptcache_id, &ptcache_id_list) {
1102  /* Check which components needs the point cache. */
1103  int flag = -1;
1104  if (ptcache_id->type == PTCACHE_TYPE_RIGIDBODY) {
1105  if (object->rigidbody_object->type == RBO_TYPE_PASSIVE) {
1106  continue;
1107  }
1108  flag = FLAG_TRANSFORM;
1109  OperationKey transform_key(
1111  add_relation(point_cache_key, transform_key, "Point Cache -> Rigid Body");
1112  /* Manual changes to effectors need to invalidate simulation. */
1113  OperationKey rigidbody_rebuild_key(
1115  add_relation(rigidbody_rebuild_key,
1116  point_cache_key,
1117  "Rigid Body Rebuild -> Point Cache Reset",
1119  }
1120  else {
1121  flag = FLAG_GEOMETRY;
1123  add_relation(point_cache_key, geometry_key, "Point Cache -> Geometry");
1124  }
1125  BLI_assert(flag != -1);
1126  /* Tag that we did handle that component. */
1127  handled_components |= flag;
1128  if (handled_components == FLAG_ALL) {
1129  break;
1130  }
1131  }
1132  /* Manual edits to any dependency (or self) should reset the point cache. */
1133  if (!BLI_listbase_is_empty(&ptcache_id_list)) {
1134  OperationKey transform_eval_key(
1136  OperationKey geometry_init_key(
1138  add_relation(transform_eval_key,
1139  point_cache_key,
1140  "Transform Simulation -> Point Cache",
1142  add_relation(geometry_init_key,
1143  point_cache_key,
1144  "Geometry Init -> Point Cache",
1146  }
1147  BLI_freelistN(&ptcache_id_list);
1148 }
1149 
1151  NodeType component_type,
1152  const char *component_subdata,
1154  RootPChanMap *root_map)
1155 {
1156  OperationKey constraint_op_key(id,
1157  component_type,
1158  component_subdata,
1159  (component_type == NodeType::BONE) ?
1162  /* Add dependencies for each constraint in turn. */
1163  for (bConstraint *con = (bConstraint *)constraints->first; con; con = con->next) {
1165  ListBase targets = {nullptr, nullptr};
1166  /* Invalid constraint type. */
1167  if (cti == nullptr) {
1168  continue;
1169  }
1170 
1171  const BuilderStack::ScopedEntry stack_entry = stack_.trace(*con);
1172 
1173  /* Special case for camera tracking -- it doesn't use targets to
1174  * define relations. */
1175  /* TODO: we can now represent dependencies in a much richer manner,
1176  * so review how this is done. */
1177  if (ELEM(cti->type,
1181  bool depends_on_camera = false;
1182  if (cti->type == CONSTRAINT_TYPE_FOLLOWTRACK) {
1184  if (((data->clip) || (data->flag & FOLLOWTRACK_ACTIVECLIP)) && data->track[0]) {
1185  depends_on_camera = true;
1186  }
1187  if (data->depth_ob) {
1188  ComponentKey depth_transform_key(&data->depth_ob->id, NodeType::TRANSFORM);
1189  ComponentKey depth_geometry_key(&data->depth_ob->id, NodeType::GEOMETRY);
1190  add_relation(depth_transform_key, constraint_op_key, cti->name);
1191  add_relation(depth_geometry_key, constraint_op_key, cti->name);
1192  }
1193  }
1194  else if (cti->type == CONSTRAINT_TYPE_OBJECTSOLVER) {
1195  depends_on_camera = true;
1196  }
1197  if (depends_on_camera && scene_->camera != nullptr) {
1198  ComponentKey camera_key(&scene_->camera->id, NodeType::TRANSFORM);
1199  add_relation(camera_key, constraint_op_key, cti->name);
1200  }
1201  /* TODO(sergey): This is more a TimeSource -> MovieClip ->
1202  * Constraint dependency chain. */
1203  TimeSourceKey time_src_key;
1204  add_relation(time_src_key, constraint_op_key, "TimeSrc -> Animation");
1205  }
1206  else if (cti->type == CONSTRAINT_TYPE_TRANSFORM_CACHE) {
1207  /* TODO(kevin): This is more a TimeSource -> CacheFile -> Constraint
1208  * dependency chain. */
1209  TimeSourceKey time_src_key;
1210  add_relation(time_src_key, constraint_op_key, "TimeSrc -> Animation");
1212  if (data->cache_file) {
1213  ComponentKey cache_key(&data->cache_file->id, NodeType::CACHE);
1214  add_relation(cache_key, constraint_op_key, cti->name);
1215  }
1216  }
1217  else if (BKE_constraint_targets_get(con, &targets)) {
1218  LISTBASE_FOREACH (bConstraintTarget *, ct, &targets) {
1219  if (ct->tar == nullptr) {
1220  continue;
1221  }
1223  /* Ignore IK constraints - these are handled separately
1224  * (on pose level). */
1225  }
1227  /* These constraints require path geometry data. */
1228  ComponentKey target_key(&ct->tar->id, NodeType::GEOMETRY);
1229  add_relation(target_key, constraint_op_key, cti->name);
1230  ComponentKey target_transform_key(&ct->tar->id, NodeType::TRANSFORM);
1231  add_relation(target_transform_key, constraint_op_key, cti->name);
1232  }
1233  else if ((ct->tar->type == OB_ARMATURE) && (ct->subtarget[0])) {
1234  OperationCode opcode;
1235  /* relation to bone */
1236  opcode = bone_target_opcode(
1237  &ct->tar->id, ct->subtarget, id, component_subdata, root_map);
1238  /* Armature constraint always wants the final position and chan_mat. */
1239  if (ELEM(con->type, CONSTRAINT_TYPE_ARMATURE)) {
1240  opcode = OperationCode::BONE_DONE;
1241  }
1242  /* if needs bbone shape, reference the segment computation */
1243  if (BKE_constraint_target_uses_bbone(con, ct) &&
1244  check_pchan_has_bbone_segments(ct->tar, ct->subtarget)) {
1246  }
1247  OperationKey target_key(&ct->tar->id, NodeType::BONE, ct->subtarget, opcode);
1248  add_relation(target_key, constraint_op_key, cti->name);
1249  }
1250  else if (ELEM(ct->tar->type, OB_MESH, OB_LATTICE) && (ct->subtarget[0])) {
1251  /* Vertex group. */
1252  /* NOTE: Vertex group is likely to be used to get vertices
1253  * in a world space. This requires to know both geometry
1254  * and transformation of the target object. */
1255  ComponentKey target_transform_key(&ct->tar->id, NodeType::TRANSFORM);
1256  ComponentKey target_geometry_key(&ct->tar->id, NodeType::GEOMETRY);
1257  add_relation(target_transform_key, constraint_op_key, cti->name);
1258  add_relation(target_geometry_key, constraint_op_key, cti->name);
1260  }
1261  else if (con->type == CONSTRAINT_TYPE_SHRINKWRAP) {
1262  bShrinkwrapConstraint *scon = (bShrinkwrapConstraint *)con->data;
1263 
1264  /* Constraints which requires the target object surface. */
1265  ComponentKey target_key(&ct->tar->id, NodeType::GEOMETRY);
1266  add_relation(target_key, constraint_op_key, cti->name);
1267 
1268  /* Add dependency on normal layers if necessary. */
1269  if (ct->tar->type == OB_MESH && scon->shrinkType != MOD_SHRINKWRAP_NEAREST_VERTEX) {
1270  bool track = (scon->flag & CON_SHRINKWRAP_TRACK_NORMAL) != 0;
1271  if (track || BKE_shrinkwrap_needs_normals(scon->shrinkType, scon->shrinkMode)) {
1272  add_customdata_mask(ct->tar,
1275  }
1278  }
1279  }
1280 
1281  /* NOTE: obdata eval now doesn't necessarily depend on the
1282  * object's transform. */
1283  ComponentKey target_transform_key(&ct->tar->id, NodeType::TRANSFORM);
1284  add_relation(target_transform_key, constraint_op_key, cti->name);
1285  }
1286  else {
1287  /* Standard object relation. */
1288  // TODO: loc vs rot vs scale?
1289  if (&ct->tar->id == id) {
1290  /* Constraint targeting own object:
1291  * - This case is fine IF we're dealing with a bone
1292  * constraint pointing to its own armature. In that
1293  * case, it's just transform -> bone.
1294  * - If however it is a real self targeting case, just
1295  * make it depend on the previous constraint (or the
1296  * pre-constraint state). */
1297  if ((ct->tar->type == OB_ARMATURE) && (component_type == NodeType::BONE)) {
1298  OperationKey target_key(
1300  add_relation(target_key, constraint_op_key, cti->name);
1301  }
1302  else {
1303  OperationKey target_key(
1305  add_relation(target_key, constraint_op_key, cti->name);
1306  }
1307  }
1308  else {
1309  /* Normal object dependency. */
1310  OperationKey target_key(
1312  add_relation(target_key, constraint_op_key, cti->name);
1313  }
1314  }
1315  /* Constraints which needs world's matrix for transform.
1316  * TODO(sergey): More constraints here? */
1317  if (ELEM(con->type,
1322  /* TODO(sergey): Add used space check. */
1323  ComponentKey target_transform_key(&ct->tar->id, NodeType::TRANSFORM);
1324  add_relation(target_transform_key, constraint_op_key, cti->name);
1325  }
1326  }
1327  BKE_constraint_targets_flush(con, &targets, true);
1328  }
1329  }
1330 }
1331 
1333 {
1334  /* Images. */
1336  /* Animation curves and NLA. */
1338  /* Drivers. */
1340 
1341  if (check_id_has_anim_component(id)) {
1342  ComponentKey animation_key(id, NodeType::ANIMATION);
1343  ComponentKey parameters_key(id, NodeType::PARAMETERS);
1344  add_relation(animation_key, parameters_key, "Animation -> Parameters");
1346  }
1347 }
1348 
1350 {
1351  AnimData *adt = BKE_animdata_from_id(id);
1352  if (adt == nullptr) {
1353  return;
1354  }
1355  if (adt->action != nullptr) {
1356  build_action(adt->action);
1357  }
1358  if (adt->action == nullptr && BLI_listbase_is_empty(&adt->nla_tracks)) {
1359  return;
1360  }
1361  /* Ensure evaluation order from entry to exit. */
1365  add_relation(animation_entry_key, animation_eval_key, "Init -> Eval");
1366  add_relation(animation_eval_key, animation_exit_key, "Eval -> Exit");
1367  /* Wire up dependency from action. */
1368  ComponentKey adt_key(id, NodeType::ANIMATION);
1369  /* Relation from action itself. */
1370  if (adt->action != nullptr) {
1371  ComponentKey action_key(&adt->action->id, NodeType::ANIMATION);
1372  add_relation(action_key, adt_key, "Action -> Animation");
1373  }
1374  /* Get source operations. */
1375  Node *node_from = get_node(adt_key);
1376  BLI_assert(node_from != nullptr);
1377  if (node_from == nullptr) {
1378  return;
1379  }
1380  OperationNode *operation_from = node_from->get_exit_operation();
1381  BLI_assert(operation_from != nullptr);
1382  /* Build relations from animation operation to properties it changes. */
1383  if (adt->action != nullptr) {
1384  build_animdata_curves_targets(id, adt_key, operation_from, &adt->action->curves);
1385  }
1386  LISTBASE_FOREACH (NlaTrack *, nlt, &adt->nla_tracks) {
1387  build_animdata_nlastrip_targets(id, adt_key, operation_from, &nlt->strips);
1388  }
1389 }
1390 
1392  ComponentKey &adt_key,
1393  OperationNode *operation_from,
1394  ListBase *curves)
1395 {
1396  /* Iterate over all curves and build relations. */
1397  PointerRNA id_ptr;
1398  RNA_id_pointer_create(id, &id_ptr);
1399  LISTBASE_FOREACH (FCurve *, fcu, curves) {
1400  PointerRNA ptr;
1401  PropertyRNA *prop;
1402  int index;
1403  if (!RNA_path_resolve_full(&id_ptr, fcu->rna_path, &ptr, &prop, &index)) {
1404  continue;
1405  }
1406  Node *node_to = rna_node_query_.find_node(&ptr, prop, RNAPointerSource::ENTRY);
1407  if (node_to == nullptr) {
1408  continue;
1409  }
1410  OperationNode *operation_to = node_to->get_entry_operation();
1411  /* NOTE: Special case for bones, avoid relation from animation to
1412  * each of the bones. Bone evaluation could only start from pose
1413  * init anyway. */
1414  if (operation_to->opcode == OperationCode::BONE_LOCAL) {
1416  add_relation(adt_key, pose_init_key, "Animation -> Prop", RELATION_CHECK_BEFORE_ADD);
1417  continue;
1418  }
1420  operation_from, operation_to, "Animation -> Prop", RELATION_CHECK_BEFORE_ADD);
1421  /* It is possible that animation is writing to a nested ID data-block,
1422  * need to make sure animation is evaluated after target ID is copied. */
1423  const IDNode *id_node_from = operation_from->owner->owner;
1424  const IDNode *id_node_to = operation_to->owner->owner;
1425  if (id_node_from != id_node_to) {
1426  ComponentKey cow_key(id_node_to->id_orig, NodeType::COPY_ON_WRITE);
1427  add_relation(cow_key,
1428  adt_key,
1429  "Animated CoW -> Animation",
1431  }
1432  }
1433 }
1434 
1436  ComponentKey &adt_key,
1437  OperationNode *operation_from,
1438  ListBase *strips)
1439 {
1440  LISTBASE_FOREACH (NlaStrip *, strip, strips) {
1441  if (strip->act != nullptr) {
1442  build_action(strip->act);
1443 
1444  ComponentKey action_key(&strip->act->id, NodeType::ANIMATION);
1445  add_relation(action_key, adt_key, "Action -> Animation");
1446 
1447  build_animdata_curves_targets(id, adt_key, operation_from, &strip->act->curves);
1448  }
1449  else if (strip->strips.first != nullptr) {
1450  build_animdata_nlastrip_targets(id, adt_key, operation_from, &strip->strips);
1451  }
1452  }
1453 }
1454 
1456 {
1457  AnimData *adt = BKE_animdata_from_id(id);
1458  if (adt == nullptr) {
1459  return;
1460  }
1461  ComponentKey adt_key(id, NodeType::ANIMATION);
1462  LISTBASE_FOREACH (FCurve *, fcu, &adt->drivers) {
1463  OperationKey driver_key(id,
1466  fcu->rna_path ? fcu->rna_path : "",
1467  fcu->array_index);
1468 
1469  /* create the driver's relations to targets */
1470  build_driver(id, fcu);
1471 
1472  /* prevent driver from occurring before own animation... */
1473  if (adt->action || adt->nla_tracks.first) {
1474  add_relation(adt_key, driver_key, "AnimData Before Drivers");
1475  }
1476  }
1477 }
1478 
1480 {
1481  /* See #DepsgraphNodeBuilder::build_animation_images. */
1482  bool has_image_animation = false;
1483  if (ELEM(GS(id->name), ID_MA, ID_WO)) {
1485  if (ntree != nullptr &&
1487  has_image_animation = true;
1488  }
1489  }
1490 
1491  if (has_image_animation || BKE_image_user_id_has_animation(id)) {
1492  OperationKey image_animation_key(
1494  TimeSourceKey time_src_key;
1495  add_relation(time_src_key, image_animation_key, "TimeSrc -> Image Animation");
1496 
1497  /* The image users of these ids may change during evaluation. Make sure that the image
1498  * animation update happens after evaluation. */
1499  if (GS(id->name) == ID_MA) {
1501  add_relation(material_update_key, image_animation_key, "Material Update -> Image Animation");
1502  }
1503  else if (GS(id->name) == ID_WO) {
1505  add_relation(world_update_key, image_animation_key, "World Update -> Image Animation");
1506  }
1507  else if (GS(id->name) == ID_NT) {
1509  add_relation(ntree_output_key, image_animation_key, "NTree Output -> Image Animation");
1510  }
1511  }
1512 }
1513 
1515 {
1516  if (GS(id->name) != ID_OB) {
1517  return;
1518  }
1519 
1520  const Object *object = (Object *)id;
1521  if (object->pd == nullptr || object->pd->forcefield == PFIELD_NULL) {
1522  return;
1523  }
1524 
1525  /* Updates to animation data (in the UI, for example by altering FCurve Modifier parameters
1526  * animating force field strength) may need to rebuild the rigid body world. */
1527  ComponentKey animation_key(id, NodeType::ANIMATION);
1529  add_relation(animation_key, rigidbody_key, "Animation -> Rigid Body");
1530 }
1531 
1533 {
1534  if (built_map_.checkIsBuiltAndTag(action)) {
1535  return;
1536  }
1537 
1538  const BuilderStack::ScopedEntry stack_entry = stack_.trace(action->id);
1539 
1540  build_idproperties(action->id.properties);
1541  if (!BLI_listbase_is_empty(&action->curves)) {
1542  TimeSourceKey time_src_key;
1543  ComponentKey animation_key(&action->id, NodeType::ANIMATION);
1544  add_relation(time_src_key, animation_key, "TimeSrc -> Animation");
1545  }
1546 }
1547 
1549 {
1550  ChannelDriver *driver = fcu->driver;
1551  OperationKey driver_key(id,
1554  fcu->rna_path ? fcu->rna_path : "",
1555  fcu->array_index);
1556  /* Driver -> data components (for interleaved evaluation
1557  * bones/constraints/modifiers). */
1558  build_driver_data(id, fcu);
1559  /* Loop over variables to get the target relationships. */
1560  build_driver_variables(id, fcu);
1561  /* It's quite tricky to detect if the driver actually depends on time or
1562  * not, so for now we'll be quite conservative here about optimization and
1563  * consider all python drivers to be depending on time. */
1564  if (driver_depends_on_time(driver)) {
1565  TimeSourceKey time_src_key;
1566  add_relation(time_src_key, driver_key, "TimeSrc -> Driver");
1567  }
1568 }
1569 
1571 {
1572  /* Validate the RNA path pointer just in case. */
1573  const char *rna_path = fcu->rna_path;
1574  if (rna_path == nullptr || rna_path[0] == '\0') {
1575  return;
1576  }
1577  /* Parse the RNA path to find the target property pointer. */
1578  RNAPathKey property_entry_key(id, rna_path, RNAPointerSource::ENTRY);
1579  if (RNA_pointer_is_null(&property_entry_key.ptr)) {
1580  /* TODO(sergey): This would only mean that driver is broken.
1581  * so we can't create relation anyway. However, we need to avoid
1582  * adding drivers which are known to be buggy to a dependency
1583  * graph, in order to save computational power. */
1584  return;
1585  }
1586  OperationKey driver_key(
1588  /* If the target of the driver is a Bone property, find the Armature data,
1589  * and then link the driver to all pose bone evaluation components that use
1590  * it. This is necessary to provide more granular dependencies specifically for
1591  * Bone objects, because the armature data doesn't have per-bone components,
1592  * and generic add_relation can only add one link. */
1593  ID *id_ptr = property_entry_key.ptr.owner_id;
1594  bool is_bone = id_ptr && property_entry_key.ptr.type == &RNA_Bone;
1595  /* If the Bone property is referenced via obj.pose.bones[].bone,
1596  * the RNA pointer refers to the Object ID, so skip to data. */
1597  if (is_bone && GS(id_ptr->name) == ID_OB) {
1598  id_ptr = (ID *)((Object *)id_ptr)->data;
1599  }
1600  if (is_bone && GS(id_ptr->name) == ID_AR) {
1601  /* Drivers on armature-level bone settings (i.e. bbone stuff),
1602  * which will affect the evaluation of corresponding pose bones. */
1603  Bone *bone = (Bone *)property_entry_key.ptr.data;
1604  if (bone == nullptr) {
1605  fprintf(stderr, "Couldn't find armature bone name for driver path - '%s'\n", rna_path);
1606  return;
1607  }
1608 
1609  const char *prop_identifier = RNA_property_identifier(property_entry_key.prop);
1610  const bool driver_targets_bbone = STRPREFIX(prop_identifier, "bbone_");
1611 
1612  /* Find objects which use this, and make their eval callbacks depend on this. */
1613  for (IDNode *to_node : graph_->id_nodes) {
1614  if (GS(to_node->id_orig->name) != ID_OB) {
1615  continue;
1616  }
1617 
1618  /* We only care about objects with pose data which use this. */
1619  Object *object = (Object *)to_node->id_orig;
1620  if (object->data != id_ptr || object->pose == nullptr) {
1621  continue;
1622  }
1623 
1624  bPoseChannel *pchan = BKE_pose_channel_find_name(object->pose, bone->name);
1625  if (pchan == nullptr) {
1626  continue;
1627  }
1628 
1629  OperationCode target_op = driver_targets_bbone ? OperationCode::BONE_SEGMENTS :
1631  OperationKey bone_key(&object->id, NodeType::BONE, pchan->name, target_op);
1632  add_relation(driver_key, bone_key, "Arm Bone -> Driver -> Bone");
1633  }
1634  /* Make the driver depend on COW, similar to the generic case below. */
1635  if (id_ptr != id) {
1636  ComponentKey cow_key(id_ptr, NodeType::COPY_ON_WRITE);
1637  add_relation(cow_key, driver_key, "Driven CoW -> Driver", RELATION_CHECK_BEFORE_ADD);
1638  }
1639  }
1640  else {
1641  /* If it's not a Bone, handle the generic single dependency case. */
1642  Node *node_to = get_node(property_entry_key);
1643  if (node_to != nullptr) {
1644  add_relation(driver_key, property_entry_key, "Driver -> Driven Property");
1645  }
1646 
1647  /* Similar to the case with f-curves, driver might drive a nested
1648  * data-block, which means driver execution should wait for that
1649  * data-block to be copied. */
1650  {
1651  PointerRNA id_ptr;
1652  PointerRNA ptr;
1653  RNA_id_pointer_create(id, &id_ptr);
1654  if (RNA_path_resolve_full(&id_ptr, fcu->rna_path, &ptr, nullptr, nullptr)) {
1655  if (id_ptr.owner_id != ptr.owner_id) {
1657  add_relation(cow_key, driver_key, "Driven CoW -> Driver", RELATION_CHECK_BEFORE_ADD);
1658  }
1659  }
1660  }
1661  if (rna_prop_affects_parameters_node(&property_entry_key.ptr, property_entry_key.prop)) {
1662  RNAPathKey property_exit_key(property_entry_key.id,
1663  property_entry_key.ptr,
1664  property_entry_key.prop,
1667  add_relation(property_exit_key, parameters_key, "Driven Property -> Properties");
1668  }
1669  }
1670 
1671  /* Assume drivers on a node tree affect the evaluated output of the node tree. In theory we could
1672  * check if the driven value actually affects the output, i.e. if it drives a node that is linked
1673  * to the output. */
1674  if (GS(id_ptr->name) == ID_NT) {
1675  ComponentKey ntree_output_key(id_ptr, NodeType::NTREE_OUTPUT);
1676  add_relation(driver_key, ntree_output_key, "Drivers -> NTree Output");
1677  }
1678 }
1679 
1681 {
1682  ChannelDriver *driver = fcu->driver;
1683  OperationKey driver_key(id,
1686  fcu->rna_path ? fcu->rna_path : "",
1687  fcu->array_index);
1688  const char *rna_path = fcu->rna_path ? fcu->rna_path : "";
1689  const RNAPathKey self_key(id, rna_path, RNAPointerSource::ENTRY);
1690  LISTBASE_FOREACH (DriverVar *, dvar, &driver->variables) {
1691  /* Only used targets. */
1693  ID *target_id = dtar->id;
1694  if (target_id == nullptr) {
1695  continue;
1696  }
1697  build_id(target_id);
1698  build_driver_id_property(target_id, dtar->rna_path);
1699  Object *object = nullptr;
1700  if (GS(target_id->name) == ID_OB) {
1701  object = (Object *)target_id;
1702  }
1703  /* Special handling for directly-named bones. */
1704  if ((dtar->flag & DTAR_FLAG_STRUCT_REF) && (object && object->type == OB_ARMATURE) &&
1705  (dtar->pchan_name[0])) {
1706  bPoseChannel *target_pchan = BKE_pose_channel_find_name(object->pose, dtar->pchan_name);
1707  if (target_pchan == nullptr) {
1708  continue;
1709  }
1710  OperationKey variable_key(
1711  target_id, NodeType::BONE, target_pchan->name, OperationCode::BONE_DONE);
1712  if (is_same_bone_dependency(variable_key, self_key)) {
1713  continue;
1714  }
1715  add_relation(variable_key, driver_key, "Bone Target -> Driver");
1716  }
1717  else if (dtar->flag & DTAR_FLAG_STRUCT_REF) {
1718  /* Get node associated with the object's transforms. */
1719  if (target_id == id) {
1720  /* Ignore input dependency if we're driving properties of
1721  * the same ID, otherwise we'll be ending up in a cyclic
1722  * dependency here. */
1723  continue;
1724  }
1726  add_relation(target_key, driver_key, "Target -> Driver");
1727  }
1728  else if (dtar->rna_path != nullptr && dtar->rna_path[0] != '\0') {
1729  RNAPathKey variable_exit_key(target_id, dtar->rna_path, RNAPointerSource::EXIT);
1730  if (RNA_pointer_is_null(&variable_exit_key.ptr)) {
1731  continue;
1732  }
1733  if (is_same_bone_dependency(variable_exit_key, self_key) ||
1734  is_same_nodetree_node_dependency(variable_exit_key, self_key)) {
1735  continue;
1736  }
1737  add_relation(variable_exit_key, driver_key, "RNA Target -> Driver");
1738 
1739  /* It is possible that RNA path points to a property of a different ID than the target_id:
1740  * for example, paths like "data" on Object, "camera" on Scene.
1741  *
1742  * For the demonstration purposes lets consider a driver variable uses Scene ID as target
1743  * and "camera.location.x" as its RNA path. If the scene has 2 different cameras at
1744  * 2 different locations changing the active scene camera is expected to immediately be
1745  * reflected in the variable value. In order to achieve this behavior we create a relation
1746  * from the target ID to the driver so that if the ID property of the target ID changes the
1747  * driver is re-evaluated.
1748  *
1749  * The most straightforward (at the moment of writing this comment) way of figuring out
1750  * such relation is to use copy-on-write operation of the target ID. There are two down
1751  * sides of this approach which are considered a design limitation as there is a belief
1752  * that they are not common in practice or are not reliable due to other issues:
1753  *
1754  * - IDs which are not covered with the copy-on-write mechanism.
1755  *
1756  * Such IDs are either do not have ID properties, or are not part of the dependency
1757  * graph.
1758  *
1759  * - Modifications of evaluated IDs from a Python handler.
1760  * Such modifications are not fully integrated in the dependency graph evaluation as it
1761  * has issues with copy-on-write tagging and the fact that relations are defined by the
1762  * original main database status. */
1763  if (target_id != variable_exit_key.ptr.owner_id) {
1764  if (deg_copy_on_write_is_needed(GS(target_id->name))) {
1765  ComponentKey target_id_key(target_id, NodeType::COPY_ON_WRITE);
1766  add_relation(target_id_key, driver_key, "Target ID -> Driver");
1767  }
1768  }
1769 
1770  /* The RNA getter for `object.data` can write to the mesh datablock due
1771  * to the call to `BKE_mesh_wrapper_ensure_subdivision()`. This relation
1772  * ensures it is safe to call when the driver is evaluated.
1773  *
1774  * For the sake of making the code more generic/defensive, the relation
1775  * is added for any geometry type.
1776  *
1777  * See T96289 for more info. */
1778  if (object != nullptr && OB_TYPE_IS_GEOMETRY(object->type)) {
1779  StringRef rna_path(dtar->rna_path);
1780  if (rna_path == "data" || rna_path.startswith("data.")) {
1781  ComponentKey ob_key(target_id, NodeType::GEOMETRY);
1782  add_relation(ob_key, driver_key, "ID -> Driver");
1783  }
1784  }
1785  }
1786  else {
1787  /* If rna_path is nullptr, and DTAR_FLAG_STRUCT_REF isn't set, this
1788  * is an incomplete target reference, so nothing to do here. */
1789  }
1790  }
1792  }
1793 }
1794 
1796 {
1797  if (id == nullptr || rna_path == nullptr) {
1798  return;
1799  }
1800  PointerRNA id_ptr, ptr;
1801  PropertyRNA *prop;
1802  int index;
1803  RNA_id_pointer_create(id, &id_ptr);
1804  if (!RNA_path_resolve_full(&id_ptr, rna_path, &ptr, &prop, &index)) {
1805  return;
1806  }
1807  if (prop == nullptr) {
1808  return;
1809  }
1810  if (!rna_prop_affects_parameters_node(&ptr, prop)) {
1811  return;
1812  }
1813  const char *prop_identifier = RNA_property_identifier((PropertyRNA *)prop);
1814  /* Custom properties of bones are placed in their components to improve granularity. */
1815  OperationKey id_property_key;
1816  if (RNA_struct_is_a(ptr.type, &RNA_PoseBone)) {
1817  const bPoseChannel *pchan = static_cast<const bPoseChannel *>(ptr.data);
1818  id_property_key = OperationKey(
1819  id, NodeType::BONE, pchan->name, OperationCode::ID_PROPERTY, prop_identifier);
1820  /* Create relation from the parameters component so that tagging armature for parameters update
1821  * properly propagates updates to all properties on bones and deeper (if needed). */
1823  add_relation(
1824  parameters_init_key, id_property_key, "Init -> ID Property", RELATION_CHECK_BEFORE_ADD);
1825  }
1826  else {
1827  id_property_key = OperationKey(
1828  id, NodeType::PARAMETERS, OperationCode::ID_PROPERTY, prop_identifier);
1829  }
1831  add_relation(
1832  id_property_key, parameters_exit_key, "ID Property -> Done", RELATION_CHECK_BEFORE_ADD);
1833 }
1834 
1836 {
1840  add_relation(parameters_entry_key, parameters_eval_key, "Entry -> Eval");
1841  add_relation(parameters_eval_key, parameters_exit_key, "Entry -> Exit");
1842 }
1843 
1845 {
1847  ComponentKey geometry_key(&object->id, NodeType::GEOMETRY);
1848  ComponentKey transform_key(&object->id, NodeType::TRANSFORM);
1849  add_relation(geometry_key, dimensions_key, "Geometry -> Dimensions");
1850  add_relation(transform_key, dimensions_key, "Transform -> Dimensions");
1851 }
1852 
1854 {
1855  if (built_map_.checkIsBuiltAndTag(world)) {
1856  return;
1857  }
1858 
1859  const BuilderStack::ScopedEntry stack_entry = stack_.trace(world->id);
1860 
1862  /* animation */
1863  build_animdata(&world->id);
1865 
1866  /* Animated / driven parameters (without nodetree). */
1868  ComponentKey parameters_key(&world->id, NodeType::PARAMETERS);
1869  add_relation(parameters_key, world_key, "World's parameters");
1870 
1871  /* world's nodetree */
1872  if (world->nodetree != nullptr) {
1874  OperationKey ntree_key(
1876  add_relation(ntree_key, world_key, "World's NTree");
1878  }
1879 }
1880 
1882 {
1886  /* Simulation depends on time. */
1887  TimeSourceKey time_src_key;
1888  add_relation(time_src_key, rb_init_key, "TimeSrc -> Rigidbody Init");
1889  /* Simulation should always be run after initialization. */
1890  /* NOTE: It is possible in theory to have dependency cycle which involves
1891  * this relation. We never want it to be killed. */
1892  add_relation(rb_init_key, rb_simulate_key, "Rigidbody [Init -> SimStep]", RELATION_FLAG_GODMODE);
1893  /* Effectors should be evaluated at the time simulation is being
1894  * initialized.
1895  * TODO(sergey): Verify that it indeed goes to initialization and not to a
1896  * simulation. */
1897  ListBase *effector_relations = build_effector_relations(graph_, rbw->effector_weights->group);
1898  LISTBASE_FOREACH (EffectorRelation *, effector_relation, effector_relations) {
1899  ComponentKey effector_transform_key(&effector_relation->ob->id, NodeType::TRANSFORM);
1900  add_relation(effector_transform_key, rb_init_key, "RigidBody Field");
1901  if (effector_relation->pd != nullptr) {
1902  const short shape = effector_relation->pd->shape;
1904  ComponentKey effector_geometry_key(&effector_relation->ob->id, NodeType::GEOMETRY);
1905  add_relation(effector_geometry_key, rb_init_key, "RigidBody Field");
1906  }
1907  if ((effector_relation->pd->forcefield == PFIELD_TEXTURE) &&
1908  (effector_relation->pd->tex != nullptr)) {
1909  ComponentKey tex_key(&effector_relation->pd->tex->id, NodeType::GENERIC_DATABLOCK);
1910  add_relation(tex_key, rb_init_key, "Force field Texture");
1911  }
1912  }
1913  }
1914  /* Objects. */
1915  if (rbw->group != nullptr) {
1916  build_collection(nullptr, nullptr, rbw->group);
1918  if (object->type != OB_MESH) {
1919  continue;
1920  }
1921  if (object->rigidbody_object == nullptr) {
1922  continue;
1923  }
1924 
1925  if (object->parent != nullptr && object->parent->rigidbody_object != nullptr &&
1927  /* If we are a child of a compound shape object, the transforms and sim evaluation will be
1928  * handled by the parent compound shape object. Do not add any evaluation triggers
1929  * for the child objects.
1930  */
1931  continue;
1932  }
1933 
1934  /* Simulation uses object transformation after parenting and solving constraints. */
1935  OperationKey object_transform_simulation_init_key(
1937  OperationKey object_transform_eval_key(
1939  add_relation(object_transform_simulation_init_key,
1940  rb_simulate_key,
1941  "Object Transform -> Rigidbody Sim Eval");
1942  /* Geometry must be known to create the rigid body. RBO_MESH_BASE
1943  * uses the non-evaluated mesh, so then the evaluation is
1944  * unnecessary. */
1946  /* NOTE: We prefer this relation to be never killed, to avoid
1947  * access partially evaluated mesh from solver. */
1948  ComponentKey object_geometry_key(&object->id, NodeType::GEOMETRY);
1949  add_relation(object_geometry_key,
1950  rb_simulate_key,
1951  "Object Geom Eval -> Rigidbody Sim Eval",
1953  }
1954 
1955  /* Final transform is whatever the solver gave to us. */
1956  if (object->rigidbody_object->type == RBO_TYPE_ACTIVE) {
1957  /* We do not have to update the objects final transform after the simulation if it is
1958  * passive or controlled by the animation system in blender.
1959  * (Bullet doesn't move the object at all in these cases).
1960  * But we can't update the depsgraph when the animated property in changed during playback.
1961  * So always assume that active bodies needs updating. */
1962  OperationKey rb_transform_copy_key(
1964  /* Rigid body synchronization depends on the actual simulation. */
1965  add_relation(rb_simulate_key, rb_transform_copy_key, "Rigidbody Sim Eval -> RBO Sync");
1966 
1967  OperationKey object_transform_final_key(
1969  add_relation(rb_transform_copy_key,
1970  object_transform_final_key,
1971  "Rigidbody Sync -> Transform Final");
1972  }
1973  }
1975  }
1976 }
1977 
1979 {
1980  TimeSourceKey time_src_key;
1981  OperationKey obdata_ubereval_key(&object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL);
1982  OperationKey eval_init_key(
1984  OperationKey eval_done_key(
1986  ComponentKey eval_key(&object->id, NodeType::PARTICLE_SYSTEM);
1987  if (BKE_ptcache_object_has(scene_, object, 0)) {
1988  ComponentKey point_cache_key(&object->id, NodeType::POINT_CACHE);
1989  add_relation(
1990  eval_key, point_cache_key, "Particle Point Cache", RELATION_FLAG_FLUSH_USER_EDIT_ONLY);
1991  }
1992  /* Particle systems. */
1993  LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) {
1994  ParticleSettings *part = psys->part;
1995  /* Build particle settings relations.
1996  * NOTE: The call itself ensures settings are only build once. */
1998  /* This particle system. */
1999  OperationKey psys_key(
2001  /* Update particle system when settings changes. */
2002  OperationKey particle_settings_key(
2004  add_relation(particle_settings_key, eval_init_key, "Particle Settings Change");
2005  add_relation(eval_init_key, psys_key, "Init -> PSys");
2006  add_relation(psys_key, eval_done_key, "PSys -> Done");
2007  /* TODO(sergey): Currently particle update is just a placeholder,
2008  * hook it to the ubereval node so particle system is getting updated
2009  * on playback. */
2010  add_relation(psys_key, obdata_ubereval_key, "PSys -> UberEval");
2011  /* Collisions. */
2012  if (part->type != PART_HAIR) {
2014  psys_key, object, part->collision_group, "Particle Collision");
2015  }
2016  else if ((psys->flag & PSYS_HAIR_DYNAMICS) && psys->clmd != nullptr &&
2017  psys->clmd->coll_parms != nullptr) {
2019  psys_key, object, psys->clmd->coll_parms->group, "Hair Collision");
2020  }
2021  /* Effectors. */
2023  psys_key, object, psys, part->effector_weights, part->type == PART_HAIR, "Particle Field");
2024  /* Boids. */
2025  if (part->boids != nullptr) {
2026  LISTBASE_FOREACH (BoidState *, state, &part->boids->states) {
2027  LISTBASE_FOREACH (BoidRule *, rule, &state->rules) {
2028  Object *ruleob = nullptr;
2029  if (rule->type == eBoidRuleType_Avoid) {
2030  ruleob = ((BoidRuleGoalAvoid *)rule)->ob;
2031  }
2032  else if (rule->type == eBoidRuleType_FollowLeader) {
2033  ruleob = ((BoidRuleFollowLeader *)rule)->ob;
2034  }
2035  if (ruleob != nullptr) {
2036  ComponentKey ruleob_key(&ruleob->id, NodeType::TRANSFORM);
2037  add_relation(ruleob_key, psys_key, "Boid Rule");
2038  }
2039  }
2040  }
2041  }
2042  /* Keyed particle targets. */
2044  LISTBASE_FOREACH (ParticleTarget *, particle_target, &psys->targets) {
2045  if (ELEM(particle_target->ob, nullptr, object)) {
2046  continue;
2047  }
2048  /* Make sure target object is pulled into the graph. */
2049  build_object(particle_target->ob);
2050  /* Use geometry component, since that's where particles are
2051  * actually evaluated. */
2052  ComponentKey target_key(&particle_target->ob->id, NodeType::GEOMETRY);
2053  add_relation(target_key, psys_key, "Keyed Target");
2054  }
2055  }
2056  /* Visualization. */
2057  switch (part->ren_as) {
2058  case PART_DRAW_OB:
2059  if (part->instance_object != nullptr) {
2060  /* Make sure object's relations are all built. */
2062  /* Build relation for the particle visualization. */
2064  }
2065  break;
2066  case PART_DRAW_GR:
2067  if (part->instance_collection != nullptr) {
2068  build_collection(nullptr, nullptr, part->instance_collection);
2070  build_particle_system_visualization_object(object, psys, go->ob);
2071  }
2072  }
2073  break;
2074  }
2075  }
2076  /* Particle depends on the object transform, so that channel is to be ready
2077  * first. */
2078  add_depends_on_transform_relation(&object->id, obdata_ubereval_key, "Particle Eval");
2079 }
2080 
2082 {
2083  if (built_map_.checkIsBuiltAndTag(part)) {
2084  return;
2085  }
2086 
2087  const BuilderStack::ScopedEntry stack_entry = stack_.trace(part->id);
2088 
2089  /* Animation data relations. */
2090  build_animdata(&part->id);
2091  build_parameters(&part->id);
2092  OperationKey particle_settings_init_key(
2094  OperationKey particle_settings_eval_key(
2096  OperationKey particle_settings_reset_key(
2098  add_relation(
2099  particle_settings_init_key, particle_settings_eval_key, "Particle Settings Init Order");
2100  add_relation(particle_settings_reset_key, particle_settings_eval_key, "Particle Settings Reset");
2101  /* Texture slots. */
2102  for (MTex *mtex : part->mtex) {
2103  if (mtex == nullptr || mtex->tex == nullptr) {
2104  continue;
2105  }
2106  build_texture(mtex->tex);
2107  ComponentKey texture_key(&mtex->tex->id, NodeType::GENERIC_DATABLOCK);
2108  add_relation(texture_key,
2109  particle_settings_reset_key,
2110  "Particle Texture -> Particle Reset",
2112  add_relation(texture_key, particle_settings_eval_key, "Particle Texture -> Particle Eval");
2113  /* TODO(sergey): Consider moving texture space handling to its own
2114  * function. */
2115  if (mtex->texco == TEXCO_OBJECT && mtex->object != nullptr) {
2116  ComponentKey object_key(&mtex->object->id, NodeType::TRANSFORM);
2117  add_relation(object_key, particle_settings_eval_key, "Particle Texture Space");
2118  }
2119  }
2120  if (check_id_has_anim_component(&part->id)) {
2121  ComponentKey animation_key(&part->id, NodeType::ANIMATION);
2122  add_relation(animation_key, particle_settings_eval_key, "Particle Settings Animation");
2123  }
2124 }
2125 
2127  ParticleSystem *psys,
2128  Object *draw_object)
2129 {
2130  OperationKey psys_key(
2132  OperationKey obdata_ubereval_key(&object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL);
2133  ComponentKey dup_ob_key(&draw_object->id, NodeType::TRANSFORM);
2134  add_relation(dup_ob_key, psys_key, "Particle Object Visualization");
2135  if (draw_object->type == OB_MBALL) {
2136  ComponentKey dup_geometry_key(&draw_object->id, NodeType::GEOMETRY);
2137  add_relation(obdata_ubereval_key, dup_geometry_key, "Particle MBall Visualization");
2138  }
2139 }
2140 
2141 /* Shapekeys */
2143 {
2144  if (built_map_.checkIsBuiltAndTag(key)) {
2145  return;
2146  }
2147 
2148  const BuilderStack::ScopedEntry stack_entry = stack_.trace(key->id);
2149 
2151  /* Attach animdata to geometry. */
2152  build_animdata(&key->id);
2153  build_parameters(&key->id);
2154  /* Connect all blocks properties to the final result evaluation. */
2155  ComponentKey geometry_key(&key->id, NodeType::GEOMETRY);
2157  LISTBASE_FOREACH (KeyBlock *, key_block, &key->block) {
2158  OperationKey key_block_key(
2159  &key->id, NodeType::PARAMETERS, OperationCode::PARAMETERS_EVAL, key_block->name);
2160  add_relation(key_block_key, geometry_key, "Key Block Properties");
2161  add_relation(key_block_key, parameters_eval_key, "Key Block Properties");
2162  }
2163 }
2164 
2186 {
2187  ID *obdata = (ID *)object->data;
2188  /* Init operation of object-level geometry evaluation. */
2190  /* Get nodes for result of obdata's evaluation, and geometry evaluation
2191  * on object. */
2192  ComponentKey obdata_geom_key(obdata, NodeType::GEOMETRY);
2193  ComponentKey geom_key(&object->id, NodeType::GEOMETRY);
2194  /* Link components to each other. */
2195  add_relation(obdata_geom_key, geom_key, "Object Geometry Base Data");
2196  OperationKey obdata_ubereval_key(&object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL);
2197  /* Special case: modifiers evaluation queries scene for various things like
2198  * data mask to be used. We add relation here to ensure object is never
2199  * evaluated prior to Scene's CoW is ready. */
2201  add_relation(scene_key, obdata_ubereval_key, "CoW Relation", RELATION_FLAG_NO_FLUSH);
2202  /* Modifiers */
2203  if (object->modifiers.first != nullptr) {
2205  ctx.scene = scene_;
2206  ctx.object = object;
2207  LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
2208  const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md->type);
2209  if (mti->updateDepsgraph) {
2210  const BuilderStack::ScopedEntry stack_entry = stack_.trace(*md);
2211 
2212  DepsNodeHandle handle = create_node_handle(obdata_ubereval_key);
2213  ctx.node = reinterpret_cast<::DepsNodeHandle *>(&handle);
2214  mti->updateDepsgraph(md, &ctx);
2215  }
2216  if (BKE_modifier_depends_ontime(scene_, md)) {
2217  TimeSourceKey time_src_key;
2218  add_relation(time_src_key, obdata_ubereval_key, "Time Source -> Modifier");
2219  }
2220  }
2221  }
2222  /* Grease Pencil Modifiers. */
2223  if (object->greasepencil_modifiers.first != nullptr) {
2225  ctx.scene = scene_;
2226  ctx.object = object;
2229  (GpencilModifierType)md->type);
2230  if (mti->updateDepsgraph) {
2231  DepsNodeHandle handle = create_node_handle(obdata_ubereval_key);
2232  ctx.node = reinterpret_cast<::DepsNodeHandle *>(&handle);
2233  mti->updateDepsgraph(md, &ctx, graph_->mode);
2234  }
2236  TimeSourceKey time_src_key;
2237  add_relation(time_src_key, obdata_ubereval_key, "Time Source");
2238  }
2239  }
2240  }
2241  /* Shader FX. */
2242  if (object->shader_fx.first != nullptr) {
2244  ctx.scene = scene_;
2245  ctx.object = object;
2246  LISTBASE_FOREACH (ShaderFxData *, fx, &object->shader_fx) {
2247  const ShaderFxTypeInfo *fxi = BKE_shaderfx_get_info((ShaderFxType)fx->type);
2248  if (fxi->updateDepsgraph) {
2249  DepsNodeHandle handle = create_node_handle(obdata_ubereval_key);
2250  ctx.node = reinterpret_cast<::DepsNodeHandle *>(&handle);
2251  fxi->updateDepsgraph(fx, &ctx);
2252  }
2253  if (BKE_shaderfx_depends_ontime(fx)) {
2254  TimeSourceKey time_src_key;
2255  add_relation(time_src_key, obdata_ubereval_key, "Time Source");
2256  }
2257  }
2258  }
2259  /* Materials. */
2260  build_materials(object->mat, object->totcol);
2261  /* Geometry collision. */
2262  if (ELEM(object->type, OB_MESH, OB_CURVES_LEGACY, OB_LATTICE)) {
2263  // add geometry collider relations
2264  }
2265  /* Make sure uber update is the last in the dependencies. */
2266  if (object->type != OB_ARMATURE) {
2267  /* Armatures does no longer require uber node. */
2268  OperationKey obdata_ubereval_key(
2270  add_relation(geom_init_key, obdata_ubereval_key, "Object Geometry UberEval");
2271  }
2272  if (object->type == OB_MBALL) {
2273  Object *mom = BKE_mball_basis_find(scene_, object);
2274  ComponentKey mom_geom_key(&mom->id, NodeType::GEOMETRY);
2275  /* motherball - mom depends on children! */
2276  if (mom == object) {
2277  ComponentKey mom_transform_key(&mom->id, NodeType::TRANSFORM);
2278  add_relation(mom_transform_key, mom_geom_key, "Metaball Motherball Transform -> Geometry");
2279  }
2280  else {
2281  ComponentKey transform_key(&object->id, NodeType::TRANSFORM);
2282  add_relation(geom_key, mom_geom_key, "Metaball Motherball");
2283  add_relation(transform_key, mom_geom_key, "Metaball Motherball");
2284  }
2285  }
2286  /* NOTE: This is compatibility code to support particle systems
2287  *
2288  * for viewport being properly rendered in final render mode.
2289  * This relation is similar to what dag_object_time_update_flags()
2290  * was doing for mesh objects with particle system.
2291  *
2292  * Ideally we need to get rid of this relation. */
2293  if (object_particles_depends_on_time(object)) {
2294  TimeSourceKey time_key;
2295  OperationKey obdata_ubereval_key(
2297  add_relation(time_key, obdata_ubereval_key, "Legacy particle time");
2298  }
2299  /* Object data data-block. */
2301  Key *key = BKE_key_from_object(object);
2302  if (key != nullptr) {
2303  if (key->adt != nullptr) {
2304  if (key->adt->action || key->adt->nla_tracks.first) {
2305  ComponentKey obdata_key((ID *)object->data, NodeType::GEOMETRY);
2306  ComponentKey adt_key(&key->id, NodeType::ANIMATION);
2307  add_relation(adt_key, obdata_key, "Animation");
2308  }
2309  }
2310  }
2311  build_dimensions(object);
2312  /* Synchronization back to original object. */
2313  ComponentKey final_geometry_key(&object->id, NodeType::GEOMETRY);
2314  OperationKey synchronize_key(
2316  add_relation(final_geometry_key, synchronize_key, "Synchronize to Original");
2317  /* Batch cache. */
2318  OperationKey object_data_select_key(
2320  OperationKey object_select_key(
2322  add_relation(object_data_select_key, object_select_key, "Data Selection -> Object Selection");
2323  add_relation(
2324  geom_key, object_select_key, "Object Geometry -> Select Update", RELATION_FLAG_NO_FLUSH);
2325 }
2326 
2328 {
2329  if (built_map_.checkIsBuiltAndTag(obdata)) {
2330  return;
2331  }
2332 
2333  const BuilderStack::ScopedEntry stack_entry = stack_.trace(*obdata);
2334 
2335  build_idproperties(obdata->properties);
2336  /* Animation. */
2337  build_animdata(obdata);
2338  build_parameters(obdata);
2339  /* ShapeKeys. */
2340  Key *key = BKE_key_from_id(obdata);
2341  if (key != nullptr) {
2342  build_shapekeys(key);
2343  }
2344  /* Link object data evaluation node to exit operation. */
2345  OperationKey obdata_geom_eval_key(obdata, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL);
2346  OperationKey obdata_geom_done_key(obdata, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_DONE);
2347  add_relation(obdata_geom_eval_key, obdata_geom_done_key, "ObData Geom Eval Done");
2348 
2349  /* Link object data evaluation to parameter evaluation. */
2350  ComponentKey parameters_key(obdata, NodeType::PARAMETERS);
2351  add_relation(parameters_key, obdata_geom_eval_key, "ObData Geom Params");
2352 
2353  /* Type-specific links. */
2354  const ID_Type id_type = GS(obdata->name);
2355  switch (id_type) {
2356  case ID_ME:
2357  break;
2358  case ID_MB:
2359  break;
2360  case ID_CU_LEGACY: {
2361  Curve *cu = (Curve *)obdata;
2362  if (cu->bevobj != nullptr) {
2363  ComponentKey bevob_geom_key(&cu->bevobj->id, NodeType::GEOMETRY);
2364  add_relation(bevob_geom_key, obdata_geom_eval_key, "Curve Bevel Geometry");
2365  ComponentKey bevob_key(&cu->bevobj->id, NodeType::TRANSFORM);
2366  add_relation(bevob_key, obdata_geom_eval_key, "Curve Bevel Transform");
2367  build_object(cu->bevobj);
2368  }
2369  if (cu->taperobj != nullptr) {
2370  ComponentKey taperob_key(&cu->taperobj->id, NodeType::GEOMETRY);
2371  add_relation(taperob_key, obdata_geom_eval_key, "Curve Taper");
2372  build_object(cu->taperobj);
2373  }
2374  if (cu->textoncurve != nullptr) {
2375  ComponentKey textoncurve_geom_key(&cu->textoncurve->id, NodeType::GEOMETRY);
2376  add_relation(textoncurve_geom_key, obdata_geom_eval_key, "Text on Curve Geometry");
2377  ComponentKey textoncurve_key(&cu->textoncurve->id, NodeType::TRANSFORM);
2378  add_relation(textoncurve_key, obdata_geom_eval_key, "Text on Curve Transform");
2380  }
2381  break;
2382  }
2383  case ID_LT:
2384  break;
2385  case ID_GD: /* Grease Pencil */
2386  {
2387  bGPdata *gpd = (bGPdata *)obdata;
2388 
2389  /* Geometry cache needs to be recalculated on frame change
2390  * (e.g. to fix crashes after scrubbing the timeline when
2391  * onion skinning is enabled, since the ghosts need to be
2392  * re-added to the cache once scrubbing ends). */
2393  TimeSourceKey time_key;
2394  ComponentKey geometry_key(obdata, NodeType::GEOMETRY);
2395  add_relation(time_key, geometry_key, "GP Frame Change");
2396 
2397  /* Geometry cache also needs to be recalculated when Material
2398  * settings change (e.g. when fill.opacity changes on/off,
2399  * we need to rebuild the bGPDstroke->triangles caches). */
2400  for (int i = 0; i < gpd->totcol; i++) {
2401  Material *ma = gpd->mat[i];
2402  if ((ma != nullptr) && (ma->gp_style != nullptr)) {
2404  add_relation(material_key, geometry_key, "Material -> GP Data");
2405  }
2406  }
2407 
2408  /* Layer parenting need react to the parent object transformation. */
2409  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
2410  if (gpl->parent != nullptr) {
2411  ComponentKey gpd_geom_key(&gpd->id, NodeType::GEOMETRY);
2412 
2413  if (gpl->partype == PARBONE) {
2414  ComponentKey bone_key(&gpl->parent->id, NodeType::BONE, gpl->parsubstr);
2415  OperationKey armature_key(
2417 
2418  add_relation(bone_key, gpd_geom_key, "Bone Parent");
2419  add_relation(armature_key, gpd_geom_key, "Armature Parent");
2420  }
2421  else {
2422  ComponentKey transform_key(&gpl->parent->id, NodeType::TRANSFORM);
2423  add_relation(transform_key, gpd_geom_key, "GPencil Parent Layer");
2424  }
2425  }
2426  }
2427  break;
2428  }
2429  case ID_CV: {
2430  Curves *curves_id = reinterpret_cast<Curves *>(obdata);
2431  if (curves_id->surface != nullptr) {
2432  build_object(curves_id->surface);
2433 
2434  /* The relations between the surface and the curves are handled as part of the modifier
2435  * stack building. */
2436  }
2437  break;
2438  }
2439  case ID_PT:
2440  break;
2441  case ID_VO: {
2442  Volume *volume = (Volume *)obdata;
2443  if (volume->is_sequence) {
2444  TimeSourceKey time_key;
2445  ComponentKey geometry_key(obdata, NodeType::GEOMETRY);
2446  add_relation(time_key, geometry_key, "Volume sequence time");
2447  }
2448  break;
2449  }
2450  default:
2451  BLI_assert_msg(0, "Should not happen");
2452  break;
2453  }
2454 }
2455 
2457 {
2458  if (built_map_.checkIsBuiltAndTag(armature)) {
2459  return;
2460  }
2461 
2462  const BuilderStack::ScopedEntry stack_entry = stack_.trace(armature->id);
2463 
2464  build_idproperties(armature->id.properties);
2465  build_animdata(&armature->id);
2466  build_parameters(&armature->id);
2467  build_armature_bones(&armature->bonebase);
2468 }
2469 
2471 {
2472  LISTBASE_FOREACH (Bone *, bone, bones) {
2473  build_idproperties(bone->prop);
2474  build_armature_bones(&bone->childbase);
2475  }
2476 }
2477 
2479 {
2480  if (built_map_.checkIsBuiltAndTag(camera)) {
2481  return;
2482  }
2483 
2484  const BuilderStack::ScopedEntry stack_entry = stack_.trace(camera->id);
2485 
2486  build_idproperties(camera->id.properties);
2487  build_animdata(&camera->id);
2488  build_parameters(&camera->id);
2489  if (camera->dof.focus_object != nullptr) {
2490  build_object(camera->dof.focus_object);
2491  ComponentKey camera_parameters_key(&camera->id, NodeType::PARAMETERS);
2492  ComponentKey dof_ob_key(&camera->dof.focus_object->id, NodeType::TRANSFORM);
2493  add_relation(dof_ob_key, camera_parameters_key, "Camera DOF");
2494  if (camera->dof.focus_subtarget[0]) {
2495  OperationKey target_key(&camera->dof.focus_object->id,
2497  camera->dof.focus_subtarget,
2499  add_relation(target_key, camera_parameters_key, "Camera DOF subtarget");
2500  }
2501  }
2502 }
2503 
2504 /* Lights */
2506 {
2507  if (built_map_.checkIsBuiltAndTag(lamp)) {
2508  return;
2509  }
2510 
2511  const BuilderStack::ScopedEntry stack_entry = stack_.trace(lamp->id);
2512 
2514  build_animdata(&lamp->id);
2516 
2517  ComponentKey lamp_parameters_key(&lamp->id, NodeType::PARAMETERS);
2518 
2519  /* For allowing drivers on lamp properties. */
2520  ComponentKey shading_key(&lamp->id, NodeType::SHADING);
2521  add_relation(lamp_parameters_key, shading_key, "Light Shading Parameters");
2522 
2523  /* light's nodetree */
2524  if (lamp->nodetree != nullptr) {
2526  OperationKey ntree_key(
2528  add_relation(ntree_key, shading_key, "NTree->Light Parameters");
2530  }
2531 }
2532 
2534 {
2535  build_idproperties(socket->prop);
2536 
2537  if (socket->type == SOCK_OBJECT) {
2538  Object *object = ((bNodeSocketValueObject *)socket->default_value)->value;
2539  if (object != nullptr) {
2540  build_object(object);
2541  }
2542  }
2543  else if (socket->type == SOCK_IMAGE) {
2544  Image *image = ((bNodeSocketValueImage *)socket->default_value)->value;
2545  if (image != nullptr) {
2546  build_image(image);
2547  }
2548  }
2549  else if (socket->type == SOCK_COLLECTION) {
2550  Collection *collection = ((bNodeSocketValueCollection *)socket->default_value)->value;
2551  if (collection != nullptr) {
2552  build_collection(nullptr, nullptr, collection);
2553  }
2554  }
2555  else if (socket->type == SOCK_TEXTURE) {
2556  Tex *texture = ((bNodeSocketValueTexture *)socket->default_value)->value;
2557  if (texture != nullptr) {
2558  build_texture(texture);
2559  }
2560  }
2561  else if (socket->type == SOCK_MATERIAL) {
2563  if (material != nullptr) {
2565  }
2566  }
2567 }
2568 
2570 {
2571  if (ntree == nullptr) {
2572  return;
2573  }
2574  if (built_map_.checkIsBuiltAndTag(ntree)) {
2575  return;
2576  }
2577 
2578  const BuilderStack::ScopedEntry stack_entry = stack_.trace(ntree->id);
2579 
2581  build_animdata(&ntree->id);
2584  /* nodetree's nodes... */
2585  LISTBASE_FOREACH (bNode *, bnode, &ntree->nodes) {
2586  build_idproperties(bnode->prop);
2587  LISTBASE_FOREACH (bNodeSocket *, socket, &bnode->inputs) {
2588  build_nodetree_socket(socket);
2589  }
2590  LISTBASE_FOREACH (bNodeSocket *, socket, &bnode->outputs) {
2591  build_nodetree_socket(socket);
2592  }
2593 
2594  ID *id = bnode->id;
2595  if (id == nullptr) {
2596  continue;
2597  }
2598  ID_Type id_type = GS(id->name);
2599  if (id_type == ID_MA) {
2600  build_material((Material *)bnode->id);
2601  ComponentKey material_key(id, NodeType::SHADING);
2602  add_relation(material_key, ntree_output_key, "Material -> Node");
2603  }
2604  else if (id_type == ID_TE) {
2605  build_texture((Tex *)bnode->id);
2606  ComponentKey texture_key(id, NodeType::GENERIC_DATABLOCK);
2607  add_relation(texture_key, ntree_output_key, "Texture -> Node");
2608  }
2609  else if (id_type == ID_IM) {
2610  build_image((Image *)bnode->id);
2612  add_relation(image_key, ntree_output_key, "Image -> Node");
2613  }
2614  else if (id_type == ID_OB) {
2615  build_object((Object *)id);
2616  ComponentKey object_transform_key(id, NodeType::TRANSFORM);
2617  add_relation(object_transform_key, ntree_output_key, "Object Transform -> Node");
2618  if (object_have_geometry_component(reinterpret_cast<Object *>(id))) {
2619  ComponentKey object_geometry_key(id, NodeType::GEOMETRY);
2620  add_relation(object_geometry_key, ntree_output_key, "Object Geometry -> Node");
2621  }
2622  }
2623  else if (id_type == ID_SCE) {
2624  Scene *node_scene = (Scene *)id;
2625  build_scene_parameters(node_scene);
2626  /* Camera is used by defocus node.
2627  *
2628  * On the one hand it's annoying to always pull it in, but on another hand it's also annoying
2629  * to have hardcoded node-type exception here. */
2630  if (node_scene->camera != nullptr) {
2631  build_object(node_scene->camera);
2632  }
2633  }
2634  else if (id_type == ID_TXT) {
2635  /* Ignore script nodes. */
2636  }
2637  else if (id_type == ID_MSK) {
2638  build_mask((Mask *)id);
2640  add_relation(mask_key, ntree_output_key, "Mask -> Node");
2641  }
2642  else if (id_type == ID_MC) {
2643  build_movieclip((MovieClip *)id);
2645  add_relation(clip_key, ntree_output_key, "Clip -> Node");
2646  }
2647  else if (id_type == ID_VF) {
2648  build_vfont((VFont *)id);
2650  add_relation(vfont_key, ntree_output_key, "VFont -> Node");
2651  }
2652  else if (ELEM(bnode->type, NODE_GROUP, NODE_CUSTOM_GROUP)) {
2653  bNodeTree *group_ntree = (bNodeTree *)id;
2654  build_nodetree(group_ntree);
2655  ComponentKey group_output_key(&group_ntree->id, NodeType::NTREE_OUTPUT);
2656  /* This relation is not necessary in all cases (e.g. when the group node is not connected to
2657  * the output). Currently, we lack the infrastructure to check for these cases efficiently.
2658  * That can be added later. */
2659  add_relation(group_output_key, ntree_output_key, "Group Node");
2660  }
2661  else {
2662  BLI_assert_msg(0, "Unknown ID type used for node");
2663  }
2664  }
2665 
2666  LISTBASE_FOREACH (bNodeSocket *, socket, &ntree->inputs) {
2667  build_idproperties(socket->prop);
2668  }
2669  LISTBASE_FOREACH (bNodeSocket *, socket, &ntree->outputs) {
2670  build_idproperties(socket->prop);
2671  }
2672 
2673  if (check_id_has_anim_component(&ntree->id)) {
2674  ComponentKey animation_key(&ntree->id, NodeType::ANIMATION);
2675  add_relation(animation_key, ntree_output_key, "NTree Shading Parameters");
2676  }
2677 }
2678 
2679 /* Recursively build graph for material */
2681 {
2682  if (built_map_.checkIsBuiltAndTag(material)) {
2683  return;
2684  }
2685 
2686  const BuilderStack::ScopedEntry stack_entry = stack_.trace(material->id);
2687 
2689  /* animation */
2692 
2693  /* Animated / driven parameters (without nodetree). */
2695  ComponentKey parameters_key(&material->id, NodeType::PARAMETERS);
2696  add_relation(parameters_key, material_key, "Material's parameters");
2697 
2698  /* material's nodetree */
2699  if (material->nodetree != nullptr) {
2701  OperationKey ntree_key(
2703  add_relation(ntree_key, material_key, "Material's NTree");
2705  }
2706 }
2707 
2709 {
2710  for (int i = 0; i < num_materials; i++) {
2711  if (materials[i] == nullptr) {
2712  continue;
2713  }
2715  }
2716 }
2717 
2718 /* Recursively build graph for texture */
2720 {
2721  if (built_map_.checkIsBuiltAndTag(texture)) {
2722  return;
2723  }
2724 
2725  const BuilderStack::ScopedEntry stack_entry = stack_.trace(texture->id);
2726 
2727  /* texture itself */
2728  ComponentKey texture_key(&texture->id, NodeType::GENERIC_DATABLOCK);
2729  build_idproperties(texture->id.properties);
2730  build_animdata(&texture->id);
2731  build_parameters(&texture->id);
2732 
2733  /* texture's nodetree */
2734  if (texture->nodetree) {
2735  build_nodetree(texture->nodetree);
2736  OperationKey ntree_key(
2738  add_relation(ntree_key, texture_key, "Texture's NTree");
2739  build_nested_nodetree(&texture->id, texture->nodetree);
2740  }
2741 
2742  /* Special cases for different IDs which texture uses. */
2743  if (texture->type == TEX_IMAGE) {
2744  if (texture->ima != nullptr) {
2745  build_image(texture->ima);
2746 
2747  ComponentKey image_key(&texture->ima->id, NodeType::GENERIC_DATABLOCK);
2748  add_relation(image_key, texture_key, "Texture Image");
2749  }
2750  }
2751 
2752  if (check_id_has_anim_component(&texture->id)) {
2753  ComponentKey animation_key(&texture->id, NodeType::ANIMATION);
2754  add_relation(animation_key, texture_key, "Datablock Animation");
2755  }
2756 
2757  if (BKE_image_user_id_has_animation(&texture->id)) {
2758  ComponentKey image_animation_key(&texture->id, NodeType::IMAGE_ANIMATION);
2759  add_relation(image_animation_key, texture_key, "Datablock Image Animation");
2760  }
2761 }
2762 
2764 {
2765  if (built_map_.checkIsBuiltAndTag(image)) {
2766  return;
2767  }
2768 
2769  const BuilderStack::ScopedEntry stack_entry = stack_.trace(image->id);
2770 
2771  build_idproperties(image->id.properties);
2772  build_parameters(&image->id);
2773 }
2774 
2776 {
2777  if (built_map_.checkIsBuiltAndTag(cache_file)) {
2778  return;
2779  }
2780 
2781  const BuilderStack::ScopedEntry stack_entry = stack_.trace(cache_file->id);
2782 
2783  build_idproperties(cache_file->id.properties);
2784  /* Animation. */
2785  build_animdata(&cache_file->id);
2786  build_parameters(&cache_file->id);
2787  if (check_id_has_anim_component(&cache_file->id)) {
2788  ComponentKey animation_key(&cache_file->id, NodeType::ANIMATION);
2789  ComponentKey datablock_key(&cache_file->id, NodeType::CACHE);
2790  add_relation(animation_key, datablock_key, "Datablock Animation");
2791  }
2792  if (check_id_has_driver_component(&cache_file->id)) {
2793  ComponentKey animation_key(&cache_file->id, NodeType::PARAMETERS);
2794  ComponentKey datablock_key(&cache_file->id, NodeType::CACHE);
2795  add_relation(animation_key, datablock_key, "Drivers -> Cache Eval");
2796  }
2797 
2798  /* Cache file updates */
2799  if (cache_file->is_sequence) {
2800  OperationKey cache_update_key(
2802  TimeSourceKey time_src_key;
2803  add_relation(time_src_key, cache_update_key, "TimeSrc -> Cache File Eval");
2804  }
2805 }
2806 
2808 {
2809  if (built_map_.checkIsBuiltAndTag(mask)) {
2810  return;
2811  }
2812 
2813  const BuilderStack::ScopedEntry stack_entry = stack_.trace(mask->id);
2814 
2815  ID *mask_id = &mask->id;
2816  build_idproperties(mask_id->properties);
2817  /* F-Curve animation. */
2818  build_animdata(mask_id);
2819  build_parameters(mask_id);
2820  /* Own mask animation. */
2821  OperationKey mask_animation_key(mask_id, NodeType::ANIMATION, OperationCode::MASK_ANIMATION);
2822  TimeSourceKey time_src_key;
2823  add_relation(time_src_key, mask_animation_key, "TimeSrc -> Mask Animation");
2824  /* Final mask evaluation. */
2826  add_relation(mask_animation_key, mask_eval_key, "Mask Animation -> Mask Eval");
2827  /* Build parents. */
2828  LISTBASE_FOREACH (MaskLayer *, mask_layer, &mask->masklayers) {
2829  LISTBASE_FOREACH (MaskSpline *, spline, &mask_layer->splines) {
2830  for (int i = 0; i < spline->tot_point; i++) {
2831  MaskSplinePoint *point = &spline->points[i];
2832  MaskParent *parent = &point->parent;
2833  if (parent == nullptr || parent->id == nullptr) {
2834  continue;
2835  }
2836  build_id(parent->id);
2837  if (parent->id_type == ID_MC) {
2838  OperationKey movieclip_eval_key(
2840  add_relation(movieclip_eval_key, mask_eval_key, "Movie Clip -> Mask Eval");
2841  }
2842  }
2843  }
2844  }
2845 }
2846 
2848 {
2849  if (built_map_.checkIsBuiltAndTag(linestyle)) {
2850  return;
2851  }
2852 
2853  const BuilderStack::ScopedEntry stack_entry = stack_.trace(linestyle->id);
2854 
2855  ID *linestyle_id = &linestyle->id;
2856  build_parameters(linestyle_id);
2857  build_idproperties(linestyle_id->properties);
2858  build_animdata(linestyle_id);
2860 }
2861 
2863 {
2864  if (built_map_.checkIsBuiltAndTag(clip)) {
2865  return;
2866  }
2867 
2868  const BuilderStack::ScopedEntry stack_entry = stack_.trace(clip->id);
2869 
2870  /* Animation. */
2872  build_animdata(&clip->id);
2873  build_parameters(&clip->id);
2874 }
2875 
2877 {
2878  if (built_map_.checkIsBuiltAndTag(probe)) {
2879  return;
2880  }
2881 
2882  const BuilderStack::ScopedEntry stack_entry = stack_.trace(probe->id);
2883 
2885  build_animdata(&probe->id);
2886  build_parameters(&probe->id);
2887 }
2888 
2890 {
2891  if (built_map_.checkIsBuiltAndTag(speaker)) {
2892  return;
2893  }
2894 
2895  const BuilderStack::ScopedEntry stack_entry = stack_.trace(speaker->id);
2896 
2897  build_idproperties(speaker->id.properties);
2898  build_animdata(&speaker->id);
2899  build_parameters(&speaker->id);
2900  if (speaker->sound != nullptr) {
2901  build_sound(speaker->sound);
2902  ComponentKey speaker_key(&speaker->id, NodeType::AUDIO);
2903  ComponentKey sound_key(&speaker->sound->id, NodeType::AUDIO);
2904  add_relation(sound_key, speaker_key, "Sound -> Speaker");
2905  }
2906 }
2907 
2909 {
2910  if (built_map_.checkIsBuiltAndTag(sound)) {
2911  return;
2912  }
2913 
2914  const BuilderStack::ScopedEntry stack_entry = stack_.trace(sound->id);
2915 
2917  build_animdata(&sound->id);
2918  build_parameters(&sound->id);
2919 }
2920 
2922 {
2923  if (built_map_.checkIsBuiltAndTag(simulation)) {
2924  return;
2925  }
2926 
2927  const BuilderStack::ScopedEntry stack_entry = stack_.trace(simulation->id);
2928 
2932 
2935 
2936  OperationKey simulation_eval_key(
2938  TimeSourceKey time_src_key;
2939  add_relation(time_src_key, simulation_eval_key, "TimeSrc -> Simulation");
2940 
2941  OperationKey nodetree_key(
2943  add_relation(nodetree_key, simulation_eval_key, "NodeTree -> Simulation", 0);
2944 }
2945 
2947  DepsgraphRelationBuilder *builder;
2950 };
2951 
2952 static bool seq_build_prop_cb(Sequence *seq, void *user_data)
2953 {
2955 
2956  cd->builder->build_idproperties(seq->prop);
2957  if (seq->sound != nullptr) {
2958  cd->builder->build_sound(seq->sound);
2959  ComponentKey sound_key(&seq->sound->id, NodeType::AUDIO);
2960  cd->builder->add_relation(sound_key, cd->sequencer_key, "Sound -> Sequencer");
2961  cd->has_audio_strips = true;
2962  }
2963  if (seq->scene != nullptr) {
2964  cd->builder->build_scene_parameters(seq->scene);
2965  /* This is to support 3D audio. */
2966  cd->has_audio_strips = true;
2967  }
2968  if (seq->type == SEQ_TYPE_SCENE && seq->scene != nullptr) {
2969  if (seq->flag & SEQ_SCENE_STRIPS) {
2970  cd->builder->build_scene_sequencer(seq->scene);
2971  ComponentKey sequence_scene_audio_key(&seq->scene->id, NodeType::AUDIO);
2972  cd->builder->add_relation(
2973  sequence_scene_audio_key, cd->sequencer_key, "Sequence Scene Audio -> Sequencer");
2974  ComponentKey sequence_scene_key(&seq->scene->id, NodeType::SEQUENCER);
2975  cd->builder->add_relation(
2976  sequence_scene_key, cd->sequencer_key, "Sequence Scene -> Sequencer");
2977  }
2978  ViewLayer *sequence_view_layer = BKE_view_layer_default_render(seq->scene);
2979  cd->builder->build_scene_speakers(seq->scene, sequence_view_layer);
2980  }
2981  /* TODO(sergey): Movie clip, camera, mask. */
2982  return true;
2983 }
2984 
2986 {
2987  if (scene->ed == nullptr) {
2988  return;
2989  }
2991  return;
2992  }
2993 
2994  /* TODO(sergey): Trace as a scene sequencer. */
2995 
2997  ComponentKey scene_audio_key(&scene->id, NodeType::AUDIO);
2998  /* Make sure dependencies from sequences data goes to the sequencer evaluation. */
3000 
3001  Seq_build_prop_cb_data cb_data = {this, sequencer_key, false};
3002 
3004  if (cb_data.has_audio_strips) {
3005  add_relation(sequencer_key, scene_audio_key, "Sequencer -> Audio");
3006  }
3007 }
3008 
3010 {
3011  OperationKey scene_audio_entry_key(&scene->id, NodeType::AUDIO, OperationCode::AUDIO_ENTRY);
3012  OperationKey scene_audio_volume_key(&scene->id, NodeType::AUDIO, OperationCode::AUDIO_VOLUME);
3014  add_relation(scene_audio_entry_key, scene_audio_volume_key, "Audio Entry -> Volume");
3015  add_relation(scene_audio_volume_key, scene_sound_eval_key, "Audio Volume -> Sound");
3016 
3018  ComponentKey scene_anim_key(&scene->id, NodeType::ANIMATION);
3019  add_relation(scene_anim_key, scene_audio_volume_key, "Animation -> Audio Volume");
3020  }
3021 }
3022 
3024 {
3025  LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
3026  Object *object = base->object;
3027  if (object->type != OB_SPEAKER || !need_pull_base_into_graph(base)) {
3028  continue;
3029  }
3030  build_object(base->object);
3031  }
3032 }
3033 
3035 {
3036  if (built_map_.checkIsBuiltAndTag(vfont)) {
3037  return;
3038  }
3039 
3040  const BuilderStack::ScopedEntry stack_entry = stack_.trace(vfont->id);
3041 
3042  build_parameters(&vfont->id);
3044 }
3045 
3047 {
3048  for (IDNode *id_node : graph_->id_nodes) {
3050  }
3051 }
3052 
3059 void DepsgraphRelationBuilder::build_nested_datablock(ID *owner, ID *id, bool flush_cow_changes)
3060 {
3061  int relation_flag = 0;
3062  if (!flush_cow_changes) {
3063  relation_flag |= RELATION_FLAG_NO_FLUSH;
3064  }
3065  OperationKey owner_copy_on_write_key(
3068  add_relation(id_copy_on_write_key, owner_copy_on_write_key, "Eval Order", relation_flag);
3069 }
3070 
3072 {
3073  if (ntree == nullptr) {
3074  return;
3075  }
3076  /* Don't flush cow changes, because the node tree may change in ways that do not affect the
3077  * owner data block (e.g. when a node is deleted that is not connected to any output).
3078  * Data blocks owning node trees should add a relation to the `NTREE_OUTPUT` node instead. */
3079  build_nested_datablock(owner, &ntree->id, false);
3080 }
3081 
3083 {
3084  if (key == nullptr) {
3085  return;
3086  }
3087  build_nested_datablock(owner, &key->id, true);
3088 }
3089 
3091 {
3092  ID *id_orig = id_node->id_orig;
3093 
3094  const ID_Type id_type = GS(id_orig->name);
3095 
3096  if (!deg_copy_on_write_is_needed(id_type)) {
3097  return;
3098  }
3099 
3100  TimeSourceKey time_source_key;
3102  /* XXX: This is a quick hack to make Alt-A to work. */
3103  // add_relation(time_source_key, copy_on_write_key, "Fluxgate capacitor hack");
3104  /* Resat of code is using rather low level trickery, so need to get some
3105  * explicit pointers. */
3106  Node *node_cow = find_node(copy_on_write_key);
3107  OperationNode *op_cow = node_cow->get_exit_operation();
3108  /* Plug any other components to this one. */
3109  for (ComponentNode *comp_node : id_node->components.values()) {
3110  if (comp_node->type == NodeType::COPY_ON_WRITE) {
3111  /* Copy-on-write component never depends on itself. */
3112  continue;
3113  }
3114  if (!comp_node->depends_on_cow()) {
3115  /* Component explicitly requests to not add relation. */
3116  continue;
3117  }
3118  int rel_flag = (RELATION_FLAG_NO_FLUSH | RELATION_FLAG_GODMODE);
3119  if ((ELEM(id_type, ID_ME, ID_CV, ID_PT, ID_VO) && comp_node->type == NodeType::GEOMETRY) ||
3120  (id_type == ID_CF && comp_node->type == NodeType::CACHE)) {
3121  rel_flag &= ~RELATION_FLAG_NO_FLUSH;
3122  }
3123  /* TODO(sergey): Needs better solution for this. */
3124  if (id_type == ID_SO) {
3125  rel_flag &= ~RELATION_FLAG_NO_FLUSH;
3126  }
3127  /* Notes on exceptions:
3128  * - Parameters component is where drivers are living. Changing any
3129  * of the (custom) properties in the original datablock (even the
3130  * ones which do not imply other component update) need to make
3131  * sure drivers are properly updated.
3132  * This way, for example, changing ID property will properly poke
3133  * all drivers to be updated.
3134  *
3135  * - View layers have cached array of bases in them, which is not
3136  * copied by copy-on-write, and not preserved. PROBABLY it is better
3137  * to preserve that cache in copy-on-write, but for the time being
3138  * we allow flush to layer collections component which will ensure
3139  * that cached array of bases exists and is up-to-date. */
3140  if (ELEM(comp_node->type, NodeType::PARAMETERS, NodeType::LAYER_COLLECTIONS)) {
3141  rel_flag &= ~RELATION_FLAG_NO_FLUSH;
3142  }
3143  /* All entry operations of each component should wait for a proper
3144  * copy of ID. */
3145  OperationNode *op_entry = comp_node->get_entry_operation();
3146  if (op_entry != nullptr) {
3147  Relation *rel = graph_->add_new_relation(op_cow, op_entry, "CoW Dependency");
3148  rel->flag |= rel_flag;
3149  }
3150  /* All dangling operations should also be executed after copy-on-write. */
3151  for (OperationNode *op_node : comp_node->operations_map->values()) {
3152  if (op_node == op_entry) {
3153  continue;
3154  }
3155  if (op_node->inlinks.is_empty()) {
3156  Relation *rel = graph_->add_new_relation(op_cow, op_node, "CoW Dependency");
3157  rel->flag |= rel_flag;
3158  }
3159  else {
3160  bool has_same_comp_dependency = false;
3161  for (Relation *rel_current : op_node->inlinks) {
3162  if (rel_current->from->type != NodeType::OPERATION) {
3163  continue;
3164  }
3165  OperationNode *op_node_from = (OperationNode *)rel_current->from;
3166  if (op_node_from->owner == op_node->owner) {
3167  has_same_comp_dependency = true;
3168  break;
3169  }
3170  }
3171  if (!has_same_comp_dependency) {
3172  Relation *rel = graph_->add_new_relation(op_cow, op_node, "CoW Dependency");
3173  rel->flag |= rel_flag;
3174  }
3175  }
3176  }
3177  /* NOTE: We currently ignore implicit relations to an external
3178  * data-blocks for copy-on-write operations. This means, for example,
3179  * copy-on-write component of Object will not wait for copy-on-write
3180  * component of its Mesh. This is because pointers are all known
3181  * already so remapping will happen all correct. And then If some object
3182  * evaluation step needs geometry, it will have transitive dependency
3183  * to Mesh copy-on-write already. */
3184  }
3185  /* TODO(sergey): This solves crash for now, but causes too many
3186  * updates potentially. */
3187  if (GS(id_orig->name) == ID_OB) {
3188  Object *object = (Object *)id_orig;
3189  ID *object_data_id = (ID *)object->data;
3190  if (object_data_id != nullptr) {
3191  if (deg_copy_on_write_is_needed(object_data_id)) {
3192  OperationKey data_copy_on_write_key(
3194  add_relation(
3195  data_copy_on_write_key, copy_on_write_key, "Eval Order", RELATION_FLAG_GODMODE);
3196  }
3197  }
3198  else {
3199  BLI_assert(object->type == OB_EMPTY);
3200  }
3201  }
3202 
3203 #if 0
3204  /* NOTE: Relation is disabled since AnimationBackup() is disabled.
3205  * See comment in AnimationBackup:init_from_id(). */
3206 
3207  /* Copy-on-write of write will iterate over f-curves to store current values corresponding
3208  * to their RNA path. This means that action must be copied prior to the ID's copy-on-write,
3209  * otherwise depsgraph might try to access freed data. */
3210  AnimData *animation_data = BKE_animdata_from_id(id_orig);
3211  if (animation_data != nullptr) {
3212  if (animation_data->action != nullptr) {
3213  OperationKey action_copy_on_write_key(
3215  add_relation(action_copy_on_write_key,
3216  copy_on_write_key,
3217  "Eval Order",
3219  }
3220  }
3221 #endif
3222 }
3223 
3224 /* **** ID traversal callbacks functions **** */
3225 
3226 void DepsgraphRelationBuilder::modifier_walk(void *user_data,
3227  struct Object * /*object*/,
3228  struct ID **idpoin,
3229  int /*cb_flag*/)
3230 {
3231  BuilderWalkUserData *data = (BuilderWalkUserData *)user_data;
3232  ID *id = *idpoin;
3233  if (id == nullptr) {
3234  return;
3235  }
3236  data->builder->build_id(id);
3237 }
3238 
3239 void DepsgraphRelationBuilder::constraint_walk(bConstraint * /*con*/,
3240  ID **idpoin,
3241  bool /*is_reference*/,
3242  void *user_data)
3243 {
3244  BuilderWalkUserData *data = (BuilderWalkUserData *)user_data;
3245  ID *id = *idpoin;
3246  if (id == nullptr) {
3247  return;
3248  }
3249  data->builder->build_id(id);
3250 }
3251 
3252 } // namespace blender::deg
Blender kernel action and pose functionality.
struct bPoseChannel * BKE_pose_channel_find_name(const struct bPose *pose, const char *name)
struct AnimData * BKE_animdata_from_id(const struct ID *id)
#define FOREACH_COLLECTION_OBJECT_RECURSIVE_END
#define FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_BEGIN(_collection, _object, _mode)
#define FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(_collection, _object)
#define FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_END
void BKE_constraints_id_loop(struct ListBase *list, ConstraintIDFunc func, void *userdata)
Definition: constraint.c:5877
void BKE_constraint_targets_flush(struct bConstraint *con, struct ListBase *targets, bool no_copy)
Definition: constraint.c:6186
int BKE_constraint_targets_get(struct bConstraint *con, struct ListBase *r_targets)
Definition: constraint.c:6157
bool BKE_constraint_target_uses_bbone(struct bConstraint *con, struct bConstraintTarget *ct)
Definition: constraint.c:5847
const bConstraintTypeInfo * BKE_constraint_typeinfo_get(struct bConstraint *con)
Definition: constraint.c:5506
bool BKE_driver_expression_depends_on_time(struct ChannelDriver *driver)
#define DRIVER_TARGETS_USED_LOOPER_BEGIN(dvar)
#define DRIVER_TARGETS_LOOPER_END
void void BKE_gpencil_modifiers_foreach_ID_link(struct Object *ob, GreasePencilIDWalkFunc walk, void *userData)
bool BKE_gpencil_modifier_depends_ontime(struct GpencilModifierData *md)
const GpencilModifierTypeInfo * BKE_gpencil_modifier_get_info(GpencilModifierType type)
void IDP_foreach_property(struct IDProperty *id_property_root, int type_filter, IDPForeachPropertyCallback callback, void *user_data)
Definition: idprop.c:1117
bool BKE_image_user_id_has_animation(struct ID *id)
struct Key * BKE_key_from_id(struct ID *id)
Definition: key.c:1783
struct Key * BKE_key_from_object(struct Object *ob)
Definition: key.c:1803
struct ViewLayer * BKE_view_layer_default_render(const struct Scene *scene)
General operations, lookup, etc. for materials.
struct Material *** BKE_object_material_array_p(struct Object *ob)
Definition: material.c:311
short * BKE_object_material_len_p(struct Object *ob)
Definition: material.c:344
struct Object * BKE_mball_basis_find(struct Scene *scene, struct Object *ob)
Definition: mball.c:508
const ModifierTypeInfo * BKE_modifier_get_info(ModifierType type)
bool BKE_modifier_depends_ontime(struct Scene *scene, struct ModifierData *md)
void BKE_modifiers_foreach_ID_link(struct Object *ob, IDWalkFunc walk, void *userData)
#define NODE_CUSTOM_GROUP
Definition: BKE_node.h:989
struct bNodeTree ** BKE_ntree_ptr_from_id(struct ID *id)
Definition: node.cc:3209
General operations, lookup, etc. for blender objects.
void BKE_ptcache_ids_from_object(struct ListBase *lb, struct Object *ob, struct Scene *scene, int duplis)
Definition: pointcache.c:1250
bool BKE_ptcache_object_has(struct Scene *scene, struct Object *ob, int duplis)
Definition: pointcache.c:1263
#define PTCACHE_TYPE_RIGIDBODY
API for Blender-side Rigid Body stuff.
bool BKE_shaderfx_depends_ontime(struct ShaderFxData *fx)
Definition: shader_fx.c:132
void BKE_shaderfx_foreach_ID_link(struct Object *ob, ShaderFxIDWalkFunc walk, void *userData)
Definition: shader_fx.c:246
const ShaderFxTypeInfo * BKE_shaderfx_get_info(ShaderFxType type)
Definition: shader_fx.c:139
bool BKE_shrinkwrap_needs_normals(int shrinkType, int shrinkMode)
Definition: shrinkwrap.c:90
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition: BLI_assert.h:53
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:269
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:466
#define STRPREFIX(a, b)
#define ELEM(...)
#define STREQ(a, b)
@ DAG_EVAL_NEED_SHRINKWRAP_BOUNDARY
Definition: DEG_depsgraph.h:57
@ DAG_EVAL_NEED_CURVE_PATH
Definition: DEG_depsgraph.h:54
@ IDP_TYPE_FILTER_ID
Definition: DNA_ID.h:155
@ IDP_ID
Definition: DNA_ID.h:142
ID_Type
Definition: DNA_ID_enums.h:44
@ ID_WM
Definition: DNA_ID_enums.h:72
@ ID_CA
Definition: DNA_ID_enums.h:56
@ ID_AR
Definition: DNA_ID_enums.h:66
@ ID_MC
Definition: DNA_ID_enums.h:73
@ ID_CF
Definition: DNA_ID_enums.h:78
@ ID_LI
Definition: DNA_ID_enums.h:46
@ ID_TE
Definition: DNA_ID_enums.h:52
@ ID_IM
Definition: DNA_ID_enums.h:53
@ ID_VO
Definition: DNA_ID_enums.h:83
@ ID_WS
Definition: DNA_ID_enums.h:79
@ ID_NT
Definition: DNA_ID_enums.h:68
@ ID_LA
Definition: DNA_ID_enums.h:55
@ ID_KE
Definition: DNA_ID_enums.h:58
@ ID_TXT
Definition: DNA_ID_enums.h:62
@ ID_SO
Definition: DNA_ID_enums.h:64
@ ID_SCE
Definition: DNA_ID_enums.h:45
@ ID_LS
Definition: DNA_ID_enums.h:75
@ ID_MSK
Definition: DNA_ID_enums.h:74
@ ID_GD
Definition: DNA_ID_enums.h:71
@ ID_CV
Definition: DNA_ID_enums.h:81
@ ID_PAL
Definition: DNA_ID_enums.h:76
@ ID_BR
Definition: DNA_ID_enums.h:69
@ ID_LP
Definition: DNA_ID_enums.h:80
@ ID_WO
Definition: DNA_ID_enums.h:59
@ ID_SIM
Definition: DNA_ID_enums.h:84
@ ID_MA
Definition: DNA_ID_enums.h:51
@ ID_AC
Definition: DNA_ID_enums.h:67
@ ID_SCR
Definition: DNA_ID_enums.h:60
@ ID_CU_LEGACY
Definition: DNA_ID_enums.h:49
@ ID_VF
Definition: DNA_ID_enums.h:61
@ ID_ME
Definition: DNA_ID_enums.h:48
@ ID_IP
Definition: DNA_ID_enums.h:57
@ ID_GR
Definition: DNA_ID_enums.h:65
@ ID_SPK
Definition: DNA_ID_enums.h:63
@ ID_MB
Definition: DNA_ID_enums.h:50
@ ID_LT
Definition: DNA_ID_enums.h:54
@ ID_OB
Definition: DNA_ID_enums.h:47
@ ID_PA
Definition: DNA_ID_enums.h:70
@ ID_PT
Definition: DNA_ID_enums.h:82
@ ID_PC
Definition: DNA_ID_enums.h:77
@ DTAR_FLAG_STRUCT_REF
@ eBoidRuleType_Avoid
@ eBoidRuleType_FollowLeader
Object groups, one object can be in many groups at once.
@ CONSTRAINT_TYPE_FOLLOWTRACK
@ CONSTRAINT_TYPE_OBJECTSOLVER
@ CONSTRAINT_TYPE_ARMATURE
@ CONSTRAINT_TYPE_LOCLIKE
@ CONSTRAINT_TYPE_SHRINKWRAP
@ CONSTRAINT_TYPE_CAMERASOLVER
@ CONSTRAINT_TYPE_ROTLIKE
@ CONSTRAINT_TYPE_SPLINEIK
@ CONSTRAINT_TYPE_KINEMATIC
@ CONSTRAINT_TYPE_TRANSLIKE
@ CONSTRAINT_TYPE_CLAMPTO
@ CONSTRAINT_TYPE_FOLLOWPATH
@ CONSTRAINT_TYPE_SIZELIKE
@ CONSTRAINT_TYPE_TRANSFORM_CACHE
@ FOLLOWTRACK_ACTIVECLIP
@ CON_SHRINKWRAP_TRACK_NORMAL
@ CU_PATH
#define CD_MASK_NORMAL
#define CD_MASK_ORIGINDEX
#define CD_MASK_MDEFORMVERT
#define CD_MASK_CUSTOMLOOPNORMAL
#define TEXCO_OBJECT
@ MOD_SHRINKWRAP_TARGET_PROJECT
@ MOD_SHRINKWRAP_NEAREST_VERTEX
ModifierType
@ eModifierType_Collision
@ NTREE_RUNTIME_FLAG_HAS_IMAGE_ANIMATION
@ SOCK_TEXTURE
@ SOCK_MATERIAL
@ SOCK_IMAGE
@ SOCK_COLLECTION
@ SOCK_OBJECT
#define PFIELD_SHAPE_SURFACE
#define PFIELD_VISIBILITY
@ PFIELD_FLUIDFLOW
@ PFIELD_GUIDE
@ PFIELD_TEXTURE
#define PFIELD_SHAPE_POINTS
Object is a sort of wrapper for general info.
#define OB_TYPE_IS_GEOMETRY(_type)
@ OB_SPEAKER
@ OB_LATTICE
@ OB_MBALL
@ OB_EMPTY
@ OB_SURF
@ OB_CAMERA
@ OB_FONT
@ OB_ARMATURE
@ OB_LAMP
@ OB_MESH
@ OB_POINTCLOUD
@ OB_VOLUME
@ OB_CURVES_LEGACY
@ OB_CURVES
@ OB_GPENCIL
@ OB_LIGHTPROBE
@ OB_DUPLI
@ OB_DUPLIVERTS
@ PARVERT1
@ PARSKEL
@ PARVERT3
@ PARBONE
#define PART_PHYS_KEYED
#define PART_DRAW_OB
#define PART_PHYS_BOIDS
#define PSYS_HAIR_DYNAMICS
@ PART_HAIR
#define PART_DRAW_GR
Types and defines for representing Rigid Body entities.
@ RBO_TYPE_ACTIVE
@ RBO_TYPE_PASSIVE
@ RB_SHAPE_COMPOUND
#define AUDIO_VOLUME_ANIMATED
@ SEQ_TYPE_SCENE
@ SEQ_SCENE_STRIPS
ShaderFxType
Read Guarded memory(de)allocation.
NODE_GROUP
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to curves
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 Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise 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
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 Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise 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 TEX_IMAGE
btSequentialImpulseConstraintSolverMt int btPersistentManifold int btTypedConstraint ** constraints
constexpr bool startswith(StringRef prefix) const
bool checkIsBuiltAndTag(ID *id, int tag=TAG_COMPLETE)
bool checkIsBuilt(ID *id, int tag=TAG_COMPLETE) const
ScopedEntry trace(const Args &...args)
virtual bool check_pchan_has_bbone_segments(const Object *object, const bPoseChannel *pchan)
Definition: deg_builder.cc:118
virtual bool need_pull_base_into_graph(const Base *base)
Definition: deg_builder.cc:67
bool has_node(const OperationKey &key) const
void add_particle_collision_relations(const OperationKey &key, Object *object, Collection *collection, const char *name)
Relation * add_depends_on_transform_relation(ID *id, const KeyTo &key_to, const char *description, int flags=0)
virtual void build_freestyle_linestyle(FreestyleLineStyle *linestyle)
virtual void build_object_layer_component_relations(Object *object)
virtual void build_object_from_view_layer_base(Object *object)
virtual void build_driver(ID *id, FCurve *fcurve)
virtual void build_dimensions(Object *object)
virtual void build_driver_data(ID *id, FCurve *fcurve)
virtual void build_nested_nodetree(ID *owner, bNodeTree *ntree)
virtual void build_nodetree_socket(bNodeSocket *socket)
virtual void build_action(bAction *action)
virtual void build_collection(LayerCollection *from_layer_collection, Object *object, Collection *collection)
virtual void build_speaker(Speaker *speaker)
TimeSourceNode * get_node(const TimeSourceKey &key) const
bool is_same_nodetree_node_dependency(const KeyFrom &key_from, const KeyTo &key_to)
virtual void build_scene_speakers(Scene *scene, ViewLayer *view_layer)
OperationNode * find_node(const OperationKey &key) const
virtual void build_armature(bArmature *armature)
virtual void build_armature_bones(ListBase *bones)
virtual void build_object_pointcache(Object *object)
virtual void build_constraints(ID *id, NodeType component_type, const char *component_subdata, ListBase *constraints, RootPChanMap *root_map)
virtual void build_animdata_curves_targets(ID *id, ComponentKey &adt_key, OperationNode *operation_from, ListBase *curves)
virtual void build_object_data_light(Object *object)
void add_customdata_mask(Object *object, const DEGCustomDataMeshMasks &customdata_masks)
bool is_same_bone_dependency(const KeyFrom &key_from, const KeyTo &key_to)
virtual void build_driver_id_property(ID *id, const char *rna_path)
virtual void build_scene_sequencer(Scene *scene)
virtual void build_object_data_camera(Object *object)
virtual void build_object_data_geometry(Object *object)
DepsgraphRelationBuilder(Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache)
virtual void build_object_data_lightprobe(Object *object)
virtual void build_particle_settings(ParticleSettings *part)
void add_special_eval_flag(ID *id, uint32_t flag)
virtual void build_movieclip(MovieClip *clip)
virtual void build_nodetree(bNodeTree *ntree)
Relation * add_relation(const KeyFrom &key_from, const KeyTo &key_to, const char *description, int flags=0)
virtual void build_object_data_geometry_datablock(ID *obdata)
void add_particle_forcefield_relations(const OperationKey &key, Object *object, ParticleSystem *psys, EffectorWeights *eff, bool add_absorption, const char *name)
virtual void build_nested_datablock(ID *owner, ID *id, bool flush_cow_changes)
virtual void build_particle_system_visualization_object(Object *object, ParticleSystem *psys, Object *draw_object)
virtual void build_lightprobe(LightProbe *probe)
void add_visibility_relation(ID *id_from, ID *id_to)
virtual void build_driver_variables(ID *id, FCurve *fcurve)
virtual void build_nested_shapekey(ID *owner, Key *key)
virtual void build_object_parent(Object *object)
virtual void build_simulation(Simulation *simulation)
virtual void build_materials(Material **materials, int num_materials)
virtual void build_object_data_speaker(Object *object)
Relation * add_operation_relation(OperationNode *node_from, OperationNode *node_to, const char *description, int flags=0)
virtual void build_object_data(Object *object)
virtual void build_idproperties(IDProperty *id_property)
virtual void build_cachefile(CacheFile *cache_file)
DepsNodeHandle create_node_handle(const KeyType &key, const char *default_name="")
void add_modifier_to_transform_relation(const DepsNodeHandle *handle, const char *description)
virtual void build_animdata_nlastrip_targets(ID *id, ComponentKey &adt_key, OperationNode *operation_from, ListBase *strips)
Relation * add_time_relation(TimeSourceNode *timesrc, Node *node_to, const char *description, int flags=0)
virtual void build_particle_systems(Object *object)
Node * find_node(const PointerRNA *ptr, const PropertyRNA *prop, RNAPointerSource source)
OperationNode * node
Depsgraph * graph
#define DEG_DEBUG_PRINTF(depsgraph, type,...)
Definition: deg_debug.h:51
const IDNode * id_node
Scene scene
Curve curve
FreestyleLineStyle linestyle
World world
Material material
Simulation simulation
Light lamp
void * user_data
depth_tx normal_tx diffuse_light_tx specular_light_tx volume_light_tx environment_tx ambient_occlusion_tx aov_value_tx in_weight_img image(1, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D_ARRAY, "out_weight_img") .image(3
bNodeTree * ntree
smooth(Type::VEC4, "color_mul") .smooth(Type gpFillTexture gpSceneDepthTexture materials[GPENCIL_MATERIAL_BUFFER_LEN]
Definition: gpencil_info.hh:29
#define GS(x)
Definition: iris.c:225
void SEQ_for_each_callback(ListBase *seqbase, SeqForEachFunc callback, void *user_data)
Definition: iterator.c:76
const int state
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
Definition: math_float4.h:513
NodeType geometry_tag_to_component(const ID *id)
@ RELATION_FLAG_FLUSH_USER_EDIT_ONLY
static bool seq_build_prop_cb(Sequence *seq, void *user_data)
bool rna_prop_affects_parameters_node(const PointerRNA *ptr, const PropertyRNA *prop)
ListBase * build_collision_relations(Depsgraph *graph, Collection *collection, unsigned int modifier_type)
struct Seq_build_prop_cb_data { DepsgraphRelationBuilder *builder Seq_build_prop_cb_data
static void build_idproperties_callback(IDProperty *id_property, void *user_data)
bool deg_copy_on_write_is_needed(const ID *id_orig)
static bool rigidbody_object_depends_on_evaluated_geometry(const RigidBodyOb *rbo)
ListBase * build_effector_relations(Depsgraph *graph, Collection *collection)
ComponentKey sequencer_key
const char * operationCodeAsString(OperationCode opcode)
bool RNA_struct_is_a(const StructRNA *type, const StructRNA *srna)
Definition: rna_access.c:695
void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
Definition: rna_access.c:112
const char * RNA_property_identifier(const PropertyRNA *prop)
Definition: rna_access.c:1000
bool RNA_pointer_is_null(const PointerRNA *ptr)
Definition: rna_access.c:164
bool RNA_path_resolve_full(const PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index)
Definition: rna_path.cc:515
unsigned int uint32_t
Definition: stdint.h:80
bAction * action
ListBase drivers
ListBase nla_tracks
struct ListBase states
char name[64]
ListBase variables
struct Collection * group
struct ClothCollSettings * coll_parms
struct Object * bevobj
struct Object * textoncurve
struct Object * taperobj
struct Object * surface
char num_targets
DriverTarget targets[8]
ListBase seqbase
struct Collection * group
char * rna_path
ChannelDriver * driver
int array_index
struct bNodeTree * nodetree
void(* updateDepsgraph)(struct GpencilModifierData *md, const struct ModifierUpdateDepsgraphContext *ctx, int mode)
void * pointer
Definition: DNA_ID.h:100
IDPropertyData data
Definition: DNA_ID.h:117
char type
Definition: DNA_ID.h:108
Definition: DNA_ID.h:368
IDProperty * properties
Definition: DNA_ID.h:409
char name[66]
Definition: DNA_ID.h:378
ID id
Definition: DNA_key_types.h:63
struct AnimData * adt
Definition: DNA_key_types.h:65
ListBase block
Definition: DNA_key_types.h:84
struct bNodeTree * nodetree
void * first
Definition: DNA_listBase.h:31
short texco
struct Object * object
struct Tex * tex
Definition: BKE_main.h:121
struct bNodeTree * nodetree
struct MaterialGPencilStyle * gp_style
void(* updateDepsgraph)(struct ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
Definition: BKE_modifier.h:298
struct DepsNodeHandle * node
Definition: BKE_modifier.h:134
short partype
ListBase particlesystem
short transflag
ListBase constraints
struct Collection * instance_collection
struct bPose * pose
ListBase modifiers
struct RigidBodyOb * rigidbody_object
ListBase greasepencil_modifiers
struct Material ** mat
struct PartDeflect * pd
ListBase shader_fx
struct Object * parent
void * data
char parsubstr[64]
struct Collection * collision_group
struct Collection * instance_collection
struct BoidSettings * boids
struct EffectorWeights * effector_weights
struct MTex * mtex[18]
struct Object * instance_object
struct ListBase targets
ParticleSettings * part
struct ClothModifierData * clmd
struct StructRNA * type
Definition: RNA_types.h:37
void * data
Definition: RNA_types.h:38
struct ID * owner_id
Definition: RNA_types.h:36
struct Collection * group
struct EffectorWeights * effector_weights
struct RigidBodyWorld * rigidbody_world
struct Editing * ed
struct Object * camera
struct AudioData audio
struct Scene * scene
struct bSound * sound
struct IDProperty * prop
void(* updateDepsgraph)(struct ShaderFxData *fx, const struct ModifierUpdateDepsgraphContext *ctx)
struct bNodeTree * nodetree
struct bSound * sound
short type
struct bNodeTree * nodetree
struct Image * ima
ListBase object_bases
char is_sequence
struct bNodeTree * nodetree
ListBase curves
ListBase bonebase
ListBase layers
struct Material ** mat
IDProperty * prop
void * default_value
bNodeTreeRuntimeHandle * runtime
ListBase nodes
ListBase inputs
ListBase outputs
OperationNode * find_operation(OperationIDKey key) const
static DEGCustomDataMeshMasks MaskVert(const uint64_t vert_mask)
static DEGCustomDataMeshMasks MaskFace(const uint64_t face_mask)
static DEGCustomDataMeshMasks MaskLoop(const uint64_t loop_mask)
static DEGCustomDataMeshMasks MaskEdge(const uint64_t edge_mask)
static DEGCustomDataMeshMasks MaskPoly(const uint64_t poly_mask)
IDNode * find_id_node(const ID *id) const
Definition: depsgraph.cc:101
eEvaluationMode mode
Definition: depsgraph.h:130
Relation * add_new_relation(Node *from, Node *to, const char *description, int flags=0)
Definition: depsgraph.cc:171
TimeSourceNode * time_source
Definition: depsgraph.h:89
IDDepsNodes id_nodes
Definition: depsgraph.h:86
virtual OperationNode * get_exit_operation()
Definition: deg_node.h:202
virtual string identifier() const
Definition: deg_node.cc:295
virtual OperationNode * get_entry_operation()
Definition: deg_node.h:198
virtual string identifier() const override
virtual OperationNode * get_entry_operation() override
PointerRNA * ptr
Definition: wm_files.c:3480