feat(importing): Add head bone tail positions and improve armature modification logic

- Add 74 head bone tail position definitions to better_fbx_bone_tails dictionary for improved bone orientation accuracy
- Create backup file modifyarmature_bak.py for version control
- Conditionally apply delete_accessory_bones() only for Koikatsu armature type (C)
- Add cf_J_hitomi_tx_R and cf_J_hitomi_tx_L to preserved bones list
- Implement conditional bone reorientation logic for non-Koikatsu armature types (A/B/D)
- Simplify leg bone tail relocation by removing better_fbx data check and always applying standard z-alignment
- Improve armature modification workflow to handle different armature types with appropriate bone processing strategies
This commit is contained in:
2025-12-06 20:42:38 +08:00
parent 5d9e09e9c3
commit c50148a927

View File

@@ -231,6 +231,82 @@ better_fbx_bone_tails = {
'cf_j_index01_R': (-0.0308635831, -0.0027105501, -0.0027000904),
'cf_j_index02_R': (-0.0205416679, -0.0018021995, -0.0018149614),
'cf_j_index03_R': (-0.0205416679, -0.0018021995, -0.0018149614),
# 头部骨骼 (p_cf_head_bone 及其子骨骼共74个)
'p_cf_head_bone': (0.0, 0.0, 0.0099999998),
'cf_J_N_FaceRoot': (-4e-10, 0.0, 0.0099999998),
'cf_J_FaceRoot': (0.0, -0.0060000001, 0.0199999996),
'cf_J_FaceBase': (6.7e-09, -0.0321580991, 0.0155400224),
'cf_J_FaceUp_ty': (-5e-09, -0.0012981864, 0.0153640173),
'cf_J_EarBase_ry_L': (0.0040000007, 0.0065659345, 0.0013576597),
'cf_J_EarLow_L': (-0.0119999945, 0.0036456594, -0.0224846825),
'cf_J_EarUp_L': (0.0200000033, 0.0094862096, 0.0251999944),
'cf_J_EarBase_ry_R': (-0.0040000007, 0.0065659294, 0.0010771602),
'cf_J_EarLow_R': (0.0120000094, 0.0036456697, -0.0230684578),
'cf_J_EarUp_R': (-0.0200000033, 0.0094861891, 0.0252227858),
'cf_J_FaceUp_tz': (1.5e-08, -0.0822834074, 0.0294848457),
'cf_J_Eye_tz': (1.74653e-05, 7.5e-09, 0.0040000007),
'cf_J_Eye_txdam_L': (0.0005303472, -0.0006456077, 0.0108191594),
'cf_J_Eye_tx_L': (0.0005303472, -0.0006456077, 0.0108191594),
'cf_J_Eye_rz_L': (0.0020232424, -0.0143185034, -0.0075755417),
'cf_J_CheekUp2_L': (0.0024154074, 0.0097409822, -0.0335302614),
'cf_J_Eye01_s_L': (-0.0192517117, -0.0222310573, -0.0043519735),
'cf_J_Eye02_s_L': (-0.0125349201, -0.0245135501, 0.0108480155),
'cf_J_Eye03_s_L': (0.0034999885, -0.0231375471, 0.0147431493),
'cf_J_Eye04_s_L': (0.0165117607, -0.0177816749, 0.008518368),
'cf_J_Eye05_s_L': (0.0244611353, -0.0106068701, -0.0038318336),
'cf_J_Eye06_s_L': (0.0179830194, -0.0083362609, -0.0178645924),
'cf_J_Eye07_s_L': (0.0006974302, -0.0135568678, -0.0231180415),
'cf_J_Eye08_s_L': (-0.0155729428, -0.0184436664, -0.0195927024),
'cf_J_Eye_txdam_R': (-0.0005300008, -0.0006456077, 0.0108191594),
'cf_J_Eye_tx_R': (-0.0005300008, -0.0006456077, 0.0108191594),
'cf_J_Eye_rz_R': (-0.0018717796, -0.0143385679, -0.007591337),
'cf_J_CheekUp2_R': (-0.0024154112, 0.0097409934, -0.03353028),
'cf_J_Eye01_s_R': (0.0192652196, -0.0221798792, -0.0043867007),
'cf_J_Eye02_s_R': (0.012559589, -0.0245160758, 0.0108663738),
'cf_J_Eye03_s_R': (-0.00215628, -0.0233592987, 0.0145589486),
'cf_J_Eye04_s_R': (-0.0165314898, -0.017822504, 0.0085391998),
'cf_J_Eye05_s_R': (-0.0245011002, -0.0106083676, -0.0038220957),
'cf_J_Eye06_s_R': (-0.0179587901, -0.0083584338, -0.0178358555),
'cf_J_Eye07_s_R': (-0.0006720722, -0.0135397911, -0.0230915993),
'cf_J_Eye08_s_R': (0.0155643187, -0.018403694, -0.0196200199),
'cf_J_Mayu_ty': (1.36853e-05, 0.0106744692, 0.0),
'cf_J_Mayumoto_L': (0.0005722754, -0.0010105595, 0.0111785308),
'cf_J_Mayu_L': (0.0005722754, -0.0010105595, 0.0111785308),
'cf_J_MayuMid_s_L': (-0.0148523003, -0.0054057986, -3.12626e-05),
'cf_J_MayuTip_s_L': (0.0133357644, 0.0048538223, 0.0),
'cf_J_Mayumoto_R': (-0.0005719997, -0.0010160729, 0.0111785308),
'cf_J_Mayu_R': (-0.0005719997, -0.0010160729, 0.0111785308),
'cf_J_MayuMid_s_R': (0.0140953921, -0.0051302984, -3.12626e-05),
'cf_J_MayuTip_s_R': (-0.0125368983, 0.0045630634, -3.12626e-05),
'cf_J_FaceLow_tz': (5e-09, -0.025674995, -0.0074298549),
'cf_J_MouthBase_ty': (-2e-10, -0.0008716434, 0.0101031829),
'cf_J_MouthBase_rx': (-5e-09, 0.0124999955, 0.0),
'cf_J_MouthCavity': (-1e-08, 0.0249999985, 0.0),
'cf_J_MouthMove': (0.0, -0.0028492734, -0.0003052),
'cf_J_Mouth_L': (0.0060000005, -0.0007560551, 0.0),
'cf_J_Mouth_R': (-0.0059999996, -0.0007560551, 0.0),
'cf_J_MouthLow': (0.0, -0.0030992031, -0.0026312196),
'cf_J_Mouthup': (0.0, -0.0067858025, 0.0014104201),
'cf_J_FaceLow_sx': (0.0, -0.0006982945, -0.0140105523),
'cf_J_Chin_Base': (2e-10, -0.0075257719, -0.0307464823),
'cf_J_CheekLow_s_L': (0.0259999987, 7.5e-09, -0.0293771196),
'cf_J_CheekLow_s_R': (-0.0259999968, 0.0, -0.0293771196),
'cf_J_Chin_s': (1e-08, -0.0174226761, -0.0165147893),
'cf_J_ChinTip_Base': (1e-08, -0.0174226761, -0.0165147875),
'cf_J_ChinLow': (0.0, -0.0020948797, -0.0420316607),
'cf_J_CheekUpBase': (1.2e-09, -0.0249999985, 0.0044998601),
'cf_J_CheekUp_s_L': (0.0459999964, -0.0249999911, 0.0045103002),
'cf_J_CheekUp_s_R': (-0.0460000038, -0.0250000022, 0.00448942),
'cf_J_NoseBase': (5e-09, -0.0072341338, 0.012515638),
'cf_J_NoseBase_rx': (1e-08, -0.0150000006, 0.0),
'cf_J_Nose_rx': (0.0, -0.0091642886, 0.0),
'cf_J_Nose_tip': (0.0, -0.0091642886, 0.0),
'cf_J_NoseBridge_ty': (-2e-10, -0.0008712783, 0.010564737),
'cf_J_NoseBridge_rx': (-2e-10, -0.0008714795, 0.010564737),
'N_tonn_face': (0.0, 0.0, 0.0099999998),
'N_cf_haed': (0.0, 0.0, 0.0099999998),
'cf_O_face_atari': (0.0, 0.0, 0.0099999998),
}
class modify_armature(bpy.types.Operator):
@@ -410,8 +486,9 @@ class modify_armature(bpy.types.Operator):
bpy.ops.armature.select_all(action='INVERT')
bpy.ops.armature.delete()
# 删除无用的配饰骨骼(头发、衣服等),只保留核心人体骨骼
# self.delete_accessory_bones()
# 只在选择 Koikatsu armature (C) 时删除配饰骨骼
if bpy.context.scene.kkbp.armature_dropdown == 'C':
self.delete_accessory_bones()
c.print_timer('delete_non_height_bones')
@@ -433,6 +510,8 @@ class modify_armature(bpy.types.Operator):
'p_cf_head_bone', # 头部骨骼
'a_n_back', # 背部锚点
'a_n_headside', # 头部侧面锚点
'cf_J_hitomi_tx_R',
'cf_J_hitomi_tx_L',
]
# 收集所有需要删除的骨骼(不在 better_fbx_bone_tails 中且不在必须保留列表中的)
@@ -531,6 +610,24 @@ class modify_armature(bpy.types.Operator):
for finger in finger_list:
resize_finger(finger)
# 对于非 Koikatsu armature (A/B/D),使用原始的骨骼重定向逻辑
# Koikatsu armature (C) 会在最后统一应用 better_fbx 骨骼方向
if bpy.context.scene.kkbp.armature_dropdown != 'C':
height_adjust = Vector((0,0,0.1))
def reorient(bone):
armature.data.edit_bones[bone].tail = armature.data.edit_bones[bone].head + height_adjust
reorient_list = [
'cf_j_thigh00_R', 'cf_j_thigh00_L',
'cf_j_leg01_R', 'cf_j_leg01_L',
'cf_j_leg03_R', 'cf_j_leg03_L',
'cf_j_foot_R', 'cf_j_foot_L',
'cf_d_arm01_R', 'cf_d_arm01_L',
'cf_d_shoulder02_R', 'cf_d_shoulder02_L',]
for bone in reorient_list:
reorient(bone)
c.print_timer('modify_finger_bone_orientations')
def set_bone_roll_data(self):
@@ -884,14 +981,8 @@ class modify_armature(bpy.types.Operator):
#relocate the tail of some bones to make IKs easier
def relocate_tail(bone1, bone2, direction):
if direction == 'leg':
# 使用 better_fbx 数据而不是简单地对齐到目标骨骼
if bone1 in better_fbx_bone_tails:
print(f"[KKBP] 保留 {bone1} 的 better_fbx 骨骼方向")
# 不修改尾部,保留之前设置的方向
pass
else:
armature.data.edit_bones[bone1].tail.z = armature.data.edit_bones[bone2].head.z
armature.data.edit_bones[bone1].roll = 0
armature.data.edit_bones[bone1].tail.z = armature.data.edit_bones[bone2].head.z
armature.data.edit_bones[bone1].roll = 0
#move the bone forward a bit or the ik bones might not bend correctly
armature.data.edit_bones[bone1].head.y += -0.01
elif direction == 'arm':
@@ -904,15 +995,9 @@ class modify_armature(bpy.types.Operator):
armature.data.edit_bones[bone1].tail.z += .01
armature.data.edit_bones[bone1].head = armature.data.edit_bones[bone2].head
else:
# 使用 better_fbx 数据而不是简单地对齐到目标骨骼
if bone1 in better_fbx_bone_tails:
print(f"[KKBP] 保留 {bone1} 的 better_fbx 骨骼方向")
# 不修改尾部,保留之前设置的方向
pass
else:
armature.data.edit_bones[bone1].tail.y = armature.data.edit_bones[bone2].head.y
armature.data.edit_bones[bone1].tail.z = armature.data.edit_bones[bone2].head.z
armature.data.edit_bones[bone1].roll = 0
armature.data.edit_bones[bone1].tail.y = armature.data.edit_bones[bone2].head.y
armature.data.edit_bones[bone1].tail.z = armature.data.edit_bones[bone2].head.z
armature.data.edit_bones[bone1].roll = 0
relocate_tail('cf_j_leg01_R', 'cf_j_foot_R', 'leg')
relocate_tail('cf_j_leg01_L', 'cf_j_foot_L', 'leg')
relocate_tail('cf_j_forearm01_R', 'cf_j_hand_R', 'arm')
@@ -1127,7 +1212,12 @@ class modify_armature(bpy.types.Operator):
c.print_timer('rename_mmd_bones')
def apply_better_fbx_bone_orientations(self):
'''统一应用 better_fbx 骨骼方向,确保不被其他步骤覆盖'''
'''统一应用 better_fbx 骨骼方向,确保不被其他步骤覆盖 (仅在选择 Koikatsu armature 时)'''
# 只在选择 Koikatsu armature (C) 时应用 better_fbx 骨骼方向
if bpy.context.scene.kkbp.armature_dropdown != 'C':
c.print_timer('apply_better_fbx_bone_orientations (skipped)')
return
armature = c.get_armature()
c.switch(armature, 'edit')