Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * Contributor(s): Willian P. Germano, Campbell Barton 00019 * 00020 * ***** END GPL LICENSE BLOCK ***** 00021 */ 00022 00031 /* ****************************************** */ 00032 /* Drivers - PyExpression Evaluation */ 00033 00034 #include <Python.h> 00035 00036 #include "DNA_anim_types.h" 00037 00038 #include "BLI_listbase.h" 00039 #include "BLI_math_base.h" 00040 00041 #include "BKE_fcurve.h" 00042 #include "BKE_global.h" 00043 00044 #include "bpy_driver.h" 00045 00046 extern void BPY_update_rna_module(void); 00047 00048 00049 /* for pydrivers (drivers using one-line Python expressions to express relationships between targets) */ 00050 PyObject *bpy_pydriver_Dict = NULL; 00051 00052 /* For faster execution we keep a special dictionary for pydrivers, with 00053 * the needed modules and aliases. 00054 */ 00055 int bpy_pydriver_create_dict(void) 00056 { 00057 PyObject *d, *mod; 00058 00059 /* validate namespace for driver evaluation */ 00060 if (bpy_pydriver_Dict) return -1; 00061 00062 d = PyDict_New(); 00063 if (d == NULL) 00064 return -1; 00065 else 00066 bpy_pydriver_Dict = d; 00067 00068 /* import some modules: builtins, bpy, math, (Blender.noise)*/ 00069 PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins()); 00070 00071 mod = PyImport_ImportModule("math"); 00072 if (mod) { 00073 PyDict_Merge(d, PyModule_GetDict(mod), 0); /* 0 - dont overwrite existing values */ 00074 Py_DECREF(mod); 00075 } 00076 00077 /* add bpy to global namespace */ 00078 mod = PyImport_ImportModuleLevel((char *)"bpy", NULL, NULL, NULL, 0); 00079 if (mod) { 00080 PyDict_SetItemString(bpy_pydriver_Dict, "bpy", mod); 00081 Py_DECREF(mod); 00082 } 00083 00084 /* add noise to global namespace */ 00085 mod = PyImport_ImportModuleLevel((char *)"mathutils", NULL, NULL, NULL, 0); 00086 if (mod) { 00087 PyObject *modsub = PyDict_GetItemString(PyModule_GetDict(mod), "noise"); 00088 PyDict_SetItemString(bpy_pydriver_Dict, "noise", modsub); 00089 Py_DECREF(mod); 00090 } 00091 00092 return 0; 00093 } 00094 00095 /* note, this function should do nothing most runs, only when changing frame */ 00096 static PyObject *bpy_pydriver_InternStr__frame = NULL; 00097 /* not thread safe but neither is python */ 00098 static float bpy_pydriver_evaltime_prev = FLT_MAX; 00099 00100 static void bpy_pydriver_update_dict(const float evaltime) 00101 { 00102 if (bpy_pydriver_evaltime_prev != evaltime) { 00103 00104 /* currently only update the frame */ 00105 if (bpy_pydriver_InternStr__frame == NULL) { 00106 bpy_pydriver_InternStr__frame = PyUnicode_FromString("frame"); 00107 } 00108 00109 PyDict_SetItem(bpy_pydriver_Dict, 00110 bpy_pydriver_InternStr__frame, 00111 PyFloat_FromDouble(evaltime)); 00112 00113 bpy_pydriver_evaltime_prev = evaltime; 00114 } 00115 } 00116 00117 /* Update function, it gets rid of pydrivers global dictionary, forcing 00118 * BPY_driver_exec to recreate it. This function is used to force 00119 * reloading the Blender text module "pydrivers.py", if available, so 00120 * updates in it reach pydriver evaluation. 00121 */ 00122 void BPY_driver_reset(void) 00123 { 00124 PyGILState_STATE gilstate; 00125 int use_gil = 1; /* !PYC_INTERPRETER_ACTIVE; */ 00126 00127 if (use_gil) 00128 gilstate = PyGILState_Ensure(); 00129 00130 if (bpy_pydriver_Dict) { /* free the global dict used by pydrivers */ 00131 PyDict_Clear(bpy_pydriver_Dict); 00132 Py_DECREF(bpy_pydriver_Dict); 00133 bpy_pydriver_Dict = NULL; 00134 } 00135 00136 if (bpy_pydriver_InternStr__frame) { 00137 Py_DECREF(bpy_pydriver_InternStr__frame); 00138 bpy_pydriver_InternStr__frame = NULL; 00139 bpy_pydriver_evaltime_prev = FLT_MAX; 00140 } 00141 00142 if (use_gil) 00143 PyGILState_Release(gilstate); 00144 00145 return; 00146 } 00147 00148 /* error return function for BPY_eval_pydriver */ 00149 static void pydriver_error(ChannelDriver *driver) 00150 { 00151 driver->flag |= DRIVER_FLAG_INVALID; /* py expression failed */ 00152 fprintf(stderr, "\nError in Driver: The following Python expression failed:\n\t'%s'\n\n", driver->expression); 00153 00154 // BPy_errors_to_report(NULL); // TODO - reports 00155 PyErr_Print(); 00156 PyErr_Clear(); 00157 } 00158 00159 /* This evals py driver expressions, 'expr' is a Python expression that 00160 * should evaluate to a float number, which is returned. 00161 * 00162 * (old)note: PyGILState_Ensure() isnt always called because python can call 00163 * the bake operator which intern starts a thread which calls scene update 00164 * which does a driver update. to avoid a deadlock check PYC_INTERPRETER_ACTIVE 00165 * if PyGILState_Ensure() is needed - see [#27683] 00166 * 00167 * (new)note: checking if python is running is not threadsafe [#28114] 00168 * now release the GIL on python operator execution instead, using 00169 * PyEval_SaveThread() / PyEval_RestoreThread() so we dont lock up blender. 00170 */ 00171 float BPY_driver_exec(ChannelDriver *driver, const float evaltime) 00172 { 00173 PyObject *driver_vars = NULL; 00174 PyObject *retval = NULL; 00175 PyObject *expr_vars; /* speed up by pre-hashing string & avoids re-converting unicode strings for every execution */ 00176 PyObject *expr_code; 00177 PyGILState_STATE gilstate; 00178 int use_gil; 00179 00180 DriverVar *dvar; 00181 double result = 0.0; /* default return */ 00182 char *expr = NULL; 00183 short targets_ok = 1; 00184 int i; 00185 00186 /* get the py expression to be evaluated */ 00187 expr = driver->expression; 00188 if ((expr == NULL) || (expr[0] == '\0')) 00189 return 0.0f; 00190 00191 if (!(G.f & G_SCRIPT_AUTOEXEC)) { 00192 printf("skipping driver '%s', automatic scripts are disabled\n", driver->expression); 00193 return 0.0f; 00194 } 00195 00196 use_gil = 1; /* !PYC_INTERPRETER_ACTIVE; */ 00197 00198 if (use_gil) 00199 gilstate = PyGILState_Ensure(); 00200 00201 /* needed since drivers are updated directly after undo where 'main' is 00202 * re-allocated [#28807] */ 00203 BPY_update_rna_module(); 00204 00205 /* init global dictionary for py-driver evaluation settings */ 00206 if (!bpy_pydriver_Dict) { 00207 if (bpy_pydriver_create_dict() != 0) { 00208 fprintf(stderr, "Pydriver error: couldn't create Python dictionary"); 00209 if (use_gil) 00210 PyGILState_Release(gilstate); 00211 return 0.0f; 00212 } 00213 } 00214 00215 /* update global namespace */ 00216 bpy_pydriver_update_dict(evaltime); 00217 00218 00219 if (driver->expr_comp == NULL) 00220 driver->flag |= DRIVER_FLAG_RECOMPILE; 00221 00222 /* compile the expression first if it hasn't been compiled or needs to be rebuilt */ 00223 if (driver->flag & DRIVER_FLAG_RECOMPILE) { 00224 Py_XDECREF(driver->expr_comp); 00225 driver->expr_comp = PyTuple_New(2); 00226 00227 expr_code = Py_CompileString(expr, "<bpy driver>", Py_eval_input); 00228 PyTuple_SET_ITEM(((PyObject *)driver->expr_comp), 0, expr_code); 00229 00230 driver->flag &= ~DRIVER_FLAG_RECOMPILE; 00231 driver->flag |= DRIVER_FLAG_RENAMEVAR; /* maybe this can be removed but for now best keep until were sure */ 00232 } 00233 else { 00234 expr_code = PyTuple_GET_ITEM(((PyObject *)driver->expr_comp), 0); 00235 } 00236 00237 if (driver->flag & DRIVER_FLAG_RENAMEVAR) { 00238 /* may not be set */ 00239 expr_vars = PyTuple_GET_ITEM(((PyObject *)driver->expr_comp), 1); 00240 Py_XDECREF(expr_vars); 00241 00242 expr_vars = PyTuple_New(BLI_countlist(&driver->variables)); 00243 PyTuple_SET_ITEM(((PyObject *)driver->expr_comp), 1, expr_vars); 00244 00245 for (dvar = driver->variables.first, i = 0; dvar; dvar = dvar->next) { 00246 PyTuple_SET_ITEM(expr_vars, i++, PyUnicode_FromString(dvar->name)); 00247 } 00248 00249 driver->flag &= ~DRIVER_FLAG_RENAMEVAR; 00250 } 00251 else { 00252 expr_vars = PyTuple_GET_ITEM(((PyObject *)driver->expr_comp), 1); 00253 } 00254 00255 /* add target values to a dict that will be used as '__locals__' dict */ 00256 driver_vars = PyDict_New(); // XXX do we need to decref this? 00257 for (dvar = driver->variables.first, i = 0; dvar; dvar = dvar->next) { 00258 PyObject *driver_arg = NULL; 00259 float tval = 0.0f; 00260 00261 /* try to get variable value */ 00262 tval = driver_get_variable_value(driver, dvar); 00263 driver_arg = PyFloat_FromDouble((double)tval); 00264 00265 /* try to add to dictionary */ 00266 /* if (PyDict_SetItemString(driver_vars, dvar->name, driver_arg)) { */ 00267 if (PyDict_SetItem(driver_vars, PyTuple_GET_ITEM(expr_vars, i++), driver_arg) < 0) { 00268 /* this target failed - bad name */ 00269 if (targets_ok) { 00270 /* first one - print some extra info for easier identification */ 00271 fprintf(stderr, "\nBPY_driver_eval() - Error while evaluating PyDriver:\n"); 00272 targets_ok = 0; 00273 } 00274 00275 fprintf(stderr, "\tBPY_driver_eval() - couldn't add variable '%s' to namespace\n", dvar->name); 00276 // BPy_errors_to_report(NULL); // TODO - reports 00277 PyErr_Print(); 00278 PyErr_Clear(); 00279 } 00280 } 00281 00282 00283 #if 0 // slow, with this can avoid all Py_CompileString above. 00284 /* execute expression to get a value */ 00285 retval = PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict, driver_vars); 00286 #else 00287 /* evaluate the compiled expression */ 00288 if (expr_code) 00289 retval = PyEval_EvalCode((void *)expr_code, bpy_pydriver_Dict, driver_vars); 00290 #endif 00291 00292 /* decref the driver vars first... */ 00293 Py_DECREF(driver_vars); 00294 00295 /* process the result */ 00296 if (retval == NULL) { 00297 pydriver_error(driver); 00298 } 00299 else if ((result = PyFloat_AsDouble(retval)) == -1.0 && PyErr_Occurred()) { 00300 pydriver_error(driver); 00301 Py_DECREF(retval); 00302 result = 0.0; 00303 } 00304 else { 00305 /* all fine, make sure the "invalid expression" flag is cleared */ 00306 driver->flag &= ~DRIVER_FLAG_INVALID; 00307 Py_DECREF(retval); 00308 } 00309 00310 if (use_gil) 00311 PyGILState_Release(gilstate); 00312 00313 if (finite(result)) { 00314 return (float)result; 00315 } 00316 else { 00317 fprintf(stderr, "\tBPY_driver_eval() - driver '%s' evaluates to '%f'\n", dvar->name, result); 00318 return 0.0f; 00319 } 00320 }