Index

以下のデータからスタート

Maya MAファイルをダウンロード (skirtRig_startData) version maya2017

上記テストデータに対する、
実現用の python コードは以下

# http://tech-coyote.com/archives/1077
# スカートリグ サンプル

# -*- coding: utf-8 -*-
import maya.cmds as cmds
import maya.mel as mel
import maya.OpenMaya as om

# ① set作成
def createJTSet_exe():
    srcJT = 'SourceJoint'
    srcJT_end = 'SourceJoint_End'  
    wgtLct_src = 'WeightLoc_Source'
    wgtLct = 'WeightLoc'
    gp = 'skirtJT_weightCalcurateSrc_Gp'

    cmds.joint(p = [0, 0, 0], n = srcJT)  # 'SourceJoint'
    cmds.joint(p = [6, 0, 0], n = srcJT_end)  # 'SourceJoint_End' 
    cmds.spaceLocator(p = [0, 0, 0], n = wgtLct_src)
    cmds.parent(wgtLct_src, srcJT)
    cmds.spaceLocator(p = [0, 0, 0], n = wgtLct)
    cmds.group(srcJT, wgtLct, n = gp)

    cmds.delete(cmds.pointConstraint(srcJT_end, wgtLct_src, offset =[0, 0, 0], weight = 1))  # 'WeightLoc_Source'

    om.MGlobal.displayInfo(u'done')

createJTSet_exe()

# ② 足のジョイントの回転値を受け取るジョイントや必要なロケーターを作成
ifJT = 'hip_if_L'

def decompMat_exe():
    srcJT = 'SourceJoint'
    wgtLct_src = 'WeightLoc_Source'
    wgtLct = 'WeightLoc'

    decompMat = cmds.createNode('decomposeMatrix')

    cmds.connectAttr("%s.worldMatrix[0]" % wgtLct_src, "%s.inputMatrix" % decompMat, f = True)

    cmds.connectAttr("%s.outputTranslateY" % decompMat, "%s.translateY" % wgtLct, f = True)
    cmds.connectAttr("%s.outputTranslateZ" % decompMat, "%s.translateZ" % wgtLct, f = True)

    om.MGlobal.displayInfo(u'done')

decompMat_exe()

def elrAndQat_exe(ifJT):
    srcJT = 'SourceJoint'
    elr2Qat = cmds.createNode('eulerToQuat')
    qat2Elr = cmds.createNode('quatToEuler')

    # connectAttr -f WeightLoc_Source.worldMatrix[0] decomposeMatrix1.inputMatrix;

    # connectAttr -f decomposeMatrix1.outputTranslateY WeightLoc.translateY;
    # connectAttr -f decomposeMatrix1.outputTranslateZ WeightLoc.translateZ;

    cmds.connectAttr("%s.rotate" % ifJT, "%s.inputRotate" % elr2Qat, f = True)

    cmds.connectAttr("%s.outputQuat" % elr2Qat, "%s.inputQuat" % qat2Elr, f = True)

    cmds.connectAttr("%s.outputRotate" % qat2Elr, "%s.rotate" % srcJT, f = True)

    # connectAttr -f hip_jt_L.rotate eulerToQuat1.inputRotate;

    # connectAttr -f eulerToQuat1.outputQuat quatToEuler1.inputQuat;

    # connectAttr -f quatToEuler1.outputRotate SourceJoint.rotate;

    om.MGlobal.displayInfo(u'done')

elrAndQat_exe(ifJT)


# ③ 最終的に回転値をジョイントに受け渡すためのトランスフォーム等を作成
# -*- coding: utf-8 -*-
import maya.cmds as cmds
# selection 共通関数 v3 -flatten込み-
def commonCheckSelection(*args):
    u""" <selection 共通関数 v3 -flatten込み>
    :return selList:
    :rtype selList: list of unicode
    """
    selList = cmds.ls(sl = True, flatten = True) or []
    # print(selList)
    # if not len(selList):
    #     print('\n' + '***' * 10)
    #     print(u'# result : node を選択し、してください。')
    #     print('***' * 20 + '\n')
    # else:
    #     print('\n' + '***' * 10)
    #     print(u'# result : commonCheckSelection:継続中')
    #     print('***' * 10 + '\n')

    print(selList)

    # print(type(selList))
    # for index in selList:
        # print(index)
        # print(type(index))  # type 'unicode'
    return selList

skirtJT = commonCheckSelection()
if len(skirtJT):
    skirtJT = skirtJT[0]
    print(skirtJT)

