commit
7d887204ac
|
@ -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)
|
||||||
|
@ -178,19 +170,16 @@ def _init(self, target = None, parent = None):
|
||||||
" a post-processing to triangulate your"
|
" a post-processing to triangulate your"
|
||||||
" faces.")
|
" faces.")
|
||||||
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'):
|
||||||
|
|
|
@ -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
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue