numpymodule.py :  » Game-2D-3D » PyOpenGL » PyOpenGL-3.0.1 » OpenGL » arrays » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Game 2D 3D » PyOpenGL 
PyOpenGL » PyOpenGL 3.0.1 » OpenGL » arrays » numpymodule.py
"""Numpy (new version) module implementation of the OpenGL-ctypes array interfaces

XXX Need to register handlers for all of the scalar types that numpy returns,
would like to have all return values be int/float if they are of  compatible
type as well.
"""
REGISTRY_NAME = 'numpy'
try:
    import numpy
except ImportError, err:
    raise ImportError( """No numpy module present: %s"""%(err))

import operator,logging
import OpenGL
import ctypes
c_void_p = ctypes.c_void_p
from OpenGL import constants,constant,error
from OpenGL.arrays import formathandler
log = logging.getLogger( 'OpenGL.arrays.numpymodule' )

from OpenGL import acceleratesupport
NumpyHandler = None
if acceleratesupport.ACCELERATE_AVAILABLE:
    try:
        from OpenGL_accelerate.numpy_formathandler import NumpyHandler
    except ImportError, err:
        log.warn(
            "Unable to load numpy_formathandler accelerator from OpenGL_accelerate"
        )
if NumpyHandler is None:
    # numpy's array interface has changed over time :(
    testArray = numpy.array( [1,2,3,4],'i' )
    # Numpy's "ctypes" interface actually creates a new ctypes object 
    # in python for every access of the .ctypes attribute... which can take 
    # ridiculously large periods when you multiply it by millions of iterations
    if hasattr(testArray,'__array_interface__'):
        def dataPointer( cls, instance ):
            """Convert given instance to a data-pointer value (integer)"""
            try:
                return long(instance.__array_interface__['data'][0])
            except AttributeError, err:
                instance = cls.asArray( instance )
                try:
                    return long(instance.__array_interface__['data'][0])
                except AttributeError, err:
                    return long(instance.__array_data__[0],0)
    else:
        def dataPointer( cls, instance ):
            """Convert given instance to a data-pointer value (integer)"""
            try:
                return long(instance.__array_data__[0],0)
            except AttributeError, err:
                instance = cls.asArray( instance )
                try:
                    return long(instance.__array_interface__['data'][0])
                except AttributeError, err:
                    return long(instance.__array_data__[0],0)
    del testArray
    dataPointer = classmethod( dataPointer )


    class NumpyHandler( formathandler.FormatHandler ):
        """Numpy-specific data-type handler for OpenGL
        
        Attributes:
        
            ERROR_ON_COPY -- if True, will raise errors 
                if we have to copy an array object in order to produce
                a contiguous array of the correct type.
        """
        HANDLED_TYPES = (numpy.ndarray,)# list, tuple )
        dataPointer = dataPointer
        isOutput = True
        ERROR_ON_COPY = OpenGL.ERROR_ON_COPY
        @classmethod
        def zeros( cls, dims, typeCode ):
            """Return Numpy array of zeros in given size"""
            return numpy.zeros( dims, GL_TYPE_TO_ARRAY_MAPPING[typeCode])
        @classmethod
        def arrayToGLType( cls, value ):
            """Given a value, guess OpenGL type of the corresponding pointer"""
            typeCode = value.dtype
            constant = ARRAY_TO_GL_TYPE_MAPPING.get( typeCode )
            if constant is None:
                raise TypeError(
                    """Don't know GL type for array of type %r, known types: %s\nvalue:%s"""%(
                        typeCode, ARRAY_TO_GL_TYPE_MAPPING.keys(), value,
                    )
                )
            return constant
        
        @classmethod
        def arraySize( cls, value, typeCode = None ):
            """Given a data-value, calculate dimensions for the array"""
            return value.size
        @classmethod
        def arrayByteCount( cls, value, typeCode = None ):
            """Given a data-value, calculate number of bytes required to represent"""
            try:
                return value.nbytes
            except AttributeError, err:
                if cls.ERROR_ON_COPY:
                    raise error.CopyError(
                        """Non-numpy array passed to numpy arrayByteCount: %s""",
                        type(value),
                    )
                value = cls.asArray( value, typeCode )
                return value.nbytes
        @classmethod
        def asArray( cls, value, typeCode=None ):
            """Convert given value to an array value of given typeCode"""
            if value is None:
                return value
            else:
                return cls.contiguous( value, typeCode )

        @classmethod
        def contiguous( cls, source, typeCode=None ):
            """Get contiguous array from source
            
            source -- numpy Python array (or compatible object)
                for use as the data source.  If this is not a contiguous
                array of the given typeCode, a copy will be made, 
                otherwise will just be returned unchanged.
            typeCode -- optional 1-character typeCode specifier for
                the numpy.array function.
                
            All gl*Pointer calls should use contiguous arrays, as non-
            contiguous arrays will be re-copied on every rendering pass.
            Although this doesn't raise an error, it does tend to slow
            down rendering.
            """
            typeCode = GL_TYPE_TO_ARRAY_MAPPING[ typeCode ]
            try:
                contiguous = source.flags.contiguous
            except AttributeError, err:
                if typeCode:
                    return numpy.ascontiguousarray( source, typeCode )
                else:
                    return numpy.ascontiguousarray( source )
            else:
                if contiguous and (typeCode is None or typeCode==source.dtype.char):
                    return source
                elif (contiguous and cls.ERROR_ON_COPY):
                    from OpenGL import error
                    raise error.CopyError(
                        """Array of type %r passed, required array of type %r""",
                        source.dtype.char, typeCode,
                    )
                else:
                    # We have to do astype to avoid errors about unsafe conversions
                    # XXX Confirm that this will *always* create a new contiguous array 
                    # XXX Guard against wacky conversion types like uint to float, where
                    # we really don't want to have the C-level conversion occur.
                    # XXX ascontiguousarray is apparently now available in numpy!
                    if cls.ERROR_ON_COPY:
                        from OpenGL import error
                        raise error.CopyError(
                            """Non-contiguous array passed""",
                            source,
                        )
                    if typeCode is None:
                        typeCode = source.dtype.char
                    return numpy.ascontiguousarray( source, typeCode )
        @classmethod
        def unitSize( cls, value, typeCode=None ):
            """Determine unit size of an array (if possible)"""
            return value.shape[-1]
        @classmethod
        def dimensions( cls, value, typeCode=None ):
            """Determine dimensions of the passed array value (if possible)"""
            return value.shape
        @classmethod
        def from_param( cls, instance, typeCode=None ):
            try:
                pointer = cls.dataPointer( instance )
            except TypeError, err:
                array = cls.asArray( instance, typeCode )
                pp = cls.dataPointer( array )
                pp._temporary_array_ = (array,)
                return pp
            else:
                if typeCode and instance.dtype != GL_TYPE_TO_ARRAY_MAPPING[ typeCode ]:
                    raise error.CopyError(
                        """Array of type %r passed, required array of type %r""",
                        instance.dtype.char, typeCode,
                    )          
                return c_void_p( pointer )

