Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGermano <germano.costa@ig.com.br>2017-09-27 17:20:00 +0300
committerGermano <germano.costa@ig.com.br>2017-09-27 17:20:00 +0300
commit2de5e14f53e9a439ae87deb16f816ec71445c1ba (patch)
tree5259d9a9d2581695a15ab84c6d57b66857937c22 /source/blender/python
parent88520dd5b6ff5bf310421ab6b9a30d7d49425685 (diff)
bgl module: Interpret a buffer as a bgl.Buffer
Differential Revision: https://developer.blender.org/D2857
Diffstat (limited to 'source/blender/python')
-rw-r--r--source/blender/python/generic/bgl.c120
1 files changed, 84 insertions, 36 deletions
diff --git a/source/blender/python/generic/bgl.c b/source/blender/python/generic/bgl.c
index 3ea10228ad4..79d01d25e17 100644
--- a/source/blender/python/generic/bgl.c
+++ b/source/blender/python/generic/bgl.c
@@ -472,6 +472,34 @@ int BGL_typeSize(int type)
return -1;
}
+static int gl_buffer_type_from_py_format_char(char format)
+{
+ switch (format) {
+ case 'b':
+ return GL_BYTE;
+ case 'h':
+ case 'i':
+ return GL_SHORT;
+ case 'l':
+ return GL_INT;
+ case 'f':
+ return GL_FLOAT;
+ case 'd':
+ return GL_DOUBLE;
+ }
+ return -1; /* UNKNOWN */
+}
+
+static bool compare_dimensions(int ndim, int *dim1, Py_ssize_t *dim2)
+{
+ for (int i = 0; i < ndim; i++) {
+ if (dim1[i] != dim2[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
/** \} */
@@ -630,6 +658,22 @@ PyTypeObject BGL_bufferType = {
NULL /*tp_del*/
};
+
+static Buffer *BGL_MakeBuffer_FromData(PyObject *parent, int type, int ndimensions, int *dimensions, void *buf)
+{
+ Buffer *buffer = (Buffer *)PyObject_NEW(Buffer, &BGL_bufferType);
+
+ Py_XINCREF(parent);
+ buffer->parent = parent;
+ buffer->ndimensions = ndimensions;
+ buffer->dimensions = MEM_mallocN(ndimensions * sizeof(int), "Buffer dimensions");
+ memcpy(buffer->dimensions, dimensions, ndimensions * sizeof(int));
+ buffer->type = type;
+ buffer->buf.asvoid = buf;
+
+ return buffer;
+}
+
/**
* Create a buffer object
*
@@ -641,30 +685,21 @@ Buffer *BGL_MakeBuffer(int type, int ndimensions, int *dimensions, void *initbuf
{
Buffer *buffer;
void *buf = NULL;
- int i, size, length;
+ int i, size = BGL_typeSize(type);
- length = 1;
for (i = 0; i < ndimensions; i++) {
- length *= dimensions[i];
+ size *= dimensions[i];
}
- size = BGL_typeSize(type);
+ buf = MEM_mallocN(size, "Buffer buffer");
- buf = MEM_mallocN(length * size, "Buffer buffer");
-
- buffer = (Buffer *)PyObject_NEW(Buffer, &BGL_bufferType);
- buffer->parent = NULL;
- buffer->ndimensions = ndimensions;
- buffer->dimensions = MEM_mallocN(ndimensions * sizeof(int), "Buffer dimensions");
- memcpy(buffer->dimensions, dimensions, ndimensions * sizeof(int));
- buffer->type = type;
- buffer->buf.asvoid = buf;
+ buffer = BGL_MakeBuffer_FromData(NULL, type, ndimensions, dimensions, buf);
if (initbuffer) {
- memcpy(buffer->buf.asvoid, initbuffer, length * size);
+ memcpy(buffer->buf.asvoid, initbuffer, size);
}
else {
- memset(buffer->buf.asvoid, 0, length * size);
+ memset(buffer->buf.asvoid, 0, size);
}
return buffer;
}
@@ -674,7 +709,7 @@ Buffer *BGL_MakeBuffer(int type, int ndimensions, int *dimensions, void *initbuf
static PyObject *Buffer_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject *kwds)
{
PyObject *length_ob = NULL, *init = NULL;
- Buffer *buffer;
+ Buffer *buffer = NULL;
int dimensions[MAX_DIMENSIONS];
int type;
@@ -739,9 +774,32 @@ static PyObject *Buffer_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject
return NULL;
}
- buffer = BGL_MakeBuffer(type, ndimensions, dimensions, NULL);
- if (init && ndimensions) {
- if (Buffer_ass_slice(buffer, 0, dimensions[0], init)) {
+ if (init && PyObject_CheckBuffer(init)) {
+ Py_buffer pybuffer;
+
+ if (PyObject_GetBuffer(init, &pybuffer, PyBUF_ND | PyBUF_FORMAT) == -1) {
+ /* PyObject_GetBuffer raise a PyExc_BufferError */
+ return NULL;
+ }
+
+ if (type != gl_buffer_type_from_py_format_char(*pybuffer.format)) {
+ PyErr_Format(PyExc_TypeError,
+ "`GL_TYPE` and `format` of object with buffer interface do not match");
+ }
+ else if (ndimensions != pybuffer.ndim ||
+ !compare_dimensions(ndimensions, dimensions, pybuffer.shape))
+ {
+ PyErr_Format(PyExc_TypeError, "array size does not match");
+ }
+ else {
+ buffer = BGL_MakeBuffer_FromData(init, type, pybuffer.ndim, dimensions, pybuffer.buf);
+ }
+
+ PyBuffer_Release(&pybuffer);
+ }
+ else {
+ buffer = BGL_MakeBuffer(type, ndimensions, dimensions, NULL);
+ if (init && Buffer_ass_slice(buffer, 0, dimensions[0], init)) {
Py_DECREF(buffer);
return NULL;
}
@@ -774,27 +832,17 @@ static PyObject *Buffer_item(Buffer *self, int i)
}
}
else {
- Buffer *newbuf;
- int j, length, size;
+ int j, offset = i * BGL_typeSize(self->type);
- length = 1;
for (j = 1; j < self->ndimensions; j++) {
- length *= self->dimensions[j];
+ offset *= self->dimensions[j];
}
- size = BGL_typeSize(self->type);
-
- newbuf = (Buffer *)PyObject_NEW(Buffer, &BGL_bufferType);
-
- Py_INCREF(self);
- newbuf->parent = (PyObject *)self;
-
- newbuf->ndimensions = self->ndimensions - 1;
- newbuf->type = self->type;
- newbuf->buf.asvoid = self->buf.asbyte + i * length * size;
- newbuf->dimensions = MEM_mallocN(newbuf->ndimensions * sizeof(int), "Buffer dimensions");
- memcpy(newbuf->dimensions, self->dimensions + 1, newbuf->ndimensions * sizeof(int));
- return (PyObject *)newbuf;
+ return BGL_MakeBuffer_FromData(
+ self, self->type,
+ self->ndimensions - 1,
+ self->dimensions + 1,
+ self->buf.asbyte + offset);
}
return NULL;