diff options
author | Campbell Barton <ideasman42@gmail.com> | 2009-12-08 13:36:46 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2009-12-08 13:36:46 +0300 |
commit | 0391b1ab780b34a149d3c4181d0fe676ef55199e (patch) | |
tree | fcc5611cd83129f9c475591d47fb47cea84dc491 /source/blender | |
parent | 445d077cf4ecc84b5d5cf422bfb2040186d60164 (diff) |
compile python driver expressions for faster re-evaluation.
approx 15-25x speedup
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/intern/fcurve.c | 7 | ||||
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 6 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_anim_types.h | 5 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_fcurve.c | 9 | ||||
-rw-r--r-- | source/blender/python/BPY_extern.h | 2 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_interface.c | 18 |
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); |