March 4th, 2014

A set of tools that help you create complex joint based facial rigs.  Currently requires (and is included for free with) abAutoRig Premium.

  • Quickly build and mirror face rig Weight Joints and controls .
  • Easily create complex multi-driver SDKs.
  • multi-driver SDKs don't need to be zeroed to set new keys (allowing you to better tweak how SDKs interact).
  • Mirror SDKs.
  • Built to integrate with abAutoRig rigs (including support for Simple Skeletons).
  • More, more, more!
  • some other stuff.

A Brief Overview

This script is intended to create joint based face rigs.  It offers no support for blendshapes, wire deformers or any other methods that might be used in facial rigging.

The work flow goes like so:

  • Starting with half of the face (usually X+), create and position locators where you want your joints to go.  Locators can be created at currently selected vertices, along nurbs curves, or at the position of another transform.

Note that the name of the locator will be used in the naming of the joint unless you've disabled "Use Locator Name for New Joint" in the "Joints" tab of the UI.

  • Once you're happy with the placement of your locators, select those you wish to convert, and click the "Convert Locs To Joints" button.  A joint will be created at each selected locator, along with two control curves: a driven control and a fine control.  The driven controls exist only to be driven by your facial controls, while the fine controls are used to fine tune expressions.

  • If you're happy with their positions you can choose to mirror them now.  Or, if you're like me, you can wait until the end to mirror everything.

  • Bind the joints to your mesh and adjust their weights appropriately (fun!).  You could also choose to do just a preliminary weighting at this point, returning later to refine it once your entire rig is set up.  Move, add and delete joints as you see fit.

  • Create your character's facial controls.  The workflow is just like the joint creation process; create and position locators which get converted into controls.

  • Mirror your controls (Or again, get one side of the face working and wait until the end to mirror everything).

  • Create your SDKs (Set Driven Keys).  You'll connect your controls to the position, rotation and/or scale of your joints with SDKs which allowing simple control movements to adjust multiple joint positions.  In this way you'll be able to move multiple joints in complex ways with a simplified control system (e.g. a control at the side of the lips that pulls the corner of the mouth up, down, in, and out across the face).

  • If you're me, here is where you mirror all of your joints and controls.

  • Mirror your SDKs.

  • Clean up any loose ends (tweak and re-mirror SDKs, set limits on your controls, connect the visibility of the driven and fine control curves to attributes on your rig, beautify control curves, etc).

  • If you're importing your character into a game engine (or otherwise just want to use the Simple Skeleton feature in abAutoRig) this is where you'll create Simple Skeleton joints for your face rig.  You can easily transfer the skin weights from your face joints to the Simple Skeleton joints using the Simple Skeleton UI in abAutoRig.

A Few Notes

The name field is important.  Most features won't work without a valid character name.  If something isn't doing what you think it should, check to make sure that you've set the name correctly (especially if you're making changes to an existing face rig).

Avoid using undo with abFaceRigTools.  Maya doesn't like undoing all the arcane mel I've woven with this script, and will occasionally choke on it.  Everything is deletable via functions in the UI anyway, so it shouldn't be a problem (take note of Utilities Tab > Delete Selected Joints And Controls).

This one's important!  Don't rename any of the transforms created by the script.  Related objects (like a Weight Joint and its control curves) have  special hidden attributes that let them know about each other.  If you rename any of them, they'll forget and things won't work as well as they should.  If you do want to rename them, there's a tool in the Utilities tab meant for that very purpose (Utilities Tab > Rename Selected Joint/Control).

One of the cool features allowed by these hidden attributes is that you don't have be super precise when selecting specific objects for an operation.  For example, when creating SDKs the script wants a selection of driven controls -- no joints, no fine controls, just driven controls.  However, because each of these objects knows the others in their immediate group, you can select a joint, its driven or fine control, or all of them and the script will still be able to get the driven control curve that it needs.

A Short Glossary

Here are a couple of concepts/object types specific to this script that I should probably explain:

Rotation Joint: A optional joint around which your Weight Joint can be rotated (and to which it will be parented).  Rotation Joints are useful when rigging eyelids, or any situation where you want a Weight Joint to rotate around an external pivot (usually the center of the eyeball).

