diff options
author | Alexander Gavrilov <angavrilov@gmail.com> | 2018-08-09 17:17:40 +0300 |
---|---|---|
committer | Alexander Gavrilov <angavrilov@gmail.com> | 2018-08-13 19:02:49 +0300 |
commit | a5aeca4a64dfd2ec6d0d68acf2fd9e4a9498558d (patch) | |
tree | 22a4b37f06121e36ee35c14046835f08ba702d81 | |
parent | ff6bd57873ec11f7748bc74bf3d628b3cbe38f70 (diff) |
Fix dependency graph for constraints depending on B-Bone shape.
Some constraints have an option to take the final bezier shape of
the target B-Bone into account. This shape usually depends on two
other bones in addition to the target itself, so the graph should
include the relevant dependencies.
Reviewers: sergey
Differential Revision: https://developer.blender.org/D3591
-rw-r--r-- | source/blender/blenkernel/BKE_armature.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/armature.c | 35 | ||||
-rw-r--r-- | source/blender/depsgraph/intern/builder/deg_builder_relations.cc | 83 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_constraint_types.h | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_armature.c | 12 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_constraint.c | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_pose.c | 14 |
7 files changed, 98 insertions, 52 deletions
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index 17329beb325..2e2da281af4 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -140,6 +140,8 @@ typedef struct Mat4 { float mat[4][4]; } Mat4; +void BKE_pchan_get_bbone_handles(struct bPoseChannel *pchan, struct bPoseChannel **r_prev, struct bPoseChannel **r_next); + void equalize_bbone_bezier(float *data, int desired); void b_bone_spline_setup(struct bPoseChannel *pchan, int rest, Mat4 result_array[MAX_BBONE_SUBDIV]); diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index cea81a82f4b..9174038dfbb 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -433,6 +433,25 @@ void equalize_bbone_bezier(float *data, int desired) copy_qt_qt(fp, temp[MAX_BBONE_SUBDIV]); } +/* get "next" and "prev" bones - these are used for handle calculations */ +void BKE_pchan_get_bbone_handles(bPoseChannel *pchan, bPoseChannel **r_prev, bPoseChannel **r_next) +{ + if (pchan->bboneflag & PCHAN_BBONE_CUSTOM_HANDLES) { + /* use the provided bones as the next/prev - leave blank to eliminate this effect altogether */ + *r_prev = pchan->bbone_prev; + *r_next = pchan->bbone_next; + } + else { + /* evaluate next and prev bones */ + if (pchan->bone->flag & BONE_CONNECTED) + *r_prev = pchan->parent; + else + *r_prev = NULL; + + *r_next = pchan->child; + } +} + /* returns pointer to static array, filled with desired amount of bone->segments elements */ /* this calculation is done within unit bone space */ void b_bone_spline_setup(bPoseChannel *pchan, int rest, Mat4 result_array[MAX_BBONE_SUBDIV]) @@ -460,21 +479,7 @@ void b_bone_spline_setup(bPoseChannel *pchan, int rest, Mat4 result_array[MAX_BB } } - /* get "next" and "prev" bones - these are used for handle calculations */ - if (pchan->bboneflag & PCHAN_BBONE_CUSTOM_HANDLES) { - /* use the provided bones as the next/prev - leave blank to eliminate this effect altogether */ - prev = pchan->bbone_prev; - next = pchan->bbone_next; - } - else { - /* evaluate next and prev bones */ - if (bone->flag & BONE_CONNECTED) - prev = pchan->parent; - else - prev = NULL; - - next = pchan->child; - } + BKE_pchan_get_bbone_handles(pchan, &prev, &next); /* find the handle points, since this is inside bone space, the * first point = (0, 0, 0) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 147e80cc794..2efe14557a6 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -185,6 +185,23 @@ static bool check_id_has_anim_component(ID *id) (!BLI_listbase_is_empty(&adt->nla_tracks)); } +static eDepsOperation_Code bone_target_opcode(ID *target, const char *subtarget, ID *id, const char *component_subdata, RootPChanMap *root_map) +{ + /* same armature */ + if (target == id) { + /* Using "done" here breaks in-chain deps, while using + * "ready" here breaks most production rigs instead. + * So, we do a compromise here, and only do this when an + * IK chain conflict may occur. + */ + if (root_map->has_common_root(component_subdata, subtarget)) { + return DEG_OPCODE_BONE_READY; + } + } + + return DEG_OPCODE_BONE_DONE; +} + /* **** General purpose functions **** */ DepsgraphRelationBuilder::DepsgraphRelationBuilder(Main *bmain, @@ -907,38 +924,42 @@ void DepsgraphRelationBuilder::build_constraints(ID *id, add_relation(target_transform_key, constraint_op_key, cti->name); } else if ((ct->tar->type == OB_ARMATURE) && (ct->subtarget[0])) { - /* bone */ - if (&ct->tar->id == id) { - /* same armature */ - eDepsOperation_Code target_key_opcode; - /* Using "done" here breaks in-chain deps, while using - * "ready" here breaks most production rigs instead. - * So, we do a compromise here, and only do this when an - * IK chain conflict may occur. - */ - if (root_map->has_common_root(component_subdata, - ct->subtarget)) - { - target_key_opcode = DEG_OPCODE_BONE_READY; - } - else { - target_key_opcode = DEG_OPCODE_BONE_DONE; + eDepsOperation_Code opcode; + /* relation to bone */ + opcode = bone_target_opcode(&ct->tar->id, ct->subtarget, + id, component_subdata, root_map); + OperationKey target_key(&ct->tar->id, + DEG_NODE_TYPE_BONE, + ct->subtarget, + opcode); + add_relation(target_key, constraint_op_key, cti->name); + /* if needs bbone shape, also reference handles */ + if (con->flag & CONSTRAINT_BBONE_SHAPE) { + bPoseChannel *pchan = BKE_pose_channel_find_name(ct->tar->pose, ct->subtarget); + /* actually a bbone */ + if (pchan && pchan->bone && pchan->bone->segments > 1) { + bPoseChannel *prev, *next; + BKE_pchan_get_bbone_handles(pchan, &prev, &next); + /* add handle links */ + if (prev) { + opcode = bone_target_opcode(&ct->tar->id, prev->name, + id, component_subdata, root_map); + OperationKey prev_key(&ct->tar->id, + DEG_NODE_TYPE_BONE, + prev->name, + opcode); + add_relation(prev_key, constraint_op_key, cti->name); + } + if (next) { + opcode = bone_target_opcode(&ct->tar->id, next->name, + id, component_subdata, root_map); + OperationKey next_key(&ct->tar->id, + DEG_NODE_TYPE_BONE, + next->name, + opcode); + add_relation(next_key, constraint_op_key, cti->name); + } } - OperationKey target_key(&ct->tar->id, - DEG_NODE_TYPE_BONE, - ct->subtarget, - target_key_opcode); - add_relation(target_key, constraint_op_key, cti->name); - } - else { - /* Different armature - we can safely use the result - * of that. - */ - OperationKey target_key(&ct->tar->id, - DEG_NODE_TYPE_BONE, - ct->subtarget, - DEG_OPCODE_BONE_DONE); - add_relation(target_key, constraint_op_key, cti->name); } } else if (ELEM(ct->tar->type, OB_MESH, OB_LATTICE) && diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index ada4073f51f..e1c082748fd 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -524,7 +524,7 @@ typedef enum eBConstraint_Flags { CONSTRAINT_PROXY_LOCAL = (1<<8), /* indicates that constraint is temporarily disabled (only used in GE) */ CONSTRAINT_OFF = (1<<9), - /* use bbone curve shape when calculating headtail values */ + /* use bbone curve shape when calculating headtail values (also used by dependency graph!) */ CONSTRAINT_BBONE_SHAPE = (1<<10), /* That constraint has been inserted in local override (i.e. it can be fully edited!). */ CONSTRAINT_STATICOVERRIDE_LOCAL = (1 << 11), diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c index a4126e921d9..a44ccffdd05 100644 --- a/source/blender/makesrna/intern/rna_armature.c +++ b/source/blender/makesrna/intern/rna_armature.c @@ -52,6 +52,7 @@ #include "BKE_armature.h" #include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" static void rna_Armature_update_data(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { @@ -62,6 +63,15 @@ static void rna_Armature_update_data(Main *UNUSED(bmain), Scene *UNUSED(scene), /*WM_main_add_notifier(NC_OBJECT|ND_POSE, NULL); */ } +static void rna_Armature_dependency_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) +{ + ID *id = ptr->id.data; + + DEG_relations_tag_update(bmain); + + DEG_id_tag_update(id, 0); + WM_main_add_notifier(NC_GEOM | ND_DATA, id); +} static void rna_Armature_act_bone_set(PointerRNA *ptr, PointerRNA value) { @@ -722,7 +732,7 @@ static void rna_def_bone_common(StructRNA *srna, int editbone) RNA_def_property_int_sdna(prop, NULL, "segments"); RNA_def_property_range(prop, 1, 32); RNA_def_property_ui_text(prop, "B-Bone Segments", "Number of subdivisions of bone (for B-Bones only)"); - RNA_def_property_update(prop, 0, "rna_Armature_update_data"); + RNA_def_property_update(prop, 0, "rna_Armature_dependency_update"); prop = RNA_def_property(srna, "bbone_x", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "xwidth"); diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index 1a0dc6dfea6..6cc9d1ef5a6 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -517,7 +517,7 @@ static void rna_def_constraint_headtail_common(StructRNA *srna) prop = RNA_def_property(srna, "use_bbone_shape", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, "bConstraint", "flag", CONSTRAINT_BBONE_SHAPE); RNA_def_property_ui_text(prop, "Follow B-Bone", "Follow shape of B-Bone segments when calculating Head/Tail position"); - RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); + RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update"); } static void rna_def_constraint_target_common(StructRNA *srna) diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index 882e195a520..322f5a02f57 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -127,6 +127,14 @@ static void rna_Pose_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRN WM_main_add_notifier(NC_OBJECT | ND_POSE, ptr->id.data); } +static void rna_Pose_dependency_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) +{ + DEG_relations_tag_update(bmain); + + DEG_id_tag_update(ptr->id.data, OB_RECALC_DATA); + WM_main_add_notifier(NC_OBJECT | ND_POSE, ptr->id.data); +} + static void rna_Pose_IK_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { /* XXX when to use this? ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK); */ @@ -963,7 +971,7 @@ static void rna_def_pose_channel(BlenderRNA *brna) "Use custom reference bones as handles for B-Bones instead of next/previous bones, " "leave these blank to use only B-Bone offset properties to control the shape"); RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable"); - RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update"); + RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_dependency_update"); prop = RNA_def_property(srna, "bbone_custom_handle_start", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "bbone_prev"); @@ -972,7 +980,7 @@ static void rna_def_pose_channel(BlenderRNA *brna) RNA_def_property_ui_text(prop, "B-Bone Start Handle", "Bone that serves as the start handle for the B-Bone curve"); RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable"); - RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update"); + RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_dependency_update"); prop = RNA_def_property(srna, "use_bbone_relative_start_handle", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "bboneflag", PCHAN_BBONE_CUSTOM_START_REL); @@ -988,7 +996,7 @@ static void rna_def_pose_channel(BlenderRNA *brna) RNA_def_property_ui_text(prop, "B-Bone End Handle", "Bone that serves as the end handle for the B-Bone curve"); RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable"); - RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update"); + RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_dependency_update"); prop = RNA_def_property(srna, "use_bbone_relative_end_handle", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "bboneflag", PCHAN_BBONE_CUSTOM_END_REL); |