New Addon: Import Autodesk .max #105013
@ -55,7 +55,7 @@ class Import3DS(bpy.types.Operator, ImportHelper):
|
||||
soft_min=0.0, soft_max=1000.0,
|
||||
default=10.0,
|
||||
)
|
||||
convert_unit: BoolProperty(
|
||||
use_scene_unit: BoolProperty(
|
||||
name="Scene Units",
|
||||
description="Converts to scene unit length settings",
|
||||
default=False,
|
||||
@ -72,7 +72,7 @@ class Import3DS(bpy.types.Operator, ImportHelper):
|
||||
('MESH', "Mesh".rjust(11), "", 'MESH_DATA', 0x2),
|
||||
('LIGHT', "Light".rjust(12), "", 'LIGHT_DATA', 0x4),
|
||||
('CAMERA', "Camera".rjust(11), "", 'CAMERA_DATA', 0x8),
|
||||
('EMPTY', "Empty".rjust(11), "", 'EMPTY_DATA', 0x10),
|
||||
('EMPTY', "Empty".rjust(11), "", 'EMPTY_AXIS', 0x10),
|
||||
),
|
||||
description="Object types to import",
|
||||
default={'WORLD', 'MESH', 'LIGHT', 'CAMERA', 'EMPTY'},
|
||||
@ -83,7 +83,7 @@ class Import3DS(bpy.types.Operator, ImportHelper):
|
||||
"importing incorrectly",
|
||||
default=True,
|
||||
)
|
||||
read_keyframe: BoolProperty(
|
||||
use_keyframes: BoolProperty(
|
||||
name="Animation",
|
||||
description="Read the keyframe data",
|
||||
default=True,
|
||||
@ -93,6 +93,11 @@ class Import3DS(bpy.types.Operator, ImportHelper):
|
||||
description="Transform to matrix world",
|
||||
default=False,
|
||||
)
|
||||
use_cursor: BoolProperty(
|
||||
name="Cursor Origin",
|
||||
description="Read the 3D cursor location",
|
||||
default=False,
|
||||
)
|
||||
|
||||
def execute(self, context):
|
||||
from . import import_3ds
|
||||
@ -139,8 +144,11 @@ class MAX3DS_PT_import_include(bpy.types.Panel):
|
||||
layrow.label(text="", icon='OUTLINER_OB_IMAGE' if operator.use_image_search else 'IMAGE_DATA')
|
||||
layout.column().prop(operator, "object_filter")
|
||||
layrow = layout.row(align=True)
|
||||
layrow.prop(operator, "read_keyframe")
|
||||
layrow.label(text="", icon='ANIM' if operator.read_keyframe else 'DECORATE_DRIVER')
|
||||
layrow.prop(operator, "use_keyframes")
|
||||
layrow.label(text="", icon='ANIM' if operator.use_keyframes else 'DECORATE_DRIVER')
|
||||
layrow = layout.row(align=True)
|
||||
layrow.prop(operator, "use_cursor")
|
||||
layrow.label(text="", icon='PIVOT_CURSOR' if operator.use_cursor else 'CURSOR')
|
||||
|
||||
|
||||
class MAX3DS_PT_import_transform(bpy.types.Panel):
|
||||
@ -166,8 +174,8 @@ class MAX3DS_PT_import_transform(bpy.types.Panel):
|
||||
|
||||
layout.prop(operator, "constrain_size")
|
||||
layrow = layout.row(align=True)
|
||||
layrow.prop(operator, "convert_unit")
|
||||
layrow.label(text="", icon='EMPTY_ARROWS' if operator.convert_unit else 'EMPTY_DATA')
|
||||
layrow.prop(operator, "use_scene_unit")
|
||||
layrow.label(text="", icon='EMPTY_ARROWS' if operator.use_scene_unit else 'EMPTY_DATA')
|
||||
layrow = layout.row(align=True)
|
||||
layrow.prop(operator, "use_apply_transform")
|
||||
layrow.label(text="", icon='MESH_CUBE' if operator.use_apply_transform else 'MOD_SOLIDIFY')
|
||||
@ -198,7 +206,7 @@ class Export3DS(bpy.types.Operator, ExportHelper):
|
||||
soft_min=0.0, soft_max=100000.0,
|
||||
default=1.0,
|
||||
)
|
||||
apply_unit: BoolProperty(
|
||||
use_scene_unit: BoolProperty(
|
||||
name="Scene Units",
|
||||
description="Take the scene unit length settings into account",
|
||||
default=False,
|
||||
@ -214,7 +222,7 @@ class Export3DS(bpy.types.Operator, ExportHelper):
|
||||
('MESH', "Mesh".rjust(11), "", 'MESH_DATA', 0x2),
|
||||
('LIGHT', "Light".rjust(12), "", 'LIGHT_DATA',0x4),
|
||||
('CAMERA', "Camera".rjust(11), "", 'CAMERA_DATA',0x8),
|
||||
('EMPTY', "Empty".rjust(11), "", 'EMPTY_DATA',0x10),
|
||||
('EMPTY', "Empty".rjust(11), "", 'EMPTY_AXIS',0x10),
|
||||
),
|
||||
description="Object types to export",
|
||||
default={'WORLD', 'MESH', 'LIGHT', 'CAMERA', 'EMPTY'},
|
||||
@ -224,11 +232,16 @@ class Export3DS(bpy.types.Operator, ExportHelper):
|
||||
description="Export hierarchy chunks",
|
||||
default=False,
|
||||
)
|
||||
write_keyframe: BoolProperty(
|
||||
use_keyframes: BoolProperty(
|
||||
name="Animation",
|
||||
description="Write the keyframe data",
|
||||
default=False,
|
||||
)
|
||||
use_cursor: BoolProperty(
|
||||
name="Cursor Origin",
|
||||
description="Save the 3D cursor location",
|
||||
default=False,
|
||||
)
|
||||
|
||||
def execute(self, context):
|
||||
from . import export_3ds
|
||||
@ -278,9 +291,11 @@ class MAX3DS_PT_export_include(bpy.types.Panel):
|
||||
layrow.prop(operator, "use_hierarchy")
|
||||
layrow.label(text="", icon='OUTLINER' if operator.use_hierarchy else 'CON_CHILDOF')
|
||||
layrow = layout.row(align=True)
|
||||
layrow.prop(operator, "write_keyframe")
|
||||
layrow.label(text="", icon='ANIM' if operator.write_keyframe else 'DECORATE_DRIVER')
|
||||
layout.use_property_split = True
|
||||
layrow.prop(operator, "use_keyframes")
|
||||
layrow.label(text="", icon='ANIM' if operator.use_keyframes else 'DECORATE_DRIVER')
|
||||
layrow = layout.row(align=True)
|
||||
layrow.prop(operator, "use_cursor")
|
||||
layrow.label(text="", icon='PIVOT_CURSOR' if operator.use_cursor else 'CURSOR')
|
||||
|
||||
|
||||
class MAX3DS_PT_export_transform(bpy.types.Panel):
|
||||
@ -306,8 +321,8 @@ class MAX3DS_PT_export_transform(bpy.types.Panel):
|
||||
|
||||
layout.prop(operator, "scale_factor")
|
||||
layrow = layout.row(align=True)
|
||||
layrow.prop(operator, "apply_unit")
|
||||
layrow.label(text="", icon='EMPTY_ARROWS' if operator.apply_unit else 'EMPTY_DATA')
|
||||
layrow.prop(operator, "use_scene_unit")
|
||||
layrow.label(text="", icon='EMPTY_ARROWS' if operator.use_scene_unit else 'EMPTY_DATA')
|
||||
layout.prop(operator, "axis_forward")
|
||||
layout.prop(operator, "axis_up")
|
||||
|
||||
|
@ -36,6 +36,7 @@ SOLIDBACKGND = 0x1200 # The background color (RGB)
|
||||
USE_SOLIDBGND = 0x1201 # The background color flag
|
||||
VGRADIENT = 0x1300 # The background gradient colors
|
||||
USE_VGRADIENT = 0x1301 # The background gradient flag
|
||||
O_CONSTS = 0x1500 # The origin of the 3D cursor
|
||||
AMBIENTLIGHT = 0x2100 # The color of the ambient light
|
||||
LAYER_FOG = 0x2302 # The fog atmosphere settings
|
||||
USE_LAYER_FOG = 0x2303 # The fog atmosphere flag
|
||||
@ -1497,8 +1498,8 @@ def make_ambient_node(world):
|
||||
# EXPORT #
|
||||
##########
|
||||
|
||||
def save(operator, context, filepath="", scale_factor=1.0, apply_unit=False, use_selection=False,
|
||||
object_filter=None, use_hierarchy=False, write_keyframe=False, global_matrix=None):
|
||||
def save(operator, context, filepath="", scale_factor=1.0, use_scene_unit=False, use_selection=False,
|
||||
object_filter=None, use_hierarchy=False, use_keyframes=False, global_matrix=None, use_cursor=False):
|
||||
"""Save the Blender scene to a 3ds file."""
|
||||
|
||||
# Time the export
|
||||
@ -1511,7 +1512,7 @@ def save(operator, context, filepath="", scale_factor=1.0, apply_unit=False, use
|
||||
world = scene.world
|
||||
|
||||
unit_measure = 1.0
|
||||
if apply_unit:
|
||||
if use_scene_unit:
|
||||
unit_length = scene.unit_settings.length_unit
|
||||
if unit_length == 'KILOMETERS':
|
||||
unit_measure = 0.001
|
||||
@ -1549,21 +1550,29 @@ def save(operator, context, filepath="", scale_factor=1.0, apply_unit=False, use
|
||||
mscale.add_variable("scale", _3ds_float(1.0))
|
||||
object_info.add_subchunk(mscale)
|
||||
|
||||
# Add 3D cursor location
|
||||
if use_cursor:
|
||||
cursor_chunk = _3ds_chunk(O_CONSTS)
|
||||
cursor_chunk.add_variable("cursor", _3ds_point_3d(scene.cursor.location))
|
||||
object_info.add_subchunk(cursor_chunk)
|
||||
|
||||
# Init main keyframe data chunk
|
||||
if write_keyframe:
|
||||
if use_keyframes:
|
||||
revision = 0x0005
|
||||
stop = scene.frame_end
|
||||
start = scene.frame_start
|
||||
curtime = scene.frame_current
|
||||
kfdata = make_kfdata(revision, start, stop, curtime)
|
||||
|
||||
# Add AMBIENT, BACKGROUND and BITMAP
|
||||
# Add AMBIENT color
|
||||
if world is not None and 'WORLD' in object_filter:
|
||||
ambient_chunk = _3ds_chunk(AMBIENTLIGHT)
|
||||
ambient_light = _3ds_chunk(RGB)
|
||||
ambient_light.add_variable("ambient", _3ds_float_color(world.color))
|
||||
ambient_chunk.add_subchunk(ambient_light)
|
||||
object_info.add_subchunk(ambient_chunk)
|
||||
|
||||
# Add BACKGROUND and BITMAP
|
||||
if world.use_nodes:
|
||||
ntree = world.node_tree.links
|
||||
background_color_chunk = _3ds_chunk(RGB)
|
||||
@ -1604,7 +1613,7 @@ def save(operator, context, filepath="", scale_factor=1.0, apply_unit=False, use
|
||||
object_info.add_subchunk(fog_chunk)
|
||||
if layer.use_pass_mist:
|
||||
object_info.add_subchunk(use_fog_flag)
|
||||
if write_keyframe and world.animation_data:
|
||||
if use_keyframes and world.animation_data:
|
||||
kfdata.add_subchunk(make_ambient_node(world))
|
||||
|
||||
# Make a list of all materials used in the selected meshes (use dictionary, each material is added once)
|
||||
@ -1746,13 +1755,13 @@ def save(operator, context, filepath="", scale_factor=1.0, apply_unit=False, use
|
||||
operator.report({'WARNING'}, "Object %r can't be written into a 3DS file")
|
||||
|
||||
# Export object node
|
||||
if write_keyframe:
|
||||
if use_keyframes:
|
||||
kfdata.add_subchunk(make_object_node(ob, translation, rotation, scale, name_id))
|
||||
|
||||
i += i
|
||||
|
||||
# Create chunks for all empties - only requires a object node
|
||||
if write_keyframe:
|
||||
if use_keyframes:
|
||||
for ob in empty_objects:
|
||||
kfdata.add_subchunk(make_object_node(ob, translation, rotation, scale, name_id))
|
||||
|
||||
@ -1816,7 +1825,7 @@ def save(operator, context, filepath="", scale_factor=1.0, apply_unit=False, use
|
||||
object_info.add_subchunk(object_chunk)
|
||||
|
||||
# Export light and spotlight target node
|
||||
if write_keyframe:
|
||||
if use_keyframes:
|
||||
kfdata.add_subchunk(make_object_node(ob, translation, rotation, scale, name_id))
|
||||
if ob.data.type == 'SPOT':
|
||||
kfdata.add_subchunk(make_target_node(ob, translation, rotation, scale, name_id))
|
||||
@ -1850,7 +1859,7 @@ def save(operator, context, filepath="", scale_factor=1.0, apply_unit=False, use
|
||||
object_info.add_subchunk(object_chunk)
|
||||
|
||||
# Export camera and target node
|
||||
if write_keyframe:
|
||||
if use_keyframes:
|
||||
kfdata.add_subchunk(make_object_node(ob, translation, rotation, scale, name_id))
|
||||
kfdata.add_subchunk(make_target_node(ob, translation, rotation, scale, name_id))
|
||||
|
||||
@ -1858,7 +1867,7 @@ def save(operator, context, filepath="", scale_factor=1.0, apply_unit=False, use
|
||||
primary.add_subchunk(object_info)
|
||||
|
||||
# Add main keyframe data chunk to primary chunk
|
||||
if write_keyframe:
|
||||
if use_keyframes:
|
||||
primary.add_subchunk(kfdata)
|
||||
|
||||
# The chunk hierarchy is completely built, now check the size
|
||||
|
@ -43,6 +43,7 @@ SOLIDBACKGND = 0x1200 # The background color (RGB)
|
||||
USE_SOLIDBGND = 0x1201 # The background color flag
|
||||
VGRADIENT = 0x1300 # The background gradient colors
|
||||
USE_VGRADIENT = 0x1301 # The background gradient flag
|
||||
O_CONSTS = 0x1500 # The origin of the 3D cursor
|
||||
AMBIENTLIGHT = 0x2100 # The color of the ambient light
|
||||
LAYER_FOG = 0x2302 # The fog atmosphere settings
|
||||
USE_LAYER_FOG = 0x2303 # The fog atmosphere flag
|
||||
@ -333,8 +334,8 @@ def add_texture_to_material(image, contextWrapper, pct, extend, alpha, scale, of
|
||||
childs_list = []
|
||||
parent_list = []
|
||||
|
||||
def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAIN,
|
||||
FILTER, IMAGE_SEARCH, WORLD_MATRIX, KEYFRAME, CONVERSE, MEASURE):
|
||||
def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAIN, FILTER,
|
||||
IMAGE_SEARCH, WORLD_MATRIX, KEYFRAME, CONVERSE, MEASURE, CURSOR):
|
||||
|
||||
contextObName = None
|
||||
contextWorld = None
|
||||
@ -679,6 +680,10 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAI
|
||||
if version > 3:
|
||||
print("\tNon-Fatal Error: Version greater than 3, may not load correctly: ", version)
|
||||
|
||||
# If cursor location
|
||||
elif CURSOR and new_chunk.ID == O_CONSTS:
|
||||
context.scene.cursor.location = read_float_array(new_chunk)
|
||||
|
||||
# If ambient light chunk
|
||||
elif CreateWorld and new_chunk.ID == AMBIENTLIGHT:
|
||||
path, filename = os.path.split(file.name)
|
||||
@ -768,8 +773,8 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAI
|
||||
|
||||
# is it an object info chunk?
|
||||
elif new_chunk.ID == OBJECTINFO:
|
||||
process_next_chunk(context, file, new_chunk, imported_objects, CONSTRAIN,
|
||||
FILTER, IMAGE_SEARCH, WORLD_MATRIX, KEYFRAME, CONVERSE, MEASURE)
|
||||
process_next_chunk(context, file, new_chunk, imported_objects, CONSTRAIN, FILTER,
|
||||
IMAGE_SEARCH, WORLD_MATRIX, KEYFRAME, CONVERSE, MEASURE, CURSOR)
|
||||
|
||||
# keep track of how much we read in the main chunk
|
||||
new_chunk.bytes_read += temp_chunk.bytes_read
|
||||
@ -1416,7 +1421,7 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAI
|
||||
##########
|
||||
|
||||
def load_3ds(filepath, context, CONSTRAIN=10.0, UNITS=False, IMAGE_SEARCH=True, FILTER=None,
|
||||
WORLD_MATRIX=False, KEYFRAME=True, APPLY_MATRIX=True, CONVERSE=None):
|
||||
WORLD_MATRIX=False, KEYFRAME=True, APPLY_MATRIX=True, CONVERSE=None, CURSOR=False):
|
||||
|
||||
print("importing 3DS: %r..." % (filepath), end="")
|
||||
|
||||
@ -1458,8 +1463,8 @@ def load_3ds(filepath, context, CONSTRAIN=10.0, UNITS=False, IMAGE_SEARCH=True,
|
||||
MEASURE = 0.000001
|
||||
|
||||
imported_objects = [] # Fill this list with objects
|
||||
process_next_chunk(context, file, current_chunk, imported_objects, CONSTRAIN,
|
||||
FILTER, IMAGE_SEARCH, WORLD_MATRIX, KEYFRAME, CONVERSE, MEASURE)
|
||||
process_next_chunk(context, file, current_chunk, imported_objects, CONSTRAIN, FILTER,
|
||||
IMAGE_SEARCH, WORLD_MATRIX, KEYFRAME, CONVERSE, MEASURE, CURSOR)
|
||||
|
||||
# fixme, make unglobal
|
||||
object_dictionary.clear()
|
||||
@ -1553,12 +1558,12 @@ def load_3ds(filepath, context, CONSTRAIN=10.0, UNITS=False, IMAGE_SEARCH=True,
|
||||
file.close()
|
||||
|
||||
|
||||
def load(operator, context, filepath="", constrain_size=0.0, convert_unit=False,
|
||||
def load(operator, context, filepath="", constrain_size=0.0, use_scene_unit=False,
|
||||
use_image_search=True, object_filter=None, use_world_matrix=False,
|
||||
read_keyframe=True, use_apply_transform=True, global_matrix=None,):
|
||||
use_keyframes=True, use_apply_transform=True, global_matrix=None, use_cursor=False):
|
||||
|
||||
load_3ds(filepath, context, CONSTRAIN=constrain_size, UNITS=convert_unit,
|
||||
load_3ds(filepath, context, CONSTRAIN=constrain_size, UNITS=use_scene_unit,
|
||||
IMAGE_SEARCH=use_image_search, FILTER=object_filter, WORLD_MATRIX=use_world_matrix,
|
||||
KEYFRAME=read_keyframe, APPLY_MATRIX=use_apply_transform, CONVERSE=global_matrix,)
|
||||
KEYFRAME=use_keyframes, APPLY_MATRIX=use_apply_transform, CONVERSE=global_matrix, CURSOR=use_cursor,)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
Loading…
Reference in New Issue
Block a user