[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [1692] trunk/py/scripts/addons/rigify: Rigify:
Nathan Vegdahl
cessen at cessen.com
Thu Mar 10 01:53:25 CET 2011
Revision: 1692
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=1692
Author: cessen
Date: 2011-03-10 00:53:24 +0000 (Thu, 10 Mar 2011)
Log Message:
-----------
Rigify:
- Added IK/FK snapping (both directions) for legs.
- Cleaned up another operator so that it works with undo.
- PEP8 cleanups.
Modified Paths:
--------------
trunk/py/scripts/addons/rigify/__init__.py
trunk/py/scripts/addons/rigify/rig_ui_template.py
trunk/py/scripts/addons/rigify/rigs/biped/leg/__init__.py
trunk/py/scripts/addons/rigify/rigs/biped/leg/fk.py
trunk/py/scripts/addons/rigify/rigs/biped/leg/ik.py
trunk/py/scripts/addons/rigify/rigs/finger.py
trunk/py/scripts/addons/rigify/ui.py
Modified: trunk/py/scripts/addons/rigify/__init__.py
===================================================================
--- trunk/py/scripts/addons/rigify/__init__.py 2011-03-09 22:13:51 UTC (rev 1691)
+++ trunk/py/scripts/addons/rigify/__init__.py 2011-03-10 00:53:24 UTC (rev 1692)
@@ -116,7 +116,6 @@
name = bpy.props.StringProperty()
-
##### REGISTER #####
def register():
@@ -142,6 +141,7 @@
except AttributeError:
pass
+
def unregister():
del bpy.types.PoseBone.rigify_type
del bpy.types.PoseBone.rigify_parameters
Modified: trunk/py/scripts/addons/rigify/rig_ui_template.py
===================================================================
--- trunk/py/scripts/addons/rigify/rig_ui_template.py 2011-03-09 22:13:51 UTC (rev 1691)
+++ trunk/py/scripts/addons/rigify/rig_ui_template.py 2011-03-10 00:53:24 UTC (rev 1692)
@@ -31,15 +31,15 @@
This is with constraints applied.
"""
rest_inv = pbs.bone.matrix_local.inverted()
-
+
if pbs.parent:
par_inv = pbs.parent.matrix.inverted()
par_rest = pbs.parent.bone.matrix_local.copy()
-
+
smat = rest_inv * (par_rest * (par_inv * mat))
else:
smat = rest_inv * mat
-
+
return smat
@@ -55,7 +55,7 @@
Matrix should be given in local space.
"""
q = mat.to_quaternion()
-
+
if pb.rotation_mode == 'QUATERNION':
pb.rotation_quaternion = q
elif pb.rotation_mode == 'AXIS_ANGLE':
@@ -82,63 +82,63 @@
pb.location = mat.to_translation()
else:
loc = mat.to_translation()
-
+
rest = pb.bone.matrix_local.copy()
if pb.bone.parent:
par_rest = pb.bone.parent.matrix_local.copy()
else:
par_rest = Matrix()
-
+
q = (par_rest.inverted() * rest).to_quaternion()
pb.location = loc * q
-def fk2ik(obj, fk, ik):
+def fk2ik_arm(obj, fk, ik):
""" Matches the fk bones in an arm rig to the ik bones.
"""
pb = obj.pose.bones
-
+
uarm = pb[fk[0]]
farm = pb[fk[1]]
hand = pb[fk[2]]
-
+
uarmi = pb[ik[0]]
farmi = pb[ik[1]]
handi = pb[ik[2]]
-
+
uarmmat = get_pose_matrix_in_other_space(uarmi.matrix, uarm)
set_pose_rotation(uarm, uarmmat)
set_pose_scale(uarm, uarmmat)
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.mode_set(mode='POSE')
-
+
farmmat = get_pose_matrix_in_other_space(farmi.matrix, farm)
set_pose_rotation(farm, farmmat)
set_pose_scale(farm, farmmat)
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.mode_set(mode='POSE')
-
+
handmat = get_pose_matrix_in_other_space(handi.matrix, hand)
set_pose_rotation(hand, handmat)
set_pose_scale(hand, handmat)
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.mode_set(mode='POSE')
-
-
-def ik2fk(obj, fk, ik):
+
+
+def ik2fk_arm(obj, fk, ik):
""" Matches the ik bones in an arm rig to the fk bones.
"""
pb = obj.pose.bones
-
+
uarm = pb[fk[0]]
farm = pb[fk[1]]
hand = pb[fk[2]]
-
+
uarmi = pb[ik[0]]
farmi = pb[ik[1]]
handi = pb[ik[2]]
pole = pb[ik[3]]
-
+
# Hand position
handmat = get_pose_matrix_in_other_space(hand.matrix, handi)
set_pose_translation(handi, handmat)
@@ -146,15 +146,15 @@
set_pose_scale(handi, handmat)
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.mode_set(mode='POSE')
-
+
# Pole target position
a = uarm.matrix.to_translation()
b = farm.matrix.to_translation() + farm.vector
-
+
# Vector from the head of the upper arm to the
# tip of the forearm
armv = b - a
-
+
# Create a vector that is not aligned with armv.
# It doesn't matter what vector. Just any vector
# that's guaranteed to not be pointing in the same
@@ -165,33 +165,33 @@
v = Vector((0,1,0))
else:
v = Vector((0,0,1))
-
+
# cross v with armv to get a vector perpendicular to armv
pv = v.cross(armv).normalized() * (uarm.length + farm.length)
-
+
def set_pole(pvi):
# Translate pvi into armature space
ploc = a + (armv/2) + pvi
-
+
# Set pole target to location
mat = get_pose_matrix_in_other_space(Matrix().Translation(ploc), pole)
set_pose_translation(pole, mat)
-
+
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.mode_set(mode='POSE')
-
+
set_pole(pv)
-
+
# Get the rotation difference between the ik and fk upper arms
q1 = uarm.matrix.to_quaternion()
q2 = uarmi.matrix.to_quaternion()
angle = acos(min(1,max(-1,q1.dot(q2)))) * 2
-
+
# Compensate for the rotation difference
if angle > 0.00001:
pv *= Matrix.Rotation(angle, 4, armv).to_quaternion()
set_pole(pv)
-
+
q1 = uarm.matrix.to_quaternion()
q2 = uarmi.matrix.to_quaternion()
angle2 = acos(min(1,max(-1,q1.dot(q2)))) * 2
@@ -200,17 +200,132 @@
set_pole(pv)
+def fk2ik_leg(obj, fk, ik):
+ """ Matches the fk bones in a leg rig to the ik bones.
+ """
+ pb = obj.pose.bones
+
+ thigh = pb[fk[0]]
+ shin = pb[fk[1]]
+ foot = pb[fk[2]]
+ mfoot = pb[fk[3]]
+
+ thighi = pb[ik[0]]
+ shini = pb[ik[1]]
+ mfooti = pb[ik[2]]
+
+ thighmat = get_pose_matrix_in_other_space(thighi.matrix, thigh)
+ set_pose_rotation(thigh, thighmat)
+ set_pose_scale(thigh, thighmat)
+ bpy.ops.object.mode_set(mode='OBJECT')
+ bpy.ops.object.mode_set(mode='POSE')
+
+ shinmat = get_pose_matrix_in_other_space(shini.matrix, shin)
+ set_pose_rotation(shin, shinmat)
+ set_pose_scale(shin, shinmat)
+ bpy.ops.object.mode_set(mode='OBJECT')
+ bpy.ops.object.mode_set(mode='POSE')
+
+ mat = mfoot.bone.matrix_local.inverted() * foot.bone.matrix_local
+ footmat = get_pose_matrix_in_other_space(mfooti.matrix, foot) * mat
+ set_pose_rotation(foot, footmat)
+ set_pose_scale(foot, footmat)
+ bpy.ops.object.mode_set(mode='OBJECT')
+ bpy.ops.object.mode_set(mode='POSE')
+
+
+def ik2fk_leg(obj, fk, ik):
+ """ Matches the ik bones in a leg rig to the fk bones.
+ """
+ pb = obj.pose.bones
+
+ thigh = pb[fk[0]]
+ shin = pb[fk[1]]
+ mfoot = pb[fk[2]]
+
+ thighi = pb[ik[0]]
+ shini = pb[ik[1]]
+ footi = pb[ik[2]]
+ footroll = pb[ik[3]]
+ pole = pb[ik[4]]
+ mfooti = pb[ik[5]]
+
+ # Clear footroll
+ set_pose_rotation(footroll, Matrix())
+
+ # Foot position
+ mat = mfooti.bone.matrix_local.inverted() * footi.bone.matrix_local
+ footmat = get_pose_matrix_in_other_space(mfoot.matrix, footi) * mat
+ set_pose_translation(footi, footmat)
+ set_pose_rotation(footi, footmat)
+ set_pose_scale(footi, footmat)
+ bpy.ops.object.mode_set(mode='OBJECT')
+ bpy.ops.object.mode_set(mode='POSE')
+
+ # Pole target position
+ a = thigh.matrix.to_translation()
+ b = shin.matrix.to_translation() + shin.vector
+
+ # Vector from the head of the thigh to the
+ # tip of the shin
+ legv = b - a
+
+ # Create a vector that is not aligned with legv.
+ # It doesn't matter what vector. Just any vector
+ # that's guaranteed to not be pointing in the same
+ # direction.
+ if abs(legv[0]) < abs(legv[1]) and abs(legv[0]) < abs(legv[2]):
+ v = Vector((1,0,0))
+ elif abs(legv[1]) < abs(legv[2]):
+ v = Vector((0,1,0))
+ else:
+ v = Vector((0,0,1))
+
+ # Get a vector perpendicular to legv
+ pv = v.cross(legv).normalized() * (thigh.length + shin.length)
+
+ def set_pole(pvi):
+ # Translate pvi into armature space
+ ploc = a + (legv/2) + pvi
+
+ # Set pole target to location
+ mat = get_pose_matrix_in_other_space(Matrix().Translation(ploc), pole)
+ set_pose_translation(pole, mat)
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+ bpy.ops.object.mode_set(mode='POSE')
+
+ set_pole(pv)
+
+ # Get the rotation difference between the ik and fk thighs
+ q1 = thigh.matrix.to_quaternion()
+ q2 = thighi.matrix.to_quaternion()
+ angle = acos(min(1,max(-1,q1.dot(q2)))) * 2
+
+ # Compensate for the rotation difference
+ if angle > 0.00001:
+ pv *= Matrix.Rotation(angle, 4, legv).to_quaternion()
+ set_pole(pv)
+
+ q1 = thigh.matrix.to_quaternion()
+ q2 = thighi.matrix.to_quaternion()
+ angle2 = acos(min(1,max(-1,q1.dot(q2)))) * 2
+ if angle2 > 0.00001:
+ pv *= Matrix.Rotation((angle*(-2)), 4, legv).to_quaternion()
+ set_pole(pv)
+
+
class Rigify_Arm_FK2IK(bpy.types.Operator):
""" Snaps an FK arm to an IK arm.
"""
bl_idname = "pose.rigify_arm_fk2ik_" + rig_id
bl_label = "Rigify Snap FK arm to IK"
bl_options = {'UNDO'}
-
+
uarm_fk = bpy.props.StringProperty(name="Upper Arm FK Name")
farm_fk = bpy.props.StringProperty(name="Forerm FK Name")
hand_fk = bpy.props.StringProperty(name="Hand FK Name")
-
+
uarm_ik = bpy.props.StringProperty(name="Upper Arm IK Name")
farm_ik = bpy.props.StringProperty(name="Forearm IK Name")
hand_ik = bpy.props.StringProperty(name="Hand IK Name")
@@ -223,7 +338,7 @@
use_global_undo = context.user_preferences.edit.use_global_undo
context.user_preferences.edit.use_global_undo = False
try:
- fk2ik(context.active_object, fk=[self.uarm_fk, self.farm_fk, self.hand_fk], ik=[self.uarm_ik, self.farm_ik, self.hand_ik])
+ fk2ik_arm(context.active_object, fk=[self.uarm_fk, self.farm_fk, self.hand_fk], ik=[self.uarm_ik, self.farm_ik, self.hand_ik])
finally:
context.user_preferences.edit.use_global_undo = use_global_undo
return {'FINISHED'}
@@ -233,13 +348,13 @@
""" Snaps an IK arm to an FK arm.
"""
bl_idname = "pose.rigify_arm_ik2fk_" + rig_id
- bl_label = "Snap IK arm to FK"
+ bl_label = "Rigify Snap IK arm to FK"
bl_options = {'UNDO'}
-
+
uarm_fk = bpy.props.StringProperty(name="Upper Arm FK Name")
farm_fk = bpy.props.StringProperty(name="Forerm FK Name")
hand_fk = bpy.props.StringProperty(name="Hand FK Name")
-
+
uarm_ik = bpy.props.StringProperty(name="Upper Arm IK Name")
farm_ik = bpy.props.StringProperty(name="Forearm IK Name")
hand_ik = bpy.props.StringProperty(name="Hand IK Name")
@@ -253,14 +368,79 @@
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-extensions-cvs
mailing list