* rename 'rna_path' --> 'data_path', rna and dna are for internal use and are not descriptive.

* armature.pose_position: POSE_POSITION, REST_POSITION --> POSE, REST
* rigify now forces rest pose mode
* updated neck_flex to keep original bones unchanged
This commit is contained in:
Campbell Barton 2009-12-10 22:23:09 +00:00
parent 2a785e8fae
commit 97abf6ad96
15 changed files with 89 additions and 60 deletions

@ -150,16 +150,16 @@ def graph_armature(obj, path, FAKE_PARENT=True, CONSTRAINTS=True, DRIVERS=True,
if animation_data:
fcurve_drivers = [fcurve_driver for fcurve_driver in animation_data.drivers]
fcurve_drivers.sort(key=lambda fcurve_driver: fcurve_driver.rna_path)
fcurve_drivers.sort(key=lambda fcurve_driver: fcurve_driver.data_path)
for fcurve_driver in fcurve_drivers:
rna_path = fcurve_driver.rna_path
rna_path = fcurve_driver.data_path
pbone = rna_path_as_pbone(rna_path)
if pbone:
for target in fcurve_driver.driver.targets:
pbone_target = rna_path_as_pbone(target.rna_path)
rna_path_target = target.rna_path
pbone_target = rna_path_as_pbone(target.data_path)
rna_path_target = target.data_path
if pbone_target:
opts = ['dir=forward', "weight=1", "arrowhead=normal", "arrowtail=none", "constraint=false", 'color="blue"', "labelfontsize=4"] # ,
display_source = rna_path.replace("pose.bones", "")

@ -49,6 +49,8 @@ def submodule_func_from_type(bone_type):
def validate_rig(context, obj):
type_found = False
for pbone in obj.pose.bones:
bone_name = pbone.name
bone_type = pbone.get("type", "")
@ -62,18 +64,28 @@ def validate_rig(context, obj):
submod, type_func = submodule_func_from_type(bone_type)
reload(submod)
submod.metarig_definition(obj, bone_name)
type_found = True
# missing, - check for duplicate root bone.
if not type_found:
raise RigifyError("This rig has no 'type' properties defined on any pose bones, nothing to do")
def generate_rig(context, obj_orig, prefix="ORG-", META_DEF=True):
from collections import OrderedDict
import rigify_utils
reload(rigify_utils)
# Not needed but catches any errors before duplicating
# validate_rig(context, obj_orig)
global_undo = context.user_preferences.edit.global_undo
context.user_preferences.edit.global_undo = False
mode_orig = context.mode
rest_backup = obj_orig.data.pose_position
obj_orig.data.pose_position = 'REST'
bpy.ops.object.mode_set(mode='OBJECT')
@ -254,15 +266,20 @@ def generate_rig(context, obj_orig, prefix="ORG-", META_DEF=True):
con.target = obj
con.subtarget = bone_name
# would be 'REST' from when copied
obj_def.data.pose_position = 'POSE'
# Only for demo'ing
# obj.restrict_view = True
obj.data.draw_axes = False
bpy.ops.object.mode_set(mode=mode_orig)
obj_orig.data.pose_position = rest_backup
obj.data.pose_position = 'POSE'
context.user_preferences.edit.global_undo = global_undo
return obj

@ -240,7 +240,7 @@ def fk(obj, definitions, base_names):
tar.name = "hinge"
tar.id_type = 'OBJECT'
tar.id = obj
tar.rna_path = controller_path + '["hinge"]'
tar.data_path = controller_path + '["hinge"]'
mod = driver_fcurve.modifiers[0]
mod.poly_order = 1

@ -67,6 +67,9 @@ def metarig_definition(obj, orig_bone_name):
if len(children) != 1:
raise RigifyError("only 1 child supported for delta on bone '%s'" % delta.name)
if delta.connected:
raise RigifyError("bone cannot be connected to its parent '%s'" % delta.name)
bone_definition = [delta.name, children[0].name]
return bone_definition

@ -201,14 +201,14 @@ def main(obj, bone_definition, base_names):
tar.name = "scale"
tar.id_type = 'OBJECT'
tar.id = obj
tar.rna_path = controller_path + '.scale[1]'
tar.data_path = controller_path + '.scale[1]'
# bend target
tar = driver.targets.new()
tar.name = "br"
tar.id_type = 'OBJECT'
tar.id = obj
tar.rna_path = controller_path + '["bend_ratio"]'
tar.data_path = controller_path + '["bend_ratio"]'
# XXX - todo, any number
if i == 0:

@ -341,7 +341,7 @@ def fk(obj, bone_definition, base_names):
tar.name = "var"
tar.id_type = 'OBJECT'
tar.id = obj
tar.rna_path = hinge_driver_path
tar.data_path = hinge_driver_path
mod = fcurve.modifiers[0]
mod.poly_order = 1

@ -121,10 +121,14 @@ def main(obj, bone_definition, base_names):
neck_chain_basename = base_names[mt_chain.neck_01_e.name].split(".")[0]
neck_chain_segment_length = mt_chain.neck_01_e.length
ex = bone_class_instance(obj, ["body", "head", "head_hinge", "neck_socket"]) # hinge & extras
ex = bone_class_instance(obj, ["body", "head", "head_hinge", "neck_socket", "head_ctrl"]) # hinge & extras
# Add the head hinge at the bodys location, becomes the parent of the original head
# apply everything to this copy of the chain
ex_chain = mt_chain.copy(base_names=base_names)
ex_chain.neck_01_e.parent = mt_chain.neck_01_e.parent
# Copy the head bone and offset
ex.head_e = copy_bone_simple(arm, mt.head, "MCH_%s" % base_names[mt.head], parent=True)
@ -142,10 +146,6 @@ def main(obj, bone_definition, base_names):
ex.head_hinge_e.head.y += head_length / 4.0
ex.head_hinge_e.tail.y += head_length / 4.0
# reparent the head, assume its not connected
mt.head_e.connected = False
mt.head_e.parent = ex.head_hinge_e
# Insert the neck socket, the head copys this loation
ex.neck_socket_e = arm.edit_bones.new("MCH-%s_socked" % neck_chain_basename)
ex.neck_socket = ex.neck_socket_e.name
@ -155,20 +155,21 @@ def main(obj, bone_definition, base_names):
ex.neck_socket_e.tail = mt.head_e.head - Vector(0.0, neck_chain_segment_length / 2.0, 0.0)
ex.neck_socket_e.roll = 0.0
# offset the head, not really needed since it has a copyloc constraint
mt.head_e.head.y += head_length / 4.0
mt.head_e.tail.y += head_length / 4.0
for i, attr in enumerate(mt_chain.attr_names):
neck_e = getattr(mt_chain, attr + "_e")
# copy of the head for controling
ex.head_ctrl_e = copy_bone_simple(arm, mt.head, base_names[mt.head])
ex.head_ctrl = ex.head_ctrl_e.name
ex.head_ctrl_e.parent = ex.head_hinge_e
for i, attr in enumerate(ex_chain.attr_names):
neck_e = getattr(ex_chain, attr + "_e")
# dont store parent names, re-reference as each chain bones parent.
neck_e_parent = arm.edit_bones.new("MCH-rot_%s" % base_names[neck_e.name])
neck_e_parent = arm.edit_bones.new("MCH-rot_%s" % base_names[getattr(mt_chain, attr)])
neck_e_parent.head = neck_e.head
neck_e_parent.tail = neck_e.head + ((mt.head_e.tail - mt.head_e.head).normalize() * neck_chain_segment_length / 2.0)
neck_e_parent.roll = mt.head_e.roll
orig_parent = neck_e.parent
neck_e.connected = False
neck_e.parent = neck_e_parent
@ -184,20 +185,21 @@ def main(obj, bone_definition, base_names):
mt.update()
mt_chain.update()
ex_chain.update()
ex.update()
# Simple one off constraints, no drivers
con = mt.head_p.constraints.new('COPY_LOCATION')
con = ex.head_ctrl_p.constraints.new('COPY_LOCATION')
con.target = obj
con.subtarget = ex.neck_socket
con = ex.head_p.constraints.new('COPY_ROTATION')
con.target = obj
con.subtarget = mt.head
con.subtarget = ex.head_ctrl
# driven hinge
prop = rna_idprop_ui_prop_get(mt.head_p, "hinge", create=True)
mt.head_p["hinge"] = 0.0
prop = rna_idprop_ui_prop_get(ex.head_ctrl_p, "hinge", create=True)
ex.head_ctrl_p["hinge"] = 0.0
prop["soft_min"] = 0.0
prop["soft_max"] = 1.0
@ -207,7 +209,7 @@ def main(obj, bone_definition, base_names):
con.subtarget = mt.body
# add driver
hinge_driver_path = mt.head_p.path_to_id() + '["hinge"]'
hinge_driver_path = ex.head_ctrl_p.path_to_id() + '["hinge"]'
fcurve = con.driver_add("influence", 0)
driver = fcurve.driver
@ -216,7 +218,7 @@ def main(obj, bone_definition, base_names):
tar.name = "var"
tar.id_type = 'OBJECT'
tar.id = obj
tar.rna_path = hinge_driver_path
tar.data_path = hinge_driver_path
#mod = fcurve_driver.modifiers.new('GENERATOR')
mod = fcurve.modifiers[0]
@ -224,12 +226,12 @@ def main(obj, bone_definition, base_names):
mod.coefficients[0] = 1.0
mod.coefficients[1] = -1.0
head_driver_path = mt.head_p.path_to_id()
head_driver_path = ex.head_ctrl_p.path_to_id()
target_names = [("b%.2d" % (i + 1)) for i in range(len(neck_chain))]
mt.head_p["bend_tot"] = 0.0
fcurve = mt.head_p.driver_add('["bend_tot"]', 0)
ex.head_ctrl_p["bend_tot"] = 0.0
fcurve = ex.head_ctrl_p.driver_add('["bend_tot"]', 0)
driver = fcurve.driver
driver.type = 'SUM'
fcurve.modifiers.remove(0) # grr dont need a modifier
@ -239,19 +241,19 @@ def main(obj, bone_definition, base_names):
tar.name = target_names[i]
tar.id_type = 'OBJECT'
tar.id = obj
tar.rna_path = head_driver_path + ('["bend_%.2d"]' % (i + 1))
tar.data_path = head_driver_path + ('["bend_%.2d"]' % (i + 1))
for i, attr in enumerate(mt_chain.attr_names):
neck_p = getattr(mt_chain, attr + "_p")
for i, attr in enumerate(ex_chain.attr_names):
neck_p = getattr(ex_chain, attr + "_p")
neck_p.lock_location = True, True, True
neck_p.lock_location = True, True, True
neck_p.lock_rotations_4d = True
# Add bend prop
prop_name = "bend_%.2d" % (i + 1)
prop = rna_idprop_ui_prop_get(mt.head_p, prop_name, create=True)
mt.head_p[prop_name] = 1.0
prop = rna_idprop_ui_prop_get(ex.head_ctrl_p, prop_name, create=True)
ex.head_ctrl_p[prop_name] = 1.0
prop["soft_min"] = 0.0
prop["soft_max"] = 1.0
@ -279,13 +281,20 @@ def main(obj, bone_definition, base_names):
tar.name = "bend_tot"
tar.id_type = 'OBJECT'
tar.id = obj
tar.rna_path = head_driver_path + ('["bend_tot"]')
tar.data_path = head_driver_path + ('["bend_tot"]')
tar = driver.targets.new()
tar.name = "bend"
tar.id_type = 'OBJECT'
tar.id = obj
tar.rna_path = head_driver_path + ('["%s"]' % prop_name)
tar.data_path = head_driver_path + ('["%s"]' % prop_name)
# finally constrain the original bone to this one
orig_neck_p = getattr(mt_chain, attr + "_p")
con = orig_neck_p.constraints.new('COPY_ROTATION')
con.target = obj
con.subtarget = neck_p.name
# no blending the result of this
return None

@ -145,7 +145,7 @@ def main(obj, bone_definition, base_names):
tar.name = "x"
tar.id_type = 'OBJECT'
tar.id = obj
tar.rna_path = controller_path + ".rotation_euler[0]"
tar.data_path = controller_path + ".rotation_euler[0]"
# *****
@ -156,7 +156,7 @@ def main(obj, bone_definition, base_names):
tar.name = "x"
tar.id_type = 'OBJECT'
tar.id = obj
tar.rna_path = controller_path + ".rotation_euler[0]"
tar.data_path = controller_path + ".rotation_euler[0]"
# *****
@ -166,13 +166,13 @@ def main(obj, bone_definition, base_names):
tar.name = "x"
tar.id_type = 'OBJECT'
tar.id = obj
tar.rna_path = controller_path + ".rotation_euler[0]"
tar.data_path = controller_path + ".rotation_euler[0]"
tar = driver.targets.new()
tar.name = "s"
tar.id_type = 'OBJECT'
tar.id = obj
tar.rna_path = controller_path + '["spread"]'
tar.data_path = controller_path + '["spread"]'
for i, child_name in enumerate(children):

@ -322,7 +322,7 @@ def main(obj, bone_definition, base_names):
tar.name = "var"
tar.id_type = 'OBJECT'
tar.id = obj
tar.rna_path = ex.ribcage_copy_p.path_to_id() + '["hinge"]'
tar.data_path = ex.ribcage_copy_p.path_to_id() + '["hinge"]'
mod = fcurve.modifiers[0]
mod.poly_order = 1
@ -406,7 +406,7 @@ def main(obj, bone_definition, base_names):
tar.name = target_names[i]
tar.id_type = 'OBJECT'
tar.id = obj
tar.rna_path = rib_driver_path + ('["bend_%.2d"]' % (i + 1))
tar.data_path = rib_driver_path + ('["bend_%.2d"]' % (i + 1))
for i in range(1, spine_chain_len):
@ -441,13 +441,13 @@ def main(obj, bone_definition, base_names):
tar.name = "bend_tot"
tar.id_type = 'OBJECT'
tar.id = obj
tar.rna_path = rib_driver_path + ('["bend_tot"]')
tar.data_path = rib_driver_path + ('["bend_tot"]')
tar = driver.targets.new()
tar.name = "bend"
tar.id_type = 'OBJECT'
tar.id = obj
tar.rna_path = rib_driver_path + ('["%s"]' % prop_name)
tar.data_path = rib_driver_path + ('["%s"]' % prop_name)
@ -490,7 +490,7 @@ def main(obj, bone_definition, base_names):
tar.name = "var"
tar.id_type = 'OBJECT'
tar.id = obj
tar.rna_path = rib_driver_path + '["pivot_slide"]'
tar.data_path = rib_driver_path + '["pivot_slide"]'
mod = fcurve.modifiers[0]
mod.poly_order = 1

@ -141,7 +141,7 @@ def blend_bone_list(obj, apply_bones, from_bones, to_bones, target_bone=None, ta
tar.name = target_bone
tar.id_type = 'OBJECT'
tar.id = obj
tar.rna_path = driver_path
tar.data_path = driver_path
def blend_location(new_pbone, from_bone_name, to_bone_name):
con = new_pbone.constraints.new('COPY_LOCATION')

@ -134,7 +134,7 @@ class SCENE_PT_keying_set_paths(SceneButtonsPanel):
col = layout.column()
col.label(text="Target:")
col.template_any_ID(ksp, "id", "id_type")
col.template_path_builder(ksp, "rna_path", ksp.id)
col.template_path_builder(ksp, "data_path", ksp.id)
row = layout.row()

@ -203,9 +203,9 @@ static void rna_def_keyingset_path(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Grouping Method", "Method used to define which Group-name to use.");
/* Path + Array Index */
prop= RNA_def_property(srna, "rna_path", PROP_STRING, PROP_NONE);
prop= RNA_def_property(srna, "data_path", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(prop, "rna_ksPath_RnaPath_get", "rna_ksPath_RnaPath_length", "rna_ksPath_RnaPath_set");
RNA_def_property_ui_text(prop, "RNA Path", "RNA Path to property setting.");
RNA_def_property_ui_text(prop, "Data Path", "Path to property setting.");
RNA_def_struct_name_property(srna, prop); // XXX this is the best indicator for now...
prop= RNA_def_property(srna, "array_index", PROP_INT, PROP_NONE);

@ -76,7 +76,7 @@ void RNA_api_keyingset(StructRNA *srna)
parm= RNA_def_pointer(func, "target_id", "ID", "Target ID", "ID-Datablock for the destination.");
RNA_def_property_flag(parm, PROP_REQUIRED);
/* rna-path */
parm= RNA_def_string(func, "rna_path", "", 256, "RNA-Path", "RNA-Path to destination property."); // xxx hopefully this is long enough
parm= RNA_def_string(func, "data_path", "", 256, "Data-Path", "RNA-Path to destination property."); // xxx hopefully this is long enough
RNA_def_property_flag(parm, PROP_REQUIRED);
parm=RNA_def_int(func, "array_index", 0, 0, INT_MAX, "Array Index", "If applicable, the index ", 0, INT_MAX);
/* flags */

@ -752,8 +752,8 @@ static void rna_def_armature(BlenderRNA *brna)
{0, "TAILS", 0, "Tails", "Calculate bone paths from tails"},
{0, NULL, 0, NULL, NULL}};
static const EnumPropertyItem prop_pose_position_items[]= {
{0, "POSE_POSITION", 0, "Pose Position", "Show armature in posed state."},
{ARM_RESTPOS, "REST_POSITION", 0, "Rest Position", "Show Armature in binding pose state. No posing possible."},
{0, "POSE", 0, "Pose Position", "Show armature in posed state."},
{ARM_RESTPOS, "REST", 0, "Rest Position", "Show Armature in binding pose state. No posing possible."},
{0, NULL, 0, NULL, NULL}};
srna= RNA_def_struct(brna, "Armature", "ID");

@ -747,9 +747,9 @@ static void rna_def_drivertarget(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_DriverTarget_update_data");
/* Target Properties - Property to Drive */
prop= RNA_def_property(srna, "rna_path", PROP_STRING, PROP_NONE);
prop= RNA_def_property(srna, "data_path", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(prop, "rna_DriverTarget_RnaPath_get", "rna_DriverTarget_RnaPath_length", "rna_DriverTarget_RnaPath_set");
RNA_def_property_ui_text(prop, "RNA Path", "RNA Path (from Object) to property used");
RNA_def_property_ui_text(prop, "Data Path", "RNA Path (from Object) to property used");
RNA_def_property_update(prop, 0, "rna_DriverTarget_update_data");
prop= RNA_def_property(srna, "array_index", PROP_INT, PROP_NONE);
@ -926,9 +926,9 @@ static void rna_def_fcurve(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Driver", "Channel Driver (only set for Driver F-Curves)");
/* Path + Array Index */
prop= RNA_def_property(srna, "rna_path", PROP_STRING, PROP_NONE);
prop= RNA_def_property(srna, "data_path", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(prop, "rna_FCurve_RnaPath_get", "rna_FCurve_RnaPath_length", "rna_FCurve_RnaPath_set");
RNA_def_property_ui_text(prop, "RNA Path", "RNA Path to property affected by F-Curve.");
RNA_def_property_ui_text(prop, "Data Path", "RNA Path to property affected by F-Curve.");
RNA_def_property_update(prop, NC_ANIMATION, NULL); // XXX need an update callback for this to that animation gets evaluated
prop= RNA_def_property(srna, "array_index", PROP_INT, PROP_NONE);