From a68e10be5ef1563073aa37db505335dd507358f6 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 4 Dec 2017 16:02:09 +0100 Subject: [PATCH 01/36] Depsgraph: Correct RNA pointer criteria to deal with bone custom properties --- source/blender/depsgraph/intern/depsgraph.cc | 60 ++++++++++++++------ 1 file changed, 44 insertions(+), 16 deletions(-) diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc index cdf59f61d0c..ffdd0004727 100644 --- a/source/blender/depsgraph/intern/depsgraph.cc +++ b/source/blender/depsgraph/intern/depsgraph.cc @@ -107,25 +107,39 @@ static bool pointer_to_id_node_criteria(const PointerRNA *ptr, return false; } -static bool pointer_to_component_node_criteria(const PointerRNA *ptr, - const PropertyRNA *prop, - ID **id, - eDepsNode_Type *type, - const char **subdata) +static bool pointer_to_component_node_criteria( + const PointerRNA *ptr, + const PropertyRNA *prop, + ID **id, + eDepsNode_Type *type, + const char **subdata, + eDepsOperation_Code *operation_code, + const char **operation_name, + int *operation_name_tag) { if (ptr->type == NULL) { return false; } /* Set default values for returns. */ - *id = (ID *)ptr->id.data; /* For obvious reasons... */ - *subdata = ""; /* Default to no subdata (e.g. bone) name - * lookup in most cases. */ + *id = (ID *)ptr->id.data; + *subdata = ""; + *operation_code = DEG_OPCODE_OPERATION; + *operation_name = ""; + *operation_name_tag = -1; /* Handling of commonly known scenarios. */ if (ptr->type == &RNA_PoseBone) { bPoseChannel *pchan = (bPoseChannel *)ptr->data; - /* Bone - generally, we just want the bone component. */ - *type = DEG_NODE_TYPE_BONE; - *subdata = pchan->name; + if (prop != NULL && RNA_property_is_idprop(prop)) { + *type = DEG_NODE_TYPE_PARAMETERS; + *subdata = ""; + *operation_code = DEG_OPCODE_PARAMETERS_EVAL; + *operation_name = pchan->name;; + } + else { + /* Bone - generally, we just want the bone component. */ + *type = DEG_NODE_TYPE_BONE; + *subdata = pchan->name; + } return true; } else if (ptr->type == &RNA_Bone) { @@ -211,18 +225,32 @@ DepsNode *Depsgraph::find_node_from_pointer(const PointerRNA *ptr, const PropertyRNA *prop) const { ID *id; - eDepsNode_Type type; - const char *name; + eDepsNode_Type node_type; + const char *component_name, *operation_name; + eDepsOperation_Code operation_code; + int operation_name_tag; /* Get querying conditions. */ if (pointer_to_id_node_criteria(ptr, prop, &id)) { return find_id_node(id); } - else if (pointer_to_component_node_criteria(ptr, prop, &id, &type, &name)) { + else if (pointer_to_component_node_criteria( + ptr, prop, + &id, &node_type, &component_name, + &operation_code, &operation_name, &operation_name_tag)) + { IDDepsNode *id_node = find_id_node(id); - if (id_node != NULL) { - return id_node->find_component(type, name); + if (id_node == NULL) { + return NULL; } + ComponentDepsNode *comp_node = + id_node->find_component(node_type, component_name); + if (operation_code == DEG_OPCODE_OPERATION) { + return comp_node; + } + return comp_node->find_operation(operation_code, + operation_name, + operation_name_tag); } return NULL; From aed1320b247ecf1d75bc84a99dca40da342fde59 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 4 Dec 2017 16:23:14 +0100 Subject: [PATCH 02/36] Add utility function to compare PointerRNA with NULL Thanks Campbell for review! --- source/blender/makesrna/RNA_access.h | 1 + source/blender/makesrna/intern/rna_access.c | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 7e8c860863d..a975cbbfd7d 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -724,6 +724,7 @@ extern StructRNA RNA_XorController; void RNA_main_pointer_create(struct Main *main, PointerRNA *r_ptr); void RNA_id_pointer_create(struct ID *id, PointerRNA *r_ptr); void RNA_pointer_create(struct ID *id, StructRNA *type, void *data, PointerRNA *r_ptr); +bool RNA_pointer_is_null(const PointerRNA *ptr); bool RNA_path_resolved_create( PointerRNA *ptr, struct PropertyRNA *prop, diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 471db22af8e..1f974f3a440 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -172,6 +172,11 @@ void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr) } } +bool RNA_pointer_is_null(const PointerRNA *ptr) +{ + return !((ptr->data != NULL) && (ptr->id.data != NULL) && (ptr->type != NULL)); +} + static void rna_pointer_inherit_id(StructRNA *type, PointerRNA *parent, PointerRNA *ptr) { if (type && type->flag & STRUCT_ID) { From 0cd2303e676ec9f5f45be98083a734924e5f8c0f Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 4 Dec 2017 16:27:32 +0100 Subject: [PATCH 03/36] Depsgraph: Cleanup, don't use static qualifier inside of anonymous namespace --- .../depsgraph/intern/builder/deg_builder_relations.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 275c6847e43..18298218e91 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -119,10 +119,10 @@ struct BuilderWalkUserData { DepsgraphRelationBuilder *builder; }; -static void modifier_walk(void *user_data, - struct Object * /*object*/, - struct Object **obpoin, - int /*cb_flag*/) +void modifier_walk(void *user_data, + struct Object * /*object*/, + struct Object **obpoin, + int /*cb_flag*/) { BuilderWalkUserData *data = (BuilderWalkUserData *)user_data; if (*obpoin) { From 284f106c91679a0c750f5c701e382f265412d58e Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 4 Dec 2017 16:44:07 +0100 Subject: [PATCH 04/36] Depsgraph: begin use of RNAPathKey instead of re-implemented checks in driver variables --- .../intern/builder/deg_builder_relations.cc | 31 ++++------------ .../intern/builder/deg_builder_relations.h | 36 +++++++++++++++++++ 2 files changed, 43 insertions(+), 24 deletions(-) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 18298218e91..f2d1dd43438 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -962,8 +962,8 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) fcu->rna_path ? fcu->rna_path : "", fcu->array_index); bPoseChannel *pchan = NULL; - const char *rna_path = fcu->rna_path ? fcu->rna_path : ""; + const RNAPathKey self_key(id, rna_path); /* Create dependency between driver and data affected by it. */ /* - direct property relationship... */ @@ -1142,31 +1142,14 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) add_relation(target_key, driver_key, "Target -> Driver"); } else if (dtar->rna_path && strstr(dtar->rna_path, "pose.bones[")) { - /* Workaround for ensuring that local bone transforms don't end - * up having to wait for pose eval to finish (to prevent cycles). - */ - Object *object = (Object *)dtar->id; - char *bone_name = BLI_str_quoted_substrN(dtar->rna_path, - "pose.bones["); - bPoseChannel *target_pchan = - BKE_pose_channel_find_name(object->pose, bone_name); - if (bone_name != NULL) { - MEM_freeN(bone_name); - bone_name = NULL; + RNAPathKey variable_key(dtar->id, dtar->rna_path); + if (RNA_pointer_is_null(&variable_key.ptr)) { + continue; } - if (target_pchan != NULL) { - if (dtar->id == id && - pchan != NULL && - STREQ(pchan->name, target_pchan->name)) - { - continue; - } - OperationKey bone_key(dtar->id, - DEG_NODE_TYPE_BONE, - target_pchan->name, - DEG_OPCODE_BONE_LOCAL); - add_relation(bone_key, driver_key, "RNA Bone -> Driver"); + if (is_same_bone_dependency(variable_key, self_key)) { + continue; } + add_relation(variable_key, driver_key, "RNA Bone -> Driver"); } else { if (dtar->id == id) { diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index 68762043e5e..e61cd95cb96 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -31,6 +31,7 @@ #pragma once #include +#include #include "intern/depsgraph_types.h" @@ -43,6 +44,7 @@ #include "BLI_string.h" #include "intern/nodes/deg_node.h" +#include "intern/nodes/deg_node_component.h" #include "intern/nodes/deg_node_operation.h" struct Base; @@ -266,6 +268,9 @@ protected: bool needs_animdata_node(ID *id); + template + bool is_same_bone_dependency(const KeyFrom& key_from, const KeyTo& key_to); + private: /* State which never changes, same for the whole builder time. */ Main *bmain_; @@ -378,4 +383,35 @@ DepsNodeHandle DepsgraphRelationBuilder::create_node_handle( return DepsNodeHandle(this, get_node(key), default_name); } +/* Rig compatibility: we check if bone is using local transform as a variable + * for driver on itself and ignore those relations to avoid "false-positive" + * dependency cycles. + */ +template +bool DepsgraphRelationBuilder::is_same_bone_dependency(const KeyFrom& key_from, + const KeyTo& key_to) +{ + /* Get operations for requested keys. */ + DepsNode *node_from = get_node(key_from); + DepsNode *node_to = get_node(key_to); + if (node_from == NULL || node_to == NULL) { + return false; + } + OperationDepsNode *op_from = node_from->get_exit_operation(); + OperationDepsNode *op_to = node_to->get_entry_operation(); + if (op_from == NULL || op_to == NULL) { + return false; + } + /* We are only interested in relations like BONE_DONE -> BONE_LOCAL... */ + if (!(op_from->opcode == DEG_OPCODE_BONE_DONE && + op_to->opcode == DEG_OPCODE_BONE_LOCAL)) { + return false; + } + /* ... BUT, we also need to check if it's same bone. */ + if (!STREQ(op_from->owner->name, op_to->owner->name)) { + return false; + } + return true; +} + } // namespace DEG From 97e92d6f3ecb5a5b40f97701b72a91392052cbf2 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 4 Dec 2017 16:51:29 +0100 Subject: [PATCH 05/36] Depsgraph: SImplify chjecks in directly address bone --- .../intern/builder/deg_builder_relations.cc | 33 +++++++------------ 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index f2d1dd43438..0d78192a2ef 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -1104,28 +1104,19 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) if ((dtar->flag & DTAR_FLAG_STRUCT_REF) && (dtar->pchan_name[0])) { Object *object = (Object *)dtar->id; bPoseChannel *target_pchan = - BKE_pose_channel_find_name(object->pose, dtar->pchan_name); - if (target_pchan != NULL) { - /* Get node associated with bone. */ - // XXX: watch the space! - /* Some cases can't use final bone transform, for example: - * - Driving the bone with itself (addressed here) - * - Relations inside an IK chain (TODO?) - */ - if (dtar->id == id && - pchan != NULL && - STREQ(pchan->name, target_pchan->name)) - { - continue; - } - OperationKey target_key(dtar->id, - DEG_NODE_TYPE_BONE, - target_pchan->name, - DEG_OPCODE_BONE_DONE); - add_relation(target_key, - driver_key, - "Bone Target -> Driver"); + BKE_pose_channel_find_name(object->pose, + dtar->pchan_name); + if (target_pchan == NULL) { + continue; } + OperationKey variable_key(dtar->id, + DEG_NODE_TYPE_BONE, + target_pchan->name, + DEG_OPCODE_BONE_DONE); + if (is_same_bone_dependency(variable_key, self_key)) { + continue; + } + add_relation(variable_key, driver_key, "Bone Target -> Driver"); } else if (dtar->flag & DTAR_FLAG_STRUCT_REF) { /* Get node associated with the object's transforms. */ From 52e81de9f72d27973587ed7dfe429ce09b9a10db Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 4 Dec 2017 16:58:02 +0100 Subject: [PATCH 06/36] Depsgraph: Don't see reason to have special case for bone's RNA path --- .../blender/depsgraph/intern/builder/deg_builder_relations.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 0d78192a2ef..8161e646564 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -1132,7 +1132,7 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) DEG_OPCODE_TRANSFORM_FINAL); add_relation(target_key, driver_key, "Target -> Driver"); } - else if (dtar->rna_path && strstr(dtar->rna_path, "pose.bones[")) { + else if (dtar->rna_path) { RNAPathKey variable_key(dtar->id, dtar->rna_path); if (RNA_pointer_is_null(&variable_key.ptr)) { continue; From 3795e37c62689c19b2df1d61ac932156e62196d2 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 4 Dec 2017 17:01:02 +0100 Subject: [PATCH 07/36] Depsgraph: Cleanup, split build_driver function up --- .../intern/builder/deg_builder_relations.cc | 34 +++++++++++++------ .../intern/builder/deg_builder_relations.h | 1 + 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 8161e646564..9a106129a7c 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -1093,6 +1093,30 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) * initialised later? */ /* Loop over variables to get the target relationships. */ + build_driver_variables(id, fcu); + /* It's quite tricky to detect if the driver actually depends on time or + * not, so for now we'll be quite conservative here about optimization and + * consider all python drivers to be depending on time. + */ + if ((driver->type == DRIVER_TYPE_PYTHON) && + python_driver_depends_on_time(driver)) + { + TimeSourceKey time_src_key; + add_relation(time_src_key, driver_key, "TimeSrc -> Driver"); + } +} + +void DepsgraphRelationBuilder::build_driver_variables(ID *id, FCurve *fcu) +{ + ChannelDriver *driver = fcu->driver; + OperationKey driver_key(id, + DEG_NODE_TYPE_PARAMETERS, + DEG_OPCODE_DRIVER, + fcu->rna_path ? fcu->rna_path : "", + fcu->array_index); + const char *rna_path = fcu->rna_path ? fcu->rna_path : ""; + const RNAPathKey self_key(id, rna_path); + LINKLIST_FOREACH (DriverVar *, dvar, &driver->variables) { /* Only used targets. */ DRIVER_TARGETS_USED_LOOPER(dvar) @@ -1158,16 +1182,6 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) } DRIVER_TARGETS_LOOPER_END } - /* It's quite tricky to detect if the driver actually depends on time or - * not, so for now we'll be quite conservative here about optimization and - * consider all python drivers to be depending on time. - */ - if ((driver->type == DRIVER_TYPE_PYTHON) && - python_driver_depends_on_time(driver)) - { - TimeSourceKey time_src_key; - add_relation(time_src_key, driver_key, "TimeSrc -> Driver"); - } } void DepsgraphRelationBuilder::build_world(World *world) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index e61cd95cb96..7aadf197c7b 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -198,6 +198,7 @@ struct DepsgraphRelationBuilder RootPChanMap *root_map); void build_animdata(ID *id); void build_driver(ID *id, FCurve *fcurve); + void build_driver_variables(ID *id, FCurve *fcurve); void build_world(World *world); void build_rigidbody(Scene *scene); void build_particles(Object *object); From 7586266343fbedbf30b5f0099558db8c102d323c Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 4 Dec 2017 13:49:13 +0100 Subject: [PATCH 08/36] Depsgraph: Use existing utility function to get driver target node Only done for pose bone for now, but the idea is to go case bu case in build_driver and move all custom logic from there to find_node_from_pointer(). --- .../intern/builder/deg_builder_relations.cc | 30 ++----------------- 1 file changed, 2 insertions(+), 28 deletions(-) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 9a106129a7c..5e821ce49ab 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -961,7 +961,6 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) DEG_OPCODE_DRIVER, fcu->rna_path ? fcu->rna_path : "", fcu->array_index); - bPoseChannel *pchan = NULL; const char *rna_path = fcu->rna_path ? fcu->rna_path : ""; const RNAPathKey self_key(id, rna_path); @@ -975,33 +974,8 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) */ // XXX: this probably should probably be moved out into a separate function. if (strstr(rna_path, "pose.bones[") != NULL) { - /* interleaved drivers during bone eval */ - /* TODO: ideally, if this is for a constraint, it goes to said - * constraint. - */ - Object *object = (Object *)id; - char *bone_name; - - bone_name = BLI_str_quoted_substrN(rna_path, "pose.bones["); - pchan = BKE_pose_channel_find_name(object->pose, bone_name); - - if (bone_name) { - MEM_freeN(bone_name); - bone_name = NULL; - } - - if (pchan) { - OperationKey bone_key(id, - DEG_NODE_TYPE_BONE, - pchan->name, - DEG_OPCODE_BONE_LOCAL); - add_relation(driver_key, bone_key, "Driver -> Bone"); - } - else { - fprintf(stderr, - "Couldn't find bone name for driver path - '%s'\n", - rna_path); - } + RNAPathKey target_key(id, rna_path); + add_relation(driver_key, target_key, "Driver -> Target"); } else if (GS(id->name) == ID_AR && strstr(rna_path, "bones[")) { /* Drivers on armature-level bone settings (i.e. bbone stuff), From 235a68d8f355104c4f4bb30b3c58cf35e7bfc75d Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 4 Dec 2017 13:59:17 +0100 Subject: [PATCH 09/36] Depsgraph: Use generic function for modifiers driver target --- .../depsgraph/intern/builder/deg_builder_relations.cc | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 5e821ce49ab..2755357e11b 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -1018,15 +1018,8 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) } } else if (GS(id->name) == ID_OB && strstr(rna_path, "modifiers[")) { - OperationKey modifier_key(id, - DEG_NODE_TYPE_GEOMETRY, - DEG_OPCODE_GEOMETRY_UBEREVAL); - if (has_node(modifier_key)) { - add_relation(driver_key, modifier_key, "Driver -> Modifier"); - } - else { - printf("Unexisting driver RNA path: %s\n", rna_path); - } + RNAPathKey target_key(id, rna_path); + add_relation(driver_key, target_key, "Driver -> Target"); } else if (GS(id->name) == ID_KE && strstr(rna_path, "key_blocks[")) { /* Shape key driver - hook into the base geometry operation. */ From f8fd8b0744104877a579ab4b603e2a8fb596e503 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 4 Dec 2017 14:08:53 +0100 Subject: [PATCH 10/36] Depsgraph: Use generic function for shape key driver target --- .../depsgraph/intern/builder/deg_builder_relations.cc | 8 ++------ source/blender/depsgraph/intern/depsgraph.cc | 2 +- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 2755357e11b..24894663920 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -1022,12 +1022,8 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) add_relation(driver_key, target_key, "Driver -> Target"); } else if (GS(id->name) == ID_KE && strstr(rna_path, "key_blocks[")) { - /* Shape key driver - hook into the base geometry operation. */ - // XXX: double check where this points - Key *shape_key = (Key *)id; - - ComponentKey geometry_key(shape_key->from, DEG_NODE_TYPE_GEOMETRY); - add_relation(driver_key, geometry_key, "Driver -> ShapeKey Geom"); + RNAPathKey target_key(id, rna_path); + add_relation(driver_key, target_key, "Driver -> Target"); } else if (strstr(rna_path, "key_blocks[")) { ComponentKey geometry_key(id, DEG_NODE_TYPE_GEOMETRY); diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc index ffdd0004727..a1251a4f425 100644 --- a/source/blender/depsgraph/intern/depsgraph.cc +++ b/source/blender/depsgraph/intern/depsgraph.cc @@ -202,7 +202,7 @@ static bool pointer_to_component_node_criteria( * owns it. */ *id = key->from; - *type = DEG_NODE_TYPE_PARAMETERS; + *type = DEG_NODE_TYPE_GEOMETRY; return true; } else if (RNA_struct_is_a(ptr->type, &RNA_Sequence)) { From 070c735b139bfa07cf667a26f788aecc60e7d95d Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 4 Dec 2017 17:37:21 +0100 Subject: [PATCH 11/36] Depsgraph: Fix wrong relations built for drivers When target was changed from bone to regular object, new dependency graph was still trying to build relations as if driver was using bone. --- .../depsgraph/intern/builder/deg_builder_relations.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 24894663920..a445068b9a8 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -1088,7 +1088,10 @@ void DepsgraphRelationBuilder::build_driver_variables(ID *id, FCurve *fcu) continue; } /* Special handling for directly-named bones. */ - if ((dtar->flag & DTAR_FLAG_STRUCT_REF) && (dtar->pchan_name[0])) { + if ((dtar->flag & DTAR_FLAG_STRUCT_REF) && + (((Object *)dtar->id)->type == OB_ARMATURE) && + (dtar->pchan_name[0])) + { Object *object = (Object *)dtar->id; bPoseChannel *target_pchan = BKE_pose_channel_find_name(object->pose, From 35364e2fb228eae741f9591eb270e5eb3c9a6913 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 4 Dec 2017 17:39:58 +0100 Subject: [PATCH 12/36] Depsgraph: Use generic function for shape key driver target There was a second place for shape keys. --- .../blender/depsgraph/intern/builder/deg_builder_relations.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index a445068b9a8..e8a54108eb4 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -1026,8 +1026,8 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) add_relation(driver_key, target_key, "Driver -> Target"); } else if (strstr(rna_path, "key_blocks[")) { - ComponentKey geometry_key(id, DEG_NODE_TYPE_GEOMETRY); - add_relation(driver_key, geometry_key, "Driver -> ShapeKey Geom"); + RNAPathKey target_key(id, rna_path); + add_relation(driver_key, target_key, "Driver -> Target"); } else { if (GS(id->name) == ID_OB) { From fe5e8593b7d1fb64fda9d853834f6002040dd607 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 4 Dec 2017 18:00:24 +0100 Subject: [PATCH 13/36] Depsgraph: Remove confusing ID node criteria it sometimes overrides all possible other criteria, even tho we might want to be very specific about what component we are looking for here. --- source/blender/depsgraph/intern/depsgraph.cc | 22 +------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc index a1251a4f425..295bc398061 100644 --- a/source/blender/depsgraph/intern/depsgraph.cc +++ b/source/blender/depsgraph/intern/depsgraph.cc @@ -91,22 +91,6 @@ Depsgraph::~Depsgraph() /* Query Conditions from RNA ----------------------- */ -static bool pointer_to_id_node_criteria(const PointerRNA *ptr, - const PropertyRNA *prop, - ID **id) -{ - if (ptr->type == NULL) { - return false; - } - if (prop != NULL) { - if (RNA_struct_is_ID(ptr->type)) { - *id = (ID *)ptr->data; - return true; - } - } - return false; -} - static bool pointer_to_component_node_criteria( const PointerRNA *ptr, const PropertyRNA *prop, @@ -230,11 +214,7 @@ DepsNode *Depsgraph::find_node_from_pointer(const PointerRNA *ptr, eDepsOperation_Code operation_code; int operation_name_tag; - /* Get querying conditions. */ - if (pointer_to_id_node_criteria(ptr, prop, &id)) { - return find_id_node(id); - } - else if (pointer_to_component_node_criteria( + if (pointer_to_component_node_criteria( ptr, prop, &id, &node_type, &component_name, &operation_code, &operation_name, &operation_name_tag)) From b26992fe6e3ed071295e01e958affb55e52a51a6 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 4 Dec 2017 18:06:02 +0100 Subject: [PATCH 14/36] Depsgraph: Add criteria for RNA_Key --- source/blender/depsgraph/intern/depsgraph.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc index 295bc398061..0cc31a53732 100644 --- a/source/blender/depsgraph/intern/depsgraph.cc +++ b/source/blender/depsgraph/intern/depsgraph.cc @@ -189,6 +189,11 @@ static bool pointer_to_component_node_criteria( *type = DEG_NODE_TYPE_GEOMETRY; return true; } + else if (ptr->type == &RNA_Key) { + *id = (ID *)ptr->id.data; + *type = DEG_NODE_TYPE_GEOMETRY; + return true; + } else if (RNA_struct_is_a(ptr->type, &RNA_Sequence)) { Sequence *seq = (Sequence *)ptr->data; /* Sequencer strip */ From 8912e4faef5f57ca0e396f8e8c20f059720e7631 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 4 Dec 2017 18:06:13 +0100 Subject: [PATCH 15/36] Depsgraph: Replace last obvious part of driver builder with generic RNA code --- .../intern/builder/deg_builder_relations.cc | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index e8a54108eb4..f821d6c9bf9 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -1030,21 +1030,8 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) add_relation(driver_key, target_key, "Driver -> Target"); } else { - if (GS(id->name) == ID_OB) { - /* assume that driver affects a transform... */ - OperationKey local_transform_key(id, - DEG_NODE_TYPE_TRANSFORM, - DEG_OPCODE_TRANSFORM_LOCAL); - add_relation(driver_key, - local_transform_key, - "Driver -> Transform"); - } - else if (GS(id->name) == ID_KE) { - ComponentKey geometry_key(id, DEG_NODE_TYPE_GEOMETRY); - add_relation(driver_key, - geometry_key, - "Driver -> Shapekey Geometry"); - } + RNAPathKey target_key(id, rna_path); + add_relation(driver_key, target_key, "Driver -> Target"); } /* Ensure that affected prop's update callbacks will be triggered once * done. From 8c4363e3b1abe13bdd3936aeeac261dc891d849a Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 4 Dec 2017 18:06:52 +0100 Subject: [PATCH 16/36] Depsgraph: Remove old comments which are likely outdated --- .../intern/builder/deg_builder_relations.cc | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index f821d6c9bf9..1f6d0f4ff56 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -963,12 +963,6 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) fcu->array_index); const char *rna_path = fcu->rna_path ? fcu->rna_path : ""; const RNAPathKey self_key(id, rna_path); - - /* Create dependency between driver and data affected by it. */ - /* - direct property relationship... */ - //RNAPathKey affected_key(id, fcu->rna_path); - //add_relation(driver_key, affected_key, "Driver -> Data"); - /* Driver -> data components (for interleaved evaluation * bones/constraints/modifiers). */ @@ -1033,15 +1027,6 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) RNAPathKey target_key(id, rna_path); add_relation(driver_key, target_key, "Driver -> Target"); } - /* Ensure that affected prop's update callbacks will be triggered once - * done. - */ - /* TODO: Implement this once the functionality to add these links exists - * RNA. - */ - /* XXX: the data itself could also set this, if it were to be truly - * initialised later? - */ /* Loop over variables to get the target relationships. */ build_driver_variables(id, fcu); /* It's quite tricky to detect if the driver actually depends on time or From 3e9cd536872c76c291774470addeb12a4e564a34 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 4 Dec 2017 18:08:29 +0100 Subject: [PATCH 17/36] Depsgraph: Cleanup, deduplicate as much as possible in build_driver --- .../intern/builder/deg_builder_relations.cc | 20 +------------------ 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 1f6d0f4ff56..df69c64f9aa 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -966,18 +966,12 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) /* Driver -> data components (for interleaved evaluation * bones/constraints/modifiers). */ - // XXX: this probably should probably be moved out into a separate function. - if (strstr(rna_path, "pose.bones[") != NULL) { - RNAPathKey target_key(id, rna_path); - add_relation(driver_key, target_key, "Driver -> Target"); - } - else if (GS(id->name) == ID_AR && strstr(rna_path, "bones[")) { + if (GS(id->name) == ID_AR && strstr(rna_path, "bones[")) { /* Drivers on armature-level bone settings (i.e. bbone stuff), * which will affect the evaluation of corresponding pose bones. */ IDDepsNode *arm_node = graph_->find_id_node(id); char *bone_name = BLI_str_quoted_substrN(rna_path, "bones["); - if (arm_node && bone_name) { /* Find objects which use this, and make their eval callbacks * depend on this. @@ -1011,18 +1005,6 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) rna_path); } } - else if (GS(id->name) == ID_OB && strstr(rna_path, "modifiers[")) { - RNAPathKey target_key(id, rna_path); - add_relation(driver_key, target_key, "Driver -> Target"); - } - else if (GS(id->name) == ID_KE && strstr(rna_path, "key_blocks[")) { - RNAPathKey target_key(id, rna_path); - add_relation(driver_key, target_key, "Driver -> Target"); - } - else if (strstr(rna_path, "key_blocks[")) { - RNAPathKey target_key(id, rna_path); - add_relation(driver_key, target_key, "Driver -> Target"); - } else { RNAPathKey target_key(id, rna_path); add_relation(driver_key, target_key, "Driver -> Target"); From b5a8d0acaf86f3767b2ec9e6e9ccc7d859dc67b9 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 4 Dec 2017 18:11:43 +0100 Subject: [PATCH 18/36] Depsgraph: Cleanup, split driver builder function --- .../intern/builder/deg_builder_relations.cc | 38 ++++++++++++------- .../intern/builder/deg_builder_relations.h | 1 + 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index df69c64f9aa..522ed9956ca 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -961,11 +961,33 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) DEG_OPCODE_DRIVER, fcu->rna_path ? fcu->rna_path : "", fcu->array_index); - const char *rna_path = fcu->rna_path ? fcu->rna_path : ""; - const RNAPathKey self_key(id, rna_path); /* Driver -> data components (for interleaved evaluation * bones/constraints/modifiers). */ + build_driver_data(id, fcu); + /* Loop over variables to get the target relationships. */ + build_driver_variables(id, fcu); + /* It's quite tricky to detect if the driver actually depends on time or + * not, so for now we'll be quite conservative here about optimization and + * consider all python drivers to be depending on time. + */ + if ((driver->type == DRIVER_TYPE_PYTHON) && + python_driver_depends_on_time(driver)) + { + TimeSourceKey time_src_key; + add_relation(time_src_key, driver_key, "TimeSrc -> Driver"); + } +} + +void DepsgraphRelationBuilder::build_driver_data(ID *id, FCurve *fcu) +{ + OperationKey driver_key(id, + DEG_NODE_TYPE_PARAMETERS, + DEG_OPCODE_DRIVER, + fcu->rna_path ? fcu->rna_path : "", + fcu->array_index); + const char *rna_path = fcu->rna_path ? fcu->rna_path : ""; + const RNAPathKey self_key(id, rna_path); if (GS(id->name) == ID_AR && strstr(rna_path, "bones[")) { /* Drivers on armature-level bone settings (i.e. bbone stuff), * which will affect the evaluation of corresponding pose bones. @@ -1009,18 +1031,6 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) RNAPathKey target_key(id, rna_path); add_relation(driver_key, target_key, "Driver -> Target"); } - /* Loop over variables to get the target relationships. */ - build_driver_variables(id, fcu); - /* It's quite tricky to detect if the driver actually depends on time or - * not, so for now we'll be quite conservative here about optimization and - * consider all python drivers to be depending on time. - */ - if ((driver->type == DRIVER_TYPE_PYTHON) && - python_driver_depends_on_time(driver)) - { - TimeSourceKey time_src_key; - add_relation(time_src_key, driver_key, "TimeSrc -> Driver"); - } } void DepsgraphRelationBuilder::build_driver_variables(ID *id, FCurve *fcu) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index 7aadf197c7b..1cf2f9847e2 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -198,6 +198,7 @@ struct DepsgraphRelationBuilder RootPChanMap *root_map); void build_animdata(ID *id); void build_driver(ID *id, FCurve *fcurve); + void build_driver_data(ID *id, FCurve *fcurve); void build_driver_variables(ID *id, FCurve *fcurve); void build_world(World *world); void build_rigidbody(Scene *scene); From 9f9b666d9a281e813c50ee2de8337713066482f1 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 4 Dec 2017 18:24:38 +0100 Subject: [PATCH 19/36] Depsgraph: Correct fallback for the parameters calculation We can't use a single component here, sine it might consist of multiple operations. So, for example, having driver operation will confuse targets of another driver. --- source/blender/depsgraph/intern/depsgraph.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc index 0cc31a53732..e7811ce47fb 100644 --- a/source/blender/depsgraph/intern/depsgraph.cc +++ b/source/blender/depsgraph/intern/depsgraph.cc @@ -204,6 +204,9 @@ static bool pointer_to_component_node_criteria( if (prop != NULL) { /* All unknown data effectively falls under "parameter evaluation". */ *type = DEG_NODE_TYPE_PARAMETERS; + *operation_code = DEG_OPCODE_PARAMETERS_EVAL; + *operation_name = ""; + *operation_name_tag = -1; return true; } return false; From f1ad6b43b316b4f6da2937f11a7aca4302a86dc8 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 4 Dec 2017 18:34:27 +0100 Subject: [PATCH 20/36] Depsgraph: Cleanup, split build_animation --- .../intern/builder/deg_builder_relations.cc | 39 ++++++++++++------- .../intern/builder/deg_builder_relations.h | 2 + 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 522ed9956ca..58d80dc9553 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -870,26 +870,35 @@ void DepsgraphRelationBuilder::build_constraints(ID *id, } void DepsgraphRelationBuilder::build_animdata(ID *id) +{ + /* Animation curves and NLA. */ + build_animdata_curves(id); + /* Drivers. */ + build_animdata_drievrs(id); +} + +void DepsgraphRelationBuilder::build_animdata_curves(ID *id) { AnimData *adt = BKE_animdata_from_id(id); - - if (adt == NULL) + if (adt == NULL) { return; - - ComponentKey adt_key(id, DEG_NODE_TYPE_ANIMATION); - - /* animation */ - if (adt->action || adt->nla_tracks.first) { - /* wire up dependency to time source */ - TimeSourceKey time_src_key; - add_relation(time_src_key, adt_key, "TimeSrc -> Animation"); - - // XXX: Hook up specific update callbacks for special properties which may need it... - - // XXX: animdata "hierarchy" - top-level overrides need to go after lower-down } + ComponentKey adt_key(id, DEG_NODE_TYPE_ANIMATION); + if (adt->action == NULL && adt->nla_tracks.first == NULL) { + return; + } + /* Wire up dependency to time source. */ + TimeSourceKey time_src_key; + add_relation(time_src_key, adt_key, "TimeSrc -> Animation"); +} - /* drivers */ +void DepsgraphRelationBuilder::build_animdata_drievrs(ID *id) +{ + AnimData *adt = BKE_animdata_from_id(id); + if (adt == NULL) { + return; + } + ComponentKey adt_key(id, DEG_NODE_TYPE_ANIMATION); LINKLIST_FOREACH (FCurve *, fcu, &adt->drivers) { OperationKey driver_key(id, DEG_NODE_TYPE_PARAMETERS, diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index 1cf2f9847e2..2b2e133e98e 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -197,6 +197,8 @@ struct DepsgraphRelationBuilder ListBase *constraints, RootPChanMap *root_map); void build_animdata(ID *id); + void build_animdata_curves(ID *id); + void build_animdata_drievrs(ID *id); void build_driver(ID *id, FCurve *fcurve); void build_driver_data(ID *id, FCurve *fcurve); void build_driver_variables(ID *id, FCurve *fcurve); From 335343fe93a9d96d293011ff263495be37ec2a62 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 5 Dec 2017 10:14:12 +0100 Subject: [PATCH 21/36] Fix T53408: Updating Cycles Nodes via Drivers in Material View This is something what should be supported by the new dependency graph. Fixed by making it so, build_animation() adds relation between Animation component and whatever-is-being-animated. In fact, for now, only relations to ID properties are added. Rest of the relations are kind of hacked in all over the code and needs to be removed and verified with specific .blend files. --- .../intern/builder/deg_builder_relations.cc | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 58d80dc9553..083f0126caa 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -890,6 +890,28 @@ void DepsgraphRelationBuilder::build_animdata_curves(ID *id) /* Wire up dependency to time source. */ TimeSourceKey time_src_key; add_relation(time_src_key, adt_key, "TimeSrc -> Animation"); + /* Build dependencies from FCurve to a "target" which is modified by + * the curve. + */ + if (adt->action != NULL) { + PointerRNA id_ptr; + RNA_id_pointer_create(id, &id_ptr); + LINKLIST_FOREACH(FCurve *, fcu, &adt->action->curves) { + PointerRNA ptr; + PropertyRNA *prop; + int index; + if (!RNA_path_resolve_full(&id_ptr, fcu->rna_path, + &ptr, &prop, &index)) + { + continue; + } + /* TODO(sergey): Avoid duplicated relations. */ + if (prop != NULL && RNA_property_is_idprop(prop)) { + RNAPathKey prop_key(id, fcu->rna_path); + add_relation(adt_key, prop_key, "Animation -> ID Prop"); + } + } + } } void DepsgraphRelationBuilder::build_animdata_drievrs(ID *id) From 7de3c8ace786d56e1f73851cdc85b1413658bba3 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 5 Dec 2017 11:35:28 +0100 Subject: [PATCH 22/36] Depsgraph: Move implementation part of relations header to own file --- source/blender/depsgraph/CMakeLists.txt | 1 + .../intern/builder/deg_builder_relations.h | 122 +------------- .../builder/deg_builder_relations_impl.h | 152 ++++++++++++++++++ 3 files changed, 156 insertions(+), 119 deletions(-) create mode 100644 source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h diff --git a/source/blender/depsgraph/CMakeLists.txt b/source/blender/depsgraph/CMakeLists.txt index ac8d01ab739..9478ca306e9 100644 --- a/source/blender/depsgraph/CMakeLists.txt +++ b/source/blender/depsgraph/CMakeLists.txt @@ -75,6 +75,7 @@ set(SRC intern/builder/deg_builder_nodes.h intern/builder/deg_builder_pchanmap.h intern/builder/deg_builder_relations.h + intern/builder/deg_builder_relations_impl.h intern/builder/deg_builder_transitive.h intern/eval/deg_eval.h intern/eval/deg_eval_flush.h diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index 2b2e133e98e..5bfd3341662 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -299,123 +299,7 @@ struct DepsNodeHandle const char *default_name; }; -/* Utilities for Builders ----------------------------------------------------- */ - -template -OperationDepsNode *DepsgraphRelationBuilder::find_operation_node(const KeyType& key) -{ - DepsNode *node = get_node(key); - return node != NULL ? node->get_exit_operation() : NULL; -} - -template -void DepsgraphRelationBuilder::add_relation(const KeyFrom &key_from, - const KeyTo &key_to, - const char *description) -{ - DepsNode *node_from = get_node(key_from); - DepsNode *node_to = get_node(key_to); - OperationDepsNode *op_from = node_from ? node_from->get_exit_operation() : NULL; - OperationDepsNode *op_to = node_to ? node_to->get_entry_operation() : NULL; - if (op_from && op_to) { - add_operation_relation(op_from, op_to, description); - } - else { - if (!op_from) { - /* XXX TODO handle as error or report if needed */ - fprintf(stderr, "add_relation(%s) - Could not find op_from (%s)\n", - description, key_from.identifier().c_str()); - } - else { - fprintf(stderr, "add_relation(%s) - Failed, but op_from (%s) was ok\n", - description, key_from.identifier().c_str()); - } - if (!op_to) { - /* XXX TODO handle as error or report if needed */ - fprintf(stderr, "add_relation(%s) - Could not find op_to (%s)\n", - description, key_to.identifier().c_str()); - } - else { - fprintf(stderr, "add_relation(%s) - Failed, but op_to (%s) was ok\n", - description, key_to.identifier().c_str()); - } - } -} - -template -void DepsgraphRelationBuilder::add_relation(const TimeSourceKey &key_from, - const KeyTo &key_to, - const char *description) -{ - TimeSourceDepsNode *time_from = get_node(key_from); - DepsNode *node_to = get_node(key_to); - OperationDepsNode *op_to = node_to ? node_to->get_entry_operation() : NULL; - if (time_from != NULL && op_to != NULL) { - add_time_relation(time_from, op_to, description); - } -} - -template -void DepsgraphRelationBuilder::add_node_handle_relation( - const KeyType &key_from, - const DepsNodeHandle *handle, - const char *description) -{ - DepsNode *node_from = get_node(key_from); - OperationDepsNode *op_from = node_from ? node_from->get_exit_operation() : NULL; - OperationDepsNode *op_to = handle->node->get_entry_operation(); - if (op_from != NULL && op_to != NULL) { - add_operation_relation(op_from, op_to, description); - } - else { - if (!op_from) { - fprintf(stderr, "add_node_handle_relation(%s) - Could not find op_from (%s)\n", - description, key_from.identifier().c_str()); - } - if (!op_to) { - fprintf(stderr, "add_node_handle_relation(%s) - Could not find op_to (%s)\n", - description, key_from.identifier().c_str()); - } - } -} - -template -DepsNodeHandle DepsgraphRelationBuilder::create_node_handle( - const KeyType &key, - const char *default_name) -{ - return DepsNodeHandle(this, get_node(key), default_name); -} - -/* Rig compatibility: we check if bone is using local transform as a variable - * for driver on itself and ignore those relations to avoid "false-positive" - * dependency cycles. - */ -template -bool DepsgraphRelationBuilder::is_same_bone_dependency(const KeyFrom& key_from, - const KeyTo& key_to) -{ - /* Get operations for requested keys. */ - DepsNode *node_from = get_node(key_from); - DepsNode *node_to = get_node(key_to); - if (node_from == NULL || node_to == NULL) { - return false; - } - OperationDepsNode *op_from = node_from->get_exit_operation(); - OperationDepsNode *op_to = node_to->get_entry_operation(); - if (op_from == NULL || op_to == NULL) { - return false; - } - /* We are only interested in relations like BONE_DONE -> BONE_LOCAL... */ - if (!(op_from->opcode == DEG_OPCODE_BONE_DONE && - op_to->opcode == DEG_OPCODE_BONE_LOCAL)) { - return false; - } - /* ... BUT, we also need to check if it's same bone. */ - if (!STREQ(op_from->owner->name, op_to->owner->name)) { - return false; - } - return true; -} - } // namespace DEG + + +#include "intern/builder/deg_builder_relations_impl.h" diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h b/source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h new file mode 100644 index 00000000000..38c0b205661 --- /dev/null +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h @@ -0,0 +1,152 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2013 Blender Foundation. + * All rights reserved. + * + * Original Author: Lukas Toenne + * Contributor(s): Sergey SHarybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/depsgraph/intern/builder/deg_builder_relations_impl.h + * \ingroup depsgraph + */ + +#pragma once + +namespace DEG { + +template +OperationDepsNode *DepsgraphRelationBuilder::find_operation_node(const KeyType& key) +{ + DepsNode *node = get_node(key); + return node != NULL ? node->get_exit_operation() : NULL; +} + +template +void DepsgraphRelationBuilder::add_relation(const KeyFrom &key_from, + const KeyTo &key_to, + const char *description) +{ + DepsNode *node_from = get_node(key_from); + DepsNode *node_to = get_node(key_to); + OperationDepsNode *op_from = node_from ? node_from->get_exit_operation() : NULL; + OperationDepsNode *op_to = node_to ? node_to->get_entry_operation() : NULL; + if (op_from && op_to) { + add_operation_relation(op_from, op_to, description); + } + else { + if (!op_from) { + /* XXX TODO handle as error or report if needed */ + fprintf(stderr, "add_relation(%s) - Could not find op_from (%s)\n", + description, key_from.identifier().c_str()); + } + else { + fprintf(stderr, "add_relation(%s) - Failed, but op_from (%s) was ok\n", + description, key_from.identifier().c_str()); + } + if (!op_to) { + /* XXX TODO handle as error or report if needed */ + fprintf(stderr, "add_relation(%s) - Could not find op_to (%s)\n", + description, key_to.identifier().c_str()); + } + else { + fprintf(stderr, "add_relation(%s) - Failed, but op_to (%s) was ok\n", + description, key_to.identifier().c_str()); + } + } +} + +template +void DepsgraphRelationBuilder::add_relation(const TimeSourceKey &key_from, + const KeyTo &key_to, + const char *description) +{ + TimeSourceDepsNode *time_from = get_node(key_from); + DepsNode *node_to = get_node(key_to); + OperationDepsNode *op_to = node_to ? node_to->get_entry_operation() : NULL; + if (time_from != NULL && op_to != NULL) { + add_time_relation(time_from, op_to, description); + } +} + +template +void DepsgraphRelationBuilder::add_node_handle_relation( + const KeyType &key_from, + const DepsNodeHandle *handle, + const char *description) +{ + DepsNode *node_from = get_node(key_from); + OperationDepsNode *op_from = node_from ? node_from->get_exit_operation() : NULL; + OperationDepsNode *op_to = handle->node->get_entry_operation(); + if (op_from != NULL && op_to != NULL) { + add_operation_relation(op_from, op_to, description); + } + else { + if (!op_from) { + fprintf(stderr, "add_node_handle_relation(%s) - Could not find op_from (%s)\n", + description, key_from.identifier().c_str()); + } + if (!op_to) { + fprintf(stderr, "add_node_handle_relation(%s) - Could not find op_to (%s)\n", + description, key_from.identifier().c_str()); + } + } +} + +template +DepsNodeHandle DepsgraphRelationBuilder::create_node_handle( + const KeyType &key, + const char *default_name) +{ + return DepsNodeHandle(this, get_node(key), default_name); +} + +/* Rig compatibility: we check if bone is using local transform as a variable + * for driver on itself and ignore those relations to avoid "false-positive" + * dependency cycles. + */ +template +bool DepsgraphRelationBuilder::is_same_bone_dependency(const KeyFrom& key_from, + const KeyTo& key_to) +{ + /* Get operations for requested keys. */ + DepsNode *node_from = get_node(key_from); + DepsNode *node_to = get_node(key_to); + if (node_from == NULL || node_to == NULL) { + return false; + } + OperationDepsNode *op_from = node_from->get_exit_operation(); + OperationDepsNode *op_to = node_to->get_entry_operation(); + if (op_from == NULL || op_to == NULL) { + return false; + } + /* We are only interested in relations like BONE_DONE -> BONE_LOCAL... */ + if (!(op_from->opcode == DEG_OPCODE_BONE_DONE && + op_to->opcode == DEG_OPCODE_BONE_LOCAL)) { + return false; + } + /* ... BUT, we also need to check if it's same bone. */ + if (!STREQ(op_from->owner->name, op_to->owner->name)) { + return false; + } + return true; +} + +} // namespace DEG From 8b3aa8ef45ea5f6dff88706f274638ef9a43d71a Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 5 Dec 2017 11:37:27 +0100 Subject: [PATCH 23/36] Depsgraph: Cleanup, line wrapping --- .../depsgraph/intern/builder/deg_builder_relations.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index 5bfd3341662..b06d491a9aa 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -286,10 +286,12 @@ private: struct DepsNodeHandle { - DepsNodeHandle(DepsgraphRelationBuilder *builder, OperationDepsNode *node, const char *default_name = "") : - builder(builder), - node(node), - default_name(default_name) + DepsNodeHandle(DepsgraphRelationBuilder *builder, + OperationDepsNode *node, + const char *default_name = "") + : builder(builder), + node(node), + default_name(default_name) { BLI_assert(node != NULL); } From 4a99cc5850bff6033080a27d81e73f3355af996a Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 5 Dec 2017 12:52:17 +0100 Subject: [PATCH 24/36] Depsgraph: Add ability to check whether relation exists before adding it Currently not used, but this is aimed to be used when adding relations from FCurve to property which is being animated. --- .../intern/builder/deg_builder_relations.cc | 10 ++-- .../intern/builder/deg_builder_relations.h | 15 +++-- .../builder/deg_builder_relations_impl.h | 15 +++-- source/blender/depsgraph/intern/depsgraph.cc | 59 ++++++++++++------- source/blender/depsgraph/intern/depsgraph.h | 14 ++++- 5 files changed, 74 insertions(+), 39 deletions(-) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 083f0126caa..c1570f310ef 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -274,10 +274,11 @@ bool DepsgraphRelationBuilder::has_node(const OperationKey &key) const void DepsgraphRelationBuilder::add_time_relation(TimeSourceDepsNode *timesrc, DepsNode *node_to, - const char *description) + const char *description, + bool check_unique) { if (timesrc && node_to) { - graph_->add_new_relation(timesrc, node_to, description); + graph_->add_new_relation(timesrc, node_to, description, check_unique); } else { DEG_DEBUG_PRINTF("add_time_relation(%p = %s, %p = %s, %s) Failed\n", @@ -290,10 +291,11 @@ void DepsgraphRelationBuilder::add_time_relation(TimeSourceDepsNode *timesrc, void DepsgraphRelationBuilder::add_operation_relation( OperationDepsNode *node_from, OperationDepsNode *node_to, - const char *description) + const char *description, + bool check_unique) { if (node_from && node_to) { - graph_->add_new_relation(node_from, node_to, description); + graph_->add_new_relation(node_from, node_to, description, check_unique); } else { DEG_DEBUG_PRINTF("add_operation_relation(%p = %s, %p = %s, %s) Failed\n", diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index b06d491a9aa..99256dc017c 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -174,17 +174,20 @@ struct DepsgraphRelationBuilder template void add_relation(const KeyFrom& key_from, const KeyTo& key_to, - const char *description); + const char *description, + bool check_unique = false); template void add_relation(const TimeSourceKey& key_from, const KeyTo& key_to, - const char *description); + const char *description, + bool check_unique = false); template void add_node_handle_relation(const KeyType& key_from, const DepsNodeHandle *handle, - const char *description); + const char *description, + bool check_unique = false); void build_scene(Scene *scene); void build_group(Object *object, Group *group); @@ -261,10 +264,12 @@ protected: void add_time_relation(TimeSourceDepsNode *timesrc, DepsNode *node_to, - const char *description); + const char *description, + bool check_unique = false); void add_operation_relation(OperationDepsNode *node_from, OperationDepsNode *node_to, - const char *description); + const char *description, + bool check_unique = false); template DepsNodeHandle create_node_handle(const KeyType& key, diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h b/source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h index 38c0b205661..ba55a83b767 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h @@ -42,14 +42,15 @@ OperationDepsNode *DepsgraphRelationBuilder::find_operation_node(const KeyType& template void DepsgraphRelationBuilder::add_relation(const KeyFrom &key_from, const KeyTo &key_to, - const char *description) + const char *description, + bool check_unique) { DepsNode *node_from = get_node(key_from); DepsNode *node_to = get_node(key_to); OperationDepsNode *op_from = node_from ? node_from->get_exit_operation() : NULL; OperationDepsNode *op_to = node_to ? node_to->get_entry_operation() : NULL; if (op_from && op_to) { - add_operation_relation(op_from, op_to, description); + add_operation_relation(op_from, op_to, description, check_unique); } else { if (!op_from) { @@ -76,13 +77,14 @@ void DepsgraphRelationBuilder::add_relation(const KeyFrom &key_from, template void DepsgraphRelationBuilder::add_relation(const TimeSourceKey &key_from, const KeyTo &key_to, - const char *description) + const char *description, + bool check_unique) { TimeSourceDepsNode *time_from = get_node(key_from); DepsNode *node_to = get_node(key_to); OperationDepsNode *op_to = node_to ? node_to->get_entry_operation() : NULL; if (time_from != NULL && op_to != NULL) { - add_time_relation(time_from, op_to, description); + add_time_relation(time_from, op_to, description, check_unique); } } @@ -90,13 +92,14 @@ template void DepsgraphRelationBuilder::add_node_handle_relation( const KeyType &key_from, const DepsNodeHandle *handle, - const char *description) + const char *description, + bool check_unique) { DepsNode *node_from = get_node(key_from); OperationDepsNode *op_from = node_from ? node_from->get_exit_operation() : NULL; OperationDepsNode *op_to = handle->node->get_entry_operation(); if (op_from != NULL && op_to != NULL) { - add_operation_relation(op_from, op_to, description); + add_operation_relation(op_from, op_to, description, check_unique); } else { if (!op_from) { diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc index e7811ce47fb..835cf81655a 100644 --- a/source/blender/depsgraph/intern/depsgraph.cc +++ b/source/blender/depsgraph/intern/depsgraph.cc @@ -292,10 +292,18 @@ void Depsgraph::clear_id_nodes() /* Add new relationship between two nodes. */ DepsRelation *Depsgraph::add_new_relation(OperationDepsNode *from, OperationDepsNode *to, - const char *description) + const char *description, + bool check_unique) { + DepsRelation *rel = NULL; + if (check_unique) { + rel = check_nodes_connected(from, to, description); + } + if (rel != NULL) { + return rel; + } /* Create new relation, and add it to the graph. */ - DepsRelation *rel = OBJECT_GUARDED_NEW(DepsRelation, from, to, description); + rel = OBJECT_GUARDED_NEW(DepsRelation, from, to, description); /* TODO(sergey): Find a better place for this. */ #ifdef WITH_OPENSUBDIV ComponentDepsNode *comp_node = from->owner; @@ -315,13 +323,38 @@ DepsRelation *Depsgraph::add_new_relation(OperationDepsNode *from, /* Add new relation between two nodes */ DepsRelation *Depsgraph::add_new_relation(DepsNode *from, DepsNode *to, - const char *description) + const char *description, + bool check_unique) { + DepsRelation *rel = NULL; + if (check_unique) { + rel = check_nodes_connected(from, to, description); + } + if (rel != NULL) { + return rel; + } /* Create new relation, and add it to the graph. */ - DepsRelation *rel = OBJECT_GUARDED_NEW(DepsRelation, from, to, description); + rel = OBJECT_GUARDED_NEW(DepsRelation, from, to, description); return rel; } +DepsRelation *Depsgraph::check_nodes_connected(const DepsNode *from, + const DepsNode *to, + const char *description) +{ + foreach (DepsRelation *rel, from->outlinks) { + BLI_assert(rel->from == from); + if (rel->to != to) { + continue; + } + if (description != NULL && !STREQ(rel->name, description)) { + continue; + } + return rel; + } + return NULL; +} + /* ************************ */ /* Relationships Management */ @@ -333,24 +366,6 @@ DepsRelation::DepsRelation(DepsNode *from, name(description), flag(0) { -#ifndef NDEBUG -/* - for (OperationDepsNode::Relations::const_iterator it = from->outlinks.begin(); - it != from->outlinks.end(); - ++it) - { - DepsRelation *rel = *it; - if (rel->from == from && - rel->to == to && - rel->type == type && - rel->name == description) - { - BLI_assert(!"Duplicated relation, should not happen!"); - } - } -*/ -#endif - /* Hook it up to the nodes which use it. * * NOTE: We register relation in the nodes which this link connects to here diff --git a/source/blender/depsgraph/intern/depsgraph.h b/source/blender/depsgraph/intern/depsgraph.h index f72f8dd9311..2fd072dbcea 100644 --- a/source/blender/depsgraph/intern/depsgraph.h +++ b/source/blender/depsgraph/intern/depsgraph.h @@ -117,11 +117,21 @@ struct Depsgraph { /* Add new relationship between two nodes. */ DepsRelation *add_new_relation(OperationDepsNode *from, OperationDepsNode *to, - const char *description); + const char *description, + bool check_unique); DepsRelation *add_new_relation(DepsNode *from, DepsNode *to, - const char *description); + const char *description, + bool check_unique); + + /* Check whether two nodes are connected by relation with given + * description. Description might be NULL to check ANY relation between + * given nodes. + */ + DepsRelation *check_nodes_connected(const DepsNode *from, + const DepsNode *to, + const char *description); /* Tag a specific node as needing updates. */ void add_entry_tag(OperationDepsNode *node); From abc55bf84a236f3e591d34a480a6fe0f8d3c7688 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 5 Dec 2017 12:57:01 +0100 Subject: [PATCH 25/36] Depsgraph: Use build_animation() to build relations to animated properties Before that it was up to lots of other places to keep track on whether something is to be dependent on time or not. Was annoying, and unreliable, and fragile. This commit avoids hacks in object builder. Other areas will be adopted soon. --- .../intern/builder/deg_builder_relations.cc | 22 +++++-------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index c1570f310ef..54d3259bc0f 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -486,11 +486,6 @@ void DepsgraphRelationBuilder::build_object(Object *object) } /* Animation data */ build_animdata(&object->id); - // XXX: This should be hooked up by the build_animdata code - if (needs_animdata_node(&object->id)) { - ComponentKey adt_key(&object->id, DEG_NODE_TYPE_ANIMATION); - add_relation(adt_key, local_transform_key, "Object Animation"); - } /* Object data. */ build_object_data(object); /* Particle systems. */ @@ -899,19 +894,12 @@ void DepsgraphRelationBuilder::build_animdata_curves(ID *id) PointerRNA id_ptr; RNA_id_pointer_create(id, &id_ptr); LINKLIST_FOREACH(FCurve *, fcu, &adt->action->curves) { - PointerRNA ptr; - PropertyRNA *prop; - int index; - if (!RNA_path_resolve_full(&id_ptr, fcu->rna_path, - &ptr, &prop, &index)) - { - continue; - } /* TODO(sergey): Avoid duplicated relations. */ - if (prop != NULL && RNA_property_is_idprop(prop)) { - RNAPathKey prop_key(id, fcu->rna_path); - add_relation(adt_key, prop_key, "Animation -> ID Prop"); - } + /* TODO(sergey): FCurve on a bone should be hooking up to pose + * init rather than to bone local. + */ + RNAPathKey prop_key(id, fcu->rna_path); + add_relation(adt_key, prop_key, "Animation -> Prop", true); } } } From 18ca793ca08f8334e37c60e06dede78c43338721 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 5 Dec 2017 13:02:36 +0100 Subject: [PATCH 26/36] Depsgraph: Cleanup, line wrapping --- .../intern/builder/deg_builder_relations.cc | 68 +++++++++++++------ 1 file changed, 48 insertions(+), 20 deletions(-) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 54d3259bc0f..aa22c1177e7 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -305,13 +305,25 @@ void DepsgraphRelationBuilder::add_operation_relation( } } -void DepsgraphRelationBuilder::add_collision_relations(const OperationKey &key, Scene *scene, Object *object, Group *group, int layer, bool dupli, const char *name) +void DepsgraphRelationBuilder::add_collision_relations( + const OperationKey &key, + 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); - - for (unsigned int i = 0; i < numcollobj; i++) - { + Object **collobjs = get_collisionobjects_ext( + scene, + object, + group, + layer, + &numcollobj, + eModifierType_Collision, + dupli); + for (unsigned int i = 0; i < numcollobj; i++) { Object *ob1 = collobjs[i]; ComponentKey trf_key(&ob1->id, DEG_NODE_TYPE_TRANSFORM); @@ -320,47 +332,63 @@ void DepsgraphRelationBuilder::add_collision_relations(const OperationKey &key, ComponentKey coll_key(&ob1->id, DEG_NODE_TYPE_GEOMETRY); add_relation(coll_key, key, name); } - - if (collobjs) + if (collobjs != NULL) { MEM_freeN(collobjs); + } } -void DepsgraphRelationBuilder::add_forcefield_relations(const OperationKey &key, Scene *scene, Object *object, ParticleSystem *psys, EffectorWeights *eff, bool add_absorption, const char *name) +void DepsgraphRelationBuilder::add_forcefield_relations( + const OperationKey &key, + Scene *scene, + Object *object, + ParticleSystem *psys, + EffectorWeights *eff, + bool add_absorption, + const char *name) { ListBase *effectors = pdInitEffectors(scene, object, psys, eff, false); - - if (effectors) { - for (EffectorCache *eff = (EffectorCache *)effectors->first; eff; eff = eff->next) { + if (effectors != NULL) { + LINKLIST_FOREACH(EffectorCache *, eff, effectors) { if (eff->ob != object) { ComponentKey eff_key(&eff->ob->id, DEG_NODE_TYPE_TRANSFORM); add_relation(eff_key, key, name); } - - if (eff->psys) { + if (eff->psys != NULL) { if (eff->ob != object) { ComponentKey eff_key(&eff->ob->id, DEG_NODE_TYPE_EVAL_PARTICLES); add_relation(eff_key, key, name); - /* TODO: remove this when/if EVAL_PARTICLES is sufficient for up to date particles */ + /* TODO: remove this when/if EVAL_PARTICLES is sufficient + * for up to date particles. + */ ComponentKey mod_key(&eff->ob->id, DEG_NODE_TYPE_GEOMETRY); add_relation(mod_key, key, name); } else if (eff->psys != psys) { - OperationKey eff_key(&eff->ob->id, DEG_NODE_TYPE_EVAL_PARTICLES, DEG_OPCODE_PARTICLE_SYSTEM_EVAL, eff->psys->name); + OperationKey eff_key(&eff->ob->id, + DEG_NODE_TYPE_EVAL_PARTICLES, + DEG_OPCODE_PARTICLE_SYSTEM_EVAL, + eff->psys->name); add_relation(eff_key, key, name); } } - if (eff->pd->forcefield == PFIELD_SMOKEFLOW && eff->pd->f_source) { - ComponentKey trf_key(&eff->pd->f_source->id, DEG_NODE_TYPE_TRANSFORM); + ComponentKey trf_key(&eff->pd->f_source->id, + DEG_NODE_TYPE_TRANSFORM); add_relation(trf_key, key, "Smoke Force Domain"); - ComponentKey eff_key(&eff->pd->f_source->id, DEG_NODE_TYPE_GEOMETRY); + ComponentKey eff_key(&eff->pd->f_source->id, + DEG_NODE_TYPE_GEOMETRY); add_relation(eff_key, key, "Smoke Force Domain"); } - if (add_absorption && (eff->pd->flag & PFIELD_VISIBILITY)) { - add_collision_relations(key, scene, object, NULL, eff->ob->lay, true, "Force Absorption"); + add_collision_relations(key, + scene, + object, + NULL, + eff->ob->lay, + true, + "Force Absorption"); } } } From cbb42fcd9622aa7224ba89ab51079e6f3e89a62c Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 5 Dec 2017 15:59:48 +0100 Subject: [PATCH 27/36] Depsgraph: Use default argument value for relations builder Follows other function definitions. --- source/blender/depsgraph/intern/depsgraph.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/depsgraph/intern/depsgraph.h b/source/blender/depsgraph/intern/depsgraph.h index 2fd072dbcea..46da40b9938 100644 --- a/source/blender/depsgraph/intern/depsgraph.h +++ b/source/blender/depsgraph/intern/depsgraph.h @@ -118,12 +118,12 @@ struct Depsgraph { DepsRelation *add_new_relation(OperationDepsNode *from, OperationDepsNode *to, const char *description, - bool check_unique); + bool check_unique = false); DepsRelation *add_new_relation(DepsNode *from, DepsNode *to, const char *description, - bool check_unique); + bool check_unique = false); /* Check whether two nodes are connected by relation with given * description. Description might be NULL to check ANY relation between From f348b7924cf230e05b1f69ad2b32ab2dd5d7879d Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 5 Dec 2017 16:09:03 +0100 Subject: [PATCH 28/36] Depsgraph: Leave armature animation relation to build_animation() Needs some optimization trick to hook pose init function to animation instead of a bone. This is how flush will work anyway. --- .../intern/builder/deg_builder_relations.cc | 64 +++++++++++++++---- .../intern/builder/deg_builder_relations.h | 1 + .../builder/deg_builder_relations_rig.cc | 5 -- 3 files changed, 51 insertions(+), 19 deletions(-) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index aa22c1177e7..a9df6efc419 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -908,27 +908,63 @@ void DepsgraphRelationBuilder::build_animdata_curves(ID *id) if (adt == NULL) { return; } - ComponentKey adt_key(id, DEG_NODE_TYPE_ANIMATION); if (adt->action == NULL && adt->nla_tracks.first == NULL) { return; } /* Wire up dependency to time source. */ + ComponentKey adt_key(id, DEG_NODE_TYPE_ANIMATION); TimeSourceKey time_src_key; add_relation(time_src_key, adt_key, "TimeSrc -> Animation"); - /* Build dependencies from FCurve to a "target" which is modified by - * the curve. - */ - if (adt->action != NULL) { - PointerRNA id_ptr; - RNA_id_pointer_create(id, &id_ptr); - LINKLIST_FOREACH(FCurve *, fcu, &adt->action->curves) { - /* TODO(sergey): Avoid duplicated relations. */ - /* TODO(sergey): FCurve on a bone should be hooking up to pose - * init rather than to bone local. - */ - RNAPathKey prop_key(id, fcu->rna_path); - add_relation(adt_key, prop_key, "Animation -> Prop", true); + /* Build relations from animation operation to properties it changes. */ + build_animdata_curves_targets(id); +} + +void DepsgraphRelationBuilder::build_animdata_curves_targets(ID *id) +{ + AnimData *adt = BKE_animdata_from_id(id); + if (adt == NULL || adt->action == NULL) { + return; + } + /* Get source operation. */ + ComponentKey adt_key(id, DEG_NODE_TYPE_ANIMATION); + DepsNode *node_from = get_node(adt_key); + BLI_assert(node_from != NULL); + if (node_from == NULL) { + return; + } + OperationDepsNode *operation_from = node_from->get_exit_operation(); + BLI_assert(operation_from != NULL); + /* Iterate over all curves and build relations. */ + PointerRNA id_ptr; + RNA_id_pointer_create(id, &id_ptr); + LINKLIST_FOREACH(FCurve *, fcu, &adt->action->curves) { + PointerRNA ptr; + PropertyRNA *prop; + int index; + if (!RNA_path_resolve_full(&id_ptr, fcu->rna_path, + &ptr, &prop, &index)) + { + continue; } + DepsNode *node_to = graph_->find_node_from_pointer(&ptr, prop); + if (node_to == NULL) { + continue; + } + OperationDepsNode *operation_to = node_to->get_entry_operation(); + /* NOTE: Special case for bones, avoid relation from animation to + * each of the bones. Bone evaluation could only start from pose + * init anyway. + */ + if (operation_to->opcode == DEG_OPCODE_BONE_LOCAL) { + OperationKey pose_init_key(id, + DEG_NODE_TYPE_EVAL_POSE, + DEG_OPCODE_POSE_INIT); + add_relation(adt_key, pose_init_key, "Animation -> Prop", true); + continue; + } + graph_->add_new_relation(operation_from, operation_to, + "Animation -> Prop", + true); } } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index 99256dc017c..f64ebebda75 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -201,6 +201,7 @@ struct DepsgraphRelationBuilder RootPChanMap *root_map); void build_animdata(ID *id); void build_animdata_curves(ID *id); + void build_animdata_curves_targets(ID *id); void build_animdata_drievrs(ID *id); void build_driver(ID *id, FCurve *fcurve); void build_driver_data(ID *id, FCurve *fcurve); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc index ff805240799..dc88d80fed9 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc @@ -324,11 +324,6 @@ void DepsgraphRelationBuilder::build_rig(Object *object) "Armature Eval"); add_relation(armature_key, init_key, "Data dependency"); - if (needs_animdata_node(&object->id)) { - ComponentKey animation_key(&object->id, DEG_NODE_TYPE_ANIMATION); - add_relation(animation_key, init_key, "Rig Animation"); - } - /* IK Solvers... * - These require separate processing steps are pose-level * to be executed between chains of bones (i.e. once the From b552e03716fde5741084bde38caed89bd8c9b21d Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 5 Dec 2017 16:19:00 +0100 Subject: [PATCH 29/36] Depsgraph: Remove workaround for animated modifiers --- .../intern/builder/deg_builder_relations.cc | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index a9df6efc419..046b44b3c5c 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -1482,7 +1482,6 @@ void DepsgraphRelationBuilder::build_obdata_geom(Object *object) LINKLIST_FOREACH (ModifierData *, md, &object->modifiers) { const ModifierTypeInfo *mti = modifierType_getInfo((ModifierType)md->type); - if (mti->updateDepsgraph) { DepsNodeHandle handle = create_node_handle(obdata_ubereval_key); mti->updateDepsgraph( @@ -1492,23 +1491,10 @@ void DepsgraphRelationBuilder::build_obdata_geom(Object *object) object, reinterpret_cast< ::DepsNodeHandle* >(&handle)); } - if (BKE_object_modifier_use_time(object, md)) { TimeSourceKey time_src_key; add_relation(time_src_key, obdata_ubereval_key, "Time Source"); - - /* Hacky fix for T45633 (Animated modifiers aren't updated) - * - * This check works because BKE_object_modifier_use_time() tests - * for either the modifier needing time, or that it is animated. - */ - /* XXX: Remove this hack when these links are added as part of build_animdata() instead */ - if (modifier_dependsOnTime(md) == false && needs_animdata_node(&object->id)) { - ComponentKey animation_key(&object->id, DEG_NODE_TYPE_ANIMATION); - add_relation(animation_key, obdata_ubereval_key, "Modifier Animation"); - } } - if (md->type == eModifierType_Cloth) { build_cloth(object, md); } From 21ef8e7d29dac03502df62e73986f71f20c2fd9d Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 5 Dec 2017 16:21:28 +0100 Subject: [PATCH 30/36] Depsgraph: Remove workaround for animated geometry component --- .../depsgraph/intern/builder/deg_builder_relations.cc | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 046b44b3c5c..6b84e3ba1c1 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -1619,16 +1619,6 @@ void DepsgraphRelationBuilder::build_obdata_geom(Object *object) if (key) { build_shapekeys(obdata, key); } - - if (needs_animdata_node(obdata)) { - ComponentKey animation_key(obdata, DEG_NODE_TYPE_ANIMATION); - ComponentKey parameters_key(obdata, DEG_NODE_TYPE_PARAMETERS); - add_relation(animation_key, parameters_key, "Geom Parameters"); - /* Evaluation usually depends on animation. - * TODO(sergey): Need to re-hook it after granular update is implemented.. - */ - add_relation(animation_key, obdata_geom_eval_key, "Animation"); - } } /* Cameras */ From 8acca0e9e12cd83ecbe12b9610ff32b6a46269eb Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 5 Dec 2017 16:35:58 +0100 Subject: [PATCH 31/36] Depsgraph: Remove workaround of parameters animation in camera This is something what should be done by build_animation(). --- .../depsgraph/intern/builder/deg_builder_relations.cc | 8 -------- 1 file changed, 8 deletions(-) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 6b84e3ba1c1..e52902b8c8a 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -1631,14 +1631,6 @@ void DepsgraphRelationBuilder::build_camera(Object *object) return; } camera_id->tag |= LIB_TAG_DOIT; - - ComponentKey parameters_key(camera_id, DEG_NODE_TYPE_PARAMETERS); - - if (needs_animdata_node(camera_id)) { - ComponentKey animation_key(camera_id, DEG_NODE_TYPE_ANIMATION); - add_relation(animation_key, parameters_key, "Camera Parameters"); - } - /* DOF */ if (cam->dof_ob) { ComponentKey ob_param_key(&object->id, DEG_NODE_TYPE_PARAMETERS); From 630ed82ff2a953eac0d490aefef30379dc1ec878 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 5 Dec 2017 16:43:27 +0100 Subject: [PATCH 32/36] Depsgraph: Remove workaround of parameters animation in lamp --- .../intern/builder/deg_builder_relations.cc | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index e52902b8c8a..1f384e35fc8 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -1648,21 +1648,13 @@ void DepsgraphRelationBuilder::build_lamp(Object *object) return; } lamp_id->tag |= LIB_TAG_DOIT; - - ComponentKey parameters_key(lamp_id, DEG_NODE_TYPE_PARAMETERS); - - if (needs_animdata_node(lamp_id)) { - ComponentKey animation_key(lamp_id, DEG_NODE_TYPE_ANIMATION); - add_relation(animation_key, parameters_key, "Lamp Parameters"); - } - /* lamp's nodetree */ - if (la->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"); } - /* textures */ build_texture_stack(la->mtex); } From 1915c30a426385dcd0b7533372105448b9233ae6 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 5 Dec 2017 16:47:20 +0100 Subject: [PATCH 33/36] Depsgraph: Remove workaround of parameters animation in node tree --- .../depsgraph/intern/builder/deg_builder_relations.cc | 5 ----- 1 file changed, 5 deletions(-) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 1f384e35fc8..788e73a3e68 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -1711,11 +1711,6 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree) BLI_assert(!"Unknown ID type used for node"); } } - - if (needs_animdata_node(ntree_id)) { - ComponentKey animation_key(ntree_id, DEG_NODE_TYPE_ANIMATION); - add_relation(animation_key, parameters_key, "NTree Parameters"); - } } /* Recursively build graph for material */ From 4c5736a77fc04b457d9187d91342b5d19eab580e Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 5 Dec 2017 16:51:21 +0100 Subject: [PATCH 34/36] Depsgraph: Cleanup, remove unused function --- .../depsgraph/intern/builder/deg_builder_relations.cc | 9 --------- .../depsgraph/intern/builder/deg_builder_relations.h | 2 -- 2 files changed, 11 deletions(-) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 788e73a3e68..5b7b4d4b533 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -1785,15 +1785,6 @@ void DepsgraphRelationBuilder::build_gpencil(bGPdata *gpd) // TODO: parent object (when that feature is implemented) } -bool DepsgraphRelationBuilder::needs_animdata_node(ID *id) -{ - AnimData *adt = BKE_animdata_from_id(id); - if (adt != NULL) { - return (adt->action != NULL) || (adt->nla_tracks.first != NULL); - } - return false; -} - void DepsgraphRelationBuilder::build_cachefile(CacheFile *cache_file) { /* Animation. */ build_animdata(&cache_file->id); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index f64ebebda75..9dd14b631af 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -276,8 +276,6 @@ protected: DepsNodeHandle create_node_handle(const KeyType& key, const char *default_name = ""); - bool needs_animdata_node(ID *id); - template bool is_same_bone_dependency(const KeyFrom& key_from, const KeyTo& key_to); From 99b9e23ce1aad3bb5371fbef76defd7ddc480e5b Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 5 Dec 2017 17:14:17 +0100 Subject: [PATCH 35/36] Depsgraph: Add missing NULL pointer check --- source/blender/depsgraph/intern/depsgraph.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc index 835cf81655a..7e9b2f5c58c 100644 --- a/source/blender/depsgraph/intern/depsgraph.cc +++ b/source/blender/depsgraph/intern/depsgraph.cc @@ -233,6 +233,9 @@ DepsNode *Depsgraph::find_node_from_pointer(const PointerRNA *ptr, } ComponentDepsNode *comp_node = id_node->find_component(node_type, component_name); + if (comp_node == NULL) { + return NULL; + } if (operation_code == DEG_OPCODE_OPERATION) { return comp_node; } @@ -240,7 +243,6 @@ DepsNode *Depsgraph::find_node_from_pointer(const PointerRNA *ptr, operation_name, operation_name_tag); } - return NULL; } From 1027ddfa2d2dc115da8fc48d0bea801a1ff1ce2b Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 5 Dec 2017 17:34:11 +0100 Subject: [PATCH 36/36] Depsgraph: Add missing bone properties to proxy rigs --- .../depsgraph/intern/builder/deg_builder_nodes_rig.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc index 19533272ef5..3ef1eb547b5 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc @@ -285,6 +285,15 @@ void DepsgraphNodeBuilder::build_proxy_rig(Object *object) op_node = add_operation_node(&object->id, DEG_NODE_TYPE_BONE, pchan->name, NULL, DEG_OPCODE_BONE_DONE); op_node->set_as_exit(); + + /* Custom properties. */ + if (pchan->prop != NULL) { + add_operation_node(&object->id, + DEG_NODE_TYPE_PARAMETERS, + NULL, + DEG_OPCODE_PARAMETERS_EVAL, + pchan->name); + } } op_node = add_operation_node(&object->id, DEG_NODE_TYPE_EVAL_POSE,