To create a Rotation Joint, enable the "Parent To Rotation Joint" check box and select a "Rotation Joint Target" (in the lower half of the "Joints" tab UI) before creating your Weight Joint.

Weight Cubes: Sometimes you may need your face joints and/or controls to move with one or more underlying rig joints, while still being driven by various SDKs.  You can do this using a Weight Cube, which is just a polygon cube with a Weight Joint attached via a follicle.  The cube can then be skinned to your underlying skeleton.

Weight Cubes are useful many situations, including setting up the lower face joints to move with the jaw.

Note: Avoid skinning Weight Cubes to other Weight Joint in the face rig, or risk the wrath of a cycle issue.

One more note: Make sure your Weight Cubes have consistent weighting across all eight of their vertices, otherwise the resulting distortions can cause messy Weight Joint rotations.  There's a tool in the "Utilities" tab built for just this task (Utilities Tab > Unify Vertex Wweights For Selected Weight Cubes).  You should use it.

How To Use This Thing

Note that this script requires djRivet.mel to run.

Once you've downloaded and installed djRivet, copy abFaceRigTools.mel into your scripts directory (or somewhere in your scriptPath), restart Maya (or enter "hash" into the mel command line) and run the following bit of mel:

source abFaceRigTools.mel;abFaceRigTools();

The UI should appear, with the "Vars" tab active.

The Vars Tab

Enter your character's name in the "Character Name" field, or right click to select an existing abAutoRig character name in the current scene.

Since this is the first time running the script, there is no existing face rig, so you'll have to create new "Rig" and "Joint Parent" groups.  Do this by clicking the "Make Rig Group" and "Make Jnt Group" buttons.  These groups are where all of the newly created face rig related nodes and Weight Joints will be placed.

Below the rig and joint group buttons are color sliders that you can use to adjust the default colors of newly created controls.

The Joints Tab

Joints (and controls) are created from locators, and locators can be created in several different ways.

First, though, it's important to know that locator naming matters.  Or it doesn't.  It all depends whether you have "Use Locator Name For New Joint" checked.  The benefit to using the joint locator name for the new joint is that you can create your locators with all of their various base names, and, once positioned correctly, you can simply select them all and click "Convert Locs To Joints".  Otherwise, unless you want all of your joints to share the same base name, you will have to create them in groups, being sure to change the base name between.

Either way, the string entered into the "Joint Loc Base Name" field is important.  When you create a locator or a joint (based on the setting of "Use Locator Name For New Joint"), that string, along with your character's name, a side prefix ("lf_", "rt_" or nothing based on the X position of the locator), and an optional alpha suffix, will determine the object's name.

Note that the alpha suffix is required when you have multiple joints with the same base name (like the mouth or the brow), but you might not want it if there's only a single joint with a particular base name (like the nose).  It's up to you.

Back to joint locs.  The easiest way to create a joint locator is to select one or more vertices on your character's face mesh, and click the "Create Joint Locators" button.  Locators will be created at all of the selected vertex positions.  They will also be created at the location of any selected transforms, or the origin, if nothing is selected.

Note that it's easy to mess up the side prefix ("lf_", "rt_", or "") in your locator name by creating locators at the X origin and then moving them left or right along the X axis.  This is only important if you're deriving the joint name from the locator name.  If you are, just make sure that the side prefix is correct before converting your locators to joints.

If you want to create joint locators along a curve, you just need to supply the curve.  Once you've got one, select it and click "Create Locs Along Selected Curve" to create however many "Curve Locs Num" locators your heart desires (up to 10, I think -- if your heart wants more, tell it it's just being greedy).

The next few controls allow you to set the size and look of the fine and driven control curves that are created along with your Weight Joints.

Check the "Parent To Rotation Joint" check box if you wish to create a Rotation Joint with your Weight Joint.  You'll also need to specify a transform in the "Rotation Joint Target" field that the script can use to derive the position and orientation of the new Rotation Joint.

The final decision to make before you create your Weight Joint is how you want it parented.  If your Weight Joint only needs to move with a single underlying rig joint, or even with another Weight Joint, specify that joint as the "Rig Joint To Follow" (RJTF).  If, on the other hand, you want to it to move with multiple underlying rig joints, create a Weight Cube by enabling the "Create Weight Cube" check box.

