[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [28903] trunk/blender/source/blender: Motion Paths: Experimental optimisations from joeedh for speeding up the calculation process

Joshua Leung aligorith at gmail.com
Fri May 21 14:17:34 CEST 2010


Revision: 28903
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=28903
Author:   aligorith
Date:     2010-05-21 14:17:34 +0200 (Fri, 21 May 2010)

Log Message:
-----------
Motion Paths: Experimental optimisations from joeedh for speeding up the calculation process 

This works by tricking the depsgraph into giving us a smaller list of objects to evaluate, with all the necessary objects + their dependencies at the start of the list. 

On any complicated setup where non-object parameters need to be referred to (i.e. by drivers) to affect an object's transform, these optimisations will fail and the old (slower) method is still the best way (modify the ifdef and comment out the optimise depsgraph call to do so). However, we'll assume that these aren't too common in real productions, so things should be fine with these fixes. If there really is a need for both, then global options to control these things could follow.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/anim.c
    trunk/blender/source/blender/editors/transform/transform_conversions.c
    trunk/blender/source/blender/makesdna/DNA_object_types.h

Modified: trunk/blender/source/blender/blenkernel/intern/anim.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/anim.c	2010-05-21 09:58:26 UTC (rev 28902)
+++ trunk/blender/source/blender/blenkernel/intern/anim.c	2010-05-21 12:17:34 UTC (rev 28903)
@@ -252,6 +252,82 @@
 
 /* ........ */
 
+/* Note on evaluation optimisations:
+ * Optimisations currently used here play tricks with the depsgraph in order to try and 
+ * evaluate as few objects as strictly necessary to get nicer performance under standard
+ * production conditions. For those people who really need the accurate version, 
+ */
+
+/* tweak the object ordering to trick depsgraph into making MotionPath calculations run faster */
+static void motionpaths_calc_optimise_depsgraph(Scene *scene, ListBase *targets)
+{
+	Base *base, *baseNext;
+	MPathTarget *mpt;
+	
+	/* make sure our temp-tag isn't already in use */
+	for (base= scene->base.first; base; base= base->next)
+		base->object->flag &= ~BA_TEMP_TAG;
+	
+	/* for each target, dump its object to the start of the list if it wasn't moved already */
+	for (mpt= targets->first; mpt; mpt= mpt->next) {
+		for (base=scene->base.first; base; base=baseNext) {
+			baseNext = base->next;
+			
+			if ((base->object == mpt->ob) && !(mpt->ob->flag & BA_TEMP_TAG)) {
+				BLI_remlink(&scene->base, base);
+				BLI_addhead(&scene->base, base);
+				
+				mpt->ob->flag |= BA_TEMP_TAG;
+				break; // we really don't need to continue anymore once this happens, but this line might really 'break'
+			}
+		}
+	}
+	
+	/* "brew me a list that's sorted a bit faster now depsy" */
+	DAG_scene_sort(scene);
+}
+
+/* update scene for current frame */
+static void motionpaths_calc_update_scene(Scene *scene)
+{
+#if 1 // 'production' optimisations always on
+	Base *base, *last=NULL;
+	
+	/* only stuff that moves or needs display still */
+	DAG_scene_update_flags(scene, scene->lay);
+	
+	/* find the last object with the tag 
+	 *	- all those afterwards are assumed to not be relevant for our calculations
+	 */
+	// optimise further by moving out...
+	for (base=scene->base.first; base; base=base->next) {
+		if (base->object->flag & BA_TEMP_TAG)
+			last = base;
+	}
+	
+	/* perform updates for tagged objects */
+	// XXX: this will break if rigs depend on scene or other data that 
+	// is animated but not attached to/updatable from objects
+	for (base=scene->base.first; base; base=base->next) {
+		/* update this object */
+		object_handle_update(scene, base->object);
+		
+		/* if this is the last one we need to update, let's stop to save some time */
+		if (base == last)
+			break;
+	}
+#else // original, 'always correct' version
+	/* do all updates 
+	 *	- if this is too slow, resort to using a more efficient way 
+	 * 	  that doesn't force complete update, but for now, this is the
+	 *	  most accurate way!
+	 */
+	scene_update_for_newframe(scene, scene->lay); // XXX this is the best way we can get anything moving
+#endif
+}
+
+/* ........ */
+
 /* perform baking for the targets on the current frame */
 static void motionpaths_calc_bake_targets(Scene *scene, ListBase *targets)
 {
@@ -313,7 +389,7 @@
 	
 	// TODO: this method could be improved...
 	//	1) max range for standard baking
-	//	2) minimum range for recalc baking (i.e. between keyfames, but how?)
+	//	2) minimum range for recalc baking (i.e. between keyframes, but how?)
 	for (mpt= targets->first; mpt; mpt= mpt->next) {
 		/* try to increase area to do (only as much as needed) */
 		sfra= MIN2(sfra, mpt->mpath->start_frame);
@@ -321,14 +397,14 @@
 	}
 	if (efra <= sfra) return;
 	
+	/* optimise the depsgraph for faster updates */
+	// TODO: whether this is used should depend on some setting for the level of optimisations used
+	motionpaths_calc_optimise_depsgraph(scene, targets);
+	
 	/* calculate path over requested range */
 	for (CFRA=sfra; CFRA<=efra; CFRA++) {
-		/* do all updates 
-		 *	- if this is too slow, resort to using a more efficient way 
-		 * 	  that doesn't force complete update, but for now, this is the
-		 *	  most accurate way!
-		 */
-		scene_update_for_newframe(scene, scene->lay); // XXX this is the best way we can get anything moving
+		/* update relevant data for new frame */
+		motionpaths_calc_update_scene(scene);
 		
 		/* perform baking for targets */
 		motionpaths_calc_bake_targets(scene, targets);
@@ -336,7 +412,7 @@
 	
 	/* reset original environment */
 	CFRA= cfra;
-	scene_update_for_newframe(scene, scene->lay); // XXX this is the best way we can get anything moving
+	motionpaths_calc_update_scene(scene);
 	
 	/* clear recalc flags from targets */
 	for (mpt= targets->first; mpt; mpt= mpt->next) {

Modified: trunk/blender/source/blender/editors/transform/transform_conversions.c
===================================================================
--- trunk/blender/source/blender/editors/transform/transform_conversions.c	2010-05-21 09:58:26 UTC (rev 28902)
+++ trunk/blender/source/blender/editors/transform/transform_conversions.c	2010-05-21 12:17:34 UTC (rev 28903)
@@ -4499,7 +4499,7 @@
 		if(base->flag & BA_WAS_SEL)
 			base->flag |= SELECT;
 
-		base->flag &= ~(BA_WAS_SEL|BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA|BA_DO_IPO|BA_TRANSFORM_CHILD|BA_TRANSFORM_PARENT);
+		base->flag &= ~(BA_WAS_SEL|BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA|BA_TEMP_TAG|BA_TRANSFORM_CHILD|BA_TRANSFORM_PARENT);
 	}
 }
 

Modified: trunk/blender/source/blender/makesdna/DNA_object_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_object_types.h	2010-05-21 09:58:26 UTC (rev 28902)
+++ trunk/blender/source/blender/makesdna/DNA_object_types.h	2010-05-21 12:17:34 UTC (rev 28903)
@@ -412,14 +412,15 @@
 #define BA_HAS_RECALC_OB	4
 #define BA_HAS_RECALC_DATA	8
 
-	// XXX DEPRECEATED SETTING...
-#define BA_DO_IPO			32
+	/* NOTE: this was used as a proper setting in past, so nullify before using */
+#define BA_TEMP_TAG			32
 
 #define BA_FROMSET			128
 
 #define BA_TRANSFORM_CHILD	256 /* child of a transformed object */
 #define BA_TRANSFORM_PARENT	8192 /* parent of a transformed object */
 
+
 /* an initial attempt as making selection more specific! */
 #define BA_DESELECT		0
 #define BA_SELECT		1





More information about the Bf-blender-cvs mailing list