bgl module: Interpret a buffer as a bgl.Buffer
Differential Revision: https://developer.blender.org/D2857
This commit is contained in:
@@ -472,6 +472,34 @@ int BGL_typeSize(int type)
|
|||||||
return -1;
|
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*/
|
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
|
* Create a buffer object
|
||||||
*
|
*
|
||||||
@@ -641,30 +685,21 @@ Buffer *BGL_MakeBuffer(int type, int ndimensions, int *dimensions, void *initbuf
|
|||||||
{
|
{
|
||||||
Buffer *buffer;
|
Buffer *buffer;
|
||||||
void *buf = NULL;
|
void *buf = NULL;
|
||||||
int i, size, length;
|
int i, size = BGL_typeSize(type);
|
||||||
|
|
||||||
length = 1;
|
|
||||||
for (i = 0; i < ndimensions; i++) {
|
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 = BGL_MakeBuffer_FromData(NULL, type, ndimensions, dimensions, buf);
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
if (initbuffer) {
|
if (initbuffer) {
|
||||||
memcpy(buffer->buf.asvoid, initbuffer, length * size);
|
memcpy(buffer->buf.asvoid, initbuffer, size);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
memset(buffer->buf.asvoid, 0, length * size);
|
memset(buffer->buf.asvoid, 0, size);
|
||||||
}
|
}
|
||||||
return buffer;
|
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)
|
static PyObject *Buffer_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject *kwds)
|
||||||
{
|
{
|
||||||
PyObject *length_ob = NULL, *init = NULL;
|
PyObject *length_ob = NULL, *init = NULL;
|
||||||
Buffer *buffer;
|
Buffer *buffer = NULL;
|
||||||
int dimensions[MAX_DIMENSIONS];
|
int dimensions[MAX_DIMENSIONS];
|
||||||
|
|
||||||
int type;
|
int type;
|
||||||
@@ -739,9 +774,32 @@ static PyObject *Buffer_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
buffer = BGL_MakeBuffer(type, ndimensions, dimensions, NULL);
|
||||||
if (init && ndimensions) {
|
if (init && Buffer_ass_slice(buffer, 0, dimensions[0], init)) {
|
||||||
if (Buffer_ass_slice(buffer, 0, dimensions[0], init)) {
|
|
||||||
Py_DECREF(buffer);
|
Py_DECREF(buffer);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -774,27 +832,17 @@ static PyObject *Buffer_item(Buffer *self, int i)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Buffer *newbuf;
|
int j, offset = i * BGL_typeSize(self->type);
|
||||||
int j, length, size;
|
|
||||||
|
|
||||||
length = 1;
|
|
||||||
for (j = 1; j < self->ndimensions; j++) {
|
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);
|
return BGL_MakeBuffer_FromData(
|
||||||
|
self, self->type,
|
||||||
Py_INCREF(self);
|
self->ndimensions - 1,
|
||||||
newbuf->parent = (PyObject *)self;
|
self->dimensions + 1,
|
||||||
|
self->buf.asbyte + offset);
|
||||||
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 NULL;
|
return NULL;
|
||||||
|
|||||||
Reference in New Issue
Block a user