From 8ed98d592e027356cee010172789e1eecaa613ce Mon Sep 17 00:00:00 2001 From: Thomas Barlow Date: Mon, 2 Dec 2024 10:44:00 +0100 Subject: [PATCH] Fix #127765: FBX Export: Incorrect materials with Geometry Nodes Geometry Nodes can change the materials of the Object, for Mesh Objects, the new materials are present in the evaluated Object, but for non-Mesh Objects, the new materials may not be present until the evaluated Object has been converted to a Mesh. This patch fixes the materials in FBX export, with Apply Modifiers enabled, of non-Mesh types with Geometry Nodes that change materials. Rather than getting the materials from the evaluated Object, the materials are now retrieved from the Mesh created from the evaluated Object. To support object-linked material slots, the materials on the new Mesh are replaced at the same indices as the object-linked material slots. Pull Request: https://projects.blender.org/blender/blender/pulls/130485 --- scripts/addons_core/io_scene_fbx/__init__.py | 2 +- .../addons_core/io_scene_fbx/export_fbx_bin.py | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/scripts/addons_core/io_scene_fbx/__init__.py b/scripts/addons_core/io_scene_fbx/__init__.py index 8f195a4175d..bb36400aa91 100644 --- a/scripts/addons_core/io_scene_fbx/__init__.py +++ b/scripts/addons_core/io_scene_fbx/__init__.py @@ -5,7 +5,7 @@ bl_info = { "name": "FBX format", "author": "Campbell Barton, Bastien Montagne, Jens Restemeier, @Mysteryem", - "version": (5, 12, 5), + "version": (5, 12, 6), "blender": (4, 2, 0), "location": "File > Import-Export", "description": "FBX IO meshes, UVs, vertex colors, materials, textures, cameras, lamps and actions", diff --git a/scripts/addons_core/io_scene_fbx/export_fbx_bin.py b/scripts/addons_core/io_scene_fbx/export_fbx_bin.py index 04749b199f3..cfa8c371f46 100644 --- a/scripts/addons_core/io_scene_fbx/export_fbx_bin.py +++ b/scripts/addons_core/io_scene_fbx/export_fbx_bin.py @@ -2681,17 +2681,23 @@ def fbx_data_from_scene(scene, depsgraph, settings): # 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 # free them afterwards. Not ideal but ensures correct ownership. + # This also converts non-mesh Objects to Mesh data. tmp_me = bpy.data.meshes.new_from_object( ob_to_convert, preserve_all_data_layers=True, depsgraph=depsgraph) - # Usually the materials of the evaluated object will be the same, but modifiers, such as Geometry Nodes, - # can change the materials. - orig_mats = tuple(slot.material for slot in ob.material_slots) - eval_mats = tuple(slot.material.original if slot.material else None - for slot in ob_to_convert.material_slots) + # Usually the materials of the evaluated Object converted to a Mesh will be the same as the original + # Object, but modifiers, such as Geometry Nodes, can change the materials. + orig_mats = [slot.material for slot in ob.material_slots] + eval_mats = list(tmp_me.materials) if orig_mats != eval_mats: + # An object-linked material slot replaces the material on the data at the slot's index. If applying + # modifiers changes the materials on the data, the object-linked material slot will replace the new + # material at the same index as before. + for i, slot in zip(range(len(eval_mats)), ob.material_slots): + if slot.link == 'OBJECT': + eval_mats[i] = slot.material # Override the default behavior of getting materials from `ob_obj.bdata.material_slots`. - ob_obj.override_materials = eval_mats + ob_obj.override_materials = tuple(eval_mats) elif do_convert: tmp_me = bpy.data.meshes.new_from_object(ob, preserve_all_data_layers=True, depsgraph=depsgraph) elif do_copy: