浏览代码

Filter out illegal chars in bone name

Jason0214 6 年之前
父节点
当前提交
58ddfd7dd2

+ 3 - 1
io_scene_godot/converters/animation.py

@@ -571,7 +571,9 @@ def export_transform_action(godot_node, animation_player,
             track_path = NodePath(
                 animation_player.parent.get_path(),
                 godot_node.get_path(),
-                blender_path_to_bone_name(object_path)
+                godot_node.find_bone_name(
+                    blender_path_to_bone_name(object_path)
+                ),
             )
 
             transform_mtx_list = [x.to_matrix() for x in frame_value_list]

+ 40 - 7
io_scene_godot/converters/armature.py

@@ -1,4 +1,5 @@
 """Export a armature node"""
+import collections
 import mathutils
 from ..structures import NodeTemplate, NodePath, Array
 
@@ -10,7 +11,9 @@ def export_bone_attachment(escn_file, node, parent_gd_node):
 
     # node.parent_bone is exactly the bone name
     # in the parent armature node
-    bone_attachment['bone_name'] = "\"{}\"".format(node.parent_bone)
+    bone_attachment['bone_name'] = "\"{}\"".format(
+        parent_gd_node.find_bone_name(node.parent_bone)
+    )
 
     # parent_gd_node is the SkeletonNode with the parent bone
     bone_id = parent_gd_node.find_bone_id(node.parent_bone)
@@ -87,21 +90,51 @@ def export_bone(pose_bone, bl_bones_to_export):
 
 class SkeletonNode(NodeTemplate):
     """tscn node with type Skeleton"""
+    BoneInfo = collections.namedtuple(
+        "boneInfo",
+        ('id', 'name'),
+    )
+
     def __init__(self, name, parent):
         super().__init__(name, "Skeleton", parent)
-        self.bone_name_to_id_map = dict()
+        # Mapping from blender bone name to godot bone id and name
+        self.bones = dict()
+
+    def find_bone_id(self, bl_bone_name):
+        """"Given blender bone name return the bone id in Skeleton node"""
+        if bl_bone_name not in self.bones:
+            return -1
+        return self.bones[bl_bone_name].id
 
-    def find_bone_id(self, bone_name):
-        """"Given bone name find the bone id in Skeleton node"""
-        return self.bone_name_to_id_map.get(bone_name, -1)
+    def find_bone_name(self, bl_bone_name):
+        """"Given blender bone name return the bone name in Skeleton node"""
+        if bl_bone_name not in self.bones:
+            return ""
+        return self.bones[bl_bone_name].name
 
     def add_bones(self, bone_list):
         """Add a list of bone to skeleton node"""
         # need first add all bones into name_to_id_map,
         # otherwise the parent bone finding would be incorrect
+        bone_name_set = set()
         for bone in bone_list:
-            bone.id = len(self.bone_name_to_id_map)
-            self.bone_name_to_id_map[bone.name] = bone.id
+            bone.id = len(self.bones)
+            bl_bone_name = bone.name
+
+            # filter illegal char from blender bone name
+            bone.name = bone.name.replace(":", "").replace("/", "")
+            # solve possible name conflict
+            iterations = 1
+            gd_bone_name = bone.name
+            while gd_bone_name in bone_name_set:
+                gd_bone_name = bone.name + str(iterations).zfill(3)
+                iterations += 1
+            bone.name = gd_bone_name
+
+            bone_name_set.add(bone.name)
+            self.bones[bl_bone_name] = SkeletonNode.BoneInfo(
+                bone.id, bone.name
+            )
 
         for bone in bone_list:
             bone_prefix = 'bones/{}'.format(bone.id)

+ 2 - 2
io_scene_godot/converters/mesh.py

@@ -140,10 +140,10 @@ class MeshResourceExporter:
     def init_mesh_bones_data(self, skeleton_node):
         """Find the mapping relation between vertex groups
         and bone id"""
-        for bone_name, bone_id in skeleton_node.bone_name_to_id_map.items():
+        for bone_name, bone_info in skeleton_node.bones.items():
             group = self.object.vertex_groups.get(bone_name)
             if group is not None:
-                self.vgroup_to_bone_mapping[group.index] = bone_id
+                self.vgroup_to_bone_mapping[group.index] = bone_info.id
 
     def export_mesh(self, escn_file, export_settings):
         """Saves a mesh into the escn file """

文件差异内容过多而无法显示
+ 10 - 0
tests/reference_exports/armature/armature_illegal_bone_name.escn


二进制
tests/test_scenes/armature/armature_illegal_bone_name.blend


部分文件因为文件数量过多而无法显示