diff options
author | Campbell Barton <ideasman42@gmail.com> | 2009-12-02 05:56:22 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2009-12-02 05:56:22 +0300 |
commit | 50c8c28c60a88a615c1dbace004b75316ebd2437 (patch) | |
tree | 515011097322613565d0b21e46afe2711596ea35 /release | |
parent | fd69360fd2c8bb9850134e37ec18608cfd94dbce (diff) |
- finished spine rig generator, (drivers, constraints)
- bug with args passed for class slots being modified in place.
- sort graphviz bones & drivers (useful for diffing 2 armatures)
Diffstat (limited to 'release')
-rw-r--r-- | release/scripts/modules/graphviz_export.py | 14 | ||||
-rw-r--r-- | release/scripts/modules/rigify/__init__.py | 4 | ||||
-rw-r--r-- | release/scripts/modules/rigify/spine.py | 215 |
3 files changed, 223 insertions, 10 deletions
diff --git a/release/scripts/modules/graphviz_export.py b/release/scripts/modules/graphviz_export.py index 1e6d9ffe95b..c5b8b185893 100644 --- a/release/scripts/modules/graphviz_export.py +++ b/release/scripts/modules/graphviz_export.py @@ -26,7 +26,7 @@ footer = ''' } ''' -def compat_str(text, line_length=22): +def compat_str(text, line_length=0): if line_length: text_ls = [] @@ -88,7 +88,9 @@ def graph_armature(obj, path, FAKE_PARENT=True, CONSTRAINTS=True, DRIVERS=True): if FAKE_PARENT: fw('"Object::%s" [];\n' % obj.name) - for bone in arm.bones: + for bone in bones: + bone = arm.bones[bone] + parent = bone.parent if parent: parent_name = parent.name @@ -131,7 +133,11 @@ def graph_armature(obj, path, FAKE_PARENT=True, CONSTRAINTS=True, DRIVERS=True): animation_data = obj.animation_data if animation_data: - for fcurve_driver in animation_data.drivers: + + fcurve_drivers = [fcurve_driver for fcurve_driver in animation_data.drivers] + fcurve_drivers.sort(key=lambda fcurve_driver: fcurve_driver.rna_path) + + for fcurve_driver in fcurve_drivers: rna_path = fcurve_driver.rna_path pbone = rna_path_as_pbone(rna_path) @@ -158,5 +164,5 @@ if __name__ == "__main__": import bpy import os path ="/tmp/test.dot" - graph_armature(bpy.context.object, path, CONSTRAINTS=False, DRIVERS=False) + graph_armature(bpy.context.object, path, CONSTRAINTS=True, DRIVERS=True) os.system("dot -Tpng %s > %s; eog %s &" % (path, path + '.png', path + '.png')) diff --git a/release/scripts/modules/rigify/__init__.py b/release/scripts/modules/rigify/__init__.py index 9d34f9a72ff..a0b5c721b2a 100644 --- a/release/scripts/modules/rigify/__init__.py +++ b/release/scripts/modules/rigify/__init__.py @@ -31,7 +31,9 @@ def auto_class_instance(slots, name="ContainerClass"): return auto_class(slots, name)() def bone_class_instance(obj, slots, name="BoneContainer"): - for member in slots[:]: + slots = slots[:] # dont modify the original + for i in range(len(slots)): + member = slots[i] slots.append(member + "_b") # bone bone slots.append(member + "_p") # pose bone slots.append(member + "_e") # edit bone diff --git a/release/scripts/modules/rigify/spine.py b/release/scripts/modules/rigify/spine.py index ebc8b6ccdc0..d507d6fe1bc 100644 --- a/release/scripts/modules/rigify/spine.py +++ b/release/scripts/modules/rigify/spine.py @@ -114,6 +114,7 @@ def main(obj, orig_bone_name): # - copy (*use original name*) # - reverse (MCH-rev_*) spine_chain_attrs = [("spine_%.2d" % (i + 1)) for i in range(len(spine_chain_orig))] + mt_chain = bone_class_instance(obj, spine_chain_attrs) # ORG_* rv_chain = bone_class_instance(obj, spine_chain_attrs) # * ex_chain = bone_class_instance(obj, spine_chain_attrs) # MCH-rev_* @@ -152,7 +153,7 @@ def main(obj, orig_bone_name): # ex_chain needs to interlace bones! # Note, skip the first bone - for i in range(1, len(spine_chain_orig)): # similar to neck + for i in range(1, len(spine_chain_attrs)): # similar to neck child_name_orig = spine_chain_orig[i] spine_e = getattr(mt_chain, spine_chain_attrs[i] + "_e") @@ -174,14 +175,218 @@ def main(obj, orig_bone_name): # Rotate the rev chain 180 about the by the first bones center point pivot = (rv_chain.spine_01_e.head + rv_chain.spine_01_e.tail) * 0.5 matrix = RotationMatrix(radians(180), 3, 'X') - for i in range(len(spine_chain_orig)): # similar to neck + for i in range(len(spine_chain_attrs)): # similar to neck spine_e = getattr(rv_chain, spine_chain_attrs[i] + "_e") # use the first bone as the pivot spine_e.head = ((spine_e.head - pivot) * matrix) + pivot spine_e.tail = ((spine_e.tail - pivot) * matrix) + pivot spine_e.roll += pi # 180d roll + del spine_e + + + bpy.ops.object.mode_set(mode='OBJECT') + + # refresh pose bones + mt.update() + ex.update() + df.update() + mt_chain.update() + ex_chain.update() + rv_chain.update() + + # 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 + 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 + con.subtarget = mt.pelvis + + # add driver + hinge_driver_path = mt.ribcage_p.path_to_id() + '["hinge"]' + + fcurve = con.driver_add("influence", 0) + driver = fcurve.driver + tar = driver.targets.new() + driver.type = 'AVERAGE' + tar.name = "var" + tar.id_type = 'OBJECT' + tar.id = obj + tar.rna_path = hinge_driver_path + + mod = fcurve.modifiers[0] + mod.poly_order = 1 + mod.coefficients[0] = 1.0 + mod.coefficients[1] = -1.0 + + + + con = ex.spine_rotate_p.constraints.new('COPY_ROTATION') + con.target = obj + con.subtarget = mt.ribcage + + + # ex.pelvis_p / MCH-wgt_pelvis + con = ex.pelvis_p.constraints.new('COPY_LOCATION') + con.target = obj + con.subtarget = mt_chain.spine_01 + + con = ex.pelvis_p.constraints.new('COPY_ROTATION') + con.target = obj + con.subtarget = mt_chain.spine_01 + + # ex.ribcage_p / MCH-wgt_rib_cage + con = ex.ribcage_p.constraints.new('COPY_LOCATION') + con.target = obj + con.subtarget = getattr(mt_chain, spine_chain_attrs[-1]) + con.head_tail = 0.0 + + con = ex.ribcage_p.constraints.new('COPY_ROTATION') + con.target = obj + con.subtarget = getattr(mt_chain, spine_chain_attrs[-1]) + + # mt.pelvis_p / rib_cage + con = mt.ribcage_p.constraints.new('COPY_LOCATION') + con.target = obj + con.subtarget = mt.pelvis + con.head_tail = 0.0 + + # This stores all important ID props + prop = rna_idprop_ui_prop_get(mt.ribcage_p, "hinge", create=True) + mt.ribcage_p["hinge"] = 1.0 + prop["soft_min"] = 0.0 + prop["soft_max"] = 1.0 + + prop = rna_idprop_ui_prop_get(mt.ribcage_p, "pivot_slide", create=True) + mt.ribcage_p["pivot_slide"] = 0.5 + prop["soft_min"] = 1.0 / len(spine_chain_attrs) + prop["soft_max"] = 1.0 + + for i in range(len(spine_chain_attrs) - 1): + prop_name = "bend_%.2d" % (i + 1) + prop = rna_idprop_ui_prop_get(mt.ribcage_p, prop_name, create=True) + mt.ribcage_p[prop_name] = 1.0 + prop["soft_min"] = 0.0 + prop["soft_max"] = 1.0 + + # Create a fake connected parent/child relationship with bone location constraints + # positioned at the tip. + + # reverse bones / MCH-rev_spine.## + for i in range(1, len(spine_chain_attrs)): + spine_p = getattr(rv_chain, spine_chain_attrs[i] + "_p") + spine_fake_parent_name = getattr(rv_chain, spine_chain_attrs[i - 1]) + + con = spine_p.constraints.new('COPY_LOCATION') + con.target = obj + con.subtarget = spine_fake_parent_name + con.head_tail = 1.0 + del spine_p, spine_fake_parent_name, con + + + # Constrain 'inbetween' bones + + # b01/max(0.001,b01+b02+b03+b04+b05) + target_names = [("b%.2d" % (i + 1)) for i in range(len(spine_chain_attrs) - 1)] + expression_suffix = "/max(0.001,%s)" % "+".join(target_names) + + rib_driver_path = mt.ribcage_p.path_to_id() + + for i in range(1, len(spine_chain_attrs)): + + spine_p = getattr(ex_chain, spine_chain_attrs[i] + "_p") + spine_p_parent = spine_p.parent # interlaced bone + + con = spine_p_parent.constraints.new('COPY_ROTATION') + con.target = obj + con.subtarget = ex.spine_rotate + con.owner_space = 'LOCAL' + con.target_space = 'LOCAL' + del spine_p + + # add driver + fcurve = con.driver_add("influence", 0) + driver = fcurve.driver + driver.type = 'SCRIPTED' + # b01/max(0.001,b01+b02+b03+b04+b05) + driver.expression = target_names[i - 1] + expression_suffix + fcurve.modifiers.remove(0) # grr dont need a modifier + + for j in range(len(spine_chain_attrs) - 1): + tar = driver.targets.new() + tar.name = target_names[j] + tar.id_type = 'OBJECT' + tar.id = obj + tar.rna_path = rib_driver_path + ('["bend_%.2d"]' % (j + 1)) + + + # original bone drivers + # note: the first bone has a lot more constraints, but also this simple one is first. + for i in range(len(spine_chain_attrs)): + spine_p = getattr(mt_chain, spine_chain_attrs[i] + "_p") + + con = spine_p.constraints.new('COPY_ROTATION') + con.target = obj + con.subtarget = getattr(ex_chain, spine_chain_attrs[i]) # lock to the copy's rotation + del spine_p + + # pivot slide: - lots of copy location constraints. + + con = mt_chain.spine_01_p.constraints.new('COPY_LOCATION') + con.name = "base" + con.target = obj + con.subtarget = rv_chain.spine_01 # lock to the reverse location + + for i in range(1, len(spine_chain_attrs) + 1): + con = mt_chain.spine_01_p.constraints.new('COPY_LOCATION') + con.name = "slide_%d" % i + con.target = obj + + if i == len(spine_chain_attrs): + attr = spine_chain_attrs[i - 1] + else: + attr = spine_chain_attrs[i] + + con.subtarget = getattr(rv_chain, attr) # lock to the reverse location + + if i == len(spine_chain_attrs): + con.head_tail = 1.0 + + fcurve = con.driver_add("influence", 0) + driver = fcurve.driver + tar = driver.targets.new() + driver.type = 'AVERAGE' + tar.name = "var" + tar.id_type = 'OBJECT' + tar.id = obj + tar.rna_path = rib_driver_path + '["pivot_slide"]' + + mod = fcurve.modifiers[0] + mod.poly_order = 1 + mod.coefficients[0] = - (i - 1) + mod.coefficients[1] = len(spine_chain_attrs) - # done with editmode - # TODO, posemode -
\ No newline at end of file |