30#define PYGPU_AS_NATIVE_SWITCH(attr) \
31 switch (attr->comp_type) { \
33 PY_AS_NATIVE(int8_t, PyC_Long_AsI8); \
37 PY_AS_NATIVE(uint8_t, PyC_Long_AsU8); \
40 case GPU_COMP_I16: { \
41 PY_AS_NATIVE(int16_t, PyC_Long_AsI16); \
44 case GPU_COMP_U16: { \
45 PY_AS_NATIVE(uint16_t, PyC_Long_AsU16); \
48 case GPU_COMP_I32: { \
49 PY_AS_NATIVE(int32_t, PyC_Long_AsI32); \
52 case GPU_COMP_U32: { \
53 PY_AS_NATIVE(uint32_t, PyC_Long_AsU32); \
56 case GPU_COMP_F32: { \
57 PY_AS_NATIVE(float, PyFloat_AsDouble); \
61 BLI_assert_unreachable(); \
69#define PY_AS_NATIVE(ty_dst, py_as_native) \
71 ty_dst *data_dst = static_cast<ty_dst *>(data_dst_void); \
72 *data_dst = py_as_native(py_src); \
83 PyObject *py_seq_fast,
87 PyObject **value_fast_items = PySequence_Fast_ITEMS(py_seq_fast);
92#define PY_AS_NATIVE(ty_dst, py_as_native) \
93 ty_dst *data_dst = static_cast<ty_dst *>(data_dst_void); \
94 for (uint i = 0; i < len; i++) { \
95 data_dst[i] = py_as_native(value_fast_items[i]); \
104#undef PYGPU_AS_NATIVE_SWITCH
105#undef WARN_TYPE_LIMIT_PUSH
106#undef WARN_TYPE_LIMIT_POP
111 const char *error_prefix)
113 const char *exc_str_size_mismatch =
"Expected a %s of size %d, got %u";
119 if (PyObject_CheckBuffer(seq)) {
122 if (PyObject_GetBuffer(seq, &pybuffer, PyBUF_STRIDES | PyBUF_ND) == -1) {
127 const uint comp_len = pybuffer.ndim == 1 ? 1 :
uint(pybuffer.shape[1]);
129 if (pybuffer.shape[0] != vert_len) {
131 PyExc_ValueError, exc_str_size_mismatch,
"sequence", vert_len, pybuffer.shape[0]);
134 else if (comp_len != attr->
comp_len) {
135 PyErr_Format(PyExc_ValueError, exc_str_size_mismatch,
"component", attr->
comp_len, comp_len);
142 PyBuffer_Release(&pybuffer);
148 PyObject *seq_fast = PySequence_Fast(seq,
"Vertex buffer fill");
149 if (seq_fast ==
nullptr) {
153 const uint seq_len = PySequence_Fast_GET_SIZE(seq_fast);
155 if (seq_len != vert_len) {
156 PyErr_Format(PyExc_ValueError, exc_str_size_mismatch,
"sequence", vert_len, seq_len);
159 PyObject **seq_items = PySequence_Fast_ITEMS(seq_fast);
162 for (
uint i = 0; i < seq_len; i++) {
164 PyObject *item = seq_items[i];
169 for (
uint i = 0; i < seq_len; i++) {
171 PyObject *seq_fast_item = PySequence_Fast(seq_items[i], error_prefix);
173 if (seq_fast_item ==
nullptr) {
177 if (PySequence_Fast_GET_SIZE(seq_fast_item) != attr->
comp_len) {
178 PyErr_Format(PyExc_ValueError,
179 exc_str_size_mismatch,
182 PySequence_Fast_GET_SIZE(seq_fast_item));
184 Py_DECREF(seq_fast_item);
190 Py_DECREF(seq_fast_item);
194 if (PyErr_Occurred()) {
207 PyObject *py_seq_data,
208 const char *error_prefix)
211 PyErr_Format(PyExc_ValueError,
"Format id %d out of range",
id);
215 if (buf->
data<
char>().data() ==
nullptr) {
216 PyErr_SetString(PyExc_ValueError,
"Can't fill, static buffer already in use");
242 static const char *_keywords[] = {
"format",
"len",
nullptr};
243 static _PyArg_Parser _parser = {
247 ":GPUVertBuf.__new__",
251 if (!_PyArg_ParseTupleAndKeywordsFast(
267 pygpu_vertbuf_attr_fill_doc,
268 ".. method:: attr_fill(id, data)\n"
270 " Insert data into the buffer for a single attribute.\n"
272 " :arg id: Either the name or the id of the attribute.\n"
273 " :type id: int | str\n"
274 " :arg data: Buffer or sequence of data that should be stored in the buffer\n"
275 " :type data: Buffer | "
276 "Sequence[float] | Sequence[int] | Sequence[Sequence[float]] | Sequence[Sequence[int]]\n");
280 PyObject *identifier;
282 static const char *_keywords[] = {
"id",
"data",
nullptr};
283 static _PyArg_Parser _parser = {
291 if (!_PyArg_ParseTupleAndKeywordsFast(args, kwds, &_parser, &identifier, &data)) {
297 if (PyLong_Check(identifier)) {
298 id = PyLong_AsLong(identifier);
300 else if (PyUnicode_Check(identifier)) {
302 const char *name = PyUnicode_AsUTF8(identifier);
305 PyErr_Format(PyExc_ValueError,
"Unknown attribute '%s'", name);
310 PyErr_SetString(PyExc_TypeError,
"expected int or str type as identifier");
321#if (defined(__GNUC__) && !defined(__clang__))
322# pragma GCC diagnostic push
323# pragma GCC diagnostic ignored "-Wcast-function-type"
329 METH_VARARGS | METH_KEYWORDS,
330 pygpu_vertbuf_attr_fill_doc},
331 {
nullptr,
nullptr, 0,
nullptr},
334#if (defined(__GNUC__) && !defined(__clang__))
335# pragma GCC diagnostic pop
346 pygpu_vertbuf__tp_doc,
347 ".. class:: GPUVertBuf(format, len)\n"
351 " :arg format: Vertex format.\n"
352 " :type format: :class:`gpu.types.GPUVertFormat`\n"
353 " :arg len: Amount of vertices that will fit into this buffer.\n"
354 " :type len: int\n");
356 PyVarObject_HEAD_INIT(
nullptr, 0)
376 pygpu_vertbuf__tp_doc,
420 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 *)
Read Guarded memory(de)allocation.
#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()