def skirtrJT_exe(skirtJT):
    cmds.select(skirtJT, r = True)

    import YO_createSpaceNode

    # 1. skirt_jtAConnect_AL  < -- skirtJT と同じ向き
    YO_createSpaceNode.exe(typ = 1, nt = 'locator', n = [u'~', u'~[Space]', u'~', u'', u''])
    newNode = cmds.ls(sl = True, r = True) or []
    newNode = newNode[0]
    newName = newNode.replace('Space', 'Connect')
    cmds.rename(newNode, newName)
    newNode = cmds.ls(sl = True, r = True) or []
    skirt_jt_connect = newNode[0]
    cmds.ungroup()
    mel.eval("swap")

    # 2. skirt_jtATransNode_AL  < -- ifJT と同じ向き
    cmds.select(skirtJT, r = True)
    YO_createSpaceNode.exe(typ = 1, nt = 'locator', n = [u'~', u'~[Space]', u'~', u'', u''])
    newNode = cmds.ls(sl = True, r = True) or []
    newNode = newNode[0]
    newName = newNode.replace('Space', 'TransNode')
    cmds.rename(newNode, newName)
    newNode = cmds.ls(sl = True, r = True) or []
    skirt_jt_transNode = newNode[0]
    cmds.ungroup()
    mel.eval("swap")

    oriConst = cmds.orientConstraint(ifJT, skirt_jt_transNode)[0]
    cmds.delete(oriConst)

    # 3. skirt_jtATransOffset_AL  < -- ifJT と同じ向き。つまり、2. のspace
    cmds.select(skirt_jt_transNode, r = True)
    YO_createSpaceNode.exe(typ = 1, nt = 'locator', n = [u'~', u'~[Space]', u'~', u'', u''])
    newNode = cmds.ls(sl = True, r = True) or []
    newNode = newNode[0]
    newName = newNode.replace('TransNodeSpace', 'TransOffset')
    cmds.rename(newNode, newName)
    newNode = cmds.ls(sl = True, r = True) or []
    skirt_jt_transOffset = newNode[0]

    # 階層の整理
    cmds.parent(skirt_jt_connect, skirt_jt_transNode)

    return skirt_jt_transOffset, skirt_jt_transNode, skirt_jt_connect

    om.MGlobal.displayInfo(u'done')

skirt_jt_transOffset, skirt_jt_transNode, skirt_jt_connect = skirtrJT_exe(skirtJT)
print(skirt_jt_transOffset, skirt_jt_transNode, skirt_jt_connect)

# ④ ロケーターの移動値をpairBlendノードのウェイトに使用するために、ノードを構築
clmp = cmds.createNode('clamp')
cmds.setAttr('%s.minR' % clmp, -1)
cmds.setAttr('%s.maxR' % clmp, 0)
cmds.setAttr('%s.minG' % clmp, 0)
cmds.setAttr('%s.maxG' % clmp, 1)
cmds.setAttr('%s.minB' % clmp, 0)
cmds.setAttr('%s.maxB' % clmp, 1)

cmds.connectAttr("%s.ty" % wgtLct, "%s.inputR" % clmp, f = True)
cmds.connectAttr("%s.ty" % wgtLct, "%s.inputG" % clmp, f = True)
cmds.connectAttr("%s.tz" % wgtLct, "%s.inputB" % clmp, f = True)

multD = cmds.createNode('multiplyDivide')
cmds.setAttr('%s.input2X' % multD, -1)

cmds.connectAttr("%s.output" % clmp, "%s.input1" % multD, f = True)

'''
setAttr "clamp1.minR" -1;
setAttr "clamp1.maxR" 0;
setAttr "clamp1.minG" 0;
setAttr "clamp1.maxG" 1;
setAttr "clamp1.minB" 0;
setAttr "clamp1.maxB" 1;
connectAttr -f WeightLoc.translateY clamp1.inputR;
connectAttr -f WeightLoc.translateY clamp1.inputG;
connectAttr -f WeightLoc.translateZ clamp1.inputB;
setAttr "multiplyDivide1.input2X" -1;

connectAttr -f clamp1.output multiplyDivide1.input1;
'''

# 視認性を加味
cmds.addAttr('clamp1', ln="outX", dv=0, at='double')
cmds.setAttr('clamp1.outX', e=1, keyable=True)
cmds.addAttr('clamp1', ln="outY", dv=0, at='double')
cmds.setAttr('clamp1.outY', e=1, keyable=True)
cmds.addAttr('clamp1', ln="outZ", dv=0, at='double')
cmds.setAttr('clamp1.outZ', e=1, keyable=True)
cmds.connectAttr('clamp1.outputR', 'clamp1.outX', f=1)
cmds.connectAttr('clamp1.outputG', 'clamp1.outY', f=1)
cmds.connectAttr('clamp1.outputB', 'clamp1.outZ', f=1)

# 視認性を加味
cmds.addAttr('multiplyDivide1', ln="outX", dv=0, at='double')
cmds.setAttr('multiplyDivide1.outX', e=1, keyable=True)
cmds.addAttr('multiplyDivide1', ln="outY", dv=0, at='double')
cmds.setAttr('multiplyDivide1.outY', e=1, keyable=True)
cmds.addAttr('multiplyDivide1', ln="outZ", dv=0, at='double')
cmds.setAttr('multiplyDivide1.outZ', e=1, keyable=True)
cmds.connectAttr('multiplyDivide1.outputX', 'multiplyDivide1.outX', f=1)
cmds.connectAttr('multiplyDivide1.outputY', 'multiplyDivide1.outY', f=1)
cmds.connectAttr('multiplyDivide1.outputZ', 'multiplyDivide1.outZ', f=1)