Note that you can set another face rig Weight Joint as an RJTF.  In this way you can emulate an FK rig (useful when rigging the tongue, for example).  But you can not do this with Weight Cubes.  Weight Cubes must be bound to underlying rig joints.  Do not bind them to other face rig Weight Joints.

If you change your mind and decide that you want to use a Weight Cube instead of an RJTF for a given joint (or vice versa), check the "Utilities" tab for the "Set New 'Rig Joint To Follow' For Selected" and the "Create Weight Cubes For Selected" buttons.

You're now ready to create your joints.  If "Use Locator Name For New Joint" is disabled, make sure that the string in the "Joint Loc Base Name" field is what to use as a basename for your newly created Weight Joints.  Once you're good, select all of the locators you want converted, and click the "Convert Locs To Joints" button.

The Controls Tab

Controls, in the context of this script, refer to control curve transforms that the animator can translate in X, Y, and/or Z to drive one or more Weight Joint, Rotation Joint, or even other controls' SDKs (via their translation, rotation, or scale channels).  You can set them up however you wish.  You can have controls at the corners of the mouth that stretch or compress it when moved in X, blend between smile and frown when moved in Y, and puff it out when moved in Z.  You can have controls that move the entire mouth (including those mouth corner controls).  Brow controls, cheek controls, nose controls, eyelid controls, whatever.  Set them up in whatever way makes the most sense to you, and keeps you from having to animate individual Weight Joint fine control curves as much as possible.

Here I should note that you don't actually need to create any controls for your face rig.  You can mirror your Weight Joints, bind them to your mesh and be done.  Hooray!  But then you'll be left having to animate three translation (if not rotation and scale) channels on forty (or more) different Weight Joints.

Which sucks.  And is not something that I ever want to do.

So what I'm saying here is: if you love your animator, you'll use controls.

Ok, now that you've decided to use controls (great choice, btw), here's a quick tour through the "Controls" tab.  It's very similar to the "Joints" tab, so I'll skip that which I've already covered above.

A quick note regarding the Weight Cube and RJTF ("Rig Joint To Follow," remember) options.  Just like Weight Joints, controls can be parented to an RJTF or they can be attached to a Weight Cube.  These two parenting methods function the same way they do for joints.  They allow you to create facial controls directly on the face, which can make for a very intuitive rig.  Don't worry, though, if you prefer off face controls.  You can do that, too.

The two most significant differences between this tab and the "Joints" tab are:  

The Control Curve Alignment Axis" option menu:  This lets you choose how the control curve is aligned to the locator from which it's created.  The control curve will face forward down the specified axis of the locator(s).

The X, Y, Z grid of buttons below the "Convert Selected Loc To Control" button:  These buttons allow you to quickly lock/unlock and set/unset upper and lower limits on the translation channels of any selected controls.

To set a limit:

  • Select a control.

  • Adjust the X, Y, or Z attribute to the value that you wish to use as the limit.

  • Click that attribute's button in the "Set Upper Limits" or "Set Lower Limits" row.

  • Click the same button again to remove the limit.

Note that you can automatically set limits using the "Auto Set Limits On Selected Controls" button in the "Utilities" tab.  When clicked with one or more controls selected, this button will determine the upper and lower range of any driven SDKs and will use those values to set the upper and lower limits for each control attribute.

The SDK Tab

Here is where you create the SDKs that connect your controls to your Weight Joints, Rotation Joints, and even other controls.

To begin, select the control that you wish to drive your Weight Joints, and click the "Load Driver" button.  Select the control attribute you wish to use as the specific driver from the "Driver Attributes" option menu.  Enable "Show Only Connected Driver Attributes" to display only those attributes that are currently driving one or more SDKs.

With the driver attribute selected, you can now select the objects you wish to drive.  Select one or more Weight Joints, Rotation Joints, and/or controls (obviously not the current driver) and click the "Add Selected Joints And Controls To Driven" button.  The names of the objects you selected should appear in the text list below.

