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