documentation - brief descriptions for bpy api files.
[blender.git] / source / blender / python / intern / bpy_driver.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
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.
8  *
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.
13  *
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.
17  *
18  * Contributor(s): Willian P. Germano, Campbell Barton
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 /** \file blender/python/intern/bpy_driver.c
24  *  \ingroup pythonintern
25  *
26  * This file defines the 'BPY_driver_exec' to execute python drivers,
27  * called by the animation system, there are also some utility functions
28  * to deal with the namespace used for driver execution.
29  */
30
31 /* ****************************************** */
32 /* Drivers - PyExpression Evaluation */
33
34 #include <Python.h>
35
36 #include "DNA_anim_types.h"
37
38 #include "BLI_listbase.h"
39 #include "BLI_math_base.h"
40
41 #include "BKE_fcurve.h"
42 #include "BKE_global.h"
43
44 #include "bpy_driver.h"
45
46 extern void BPY_update_rna_module(void);
47
48
49 /* for pydrivers (drivers using one-line Python expressions to express relationships between targets) */
50 PyObject *bpy_pydriver_Dict= NULL;
51
52 /* For faster execution we keep a special dictionary for pydrivers, with
53  * the needed modules and aliases.
54  */
55 int bpy_pydriver_create_dict(void)
56 {
57         PyObject *d, *mod;
58
59         /* validate namespace for driver evaluation */
60         if (bpy_pydriver_Dict) return -1;
61
62         d= PyDict_New();
63         if (d == NULL)
64                 return -1;
65         else
66                 bpy_pydriver_Dict= d;
67
68         /* import some modules: builtins, bpy, math, (Blender.noise)*/
69         PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins());
70
71         mod= PyImport_ImportModule("math");
72         if (mod) {
73                 PyDict_Merge(d, PyModule_GetDict(mod), 0); /* 0 - dont overwrite existing values */
74                 Py_DECREF(mod);
75         }
76
77         /* add bpy to global namespace */
78         mod= PyImport_ImportModuleLevel((char *)"bpy", NULL, NULL, NULL, 0);
79         if (mod) {
80                 PyDict_SetItemString(bpy_pydriver_Dict, "bpy", mod);
81                 Py_DECREF(mod);
82         }
83
84         /* add noise to global namespace */
85         mod= PyImport_ImportModuleLevel((char *)"noise", NULL, NULL, NULL, 0);
86         if (mod) {
87                 PyDict_SetItemString(bpy_pydriver_Dict, "noise", mod);
88                 Py_DECREF(mod);
89         }
90
91         return 0;
92 }
93
94 /* Update function, it gets rid of pydrivers global dictionary, forcing
95  * BPY_driver_exec to recreate it. This function is used to force
96  * reloading the Blender text module "pydrivers.py", if available, so
97  * updates in it reach pydriver evaluation.
98  */
99 void BPY_driver_reset(void)
100 {
101         PyGILState_STATE gilstate;
102         int use_gil= 1; /* !PYC_INTERPRETER_ACTIVE; */
103
104         if (use_gil)
105                 gilstate= PyGILState_Ensure();
106
107         if (bpy_pydriver_Dict) { /* free the global dict used by pydrivers */
108                 PyDict_Clear(bpy_pydriver_Dict);
109                 Py_DECREF(bpy_pydriver_Dict);
110                 bpy_pydriver_Dict= NULL;
111         }
112
113         if (use_gil)
114                 PyGILState_Release(gilstate);
115
116         return;
117 }
118
119 /* error return function for BPY_eval_pydriver */
120 static void pydriver_error(ChannelDriver *driver)
121 {
122         driver->flag |= DRIVER_FLAG_INVALID; /* py expression failed */
123         fprintf(stderr, "\nError in Driver: The following Python expression failed:\n\t'%s'\n\n", driver->expression);
124
125         // BPy_errors_to_report(NULL); // TODO - reports
126         PyErr_Print();
127         PyErr_Clear();
128 }
129
130 /* This evals py driver expressions, 'expr' is a Python expression that
131  * should evaluate to a float number, which is returned.
132  *
133  * (old)note: PyGILState_Ensure() isnt always called because python can call
134  * the bake operator which intern starts a thread which calls scene update
135  * which does a driver update. to avoid a deadlock check PYC_INTERPRETER_ACTIVE
136  * if PyGILState_Ensure() is needed - see [#27683]
137  *
138  * (new)note: checking if python is running is not threadsafe [#28114]
139  * now release the GIL on python operator execution instead, using
140  * PyEval_SaveThread() / PyEval_RestoreThread() so we dont lock up blender.
141  */
142 float BPY_driver_exec(ChannelDriver *driver)
143 {
144         PyObject *driver_vars=NULL;
145         PyObject *retval= NULL;
146         PyObject *expr_vars; /* speed up by pre-hashing string & avoids re-converting unicode strings for every execution */
147         PyObject *expr_code;
148         PyGILState_STATE gilstate;
149         int use_gil;
150
151         DriverVar *dvar;
152         double result= 0.0; /* default return */
153         char *expr= NULL;
154         short targets_ok= 1;
155         int i;
156
157         /* get the py expression to be evaluated */
158         expr= driver->expression;
159         if ((expr == NULL) || (expr[0]=='\0'))
160                 return 0.0f;
161
162         if (!(G.f & G_SCRIPT_AUTOEXEC)) {
163                 printf("skipping driver '%s', automatic scripts are disabled\n", driver->expression);
164                 return 0.0f;
165         }
166
167         use_gil= 1; /* !PYC_INTERPRETER_ACTIVE; */
168
169         if (use_gil)
170                 gilstate= PyGILState_Ensure();
171
172         /* needed since drivers are updated directly after undo where 'main' is
173          * re-allocated [#28807] */
174         BPY_update_rna_module();
175
176         /* init global dictionary for py-driver evaluation settings */
177         if (!bpy_pydriver_Dict) {
178                 if (bpy_pydriver_create_dict() != 0) {
179                         fprintf(stderr, "Pydriver error: couldn't create Python dictionary");
180                         if (use_gil)
181                                 PyGILState_Release(gilstate);
182                         return 0.0f;
183                 }
184         }
185
186         if (driver->expr_comp==NULL)
187                 driver->flag |= DRIVER_FLAG_RECOMPILE;
188
189         /* compile the expression first if it hasn't been compiled or needs to be rebuilt */
190         if (driver->flag & DRIVER_FLAG_RECOMPILE) {
191                 Py_XDECREF(driver->expr_comp);
192                 driver->expr_comp= PyTuple_New(2);
193
194                 expr_code= Py_CompileString(expr, "<bpy driver>", Py_eval_input);
195                 PyTuple_SET_ITEM(((PyObject *)driver->expr_comp), 0, expr_code);
196
197                 driver->flag &= ~DRIVER_FLAG_RECOMPILE;
198                 driver->flag |= DRIVER_FLAG_RENAMEVAR; /* maybe this can be removed but for now best keep until were sure */
199         }
200         else {
201                 expr_code= PyTuple_GET_ITEM(((PyObject *)driver->expr_comp), 0);
202         }
203
204         if (driver->flag & DRIVER_FLAG_RENAMEVAR) {
205                 /* may not be set */
206                 expr_vars= PyTuple_GET_ITEM(((PyObject *)driver->expr_comp), 1);
207                 Py_XDECREF(expr_vars);
208
209                 expr_vars= PyTuple_New(BLI_countlist(&driver->variables));
210                 PyTuple_SET_ITEM(((PyObject *)driver->expr_comp), 1, expr_vars);
211
212                 for (dvar= driver->variables.first, i=0; dvar; dvar= dvar->next) {
213                         PyTuple_SET_ITEM(expr_vars, i++, PyUnicode_FromString(dvar->name));
214                 }
215                 
216                 driver->flag &= ~DRIVER_FLAG_RENAMEVAR;
217         }
218         else {
219                 expr_vars= PyTuple_GET_ITEM(((PyObject *)driver->expr_comp), 1);
220         }
221
222         /* add target values to a dict that will be used as '__locals__' dict */
223         driver_vars= PyDict_New(); // XXX do we need to decref this?
224         for (dvar= driver->variables.first, i=0; dvar; dvar= dvar->next) {
225                 PyObject *driver_arg= NULL;
226                 float tval= 0.0f;
227                 
228                 /* try to get variable value */
229                 tval= driver_get_variable_value(driver, dvar);
230                 driver_arg= PyFloat_FromDouble((double)tval);
231                 
232                 /* try to add to dictionary */
233                 /* if (PyDict_SetItemString(driver_vars, dvar->name, driver_arg)) { */
234                 if (PyDict_SetItem(driver_vars, PyTuple_GET_ITEM(expr_vars, i++), driver_arg) < 0) {
235                         /* this target failed - bad name */
236                         if (targets_ok) {
237                                 /* first one - print some extra info for easier identification */
238                                 fprintf(stderr, "\nBPY_driver_eval() - Error while evaluating PyDriver:\n");
239                                 targets_ok= 0;
240                         }
241                         
242                         fprintf(stderr, "\tBPY_driver_eval() - couldn't add variable '%s' to namespace\n", dvar->name);
243                         // BPy_errors_to_report(NULL); // TODO - reports
244                         PyErr_Print();
245                         PyErr_Clear();
246                 }
247         }
248
249 #if 0 // slow, with this can avoid all Py_CompileString above.
250         /* execute expression to get a value */
251         retval= PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict, driver_vars);
252 #else
253         /* evaluate the compiled expression */
254         if (expr_code)
255                 retval= PyEval_EvalCode((void *)expr_code, bpy_pydriver_Dict, driver_vars);
256 #endif
257
258         /* decref the driver vars first...  */
259         Py_DECREF(driver_vars);
260
261         /* process the result */
262         if (retval == NULL) {
263                 pydriver_error(driver);
264         }
265         else if ((result= PyFloat_AsDouble(retval)) == -1.0 && PyErr_Occurred()) {
266                 pydriver_error(driver);
267                 Py_DECREF(retval);
268                 result= 0.0;
269         }
270         else {
271                 /* all fine, make sure the "invalid expression" flag is cleared */
272                 driver->flag &= ~DRIVER_FLAG_INVALID;
273                 Py_DECREF(retval);
274         }
275
276         if (use_gil)
277                 PyGILState_Release(gilstate);
278
279         if (finite(result)) {
280                 return (float)result;
281         }
282         else {
283                 fprintf(stderr, "\tBPY_driver_eval() - driver '%s' evaluates to '%f'\n", dvar->name, result);
284                 return 0.0f;
285         }
286 }