Fix #104714: Missing shape keys in FBX export when original mesh data cannot be used #104890

Merged
Thomas Barlow merged 7 commits from Mysteryem/blender-addons:fbx_fix_triangulate_removing_shapes into main 2023-09-19 02:26:19 +02:00
Showing only changes of commit 733598d5c1 - Show all commits

View File

@ -2594,14 +2594,13 @@ def fbx_data_from_scene(scene, depsgraph, settings):
# If modifiers has been altered need to update dependency graph. # If modifiers has been altered need to update dependency graph.
if backup_pose_positions or tmp_mods: if backup_pose_positions or tmp_mods:
depsgraph.update() depsgraph.update()
if settings.use_mesh_modifiers: if settings.use_mesh_modifiers or ob.type in BLENDER_OTHER_OBJECT_TYPES:
ob_to_convert = ob.evaluated_get(depsgraph) ob_to_convert = ob.evaluated_get(depsgraph)
# NOTE: The dependency graph might be re-evaluating multiple times, which could # NOTE: The dependency graph might be re-evaluating multiple times, which could
# potentially free the mesh created early on. So we put those meshes to bmain and # potentially free the mesh created early on. So we put those meshes to bmain and
# free them afterwards. Not ideal but ensures correct ownerwhip. # free them afterwards. Not ideal but ensures correct ownerwhip.
tmp_me = bpy.data.meshes.new_from_object( tmp_me = bpy.data.meshes.new_from_object(
ob_to_convert, preserve_all_data_layers=True, depsgraph=depsgraph) ob_to_convert, preserve_all_data_layers=True, depsgraph=depsgraph)
free = True
# Usually the materials of the evaluated object will be the same, but modifiers, such as Geometry # Usually the materials of the evaluated object will be the same, but modifiers, such as Geometry
# Nodes, can change the materials. # Nodes, can change the materials.
@ -2612,11 +2611,9 @@ def fbx_data_from_scene(scene, depsgraph, settings):
# Override the default behaviour of getting materials from ob_obj.bdata.material_slots. # Override the default behaviour of getting materials from ob_obj.bdata.material_slots.
ob_obj.override_materials = eval_mats ob_obj.override_materials = eval_mats
else: else:
# Creates a temporary mesh owned by the Object without adding it to bpy.data.meshes. Most # bpy.data.meshes.new_from_object always removes shape keys (see #104714), so create a copy of the
# importantly, compared to bpy.data.meshes.new_from_object, it does not remove shape keys from the # mesh instead.
# new mesh. We'll forcefully free these temporary meshes at the end of the export. tmp_me = ob.data.copy()
tmp_me = ob.to_mesh(preserve_all_data_layers=True, depsgraph=depsgraph)
free = False
# Triangulate the mesh if requested # Triangulate the mesh if requested
if settings.use_triangles: if settings.use_triangles:
@ -2627,7 +2624,7 @@ def fbx_data_from_scene(scene, depsgraph, settings):
bm.to_mesh(tmp_me) bm.to_mesh(tmp_me)
bm.free() bm.free()
data_meshes[ob_obj] = (get_blenderID_key(tmp_me), tmp_me, free) data_meshes[ob_obj] = (get_blenderID_key(tmp_me), tmp_me, True)
# Change armatures back. # Change armatures back.
for armature, pose_position in backup_pose_positions: for armature, pose_position in backup_pose_positions:
print((armature, pose_position)) print((armature, pose_position))
@ -3018,10 +3015,7 @@ def fbx_scene_data_cleanup(scene_data):
""" """
# Delete temp meshes. # Delete temp meshes.
done_meshes = set() done_meshes = set()
for ob_obj, (me_key, me, free) in scene_data.data_meshes.items(): for me_key, me, free in scene_data.data_meshes.values():
# Clear temporary meshes created by Object.to_mesh().
ob_obj.bdata.to_mesh_clear()
# Clear temporary meshes created when applying modifiers.
if free and me_key not in done_meshes: if free and me_key not in done_meshes:
bpy.data.meshes.remove(me) bpy.data.meshes.remove(me)
done_meshes.add(me_key) done_meshes.add(me_key)