Actually, the names may not be those of the objects that you had selected.  In the case of Weight Joints, the script is looking for driven controls which, as the name may indicate, exist to be driven.  You can select Weight Joints (or the fine controls of Weight Joints) and the script will know to load the correct driven controls.  The script does the same for controls and Rotation Joints.  And again, this is why you can't just change the name of the your face rig nodes without using the tools provided in the "Utilities" tab (Utilities > Rename Selected Joint/Control).

Note that an initial SDK is set when you click the "Add Selected Joints And Controls To Driven" button, so you generally want to make sure that your driver attribute is set to zero.

SDKs will be set for the translate, rotate, and scale attribute channels based on the status of the "Translate," "Rotate," and "Scale" "Key" check boxes (above the "Add Selected joints And Controls To Driven" button).

Now that you have some objects in the driven list you can:

  • Adjust your driver attribute.  Use the "Driver Val" slider and/or buttons below to do this quickly.

  • Move, rotate, and scale one or more of your driven objects in whatever way makes sense relative to the control translation.

  • Click the "Set Driven Key" button to create a new SDK for all of the driven objects in the list.  Note that your current scene selection is irrelevant when you set a key using this button.

One of this script's most useful features is the way it sets SDKs on objects with attributes driven by multiple drivers.  Usually, when setting SDKs on such objects, you have to make sure that all other incoming driver attributes are set to zero when creating (or setting) an SDK.  If you don't, your drivers won't blend as expected.

This script, however, stores all other incoming driver values and sets them to zero before setting an SDK.  It then resets the attribute drivers to their original values.  The upshot of all this is that you can set SDKs on your driven objects while their positions are being affected by other (parallel) drivers.  The influence of all of other incoming drivers will be stripped out of your object's translation, rotation and scale before the SDK is set.  As a result, setting up your controls and getting your SDKs to blend well becomes a lot easier.

Below the "Set Driven Key" button are five buttons that allow you to navigate around your existing SDK keys:

  • << and >>: Sets the current driver attribute to its min and max values, respectively.

  • < and >: Sets the current driver attribute to previous and next values, respectively.

  • |: Sets the current driver attribute to zero.

The "Driver Val" slider and incremental adjustment buttons below are useful for quickly changing the current driver's value without having to jump into the scene to select and move the actual driver transform.  The range of the "Driver Val" slider is updated automatically whenever you click the "Set Driven Key" button.  If you find the  slider limits don't match the range of the current driver SDK values, click the "R" button to refresh them.

At the bottom of the tab are five buttons with "----" for labels.  These are quick save slots you can use when positioning your driven objects.  Select one or more objects and click an empty slot (labeled "----").  The label will change to the save slot number (1-5).  You can now restore the translation, rotation and scale of those objects by clicking the same button again.  Hold the control key and click a save slot to overwrite an existing save with the current selection (or empty it again if nothing is selected).

When the driven list is populated with at least one or more entries, a context menu becomes available.  RMB clicking it will bring up the following menu items:

  • Select All Driven Objects: Select all of the transforms in the scene driven by the currently selected driver attribute.

  • Select Highlighted Objects: Select the transforms of the currently highlighted entries in the text list.

  • Reveal Scene Selection In List: Highlight the text list entries of any transforms currently selected in the scene.

  • Select SDKs For Selected: Select the SDK curves for the currently selected text list entries, or all list entries if none are selected.  Used when editing SDKs in the Graph Editor.

  • Select T[x|y|z] Curves: Show only the X, Y, or Z translation channels of the currently selected text list entries (or all entries, if none are selected) in the Graph Editor.

  • Select Rx|y|z] Curves: Show only the X, Y, or Z rotation channels of the currently selected text list entries (or all entries, if none are selected) in the Graph Editor.

  • Apply Control Offset To Selected: Offsets the position of the selected text list entries from their start position by the same amount as the current driver offset.  This is one that I needed this at some point, and now can't remember why.  Rest assured that it will be here when you need it.

  • Delete All Keys At Current Value: Delete any SDK keys for the selected text list entries (driven by the current driver attribute) at the current driver attribute value ("Driver Val").

  • Remove Selected Objects From Driven: Delete all SDKs coming from the current driver to any selected text list entries.  This will remove the selected entries from the text list.

