Home Website Youtube GitHub

Post script to hide ctl shapes visibility

Hello :slight_smile: I am stuck with the post script stuff. I am making an Epic bipedrig and I want to run a post scrtip to hide all the controller shapes I do not need to be visible when I build the rig from the guide.
For example,I do not need to have visible spine_C0_tan0_ctlShape and spine_C0_tan1_ctlShape.

The script I use is :

import mgear.shifter as shifter

List of objects to hide the controller shapes from

objects = [obj1, obj2 …] # Replace with your own objects

Loop through each object in the list

for obj in objects:
# Hide the controller shape

I do not have an error (with other scripts I did), but it does not hide the controllers shape I enumerated neither.
So I am not sure what I am doing wrong, hope someone to be able to help me out with this one.

Thank you!

Hi there,

First of all, on the forum, you can surround code with triple backticks so it formats properly:

import mgear.shifter as shifter

Second, can you please show real code you’re trying to run? Examples like objects = [obj1, obj2 …] doesn’t show if you have typos or problems with your code.

Alternatively, if you never need those controls, one thing I do is just delete the shape, and extract the empty transform with mGear → Shifter → Extract Controls. Then when you build next, it will use the empty transform for the controller. The control will still be there, but you’ll never see it. If you ever want it back to default, just delete the empty transform from the controllers_org group.


many thanks for your quick response and information. I would like to find a working solution about the code, instead of deleting manually some controller shapes.

This is the last script I used but still gives me errors of the guide name. I double check syntax also, it seems has no errors there.

import mgear.shifter as shifter
import mgear.core.pyqt as gqt
from mgear.core import attribute
def hide_ctrl_shapes(node, shapes_to_hide):
    ctrl_shapes = [shape for shape in node.getShapes() if shape.nodeType() == "nurbsCurve"]
    for shape in ctrl_shapes:
        if shape.name() in shapes_to_hide:

guide = shifter.getGuideByName("guide")  # example guide name

ctrl_list = guide.getControllers(["arm_L0_mid_ctl", "arm_R0_mid_ctl", "spine_C0_tan1_ctl", "spine_C0_tan0_ctl", "leg_L0_root_ctl", "leg_R0_root_ctl", "foot_L0_heel_ctl", "foot_R0_heel_ctl", "foot_L0_bk1_ctl", "foot_R0_bk1_ctl", "foot_L0_bk0_ctl", "foot_R0_bk0_ctl]) 

shapes_to_hide = ["square", "circle"]  # example list of shape names to hide
for ctl in ctrl_list:
    attr = attribute.getDriverAttr(ctl, "controlVis")
    gqt.addPostScript(attr, lambda: hide_ctrl_shapes(ctl, shapes_to_hide))

I also tried a simple code but still gives me errors. I tried with and without “Shapes”

objects = [arm_R0_mid_ctlShape, leg_L0_mid_ctlShape, leg_R0_mid_ctlShape, leg_L0_root_ctlShape, leg_R0_root_ctlShape, spine_C0_tan0_ctlShape, spine_C0_tan1_ctlShape, ik_foot_L0_ctlShape, ik_foot_R0_ctlShape, arm_L0_ikRot_ctlShape, arm_R0_ikRot_ctlShape, foot_L0_bk0_ctlShape, arm_L0_ikRot_ctl_1crvShape, arm_R0_ikRot_ctlShape]

for obj in objects:

    shifter.hideControllerShape(obj) ```
  1. In your line “ctrl_list”, look at the end of your list. You forgot a quotation mark after foot_R0_bk0_ctl.

... "foot_L0_bk0_ctl", "foot_R0_bk0_ctl])

  1. In your objects list, you are listing:
objects = [arm_R0_mid_ctlShape, leg_L0_mid_ctlShape, ETC...

You need to define those as strings by surrounding them with quotation marks, unless they are already defined as variables. Otherwise you will get an undefined error.

  1. I wonder why you are using gqt.addPostScript to make a lambda function. Do you know why, or were you following a tutorial? This seems complicated for no reason. You don’t need fancy structures like that to run a function. Just run the function.

  2. You are looking for “square” and “circle”. And your code will only set the visibility False if the shape name is “square” or “circle”. Do your controls have that in the name? Also the way you are testing is asking if the shape name is either “square” or “circle”. You probably meant to check if “square” or “circle” is inside your shape’s name. It’s backwards.

  3. I tested on the Shifter biped template. And some of the shapes you are listing have connections for their visibility by default in that template. So if your rig is similar, you’ll have to either test if the attribute is connected, or disconnect it. The script could be as simple as this:

(unless you have a reason to specify which guide you are operating on, then maybe you still need to use shifter.getGuideByName.)

import pymel.core as pm

ctrl_list = pm.ls(["arm_L0_mid_ctl", "arm_R0_mid_ctl", "spine_C0_tan1_ctl", "spine_C0_tan0_ctl", "leg_L0_root_ctl", "leg_R0_root_ctl", "foot_L0_heel_ctl", "foot_R0_heel_ctl", "foot_L0_bk1_ctl", "foot_R0_bk1_ctl", "foot_L0_bk0_ctl", "foot_R0_bk0_ctl"])

for ctrl in ctrl_list:
    for shape in ctrl.getShapes():
        if shape.nodeType() == "nurbsCurve":

You only have to extract it once, then it’s done forever. But you don’t have to do it manually. There are commands to delete shapes, and extract shapes too. If you do it by extracting, you can save the controllers_org group for other characters, and have matching icons for all your characters automatically.

Or instead of setting visibility off, you could also just delete the shape in your script. It would skip the need to check for connections to visibility. And prevent any animators from accidentally making them visible again.

Just ideas! Do what works for you!


Hey Chris!

If I am deleting a control shape, I also remove it from “rig_controls_grp” so it can not be selected with sets. I think I started doing this because for example, our animators wanted Elbow Mid control to have an option like pin or follow, so I had to do some constraining to that control therefore I no longer want them to accidentally key that control and have blended keys.

I think I could’ve done that constraining in a non-destructive way but my solution was to hide its shape and remove it from “rig_controls_grp”. Is there a better way?


Hi Chris,

Thank you so much for the help. Your script works as a charm.

I am pretty new in python and I used some here and there stuff I had in my co workers folder, however learning more scripting is my next goal :slight_smile: but your explanations were amazing and very helpful

1 Like

I don’t know if there is a “better” way. Your way sounds like it would work just fine! And I do the same thing. I sometime rename unwanted controls “_null”, remove them from the sets, and delete the shapes. I simplify the foot roll and the spine quite a lot in my rigs.

And then if you are using a pre-made Picker template, remove it from the Picker too.

“non-destructive”. I think that only matters if you had existing animation on a rig that you’d risk breaking. Otherwise, there is no reason to stick to the components as they are. Feel totally free to customize them as you need.

1 Like