File: arraydatatype.py

package info (click to toggle)
pyopengl 3.1.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 11,184 kB
  • ctags: 21,473
  • sloc: python: 80,468; makefile: 4
file content (301 lines) | stat: -rw-r--r-- 13,543 bytes parent folder | download | duplicates (12)
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
"""Array data-type implementations (abstraction points for GL array types"""
import ctypes
import OpenGL
from OpenGL.raw.GL import _types
from OpenGL import plugins
from OpenGL.arrays import formathandler, _arrayconstants as GL_1_1
from OpenGL import logs
_log = logs.getLog( 'OpenGL.arrays.arraydatatype' )


from OpenGL import acceleratesupport
ADT = None
if acceleratesupport.ACCELERATE_AVAILABLE:
    try:
        from OpenGL_accelerate.arraydatatype import ArrayDatatype as ADT
    except ImportError as err:
        _log.warn(
            "Unable to load ArrayDatatype accelerator from OpenGL_accelerate"
        )
if ADT is None:
    # Python-coded version
    class HandlerRegistry( dict ):
        GENERIC_OUTPUT_PREFERENCES = ['numpy','ctypesarrays']
        def __init__( self, plugin_match ):
            self.match = plugin_match
            self.output_handler = None 
            self.preferredOutput = None
            self.all_output_handlers = []
        def __call__( self, value ):
            """Lookup of handler for given value"""
            try:
                typ = value.__class__
            except AttributeError as err:
                typ = type(value)
            handler = self.get( typ )
            if not handler:
                if hasattr( typ, '__mro__' ):
                    for base in typ.__mro__:
                        handler = self.get( base )
                        if not handler:
                            handler = self.match( base )
                            if handler:
                                handler = handler.load()
                                if handler:
                                    handler = handler()
                        if handler:
                            self[ typ ] = handler
                            if hasattr( handler, 'registerEquivalent' ):
                                handler.registerEquivalent( typ, base )
                            return handler
                raise TypeError(
                    """No array-type handler for type %s.%s (value: %s) registered"""%(
                        typ.__module__, type.__name__, repr(value)[:50]
                    )
                )
            return handler
        
        def handler_by_plugin_name( self, name ):
            plugin = plugins.FormatHandler.by_name( name )
            if plugin:
                try:
                    return plugin.load()
                except ImportError as err:
                    return None
            else:
                raise RuntimeError( 'No handler of name %s found'%(name,))
        
        def get_output_handler( self ):
            """Fast-path lookup for output handler object"""
            if self.output_handler is None:
                if self.preferredOutput is not None:
                    self.output_handler = self.handler_by_plugin_name( self.preferredOutput )
                if not self.output_handler:
                    for preferred in self.GENERIC_OUTPUT_PREFERENCES:
                        self.output_handler = self.handler_by_plugin_name( preferred )
                        if self.output_handler:
                            break
                if not self.output_handler:
                    raise RuntimeError(
                        """Unable to find any output handler at all (not even ctypes/numpy ones!)"""
                    )
            return self.output_handler
        
        def register( self, handler, types=None ):
            """Register this class as handler for given set of types"""
            if not isinstance( types, (list,tuple)):
                types = [ types ]
            for type in types:
                self[ type ] = handler
            if handler.isOutput:
                self.all_output_handlers.append( handler )
            
        def registerReturn( self, handler ):
            """Register this handler as the default return-type handler"""
            if isinstance( handler, (str,unicode)):
                self.preferredOutput = handler 
                self.output_handler = None
            else:
                self.preferredOutput = None 
                self.output_handler = handler 
    
    GLOBAL_REGISTRY = HandlerRegistry( plugins.FormatHandler.match)
    formathandler.FormatHandler.TYPE_REGISTRY = GLOBAL_REGISTRY
    
    class ArrayDatatype( object ):
        """Mix-in for array datatype classes
        
        The ArrayDatatype marker essentially is used to mark a particular argument
        as having an "array" type, which means that it is eligible for handling 
        via the arrays sub-package and its registered handlers.
        """
        typeConstant = None
        handler = GLOBAL_REGISTRY
        getHandler = GLOBAL_REGISTRY.__call__
        returnHandler = GLOBAL_REGISTRY.get_output_handler
        isAccelerated = False
        @classmethod
        def getRegistry( cls ):
            """Get our handler registry"""
            return cls.handler 
        def from_param( cls, value, typeConstant=None ):
            """Given a value in a known data-pointer type, convert to a ctypes pointer"""
            return cls.getHandler(value).from_param( value, cls.typeConstant )
        from_param = classmethod( logs.logOnFail( from_param, _log ) )
        def dataPointer( cls, value ):
            """Given a value in a known data-pointer type, return long for pointer"""
            try:
                return cls.getHandler(value).dataPointer( value )
            except Exception as err:
                _log.warn(
                    """Failure in dataPointer for %s instance %s""", type(value), value,
                )
                raise
        dataPointer = classmethod( logs.logOnFail( dataPointer, _log ) )
        def voidDataPointer( cls, value ):
            """Given value in a known data-pointer type, return void_p for pointer"""
            pointer = cls.dataPointer( value )
            try:
                return ctypes.c_void_p(pointer)
            except TypeError as err:
                return pointer
        voidDataPointer = classmethod( logs.logOnFail( voidDataPointer, _log ) )
        def typedPointer( cls, value ):
            """Return a pointer-to-base-type pointer for given value"""
            return ctypes.cast( cls.dataPointer(value), ctypes.POINTER( cls.baseType ))
        typedPointer = classmethod( typedPointer )
        def asArray( cls, value, typeCode=None ):
            """Given a value, convert to preferred array representation"""
            return cls.getHandler(value).asArray( value, typeCode or cls.typeConstant )
        asArray = classmethod( logs.logOnFail( asArray, _log ) )
        def arrayToGLType( cls, value ):
            """Given a data-value, guess the OpenGL type of the corresponding pointer
            
            Note: this is not currently used in PyOpenGL and may be removed 
            eventually.
            """
            return cls.getHandler(value).arrayToGLType( value )
        arrayToGLType = classmethod( logs.logOnFail( arrayToGLType, _log ) )
        def arraySize( cls, value, typeCode = None ):
            """Given a data-value, calculate dimensions for the array (number-of-units)"""
            return cls.getHandler(value).arraySize( value, typeCode or cls.typeConstant )
        arraySize = classmethod( logs.logOnFail( arraySize, _log ) )
        def unitSize( cls, value, typeCode=None ):
            """Determine unit size of an array (if possible)
            
            Uses our local type if defined, otherwise asks the handler to guess...
            """
            return cls.getHandler(value).unitSize( value, typeCode or cls.typeConstant )
        unitSize = classmethod( logs.logOnFail( unitSize, _log ) )
        def zeros( cls, dims, typeCode=None ):
            """Allocate a return array of the given dimensions filled with zeros"""
            return cls.returnHandler().zeros( dims, typeCode or cls.typeConstant )
        zeros = classmethod( logs.logOnFail( zeros, _log ) )
        def dimensions( cls, value ):
            """Given a data-value, get the dimensions (assumes full structure info)"""
            return cls.getHandler(value).dimensions( value )
        dimensions = classmethod( logs.logOnFail( dimensions, _log ) )
        
        def arrayByteCount( cls, value ):
            """Given a data-value, try to determine number of bytes it's final form occupies
            
            For most data-types this is arraySize() * atomic-unit-size
            """
            return cls.getHandler(value).arrayByteCount( value )
        arrayByteCount = classmethod( logs.logOnFail( arrayByteCount, _log ) )
            

    # the final array data-type classes...
    class GLclampdArray( ArrayDatatype, ctypes.POINTER(_types.GLclampd )):
        """Array datatype for GLclampd types"""
        baseType = _types.GLclampd
        typeConstant = _types.GL_DOUBLE

    class GLclampfArray( ArrayDatatype, ctypes.POINTER(_types.GLclampf )):
        """Array datatype for GLclampf types"""
        baseType = _types.GLclampf
        typeConstant = _types.GL_FLOAT

    class GLfloatArray( ArrayDatatype, ctypes.POINTER(_types.GLfloat )):
        """Array datatype for GLfloat types"""
        baseType = _types.GLfloat
        typeConstant = _types.GL_FLOAT

    class GLdoubleArray( ArrayDatatype, ctypes.POINTER(_types.GLdouble )):
        """Array datatype for GLdouble types"""
        baseType = _types.GLdouble
        typeConstant = _types.GL_DOUBLE

    class GLbyteArray( ArrayDatatype, ctypes.POINTER(_types.GLbyte )):
        """Array datatype for GLbyte types"""
        baseType = _types.GLbyte
        typeConstant = _types.GL_BYTE

    class GLcharArray( ArrayDatatype, ctypes.c_char_p):
        """Array datatype for ARB extension pointers-to-arrays"""
        baseType = _types.GLchar
        typeConstant = _types.GL_BYTE
    GLcharARBArray = GLcharArray

    class GLshortArray( ArrayDatatype, ctypes.POINTER(_types.GLshort )):
        """Array datatype for GLshort types"""
        baseType = _types.GLshort
        typeConstant = _types.GL_SHORT

    class GLintArray( ArrayDatatype, ctypes.POINTER(_types.GLint )):
        """Array datatype for GLint types"""
        baseType = _types.GLint
        typeConstant = _types.GL_INT

    class GLubyteArray( ArrayDatatype, ctypes.POINTER(_types.GLubyte )):
        """Array datatype for GLubyte types"""
        baseType = _types.GLubyte
        typeConstant = _types.GL_UNSIGNED_BYTE
    GLbooleanArray = GLubyteArray

    class GLushortArray( ArrayDatatype, ctypes.POINTER(_types.GLushort )):
        """Array datatype for GLushort types"""
        baseType = _types.GLushort
        typeConstant = _types.GL_UNSIGNED_SHORT

    class GLuintArray( ArrayDatatype, ctypes.POINTER(_types.GLuint )):
        """Array datatype for GLuint types"""
        baseType = _types.GLuint
        typeConstant = _types.GL_UNSIGNED_INT
    
    class GLint64Array( ArrayDatatype, ctypes.POINTER(_types.GLint64 )):
        """Array datatype for GLuint types"""
        baseType = _types.GLint64
        typeConstant = None # TODO: find out what this should be!
    
    class GLuint64Array( ArrayDatatype, ctypes.POINTER(_types.GLuint64 )):
        """Array datatype for GLuint types"""
        baseType = _types.GLuint64
        typeConstant = _types.GL_UNSIGNED_INT64

    class GLenumArray( ArrayDatatype, ctypes.POINTER(_types.GLenum )):
        """Array datatype for GLenum types"""
        baseType = _types.GLenum
        typeConstant = _types.GL_UNSIGNED_INT
    class GLsizeiArray( ArrayDatatype, ctypes.POINTER(_types.GLsizei )):
        """Array datatype for GLsizei types"""
        baseType = _types.GLsizei
        typeConstant = _types.GL_INT
    class GLvoidpArray( ArrayDatatype, ctypes.POINTER(_types.GLvoid )):
        """Array datatype for GLenum types"""
        baseType = _types.GLvoidp
        typeConstant = _types.GL_VOID_P
