Changeset View
Changeset View
Standalone View
Standalone View
source/blender/python/intern/bpy_interface.c
| Show First 20 Lines • Show All 560 Lines • ▼ Show 20 Lines | void BPY_DECREF_RNA_INVALIDATE(void *pyob_ptr) | ||||
| const int do_invalidate = (Py_REFCNT((PyObject *)pyob_ptr) > 1); | const int do_invalidate = (Py_REFCNT((PyObject *)pyob_ptr) > 1); | ||||
| Py_DECREF((PyObject *)pyob_ptr); | Py_DECREF((PyObject *)pyob_ptr); | ||||
| if (do_invalidate) { | if (do_invalidate) { | ||||
| pyrna_invalidate(pyob_ptr); | pyrna_invalidate(pyob_ptr); | ||||
| } | } | ||||
| PyGILState_Release(gilstate); | PyGILState_Release(gilstate); | ||||
| } | } | ||||
| /* return -1 on error, else 0 */ | /* return -1 on error, else 0 */ | ||||
| int BPY_button_exec(bContext *C, const char *expr, double *value, const bool verbose) | int BPY_button_exec(bContext *C, const char *expr, double *value, const bool verbose) | ||||
| { | { | ||||
| PyGILState_STATE gilstate; | PyGILState_STATE gilstate; | ||||
| PyObject *py_dict, *mod, *retval; | |||||
| int error_ret = 0; | int error_ret = 0; | ||||
campbellbarton: differentiation here is a bit fuzzy.
- `bpy_button_exec` - caller needs to handle errors… | |||||
| PyObject *main_mod = NULL; | |||||
| if (!value || !expr) return -1; | if (!value || !expr) return -1; | ||||
| if (expr[0] == '\0') { | if (expr[0] == '\0') { | ||||
| *value = 0.0; | *value = 0.0; | ||||
| return error_ret; | return error_ret; | ||||
| } | } | ||||
| bpy_context_set(C, &gilstate); | bpy_context_set(C, &gilstate); | ||||
| PyC_MainModule_Backup(&main_mod); | error_ret = PyC_RunString_AsNumber(expr, value, "<blender button>"); | ||||
| py_dict = PyC_DefaultNameSpace("<blender button>"); | |||||
| mod = PyImport_ImportModule("math"); | |||||
| if (mod) { | |||||
| PyDict_Merge(py_dict, PyModule_GetDict(mod), 0); /* 0 - don't overwrite existing values */ | |||||
| Py_DECREF(mod); | |||||
| } | |||||
| else { /* highly unlikely but possibly */ | |||||
| PyErr_Print(); | |||||
| PyErr_Clear(); | |||||
| } | |||||
| retval = PyRun_String(expr, Py_eval_input, py_dict, py_dict); | |||||
| if (retval == NULL) { | |||||
| error_ret = -1; | |||||
| } | |||||
| else { | |||||
| double val; | |||||
| if (PyTuple_Check(retval)) { | |||||
| /* Users my have typed in 10km, 2m | |||||
| * add up all values */ | |||||
| int i; | |||||
| val = 0.0; | |||||
| for (i = 0; i < PyTuple_GET_SIZE(retval); i++) { | |||||
| const double val_item = PyFloat_AsDouble(PyTuple_GET_ITEM(retval, i)); | |||||
| if (val_item == -1 && PyErr_Occurred()) { | |||||
| val = -1; | |||||
| break; | |||||
| } | |||||
| val += val_item; | |||||
| } | |||||
| } | |||||
| else { | |||||
| val = PyFloat_AsDouble(retval); | |||||
| } | |||||
| Py_DECREF(retval); | |||||
| if (val == -1 && PyErr_Occurred()) { | |||||
| error_ret = -1; | |||||
| } | |||||
| else if (!finite(val)) { | |||||
| *value = 0.0; | |||||
| } | |||||
| else { | |||||
| *value = val; | |||||
| } | |||||
| } | |||||
| if (error_ret) { | if (error_ret) { | ||||
| if (verbose) { | if (verbose) { | ||||
| BPy_errors_to_report(CTX_wm_reports(C)); | BPy_errors_to_report(CTX_wm_reports(C)); | ||||
| } | } | ||||
| else { | else { | ||||
| PyErr_Clear(); | PyErr_Clear(); | ||||
| } | } | ||||
| } | } | ||||
| PyC_MainModule_Restore(main_mod); | |||||
| bpy_context_clear(C, &gilstate); | bpy_context_clear(C, &gilstate); | ||||
| return error_ret; | return error_ret; | ||||
| } | } | ||||
| int BPY_string_exec(bContext *C, const char *expr) | int BPY_string_exec(bContext *C, const char *expr) | ||||
| { | { | ||||
| PyGILState_STATE gilstate; | PyGILState_STATE gilstate; | ||||
| PyObject *main_mod = NULL; | PyObject *main_mod = NULL; | ||||
| PyObject *py_dict, *retval; | PyObject *py_dict, *retval; | ||||
| ▲ Show 20 Lines • Show All 295 Lines • Show Last 20 Lines | |||||
differentiation here is a bit fuzzy.
bpy_button_exec Should probably be moved to generic api py_capi_utils.c, maybe call.
PyC_RunString_AsNumber(const char *expr, double *value, const char *filename) {...}Then call as: