[Bf-blender-cvs] [dce19ba] depsgraph_refactor: Depsgraph: Experiment with bettr handling of parents when there are IK solvers

Sergey Sharybin noreply at git.blender.org
Fri Nov 21 14:32:13 CET 2014


Commit: dce19babfa213609e3af0ca20844dd2ef3519b5a
Author: Sergey Sharybin
Date:   Fri Nov 21 14:27:56 2014 +0100
Branches: depsgraph_refactor
https://developer.blender.org/rBdce19babfa213609e3af0ca20844dd2ef3519b5a

Depsgraph: Experiment with bettr handling of parents when there are IK solvers

The main issue here is that pchans from the same IK solver chain should use pre-solver
position of the parent pchan. But in cases when pchan's parent is in different solver
it's child should depend on the solved result of the bone transform.

The last rule was violated in previous implementation. Now added quite quick and not
so quick code to check if pchan and it's parent are in the same IK solver and made
dependencies built based on this information/

This isn't final at all, committing just for the reference. Next step would be to gather
all collected knowledge from this week and implement rig dependencies in a really clean
fashion.

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

M	source/blender/depsgraph/intern/depsgraph_build.h
M	source/blender/depsgraph/intern/depsgraph_build_relations.cpp

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

diff --git a/source/blender/depsgraph/intern/depsgraph_build.h b/source/blender/depsgraph/intern/depsgraph_build.h
index 76c49a4..7ba0b04 100644
--- a/source/blender/depsgraph/intern/depsgraph_build.h
+++ b/source/blender/depsgraph/intern/depsgraph_build.h
@@ -206,6 +206,9 @@ struct RNAPathKey
 };
 
 struct DepsgraphRelationBuilder {
+	typedef vector<const char*> RootPChanVector;
+	typedef unordered_map<const char*, RootPChanVector> RootPChanMap;
+
 	DepsgraphRelationBuilder(Depsgraph *graph);
 	
 	template <typename KeyFrom, typename KeyTo>
@@ -229,8 +232,8 @@ struct DepsgraphRelationBuilder {
 	void build_world(Scene *scene, World *world);
 	void build_rigidbody(Scene *scene);
 	void build_particles(Scene *scene, Object *ob);
-	void build_ik_pose(Object *ob, bPoseChannel *pchan, bConstraint *con);
-	void build_splineik_pose(Object *ob, bPoseChannel *pchan, bConstraint *con);
+	void build_ik_pose(Object *ob, bPoseChannel *pchan, bConstraint *con, RootPChanMap *root_map);
+	void build_splineik_pose(Object *ob, bPoseChannel *pchan, bConstraint *con, RootPChanMap *root_map);
 	void build_rig(Scene *scene, Object *ob);
 	void build_shapekeys(ID *obdata, Key *key);
 	void build_obdata_geom(Scene *scene, Object *ob);
diff --git a/source/blender/depsgraph/intern/depsgraph_build_relations.cpp b/source/blender/depsgraph/intern/depsgraph_build_relations.cpp
index 5b77b25..7598ac0 100644
--- a/source/blender/depsgraph/intern/depsgraph_build_relations.cpp
+++ b/source/blender/depsgraph/intern/depsgraph_build_relations.cpp
@@ -747,8 +747,60 @@ static bPoseChannel* splineik_solver_rootchan_find(bPoseChannel *pchan,
 	return rootchan;
 }
 
+static void root_map_add_bone(const char *bone,
+                              const char *root,
+                              DepsgraphRelationBuilder::RootPChanMap *root_map)
+{
+	DepsgraphRelationBuilder::RootPChanMap::iterator found = root_map->find(bone);
+	printf("%s: %s %s\n", __func__, bone, root);
+	if (found != root_map->end()) {
+		found->second.push_back(root);
+	}
+	else {
+		DepsgraphRelationBuilder::RootPChanVector new_vector;
+		new_vector.push_back(root);
+		root_map->insert(std::pair<const char*, DepsgraphRelationBuilder::RootPChanVector> (bone, new_vector));
+	}
+}
+
+static bool pchan_check_common_solver_root(const DepsgraphRelationBuilder::RootPChanMap &root_map,
+                                           const char *pchan1, const char *pchan2)
+{
+	const DepsgraphRelationBuilder::RootPChanMap::const_iterator found1 = root_map.find(pchan1);
+	if (found1 == root_map.end()) {
+		return false;
+	}
+
+	const DepsgraphRelationBuilder::RootPChanMap::const_iterator found2 = root_map.find(pchan2);
+	if (found2 == root_map.end()) {
+		return false;
+	}
+
+	const DepsgraphRelationBuilder::RootPChanVector &vec1 = found1->second;
+	const DepsgraphRelationBuilder::RootPChanVector &vec2 = found2->second;
+
+	for (DepsgraphRelationBuilder::RootPChanVector::const_iterator it1 = vec1.begin();
+	     it1 != vec1.end();
+	     ++it1)
+	{
+		for (DepsgraphRelationBuilder::RootPChanVector::const_iterator it2 = vec2.begin();
+		     it2 != vec2.end();
+		     ++it2)
+		{
+			if (strcmp(*it1, *it2) == 0) {
+				return true;
+			}
+		}
+	}
+
+	return false;
+}
+
 /* IK Solver Eval Steps */
-void DepsgraphRelationBuilder::build_ik_pose(Object *ob, bPoseChannel *pchan, bConstraint *con)
+void DepsgraphRelationBuilder::build_ik_pose(Object *ob,
+                                             bPoseChannel *pchan,
+                                             bConstraint *con,
+                                             RootPChanMap *root_map)
 {
 	bKinematicConstraint *data = (bKinematicConstraint *)con->data;
 	
@@ -786,6 +838,7 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *ob, bPoseChannel *pchan, bC
 			add_relation(target_key, pose_key, DEPSREL_TYPE_TRANSFORM, con->name);
 		}
 	}
+	root_map_add_bone(pchan->name, rootchan->name, root_map);
 
 	bPoseChannel *parchan = pchan;
 	/* exclude tip from chain? */
@@ -810,6 +863,8 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *ob, bPoseChannel *pchan, bC
 		OperationKey final_transforms_key(&ob->id, DEPSNODE_TYPE_BONE, parchan->name, "Bone Final Transforms");
 		add_relation(solver_key, final_transforms_key, DEPSREL_TYPE_TRANSFORM, "IK Solver Result");
 
+		root_map_add_bone(parchan->name, rootchan->name, root_map);
+
 		/* continue up chain, until we reach target number of items... */
 		segcount++;
 		if ((segcount == data->rootbone) || (segcount > 255)) break;  /* 255 is weak */
@@ -822,7 +877,10 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *ob, bPoseChannel *pchan, bC
 }
 
 /* Spline IK Eval Steps */
