浏览代码

Merge pull request #49 from severin-lemaignan/master

[pyassimp] Fixes for python 3.3 and 64bits
Kim Kulling 12 年之前
父节点
当前提交
9040724fc0

+ 8 - 8
port/PyAssimp/pyassimp/core.py

@@ -59,12 +59,12 @@ def make_tuple(ai_obj, type = None):
 
 
 def call_init(obj, caller = None):
 def call_init(obj, caller = None):
         # init children
         # init children
-        if hasattr(obj, '_init'):
+        if helper.hasattr_silent(obj, '_init'):
             obj._init(parent = caller)
             obj._init(parent = caller)
 
 
         # pointers
         # pointers
-        elif hasattr(obj, 'contents'):
-            if hasattr(obj.contents, '_init'):
+        elif helper.hasattr_silent(obj, 'contents'):
+            if helper.hasattr_silent(obj.contents, '_init'):
                 obj.contents._init(target = obj, parent = caller)
                 obj.contents._init(target = obj, parent = caller)
 
 
 
 
@@ -76,7 +76,7 @@ def _init(self, target = None, parent = None):
     :param target: set the object which receive the added methods. Useful when manipulating
     :param target: set the object which receive the added methods. Useful when manipulating
     pointers, to skip the intermediate 'contents' deferencing.
     pointers, to skip the intermediate 'contents' deferencing.
     """
     """
-    if hasattr(self, '_is_init'):
+    if helper.hasattr_silent(self, '_is_init'):
         return self
         return self
     self._is_init = True
     self._is_init = True
     
     
@@ -108,7 +108,7 @@ def _init(self, target = None, parent = None):
 
 
 
 
         if isinstance(obj, structs.String):
         if isinstance(obj, structs.String):
-            setattr(target, 'name', str(obj.data))
+            setattr(target, 'name', obj.data.decode("utf-8"))
             setattr(target.__class__, '__repr__', lambda x: str(x.__class__) + "(" + x.name + ")")
             setattr(target.__class__, '__repr__', lambda x: str(x.__class__) + "(" + x.name + ")")
             setattr(target.__class__, '__str__', lambda x: x.name)
             setattr(target.__class__, '__str__', lambda x: x.name)
             continue
             continue
@@ -121,7 +121,7 @@ def _init(self, target = None, parent = None):
                 logger.debug("Added a parent as self." + name)
                 logger.debug("Added a parent as self." + name)
                 continue
                 continue
 
 
-            if hasattr(self, 'mNum' + m[1:]):
+            if helper.hasattr_silent(self, 'mNum' + m[1:]):
 
 
                 length =  getattr(self, 'mNum' + m[1:])
                 length =  getattr(self, 'mNum' + m[1:])
     
     
@@ -346,7 +346,7 @@ def _get_properties(properties, length):
     for p in [properties[i] for i in range(length)]:
     for p in [properties[i] for i in range(length)]:
         #the name
         #the name
         p = p.contents
         p = p.contents
-        key = str(p.mKey.data).split('.')[1]
+        key = str(p.mKey.data.decode("utf-8")).split('.')[1]
 
 
         #the data
         #the data
         from ctypes import POINTER, cast, c_int, c_float, sizeof
         from ctypes import POINTER, cast, c_int, c_float, sizeof
@@ -354,7 +354,7 @@ def _get_properties(properties, length):
             arr = cast(p.mData, POINTER(c_float * int(p.mDataLength/sizeof(c_float)) )).contents
             arr = cast(p.mData, POINTER(c_float * int(p.mDataLength/sizeof(c_float)) )).contents
             value = [x for x in arr]
             value = [x for x in arr]
         elif p.mType == 3: #string can't be an array
         elif p.mType == 3: #string can't be an array
-            value = cast(p.mData, POINTER(structs.String)).contents.data
+            value = cast(p.mData, POINTER(structs.MaterialPropertyString)).contents.data.decode("utf-8")
         elif p.mType == 4:
         elif p.mType == 4:
             arr = cast(p.mData, POINTER(c_int * int(p.mDataLength/sizeof(c_int)) )).contents
             arr = cast(p.mData, POINTER(c_int * int(p.mDataLength/sizeof(c_int)) )).contents
             value = [x for x in arr]
             value = [x for x in arr]

