Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2009-12-08 13:36:46 +0300
committerCampbell Barton <ideasman42@gmail.com>2009-12-08 13:36:46 +0300
commit0391b1ab780b34a149d3c4181d0fe676ef55199e (patch)
treefcc5611cd83129f9c475591d47fb47cea84dc491 /source
parent445d077cf4ecc84b5d5cf422bfb2040186d60164 (diff)
compile python driver expressions for faster re-evaluation.
approx 15-25x speedup
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/intern/fcurve.c7
-rw-r--r--source/blender/blenloader/intern/writefile.c6
-rw-r--r--source/blender/makesdna/DNA_anim_types.h5
-rw-r--r--source/blender/makesrna/intern/rna_fcurve.c9
-rw-r--r--source/blender/python/BPY_extern.h2
-rw-r--r--source/blender/python/intern/bpy_interface.c18
6 files changed, 40 insertions, 7 deletions
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index b3a6b773cf3..04fcd43b883 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -758,7 +758,12 @@ void fcurve_free_driver(FCurve *fcu)
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;
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 2bfc726b7c7..3d654f5ebc9 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -934,8 +934,14 @@ static void write_fcurves(WriteData *wd, ListBase *fcurves)
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);
diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h
index 09f77d98f4b..c5d0231ce62 100644
--- a/source/blender/makesdna/DNA_anim_types.h
+++ b/source/blender/makesdna/DNA_anim_types.h
@@ -291,7 +291,8 @@ typedef struct ChannelDriver {
/* 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 @@ typedef enum eDriver_Flags {
/* 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 -------------------------------------- */
diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c
index bf8b74d08ee..e126175a020 100644
--- a/source/blender/makesrna/intern/rna_fcurve.c
+++ b/source/blender/makesrna/intern/rna_fcurve.c
@@ -105,6 +105,13 @@ static void rna_ChannelDriver_update_data(bContext *C, PointerRNA *ptr)
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 @@ static void rna_def_channeldriver(BlenderRNA *brna)
/* 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);
diff --git a/source/blender/python/BPY_extern.h b/source/blender/python/BPY_extern.h
index a055060ed07..6a94443dd8b 100644
--- a/source/blender/python/BPY_extern.h
+++ b/source/blender/python/BPY_extern.h
@@ -134,7 +134,7 @@ extern "C" {
// 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); */
diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c
index d4d0cbf602f..af1d522600a 100644
--- a/source/blender/python/intern/bpy_interface.c
+++ b/source/blender/python/intern/bpy_interface.c
@@ -549,7 +549,9 @@ int BPY_run_script_space_listener(bContext *C, SpaceScript * sc)
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 @@ static float pydriver_error(ChannelDriver *driver)
float BPY_pydriver_eval (ChannelDriver *driver)
{
PyObject *driver_vars=NULL;
- PyObject *retval;
+ PyObject *retval= NULL;
PyGILState_STATE gilstate;
DriverTarget *dtar;
@@ -772,10 +774,20 @@ float BPY_pydriver_eval (ChannelDriver *driver)
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);