else:
    # Cython-coded array handler
    _log.info( 'Using accelerated ArrayDatatype' )
    ArrayDatatype = ADT( None, None )
    GLclampdArray = ADT( GL_1_1.GL_DOUBLE, _types.GLclampd )
    GLclampfArray = ADT( GL_1_1.GL_FLOAT, _types.GLclampf )
    GLdoubleArray = ADT( GL_1_1.GL_DOUBLE, _types.GLdouble )
    GLfloatArray = ADT( GL_1_1.GL_FLOAT, _types.GLfloat )
    GLbyteArray = ADT( GL_1_1.GL_BYTE, _types.GLbyte )
    GLcharArray = GLcharARBArray = ADT( GL_1_1.GL_BYTE, _types.GLchar )
    GLshortArray = ADT( GL_1_1.GL_SHORT, _types.GLshort )
    GLintArray = ADT( GL_1_1.GL_INT, _types.GLint )
    GLubyteArray = GLbooleanArray = ADT( GL_1_1.GL_UNSIGNED_BYTE, _types.GLubyte )
    GLushortArray = ADT( GL_1_1.GL_UNSIGNED_SHORT, _types.GLushort )
    GLuintArray = ADT( GL_1_1.GL_UNSIGNED_INT, _types.GLuint )
    GLint64Array = ADT( None, _types.GLint64 )
    GLuint64Array = ADT( GL_1_1.GL_UNSIGNED_INT64, _types.GLuint64 )
    GLenumArray = ADT( GL_1_1.GL_UNSIGNED_INT, _types.GLenum )
    GLsizeiArray = ADT( GL_1_1.GL_INT, _types.GLsizei )
    GLvoidpArray = ADT( _types.GL_VOID_P, _types.GLvoidp )

GL_CONSTANT_TO_ARRAY_TYPE = {
    GL_1_1.GL_DOUBLE : GLclampdArray,
    GL_1_1.GL_FLOAT : GLclampfArray,
    GL_1_1.GL_FLOAT : GLfloatArray,
    GL_1_1.GL_DOUBLE : GLdoubleArray,
    GL_1_1.GL_BYTE : GLbyteArray,
    GL_1_1.GL_SHORT : GLshortArray,
    GL_1_1.GL_INT : GLintArray,
    GL_1_1.GL_UNSIGNED_BYTE : GLubyteArray,
    GL_1_1.GL_UNSIGNED_SHORT : GLushortArray,
    GL_1_1.GL_UNSIGNED_INT : GLuintArray,
    #GL_1_1.GL_UNSIGNED_INT : GLenumArray,
}