Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Vegdahl <cessen@cessen.com>2010-01-19 22:07:09 +0300
committerNathan Vegdahl <cessen@cessen.com>2010-01-19 22:07:09 +0300
commitc54d54e8aeb386fd8f5cbd61d62fb5a490bb6ea8 (patch)
tree6a9fdb6aa9b7ddf4ae4c864bd42075efdc6ae3de /release
parent40fb29862ea06794d27378aaf64638d8c1f72121 (diff)
Rigify:
- Added two driven-shape-key rig types that create and drive shape keys on a mesh/meshes based on the distance or rotation difference between two bones. - Fixed bug in finger curl rig type where secondary finger controls were not created. Finger type can also now (optionally) have a hinge switch (useful when using it for wings). - Changed the blending system in rigify_utils to use copy_transforms constraints instead of copy_loc+copy_rot. - Finished the quadruped leg type. Now has both ik and fk control and ik/fk switching. Also uses a rotating bone to control the knee direction instead of a pole target (seems to work more consistently for quadruped setups). There's still one annoying bug regarding foot roll, but it's not blocking. I'll track it down later. - Mouth rig now creates corrective shape keys on the face mesh for dealing with mouth corners when they spread open. - Biped arm and leg types now cause mesh to scale when you scale the fk controls. - Misc improvements to the rig types.
Diffstat (limited to 'release')
-rw-r--r--release/scripts/modules/rigify/arm_biped.py20
-rw-r--r--release/scripts/modules/rigify/finger_curl.py236
-rw-r--r--release/scripts/modules/rigify/leg_biped.py17
-rw-r--r--release/scripts/modules/rigify/leg_quadruped.py281
-rw-r--r--release/scripts/modules/rigify/mouth.py526
-rw-r--r--release/scripts/modules/rigify/neck_flex.py3
-rw-r--r--release/scripts/modules/rigify/palm_curl.py3
-rw-r--r--release/scripts/modules/rigify/shape_key_distance.py176
-rw-r--r--release/scripts/modules/rigify/shape_key_rotdiff.py176
-rw-r--r--release/scripts/modules/rigify/spine_pivot_flex.py8
-rw-r--r--release/scripts/modules/rigify_utils.py28
11 files changed, 1239 insertions, 235 deletions
diff --git a/release/scripts/modules/rigify/arm_biped.py b/release/scripts/modules/rigify/arm_biped.py
index 26b56164b37..f3d449e5aff 100644
--- a/release/scripts/modules/rigify/arm_biped.py
+++ b/release/scripts/modules/rigify/arm_biped.py
@@ -223,6 +223,7 @@ def fk(obj, definitions, base_names, options):
fk_chain.forearm_p.rotation_mode = 'XYZ'
fk_chain.forearm_p.lock_rotation = (False, True, True)
fk_chain.hand_p.rotation_mode = 'ZXY'
+ fk_chain.arm_p.lock_location = True, True, True
con = fk_chain.arm_p.constraints.new('COPY_LOCATION')
con.target = obj
@@ -276,7 +277,14 @@ def fk(obj, definitions, base_names, options):
fk_chain.arm_b.layer = layer
fk_chain.forearm_b.layer = layer
fk_chain.hand_b.layer = layer
-
+
+ # Forearm was getting wrong roll somehow. Hack to fix that.
+ bpy.ops.object.mode_set(mode='EDIT')
+ fk_chain.update()
+ mt.update()
+ fk_chain.forearm_e.roll = mt.forearm_e.roll
+ bpy.ops.object.mode_set(mode='OBJECT')
+
bpy.ops.object.mode_set(mode='EDIT')
return None, fk_chain.arm, fk_chain.forearm, fk_chain.hand
@@ -338,6 +346,11 @@ def deform(obj, definitions, base_names, options):
con.target = obj
con.subtarget = definitions[2]
+ con = uarm1.constraints.new('COPY_SCALE')
+ con.name = "trackto"
+ con.target = obj
+ con.subtarget = definitions[1]
+
con = uarm2.constraints.new('COPY_ROTATION')
con.name = "copy_rot"
con.target = obj
@@ -349,6 +362,11 @@ def deform(obj, definitions, base_names, options):
con.target = obj
con.subtarget = definitions[2]
+ con = farm1.constraints.new('COPY_SCALE')
+ con.name = "copy_rot"
+ con.target = obj
+ con.subtarget = definitions[2]
+
con = farm2.constraints.new('COPY_ROTATION')
con.name = "copy_rot"
con.target = obj
diff --git a/release/scripts/modules/rigify/finger_curl.py b/release/scripts/modules/rigify/finger_curl.py
index 085eba180fd..997ed889bb2 100644
--- a/release/scripts/modules/rigify/finger_curl.py
+++ b/release/scripts/modules/rigify/finger_curl.py
@@ -150,103 +150,171 @@ def deform(obj, definitions, base_names, options):
def main(obj, bone_definition, base_names, options):
# *** EDITMODE
-
+ bpy.ops.object.mode_set(mode='EDIT')
+
# get assosiated data
arm = obj.data
- orig_ebone = arm.edit_bones[bone_definition[0]]
-
- obj.animation_data_create() # needed if its a new armature with no keys
-
- children = orig_ebone.children_recursive
- tot_len = reduce(lambda f, ebone: f + ebone.length, children, orig_ebone.length)
-
- # FIXME, the line below is far too arbitrary
- base_name = base_names[bone_definition[0]].rsplit(".", 2)[0]
-
- # first make a new bone at the location of the finger
- #control_ebone = arm.edit_bones.new(base_name)
- control_ebone = copy_bone_simple(arm, bone_definition[0], base_name + get_side_name(base_names[bone_definition[0]]), parent=True)
- control_bone_name = control_ebone.name # we dont know if we get the name requested
-
- control_ebone.connected = orig_ebone.connected
- control_ebone.parent = orig_ebone.parent
- control_ebone.length = tot_len
-
- # now add bones inbetween this and its children recursively
-
- # switching modes so store names only!
- children = [ebone.name for ebone in children]
-
- driver_bone_pairs = []
-
- for child_bone_name in children:
- child_ebone = arm.edit_bones[child_bone_name]
-
- # finger.02 --> finger_driver.02
- driver_bone_name = child_bone_name.split('.')
- driver_bone_name = driver_bone_name[0] + "_driver." + ".".join(driver_bone_name[1:])
-
- driver_ebone = copy_bone_simple(arm, child_ebone.name, driver_bone_name)
- driver_ebone.length *= 0.5
-
- # Insert driver_ebone in the chain without connected parents
- driver_ebone.connected = False
- driver_ebone.parent = child_ebone.parent
-
- child_ebone.connected = False
- child_ebone.parent = driver_ebone
-
- # Add the drivers to these when in posemode.
- driver_bone_pairs.append((child_bone_name, driver_bone_name))
-
- del control_ebone
+ bb = obj.data.bones
+ eb = obj.data.edit_bones
+ pb = obj.pose.bones
+
+ org_f1 = bone_definition[0] # Original finger bone 01
+ org_f2 = bone_definition[1] # Original finger bone 02
+ org_f3 = bone_definition[2] # Original finger bone 03
+
+ # Check options
+ if "bend_ratio" in options:
+ bend_ratio = options["bend_ratio"]
+ else:
+ bend_ratio = 0.4
+
+ yes = [1, 1.0, True, "True", "true", "Yes", "yes"]
+ make_hinge = False
+ if ("hinge" in options) and (eb[org_f1].parent is not None):
+ if options["hinge"] in yes:
+ make_hinge = True
+
+ # Needed if its a new armature with no keys
+ obj.animation_data_create()
+
+ # Create the control bone
+ base_name = base_names[bone_definition[0]].split(".", 1)[0]
+ tot_len = eb[org_f1].length + eb[org_f2].length + eb[org_f3].length
+ control = copy_bone_simple(arm, bone_definition[0], base_name + get_side_name(base_names[bone_definition[0]]), parent=True).name
+ eb[control].connected = eb[org_f1].connected
+ eb[control].parent = eb[org_f1].parent
+ eb[control].length = tot_len
+
+ # Create secondary control bones
+ f1 = copy_bone_simple(arm, bone_definition[0], base_names[bone_definition[0]]).name
+ f2 = copy_bone_simple(arm, bone_definition[1], base_names[bone_definition[1]]).name
+ f3 = copy_bone_simple(arm, bone_definition[2], base_names[bone_definition[2]]).name
+
+ # Create driver bones
+ df1 = copy_bone_simple(arm, bone_definition[0], "MCH-" + base_names[bone_definition[0]]).name
+ eb[df1].length /= 2
+ df2 = copy_bone_simple(arm, bone_definition[1], "MCH-" + base_names[bone_definition[1]]).name
+ eb[df2].length /= 2
+ df3 = copy_bone_simple(arm, bone_definition[2], "MCH-" + base_names[bone_definition[2]]).name
+ eb[df3].length /= 2
+
+ # Set parents of the bones, interleaving the driver bones with the secondary control bones
+ eb[f3].connected = False
+ eb[df3].connected = False
+ eb[f2].connected = False
+ eb[df2].connected = False
+ eb[f1].connected = False
+ eb[df1].connected = eb[org_f1].connected
+
+ eb[f3].parent = eb[df3]
+ eb[df3].parent = eb[f2]
+ eb[f2].parent = eb[df2]
+ eb[df2].parent = eb[f1]
+ eb[f1].parent = eb[df1]
+ eb[df1].parent = eb[org_f1].parent
+
+ # Set up bones for hinge
+ if make_hinge:
+ socket = copy_bone_simple(arm, org_f1, "MCH-socket_"+control, parent=True).name
+ hinge = copy_bone_simple(arm, eb[org_f1].parent.name, "MCH-hinge_"+control).name
+
+ eb[control].connected = False
+ eb[control].parent = eb[hinge]
+
+ # Create the deform rig while we're still in edit mode
deform(obj, bone_definition, base_names, options)
-
+
+
# *** POSEMODE
bpy.ops.object.mode_set(mode='OBJECT')
-
-
- orig_pbone = obj.pose.bones[bone_definition[0]]
- control_pbone = obj.pose.bones[control_bone_name]
- control_bbone = arm.bones[control_bone_name]
- control_pbone.rotation_mode = obj.pose.bones[bone_definition[0]].rotation_mode
-
-
- # only allow Y scale
- control_pbone.lock_scale = (True, False, True)
-
- control_pbone["bend_ratio"] = 0.4
- prop = rna_idprop_ui_prop_get(control_pbone, "bend_ratio", create=True)
+
+ # Set rotation modes and axis locks
+ pb[control].rotation_mode = obj.pose.bones[bone_definition[0]].rotation_mode
+ pb[control].lock_location = True, True, True
+ pb[control].lock_scale = True, False, True
+ pb[f1].rotation_mode = 'YZX'
+ pb[f2].rotation_mode = 'YZX'
+ pb[f3].rotation_mode = 'YZX'
+ pb[f1].lock_location = True, True, True
+ pb[f2].lock_location = True, True, True
+ pb[f3].lock_location = True, True, True
+ pb[df2].rotation_mode = 'YZX'
+ pb[df3].rotation_mode = 'YZX'
+
+ # Add the bend_ratio property to the control bone
+ pb[control]["bend_ratio"] = bend_ratio
+ prop = rna_idprop_ui_prop_get(pb[control], "bend_ratio", create=True)
prop["soft_min"] = 0.0
prop["soft_max"] = 1.0
-
- con = orig_pbone.constraints.new('COPY_LOCATION')
+
+ # Add hinge property to the control bone
+ if make_hinge:
+ pb[control]["hinge"] = 0.0
+ prop = rna_idprop_ui_prop_get(pb[control], "hinge", create=True)
+ prop["soft_min"] = 0.0
+ prop["soft_max"] = 1.0
+
+ # Constraints
+ con = pb[df1].constraints.new('COPY_LOCATION')
con.target = obj
- con.subtarget = control_bone_name
+ con.subtarget = control
- con = orig_pbone.constraints.new('COPY_ROTATION')
+ con = pb[df1].constraints.new('COPY_ROTATION')
con.target = obj
- con.subtarget = control_bone_name
-
-
-
- # setup child drivers on each new smaller bone added. assume 2 for now.
+ con.subtarget = control
+
+ con = pb[org_f1].constraints.new('COPY_TRANSFORMS')
+ con.target = obj
+ con.subtarget = f1
+
+ con = pb[org_f2].constraints.new('COPY_TRANSFORMS')
+ con.target = obj
+ con.subtarget = f2
+
+ con = pb[org_f3].constraints.new('COPY_TRANSFORMS')
+ con.target = obj
+ con.subtarget = f3
+
+ if make_hinge:
+ con = pb[hinge].constraints.new('COPY_TRANSFORMS')
+ con.target = obj
+ con.subtarget = bb[org_f1].parent.name
+
+ hinge_driver_path = pb[control].path_to_id() + '["hinge"]'
+
+ fcurve = con.driver_add("influence", 0)
+ driver = fcurve.driver
+ var = driver.variables.new()
+ driver.type = 'AVERAGE'
+ var.name = "var"
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = hinge_driver_path
- # drives the bones
- controller_path = control_pbone.path_to_id() # 'pose.bones["%s"]' % control_bone_name
+ mod = fcurve.modifiers[0]
+ mod.poly_order = 1
+ mod.coefficients[0] = 1.0
+ mod.coefficients[1] = -1.0
+
+ con = pb[control].constraints.new('COPY_LOCATION')
+ con.target = obj
+ con.subtarget = socket
+
+ # Create the drivers for the driver bones (control bone scale rotates driver bones)
+ controller_path = pb[control].path_to_id() # 'pose.bones["%s"]' % control_bone_name
i = 0
- for child_bone_name, driver_bone_name in driver_bone_pairs:
+ for bone in [df2, df3]:
# XXX - todo, any number
if i == 2:
break
- driver_pbone = obj.pose.bones[driver_bone_name]
+ pbone = pb[bone]
- driver_pbone.rotation_mode = 'YZX'
- fcurve_driver = driver_pbone.driver_add("rotation_euler", 0)
+ pbone.rotation_mode = 'YZX'
+ fcurve_driver = pbone.driver_add("rotation_euler", 0)
#obj.driver_add('pose.bones["%s"].scale', 1)
#obj.animation_data.drivers[-1] # XXX, WATCH THIS
@@ -272,24 +340,18 @@ def main(obj, bone_definition, base_names, options):
elif i == 1:
driver.expression = '(-scale+1.0)*pi*2.0*br'
- child_pbone = obj.pose.bones[child_bone_name]
-
- # only allow X rotation
- driver_pbone.lock_rotation = child_pbone.lock_rotation = (False, True, True)
-
i += 1
-
- # last step setup layers
+ # Last step setup layers
if "ex_layer" in options:
layer = [n==options["ex_layer"] for n in range(0,32)]
else:
layer = list(arm.bones[bone_definition[0]].layer)
- for child_bone_name, driver_bone_name in driver_bone_pairs:
- arm.bones[driver_bone_name].layer = layer
+ for bone_name in [f1, f2, f3]:
+ arm.bones[bone_name].layer = layer
layer = list(arm.bones[bone_definition[0]].layer)
- control_bbone.layer = layer
+ bb[control].layer = layer
# no blending the result of this
return None
diff --git a/release/scripts/modules/rigify/leg_biped.py b/release/scripts/modules/rigify/leg_biped.py
index 70be980d7b2..5c214cea362 100644
--- a/release/scripts/modules/rigify/leg_biped.py
+++ b/release/scripts/modules/rigify/leg_biped.py
@@ -219,6 +219,8 @@ def ik(obj, bone_definition, base_names, options):
ik.foot_roll_p.lock_rotation = False, True, True
ik_chain.toe_p.rotation_mode = 'YXZ'
ik_chain.toe_p.lock_rotation = False, True, True
+ ik_chain.toe_p.lock_location = True, True, True
+ ik.foot_roll_p.lock_location = True, True, True
# IK
con = ik_chain.shin_p.constraints.new('IK')
@@ -329,6 +331,7 @@ def fk(obj, bone_definition, base_names, options):
foot_p.rotation_mode = 'YXZ'
fk_chain.toe_p.rotation_mode = 'YXZ'
fk_chain.toe_p.lock_rotation = False, True, True
+ fk_chain.thigh_p.lock_location = True, True, True
con = fk_chain.thigh_p.constraints.new('COPY_LOCATION')
con.target = obj
@@ -336,7 +339,7 @@ def fk(obj, bone_definition, base_names, options):
# hinge
prop = rna_idprop_ui_prop_get(fk_chain.thigh_p, "hinge", create=True)
- fk_chain.thigh_p["hinge"] = 0.5
+ fk_chain.thigh_p["hinge"] = 0.0
prop["soft_min"] = 0.0
prop["soft_max"] = 1.0
@@ -441,6 +444,11 @@ def deform(obj, definitions, base_names, options):
con.target = obj
con.subtarget = definitions[2]
+ con = uleg1.constraints.new('COPY_SCALE')
+ con.name = "scale"
+ con.target = obj
+ con.subtarget = definitions[1]
+
con = uleg2.constraints.new('COPY_ROTATION')
con.name = "copy_rot"
con.target = obj
@@ -452,6 +460,11 @@ def deform(obj, definitions, base_names, options):
con.target = obj
con.subtarget = definitions[2]
+ con = lleg1.constraints.new('COPY_SCALE')
+ con.name = "copy_rot"
+ con.target = obj
+ con.subtarget = definitions[2]
+
con = lleg2.constraints.new('COPY_ROTATION')
con.name = "copy_rot"
con.target = obj
@@ -484,5 +497,5 @@ def main(obj, bone_definition, base_names, options):
deform(obj, bone_definition, base_names, options)
bpy.ops.object.mode_set(mode='OBJECT')
- blend_bone_list(obj, bone_definition + [None], bones_fk, bones_ik, target_bone=bones_ik[6], target_prop="ik", blend_default=0.0)
+ blend_bone_list(obj, bone_definition + [None], bones_fk, bones_ik, target_bone=bones_ik[6], target_prop="ik", blend_default=1.0)
diff --git a/release/scripts/modules/rigify/leg_quadruped.py b/release/scripts/modules/rigify/leg_quadruped.py
index 49a404aef33..d1f74ca28bf 100644
--- a/release/scripts/modules/rigify/leg_quadruped.py
+++ b/release/scripts/modules/rigify/leg_quadruped.py
@@ -19,6 +19,8 @@
# <pep8 compliant>
import bpy
+from rna_prop_ui import rna_idprop_ui_prop_get
+from math import pi
from rigify import RigifyError
from rigify_utils import bone_class_instance, copy_bone_simple, add_pole_target_bone, get_side_name, get_base_name
from Mathutils import Vector
@@ -104,6 +106,8 @@ def metarig_definition(obj, orig_bone_name):
def ik(obj, bone_definition, base_names, options):
+ eb = obj.data.edit_bones
+ pb = obj.pose.bones
arm = obj.data
bpy.ops.object.mode_set(mode='EDIT')
@@ -114,13 +118,14 @@ def ik(obj, bone_definition, base_names, options):
mt.attr_initialize(METARIG_NAMES, bone_definition)
mt_chain.attr_initialize(METARIG_NAMES, bone_definition)
- ik_chain = mt_chain.copy(to_fmt="%s", base_names=base_names)
+ ik_chain = mt_chain.copy(to_fmt="MCH-%s.ik", base_names=base_names)
ik_chain.thigh_e.connected = False
ik_chain.thigh_e.parent = mt.hips_e
ik_chain.foot_e.parent = None
- ik_chain.rename("foot", get_base_name(ik_chain.foot) + "_ik" + get_side_name(ik_chain.foot))
+ ik_chain.rename("foot", get_base_name(base_names[bone_definition[3]]) + "_ik" + get_side_name(base_names[bone_definition[3]]))
+ ik_chain.rename("toe", get_base_name(base_names[bone_definition[4]]) + "_ik" + get_side_name(base_names[bone_definition[4]]))
# keep the foot_ik as the parent
ik_chain.toe_e.connected = False
@@ -129,21 +134,29 @@ def ik(obj, bone_definition, base_names, options):
ik_chain.foot_e.align_orientation(mt_chain.toe_e)
# children of ik_foot
- ik = bone_class_instance(obj, ["foot_roll", "foot_roll_01", "foot_roll_02", "knee_target", "foot_target"])
-
- ik.knee_target = add_pole_target_bone(obj, mt_chain.shin, "knee_target" + get_side_name(base_names[mt_chain.foot])) #XXX - pick a better name
- ik.update()
- ik.knee_target_e.parent = mt.hips_e
+ ik = bone_class_instance(obj, ["foot_roll", "foot_roll_01", "foot_roll_02", "foot_target"])
+
+ # knee rotator
+ knee_rotator = copy_bone_simple(arm, mt_chain.toe, "knee_rotator" + get_side_name(base_names[mt_chain.foot]), parent=True).name
+ eb[knee_rotator].connected = False
+ eb[knee_rotator].parent = eb[mt.hips]
+ eb[knee_rotator].head = eb[ik_chain.thigh].head
+ eb[knee_rotator].tail = eb[knee_rotator].head + eb[mt_chain.toe].vector
+ eb[knee_rotator].length = eb[ik_chain.thigh].length / 2
+ eb[knee_rotator].roll += pi/2
+
+ # parent ik leg to the knee rotator
+ eb[ik_chain.thigh].parent = eb[knee_rotator]
# foot roll is an interesting one!
# plot a vector from the toe bones head, bactwards to the length of the foot
# then align it with the foot but reverse direction.
ik.foot_roll_e = copy_bone_simple(arm, mt_chain.toe, get_base_name(base_names[mt_chain.foot]) + "_roll" + get_side_name(base_names[mt_chain.foot]))
ik.foot_roll = ik.foot_roll_e.name
+ ik.foot_roll_e.connected = False
ik.foot_roll_e.parent = ik_chain.foot_e
- ik.foot_roll_e.translate(- (mt_chain.toe_e.vector.normalize() * mt_chain.foot_e.length))
- ik.foot_roll_e.align_orientation(mt_chain.foot_e)
- ik.foot_roll_e.tail = ik.foot_roll_e.head - ik.foot_roll_e.vector # flip
+ ik.foot_roll_e.head -= mt_chain.toe_e.vector.normalize() * mt_chain.foot_e.length
+ ik.foot_roll_e.tail = ik.foot_roll_e.head - (mt_chain.foot_e.vector.normalize() * mt_chain.toe_e.length)
ik.foot_roll_e.align_roll(mt_chain.foot_e.matrix.rotationPart() * Vector(0.0, 0.0, -1.0))
# MCH-foot
@@ -173,23 +186,74 @@ def ik(obj, bone_definition, base_names, options):
mt_chain.update()
ik.update()
ik_chain.update()
+
+ # Set rotation modes and axis locks
+ #pb[knee_rotator].rotation_mode = 'YXZ'
+ #pb[knee_rotator].lock_rotation = False, True, False
+ pb[knee_rotator].lock_location = True, True, True
+ pb[ik.foot_roll].rotation_mode = 'XYZ'
+ pb[ik.foot_roll].lock_rotation = False, True, True
+ pb[ik_chain.toe].rotation_mode = 'XYZ'
+ pb[ik_chain.toe].lock_rotation = False, True, True
+
+ # IK switch property
+ prop = rna_idprop_ui_prop_get(pb[ik_chain.foot], "ik", create=True)
+ pb[ik_chain.foot]["ik"] = 1.0
+ prop["soft_min"] = 0.0
+ prop["soft_max"] = 1.0
+ prop["min"] = 0.0
+ prop["max"] = 1.0
+
+ ik_driver_path = pb[ik_chain.foot].path_to_id() + '["ik"]'
# simple constraining of orig bones
con = mt_chain.thigh_p.constraints.new('COPY_TRANSFORMS')
con.target = obj
con.subtarget = ik_chain.thigh
+ fcurve = con.driver_add("influence", 0)
+ driver = fcurve.driver
+ var = driver.variables.new()
+ driver.type = 'AVERAGE'
+ var.name = "var"
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = ik_driver_path
con = mt_chain.shin_p.constraints.new('COPY_TRANSFORMS')
con.target = obj
con.subtarget = ik_chain.shin
+ fcurve = con.driver_add("influence", 0)
+ driver = fcurve.driver
+ var = driver.variables.new()
+ driver.type = 'AVERAGE'
+ var.name = "var"
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = ik_driver_path
con = mt_chain.foot_p.constraints.new('COPY_TRANSFORMS')
con.target = obj
con.subtarget = ik.foot_roll_02
+ fcurve = con.driver_add("influence", 0)
+ driver = fcurve.driver
+ var = driver.variables.new()
+ driver.type = 'AVERAGE'
+ var.name = "var"
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = ik_driver_path
con = mt_chain.toe_p.constraints.new('COPY_TRANSFORMS')
con.target = obj
con.subtarget = ik_chain.toe
+ fcurve = con.driver_add("influence", 0)
+ driver = fcurve.driver
+ var = driver.variables.new()
+ driver.type = 'AVERAGE'
+ var.name = "var"
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = ik_driver_path
# others...
con = ik.foot_roll_01_p.constraints.new('COPY_ROTATION')
@@ -211,8 +275,7 @@ def ik(obj, bone_definition, base_names, options):
con.target = obj
con.subtarget = ik.foot_target
- con.pole_target = obj
- con.pole_subtarget = ik.knee_target
+ con.pole_target = None
ik.update()
ik_chain.update()
@@ -226,12 +289,204 @@ def ik(obj, bone_definition, base_names, options):
obj.data.bones[getattr(ik_chain, attr)].layer = layer
for attr in ik.attr_names:
obj.data.bones[getattr(ik, attr)].layer = layer
+ obj.data.bones[knee_rotator].layer = layer
+
+ return None, ik_chain.thigh, ik_chain.shin, ik_chain.foot, ik_chain.toe
- return None, ik_chain.thigh, ik_chain.shin, ik_chain.foot, ik_chain.toe
+def fk(obj, bone_definition, base_names, options):
+ eb = obj.data.edit_bones
+ pb = obj.pose.bones
+ arm = obj.data
+ bpy.ops.object.mode_set(mode='EDIT')
+
+ # setup the existing bones, use names from METARIG_NAMES
+ mt = bone_class_instance(obj, ["hips"])
+ mt_chain = bone_class_instance(obj, ["thigh", "shin", "foot", "toe"])
+
+ mt.attr_initialize(METARIG_NAMES, bone_definition)
+ mt_chain.attr_initialize(METARIG_NAMES, bone_definition)
+
+ fk_chain = mt_chain.copy(to_fmt="%s", base_names=base_names)
+
+ # Create the socket
+ socket = copy_bone_simple(arm, mt_chain.thigh, "MCH-leg_socket").name
+ eb[socket].parent = eb[mt.hips]
+ eb[socket].length = eb[mt_chain.thigh].length / 4
+
+ # Create the hinge
+ hinge = copy_bone_simple(arm, mt.hips, "MCH-leg_hinge").name
+ eb[hinge].length = eb[mt.hips].length / 2
+
+ # Make leg child of hinge
+ eb[fk_chain.thigh].connected = False
+ eb[fk_chain.thigh].parent = eb[hinge]
+
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ # Set rotation modes and axis locks
+ pb[fk_chain.shin].rotation_mode = 'XYZ'
+ pb[fk_chain.shin].lock_rotation = False, True, True
+
+ # Constrain original bones to control bones
+ con = mt_chain.thigh_p.constraints.new('COPY_TRANSFORMS')
+ con.target = obj
+ con.subtarget = fk_chain.thigh
+
+ con = mt_chain.shin_p.constraints.new('COPY_TRANSFORMS')
+ con.target = obj
+ con.subtarget = fk_chain.shin
+
+ con = mt_chain.foot_p.constraints.new('COPY_TRANSFORMS')
+ con.target = obj
+ con.subtarget = fk_chain.foot
+
+ con = mt_chain.toe_p.constraints.new('COPY_TRANSFORMS')
+ con.target = obj
+ con.subtarget = fk_chain.toe
+
+ # Socket constraint
+ con = pb[fk_chain.thigh].constraints.new('COPY_LOCATION')
+ con.target = obj
+ con.subtarget = socket
+
+ # Hinge constraint
+ con = pb[hinge].constraints.new('COPY_TRANSFORMS')
+ con.target = obj
+ con.subtarget = mt.hips
+
+ prop = rna_idprop_ui_prop_get(pb[fk_chain.thigh], "hinge", create=True)
+ pb[fk_chain.thigh]["hinge"] = 0.0
+ prop["soft_min"] = 0.0
+ prop["soft_max"] = 1.0
+ prop["min"] = 0.0
+ prop["max"] = 1.0
+
+ hinge_driver_path = pb[fk_chain.thigh].path_to_id() + '["hinge"]'
+
+ fcurve = con.driver_add("influence", 0)
+ driver = fcurve.driver
+ var = driver.variables.new()
+ driver.type = 'AVERAGE'
+ var.name = "var"
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = hinge_driver_path
+
+ mod = fcurve.modifiers[0]
+ mod.poly_order = 1
+ mod.coefficients[0] = 1.0
+ mod.coefficients[1] = -1.0
+
+ return None, fk_chain.thigh, fk_chain.shin, fk_chain.foot, fk_chain.toe
+
+
+
+
+def deform(obj, definitions, base_names, options):
+ bpy.ops.object.mode_set(mode='EDIT')
+
+ # Create upper leg bones: two bones, each half of the upper leg.
+ uleg1 = copy_bone_simple(obj.data, definitions[1], "DEF-%s.01" % base_names[definitions[1]], parent=True)
+ uleg2 = copy_bone_simple(obj.data, definitions[1], "DEF-%s.02" % base_names[definitions[1]], parent=True)
+ uleg1.connected = False
+ uleg2.connected = False
+ uleg2.parent = uleg1
+ center = uleg1.center
+ uleg1.tail = center
+ uleg2.head = center
+
+ # Create lower leg bones: two bones, each half of the lower leg.
+ lleg1 = copy_bone_simple(obj.data, definitions[2], "DEF-%s.01" % base_names[definitions[2]], parent=True)
+ lleg2 = copy_bone_simple(obj.data, definitions[2], "DEF-%s.02" % base_names[definitions[2]], parent=True)
+ lleg1.connected = False
+ lleg2.connected = False
+ lleg2.parent = lleg1
+ center = lleg1.center
+ lleg1.tail = center
+ lleg2.head = center
+
+ # Create a bone for the second lower leg deform bone to twist with
+ twist = copy_bone_simple(obj.data, lleg2.name, "MCH-leg_twist")
+ twist.length /= 4
+ twist.connected = False
+ twist.parent = obj.data.edit_bones[definitions[3]]
+
+ # Create foot bone
+ foot = copy_bone_simple(obj.data, definitions[3], "DEF-%s" % base_names[definitions[3]], parent=True)
+
+ # Create toe bone
+ toe = copy_bone_simple(obj.data, definitions[4], "DEF-%s" % base_names[definitions[4]], parent=True)
+
+ # Store names before leaving edit mode
+ uleg1_name = uleg1.name
+ uleg2_name = uleg2.name
+ lleg1_name = lleg1.name
+ lleg2_name = lleg2.name
+ twist_name = twist.name
+ foot_name = foot.name
+ toe_name = toe.name
+
+ # Leave edit mode
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ # Get the pose bones
+ uleg1 = obj.pose.bones[uleg1_name]
+ uleg2 = obj.pose.bones[uleg2_name]
+ lleg1 = obj.pose.bones[lleg1_name]
+ lleg2 = obj.pose.bones[lleg2_name]
+ foot = obj.pose.bones[foot_name]
+ toe = obj.pose.bones[toe_name]
+
+ # Upper leg constraints
+ con = uleg1.constraints.new('DAMPED_TRACK')
+ con.name = "trackto"
+ con.target = obj
+ con.subtarget = definitions[2]
+
+ con = uleg2.constraints.new('COPY_ROTATION')
+ con.name = "copy_rot"
+ con.target = obj
+ con.subtarget = definitions[1]
+
+ # Lower leg constraints
+ con = lleg1.constraints.new('COPY_ROTATION')
+ con.name = "copy_rot"
+ con.target = obj
+ con.subtarget = definitions[2]
+
+ con = lleg2.constraints.new('COPY_ROTATION')
+ con.name = "copy_rot"
+ con.target = obj
+ con.subtarget = twist_name
+
+ con = lleg2.constraints.new('DAMPED_TRACK')
+ con.name = "trackto"
+ con.target = obj
+ con.subtarget = definitions[3]
+
+ # Foot constraint
+ con = foot.constraints.new('COPY_ROTATION')
+ con.name = "copy_rot"
+ con.target = obj
+ con.subtarget = definitions[3]
+
+ # Toe constraint
+ con = toe.constraints.new('COPY_ROTATION')
+ con.name = "copy_rot"
+ con.target = obj
+ con.subtarget = definitions[4]
+
+ bpy.ops.object.mode_set(mode='EDIT')
+ return (uleg1_name, uleg2_name, lleg1_name, lleg2_name, foot_name, toe_name, None)
+
+
def main(obj, bone_definition, base_names, options):
+ bones_fk = fk(obj, bone_definition, base_names, options)
bones_ik = ik(obj, bone_definition, base_names, options)
+ deform(obj, bone_definition, base_names, options)
return bones_ik
diff --git a/release/scripts/modules/rigify/mouth.py b/release/scripts/modules/rigify/mouth.py
index b22df918675..e2ca1ab4d0c 100644
--- a/release/scripts/modules/rigify/mouth.py
+++ b/release/scripts/modules/rigify/mouth.py
@@ -19,15 +19,69 @@
# <pep8 compliant>
import bpy
-from math import acos
+from rna_prop_ui import rna_idprop_ui_prop_get
+from math import acos, pi
from Mathutils import Vector
-from rigify import get_layer_dict
+from rigify import get_layer_dict, RigifyError
from rigify_utils import bone_class_instance, copy_bone_simple
#METARIG_NAMES = ("cpy",)
RIG_TYPE = "mouth"
+def mark_actions():
+ for action in bpy.data.actions:
+ action.tag = True
+
+def get_unmarked_action():
+ for action in bpy.data.actions:
+ if action.tag != True:
+ return action
+ return None
+
+def add_action(name=None):
+ mark_actions()
+ bpy.ops.action.new()
+ action = get_unmarked_action()
+ if name is not None:
+ action.name = name
+ return action
+
+def addget_shape_key(obj, name="Key"):
+ """ Fetches a shape key, or creates it if it doesn't exist
+ """
+ # Create a shapekey set if it doesn't already exist
+ if obj.data.shape_keys is None:
+ shape = obj.add_shape_key(name="Basis", from_mix=False)
+ obj.active_shape_key_index = 0
+
+ # Get the shapekey, or create it if it doesn't already exist
+ if name in obj.data.shape_keys.keys:
+ shape_key = obj.data.shape_keys.keys[name]
+ else:
+ shape_key = obj.add_shape_key(name=name, from_mix=False)
+
+ return shape_key
+
+
+def addget_shape_key_driver(obj, name="Key"):
+ """ Fetches the driver for the shape key, or creates it if it doesn't
+ already exist.
+ """
+ driver_path = 'keys["' + name + '"].value'
+ fcurve = None
+ driver = None
+ if obj.data.shape_keys.animation_data is not None:
+ for driver_s in obj.data.shape_keys.animation_data.drivers:
+ if driver_s.data_path == driver_path:
+ fcurve = driver_s
+ if fcurve == None:
+ fcurve = obj.data.shape_keys.keys[name].driver_add("value", 0)
+ fcurve.driver.type = 'AVERAGE'
+
+ return fcurve
+
+
def metarig_template():
# generated by rigify.write_meta_rig
bpy.ops.object.mode_set(mode='EDIT')
@@ -49,7 +103,7 @@ def metarig_definition(obj, orig_bone_name):
chain = []
try:
- chain += [bone.parent.name, bone.parent.parent.name, bone.name]
+ chain += [bone.parent.parent.name, bone.parent.name, bone.name]
except AttributeError:
raise RigifyError("'%s' rig type requires a chain of two parents (bone: %s)" % (RIG_TYPE, base_names[0]))
@@ -67,62 +121,70 @@ def deform(obj, definitions, base_names, options):
eb = obj.data.edit_bones
pb = obj.pose.bones
+ print("YAHOO")
+
+ # Options
+ req_options = ["mesh"]
+ for option in req_options:
+ if option not in options:
+ raise RigifyError("'%s' rig type requires a '%s' option (bone: %s)" % (RIG_TYPE, option, base_names[definitions[0]]))
+
+ print("YAHOO2")
+
+ meshes = options["mesh"].replace(" ", "").split(",")
+
# Upper lip MCH
- lip1 = make_lip_stretch_bone(obj, "MCH-lip", definitions[2], definitions[3], 1.0)
- lip2 = make_lip_stretch_bone(obj, "MCH-lip", definitions[3], definitions[4], 1.0)
- lip22 = make_lip_stretch_bone(obj, "MCH-lip", definitions[4], definitions[5], 1.0)
- lip33 = make_lip_stretch_bone(obj, "MCH-lip", definitions[4], definitions[3], 1.0)
- lip3 = make_lip_stretch_bone(obj, "MCH-lip", definitions[5], definitions[4], 1.0)
- lip4 = make_lip_stretch_bone(obj, "MCH-lip", definitions[6], definitions[5], 1.0)
-
- dlip22 = copy_bone_simple(obj.data, lip22, "MCH-lip", parent=True).name
- dlip33 = copy_bone_simple(obj.data, lip33, "MCH-lip", parent=True).name
- eb[dlip22].bbone_segments = 8
- eb[dlip33].bbone_segments = 8
-
- eb[lip1].parent = eb[definitions[2]]
- eb[lip2].parent = eb[definitions[3]]
- eb[lip22].parent = eb[definitions[4]]
- eb[lip33].parent = eb[definitions[4]]
- eb[lip3].parent = eb[definitions[5]]
- eb[lip4].parent = eb[definitions[6]]
+ lip1 = make_lip_stretch_bone(obj, "MCH-lip", definitions[3], definitions[2], 0.0)
+ lip2 = make_lip_stretch_bone(obj, "MCH-lip", definitions[4], definitions[3], 0.0)
+ lip22 = make_lip_stretch_bone(obj, "MCH-lip", definitions[5], definitions[4], 0.0)
+ lip33 = make_lip_stretch_bone(obj, "MCH-lip", definitions[3], definitions[4], 0.0)
+ lip3 = make_lip_stretch_bone(obj, "MCH-lip", definitions[4], definitions[5], 0.0)
+ lip4 = make_lip_stretch_bone(obj, "MCH-lip", definitions[5], definitions[6], 0.0)
+
+ eb[lip1].parent = eb[definitions[3]]
+ eb[lip2].parent = eb[definitions[4]]
+ eb[lip22].parent = eb[definitions[5]]
+ eb[lip33].parent = eb[definitions[3]]
+ eb[lip3].parent = eb[definitions[4]]
+ eb[lip4].parent = eb[definitions[5]]
+
+ eb[lip22].bbone_segments = 8
+ eb[lip33].bbone_segments = 8
# Lower lip MCH
- lip5 = make_lip_stretch_bone(obj, "MCH-lip", definitions[6], definitions[7], 1.0)
- lip6 = make_lip_stretch_bone(obj, "MCH-lip", definitions[7], definitions[8], 1.0)
- lip66 = make_lip_stretch_bone(obj, "MCH-lip", definitions[8], definitions[9], 1.0)
- lip77 = make_lip_stretch_bone(obj, "MCH-lip", definitions[8], definitions[7], 1.0)
- lip7 = make_lip_stretch_bone(obj, "MCH-lip", definitions[9], definitions[8], 1.0)
- lip8 = make_lip_stretch_bone(obj, "MCH-lip", definitions[2], definitions[9], 1.0)
-
- dlip66 = copy_bone_simple(obj.data, lip66, "MCH-lip", parent=True).name
- dlip77 = copy_bone_simple(obj.data, lip77, "MCH-lip", parent=True).name
- eb[dlip66].bbone_segments = 8
- eb[dlip77].bbone_segments = 8
-
- eb[lip5].parent = eb[definitions[6]]
- eb[lip6].parent = eb[definitions[7]]
- eb[lip66].parent = eb[definitions[8]]
- eb[lip77].parent = eb[definitions[8]]
- eb[lip7].parent = eb[definitions[9]]
- eb[lip8].parent = eb[definitions[2]]
+ lip5 = make_lip_stretch_bone(obj, "MCH-lip", definitions[7], definitions[6], 0.0)
+ lip6 = make_lip_stretch_bone(obj, "MCH-lip", definitions[8], definitions[7], 0.0)
+ lip66 = make_lip_stretch_bone(obj, "MCH-lip", definitions[9], definitions[8], 0.0)
+ lip77 = make_lip_stretch_bone(obj, "MCH-lip", definitions[7], definitions[8], 0.0)
+ lip7 = make_lip_stretch_bone(obj, "MCH-lip", definitions[8], definitions[9], 0.0)
+ lip8 = make_lip_stretch_bone(obj, "MCH-lip", definitions[9], definitions[2], 0.0)
+
+ eb[lip5].parent = eb[definitions[7]]
+ eb[lip6].parent = eb[definitions[8]]
+ eb[lip66].parent = eb[definitions[9]]
+ eb[lip77].parent = eb[definitions[7]]
+ eb[lip7].parent = eb[definitions[8]]
+ eb[lip8].parent = eb[definitions[9]]
+
+ eb[lip66].bbone_segments = 8
+ eb[lip77].bbone_segments = 8
# Upper lip DEF
- dlip1 = copy_bone_simple(obj.data, lip1, "DEF-lip", parent=True).name
- dlip2 = copy_bone_simple(obj.data, lip2, "DEF-lip", parent=True).name
- dlip3 = copy_bone_simple(obj.data, lip3, "DEF-lip", parent=True).name
- dlip4 = copy_bone_simple(obj.data, lip4, "DEF-lip", parent=True).name
+ dlip1 = copy_bone_simple(obj.data, lip1, "DEF-" + base_names[definitions[4]] + ".01.R", parent=True).name
+ dlip2 = copy_bone_simple(obj.data, lip2, "DEF-" + base_names[definitions[4]] + ".02.R", parent=True).name
+ dlip3 = copy_bone_simple(obj.data, lip3, "DEF-" + base_names[definitions[4]] + ".02.L", parent=True).name
+ dlip4 = copy_bone_simple(obj.data, lip4, "DEF-" + base_names[definitions[4]] + ".01.L", parent=True).name
- eb[dlip2].parent = eb[dlip1]
- eb[dlip22].parent = eb[dlip2]
+ eb[dlip1].parent = eb[dlip2]
+ eb[dlip2].parent = eb[lip22]
- eb[dlip3].parent = eb[dlip4]
- eb[dlip33].parent = eb[dlip3]
+ eb[dlip4].parent = eb[dlip3]
+ eb[dlip3].parent = eb[lip33]
- eb[dlip2].connected = True
- eb[dlip22].connected = True
- eb[dlip3].connected = True
- eb[dlip33].connected = True
+ eb[dlip1].connected = True
+ eb[dlip2].connected = True
+ eb[dlip4].connected = True
+ eb[dlip3].connected = True
eb[dlip1].bbone_segments = 8
eb[dlip2].bbone_segments = 8
@@ -130,43 +192,37 @@ def deform(obj, definitions, base_names, options):
eb[dlip4].bbone_segments = 8
# Lower lip DEF
- dlip5 = copy_bone_simple(obj.data, lip5, "DEF-lip", parent=True).name
- dlip6 = copy_bone_simple(obj.data, lip6, "DEF-lip", parent=True).name
- dlip7 = copy_bone_simple(obj.data, lip7, "DEF-lip", parent=True).name
- dlip8 = copy_bone_simple(obj.data, lip8, "DEF-lip", parent=True).name
+ dlip8 = copy_bone_simple(obj.data, lip8, "DEF-" + base_names[definitions[8]] + ".01.R", parent=True).name
+ dlip7 = copy_bone_simple(obj.data, lip7, "DEF-" + base_names[definitions[8]] + ".02.R", parent=True).name
+ dlip6 = copy_bone_simple(obj.data, lip6, "DEF-" + base_names[definitions[8]] + ".02.L", parent=True).name
+ dlip5 = copy_bone_simple(obj.data, lip5, "DEF-" + base_names[definitions[8]] + ".01.L", parent=True).name
- eb[dlip6].parent = eb[dlip5]
- eb[dlip66].parent = eb[dlip6]
- eb[dlip7].parent = eb[dlip8]
- eb[dlip77].parent = eb[dlip7]
+ eb[dlip5].parent = eb[dlip6]
+ eb[dlip6].parent = eb[lip66]
+ eb[dlip8].parent = eb[dlip7]
+ eb[dlip7].parent = eb[lip77]
+
+ eb[dlip5].connected = True
eb[dlip6].connected = True
- eb[dlip66].connected = True
+ eb[dlip8].connected = True
eb[dlip7].connected = True
- eb[dlip77].connected = True
eb[dlip5].bbone_segments = 8
eb[dlip6].bbone_segments = 8
eb[dlip7].bbone_segments = 8
eb[dlip8].bbone_segments = 8
-
+ print("OBJECT MODE1")
bpy.ops.object.mode_set(mode='OBJECT')
+ print("OBJECT MODE2")
# Constraints
con = pb[dlip1].constraints.new('COPY_TRANSFORMS')
con.target = obj
con.subtarget = lip1
- con = pb[dlip22].constraints.new('COPY_TRANSFORMS')
- con.target = obj
- con.subtarget = lip22
-
- con = pb[dlip33].constraints.new('COPY_TRANSFORMS')
- con.target = obj
- con.subtarget = lip33
-
con = pb[dlip2].constraints.new('COPY_TRANSFORMS')
con.target = obj
con.subtarget = lip2
@@ -187,14 +243,6 @@ def deform(obj, definitions, base_names, options):
con.target = obj
con.subtarget = lip6
- con = pb[dlip66].constraints.new('COPY_TRANSFORMS')
- con.target = obj
- con.subtarget = lip66
-
- con = pb[dlip77].constraints.new('COPY_TRANSFORMS')
- con.target = obj
- con.subtarget = lip77
-
con = pb[dlip7].constraints.new('COPY_TRANSFORMS')
con.target = obj
con.subtarget = lip7
@@ -203,6 +251,90 @@ def deform(obj, definitions, base_names, options):
con.target = obj
con.subtarget = lip8
+ # Corrective shape keys for the corners of the mouth.
+ bpy.ops.object.mode_set(mode='EDIT')
+
+ # Calculate the rotation difference between the bones
+ rotdiff_r = acos(eb[lip1].matrix.toQuat() * eb[lip8].matrix.toQuat()) * 2
+ rotdiff_l = acos(eb[lip4].matrix.toQuat() * eb[lip5].matrix.toQuat()) * 2
+
+ print (rotdiff_l)
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+
+
+ # Left side
+ for mesh_name in meshes:
+ mesh_obj = bpy.data.objects[mesh_name]
+ shape_key_name = "COR-" + base_names[definitions[4]] + ".L.spread"
+
+ # Add/get the shape key
+ shape_key = addget_shape_key(mesh_obj, name=shape_key_name)
+
+ # Add/get the shape key driver
+ fcurve = addget_shape_key_driver(mesh_obj, name=shape_key_name)
+ driver = fcurve.driver
+
+ # Get the variable, or create it if it doesn't already exist
+ var_name = base_names[definitions[6]]
+ if var_name in driver.variables:
+ var = driver.variables[var_name]
+ else:
+ var = driver.variables.new()
+ var.name = var_name
+
+ # Set up the variable
+ var.type = "ROTATION_DIFF"
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].bone_target = lip4
+ var.targets[1].id_type = 'OBJECT'
+ var.targets[1].id = obj
+ var.targets[1].bone_target = lip5
+
+ # Set fcurve offset
+ mod = fcurve.modifiers[0]
+ if rotdiff_l != pi:
+ mod.coefficients[0] = -rotdiff_l / (pi-rotdiff_l)
+ mod.coefficients[1] = 1 / (pi-rotdiff_l)
+
+ # Right side
+ for mesh_name in meshes:
+ mesh_obj = bpy.data.objects[mesh_name]
+ shape_key_name = "COR-" + base_names[definitions[4]] + ".R.spread"
+
+ # Add/get the shape key
+ shape_key = addget_shape_key(mesh_obj, name=shape_key_name)
+
+ # Add/get the shape key driver
+ fcurve = addget_shape_key_driver(mesh_obj, name=shape_key_name)
+ driver = fcurve.driver
+
+ # Get the variable, or create it if it doesn't already exist
+ var_name = base_names[definitions[2]]
+ if var_name in driver.variables:
+ var = driver.variables[var_name]
+ else:
+ var = driver.variables.new()
+ var.name = var_name
+
+ # Set up the variable
+ var.type = "ROTATION_DIFF"
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].bone_target = lip1
+ var.targets[1].id_type = 'OBJECT'
+ var.targets[1].id = obj
+ var.targets[1].bone_target = lip8
+
+ # Set fcurve offset
+ mod = fcurve.modifiers[0]
+ if rotdiff_r != pi:
+ mod.coefficients[0] = -rotdiff_r / (pi-rotdiff_r)
+ mod.coefficients[1] = 1 / (pi-rotdiff_r)
+
+
return (None,)
@@ -217,6 +349,7 @@ def control(obj, definitions, base_names, options):
head_e = eb[definitions[0]]
jaw_e = eb[definitions[1]]
+ jaw = definitions[1]
# Head lips
hlip1 = copy_bone_simple(obj.data, definitions[2], "MCH-"+base_names[definitions[2]]+".head").name
@@ -285,14 +418,14 @@ def control(obj, definitions, base_names, options):
eb[lip7].roll = 0
eb[lip8].roll = 0
- eb[lip1].parent = eb[jlip1]
- eb[lip2].parent = eb[jlip2]
- eb[lip3].parent = eb[jlip3]
- eb[lip4].parent = eb[jlip4]
- eb[lip5].parent = eb[jlip5]
- eb[lip6].parent = eb[jlip6]
- eb[lip7].parent = eb[jlip7]
- eb[lip8].parent = eb[jlip8]
+ eb[lip1].parent = eb[hlip1]
+ eb[lip2].parent = eb[hlip2]
+ eb[lip3].parent = eb[hlip3]
+ eb[lip4].parent = eb[hlip4]
+ eb[lip5].parent = eb[hlip5]
+ eb[lip6].parent = eb[hlip6]
+ eb[lip7].parent = eb[hlip7]
+ eb[lip8].parent = eb[hlip8]
# Link lips
llip1 = copy_bone_simple(obj.data, definitions[2], "MCH-"+base_names[definitions[2]]+".link").name
@@ -313,53 +446,84 @@ def control(obj, definitions, base_names, options):
eb[llip7].parent = eb[lip7]
eb[llip8].parent = eb[lip8]
+ # Jaw open tracker
+ jopent = copy_bone_simple(obj.data, jaw_e.name, "MCH-"+base_names[jaw_e.name]+".track", parent=True).name
+ eb[jopent].connected = False
+ eb[jopent].tail = jaw_e.tail + Vector(0,0,jaw_e.length)
+ eb[jopent].head = jaw_e.tail
bpy.ops.object.mode_set(mode='OBJECT')
+ # Add eye close action if it doesn't already exist
+ action_name = "mouth_open"
+ if action_name in bpy.data.actions:
+ open_action = bpy.data.actions[action_name]
+ else:
+ open_action = add_action(name=action_name)
+
+ # Add close property (useful when making the animation in the action)
+ prop_name = "open_action"
+ prop = rna_idprop_ui_prop_get(pb[lip1], prop_name, create=True)
+ pb[lip1][prop_name] = 1.0
+ prop["soft_min"] = 0.0
+ prop["soft_max"] = 1.0
+ prop["min"] = 0.0
+ prop["max"] = 1.0
+
+ open_driver_path = pb[lip1].path_to_id() + '["open_action"]'
+
# Constraints
- # Jaw lips to head lips
- influence = [0.0, 0.1, 0.5]
+ # Jaw open tracker stretches to jaw tip
+ con = pb[jopent].constraints.new('STRETCH_TO')
+ con.target = obj
+ con.subtarget = jaw
+ con.head_tail = 1.0
+ con.original_length = bb[jopent].length
+ con.volume = 'NO_VOLUME'
+
+ # Head lips to jaw lips
+ influence = [0.0, 0.1, 0.5, 0.25, 0.0]
- con = pb[jlip1].constraints.new('COPY_TRANSFORMS')
+ con = pb[hlip1].constraints.new('COPY_TRANSFORMS')
con.target = obj
- con.subtarget = hlip1
+ con.subtarget = jlip1
con.influence = influence[2]
- con = pb[jlip2].constraints.new('COPY_TRANSFORMS')
+ con = pb[hlip2].constraints.new('COPY_TRANSFORMS')
con.target = obj
- con.subtarget = hlip2
+ con.subtarget = jlip2
con.influence = influence[1]
- con = pb[jlip3].constraints.new('COPY_TRANSFORMS')
+ con = pb[hlip3].constraints.new('COPY_TRANSFORMS')
con.target = obj
- con.subtarget = hlip3
+ con.subtarget = jlip3
con.influence = influence[0]
- con = pb[jlip4].constraints.new('COPY_TRANSFORMS')
+ con = pb[hlip4].constraints.new('COPY_TRANSFORMS')
con.target = obj
- con.subtarget = hlip4
+ con.subtarget = jlip4
con.influence = influence[1]
- con = pb[jlip5].constraints.new('COPY_TRANSFORMS')
+ con = pb[hlip5].constraints.new('COPY_TRANSFORMS')
con.target = obj
- con.subtarget = hlip5
+ con.subtarget = jlip5
con.influence = influence[2]
- con = pb[jlip6].constraints.new('COPY_TRANSFORMS')
+ con = pb[hlip6].constraints.new('COPY_TRANSFORMS')
con.target = obj
- con.subtarget = hlip6
- con.influence = 1.0 - influence[1]
+ con.subtarget = jlip6
+ con.influence = 1.0 - influence[3]
- con = pb[jlip7].constraints.new('COPY_TRANSFORMS')
+ con = pb[hlip7].constraints.new('COPY_TRANSFORMS')
con.target = obj
- con.subtarget = hlip7
- con.influence = 1.0 - influence[0]
+ con.subtarget = jlip7
+ con.influence = 1.0 - influence[4]
- con = pb[jlip8].constraints.new('COPY_TRANSFORMS')
+ con = pb[hlip8].constraints.new('COPY_TRANSFORMS')
con.target = obj
- con.subtarget = hlip8
- con.influence = 1.0 - influence[1]
+ con.subtarget = jlip8
+ con.influence = 1.0 - influence[3]
# ORG bones to link lips
con = pb[definitions[2]].constraints.new('COPY_TRANSFORMS')
@@ -394,6 +558,151 @@ def control(obj, definitions, base_names, options):
con.target = obj
con.subtarget = llip8
+ # Action constraints for open mouth
+ con = pb[lip1].constraints.new('ACTION')
+ con.target = obj
+ con.subtarget = jopent
+ con.action = open_action
+ con.transform_channel = 'SCALE_Y'
+ con.start_frame = 0
+ con.end_frame = 60
+ con.minimum = 0.0
+ con.maximum = 1.0
+ con.target_space = 'LOCAL'
+ fcurve = con.driver_add("influence", 0)
+ driver = fcurve.driver
+ driver.type = 'AVERAGE'
+ var = driver.variables.new()
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = open_driver_path
+
+ con = pb[lip2].constraints.new('ACTION')
+ con.target = obj
+ con.subtarget = jopent
+ con.action = open_action
+ con.transform_channel = 'SCALE_Y'
+ con.start_frame = 0
+ con.end_frame = 60
+ con.minimum = 0.0
+ con.maximum = 1.0
+ con.target_space = 'LOCAL'
+ fcurve = con.driver_add("influence", 0)
+ driver = fcurve.driver
+ driver.type = 'AVERAGE'
+ var = driver.variables.new()
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = open_driver_path
+
+ con = pb[lip3].constraints.new('ACTION')
+ con.target = obj
+ con.subtarget = jopent
+ con.action = open_action
+ con.transform_channel = 'SCALE_Y'
+ con.start_frame = 0
+ con.end_frame = 60
+ con.minimum = 0.0
+ con.maximum = 1.0
+ con.target_space = 'LOCAL'
+ fcurve = con.driver_add("influence", 0)
+ driver = fcurve.driver
+ driver.type = 'AVERAGE'
+ var = driver.variables.new()
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = open_driver_path
+
+ con = pb[lip4].constraints.new('ACTION')
+ con.target = obj
+ con.subtarget = jopent
+ con.action = open_action
+ con.transform_channel = 'SCALE_Y'
+ con.start_frame = 0
+ con.end_frame = 60
+ con.minimum = 0.0
+ con.maximum = 1.0
+ con.target_space = 'LOCAL'
+ fcurve = con.driver_add("influence", 0)
+ driver = fcurve.driver
+ driver.type = 'AVERAGE'
+ var = driver.variables.new()
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = open_driver_path
+
+ con = pb[lip5].constraints.new('ACTION')
+ con.target = obj
+ con.subtarget = jopent
+ con.action = open_action
+ con.transform_channel = 'SCALE_Y'
+ con.start_frame = 0
+ con.end_frame = 60
+ con.minimum = 0.0
+ con.maximum = 1.0
+ con.target_space = 'LOCAL'
+ fcurve = con.driver_add("influence", 0)
+ driver = fcurve.driver
+ driver.type = 'AVERAGE'
+ var = driver.variables.new()
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = open_driver_path
+
+ con = pb[lip6].constraints.new('ACTION')
+ con.target = obj
+ con.subtarget = jopent
+ con.action = open_action
+ con.transform_channel = 'SCALE_Y'
+ con.start_frame = 0
+ con.end_frame = 60
+ con.minimum = 0.0
+ con.maximum = 1.0
+ con.target_space = 'LOCAL'
+ fcurve = con.driver_add("influence", 0)
+ driver = fcurve.driver
+ driver.type = 'AVERAGE'
+ var = driver.variables.new()
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = open_driver_path
+
+ con = pb[lip7].constraints.new('ACTION')
+ con.target = obj
+ con.subtarget = jopent
+ con.action = open_action
+ con.transform_channel = 'SCALE_Y'
+ con.start_frame = 0
+ con.end_frame = 60
+ con.minimum = 0.0
+ con.maximum = 1.0
+ con.target_space = 'LOCAL'
+ fcurve = con.driver_add("influence", 0)
+ driver = fcurve.driver
+ driver.type = 'AVERAGE'
+ var = driver.variables.new()
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = open_driver_path
+
+ con = pb[lip8].constraints.new('ACTION')
+ con.target = obj
+ con.subtarget = jopent
+ con.action = open_action
+ con.transform_channel = 'SCALE_Y'
+ con.start_frame = 0
+ con.end_frame = 60
+ con.minimum = 0.0
+ con.maximum = 1.0
+ con.target_space = 'LOCAL'
+ fcurve = con.driver_add("influence", 0)
+ driver = fcurve.driver
+ driver.type = 'AVERAGE'
+ var = driver.variables.new()
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = open_driver_path
+
# Set layers
layer = list(bb[definitions[2]].layer)
@@ -414,9 +723,12 @@ def control(obj, definitions, base_names, options):
def main(obj, bone_definition, base_names, options):
# Create control rig
+ print("CONTROL")
control(obj, bone_definition, base_names, options)
+ print("DEFORM")
# Create deform rig
deform(obj, bone_definition, base_names, options)
+ print("DONE")
return (None,)
diff --git a/release/scripts/modules/rigify/neck_flex.py b/release/scripts/modules/rigify/neck_flex.py
index f9b7a9ae99d..d26510f49b2 100644
--- a/release/scripts/modules/rigify/neck_flex.py
+++ b/release/scripts/modules/rigify/neck_flex.py
@@ -213,6 +213,9 @@ def main(obj, bone_definition, base_names, options):
ex_chain.update()
ex.update()
+ # Axis locks
+ ex.head_ctrl_p.lock_location = True, True, True
+
# Simple one off constraints, no drivers
con = ex.head_ctrl_p.constraints.new('COPY_LOCATION')
con.target = obj
diff --git a/release/scripts/modules/rigify/palm_curl.py b/release/scripts/modules/rigify/palm_curl.py
index 9e60bc9dc22..b231919823b 100644
--- a/release/scripts/modules/rigify/palm_curl.py
+++ b/release/scripts/modules/rigify/palm_curl.py
@@ -152,6 +152,7 @@ def main(obj, bone_definition, base_names, options):
control_pbone.rotation_mode = 'YZX'
control_pbone.lock_rotation = False, True, True
+ control_pbone.lock_location = True, True, True
driver_fcurves = pinky_pbone.driver_add("rotation_euler")
@@ -163,6 +164,8 @@ def main(obj, bone_definition, base_names, options):
prop = rna_idprop_ui_prop_get(control_pbone, "spread", create=True)
prop["soft_min"] = -1.0
prop["soft_max"] = 1.0
+ prop["min"] = -1.0
+ prop["max"] = 1.0
# *****
diff --git a/release/scripts/modules/rigify/shape_key_distance.py b/release/scripts/modules/rigify/shape_key_distance.py
new file mode 100644
index 00000000000..7701e725ea9
--- /dev/null
+++ b/release/scripts/modules/rigify/shape_key_distance.py
@@ -0,0 +1,176 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+import bpy
+from rna_prop_ui import rna_idprop_ui_prop_get
+from math import acos
+from Mathutils import Vector
+from rigify import get_layer_dict
+from rigify_utils import bone_class_instance, copy_bone_simple
+
+#METARIG_NAMES = ("cpy",)
+RIG_TYPE = "shape_key_distance"
+
+
+def addget_shape_key(obj, name="Key"):
+ """ Fetches a shape key, or creates it if it doesn't exist
+ """
+ # Create a shapekey set if it doesn't already exist
+ if obj.data.shape_keys is None:
+ shape = obj.add_shape_key(name="Basis", from_mix=False)
+ obj.active_shape_key_index = 0
+
+ # Get the shapekey, or create it if it doesn't already exist
+ if name in obj.data.shape_keys.keys:
+ shape_key = obj.data.shape_keys.keys[name]
+ else:
+ shape_key = obj.add_shape_key(name=name, from_mix=False)
+
+ return shape_key
+
+
+def addget_shape_key_driver(obj, name="Key"):
+ """ Fetches the driver for the shape key, or creates it if it doesn't
+ already exist.
+ """
+ driver_path = 'keys["' + name + '"].value'
+ fcurve = None
+ driver = None
+ if obj.data.shape_keys.animation_data is not None:
+ for driver_s in obj.data.shape_keys.animation_data.drivers:
+ if driver_s.data_path == driver_path:
+ fcurve = driver_s
+ if fcurve == None:
+ fcurve = obj.data.shape_keys.keys[name].driver_add("value", 0)
+ fcurve.driver.type = 'AVERAGE'
+
+ return fcurve
+
+
+
+
+def metarig_template():
+ # generated by rigify.write_meta_rig
+ bpy.ops.object.mode_set(mode='EDIT')
+ obj = bpy.context.active_object
+ arm = obj.data
+ bone = arm.edit_bones.new('Bone')
+ bone.head[:] = 0.0000, 0.0000, 0.0000
+ bone.tail[:] = 0.0000, 0.0000, 1.0000
+ bone.roll = 0.0000
+ bone.connected = False
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+ pbone = obj.pose.bones['Bone']
+ pbone['type'] = 'copy'
+
+
+def metarig_definition(obj, orig_bone_name):
+ bone = obj.data.bones[orig_bone_name]
+ return [bone.name]
+
+
+def deform(obj, definitions, base_names, options):
+ bpy.ops.object.mode_set(mode='EDIT')
+ eb = obj.data.edit_bones
+
+ bone_from = definitions[0]
+
+
+ # Options
+ req_options = ["to", "mesh", "shape_key"]
+ for option in req_options:
+ if option not in options:
+ raise RigifyError("'%s' rig type requires a '%s' option (bone: %s)" % (RIG_TYPE, option, base_names[definitions[0]]))
+
+ bone_to = "ORG-" + options["to"]
+ meshes = options["mesh"].replace(" ", "").split(",")
+ shape_key_name = options["shape_key"]
+
+ if "dmul" in options:
+ shape_blend_fac = options["dmul"]
+ else:
+ shape_blend_fac = 1.0
+
+
+ # Calculate the distance between the bones
+ distance = (eb[bone_from].head - eb[bone_to].head).length
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ # For every listed mesh object
+ for mesh_name in meshes:
+ mesh_obj = bpy.data.objects[mesh_name]
+
+ # Add/get the shape key
+ shape_key = addget_shape_key(mesh_obj, name=shape_key_name)
+
+ # Add/get the shape key driver
+ fcurve = addget_shape_key_driver(mesh_obj, name=shape_key_name)
+ driver = fcurve.driver
+
+ # Get the variable, or create it if it doesn't already exist
+ var_name = base_names[bone_from]
+ if var_name in driver.variables:
+ var = driver.variables[var_name]
+ else:
+ var = driver.variables.new()
+ var.name = var_name
+
+ # Set up the variable
+ var.type = "LOC_DIFF"
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].bone_target = bone_from
+ var.targets[1].id_type = 'OBJECT'
+ var.targets[1].id = obj
+ var.targets[1].bone_target = bone_to
+
+ # Set fcurve offset, so zero is at the rest distance
+
+ mod = fcurve.modifiers[0]
+ if distance > 0.00001:
+ mod.coefficients[0] = -shape_blend_fac
+ mod.coefficients[1] = shape_blend_fac / distance
+
+ return (None,)
+
+
+
+
+def control(obj, definitions, base_names, options):
+ """ options:
+ mesh: name of mesh object with the shape key
+ shape_key: name of shape key
+ to: name of bone to measure distance from
+ """
+ pass
+
+
+
+
+def main(obj, bone_definition, base_names, options):
+ # Create control rig
+ #control(obj, bone_definition, base_names, options)
+ # Create deform rig
+ deform(obj, bone_definition, base_names, options)
+
+ return (None,)
+
diff --git a/release/scripts/modules/rigify/shape_key_rotdiff.py b/release/scripts/modules/rigify/shape_key_rotdiff.py
new file mode 100644
index 00000000000..98ab1bd16b7
--- /dev/null
+++ b/release/scripts/modules/rigify/shape_key_rotdiff.py
@@ -0,0 +1,176 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+import bpy
+from rna_prop_ui import rna_idprop_ui_prop_get
+from math import acos
+from Mathutils import Vector
+from rigify import get_layer_dict
+from rigify_utils import bone_class_instance, copy_bone_simple
+
+#METARIG_NAMES = ("cpy",)
+RIG_TYPE = "shape_key_rotdiff"
+
+
+def addget_shape_key(obj, name="Key"):
+ """ Fetches a shape key, or creates it if it doesn't exist
+ """
+ # Create a shapekey set if it doesn't already exist
+ if obj.data.shape_keys is None:
+ shape = obj.add_shape_key(name="Basis", from_mix=False)
+ obj.active_shape_key_index = 0
+
+ # Get the shapekey, or create it if it doesn't already exist
+ if name in obj.data.shape_keys.keys:
+ shape_key = obj.data.shape_keys.keys[name]
+ else:
+ shape_key = obj.add_shape_key(name=name, from_mix=False)
+
+ return shape_key
+
+
+def addget_shape_key_driver(obj, name="Key"):
+ """ Fetches the driver for the shape key, or creates it if it doesn't
+ already exist.
+ """
+ driver_path = 'keys["' + name + '"].value'
+ fcurve = None
+ driver = None
+ if obj.data.shape_keys.animation_data is not None:
+ for driver_s in obj.data.shape_keys.animation_data.drivers:
+ if driver_s.data_path == driver_path:
+ fcurve = driver_s
+ if fcurve == None:
+ fcurve = obj.data.shape_keys.keys[name].driver_add("value", 0)
+ fcurve.driver.type = 'AVERAGE'
+
+ return fcurve
+
+
+
+
+def metarig_template():
+ # generated by rigify.write_meta_rig
+ bpy.ops.object.mode_set(mode='EDIT')
+ obj = bpy.context.active_object
+ arm = obj.data
+ bone = arm.edit_bones.new('Bone')
+ bone.head[:] = 0.0000, 0.0000, 0.0000
+ bone.tail[:] = 0.0000, 0.0000, 1.0000
+ bone.roll = 0.0000
+ bone.connected = False
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+ pbone = obj.pose.bones['Bone']
+ pbone['type'] = 'copy'
+
+
+def metarig_definition(obj, orig_bone_name):
+ bone = obj.data.bones[orig_bone_name]
+ return [bone.name]
+
+
+def deform(obj, definitions, base_names, options):
+ bpy.ops.object.mode_set(mode='EDIT')
+ eb = obj.data.edit_bones
+
+ bone_from = definitions[0]
+
+
+ # Options
+ req_options = ["to", "mesh", "shape_key"]
+ for option in req_options:
+ if option not in options:
+ raise RigifyError("'%s' rig type requires a '%s' option (bone: %s)" % (RIG_TYPE, option, base_names[definitions[0]]))
+
+ bone_to = "ORG-" + options["to"]
+ meshes = options["mesh"].replace(" ", "").split(",")
+ shape_key_name = options["shape_key"]
+
+ if "dmul" in options:
+ shape_blend_fac = options["dmul"]
+ else:
+ shape_blend_fac = 1.0
+
+
+ # Calculate the rotation difference between the bones
+ rotdiff = (eb[bone_from].matrix.toQuat() * eb[bone_to].matrix.toQuat()) * 2
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ # For every listed mesh object
+ for mesh_name in meshes:
+ mesh_obj = bpy.data.objects[mesh_name]
+
+ # Add/get the shape key
+ shape_key = addget_shape_key(mesh_obj, name=shape_key_name)
+
+ # Add/get the shape key driver
+ fcurve = addget_shape_key_driver(mesh_obj, name=shape_key_name)
+ driver = fcurve.driver
+
+ # Get the variable, or create it if it doesn't already exist
+ var_name = base_names[bone_from]
+ if var_name in driver.variables:
+ var = driver.variables[var_name]
+ else:
+ var = driver.variables.new()
+ var.name = var_name
+
+ # Set up the variable
+ var.type = "ROTATION_DIFF"
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].bone_target = bone_from
+ var.targets[1].id_type = 'OBJECT'
+ var.targets[1].id = obj
+ var.targets[1].bone_target = bone_to
+
+ # Set fcurve offset, so zero is at the rest distance
+
+ mod = fcurve.modifiers[0]
+ if rotdiff > 0.00001:
+ mod.coefficients[0] = -shape_blend_fac
+ mod.coefficients[1] = shape_blend_fac / rotdiff
+
+ return (None,)
+
+
+
+
+def control(obj, definitions, base_names, options):
+ """ options:
+ mesh: name of mesh object with the shape key
+ shape_key: name of shape key
+ to: name of bone to measure distance from
+ """
+ pass
+
+
+
+
+def main(obj, bone_definition, base_names, options):
+ # Create control rig
+ #control(obj, bone_definition, base_names, options)
+ # Create deform rig
+ deform(obj, bone_definition, base_names, options)
+
+ return (None,)
+
diff --git a/release/scripts/modules/rigify/spine_pivot_flex.py b/release/scripts/modules/rigify/spine_pivot_flex.py
index 6d01e0263eb..20935b0bc6c 100644
--- a/release/scripts/modules/rigify/spine_pivot_flex.py
+++ b/release/scripts/modules/rigify/spine_pivot_flex.py
@@ -304,6 +304,9 @@ def main(obj, bone_definition, base_names, options):
mt_chain.update()
ex_chain.update()
rv_chain.update()
+
+ # Axis locks
+ ex.ribcage_copy_p.lock_location = True, True, True
# df.pelvis_p / DEF-wgt_pelvis
con = df.pelvis_p.constraints.new('COPY_LOCATION')
@@ -437,7 +440,10 @@ def main(obj, bone_definition, base_names, options):
# Add bend prop
prop_name = "bend_%.2d" % i
prop = rna_idprop_ui_prop_get(ex.ribcage_copy_p, prop_name, create=True)
- ex.ribcage_copy_p[prop_name] = 1.0
+ if ("bend_%.2d" % i) in options:
+ ex.ribcage_copy_p[prop_name] = options["bend_%.2d" % i]
+ else:
+ ex.ribcage_copy_p[prop_name] = 1.0
prop["soft_min"] = 0.0
prop["soft_max"] = 1.0
diff --git a/release/scripts/modules/rigify_utils.py b/release/scripts/modules/rigify_utils.py
index 2a1c92534a0..e45f0dbc63a 100644
--- a/release/scripts/modules/rigify_utils.py
+++ b/release/scripts/modules/rigify_utils.py
@@ -145,28 +145,12 @@ def blend_bone_list(obj, apply_bones, from_bones, to_bones, target_bone=None, ta
var.targets[0].id = obj
var.targets[0].data_path = driver_path
- def blend_location(new_pbone, from_bone_name, to_bone_name):
- con = new_pbone.constraints.new('COPY_LOCATION')
+ def blend_transforms(new_pbone, from_bone_name, to_bone_name):
+ con = new_pbone.constraints.new('COPY_TRANSFORMS')
con.target = obj
con.subtarget = from_bone_name
- con = new_pbone.constraints.new('COPY_LOCATION')
- con.target = obj
- con.subtarget = to_bone_name
-
- fcurve = con.driver_add("influence", 0)
- driver = fcurve.driver
- driver.type = 'AVERAGE'
- fcurve.modifiers.remove(0) # grr dont need a modifier
-
- blend_target(driver)
-
- def blend_rotation(new_pbone, from_bone_name, to_bone_name):
- con = new_pbone.constraints.new('COPY_ROTATION')
- con.target = obj
- con.subtarget = from_bone_name
-
- con = new_pbone.constraints.new('COPY_ROTATION')
+ con = new_pbone.constraints.new('COPY_TRANSFORMS')
con.target = obj
con.subtarget = to_bone_name
@@ -187,12 +171,8 @@ def blend_bone_list(obj, apply_bones, from_bones, to_bones, target_bone=None, ta
new_pbone = obj.pose.bones[new_bone_name]
- # if the bone is connected or its location is totally locked then dont add location blending.
- if not (new_pbone.bone.connected or (False not in new_pbone.lock_location)):
- blend_location(new_pbone, from_bone_name, to_bone_name)
+ blend_transforms(new_pbone, from_bone_name, to_bone_name)
- if not (False not in new_pbone.lock_rotation): # TODO. 4D chech?
- blend_rotation(new_pbone, from_bone_name, to_bone_name)
def add_pole_target_bone(obj, base_bone_name, name, mode='CROSS'):