Merge pull request #146 from 989onan/patch-1
Create centralized method for identifying bones
This commit is contained in:
@@ -18,6 +18,7 @@ from bpy.utils import register_class
|
||||
from ..core.logging_setup import logger
|
||||
from ..core.translations import t
|
||||
from ..core.dictionaries import bone_names
|
||||
from .dictionaries import reverse_bone_lookup, bone_names
|
||||
|
||||
class SceneMatClass(PropertyGroup):
|
||||
mat: PointerProperty(type=Material)
|
||||
@@ -386,6 +387,19 @@ def simplify_bonename(name: str) -> str:
|
||||
"""Simplify bone name by removing spaces, underscores, dots and converting to lowercase"""
|
||||
return name.lower().translate(dict.fromkeys(map(ord, u" _.")))
|
||||
|
||||
|
||||
def identify_bones(arm_data: bpy.types.Armature, context: bpy.types.Context) -> Dict[str,str]:
|
||||
"""Identify bone names in an armature based on our reverse dictionary, so there is no confusion to what a bone is.
|
||||
Essentially makes a dictionary of keys from dictionaries.bone_names like "hips", and the corosponding value is the bone that can be mapped to that key."""
|
||||
returned: Dict[str,str] = {}
|
||||
for bone in arm_data.bones:
|
||||
|
||||
simplified_name = simplify_bonename(bone.name)
|
||||
|
||||
if simplified_name in reverse_bone_lookup:
|
||||
returned[reverse_bone_lookup[simplified_name]] = bone.name
|
||||
return returned
|
||||
|
||||
def duplicate_bone_chain(bones: List[EditBone]) -> List[EditBone]:
|
||||
"""Duplicate a chain of bones while preserving hierarchy"""
|
||||
new_bones: List[EditBone] = []
|
||||
|
||||
+35
-18
@@ -1,9 +1,12 @@
|
||||
# GPL Licence
|
||||
|
||||
|
||||
# Bone names from https://github.com/triazo/immersive_scaler/
|
||||
# Note from @989onan: Please make sure to make your names are lowercase in this array. I banged my head metaphorically till I figured that out...
|
||||
# Note from @989onan: Please make sure to make your names are lowercase in this array, or it will never find a match. I banged my head metaphorically till I figured that out...
|
||||
# Note2: Remove all "_", ".", and " " (space) from your values array or it will also not ever find a match!!!!
|
||||
# Taken from Tuxedo/Cats
|
||||
|
||||
from .common import simplify_bonename
|
||||
|
||||
bone_names = {
|
||||
# Right side bones
|
||||
"right_shoulder": [
|
||||
@@ -254,26 +257,26 @@ bone_names = {
|
||||
|
||||
# Add VRM bone name variations
|
||||
bone_names.update({
|
||||
'hips': bone_names['hips'] + ['j_bip_c_hips', 'j_hips', 'vrm_hips'],
|
||||
'spine': bone_names['spine'] + ['j_bip_c_spine', 'j_spine', 'vrm_spine'],
|
||||
'chest': bone_names['chest'] + ['j_bip_c_chest', 'j_chest', 'vrm_chest'],
|
||||
'upper_chest': bone_names['upper_chest'] + ['j_bip_c_upper_chest', 'j_upper_chest', 'vrm_upperchest'],
|
||||
'neck': bone_names['neck'] + ['j_bip_c_neck', 'j_neck', 'vrm_neck'],
|
||||
'head': bone_names['head'] + ['j_bip_c_head', 'j_head', 'vrm_head'],
|
||||
'hips': bone_names['hips'] + ['jbipchips', 'jhips', 'vrmhips'],
|
||||
'spine': bone_names['spine'] + ['jbipcspine', 'jspine', 'vrmspine'],
|
||||
'chest': bone_names['chest'] + ['jbipcchest', 'jchest', 'vrmchest'],
|
||||
'upper_chest': bone_names['upperchest'] + ['jbipcupperchest', 'jupperchest', 'vrmupperchest'],
|
||||
'neck': bone_names['neck'] + ['jbipcneck', 'jneck', 'vrmneck'],
|
||||
'head': bone_names['head'] + ['jbipchead', 'jhead', 'vrmhead'],
|
||||
|
||||
# VRM specific finger naming
|
||||
'thumb_0_l': bone_names['thumb_0_l'] + ['thumb_metacarpal_l', 'j_thumb1_l'],
|
||||
'index_0_l': bone_names['index_0_l'] + ['index_metacarpal_l', 'j_index1_l'],
|
||||
'middle_0_l': bone_names['middle_0_l'] + ['middle_metacarpal_l', 'j_middle1_l'],
|
||||
'ring_0_l': bone_names['ring_0_l'] + ['ring_metacarpal_l', 'j_ring1_l'],
|
||||
'pinkie_0_l': bone_names['pinkie_0_l'] + ['little_metacarpal_l', 'j_little1_l'],
|
||||
'thumb_0_l': bone_names['thumb_0_l'] + ['thumbmetacarpall', 'jthumb1l'],
|
||||
'index_0_l': bone_names['index_0_l'] + ['indexmetacarpall', 'jindex1l'],
|
||||
'middle_0_l': bone_names['middle_0_l'] + ['middlemetacarpall', 'jmiddle1l'],
|
||||
'ring_0_l': bone_names['ring_0_l'] + ['ringmetacarpall', 'jring1l'],
|
||||
'pinkie_0_l': bone_names['pinkie_0_l'] + ['littlemetacarpall', 'jlittle1l'],
|
||||
|
||||
# Mirror for right side
|
||||
'thumb_0_r': bone_names['thumb_0_r'] + ['thumb_metacarpal_r', 'j_thumb1_r'],
|
||||
'index_0_r': bone_names['index_0_r'] + ['index_metacarpal_r', 'j_index1_r'],
|
||||
'middle_0_r': bone_names['middle_0_r'] + ['middle_metacarpal_r', 'j_middle1_r'],
|
||||
'ring_0_r': bone_names['ring_0_r'] + ['ring_metacarpal_r', 'j_ring1_r'],
|
||||
'pinkie_0_r': bone_names['pinkie_0_r'] + ['little_metacarpal_r', 'j_little1_r']
|
||||
'thumb_0_r': bone_names['thumb_0_r'] + ['thumbmetacarpalr', 'jthumb1r'],
|
||||
'index_0_r': bone_names['index_0_r'] + ['indexmetacarpalr', 'jindex1r'],
|
||||
'middle_0_r': bone_names['middle_0_r'] + ['middlemetacarpalr', 'jmiddle1r'],
|
||||
'ring_0_r': bone_names['ring_0_r'] + ['ringmetacarpalr', 'jring1r'],
|
||||
'pinkie_0_r': bone_names['pinkie_0_r'] + ['littlemetacarpalr', 'jlittle1r']
|
||||
})
|
||||
|
||||
# array taken from cats
|
||||
@@ -355,6 +358,8 @@ resonite_translations = {
|
||||
'thumb_3_r': "thumb3.R"
|
||||
}
|
||||
|
||||
|
||||
|
||||
standard_bones = {
|
||||
# Core Structure
|
||||
'hips': 'Hips',
|
||||
@@ -941,3 +946,15 @@ for category, mappings in non_standard_mappings.items():
|
||||
bone_names[category].extend(mappings)
|
||||
else:
|
||||
bone_names[category] = mappings
|
||||
|
||||
|
||||
# Since data set is very poisoned by bone names that aren't simplified (And as such will not map properly using the function) we will just force convert them to the proper format at the end here. - @989onan
|
||||
for standard, mappings in bone_names:
|
||||
for i in len(mappings):
|
||||
bone_names[standard][i] = simplify_bonename(mappings[i])
|
||||
|
||||
# Create reverse lookup dictionary (conversion/translation)
|
||||
reverse_bone_lookup = {}
|
||||
for preferred_name, name_list in bone_names.items():
|
||||
for name in name_list:
|
||||
reverse_bone_lookup[name] = preferred_name
|
||||
|
||||
+11
-19
@@ -3,15 +3,16 @@ import bpy
|
||||
import bpy_extras
|
||||
from numpy import double
|
||||
from typing import Set, Dict
|
||||
import re
|
||||
|
||||
from .common import get_active_armature, simplify_bonename, ProgressTracker
|
||||
from .common import get_active_armature, simplify_bonename, validate_armature, ProgressTracker, identify_bones
|
||||
from bpy.types import Context, Operator
|
||||
from ..core.translations import t
|
||||
from ..core.dictionaries import bone_names, resonite_translations
|
||||
from ..core.logging_setup import logger
|
||||
from ..core.armature_validation import validate_armature
|
||||
|
||||
import re
|
||||
|
||||
from .resonite_loader import resonite_animx, resonite_types
|
||||
import os
|
||||
|
||||
@@ -65,30 +66,21 @@ class AvatarToolkit_OT_ConvertResonite(Operator):
|
||||
untranslated_bones: Set[str] = set()
|
||||
simplified_names: Dict[str, str] = {}
|
||||
|
||||
# Create reverse lookup dictionary
|
||||
reverse_bone_lookup = {}
|
||||
for preferred_name, name_list in bone_names.items():
|
||||
for name in name_list:
|
||||
reverse_bone_lookup[name] = preferred_name
|
||||
|
||||
try:
|
||||
context.view_layer.objects.active = armature
|
||||
bpy.ops.object.mode_set(mode='EDIT')
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
arm_data: bpy.types.Armature = armature.data
|
||||
# Cache simplified bone names
|
||||
for bone in armature.data.bones:
|
||||
simplified_names[bone.name] = simplify_bonename(bone.name)
|
||||
|
||||
total_bones = len(armature.data.bones)
|
||||
with ProgressTracker(context, total_bones, t("Tools.convert_resonite.operation")) as progress:
|
||||
for bone in armature.data.bones:
|
||||
# Remove any existing "<noik>" tags
|
||||
for bone in arm_data.bones:
|
||||
bone.name = re.compile(re.escape("<noik>"), re.IGNORECASE).sub("", bone.name)
|
||||
simplified_name = simplified_names[bone.name]
|
||||
|
||||
if simplified_name in reverse_bone_lookup and reverse_bone_lookup[simplified_name] in resonite_translations:
|
||||
new_name = resonite_translations[reverse_bone_lookup[simplified_name]]
|
||||
total_bones = len(arm_data.bones)
|
||||
with ProgressTracker(context, total_bones, t("Tools.convert_resonite.operation")) as progress:
|
||||
for key_simple,bone_name in identify_bones(arm_data,context).items():
|
||||
|
||||
if key_simple in resonite_translations:
|
||||
new_name = resonite_translations[key_simple]
|
||||
logger.debug(f"Translating bone: {bone.name} -> {new_name}")
|
||||
bone.name = new_name
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user