[Bf-blender-cvs] [a5aeca4a64d] blender2.8: Fix dependency graph for constraints depending on B-Bone shape.

Alexander Gavrilov noreply at git.blender.org
Mon Aug 13 18:21:32 CEST 2018


Commit: a5aeca4a64dfd2ec6d0d68acf2fd9e4a9498558d
Author: Alexander Gavrilov
Date:   Thu Aug 9 17:17:40 2018 +0300
Branches: blender2.8
https://developer.blender.org/rBa5aeca4a64dfd2ec6d0d68acf2fd9e4a9498558d

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

===================================================================

M	source/blender/blenkernel/BKE_armature.h
M	source/blender/blenkernel/intern/armature.c
M	source/blender/depsgraph/intern/builder/deg_builder_relations.cc
M	source/blender/makesdna/DNA_constraint_types.h
M	source/blender/makesrna/intern/rna_armature.c
M	source/blender/makesrna/intern/rna_constraint.c
M	source/blender/makesrna/intern/rna_pose.c

===================================================================

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(bm

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list