my funeral week

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

MayaScripts_GetConstraintConnection:コンストレイントの接続先を取得

ノードにコンストレイントが設定されている時、その接続先を取得したいことってありませんか? 私は作業中に何度もあります。

自分で設定したコンストレイントなら、未だしも他人が設定したものを、いちいちノードエディターを開いて対象のノードを調べるのは 面倒すぎる ので、表題の通りのスクリプトを作成しました。

というか、去年も同じものを制作したんです。


chototoilet108.hatenablog.com


今回の記事は、それのアップグレード版になります。 念の為前回のものは前回のものとして残しておきたかったのと少し機能が増えましたので、別記事にさせて貰いました。



GetConstraintConnections

基本的な利用方法は、前バージョンと同じです。
選択されているノードのコンストレイントによる接続を辿って、拘束側又は被拘束側のノードを取得し選択します。

以下、ソースコード

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

VERSION = "1.4"
NAME = "GetConstraintConnections"
print "\n__" + NAME + VERSION + " imported__"

def __getTransform (target):
    return [i for i in target if isinstance(i, pm.nodetypes.Transform)]
    
def __getConnectionSRC (target, nodeType = "", transform = False):
    result = list(set(target.connections(type = nodeType, d = False)))
    if transform : result = __getTransform(result)
    return result

def __getConnectionDST (target, nodeType = "", transform = False):
    result = list(set(target.connections(type = nodeType, s = False)))
    if transform : result = __getTransform(result)
    return result
    
def getSrc (target):
    """Source側のコネクションを辿る"""
    result = list()
    constraints = list()
    for pairBlend in __getConnectionSRC(target, "pairBlend"):
        constraints.extend(__getConnectionSRC(pairBlend, "constraint"))
    for constraint in constraints + __getConnectionSRC(target, "constraint"):
        result.extend(constraint.getTargetList())
    return list(set(result)) # 検出したノードの出力

def getDst (target):
    """Destination側を辿る"""
    result = list()
    for constraint in __getConnectionDST(target, "constraint"):
        connected = list()
        for pairBlend in __getConnectionDST(constraint, "pairBlend"):
            connected.extend(__getConnectionDST(pairBlend, transform = True))
        if not connected : connected = __getConnectionDST(constraint, transform = True)
        if constraint in connected : connected.remove(constraint)
        if target in connected : connected.remove(target)
        result.extend(connected)
    return list(set(result)) # 検出したノードの出力
    
def main ():
    """SrcまたはDst側を辿り選択する"""
    result = list()
    for i in __getTransform(pm.selected()):
        connected = getSrc(i)
        if not connected : connected = getDst(i)
        result.extend(connected)
    pm.select(result)


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

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

もし、前のバージョンをお持ちの方がいらっしゃいましたら、上記のコードで上書いて貰っても構いません。 Maya上で実行できる状態になってれば何でもいいです。


使い方

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

import GetConstraintConnections
GetConstraintConnections.main()

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

ここまでは、前バージョンと同じです。


改善点

今回のバージョンでは、以下の点が追加されました。

  • Transformを継承したノード全てに反応するようになった。
  • getSrc( )getDst( ) の追加。
    • getSrc( ):拘束側に限定して検索し、Mayaノードとして出力する。
    • getDst( ):被拘束側に限定して検索し、Mayaノードとして出力する。

また、拘束側を取得する際は単にコネクションを辿るのではなく、コンストレイントノードの機能「getTargetList()」を利用しているので、精度は問題ないかと思います。

被拘束側を取得する際は、まだ不安は残りますが・・・一般的なコンストレイントの利用方法であれば問題ないレベルの精度になっているはずです。コンストレイントノードの種類の検知と、PairBlendノードの処理さえ上手くやればもっと精度が上がる気もするのですが、何か良い方法はありませんかね。

Mayaノードとして出力する機能を設けたおかげで、他のスクリプトからモジュールとしての利用もしやすくなりました。というのも、今回のアップデートはそれが大きな目的です。


とまぁ、こんな感じです。
特にこれ以上書くことも思いつかないので、この辺で失礼します。