2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * Contributor(s): Willian P. Germano, Campbell Barton
20 * ***** END GPL LICENSE BLOCK *****
23 /** \file blender/python/intern/bpy_driver.c
24 * \ingroup pythonintern
26 * This file defines the 'BPY_driver_exec' to execute python driver expressions,
27 * called by the animation system, there are also some utility functions
28 * to deal with the namespace used for driver execution.
31 /* ****************************************** */
32 /* Drivers - PyExpression Evaluation */
36 #include "DNA_anim_types.h"
38 #include "BLI_listbase.h"
39 #include "BLI_math_base.h"
41 #include "BKE_fcurve.h"
42 #include "BKE_global.h"
44 #include "bpy_driver.h"
46 extern void BPY_update_rna_module(void);
49 /* for pydrivers (drivers using one-line Python expressions to express relationships between targets) */
50 PyObject *bpy_pydriver_Dict= NULL;
52 /* For faster execution we keep a special dictionary for pydrivers, with
53 * the needed modules and aliases.
55 int bpy_pydriver_create_dict(void)
59 /* validate namespace for driver evaluation */
60 if (bpy_pydriver_Dict) return -1;
68 /* import some modules: builtins, bpy, math, (Blender.noise)*/
69 PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins());
71 mod= PyImport_ImportModule("math");
73 PyDict_Merge(d, PyModule_GetDict(mod), 0); /* 0 - dont overwrite existing values */
77 /* add bpy to global namespace */
78 mod= PyImport_ImportModuleLevel((char *)"bpy", NULL, NULL, NULL, 0);
80 PyDict_SetItemString(bpy_pydriver_Dict, "bpy", mod);
84 /* add noise to global namespace */
85 mod= PyImport_ImportModuleLevel((char *)"noise", NULL, NULL, NULL, 0);
87 PyDict_SetItemString(bpy_pydriver_Dict, "noise", mod);
94 /* note, this function should do nothing most runs, only when changing frame */
95 static PyObject *bpy_pydriver_InternStr__frame= NULL;
97 static void bpy_pydriver_update_dict(const float evaltime)
99 /* not thread safe but neither is python */
100 static float evaltime_prev= FLT_MAX;
102 if (evaltime_prev != evaltime) {
104 /* currently only update the frame */
105 if (bpy_pydriver_InternStr__frame == NULL) {
106 bpy_pydriver_InternStr__frame= PyUnicode_FromString("frame");
109 PyDict_SetItem(bpy_pydriver_Dict,
110 bpy_pydriver_InternStr__frame,
111 PyFloat_FromDouble(evaltime));
113 evaltime_prev= evaltime;
117 /* Update function, it gets rid of pydrivers global dictionary, forcing
118 * BPY_driver_exec to recreate it. This function is used to force
119 * reloading the Blender text module "pydrivers.py", if available, so
120 * updates in it reach pydriver evaluation.
122 void BPY_driver_reset(void)
124 PyGILState_STATE gilstate;
125 int use_gil= 1; /* !PYC_INTERPRETER_ACTIVE; */
128 gilstate= PyGILState_Ensure();
130 if (bpy_pydriver_Dict) { /* free the global dict used by pydrivers */
131 PyDict_Clear(bpy_pydriver_Dict);
132 Py_DECREF(bpy_pydriver_Dict);
133 bpy_pydriver_Dict= NULL;
136 if (bpy_pydriver_InternStr__frame) {
137 Py_DECREF(bpy_pydriver_InternStr__frame);
138 bpy_pydriver_InternStr__frame= NULL;
142 PyGILState_Release(gilstate);
147 /* error return function for BPY_eval_pydriver */
148 static void pydriver_error(ChannelDriver *driver)
150 driver->flag |= DRIVER_FLAG_INVALID; /* py expression failed */
151 fprintf(stderr, "\nError in Driver: The following Python expression failed:\n\t'%s'\n\n", driver->expression);
153 // BPy_errors_to_report(NULL); // TODO - reports
158 /* This evals py driver expressions, 'expr' is a Python expression that
159 * should evaluate to a float number, which is returned.
161 * (old)note: PyGILState_Ensure() isnt always called because python can call
162 * the bake operator which intern starts a thread which calls scene update
163 * which does a driver update. to avoid a deadlock check PYC_INTERPRETER_ACTIVE
164 * if PyGILState_Ensure() is needed - see [#27683]
166 * (new)note: checking if python is running is not threadsafe [#28114]
167 * now release the GIL on python operator execution instead, using
168 * PyEval_SaveThread() / PyEval_RestoreThread() so we dont lock up blender.
170 float BPY_driver_exec(ChannelDriver *driver, const float evaltime)
172 PyObject *driver_vars=NULL;
173 PyObject *retval= NULL;
174 PyObject *expr_vars; /* speed up by pre-hashing string & avoids re-converting unicode strings for every execution */
176 PyGILState_STATE gilstate;
180 double result= 0.0; /* default return */
185 /* get the py expression to be evaluated */
186 expr= driver->expression;
187 if ((expr == NULL) || (expr[0]=='\0'))
190 if (!(G.f & G_SCRIPT_AUTOEXEC)) {
191 printf("skipping driver '%s', automatic scripts are disabled\n", driver->expression);
195 use_gil= 1; /* !PYC_INTERPRETER_ACTIVE; */
198 gilstate= PyGILState_Ensure();
200 /* needed since drivers are updated directly after undo where 'main' is
201 * re-allocated [#28807] */
202 BPY_update_rna_module();
204 /* init global dictionary for py-driver evaluation settings */
205 if (!bpy_pydriver_Dict) {
206 if (bpy_pydriver_create_dict() != 0) {
207 fprintf(stderr, "Pydriver error: couldn't create Python dictionary");
209 PyGILState_Release(gilstate);
214 /* update global namespace */
215 bpy_pydriver_update_dict(evaltime);
218 if (driver->expr_comp==NULL)
219 driver->flag |= DRIVER_FLAG_RECOMPILE;
221 /* compile the expression first if it hasn't been compiled or needs to be rebuilt */
222 if (driver->flag & DRIVER_FLAG_RECOMPILE) {
223 Py_XDECREF(driver->expr_comp);
224 driver->expr_comp= PyTuple_New(2);
226 expr_code= Py_CompileString(expr, "<bpy driver>", Py_eval_input);
227 PyTuple_SET_ITEM(((PyObject *)driver->expr_comp), 0, expr_code);
229 driver->flag &= ~DRIVER_FLAG_RECOMPILE;
230 driver->flag |= DRIVER_FLAG_RENAMEVAR; /* maybe this can be removed but for now best keep until were sure */
233 expr_code= PyTuple_GET_ITEM(((PyObject *)driver->expr_comp), 0);
236 if (driver->flag & DRIVER_FLAG_RENAMEVAR) {
238 expr_vars= PyTuple_GET_ITEM(((PyObject *)driver->expr_comp), 1);
239 Py_XDECREF(expr_vars);
241 expr_vars= PyTuple_New(BLI_countlist(&driver->variables));
242 PyTuple_SET_ITEM(((PyObject *)driver->expr_comp), 1, expr_vars);
244 for (dvar= driver->variables.first, i=0; dvar; dvar= dvar->next) {
245 PyTuple_SET_ITEM(expr_vars, i++, PyUnicode_FromString(dvar->name));
248 driver->flag &= ~DRIVER_FLAG_RENAMEVAR;
251 expr_vars= PyTuple_GET_ITEM(((PyObject *)driver->expr_comp), 1);
254 /* add target values to a dict that will be used as '__locals__' dict */
255 driver_vars= PyDict_New(); // XXX do we need to decref this?
256 for (dvar= driver->variables.first, i=0; dvar; dvar= dvar->next) {
257 PyObject *driver_arg= NULL;
260 /* try to get variable value */
261 tval= driver_get_variable_value(driver, dvar);
262 driver_arg= PyFloat_FromDouble((double)tval);
264 /* try to add to dictionary */
265 /* if (PyDict_SetItemString(driver_vars, dvar->name, driver_arg)) { */
266 if (PyDict_SetItem(driver_vars, PyTuple_GET_ITEM(expr_vars, i++), driver_arg) < 0) {
267 /* this target failed - bad name */
269 /* first one - print some extra info for easier identification */
270 fprintf(stderr, "\nBPY_driver_eval() - Error while evaluating PyDriver:\n");
274 fprintf(stderr, "\tBPY_driver_eval() - couldn't add variable '%s' to namespace\n", dvar->name);
275 // BPy_errors_to_report(NULL); // TODO - reports
282 #if 0 // slow, with this can avoid all Py_CompileString above.
283 /* execute expression to get a value */
284 retval= PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict, driver_vars);
286 /* evaluate the compiled expression */
288 retval= PyEval_EvalCode((void *)expr_code, bpy_pydriver_Dict, driver_vars);
291 /* decref the driver vars first... */
292 Py_DECREF(driver_vars);
294 /* process the result */
295 if (retval == NULL) {
296 pydriver_error(driver);
298 else if ((result= PyFloat_AsDouble(retval)) == -1.0 && PyErr_Occurred()) {
299 pydriver_error(driver);
304 /* all fine, make sure the "invalid expression" flag is cleared */
305 driver->flag &= ~DRIVER_FLAG_INVALID;
310 PyGILState_Release(gilstate);
312 if (finite(result)) {
313 return (float)result;
316 fprintf(stderr, "\tBPY_driver_eval() - driver '%s' evaluates to '%f'\n", dvar->name, result);