パスのリンク切れとか、このアセットは使用しない等々の理由で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)
テスト
改修
たとえば、リファレンス元のファイルパスが存在しないものだけ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)
こんな感じでしょうか?
ひとまずさっきの状態で試してみると
tama2はパスが通ってない状態、
tama1の2個目はパスが生きてる状態。
この状態で実行すると
両方消えてしまいました。
修正
これの原因はここにあります。
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)
これで先ほどの状態で試してみると、パスが切れているリファレンスだけを除去できました。