New Addon: Import Autodesk .max #22
@ -161,15 +161,14 @@ def unregister():
|
||||
MAGIC = b'\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1'
|
||||
WORD_CLSID = "00020900-0000-0000-C000-000000000046"
|
||||
|
||||
MIN_FILE_SIZE = 1536
|
||||
UNKNOWN_SIZE = 0x7FFFFFFF
|
||||
MAXFILE_SIZE = 0x7FFFFFFFFFFFFFFF
|
||||
MAXREGSECT = 0xFFFFFFFA # (-6) maximum SECT
|
||||
DIFSECT = 0xFFFFFFFC # (-4) denotes a DIFAT sector in a FAT
|
||||
FATSECT = 0xFFFFFFFD # (-3) denotes a FAT sector in a FAT
|
||||
ENDOFCHAIN = 0xFFFFFFFE # (-2) end of a virtual stream chain
|
||||
FREESECT = 0xFFFFFFFF # (-1) unallocated sector
|
||||
MAXREGSID = 0xFFFFFFFA # (-6) maximum directory entry ID
|
||||
NOSTREAM = 0xFFFFFFFF # (-1) unallocated directory entry
|
||||
UNKNOWN_SIZE = 0x7FFFFFFF
|
||||
MIN_FILE_SIZE = 1536
|
||||
|
||||
STGTY_EMPTY = 0 # empty directory entry
|
||||
STGTY_STORAGE = 1 # element is a storage object
|
||||
@ -192,12 +191,15 @@ TYP_NAME = 0x0962
|
||||
INVALID_NAME = re.compile('^[0-9].*')
|
||||
UNPACK_BOX_DATA = struct.Struct('<HIHHBff').unpack_from # Index, int, short, short, byte, float, Length
|
||||
|
||||
CONFIG = []
|
||||
CLS_DATA = []
|
||||
DLL_DIR_LIST = []
|
||||
CLS_DIR3_LIST = []
|
||||
VID_PST_QUE = []
|
||||
SCENE_LIST = []
|
||||
FLOAT_POINT = 0x71F11549498702E7 # Float Wire
|
||||
MATRIX_POS = 0xFFEE238A118F7E02 # Position XYZ
|
||||
MATRIX_ROT = 0x3A90416731381913 # Rotation Wire
|
||||
MATRIX_SCL = 0xFEEE238B118F7C01 # Scale XYZ
|
||||
EDIT_MESH = 0x00000000E44F10B3 # Editable Mesh
|
||||
EDIT_POLY = 0x192F60981BF8338D # Editable Poly
|
||||
CORO_MTL = 0x448931dd70be6506 # CoronaMtl
|
||||
ARCH_MTL = 0x4A16365470B05735 # ArchMtl
|
||||
VRAY_MTL = 0x7034695C37BF3F2F # VRayMtl
|
||||
|
||||
SKIPPABLE = {
|
||||
0x0000000000001002: 'Camera',
|
||||
@ -222,6 +224,13 @@ SKIPPABLE = {
|
||||
0x77566F65081F1DFC: 'Plane',
|
||||
}
|
||||
|
||||
CONFIG = []
|
||||
CLS_DATA = []
|
||||
DLL_DIR_LIST = []
|
||||
CLS_DIR3_LIST = []
|
||||
VID_PST_QUE = []
|
||||
SCENE_LIST = []
|
||||
|
||||
|
||||
def get_valid_name(name):
|
||||
if (INVALID_NAME.match(name)):
|
||||
@ -326,7 +335,7 @@ class MaxStream(io.BytesIO):
|
||||
sector_data = fp.read(sectorsize)
|
||||
data.append(sector_data)
|
||||
try:
|
||||
sect = fat[sect] & 0xFFFFFFFF
|
||||
sect = fat[sect] & FREESECT
|
||||
except IndexError:
|
||||
break
|
||||
data = b"".join(data)
|
||||
@ -404,12 +413,12 @@ class MaxFileDirEntry:
|
||||
next_sect = maxfile.fat[next_sect]
|
||||
|
||||
def build_storage_tree(self):
|
||||
if self.sid_child != NOSTREAM:
|
||||
if self.sid_child != FREESECT:
|
||||
self.append_kids(self.sid_child)
|
||||
self.kids.sort()
|
||||
|
||||
def append_kids(self, child_sid):
|
||||
if child_sid == NOSTREAM:
|
||||
if child_sid == FREESECT:
|
||||
return
|
||||
else:
|
||||
child = self.maxfile._load_direntry(child_sid)
|
||||
@ -575,7 +584,7 @@ class ImportMaxFile:
|
||||
fat1 = self.sector_array(sect)
|
||||
isect = None
|
||||
for isect in fat1:
|
||||
isect = isect & 0xFFFFFFFF
|
||||
isect = isect & FREESECT
|
||||
if isect == ENDOFCHAIN or isect == FREESECT:
|
||||
break
|
||||
sector = self.getsect(isect)
|
||||
@ -923,11 +932,11 @@ class ChunkReader():
|
||||
def get_next_chunk(self, data, offset, level, number, containerReader, primitiveReader):
|
||||
header = 6
|
||||
typ, siz, = struct.unpack("<Hi", data[offset:offset+header])
|
||||
chunksize = siz & 0x7FFFFFFF
|
||||
chunksize = siz & UNKNOWN_SIZE
|
||||
if (siz == 0):
|
||||
siz, = struct.unpack("<q", data[offset+header:offset+header+8])
|
||||
header += 8
|
||||
chunksize = siz & 0x7FFFFFFFFFFFFFFF
|
||||
chunksize = siz & MAXFILE_SIZE
|
||||
if (siz < 0):
|
||||
chunk = containerReader(typ, chunksize, level, number, primitiveReader)
|
||||
else:
|
||||
@ -1103,7 +1112,7 @@ def get_point(floatval, default=0.0):
|
||||
except:
|
||||
print("SyntaxError: %s - assuming 0.0!\n" %(floatval))
|
||||
return default
|
||||
if (uid == 0x71F11549498702E7): # Float Wire
|
||||
if (uid == FLOAT_POINT): # Float Wire
|
||||
flv = get_references(floatval)[0]
|
||||
return get_point(flv)
|
||||
else:
|
||||
@ -1126,7 +1135,7 @@ def get_position(pos):
|
||||
mtx = mathutils.Matrix.Identity(4)
|
||||
if (pos):
|
||||
uid = get_guid(pos)
|
||||
if (uid == 0xFFEE238A118F7E02): # Position XYZ
|
||||
if (uid == MATRIX_POS): # Position XYZ
|
||||
position = get_point_3d(pos)
|
||||
elif (uid == 0x442312): # TCB Position
|
||||
position = pos.get_first(0x2503).data
|
||||
@ -1152,7 +1161,7 @@ def get_rotation(pos):
|
||||
refs = get_references(pos)
|
||||
if (len(refs) > 3):
|
||||
return get_rotation(refs[0])
|
||||
elif (uid == 0x3A90416731381913): # Rotation Wire
|
||||
elif (uid == MATRIX_ROT): # Rotation Wire
|
||||
return get_rotation(get_references(pos)[0])
|
||||
if (rotation):
|
||||
mtx = mathutils.Matrix.Rotation(rotation.angle, 4, rotation.axis)
|
||||
@ -1173,7 +1182,7 @@ def get_scale(pos):
|
||||
if (scale is None):
|
||||
scale = pos.get_first(0x2505)
|
||||
pos = scale.data
|
||||
elif (uid == 0xFEEE238B118F7C01): # ScaleXYZ
|
||||
elif (uid == MATRIX_SCL): # ScaleXYZ
|
||||
pos = get_point_3d(pos, 1.0)
|
||||
else:
|
||||
return mtx
|
||||
@ -1287,6 +1296,7 @@ def get_arch_material(ad):
|
||||
material = Material()
|
||||
try:
|
||||
material.set('diffuse', get_color(ad, 0x1A))
|
||||
material.set('specular', get_color(ad, 0x02))
|
||||
except:
|
||||
pass
|
||||
return material
|
||||
@ -1302,10 +1312,10 @@ def adjust_material(obj, mat):
|
||||
elif (uid == 0x0200): # Multi/Sub-Object
|
||||
refs = get_references(mat)
|
||||
material = adjust_material(obj, refs[-1])
|
||||
elif (uid == 0x7034695C37BF3F2F): # VRayMtl
|
||||
elif (uid == VRAY_MTL): # VRayMtl
|
||||
refs = get_reference(mat)
|
||||
material = get_vray_material(refs[1])
|
||||
elif (uid == 0x4A16365470B05735): # Arch
|
||||
elif (uid == ARCH_MTL): # Arch
|
||||
refs = get_references(mat)
|
||||
material = get_arch_material(refs[0])
|
||||
if (obj is not None) and (material is not None):
|
||||
@ -1539,9 +1549,9 @@ def create_mesh(context, node, msh, mtx, mat, umt, uvm):
|
||||
created = False
|
||||
uid = get_guid(msh)
|
||||
msh.geometry = None
|
||||
if (uid == 0x0E44F10B3):
|
||||
if (uid == EDIT_MESH):
|
||||
created = create_editable_mesh(context, node, msh, mat, mtx, umt)
|
||||
elif (uid == 0x192F60981BF8338D):
|
||||
elif (uid == EDIT_POLY):
|
||||
created = create_editable_poly(context, node, msh, mat, mtx, umt, uvm)
|
||||
elif (uid in {0x2032, 0x2033}):
|
||||
created = create_shell(context, node, msh, mat, mtx, umt, uvm)
|
||||
@ -1557,7 +1567,7 @@ def create_object(context, node, mscale, usemat, uvmesh, transform):
|
||||
node.parent = parent
|
||||
name = get_node_name(node)
|
||||
prs, msh, mat, lyr = get_matrix_mesh_material(node)
|
||||
while ((parent is not None) and (get_guid(parent) != 0x0002)):
|
||||
while ((parent is not None) and (get_guid(parent) != 0x02)):
|
||||
name = "%s/%s" %(get_node_name(parent), name)
|
||||
parent_mtx = parent.matrix
|
||||
if (parent_mtx):
|
||||
@ -1573,7 +1583,7 @@ def create_object(context, node, mscale, usemat, uvmesh, transform):
|
||||
def make_scene(context, mscale, usemat, uvmesh, transform, parent, level=0):
|
||||
for chunk in parent.children:
|
||||
if (isinstance(chunk, SceneChunk)):
|
||||
if ((get_guid(chunk) == 0x0001) and (get_super_id(chunk) == 0x0001)):
|
||||
if ((get_guid(chunk) == 0x01) and (get_super_id(chunk) == 0x01)):
|
||||
try:
|
||||
create_object(context, chunk, mscale, usemat, uvmesh, transform)
|
||||
except Exception as exc:
|
||||
|
Reference in New Issue
Block a user