From 0bd1fbc731cb21ba92262e2fff48ff49a21c3aa3 Mon Sep 17 00:00:00 2001 From: Julien Duroure Date: Tue, 17 Jun 2025 12:45:53 +0200 Subject: [PATCH] glTF exporter: Variant: Sanity checks to avoid bad duplicate exports --- scripts/addons_core/io_scene_gltf2/__init__.py | 2 +- .../io_scene_gltf2/blender/com/gltf2_blender_ui.py | 13 +++++++++++-- .../io_scene_gltf2/blender/exp/primitives.py | 12 ++++++++++++ 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/scripts/addons_core/io_scene_gltf2/__init__.py b/scripts/addons_core/io_scene_gltf2/__init__.py index 83070ddafff..f952c720434 100755 --- a/scripts/addons_core/io_scene_gltf2/__init__.py +++ b/scripts/addons_core/io_scene_gltf2/__init__.py @@ -5,7 +5,7 @@ bl_info = { 'name': 'glTF 2.0 format', 'author': 'Julien Duroure, Scurest, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen, Jim Eckerlein, and many external contributors', - "version": (4, 5, 41), + "version": (4, 5, 42), 'blender': (4, 4, 0), 'location': 'File > Import-Export', 'description': 'Import-Export as glTF 2.0', diff --git a/scripts/addons_core/io_scene_gltf2/blender/com/gltf2_blender_ui.py b/scripts/addons_core/io_scene_gltf2/blender/com/gltf2_blender_ui.py index 67d6d9c41b1..41300447947 100644 --- a/scripts/addons_core/io_scene_gltf2/blender/com/gltf2_blender_ui.py +++ b/scripts/addons_core/io_scene_gltf2/blender/com/gltf2_blender_ui.py @@ -212,18 +212,27 @@ class SCENE_OT_gltf2_assign_to_variant(bpy.types.Operator): for mat_slot_idx, s in enumerate(obj.material_slots): # Check if there is already data for this slot found = False + variant_found = False for i in obj.data.gltf2_variant_mesh_data: if i.material_slot_index == mat_slot_idx and i.material == s.material: found = True variant_primitive = i + elif i.material_slot_index == mat_slot_idx and bpy.data.scenes[0].gltf2_active_variant in [ + v.variant.variant_idx for v in i.variants]: + # User changed the material, so store the new one (replace instead of add) + found = True + variant_found = True + variant_primitive = i + i.material = s.material if found is False: variant_primitive = obj.data.gltf2_variant_mesh_data.add() variant_primitive.material_slot_index = mat_slot_idx variant_primitive.material = s.material - vari = variant_primitive.variants.add() - vari.variant.variant_idx = bpy.data.scenes[0].gltf2_active_variant + if variant_found is False: + vari = variant_primitive.variants.add() + vari.variant.variant_idx = bpy.data.scenes[0].gltf2_active_variant return {'FINISHED'} diff --git a/scripts/addons_core/io_scene_gltf2/blender/exp/primitives.py b/scripts/addons_core/io_scene_gltf2/blender/exp/primitives.py index a7bf2181b64..0c44dbc5a0d 100644 --- a/scripts/addons_core/io_scene_gltf2/blender/exp/primitives.py +++ b/scripts/addons_core/io_scene_gltf2/blender/exp/primitives.py @@ -304,14 +304,26 @@ def __gather_extensions(blender_mesh, # Material idx is the slot idx. Retrieve associated variant, if any mapping = [] + variants_idx_in_use = [] for i in [v for v in blender_mesh.gltf2_variant_mesh_data if v.material_slot_index == material_idx]: variants = [] for idx, v in enumerate(i.variants): if v.variant.variant_idx in [o.variant.variant_idx for o in i.variants[:idx]]: # Avoid duplicates continue + + # Avoid duplicates from a previous variant (in mapping list) + # This happen only before fix of #2542 + if v.variant.variant_idx in variants_idx_in_use: + # Avoid duplicates + export_settings['log'].warning( + 'Variant ' + str(v.variant.variant_idx) + + ' has 2 differents materials for a single slot. Skipping it.') + continue + vari = ext_variants.gather_variant(v.variant.variant_idx, export_settings) if vari is not None: + variants_idx_in_use.append(v.variant.variant_idx) variant_extension = gltf2_io_extensions.ChildOfRootExtension( name="KHR_materials_variants", path=["variants"],