forked from bartvdbraak/blender
pydrivers: 'frame' is now in the driver namespace,
- no need to link to scenes when using a frame from the pydriver, this made linking rigs for eg, quite messy. - advantage that we get subframe values (where scenes from was fixed to a whole number).
This commit is contained in:
parent
1cfbde0eb4
commit
db44a92a11
@ -1576,7 +1576,7 @@ float driver_get_variable_value (ChannelDriver *driver, DriverVar *dvar)
|
|||||||
* - "evaltime" is the frame at which F-Curve is being evaluated
|
* - "evaltime" is the frame at which F-Curve is being evaluated
|
||||||
* - has to return a float value
|
* - has to return a float value
|
||||||
*/
|
*/
|
||||||
static float evaluate_driver (ChannelDriver *driver, float UNUSED(evaltime))
|
static float evaluate_driver (ChannelDriver *driver, const float evaltime)
|
||||||
{
|
{
|
||||||
DriverVar *dvar;
|
DriverVar *dvar;
|
||||||
|
|
||||||
@ -1663,8 +1663,10 @@ static float evaluate_driver (ChannelDriver *driver, float UNUSED(evaltime))
|
|||||||
/* this evaluates the expression using Python,and returns its result:
|
/* this evaluates the expression using Python,and returns its result:
|
||||||
* - on errors it reports, then returns 0.0f
|
* - on errors it reports, then returns 0.0f
|
||||||
*/
|
*/
|
||||||
driver->curval= BPY_driver_exec(driver);
|
driver->curval= BPY_driver_exec(driver, evaltime);
|
||||||
}
|
}
|
||||||
|
#else /* WITH_PYTHON*/
|
||||||
|
(void)evaltime;
|
||||||
#endif /* WITH_PYTHON*/
|
#endif /* WITH_PYTHON*/
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2087,7 +2089,7 @@ static float fcurve_eval_samples (FCurve *fcu, FPoint *fpts, float evaltime)
|
|||||||
/* Evaluate and return the value of the given F-Curve at the specified frame ("evaltime")
|
/* Evaluate and return the value of the given F-Curve at the specified frame ("evaltime")
|
||||||
* Note: this is also used for drivers
|
* Note: this is also used for drivers
|
||||||
*/
|
*/
|
||||||
float evaluate_fcurve (FCurve *fcu, float evaltime)
|
float evaluate_fcurve (FCurve *fcu, float evaltime)
|
||||||
{
|
{
|
||||||
float cvalue= 0.0f;
|
float cvalue= 0.0f;
|
||||||
float devaltime;
|
float devaltime;
|
||||||
|
@ -164,24 +164,7 @@ int ui_but_anim_expression_create(uiBut *but, const char *str)
|
|||||||
/* set the expression */
|
/* set the expression */
|
||||||
// TODO: need some way of identifying variables used
|
// TODO: need some way of identifying variables used
|
||||||
BLI_strncpy_utf8(driver->expression, str, sizeof(driver->expression));
|
BLI_strncpy_utf8(driver->expression, str, sizeof(driver->expression));
|
||||||
|
|
||||||
/* FIXME: for now, assume that
|
|
||||||
* - for expressions, users are likely to be using "frame" -> current frame" as a variable
|
|
||||||
* - driver_add_new_variable() adds a single-prop variable by default
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
DriverVar *dvar;
|
|
||||||
DriverTarget *dtar;
|
|
||||||
|
|
||||||
dvar = driver_add_new_variable(driver);
|
|
||||||
BLI_strncpy(dvar->name, "frame", sizeof(dvar->name));
|
|
||||||
|
|
||||||
dtar = &dvar->targets[0];
|
|
||||||
dtar->id = (ID *)CTX_data_scene(C); // XXX: should we check that C is valid first?
|
|
||||||
dtar->idtype= ID_SCE;
|
|
||||||
dtar->rna_path = BLI_sprintfN("frame_current");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* updates */
|
/* updates */
|
||||||
driver->flag |= DRIVER_FLAG_RECOMPILE;
|
driver->flag |= DRIVER_FLAG_RECOMPILE;
|
||||||
WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME, NULL);
|
WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME, NULL);
|
||||||
|
@ -74,7 +74,7 @@ void BPY_modules_load_user(struct bContext *C);
|
|||||||
void BPY_app_handlers_reset(const short do_all);
|
void BPY_app_handlers_reset(const short do_all);
|
||||||
|
|
||||||
void BPY_driver_reset(void);
|
void BPY_driver_reset(void);
|
||||||
float BPY_driver_exec(struct ChannelDriver *driver);
|
float BPY_driver_exec(struct ChannelDriver *driver, const float evaltime);
|
||||||
|
|
||||||
int BPY_button_exec(struct bContext *C, const char *expr, double *value, const short verbose);
|
int BPY_button_exec(struct bContext *C, const char *expr, double *value, const short verbose);
|
||||||
int BPY_string_exec(struct bContext *C, const char *expr);
|
int BPY_string_exec(struct bContext *C, const char *expr);
|
||||||
|
@ -91,6 +91,29 @@ int bpy_pydriver_create_dict(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* note, this function should do nothing most runs, only when changing frame */
|
||||||
|
static PyObject *bpy_pydriver_InternStr__frame= NULL;
|
||||||
|
|
||||||
|
static void bpy_pydriver_update_dict(const float evaltime)
|
||||||
|
{
|
||||||
|
/* not thread safe but neither is python */
|
||||||
|
static float evaltime_prev= FLT_MAX;
|
||||||
|
|
||||||
|
if (evaltime_prev != evaltime) {
|
||||||
|
|
||||||
|
/* currently only update the frame */
|
||||||
|
if (bpy_pydriver_InternStr__frame == NULL) {
|
||||||
|
bpy_pydriver_InternStr__frame= PyUnicode_FromString("frame");
|
||||||
|
}
|
||||||
|
|
||||||
|
PyDict_SetItem(bpy_pydriver_Dict,
|
||||||
|
bpy_pydriver_InternStr__frame,
|
||||||
|
PyFloat_FromDouble(evaltime));
|
||||||
|
|
||||||
|
evaltime_prev= evaltime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Update function, it gets rid of pydrivers global dictionary, forcing
|
/* Update function, it gets rid of pydrivers global dictionary, forcing
|
||||||
* BPY_driver_exec to recreate it. This function is used to force
|
* BPY_driver_exec to recreate it. This function is used to force
|
||||||
* reloading the Blender text module "pydrivers.py", if available, so
|
* reloading the Blender text module "pydrivers.py", if available, so
|
||||||
@ -110,6 +133,11 @@ void BPY_driver_reset(void)
|
|||||||
bpy_pydriver_Dict= NULL;
|
bpy_pydriver_Dict= NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bpy_pydriver_InternStr__frame) {
|
||||||
|
Py_DECREF(bpy_pydriver_InternStr__frame);
|
||||||
|
bpy_pydriver_InternStr__frame= NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (use_gil)
|
if (use_gil)
|
||||||
PyGILState_Release(gilstate);
|
PyGILState_Release(gilstate);
|
||||||
|
|
||||||
@ -139,7 +167,7 @@ static void pydriver_error(ChannelDriver *driver)
|
|||||||
* now release the GIL on python operator execution instead, using
|
* now release the GIL on python operator execution instead, using
|
||||||
* PyEval_SaveThread() / PyEval_RestoreThread() so we dont lock up blender.
|
* PyEval_SaveThread() / PyEval_RestoreThread() so we dont lock up blender.
|
||||||
*/
|
*/
|
||||||
float BPY_driver_exec(ChannelDriver *driver)
|
float BPY_driver_exec(ChannelDriver *driver, const float evaltime)
|
||||||
{
|
{
|
||||||
PyObject *driver_vars=NULL;
|
PyObject *driver_vars=NULL;
|
||||||
PyObject *retval= NULL;
|
PyObject *retval= NULL;
|
||||||
@ -183,6 +211,10 @@ float BPY_driver_exec(ChannelDriver *driver)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* update global namespace */
|
||||||
|
bpy_pydriver_update_dict(evaltime);
|
||||||
|
|
||||||
|
|
||||||
if (driver->expr_comp==NULL)
|
if (driver->expr_comp==NULL)
|
||||||
driver->flag |= DRIVER_FLAG_RECOMPILE;
|
driver->flag |= DRIVER_FLAG_RECOMPILE;
|
||||||
|
|
||||||
@ -246,6 +278,7 @@ float BPY_driver_exec(ChannelDriver *driver)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if 0 // slow, with this can avoid all Py_CompileString above.
|
#if 0 // slow, with this can avoid all Py_CompileString above.
|
||||||
/* execute expression to get a value */
|
/* execute expression to get a value */
|
||||||
retval= PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict, driver_vars);
|
retval= PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict, driver_vars);
|
||||||
|
@ -33,7 +33,7 @@ int bpy_pydriver_create_dict(void);
|
|||||||
extern PyObject *bpy_pydriver_Dict;
|
extern PyObject *bpy_pydriver_Dict;
|
||||||
|
|
||||||
/* externals */
|
/* externals */
|
||||||
float BPY_driver_exec(struct ChannelDriver *driver);
|
float BPY_driver_exec(struct ChannelDriver *driver, const float evaltime);
|
||||||
void BPY_driver_reset(void);
|
void BPY_driver_reset(void);
|
||||||
|
|
||||||
#endif // BPY_DRIVER_H
|
#endif // BPY_DRIVER_H
|
||||||
|
@ -454,7 +454,7 @@ void BPY_text_free_code(struct Text *text) {}
|
|||||||
void BPY_id_release(struct Text *text) {}
|
void BPY_id_release(struct Text *text) {}
|
||||||
int BPY_context_member_get(struct Context *C, const char *member, struct bContextDataResult *result) { return 0; }
|
int BPY_context_member_get(struct Context *C, const char *member, struct bContextDataResult *result) { return 0; }
|
||||||
void BPY_pyconstraint_target(struct bPythonConstraint *con, struct bConstraintTarget *ct) {}
|
void BPY_pyconstraint_target(struct bPythonConstraint *con, struct bConstraintTarget *ct) {}
|
||||||
float BPY_driver_exec(struct ChannelDriver *driver) {return 0.0f;} /* might need this one! */
|
float BPY_driver_exec(struct ChannelDriver *driver, const float evaltime) {return 0.0f;} /* might need this one! */
|
||||||
void BPY_DECREF(void *pyob_ptr) {}
|
void BPY_DECREF(void *pyob_ptr) {}
|
||||||
void BPY_pyconstraint_exec(struct bPythonConstraint *con, struct bConstraintOb *cob, struct ListBase *targets) {}
|
void BPY_pyconstraint_exec(struct bPythonConstraint *con, struct bConstraintOb *cob, struct ListBase *targets) {}
|
||||||
void macro_wrapper(struct wmOperatorType *ot, void *userdata) {} ;
|
void macro_wrapper(struct wmOperatorType *ot, void *userdata) {} ;
|
||||||
|
Loading…
Reference in New Issue
Block a user