File: arrayhelpers.py

package info (click to toggle)
pyopengl 3.1.10%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 15,024 kB
  • sloc: python: 108,056; sh: 13; makefile: 8
file content (219 lines) | stat: -rw-r--r-- 7,169 bytes parent folder | download | duplicates (2)
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
"""Helper functions for wrapping array-using operations

These are functions intended to be used in wrapping
GL functions that deal with OpenGL array data-types.
"""

import OpenGL
import ctypes
from OpenGL import _configflags
from OpenGL import contextdata, error, converters
from OpenGL.arrays import arraydatatype
from OpenGL._bytes import bytes, unicode
import logging

_log = logging.getLogger('OpenGL.arrays.arrayhelpers')
from OpenGL import acceleratesupport

AsArrayTypedSizeChecked = None
if acceleratesupport.ACCELERATE_AVAILABLE:
    try:
        from OpenGL_accelerate.arraydatatype import AsArrayTypedSizeChecked
        from OpenGL_accelerate.wrapper import returnPyArgumentIndex
        from OpenGL_accelerate.arraydatatype import (
            AsArrayOfType,
            AsArrayTyped,
            AsArrayTypedSize,
        )
    except ImportError as err:
        _log.warning("Unable to load arrayhelpers accelerator from OpenGL_accelerate")
if AsArrayTypedSizeChecked is None:

    def returnPointer(
        result,
        baseOperation,
        pyArgs,
        cArgs,
    ):
        """Return the converted object as result of function

        Note: this is a hack that always returns pyArgs[0]!
        """
        return pyArgs[0]

    class AsArrayOfType(converters.PyConverter):
        """Given arrayName and typeName coerce arrayName to array of type typeName

        TODO: It should be possible to drop this if ERROR_ON_COPY,
        as array inputs always have to be the final objects in that
        case.
        """

        argNames = ('arrayName', 'typeName')
        indexLookups = (
            ('arrayIndex', 'arrayName', 'pyArgIndex'),
            ('typeIndex', 'typeName', 'pyArgIndex'),
        )

        def __init__(self, arrayName='pointer', typeName='type'):
            self.arrayName = arrayName
            self.typeName = typeName

        def __call__(self, arg, wrappedOperation, args):
            """Get the arg as an array of the appropriate type"""
            type = args[self.typeIndex]
            arrayType = arraydatatype.GL_CONSTANT_TO_ARRAY_TYPE[type]
            return arrayType.asArray(arg)

    class AsArrayTyped(converters.PyConverter):
        """Given arrayName and arrayType, convert arrayName to array of type

        TODO: It should be possible to drop this if ERROR_ON_COPY,
        as array inputs always have to be the final objects in that
        case.
        """

        argNames = ('arrayName', 'arrayType')
        indexLookups = (('arrayIndex', 'arrayName', 'pyArgIndex'),)

        def __init__(self, arrayName='pointer', arrayType=None):
            self.arrayName = arrayName
            self.arrayType = arrayType

        def __call__(self, arg, wrappedOperation, args):
            """Get the arg as an array of the appropriate type"""
            return self.arrayType.asArray(arg)

    class AsArrayTypedSize(converters.CConverter):
        """Given arrayName and arrayType, determine size of arrayName"""

        argNames = ('arrayName', 'arrayType')
        indexLookups = (('arrayIndex', 'arrayName', 'pyArgIndex'),)

        def __init__(self, arrayName='pointer', arrayType=None):
            self.arrayName = arrayName
            self.arrayType = arrayType

        def __call__(self, pyArgs, index, wrappedOperation):
            """Get the arg as an array of the appropriate type"""
            return self.arrayType.arraySize(pyArgs[self.arrayIndex])

else:
    returnPointer = returnPyArgumentIndex(0)

if not _configflags.ERROR_ON_COPY:

    def asArrayType(typ, size=None):
        """Create PyConverter to get first argument as array of type"""
        return converters.CallFuncPyConverter(typ.asArray)

else:

    def asArrayType(typ, size=None):
        """No converter required"""
        return None


if not _configflags.ARRAY_SIZE_CHECKING:
    asArrayTypeSize = asArrayType
else:
    if AsArrayTypedSizeChecked:
        asArrayTypeSize = AsArrayTypedSizeChecked
    else:

        def asArrayTypeSize(typ, size):
            """Create PyConverter function to get array as type and check size

            Produces a raw function, not a PyConverter instance
            """
            # asArray = typ.asArray
            dataType = typ.typeConstant
            # arraySize = typ.arraySize
            expectedBytes = ctypes.sizeof(typ.baseType) * size

            def asArraySize(incoming, function, args):
                handler = typ.getHandler(incoming)
                result = handler.asArray(incoming, dataType)
                # check that the number of bytes expected is present...
                byteSize = handler.arrayByteCount(result)
                if byteSize != expectedBytes:
                    raise ValueError(
                        """Expected %r byte array, got %r byte array"""
                        % (
                            expectedBytes,
                            byteSize,
                        ),
                        incoming,
                    )
                return result

            return asArraySize


if not _configflags.ERROR_ON_COPY:

    def asVoidArray():
        """Create PyConverter returning incoming as an array of any type"""
        from OpenGL.arrays import ArrayDatatype

        return converters.CallFuncPyConverter(ArrayDatatype.asArray)

else:

    def asVoidArray():
        """If there's no copying allowed, we can use default passing"""
        return None


class storePointerType(object):
    """Store named pointer value in context indexed by constant

    pointerName -- named pointer argument
    constant -- constant used to index in the context storage

    Note: OpenGL.STORE_POINTERS can be set with ERROR_ON_COPY
    to ignore this storage operation.

    Stores the pyArgs (i.e. result of pyConverters) for the named
    pointer argument...
    """

    def __init__(self, pointerName, constant):
        self.pointerName = pointerName
        self.constant = constant

    def finalise(self, wrapper):
        self.pointerIndex = wrapper.pyArgIndex(self.pointerName)

    def __call__(self, result, baseOperation, pyArgs, cArgs):
        contextdata.setValue(self.constant, pyArgs[self.pointerIndex])


def setInputArraySizeType(baseOperation, size, type, argName=0):
    """Decorate function with vector-handling code for a single argument

    if OpenGL.ERROR_ON_COPY is False, then we return the
    named argument, converting to the passed array type,
    optionally checking that the array matches size.

    if OpenGL.ERROR_ON_COPY is True, then we will dramatically
    simplify this function, only wrapping if size is True, i.e.
    only wrapping if we intend to do a size check on the array.
    """
    from OpenGL import wrapper

    return wrapper.wrapper(baseOperation).setInputArraySize(argName, size)


def arraySizeOfFirstType(typ, default):
    unitSize = typ.unitSize

    def arraySizeOfFirst(pyArgs, index, baseOperation):
        """Return the array size of the first argument"""
        array = pyArgs[0]
        if array is None:
            return default
        else:
            return unitSize(array)

    return arraySizeOfFirst