[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [26935] trunk/blender/release/scripts/ modules/rigify/tail_control.py: Rigify:
Nathan Vegdahl
cessen at cessen.com
Mon Feb 15 17:46:25 CET 2010
Revision: 26935
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=26935
Author: cessen
Date: 2010-02-15 17:46:24 +0100 (Mon, 15 Feb 2010)
Log Message:
-----------
Rigify:
Added a tail control rig.
For now, you have to manually hook the resulting controls up to a separate spline IK rig that you make by hand. Perhaps this can be automated in the future.
For anyone using this: keep in mind that you need separate armatures for the tail deformation bones and tail control bones. Otherwise you create a cyclic dependency like so:
tail deform bones <- spline object <- tail control bones
Added Paths:
-----------
trunk/blender/release/scripts/modules/rigify/tail_control.py
Added: trunk/blender/release/scripts/modules/rigify/tail_control.py
===================================================================
--- trunk/blender/release/scripts/modules/rigify/tail_control.py (rev 0)
+++ trunk/blender/release/scripts/modules/rigify/tail_control.py 2010-02-15 16:46:24 UTC (rev 26935)
@@ -0,0 +1,166 @@
+# ##### 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 rigify import RigifyError
+from rigify_utils import bone_class_instance, copy_bone_simple
+from rna_prop_ui import rna_idprop_ui_prop_get
+from Mathutils import Vector, RotationMatrix
+from math import radians, pi
+
+# not used, defined for completeness
+METARIG_NAMES = ("pelvis", "ribcage")
+
+
+def metarig_template():
+ # TODO
+ pass
+ # 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('tail.01')
+ #bone.head[:] = 0.0000, -0.0306, 0.1039
+ #bone.tail[:] = 0.0000, -0.0306, -0.0159
+ #bone.roll = 0.0000
+ #bone.connected = False
+
+ #bpy.ops.object.mode_set(mode='OBJECT')
+ #pbone = obj.pose.bones['tail.01']
+ #pbone['type'] = 'tail_spline_ik'
+
+
+def metarig_definition(obj, orig_bone_name):
+ """ Collects and returns the relevent bones for the rig.
+ The bone given is the first in the chain of tail bones.
+ It includes bones in the chain up until it hits a bone that doesn't
+ have the same name base.
+
+ tail.01 -> tail.02 -> tail.03 -> ... -> tail.n
+ """
+ arm = obj.data
+ tail_base = arm.bones[orig_bone_name]
+
+ if tail_base.parent == None:
+ raise RigifyError("'tail_control' rig type on bone '%s' requires a parent." % orig_bone_name)
+
+ bone_definitions = [tail_base.name]
+ bone_definitions.extend([child.name for child in tail_base.children_recursive_basename])
+ return bone_definitions
+
+
+def main(obj, bone_definitions, base_names, options):
+ bpy.ops.object.mode_set(mode='EDIT')
+ arm = obj.data
+ bb = obj.data.bones
+ eb = obj.data.edit_bones
+ pb = obj.pose.bones
+
+ # Create bones for hinge/free
+ # hinge 1 sticks with the parent
+ # hinge 2 is the parent of the tail controls
+ hinge1 = copy_bone_simple(arm, bone_definitions[0], "MCH-%s.hinge1" % base_names[bone_definitions[0]], parent=True).name
+ hinge2 = copy_bone_simple(arm, bone_definitions[0], "MCH-%s.hinge2" % base_names[bone_definitions[0]], parent=False).name
+
+ # Create tail control bones
+ bones = []
+ i = 0
+ for bone_def in bone_definitions:
+ bone = copy_bone_simple(arm, bone_def, base_names[bone_def], parent=True).name
+ if i == 1: # Don't change parent of first tail bone
+ eb[bone].connected = False
+ eb[bone].parent = eb[hinge2]
+ eb[bone].local_location = False
+ i = 1
+ bones += [bone]
+
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ # Rotation mode and axis locks
+ for bone, org_bone in zip(bones, bone_definitions):
+ pb[bone].rotation_mode = pb[org_bone].rotation_mode
+ pb[bone].lock_location = tuple(pb[org_bone].lock_location)
+ pb[bone].lock_rotations_4d = pb[org_bone].lock_rotations_4d
+ pb[bone].lock_rotation = tuple(pb[org_bone].lock_rotation)
+ pb[bone].lock_rotation_w = pb[org_bone].lock_rotation_w
+ pb[bone].lock_scale = tuple(pb[org_bone].lock_scale)
+
+ # Add custom properties
+ pb[bones[0]]["hinge"] = 0.0
+ prop = rna_idprop_ui_prop_get(pb[bones[0]], "hinge", create=True)
+ prop["min"] = 0.0
+ prop["max"] = 1.0
+ prop["soft_min"] = 0.0
+ prop["soft_max"] = 1.0
+
+ pb[bones[0]]["free"] = 0.0
+ prop = rna_idprop_ui_prop_get(pb[bones[0]], "free", create=True)
+ prop["min"] = 0.0
+ prop["max"] = 1.0
+ prop["soft_min"] = 0.0
+ prop["soft_max"] = 1.0
+
+ # Add constraints
+ for bone, org_bone in zip(bones, bone_definitions):
+ con = pb[org_bone].constraints.new('COPY_TRANSFORMS')
+ con.target = obj
+ con.subtarget = bone
+
+ con_f = pb[hinge2].constraints.new('COPY_LOCATION')
+ con_f.target = obj
+ con_f.subtarget = hinge1
+
+ con_h = pb[hinge2].constraints.new('COPY_TRANSFORMS')
+ con_h.target = obj
+ con_h.subtarget = hinge1
+
+ # Add drivers
+ bone_path = pb[bones[0]].path_to_id()
+
+ driver_fcurve = con_f.driver_add("influence", 0)
+ driver = driver_fcurve.driver
+ driver.type = 'AVERAGE'
+ var = driver.variables.new()
+ var.name = "free"
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = bone_path + '["free"]'
+ mod = driver_fcurve.modifiers[0]
+ mod.poly_order = 1
+ mod.coefficients[0] = 1.0
+ mod.coefficients[1] = -1.0
+
+ driver_fcurve = con_h.driver_add("influence", 0)
+ driver = driver_fcurve.driver
+ driver.type = 'AVERAGE'
+ var = driver.variables.new()
+ var.name = "hinge"
+ var.targets[0].id_type = 'OBJECT'
+ var.targets[0].id = obj
+ var.targets[0].data_path = bone_path + '["hinge"]'
+ mod = driver_fcurve.modifiers[0]
+ mod.poly_order = 1
+ mod.coefficients[0] = 1.0
+ mod.coefficients[1] = -1.0
+
+
+ return None
+
More information about the Bf-blender-cvs
mailing list