25 #define PY_SSIZE_T_CLEAN
28 #include <structmember.h>
35 #include "../generic/py_capi_utils.h"
76 "bpy.utils.units.systems",
77 "This named tuple contains all predefined unit systems",
82 "bpy.utils.units.categories",
83 "This named tuple contains all predefined unit names",
92 PyStructSequence_Desc *py_sseq_desc,
93 const char **str_items)
95 PyObject *py_struct_seq;
98 const char **str_iter;
99 PyStructSequence_Field *desc;
103 for (str_iter = str_items, desc = py_sseq_desc->fields; *str_iter; str_iter++, desc++) {
104 desc->name = (
char *)*str_iter;
108 desc->name = desc->doc =
NULL;
110 PyStructSequence_InitType(py_type, py_sseq_desc);
113 py_struct_seq = PyStructSequence_New(py_type);
116 for (str_iter = str_items; *str_iter; str_iter++) {
117 PyStructSequence_SET_ITEM(py_struct_seq,
pos++, PyUnicode_FromString((*str_iter)));
120 return py_struct_seq;
123 static bool bpyunits_validate(
const char *usys_str,
const char *ucat_str,
int *r_usys,
int *r_ucat)
127 PyErr_Format(PyExc_ValueError,
"Unknown unit system specified: %.200s.", usys_str);
133 PyErr_Format(PyExc_ValueError,
"Unknown unit category specified: %.200s.", ucat_str);
138 PyErr_Format(PyExc_ValueError,
139 "%.200s / %.200s unit system/category combination is not valid.",
149 bpyunits_to_value_doc,
150 ".. method:: to_value(unit_system, unit_category, str_input, str_ref_unit=None)\n"
152 " Convert a given input string into a float value.\n"
154 " :arg unit_system: The unit system, from :attr:`bpy.utils.units.systems`.\n"
155 " :type unit_system: string\n"
156 " :arg unit_category: The category of data we are converting (length, area, rotation, "
158 " from :attr:`bpy.utils.units.categories`.\n"
159 " :type unit_category: string\n"
160 " :arg str_input: The string to convert to a float value.\n"
161 " :type str_input: string\n"
162 " :arg str_ref_unit: A reference string from which to extract a default unit, if none is "
163 "found in ``str_input``.\n"
164 " :type str_ref_unit: string or None\n"
165 " :return: The converted/interpreted value.\n"
167 " :raises ValueError: if conversion fails to generate a valid python float value.\n");
171 const float scale = 1.0f;
179 static const char *_keywords[] = {
186 static _PyArg_Parser _parser = {
"sss#|z:to_value", _keywords, 0};
187 if (!_PyArg_ParseTupleAndKeywordsFast(
188 args, kw, &_parser, &usys_str, &ucat_str, &inpt, &str_len, &uref)) {
196 str_len = str_len * 2 + 64;
197 str = PyMem_MALLOC(
sizeof(*
str) * (
size_t)str_len);
203 if (PyErr_Occurred()) {
209 PyExc_ValueError,
"'%.200s' (converted as '%s') could not be evaluated.", inpt,
str);
221 ".. method:: to_string(unit_system, unit_category, value, precision=3, "
222 "split_unit=False, compatible_unit=False)\n"
224 " Convert a given input float value into a string with units.\n"
226 " :arg unit_system: The unit system, from :attr:`bpy.utils.units.systems`.\n"
227 " :type unit_system: string\n"
228 " :arg unit_category: The category of data we are converting (length, area, "
230 " from :attr:`bpy.utils.units.categories`.\n"
231 " :type unit_category: string\n"
232 " :arg value: The value to convert to a string.\n"
233 " :type value: float\n"
234 " :arg precision: Number of digits after the comma.\n"
235 " :type precision: int\n"
236 " :arg split_unit: Whether to use several units if needed (1m1cm), or always only "
238 " :type split_unit: bool\n"
239 " :arg compatible_unit: Whether to use keyboard-friendly units (1m2) or nicer "
240 "utf-8 ones (1m²).\n"
241 " :type compatible_unit: bool\n"
242 " :return: The converted string.\n"
244 " :raises ValueError: if conversion fails to generate a valid python string.\n");
247 char *usys_str =
NULL, *ucat_str =
NULL;
250 bool split_unit =
false, compatible_unit =
false;
254 static const char *_keywords[] = {
263 static _PyArg_Parser _parser = {
"ssd|iO&O&:to_string", _keywords, 0};
264 if (!_PyArg_ParseTupleAndKeywordsFast(args,
291 char buf1[64], buf2[64], *
str;
295 buf1,
sizeof(buf1), value, precision, usys, ucat, (
bool)split_unit,
false);
297 if (compatible_unit) {
314 METH_VARARGS | METH_KEYWORDS,
315 bpyunits_to_value_doc},
318 METH_VARARGS | METH_KEYWORDS,
319 bpyunits_to_string_doc},
323 PyDoc_STRVAR(bpyunits_doc,
"This module contains some data/methods regarding units handling.");
326 PyModuleDef_HEAD_INIT,
339 PyObject *submodule, *item;
342 PyDict_SetItemString(PyImport_GetModuleDict(),
bpyunits_module.m_name, submodule);
349 PyModule_AddObject(submodule,
"systems", item);
354 PyModule_AddObject(submodule,
"categories", item);
bool BKE_unit_is_valid(int system, int type)
size_t BKE_unit_value_as_string_adaptive(char *str, int len_max, double value, int prec, int system, int type, bool split, bool pad)
void BKE_unit_name_to_alt(char *str, int len_max, const char *orig_str, int system, int type)
bool BKE_unit_replace_string(char *str, int len_max, const char *str_prev, double scale_pref, int system, int type)
int BLI_str_index_in_array(const char *__restrict str, const char **__restrict str_array) ATTR_NONNULL()
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
static PyObject * py_structseq_from_strings(PyTypeObject *py_type, PyStructSequence_Desc *py_sseq_desc, const char **str_items)
static PyStructSequence_Field bpyunits_systems_fields[ARRAY_SIZE(bpyunits_usystem_items)]
static PyObject * bpyunits_to_string(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
PyObject * BPY_utils_units(void)
static const char * bpyunits_usystem_items[]
static const char * bpyunits_ucategorie_items[]
static PyStructSequence_Desc bpyunits_categories_desc
static PyMethodDef bpyunits_methods[]
static PyObject * bpyunits_to_value(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
static PyStructSequence_Field bpyunits_categories_fields[ARRAY_SIZE(bpyunits_ucategorie_items)]
static PyTypeObject BPyUnitsCategoriesType
static bool bpyunits_validate(const char *usys_str, const char *ucat_str, int *r_usys, int *r_ucat)
static PyStructSequence_Desc bpyunits_systems_desc
PyDoc_STRVAR(bpyunits_to_value_doc, ".. method:: to_value(unit_system, unit_category, str_input, str_ref_unit=None)\n" "\n" " Convert a given input string into a float value.\n" "\n" " :arg unit_system: The unit system, from :attr:`bpy.utils.units.systems`.\n" " :type unit_system: string\n" " :arg unit_category: The category of data we are converting (length, area, rotation, " "etc.),\n" " from :attr:`bpy.utils.units.categories`.\n" " :type unit_category: string\n" " :arg str_input: The string to convert to a float value.\n" " :type str_input: string\n" " :arg str_ref_unit: A reference string from which to extract a default unit, if none is " "found in ``str_input``.\n" " :type str_ref_unit: string or None\n" " :return: The converted/interpreted value.\n" " :rtype: float\n" " :raises ValueError: if conversion fails to generate a valid python float value.\n")
static struct PyModuleDef bpyunits_module
static PyTypeObject BPyUnitsSystemsType
bool PyC_RunString_AsNumber(const char *imports[], const char *expr, const char *filename, double *r_value)
int PyC_ParseBool(PyObject *o, void *p)