[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [25208] trunk/blender/source/blender: compile python driver expressions for faster re-evaluation.

Campbell Barton ideasman42 at gmail.com
Tue Dec 8 11:36:46 CET 2009


Revision: 25208
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=25208
Author:   campbellbarton
Date:     2009-12-08 11:36:46 +0100 (Tue, 08 Dec 2009)

Log Message:
-----------
compile python driver expressions for faster re-evaluation.
approx 15-25x speedup

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/fcurve.c
    trunk/blender/source/blender/blenloader/intern/writefile.c
    trunk/blender/source/blender/makesdna/DNA_anim_types.h
    trunk/blender/source/blender/makesrna/intern/rna_fcurve.c
    trunk/blender/source/blender/python/BPY_extern.h
    trunk/blender/source/blender/python/intern/bpy_interface.c

Modified: trunk/blender/source/blender/blenkernel/intern/fcurve.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/fcurve.c	2009-12-08 10:02:22 UTC (rev 25207)
+++ trunk/blender/source/blender/blenkernel/intern/fcurve.c	2009-12-08 10:36:46 UTC (rev 25208)
@@ -758,7 +758,12 @@
 		dtarn= dtar->next;
 		driver_free_target(driver, dtar);
 	}
-	
+
+#ifndef DISABLE_PYTHON
+	if(driver->expr_comp)
+		BPY_DECREF(driver->expr_comp);
+#endif
+
 	/* free driver itself, then set F-Curve's point to this to NULL (as the curve may still be used) */
 	MEM_freeN(driver);
 	fcu->driver= NULL;

Modified: trunk/blender/source/blender/blenloader/intern/writefile.c
===================================================================
--- trunk/blender/source/blender/blenloader/intern/writefile.c	2009-12-08 10:02:22 UTC (rev 25207)
+++ trunk/blender/source/blender/blenloader/intern/writefile.c	2009-12-08 10:36:46 UTC (rev 25208)
@@ -934,8 +934,14 @@
 			ChannelDriver *driver= fcu->driver;
 			DriverTarget *dtar;
 			
+			/* don't save compiled python bytecode */
+			void *expr_comp= driver->expr_comp;
+			driver->expr_comp= NULL;
+
 			writestruct(wd, DATA, "ChannelDriver", 1, driver);
 			
+			driver->expr_comp= expr_comp; /* restore */
+
 			/* targets */
 			for (dtar= driver->targets.first; dtar; dtar= dtar->next) {
 				writestruct(wd, DATA, "DriverTarget", 1, dtar);

Modified: trunk/blender/source/blender/makesdna/DNA_anim_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_anim_types.h	2009-12-08 10:02:22 UTC (rev 25207)
+++ trunk/blender/source/blender/makesdna/DNA_anim_types.h	2009-12-08 10:36:46 UTC (rev 25208)
@@ -291,7 +291,8 @@
 	/* python expression to execute (may call functions defined in an accessory file) 
 	 * which relates the target 'variables' in some way to yield a single usable value
 	 */
-	char expression[256]; 
+	char expression[256];
+	void *expr_comp; /* PyObject - compiled expression, dont save this */
 	
 	float curval;		/* result of previous evaluation, for subtraction from result under certain circumstances */
 	float influence;	/* influence of driver on result */ // XXX to be implemented... this is like the constraint influence setting
@@ -322,6 +323,8 @@
 		/* driver does replace value, but overrides (for layering of animation over driver) */
 		// TODO: this needs to be implemented at some stage or left out...
 	DRIVER_FLAG_LAYERING	= (1<<2),
+
+	DRIVER_FLAG_RECOMPILE	= (1<<3), /* use when the expression needs to be recompiled */
 } eDriver_Flags;
 
 /* F-Curves -------------------------------------- */

