Blender Rigify Bone Selector Panel

I’ve been ramping up my animation production lately, and one of the annoyances that I’ve run across while using Blender’s Rigify armature is that it can be difficult to select some of the control bones for a few reasons. In Wireframe display mode, trying to find the proper line segment to click on can be tedious. It helps to disable selection of meshes in the Outliner, but that still doesn’t help not being able to see the appropriate object to select. rigify_model_wireframeIn Solid, Texture, or Material display mode, again, it does help to disable mesh selection, but when the control bone is completely hidden by the mesh, as is the case for my character’s head, you have to start guessing where to click.

rigify_model_texture

The best option by far, suggested to me by reddit user WhatISaidB4, is to enable X-Ray mode in the Armature panel.

rigify_model_armature_xray

Definitely an improvement over the other viewing options, but as you can see, it’s still a bit cluttered when having to make rapid selections.

So I wrote up a Python script to add a bone selector in the Properties panel of the 3D View.

rig_bone_selector

The top “Use Front View” button toggles the view orientation, so that when you’re viewing the character from the front, the left-hand buttons select the right side of the character. If the option is disabled, then the left-hand buttons select the left side of the character.

The buttons outlined in boxes are the inverse kinematics (IK) bone selectors, and everything else refers to a forward kinematics (FK) control bone.

This panel differs from the Rig Layers panel, in that this is for selection, whereas the Rig Layers panel is for toggling the visibility of the rig layers in which each bone resides.

Below is the entire script. You can click on it to download it if you want, and you can just plop into your /Blender/<ver>/scripts/addons directory for Blender, and enabled in the File > User Preferences... > Add-ons window.

Download

#  UTW_RigBoneSelect

#Copyright (c) 2015 Under the Weather, LLC
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software
# and associated documentation files (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all copies
# or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
# PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
# FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

bl_info = {
    "name": "UTW Rig Bone Selector",
    "author": "Under the Weather, LLC",
    "category": "Object",
    "description": "UTW Rig Bone Selector",
}

import bpy

class UTW_RigBoneSelectPanel(bpy.types.Panel):
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_label = "Rig Bone Select"
    
    bpy.types.Scene.use_rig_front_view = bpy.props.BoolProperty(name="Use Front View", default=True, description="Enable if the character is facing frontwards.")

    def side(self, left_side_button, context):
        if left_side_button:
            return "R" if context.scene['use_rig_front_view'] is 1 else "L"
        else:
            return "L" if context.scene['use_rig_front_view'] is 1 else "R"

    def draw_leg_controls(self, col, context, side):
        col.operator("utw.selectrigbone", text="Thigh").bone_name="thigh.fk." + self.side(side, context)
        col.operator("utw.selectrigbone", text="Shin").bone_name="shin.fk." + self.side(side, context)
        box2 = col.box()
        box2.operator("utw.selectrigbone", text="Knee").bone_name="knee_target.ik." + self.side(side, context)
        box2.operator("utw.selectrigbone", text="Foot").bone_name="foot.ik." + self.side(side, context)
        box2.operator("utw.selectrigbone", text="Heel").bone_name="foot_roll.ik." + self.side(side, context)
        col.operator("utw.selectrigbone", text="Foot").bone_name="foot.fk." + self.side(side, context)
        col.operator("utw.selectrigbone", text="Toe").bone_name="toe." + self.side(side, context)
        
    def draw(self, context):
        layout = self.layout
        col = layout.column()

        row = col.row()

        row.prop(context.scene, 'use_rig_front_view', toggle=True)

        row = col.row()
        row.operator("utw.selectrigbone", text="Head").bone_name="head"

        row = col.row()
        row.operator("utw.selectrigbone", text="Shoulder").bone_name="shoulder." + self.side(True, context)
        row.operator("utw.selectrigbone", text="Neck").bone_name="neck"
        row.operator("utw.selectrigbone", text="Shoulder").bone_name="shoulder." + self.side(False, context)

        row = col.row()
        col1 = row.column()
        col1.operator("utw.selectrigbone", text="UpperArm").bone_name="upper_arm.fk." + self.side(True, context)
        col1.operator("utw.selectrigbone", text="Forearm").bone_name="forearm.fk." + self.side(True, context)
        row.operator("utw.selectrigbone", text="Chest").bone_name="chest"
        col2 = row.column()
        col2.operator("utw.selectrigbone", text="UpperArm").bone_name="upper_arm.fk." + self.side(False, context)
        col2.operator("utw.selectrigbone", text="Forearm").bone_name="forearm.fk." + self.side(False, context)
        
        row = col.row()
        box1 = row.box()
        box1.operator("utw.selectrigbone", text="Elbow").bone_name="elbow_target.ik." + self.side(True, context)
        box1.operator("utw.selectrigbone", text="Hand").bone_name="hand.ik." + self.side(True, context)
        col2 = row.column()
        col2.alignment = 'EXPAND'
        col2.operator("utw.selectrigbone", text="Spine").bone_name="spine"
        box2 = row.box()
        box2.operator("utw.selectrigbone", text="Elbow").bone_name="elbow_target.ik." + self.side(False, context)
        box2.operator("utw.selectrigbone", text="Hand").bone_name="hand.ik." + self.side(False, context)


        row = col.row()
        col1 = row.column()
        col1.operator("utw.selectrigbone", text="Hand").bone_name="hand.fk." + self.side(True, context)
        col1.operator("utw.selectrigbone", text="Palm").bone_name="palm." + self.side(True, context)
        colmid = row.column()
        colmid.operator("utw.selectrigbone", text="Torso").bone_name="torso"
        col2 = row.column()
        col2.operator("utw.selectrigbone", text="Hand").bone_name="hand.fk." + self.side(False, context)
        col2.operator("utw.selectrigbone", text="Palm").bone_name="palm." + self.side(False, context)

        row = col.row()
        col1 = row.column()
        self.draw_leg_controls(col1, context, True)

        col3 = row.column()
        self.draw_leg_controls(col3, context, False)

        row = col.row()
        row.operator("utw.selectrigbone", text="Root").bone_name="root"


class UTW_RigBoneSelect(bpy.types.Operator):
    bl_idname = "utw.selectrigbone"
    bl_label = "Bone Selector"

    bone_name = bpy.props.StringProperty()
 
    def execute(self, context):
        bpy.ops.object.select_pattern(pattern=self.bone_name, extend=False)
        return{'FINISHED'}   

def register():
    bpy.utils.register_class(UTW_RigBoneSelect)
    bpy.utils.register_class(UTW_RigBoneSelectPanel)

def unregister():
    bpy.utils.unregister_class(UTW_RigBoneSelect)
    bpy.utils.unregister_class(UTW_RigBoneSelectPanel)

#register()

I’ve seen some really slick bone selector utilities in Maya (you can do a Google image search for “Maya bone rig selector” to see what I mean), which I actually wanted to add for Blender, but I think this is about as far as I think I’m going to go. Hoping this helps streamline somebody’s Blender animation process.

Make it fun!

  • Blender 2.74
  • Python 2.7.10

 

This entry was posted in Art, Dev, Programming. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *