[Bf-blender-cvs] [b2ca2bb5911] blender2.8: Depsgraph: Add code which helps catching cases when requested ID node is not ready yet

Sergey Sharybin noreply at git.blender.org
Wed Jul 19 17:34:03 CEST 2017


Commit: b2ca2bb59112c775d4d0005f1f6a21e87d650a84
Author: Sergey Sharybin
Date:   Wed Jul 19 11:08:39 2017 +0200
Branches: blender2.8
https://developer.blender.org/rBb2ca2bb59112c775d4d0005f1f6a21e87d650a84

Depsgraph: Add code which helps catching cases when requested ID node is not ready yet

This shows the bug when IK solver doesn't update reliably when targeted an external
object and when that object is handled by build_object() after the armature.

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

M	source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
M	source/blender/depsgraph/intern/depsgraph.cc
M	source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc

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

diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index b38cbf36b9d..b8e64584b14 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -786,8 +786,6 @@ void DepsgraphNodeBuilder::build_shapekeys(Key *key)
 // XXX: what happens if the datablock is shared!
 void DepsgraphNodeBuilder::build_obdata_geom(Scene *scene, Object *ob)
 {
-	ID *obdata = (ID *)ob->data;
-	ID *obdata_cow = get_cow_id(obdata);
 	OperationDepsNode *op_node;
 	Scene *scene_cow = get_cow_datablock(scene);
 	Object *object_cow = get_cow_datablock(ob);
@@ -858,9 +856,14 @@ void DepsgraphNodeBuilder::build_obdata_geom(Scene *scene, Object *ob)
 		// add geometry collider relations
 	}
 
+	ID *obdata = (ID *)ob->data;
 	if (obdata->tag & LIB_TAG_DOIT) {
 		return;
 	}
+	obdata->tag |= LIB_TAG_DOIT;
+	/* Make sure we've got an ID node before requesting CoW pointer. */
+	(void) add_id_node((ID *)obdata);
+	ID *obdata_cow = get_cow_id(obdata);
 
 	/* ShapeKeys */
 	Key *key = BKE_key_from_object(ob);
diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc
index dc3174751bd..e36ecf84539 100644
--- a/source/blender/depsgraph/intern/depsgraph.cc
+++ b/source/blender/depsgraph/intern/depsgraph.cc
@@ -412,6 +412,16 @@ ID *Depsgraph::get_cow_id(const ID *id_orig) const
 {
 	IDDepsNode *id_node = find_id_node(id_orig);
 	if (id_node == NULL) {
+		/* This function is used from places where we expect ID to be either
+		 * already a copy-on-write version or have a corresponding copy-on-write
+		 * version.
+		 *
+		 * We try to enforce that in debug builds, for for release we play a bit
+		 * safer game here.
+		 */
+		if ((id_orig->tag & LIB_TAG_COPY_ON_WRITE) == 0) {
+			BLI_assert(!"Request for non-existing copy-on-write ID");
+		}
 		return (ID *)id_orig;
 	}
 	return id_node->id_cow;
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
index b8eb35747c8..ed9ea9e4d47 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
@@ -286,6 +286,35 @@ Scene *scene_copy_no_main(Scene *scene)
 	return new_scene;
 }
 
+/* Check whether given ID is expanded or still a shallow copy. */
+BLI_INLINE bool check_datablock_expanded(const ID *id_cow)
+{
+	return (id_cow->name[0] != '\0');
+}
+
+/* Check whether datablock was already expanded during depsgraph
+ * construction.
+ */
+static bool check_datablock_expanded_at_construction(const ID *id_orig)
+{
+	const short id_type = GS(id_orig->name);
+	return (id_type == ID_SCE) ||
+	       (id_type == ID_OB && ((Object *)id_orig)->type == OB_ARMATURE) ||
+	       (id_type == ID_AR);
+}
+
+/* Those are datablocks which are not covered by dependency graph and hence
+ * does not need any remapping or anything.
+ */
+static bool check_datablocks_copy_on_writable(const ID *id_orig)
+{
+	const short id_type = GS(id_orig->name);
+	return !ELEM(id_type, ID_BR,
+	                      ID_TE,
+	                      ID_IM,
+	                      ID_LS);
+}
+
 /* Callback for BKE_library_foreach_ID_link which remaps original ID pointer
  * with the one created by CoW system.
  */
@@ -320,7 +349,7 @@ int foreach_libblock_remap_callback(void *user_data_v,
 			              id_orig->name, id_orig, user_data->real_id);
 			*id_p = user_data->real_id;
 		}
-		else {
+		else if (check_datablocks_copy_on_writable(id_orig)) {
 			ID *id_cow = depsgraph->get_cow_id(id_orig);
 			BLI_assert(id_cow != NULL);
 			DEG_COW_PRINT("    Remapping datablock for %s: id_orig=%p id_cow=%p\n",
@@ -331,23 +360,6 @@ int foreach_libblock_remap_callback(void *user_data_v,
 	return IDWALK_RET_NOP;
 }
 
-/* Check whether given ID is expanded or still a shallow copy. */
-BLI_INLINE bool check_datablock_expanded(const ID *id_cow)
-{
-	return (id_cow->name[0] != '\0');
-}
-
-/* Check whether datablock was already expanded during depsgraph
- * construction.
- */
-static bool check_datablock_expanded_at_construction(const ID *id_orig)
-{
-	const short id_type = GS(id_orig->name);
-	return (id_type == ID_SCE) ||
-	       (id_type == ID_OB && ((Object *)id_orig)->type == OB_ARMATURE) ||
-	       (id_type == ID_AR);
-}
-
 /* Do some special treatment of data transfer from original ID to it's
  * CoW complementary part.
  *




More information about the Bf-blender-cvs mailing list