[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [60222] trunk/blender/source/blender/ blenkernel/intern/depsgraph.c: Fix #36754: animation not evaluated on object two levels down in dupligroups.

Brecht Van Lommel brechtvanlommel at pandora.be
Wed Sep 18 19:09:29 CEST 2013


Revision: 60222
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=60222
Author:   blendix
Date:     2013-09-18 17:09:28 +0000 (Wed, 18 Sep 2013)
Log Message:
-----------
Fix #36754: animation not evaluated on object two levels down in dupligroups.
Depsgraph would only consider one level, now it works recursive.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/depsgraph.c

Modified: trunk/blender/source/blender/blenkernel/intern/depsgraph.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/depsgraph.c	2013-09-18 15:48:24 UTC (rev 60221)
+++ trunk/blender/source/blender/blenkernel/intern/depsgraph.c	2013-09-18 17:09:28 UTC (rev 60222)
@@ -820,12 +820,26 @@
 		dag_add_relation(dag, scenenode, node, DAG_RL_SCENE, "Scene Relation");
 }
 
+static void build_dag_group(DagForest *dag, DagNode *scenenode, Scene *scene, Group *group, short mask)
+{
+	GroupObject *go;
+
+	if (group->id.flag & LIB_DOIT)
+		return;
+	
+	group->id.flag |= LIB_DOIT;
+
+	for (go = group->gobject.first; go; go = go->next) {
+		build_dag_object(dag, scenenode, scene, go->ob, mask);
+		if (go->ob->dup_group)
+			build_dag_group(dag, scenenode, scene, go->ob->dup_group, mask);
+	}
+}
+
 DagForest *build_dag(Main *bmain, Scene *sce, short mask)
 {
 	Base *base;
 	Object *ob;
-	Group *group;
-	GroupObject *go;
 	DagNode *node;
 	DagNode *scenenode;
 	DagForest *dag;
@@ -842,6 +856,7 @@
 	/* clear "LIB_DOIT" flag from all materials, to prevent infinite recursion problems later [#32017] */
 	tag_main_idcode(bmain, ID_MA, FALSE);
 	tag_main_idcode(bmain, ID_LA, FALSE);
+	tag_main_idcode(bmain, ID_GR, FALSE);
 	
 	/* add base node for scene. scene is always the first node in DAG */
 	scenenode = dag_add_node(dag, sce);
@@ -853,21 +868,11 @@
 		build_dag_object(dag, scenenode, sce, ob, mask);
 		if (ob->proxy)
 			build_dag_object(dag, scenenode, sce, ob->proxy, mask);
-		
-		/* handled in next loop */
 		if (ob->dup_group) 
-			ob->dup_group->id.flag |= LIB_DOIT;
+			build_dag_group(dag, scenenode, sce, ob->dup_group, mask);
 	}
 	
-	/* add groups used in current scene objects */
-	for (group = bmain->group.first; group; group = group->id.next) {
-		if (group->id.flag & LIB_DOIT) {
-			for (go = group->gobject.first; go; go = go->next) {
-				build_dag_object(dag, scenenode, sce, go->ob, mask);
-			}
-			group->id.flag &= ~LIB_DOIT;
-		}
-	}
+	tag_main_idcode(bmain, ID_GR, FALSE);
 	
 	/* Now all relations were built, but we need to solve 1 exceptional case;
 	 * When objects have multiple "parents" (for example parent + constraint working on same object)
@@ -1928,6 +1933,25 @@
 		lib_id_recalc_data_tag(bmain, &ob->id);
 
 }
+
+/* recursively update objects in groups, each group is done at most once */
+static void dag_group_update_flags(Main *bmain, Scene *scene, Group *group, const short do_time)
+{
+	GroupObject *go;
+
+	if (group->id.flag & LIB_DOIT)
+		return;
+	
+	group->id.flag |= LIB_DOIT;
+
+	for (go = group->gobject.first; go; go = go->next) {
+		if (do_time)
+			dag_object_time_update_flags(bmain, scene, go->ob);
+		if (go->ob->dup_group)
+			dag_group_update_flags(bmain, scene, go->ob->dup_group, do_time);
+	}
+}
+
 /* flag all objects that need recalc, for changes in time for example */
 /* do_time: make this optional because undo resets objects to their animated locations without this */
 void DAG_scene_update_flags(Main *bmain, Scene *scene, unsigned int lay, const short do_time)
