forked from bartvdbraak/blender
Rigify:
- Removed control-shape deformation bones from the spine rig (no longer necessary thanks to the new "custom shape at" feature). - Various improvements to the mouth rig, including a corrective shape key for mouth-open. - The new method of generating into the same armature object every time wasn't copying pose bone data in the process, such as rotation mode and transform locks.
This commit is contained in:
parent
5fe3524ab1
commit
fb8d6b9f7a
@ -231,10 +231,31 @@ def generate_rig(context, obj_orig, prefix="ORG-", META_DEF=True):
|
||||
obj.selected = True
|
||||
scene.objects.active = obj
|
||||
|
||||
# Copy over the pose_bone custom properties
|
||||
# Copy over the pose_bone properties
|
||||
for bone in obj_orig.pose.bones:
|
||||
bone_gen = obj.pose.bones[bone.name]
|
||||
|
||||
# Rotation mode and transform locks
|
||||
bone_gen.rotation_mode = bone.rotation_mode
|
||||
bone_gen.lock_rotation = tuple(bone.lock_rotation)
|
||||
bone_gen.lock_rotation_w = bone.lock_rotation_w
|
||||
bone_gen.lock_rotations_4d = bone.lock_rotations_4d
|
||||
bone_gen.lock_location = tuple(bone.lock_location)
|
||||
bone_gen.lock_scale = tuple(bone.lock_scale)
|
||||
|
||||
# Custom properties
|
||||
for prop in bone.keys():
|
||||
obj.pose.bones[bone.name][prop] = bone[prop]
|
||||
bone_gen[prop] = bone[prop]
|
||||
|
||||
# Copy over bone properties
|
||||
for bone in obj_orig.data.bones:
|
||||
bone_gen = obj.data.bones[bone.name]
|
||||
|
||||
# B-bone stuff
|
||||
bone_gen.bbone_segments = bone.bbone_segments
|
||||
bone_gen.bbone_in = bone.bbone_in
|
||||
bone_gen.bbone_out = bone.bbone_out
|
||||
|
||||
|
||||
# Create proxy deformation rig
|
||||
# TODO: remove this
|
||||
|
@ -119,8 +119,11 @@ def deform(obj, definitions, base_names, options):
|
||||
bpy.ops.object.mode_set(mode='EDIT')
|
||||
|
||||
eb = obj.data.edit_bones
|
||||
bb = obj.data.bones
|
||||
pb = obj.pose.bones
|
||||
|
||||
jaw = definitions[1]
|
||||
|
||||
# Options
|
||||
req_options = ["mesh"]
|
||||
for option in req_options:
|
||||
@ -210,6 +213,16 @@ def deform(obj, definitions, base_names, options):
|
||||
eb[dlip7].bbone_segments = 8
|
||||
eb[dlip8].bbone_segments = 8
|
||||
|
||||
# Jaw open bones
|
||||
jopen1 = copy_bone_simple(obj.data, jaw, "MCH-"+base_names[jaw]+".track1", parent=True).name
|
||||
eb[jopen1].connected = False
|
||||
eb[jopen1].head = eb[jaw].tail
|
||||
eb[jopen1].tail = eb[jopen1].head + Vector(0, 0, eb[jaw].length/4)
|
||||
|
||||
jopen2 = copy_bone_simple(obj.data, jopen1, "MCH-"+base_names[jaw]+".track2").name
|
||||
eb[jopen2].parent = eb[jaw]
|
||||
|
||||
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
# Constraints
|
||||
@ -255,8 +268,7 @@ def deform(obj, definitions, base_names, options):
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
|
||||
|
||||
# Left side
|
||||
# Left side shape key
|
||||
for mesh_name in meshes:
|
||||
mesh_obj = bpy.data.objects[mesh_name]
|
||||
shape_key_name = "COR-" + base_names[definitions[4]] + ".L.spread"
|
||||
@ -278,10 +290,8 @@ def deform(obj, definitions, base_names, options):
|
||||
|
||||
# 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
|
||||
|
||||
@ -291,7 +301,7 @@ def deform(obj, definitions, base_names, options):
|
||||
mod.coefficients[0] = -rotdiff_l / (pi-rotdiff_l)
|
||||
mod.coefficients[1] = 1 / (pi-rotdiff_l)
|
||||
|
||||
# Right side
|
||||
# Right side shape key
|
||||
for mesh_name in meshes:
|
||||
mesh_obj = bpy.data.objects[mesh_name]
|
||||
shape_key_name = "COR-" + base_names[definitions[4]] + ".R.spread"
|
||||
@ -313,10 +323,8 @@ def deform(obj, definitions, base_names, options):
|
||||
|
||||
# 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
|
||||
|
||||
@ -325,7 +333,38 @@ def deform(obj, definitions, base_names, options):
|
||||
if rotdiff_r != pi:
|
||||
mod.coefficients[0] = -rotdiff_r / (pi-rotdiff_r)
|
||||
mod.coefficients[1] = 1 / (pi-rotdiff_r)
|
||||
|
||||
# Jaw open corrective shape key
|
||||
for mesh_name in meshes:
|
||||
mesh_obj = bpy.data.objects[mesh_name]
|
||||
shape_key_name = "COR-" + base_names[definitions[4]] + ".jaw_open"
|
||||
|
||||
# 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[4]]
|
||||
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 = obj
|
||||
var.targets[0].bone_target = jopen1
|
||||
var.targets[1].id = obj
|
||||
var.targets[1].bone_target = jopen2
|
||||
|
||||
# Set fcurve offset
|
||||
mod = fcurve.modifiers[0]
|
||||
mod.coefficients[0] = 0.0
|
||||
mod.coefficients[1] = 1.0 / bb[jaw].length
|
||||
|
||||
return (None,)
|
||||
|
||||
@ -446,7 +485,7 @@ def control(obj, definitions, base_names, options):
|
||||
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
# Add eye close action if it doesn't already exist
|
||||
# Add mouth open 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]
|
||||
@ -464,6 +503,7 @@ def control(obj, definitions, base_names, options):
|
||||
|
||||
open_driver_path = pb[lip1].path_to_id() + '["open_action"]'
|
||||
|
||||
|
||||
# Constraints
|
||||
|
||||
# Jaw open tracker stretches to jaw tip
|
||||
@ -475,7 +515,7 @@ def control(obj, definitions, base_names, options):
|
||||
con.volume = 'NO_VOLUME'
|
||||
|
||||
# Head lips to jaw lips
|
||||
influence = [0.0, 0.1, 0.5, 0.25, 0.0]
|
||||
influence = [0.02, 0.15, 0.5, 0.25, 0.0]
|
||||
|
||||
con = pb[hlip1].constraints.new('COPY_TRANSFORMS')
|
||||
con.target = obj
|
||||
|
@ -168,8 +168,7 @@ def main(obj, bone_definition, base_names, options):
|
||||
#child.parent = mt.pelvis_e # was mt.ribcage
|
||||
|
||||
# The first bone in the chain happens to be the basis of others, create them now
|
||||
ex = bone_class_instance(obj, ["pelvis", "pelvis_copy", "ribcage", "ribcage_hinge", "ribcage_copy", "spine_rotate"])
|
||||
df = bone_class_instance(obj, ["pelvis", "ribcage"]) # DEF-wgt_pelvis, DEF-wgt_rib_cage
|
||||
ex = bone_class_instance(obj, ["pelvis_copy", "ribcage_hinge", "ribcage_copy", "spine_rotate"])
|
||||
|
||||
ex.pelvis_copy_e = copy_bone_simple(arm, mt.pelvis, base_names[mt.pelvis]) # no parent
|
||||
ex.pelvis_copy = ex.pelvis_copy_e.name
|
||||
@ -186,33 +185,15 @@ def main(obj, bone_definition, base_names, options):
|
||||
ex.spine_rotate_e.connected = False
|
||||
ex.spine_rotate_e.parent = ex.pelvis_copy_e
|
||||
|
||||
df.pelvis_e = copy_bone_simple(arm, child.name, "DEF-wgt_%s" % base_names[mt.pelvis])
|
||||
df.pelvis = df.pelvis_e.name
|
||||
df.pelvis_e.translate(Vector(spine_chain_segment_length * 2.0, - spine_chain_segment_length, 0.0))
|
||||
|
||||
ex.pelvis_e = copy_bone_simple(arm, child.name, "MCH-wgt_%s" % base_names[mt.pelvis])
|
||||
ex.pelvis = ex.pelvis_e.name
|
||||
ex.pelvis_e.translate(Vector(0.0, - spine_chain_segment_length, 0.0))
|
||||
ex.pelvis_e.connected = False
|
||||
ex.pelvis_e.parent = ex.pelvis_copy_e
|
||||
|
||||
# Copy the last bone now
|
||||
child = spine_chain[-1]
|
||||
|
||||
df.ribcage_e = copy_bone_simple(arm, child.name, "DEF-wgt_%s" % base_names[mt.ribcage])
|
||||
df.ribcage = df.ribcage_e.name
|
||||
df.ribcage_e.translate(Vector(spine_chain_segment_length * 2.0, - df.ribcage_e.length / 2.0, 0.0))
|
||||
|
||||
ex.ribcage_copy_e = copy_bone_simple(arm, mt.ribcage, base_names[mt.ribcage])
|
||||
ex.ribcage_copy = ex.ribcage_copy_e.name
|
||||
ex.ribcage_copy_e.connected = False
|
||||
ex.ribcage_copy_e.parent = ex.ribcage_hinge_e
|
||||
|
||||
ex.ribcage_e = copy_bone_simple(arm, child.name, "MCH-wgt_%s" % base_names[mt.ribcage])
|
||||
ex.ribcage = ex.ribcage_e.name
|
||||
ex.ribcage_e.translate(Vector(0.0, - ex.ribcage_e.length / 2.0, 0.0))
|
||||
ex.ribcage_e.parent = ex.ribcage_copy_e
|
||||
|
||||
spine_chain = [child.name for child in spine_chain]
|
||||
|
||||
# We have 3 spine chains
|
||||
@ -300,7 +281,6 @@ def main(obj, bone_definition, base_names, options):
|
||||
# refresh pose bones
|
||||
mt.update()
|
||||
ex.update()
|
||||
df.update()
|
||||
mt_chain.update()
|
||||
ex_chain.update()
|
||||
rv_chain.update()
|
||||
@ -308,34 +288,6 @@ def main(obj, bone_definition, base_names, options):
|
||||
# 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')
|
||||
con.target = obj
|
||||
con.subtarget = ex.pelvis
|
||||
con.owner_space = 'LOCAL'
|
||||
con.target_space = 'LOCAL'
|
||||
|
||||
con = df.pelvis_p.constraints.new('COPY_ROTATION')
|
||||
con.target = obj
|
||||
con.subtarget = ex.pelvis
|
||||
con.owner_space = 'LOCAL'
|
||||
con.target_space = 'LOCAL'
|
||||
|
||||
# df.ribcage_p / DEF-wgt_rib_cage
|
||||
df.ribcage_p.lock_location = True, True, True
|
||||
|
||||
con = df.ribcage_p.constraints.new('COPY_ROTATION')
|
||||
con.target = obj
|
||||
con.subtarget = ex.ribcage
|
||||
con.owner_space = 'LOCAL'
|
||||
con.target_space = 'LOCAL'
|
||||
|
||||
con = df.ribcage_p.constraints.new('COPY_LOCATION')
|
||||
con.target = obj
|
||||
con.subtarget = ex.ribcage
|
||||
con.owner_space = 'LOCAL'
|
||||
con.target_space = 'LOCAL'
|
||||
|
||||
con = ex.ribcage_hinge_p.constraints.new('COPY_ROTATION')
|
||||
con.name = "hinge"
|
||||
con.target = obj
|
||||
@ -356,35 +308,10 @@ def main(obj, bone_definition, base_names, options):
|
||||
mod.coefficients[0] = 1.0
|
||||
mod.coefficients[1] = -1.0
|
||||
|
||||
|
||||
con = ex.spine_rotate_p.constraints.new('COPY_ROTATION')
|
||||
con.target = obj
|
||||
con.subtarget = ex.ribcage_copy
|
||||
|
||||
|
||||
# ex.pelvis_p / MCH-wgt_pelvis
|
||||
con = ex.pelvis_p.constraints.new('COPY_LOCATION')
|
||||
con.target = obj
|
||||
con.subtarget = mt_chain.spine_01
|
||||
con.owner_space = 'WORLD'
|
||||
con.target_space = 'WORLD'
|
||||
|
||||
con = ex.pelvis_p.constraints.new('COPY_ROTATION')
|
||||
con.target = obj
|
||||
con.subtarget = mt_chain.spine_01
|
||||
con.owner_space = 'WORLD'
|
||||
con.target_space = 'WORLD'
|
||||
|
||||
# ex.ribcage_p / MCH-wgt_rib_cage
|
||||
con = ex.ribcage_p.constraints.new('COPY_LOCATION')
|
||||
con.target = obj
|
||||
con.subtarget = getattr(mt_chain, mt_chain.attr_names[-1])
|
||||
con.head_tail = 0.0
|
||||
|
||||
con = ex.ribcage_p.constraints.new('COPY_ROTATION')
|
||||
con.target = obj
|
||||
con.subtarget = getattr(mt_chain, mt_chain.attr_names[-1])
|
||||
|
||||
# ex.pelvis_copy_p / rib_cage
|
||||
con = ex.ribcage_copy_p.constraints.new('COPY_LOCATION')
|
||||
con.target = obj
|
||||
@ -543,8 +470,6 @@ def main(obj, bone_definition, base_names, options):
|
||||
getattr(ex, attr + "_b").layer = layer
|
||||
for attr in ex_chain.attr_names:
|
||||
getattr(ex_chain, attr + "_b").layer = layer
|
||||
for attr in df.attr_names:
|
||||
getattr(df, attr + "_b").layer = layer
|
||||
for attr in rv_chain.attr_names:
|
||||
getattr(rv_chain, attr + "_b").layer = layer
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user