Merge branch 'master' into blender2.8
[blender.git] / source / blender / python / gpu / gpu_py_element.c
index 657358d04482537ea0af2fa76505950ff2088db1..12027d2e2b80c2ed2f1dfcb7c17e237d6ff7d142 100644 (file)
@@ -47,6 +47,7 @@
 
 static PyObject *bpygpu_IndexBuf_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject *kwds)
 {
+       const char *error_prefix = "IndexBuf.__new__";
        bool ok = true;
 
        struct {
@@ -91,20 +92,11 @@ static PyObject *bpygpu_IndexBuf_new(PyTypeObject *UNUSED(type), PyObject *args,
                        return NULL;
                }
 
-               bool format_error = pybuffer.itemsize != 4;
+               if (pybuffer.itemsize != 4 ||
+                   PyC_StructFmt_type_is_float_any(PyC_StructFmt_type_from_str(pybuffer.format)))
                {
-                       char *typestr = pybuffer.format;
-                       if (ELEM(typestr[0], '<', '>', '|')) {
-                               typestr += 1;
-                       }
-                       if (ELEM(typestr[0], 'f', 'd')) {
-                               format_error = true;
-                       }
-               }
-
-               if (format_error) {
                        PyErr_Format(PyExc_ValueError,
-                               "Each index must be an integer value with 4 bytes in size");
+                                    "Each index must be an 4-bytes integer value");
                        return NULL;
                }
 
@@ -125,14 +117,13 @@ static PyObject *bpygpu_IndexBuf_new(PyTypeObject *UNUSED(type), PyObject *args,
                        GPU_indexbuf_add_generic_vert(&builder, *buf);
                }
 #else
-               memcpy(builder.data, pybuffer.buf, index_len * sizeof(builder.data));
+               memcpy(builder.data, pybuffer.buf, index_len * sizeof(*builder.data));
                builder.index_len = index_len;
 #endif
                PyBuffer_Release(&pybuffer);
        }
        else {
-               PyObject *seq_fast = PySequence_Fast(
-                       params.seq, "Index Buffer Initialization");
+               PyObject *seq_fast = PySequence_Fast(params.seq, error_prefix);
 
                if (seq_fast == NULL) {
                        return false;
@@ -157,28 +148,27 @@ static PyObject *bpygpu_IndexBuf_new(PyTypeObject *UNUSED(type), PyObject *args,
                        }
                }
                else {
+                       int values[4];
                        for (uint i = 0; i < seq_len; i++) {
-                               PyObject *item = seq_items[i];
-                               if (!PyTuple_CheckExact(item)) {
-                                       PyErr_Format(PyExc_ValueError,
-                                                    "expected a tuple, got %s",
-                                                    Py_TYPE(item)->tp_name);
-                                       ok = false;
-                                       goto finally;
-                               }
-                               if (PyTuple_GET_SIZE(item) != verts_per_prim) {
-                                       PyErr_Format(PyExc_ValueError,
-                                                    "Expected a Tuple of size %d, got %d",
-                                                    PyTuple_GET_SIZE(item));
+                               PyObject *seq_fast_item = PySequence_Fast(seq_items[i], error_prefix);
+                               if (seq_fast_item == NULL) {
+                                       PyErr_Format(PyExc_TypeError,
+                                                    "%s: expected a sequence, got %s",
+                                                    error_prefix, Py_TYPE(seq_items[i])->tp_name);
                                        ok = false;
                                        goto finally;
                                }
 
-                               for (uint j = 0; j < verts_per_prim; j++) {
-                                       GPU_indexbuf_add_generic_vert(
-                                               &builder,
-                                               PyC_Long_AsU32(PyTuple_GET_ITEM(item, j)));
+                               ok = PyC_AsArray_FAST(
+                                       values, seq_fast_item, verts_per_prim,
+                                       &PyLong_Type, false, error_prefix) == 0;
+
+                               if (ok) {
+                                       for (uint j = 0; j < verts_per_prim; j++) {
+                                               GPU_indexbuf_add_generic_vert(&builder, values[j]);
+                                       }
                                }
+                               Py_DECREF(seq_fast_item);
                        }
                }
 
@@ -206,19 +196,20 @@ static void bpygpu_IndexBuf_dealloc(BPyGPUIndexBuf *self)
 }
 
 PyDoc_STRVAR(py_gpu_element_doc,
-"GPUIndexBuf(type, seq)\n"
+".. class:: GPUIndexBuf(type, seq)\n"
 "\n"
-"Contains a VBO."
+"   Contains an index buffer.\n"
 "\n"
-"   :param prim_type:\n"
-"      One of these primitive types: {\n"
-"      'POINTS',\n"
-"      'LINES',\n"
-"      'TRIS',\n"
-"      'LINE_STRIP_ADJ'}\n"
+"   :param type: One of these primitive types: {\n"
+"      `POINTS`,\n"
+"      `LINES`,\n"
+"      `TRIS`,\n"
+"      `LINE_STRIP_ADJ` }\n"
 "   :type type: `str`\n"
-"   :param seq: Sequence of integers.\n"
-"   :type buf: `Any 1D or 2D Sequence`\n"
+"   :param seq: Indices this index buffer will contain.\n"
+"      Whether a 1D or 2D sequence is required depends on the type.\n"
+"      Optionally the sequence can support the buffer protocol.\n"
+"   :type seq: 1D or 2D sequence\n"
 );
 PyTypeObject BPyGPUIndexBuf_Type = {
        PyVarObject_HEAD_INIT(NULL, 0)