Rigify Global IK/FK Switch?

Hello friends, I’m doing a bunch of retargeting to Rigify and sometimes it would be very handy to switch ALL IK/FK for limbs and fingers. Also it would be nice to be able to set up switches for subsets, like hit a button and all of the right arm and fingers are IK. Or FK.

The way it is now I have to do a selection of fingers and hand and go down the list to turn everything on or off.

Does that make sense? I’m somewhat a noob to Rigify, would appreciate any insight.

Many thanks.

First thing that comes to mind is to do it with python. That would give you a button(s) in the UI like the rest of the controls. But most people don’t know python…

You could also do it with rigging, creating bones to act as the switches, and use drivers on the rigify FK/IK switches. But you’d have to know rigging to pull that off.

Maybe these ideas will spark other ideas from others…

Randy

I can also drive them from a CA…not as elegant as your solution (and thank you!), but I am weak @ python, sad to say.

I’m somewhat surprised that the solution isn’t already part of rigify…it’s such a robust and solid rig that I just expected such switches to be there already.

Yeah I thought about driving from custom attribute too…

How weak @ python are you?

Notice the bottom panel - Rig Switches. Every time I click the Left Arm Switch button, the arm switches from FK to IK or IK to FK. Right now, it’s either FK or IK, no decimal values like 0.5 will work.

Code should be easy to duplicate for the rest of the limbs if you know the basics of python in blender.

I’m not posting the code now because it’s for v3.6.5, I’ll post it when I get it updated for 4.0x.

Randy

Hey Randy, thanks for this. I know enough about coding to be able to hack scripts well enough. Nothing above beginner level, sorry to say.

It looks like you have exactly what I’m talking about in your 3.6 code. Please do give a shout when you update it! Even being able to study what you have now would be a good starting point for me, an excellent opportunity to learn.

Turns out the code works in 4.0.2

I don’t know why I worked on this in 3.6.5, guess because I still have projects in that version.

Anyway, copy and paste this code into the text editor, give it a name like FK-IK_Switches.py and execute it and it should give you the menu in my screenshot.

Edit - code deleted from this post, see below

Duplicate the Switch_LeftArm_Operator code and change the bone names for the right arm. Change the name of the operator to Switch_RightArm_Operator and add that to the RigSwitch panel. Also add the Switch_RightArm_Operator in the register() function.

Feel free to ask questions,
Randy

This is fantastic, Randy! Thanks so much. I had to plug in the name of the rig in the “rig” field to make it work. I’m assuming that’s not correct? Probably need to set it for selected armature? I’m going to enjoy studying this, thanks a million. It definitely works, I’m wondering how it gets implemented for multiple rigs in the same scene. Really good knowledge getting shared here, much appreciation. I’ll jump into adding the right arm tomorrow.

I took another trip thru the code the other night… Streamlined it a bit, removed stuff that wasn’t needed. Added in the right arm switching code as an example

import bpy


class RigSwitch(bpy.types.Panel):
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_label = "Rig Switches"
    bl_idname = "VIEW3D_PT_rig_switch"
    bl_category = 'Item'

    @classmethod
    def poll(self, context):
        return context.mode == 'POSE'

    def draw(self, context):
        layout = self.layout      
        layout.label(text="Global FK/IK Switches")
        row = layout.row()
        row.operator('pose.switch_left_arm_operator')
        row = layout.row()
        row.operator('pose.switch_right_arm_operator')
        

class Switch_LeftArm_Operator(bpy.types.Operator):
    """Toggles Left Arm FK/IK"""
    bl_idname = "pose.switch_left_arm_operator"
    bl_label = "Left Arm Toggle"

    @classmethod
    def poll(cls, context):
        return context.mode == 'POSE'

    def execute(self, context):        
        if (bpy.context.active_object.pose.bones['upper_arm_parent.L']['IK_FK'] >= 0.5):
            bpy.context.active_object.pose.bones['upper_arm_parent.L']['IK_FK'] = 0
        elif (bpy.context.active_object.pose.bones['upper_arm_parent.L']['IK_FK'] <= 0.5):
             bpy.context.active_object.pose.bones['upper_arm_parent.L']['IK_FK'] = 1
                
        return {'FINISHED'}


