New Addon: Import Autodesk .max #105013
@ -710,6 +710,7 @@ def make_material_chunk(material, image):
|
|||||||
material_chunk.add_subchunk(make_percent_subchunk(MATTRANS, 1 - wrap.alpha))
|
material_chunk.add_subchunk(make_percent_subchunk(MATTRANS, 1 - wrap.alpha))
|
||||||
material_chunk.add_subchunk(make_percent_subchunk(MATXPFALL, wrap.transmission))
|
material_chunk.add_subchunk(make_percent_subchunk(MATXPFALL, wrap.transmission))
|
||||||
material_chunk.add_subchunk(make_percent_subchunk(MATSELFILPCT, wrap.emission_strength))
|
material_chunk.add_subchunk(make_percent_subchunk(MATSELFILPCT, wrap.emission_strength))
|
||||||
|
material_chunk.add_subchunk(make_percent_subchunk(MATREFBLUR, wrap.node_principled_bsdf.inputs['Coat Weight'].default_value))
|
||||||
material_chunk.add_subchunk(shading)
|
material_chunk.add_subchunk(shading)
|
||||||
|
|
||||||
primary_tex = False
|
primary_tex = False
|
||||||
@ -1303,10 +1304,11 @@ def make_object_node(ob, translation, rotation, scale, name_id):
|
|||||||
else: # Add flag variables - Based on observation flags1 is usually 0x0040 and 0x4000 for empty objects
|
else: # Add flag variables - Based on observation flags1 is usually 0x0040 and 0x4000 for empty objects
|
||||||
obj_node_header_chunk.add_variable("name", _3ds_string(sane_name(name)))
|
obj_node_header_chunk.add_variable("name", _3ds_string(sane_name(name)))
|
||||||
obj_node_header_chunk.add_variable("flags1", _3ds_ushort(0x0040))
|
obj_node_header_chunk.add_variable("flags1", _3ds_ushort(0x0040))
|
||||||
|
# Flag 0x01 display path 0x02 use autosmooth 0x04 object frozen 0x10 motion blur 0x20 material morph 0x40 mesh morph
|
||||||
"""Flags2 defines 0x01 for display path, 0x04 object frozen,
|
if ob.type == 'MESH' and 'Smooth by Angle' in ob.modifiers:
|
||||||
0x10 for motion blur, 0x20 for material morph and bit 0x40 for mesh morph."""
|
ob_node_header_chunk.add_variable("flags2", _3ds_ushort(0x02))
|
||||||
obj_node_header_chunk.add_variable("flags2", _3ds_ushort(0))
|
else:
|
||||||
|
ob_node_header_chunk.add_variable("flags2", _3ds_ushort(0))
|
||||||
obj_node_header_chunk.add_variable("parent", _3ds_ushort(ROOT_OBJECT))
|
obj_node_header_chunk.add_variable("parent", _3ds_ushort(ROOT_OBJECT))
|
||||||
|
|
||||||
'''
|
'''
|
||||||
@ -1346,6 +1348,12 @@ def make_object_node(ob, translation, rotation, scale, name_id):
|
|||||||
obj_boundbox.add_variable("max", _3ds_point_3d(ob.bound_box[6]))
|
obj_boundbox.add_variable("max", _3ds_point_3d(ob.bound_box[6]))
|
||||||
obj_node.add_subchunk(obj_boundbox)
|
obj_node.add_subchunk(obj_boundbox)
|
||||||
|
|
||||||
|
# Add smooth angle if smooth modifier is used
|
||||||
|
if ob.type == 'MESH' and 'Smooth by Angle' in ob.modifiers:
|
||||||
|
obj_morph_smooth = _3ds_chunk(OBJECT_MORPH_SMOOTH)
|
||||||
|
obj_morph_smooth.add_variable("angle", _3ds_float(round(ob.modifiers['Smooth by Angle']['Input_1'], 6)))
|
||||||
|
obj_node.add_subchunk(obj_morph_smooth)
|
||||||
|
|
||||||
# Add track chunks for position, rotation, size
|
# Add track chunks for position, rotation, size
|
||||||
ob_scale = scale[name] # and collect masterscale
|
ob_scale = scale[name] # and collect masterscale
|
||||||
if parent is None or (parent.name not in name_id):
|
if parent is None or (parent.name not in name_id):
|
||||||
|
@ -361,6 +361,7 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAI
|
|||||||
contextColor = None
|
contextColor = None
|
||||||
contextWrapper = None
|
contextWrapper = None
|
||||||
contextMatrix = None
|
contextMatrix = None
|
||||||
|
contextReflection = None
|
||||||
contextTransmission = None
|
contextTransmission = None
|
||||||
contextMesh_vertls = None
|
contextMesh_vertls = None
|
||||||
contextMesh_facels = None
|
contextMesh_facels = None
|
||||||
@ -544,6 +545,7 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAI
|
|||||||
contextWrapper.emission_color = contextMaterial.line_color[:3]
|
contextWrapper.emission_color = contextMaterial.line_color[:3]
|
||||||
contextWrapper.emission_strength = contextMaterial.line_priority / 100
|
contextWrapper.emission_strength = contextMaterial.line_priority / 100
|
||||||
contextWrapper.alpha = contextMaterial.diffuse_color[3] = contextAlpha
|
contextWrapper.alpha = contextMaterial.diffuse_color[3] = contextAlpha
|
||||||
|
contextWrapper.node_principled_bsdf.inputs['Coat Weight'].default_value = contextReflection
|
||||||
|
|
||||||
while (new_chunk.bytes_read < new_chunk.length):
|
while (new_chunk.bytes_read < new_chunk.length):
|
||||||
read_chunk(file, temp_chunk)
|
read_chunk(file, temp_chunk)
|
||||||
@ -907,6 +909,7 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAI
|
|||||||
# If material chunk
|
# If material chunk
|
||||||
elif new_chunk.ID == MATERIAL:
|
elif new_chunk.ID == MATERIAL:
|
||||||
contextAlpha = True
|
contextAlpha = True
|
||||||
|
contextReflection = False
|
||||||
contextTransmission = False
|
contextTransmission = False
|
||||||
contextColor = mathutils.Color((0.8, 0.8, 0.8))
|
contextColor = mathutils.Color((0.8, 0.8, 0.8))
|
||||||
contextMaterial = bpy.data.materials.new('Material')
|
contextMaterial = bpy.data.materials.new('Material')
|
||||||
@ -998,12 +1001,22 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAI
|
|||||||
|
|
||||||
elif new_chunk.ID == MAT_XPFALL:
|
elif new_chunk.ID == MAT_XPFALL:
|
||||||
read_chunk(file, temp_chunk)
|
read_chunk(file, temp_chunk)
|
||||||
if temp_chunk.ID == PCTI:
|
if temp_chunk.ID == PCT_SHORT:
|
||||||
contextTransmission = float(read_short(temp_chunk) / 100)
|
contextTransmission = float(read_short(temp_chunk) / 100)
|
||||||
else:
|
else:
|
||||||
skip_to_end(file, temp_chunk)
|
skip_to_end(file, temp_chunk)
|
||||||
new_chunk.bytes_read += temp_chunk.bytes_read
|
new_chunk.bytes_read += temp_chunk.bytes_read
|
||||||
|
|
||||||
|
elif new_chunk.ID == MAT_REFBLUR:
|
||||||
|
read_chunk(file, temp_chunk)
|
||||||
|
if temp_chunk.ID == PCT_SHORT:
|
||||||
|
contextReflection = float(read_short(temp_chunk) / 100)
|
||||||
|
elif temp_chunk.ID == PCT_FLOAT:
|
||||||
|
contextReflection = float(read_float(temp_chunk))
|
||||||
|
else:
|
||||||
|
skip_to_end(file, temp_chunk)
|
||||||
|
new_chunk.bytes_read += temp_chunk.bytes_read
|
||||||
|
|
||||||
elif new_chunk.ID == MAT_SELF_ILPCT:
|
elif new_chunk.ID == MAT_SELF_ILPCT:
|
||||||
read_chunk(file, temp_chunk)
|
read_chunk(file, temp_chunk)
|
||||||
if temp_chunk.ID == PCT_SHORT:
|
if temp_chunk.ID == PCT_SHORT:
|
||||||
@ -1027,6 +1040,7 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAI
|
|||||||
contextWrapper.emission_color = contextMaterial.line_color[:3]
|
contextWrapper.emission_color = contextMaterial.line_color[:3]
|
||||||
contextWrapper.emission_strength = contextMaterial.line_priority / 100
|
contextWrapper.emission_strength = contextMaterial.line_priority / 100
|
||||||
contextWrapper.alpha = contextMaterial.diffuse_color[3] = contextAlpha
|
contextWrapper.alpha = contextMaterial.diffuse_color[3] = contextAlpha
|
||||||
|
contextWrapper.node_principled_bsdf.inputs['Coat Weight'].default_value = contextReflection
|
||||||
contextWrapper.use_nodes = False
|
contextWrapper.use_nodes = False
|
||||||
if shading >= 3:
|
if shading >= 3:
|
||||||
contextWrapper.use_nodes = True
|
contextWrapper.use_nodes = True
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
bl_info = {
|
bl_info = {
|
||||||
"name": "FBX format",
|
"name": "FBX format",
|
||||||
"author": "Campbell Barton, Bastien Montagne, Jens Restemeier, @Mysteryem",
|
"author": "Campbell Barton, Bastien Montagne, Jens Restemeier, @Mysteryem",
|
||||||
"version": (5, 8, 8),
|
"version": (5, 8, 11),
|
||||||
"blender": (4, 0, 0),
|
"blender": (4, 1, 0),
|
||||||
"location": "File > Import-Export",
|
"location": "File > Import-Export",
|
||||||
"description": "FBX IO meshes, UVs, vertex colors, materials, textures, cameras, lamps and actions",
|
"description": "FBX IO meshes, UVs, vertex colors, materials, textures, cameras, lamps and actions",
|
||||||
"warning": "",
|
"warning": "",
|
||||||
|
@ -1363,14 +1363,13 @@ def blen_read_geom_array_foreach_set_allsame(blen_data, blen_attr, blen_dtype, f
|
|||||||
|
|
||||||
def blen_read_geom_array_foreach_set_looptovert(mesh, blen_data, blen_attr, blen_dtype, fbx_data, stride, item_size,
|
def blen_read_geom_array_foreach_set_looptovert(mesh, blen_data, blen_attr, blen_dtype, fbx_data, stride, item_size,
|
||||||
descr, xform):
|
descr, xform):
|
||||||
"""Generic fbx_layer to blen_data foreach setter for polyloop ByVertice layers.
|
"""Generic fbx_layer to blen_data foreach setter for face corner ByVertice layers.
|
||||||
blen_data must be a bpy_prop_collection or 2d np.ndarray whose second axis length is item_size.
|
blen_data must be a bpy_prop_collection or 2d np.ndarray whose second axis length is item_size.
|
||||||
fbx_data must be an array.array"""
|
fbx_data must be an array.array"""
|
||||||
# The fbx_data is mapped to vertices. To expand fbx_data to polygon loops, get an array of the vertex index of each
|
# The fbx_data is mapped to vertices. To expand fbx_data to face corners, get an array of the vertex index of each
|
||||||
# polygon loop that will then be used to index fbx_data
|
# face corner that will then be used to index fbx_data.
|
||||||
loop_vertex_indices = np.empty(len(mesh.loops), dtype=np.uintc)
|
corner_vertex_indices = MESH_ATTRIBUTE_CORNER_VERT.to_ndarray(mesh.attributes)
|
||||||
mesh.loops.foreach_get("vertex_index", loop_vertex_indices)
|
blen_read_geom_array_foreach_set_indexed(blen_data, blen_attr, blen_dtype, fbx_data, corner_vertex_indices, stride,
|
||||||
blen_read_geom_array_foreach_set_indexed(blen_data, blen_attr, blen_dtype, fbx_data, loop_vertex_indices, stride,
|
|
||||||
item_size, descr, xform)
|
item_size, descr, xform)
|
||||||
|
|
||||||
|
|
||||||
@ -1747,11 +1746,13 @@ def blen_read_geom_layer_normal(fbx_obj, mesh, xform=None):
|
|||||||
poly_loop_totals = np.empty(len(mesh.polygons), dtype=np.uintc)
|
poly_loop_totals = np.empty(len(mesh.polygons), dtype=np.uintc)
|
||||||
mesh.polygons.foreach_get("loop_total", poly_loop_totals)
|
mesh.polygons.foreach_get("loop_total", poly_loop_totals)
|
||||||
loop_normals = np.repeat(bdata, poly_loop_totals, axis=0)
|
loop_normals = np.repeat(bdata, poly_loop_totals, axis=0)
|
||||||
mesh.attributes["temp_custom_normals"].data.foreach_set("normal", loop_normals.ravel())
|
mesh.attributes["temp_custom_normals"].data.foreach_set("vector", loop_normals.ravel())
|
||||||
elif blen_data_type == "Vertices":
|
elif blen_data_type == "Vertices":
|
||||||
|
# Note: Currently unreachable because `blen_read_geom_array_mapped_polyloop` covers all the supported
|
||||||
|
# import cases covered by `blen_read_geom_array_mapped_vert`.
|
||||||
# We have to copy vnors to lnors! Far from elegant, but simple.
|
# We have to copy vnors to lnors! Far from elegant, but simple.
|
||||||
loop_vertex_indices = MESH_ATTRIBUTE_CORNER_VERT.to_ndarray(mesh.attributes)
|
loop_vertex_indices = MESH_ATTRIBUTE_CORNER_VERT.to_ndarray(mesh.attributes)
|
||||||
mesh.attributes["temp_custom_normals"].data.foreach_set("normal", bdata[loop_vertex_indices].ravel())
|
mesh.attributes["temp_custom_normals"].data.foreach_set("vector", bdata[loop_vertex_indices].ravel())
|
||||||
return True
|
return True
|
||||||
|
|
||||||
blen_read_geom_array_error_mapping("normal", fbx_layer_mapping)
|
blen_read_geom_array_error_mapping("normal", fbx_layer_mapping)
|
||||||
|
Loading…
Reference in New Issue
Block a user