Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/depsgraph/intern/builder/deg_builder_relations.cc')
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc386
1 files changed, 309 insertions, 77 deletions
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index c30d3fecdd5..8afb23f08fa 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -61,6 +61,7 @@ extern "C" {
#include "DNA_movieclip_types.h"
#include "DNA_node_types.h"
#include "DNA_particle_types.h"
+#include "DNA_lightprobe_types.h"
#include "DNA_object_types.h"
#include "DNA_rigidbody_types.h"
#include "DNA_scene_types.h"
@@ -127,7 +128,7 @@ void modifier_walk(void *user_data,
{
BuilderWalkUserData *data = (BuilderWalkUserData *)user_data;
if (*obpoin) {
- data->builder->build_object(*obpoin);
+ data->builder->build_object(NULL, *obpoin);
}
}
@@ -140,7 +141,7 @@ void constraint_walk(bConstraint * /*con*/,
if (*idpoin) {
ID *id = *idpoin;
if (GS(id->name) == ID_OB) {
- data->builder->build_object((Object *)id);
+ data->builder->build_object(NULL, (Object *)id);
}
}
}
@@ -312,19 +313,16 @@ void DepsgraphRelationBuilder::add_collision_relations(
Scene *scene,
Object *object,
Group *group,
- int layer,
bool dupli,
const char *name)
{
unsigned int numcollobj;
- Object **collobjs = get_collisionobjects_ext(
- scene,
- object,
- group,
- layer,
- &numcollobj,
- eModifierType_Collision,
- dupli);
+ Object **collobjs = get_collisionobjects_ext(scene,
+ object,
+ group,
+ &numcollobj,
+ eModifierType_Collision,
+ dupli);
for (unsigned int i = 0; i < numcollobj; i++) {
Object *ob1 = collobjs[i];
@@ -348,9 +346,9 @@ void DepsgraphRelationBuilder::add_forcefield_relations(
bool add_absorption,
const char *name)
{
- ListBase *effectors = pdInitEffectors(scene, object, psys, eff, false);
+ ListBase *effectors = pdInitEffectors(NULL, scene, object, psys, eff, false);
if (effectors != NULL) {
- BLI_LISTBASE_FOREACH(EffectorCache *, eff, effectors) {
+ BLI_LISTBASE_FOREACH (EffectorCache *, eff, effectors) {
if (eff->ob != object) {
ComponentKey eff_key(&eff->ob->id, DEG_NODE_TYPE_TRANSFORM);
add_relation(eff_key, key, name);
@@ -388,7 +386,6 @@ void DepsgraphRelationBuilder::add_forcefield_relations(
scene,
object,
NULL,
- eff->ob->lay,
true,
"Force Absorption");
}
@@ -420,7 +417,7 @@ void DepsgraphRelationBuilder::begin_build()
nodetree->id.tag &= ~LIB_TAG_DOIT;
}
}
- FOREACH_NODETREE_END;
+ FOREACH_NODETREE_END
}
void DepsgraphRelationBuilder::build_group(Object *object, Group *group)
@@ -430,21 +427,26 @@ void DepsgraphRelationBuilder::build_group(Object *object, Group *group)
OperationKey object_local_transform_key(object != NULL ? &object->id : NULL,
DEG_NODE_TYPE_TRANSFORM,
DEG_OPCODE_TRANSFORM_LOCAL);
- BLI_LISTBASE_FOREACH (GroupObject *, go, &group->gobject) {
- if (!group_done) {
- build_object(go->ob);
+ if (!group_done) {
+ BLI_LISTBASE_FOREACH (Base *, base, &group->view_layer->object_bases) {
+ build_object(NULL, base->object);
}
- if (object != NULL) {
- ComponentKey dupli_transform_key(&go->ob->id, DEG_NODE_TYPE_TRANSFORM);
+ group_id->tag |= LIB_TAG_DOIT;
+ }
+ if (object != NULL) {
+ BLI_LISTBASE_FOREACH (Base *, base, &group->view_layer->object_bases) {
+ ComponentKey dupli_transform_key(&base->object->id, DEG_NODE_TYPE_TRANSFORM);
add_relation(dupli_transform_key, object_local_transform_key, "Dupligroup");
}
}
- group_id->tag |= LIB_TAG_DOIT;
}
-void DepsgraphRelationBuilder::build_object(Object *object)
+void DepsgraphRelationBuilder::build_object(Base *base, Object *object)
{
if (object->id.tag & LIB_TAG_DOIT) {
+ if (base != NULL) {
+ build_object_flags(base, object);
+ }
return;
}
object->id.tag |= LIB_TAG_DOIT;
@@ -464,6 +466,8 @@ void DepsgraphRelationBuilder::build_object(Object *object)
OperationKey ob_ubereval_key(&object->id,
DEG_NODE_TYPE_TRANSFORM,
DEG_OPCODE_TRANSFORM_OBJECT_UBEREVAL);
+ /* Various flags, flushing from bases/collections. */
+ build_object_flags(base, object);
/* Parenting. */
if (object->parent != NULL) {
/* Parent relationship. */
@@ -531,7 +535,7 @@ void DepsgraphRelationBuilder::build_object(Object *object)
/* Object that this is a proxy for. */
if (object->proxy != NULL) {
object->proxy->proxy_from = object;
- build_object(object->proxy);
+ build_object(NULL, object->proxy);
/* TODO(sergey): This is an inverted relation, matches old depsgraph
* behavior and need to be investigated if it still need to be inverted.
*/
@@ -545,6 +549,20 @@ void DepsgraphRelationBuilder::build_object(Object *object)
}
}
+void DepsgraphRelationBuilder::build_object_flags(Base *base, Object *object)
+{
+ if (base == NULL) {
+ return;
+ }
+ OperationKey view_layer_done_key(&scene_->id,
+ DEG_NODE_TYPE_LAYER_COLLECTIONS,
+ DEG_OPCODE_VIEW_LAYER_DONE);
+ OperationKey object_flags_key(&object->id,
+ DEG_NODE_TYPE_LAYER_COLLECTIONS,
+ DEG_OPCODE_OBJECT_BASE_FLAGS);
+ add_relation(view_layer_done_key, object_flags_key, "Base flags flush");
+}
+
void DepsgraphRelationBuilder::build_object_data(Object *object)
{
if (object->data == NULL) {
@@ -579,6 +597,9 @@ void DepsgraphRelationBuilder::build_object_data(Object *object)
case OB_CAMERA:
build_camera(object);
break;
+ case OB_LIGHTPROBE:
+ build_lightprobe(object);
+ break;
}
Key *key = BKE_key_from_object(object);
if (key != NULL) {
@@ -976,6 +997,18 @@ void DepsgraphRelationBuilder::build_animdata_curves_targets(
graph_->add_new_relation(operation_from, operation_to,
"Animation -> Prop",
true);
+ /* It is possible that animation is writing to a nested ID datablock,
+ * need to make sure animation is evaluated after target ID is copied.
+ */
+ if (DEG_depsgraph_use_copy_on_write()) {
+ const IDDepsNode *id_node_from = operation_from->owner->owner;
+ const IDDepsNode *id_node_to = operation_to->owner->owner;
+ if (id_node_from != id_node_to) {
+ ComponentKey cow_key(id_node_to->id_orig,
+ DEG_NODE_TYPE_COPY_ON_WRITE);
+ add_relation(cow_key, adt_key, "Target CoW -> Animation", true);
+ }
+ }
}
}
@@ -1014,7 +1047,6 @@ void DepsgraphRelationBuilder::build_animdata_drivers(ID *id)
/* create the driver's relations to targets */
build_driver(id, fcu);
-
/* Special case for array drivers: we can not multithread them because
* of the way how they work internally: animation system will write the
* whole array back to RNA even when changing individual array value.
@@ -1109,18 +1141,18 @@ void DepsgraphRelationBuilder::build_driver_data(ID *id, FCurve *fcu)
*/
IDDepsNode *arm_node = graph_->find_id_node(id);
char *bone_name = BLI_str_quoted_substrN(rna_path, "bones[");
- if (arm_node && bone_name) {
+ if (arm_node != NULL && bone_name != NULL) {
/* Find objects which use this, and make their eval callbacks
* depend on this.
*/
foreach (DepsRelation *rel, arm_node->outlinks) {
IDDepsNode *to_node = (IDDepsNode *)rel->to;
/* We only care about objects with pose data which use this. */
- if (GS(to_node->id->name) == ID_OB) {
- Object *object = (Object *)to_node->id;
- /* NOTE: object->pose may be NULL. */
- bPoseChannel *pchan = BKE_pose_channel_find_name(
- object->pose, bone_name);
+ if (GS(to_node->id_orig->name) == ID_OB) {
+ Object *object = (Object *)to_node->id_orig;
+ // NOTE: object->pose may be NULL
+ bPoseChannel *pchan = BKE_pose_channel_find_name(object->pose,
+ bone_name);
if (pchan != NULL) {
OperationKey bone_key(&object->id,
DEG_NODE_TYPE_BONE,
@@ -1145,6 +1177,25 @@ void DepsgraphRelationBuilder::build_driver_data(ID *id, FCurve *fcu)
else {
RNAPathKey target_key(id, rna_path);
add_relation(driver_key, target_key, "Driver -> Target");
+ /* Similar to the case with f-curves, driver might drive a nested
+ * datablock, which means driver execution should wait for that
+ * datablock to be copied.
+ */
+ if (DEG_depsgraph_use_copy_on_write()) {
+ PointerRNA id_ptr;
+ PointerRNA ptr;
+ RNA_id_pointer_create(id, &id_ptr);
+ if (RNA_path_resolve_full(&id_ptr, fcu->rna_path, &ptr, NULL, NULL)) {
+ if (id_ptr.id.data != ptr.id.data) {
+ ComponentKey cow_key((ID *)ptr.id.data,
+ DEG_NODE_TYPE_COPY_ON_WRITE);
+ add_relation(cow_key,
+ driver_key,
+ "Target CoW -> Driver",
+ true);
+ }
+ }
+ }
}
}
@@ -1250,9 +1301,9 @@ void DepsgraphRelationBuilder::build_world(World *world)
/* world's nodetree */
if (world->nodetree != NULL) {
build_nodetree(world->nodetree);
- ComponentKey ntree_key(&world->nodetree->id, DEG_NODE_TYPE_PARAMETERS);
- ComponentKey world_key(world_id, DEG_NODE_TYPE_PARAMETERS);
- add_relation(ntree_key, world_key, "NTree->World Parameters");
+ ComponentKey ntree_key(&world->nodetree->id, DEG_NODE_TYPE_SHADING);
+ ComponentKey world_key(world_id, DEG_NODE_TYPE_SHADING);
+ add_relation(ntree_key, world_key, "NTree->World Shading Update");
}
}
@@ -1274,8 +1325,8 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene)
/* objects - simulation participants */
if (rbw->group) {
- BLI_LISTBASE_FOREACH (GroupObject *, go, &rbw->group->gobject) {
- Object *object = go->ob;
+ BLI_LISTBASE_FOREACH (Base *, base, &rbw->group->view_layer->object_bases) {
+ Object *object = base->object;
if (object == NULL || object->type != OB_MESH) {
continue;
}
@@ -1328,8 +1379,8 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene)
/* constraints */
if (rbw->constraints) {
- BLI_LISTBASE_FOREACH (GroupObject *, go, &rbw->constraints->gobject) {
- Object *object = go->ob;
+ BLI_LISTBASE_FOREACH (Base *, base, &rbw->constraints->view_layer->object_bases) {
+ Object *object = base->object;
if (object == NULL || !object->rigidbody_constraint) {
continue;
}
@@ -1366,13 +1417,36 @@ void DepsgraphRelationBuilder::build_particles(Object *object)
/* Particle systems. */
BLI_LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) {
ParticleSettings *part = psys->part;
- /* Animation of particle settings, */
- build_animdata(&part->id);
+
+ /* Build particle settings relations.
+ *
+ * NOTE: The call itself ensures settings are only build once.
+ */
+ build_particle_settings(part);
+
/* This particle system. */
OperationKey psys_key(&object->id,
DEG_NODE_TYPE_EVAL_PARTICLES,
DEG_OPCODE_PARTICLE_SYSTEM_EVAL,
psys->name);
+
+ /* Update particle system when settings changes. */
+ OperationKey particle_settings_key(&part->id,
+ DEG_NODE_TYPE_PARAMETERS,
+ DEG_OPCODE_PARTICLE_SETTINGS_EVAL);
+ OperationKey particle_settings_recalc_clear_key(
+ &part->id,
+ DEG_NODE_TYPE_PARAMETERS,
+ DEG_OPCODE_PARTICLE_SETTINGS_RECALC_CLEAR);
+ OperationKey psys_settings_key(&object->id,
+ DEG_NODE_TYPE_EVAL_PARTICLES,
+ DEG_OPCODE_PARTICLE_SETTINGS_EVAL,
+ psys->name);
+ add_relation(particle_settings_key, psys_settings_key, "Particle Settings Change");
+ add_relation(psys_settings_key, psys_key, "Particle Settings Update");
+ add_relation(psys_key,
+ particle_settings_recalc_clear_key,
+ "Particle Settings Recalc Clear");
add_relation(eval_init_key, psys_key, "Init -> PSys");
/* TODO(sergey): Currently particle update is just a placeholder,
* hook it to the ubereval node so particle system is getting updated
@@ -1385,18 +1459,17 @@ void DepsgraphRelationBuilder::build_particles(Object *object)
scene_,
object,
part->collision_group,
- object->lay,
true,
"Particle Collision");
}
else if ((psys->flag & PSYS_HAIR_DYNAMICS) &&
- psys->clmd && psys->clmd->coll_parms)
+ psys->clmd != NULL &&
+ psys->clmd->coll_parms != NULL)
{
add_collision_relations(psys_key,
scene_,
object,
psys->clmd->coll_parms->group,
- object->lay | scene_->lay,
true,
"Hair Collision");
}
@@ -1408,7 +1481,7 @@ void DepsgraphRelationBuilder::build_particles(Object *object)
part->effector_weights,
part->type == PART_HAIR,
"Particle Field");
- /* Boids. */
+ /* Boids .*/
if (part->boids) {
BLI_LISTBASE_FOREACH (BoidState *, state, &part->boids->states) {
BLI_LISTBASE_FOREACH (BoidRule *, rule, &state->rules) {
@@ -1427,12 +1500,11 @@ void DepsgraphRelationBuilder::build_particles(Object *object)
}
}
}
-
switch (part->ren_as) {
case PART_DRAW_OB:
if (part->dup_ob != NULL) {
/* Make sure object's relations are all built. */
- build_object(part->dup_ob);
+ build_object(NULL, part->dup_ob);
/* Build relation for the particle visualization. */
build_particles_visualization_object(object,
psys,
@@ -1461,8 +1533,27 @@ void DepsgraphRelationBuilder::build_particles(Object *object)
ComponentKey transform_key(&object->id, DEG_NODE_TYPE_TRANSFORM);
add_relation(transform_key, obdata_ubereval_key, "Partcile Eval");
- /* pointcache */
- // TODO...
+ /* TODO(sergey): Do we need a point cache operations here? */
+}
+
+void DepsgraphRelationBuilder::build_particle_settings(ParticleSettings *part)
+{
+ ID *part_id = &part->id;
+ if (part_id->tag & LIB_TAG_DOIT) {
+ return;
+ }
+ part_id->tag |= LIB_TAG_DOIT;
+
+ /* Animation data relations. */
+ build_animdata(&part->id);
+
+ OperationKey eval_key(part_id,
+ DEG_NODE_TYPE_PARAMETERS,
+ DEG_OPCODE_PARTICLE_SETTINGS_EVAL);
+ OperationKey recalc_clear_key(part_id,
+ DEG_NODE_TYPE_PARAMETERS,
+ DEG_OPCODE_PARTICLE_SETTINGS_RECALC_CLEAR);
+ add_relation(eval_key, recalc_clear_key, "Particle Settings Clear Recalc");
}
void DepsgraphRelationBuilder::build_particles_visualization_object(
@@ -1558,12 +1649,22 @@ void DepsgraphRelationBuilder::build_obdata_geom(Object *object)
/* link components to each other */
add_relation(obdata_geom_key, geom_key, "Object Geometry Base Data");
+ OperationKey obdata_ubereval_key(&object->id,
+ DEG_NODE_TYPE_GEOMETRY,
+ DEG_OPCODE_GEOMETRY_UBEREVAL);
+
+ /* Special case: modifiers and DerivedMesh creation queries scene for various
+ * things like data mask to be used. We add relation here to ensure object is
+ * never evaluated prior to Scene's CoW is ready.
+ */
+ OperationKey scene_key(&scene_->id,
+ DEG_NODE_TYPE_PARAMETERS,
+ DEG_OPCODE_PLACEHOLDER,
+ "Scene Eval");
+ add_relation(scene_key, obdata_ubereval_key, "CoW Relation");
+
/* Modifiers */
if (object->modifiers.first != NULL) {
- OperationKey obdata_ubereval_key(&object->id,
- DEG_NODE_TYPE_GEOMETRY,
- DEG_OPCODE_GEOMETRY_UBEREVAL);
-
BLI_LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
const ModifierTypeInfo *mti = modifierType_getInfo((ModifierType)md->type);
if (mti->updateDepsgraph) {
@@ -1591,6 +1692,14 @@ void DepsgraphRelationBuilder::build_obdata_geom(Object *object)
Material *ma = give_current_material(object, a);
if (ma != NULL) {
build_material(ma);
+
+ if (object->type == OB_MESH) {
+ OperationKey material_key(&ma->id,
+ DEG_NODE_TYPE_SHADING,
+ DEG_OPCODE_MATERIAL_UPDATE);
+ OperationKey shading_key(&object->id, DEG_NODE_TYPE_SHADING, DEG_OPCODE_SHADING);
+ add_relation(material_key, shading_key, "Material Update");
+ }
}
}
}
@@ -1669,18 +1778,18 @@ void DepsgraphRelationBuilder::build_obdata_geom(Object *object)
// XXX: these needs geom data, but where is geom stored?
if (cu->bevobj) {
ComponentKey bevob_key(&cu->bevobj->id, DEG_NODE_TYPE_GEOMETRY);
- build_object(cu->bevobj);
+ build_object(NULL, cu->bevobj);
add_relation(bevob_key, geom_key, "Curve Bevel");
}
if (cu->taperobj) {
ComponentKey taperob_key(&cu->taperobj->id, DEG_NODE_TYPE_GEOMETRY);
- build_object(cu->taperobj);
+ build_object(NULL, cu->taperobj);
add_relation(taperob_key, geom_key, "Curve Taper");
}
if (object->type == OB_FONT) {
if (cu->textoncurve) {
ComponentKey textoncurve_key(&cu->textoncurve->id, DEG_NODE_TYPE_GEOMETRY);
- build_object(cu->textoncurve);
+ build_object(NULL, cu->textoncurve);
add_relation(textoncurve_key, geom_key, "Text on Curve");
}
}
@@ -1715,11 +1824,17 @@ void DepsgraphRelationBuilder::build_camera(Object *object)
return;
}
camera_id->tag |= LIB_TAG_DOIT;
+
+ ComponentKey object_parameters_key(&object->id, DEG_NODE_TYPE_PARAMETERS);
+ ComponentKey camera_parameters_key(camera_id, DEG_NODE_TYPE_PARAMETERS);
+
+ add_relation(camera_parameters_key, object_parameters_key,
+ "Camera -> Object");
+
/* DOF */
- if (cam->dof_ob) {
- ComponentKey ob_param_key(&object->id, DEG_NODE_TYPE_PARAMETERS);
+ if (cam->dof_ob != NULL) {
ComponentKey dof_ob_key(&cam->dof_ob->id, DEG_NODE_TYPE_TRANSFORM);
- add_relation(dof_ob_key, ob_param_key, "Camera DOF");
+ add_relation(dof_ob_key, object_parameters_key, "Camera DOF");
}
}
@@ -1732,30 +1847,44 @@ void DepsgraphRelationBuilder::build_lamp(Object *object)
return;
}
lamp_id->tag |= LIB_TAG_DOIT;
+
+ ComponentKey object_parameters_key(&object->id, DEG_NODE_TYPE_PARAMETERS);
+ ComponentKey lamp_parameters_key(lamp_id, DEG_NODE_TYPE_PARAMETERS);
+
+ add_relation(lamp_parameters_key, object_parameters_key,
+ "Lamp -> Object");
+
/* lamp's nodetree */
if (la->nodetree != NULL) {
build_nodetree(la->nodetree);
- ComponentKey parameters_key(lamp_id, DEG_NODE_TYPE_PARAMETERS);
- ComponentKey nodetree_key(&la->nodetree->id, DEG_NODE_TYPE_PARAMETERS);
- add_relation(nodetree_key, parameters_key, "NTree->Lamp Parameters");
+ ComponentKey nodetree_key(&la->nodetree->id, DEG_NODE_TYPE_SHADING);
+ add_relation(nodetree_key, lamp_parameters_key, "NTree->Lamp Parameters");
}
/* textures */
build_texture_stack(la->mtex);
+
+ if (DEG_depsgraph_use_copy_on_write()) {
+ /* Make sure copy on write of lamp data is always properly updated for
+ * visible lamps.
+ */
+ OperationKey ob_copy_on_write_key(&object->id,
+ DEG_NODE_TYPE_COPY_ON_WRITE,
+ DEG_OPCODE_COPY_ON_WRITE);
+ OperationKey lamp_copy_on_write_key(lamp_id,
+ DEG_NODE_TYPE_COPY_ON_WRITE,
+ DEG_OPCODE_COPY_ON_WRITE);
+ add_relation(lamp_copy_on_write_key, ob_copy_on_write_key, "Eval Order");
+ }
}
void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree)
{
- if (!ntree)
+ if (ntree == NULL) {
return;
-
+ }
ID *ntree_id = &ntree->id;
-
build_animdata(ntree_id);
-
- OperationKey parameters_key(ntree_id,
- DEG_NODE_TYPE_PARAMETERS,
- DEG_OPCODE_PARAMETERS_EVAL);
-
+ ComponentKey shading_key(ntree_id, DEG_NODE_TYPE_SHADING);
/* nodetree's nodes... */
BLI_LISTBASE_FOREACH (bNode *, bnode, &ntree->nodes) {
ID *id = bnode->id;
@@ -1773,7 +1902,7 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree)
/* nothing for now. */
}
else if (id_type == ID_OB) {
- build_object((Object *)id);
+ build_object(NULL, (Object *)id);
}
else if (id_type == ID_SCE) {
/* Scenes are used by compositor trees, and handled by render
@@ -1789,15 +1918,22 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree)
build_nodetree(group_ntree);
group_ntree->id.tag |= LIB_TAG_DOIT;
}
- OperationKey group_parameters_key(&group_ntree->id,
- DEG_NODE_TYPE_PARAMETERS,
- DEG_OPCODE_PARAMETERS_EVAL);
- add_relation(group_parameters_key, parameters_key, "Group Node");
+ ComponentKey group_shading_key(&group_ntree->id,
+ DEG_NODE_TYPE_SHADING);
+ add_relation(group_shading_key, shading_key, "Group Node");
}
else {
BLI_assert(!"Unknown ID type used for node");
}
}
+
+ OperationKey shading_update_key(ntree_id,
+ DEG_NODE_TYPE_SHADING,
+ DEG_OPCODE_MATERIAL_UPDATE);
+ OperationKey shading_parameters_key(ntree_id,
+ DEG_NODE_TYPE_SHADING_PARAMETERS,
+ DEG_OPCODE_MATERIAL_UPDATE);
+ add_relation(shading_parameters_key, shading_update_key, "NTree Shading Parameters");
}
/* Recursively build graph for material */
@@ -1819,12 +1955,11 @@ void DepsgraphRelationBuilder::build_material(Material *ma)
if (ma->nodetree != NULL) {
build_nodetree(ma->nodetree);
OperationKey ntree_key(&ma->nodetree->id,
- DEG_NODE_TYPE_PARAMETERS,
- DEG_OPCODE_PARAMETERS_EVAL);
+ DEG_NODE_TYPE_SHADING,
+ DEG_OPCODE_MATERIAL_UPDATE);
OperationKey material_key(&ma->id,
DEG_NODE_TYPE_SHADING,
- DEG_OPCODE_PLACEHOLDER,
- "Material Update");
+ DEG_OPCODE_MATERIAL_UPDATE);
add_relation(ntree_key, material_key, "Material's NTree");
}
}
@@ -1900,4 +2035,101 @@ void DepsgraphRelationBuilder::build_movieclip(MovieClip *clip)
build_animdata(&clip->id);
}
+void DepsgraphRelationBuilder::build_lightprobe(Object *object)
+{
+ LightProbe *probe = (LightProbe *)object->data;
+ ID *probe_id = &probe->id;
+ if (probe_id->tag & LIB_TAG_DOIT) {
+ return;
+ }
+ probe_id->tag |= LIB_TAG_DOIT;
+ build_animdata(&probe->id);
+
+ OperationKey probe_key(probe_id,
+ DEG_NODE_TYPE_PARAMETERS,
+ DEG_OPCODE_PLACEHOLDER,
+ "LightProbe Eval");
+ OperationKey object_key(&object->id,
+ DEG_NODE_TYPE_PARAMETERS,
+ DEG_OPCODE_PLACEHOLDER,
+ "LightProbe Eval");
+ add_relation(probe_key, object_key, "LightProbe Update");
+}
+
+void DepsgraphRelationBuilder::build_copy_on_write_relations()
+{
+ foreach (IDDepsNode *id_node, graph_->id_nodes) {
+ build_copy_on_write_relations(id_node);
+ }
+}
+
+void DepsgraphRelationBuilder::build_copy_on_write_relations(IDDepsNode *id_node)
+{
+ ID *id_orig = id_node->id_orig;
+
+ TimeSourceKey time_source_key;
+ OperationKey copy_on_write_key(id_orig,
+ DEG_NODE_TYPE_COPY_ON_WRITE,
+ DEG_OPCODE_COPY_ON_WRITE);
+ /* XXX: This is a quick hack to make Alt-A to work. */
+ // add_relation(time_source_key, copy_on_write_key, "Fluxgate capacitor hack");
+ /* Resat of code is using rather low level trickery, so need to get some
+ * explicit pointers.
+ */
+ DepsNode *node_cow = find_node(copy_on_write_key);
+ OperationDepsNode *op_cow = node_cow->get_exit_operation();
+ /* Plug any other components to this one. */
+ GHASH_FOREACH_BEGIN(ComponentDepsNode *, comp_node, id_node->components)
+ {
+ if (comp_node->type == DEG_NODE_TYPE_COPY_ON_WRITE) {
+ /* Copy-on-write component never depends on itself. */
+ continue;
+ }
+ if (!comp_node->depends_on_cow()) {
+ /* Component explicitly requests to not add relation. */
+ continue;
+ }
+ /* All entry operations of each component should wait for a proper
+ * copy of ID.
+ */
+ OperationDepsNode *op_entry = comp_node->get_entry_operation();
+ if (op_entry != NULL) {
+ graph_->add_new_relation(op_cow, op_entry, "CoW Dependency");
+ }
+ /* All dangling operations should also be executed after copy-on-write. */
+ GHASH_FOREACH_BEGIN(OperationDepsNode *, op_node, comp_node->operations_map)
+ {
+ if (op_node->inlinks.size() == 0) {
+ graph_->add_new_relation(op_cow, op_node, "CoW Dependency");
+ }
+ }
+ GHASH_FOREACH_END();
+ /* NOTE: We currently ignore implicit relations to an external
+ * datablocks for copy-on-write operations. This means, for example,
+ * copy-on-write component of Object will not wait for copy-on-write
+ * component of it's Mesh. This is because pointers are all known
+ * already so remapping will happen all correct. And then If some object
+ * evaluation step needs geometry, it will have transitive dependency
+ * to Mesh copy-on-write already.
+ */
+ }
+ GHASH_FOREACH_END();
+ /* TODO(sergey): This solves crash for now, but causes too many
+ * updates potentially.
+ */
+ if (GS(id_orig->name) == ID_OB) {
+ Object *object = (Object *)id_orig;
+ ID *object_data_id = (ID *)object->data;
+ if (object_data_id != NULL) {
+ OperationKey data_copy_on_write_key(object_data_id,
+ DEG_NODE_TYPE_COPY_ON_WRITE,
+ DEG_OPCODE_COPY_ON_WRITE);
+ add_relation(data_copy_on_write_key, copy_on_write_key, "Eval Order");
+ }
+ else {
+ BLI_assert(object->type == OB_EMPTY);
+ }
+ }
+}
+
} // namespace DEG