Note that if "Remove Selected Objects From Driven" isn't removing a driven object from the list, you may have to delete it manually.  To do this:

  • Select the object's entry in the list.

  • Click "Select SDKs For Selected" in the context menu.

  • Select and delete all of the curves displayed in the Graph Editor.

The Mirror Tab

Note that your rig and all of its member joints and controls should be at their zero positions before you mirror them.  Joints and controls do not need to be zeroed if you're only mirroring SDKs.

The first thing to decide, when mirroring an object (using one the the first three buttons at the top of this tab), is how you want your result objects to be aligned.  You specify this by selecting one of three options from the "Object Mirroring Method" option menu:

  • Negative Scale: The object(s) will be mirrored as if they were negatively scaled across the YZ plane.

  • Behavior: The object(s) will be mirrored as if using "Behavior" as the "Mirror Function" in a "Mirror Joint" operation.

  • Retain Orientation: The translation of the object(s) will be mirrored, but rotation will not.  Useful for joints that are aligned with the world axes.

The next three buttons allow you to mirror any selected joints, controls and locators across the YZ plane.  The difference between "Mirror Selected Joints And Controls" and "Mirror Selected Joints And Controls (Forced)" is that the former will skip any existing mirrored objects that it finds, while the later will delete those existing mirrored objects and replace them with new ones.

Mirror Weight Cube weights by selecting one or more Weight Cubes and clicking the "Mirror Selected Weight Cube Weights" button.

The "Mirror Control Curve From/To" button can be used to copy a mirror of the control curve shape (the actual wire) from one control to another.  To use it:

  • Select the control curve with the wire that you want to copy.

  • Select the mirror control to which you wish it copied

  • Click the "Mirror Control Curve From/To" button.

The Mirrorining -- Part II: This Is Kind Of A Big Tab

Before you mirror your SDKs, you must mirror the driver and driven objects (controls, Weight Joints and Rotation Joints) that they connect.  If either the mirror driver or mirror driven objects do not exist, then the mirror SDK can't be created.

Note: This is important.  When mirroring SDKs, you want to select driver objects (controls) and not their driven objects.  If you try to mirror SDKs with a bunch of driven objects selected, nothing will happen.

The mirroring process for SDKs typically goes like this:

  • Select one or more controls currently driving some SDKs.

  • Enable the appropriate check boxes under "SDKs To Flip Along Float (Independent) Axis" and "SDKs To Flip Along Value (Dependent) Axis" for your currently selected objects.

  • Click the "Mirror SDKs For Selected Controls: X+ To X-" if you're mirroring SDKs from left to right (as you're facing the front of your character's head mesh), or "X- To X+" to mirror from right to left.

Hooray, you're done!  That was super easy, wasn't it?

Now move your mirror control around and observe the effect of your newly created SDKs.  If you're lucky, everything is moving as you would expect.  You probably weren't lucky, though.

And this is where things can get tricky.  Depending on the orientation and position of your mirrored driven objects (Weight Joints, controls, and Rotation Joints) and the orientation of your mirrored driver controls, you may have to flip your SDKs along their float or value axes to make the mirrored driver/driven relationship consistent with the original driver/driven objects.  You can do this by enabling the check boxes for the attributes that you want flipped along the dependent and independent axes when the SDKs are mirrored.  

Generally, if you're compensating for differences in orientation between the original and mirrored objects, you'll want to flip the SDKs along the value axis, and if you're adjusting for differences in movement of the driver control, you'll flip along the float axis.

