New python API for units handling.

Exposes all supported unit systems & types, and to_value()/to_string() functions.

Reviewed and enhanced by CampbellBarton, many thanks!

Differential Revision: https://developer.blender.org/D416
This commit is contained in:
2014-06-17 16:03:40 +02:00
parent ab5f4c4dfa
commit f94b87bbb8
8 changed files with 445 additions and 59 deletions

View File

@@ -904,3 +904,73 @@ PyObject *PyC_FlagSet_FromBitfield(PyC_FlagSet *items, int flag)
return ret;
}
/**
* \return -1 on error, else 0
*
* \note it is caller's responsibility to acquire & release GIL!
*/
int PyC_RunString_AsNumber(const char *expr, double *value, const char *filename)
{
PyObject *py_dict, *mod, *retval;
int error_ret = 0;
PyObject *main_mod = NULL;
PyC_MainModule_Backup(&main_mod);
py_dict = PyC_DefaultNameSpace(filename);
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;
}
}
PyC_MainModule_Restore(main_mod);
return error_ret;
}