MRS: Give em a hand!

Current Sprint: MK Base

  • HAND
    • First blockFrame rigBlock
  • mrsAnimate
    • Time Context
    • Bugs/workflow
  • Workflow
    • Continuing to iterate


Important Changes

If you’re currently using MRS you’ll wanna look at these until I get a chance to update the docs.

  • NEW Block – HAND
  • Context Setting
    • Context setting now in a frame to hide them to clean up UI
    • Force is a new option to say whether a block should redo a state when called. Most common use is when you have blocks a varying states in a heirarchy and just want everything at the same level without redoing states
    • When in self state, force is always assumed. This just feels better
  • Up to skeleton state, parent block state no longer matters.
  • Foot tracks to the cast plane now (ground usually)
  • Mirroring blocks should now work more consistently with loftList setup
  • Utilities Tab | Mirrored most of the td section of the cgmToolbox here to make them easy to get to.
  • Core attributes
    • loftReverseNormal | Because maya is consistently inconsistent with lofting. Between sessions. It’s nutty.
  • New Menus/Options
    • Contextual>Prerig>Handles Lock/Unlock | Lock and unlock prerig handles when you need them to not move when you’re doing shaping stuff
    • Contextual> Prerig> Arrange Various options | Snap the prerig handles along multiple arrange options
    • Contextual>Vis | Easy way to toggle rotatePlanes and visMeasure on and off
    • Contextual>Queries>Visualize Hierarchy | fixed
    • Contextual>Queries>Reorder UD | [IN TESTING] During some build options the channel box user attrs get out of a sensible order. This is the first attempt at fixing that
    • Contextual>Rig>Prechecks | Connected precheck ability to check blocks for settings problems before building
    • Contextual>Template>Snap to Rp  | Snap template handles to rp like we had prerig handles
    • Contextual>BlockFrame>Align To | Aligns a block to it’s block frame if one exists
    • Contextual>BlockFrame>Shape To | Shapes a block to it’s block frame if one exists

From last update

Fix the items from the last update before doing the final workshop package and a few new ones.

Stuff to fix:

  • HEAD
    • prerig layout stuff not working
    • When we have same joint count as handle count, use the prerig handle positions
  •  Template
    • Look at segment aiming. Saw a few flips
    • loftStart/End not setting up properly for mirroring block
      • Reworked the mirror_create call in where settings are put in
    • Look at foot ik tracking
      • Trying a point constraint group on the bank setup that doesn’t orient with the end handle
    • Shaper aiming
      • Add twist along segment
    • Pivot helper pivot handle placement. The bounding box method is not accurate
      • Snaps to closest point on curve shape now
  • Prerig
    • End handle on quad leg aiming weird by default. Fixed
    • Add a way to lock the position/rotation of the prerig handles/template handles when you’re moving other stuff.
  • Gen
    • Add the orient interp fix from segment to other modules
    • Change states
      • Only skeleton/rig state should require parent blocks to be at the same state
    • Visualize Hierarchy not working Fixed
  •  UI
    • Add an attr sort to the rigBlock to make finding stuff easier in the channel box
      • Added to ATTR and ui.
      • Contextual>Queries>Reorder UD
    • Template
      • Add mirror world space call
    • Add a forceNew toggle on the push states to make everything not have to rebuild unless you want
    • hook up vis for that and measure
      • New menu Contextual>Vis


We need a new block. A helper block to more easily set up hands. So, let’s do it.


We want a way to more easily layout and setup a whole hand. I’ve been thinking about this a while but it’s best to do some doodling to work through things.

Googled some hands and start looking for simplifying the curves of definition for our block.

We’re going to be using some of the tech from our facial blocks to set up our points of definition. Here’s the rough plan:


Gonna start working through things by grabbing the define call from muzzle and work from there. First we need to to figure out what info we need from our user.

  • numFinger
  • numThumb
  • definePose | Going to use this to specify scale space profile for he setup. To start wide and relaxed will be our options.

First pass

Got a first pass on placements. Look at things and see what we think.

  • Need to connect visibility of thumb parts to attributes hasThumbInner/Outer maybe
  • The sub controls need different colors and to aim

New Concept

So the way we’re doing this is as a frame for other blocks. So we need something to call this. First idea is ‘megaBlock’. This block type:

  • Doesn’t go beyond define state (at least for now)
  • It needs sub calls:
    • Build other blocks

Initial Attach

Got the initial finger creation and attachment working. Next is to:

  • Properly size blocks
  • Set block names
  • Split the attach out to a new call
  • Make attach work with template state/prerig
  • Then thumb