A few very important (non-obvious) notes about mirroring SDKs:

  • The SDK float and value flip settings are stored for each control attribute every time you mirror the SDKs for that control.

  • You can limit the driver attributes that get mirrored by selecting (or shift-selecting) attributes in the channelBox.  You will most likely need to do this at some point.  Float and value axis flip settings can (and will) vary for each driver attribute.

  • The "Mirror SDKs Using Saved Flip Values: X+ To X-" and neighboring "X- To X+" buttons will mirror SDKs on any currently selected driver controls using the flip settings from the last mirror operation for each individual driver attribute.  The settings of the check box attribute flip values will be ignored unless there is no saved flip data for a given driver attribute (because it's the first time that you're mirroring a given driver's SDKs).

  • There are several predefined attribute flip schemes that you can access via the "Mirror SDKs For Selected Controls: X+ To X-" button context menu (RMB to access).  The last item in this context menu, "Load Saved Settings For Selected ChannelBox Driver Attribute", will load the the attribute flip settings from the last SDK mirror operation of the selected control attribute into the UI.  Note that you must first select a single control (driving one or more SDKs) and highlight one of its attributes in the channelBox.

When you mirror a control, the name of the new control gains an "lf_" or "rt_" prefix to differentiate it from the original control.  The keyable attributes on that control, though, retain their names.  Sometimes you may want to mirror an SDK from a driver attribute with one name to an attribute with a different name (like from "lfBlink" to "rtBlink").  You can use the "Show Attribute To Attribute Mirror UI" to bring up a UI that will let you do this quickly.  To use it:

  • Load the source and destination objects by selecting them and clicking the "Select Source Object" and "Select Destination Object" buttons.

  • Select the source and destination driver attributes in the lists.

  • Click the "Mirror SDKs From Source To Destination Drivers" button.

Note that you can mirror between attributes on two separate controls, or between attributes on a single control.  Set your attribute flip values in the "Mirror" tab UI, or enable the "Use Saved Float And Value Flip Axes Settings" check box to mirror the SDKs with the last used settings.

The buttons below the "Show Attribute To Attribute Mirror UI" button all operate on curve selections in the Graph Editor:

  • Mirror SDKs Along Value Axis: X+ To X-: Mirror any SDK curves currently selected in the Graph Editor from right to left across the vertical and horizontal axes using each float axis zero SDK key as its own origin. "X- To X+" will do the same from left of the float origin to right.

  • Mirror SDKs Along Float Axis: X+ To X-: Mirror any SDK curves currently selected in the Graph Editor from right to left across the vertical axis using the value axis as the origin. "X- To X+" will do the same from left of the float origin to right.

  • Flip Selected SDKs Along Value Axis: Flip any SDK curves currently selected in the Graph Editor vertically across the value (horizontal) axis.

  • Flip Selected SDKs Along Float Axis: Flip any SDK curves currently selected in the Graph Editor horizontally across the float (vertical) axis.

Among other things, these buttons are very useful when working with weight joints that lie on the origin.

The Utilities Tab

Here is where you'll find a bunch of utilities that are useful in the course of creating a face rig.  A lot of these should be pretty self explanatory, but I'll go through them all anyway.  Also, be sure to read the annotations that appear in the help line when you hover over various UI items.  They're helpful.

Here we go:

  • Select Weight Joints, Select Driven Controls, etc:  Used to select different types of faceRig objects.  If the selection is empty, clicking one of these buttons will select all of the objects of that type in the scene.  If the selection is not empty, clicking one of the buttons will select any relatives (to the selected objects) of the specified type.

  • Filter Selected: Filter the current selection down to transforms on the left or right of the YZ plane.

  • Delete Selected Joints And Controls: Delete Weight Joints, controls, and all of their associated transforms (and removes them from any attached skinClusters).

  • Set New 'Rig Joint To Follow' For Selected: Set the "Rig Joint To Follow" for the selected Weight Joints and controls to the last selected object.

  • Move Weight Joint/Control To Selected Locator: Move a Weight Joint (and all of its relatives) to a new position.  To use it, select a locator followed by the Weight Joint (or one of its control curves) you wish to move.  Click this button to move the Weight Joint (bound to a mesh or not) to the position of the locator.

  • Copy Aim Constraint To Selected Weight Joints: A quick way to copy an aim constraint from the eyes of an abAutoRig character to a Weight Joint, to which you could then parent the eye (allowing for more versatile rigs).  Select an object with an aim constraint and one or more weightJoints to which you wish it copied.  This is sort of a vestigial function.  The new abAutoRig head setup should obviate the need for it.

  • Create Weight Cubes For Selected: Create weightCubes for any selected joints and controls, and removes any existing "Rig Joint To Follow" constraints.

  • Delete Weight Cubes For Selected: Delete weightCubes for any selected joints and controls.

  • Unify Vertex Weights For Selected Weight Cubes: Set the weights for each influence on all of the selected Weight Cube(s) vertices to their (per cube) average value.  It's important that the weights of your influences are the same for every vertex on each individual Weight Cube.  This will make that happen.

  • Auto Set Limits On Selected Controls: Set translation limits on any selected controls based on the min and max float values of any attached SDKs.

  • Remove Limits On Selected Controls: Remove all translation limits on selected controls.

  • Show Change Driver Attribute UI: Similar to the "Attribute To Attribute Mirror UI" in the "Mirror" tab, but instead of mirroring SDKs from a source to a destination, this allows you to change an SDK driver from one attribute to another.

  • Copy SDKs From/To Driven Control: Select the driven control with the SDKs that you want copied, followed by the control to which you want them pasted, and click the button.

  • Create Simple Skeleton Face Joints: This button opens a UI that allows you to quickly create a Simple Skeleton* hierarchy for any selected face rig Weight Joints or control curves.  The new joints are constrained to the Weight Joints and parented to a joint on your Simple Skeleton.  You can use the abAutoRig Simple Skeleton UI to bind, unbind and transfer weights to and from the Simple Skeleton face joints.

  • Connect Source Attribute To Selected: A quick way to connect one attribute to many (e.g. connecting the visibility of the driven and fine controls to individual visibility attributes on your rootCtrl).  First, specify your source attribute by selecting the object, highlighting the attribute in the channelBox and clicking the "Select" button.  Then select one or more destination objects, highlight the attributes in the ChannelBox that you want to connect to the source attribute, and click the "Connect Source Attribute To Selected" button.

  • New Joint/Control BaseName: Enter a new basename for a joint or control ("cheek", "ear", etc) and click the button to rename the selected Weight Joints and controls.  This will also update the names of all related objects and hidden attributes.

  • Rotate Selected Around Pivot Object: Allows you to rotate a Weight Joint around a transform for setting SDKs.  Maybe useful, maybe not.

* A Simple Skeleton is a hierarchical shadow skeleton derived from an existing abAutoRig skeleton using the "Simple Skeleton Creator" tool in abAutoRig Premium (Tools > Simple Skeleton Creator).  The tool was designed to get abAutoRig rigs into a form palatable to various game engines, but it's useful outside of that context, as well.  The Simple Skeleton game engine workflow goes like this:

  • Create a rig using abAutoRig.

  • Open the "Simple Skeleton Creator" and click the "Create Simple Skeleton For Selected Guide Skeleton" button.  Choose a name and create the Simple Skeleton.

  • If your mesh has already been skinned to your original skeleton, you can use the "Transfer Weights" buttons to replace the existing skeleton skin influences with their Simple Skeleton equivalents.  Otherwise, use the "Weight Joint Selector" with your Simple Skeleton selected in the option menu at the top of the UI.

  • You can now constrain the Simple Skeleton to your original skeleton using the "Attach" buttons in the "Simple Skeleton Creator" UI.

  • Animate your character!

  • Select the Simple Skeleton and bake the animation.

  • Detach the Simple Skeleton from the original using the "Detach Selected Simple Skeleton From Guide" and import it into your game engine.

And On That Day

He finished writing this gigantic post.

Feedback and suggestions are always appreciated.

Enjoy the script.

Make cool stuff!


Version 1.1
March 12th, 2014 Added version check for abAutoRig, and improved other checks.
Version 1.12
May 27th, 2014 Removed -pn makeIdentity flag to broaden compatibility with pre 2014 versions.  A few other changes to improve compatibility.
Version 2.0
August 19th, 2015 Added tons of new features and squashed many bugs.  I'll be posting a video soon demonstrating the basic workflow.
Version 2.1
September 18th, 2015
  • Fixed an issue with "Delete Selected Joints And Controls".  Make sure you've set the rig group and joint parent in the first tab if "Delete Selected Joints And Controls" is deleting all of your joints or controls.
  • Fixed issue with orderedSelection during locator creation.
  • Custom driver atts user curves are now zeroed when the rig is reset.
  • Weight Proxy joint translate attributes are now zeroed on build.
Version 2.11
November 3rd, 2015 Added version check for using "menuItem -dividerLabel" flag.

"abFaceRigTools" was posted on March 4th, 2014 under Mel Scripts.  It was created using Maya.  It is tagged with Face,, Joint, Rig, and Rigging,.

This entry was last updated on November 3rd, 2015.

Subscribe to the Comments Feed or Updates Feed for this entry.

Share |


December 19th, 2014 said:

video toturials please!

December 23rd, 2014 said:

It will probably be a few weeks or so, but I'll see if I can't come up with something.

kim tae kyun
February 4th, 2015 said:

video toturials please!

or "sample face" maya file

April 20th, 2015 said:

Hi crumbly! If I understand correctly, I have to have the premium version of abAutorig to have this FacialAutoRig script. Right? The cost of the license for abAutoRig II Premium is valid for a year or forever? Thank you!

April 20th, 2015 said:

Yes, that's correct.  AbFaceRig is included with abAutoRig Premium, and the license is good forever.

April 21st, 2015 said:

Ok, It's perfect for me. Now I just have to convince the boss to proceed with the purchase. There is the possibility to see a video of a character made with this face? Thank you very much!

April 22nd, 2015 said:

Unfortunately, I don't have any videos for you (the characters are not mine to share).

I'll see if I can put something together for you and everyone else who has been requesting that I do (and as I've been saying I would for years).  It probably won't be very pretty, but it should give you a taste of the workflow and what's possible.

