forked from bartvdbraak/blender
bgl module: Interpret a buffer as a bgl.Buffer
Differential Revision: https://developer.blender.org/D2857
This commit is contained in:
parent
88520dd5b6
commit
2de5e14f53
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user