From 74c348111b2bdbfd76fee18f266cfd5df32b2b5f Mon Sep 17 00:00:00 2001 From: Julien Duroure Date: Sun, 18 Aug 2024 14:43:57 +0200 Subject: [PATCH 1/3] Fix #2321 Export SK when apply modifiers with only Armature modifier --- .../blender/exp/gltf2_blender_gather_primitives_extract.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitives_extract.py b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitives_extract.py index 84d8454ad..fd64f0355 100644 --- a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitives_extract.py +++ b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitives_extract.py @@ -138,7 +138,10 @@ def prepare_data(self): # even if we apply modifiers # (For classic objects, shape keys are not preserved if we apply modifiers) # We can check it by checking if the mesh is used by a user - if self.blender_mesh.shape_keys and self.export_settings['gltf_morph'] and self.blender_mesh.users != 0: + # But ... in case we apply modifiers with only armature, the mesh is not used by a user + # But SK are still there + if self.blender_mesh.shape_keys and self.export_settings['gltf_morph'] and \ + (self.blender_mesh.users != 0 or ( self.armature is not None and self.blender_mesh.users == 0)): self.key_blocks = get_sk_exported(self.blender_mesh.shape_keys.key_blocks) # Fetch vert positions and bone data (joint,weights) From 9e3282d4418b280a1815a0d044f01abaf2ac5588 Mon Sep 17 00:00:00 2001 From: Julien Duroure Date: Thu, 12 Sep 2024 16:05:06 +0200 Subject: [PATCH 2/3] Better check of GN SK --- addons/io_scene_gltf2/blender/com/extras.py | 2 +- addons/io_scene_gltf2/blender/exp/mesh.py | 4 ++-- addons/io_scene_gltf2/blender/exp/nodes.py | 2 ++ addons/io_scene_gltf2/blender/exp/primitive_extract.py | 6 +----- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/addons/io_scene_gltf2/blender/com/extras.py b/addons/io_scene_gltf2/blender/com/extras.py index 8a952f9be..77b1e3ec2 100644 --- a/addons/io_scene_gltf2/blender/com/extras.py +++ b/addons/io_scene_gltf2/blender/com/extras.py @@ -18,7 +18,7 @@ # Custom properties, which are in most cases present and should not be imported/exported. -BLACK_LIST = ['cycles', 'cycles_visibility', 'cycles_curves', 'glTF2ExportSettings'] +BLACK_LIST = ['cycles', 'cycles_visibility', 'cycles_curves', 'glTF2ExportSettings', 'gltf2_mesh_applied'] def generate_extras(blender_element): diff --git a/addons/io_scene_gltf2/blender/exp/mesh.py b/addons/io_scene_gltf2/blender/exp/mesh.py index 8e67aea0f..fa973b163 100644 --- a/addons/io_scene_gltf2/blender/exp/mesh.py +++ b/addons/io_scene_gltf2/blender/exp/mesh.py @@ -116,7 +116,7 @@ def __gather_extras(blender_mesh: bpy.types.Mesh, extras = generate_extras(blender_mesh) or {} # Not for GN Instances - if export_settings['gltf_morph'] and blender_mesh.shape_keys and blender_mesh.users != 0: + if export_settings['gltf_morph'] and blender_mesh.shape_keys and ((blender_mesh.is_evaluated is True and blender_mesh.get('gltf2_mesh_applied') is not None) or blender_mesh.is_evaluated is False): morph_max = len(blender_mesh.shape_keys.key_blocks) - 1 if morph_max > 0: extras['targetNames'] = [k.name for k in get_sk_exported(blender_mesh.shape_keys.key_blocks)] @@ -159,7 +159,7 @@ def __gather_weights(blender_mesh: bpy.types.Mesh, return None # Not for GN Instances - if blender_mesh.users == 0: + if blender_mesh.is_evaluated is True and blender_mesh.get('gltf2_mesh_applied'): return None morph_max = len(blender_mesh.shape_keys.key_blocks) - 1 diff --git a/addons/io_scene_gltf2/blender/exp/nodes.py b/addons/io_scene_gltf2/blender/exp/nodes.py index 4341033c3..90d8e089d 100644 --- a/addons/io_scene_gltf2/blender/exp/nodes.py +++ b/addons/io_scene_gltf2/blender/exp/nodes.py @@ -305,6 +305,8 @@ def __gather_mesh(vnode, blender_object, export_settings): blender_mesh = blender_mesh_owner.to_mesh(preserve_all_data_layers=True, depsgraph=depsgraph) for prop in [p for p in blender_object.data.keys() if p not in BLACK_LIST]: blender_mesh[prop] = blender_object.data[prop] + # Store that this evaluated mesh has been created by the exporter, and is not a GN instance mesh + blender_mesh['gltf2_mesh_applied'] = True if export_settings['gltf_skins']: # restore Armature modifiers diff --git a/addons/io_scene_gltf2/blender/exp/primitive_extract.py b/addons/io_scene_gltf2/blender/exp/primitive_extract.py index 9deb44b85..b9344ac84 100644 --- a/addons/io_scene_gltf2/blender/exp/primitive_extract.py +++ b/addons/io_scene_gltf2/blender/exp/primitive_extract.py @@ -137,11 +137,7 @@ def prepare_data(self): # We need to check if we are in a GN Instance, because for GN instances, it seems that shape keys are preserved, # even if we apply modifiers # (For classic objects, shape keys are not preserved if we apply modifiers) - # We can check it by checking if the mesh is used by a user - # But ... in case we apply modifiers with only armature, the mesh is not used by a user - # But SK are still there - if self.blender_mesh.shape_keys and self.export_settings['gltf_morph'] and \ - (self.blender_mesh.users != 0 or ( self.armature is not None and self.blender_mesh.users == 0)): + if self.blender_mesh.shape_keys and self.export_settings['gltf_morph'] and ((self.blender_mesh.is_evaluated is True and self.blender_mesh.get('gltf2_mesh_applied') is not None) or self.blender_mesh.is_evaluated is False): self.key_blocks = get_sk_exported(self.blender_mesh.shape_keys.key_blocks) # Fetch vert positions and bone data (joint,weights) From 56679d30016216076973ae07a06632ef3fd82b5b Mon Sep 17 00:00:00 2001 From: Julien Duroure Date: Thu, 12 Sep 2024 16:09:00 +0200 Subject: [PATCH 3/3] Fix check --- addons/io_scene_gltf2/blender/exp/mesh.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/io_scene_gltf2/blender/exp/mesh.py b/addons/io_scene_gltf2/blender/exp/mesh.py index fa973b163..8f39fd3b5 100644 --- a/addons/io_scene_gltf2/blender/exp/mesh.py +++ b/addons/io_scene_gltf2/blender/exp/mesh.py @@ -159,7 +159,7 @@ def __gather_weights(blender_mesh: bpy.types.Mesh, return None # Not for GN Instances - if blender_mesh.is_evaluated is True and blender_mesh.get('gltf2_mesh_applied'): + if blender_mesh.is_evaluated is True and blender_mesh.get('gltf2_mesh_applied') is None: return None morph_max = len(blender_mesh.shape_keys.key_blocks) - 1