class Switch_RightArm_Operator(bpy.types.Operator):
    """Toggles Right Arm FK/IK"""
    bl_idname = "pose.switch_right_arm_operator"
    bl_label = "Right Arm Toggle"

    @classmethod
    def poll(cls, context):
        return context.mode == 'POSE'

    def execute(self, context):        
        if (bpy.context.active_object.pose.bones['upper_arm_parent.R']['IK_FK'] >= 0.5):
            bpy.context.active_object.pose.bones['upper_arm_parent.R']['IK_FK'] = 0
        elif (bpy.context.active_object.pose.bones['upper_arm_parent.R']['IK_FK'] <= 0.5):
             bpy.context.active_object.pose.bones['upper_arm_parent.R']['IK_FK'] = 1
                
        return {'FINISHED'}
        


def register():
    bpy.utils.register_class(Switch_LeftArm_Operator)
    bpy.utils.register_class(Switch_RightArm_Operator)
    bpy.utils.register_class(RigSwitch)
    

register()


This part is gone

And it should now work with as many rigify rigs as you have in the scene, but I haven’t tested that. So maybe it will work?

Randy

It’s working great so far, Randy. I’ve got 2 rigs appended and they’re both responding to the buttons. Wonderful stuff, I’ll enjoy learning from this.

Much appreciation. Now I’ll see if I can apply it to legs.

It would be sweet if I can add this button functionality to my RigUI setups. Not sure how to do that yet.

@revolt_randy

Just an update:

I was able to make a complete script that switched R L Arms, R L Legs and R L Fingers.

I was surprised to find that the fingers each have FK_IK keys instead of IK_FK keys like the limbs. Curious…but nicely instructional.

Danny Mac’s beginning python video was very helpful. I’m posting the url here because I think Danny should get some props.

So here’s the thing:
The script works if I run it but I noticed that when I switched to the second rig to play with the switches, some of the Rigify IK/FK controls aren’t there. This happens with the previous version as well. (The version without the fingers.) So maybe the script is breaking Rigify? I’ll need to keep looking.

For now, I’m just really grateful for the learning.

Take a look for error message in blender’s console window, if you haven’t already.

Can you upload a file showing the problem, I could take a look. That script really shouldn’t interfere with rigify’s scripts.

Randy

Well, Randy, I haven’t been able to recreate the problem, so either I was tripping (not impossible) or it was a one-off. If it happens again, I’ll definitely have a look in the console.

Meanwhile, I want to try and modify the script so I can automate the IK fingertips’ Parent switching from 0 to 1.

I’d be happy to post my result if anybody wants to use or improve it.

As before, many thanks for your guidance.

UPDATE: All good. Finger Tips parenting can all be done with one switch.
I need to look up how to get the buttons to be 2 to a row.

To get these new buttons to show up in the rig’s UI panel, you’ll have to edit the rig’s rig_ui.py text file for each rig. Maybe this line of code

layout.operator('pose.switch_left_arm_operator')

after line 1369 might do it for the left arm. But I haven’t tested it. Of course you’ll have to add the operator class(es) to rigify’s rig_ui.py as well. This could be messy and lead to errors.

to get 2 buttons on the same row, remove the 2nd row = layout.row()

giving you this

def draw(self, context):
        layout = self.layout      
        layout.label(text="Global FK/IK Switches")
        row = layout.row()
        row.operator('pose.switch_left_arm_operator')
        row.operator('pose.switch_right_arm_operator')

Also, don’t think I mentioned this, but to get this bit of code to run every time you open a file, in the text editor menu Text → Register, enable the check box.

Randy

Sorry Randy, I wasn’t clear. I was referring to the addon RigUI, not the rigify py script.

But what you told me is really intriguing and I’m having a look at the rigify script for the investigation and learning. Thanks very much for that.

If I get around to it, I’ll ask the addon creators, they’re really cool people.

The switches fit quite nicely into 2 buttons/row. Many, many thanks.

Same thing, to add it to that addon, it needs to have the code added to the addon’s code. You say the devs are cool maybe if you show them what you have, they’ll add it.

I could also turn this into an addon and share with the community, but does anyone really need this other than you?

Anyway, glad it’s working for you and happy that you may have learned along the way…

Randy