New Addon: Import Autodesk .max #105013
@ -30,7 +30,6 @@ bl_info = {
|
|||||||
import io, re
|
import io, re
|
||||||
import os, sys, zlib
|
import os, sys, zlib
|
||||||
import struct, array
|
import struct, array
|
||||||
import time, datetime
|
|
||||||
import math, mathutils
|
import math, mathutils
|
||||||
import bpy, bpy_extras
|
import bpy, bpy_extras
|
||||||
from bpy_extras.io_utils import axis_conversion
|
from bpy_extras.io_utils import axis_conversion
|
||||||
@ -170,23 +169,9 @@ 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
|
||||||
|
|
||||||
STGTY_EMPTY = 0 # empty directory entry
|
|
||||||
STGTY_STORAGE = 1 # element is a storage object
|
|
||||||
STGTY_STREAM = 2 # element is a stream object
|
STGTY_STREAM = 2 # element is a stream object
|
||||||
STGTY_LOCKBYTES = 3 # element is an ILockBytes object
|
|
||||||
STGTY_PROPERTY = 4 # element is an IPropertyStorage object
|
|
||||||
STGTY_ROOT = 5 # element is a root storage
|
STGTY_ROOT = 5 # element is a root storage
|
||||||
|
|
||||||
VT_EMPTY=0; VT_NULL=1; VT_I2=2; VT_I4=3; VT_R4=4; VT_R8=5; VT_CY=6;
|
|
||||||
VT_DATE=7; VT_BSTR=8; VT_DISPATCH=9; VT_ERROR=10; VT_BOOL=11;
|
|
||||||
VT_VARIANT=12; VT_UNKNOWN=13; VT_DECIMAL=14; VT_I1=16; VT_UI1=17;
|
|
||||||
VT_UI2=18; VT_UI4=19; VT_I8=20; VT_UI8=21; VT_INT=22; VT_UINT=23;
|
|
||||||
VT_VOID=24; VT_HRESULT=25; VT_PTR=26; VT_SAFEARRAY=27; VT_CARRAY=28;
|
|
||||||
VT_USERDEFINED=29; VT_LPSTR=30; VT_LPWSTR=31; VT_FILETIME=64;
|
|
||||||
VT_BLOB=65; VT_STREAM=66; VT_STORAGE=67; VT_STREAMED_OBJECT=68;
|
|
||||||
VT_STORED_OBJECT=69; VT_BLOB_OBJECT=70; VT_CF=71; VT_CLSID=72;
|
|
||||||
VT_VECTOR=0x1000;
|
|
||||||
|
|
||||||
TYP_NAME = 0x0962
|
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
|
||||||
@ -692,71 +677,6 @@ class ImportMaxFile:
|
|||||||
def get_rootentry_name(self):
|
def get_rootentry_name(self):
|
||||||
return self.root.name
|
return self.root.name
|
||||||
|
|
||||||
def getproperties(self, filename):
|
|
||||||
fp = self.openstream(filename)
|
|
||||||
data = {}
|
|
||||||
try:
|
|
||||||
stream = fp.read(28)
|
|
||||||
clsid = _clsid(stream[8:24])
|
|
||||||
stream = fp.read(20)
|
|
||||||
fmtid = _clsid(stream[:16])
|
|
||||||
fp.seek(i32(stream, 16))
|
|
||||||
stream = b"****" + fp.read(i32(fp.read(4)) - 4)
|
|
||||||
num_props = i32(stream, 4)
|
|
||||||
except BaseException as exc:
|
|
||||||
return data
|
|
||||||
|
|
||||||
num_props = min(num_props, int(len(stream) / 8))
|
|
||||||
for i in range(num_props):
|
|
||||||
property_id = 0
|
|
||||||
try:
|
|
||||||
property_id = i32(stream, 8 + i*8)
|
|
||||||
offset = i32(stream, 12 + i*8)
|
|
||||||
property_type = i32(stream, offset)
|
|
||||||
if property_type == VT_I2: # 16-bit signed integer
|
|
||||||
value = i16(stream, offset + 4)
|
|
||||||
if value >= 32768:
|
|
||||||
value = value - 65536
|
|
||||||
elif property_type == VT_UI2: # 2-byte unsigned integer
|
|
||||||
value = i16(stream, offset + 4)
|
|
||||||
elif property_type in (VT_I4, VT_INT, VT_ERROR):
|
|
||||||
value = i32(stream, offset + 4)
|
|
||||||
elif property_type in (VT_UI4, VT_UINT): # 4-byte unsigned integer
|
|
||||||
value = i32(stream, offset + 4)
|
|
||||||
elif property_type in (VT_BSTR, VT_LPSTR):
|
|
||||||
count = i32(stream, offset + 4)
|
|
||||||
value = stream[offset + 8:offset + 8 + count - 1]
|
|
||||||
value = value.replace(b'\x00', b'')
|
|
||||||
elif property_type == VT_BLOB:
|
|
||||||
count = i32(stream, offset + 4)
|
|
||||||
value = stream[offset + 8:offset + 8 + count]
|
|
||||||
elif property_type == VT_LPWSTR:
|
|
||||||
count = i32(stream, offset + 4)
|
|
||||||
value = self._decode_utf16_str(stream[offset + 8:offset + 8 + count * 2])
|
|
||||||
elif property_type == VT_FILETIME:
|
|
||||||
value = int(i32(stream, offset + 4)) + (int(i32(stream, offset + 8)) << 32)
|
|
||||||
if property_id != 10:
|
|
||||||
_FILETIME_null_date = datetime.datetime(1601, 1, 1, 0, 0, 0)
|
|
||||||
value = _FILETIME_null_date + datetime.timedelta(microseconds=value // 10)
|
|
||||||
else:
|
|
||||||
value = value // 10000000
|
|
||||||
elif property_type == VT_UI1: # 1-byte unsigned integer
|
|
||||||
value = i8(stream[offset + 4])
|
|
||||||
elif property_type == VT_CLSID:
|
|
||||||
value = _clsid(stream[offset + 4:offset + 20])
|
|
||||||
elif property_type == VT_CF:
|
|
||||||
count = i32(stream, offset + 4)
|
|
||||||
value = stream[offset + 8:offset + 8 + count]
|
|
||||||
elif property_type == VT_BOOL:
|
|
||||||
value = bool(i16(stream, offset + 4))
|
|
||||||
else:
|
|
||||||
value = None
|
|
||||||
|
|
||||||
data[property_id] = value
|
|
||||||
except BaseException as exc:
|
|
||||||
print('Error while parsing property_id:', exc)
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
###################
|
###################
|
||||||
# DATA PROCESSING #
|
# DATA PROCESSING #
|
||||||
@ -917,7 +837,7 @@ class ChunkReader():
|
|||||||
long, ofst = get_long(data, ofst)
|
long, ofst = get_long(data, ofst)
|
||||||
if (short == 0x8B1F):
|
if (short == 0x8B1F):
|
||||||
short, ofst = get_long(data, ofst)
|
short, ofst = get_long(data, ofst)
|
||||||
if (short == 0xB000000):
|
if (short in (0xB000000, 0xa040000)):
|
||||||
data = zlib.decompress(data, zlib.MAX_WBITS|32)
|
data = zlib.decompress(data, zlib.MAX_WBITS|32)
|
||||||
print(" reading '%s'..." %self.name, len(data))
|
print(" reading '%s'..." %self.name, len(data))
|
||||||
while offset < len(data):
|
while offset < len(data):
|
||||||
@ -1597,8 +1517,6 @@ def read_scene(context, maxfile, filename, mscale, usemat, uvmesh, transform):
|
|||||||
def read(context, filename, mscale, usemat, uvmesh, transform):
|
def read(context, filename, mscale, usemat, uvmesh, transform):
|
||||||
if (is_maxfile(filename)):
|
if (is_maxfile(filename)):
|
||||||
maxfile = ImportMaxFile(filename)
|
maxfile = ImportMaxFile(filename)
|
||||||
prop = maxfile.getproperties('\x05DocumentSummaryInformation')
|
|
||||||
prop = maxfile.getproperties('\x05SummaryInformation')
|
|
||||||
read_class_data(maxfile, filename)
|
read_class_data(maxfile, filename)
|
||||||
read_config(maxfile, filename)
|
read_config(maxfile, filename)
|
||||||
read_directory(maxfile, filename)
|
read_directory(maxfile, filename)
|
||||||
@ -1611,10 +1529,12 @@ def read(context, filename, mscale, usemat, uvmesh, transform):
|
|||||||
|
|
||||||
def load(operator, context, filepath="", scale_objects=1.0, use_material=True,
|
def load(operator, context, filepath="", scale_objects=1.0, use_material=True,
|
||||||
use_uv_mesh=False, use_apply_matrix=False, global_matrix=None):
|
use_uv_mesh=False, use_apply_matrix=False, global_matrix=None):
|
||||||
|
context.window.cursor_set('WAIT')
|
||||||
mscale = mathutils.Matrix.Scale(scale_objects, 4)
|
mscale = mathutils.Matrix.Scale(scale_objects, 4)
|
||||||
if global_matrix is not None:
|
if global_matrix is not None:
|
||||||
mscale = global_matrix @ mscale
|
mscale = global_matrix @ mscale
|
||||||
|
|
||||||
read(context, filepath, mscale, usemat=use_material, uvmesh=use_uv_mesh, transform=use_apply_matrix)
|
read(context, filepath, mscale, usemat=use_material, uvmesh=use_uv_mesh, transform=use_apply_matrix)
|
||||||
|
context.window.cursor_set('DEFAULT')
|
||||||
|
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
Loading…
Reference in New Issue
Block a user