简体   繁体   中英

Maya bake pivot by python

I centered the pivot as below

cmds.xform(item,centerPivots=True)

How can I bake pivot by Python in Maya? I couldn't find it in the documentation.

Here is a python version of the bake Pivot tool : It is working on a basic sphere but I could have done some mistakes At the end of the script, there is the commands to find the mel files containing the code.

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

def bakeCustomToolPivot(pos=1, ori=1):
    # Check 1) must have an object(s) selected
    objects = cmds.ls(sl=1, transforms=1)
    shapes = cmds.ls(sl=1, shapes=1)
    if len(shapes) > 0:
        transforms = cmds.listRelatives(path=1, parent=1, type='transform')
        objects += transforms

    if len(objects) == 0:
        cmds.error("m_bakeCustomToolPivot.kNoObjectsSelectedError")
        return None

    # Check 2) must be in the move/rotate/scale tool
    currentCtx = cmds.currentCtx()
    contextList = ["moveSuperContext", "manipMoveContext", "RotateSuperContext",
                   "manipRotateContext", "scaleSuperContext", "manipScaleContext"]


    if currentCtx not in contextList:
        cmds.error("m_bakeCustomToolPivot.kWrongToolError")
        return None

    # Check 3) must be in custom orientation mode
    customOri = []
    pivotModeActive = 0
    customModeActive = 0
    if currentCtx == "moveSuperContext" or currentCtx == "manipMoveContext":
        customOri = cmds.manipMoveContext('Move', q=1, orientAxes=1)
        pivotModeActive = cmds.manipMoveContext('Move', q=1, editPivotMode=1)
        customModeActive = cmds.manipMoveContext('Move', q=1, mode=1) / 6
    elif currentCtx == "RotateSuperContext" or currentCtx == "manipRotateContext":
        customOri = cmds.manipRotateContext('Rotate', q=1, orientAxes=1)
        pivotModeActive = cmds.manipRotateContext('Rotate', q=1, editPivotMode=1)
        customModeActive = cmds.manipRotateContext('Rotate', q=1, mode=1) / 3
    elif currentCtx == "scaleSuperContext" or currentCtx == "manipScaleContext":
        customOri = cmds.manipScaleContext('Scale', q=1, orientAxes=1)
        pivotModeActive = cmds.manipScaleContext('Scale', q=1, editPivotMode=1)
        customModeActive = cmds.manipScaleContext('Scale', q=1, mode=1) / 6

    if ori and not pos and not customModeActive:
        cmds.error("m_bakeCustomToolPivot.kWrongAxisOriModeError")
        return None

    # Get custom orientation
    if ori and customModeActive:
        customOri[0] = mel.eval('rad_to_deg({})'.format(customOri[0]))
        customOri[1] = mel.eval('rad_to_deg({})'.format(customOri[1]))
        customOri[2] = mel.eval('rad_to_deg({})'.format(customOri[2]))
        # Set object(s) rotation to the custom one (preserving child transform positions and geometry positions)
        cmds.rotate(customOri[0], customOri[1], customOri[2], objects, a=1, pcp=1, pgp=1, ws=1, fo=1)

    if pos:
        for object in objects:
            # Get pivot in parent space
            # object = 'pSphere4'            
            old = [0, 0, 0]
            m = cmds.xform(object, q=1, m=1)
            p = cmds.xform(object, q=1, os=1, sp=1)
            old[0] = (p[0] * m[0] + p[1] * m[4] + p[2] * m[8] + m[12])
            old[1] = (p[0] * m[1] + p[1] * m[5] + p[2] * m[9] + m[13])
            old[2] = (p[0] * m[2] + p[1] * m[6] + p[2] * m[10] + m[14])

            # Zero out pivots
            cmds.xform(objects, zeroTransformPivots=1)

            # Translate object(s) back to previous pivot (preserving child transform positions and geometry positions)
            new = cmds.getAttr(object + ".translate")[0]
            cmds.move((old[0] - new[0]), (old[1] - new[1]), (old[2] - new[2]), object, pcp=1, pgp=1, ls=1, r=1)

    # Exit pivot mode
    if pivotModeActive:
        mel.eval('ctxEditMode;')

    # Set the axis orientation mode back to object
    if ori and customModeActive:
        if currentCtx == "moveSuperContext" or currentCtx == "manipMoveContext":
            cmds.manipMoveContext('Move', e=1, mode=0)
        elif currentCtx == "RotateSuperContext" or currentCtx == "manipRotateContext":
            cmds.manipRotateContext('Rotate', e=True, mode=0)
        elif currentCtx == "scaleSuperContext" or currentCtx == "manipScaleContext":
            cmds.manipScaleContext('Scale', e=1, mode=0)
print(mel.eval('whatIs bakeCustomToolPivot;'))
print(mel.eval('whatIs performBakeCustomToolPivot;'))     
bakeCustomToolPivot()

If you have animated your "rotate pivot translate"

rotatePivotX,rotatePivotY,rotatePivotZ
scalePivotX, scalePivotY, scalePivotZ

You just have to enable keyframing and use cmds.setKeyframe

cmds.setAttr('pSphere1.rotatePivotX', k=True)
cmds.setKeyframe( 'pSphere1', attribute='rotatePivotX', t=1, v=5.5 )

then you just have to loop overtime throught every frame you want to.

Btw, if I wanted to bake a pivot I think I would just create a locator at the pivot position with

cmds.xform('pSphere1', q=True, rp=True)

DrWeeny's code was immensely helpful in my current project. To pay it forward, I made a small change to avoid unexpected results:

# Zero out pivots - breaks with multiple selected objects
cmds.xform(objects, zeroTransformPivots=1)

was changed to:

# Zero out pivots - fixed
cmds.xform(object, zeroTransformPivots=1)

With how the code is currently written it will only bake the pivot correctly on the first object in the selection. All other custom pivots in the selection will be reset to their original positions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM