4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * Contributor(s): Willian P. Germano, Campbell Barton
22 * ***** END GPL LICENSE BLOCK *****
24 /* ****************************************** */
25 /* Drivers - PyExpression Evaluation */
27 #include "DNA_anim_types.h"
29 #include "BLI_listbase.h"
30 #include "BLI_math_base.h"
32 #include "BKE_fcurve.h"
33 #include "BKE_global.h"
37 /* for pydrivers (drivers using one-line Python expressions to express relationships between targets) */
38 PyObject *bpy_pydriver_Dict = NULL;
40 /* For faster execution we keep a special dictionary for pydrivers, with
41 * the needed modules and aliases.
43 static int bpy_pydriver_create_dict(void)
47 /* validate namespace for driver evaluation */
48 if (bpy_pydriver_Dict) return -1;
54 bpy_pydriver_Dict = d;
56 /* import some modules: builtins, bpy, math, (Blender.noise )*/
57 PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins());
59 mod = PyImport_ImportModule("math");
61 PyDict_Merge(d, PyModule_GetDict(mod), 0); /* 0 - dont overwrite existing values */
63 /* Only keep for backwards compat! - just import all math into root, they are standard */
64 PyDict_SetItemString(d, "math", mod);
65 PyDict_SetItemString(d, "m", mod);
69 /* add bpy to global namespace */
70 mod= PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0);
72 PyDict_SetItemString(bpy_pydriver_Dict, "bpy", mod);
77 #if 0 // non existant yet
78 mod = PyImport_ImportModule("Blender.Noise");
80 PyDict_SetItemString(d, "noise", mod);
81 PyDict_SetItemString(d, "n", mod);
87 /* If there's a Blender text called pydrivers.py, import it.
88 * Users can add their own functions to this module.
90 if (G.f & G_SCRIPT_AUTOEXEC) {
91 mod = importText("pydrivers"); /* can also use PyImport_Import() */
93 PyDict_SetItemString(d, "pydrivers", mod);
94 PyDict_SetItemString(d, "p", mod);
100 #endif // non existant yet
105 /* Update function, it gets rid of pydrivers global dictionary, forcing
106 * BPY_pydriver_eval to recreate it. This function is used to force
107 * reloading the Blender text module "pydrivers.py", if available, so
108 * updates in it reach pydriver evaluation.
110 void BPY_pydriver_update(void)
112 PyGILState_STATE gilstate = PyGILState_Ensure();
114 if (bpy_pydriver_Dict) { /* free the global dict used by pydrivers */
115 PyDict_Clear(bpy_pydriver_Dict);
116 Py_DECREF(bpy_pydriver_Dict);
117 bpy_pydriver_Dict = NULL;
120 PyGILState_Release(gilstate);
125 /* error return function for BPY_eval_pydriver */
126 static float pydriver_error(ChannelDriver *driver)
128 if (bpy_pydriver_Dict) { /* free the global dict used by pydrivers */
129 PyDict_Clear(bpy_pydriver_Dict);
130 Py_DECREF(bpy_pydriver_Dict);
131 bpy_pydriver_Dict = NULL;
134 driver->flag |= DRIVER_FLAG_INVALID; /* py expression failed */
135 fprintf(stderr, "\nError in Driver: The following Python expression failed:\n\t'%s'\n\n", driver->expression);
137 // BPy_errors_to_report(NULL); // TODO - reports
144 /* This evals py driver expressions, 'expr' is a Python expression that
145 * should evaluate to a float number, which is returned.
147 float BPY_pydriver_eval (ChannelDriver *driver)
149 PyObject *driver_vars=NULL;
150 PyObject *retval= NULL;
151 PyObject *expr_vars; /* speed up by pre-hashing string & avoids re-converting unicode strings for every execution */
153 PyGILState_STATE gilstate;
156 double result = 0.0; /* default return */
161 /* get the py expression to be evaluated */
162 expr = driver->expression;
163 if ((expr == NULL) || (expr[0]=='\0'))
166 if(!(G.f & G_SCRIPT_AUTOEXEC)) {
167 printf("skipping driver '%s', automatic scripts are disabled\n", driver->expression);
171 gilstate = PyGILState_Ensure();
173 /* init global dictionary for py-driver evaluation settings */
174 if (!bpy_pydriver_Dict) {
175 if (bpy_pydriver_create_dict() != 0) {
176 fprintf(stderr, "Pydriver error: couldn't create Python dictionary");
177 PyGILState_Release(gilstate);
182 if(driver->expr_comp==NULL)
183 driver->flag |= DRIVER_FLAG_RECOMPILE;
185 /* compile the expression first if it hasn't been compiled or needs to be rebuilt */
186 if(driver->flag & DRIVER_FLAG_RECOMPILE) {
187 Py_XDECREF(driver->expr_comp);
188 driver->expr_comp= PyTuple_New(2);
190 expr_code= Py_CompileString(expr, "<bpy driver>", Py_eval_input);
191 PyTuple_SET_ITEM(((PyObject *)driver->expr_comp), 0, expr_code);
193 driver->flag &= ~DRIVER_FLAG_RECOMPILE;
194 driver->flag |= DRIVER_FLAG_RENAMEVAR; /* maybe this can be removed but for now best keep until were sure */
197 expr_code= PyTuple_GET_ITEM(((PyObject *)driver->expr_comp), 0);
200 if(driver->flag & DRIVER_FLAG_RENAMEVAR) {
202 expr_vars= PyTuple_GET_ITEM(((PyObject *)driver->expr_comp), 1);
203 Py_XDECREF(expr_vars);
205 /* intern the arg names so creating the namespace for every run is faster */
206 expr_vars= PyTuple_New(BLI_countlist(&driver->variables));
207 PyTuple_SET_ITEM(((PyObject *)driver->expr_comp), 1, expr_vars);
209 for (dvar= driver->variables.first, i=0; dvar; dvar= dvar->next) {
210 PyTuple_SET_ITEM(expr_vars, i++, PyUnicode_InternFromString(dvar->name));
213 driver->flag &= ~DRIVER_FLAG_RENAMEVAR;
216 expr_vars= PyTuple_GET_ITEM(((PyObject *)driver->expr_comp), 1);
219 /* add target values to a dict that will be used as '__locals__' dict */
220 driver_vars = PyDict_New(); // XXX do we need to decref this?
221 for (dvar= driver->variables.first, i=0; dvar; dvar= dvar->next) {
222 PyObject *driver_arg = NULL;
225 /* try to get variable value */
226 tval= driver_get_variable_value(driver, dvar);
227 driver_arg= PyFloat_FromDouble((double)tval);
229 /* try to add to dictionary */
230 /* if (PyDict_SetItemString(driver_vars, dvar->name, driver_arg)) { */
231 if (PyDict_SetItem(driver_vars, PyTuple_GET_ITEM(expr_vars, i++), driver_arg)) { /* use string interning for faster namespace creation */
232 /* this target failed - bad name */
234 /* first one - print some extra info for easier identification */
235 fprintf(stderr, "\nBPY_pydriver_eval() - Error while evaluating PyDriver:\n");
239 fprintf(stderr, "\tBPY_pydriver_eval() - couldn't add variable '%s' to namespace\n", dvar->name);
240 // BPy_errors_to_report(NULL); // TODO - reports
246 #if 0 // slow, with this can avoid all Py_CompileString above.
247 /* execute expression to get a value */
248 retval = PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict, driver_vars);
250 /* evaluate the compiled expression */
252 retval= PyEval_EvalCode((PyCodeObject *)expr_code, bpy_pydriver_Dict, driver_vars);
255 /* decref the driver vars first... */
256 Py_DECREF(driver_vars);
258 /* process the result */
259 if (retval == NULL) {
260 pydriver_error(driver);
261 } else if((result= PyFloat_AsDouble(retval)) == -1.0 && PyErr_Occurred()) {
262 pydriver_error(driver);
267 /* all fine, make sure the "invalid expression" flag is cleared */
268 driver->flag &= ~DRIVER_FLAG_INVALID;
272 PyGILState_Release(gilstate);
275 return (float)result;
278 fprintf(stderr, "\tBPY_pydriver_eval() - driver '%s' evaluates to '%f'\n", dvar->name, result);