0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

MayaAdvent Calendar 2024

Day 8

Mayaでreferenceをremoveしたい

Last updated at Posted at 2024-12-07

パスのリンク切れとか、このアセットは使用しない等々の理由でunload状態のreferenceが溜まると、
一気にremoveしたくなります。

とりあえず設計

逆から考えて

  • referenceをremoveする

為に

  • referenceノードを指定する?

為に

  • unload状態のreferenceノードを取得する?

かなぁー

個別に詰める

  • referenceをremoveする

まずはこれの方法を調べます。

file コマンドの removeReference オプションを使用しようかなと。
書き方的には リファレンスしているファイルパスを引数に渡してますね。

cmds.file(filePath, removeReference=True)

なので、リファレンスノードではなくリファレンス元のファイルパスが必要になってきました。
リファレンスしてるファイルパスの取得ですが、fileコマンドを使用するとすべて取得できます。

allFilePath = cmds.file(q =True ,reference =True)

この中からアンロード状態のリファレンスだけを取得したいのですが、
リファレンスのロード状況を確認するにはreferenceQueryで出来そうです。

loadState = cmds.referenceQuery(referenceNode,isLoaded=True)

ただしリファレンスノード名が引数となるのでリファレンスノードとファイルパスを紐づけた何かが欲しくなります。

fileコマンドで、ファイルパスを引数にして referenceNodeを問い合わせするとノード名が取得できます。

referenceNode = cmds.file(filePath,q =True ,referenceNode = True)

これらをまとめると

  • シーンでリファレンスしてるファイルパスをすべて取得
  • ファイルパスから個別にリファレンスノードを取得し、ロード状態を確認
  • アンロード状態のリファレンスをremove

という感じですね。
実際にスクリプト化してみるとこのようになりました。

import maya.cmds as cmds
allFilePath = cmds.file(q =True ,reference =True)

for filePath in allFilePath:
    referenceNode = cmds.file(filePath,q =True ,referenceNode = True)
    loadState = cmds.referenceQuery(referenceNode,isLoaded=True)

    if loadState == False:
        cmds.file(filePath, removeReference=True)
        

テスト

この状態で実行すると
image.png

アンロード状態のリファレンスだけ削除されました。
image.png

改修

たとえば、リファレンス元のファイルパスが存在しないものだけremoveしたい
場合には


import maya.cmds as cmds
import os
allFilePath = cmds.file(q =True ,reference =True)

for filePath in allFilePath:
    referenceNode = cmds.file(filePath,q =True ,referenceNode = True)
    loadState = cmds.referenceQuery(referenceNode,isLoaded=True)

    if os.path.exists(filePath):
        continue
        
    if loadState == False:
        cmds.file(filePath, removeReference=True)

こんな感じでしょうか?

ひとまずさっきの状態で試してみると

image.png

そのまま居残りました。
image.png

リファレンス元のファイル名を変更して実行してみると
image.png

消えました。
image.png

さらにテストを
image.png

tama2はパスが通ってない状態、
tama1の2個目はパスが生きてる状態。
この状態で実行すると

image.png

両方消えてしまいました。

修正

これの原因はここにあります。

allFilePath = cmds.file(q =True ,reference =True)

fileコマンドで取得したファイルパスを見てみると

# Result: ['C:/Users/kubo/Desktop/test/tama.ma', 'C:/Users/kubo/Desktop/test/tama.ma{1}', 'C:/Users/kubo/Desktop/test/tama2.ma'] # 

同一のリファレンス元から読んだ場合、区別するために {n} が末尾につきます。
この状態で os.path.exists() で存在を問い合わせると Falseが帰ってきてしまいます。
なので、この部分を解決するためにreferenceQueryを使用して元のファイル名を問い合わせます。

cmds.referenceQuery(referenceNode,filename=True,withoutCopyNumber =True)
import maya.cmds as cmds
import os
allFilePath = cmds.file(q =True ,reference =True)

for filePath in allFilePath:
    referenceNode = cmds.file(filePath,q =True ,referenceNode = True)
    loadState = cmds.referenceQuery(referenceNode,isLoaded=True)

    rawFilePath = cmds.referenceQuery(referenceNode,filename=True,withoutCopyNumber =True)
    
    if os.path.exists(rawFilePath):
        continue
        
    if loadState == False:
        cmds.file(filePath, removeReference=True)

これで先ほどの状態で試してみると、パスが切れているリファレンスだけを除去できました。

image.png

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?