From 2e725c0dc525072ba5b8625a79779401022f785b Mon Sep 17 00:00:00 2001 From: Tcll Date: Mon, 28 Sep 2015 14:15:06 -0400 Subject: [PATCH 1/2] Added auto-detection of numpy If numpy is not installed, pyassimp returns lists to allow the user to manage the data type. --- port/PyAssimp/pyassimp/core.py | 67 +++++++++++++++++++++++++++------- 1 file changed, 54 insertions(+), 13 deletions(-) diff --git a/port/PyAssimp/pyassimp/core.py b/port/PyAssimp/pyassimp/core.py index 29550eb35..f035b35e5 100644 --- a/port/PyAssimp/pyassimp/core.py +++ b/port/PyAssimp/pyassimp/core.py @@ -10,7 +10,9 @@ if sys.version_info < (2,6): import ctypes import os -import numpy + +try: import numpy +except: numpy = None import logging logger = logging.getLogger("pyassimp") @@ -33,12 +35,30 @@ _assimp_lib = AssimpLib() def make_tuple(ai_obj, type = None): res = None + + #notes: + # ai_obj._fields_ = [ ("attr", c_type), ... ] + # getattr(ai_obj, e[0]).__class__ == float + if isinstance(ai_obj, structs.Matrix4x4): - res = numpy.array([getattr(ai_obj, e[0]) for e in ai_obj._fields_]).reshape((4,4)) + if numpy: + res = numpy.array([getattr(ai_obj, e[0]) for e in ai_obj._fields_]).reshape((4,4)) + #import pdb;pdb.set_trace() + else: + res = [getattr(ai_obj, e[0]) for e in ai_obj._fields_] + res = [res[i:i+4] for i in xrange(0,16,4)] elif isinstance(ai_obj, structs.Matrix3x3): - res = numpy.array([getattr(ai_obj, e[0]) for e in ai_obj._fields_]).reshape((3,3)) + if numpy: + res = numpy.array([getattr(ai_obj, e[0]) for e in ai_obj._fields_]).reshape((3,3)) + else: + res = [getattr(ai_obj, e[0]) for e in ai_obj._fields_] + res = [res[i:i+3] for i in xrange(0,9,3)] else: - res = numpy.array([getattr(ai_obj, e[0]) for e in ai_obj._fields_]) + if numpy: + res = numpy.array([getattr(ai_obj, e[0]) for e in ai_obj._fields_]) + else: + res = [getattr(ai_obj, e[0]) for e in ai_obj._fields_] + return res # It is faster and more correct to have an init function for each assimp class @@ -135,9 +155,14 @@ def _init(self, target = None, parent = None): try: if obj._type_ in structs.assimp_structs_as_tuple: - setattr(target, name, numpy.array([make_tuple(obj[i]) for i in range(length)], dtype=numpy.float32)) + if numpy: + setattr(target, name, numpy.array([make_tuple(obj[i]) for i in range(length)], dtype=numpy.float32)) - logger.debug(str(self) + ": Added an array of numpy arrays (type "+ str(type(obj)) + ") as self." + name) + logger.debug(str(self) + ": Added an array of numpy arrays (type "+ str(type(obj)) + ") as self." + name) + else: + setattr(target, name, [make_tuple(obj[i]) for i in range(length)]) + + logger.debug(str(self) + ": Added a list of lists (type "+ str(type(obj)) + ") as self." + name) else: setattr(target, name, [obj[i] for i in range(length)]) #TODO: maybe not necessary to recreate an array? @@ -292,7 +317,10 @@ def release(scene): def _finalize_texture(tex, target): setattr(target, "achformathint", tex.achFormatHint) - data = numpy.array([make_tuple(getattr(tex, "pcData")[i]) for i in range(tex.mWidth * tex.mHeight)]) + if numpy: + data = numpy.array([make_tuple(getattr(tex, "pcData")[i]) for i in range(tex.mWidth * tex.mHeight)]) + else: + data = [make_tuple(getattr(tex, "pcData")[i]) for i in range(tex.mWidth * tex.mHeight)] setattr(target, "data", data) def _finalize_mesh(mesh, target): @@ -308,11 +336,18 @@ def _finalize_mesh(mesh, target): def fill(name): mAttr = getattr(mesh, name) - if mAttr: - data = numpy.array([make_tuple(getattr(mesh, name)[i]) for i in range(nb_vertices)], dtype=numpy.float32) - setattr(target, name[1:].lower(), data) + if numpy: + if mAttr: + data = numpy.array([make_tuple(getattr(mesh, name)[i]) for i in range(nb_vertices)], dtype=numpy.float32) + setattr(target, name[1:].lower(), data) + else: + setattr(target, name[1:].lower(), numpy.array([], dtype="float32")) else: - setattr(target, name[1:].lower(), numpy.array([], dtype="float32")) + if mAttr: + data = [make_tuple(getattr(mesh, name)[i]) for i in range(nb_vertices)] + setattr(target, name[1:].lower(), data) + else: + setattr(target, name[1:].lower(), []) def fillarray(name): mAttr = getattr(mesh, name) @@ -322,7 +357,10 @@ def _finalize_mesh(mesh, target): if mSubAttr: data.append([make_tuple(getattr(mesh, name)[index][i]) for i in range(nb_vertices)]) - setattr(target, name[1:].lower(), numpy.array(data, dtype=numpy.float32)) + if numpy: + setattr(target, name[1:].lower(), numpy.array(data, dtype=numpy.float32)) + else: + setattr(target, name[1:].lower(), data) fill("mNormals") fill("mTangents") @@ -332,7 +370,10 @@ def _finalize_mesh(mesh, target): fillarray("mTextureCoords") # prepare faces - faces = numpy.array([f.indices for f in target.faces], dtype=numpy.int32) + if numpy: + faces = numpy.array([f.indices for f in target.faces], dtype=numpy.int32) + else: + faces = [f.indices for f in target.faces] setattr(target, 'faces', faces) From 5ce968c67f2153435b781cf5704e2f63201f9b11 Mon Sep 17 00:00:00 2001 From: Tcll Date: Mon, 28 Sep 2015 14:18:22 -0400 Subject: [PATCH 2/2] Added auto-detection of numpy --- port/PyAssimp/pyassimp/helper.py | 85 +++++++++++++++++++++++++++++--- 1 file changed, 77 insertions(+), 8 deletions(-) diff --git a/port/PyAssimp/pyassimp/helper.py b/port/PyAssimp/pyassimp/helper.py index ccfd8d2b5..249a0f2ab 100644 --- a/port/PyAssimp/pyassimp/helper.py +++ b/port/PyAssimp/pyassimp/helper.py @@ -8,8 +8,9 @@ import os import ctypes from ctypes import POINTER import operator -import numpy -from numpy import linalg + +try: import numpy +except: numpy = None import logging;logger = logging.getLogger("pyassimp") @@ -45,20 +46,88 @@ def vec2tuple(x): def transform(vector3, matrix4x4): """ Apply a transformation matrix on a 3D vector. - :param vector3: a numpy array with 3 elements - :param matrix4x4: a numpy 4x4 matrix + :param vector3: array with 3 elements + :param matrix4x4: 4x4 matrix """ - return numpy.dot(matrix4x4, numpy.append(vector3, 1.)) - + if numpy: + return numpy.dot(matrix4x4, numpy.append(vector3, 1.)) + else: + m0,m1,m2,m3 = matrix4x4; x,y,z = vector3 + return [ + m0[0]*x + m0[1]*y + m0[2]*z + m0[3], + m1[0]*x + m1[1]*y + m1[2]*z + m1[3], + m2[0]*x + m2[1]*y + m2[2]*z + m2[3], + m3[0]*x + m3[1]*y + m3[2]*z + m3[3] + ] + +def _inv(matrix4x4): + m0,m1,m2,m3 = matrix4x4 + + det = m0[3]*m1[2]*m2[1]*m3[0] - m0[2]*m1[3]*m2[1]*m3[0] - \ + m0[3]*m1[1]*m2[2]*m3[0] + m0[1]*m1[3]*m2[2]*m3[0] + \ + m0[2]*m1[1]*m2[3]*m3[0] - m0[1]*m1[2]*m2[3]*m3[0] - \ + m0[3]*m1[2]*m2[0]*m3[1] + m0[2]*m1[3]*m2[0]*m3[1] + \ + m0[3]*m1[0]*m2[2]*m3[1] - m0[0]*m1[3]*m2[2]*m3[1] - \ + m0[2]*m1[0]*m2[3]*m3[1] + m0[0]*m1[2]*m2[3]*m3[1] + \ + m0[3]*m1[1]*m2[0]*m3[2] - m0[1]*m1[3]*m2[0]*m3[2] - \ + m0[3]*m1[0]*m2[1]*m3[2] + m0[0]*m1[3]*m2[1]*m3[2] + \ + m0[1]*m1[0]*m2[3]*m3[2] - m0[0]*m1[1]*m2[3]*m3[2] - \ + m0[2]*m1[1]*m2[0]*m3[3] + m0[1]*m1[2]*m2[0]*m3[3] + \ + m0[2]*m1[0]*m2[1]*m3[3] - m0[0]*m1[2]*m2[1]*m3[3] - \ + m0[1]*m1[0]*m2[2]*m3[3] + m0[0]*m1[1]*m2[2]*m3[3] + + return[[( m1[2]*m2[3]*m3[1] - m1[3]*m2[2]*m3[1] + m1[3]*m2[1]*m3[2] - m1[1]*m2[3]*m3[2] - m1[2]*m2[1]*m3[3] + m1[1]*m2[2]*m3[3]) /det, + ( m0[3]*m2[2]*m3[1] - m0[2]*m2[3]*m3[1] - m0[3]*m2[1]*m3[2] + m0[1]*m2[3]*m3[2] + m0[2]*m2[1]*m3[3] - m0[1]*m2[2]*m3[3]) /det, + ( m0[2]*m1[3]*m3[1] - m0[3]*m1[2]*m3[1] + m0[3]*m1[1]*m3[2] - m0[1]*m1[3]*m3[2] - m0[2]*m1[1]*m3[3] + m0[1]*m1[2]*m3[3]) /det, + ( m0[3]*m1[2]*m2[1] - m0[2]*m1[3]*m2[1] - m0[3]*m1[1]*m2[2] + m0[1]*m1[3]*m2[2] + m0[2]*m1[1]*m2[3] - m0[1]*m1[2]*m2[3]) /det], + [( m1[3]*m2[2]*m3[0] - m1[2]*m2[3]*m3[0] - m1[3]*m2[0]*m3[2] + m1[0]*m2[3]*m3[2] + m1[2]*m2[0]*m3[3] - m1[0]*m2[2]*m3[3]) /det, + ( m0[2]*m2[3]*m3[0] - m0[3]*m2[2]*m3[0] + m0[3]*m2[0]*m3[2] - m0[0]*m2[3]*m3[2] - m0[2]*m2[0]*m3[3] + m0[0]*m2[2]*m3[3]) /det, + ( m0[3]*m1[2]*m3[0] - m0[2]*m1[3]*m3[0] - m0[3]*m1[0]*m3[2] + m0[0]*m1[3]*m3[2] + m0[2]*m1[0]*m3[3] - m0[0]*m1[2]*m3[3]) /det, + ( m0[2]*m1[3]*m2[0] - m0[3]*m1[2]*m2[0] + m0[3]*m1[0]*m2[2] - m0[0]*m1[3]*m2[2] - m0[2]*m1[0]*m2[3] + m0[0]*m1[2]*m2[3]) /det], + [( m1[1]*m2[3]*m3[0] - m1[3]*m2[1]*m3[0] + m1[3]*m2[0]*m3[1] - m1[0]*m2[3]*m3[1] - m1[1]*m2[0]*m3[3] + m1[0]*m2[1]*m3[3]) /det, + ( m0[3]*m2[1]*m3[0] - m0[1]*m2[3]*m3[0] - m0[3]*m2[0]*m3[1] + m0[0]*m2[3]*m3[1] + m0[1]*m2[0]*m3[3] - m0[0]*m2[1]*m3[3]) /det, + ( m0[1]*m1[3]*m3[0] - m0[3]*m1[1]*m3[0] + m0[3]*m1[0]*m3[1] - m0[0]*m1[3]*m3[1] - m0[1]*m1[0]*m3[3] + m0[0]*m1[1]*m3[3]) /det, + ( m0[3]*m1[1]*m2[0] - m0[1]*m1[3]*m2[0] - m0[3]*m1[0]*m2[1] + m0[0]*m1[3]*m2[1] + m0[1]*m1[0]*m2[3] - m0[0]*m1[1]*m2[3]) /det], + [( m1[2]*m2[1]*m3[0] - m1[1]*m2[2]*m3[0] - m1[2]*m2[0]*m3[1] + m1[0]*m2[2]*m3[1] + m1[1]*m2[0]*m3[2] - m1[0]*m2[1]*m3[2]) /det, + ( m0[1]*m2[2]*m3[0] - m0[2]*m2[1]*m3[0] + m0[2]*m2[0]*m3[1] - m0[0]*m2[2]*m3[1] - m0[1]*m2[0]*m3[2] + m0[0]*m2[1]*m3[2]) /det, + ( m0[2]*m1[1]*m3[0] - m0[1]*m1[2]*m3[0] - m0[2]*m1[0]*m3[1] + m0[0]*m1[2]*m3[1] + m0[1]*m1[0]*m3[2] - m0[0]*m1[1]*m3[2]) /det, + ( m0[1]*m1[2]*m2[0] - m0[2]*m1[1]*m2[0] + m0[2]*m1[0]*m2[1] - m0[0]*m1[2]*m2[1] - m0[1]*m1[0]*m2[2] + m0[0]*m1[1]*m2[2]) /det]] def get_bounding_box(scene): bb_min = [1e10, 1e10, 1e10] # x,y,z bb_max = [-1e10, -1e10, -1e10] # x,y,z - return get_bounding_box_for_node(scene.rootnode, bb_min, bb_max, linalg.inv(scene.rootnode.transformation)) + inv = numpy.linalg.inv if numpy else _inv + return get_bounding_box_for_node(scene.rootnode, bb_min, bb_max, inv(scene.rootnode.transformation)) def get_bounding_box_for_node(node, bb_min, bb_max, transformation): - transformation = numpy.dot(transformation, node.transformation) + if numpy: + transformation = numpy.dot(transformation, node.transformation) + else: + t0,t1,t2,t3 = transformation + T0,T1,T2,T3 = node.transformation + transformation = [ [ + t0[0]*T0[0] + t0[1]*T1[0] + t0[2]*T2[0] + t0[3]*T3[0], + t0[0]*T0[1] + t0[1]*T1[1] + t0[2]*T2[1] + t0[3]*T3[1], + t0[0]*T0[2] + t0[1]*T1[2] + t0[2]*T2[2] + t0[3]*T3[2], + t0[0]*T0[3] + t0[1]*T1[3] + t0[2]*T2[3] + t0[3]*T3[3] + ],[ + t1[0]*T0[0] + t1[1]*T1[0] + t1[2]*T2[0] + t1[3]*T3[0], + t1[0]*T0[1] + t1[1]*T1[1] + t1[2]*T2[1] + t1[3]*T3[1], + t1[0]*T0[2] + t1[1]*T1[2] + t1[2]*T2[2] + t1[3]*T3[2], + t1[0]*T0[3] + t1[1]*T1[3] + t1[2]*T2[3] + t1[3]*T3[3] + ],[ + t2[0]*T0[0] + t2[1]*T1[0] + t2[2]*T2[0] + t2[3]*T3[0], + t2[0]*T0[1] + t2[1]*T1[1] + t2[2]*T2[1] + t2[3]*T3[1], + t2[0]*T0[2] + t2[1]*T1[2] + t2[2]*T2[2] + t2[3]*T3[2], + t2[0]*T0[3] + t2[1]*T1[3] + t2[2]*T2[3] + t2[3]*T3[3] + ],[ + t3[0]*T0[0] + t3[1]*T1[0] + t3[2]*T2[0] + t3[3]*T3[0], + t3[0]*T0[1] + t3[1]*T1[1] + t3[2]*T2[1] + t3[3]*T3[1], + t3[0]*T0[2] + t3[1]*T1[2] + t3[2]*T2[2] + t3[3]*T3[2], + t3[0]*T0[3] + t3[1]*T1[3] + t3[2]*T2[3] + t3[3]*T3[3] + ] ] + for mesh in node.meshes: for v in mesh.vertices: v = transform(v, transformation)