This is a quick overview of a production-friendly way to organize your blendshapes on a Maya rig, that makes it super easy to reuse complex rigs and save a ton of time and effort.
Even if you don't know how to script yet.
I'll show you why you should never connect controllers directly to the blendshapes of your character or prop. And not just Maya. These ideas should easily map to any other DCC app where you are connecting your geo to complex rigs.
I'll often see rigs where people have directly connected control attributes, driven keys, expressions or utility nodes to the blendshapes. An even worse thing to do is to connect controllers to blendshapes, and then connect those blendshapes out to other controls or to another blendshape! This is really messy.
Why is that bad?
Because then your rig depends on your geometry. If you replace the geo, you've lost all your hard work! If you ever have to disconnect the connections, you have to somehow store or remember how they were connected. If the modelling department sends you a completely new set of blendshapes for an updated character, you have to reconnect everything.
This isn't a made up example. I was recently cleaning and improving some old rigs from someone else. I was replacing the geometry, and had stored all the inputs and all the blendshapes. But without investigating well enough, I didn't notice a bunch of output connections coming out the blendshapes and driving other stuff. I unknowingly lost a bunch of connections and a few hours of work!
What I do instead
So instead, this is basically the way I set up all of my blendshapes. I use a "hook" node that has a bunch of float attributes with identical names to all of my blendshapes. I connect those hooks to my rig controllers. Like a nice clean API layer between controllers and geometry.
Then the hooks connect directly to the blendshapes.
A big reason I often want to temporarily disconnect blendshapes is to "bake my wraps". Sometimes it is useful to wrapDeform eyebrows onto a face, for example. But the final production rig does not need to keep the slow, heavy wraps. Instead I bake them out to their own blendshapes. I run a script to turn on every blendshape one at a time, and duplicate the wrapped geometry. Then I store those duplicates as blendshapes, copy skinning, and delete the wrap.
Then I simply reconnect the blendshapes. A simple Python script can just check for matching names. If it finds one, it connects it. But even if you don't know any scripting, this hooks setup makes it easier to connect them.
import pymel.core as pm
#SNIPPET: CONNECT BLENDSHAPES BY HOOKS
hooks = pm.PyNode('blendshape_hooks')
#allBlends = [pm.PyNode('right_brow_blendshapes')]
# Check every blendshape for matching hook names.
allBlends = pm.ls(type='blendShape')
for newBlend in allBlends:
for eachShape in newBlend.w:
shapeName = eachShape.getAlias()
if hooks.hasAttr(shapeName):
hookAttr = hooks.attr(shapeName)
try:
hookAttr.connect(eachShape, force=True)
except:
continue
Another benefit? I can just export the controls and the hooks and re-use the entire rig from character to character easily. All the complex connections from the rig are maintained, even if I delete the geometry and blendshapes and make a whole new character.
And as I wrote previously, if I want to make corrective shapes, I manually make a combinationShape node, and store those connections on my hooks as well. If you use Maya's built-in way of adding combination shapes in the Shape Editor, your connections rely on your geometry, making it harder to replace or reuse later.
Using "hooks" makes it super easy to reuse templates of complex setups. This saves a ton of time and mental space!