27#define PYGPU_AS_NATIVE_SWITCH(attr) \
28 switch (attr->comp_type) { \
30 PY_AS_NATIVE(int8_t, PyC_Long_AsI8); \
34 PY_AS_NATIVE(uint8_t, PyC_Long_AsU8); \
37 case GPU_COMP_I16: { \
38 PY_AS_NATIVE(int16_t, PyC_Long_AsI16); \
41 case GPU_COMP_U16: { \
42 PY_AS_NATIVE(uint16_t, PyC_Long_AsU16); \
45 case GPU_COMP_I32: { \
46 PY_AS_NATIVE(int32_t, PyC_Long_AsI32); \
49 case GPU_COMP_U32: { \
50 PY_AS_NATIVE(uint32_t, PyC_Long_AsU32); \
53 case GPU_COMP_F32: { \
54 if (attr->python_int_to_float) { \
55 PY_AS_NATIVE(float, PyC_Long_AsI32); \
58 PY_AS_NATIVE(float, PyFloat_AsDouble); \
63 BLI_assert_unreachable(); \
71#define PY_AS_NATIVE(ty_dst, py_as_native) \
73 ty_dst *data_dst = static_cast<ty_dst *>(data_dst_void); \
74 *data_dst = py_as_native(py_src); \
85 PyObject *py_seq_fast,
89 PyObject **value_fast_items = PySequence_Fast_ITEMS(py_seq_fast);
94#define PY_AS_NATIVE(ty_dst, py_as_native) \
95 ty_dst *data_dst = static_cast<ty_dst *>(data_dst_void); \
96 for (uint i = 0; i < len; i++) { \
97 data_dst[i] = py_as_native(value_fast_items[i]); \
106#undef PYGPU_AS_NATIVE_SWITCH
107#undef WARN_TYPE_LIMIT_PUSH
108#undef WARN_TYPE_LIMIT_POP
113 const char *error_prefix)
115 const char *exc_str_size_mismatch =
"Expected a %s of size %d, got %u";
121 if (PyObject_CheckBuffer(seq)) {
124 if (PyObject_GetBuffer(seq, &pybuffer, PyBUF_STRIDES | PyBUF_ND) == -1) {
129 const uint comp_len = pybuffer.ndim == 1 ? 1 :
uint(pybuffer.shape[1]);
131 if (pybuffer.shape[0] != vert_len) {
133 PyExc_ValueError, exc_str_size_mismatch,
"sequence", vert_len, pybuffer.shape[0]);
136 else if (comp_len != attr->
comp_len) {
137 PyErr_Format(PyExc_ValueError, exc_str_size_mismatch,
"component", attr->
comp_len, comp_len);
144 PyBuffer_Release(&pybuffer);
150 PyObject *seq_fast = PySequence_Fast(seq,
"Vertex buffer fill");
151 if (seq_fast ==
nullptr) {
155 const uint seq_len = PySequence_Fast_GET_SIZE(seq_fast);
157 if (seq_len != vert_len) {
158 PyErr_Format(PyExc_ValueError, exc_str_size_mismatch,
"sequence", vert_len, seq_len);
161 PyObject **seq_items = PySequence_Fast_ITEMS(seq_fast);
164 for (
uint i = 0;
i < seq_len;
i++) {
166 PyObject *item = seq_items[
i];
171 for (
uint i = 0;
i < seq_len;
i++) {
173 PyObject *seq_fast_item = PySequence_Fast(seq_items[
i], error_prefix);
175 if (seq_fast_item ==
nullptr) {
179 if (PySequence_Fast_GET_SIZE(seq_fast_item) != attr->
comp_len) {
180 PyErr_Format(PyExc_ValueError,
181 exc_str_size_mismatch,
184 PySequence_Fast_GET_SIZE(seq_fast_item));
186 Py_DECREF(seq_fast_item);
192 Py_DECREF(seq_fast_item);
196 if (PyErr_Occurred()) {
209 PyObject *py_seq_data,
210 const char *error_prefix)
213 PyErr_Format(PyExc_ValueError,
"Format id %d out of range",
id);
217 if (buf->
data<
char>().data() ==
nullptr) {
218 PyErr_SetString(PyExc_ValueError,
"Can't fill, static buffer already in use");
244 static const char *_keywords[] = {
"format",
"len",
nullptr};
245 static _PyArg_Parser _parser = {
249 ":GPUVertBuf.__new__",
253 if (!_PyArg_ParseTupleAndKeywordsFast(
269 pygpu_vertbuf_attr_fill_doc,
270 ".. method:: attr_fill(id, data)\n"
272 " Insert data into the buffer for a single attribute.\n"
274 " :arg id: Either the name or the id of the attribute.\n"
275 " :type id: int | str\n"
276 " :arg data: Buffer or sequence of data that should be stored in the buffer\n"
277 " :type data: Buffer | "
278 "Sequence[float] | Sequence[int] | Sequence[Sequence[float]] | Sequence[Sequence[int]]\n");
282 PyObject *identifier;
284 static const char *_keywords[] = {
"id",
"data",
nullptr};
285 static _PyArg_Parser _parser = {
293 if (!_PyArg_ParseTupleAndKeywordsFast(args, kwds, &_parser, &identifier, &
data)) {
299 if (PyLong_Check(identifier)) {
300 id = PyLong_AsLong(identifier);
302 else if (PyUnicode_Check(identifier)) {
304 const char *name = PyUnicode_AsUTF8(identifier);
307 PyErr_Format(PyExc_ValueError,
"Unknown attribute '%s'", name);
312 PyErr_SetString(PyExc_TypeError,
"expected int or str type as identifier");
325# pragma clang diagnostic push
326# pragma clang diagnostic ignored "-Wcast-function-type"
328# pragma GCC diagnostic push
329# pragma GCC diagnostic ignored "-Wcast-function-type"
336 METH_VARARGS | METH_KEYWORDS,
337 pygpu_vertbuf_attr_fill_doc},
338 {
nullptr,
nullptr, 0,
nullptr},
343# pragma clang diagnostic pop
345# pragma GCC diagnostic pop
357 pygpu_vertbuf__tp_doc,
358 ".. class:: GPUVertBuf(format, len)\n"
362 " :arg format: Vertex format.\n"
363 " :type format: :class:`gpu.types.GPUVertFormat`\n"
364 " :arg len: Amount of vertices that will fit into this buffer.\n"
365 " :type len: int\n");
367 PyVarObject_HEAD_INIT(
nullptr, 0)
387 pygpu_vertbuf__tp_doc,
431 return (PyObject *)
self;
void GPU_vertbuf_attr_get_raw_data(blender::gpu::VertBuf *, uint a_idx, GPUVertBufRaw *access)
GPU_INLINE void * GPU_vertbuf_raw_step(GPUVertBufRaw *a)
void GPU_vertbuf_attr_fill_stride(blender::gpu::VertBuf *, uint a_idx, uint stride, const void *data)
#define GPU_vertbuf_create_with_format(format)
const GPUVertFormat * GPU_vertbuf_get_format(const blender::gpu::VertBuf *verts)
void GPU_vertbuf_data_alloc(blender::gpu::VertBuf &verts, uint v_len)
uint GPU_vertbuf_get_vertex_len(const blender::gpu::VertBuf *verts)
void GPU_vertbuf_discard(blender::gpu::VertBuf *)
BMesh const char void * data
#define BPYGPU_IS_INIT_OR_ERROR_OBJ
PyTypeObject BPyGPUVertBuf_Type
PyObject * BPyGPUVertBuf_CreatePyObject(blender::gpu::VertBuf *buf)
static bool pygpu_vertbuf_fill_impl(blender::gpu::VertBuf *vbo, uint data_id, PyObject *seq, const char *error_prefix)
static PyObject * pygpu_vertbuf__tp_new(PyTypeObject *, PyObject *args, PyObject *kwds)
#define PYGPU_AS_NATIVE_SWITCH(attr)
static void pygpu_fill_format_sequence(void *data_dst_void, PyObject *py_seq_fast, const GPUVertAttr *attr)
static PyObject * pygpu_vertbuf_attr_fill(BPyGPUVertBuf *self, PyObject *args, PyObject *kwds)
static void pygpu_fill_format_elem(void *data_dst_void, PyObject *py_src, const GPUVertAttr *attr)
static int pygpu_vertbuf_fill(blender::gpu::VertBuf *buf, int id, PyObject *py_seq_data, const char *error_prefix)
static PyMethodDef pygpu_vertbuf__tp_methods[]
PyDoc_STRVAR(pygpu_vertbuf_attr_fill_doc, ".. method:: attr_fill(id, data)\n" "\n" " Insert data into the buffer for a single attribute.\n" "\n" " :arg id: Either the name or the id of the attribute.\n" " :type id: int | str\n" " :arg data: Buffer or sequence of data that should be stored in the buffer\n" " :type data: Buffer | " "Sequence[float] | Sequence[int] | Sequence[Sequence[float]] | Sequence[Sequence[int]]\n")
static void pygpu_vertbuf__tp_dealloc(BPyGPUVertBuf *self)
header-only compatibility defines.
#define PY_ARG_PARSER_HEAD_COMPAT()