- bone.basename now only gets the name before the first '.', since names like finger.01.L are common
- updated delta not to remove a bone - spine and neck rigs interpolation bones are now axis aligned to the control bone - palm tag is expected on the pointer finger rather then the wrist - operate on bone children first working up the chain (not essential but more pradictable)
This commit is contained in:
@@ -76,7 +76,8 @@ class _GenericBone:
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def basename(self):
|
def basename(self):
|
||||||
return self.name.rsplit(".", 1)[0]
|
#return self.name.rsplit(".", 1)[0]
|
||||||
|
return self.name.split(".")[0]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def parent_recursive(self):
|
def parent_recursive(self):
|
||||||
|
|||||||
@@ -438,14 +438,19 @@ def generate_rig(context, obj_orig, prefix="ORG-"):
|
|||||||
bone_typeinfo.append((submod_name, type_func))
|
bone_typeinfo.append((submod_name, type_func))
|
||||||
|
|
||||||
|
|
||||||
# now we have all the info about bones we can start operating on them
|
# sort bones, not needed but gives more pradictable execution which may be useful in rare cases
|
||||||
|
bones_sorted = obj.pose.bones.values()
|
||||||
|
bones_sorted.sort(key=lambda pbone: pbone.name) # first sort by names
|
||||||
|
bones_sorted.sort(key=lambda pbone: - len(pbone.parent_recursive)) # children before parents
|
||||||
|
|
||||||
for pbone in obj.pose.bones:
|
# now we have all the info about bones we can start operating on them
|
||||||
|
# for pbone in obj.pose.bones:
|
||||||
|
for pbone in bones_sorted:
|
||||||
bone_name = pbone.name
|
bone_name = pbone.name
|
||||||
|
|
||||||
if bone_name not in bone_typeinfos:
|
if bone_name not in bone_typeinfos:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
bone_def_dict = bone_definitions[bone_name]
|
bone_def_dict = bone_definitions[bone_name]
|
||||||
|
|
||||||
# Only blend results from the same submodule, eg.
|
# Only blend results from the same submodule, eg.
|
||||||
|
|||||||
@@ -64,10 +64,11 @@ def metarig_definition(obj, orig_bone_name):
|
|||||||
mt.update()
|
mt.update()
|
||||||
|
|
||||||
mt.shoulder_p = mt.arm_p.parent
|
mt.shoulder_p = mt.arm_p.parent
|
||||||
mt.shoulder = mt.shoulder_p.name
|
|
||||||
|
|
||||||
if not mt.shoulder_p:
|
if not mt.shoulder_p:
|
||||||
raise Exception("could not find 'arm' parent, skipping:", orig_bone_name)
|
raise Exception("could not find 'arm' parent, skipping:", orig_bone_name)
|
||||||
|
print(mt.shoulder_p)
|
||||||
|
mt.shoulder = mt.shoulder_p.name
|
||||||
|
|
||||||
# We could have some bones attached, find the bone that has this as its 2nd parent
|
# We could have some bones attached, find the bone that has this as its 2nd parent
|
||||||
hands = []
|
hands = []
|
||||||
@@ -119,13 +120,13 @@ def main(obj, definitions, base_names):
|
|||||||
mt.update()
|
mt.update()
|
||||||
|
|
||||||
# Add the edit bones
|
# Add the edit bones
|
||||||
ik.hand_e = copy_bone_simple(arm, mt.hand, prefix % mt.hand)
|
ik.hand_e = copy_bone_simple(arm, mt.hand, prefix % base_names[mt.hand])
|
||||||
ik.hand = ik.hand_e.name
|
ik.hand = ik.hand_e.name
|
||||||
|
|
||||||
ik.arm_e = copy_bone_simple(arm, mt.arm, prefix % mt.arm)
|
ik.arm_e = copy_bone_simple(arm, mt.arm, prefix % base_names[mt.arm])
|
||||||
ik.arm = ik.arm_e.name
|
ik.arm = ik.arm_e.name
|
||||||
|
|
||||||
ik.forearm_e = copy_bone_simple(arm, mt.forearm, prefix % mt.forearm)
|
ik.forearm_e = copy_bone_simple(arm, mt.forearm, prefix % base_names[mt.forearm])
|
||||||
ik.forearm = ik.forearm_e.name
|
ik.forearm = ik.forearm_e.name
|
||||||
|
|
||||||
ik.arm_e.parent = mt.arm_e.parent
|
ik.arm_e.parent = mt.arm_e.parent
|
||||||
@@ -164,32 +165,27 @@ def main(obj, definitions, base_names):
|
|||||||
|
|
||||||
bpy.ops.object.mode_set(mode='EDIT')
|
bpy.ops.object.mode_set(mode='EDIT')
|
||||||
|
|
||||||
ik.arm = ik.arm
|
|
||||||
ik.forearm = ik.forearm
|
|
||||||
ik.hand = ik.hand
|
|
||||||
ik.pole = ik.pole
|
|
||||||
|
|
||||||
def chain_switch(prefix="MCH-%s"):
|
def chain_switch(prefix="MCH-%s"):
|
||||||
|
print(mt.obj.mode)
|
||||||
sw.update()
|
sw.update()
|
||||||
mt.update()
|
mt.update()
|
||||||
|
|
||||||
sw.shoulder_e = copy_bone_simple(arm, mt.shoulder, prefix % mt.shoulder)
|
sw.shoulder_e = copy_bone_simple(arm, mt.shoulder, prefix % base_names[mt.shoulder])
|
||||||
sw.shoulder = sw.shoulder_e.name
|
sw.shoulder = sw.shoulder_e.name
|
||||||
sw.shoulder_e.parent = mt.shoulder_e.parent
|
sw.shoulder_e.parent = mt.shoulder_e.parent
|
||||||
sw.shoulder_e.connected = mt.shoulder_e.connected
|
sw.shoulder_e.connected = mt.shoulder_e.connected
|
||||||
|
|
||||||
sw.arm_e = copy_bone_simple(arm, mt.arm, prefix % mt.arm)
|
sw.arm_e = copy_bone_simple(arm, mt.arm, prefix % base_names[mt.arm])
|
||||||
sw.arm = sw.arm_e.name
|
sw.arm = sw.arm_e.name
|
||||||
sw.arm_e.parent = sw.shoulder_e
|
sw.arm_e.parent = sw.shoulder_e
|
||||||
sw.arm_e.connected = arm.edit_bones[mt.shoulder].connected
|
sw.arm_e.connected = arm.edit_bones[mt.shoulder].connected
|
||||||
|
|
||||||
sw.forearm_e = copy_bone_simple(arm, mt.forearm, prefix % mt.forearm)
|
sw.forearm_e = copy_bone_simple(arm, mt.forearm, prefix % base_names[mt.forearm])
|
||||||
sw.forearm = sw.forearm_e.name
|
sw.forearm = sw.forearm_e.name
|
||||||
sw.forearm_e.parent = sw.arm_e
|
sw.forearm_e.parent = sw.arm_e
|
||||||
sw.forearm_e.connected = arm.edit_bones[mt.forearm].connected
|
sw.forearm_e.connected = arm.edit_bones[mt.forearm].connected
|
||||||
|
|
||||||
sw.hand_e = copy_bone_simple(arm, mt.hand, prefix % mt.hand)
|
sw.hand_e = copy_bone_simple(arm, mt.hand, prefix % base_names[mt.hand])
|
||||||
sw.hand = sw.hand_e.name
|
sw.hand = sw.hand_e.name
|
||||||
sw.hand_e.parent = sw.forearm_e
|
sw.hand_e.parent = sw.forearm_e
|
||||||
sw.hand_e.connected = arm.edit_bones[mt.hand].connected
|
sw.hand_e.connected = arm.edit_bones[mt.hand].connected
|
||||||
@@ -271,7 +267,7 @@ def main(obj, definitions, base_names):
|
|||||||
|
|
||||||
def chain_shoulder(prefix="MCH-%s"):
|
def chain_shoulder(prefix="MCH-%s"):
|
||||||
|
|
||||||
sw.socket_e = copy_bone_simple(arm, mt.arm, (prefix % mt.arm) + "_socket")
|
sw.socket_e = copy_bone_simple(arm, mt.arm, (prefix % base_names[mt.arm]) + "_socket")
|
||||||
sw.socket = sw.socket_e.name
|
sw.socket = sw.socket_e.name
|
||||||
sw.socket_e.tail = arm.edit_bones[mt.shoulder].tail
|
sw.socket_e.tail = arm.edit_bones[mt.shoulder].tail
|
||||||
|
|
||||||
@@ -287,7 +283,7 @@ def main(obj, definitions, base_names):
|
|||||||
|
|
||||||
# ***** add the shoulder hinge
|
# ***** add the shoulder hinge
|
||||||
# yes this is correct, the shoulder copy gets the arm's name
|
# yes this is correct, the shoulder copy gets the arm's name
|
||||||
ex.arm_hinge_e = copy_bone_simple(arm, mt.shoulder, (prefix % mt.arm) + "_hinge")
|
ex.arm_hinge_e = copy_bone_simple(arm, mt.shoulder, (prefix % base_names[mt.arm]) + "_hinge")
|
||||||
ex.arm_hinge = ex.arm_hinge_e.name
|
ex.arm_hinge = ex.arm_hinge_e.name
|
||||||
offset = ex.arm_hinge_e.length / 2.0
|
offset = ex.arm_hinge_e.length / 2.0
|
||||||
|
|
||||||
|
|||||||
@@ -81,24 +81,27 @@ def main(obj, bone_definition, base_names):
|
|||||||
child_head = child_ebone.head.copy()
|
child_head = child_ebone.head.copy()
|
||||||
child_tail = child_ebone.tail.copy()
|
child_tail = child_ebone.tail.copy()
|
||||||
|
|
||||||
arm.edit_bones.remove(delta_ebone)
|
#arm.edit_bones.remove(delta_ebone)
|
||||||
del delta_ebone # cant use this
|
#del delta_ebone # cant use this
|
||||||
|
del child_pbone
|
||||||
|
|
||||||
bpy.ops.object.mode_set(mode='OBJECT')
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Move the child bone to the deltas location
|
# Move the child bone to the deltas location
|
||||||
obj.animation_data_create()
|
obj.animation_data_create()
|
||||||
child_pbone = obj.pose.bones[child_name]
|
delta_pbone = obj.pose.bones[delta_name]
|
||||||
|
# child_pbone = obj.pose.bones[child_name]
|
||||||
|
|
||||||
# ------------------- drivers
|
# ------------------- drivers
|
||||||
|
|
||||||
child_pbone.rotation_mode = 'XYZ'
|
delta_pbone.rotation_mode = 'XYZ'
|
||||||
|
|
||||||
rot = delta_pmatrix.invert().rotationPart() * child_pmatrix.rotationPart()
|
rot = delta_pmatrix.invert().rotationPart() * child_pmatrix.rotationPart()
|
||||||
rot = rot.invert().toEuler()
|
rot = rot.invert().toEuler()
|
||||||
|
|
||||||
fcurve_drivers = child_pbone.driver_add("rotation_euler", -1)
|
fcurve_drivers = delta_pbone.driver_add("rotation_euler", -1)
|
||||||
for i, fcurve_driver in enumerate(fcurve_drivers):
|
for i, fcurve_driver in enumerate(fcurve_drivers):
|
||||||
driver = fcurve_driver.driver
|
driver = fcurve_driver.driver
|
||||||
driver.type = 'AVERAGE'
|
driver.type = 'AVERAGE'
|
||||||
@@ -111,7 +114,7 @@ def main(obj, bone_definition, base_names):
|
|||||||
# tricky, find the transform to drive the bone to this location.
|
# tricky, find the transform to drive the bone to this location.
|
||||||
delta_head_offset = child_pmatrix.rotationPart() * (delta_phead - child_phead)
|
delta_head_offset = child_pmatrix.rotationPart() * (delta_phead - child_phead)
|
||||||
|
|
||||||
fcurve_drivers = child_pbone.driver_add("location", -1)
|
fcurve_drivers = delta_pbone.driver_add("location", -1)
|
||||||
for i, fcurve_driver in enumerate(fcurve_drivers):
|
for i, fcurve_driver in enumerate(fcurve_drivers):
|
||||||
driver = fcurve_driver.driver
|
driver = fcurve_driver.driver
|
||||||
driver.type = 'AVERAGE'
|
driver.type = 'AVERAGE'
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ def metarig_definition(obj, orig_bone_name):
|
|||||||
children = bone.children
|
children = bone.children
|
||||||
# Now there must be 2 children, only one connected
|
# Now there must be 2 children, only one connected
|
||||||
if len(children) != 2:
|
if len(children) != 2:
|
||||||
raise Exception("expected the foot to have 2 children")
|
raise Exception("expected the foot bone:'%s' to have 2 children" % bone.name )
|
||||||
|
|
||||||
if children[0].connected == children[1].connected:
|
if children[0].connected == children[1].connected:
|
||||||
raise Exception("expected one bone to be connected")
|
raise Exception("expected one bone to be connected")
|
||||||
|
|||||||
@@ -159,8 +159,9 @@ def main(obj, bone_definition, base_names):
|
|||||||
# dont store parent names, re-reference as each chain bones parent.
|
# dont store parent names, re-reference as each chain bones parent.
|
||||||
neck_e_parent = arm.edit_bones.new("MCH-rot_%s" % neck_e.name)
|
neck_e_parent = arm.edit_bones.new("MCH-rot_%s" % neck_e.name)
|
||||||
neck_e_parent.head = neck_e.head
|
neck_e_parent.head = neck_e.head
|
||||||
neck_e_parent.tail = neck_e.head + Vector(0.0, 0.0, neck_chain_segment_length / 2.0)
|
neck_e_parent.tail = neck_e.head + ((mt.head_e.tail - mt.head_e.head).normalize() * neck_chain_segment_length / 2.0)
|
||||||
neck_e_parent.roll = 0.0
|
neck_e_parent.roll = neck_e.roll
|
||||||
|
|
||||||
|
|
||||||
orig_parent = neck_e.parent
|
orig_parent = neck_e.parent
|
||||||
neck_e.connected = False
|
neck_e.connected = False
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ from rna_prop_ui import rna_idprop_ui_prop_get
|
|||||||
# not used, defined for completeness
|
# not used, defined for completeness
|
||||||
METARIG_NAMES = tuple()
|
METARIG_NAMES = tuple()
|
||||||
|
|
||||||
|
|
||||||
def metarig_template():
|
def metarig_template():
|
||||||
|
# generated by rigify.write_meta_rig
|
||||||
bpy.ops.object.mode_set(mode='EDIT')
|
bpy.ops.object.mode_set(mode='EDIT')
|
||||||
obj = bpy.context.object
|
obj = bpy.context.object
|
||||||
arm = obj.data
|
arm = obj.data
|
||||||
@@ -73,26 +73,26 @@ def metarig_template():
|
|||||||
bone.parent = arm.edit_bones['hand']
|
bone.parent = arm.edit_bones['hand']
|
||||||
|
|
||||||
bpy.ops.object.mode_set(mode='OBJECT')
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
pbone = obj.pose.bones['hand']
|
pbone = obj.pose.bones['palm.05']
|
||||||
pbone['type'] = 'palm'
|
pbone['type'] = 'palm'
|
||||||
|
|
||||||
|
|
||||||
def metarig_definition(obj, orig_bone_name):
|
def metarig_definition(obj, orig_bone_name):
|
||||||
'''
|
'''
|
||||||
The bone given is the first in a chain
|
The bone given is the first in an array of siblings with a matching basename
|
||||||
Expects an array of children sorted with the little finger lowest.
|
sorted with the little finger lowest.
|
||||||
eg.
|
eg.
|
||||||
parent -> [pinky, ring... etc]
|
[pinky, ring... etc]
|
||||||
'''
|
'''
|
||||||
arm = obj.data
|
arm = obj.data
|
||||||
bone_definition = [orig_bone_name]
|
|
||||||
palm_ebone = arm.bones[orig_bone_name]
|
palm_bone = arm.bones[orig_bone_name]
|
||||||
|
palm_parent = palm_bone.parent
|
||||||
|
palm_base = palm_bone.basename
|
||||||
|
bone_definition = [bone.name for bone in palm_parent.children if bone.basename == palm_base]
|
||||||
|
bone_definition.sort()
|
||||||
|
|
||||||
children = [ebone.name for ebone in palm_ebone.children]
|
return [palm_parent.name] + bone_definition
|
||||||
children.sort() # simply assume the pinky has the lowest name
|
|
||||||
bone_definition.extend(children)
|
|
||||||
|
|
||||||
return bone_definition
|
|
||||||
|
|
||||||
|
|
||||||
def main(obj, bone_definition, base_names):
|
def main(obj, bone_definition, base_names):
|
||||||
|
|||||||
@@ -102,11 +102,15 @@ def metarig_definition(obj, orig_bone_name):
|
|||||||
ribcage = arm.bones[orig_bone_name]
|
ribcage = arm.bones[orig_bone_name]
|
||||||
pelvis = ribcage.parent
|
pelvis = ribcage.parent
|
||||||
|
|
||||||
|
if pelvis is None:
|
||||||
|
raise Exception("expected the ribcage bone:'%s' to have a parent (ribcage)." % ribcage.name)
|
||||||
|
|
||||||
children = ribcage.children
|
children = ribcage.children
|
||||||
if len(children) != 1:
|
if len(children) != 1:
|
||||||
print("expected the ribcage to have only 1 child.")
|
raise Exception("expected the ribcage to have only 1 child.")
|
||||||
|
|
||||||
child = children[0]
|
child = children[0]
|
||||||
|
|
||||||
bone_definition = [pelvis.name, ribcage.name, child.name]
|
bone_definition = [pelvis.name, ribcage.name, child.name]
|
||||||
bone_definition.extend([child.name for child in child.children_recursive_basename])
|
bone_definition.extend([child.name for child in child.children_recursive_basename])
|
||||||
return bone_definition
|
return bone_definition
|
||||||
@@ -132,17 +136,6 @@ def main(obj, bone_definition, base_names):
|
|||||||
spine_chain = [arm.edit_bones[child_name] for child_name in spine_chain_orig]
|
spine_chain = [arm.edit_bones[child_name] for child_name in spine_chain_orig]
|
||||||
spine_chain_basename = base_names[spine_chain[0].name].rsplit(".", 1)[0] # probably 'ORG-spine.01' -> 'spine'
|
spine_chain_basename = base_names[spine_chain[0].name].rsplit(".", 1)[0] # probably 'ORG-spine.01' -> 'spine'
|
||||||
spine_chain_len = len(spine_chain_orig)
|
spine_chain_len = len(spine_chain_orig)
|
||||||
print(spine_chain_orig)
|
|
||||||
print(spine_chain_len)
|
|
||||||
|
|
||||||
'''
|
|
||||||
children = mt.ribcage_e.children
|
|
||||||
child = children[0] # validate checks for 1 only.
|
|
||||||
spine_chain_basename = child.basename # probably 'spine'
|
|
||||||
spine_chain_segment_length = child.length
|
|
||||||
spine_chain = [child] + child.children_recursive_basename
|
|
||||||
spine_chain_orig = [child.name for child in spine_chain]
|
|
||||||
'''
|
|
||||||
|
|
||||||
child = spine_chain[0]
|
child = spine_chain[0]
|
||||||
spine_chain_segment_length = child.length
|
spine_chain_segment_length = child.length
|
||||||
@@ -241,8 +234,9 @@ def main(obj, bone_definition, base_names):
|
|||||||
# dont store parent names, re-reference as each chain bones parent.
|
# dont store parent names, re-reference as each chain bones parent.
|
||||||
spine_e_parent = arm.edit_bones.new("MCH-rot_%s" % child_name_orig)
|
spine_e_parent = arm.edit_bones.new("MCH-rot_%s" % child_name_orig)
|
||||||
spine_e_parent.head = spine_e.head
|
spine_e_parent.head = spine_e.head
|
||||||
spine_e_parent.tail = spine_e.head + Vector(0.0, 0.0, spine_chain_segment_length / 2.0)
|
spine_e_parent.tail = spine_e.head + ((mt.ribcage_e.tail - mt.ribcage_e.head).normalize() * spine_chain_segment_length / 2.0)
|
||||||
spine_e_parent.roll = 0.0
|
spine_e_parent.roll = mt.ribcage_e.roll
|
||||||
|
|
||||||
|
|
||||||
spine_e = getattr(ex_chain, ex_chain.attr_names[i] + "_e")
|
spine_e = getattr(ex_chain, ex_chain.attr_names[i] + "_e")
|
||||||
orig_parent = spine_e.parent
|
orig_parent = spine_e.parent
|
||||||
|
|||||||
Reference in New Issue
Block a user