Fix for bug #21. Bone names can now only contain alphanumeric, space and underscore characters.

This commit is contained in:
Colin Basnett
2022-05-20 17:13:12 -07:00
parent a1bbf4fb1e
commit edafa1cfd7
3 changed files with 18 additions and 3 deletions

View File

@@ -1,5 +1,6 @@
import datetime import datetime
from collections import Counter from collections import Counter
import re
from typing import List, Iterable from typing import List, Iterable
from bpy.types import NlaStrip, Object from bpy.types import NlaStrip, Object
@@ -103,6 +104,14 @@ def get_psa_sequence_name(action, should_use_original_sequence_name):
return action.name return action.name
def check_bone_names(bone_names: Iterable[str]):
pattern = re.compile(r'^[a-zA-Z0-9_ ]+$')
invalid_bone_names = [x for x in bone_names if pattern.match(x) is None]
if len(invalid_bone_names) > 0:
raise RuntimeError(f'The following bone names are invalid: {invalid_bone_names}.\n'
f'Bone names must only contain letters, numbers, spaces, and underscores.')
def get_export_bone_names(armature_object, bone_filter_mode, bone_group_indices: List[int]) -> List[str]: def get_export_bone_names(armature_object, bone_filter_mode, bone_group_indices: List[int]) -> List[str]:
""" """
Returns a sorted list of bone indices that should be exported for the given bone filter mode and bone groups. Returns a sorted list of bone indices that should be exported for the given bone filter mode and bone groups.

View File

@@ -69,7 +69,7 @@ class PsaBuilder(object):
bones = list(armature.data.bones) bones = list(armature.data.bones)
# The order of the armature bones and the pose bones is not guaranteed to be the same. # The order of the armature bones and the pose bones is not guaranteed to be the same.
# As as a result, we need to reconstruct the list of pose bones in the same order as the # As a result, we need to reconstruct the list of pose bones in the same order as the
# armature bones. # armature bones.
bone_names = [x.name for x in bones] bone_names = [x.name for x in bones]
pose_bones = [(bone_names.index(bone.name), bone) for bone in armature.pose.bones] pose_bones = [(bone_names.index(bone.name), bone) for bone in armature.pose.bones]
@@ -88,10 +88,13 @@ class PsaBuilder(object):
if len(bones) == 0: if len(bones) == 0:
raise RuntimeError('No bones available for export') raise RuntimeError('No bones available for export')
# Check that all bone names are valid.
check_bone_names(map(lambda bone: bone.name, bones))
# Build list of PSA bones. # Build list of PSA bones.
for bone in bones: for bone in bones:
psa_bone = Psa.Bone() psa_bone = Psa.Bone()
psa_bone.name = bytes(bone.name, encoding='utf-8') psa_bone.name = bytes(bone.name, encoding='windows-1252')
try: try:
parent_index = bones.index(bone.parent) parent_index = bones.index(bone.parent)

View File

@@ -83,6 +83,9 @@ class PskBuilder(object):
bone_names = get_export_bone_names(armature_object, options.bone_filter_mode, options.bone_group_indices) bone_names = get_export_bone_names(armature_object, options.bone_filter_mode, options.bone_group_indices)
bones = [armature_object.data.bones[bone_name] for bone_name in bone_names] bones = [armature_object.data.bones[bone_name] for bone_name in bone_names]
# Check that all bone names are valid.
check_bone_names(map(lambda x: x.name, bones))
for bone in bones: for bone in bones:
psk_bone = Psk.Bone() psk_bone = Psk.Bone()
psk_bone.name = bytes(bone.name, encoding='windows-1252') psk_bone.name = bytes(bone.name, encoding='windows-1252')
@@ -134,7 +137,7 @@ class PskBuilder(object):
else: else:
# New material. # New material.
psk_material = Psk.Material() psk_material = Psk.Material()
psk_material.name = bytes(material.name, encoding='utf-8') psk_material.name = bytes(material.name, encoding='windows-1252')
psk_material.texture_index = len(psk.materials) psk_material.texture_index = len(psk.materials)
psk.materials.append(psk_material) psk.materials.append(psk_material)
materials[material.name] = material materials[material.name] = material