Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Vegdahl <cessen@cessen.com>2011-03-08 10:51:40 +0300
committerNathan Vegdahl <cessen@cessen.com>2011-03-08 10:51:40 +0300
commitf85cb5c36fb79629791d03a146c17370f9fd9f5f (patch)
treef640d8b5085021a1f89e961277a7bca5100c446f /rigify/rig_ui_template.py
parent0619078b325153be04606f559e21310cfef4c474 (diff)
Beginnings of ik/fk snapping functions in Rigify.
So far just IK->FK for biped.arm.
Diffstat (limited to 'rigify/rig_ui_template.py')
-rw-r--r--rigify/rig_ui_template.py175
1 files changed, 169 insertions, 6 deletions
diff --git a/rigify/rig_ui_template.py b/rigify/rig_ui_template.py
index d9469ad4..32b0d61c 100644
--- a/rigify/rig_ui_template.py
+++ b/rigify/rig_ui_template.py
@@ -16,12 +16,175 @@
#
#======================= END GPL LICENSE BLOCK ========================
-UI_SLIDERS = """
+UI_SLIDERS = '''
import bpy
rig_id = "%s"
+def get_pose_matrix_in_other_space(pose_bone, pbs):
+ """ Returns the transform matrix of pose_bone relative to pbs's transform space.
+ In other words, you could take the matrix returned from this, slap
+ it into pbs, and it would have the same world transform as pb.
+ This is with constraints applied.
+ """
+ mat = pose_bone.matrix.copy()
+ 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
+
+
+def get_local_matrix_with_constraints(pose_bone):
+ """ Returns the local matrix of the given pose bone, with constraints
+ applied.
+ """
+ return get_pose_matrix_in_other_space(pose_bone, pose_bone)
+
+
+def set_pose_rotation(pb, mat):
+ """ Sets the pose bone's rotation to the same rotation as the given matrix.
+ 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':
+ pb.rotation_axis_angle[0] = q.angle
+ pb.rotation_axis_angle[1] = q.axis[0]
+ pb.rotation_axis_angle[2] = q.axis[1]
+ pb.rotation_axis_angle[3] = q.axis[2]
+ else:
+ pb.rotation_euler = q.to_euler(pb.rotation_mode)
+
+
+def set_pose_scale(pb, mat):
+ """ Sets the pose bone's scale to the same scale as the given matrix.
+ Matrix should be given in local space.
+ """
+ pb.scale = mat.to_scale()
+
+
+def set_pose_translation(pb, mat):
+ """ Sets the pose bone's translation to the same translation as the given matrix.
+ Matrix should be given in local space.
+ """
+ pb.location = mat.to_translation()
+
+
+def fk2ik(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, 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, 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, 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):
+ """ 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]]
+
+ handmat = get_pose_matrix_in_other_space(hand, handi)
+ set_pose_translation(handi, handmat)
+ set_pose_rotation(handi, handmat)
+ set_pose_scale(handi, handmat)
+ bpy.ops.object.mode_set(mode='OBJECT')
+ bpy.ops.object.mode_set(mode='POSE')
+
+
+class Rigify_Arm_FK2IK(bpy.types.Operator):
+ """ Snaps an FK arm to an IK arm.
+ """
+ bl_idname = "pose.rigify_arm_fk2ik"
+ bl_label = "Rigify Snap FK arm to IK"
+
+ 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")
+
+ @classmethod
+ def poll(cls, context):
+ return (context.active_object != None and context.mode == 'POSE')
+
+ def execute(self, context):
+ fk2ik(context.active_object, fk=[self.uarm_fk, self.farm_fk, self.hand_fk], ik=[self.uarm_ik, self.farm_ik, self.hand_ik])
+ return {'FINISHED'}
+
+
+class Rigify_Arm_IK2FK(bpy.types.Operator):
+ """ Snaps an IK arm to an FK arm.
+ """
+ bl_idname = "pose.rigify_arm_ik2fk"
+ bl_label = "Snap IK arm to FK"
+
+ 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")
+ pole = bpy.props.StringProperty(name="Pole IK Name")
+
+ @classmethod
+ def poll(cls, context):
+ return (context.active_object != None and context.mode == 'POSE')
+
+ def execute(self, context):
+ ik2fk(context.active_object, fk=[self.uarm_fk, self.farm_fk, self.hand_fk], ik=[self.uarm_ik, self.farm_ik, self.hand_ik, self.pole])
+ return {'FINISHED'}
+
+
+bpy.utils.register_class(Rigify_Arm_FK2IK)
+bpy.utils.register_class(Rigify_Arm_IK2FK)
+
+
class RigUI(bpy.types.Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
@@ -57,14 +220,14 @@ class RigUI(bpy.types.Panel):
return False
-"""
+'''
def layers_ui(layers):
""" Turn a list of booleans into a layer UI.
"""
- code = """
+ code = '''
class RigLayers(bpy.types.Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
@@ -81,7 +244,7 @@ class RigLayers(bpy.types.Panel):
def draw(self, context):
layout = self.layout
col = layout.column()
-"""
+'''
i = 0
for layer in layers:
if layer:
@@ -95,12 +258,12 @@ class RigLayers(bpy.types.Panel):
return code
-UI_REGISTER = """
+UI_REGISTER = '''
def register():
bpy.utils.register_class(RigUI)
bpy.utils.register_class(RigLayers)
register()
-"""
+'''