[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [28072] trunk/blender/release/scripts/ modules/rigify: Added tongue and neck rigs.
Nathan Vegdahl
cessen at cessen.com
Wed Apr 7 16:46:06 CEST 2010
Revision: 28072
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=28072
Author: cessen
Date: 2010-04-07 16:46:06 +0200 (Wed, 07 Apr 2010)
Log Message:
-----------
Added tongue and neck rigs. The neck rig is quite solid, I think, and is working well in production on Durian. The tongue rig is a bit hacky, but I'm adding it for now since we're using it in Durian.
Also added pupil dilation to the eye rig type, and made the finger rig type work with two-digit fingers.
Modified Paths:
--------------
trunk/blender/release/scripts/modules/rigify/eye_balls.py
trunk/blender/release/scripts/modules/rigify/finger_curl.py
Added Paths:
-----------
trunk/blender/release/scripts/modules/rigify/neck.py
trunk/blender/release/scripts/modules/rigify/tongue.py
Modified: trunk/blender/release/scripts/modules/rigify/eye_balls.py
===================================================================
--- trunk/blender/release/scripts/modules/rigify/eye_balls.py 2010-04-07 14:01:59 UTC (rev 28071)
+++ trunk/blender/release/scripts/modules/rigify/eye_balls.py 2010-04-07 14:46:06 UTC (rev 28072)
@@ -27,6 +27,85 @@
#METARIG_NAMES = ("cpy",)
RIG_TYPE = "eye_balls"
+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
+ new = False
+ 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'
+ new = True
+
+ return fcurve, new
+
+
+def create_shape_and_driver(obj, bone, meshes, shape_name, var_name, var_path, expression):
+ """ Creates/gets a shape key and sets up a driver for it.
+
+ obj = armature object
+ bone = driving bone name
+ meshes = list of meshes to create the shapekey/driver on
+ shape_name = name of the shape key
+ var_name = name of the driving variable
+ var_path = path to the property on the bone to drive with
+ expression = python expression for the driver
+ """
+ pb = obj.pose.bones
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ for mesh_name in meshes:
+ mesh_obj = bpy.data.objects[mesh_name]
+
+ # Add/get the shape key
+ shape = addget_shape_key(mesh_obj, name=shape_name)
+
+ # Add/get the shape key driver
+ fcurve, a = addget_shape_key_driver(mesh_obj, name=shape_name)
+
+ # Set up the driver
+ driver = fcurve.driver
+ driver.type = 'SCRIPTED'
+ driver.expression = expression
+
+ # Get the variable, or create it if it doesn't already exist
+ 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 = "SINGLE_PROP"
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = 'pose.bones["' + bone + '"]' + var_path
+
+
def mark_actions():
for action in bpy.data.actions:
action.tag = True
@@ -120,6 +199,12 @@
head = definitions[0]
eye_target = definitions[1]
+ # Get list of pupil mesh objects
+ if "mesh" in options:
+ pupil_meshes = options["mesh"].replace(" ", "").split(",")
+ else:
+ pupil_meshes = []
+
# Get list of eyes
if "eyes" in options:
eye_base_names = options["eyes"].replace(" ", "").split(",")
@@ -246,9 +331,53 @@
con.minimum = 0.0
con.maximum = 2.0
con.target_space = 'LOCAL'
+
+
+ # Get/create the shape keys and drivers for pupil dilation
+ shape_names = ["PUPILS-dilate_wide", "PUPILS-dilate_narrow"]
+ slider_name = "pupil_dilate"
+
+ # Set up the custom property on the bone
+ prop = rna_idprop_ui_prop_get(pb[target_ctrl], slider_name, create=True)
+ pb[target_ctrl][slider_name] = 0.0
+ prop["min"] = 0.0
+ prop["max"] = 1.0
+ prop["soft_min"] = 0.0
+ prop["soft_max"] = 1.0
+ if len(shape_names) > 1:
+ prop["min"] = -1.0
+ prop["soft_min"] = -1.0
+ # Add the shape drivers
+ # Positive
+ if shape_names[0] != "":
+ # Set up the variables for creating the shape key driver
+ shape_name = shape_names[0]
+ var_name = slider_name.replace(".", "_").replace("-", "_")
+ var_path = '["' + slider_name + '"]'
+ if slider_name + "_fac" in options:
+ fac = options[slider_name + "_fac"]
+ else:
+ fac = 1.0
+ expression = var_name + " * " + str(fac)
+ # Create the shape key driver
+ create_shape_and_driver(obj, target_ctrl, pupil_meshes, shape_name, var_name, var_path, expression)
+ # Negative
+ if shape_names[0] != "" and len(shape_names) > 1:
+ # Set up the variables for creating the shape key driver
+ shape_name = shape_names[1]
+ var_name = slider_name.replace(".", "_").replace("-", "_")
+ var_path = '["' + slider_name + '"]'
+ if slider_name + "_fac" in options:
+ fac = options[slider_name + "_fac"]
+ else:
+ fac = 1.0
+ expression = var_name + " * " + str(fac) + " * -1"
+ # Create the shape key driver
+ create_shape_and_driver(obj, target_ctrl, pupil_meshes, shape_name, var_name, var_path, expression)
+
# Set layers
#layer = list(bb[definitions[2]].layer)
#bb[lid1].layer = layer
Modified: trunk/blender/release/scripts/modules/rigify/finger_curl.py
===================================================================
--- trunk/blender/release/scripts/modules/rigify/finger_curl.py 2010-04-07 14:01:59 UTC (rev 28071)
+++ trunk/blender/release/scripts/modules/rigify/finger_curl.py 2010-04-07 14:46:06 UTC (rev 28072)
@@ -57,31 +57,20 @@
def metarig_definition(obj, orig_bone_name):
'''
The bone given is the first in a chain
- Expects a chain of at least 2 children.
+ Expects a chain with at least 1 child of the same base name.
eg.
- finger -> finger_01 -> finger_02
+ finger_01 -> finger_02
'''
- bone_definition = []
-
orig_bone = obj.data.bones[orig_bone_name]
- bone_definition.append(orig_bone.name)
-
- bone = orig_bone
- chain = 0
- while chain < 2: # first 2 bones only have 1 child
- children = bone.children
-
- if len(children) != 1:
- raise RigifyError("expected the chain to have 2 children from bone '%s' without a fork" % orig_bone_name)
- bone = children[0]
- bone_definition.append(bone.name) # finger_02, finger_03
- chain += 1
-
- if len(bone_definition) != len(METARIG_NAMES):
- raise RigifyError("internal problem, expected %d bones" % len(METARIG_NAMES))
-
+ bone_definition = [orig_bone.name]
+
+ bone_definition.extend([child.name for child in orig_bone.children_recursive_basename])
+
+ if len(bone_definition) < 2:
+ raise RigifyError("expected the chain to have at least 1 child from bone '%s' without the same base name" % orig_bone_name)
+
return bone_definition
@@ -90,6 +79,8 @@
"""
bpy.ops.object.mode_set(mode='EDIT')
+ three_digits = True if len(definitions) > 2 else False
+
# Create base digit bones: two bones, each half of the base digit.
f1a = copy_bone_simple(obj.data, definitions[0], "DEF-%s.01" % base_names[definitions[0]], parent=True)
f1b = copy_bone_simple(obj.data, definitions[0], "DEF-%s.02" % base_names[definitions[0]], parent=True)
@@ -102,13 +93,15 @@
# Create the other deform bones.
f2 = copy_bone_simple(obj.data, definitions[1], "DEF-%s" % base_names[definitions[1]], parent=True)
- f3 = copy_bone_simple(obj.data, definitions[2], "DEF-%s" % base_names[definitions[2]], parent=True)
+ if three_digits:
+ f3 = copy_bone_simple(obj.data, definitions[2], "DEF-%s" % base_names[definitions[2]], parent=True)
# Store names before leaving edit mode
f1a_name = f1a.name
f1b_name = f1b.name
f2_name = f2.name
- f3_name = f3.name
+ if three_digits:
+ f3_name = f3.name
# Leave edit mode
bpy.ops.object.mode_set(mode='OBJECT')
@@ -117,7 +110,8 @@
f1a = obj.pose.bones[f1a_name]
f1b = obj.pose.bones[f1b_name]
f2 = obj.pose.bones[f2_name]
- f3 = obj.pose.bones[f3_name]
+ if three_digits:
+ f3 = obj.pose.bones[f3_name]
# Constrain the base digit's bones
con = f1a.constraints.new('DAMPED_TRACK')
@@ -141,15 +135,18 @@
con.target = obj
con.subtarget = definitions[1]
- con = f3.constraints.new('COPY_TRANSFORMS')
- con.name = "copy_transforms"
- con.target = obj
- con.subtarget = definitions[2]
+ if three_digits:
+ con = f3.constraints.new('COPY_TRANSFORMS')
+ con.name = "copy_transforms"
+ con.target = obj
+ con.subtarget = definitions[2]
def main(obj, bone_definition, base_names, options):
# *** EDITMODE
bpy.ops.object.mode_set(mode='EDIT')
+
+ three_digits = True if len(bone_definition) > 2 else False
# get assosiated data
arm = obj.data
@@ -159,7 +156,8 @@
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
+ if three_digits:
+ org_f3 = bone_definition[2] # Original finger bone 03
# Check options
if "bend_ratio" in options:
@@ -179,7 +177,10 @@
# 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
+ if three_digits:
+ tot_len = eb[org_f1].length + eb[org_f2].length + eb[org_f3].length
+ else:
+ tot_len = eb[org_f1].length + eb[org_f2].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
@@ -188,26 +189,30 @@
# 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
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list