[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [1684] trunk/py/scripts/addons/rigify: Beginnings of ik/fk snapping functions in Rigify.

Nathan Vegdahl cessen at cessen.com
Tue Mar 8 08:51:40 CET 2011


Revision: 1684
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=1684
Author:   cessen
Date:     2011-03-08 07:51:40 +0000 (Tue, 08 Mar 2011)
Log Message:
-----------
Beginnings of ik/fk snapping functions in Rigify.
So far just IK->FK for biped.arm.

Modified Paths:
--------------
    trunk/py/scripts/addons/rigify/rig_ui_template.py
    trunk/py/scripts/addons/rigify/rigs/biped/arm/__init__.py
    trunk/py/scripts/addons/rigify/rigs/biped/arm/ik.py

Modified: trunk/py/scripts/addons/rigify/rig_ui_template.py
===================================================================
--- trunk/py/scripts/addons/rigify/rig_ui_template.py	2011-03-07 21:51:30 UTC (rev 1683)
+++ trunk/py/scripts/addons/rigify/rig_ui_template.py	2011-03-08 07:51:40 UTC (rev 1684)
@@ -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 @@
             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 @@
     def draw(self, context):
         layout = self.layout
         col = layout.column()
-"""
+'''
     i = 0
     for layer in layers:
         if layer:
@@ -95,12 +258,12 @@
     return code
 
 
-UI_REGISTER = """
+UI_REGISTER = '''
 
 def register():
     bpy.utils.register_class(RigUI)
     bpy.utils.register_class(RigLayers)
 
 register()
-"""
+'''
 

Modified: trunk/py/scripts/addons/rigify/rigs/biped/arm/__init__.py
===================================================================
--- trunk/py/scripts/addons/rigify/rigs/biped/arm/__init__.py	2011-03-07 21:51:30 UTC (rev 1683)
+++ trunk/py/scripts/addons/rigify/rigs/biped/arm/__init__.py	2011-03-08 07:51:40 UTC (rev 1684)
@@ -27,9 +27,16 @@
 
 script = """
 fk_arm = ["%s", "%s", "%s"]
-ik_arm = ["%s", "%s"]
+ik_arm = ["%s", "%s", "%s", "%s"]
 if is_selected(fk_arm+ik_arm):
-    layout.prop(pose_bones[ik_arm[0]], '["ikfk_switch"]', text="FK / IK (" + ik_arm[0] + ")", slider=True)
+    layout.prop(pose_bones[ik_arm[2]], '["ikfk_switch"]', text="FK / IK (" + ik_arm[2] + ")", slider=True)
+    p = layout.operator("pose.rigify_arm_fk2ik", text="Snap FK->IK (" + fk_arm[0] + ")")
+    p.uarm_fk = fk_arm[0]
+    p.farm_fk = fk_arm[1]
+    p.hand_fk = fk_arm[2]
+    p.uarm_ik = ik_arm[0]
+    p.farm_ik = ik_arm[1]
+    p.hand_ik = ik_arm[2]
 if is_selected(fk_arm):
     layout.prop(pose_bones[fk_arm[0]], '["isolate"]', text="Isolate Rotation (" + fk_arm[0] + ")", slider=True)
 """
@@ -64,7 +71,7 @@
         self.deform_rig.generate()
         fk_controls = self.fk_rig.generate()
         ik_controls = self.ik_rig.generate()
-        return [script % (fk_controls[0], fk_controls[1], fk_controls[2], ik_controls[0], ik_controls[1])]
+        return [script % (fk_controls[0], fk_controls[1], fk_controls[2], ik_controls[0], ik_controls[1], ik_controls[2], ik_controls[3])]
 
     @classmethod
     def add_parameters(self, group):

Modified: trunk/py/scripts/addons/rigify/rigs/biped/arm/ik.py
===================================================================
--- trunk/py/scripts/addons/rigify/rigs/biped/arm/ik.py	2011-03-07 21:51:30 UTC (rev 1683)
+++ trunk/py/scripts/addons/rigify/rigs/biped/arm/ik.py	2011-03-08 07:51:40 UTC (rev 1684)
@@ -303,5 +303,5 @@
             mod = ob.modifiers.new("subsurf", 'SUBSURF')
             mod.levels = 2
 
-        return [hand, pole]
+        return [uarm, farm, hand, pole]
 



More information about the Bf-extensions-cvs mailing list