# ##### END GPL LICENSE BLOCK #####
import bpy
-from rigify import bone_class_instance, copy_bone_simple, add_pole_target_bone, add_stretch_to
+from rigify import bone_class_instance, copy_bone_simple, copy_bone_simple_list, add_pole_target_bone, add_stretch_to
from rna_prop_ui import rna_idprop_ui_get, rna_idprop_ui_prop_get
+METARIG_NAMES = "hips", "thigh", "shin", "foot", "toe", "heel"
+
def metarig_template():
# generated by rigify.write_meta_rig
bpy.ops.object.mode_set(mode='EDIT')
pbone = obj.pose.bones['thigh']
pbone['type'] = 'leg'
-
-def validate(obj, orig_bone_name):
+def metarig_definition(obj, orig_bone_name):
'''
The bone given is the first in a chain
Expects a chain of at least 3 children.
eg.
thigh -> shin -> foot -> [toe, heel]
'''
+
+ bone_definition = []
+
orig_bone = obj.data.bones[orig_bone_name]
+ orig_bone_parent = orig_bone.parent
+
+ if orig_bone_parent is None:
+ raise Exception("expected the thigh bone to have a parent hip bone")
+
+ bone_definition.append(orig_bone_parent.name)
+ bone_definition.append(orig_bone.name)
+
bone = orig_bone
chain = 0
- while chain < 3: # first 2 bones only have 1 child
+ while chain < 2: # first 2 bones only have 1 child
children = bone.children
+
if len(children) != 1:
- return "expected the thigh bone to have 3 children without a fork"
+ raise Exception("expected the thigh bone to have 3 children without a fork")
bone = children[0]
+ bone_definition.append(bone.name) # shin, foot
chain += 1
children = bone.children
# Now there must be 2 children, only one connected
if len(children) != 2:
- return "expected the foot to have 2 children"
+ raise Exception("expected the foot to have 2 children")
if children[0].connected == children[1].connected:
- return "expected one bone to be connected"
+ raise Exception("expected one bone to be connected")
- return ''
+ toe, heel = children
+ if heel.connected:
+ toe, heel = heel, toe
+
+
+ bone_definition.append(toe.name)
+ bone_definition.append(heel.name)
+
+ if len(bone_definition) != len(METARIG_NAMES):
+ raise Exception("internal problem, expected %d bones" % len(METARIG_NAMES))
+
+ return bone_definition
-def main(obj, orig_bone_name):
+def ik(obj, bone_definition, base_names):
from Mathutils import Vector
arm = obj.data
# children of ik_foot
ik = bone_class_instance(obj, ["foot", "foot_roll", "foot_roll_01", "foot_roll_02", "knee_target"])
- mt_chain.thigh_e = arm.edit_bones[orig_bone_name]
- mt_chain.thigh = orig_bone_name
-
- mt.hips_e = mt_chain.thigh_e.parent
- mt.hips_e.name = "ORG-" + mt.hips_e.name
- mt.hips = mt.hips_e.name
-
- mt_chain.shin_e = mt_chain.thigh_e.children[0]
- mt_chain.shin = mt_chain.shin_e.name
-
- mt_chain.foot_e = mt_chain.shin_e.children[0]
- mt_chain.foot = mt_chain.foot_e.name
-
- mt_chain.toe_e, mt.heel_e = mt_chain.foot_e.children
-
- # We dont know which is which, but know the heel is disconnected
- if not mt_chain.toe_e.connected:
- mt_chain.toe_e, mt.heel_e = mt.heel_e, mt_chain.toe_e
- mt.heel_e.name = "ORG-" + mt.heel_e.name
- mt_chain.toe, mt.heel = mt_chain.toe_e.name, mt.heel_e.name
-
- ex.thigh_socket_e = copy_bone_simple(arm, mt_chain.thigh, "MCH-%s_socket" % mt_chain.thigh, parent=True)
- ex.thigh_socket = ex.thigh_socket_e.name
- ex.thigh_socket_e.tail = ex.thigh_socket_e.head + Vector(0.0, 0.0, ex.thigh_socket_e.length / 4.0)
-
- ex.thigh_hinge_e = copy_bone_simple(arm, mt_chain.thigh, "MCH-%s_hinge" % mt_chain.thigh, parent=True)
- ex.thigh_hinge = ex.thigh_hinge_e.name
- ex.thigh_hinge_e.tail = ex.thigh_hinge_e.head + Vector(0.0, 0.0, mt_chain.thigh_e.head.length)
- ex.thigh_hinge_e.translate(Vector(-(mt.hips_e.head.x - mt_chain.thigh_e.head.x), 0.0, 0.0))
- ex.thigh_hinge_e.length = mt.hips_e.length
-
+ # XXX - duplicate below
+ for bone_class in (mt, mt_chain):
+ for attr in bone_class.attr_names:
+ i = METARIG_NAMES.index(attr)
+ ebone = arm.edit_bones[bone_definition[i]]
+ setattr(bone_class, attr, ebone.name)
+ bone_class.update()
+ # XXX - end dupe
# Make a new chain, ORG are the original bones renamed.
- fk_chain = mt_chain.copy(from_prefix="ORG-") # fk has no prefix!
- ik_chain = fk_chain.copy(to_prefix="MCH-")
-
- fk_chain.thigh_e.connected = False
- fk_chain.thigh_e.parent = ex.thigh_hinge_e
-
- # fk_chain.thigh_socket_e.parent = MCH-leg_hinge
+ ik_chain = mt_chain.copy(to_prefix="MCH-")
# simple rename
ik_chain.rename("thigh", ik_chain.thigh + "_ik")
ik_chain.rename("shin", ik_chain.shin + "_ik")
# ik foot, no parents
- base_foot_name = fk_chain.foot # whatever the foot is called, use that!
- ik.foot_e = copy_bone_simple(arm, fk_chain.foot, "%s_ik" % base_foot_name)
+ base_foot_name = base_names[mt_chain.foot] # whatever the foot is called, use that!, XXX - ORG!
+ ik.foot_e = copy_bone_simple(arm, mt_chain.foot, "%s_ik" % base_foot_name)
ik.foot = ik.foot_e.name
ik.foot_e.tail.z = ik.foot_e.head.z
ik.foot_e.roll = 0.0
# rename 'MCH-toe' --> to 'toe_ik' and make the child of ik.foot_roll_01
# ------------------ FK or IK?
- ik_chain.rename("toe", fk_chain.toe + "_ik") # only fk for the basename
+ ik_chain.rename("toe", base_names[mt_chain.toe] + "_ik")
ik_chain.toe_e.connected = False
ik_chain.toe_e.parent = ik.foot_roll_01_e
ex.update()
mt_chain.update()
ik_chain.update()
- fk_chain.update()
-
- con = fk_chain.thigh_p.constraints.new('COPY_LOCATION')
- con.target = obj
- con.subtarget = ex.thigh_socket
-
- # hinge
- prop = rna_idprop_ui_prop_get(fk_chain.thigh_p, "hinge", create=True)
- fk_chain.thigh_p["hinge"] = 0.5
- prop["soft_min"] = 0.0
- prop["soft_max"] = 1.0
-
- con = ex.thigh_hinge_p.constraints.new('COPY_ROTATION')
- con.target = obj
- con.subtarget = mt.hips
-
- # add driver
- hinge_driver_path = fk_chain.thigh_p.path_to_id() + '["hinge"]'
-
- fcurve = con.driver_add("influence", 0)
- driver = fcurve.driver
- tar = driver.targets.new()
- driver.type = 'AVERAGE'
- tar.name = "var"
- tar.id_type = 'OBJECT'
- tar.id = obj
- tar.rna_path = hinge_driver_path
-
- mod = fcurve.modifiers[0]
- mod.poly_order = 1
- mod.coefficients[0] = 1.0
- mod.coefficients[1] = -1.0
-
-
- # adds constraints to the original bones.
- mt_chain.blend(fk_chain, ik_chain, target_bone=ik.foot, target_prop="ik", use_loc=False)
-
# IK
con = ik_chain.shin_p.constraints.new('IK')
else:
con.minimum_x = -180.0 # XXX -deg
con.maximum_x = 0.0
+
+ return None, ik_chain.thigh, ik_chain.shin, ik_chain.foot, ik_chain.toe, None
+
+
+def fk(obj, bone_definition, base_names):
+ from Mathutils import Vector
+ arm = obj.data
+
+ # these account for all bones in METARIG_NAMES
+ mt_chain = bone_class_instance(obj, ["thigh", "shin", "foot", "toe"])
+ mt = bone_class_instance(obj, ["hips", "heel"])
+
+ # new bones
+ ex = bone_class_instance(obj, ["thigh_socket", "thigh_hinge"])
+
+ for bone_class in (mt, mt_chain):
+ for attr in bone_class.attr_names:
+ i = METARIG_NAMES.index(attr)
+ ebone = arm.edit_bones[bone_definition[i]]
+ setattr(bone_class, attr, ebone.name)
+ bone_class.update()
+
+ ex.thigh_socket_e = copy_bone_simple(arm, mt_chain.thigh, "MCH-%s_socket" % base_names[mt_chain.thigh], parent=True)
+ ex.thigh_socket = ex.thigh_socket_e.name
+ ex.thigh_socket_e.tail = ex.thigh_socket_e.head + Vector(0.0, 0.0, ex.thigh_socket_e.length / 4.0)
+
+ ex.thigh_hinge_e = copy_bone_simple(arm, mt_chain.thigh, "MCH-%s_hinge" % base_names[mt_chain.thigh], parent=True)
+ ex.thigh_hinge = ex.thigh_hinge_e.name
+ ex.thigh_hinge_e.tail = ex.thigh_hinge_e.head + Vector(0.0, 0.0, mt_chain.thigh_e.head.length)
+ ex.thigh_hinge_e.translate(Vector(-(mt.hips_e.head.x - mt_chain.thigh_e.head.x), 0.0, 0.0))
+ ex.thigh_hinge_e.length = mt.hips_e.length
+
+ fk_chain = mt_chain.copy() # fk has no prefix!
+
+ fk_chain.thigh_e.connected = False
+ fk_chain.thigh_e.parent = ex.thigh_hinge_e
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ ex.update()
+ mt_chain.update()
+ fk_chain.update()
+
+ con = fk_chain.thigh_p.constraints.new('COPY_LOCATION')
+ con.target = obj
+ con.subtarget = ex.thigh_socket
+
+ # hinge
+ prop = rna_idprop_ui_prop_get(fk_chain.thigh_p, "hinge", create=True)
+ fk_chain.thigh_p["hinge"] = 0.5
+ prop["soft_min"] = 0.0
+ prop["soft_max"] = 1.0
+
+ con = ex.thigh_hinge_p.constraints.new('COPY_ROTATION')
+ con.target = obj
+ con.subtarget = mt.hips
+
+ # add driver
+ hinge_driver_path = fk_chain.thigh_p.path_to_id() + '["hinge"]'
+
+ fcurve = con.driver_add("influence", 0)
+ driver = fcurve.driver
+ tar = driver.targets.new()
+ driver.type = 'AVERAGE'
+ tar.name = "var"
+ tar.id_type = 'OBJECT'
+ tar.id = obj
+ tar.rna_path = hinge_driver_path
+
+ mod = fcurve.modifiers[0]
+ mod.poly_order = 1
+ mod.coefficients[0] = 1.0
+ mod.coefficients[1] = -1.0
+
+ # dont blend the hips or heel
+ return None, fk_chain.thigh, fk_chain.shin, fk_chain.foot, fk_chain.toe, None