1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# ##### END GPL LICENSE BLOCK #####
import bgl
import ctypes
import numpy as np
# figure out size of _Py_ssize_t
if hasattr(ctypes.pythonapi, 'Py_InitModule4_64'):
_Py_ssize_t = ctypes.c_int64
else:
_Py_ssize_t = ctypes.c_int
class _PyObject(ctypes.Structure):
pass
_PyObject._fields_ = [
('ob_refcnt', _Py_ssize_t),
('ob_type', ctypes.POINTER(_PyObject)),
]
if object.__basicsize__ != ctypes.sizeof(_PyObject):
# python with trace
class _PyObject(ctypes.Structure):
_fields_ = [
('_ob_next', ctypes.POINTER(_PyObject)),
('_ob_prev', ctypes.POINTER(_PyObject)),
('ob_refcnt', _Py_ssize_t),
('ob_type', ctypes.POINTER(_PyObject)),
]
class _PyVarObject(_PyObject):
_fields_ = [
('ob_size', _Py_ssize_t),
]
class C_Buffer(_PyVarObject):
_fields_ = [
("parent", ctypes.py_object),
("type", ctypes.c_int),
("ndimensions", ctypes.c_int),
("dimensions", ctypes.POINTER(ctypes.c_int)),
("buf", ctypes.c_void_p),
]
assert ctypes.sizeof(C_Buffer) == bgl.Buffer.__basicsize__
class VoidBufValue():
def __init__(self, value):
self.buf = bgl.Buffer(bgl.GL_BYTE, 1)
self.c_buf = C_Buffer.from_address(id(self.buf))
self._allocated_buf = self.c_buf.buf
self.c_buf.buf = value
self.c_buf.type = 0 # allows repr
def __del__(self):
self.c_buf.buf = self._allocated_buf
#del self._allocated_buf
del self.buf
def np_array_as_bgl_Buffer(array):
type = array.dtype
if type == np.int8:
type = bgl.GL_BYTE
elif type == np.int16:
type = bgl.GL_SHORT
elif type == np.int32:
type = bgl.GL_INT
elif type == np.float32:
type = bgl.GL_FLOAT
elif type == np.float64:
type = bgl.GL_DOUBLE
else:
raise
_decref = ctypes.pythonapi.Py_DecRef
_incref = ctypes.pythonapi.Py_IncRef
_decref.argtypes = _incref.argtypes = [ctypes.py_object]
_decref.restype = _incref.restype = None
buf = bgl.Buffer(bgl.GL_BYTE, ((1,) * (len(array.shape) + 1)))[0]
c_buf = C_Buffer.from_address(id(buf))
_decref(c_buf.parent)
_incref(array)
c_buf.parent = array # Prevents MEM_freeN
c_buf.type = type
for i, n in enumerate(array.shape):
c_buf.dimensions[i] = n
c_buf.buf = array.ctypes.data
return buf
def bgl_Buffer_reshape(buf, shape):
assert np.prod(buf.dimensions) == np.prod(shape)
c_buf = C_Buffer.from_address(id(buf))
c_buf.ndimensions = len(shape)
tmp_buf = bgl.Buffer(c_buf.type, (1,) * len(shape))
c_tmp_buf = C_Buffer.from_address(id(tmp_buf))
for i, v in enumerate(shape):
c_tmp_buf.dimensions[i] = v
offset = C_Buffer.dimensions.offset
a = ctypes.pointer(ctypes.c_void_p.from_address(id(tmp_buf) + offset))
b = ctypes.pointer(ctypes.c_void_p.from_address(id(buf) + offset))
a[0], b[0] = b[0], a[0]
del c_buf
del c_tmp_buf
del tmp_buf
|