Working directly with the blocks felt a bit slow. So instead I started playing with visualizing the hand here. Then I’ll add work on pushing that back to the finger blocks.

Overall this feels much faster and intuitive than directly going to blocks.

Further iteration with thumb

Initially we’re just going to do an outer/inner thumb. This is just easier and if you want another thumb you can just dup those blocks after the setup builds the sub blocks.

Need a way to shape the rigBlocks from the Hand block

First we need to map the data we want to use. Even though we’re only having one thumb for now, we’re going to wire it for the future.

  • Handle drivers
    • finger[i]Drivers | msgList
    • thumbInner/Outer[i]Drivers | msgList
  • Curve
    • finger[i]Curves | msgList
    • thumbInner/OuterCurves | msgList
  • Surface
    • finger[i]LoftSurfaces | msgList
    • thumbInner/OuterlLoftSurfaces| msgList

Now that that’s stored. When we build our individual finger blocks we want to tag some data so we can get that track data so we can then update those blocks at will. Either all of them or just particular ones.

  • blockHandler
  • Should be able to index from that
  • Then get data

Scaling Loft Curves Properly

So we want to be able to use transform scale to size our loftCurves. It would be easier to just cast cvs at the target surface but this will be more consistent. Bounding box method doesn’t work when things start to rotate so we’ll go back to an older method and bring a call back from a long time ago to get the axis box size.

  • Initially tried axis box but it doesn’t work well for flat curves
  • Went to the oldest setup and brought back up to current libraries as cgm.core.lib.distance_utils.scale_to_axisSize and get_axisSize

Working pretty well. On to the rest of the fingers tomorrow.

With some more iteration got the fingers all setup and the ui elements added to work with things.

Toon test.

Review with Locke

  • Connect vis of thumb groups to numThumb
  • Creation loft curve size – try  a factor of the length from start to end
  • Flip the limb end aim to be z- so that we can snap hands to them easier
  • Add a designator for FRAME on ui
  • Play with aim vector for hand finger curves


Circling back to this…


  • Update mDrake
  • Update Horse


Need to revisit all the docs to cover the new define state stuff as well as hit loftList

  • HAND – First pass
  • Update
    • LIMB
    • HEAD
    • HANDLE
  • Tools docs
    • mrsAnimate
    • mrsBuilder

Unit Tests

Had an issue where I rolled up update into a branch and broke some stuff for a user. I need to add better MRS unit testing and so that’s going on the to do list.

Helping Benn

Benn is using MRS for a pipeline and writing a call to batch process templated rigs and needed a hand with finding calls.

Needs to get master block

from Red9.core import Red9_Meta as r9Meta
r9Meta.getMetaNodes(mTypes = 'cgmRigBlock',nTypes=['transform','network'],mAttrs='blockType=master')

Rig state call command

RIGBLOCKS.contextual_rigBlock_method_call(mBlock, 'below', 'atUtils', 'changeState','rig',forceNew=False)

Check if rig Built

ml_context = BLOCKGEN.get_rigBlock_heirarchy_context(mBlock,'below',True,False)
ml_fails = []
for mSubBlock in ml_context:
    _state =  mSubBlock.getState(False)
    if _state != 4:
if ml_fails:
    raise ValueError,"We have some failures..."

Rig Prep

  • Mirror Verify
  • Gather Space Drivers
  • Qss
  • proxyMesh
  • isHistorically interesting
  • Connect rig
mPuppet = mBlock.moduleTarget#...when mBlock is your masterBlock


Block deletion

ml_blocks = r9Meta.getMetaNodes(mTypes = 'cgmRigBlock',nTypes=['transform','network'])
for mBlock in ml_blocks:


  • MRS Animate – not working as expected
    • Wasn’t up to date
  • Clav shapes different size
    • Cast direction
  • Settings shape size mismatch on Benn’s file
  • cgmUpdateTool
    #   File "C:/Users/BennGarnish/Documents/maya/scripts\cgm\core\tools\", line 235, in uiFunc_updateMyStuff
    #     if _lastUpdate[0] != 'None':
    # TypeError: 'NoneType' object has no attribute 'getitem' #

    Added an attempt at a fix and amended the Troubleshooting doc


Josh Burton

[MRS Project Lead | CG Monks] Josh is an animator turned TD who hails from Oklahoma, pre-undergrad in the Marine Corps, animation basics at Savannah College of Art and Design, cut his teeth in gaming and commercials before co-founding CG Monks and more recently the CG Monastery. The Morpheus Rigging System is a culmination of years of R&D and he is now thrilled to see what users can create, collaborate and expand on with this open source MRS platform.