[Bf-extensions-cvs] [72227fc1] master: glTF exporter: prevent infinite recursion when mesh is skinned and parenting to same bone

Julien Duroure noreply at git.blender.org
Tue May 12 18:44:38 CEST 2020


Commit: 72227fc13ba354695244a600b0d8b6a0b5d6f460
Author: Julien Duroure
Date:   Tue May 12 18:43:44 2020 +0200
Branches: master
https://developer.blender.org/rBA72227fc13ba354695244a600b0d8b6a0b5d6f460

glTF exporter: prevent infinite recursion when mesh is skinned and parenting to same bone

Avoid this by do not skin if object is parented to a bone of the armature that skin the object: keep only parenting to bone

===================================================================

M	io_scene_gltf2/__init__.py
M	io_scene_gltf2/blender/exp/gltf2_blender_extract.py
M	io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py

===================================================================

diff --git a/io_scene_gltf2/__init__.py b/io_scene_gltf2/__init__.py
index 50a313fb..2825fa3c 100755
--- a/io_scene_gltf2/__init__.py
+++ b/io_scene_gltf2/__init__.py
@@ -15,7 +15,7 @@
 bl_info = {
     'name': 'glTF 2.0 format',
     'author': 'Julien Duroure, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen, Jim Eckerlein, and many external contributors',
-    "version": (1, 3, 14),
+    "version": (1, 3, 15),
     'blender': (2, 90, 0),
     'location': 'File > Import-Export',
     'description': 'Import-Export as glTF 2.0',
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_extract.py b/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
index 35f31c50..e2d224ce 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
@@ -409,63 +409,70 @@ def extract_primitives(glTF, blender_mesh, library, blender_object, blender_vert
 
             bone_count = 0
 
-            if blender_vertex_groups is not None and vertex.groups is not None and len(vertex.groups) > 0 and export_settings[gltf2_blender_export_keys.SKINS]:
-                joint = []
-                weight = []
-                vertex_groups = vertex.groups
-                if not export_settings['gltf_all_vertex_influences']:
-                    # sort groups by weight descending
-                    vertex_groups = sorted(vertex.groups, key=attrgetter('weight'), reverse=True)
-                for group_element in vertex_groups:
-
-                    if len(joint) == 4:
-                        bone_count += 1
-                        joints.append(joint)
-                        weights.append(weight)
-                        joint = []
-                        weight = []
-
-                    #
-
-                    joint_weight = group_element.weight
-                    if joint_weight <= 0.0:
-                        continue
-
-                    #
-
-                    vertex_group_index = group_element.group
-
-                    if vertex_group_index < 0 or vertex_group_index >= len(blender_vertex_groups):
-                        continue
-                    vertex_group_name = blender_vertex_groups[vertex_group_index].name
+            # Skin must be ignored if the object is parented to a bone of the armature
+            # (This creates an infinite recursive error)
+            # So ignoring skin in that case
+            if blender_object and blender_object.parent_type == "BONE" and blender_object.parent.name == armature.name:
+                bone_max = 0 # joints & weights will be ignored in following code
+            else:
+                # Manage joints & weights
+                if blender_vertex_groups is not None and vertex.groups is not None and len(vertex.groups) > 0 and export_settings[gltf2_blender_export_keys.SKINS]:
+                    joint = []
+                    weight = []
+                    vertex_groups = vertex.groups
+                    if not export_settings['gltf_all_vertex_influences']:
+                        # sort groups by weight descending
+                        vertex_groups = sorted(vertex.groups, key=attrgetter('weight'), reverse=True)
+                    for group_element in vertex_groups:
+
+                        if len(joint) == 4:
+                            bone_count += 1
+                            joints.append(joint)
+                            weights.append(weight)
+                            joint = []
+                            weight = []
+
+                        #
+
+                        joint_weight = group_element.weight
+                        if joint_weight <= 0.0:
+                            continue
+
+                        #
+
+                        vertex_group_index = group_element.group
+
+                        if vertex_group_index < 0 or vertex_group_index >= len(blender_vertex_groups):
+                            continue
+                        vertex_group_name = blender_vertex_groups[vertex_group_index].name
+
+                        joint_index = None
+
+                        if armature:
+                            skin = gltf2_blender_gather_skins.gather_skin(armature, export_settings)
+                            for index, j in enumerate(skin.joints):
+                                if j.name == vertex_group_name:
+                                    joint_index = index
+                                    break
 
-                    joint_index = None
+                        #
+                        if joint_index is not None:
+                            joint.append(joint_index)
+                            weight.append(joint_weight)
 
-                    if armature:
-                        skin = gltf2_blender_gather_skins.gather_skin(armature, export_settings)
-                        for index, j in enumerate(skin.joints):
-                            if j.name == vertex_group_name:
-                                joint_index = index
-                                break
-
-                    #
-                    if joint_index is not None:
-                        joint.append(joint_index)
-                        weight.append(joint_weight)
-
-                if len(joint) > 0:
-                    bone_count += 1
+                    if len(joint) > 0:
+                        bone_count += 1
 
-                    for fill in range(0, 4 - len(joint)):
-                        joint.append(0)
-                        weight.append(0.0)
+                        for fill in range(0, 4 - len(joint)):
+                            joint.append(0)
+                            weight.append(0.0)
 
-                    joints.append(joint)
-                    weights.append(weight)
+                        joints.append(joint)
+                        weights.append(weight)
 
-            for fill in range(0, bone_max - bone_count):
-                joints.append([0, 0, 0, 0])
-                weights.append([0.0, 0.0, 0.0, 0.0])
+                for fill in range(0, bone_max - bone_count):
+                    joints.append([0, 0, 0, 0])
+                    weights.append([0.0, 0.0, 0.0, 0.0])
 
             #
 
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py
index 3b0fab2d..548c5299 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py
@@ -409,6 +409,15 @@ def __gather_skin(blender_object, export_settings):
     if not any(vertex.groups is not None and len(vertex.groups) > 0 for vertex in blender_mesh.vertices):
         return None
 
+    # Prevent infinite recursive error. A mesh can't have an Armature modifier
+    # and be bone parented to a bone of this armature
+    # In that case, ignore the armature modifier, keep only the bone parenting
+    if blender_object.parent is not None \
+    and blender_object.parent_type == 'BONE' \
+    and blender_object.parent.name == modifiers["ARMATURE"].object.name:
+
+        return None
+
     # Skins and meshes must be in the same glTF node, which is different from how blender handles armatures
     return gltf2_blender_gather_skins.gather_skin(modifiers["ARMATURE"].object, export_settings)



More information about the Bf-extensions-cvs mailing list