python access to driver namespace, rather then have a textblock defined for drivers allow scripts to add functions directly.
- bpy.app.driver_namespace, read-only dictionary, edit in-place. - reset on file load and new file. - on errors the namespace used to be reset, this should not be needed. simple example. def driverFunc(val): return val * val bpy.app.driver_namespace['driverFunc'] = driverFunc ... now all drivers can access this function.
This commit is contained in:
@@ -118,7 +118,7 @@ extern "C" {
|
||||
// int BPY_do_spacehandlers(struct ScrArea *sa, unsigned short event,
|
||||
// short eventValue, unsigned short space_event);
|
||||
//
|
||||
// void BPY_pydriver_update(void);
|
||||
void BPY_reset_driver(void);
|
||||
float BPY_eval_driver(struct ChannelDriver *driver);
|
||||
//
|
||||
int BPY_eval_button(struct bContext *C, const char *expr, double *value);
|
||||
|
@@ -159,15 +159,34 @@ static PyObject *bpy_app_tempdir_get(PyObject *UNUSED(self), void *UNUSED(closur
|
||||
return PyC_UnicodeFromByte(btempdir);
|
||||
}
|
||||
|
||||
PyGetSetDef bpy_app_debug_getset= {"debug", bpy_app_debug_get, bpy_app_debug_set, "Boolean, set when blender is running in debug mode (started with -d)", NULL};
|
||||
PyGetSetDef bpy_app_tempdir_getset= {"tempdir", bpy_app_tempdir_get, NULL, "String, the temp directory used by blender (read-only)", NULL};
|
||||
static PyObject *bpy_app_driver_dict_get(PyObject *UNUSED(self), void *UNUSED(closure))
|
||||
{
|
||||
if (bpy_pydriver_Dict == NULL)
|
||||
if (bpy_pydriver_create_dict() != 0) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "bpy.app.driver_namespace failed to create dictionary");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_INCREF(bpy_pydriver_Dict);
|
||||
return bpy_pydriver_Dict;
|
||||
}
|
||||
|
||||
|
||||
PyGetSetDef bpy_app_getsets[]= {
|
||||
{"debug", bpy_app_debug_get, bpy_app_debug_set, "Boolean, set when blender is running in debug mode (started with -d)", NULL},
|
||||
{"tempdir", bpy_app_tempdir_get, NULL, "String, the temp directory used by blender (read-only)", NULL},
|
||||
{"driver_namespace", bpy_app_driver_dict_get, NULL, "Dictionary for drivers namespace, editable in-place, reset on file load (read-only)", NULL},
|
||||
{NULL, NULL, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
static void py_struct_seq_getset_init(void)
|
||||
{
|
||||
/* tricky dynamic members, not to py-spec! */
|
||||
|
||||
PyDict_SetItemString(BlenderAppType.tp_dict, bpy_app_debug_getset.name, PyDescr_NewGetSet(&BlenderAppType, &bpy_app_debug_getset));
|
||||
PyDict_SetItemString(BlenderAppType.tp_dict, bpy_app_tempdir_getset.name, PyDescr_NewGetSet(&BlenderAppType, &bpy_app_tempdir_getset));
|
||||
PyGetSetDef *getset;
|
||||
|
||||
for(getset= bpy_app_getsets; getset->name; getset++) {
|
||||
PyDict_SetItemString(BlenderAppType.tp_dict, getset->name, PyDescr_NewGetSet(&BlenderAppType, getset));
|
||||
}
|
||||
}
|
||||
/* end dynamic bpy.app */
|
||||
|
||||
|
@@ -28,4 +28,8 @@
|
||||
|
||||
PyObject *BPY_app_struct( void );
|
||||
|
||||
/* bpy_driver.c */
|
||||
int bpy_pydriver_create_dict(void);
|
||||
extern PyObject *bpy_pydriver_Dict;
|
||||
|
||||
#endif
|
||||
|
@@ -40,7 +40,7 @@ PyObject *bpy_pydriver_Dict = NULL;
|
||||
/* For faster execution we keep a special dictionary for pydrivers, with
|
||||
* the needed modules and aliases.
|
||||
*/
|
||||
static int bpy_pydriver_create_dict(void)
|
||||
int bpy_pydriver_create_dict(void)
|
||||
{
|
||||
PyObject *d, *mod;
|
||||
|
||||
@@ -103,7 +103,7 @@ static int bpy_pydriver_create_dict(void)
|
||||
* reloading the Blender text module "pydrivers.py", if available, so
|
||||
* updates in it reach pydriver evaluation.
|
||||
*/
|
||||
void BPY_pydriver_update(void)
|
||||
void BPY_reset_driver(void)
|
||||
{
|
||||
PyGILState_STATE gilstate;
|
||||
int use_gil= 1; // (PyThreadState_Get()==NULL);
|
||||
@@ -126,12 +126,6 @@ void BPY_pydriver_update(void)
|
||||
/* error return function for BPY_eval_pydriver */
|
||||
static float pydriver_error(ChannelDriver *driver)
|
||||
{
|
||||
if (bpy_pydriver_Dict) { /* free the global dict used by pydrivers */
|
||||
PyDict_Clear(bpy_pydriver_Dict);
|
||||
Py_DECREF(bpy_pydriver_Dict);
|
||||
bpy_pydriver_Dict = NULL;
|
||||
}
|
||||
|
||||
driver->flag |= DRIVER_FLAG_INVALID; /* py expression failed */
|
||||
fprintf(stderr, "\nError in Driver: The following Python expression failed:\n\t'%s'\n\n", driver->expression);
|
||||
|
||||
|
@@ -319,6 +319,7 @@ void WM_read_file(bContext *C, const char *name, ReportList *reports)
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
/* run any texts that were loaded in and flagged as modules */
|
||||
BPY_reset_driver();
|
||||
BPY_load_user_modules(C);
|
||||
#endif
|
||||
CTX_wm_window_set(C, NULL); /* exits queues */
|
||||
@@ -410,6 +411,9 @@ int WM_read_homefile(bContext *C, wmOperator *op)
|
||||
if(CTX_py_init_get(C)) {
|
||||
/* sync addons, these may have changed from the defaults */
|
||||
BPY_eval_string(C, "__import__('bpy').utils.addon_reset_all()");
|
||||
|
||||
BPY_reset_driver();
|
||||
BPY_load_user_modules(C);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@@ -146,6 +146,8 @@ void WM_init(bContext *C, int argc, char **argv)
|
||||
#ifdef WITH_PYTHON
|
||||
BPY_set_context(C); /* necessary evil */
|
||||
BPY_start_python(argc, argv);
|
||||
|
||||
BPY_reset_driver();
|
||||
BPY_load_user_modules(C);
|
||||
#else
|
||||
(void)argc; /* unused */
|
||||
|
@@ -926,6 +926,7 @@ static int load_file(int UNUSED(argc), char **argv, void *data)
|
||||
/* WM_read_file() runs normally but since we're in background mode do here */
|
||||
#ifdef WITH_PYTHON
|
||||
/* run any texts that were loaded in and flagged as modules */
|
||||
BPY_reset_driver();
|
||||
BPY_load_user_modules(C);
|
||||
#endif
|
||||
|
||||
|
Reference in New Issue
Block a user