# ⑤ 前後と横用のpairBlendノードを作成
# 1.
frontPB = 'front_pairBlend'
backPB = 'back_pairBlend'
sidePB = 'side_pairBlend'
frontSidePB = 'frontSide_pairBlend'
backSidePB = 'backSide_pairBlend'

if not cmds.objExists(frontPB):
    frontPB = cmds.createNode('pairBlend', n = 'front_pairBlend')
if not cmds.objExists(backPB):
    backPB = cmds.createNode('pairBlend', n = 'back_pairBlend')
if not cmds.objExists(sidePB):
    sidePB = cmds.createNode('pairBlend', n = 'side_pairBlend')
if not cmds.objExists(frontSidePB):
    frontSidePB = cmds.createNode('pairBlend', n = 'frontSide_pairBlend')
if not cmds.objExists(backSidePB):
    backSidePB = cmds.createNode('pairBlend', n = 'backSide_pairBlend')

# frontPB
cmds.connectAttr("%s.outputX" % multD, "%s.weight" % frontPB, f = True)
cmds.connectAttr("%s.rotate" % srcJT, "%s.inRotate2" % frontPB, f = True)

# backPB
cmds.connectAttr("%s.outputY" % multD, "%s.weight" % backPB, f = True)
cmds.connectAttr("%s.rotate" % srcJT, "%s.inRotate2" % backPB, f = True)

# sidePB
cmds.connectAttr("%s.outputZ" % multD, "%s.weight" % sidePB, f = True)
cmds.connectAttr("%s.rotate" % srcJT, "%s.inRotate2" % sidePB, f = True)

# frontSidePB
cmds.connectAttr('%s.outRotate' % frontPB, '%s.inRotate2' % frontSidePB, f=1)
cmds.connectAttr('%s.outRotate' % sidePB, '%s.inRotate1' % frontSidePB, f=1)

cmds.connectAttr('%s.outputX' % multD, '%s.weight' % frontSidePB, f=1)

# backSidePB
cmds.connectAttr('%s.outRotate' % backPB, '%s.inRotate2' % backSidePB, f=1)
cmds.connectAttr('%s.outRotate' % sidePB, '%s.inRotate1' % backSidePB, f=1)

cmds.connectAttr('%s.outputY' % multD, '%s.weight' % backSidePB, f=1)

'''
connectAttr -f multiplyDivide1.outputX front_pairBlend.weight;
connectAttr -f SourceJoint.rotate front_pairBlend.inRotate2;

connectAttr -f multiplyDivide1.outputY back_pairBlend.weight;
connectAttr -f SourceJoint.rotate back_pairBlend.inRotate2;

connectAttr -f multiplyDivide1.outputZ side_pairBlend.weight;
connectAttr -f SourceJoint.rotate side_pairBlend.inRotate2;
'''

'''
connectAttr -f front_pairBlend.outRotate frontSide_pairBlend.inRotate2;
connectAttr -f side_pairBlend.outRotate frontSide_pairBlend.inRotate1;
connectAttr -f multiplyDivide1.outputX frontSide_pairBlend.weight;
'''

'''
connectAttr -f back_pairBlend.outRotate backSide_pairBlend.inRotate2;
connectAttr -f side_pairBlend.outRotate backSide_pairBlend.inRotate1;
connectAttr -f multiplyDivide1.outputY backSide_pairBlend.weight;
'''


# 2. 手動でコネクションする。。
# ex:
# cmds.connectAttr('%s.outRotate' % frontPB, '%s.rotate' % skirt_jt_transNode, f=True)
# '''
#connectAttr -f front_pairBlend.outRotate skirt_jtATransNode_AL.rotate;
# '''
# cmds.orientConstraint(skirt_jt_connect, skirtJT)



# 3. 調整!!
# 3.1 いじってみる!! v1
#cmds.setAttr("WeightLoc_Source.translateX", 1)
#cmds.setAttr("WeightLoc.translateX", 1)

#cmds.setAttr("clamp1.minR", 0)
#cmds.setAttr("clamp1.maxR", 1)
#cmds.setAttr("clamp1.minG", -1)
#cmds.setAttr("clamp1.maxG", 0)
#cmds.setAttr("clamp1.minB", 0)
#cmds.setAttr("clamp1.maxB", 1)

#cmds.setAttr("multiplyDivide1.input2X", 1)
#cmds.setAttr("multiplyDivide1.input2Y", -1)
#cmds.setAttr("multiplyDivide1.input2Z", 1)

# 3.2 いじってみる!! v2
cmds.setAttr("WeightLoc_Source.translateX", 1)
cmds.setAttr("WeightLoc.translateX", 1)

cmds.setAttr("clamp1.minR", 0)
cmds.setAttr("clamp1.maxR", 1)
cmds.setAttr("clamp1.minG", -1)
cmds.setAttr("clamp1.maxG", 0)
cmds.setAttr("clamp1.minB", -1)
cmds.setAttr("clamp1.maxB", 0

cmds.setAttr("multiplyDivide1.input2X", 1)
cmds.setAttr("multiplyDivide1.input2Y", -1)
cmds.setAttr("multiplyDivide1.input2Z", -1)


最終更新日: 2024年4月18日 09:56:43