Blender  V3.3
bpy_app_icons.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
9 #include <Python.h>
10 
11 #include "MEM_guardedalloc.h"
12 
13 #include "BLI_utildefines.h"
14 
15 #include "BKE_icons.h"
16 
17 #include "../generic/py_capi_utils.h"
18 
19 #include "bpy_app_icons.h"
20 
21 /* We may want to load direct from file. */
23  bpy_app_icons_new_triangles_doc,
24  ".. function:: new_triangles(range, coords, colors)\n"
25  "\n"
26  " Create a new icon from triangle geometry.\n"
27  "\n"
28  " :arg range: Pair of ints.\n"
29  " :type range: tuple.\n"
30  " :arg coords: Sequence of bytes (6 floats for one triangle) for (X, Y) coordinates.\n"
31  " :type coords: byte sequence.\n"
32  " :arg colors: Sequence of ints (12 for one triangles) for RGBA.\n"
33  " :type colors: byte sequence.\n"
34  " :return: Unique icon value (pass to interface ``icon_value`` argument).\n"
35  " :rtype: int\n");
36 static PyObject *bpy_app_icons_new_triangles(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
37 {
38  /* bytes */
39  uchar coords_range[2];
40  PyObject *py_coords, *py_colors;
41 
42  static const char *_keywords[] = {"range", "coords", "colors", NULL};
43  static _PyArg_Parser _parser = {
44  "(BB)" /* `range` */
45  "S" /* `coords` */
46  "S" /* `colors` */
47  ":new_triangles",
48  _keywords,
49  0,
50  };
51  if (!_PyArg_ParseTupleAndKeywordsFast(
52  args, kw, &_parser, &coords_range[0], &coords_range[1], &py_coords, &py_colors)) {
53  return NULL;
54  }
55 
56  const int coords_len = PyBytes_GET_SIZE(py_coords);
57  const int tris_len = coords_len / 6;
58  if (tris_len * 6 != coords_len) {
59  PyErr_SetString(PyExc_ValueError, "coords must be multiple of 6");
60  return NULL;
61  }
62  if (PyBytes_GET_SIZE(py_colors) != 2 * coords_len) {
63  PyErr_SetString(PyExc_ValueError, "colors must be twice size of coords");
64  return NULL;
65  }
66 
67  const int coords_size = sizeof(uchar[2]) * tris_len * 3;
68  const int colors_size = sizeof(uchar[4]) * tris_len * 3;
69  uchar(*coords)[2] = MEM_mallocN(coords_size, __func__);
70  uchar(*colors)[4] = MEM_mallocN(colors_size, __func__);
71 
72  memcpy(coords, PyBytes_AS_STRING(py_coords), coords_size);
73  memcpy(colors, PyBytes_AS_STRING(py_colors), colors_size);
74 
75  struct Icon_Geom *geom = MEM_mallocN(sizeof(*geom), __func__);
76  geom->coords_len = tris_len;
77  geom->coords_range[0] = coords_range[0];
78  geom->coords_range[1] = coords_range[1];
79  geom->coords = coords;
80  geom->colors = colors;
81  geom->icon_id = 0;
82  const int icon_id = BKE_icon_geom_ensure(geom);
83  return PyLong_FromLong(icon_id);
84 }
85 
86 PyDoc_STRVAR(bpy_app_icons_new_triangles_from_file_doc,
87  ".. function:: new_triangles_from_file(filename)\n"
88  "\n"
89  " Create a new icon from triangle geometry.\n"
90  "\n"
91  " :arg filename: File path.\n"
92  " :type filename: string.\n"
93  " :return: Unique icon value (pass to interface ``icon_value`` argument).\n"
94  " :rtype: int\n");
95 static PyObject *bpy_app_icons_new_triangles_from_file(PyObject *UNUSED(self),
96  PyObject *args,
97  PyObject *kw)
98 {
99  /* bytes */
100  char *filename;
101 
102  static const char *_keywords[] = {"filename", NULL};
103  static _PyArg_Parser _parser = {
104  "s" /* `filename` */
105  ":new_triangles_from_file",
106  _keywords,
107  0,
108  };
109  if (!_PyArg_ParseTupleAndKeywordsFast(args, kw, &_parser, &filename)) {
110  return NULL;
111  }
112 
113  struct Icon_Geom *geom = BKE_icon_geom_from_file(filename);
114  if (geom == NULL) {
115  PyErr_SetString(PyExc_ValueError, "Unable to load from file");
116  return NULL;
117  }
118  const int icon_id = BKE_icon_geom_ensure(geom);
119  return PyLong_FromLong(icon_id);
120 }
121 
122 PyDoc_STRVAR(bpy_app_icons_release_doc,
123  ".. function:: release(icon_id)\n"
124  "\n"
125  " Release the icon.\n");
126 static PyObject *bpy_app_icons_release(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
127 {
128  int icon_id;
129  static const char *_keywords[] = {"icon_id", NULL};
130  static _PyArg_Parser _parser = {
131  "i" /* `icon_id` */
132  ":release",
133  _keywords,
134  0,
135  };
136  if (!_PyArg_ParseTupleAndKeywordsFast(args, kw, &_parser, &icon_id)) {
137  return NULL;
138  }
139 
141  PyErr_SetString(PyExc_ValueError, "invalid icon_id");
142  return NULL;
143  }
144  Py_RETURN_NONE;
145 }
146 
147 static struct PyMethodDef M_AppIcons_methods[] = {
148  {"new_triangles",
149  (PyCFunction)bpy_app_icons_new_triangles,
150  METH_VARARGS | METH_KEYWORDS,
151  bpy_app_icons_new_triangles_doc},
152  {"new_triangles_from_file",
154  METH_VARARGS | METH_KEYWORDS,
155  bpy_app_icons_new_triangles_from_file_doc},
156  {"release",
157  (PyCFunction)bpy_app_icons_release,
158  METH_VARARGS | METH_KEYWORDS,
159  bpy_app_icons_release_doc},
160  {NULL, NULL, 0, NULL},
161 };
162 
163 static struct PyModuleDef M_AppIcons_module_def = {
164  PyModuleDef_HEAD_INIT,
165  "bpy.app.icons", /* m_name */
166  NULL, /* m_doc */
167  0, /* m_size */
168  M_AppIcons_methods, /* m_methods */
169  NULL, /* m_reload */
170  NULL, /* m_traverse */
171  NULL, /* m_clear */
172  NULL, /* m_free */
173 };
174 
175 PyObject *BPY_app_icons_module(void)
176 {
177  PyObject *sys_modules = PyImport_GetModuleDict();
178 
179  PyObject *mod = PyModule_Create(&M_AppIcons_module_def);
180 
181  PyDict_SetItem(sys_modules, PyModule_GetNameObject(mod), mod);
182 
183  return mod;
184 }
struct Icon_Geom * BKE_icon_geom_from_file(const char *filename)
Definition: icons.cc:988
bool BKE_icon_delete_unmanaged(int icon_id)
Definition: icons.cc:905
int BKE_icon_geom_ensure(struct Icon_Geom *geom)
Definition: icons.cc:933
unsigned char uchar
Definition: BLI_sys_types.h:70
#define UNUSED(x)
Read Guarded memory(de)allocation.
PyObject * BPY_app_icons_module(void)
PyDoc_STRVAR(bpy_app_icons_new_triangles_doc, ".. function:: new_triangles(range, coords, colors)\n" "\n" " Create a new icon from triangle geometry.\n" "\n" " :arg range: Pair of ints.\n" " :type range: tuple.\n" " :arg coords: Sequence of bytes (6 floats for one triangle) for (X, Y) coordinates.\n" " :type coords: byte sequence.\n" " :arg colors: Sequence of ints (12 for one triangles) for RGBA.\n" " :type colors: byte sequence.\n" " :return: Unique icon value (pass to interface ``icon_value`` argument).\n" " :rtype: int\n")
static PyObject * bpy_app_icons_release(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
static struct PyModuleDef M_AppIcons_module_def
static PyObject * bpy_app_icons_new_triangles(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
Definition: bpy_app_icons.c:36
static PyObject * bpy_app_icons_new_triangles_from_file(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
Definition: bpy_app_icons.c:95
static struct PyMethodDef M_AppIcons_methods[]
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
int coords_len
Definition: BKE_icons.h:62
unsigned char(* colors)[4]
Definition: BKE_icons.h:65
int icon_id
Definition: BKE_icons.h:61
unsigned char(* coords)[2]
Definition: BKE_icons.h:64
int coords_range[2]
Definition: BKE_icons.h:63
ccl_device_inline int mod(int x, int m)
Definition: util/math.h:490