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