diff options
author | mano-wii <germano.costa@ig.com.br> | 2018-09-11 16:03:53 +0300 |
---|---|---|
committer | mano-wii <germano.costa@ig.com.br> | 2018-09-11 16:03:53 +0300 |
commit | cde66d791650dc69478eefba4d0e2f932732a8eb (patch) | |
tree | 9276aa7180a76b1709a14863242b2726e39c196b /source | |
parent | 8dde1e13e26b78295e112fccac0b2c4dfbd42e3c (diff) |
GPUVertBuf.fill: support for objects with buffer interface.
Differential Revision: https://developer.blender.org/D3684
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/python/gpu/gpu_py_vertex_buffer.c | 112 |
1 files changed, 70 insertions, 42 deletions
diff --git a/source/blender/python/gpu/gpu_py_vertex_buffer.c b/source/blender/python/gpu/gpu_py_vertex_buffer.c index 923947f6078..1b8a257425b 100644 --- a/source/blender/python/gpu/gpu_py_vertex_buffer.c +++ b/source/blender/python/gpu/gpu_py_vertex_buffer.c @@ -98,65 +98,93 @@ static bool bpygpu_vertbuf_fill_impl( GPUVertBuf *vbo, uint data_id, PyObject *seq) { + const char *exc_str_size_mismatch = "Expected a %s of size %d, got %d"; + bool ok = true; const GPUVertAttr *attr = &vbo->format.attribs[data_id]; - GPUVertBufRaw data_step; - GPU_vertbuf_attr_get_raw_data(vbo, data_id, &data_step); + if (PyObject_CheckBuffer(seq)) { + Py_buffer pybuffer; - PyObject *seq_fast = PySequence_Fast(seq, "Vertex buffer fill"); - if (seq_fast == NULL) { - goto finally; - } + if (PyObject_GetBuffer(seq, &pybuffer, PyBUF_STRIDES | PyBUF_ND) == -1) { + /* PyObject_GetBuffer raise a PyExc_BufferError */ + return false; + } - const uint seq_len = PySequence_Fast_GET_SIZE(seq_fast); + int comp_len = pybuffer.ndim == 1 ? 1 : pybuffer.shape[1]; - if (seq_len != vbo->vertex_len) { - PyErr_Format(PyExc_ValueError, - "Expected a sequence of size %d, got %d", - vbo->vertex_len, seq_len); + if (pybuffer.shape[0] != vbo->vertex_len) { + PyErr_Format(PyExc_ValueError, exc_str_size_mismatch, + "sequence", vbo->vertex_len, pybuffer.shape[0]); + ok = false; + } + else if (comp_len != attr->comp_len) { + PyErr_Format(PyExc_ValueError, exc_str_size_mismatch, + "component", attr->comp_len, comp_len); + ok = false; + } + else { + GPU_vertbuf_attr_fill_stride(vbo, data_id, pybuffer.strides[0], pybuffer.buf); + } + + PyBuffer_Release(&pybuffer); } + else { + GPUVertBufRaw data_step; + GPU_vertbuf_attr_get_raw_data(vbo, data_id, &data_step); + + PyObject *seq_fast = PySequence_Fast(seq, "Vertex buffer fill"); + if (seq_fast == NULL) { + return false; + } - PyObject **seq_items = PySequence_Fast_ITEMS(seq_fast); + const uint seq_len = PySequence_Fast_GET_SIZE(seq_fast); - if (attr->comp_len == 1) { - for (uint i = 0; i < seq_len; i++) { - uchar *data = (uchar *)GPU_vertbuf_raw_step(&data_step); - PyObject *item = seq_items[i]; - fill_format_elem(data, item, attr); + if (seq_len != vbo->vertex_len) { + PyErr_Format(PyExc_ValueError, exc_str_size_mismatch, + "sequence", vbo->vertex_len, seq_len); } - } - else { - for (uint i = 0; i < seq_len; i++) { - uchar *data = (uchar *)GPU_vertbuf_raw_step(&data_step); - 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; + + PyObject **seq_items = PySequence_Fast_ITEMS(seq_fast); + + if (attr->comp_len == 1) { + for (uint i = 0; i < seq_len; i++) { + uchar *data = (uchar *)GPU_vertbuf_raw_step(&data_step); + PyObject *item = seq_items[i]; + fill_format_elem(data, item, attr); } - if (PyTuple_GET_SIZE(item) != attr->comp_len) { - PyErr_Format(PyExc_ValueError, - "expected a tuple of size %d, got %d", - attr->comp_len, PyTuple_GET_SIZE(item)); - ok = false; - goto finally; + } + else { + for (uint i = 0; i < seq_len; i++) { + uchar *data = (uchar *)GPU_vertbuf_raw_step(&data_step); + 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) != attr->comp_len) { + PyErr_Format(PyExc_ValueError, exc_str_size_mismatch, + "tuple", attr->comp_len, PyTuple_GET_SIZE(item)); + ok = false; + goto finally; + } + + /* May trigger error, check below */ + fill_format_tuple(data, item, attr); } - - /* May trigger error, check below */ - fill_format_tuple(data, item, attr); } - } - if (PyErr_Occurred()) { - ok = false; - } + if (PyErr_Occurred()) { + ok = false; + } finally: - Py_DECREF(seq_fast); + Py_DECREF(seq_fast); + } return ok; } |