Commit: da96336e5ffa146cc240d1e9fe3c3d98e41387d1 Author: mano-wii Date: Thu Sep 27 00:53:45 2018 -0300 Branches: blender2.8 https://developer.blender.org/rBda96336e5ffa146cc240d1e9fe3c3d98e41387d1
Python GPU module: Wrap GPUIndexBuf Differential Revision D3714 =================================================================== M source/blender/gpu/GPU_element.h M source/blender/gpu/intern/gpu_element.c M source/blender/python/gpu/CMakeLists.txt M source/blender/python/gpu/gpu_py_batch.c A source/blender/python/gpu/gpu_py_element.c A source/blender/python/gpu/gpu_py_element.h A source/blender/python/gpu/gpu_py_primitive.c A source/blender/python/gpu/gpu_py_primitive.h M source/blender/python/gpu/gpu_py_types.c M source/blender/python/gpu/gpu_py_types.h =================================================================== diff --git a/source/blender/gpu/GPU_element.h b/source/blender/gpu/GPU_element.h index adc705ab641..9d2458ef1aa 100644 --- a/source/blender/gpu/GPU_element.h +++ b/source/blender/gpu/GPU_element.h @@ -89,6 +89,7 @@ void GPU_indexbuf_build_in_place(GPUIndexBufBuilder *, GPUIndexBuf *); void GPU_indexbuf_discard(GPUIndexBuf *); +int GPU_indexbuf_primitive_len(GPUPrimType prim_type); /* Macros */ diff --git a/source/blender/gpu/intern/gpu_element.c b/source/blender/gpu/intern/gpu_element.c index 56a0c90d5b5..782346f4712 100644 --- a/source/blender/gpu/intern/gpu_element.c +++ b/source/blender/gpu/intern/gpu_element.c @@ -63,6 +63,24 @@ uint GPU_indexbuf_size_get(const GPUIndexBuf *elem) #endif } +int GPU_indexbuf_primitive_len(GPUPrimType prim_type) +{ + switch (prim_type) { + case GPU_PRIM_POINTS: + return 1; + case GPU_PRIM_LINES: + return 2; + case GPU_PRIM_TRIS: + return 3; + case GPU_PRIM_LINES_ADJ: + return 4; + } +#if TRUST_NO_ONE + assert(false); +#endif + return -1; +} + void GPU_indexbuf_init_ex( GPUIndexBufBuilder *builder, GPUPrimType prim_type, uint index_len, uint vertex_len, bool use_prim_restart) @@ -77,28 +95,11 @@ void GPU_indexbuf_init_ex( void GPU_indexbuf_init(GPUIndexBufBuilder *builder, GPUPrimType prim_type, uint prim_len, uint vertex_len) { - uint verts_per_prim = 0; - switch (prim_type) { - case GPU_PRIM_POINTS: - verts_per_prim = 1; - break; - case GPU_PRIM_LINES: - verts_per_prim = 2; - break; - case GPU_PRIM_TRIS: - verts_per_prim = 3; - break; - case GPU_PRIM_LINES_ADJ: - verts_per_prim = 4; - break; - default: + int verts_per_prim = GPU_indexbuf_primitive_len(prim_type); #if TRUST_NO_ONE - assert(false); + assert(verts_per_prim != -1); #endif - return; - } - - GPU_indexbuf_init_ex(builder, prim_type, prim_len * verts_per_prim, vertex_len, false); + GPU_indexbuf_init_ex(builder, prim_type, prim_len * (uint)verts_per_prim, vertex_len, false); } void GPU_indexbuf_add_generic_vert(GPUIndexBufBuilder *builder, uint v) diff --git a/source/blender/python/gpu/CMakeLists.txt b/source/blender/python/gpu/CMakeLists.txt index bdd8fa1b996..0d4dedf7c76 100644 --- a/source/blender/python/gpu/CMakeLists.txt +++ b/source/blender/python/gpu/CMakeLists.txt @@ -36,8 +36,10 @@ set(INC_SYS set(SRC gpu_py_api.c gpu_py_batch.c + gpu_py_element.c gpu_py_matrix.c gpu_py_offscreen.c + gpu_py_primitive.c gpu_py_select.c gpu_py_shader.c gpu_py_types.c @@ -46,8 +48,10 @@ set(SRC gpu_py_api.h gpu_py_batch.h + gpu_py_element.h gpu_py_matrix.h gpu_py_offscreen.h + gpu_py_primitive.h gpu_py_select.h gpu_py_shader.h gpu_py_types.h diff --git a/source/blender/python/gpu/gpu_py_batch.c b/source/blender/python/gpu/gpu_py_batch.c index 4e7804f382f..df7d305300c 100644 --- a/source/blender/python/gpu/gpu_py_batch.c +++ b/source/blender/python/gpu/gpu_py_batch.c @@ -45,8 +45,10 @@ #include "../generic/py_capi_utils.h" +#include "gpu_py_primitive.h" #include "gpu_py_shader.h" #include "gpu_py_vertex_buffer.h" +#include "gpu_py_element.h" #include "gpu_py_batch.h" /* own include */ @@ -55,69 +57,56 @@ /** \name VertBatch Type * \{ */ -static int bpygpu_ParsePrimType(PyObject *o, void *p) -{ - Py_ssize_t mode_id_len; - const char *mode_id = _PyUnicode_AsStringAndSize(o, &mode_id_len); - if (mode_id == NULL) { - PyErr_Format(PyExc_ValueError, - "expected a string, got %s", - Py_TYPE(o)->tp_name); - return 0; - } -#define MATCH_ID(id) \ - if (mode_id_len == strlen(STRINGIFY(id))) { \ - if (STREQ(mode_id, STRINGIFY(id))) { \ - mode = GPU_PRIM_##id; \ - goto success; \ - } \ - } ((void)0) - - GPUPrimType mode; - MATCH_ID(POINTS); - MATCH_ID(LINES); - MATCH_ID(TRIS); - MATCH_ID(LINE_STRIP); - MATCH_ID(LINE_LOOP); - MATCH_ID(TRI_STRIP); - MATCH_ID(TRI_FAN); - MATCH_ID(LINE_STRIP_ADJ); - -#undef MATCH_ID - PyErr_Format(PyExc_ValueError, - "unknown type literal: '%s'", - mode_id); - return 0; - -success: - (*(GPUPrimType *)p) = mode; - return 1; -} - static PyObject *bpygpu_Batch_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject *kwds) { + const char *exc_str_missing_arg = "GPUBatch.__new__() missing required argument '%s' (pos %d)"; + struct { GPUPrimType type_id; - BPyGPUVertBuf *py_buf; - } params; + BPyGPUVertBuf *py_vertbuf; + BPyGPUIndexBuf *py_indexbuf; + } params = {GPU_PRIM_NONE, NULL, NULL}; - static const char *_keywords[] = {"type", "buf", NULL}; - static _PyArg_Parser _parser = {"$O&O!:GPUBatch.__new__", _keywords, 0}; + static const char *_keywords[] = {"type", "buf", "elem", NULL}; + static _PyArg_Parser _parser = {"|$O&O!O!:GPUBatch.__new__", _keywords, 0}; if (!_PyArg_ParseTupleAndKeywordsFast( args, kwds, &_parser, bpygpu_ParsePrimType, ¶ms.type_id, - &BPyGPUVertBuf_Type, ¶ms.py_buf)) + &BPyGPUVertBuf_Type, ¶ms.py_vertbuf, + &BPyGPUIndexBuf_Type, ¶ms.py_indexbuf)) { return NULL; } - GPUBatch *batch = GPU_batch_create(params.type_id, params.py_buf->buf, NULL); + if (params.type_id == GPU_PRIM_NONE) { + PyErr_Format(PyExc_TypeError, + exc_str_missing_arg, _keywords[0], 1); + return NULL; + } + + if (params.py_vertbuf == NULL) { + PyErr_Format(PyExc_TypeError, + exc_str_missing_arg, _keywords[1], 2); + return NULL; + } + + GPUBatch *batch = GPU_batch_create( + params.type_id, + params.py_vertbuf->buf, + params.py_indexbuf ? params.py_indexbuf->elem : NULL); + BPyGPUBatch *ret = (BPyGPUBatch *)BPyGPUBatch_CreatePyObject(batch); #ifdef USE_GPU_PY_REFERENCES - ret->references = PyList_New(1); - PyList_SET_ITEM(ret->references, 0, (PyObject *)params.py_buf); - Py_INCREF(params.py_buf); + ret->references = PyList_New(params.py_indexbuf ? 2 : 1); + PyList_SET_ITEM(ret->references, 0, (PyObject *)params.py_vertbuf); + Py_INCREF(params.py_vertbuf); + + if (params.py_indexbuf != NULL) { + PyList_SET_ITEM(ret->references, 1, (PyObject *)params.py_indexbuf); + Py_INCREF(params.py_indexbuf); + } + PyObject_GC_Track(ret); #endif @@ -373,25 +362,26 @@ static void bpygpu_Batch_dealloc(BPyGPUBatch *self) } PyDoc_STRVAR(py_gpu_batch_doc, -"GPUBatch(type, buf)\n" +"GPUBatch(type, buf, elem=None)\n" "\n" "Contains VAOs + VBOs + Shader representing a drawable entity." "\n" " :param type: One of these primitive types: {\n" -" \"POINTS\",\n" -" \"LINES\",\n" -" \"TRIS\",\n" -" \"LINE_STRIP\",\n" -" \"LINE_LOOP\",\n" -" \"TRI_STRIP\",\n" -" \"TRI_FAN\",\n" -" \"LINES_ADJ\",\n" -" \"TRIS_ADJ\",\n" -" \"LINE_STRIP_ADJ\",\n" -" \"NONE\"}\n" +" 'POINTS',\n" +" 'LINES',\n" +" 'TRIS',\n" +" 'LINE_STRIP',\n" +" 'LINE_LOOP',\n" +" 'TRI_STRIP',\n" +" 'TRI_FAN',\n" +" 'LINES_ADJ',\n" +" 'TRIS_ADJ',\n" +" 'LINE_STRIP_ADJ'}\n" " :type type: `str`\n" " :param buf: Vertex buffer.\n" " :type buf: :class: `gpu.types.GPUVertBuf`\n" +" :param elem: Optional Index buffer.\n" +" :type elem: :class: `gpu.types.GPUIndexBuf`\n" ); PyTypeObject BPyGPUBatch_Type = { PyVarObject_HEAD_INIT(NULL, 0) diff --git a/source/blender/python/gpu/gpu_py_element.c b/source/blender/python/gpu/gpu_py_element.c new file mode 100644 index 00000000000..1683def7ec8 --- /dev/null +++ b/source/blender/python/gpu/gpu_py_element.c @@ -0,0 +1,251 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/python/gpu/gpu_py_element.c + * \ingroup bpygpu + * + * - Use ``bpygpu_`` for local API. + * - Use ``BPyGPU`` for public API. + */ + +#include <Python.h> + +#include "GPU_element.h" + +#include "BLI_math.h" + +#include "MEM_guardedalloc.h" + +#include "../generic/py_capi_utils.h" +#include "../generic/python_utildefines.h" + +#include "gpu_py_primitive.h" +#include "gpu_py_element.h" /* own include */ + + +/* -------------------------------------------------------------------- */ + +/** \name IndexBuf Type + * \{ */ + +static PyObject *bpygpu_IndexBuf_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject *kwds) +{ + bool ok = true; + + struct { + GPUPrimType type_id; + PyObject *seq; + } params; + + uint verts_per_prim; + uint index_len; + GPUIndexBufBuilder builder; + + static const char *_keywords[] = {"type", "seq", NULL}; + static _PyArg_Parser _parser = {"$O&O:IndexBuf.__new__", _keywords, 0}; + if (!_PyArg_ParseTupleAndKeywordsFast( + args, kwds, &_parser, + bpygpu_ParsePrimType, ¶ms.type_id, + ¶ms.seq)) + { + return NULL; + } + + verts_per_prim = GPU_indexbuf_primitive_len(params.type_id); + if (verts_per_prim == -1) { + PyErr_Format(PyExc_ValueError, + "The argument 'type' must be " + "'POINTS', 'LINES', 'TRIS' or 'LINES_ADJ'"); + return NULL; + } + + if (PyObject_CheckBuffer(params.seq)) { + Py_buffer pybuffer; + + if (PyObject_GetBuffer(params.seq, &pybuffer, PyBUF_FORMAT | PyBUF_ND) == -1) { + /* PyObject_GetBuffer already handles error messages. */ + return NULL; + } + + if (pybuffer.ndim != 1 && pybuffer.shape[1] != verts_per_prim) { + PyErr_Format(PyExc_ValueError, + "Each primitive must exactly %d indices", + verts_per_prim); + return NULL; + } + + bool format_error = pybuffer.itemsize != 4; + { + char *typestr = pybuffer.for @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs