Go to: Synopsis. Return value. Keywords. Related. Flags. Python examples.

Synopsis

bakeDeformer([colorizeSkeleton=boolean], [customRangeOfMotion=timerange], [dstMeshName=string], [dstSkeletonName=string], [hierarchy=boolean], [influences=string[]], [maxInfluences=int], [pruneWeights=float], [smoothWeights=int], [srcMeshName=string], [srcSkeletonName=string])

Note: Strings representing object names and arguments must be separated by commas. This is not depicted in the synopsis.

bakeDeformer is undoable, NOT queryable, and NOT editable.

Given a rigged character, whose mesh shape is determined by a set of deformers, bakeDeformer calculates linear blend skin weights most closely approximating observed deformations. To do this, a test set of examples is generated by moving the rig through a range of motion. Results mesh and pose pairs are then used to solve a constrained optimization, solving for skinning weights. bakeDeformer automatically binds and applies resulting weights to the destination geometry. If the source and destination mesh/skeleton are identical, the command will replace the original deformations with a skinCluster and computed weights. See the below examples for sample usage.

Return value

stringBakeDeformer name

Keywords

bake, skinning, deformer

Related

skinPercent

Flags

colorizeSkeleton, customRangeOfMotion, dstMeshName, dstSkeletonName, hierarchy, influences, maxInfluences, pruneWeights, smoothWeights, srcMeshName, srcSkeletonName
Long name (short name) Argument types Properties
colorizeSkeleton(cs) boolean create
The new skin cluster created will have its skeleton colorized. Must be used with the -srcSkeletonName and -dstSkeletonName flags.
customRangeOfMotion(rom) timerange create
When this flag is specified with the frames for the range of motion to be used, the tool will step through each frame as a separate pose. Otherwise the tool will use the existing range of motion in the tool that rotates each influence 45 degrees.

Usage examples:

  • -rom "10:20" means all frames in the range from 10 to 20, inclusive, in the current time unit.
  • Omitting one end of a range means using either end of the animation range (or both), as in the following examples:
  • -rom "10:" means all frames from time 10 (in the current time unit) onwards to the maximum time in the animation range (on the timeline).
  • -rom ":10" means all frames from the minimum time on the animation range (on the timeline) up to (and including) time 10 (in the current time unit).
  • -rom ":" is a short form to specify all frames, from minimum to maximum time on the current animation range.

When using this flag, some of the joints in the specified range of motion may not have changed sufficiently. To improve bakeDeformer results or avoid algorithm errors, the command will return a list of influences that do not move enough in the specified range of motion. To detect these joints, the local transformation of each joint is compared between subsequent frames. We consider that a joint has sufficiently changed if any of the below criteria are met:

  • There is a rotation of at least 5 degrees, as determined by the shortest rotation between transforms.
  • There is a translation of 1% or greater of the size of the largest bounding box containing all joints for each frame.
  • There is a scaling change of at least 1%. This percentage represents the smallest scaling value over the largest scaling value (in absolute value).

If a joint has not met any of the criteria, it will be added to the warning of joints that have not moved enough.

The custom range of motion should be considered experimental.

dstMeshName(dm) string create
The destination mesh name.
dstSkeletonName(ds) string create
The destination skeleton name.
hierarchy(hi) boolean create
All children of the passed joints that are used in the influences flag are used.
influences(i) string[] create
A list of joints that are used as the influences to determine new weights.
maxInfluences(mi) int create
The maximum number of influences per vertex.
pruneWeights(pw) float create
On the newly created skin cluster, set any weight below the given the value to zero (post-processing). This will call the skinPercent command as follows: "skinPercent -pruneWeights [value] [skinClusterName] [dstMeshName]" where [value] is the value passed into this flag, [skinClusterName] is the name of the new skinCluster node created after running this tool, and [dstMeshName] is the mesh provided in the -dstMeshName flag.
smoothWeights(sw) int create
The number of smoothing iterations for smoothing weights (post-processing). This also renormalizes the remaining the weights.
srcMeshName(sm) string create
The source mesh name.
srcSkeletonName(ss) string create
The source skeleton name.

Flag can appear in Create mode of command Flag can appear in Edit mode of command
Flag can appear in Query mode of command Flag can have multiple arguments, passed either as a tuple or a list.

Python examples

import maya.cmds as cmds

import maya.cmds as cmds
import maya.mel as mel

def createJointsAndMesh(offset = (0., 0., 0.)):
    root = cmds.joint()
    for _ in range(0,5):
        cmds.joint()
        cmds.move(0., 2., 0., r=True)

    meshes = cmds.polyCube(sx=3,sy=10,sz=3,h=10)
    cmds.move(0, 5, 0, r=True)
    cmds.select([root, meshes[0]], r=True)
    cmds.move(offset[0], offset[1], offset[2], r=True)
    cmds.select(cl=True)
    return (root, meshes[0])

def bindMesh(object):
    rootJoint, mesh = object
    cmds.select(rootJoint, r=True, hi=True)
    cmds.select(mesh, add=True)
    mel.eval('SmoothBindSkin')
    cmds.select(cl=True)

def randomizeJoints(object):
    from math import degrees
    rootJoint = object[0]
    cmds.select(rootJoint, r=True)
    cmds.pickWalk(d='down')
    for i in range(4):
        rads = mel.eval('sphrand 1.')
        cmds.rotate(degrees(rads[0]), degrees(rads[1]), degrees(rads[2]))
        cmds.pickWalk(d='down')

def matchRotations(src, dst):
    cmds.select(src[0], r=True, hi=True)
    srcChain = cmds.ls(sl=True)

    cmds.select(dst[0], r=True, hi=True)
    dstChain = cmds.ls(sl=True)

    for joints in zip(dstChain, srcChain):
        cmds.select(list(joints), r=True)
        mel.eval('MatchRotation')

# Create a new scene
cmds.file(f=True, new=True)

# Create two joint chains/meshes
object1 = createJointsAndMesh()
object2 = createJointsAndMesh(offset=(5, 0, 0))

# Bind one of the joint chains to the mesh and rotate the weights
bindMesh(object1)
randomizeJoints(object1)

# Use bakeDeformer to learn and apply the linear blend skinning weights.
cmds.bakeDeformer(ss=object1[0], sm=object1[1], ds=object2[0], dm=object2[1], mi=3)

# Match the rotations of the two chains to show the results are similar
matchRotations(object1, object2)