@@ -1938,6 +1962,8 @@
 	GroupObject *go;
 	Scene *sce_iter;
 
+	tag_main_idcode(bmain, ID_GR, FALSE);
+
 	/* set ob flags where animated systems are */
 	for (SETLOOPER(scene, sce_iter, base)) {
 		ob = base->object;
@@ -1952,22 +1978,11 @@
 			dag_object_time_update_flags(bmain, sce_iter, ob);
 		}
 
-		/* handled in next loop */
+		/* recursively tag groups with LIB_DOIT, and update flags for objects */
 		if (ob->dup_group)
-			ob->dup_group->id.flag |= LIB_DOIT;
+			dag_group_update_flags(bmain, scene, ob->dup_group, do_time);
 	}
 
-	if (do_time) {
-		/* we do groups each once */
-		for (group = bmain->group.first; group; group = group->id.next) {
-			if (group->id.flag & LIB_DOIT) {
-				for (go = group->gobject.first; go; go = go->next) {
-					dag_object_time_update_flags(bmain, scene, go->ob);
-				}
-			}
-		}
-	}
-
 	for (sce_iter = scene; sce_iter; sce_iter = sce_iter->set)
 		DAG_scene_flush_update(bmain, sce_iter, lay, 1);
 	
@@ -2049,6 +2064,26 @@
 	}
 }
 
+static void dag_group_on_visible_update(Group *group)
+{
+	GroupObject *go;
+
+	if (group->id.flag & LIB_DOIT)
+		return;
+	
+	group->id.flag |= LIB_DOIT;
+
+	for (go = group->gobject.first; go; go = go->next) {
+		if (ELEM6(go->ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE))
+			go->ob->recalc |= OB_RECALC_DATA;
+		if (go->ob->proxy_from)
+			go->ob->recalc |= OB_RECALC_OB;
+
+		if (go->ob->dup_group)
+			dag_group_on_visible_update(go->ob->dup_group);
+	}
+}
+
 void DAG_on_visible_update(Main *bmain, const short do_time)
 {
 	ListBase listbase;
@@ -2062,8 +2097,6 @@
 		Scene *sce_iter;
 		Base *base;
 		Object *ob;
-		Group *group;
-		GroupObject *go;
 		DagNode *node;
 		unsigned int lay = dsl->layer, oblay;
 	
@@ -2072,6 +2105,7 @@
 		 * note armature poses or object matrices are preserved and do not
 		 * require updates, so we skip those */
 		dag_scene_flush_layers(scene, lay);
+		tag_main_idcode(bmain, ID_GR, FALSE);
 
 		for (SETLOOPER(scene, sce_iter, base)) {
 			ob = base->object;
@@ -2082,22 +2116,11 @@
 				if (ELEM6(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE))
 					ob->recalc |= OB_RECALC_DATA;
 				if (ob->dup_group) 
-					ob->dup_group->id.flag |= LIB_DOIT;
+					dag_group_on_visible_update(ob->dup_group);
 			}
 		}
 
-		for (group = bmain->group.first; group; group = group->id.next) {
-			if (group->id.flag & LIB_DOIT) {
-				for (go = group->gobject.first; go; go = go->next) {
-					if (ELEM6(go->ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE))
-						go->ob->recalc |= OB_RECALC_DATA;
-					if (go->ob->proxy_from)
-						go->ob->recalc |= OB_RECALC_OB;
-				}
-				
-				group->id.flag &= ~LIB_DOIT;
-			}
-		}
+		tag_main_idcode(bmain, ID_GR, FALSE);
 
 		/* now tag update flags, to ensure deformers get calculated on redraw */
 		DAG_scene_update_flags(bmain, scene, lay, do_time);




More information about the Bf-blender-cvs mailing list