+ 12 - 2
port/PyAssimp/pyassimp/helper.py

@@ -154,5 +154,15 @@ def search_library():
         # XXX: take version postfix of the .so on linux?
         # XXX: take version postfix of the .so on linux?
         return res[1:]
         return res[1:]
 
 
-
-
+def hasattr_silent(object, name):
+    """
+        Calls hasttr() with the given parameters and preserves the legacy (pre-Python 3.2)
+        functionality of silently catching exceptions.
+        
+        Returns the result of hasatter() or False if an exception was raised.
+    """
+    
+    try:
+        return hasattr(object, name)
+    except:
+        return False

+ 21 - 1
port/PyAssimp/pyassimp/structs.py

@@ -1,6 +1,6 @@
 #-*- coding: UTF-8 -*-
 #-*- coding: UTF-8 -*-
 
 
-from ctypes import POINTER, c_void_p, c_int, c_uint, c_char, c_float, Structure, c_char_p, c_double, c_ubyte, c_size_t
+from ctypes import POINTER, c_void_p, c_int, c_uint, c_char, c_float, Structure, c_char_p, c_double, c_ubyte, c_size_t, c_uint32
 
 
 
 
 class Vector2D(Structure):
 class Vector2D(Structure):
@@ -82,6 +82,26 @@ class String(Structure):
             ("data", c_char*MAXLEN),
             ("data", c_char*MAXLEN),
         ]
         ]
 
 
+class MaterialPropertyString(Structure):
+    """
+    See 'aiTypes.h' for details.
+    
+    The size of length is truncated to 4 bytes on 64-bit platforms when used as a
+    material property (see MaterialSystem.cpp aiMaterial::AddProperty() for details).
+    """
+
+    MAXLEN = 1024
+
+    _fields_ = [
+            # Binary length of the string excluding the terminal 0. This is NOT the
+            #  logical length of strings containing UTF-8 multibyte sequences! It's
+            #  the number of bytes from the beginning of the string to its end.
+            ("length", c_uint32),
+            
+            # String buffer. Size limit is MAXLEN
+            ("data", c_char*MAXLEN),
+        ]
+
 class MemoryInfo(Structure):
 class MemoryInfo(Structure):
     """
     """
     See 'aiTypes.h' for details.
     See 'aiTypes.h' for details.

+ 7 - 2
port/PyAssimp/scripts/3d_viewer.py

@@ -291,8 +291,13 @@ class PyAssimp3DViewer:
 
 
             stride = 24 # 6 * 4 bytes
             stride = 24 # 6 * 4 bytes
 
 
-            glUniform4f( shader.Material_diffuse, *mesh.material.properties["diffuse"] )
-            glUniform4f( shader.Material_ambient, *mesh.material.properties["ambient"] )
+            diffuse = mesh.material.properties["diffuse"]
+            if len(diffuse) == 3: diffuse.append(1.0)
+            ambient = mesh.material.properties["ambient"]
+            if len(ambient) == 3: ambient.append(1.0)
+
+            glUniform4f( shader.Material_diffuse, *diffuse )
+            glUniform4f( shader.Material_ambient, *ambient )
 
 
             vbo = mesh.gl["vbo"]
             vbo = mesh.gl["vbo"]
             vbo.bind()
             vbo.bind()

+ 8 - 1
port/PyAssimp/scripts/sample.py

@@ -77,5 +77,12 @@ def main(filename=None):
     # Finally release the model
     # Finally release the model
     pyassimp.release(scene)
     pyassimp.release(scene)
 
 
+def usage():
+    print("Usage: sample.py <3d model>")
+
 if __name__ == "__main__":
 if __name__ == "__main__":
-    main(sys.argv[1] if len(sys.argv)>1 else None)
+
+    if len(sys.argv) != 2:
+        usage()
+    else:
+        main(sys.argv[1])