From b5a42a499abea18f6a0e9eeff852bf5b1c86b37b Mon Sep 17 00:00:00 2001 From: Thomas Barlow Date: Wed, 5 Jul 2023 14:45:24 +0100 Subject: [PATCH] Fix #104737: FBX: Materials missing from linked duplicates Exporting meshes with duplicate materials combines them into a single material slot (Material->Model connection) when exporting as FBX because the material indices dict is keyed by materials. This resulted in unused duplicate material slots being included in the export. [1] removed these unused duplicate material slots, however, because the materials for each object are keyed by the object's mesh, this meant that linked duplicates sharing the same mesh (aside from the first linked duplicate processed) would not get any material slots because their materials would already be present in their mesh's dict that mapped from materials to material indices. Without larger changes to how materials and material slots are exported, it is not currently possible to simultaneously remove the unused duplicate material slots and support linked duplicates. The code for exporting materials and material slots needs some redesigning anyway so that linked duplicates with differing materials are actually exported as linked duplicates instead of duplicating their meshes on export, but this would be more of a target for 4.0. As noted in [1], reverting [0] was also an option, so this patch does as noted and reverts the functional changes of [0], but keeps the comment because it's still relevant. This patch changes the export of meshes containing duplicate materials to export unused duplicate material slots as they did before [1]. Note that because of [2], these unused duplicate material slots are visible to users when importing the .fbx back into Blender, just like any meshes with duplicate materials exported as .fbx by Blender 3.5 and earlier. [0]: 5c9ecad1d29edd8ba9ebaaad8f71839bd5d88324 [1]: 0a4e4f27043ce86c8eb885d8534cab5df30e8b54 [2]: 80db34b208f7a575aa86b06cfc8ee98cb11a1280 --- io_scene_fbx/export_fbx_bin.py | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/io_scene_fbx/export_fbx_bin.py b/io_scene_fbx/export_fbx_bin.py index 5d74c2886..65fc83b98 100644 --- a/io_scene_fbx/export_fbx_bin.py +++ b/io_scene_fbx/export_fbx_bin.py @@ -2929,25 +2929,20 @@ def fbx_data_from_scene(scene, depsgraph, settings): _objs_indices = {} for ma, (ma_key, ob_objs) in data_materials.items(): for ob_obj in ob_objs: + connections.append((b"OO", get_fbx_uuid_from_key(ma_key), ob_obj.fbx_uuid, None)) # Get index of this material for this object (or dupliobject). # Material indices for mesh faces are determined by their order in 'ma to ob' connections. # Only materials for meshes currently... # Note in case of dupliobjects a same me/ma idx will be generated several times... # Should not be an issue in practice, and it's needed in case we export duplis but not the original! if ob_obj.type not in BLENDER_OBJECT_TYPES_MESHLIKE: - connections.append((b"OO", get_fbx_uuid_from_key(ma_key), ob_obj.fbx_uuid, None)) continue _mesh_key, me, _free = data_meshes[ob_obj] - material_indices = mesh_material_indices.setdefault(me, {}) - if ma in material_indices: - # Material has already been found for this mesh. - # XXX If a mesh has multiple material slots with the same material, they are combined into one slot. - # Even if duplicate materials were exported without combining them into one slot, keeping duplicate - # materials separated does not appear to be common behaviour of external software when importing FBX. - continue - connections.append((b"OO", get_fbx_uuid_from_key(ma_key), ob_obj.fbx_uuid, None)) idx = _objs_indices[ob_obj] = _objs_indices.get(ob_obj, -1) + 1 - material_indices[ma] = idx + # XXX If a mesh has multiple material slots with the same material, they are combined into one slot. + # Even if duplicate materials were exported without combining them into one slot, keeping duplicate + # materials separated does not appear to be common behaviour of external software when importing FBX. + mesh_material_indices.setdefault(me, {})[ma] = idx del _objs_indices # Textures -- 2.30.2