Painting Weights and Skinning: A Straighforward Approach
Kiel Figgins - 3dFiggins.com


Introduction
Most of the perceived difficulty of painting weights comes from frustration of one or more of the following:

  • The mesh wasn’t created to deform
  • The joint placement was off
  • Trying to weigh multiple, dense, or overlapping meshes
  • Unclear process for painting weights
  • Unaware of additional tools to save time
  • Unrealistic expectations of skinned deformations

  • When some or all of these difficulties comes into play, painting weights can be miserable. However, with a clear mindset and exposure to certain tools and processes, you can overcome each of them fairly straightforward. This document covers: the importance of joint placement, creating a low res mesh to weight and transferring those weights back to the highres, additional time saving tools for weighting and mirroring weights, and other useful tips and information.



    Table of Contents
    Mesh Construction for Deformation
         - Even spans mean even weighting
         - Built for anatomy or simulation
         - Density at key areas for corrective blend shapes and volume preservation
         - Finger and knuckles
    Joints and Joint Placement
         - Joint Naming
         - Joint Placement
         - Overlapping Joints affect weight mirroring
         - Free Floating verse Parented Joints
         - Twist Joints
         - Helper/Additional Joints
    How to Weight Multiple / Dense / Overlapping Meshes
         - ‘Sock Puppet’ Approach
         - Creating a Sock Puppet Mesh
         - Transferring the weights back
    Painting Weights Process
         - Apply the skin
         - Calisthenics (Range of motion) on the rig
         - Viewport Setup
         - Painting Weights - Process
         - Painting Weights - Tips
    Additional Tools and Processes
         - djRivet
         - Weight Hammer
         - Mirror Skin Weights Settings
    Additional Tips
         - Skinning can either maintain volume through penetration or lose it through even distribution
         - Start rough, polish as needed
         - Unnatural animation causes unnatural deformations
         - Know when to use another Approach
    Conclusion


    Mesh Construction for Deformation
    Mesh construction for deformation is an art in itself. There is so much complexity and instruction to be found online about how to achieve proper edge flow that I will not attempt to cover it here. However, I will point out some key factors to look out for.

    Even spans mean even weighting
    This may sound like a no brainer, but having enough spans to spread the weights and deformation over will help with the final result. You can see a great breakdown here:
    http://www.hippydrome.com/Modeling.html

    You’ll notice the high deformation areas of the torso, shoulders and hips have more spans that are evenly spaced. Were areas of less deformation, such as the shins, are spaced further apart.

    Built for anatomy or simulation
    If a character is going to have simulated elements, such as a t-shirt, than having the underlying body mesh with evenly spaced, quads will be less troublesome for the solver. Again, the hippydrome mesh is a solid example:

    Fig. 01 - Even Quad Edge flow
    http://www.hippydrome.com/Modeling.html


    This even span construction also works well for more cartoony characters that may have more stylized deformation or an exaggerated range of motion.

    However, if a character is more muscular, such as a creature, then modeling to fit the muscles will produce more accurate deformation results.

    Here you can see the model’s construction fitting that of the underlying muscles:

    Fig. 02 - Anatomy Edge flow
    http://i26.tinypic.com/4g69mg.jpg


    And a more extreme example:

    Fig. 03 - Muscular Anatomy Edge flow
    http://www.zbrushcentral.com/attachment.php?attachmentid=229475


    Density at key areas for corrective blend shapes and volume preservation
    A common issue when dealing with high bend areas, like the elbow/knee/shoulder/hip, is that no matter how it’s constructed or weighted, a corrective blend shape or additional helpers joints will eventually be needed to create a more pleasing result.

    Using the knee as prime example, you can see the difference in these two legs.

    Fig. 04 - Density in high bend areas


    The leg built for even spans does not have much density to work with to sculpt out a corrective shape for a bent knee (harder edge, 90 degree point and defined knee cap). Whereas the more anatomical leg was created with deformation in mind, leaving enough spans in the mesh to allow a corrective shape.

    Finger and knuckles
    Depending on the medium, finger layout can change drastically.
    From trying to save edge loops for games:

    Fig. 05 - Low Res Game Edge flow


    A more stylized and cartoony feature:

    Fig. 06 - Stylized / Cartoony Edge flow
    http://www.hippydrome.com/ModelingHand.html


    To a full on anatomical study:

    Fig. 07 - Anatomical Edge flow
    https://vimeo.com/19554640


    For each scenario there are ways of creating the fingers that are optimized for the output. However, in a fairly standard production, I’ve found the following to hold up nicely:

    Fig. 08 - Standard Edge flow


    One of the most common missteps to making fingers, is to simply leave them as extrudes down the length with no attention or detailing in the knuckle. This way of construction leads to uneven deformation and limited polygons to manipulate if corrective shapes are needed.


    Joints and Joint Placement
    Joint Naming
    Naming the joints in relation to the body is helpful when using the Paint Weight joint list. Having all your fingers prefixed with “_Fng_”, such as “j_L_Fng_Index_1” will keep all your fingers together together on the list and reduce the time spent searching for the others.

    This can be modified to fit different workflows or preferences, such as naming the spine joints “j_Spine_0_Head”, “j_Spine_1_Neck”, “j_Spine_2_Ribcage”, “j_Spine_3_Waist”, and “j_Spine_5_Hips”. This naming will list these joints numerically from top to bottom right and next to each other on the list. Without those prefixes, you’d have to search up and down your joint list from “H” to “W” to paint the next joint.

    To effectively mirror weights, naming the joints is very important. “j_L_Elbow” and “j_R_Elbow” can be mirrored using the Search/Replace option in Mirror Skin Weights, by searching for “_L_” and replacing it with “_R_”.

    Joint Placement
    Joint placement is another area that will take a good amount of practice and trial and error to get better at. Having an understanding of where the joints are anatomically will help, but are not an end all to where to place them. For example, there are 33 vertebrae in the human spine, however, you wouldn’t want to put 33 joints in the rig for a multitude of reasons. But, knowing where the spinal column is and how its oriented to the body, will help you place joints more realistically.

    One joint that is commonly misplaced is the clavicle. The clavicle pivot should be placed slightly to the side of the sternum at the front of the chest, however, many people starting out will place it along the centerline of the body or elsewhere.

    Fig. 09 - Clavicle Joint Placement


    As mentioned before, this placement of the joint is more anatomical, but may not suit your character. Joint placement can be anatomical or more centerline. Centerline works well for more cartoony deformation, involving squash and stretch. As cartoony characters can bend differently or more extremely, having the joints in the middle will keep the deformations even and consistent, while not favoring one side or another.

    Overlapping Joints affect weight mirroring
    Another commonly misplaced joint is the eyelids, if you are using a single joint each lid. If two or more joints share the exact same position, when the skin weights are mirrored to the opposite side, the results are not what you’d expect. With that in mind, slightly offsetting joints that overlap directly will remedy this issue.

    Fig. 10 - Mirroring results with overlapping vs offset joints


    Free Floating verse Parented Joints
    How the joints are parented in the hierarchy can affect the initial bind results when a skin is applied. Below you’ll see two examples, one is the result of the joints being parented to each other, the other is if they are left free floating.

    Fig. 11 - Default skin weights - Hierarchy Joints vs Free Floating
    Twist Joints
    Twist joints help maintain volume when the joint chain is twisted along the primary axis. The most common example of this is the forearm twist. As the hand rotates, the volume in the forearm will be lost if weighed to the wrist joint or left to sheer if not influenced at all.


    Fig. 12 - Twist joints maintain volume


    Adding in these addition joints spreads out the distribution of the rotation value along the entire chain. Not only is the rotational value spread, but also helps the position of the verts being weighed, though that is slightly more difficult to explain.

    You can learn more about setups and solutions for overcoming forearm and other twist areas in a previous write-up:
    http://www.3dfiggins.com/writeups/forearmTwist/

    Helper/Additional Joints
    You can add additional joints to a skin that can help preserve specific volumes. These joints can be directly animated by hand for spot fixes, driven by Set Driven Keys or nodes for automation.

    One key place to have additional joints is the shoulder. A great example can be seen in this tutorial / script by Peter Shipkov:
    http://petershipkov.com/development/shoulderrig/shoulderrig.htm
    Another area is the elbow / knee. By placing two more joints in the skin for the front and back of the bend joint, you can have them push away as the limb bends, which in turn, will pull out the verts and give just a bit more volume in the crease area.

    Fig. 13 - Extra joints to push out on elbows



    How to Weight Multiple / Dense / Overlapping Meshes
    ‘Sock Puppet’ Approach
    Sock puppet skinning is based off merging overlapping meshes and removing unnecessary polygons to make a clean, single mesh to paint weights on to later transfer those weights back to the original meshes.

    This process can be used in multiple instances, such as:
  • Overly dense meshes: Smoothed with history deleted, exported from another program
  • Different meshes: Copying the weights from one character to another on the same rig
  • Overlapping meshes: An arm inside a sleeve, inside a jacket
  • Topology Changes: Seams, zippers, folds
  • Ride Along Meshes: Buttons, gear, clips, badges

  • Using this approach can also speed up rigging facets, such as:
  • Creating low res, deforming proxy for the Animator to work with or Cloth to sim on
  • Allow a more straight forward weight transfer if the meshes or point orders change
  • Adjusting weights on a single mesh instead of several
  • Greatly reduces time spent, especially initially, on skinning complex characters


  • Fig. 14 - Low res cage for facial meshes


    Fig. 15 - Low res cage for complex / multiple meshes



    Creating a Sock Puppet Mesh
    -Duplicate the base meshes that define the most volume of the character

    Fig. 16 - Primary meshes duplicated

    -Remove as many edges as possible to reduce the overall density

    Fig. 17 - Edges reduced

    -Separate/Delete any additional props or pieces

    Fig. 18 - Delete any additional pieces

    -Delete any overlapping or underlying meshes

    Fig. 19 - Delete any overlapping faces / pieces

    -Merge the meshes together
    -Weld the Border edges back together
    -Results in a single mesh

    Fig. 20 - Single Final mesh


    Transferring the weights back

    Below is a MEL script that will transfer the weights from one mesh and apply them to other meshes.
    To run this script:
    -Select all of the code below and paste it in to the script editor
    -Select all the meshes you'd like to paste weights to
    -Shift-Select the mesh that has proper weighting
    -Select all the code in the Script Editor
    -Hit 'Enter'

    //////////////////////////////////////////
    //Select meshes to transfer weight to, then shift-select the mesh with weights, then run this script
    
    string $userSel[] = `ls -sl`;
    
    if(`size($userSel)` > 1)
    {
    
      select $userSel[((`size($userSel)`) - 1)];
      string $cageMesh[] = `ls -sl`;
    
      select $userSel;
      select -tgl $cageMesh;
      string $pieces[] = `ls -sl`;
    
      //get inputs of weights in skin
      string $theJoints[] = `skinCluster -q -wi $cageMesh`;
    
      if(`size($theJoints)` > 0 && $cageMesh[0] != "")
      {
      
        int $counter;
        int $sizer = size($pieces);
    
        for ($counter = 0; $counter < $sizer; $counter++)
        {
    
          ///////////////////////////////////////////////////////////////////////////////////////
          //Determine if skinCluster exists on piece
          string $skins[] ;
          clear $skins ;
    
    	  string $hist[] = `listHistory -pdo 1 -il 2 $pieces[$counter]` ;
    	  string $h ;
    	  
    	  for ($h in $hist)
    	  {
    	      if (nodeType($h) == "skinCluster")
    	      {
    	          $skins[size($skins)] = $h ;
    	      }//end of if skinCluster type exists
    	  }//end of for loop through history
    
    
          /////////////////////////////////////////////////////////////////////////////////////////
          //If skinCluster Doesn't exist, add skinCluster
          if(`size($skins)` == 0)
          {
        	  select $pieces[$counter] $theJoints;
        	  newSkinCluster "-tsb -mi 10 -dr 10" ;
          }//end of apply skinCluster if none found
    
    
          //////////////////////////////////////////////////////////////////////////////////////////
          //Add all influences from cageMesh
          int $counterInf;
          int $sizerInf = size($theJoints);
          string $pieceJoints[] = `skinCluster -q -wi $pieces[$counter]`;
    
          for ($counterInf = 0; $counterInf < $sizerInf; $counterInf++)
          {
        	  int $found = stringArrayContains($theJoints[$counterInf], $pieceJoints);
        	  if($found == 0){skinCluster -e -ai $theJoints[$counterInf] $skins[0];}
          }//end of for loop through adding all cageJoints
    
    
          ///////////////////////////////////////////////////////////////////////////////////////////
          //Remove extra joints that don't match those in cageMesh skinCluster
          string $theJoints[] = `skinCluster -q -wi $cageMesh`;
          string $pieceJoints[] = `skinCluster -q -wi $pieces[$counter]`;
          string $diffJoints[] = stringArrayRemove($theJoints, $pieceJoints);
    
          int $counterInf;
          int $sizerInf = size($diffJoints);
    
          if(`size($diffJoints)` > 0)
          {
        	  for ($counterInf = 0; $counterInf < $sizerInf; $counterInf++)
        	  {
        	      skinCluster -e -ri $diffJoints[$counterInf] $skins[0];
        	  }//end of for loop through removing extra joints
          }//end of if any joints are different
    
    
          //////////////////////////////////////////////////////////////////////////////////////////
          //Transfer the Weights
          select $cageMesh $pieces[$counter];
          copySkinWeights  -noMirror -surfaceAssociation closestPoint -influenceAssociation closestJoint -influenceAssociation oneToOne -influenceAssociation name -normalize;
    
    
          //////////////////////////////////////////////////////////////////////////////////////////
          //Finalize
          print ("\nSkin Applied/Weights Transfered: " + ($counter + 1) + "/" + $sizer);
    
        }//end of loop through pieces
        
        select $userSel;
        
      }//end of if there is a skinCluster to copy from
    
    }//end of if user has selected enough items
    



    Painting Weights Process
    Apply the skin
    Select all the joints you plan to weight to, then select the ‘sock puppet’ mesh. Skin > Smooth Skin > Option Box. Use these settings:

    Fig. 21 - Initial Smooth Skin Settings


    Calisthenics (Range of motion) on the rig
    Having a set range of motion on a character will allow you to quickly scrub the timeline and see the effects of your weighting adjustments.

    Fig. 22 - Range of Motion Movie

    -Switch to the FK controls, if the character is already rigged or key directly on bind joints if not
    -Left fingers
    -Left wrist, elbow, shoulder, clavicle, stretch long, common poses (arm in front
    -Head/neck, spine from top to bottom
    -Left hip, knee, ankle, toe, stretch long, common poses (toe raise, seated position)

    Viewport Setup
    -Hide non-skinning joints, rig elements (locators, IK Handles) and non-skinning meshes to make the viewport as clean as possible
    -Show joints and geo in viewport. (Show > None. Show > Joints. Show > Polygons)
    -X-Ray joints in viewport (Shading > X-Ray Joints)
    -Set joint color to red for easy viewing of joints, since purple on black can be difficult
    (mel script)
    //Joint Color Red
    displayColor -dormant "fkJoints" 13;
    

    //To return to Default Joint Color
    displayColor -dormant "fkJoints" 8;
    


    Painting Weights - Process
    -Open Paint Weight Brush and keep the options open (Skin > Edit Smooth Skin > Paint Skin Weights Tool > Option Box)

    -From here, you can either flood mesh to root and paint from scratch or paint atop the default results. Since you’ll be adjusting all the verts anyways, it’s really about how much time you have at the moment. If time is short, you can paint atop the default values to hit main areas to get the character to animation sooner, or you can flood to the root joint and go through each section with much more precision.

    -Set Paint Operation to Add, Opacity to .4 and Value to .25

    -Right click on the left thumb tip joint, select ‘Select Influence’ in marking menu

    -Paint the verts for that joint


    Fig. 23 - Weights Before and After

    -Scrub the timeline to check your work -Use the ‘smooth’ Paint Operation in paint weights to ease the transition between two joints


    Fig. 24 - Smoothing Weights Before and After


    -For best results with ‘smooth’ use on the back/extreme side of a bend and set the Opacity to 1

    -Right click on the next thumb joint and repeat down each joint for the entire left side joints/verts

    -Once you’ve painted the left side, mirror the weights over (See below for the process and notes on mirroring)

    Painting Weights - Tips
    -Avoid using Substitute, stick with Replace/Add/Smooth on the Paint Weight Brush options. Substitute can oddly disperse weights between joints.

    -Right clicking on joint and using a marking menu to select the ‘paint weight’ option is typically faster than trying to find the same joint in the paint weight joint list.

    -You can quickly toggle between Adding and Smoothing weights by holding the Shift key while in paint mode.

    -Display Joint Size (Display > Animation > Joint Size) will quickly change the visual size of the joint without changing or having to adjust the Radius value. This works well if the joints are grossly oversized or if you’re doing many joints close together in a detailed area, such as the face.

    -Seeing the effects of smoothing weights is more clear when mesh is being deformed by that joint. For instance the shoulder, smoothing the weights when the arm is raised up or lowered, the results are much more apparent. Combine with having the joint animated for that range of motion, you can quickly scrub the timeline to see the results even more so and adjust accordingly.


    Additional Tools and Processes
    djRivet
    Often times, there are instances where one mesh has to ride along with another, but not deform. This could be buttons on a shirt or a policeman’s badge.

    The script, djRivet.mel, uses follicles to constrain objects to a polygon or nurbs surface using Maya’s hair system.
    http://www.creativecrash.com/maya/downloads/scripts-plugins/polygon/c/djrivet-mel--3 )

    You can take this script further and use multiple ‘riveted’ joints to ride along the surface of a mesh and then skin only to those riveted joints. For instance, a bandolier, slung diagonally across the chest would deform oddly has the body is bent or the shoulder raised. If you created a series of joints that were then riveted to the underlying body mesh, you could skin the bandolier mesh them for better results.

    A note about using djRivet, is that the follicles created are based off UVs. If the mesh has overlapping UVs, the rivet may not work or will behave oddly. You can work around this by having the model’s uvs laid out accordingly or by doing the following:

    Rivet Work Around:
    -Duplicate the un-UV’d mesh, name it “..._AutoUVs”
    -With the AutoUVs mesh selected, Create UVs > Automatic Mapping
    -Delete History on the AutoUVs mesh, Edit > Delete by Type > History
    -Select the un-UV’d mesh, then shift-select the AutoUVs mesh, Create Deformers > Blendshape
    -Select the newly created blendshape node under the Inputs of the AutoUVs mesh
    -Set the Influence of the un-UV’d mesh to 1 in the blendshape node

    From here you would create your rivets on the AutoUV mesh as the uvs do not overlap and the mesh will follow along with the mesh driving the blendshape

    Weight Hammer
    Weight Hammer (select verts, Skin > Edit Smooth Skin > Weight Hammer) is a function in Maya that looks at the selected verts, gathers the weights of the verts around the selection and applies those weights to the selection. This tool is useful when you have stray verts being affected by outside joints. I run into this the most often with the lips, typically the lower lips will be weighted to the head or top lip joints, causing them to sheer. Once you select the verts and run Weight Hammer, the results are clear

    Fig. 25 - Weights hammered for stray vertex


    Mirror Skin Weights Settings
    Mirroring the weights from one side of the mesh to another can save hours of work and frustration. To do so correctly relies on a few key factors that have already been addressed: mesh construction, joint naming and position. If these factors are taken care of, mirroring weights is very straightforward.

    Select your bound mesh, Skin > Edit Smooth Skin > Mirror Skin Weights > Option Box. Use the following settings:

    Fig. 26 - Mirror Weight Settings


    Keep in mind that mirroring skin weights doesn’t work correctly if:
  • Joints share exact world space
  • Naming or Joint placement is not symmetrical
  • The mesh is not symmetrical


  • This is not to say the Mirror Skin will fail, but rather the results will not be as clean and predictable as you’d imagine.


    Additional Tips
    Skinning can either maintain volume through penetration or lose it through even distribution
    One of the main struggles when you’re new to painting weights is maintaining the volume. Eventually, you realize that you can maintain the volume if you allow the meshes to penetrate or you can smooth the weights and loose that volume. Too often people spend so much time trying to get results that are not possible with a default skinCluster. If you’re working in games, typically you cannot have blend shapes or too many corrective joints, so you paint weights to maintain as much volume as possible, hence penetration. If you work in a pre-rendered environment, you can explore adding additional joints, corrective blend shapes, muscle solutions and many others to get the desired results.

    Start rough, polish as needed
    Painting weights can be a very long and tedious process. Instead of trying to get every vertex delicately weighted, put a default bind on there, fix the hot spots for volume control and start animating. Once the character is up and moving in the scene, you can see where the weights fall apart. If the shoulders or feet are sheering, fix those weights first and continue animating. By fixing as you go, at the end of the project you’ll have only cleaned up the areas that needed it and not spent time on those that didn’t.

    Unnatural animation causes unnatural deformations
    A common complaint of painting weights come from the shoulders. While it’s true that this area comes under high scrutiny, often times the rig is being animated into an unnatural pose that would be outside the range of motion for the character. Often this comes from raising the arm too high without lifting the clavicle, trying to shrug the shoulders too deeply or twisting too much (especially when twist joints aren’t being used). By putting the character in an unnatural pose, you’ll start seeing unnatural results in the skin that may need to be fixed by adjusting the pose in animation or a custom, one-off solution on the rig or in the scene.

    Know when to use another approach
    At some point, you’ll find a situation where default skin clusters and painting weights is not getting the desired results. You can try adding more and more joints, but this may not be practical, either in terms of rigging or animation. Common examples of these situations are skirts and dresses in games (which sheer when the legs separate too far apart), muscular characters (whose loss of volume or lack of flexing is more noticeable), characters with layers of cloth that drape or hold a silhouette, or when a the camera is closer and can see the deformation’s shortcomings.

    At this point, you may need to explore other options, such as: corrective blend shapes, cloth simulation, muscle simulation and so on. My only words of advice before going down these additional paths is to make sure your project truly needs those results, as each one of these other options will make your character heavier and more complex, which may lead to unforeseen problems later on.


    Conclusion
    Painting weights is not nearly as bad as it’s made out to be. With a few modifications in workflow and a better understanding of what the skinCluster can and cannot do, and you’ll find that painting weights is a far less daunting and time consuming task.





    Other Opinions, Further References, Typos, and Grammer Issues please contact KielFiggins22@gmail.com