Modified: trunk/blender/source/blender/makesrna/intern/rna_fcurve.c
===================================================================
--- trunk/blender/source/blender/makesrna/intern/rna_fcurve.c	2009-12-08 10:02:22 UTC (rev 25207)
+++ trunk/blender/source/blender/makesrna/intern/rna_fcurve.c	2009-12-08 10:36:46 UTC (rev 25208)
@@ -105,6 +105,13 @@
 	WM_event_add_notifier(C, NC_SCENE|ND_FRAME, CTX_data_scene(C));
 }
 
+static void rna_ChannelDriver_update_expr(bContext *C, PointerRNA *ptr)
+{
+	ChannelDriver *driver= ptr->data;
+	driver->flag |= DRIVER_FLAG_RECOMPILE;
+	rna_ChannelDriver_update_data(C, ptr);
+}
+
 static void rna_DriverTarget_update_data(bContext *C, PointerRNA *ptr)
 {
 	PointerRNA driverptr;
@@ -807,7 +814,7 @@
 	/* String values */
 	prop= RNA_def_property(srna, "expression", PROP_STRING, PROP_NONE);
 	RNA_def_property_ui_text(prop, "Expression", "Expression to use for Scripted Expression.");
-	RNA_def_property_update(prop, 0, "rna_ChannelDriver_update_data");
+	RNA_def_property_update(prop, 0, "rna_ChannelDriver_update_expr");
 
 	/* Collections */
 	prop= RNA_def_property(srna, "targets", PROP_COLLECTION, PROP_NONE);

Modified: trunk/blender/source/blender/python/BPY_extern.h
===================================================================
--- trunk/blender/source/blender/python/BPY_extern.h	2009-12-08 10:02:22 UTC (rev 25207)
+++ trunk/blender/source/blender/python/BPY_extern.h	2009-12-08 10:36:46 UTC (rev 25208)
@@ -134,7 +134,7 @@
 //	void BPY_scripts_clear_pyobjects( void );
 //
 //	void error_pyscript( void );
-//	void BPY_DECREF(void *pyob_ptr);	/* Py_DECREF() */
+	void BPY_DECREF(void *pyob_ptr);	/* Py_DECREF() */
 	void BPY_set_context(struct bContext *C);
 /* void BPY_Err_Handle(struct Text *text); */
 /* int BPY_spacetext_is_pywin(struct SpaceText *st); */

Modified: trunk/blender/source/blender/python/intern/bpy_interface.c
===================================================================
--- trunk/blender/source/blender/python/intern/bpy_interface.c	2009-12-08 10:02:22 UTC (rev 25207)
+++ trunk/blender/source/blender/python/intern/bpy_interface.c	2009-12-08 10:36:46 UTC (rev 25208)
@@ -549,7 +549,9 @@
 
 void BPY_DECREF(void *pyob_ptr)
 {
+	PyGILState_STATE gilstate = PyGILState_Ensure();
 	Py_DECREF((PyObject *)pyob_ptr);
+	PyGILState_Release(gilstate);
 }
 
 #if 0
@@ -721,7 +723,7 @@
 float BPY_pydriver_eval (ChannelDriver *driver)
 {
 	PyObject *driver_vars=NULL;
-	PyObject *retval;
+	PyObject *retval= NULL;
 	PyGILState_STATE gilstate;
 	
 	DriverTarget *dtar;
@@ -772,10 +774,20 @@
 			BPy_errors_to_report(NULL); // TODO - reports
 		}
 	}
-	
+
+#if 0 // slow
 	/* execute expression to get a value */
 	retval = PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict, driver_vars);
-	
+#else
+	if(driver->flag & DRIVER_FLAG_RECOMPILE || driver->expr_comp==NULL) {
+		Py_XDECREF(driver->expr_comp);
+		driver->expr_comp= Py_CompileString(expr, "<bpy driver>", Py_eval_input);
+		driver->flag &= ~DRIVER_FLAG_RECOMPILE;
+	}
+	if(driver->expr_comp)
+		retval= PyEval_EvalCode(driver->expr_comp, bpy_pydriver_Dict, driver_vars);
+#endif
+
 	/* decref the driver vars first...  */
 	Py_DECREF(driver_vars);
 	





More information about the Bf-blender-cvs mailing list