Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulien Duroure <julien.duroure@gmail.com>2020-05-12 19:43:44 +0300
committerJulien Duroure <julien.duroure@gmail.com>2020-05-12 19:43:44 +0300
commit72227fc13ba354695244a600b0d8b6a0b5d6f460 (patch)
treeb15de779585b5a38e539b876a1b8831054f0ea5c
parent64d34396670d825f03131903ef6cef4332adf653 (diff)
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
-rwxr-xr-xio_scene_gltf2/__init__.py2
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_extract.py111
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py9
3 files changed, 69 insertions, 53 deletions
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)