April 23rd, 2015 said:

This would be ideal! I'll wait for the video, thanks!

May 14th, 2015 said:

Hi Crumbly! Were you able to create some videos on the facial rig? Thanks!

May 14th, 2015 said:

Hey Michele,

Unfortunately not yet.  Once I started working with the script (abFaceRig), I decided that it needed blendShape support (among other things, like support for the pose space sculpting feature in Maya 2016).  That's all implemented (and it's pretty awesome, IMHO).  Now I just need to implement corrective pose support (I've already added plugin-less pose readers, which will make their way to abAutoRig), and a few utility features (mirror and flip blend targets in the popupMenu) and it should be good to go.

Also, the example character face is built and ready to rig.  Hopefully, it shouldn't be too much longer.

May 22nd, 2015 said:

Ok! I just bought the premium version of abAutorig and inside there faceAutoRig. If you are modifying the script then you can send me the version you are finalizing? Thank You!

May 22nd, 2015 said:

It's not ready yet (it wouldn't be of much use in it's current state), but I'll get you a copy when it is.

I'm hoping to include the abFaceRig update with the next abAutoRig version, with the standard caveat that I don't know when that will be. I hope soon, but there are still several features (one major and a few minor) that I would like to add.

June 12th, 2015 said:

The update is coming along.  I think it's got some really useful features.

It's still not ready, but I've only got one major feature left to add.  Once that's done, a bit of testing and some tweaking and it should be good to go.

June 23rd, 2015 said:

hey crumbly,

I wait for updates and video tutorial .. can you just tell us when we can get that ?

June 24th, 2015 said:

I wish I had a date for you.  I can tell you that I'm working on it, and it's going to be much better than it was before.  But I'm still not sure when it will be finished.  There's a lot of stuff going on in the script, and I just had a significant development that will result in a huge improvement, but it's going to require some deep changes to the way the facial rig is built.

Again, I wish I knew, but I'm just not sure how long it will take.


September 19th, 2015 said:

I've posted an abFaceRigTools demo/tutorial for anyone who might be interested.  I hope you find it useful!

November 3rd, 2015 said:

prefs/scripts/abFaceRigTools.mel line 113: Invalid flag '-dividerLabel' //

I am getting this error, any ideas?

November 3rd, 2015 said:

By the way, it works on 2016 but not on 2014 due to the invalid flag -dividerLabel.....

November 3rd, 2015 said:

Hey Jono,

I've updated the script (v. 2.11) to include a version check that skip the menuItem divider labels on versions of Maya 2014 and below.  Hopefully that works for you.

December 19th, 2015 said:

abFaceRigTools crash in maya 2015..Fatal Error. Attempting to save in C:/Users/me/AppData/Local/Temp/me.20151220.0619.ma...how to solve this problem?

just say it


Related Posts