Skip to content

Instantly share code, notes, and snippets.

@dantreble
Created August 9, 2021 12:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dantreble/24c46ca5f7eb61f8e51f08d6b6cf2322 to your computer and use it in GitHub Desktop.
Save dantreble/24c46ca5f7eb61f8e51f08d6b6cf2322 to your computer and use it in GitHub Desktop.
import bpy
import bmesh
import mathutils
from math import degrees, radians
def get_cc_rig():
for obj in bpy.data.objects:
if obj.type == "ARMATURE":
if obj.data.bones.get("CC_Base_BoneRoot"):
return obj
def extract_roll_vert_normal():
cc_rig = get_cc_rig()
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.select_all(action='DESELECT')
cc_rig.select_set(True)
bpy.ops.object.mode_set(mode='EDIT')
edit_bone_z = dict()
for edit_bone in cc_rig.data.edit_bones:
edit_bone_z[edit_bone.name] = edit_bone.z_axis
c_body = bpy.data.objects.get("CC_Base_Body")
bpy.ops.object.mode_set(mode='OBJECT')
cc_rig.select_set(False)
bpy.ops.object.select_all(action='DESELECT')
bm = bmesh.new()
bm.from_mesh(c_body.data)
layer_deform = bm.verts.layers.deform.active
# if layer_deform is not None:
bone_to_normalindex_dir = dict()
for bone_name, z_axis in edit_bone_z.items():
vertex_group = c_body.vertex_groups.get(bone_name)
if vertex_group is None:
continue
y_axis = edit_bone_y[bone_name]
bone_index = vertex_group.index
minangle = radians(180)
minindex = -1
minpositive = True
for index, vert in enumerate(bm.verts):
dvert = vert[layer_deform]
keys = dvert.keys()
#if (len(keys) == 1) and (keys[0] == bone_index): #100 percent weighted verts
#if bone_index in keys:
if dvert.get(bone_index, 0) > 0.5:
angle = vert.normal.angle(z_axis)
angle = vert.normal.angle(z_axis)
#print(bone_name,index,degrees(angle))
if angle < minangle:
minangle = angle
minindex = index
minpositive = True
angle = (-vert.normal).angle(z_axis)
if angle < minangle:
minangle = angle
minindex = index
minpositive = False
bone_to_normalindex_dir[bone_name] = (minindex,minpositive)
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.select_all(action='DESELECT')
cc_rig.select_set(True)
bpy.ops.object.mode_set(mode='EDIT')
bm.verts.ensure_lookup_table()
for edit_bone in cc_rig.data.edit_bones:
if edit_bone.name not in bone_to_normalindex_dir:
continue
normalindex_dir = bone_to_normalindex_dir[edit_bone.name]
if normalindex_dir[0] < 0:
continue
vert = bm.verts[normalindex_dir[0]]
z_axis = vert.normal if normalindex_dir[1] else -(vert.normal)
initial_roll = edit_bone.roll
restore_matrix = edit_bone.matrix.copy()
edit_bone.align_roll(z_axis)
final_roll = edit_bone.roll
edit_bone.matrix = restore_matrix
roll_error_adjustment = final_roll-initial_roll
#print(edit_bone.name, degrees(roll__error_adjustment))
print("\"%s\": (%d, %s,%f)," % (edit_bone.name,normalindex_dir[0],("True" if normalindex_dir[1] else "False"),roll_error_adjustment ))
extracted_roll_vertex = {"CC_Base_Pelvis": (4420, True,0.031755),
"CC_Base_L_Foot": (979, False,-0.073016),
"CC_Base_L_PinkyToe1": (1341, False,0.051410),
"CC_Base_L_RingToe1": (1281, True,-0.081089),
"CC_Base_L_MidToe1": (1276, True,0.027071),
"CC_Base_L_IndexToe1": (1271, True,0.077417),
"CC_Base_L_BigToe1": (1241, True,0.029006),
"CC_Base_L_CalfTwist01": (270, True,-6.274060),
"CC_Base_L_CalfTwist02": (304, True,6.260806),
"CC_Base_L_KneeShareBone": (118, True,0.030817),
"CC_Base_L_ThighTwist01": (2070, True,-0.013417),
"CC_Base_L_ThighTwist02": (540, False,6.209810),
"CC_Base_R_KneeShareBone": (2416, True,-0.030817),
"CC_Base_R_Foot": (3321, False,0.073017),
"CC_Base_R_BigToe1": (3622, True,-0.029007),
"CC_Base_R_PinkyToe1": (3724, False,-0.051377),
"CC_Base_R_RingToe1": (3663, True,0.081087),
"CC_Base_R_IndexToe1": (3654, True,-0.077416),
"CC_Base_R_MidToe1": (3659, True,-0.027068),
"CC_Base_R_CalfTwist01": (2569, True,6.274060),
"CC_Base_R_CalfTwist02": (2603, True,-6.260806),
"CC_Base_R_ThighTwist01": (4410, True,0.013417),
"CC_Base_R_ThighTwist02": (2881, False,-6.209810),
"CC_Base_Spine01": (2220, False,-0.012255),
"CC_Base_Spine02": (2243, False,-0.004390),
"CC_Base_NeckTwist01": (13249, False,0.002302),
"CC_Base_Head": (11681, False,-0.002782),
"CC_Base_JawRoot": (13323, False,-0.013935),
"CC_Base_L_Clavicle": (4852, False,0.541601),
"CC_Base_L_ForearmTwist01": (5016, False,0.017032),
"CC_Base_L_ForearmTwist02": (6922, False,0.025069),
"CC_Base_L_ElbowShareBone": (5018, False,0.173383),
"CC_Base_L_Hand": (6563, False,0.100460),
"CC_Base_L_Pinky1": (6072, True,-0.021422),
"CC_Base_L_Pinky2": (6216, False,-0.090521),
"CC_Base_L_Pinky3": (6248, False,0.008340),
"CC_Base_L_Ring1": (6009, False,0.039717),
"CC_Base_L_Ring2": (5988, False,-0.059878),
"CC_Base_L_Ring3": (5885, True,-0.023574),
"CC_Base_L_Mid1": (5618, False,0.020468),
"CC_Base_L_Mid2": (5511, True,-0.094710),
"CC_Base_L_Mid3": (5638, False,0.019230),
"CC_Base_L_Index1": (5694, True,-0.006783),
"CC_Base_L_Index2": (5819, False,-0.104342),
"CC_Base_L_Index3": (5703, True,-0.005980),
"CC_Base_L_Thumb1": (6788, True,0.085620),
"CC_Base_L_Thumb2": (6729, True,-0.011215),
"CC_Base_L_Thumb3": (5307, True,-0.000568),
"CC_Base_L_UpperarmTwist01": (4784, False,-0.013457),
"CC_Base_L_UpperarmTwist02": (4925, True,-0.033301),
"CC_Base_L_Breast": (1535, True,-0.408414),
"CC_Base_R_Breast": (3889, True,0.408414),
"CC_Base_R_Clavicle": (7287, False,-0.541601),
"CC_Base_R_ElbowShareBone": (7422, False,-0.173383),
"CC_Base_R_ForearmTwist01": (7421, False,-0.017032),
"CC_Base_R_ForearmTwist02": (9006, False,-0.025069),
"CC_Base_R_Hand": (9005, False,-0.100460),
"CC_Base_R_Ring1": (8433, False,-0.039717),
"CC_Base_R_Ring2": (8412, False,0.059878),
"CC_Base_R_Ring3": (8310, True,0.023572),
"CC_Base_R_Mid1": (8046, False,-0.020468),
"CC_Base_R_Mid2": (7942, True,0.094710),
"CC_Base_R_Mid3": (8066, False,-0.019212),
"CC_Base_R_Thumb1": (9201, True,-0.085620),
"CC_Base_R_Thumb2": (9144, True,0.011215),
"CC_Base_R_Thumb3": (7748, True,0.000597),
"CC_Base_R_Index1": (8124, True,0.006783),
"CC_Base_R_Index2": (8245, False,0.104342),
"CC_Base_R_Index3": (8129, True,0.006007),
"CC_Base_R_Pinky1": (8498, True,0.021453),
"CC_Base_R_Pinky2": (8638, False,0.090492),
"CC_Base_R_Pinky3": (8669, False,-0.008338),
"CC_Base_R_UpperarmTwist01": (7167, False,0.013457),
"CC_Base_R_UpperarmTwist02": (7459, True,0.033301)}
def set_roll_vert_normal():
c_body = bpy.data.objects.get("CC_Base_Body")
bm = bmesh.new()
bm.from_mesh(c_body.data)
bm.verts.ensure_lookup_table()
cc_rig = get_cc_rig()
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.select_all(action='DESELECT')
cc_rig.select_set(True)
bpy.ops.object.mode_set(mode='EDIT')
for edit_bone in cc_rig.data.edit_bones:
if edit_bone.name not in extracted_roll_vertex:
continue
vertindex_positive = extracted_roll_vertex[edit_bone.name]
if vertindex_positive[0] < 0:
continue
vert = bm.verts[vertindex_positive[0]]
z_axis = vert.normal if vertindex_positive[1] else -(vert.normal)
edit_bone.align_roll(z_axis)
edit_bone.roll = edit_bone.roll - vertindex_positive[2]
#print(z_axis_calc,edit_bone.z_axis)
def copy_roll(rig,src,dst):
src_bone = rig.data.edit_bones.get(src)
dst_bone = rig.data.edit_bones.get(dst)
dst_bone.roll = src_bone.roll
def fix_up_non_skinned_bones():
cc_rig = get_cc_rig()
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.select_all(action='DESELECT')
cc_rig.select_set(True)
bpy.ops.object.mode_set(mode='EDIT')
copy_roll(cc_rig,"CC_Base_R_ThighTwist01","CC_Base_R_Thigh")
copy_roll(cc_rig,"CC_Base_L_ThighTwist01","CC_Base_L_Thigh")
copy_roll(cc_rig,"CC_Base_R_CalfTwist01","CC_Base_R_Calf")
copy_roll(cc_rig,"CC_Base_R_CalfTwist01","CC_Base_R_KneeShareBone")
copy_roll(cc_rig,"CC_Base_L_CalfTwist01","CC_Base_L_Calf")
copy_roll(cc_rig,"CC_Base_L_CalfTwist01","CC_Base_L_KneeShareBone")
copy_roll(cc_rig,"CC_Base_R_UpperarmTwist01","CC_Base_R_Upperarm")
copy_roll(cc_rig,"CC_Base_L_UpperarmTwist01","CC_Base_L_Upperarm")
copy_roll(cc_rig,"CC_Base_R_ForearmTwist01","CC_Base_R_Forearm")
copy_roll(cc_rig,"CC_Base_R_ForearmTwist01","CC_Base_R_ElbowShareBone")
copy_roll(cc_rig,"CC_Base_L_ForearmTwist01","CC_Base_L_Forearm")
copy_roll(cc_rig,"CC_Base_L_ForearmTwist01","CC_Base_L_ElbowShareBone")
#extract_roll_vert_normal()
set_roll_vert_normal()
#fix_up_non_skinned_bones()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment