Merge pull request #449 from mikedh/master

default postprocessing options
pull/456/head
Kim Kulling 2015-01-28 09:07:15 +01:00
commit 7d887204ac
3 changed files with 74 additions and 38 deletions

View File

@ -1,5 +1,3 @@
#-*- coding: UTF-8 -*-
""" """
PyAssimp PyAssimp
@ -21,37 +19,31 @@ logger = logging.getLogger("pyassimp")
logger.addHandler(logging.NullHandler()) logger.addHandler(logging.NullHandler())
from . import structs from . import structs
from .errors import AssimpError
from . import helper from . import helper
from . import postprocess
from .errors import AssimpError
from .formats import available_formats
assimp_structs_as_tuple = ( class AssimpLib(object):
structs.Matrix4x4, """
structs.Matrix3x3, Assimp-Singleton
structs.Vector2D, """
structs.Vector3D, load, load_mem, release, dll = helper.search_library()
structs.Color3D, _assimp_lib = AssimpLib()
structs.Color4D,
structs.Quaternion,
structs.Plane,
structs.Texel)
def make_tuple(ai_obj, type = None): def make_tuple(ai_obj, type = None):
res = None res = None
if isinstance(ai_obj, structs.Matrix4x4): if isinstance(ai_obj, structs.Matrix4x4):
res = numpy.array([getattr(ai_obj, e[0]) for e in ai_obj._fields_]).reshape((4,4)) res = numpy.array([getattr(ai_obj, e[0]) for e in ai_obj._fields_]).reshape((4,4))
#import pdb;pdb.set_trace()
elif isinstance(ai_obj, structs.Matrix3x3): elif isinstance(ai_obj, structs.Matrix3x3):
res = numpy.array([getattr(ai_obj, e[0]) for e in ai_obj._fields_]).reshape((3,3)) res = numpy.array([getattr(ai_obj, e[0]) for e in ai_obj._fields_]).reshape((3,3))
else: else:
res = numpy.array([getattr(ai_obj, e[0]) for e in ai_obj._fields_]) res = numpy.array([getattr(ai_obj, e[0]) for e in ai_obj._fields_])
return res return res
# It is faster and more correct to have an init function for each assimp class # It is faster and more correct to have an init function for each assimp class
def _init_face(aiFace): def _init_face(aiFace):
aiFace.indices = [aiFace.mIndices[i] for i in range(aiFace.mNumIndices)] aiFace.indices = [aiFace.mIndices[i] for i in range(aiFace.mNumIndices)]
assimp_struct_inits = { structs.Face : _init_face } assimp_struct_inits = { structs.Face : _init_face }
def call_init(obj, caller = None): def call_init(obj, caller = None):
@ -112,7 +104,7 @@ def _init(self, target = None, parent = None):
obj = getattr(self, m) obj = getattr(self, m)
# Create tuples # Create tuples
if isinstance(obj, assimp_structs_as_tuple): if isinstance(obj, structs.assimp_structs_as_tuple):
setattr(target, name, make_tuple(obj)) setattr(target, name, make_tuple(obj))
logger.debug(str(self) + ": Added array " + str(getattr(target, name)) + " as self." + name.lower()) logger.debug(str(self) + ": Added array " + str(getattr(target, name)) + " as self." + name.lower())
continue continue
@ -142,7 +134,7 @@ def _init(self, target = None, parent = None):
try: try:
if obj._type_ in assimp_structs_as_tuple: 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)) 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)
@ -180,17 +172,14 @@ def _init(self, target = None, parent = None):
raise e raise e
else: # starts with 'm' but not iterable
else: # starts with 'm' but not iterable
setattr(target, name, obj) setattr(target, name, obj)
logger.debug("Added " + name + " as self." + name + " (type: " + str(type(obj)) + ")") logger.debug("Added " + name + " as self." + name + " (type: " + str(type(obj)) + ")")
if _is_init_type(obj): if _is_init_type(obj):
call_init(obj, target) call_init(obj, target)
if isinstance(self, structs.Mesh): if isinstance(self, structs.Mesh):
_finalize_mesh(self, target) _finalize_mesh(self, target)
@ -200,14 +189,6 @@ def _init(self, target = None, parent = None):
return self return self
class AssimpLib(object):
"""
Assimp-Singleton
"""
load, load_mem, release, dll = helper.search_library()
#the loader as singleton
_assimp_lib = AssimpLib()
def pythonize_assimp(type, obj, scene): def pythonize_assimp(type, obj, scene):
""" This method modify the Assimp data structures """ This method modify the Assimp data structures
@ -247,17 +228,16 @@ def recur_pythonize(node, scene):
pythonize the assimp datastructures. pythonize the assimp datastructures.
''' '''
node.meshes = pythonize_assimp("MESH", node.meshes, scene) node.meshes = pythonize_assimp("MESH", node.meshes, scene)
for mesh in node.meshes: for mesh in node.meshes:
mesh.material = scene.materials[mesh.materialindex] mesh.material = scene.materials[mesh.materialindex]
for cam in scene.cameras: for cam in scene.cameras:
pythonize_assimp("ADDTRANSFORMATION", cam, scene) pythonize_assimp("ADDTRANSFORMATION", cam, scene)
for c in node.children: for c in node.children:
recur_pythonize(c, scene) recur_pythonize(c, scene)
def load(filename, processing=0, file_type=None): def load(filename,
file_type = None,
processing = postprocess.aiProcess_Triangulate):
''' '''
Load a model into a scene. On failure throws AssimpError. Load a model into a scene. On failure throws AssimpError.
@ -267,12 +247,17 @@ def load(filename, processing=0, file_type=None):
If a file object is passed, file_type MUST be specified If a file object is passed, file_type MUST be specified
Otherwise Assimp has no idea which importer to use. Otherwise Assimp has no idea which importer to use.
This is named 'filename' so as to not break legacy code. This is named 'filename' so as to not break legacy code.
processing: assimp processing parameters processing: assimp postprocessing parameters. Verbose keywords are imported
file_type: string, such as 'stl' from postprocessing, and the parameters can be combined bitwise to
generate the final processing value. Note that the default value will
triangulate quad faces. Example of generating other possible values:
processing = (pyassimp.postprocess.aiProcess_Triangulate |
pyassimp.postprocess.aiProcess_OptimizeMeshes)
file_type: string of file extension, such as 'stl'
Returns Returns
--------- ---------
Scene object with model-data Scene object with model data
''' '''
if hasattr(filename, 'read'): if hasattr(filename, 'read'):

View File

@ -0,0 +1,41 @@
FORMATS = ["CSM",
"LWS",
"B3D",
"COB",
"PLY",
"IFC",
"OFF",
"SMD",
"IRRMESH",
"3D",
"DAE",
"MDL",
"HMP",
"TER",
"WRL",
"XML",
"NFF",
"AC",
"OBJ",
"3DS",
"STL",
"IRR",
"Q3O",
"Q3D"
"MS3D",
"Q3S",
"ZGL",
"MD2",
"X",
"BLEND",
"XGL",
"MD5MESH",
"MAX",
"LXO",
"DXF",
"BVH",
"LWO",
"NDO"]
def available_formats():
return FORMATS

View File

@ -897,3 +897,13 @@ class Scene(Structure):
# the scene. # the scene.
("mCameras", POINTER(POINTER(Camera))), ("mCameras", POINTER(POINTER(Camera))),
] ]
assimp_structs_as_tuple = (Matrix4x4,
Matrix3x3,
Vector2D,
Vector3D,
Color3D,
Color4D,
Quaternion,
Plane,
Texel)