FBX IO: Update for new meshes being smooth by default #105039

Merged
Thomas Barlow merged 2 commits from Mysteryem/blender-addons:fbx_update_for_smooth_mesh_default into main 2023-12-05 03:41:03 +01:00
2 changed files with 11 additions and 20 deletions

View File

@ -5,7 +5,7 @@
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, 11, 0), "version": (5, 11, 1),
"blender": (4, 1, 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",

View File

@ -1638,7 +1638,7 @@ def blen_read_geom_layer_smooth(fbx_obj, mesh):
fbx_layer = elem_find_first(fbx_obj, b'LayerElementSmoothing') fbx_layer = elem_find_first(fbx_obj, b'LayerElementSmoothing')
if fbx_layer is None: if fbx_layer is None:
return False return
# all should be valid # all should be valid
(fbx_layer_name, (fbx_layer_name,
@ -1651,13 +1651,13 @@ def blen_read_geom_layer_smooth(fbx_obj, mesh):
# udk has 'Direct' mapped, with no Smoothing, not sure why, but ignore these # udk has 'Direct' mapped, with no Smoothing, not sure why, but ignore these
if fbx_layer_data is None: if fbx_layer_data is None:
return False return
if fbx_layer_mapping == b'ByEdge': if fbx_layer_mapping == b'ByEdge':
# some models have bad edge data, we can't use this info... # some models have bad edge data, we can't use this info...
if not mesh.edges: if not mesh.edges:
print("warning skipping sharp edges data, no valid edges...") print("warning skipping sharp edges data, no valid edges...")
return False return
blen_data = MESH_ATTRIBUTE_SHARP_EDGE.ensure(mesh.attributes).data blen_data = MESH_ATTRIBUTE_SHARP_EDGE.ensure(mesh.attributes).data
fbx_item_size = 1 fbx_item_size = 1
@ -1669,21 +1669,23 @@ def blen_read_geom_layer_smooth(fbx_obj, mesh):
1, fbx_item_size, layer_id, 1, fbx_item_size, layer_id,
xform=np.logical_not, # in FBX, 0 (False) is sharp, but in Blender True is sharp. xform=np.logical_not, # in FBX, 0 (False) is sharp, but in Blender True is sharp.
) )
return False
elif fbx_layer_mapping == b'ByPolygon': elif fbx_layer_mapping == b'ByPolygon':
blen_data = MESH_ATTRIBUTE_SHARP_FACE.ensure(mesh.attributes).data sharp_face = MESH_ATTRIBUTE_SHARP_FACE.ensure(mesh.attributes)
blen_data = sharp_face.data
fbx_item_size = 1 fbx_item_size = 1
assert(fbx_item_size == MESH_ATTRIBUTE_SHARP_FACE.item_size) assert(fbx_item_size == MESH_ATTRIBUTE_SHARP_FACE.item_size)
return blen_read_geom_array_mapped_polygon( sharp_face_set_successfully = blen_read_geom_array_mapped_polygon(
mesh, blen_data, MESH_ATTRIBUTE_SHARP_FACE.foreach_attribute, MESH_ATTRIBUTE_SHARP_FACE.dtype, mesh, blen_data, MESH_ATTRIBUTE_SHARP_FACE.foreach_attribute, MESH_ATTRIBUTE_SHARP_FACE.dtype,
fbx_layer_data, None, fbx_layer_data, None,
fbx_layer_mapping, fbx_layer_ref, fbx_layer_mapping, fbx_layer_ref,
1, fbx_item_size, layer_id, 1, fbx_item_size, layer_id,
xform=lambda s: (s == 0), # smoothgroup bitflags, treat as booleans for now xform=lambda s: (s == 0), # smoothgroup bitflags, treat as booleans for now
) )
if not sharp_face_set_successfully:
mesh.attributes.remove(sharp_face)
else: else:
print("warning layer %r mapping type unsupported: %r" % (fbx_layer.id, fbx_layer_mapping)) print("warning layer %r mapping type unsupported: %r" % (fbx_layer.id, fbx_layer_mapping))
return False
def blen_read_geom_layer_edge_crease(fbx_obj, mesh): def blen_read_geom_layer_edge_crease(fbx_obj, mesh):
fbx_layer = elem_find_first(fbx_obj, b'LayerElementEdgeCrease') fbx_layer = elem_find_first(fbx_obj, b'LayerElementEdgeCrease')
@ -1883,7 +1885,7 @@ def blen_read_geom(fbx_tmpl, fbx_obj, settings):
print("ERROR: No polygons, but edges exist. Ignoring the edges!") print("ERROR: No polygons, but edges exist. Ignoring the edges!")
# must be after edge, face loading. # must be after edge, face loading.
ok_smooth = blen_read_geom_layer_smooth(fbx_obj, mesh) blen_read_geom_layer_smooth(fbx_obj, mesh)
blen_read_geom_layer_edge_crease(fbx_obj, mesh) blen_read_geom_layer_edge_crease(fbx_obj, mesh)
@ -1905,23 +1907,12 @@ def blen_read_geom(fbx_tmpl, fbx_obj, settings):
clnors = np.empty(len(mesh.loops) * 3, dtype=bl_nors_dtype) clnors = np.empty(len(mesh.loops) * 3, dtype=bl_nors_dtype)
mesh.attributes["temp_custom_normals"].data.foreach_get("vector", clnors) mesh.attributes["temp_custom_normals"].data.foreach_get("vector", clnors)
if not ok_smooth:
sharp_face = MESH_ATTRIBUTE_SHARP_FACE.get(attributes)
if sharp_face:
attributes.remove(sharp_face)
ok_smooth = True
# Iterating clnors into a nested tuple first is faster than passing clnors.reshape(-1, 3) directly into # Iterating clnors into a nested tuple first is faster than passing clnors.reshape(-1, 3) directly into
# normals_split_custom_set. We use clnors.data since it is a memoryview, which is faster to iterate than clnors. # normals_split_custom_set. We use clnors.data since it is a memoryview, which is faster to iterate than clnors.
mesh.normals_split_custom_set(tuple(zip(*(iter(clnors.data),) * 3))) mesh.normals_split_custom_set(tuple(zip(*(iter(clnors.data),) * 3)))
if settings.use_custom_normals: if settings.use_custom_normals:
mesh.attributes.remove(mesh.attributes["temp_custom_normals"]) mesh.attributes.remove(mesh.attributes["temp_custom_normals"])
if not ok_smooth:
sharp_face = MESH_ATTRIBUTE_SHARP_FACE.get(attributes)
if sharp_face:
attributes.remove(sharp_face)
if settings.use_custom_props: if settings.use_custom_props:
blen_read_custom_properties(fbx_obj, mesh, settings) blen_read_custom_properties(fbx_obj, mesh, settings)