8
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

MayaAdvent Calendar 2019

Day 15

作業中に検出した同じ名前のノードを自動的にリネームする

Last updated at Posted at 2019-12-14

この記事はMaya Advent Calendar 2019の15日目の記事になります。

先日のzebraed氏のpyside:MEventMessageを使ったcallbackはご覧になられましたでしょうか?

OpenMayaでscriptJobと同じ機能を軽くシンプルに扱えるとの事で、自分も今後活用していこうと思います。

今回はscriptJobを使って書きますが...


はじめに

ノード名が重複しているからと言ってMayaに致命的なエラーが発生することはありません。
しかし、melスクリプトを作成する際に正しい作法で処理を書かないと指定したオブジェクトが見つけられずにスクリプトが停止してしまう可能性があります。

何か起こる前に自動でリネーム出来てたら楽だよね

自動リネーム処理

1. リネームする

  1. uuidからノードを取得する。
  2. ノード名に|(バーティカルライン)が含まれていた場合、ノード名が重複している。
  3. 正規表現でベースとなるノード名を取得する。
    • 赤くマーキングされている範囲をベース名として取得する。

      image.png
  4. リネームする
    • cmds.rename
      • 新しい名前の最後に「#」を 1 つ付けると、名前の変更コマンドは、新しい名前を固有にする番号で最後の「#」を置き換えます。

出来たコードはこんな感じ

def rerename(node_uuid):
    for node in cmds.ls(node_uuid):
        if "|" in node:
            basename = re.search("^(.+)?\|(.+?)(\d+)?$", node).group(2)
            rename_name = cmds.rename(node, "{}#".format(basename))

nonSameNameAlliance.py#L5-L9

2. 手動リネーム時の処理

  • NameChangedが実行されたときにリネーム処理を実行します。
    • 手動でリネームをする場合はオブジェクトを1つしか選択していないと思うのでlsコマンドで選択しているオブジェクトを取得してUUIDに変換してリネーム処理を実行します。
def renameEvent():
    for node_uuid in cmds.ls(cmds.ls(sl=True), uuid=True):
        rerename(node_uuid)

nonSameNameAlliance.py#L11-L13

3. 複製時の処理

  • 手動で複製を行ったときは、複製されたオブジェクトに選択が移動するのでSelectionChangedが実行されたときにリネーム処理を実行します。
    • dag=Trueで階層を取得して、tr=Trueでトランスフォームノードのみ取得できるようにし、UUIDに変換してリネーム処理を実行します。
def duplicateEvent():
    for node_uuid in cmds.ls(cmds.ls(sl=True, dag=True, tr=True), uuid=True):
        rerename(node_uuid)

nonSameNameAlliance.py#L15-L17

スクリプトジョブに登録

def main():
    try:
        if jobIds is not None:
            for jobId in jobIds:
                cmds.scriptJob(kill=jobId, force=True)
    except:pass
        
    jobIds = []
    jobIds.append(cmds.scriptJob(event=["NameChanged", renameEvent], protected=True))
    jobIds.append(cmds.scriptJob(event=["SelectionChanged", duplicateEvent], protected=True))
  • スクリプトジョブに処理を登録すると、条件に合ったタイミングで登録された処理を実行してくれます。
  • 今回はrenameEventとSelectionChangedそれぞれに処理を登録しています。

nonSameNameAlliance.py#L19-L28

Maya起動時に自動でスクリプトジョブを実行する

userSetup.py
import nonSameNameAlliance;nonSameNameAlliance.main()

nonSameNameAlliance.pyをMayaのScriptsフォルダ内に配置してuserSetup.pyに起動用の処理を追記します。
これでMaya起動時にscriptJobに処理が登録されて自動リネームされるようになります。

ダウンロード

今回のソースコードはこちら
https://github.com/teionn/nonSameNameAlliance

注意点

  1. シーン内で操作をした時に自動的にノードがリネームされてしまうので、基本的にモデラー向けの内容かと思います。

  2. トランスフォームノードのみに実行されるようになっています。

  • 中間シェイプノードなどの全てのノードで効果を得たい場合はtr=Trueを消してください。
  1. このスクリプトは大文字/小文字の判定は行いません。
    Mayaは大文字/小文字違いのオブジェクトを同じ階層であっても保持することが出来てしまいます。
    image.png

この状態のままUnityにアセットを持っていくと、オブジェクトobject_aobject_Aがあった場合どちらかのオブジェクトが参照出来なくなってしまうらしいです。


明日の記事はrateionnさんによるちゃんと Remove: Unknown Plugins してますか?というお話です。

あれ… 書くの自分やん… まだ記事できてないんですけど…

間に合ったらスクリプトを無償公開する予定なのでじゃんじゃんDLしてただけると嬉しいです。

8
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?