-void DepsgraphRelationBuilder::build_splineik_pose(Object *ob, bPoseChannel *pchan, bConstraint *con)
+void DepsgraphRelationBuilder::build_splineik_pose(Object *ob,
+                                                   bPoseChannel *pchan,
+                                                   bConstraint *con,
+                                                   RootPChanMap *root_map)
 {
 	bSplineIKConstraint *data = (bSplineIKConstraint *)con->data;
 	bPoseChannel *rootchan = splineik_solver_rootchan_find(pchan, data);
@@ -850,6 +908,8 @@ void DepsgraphRelationBuilder::build_splineik_pose(Object *ob, bPoseChannel *pch
 	OperationKey final_transforms_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, "Bone Final Transforms");
 	add_relation(solver_key, final_transforms_key, DEPSREL_TYPE_TRANSFORM, "IK Solver Result");
 
+	root_map_add_bone(pchan->name, rootchan->name, root_map);
+
 	/* Walk to the chain's root */
 	size_t segcount = 0;
 	for (bPoseChannel *parchan = pchan->parent; parchan; parchan = parchan->parent) {
@@ -868,6 +928,8 @@ void DepsgraphRelationBuilder::build_splineik_pose(Object *ob, bPoseChannel *pch
 		OperationKey final_transforms_key(&ob->id, DEPSNODE_TYPE_BONE, parchan->name, "Bone Final Transforms");
 		add_relation(solver_key, final_transforms_key, DEPSREL_TYPE_TRANSFORM, "IK Solver Result");
 
+		root_map_add_bone(parchan->name, rootchan->name, root_map);
+
 		/* continue up chain, until we reach target number of items... */
 		segcount++;
 		if ((segcount == data->chainlen) || (segcount > 255)) break;  /* 255 is weak */
@@ -932,15 +994,16 @@ void DepsgraphRelationBuilder::build_rig(Scene *scene, Object *ob)
 	 * - Care is needed to ensure that multi-headed trees work out the same as in ik-tree building
 	 * - Animated chain-lengths are a problem...
 	 */
+	RootPChanMap root_map;
 	for (bPoseChannel *pchan = (bPoseChannel *)ob->pose->chanbase.first; pchan; pchan = pchan->next) {
 		for (bConstraint *con = (bConstraint *)pchan->constraints.first; con; con = con->next) {
 			switch (con->type) {
 				case CONSTRAINT_TYPE_KINEMATIC:
-					build_ik_pose(ob, pchan, con);
+					build_ik_pose(ob, pchan, con, &root_map);
 					break;
 					
 				case CONSTRAINT_TYPE_SPLINEIK:
-					build_splineik_pose(ob, pchan, con);
+					build_splineik_pose(ob, pchan, con, &root_map);
 					break;
 					
 				default:
@@ -956,7 +1019,13 @@ void DepsgraphRelationBuilder::build_rig(Scene *scene, Object *ob)
 		/* bone parent */
 		if (pchan->parent != NULL) {
 			ComponentKey bone_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->name);
+			bool has_common_root = false;
 			if (pchan->flag & POSE_DONE) {
+				has_common_root = pchan_check_common_solver_root(root_map,
+				                                                 pchan->name,
+				                                                 pchan->parent->name);
+			}
+			if (has_common_root) {
 				OperationKey parent_transforms_key = bone_transforms_key(ob, pchan->parent);
 				add_relation(parent_transforms_key, bone_key, DEPSREL_TYPE_TRANSFORM, "[Parent Bone -> Child Bone]");
 			}




More information about the Bf-blender-cvs mailing list