my funeral week

少しでも日々の生活に変化を。

MayaScripts_GetConstraint : ノードのコンストレイント先の取得

2021/11/15 Update版が以下にございます。
chototoilet108.hatenablog.com

アニメーション作業中、一時的にリグの外部にノードを作成して、コンストレイントによってリグと接続することがありますよね?
例えば、胸リグのローカル制御になっている腕リグを、グローバル制御に変更する為に、Locator等を接続する等。
場合によってはそのようなノードがシーン内にいくつも存在させてしまうこともあるのですが、一個一個接続先を確認するのも数が多いと結構 面倒 です。

さて、今日からはそんな煩わしさともおさらばできると思います。


GetConstraint

選択されているノードのコンストレイントによる接続先のノードを検索し、取得したノードを選択します。

以下、ソースコード

# -*- coding:utf-8 -*-
import pymel.core as pm

VERSION = "1.3"
print "\n__GetConstraints " + VERSION + " imported__"

def __getSelected ():
    selection = pm.selected()
    return [i for i in selection if type(i) == pm.nodetypes.Transform]

def __getConnectionSRC (target, nodeType):
    result = list(set(target.connections(type = nodeType, d = False)))
    return result

def __getConnectionDST (target, nodeType):
    result = list(set(target.connections(type = nodeType, s = False)))
    return result

def __popResultNode (totalNodes, selected, constraint):
    totalNodes.remove(selected)
    totalNodes.remove(constraint)
    return totalNodes[0]

def main ():
    results = list()
    for target in __getSelected():
        pairBlendFlag = False
        for pairBlend in __getConnectionSRC(target, "pairBlend"):
            for constraint in __getConnectionSRC(pairBlend, "constraint"):
                transform = __getConnectionSRC(constraint, "transform")
                results.append(__popResultNode(transform, target, constraint))
                pairBlendFlag = True
        if pairBlendFlag:
            continue
        for constraint in __getConnectionDST(target, "constraint"):
            transform = __getConnectionSRC(constraint, "transform")
            results.append(__popResultNode(transform, target, constraint))
    pm.select(results)


上記を「GetConstraint」とか適当な名前のPythonファイルとして保存して、以下の場所に保存してください。

C:\Users\ユーザー名\Documents\maya\scripts


使い方

以下のコードをシェルフなり、ホットキーなりに登録してください。

import GetConstraint
GetConstraint.main()

登録したら、コンストレイント先を知りたいノードを選択して、実行。
次の瞬間には接続先のノードがセレクションリストに加わっているはずです。


仕様

  • Transformノードにしか反応しません。
  • 複雑な接続方法が施されたコンストレイントには正しく取得できないと思います。


余談

XSIに存在した「 コンストレイント先の選択 」と「 被コンストレイント先の選択 」機能をMaya上で再現したいという願望から生まれました。
XSIでいうコンストレイントってのはノード同士のキネマティクスを接続する最も簡単な方法でして、入出力も分かり易く多くの人に利用されていたと思います。
Mayaにもコンストレイントは存在しますが、XSIと違ってノードの入出力が割と複雑で、今回のスクリプトではすべての状況に応じたコンストレイント先の取得はできないかもしれません。
本来であれば、このスクリプトでやっているような 「ノード同士のコネクション」ではなく「アトリビュート同士のコネクション」を辿るようにすれば、より精度の高いものになる ことは分かっているのですが、Mayaのコンストレイントノードは数種類ありまして、それぞれ入出力のアトリビュートが異なりますので、私の頭ではすべてに対応するベストな方法が思いつきませんでした・・・。 まぁ、今のところ自分の経験では特に不便することはありませんが、もっと良い方法があれば是非コメントで教えてください。
あとmainメソッド内のネストが深すぎるのも、気になる・・・。

話は変わりますが、Python2.X系のサポートが2020年の頭で打ち切られます。
Maya2019でもPython3.X系に対応していませんが、今後リリースされるバージョンではちゃんとその辺対応してくれるのでしょうか。
とは言え・・・未だにクライアントからMaya2015を使用してくれと言うのも良くある話なので、あと2~3年くらいはPython2系でも問題ないでしょうね。