try:
    numpy.array( [1], 's' )
    SHORT_TYPE = 's'
except TypeError, err:
    SHORT_TYPE = 'h'
    USHORT_TYPE = 'H'

def lookupDtype( char ):
    return numpy.zeros( (1,), dtype=char ).dtype

ARRAY_TO_GL_TYPE_MAPPING = {
    lookupDtype('d'): constants.GL_DOUBLE,
    lookupDtype('f'): constants.GL_FLOAT,
    lookupDtype('i'): constants.GL_INT,
    lookupDtype(SHORT_TYPE): constants.GL_SHORT,
    lookupDtype(USHORT_TYPE): constants.GL_UNSIGNED_SHORT,
    lookupDtype('B'): constants.GL_UNSIGNED_BYTE,
    lookupDtype('c'): constants.GL_UNSIGNED_BYTE,
    lookupDtype('b'): constants.GL_BYTE,
    lookupDtype('I'): constants.GL_UNSIGNED_INT,
    None: None,
}
GL_TYPE_TO_ARRAY_MAPPING = {
    constants.GL_DOUBLE: lookupDtype('d'),
    constants.GL_FLOAT:lookupDtype('f'),
    constants.GL_INT: lookupDtype('i'),
    constants.GL_BYTE: lookupDtype('b'),
    constants.GL_SHORT: lookupDtype(SHORT_TYPE),
    constants.GL_UNSIGNED_INT: lookupDtype('I'),
    constants.GL_UNSIGNED_BYTE: lookupDtype('B'),
    constants.GL_UNSIGNED_SHORT: lookupDtype(USHORT_TYPE),
    None: None,
}
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.