27#define PYGPU_AS_NATIVE_SWITCH(attr) \
28 switch (attr->type.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 PY_AS_NATIVE(float, PyFloat_AsDouble); \
58 BLI_assert_unreachable(); \
66#define PY_AS_NATIVE(ty_dst, py_as_native) \
68 ty_dst *data_dst = static_cast<ty_dst *>(data_dst_void); \
69 *data_dst = py_as_native(py_src); \
80 PyObject *py_seq_fast,
84 PyObject **value_fast_items = PySequence_Fast_ITEMS(py_seq_fast);
89#define PY_AS_NATIVE(ty_dst, py_as_native) \
90 ty_dst *data_dst = static_cast<ty_dst *>(data_dst_void); \
91 for (uint i = 0; i < len; i++) { \
92 data_dst[i] = py_as_native(value_fast_items[i]); \
101#undef PYGPU_AS_NATIVE_SWITCH
102#undef WARN_TYPE_LIMIT_PUSH
103#undef WARN_TYPE_LIMIT_POP
108 const char *error_prefix)
110 const char *exc_str_size_mismatch =
"Expected a %s of size %d, got %u";
116 if (PyObject_CheckBuffer(seq)) {
119 if (PyObject_GetBuffer(seq, &pybuffer, PyBUF_STRIDES | PyBUF_ND) == -1) {
124 const uint comp_len = pybuffer.ndim == 1 ? 1 :
uint(pybuffer.shape[1]);
126 if (pybuffer.shape[0] != vert_len) {
128 PyExc_ValueError, exc_str_size_mismatch,
"sequence", vert_len, pybuffer.shape[0]);
133 PyExc_ValueError, exc_str_size_mismatch,
"component", attr->
type.
comp_len(), comp_len);
140 PyBuffer_Release(&pybuffer);
146 PyObject *seq_fast = PySequence_Fast(seq,
"Vertex buffer fill");
147 if (seq_fast ==
nullptr) {
151 const uint seq_len = PySequence_Fast_GET_SIZE(seq_fast);
153 if (seq_len != vert_len) {
154 PyErr_Format(PyExc_ValueError, exc_str_size_mismatch,
"sequence", vert_len, seq_len);
157 PyObject **seq_items = PySequence_Fast_ITEMS(seq_fast);
160 for (
uint i = 0;
i < seq_len;
i++) {
162 PyObject *item = seq_items[
i];
167 for (
uint i = 0;
i < seq_len;
i++) {
169 PyObject *seq_fast_item = PySequence_Fast(seq_items[
i], error_prefix);
171 if (seq_fast_item ==
nullptr) {
175 if (PySequence_Fast_GET_SIZE(seq_fast_item) != attr->
type.
comp_len()) {
176 PyErr_Format(PyExc_ValueError,
177 exc_str_size_mismatch,
180 PySequence_Fast_GET_SIZE(seq_fast_item));
192 if (PyErr_Occurred()) {
205 PyObject *py_seq_data,
206 const char *error_prefix)
209 PyErr_Format(PyExc_ValueError,
"Format id %d out of range",
id);
213 if (buf->
data<
char>().data() ==
nullptr) {
214 PyErr_SetString(PyExc_ValueError,
"Can't fill, static buffer already in use");
240 static const char *_keywords[] = {
"format",
"len",
nullptr};
241 static _PyArg_Parser _parser = {
245 ":GPUVertBuf.__new__",
249 if (!_PyArg_ParseTupleAndKeywordsFast(
265 pygpu_vertbuf_attr_fill_doc,
266 ".. method:: attr_fill(id, data)\n"
268 " Insert data into the buffer for a single attribute.\n"
270 " :arg id: Either the name or the id of the attribute.\n"
271 " :type id: int | str\n"
272 " :arg data: Buffer or sequence of data that should be stored in the buffer\n"
273 " :type data: Buffer | "
274 "Sequence[float] | Sequence[int] | Sequence[Sequence[float]] | Sequence[Sequence[int]]\n");
278 PyObject *identifier;
280 static const char *_keywords[] = {
"id",
"data",
nullptr};
281 static _PyArg_Parser _parser = {
289 if (!_PyArg_ParseTupleAndKeywordsFast(args, kwds, &_parser, &identifier, &
data)) {
295 if (PyLong_Check(identifier)) {
296 id = PyLong_AsLong(identifier);
298 else if (PyUnicode_Check(identifier)) {
300 const char *
name = PyUnicode_AsUTF8(identifier);
303 PyErr_Format(PyExc_ValueError,
"Unknown attribute '%s'",
name);
308 PyErr_SetString(PyExc_TypeError,
"expected int or str type as identifier");
321# pragma clang diagnostic push
322# pragma clang diagnostic ignored "-Wcast-function-type"
324# pragma GCC diagnostic push
325# pragma GCC diagnostic ignored "-Wcast-function-type"
332 METH_VARARGS | METH_KEYWORDS,
333 pygpu_vertbuf_attr_fill_doc},
334 {
nullptr,
nullptr, 0,
nullptr},
339# pragma clang diagnostic pop
341# pragma GCC diagnostic pop
353 pygpu_vertbuf__tp_doc,
354 ".. class:: GPUVertBuf(format, len)\n"
358 " :arg format: Vertex format.\n"
359 " :type format: :class:`gpu.types.GPUVertFormat`\n"
360 " :arg len: Amount of vertices that will fit into this buffer.\n"
361 " :type len: int\n");
363 PyVarObject_HEAD_INIT(
nullptr, 0)
383 pygpu_vertbuf__tp_doc,
427 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)
static blender::gpu::VertBuf * GPU_vertbuf_create_with_format(const GPUVertFormat &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()
struct GPUVertAttr::Type type