[Bf-blender-cvs] [92f3b4ac647] blender2.8: Depsgraph: Initial support of armatures for copy-on-write

Sergey Sharybin noreply at git.blender.org
Fri Jul 14 15:06:54 CEST 2017


Commit: 92f3b4ac6470752ea4ec3e7a6d484897c48cc2f2
Author: Sergey Sharybin
Date:   Fri Jul 14 14:56:54 2017 +0200
Branches: blender2.8
https://developer.blender.org/rB92f3b4ac6470752ea4ec3e7a6d484897c48cc2f2

Depsgraph: Initial support of armatures for copy-on-write

This commit makes simple cases to work, for example:

- IK solver to an external object
- Object with Armature modifier, "parented" to the deforming armature
  (via animation).

More complicated setups (like agent rig) are crashing still.

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

M	source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
M	source/blender/depsgraph/intern/builder/deg_builder_nodes.h
M	source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.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 1f8b3ebaa74..935b8c543ec 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -445,39 +445,41 @@ void DepsgraphNodeBuilder::build_object(Scene *scene, Object *ob)
 void DepsgraphNodeBuilder::build_object_transform(Scene *scene, Object *ob)
 {
 	OperationDepsNode *op_node;
+	Scene *scene_cow = get_cow_datablock(scene);
+	Object *ob_cow = get_cow_datablock(ob);
 
 	/* local transforms (from transform channels - loc/rot/scale + deltas) */
 	op_node = add_operation_node(&ob->id, DEG_NODE_TYPE_TRANSFORM,
-	                             function_bind(BKE_object_eval_local_transform, _1, scene, ob),
+	                             function_bind(BKE_object_eval_local_transform,
+	                                           _1,
+	                                           scene_cow, ob_cow),
 	                             DEG_OPCODE_TRANSFORM_LOCAL);
 	op_node->set_as_entry();
 
 	/* object parent */
-	if (ob->parent) {
+	if (ob->parent != NULL) {
 		add_operation_node(&ob->id, DEG_NODE_TYPE_TRANSFORM,
-		                   function_bind(BKE_object_eval_parent, _1, scene, ob),
+		                   function_bind(BKE_object_eval_parent,
+		                                 _1,
+		                                 scene_cow, ob_cow),
 		                   DEG_OPCODE_TRANSFORM_PARENT);
 	}
 
 	/* object constraints */
-	if (ob->constraints.first) {
+	if (ob->constraints.first != NULL) {
 		build_object_constraints(scene, ob);
 	}
 
-	/* Temporary uber-update node, which does everything.
-	 * It is for the being we're porting old dependencies into the new system.
-	 * We'll get rid of this node as soon as all the granular update functions
-	 * are filled in.
-	 *
-	 * TODO(sergey): Get rid of this node.
-	 */
+	/* Rest of transformation update. */
 	add_operation_node(&ob->id, DEG_NODE_TYPE_TRANSFORM,
-	                   function_bind(BKE_object_eval_uber_transform, _1, scene, ob),
+	                   function_bind(BKE_object_eval_uber_transform,
+	                                 _1,
+	                                 scene_cow, ob_cow),
 	                   DEG_OPCODE_OBJECT_UBEREVAL);
 
 	/* object transform is done */
 	op_node = add_operation_node(&ob->id, DEG_NODE_TYPE_TRANSFORM,
-	                             function_bind(BKE_object_eval_done, _1, ob),
+	                             function_bind(BKE_object_eval_done, _1, ob_cow),
 	                             DEG_OPCODE_TRANSFORM_FINAL);
 	op_node->set_as_exit();
 }
@@ -503,7 +505,9 @@ void DepsgraphNodeBuilder::build_object_constraints(Scene *scene, Object *ob)
 {
 	/* create node for constraint stack */
 	add_operation_node(&ob->id, DEG_NODE_TYPE_TRANSFORM,
-	                   function_bind(BKE_object_eval_constraints, _1, scene, ob),
+	                   function_bind(BKE_object_eval_constraints, _1,
+	                                 get_cow_datablock(scene),
+	                                 get_cow_datablock(ob)),
 	                   DEG_OPCODE_TRANSFORM_CONSTRAINTS);
 }
 
@@ -514,23 +518,29 @@ void DepsgraphNodeBuilder::build_object_constraints(Scene *scene, Object *ob)
 void DepsgraphNodeBuilder::build_animdata(ID *id)
 {
 	AnimData *adt = BKE_animdata_from_id(id);
-
-	if (adt == NULL)
+	if (adt == NULL) {
 		return;
+	}
+	ID *id_cow = get_cow_id(id);
 
 	/* animation */
 	if (adt->action || adt->nla_tracks.first || adt->drivers.first) {
-		// XXX: Hook up specific update callbacks for special properties which may need it...
+		// XXX: Hook up specific update callbacks for special properties which
+		// may need it...
 
-		/* actions and NLA - as a single unit for now, as it gets complicated to schedule otherwise */
+		/* actions and NLA - as a single unit for now, as it gets complicated to
+		 * schedule otherwise.
+		 */
 		if ((adt->action) || (adt->nla_tracks.first)) {
 			/* create the node */
 			add_operation_node(id, DEG_NODE_TYPE_ANIMATION,
-			                   function_bind(BKE_animsys_eval_animdata, _1, id),
+			                   function_bind(BKE_animsys_eval_animdata, _1, id_cow),
 			                   DEG_OPCODE_ANIMATION, id->name);
 
-			// TODO: for each channel affected, we might also want to add some support for running RNA update callbacks on them
-			// (which will be needed for proper handling of drivers later)
+			/* TODO: for each channel affected, we might also want to add some
+			 * support for running RNA update callbacks on them
+			 * (which will be needed for proper handling of drivers later)
+			 */
 		}
 
 		/* drivers */
@@ -549,6 +559,7 @@ void DepsgraphNodeBuilder::build_animdata(ID *id)
 OperationDepsNode *DepsgraphNodeBuilder::build_driver(ID *id, FCurve *fcu)
 {
 	ChannelDriver *driver = fcu->driver;
+	ID *id_cow = get_cow_id(id);
 
 	/* Create data node for this driver */
 	/* TODO(sergey): Avoid creating same operation multiple times,
@@ -562,9 +573,10 @@ OperationDepsNode *DepsgraphNodeBuilder::build_driver(ID *id, FCurve *fcu)
 	                                                   fcu->array_index);
 
 	if (driver_op == NULL) {
+		/* TODO(sergey): Shall we use COW of fcu itself here? */
 		driver_op = add_operation_node(id,
 		                               DEG_NODE_TYPE_PARAMETERS,
-		                               function_bind(BKE_animsys_eval_driver, _1, id, fcu),
+		                               function_bind(BKE_animsys_eval_driver, _1, id_cow, fcu),
 		                               DEG_OPCODE_DRIVER,
 		                               fcu->rna_path ? fcu->rna_path : "",
 		                               fcu->array_index);
@@ -608,43 +620,49 @@ void DepsgraphNodeBuilder::build_world(World *world)
 void DepsgraphNodeBuilder::build_rigidbody(Scene *scene)
 {
 	RigidBodyWorld *rbw = scene->rigidbody_world;
+	Scene *scene_cow = get_cow_datablock(scene);
 
 	/**
 	 * Rigidbody Simulation Nodes
 	 * ==========================
 	 *
 	 * There are 3 nodes related to Rigidbody Simulation:
-	 * 1) "Initialize/Rebuild World" - this is called sparingly, only when the simulation
-	 *    needs to be rebuilt (mainly after file reload, or moving back to start frame)
-	 * 2) "Do Simulation" - perform a simulation step - interleaved between the evaluation
-	 *    steps for clusters of objects (i.e. between those affected and/or not affected by
-	 *    the sim for instance)
+	 * 1) "Initialize/Rebuild World" - this is called sparingly, only when the
+	 *    simulation needs to be rebuilt (mainly after file reload, or moving
+	 *    back to start frame)
+	 * 2) "Do Simulation" - perform a simulation step - interleaved between the
+	 *    evaluation steps for clusters of objects (i.e. between those affected
+	 *    and/or not affected by the sim for instance).
 	 *
-	 * 3) "Pull Results" - grab the specific transforms applied for a specific object -
-	 *    performed as part of object's transform-stack building
+	 * 3) "Pull Results" - grab the specific transforms applied for a specific
+	 *    object - performed as part of object's transform-stack building.
 	 */
 
-	/* create nodes ------------------------------------------------------------------------ */
-	/* XXX: is this the right component, or do we want to use another one instead? */
+	/* Create nodes --------------------------------------------------------- */
+
+	/* XXX: is this the right component, or do we want to use another one
+	 * instead?
+	 */
 
 	/* init/rebuild operation */
-	/*OperationDepsNode *init_node =*/ add_operation_node(&scene->id, DEG_NODE_TYPE_TRANSFORM,
-	                                                      function_bind(BKE_rigidbody_rebuild_sim, _1, scene),
-	                                                      DEG_OPCODE_RIGIDBODY_REBUILD);
+	/*OperationDepsNode *init_node =*/ add_operation_node(
+	        &scene->id, DEG_NODE_TYPE_TRANSFORM,
+	        function_bind(BKE_rigidbody_rebuild_sim, _1, scene_cow),
+	        DEG_OPCODE_RIGIDBODY_REBUILD);
 
 	/* do-sim operation */
 	// XXX: what happens if we need to split into several groups?
-	OperationDepsNode *sim_node     = add_operation_node(&scene->id, DEG_NODE_TYPE_TRANSFORM,
-	                                                     function_bind(BKE_rigidbody_eval_simulation, _1, scene),
-	                                                     DEG_OPCODE_RIGIDBODY_SIM);
+	OperationDepsNode *sim_node = add_operation_node(
+	        &scene->id, DEG_NODE_TYPE_TRANSFORM,
+	        function_bind(BKE_rigidbody_eval_simulation, _1, scene_cow),
+	        DEG_OPCODE_RIGIDBODY_SIM);
 
-	/* XXX: For now, the sim node is the only one that really matters here. If any other
-	 * sims get added later, we may have to remove these hacks...
+	/* XXX: For now, the sim node is the only one that really matters here.
+	 * If any other sims get added later, we may have to remove these hacks...
 	 */
 	sim_node->owner->entry_operation = sim_node;
 	sim_node->owner->exit_operation  = sim_node;
 
-
 	/* objects - simulation participants */
 	if (rbw->group) {
 		LINKLIST_FOREACH (GroupObject *, go, &rbw->group->gobject) {
@@ -654,9 +672,13 @@ void DepsgraphNodeBuilder::build_rigidbody(Scene *scene)
 				continue;
 
 			/* 2) create operation for flushing results */
-			/* object's transform component - where the rigidbody operation lives */
+			/* object's transform component - where the rigidbody operation
+			 * lives. */
 			add_operation_node(&ob->id, DEG_NODE_TYPE_TRANSFORM,
-			                   function_bind(BKE_rigidbody_object_sync_transforms, _1, scene, ob),
+			                   function_bind(BKE_rigidbody_object_sync_transforms,
+			                                 _1,
+			                                 scene_cow,
+			                                 get_cow_datablock(ob)),
 			                   DEG_OPCODE_TRANSFORM_RIGIDBODY);
 		}
 	}
@@ -683,6 +705,10 @@ void DepsgraphNodeBuilder::build_particles(Scene *scene, Object *ob)
 	ComponentDepsNode *psys_comp =
 	        add_component_node(&ob->id, DEG_NODE_TYPE_EVAL_PARTICLES);
 
+	/* TODO(sergey): Need to get COW of PSYS. */
+	Scene *scene_cow = get_cow_dat

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list