~siretart/ubuntu/utopic/blender/libav10

« back to all changes in this revision

Viewing changes to source/blender/python/intern/bpy_driver.c

  • Committer: Package Import Robot
  • Author(s): Matteo F. Vescovi
  • Date: 2012-07-23 08:54:18 UTC
  • mfrom: (14.2.16 sid)
  • mto: (14.2.19 sid)
  • mto: This revision was merged to the branch mainline in revision 42.
  • Revision ID: package-import@ubuntu.com-20120723085418-9foz30v6afaf5ffs
Tags: 2.63a-2
* debian/: Cycles support added (Closes: #658075)
  For now, this top feature has been enabled only
  on [any-amd64 any-i386] architectures because
  of OpenImageIO failing on all others
* debian/: scripts installation path changed
  from /usr/lib to /usr/share:
  + debian/patches/: patchset re-worked for path changing
  + debian/control: "Breaks" field added on yafaray-exporter

Show diffs side-by-side

added added

removed removed

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