1"""Buffer based Numpy plugin (not used)
2
3This API is no more useful than the direct Numpy version, as Numpy already
4gives us the details we need *when using the accelerator module* at a low
5level, with very fast access.  When using the non-accelerated version the
6ctypes version *might* show some performance benefits, but it's not going
7to be fast no matter what we do without C-level code.
8"""
9REGISTRY_NAME = 'numpybuffers'
10import operator
11try:
12    import numpy
13except ImportError as err:
14    raise ImportError( """No numpy module present: %s"""%(err))
15from OpenGL.arrays import buffers
16from OpenGL.raw.GL import _types
17from OpenGL.raw.GL.VERSION import GL_1_1
18from OpenGL import constant, error
19class NumpyHandler( buffers.BufferHandler ):
20    @classmethod
21    def zeros( cls, dims, typeCode ):
22        """Return Numpy array of zeros in given size"""
23        return numpy.zeros( dims, GL_TYPE_TO_ARRAY_MAPPING[typeCode])
24
25    @classmethod
26    def asArray( cls, value, typeCode=None ):
27        """Convert given value to an array value of given typeCode"""
28        return super(NumpyHandler,cls).asArray( cls.contiguous(value,typeCode), typeCode )
29    @classmethod
30    def contiguous( cls, source, typeCode=None ):
31        """Get contiguous array from source
32
33        source -- numpy Python array (or compatible object)
34            for use as the data source.  If this is not a contiguous
35            array of the given typeCode, a copy will be made,
36            otherwise will just be returned unchanged.
37        typeCode -- optional 1-character typeCode specifier for
38            the numpy.array function.
39
40        All gl*Pointer calls should use contiguous arrays, as non-
41        contiguous arrays will be re-copied on every rendering pass.
42        Although this doesn't raise an error, it does tend to slow
43        down rendering.
44        """
45        typeCode = GL_TYPE_TO_ARRAY_MAPPING[ typeCode ]
46        try:
47            contiguous = source.flags.contiguous
48        except AttributeError as err:
49            if typeCode:
50                return numpy.ascontiguousarray( source, typeCode )
51            else:
52                return numpy.ascontiguousarray( source )
53        else:
54            if contiguous and (typeCode is None or typeCode==source.dtype.char):
55                return source
56            elif (contiguous and cls.ERROR_ON_COPY):
57                from OpenGL import error
58                raise error.CopyError(
59                    """Array of type %r passed, required array of type %r""",
60                    source.dtype.char, typeCode,
61                )
62            else:
63                # We have to do astype to avoid errors about unsafe conversions
64                # XXX Confirm that this will *always* create a new contiguous array
65                # XXX Guard against wacky conversion types like uint to float, where
66                # we really don't want to have the C-level conversion occur.
67                # XXX ascontiguousarray is apparently now available in numpy!
68                if cls.ERROR_ON_COPY:
69                    from OpenGL import error
70                    raise error.CopyError(
71                        """Non-contiguous array passed""",
72                        source,
73                    )
74                if typeCode is None:
75                    typeCode = source.dtype.char
76                return numpy.ascontiguousarray( source, typeCode )
77try:
78    numpy.array( [1], 's' )
79    SHORT_TYPE = 's'
80except TypeError as err:
81    SHORT_TYPE = 'h'
82    USHORT_TYPE = 'H'
83
84def lookupDtype( char ):
85    return numpy.zeros( (1,), dtype=char ).dtype
86
87ARRAY_TO_GL_TYPE_MAPPING = {
88    lookupDtype('d'): GL_1_1.GL_DOUBLE,
89    lookupDtype('f'): GL_1_1.GL_FLOAT,
90    lookupDtype('i'): GL_1_1.GL_INT,
91    lookupDtype(SHORT_TYPE): GL_1_1.GL_SHORT,
92    lookupDtype(USHORT_TYPE): GL_1_1.GL_UNSIGNED_SHORT,
93    lookupDtype('B'): GL_1_1.GL_UNSIGNED_BYTE,
94    lookupDtype('c'): GL_1_1.GL_UNSIGNED_BYTE,
95    lookupDtype('b'): GL_1_1.GL_BYTE,
96    lookupDtype('I'): GL_1_1.GL_UNSIGNED_INT,
97    #lookupDtype('P'), GL_1_1.GL_VOID_P, # normally duplicates another type (e.g. 'I')
98    None: None,
99}
100GL_TYPE_TO_ARRAY_MAPPING = {
101    GL_1_1.GL_DOUBLE: lookupDtype('d'),
102    GL_1_1.GL_FLOAT:lookupDtype('f'),
103    GL_1_1.GL_INT: lookupDtype('i'),
104    GL_1_1.GL_BYTE: lookupDtype('b'),
105    GL_1_1.GL_SHORT: lookupDtype(SHORT_TYPE),
106    GL_1_1.GL_UNSIGNED_INT: lookupDtype('I'),
107    GL_1_1.GL_UNSIGNED_BYTE: lookupDtype('B'),
108    GL_1_1.GL_UNSIGNED_SHORT: lookupDtype(USHORT_TYPE),
109    _types.GL_VOID_P: lookupDtype('P'),
110    None: None,
111    'f': lookupDtype('f'),
112    'd': lookupDtype('d'),
113    'i': lookupDtype('i'),
114    'I': lookupDtype('I'),
115    'h': lookupDtype('h'),
116    'H': lookupDtype('H'),
117    'b': lookupDtype('b'),
118    'B': lookupDtype('B'),
119    's': lookupDtype('B'),
120}
121