マテリアルがアサインされていないテクスチャタグをシーンの中から探してすべて削除するスクリプトを書きました.
テクスチャタグにマテリアルがアサインされていない場合,テクスチャタグがハテナマークになります.テクスチャタグには投影法などのデータが格納されているので,再利用することもありますが,不要であれば削除して整理させたいところです.これらの削除は標準機能でも出来ますが,オブジェクトマネージャのフィルタを使ったりする必要があるので,ボタン一発で出来ないかなと思ったのがきっかけです.
先に言っておきますが,十分なテストをしたわけではありません.もし使う場合は参考程度にしてください.
import c4d
from c4d import gui
## Search object Hierarchy
def GetNextObject(obj):
if obj.GetDown():
obj = obj.GetDown()
return obj
if obj.GetNext():
obj = obj.GetNext()
return obj
while obj.GetUp():
obj = obj.GetUp()
if obj.GetNext():
obj = obj.GetNext()
return obj
return False
# Delete texture tag if not assigned material
def Delete_Textag_No_Material(obj):
tag = obj.GetFirstTag()
while tag:
if tag.GetType() == c4d.Ttexture:
print tag.GetType()
if not tag[c4d.TEXTURETAG_MATERIAL]:
tempTag = tag.GetNext()
doc.AddUndo(c4d.UNDOTYPE_DELETE, tag)
tag.Remove()
else:
tempTag = tag.GetNext()
else:
tempTag = tag.GetNext()
tag = tempTag
return
def main():
doc = c4d.documents.GetActiveDocument()
doc.StartUndo()
obj = doc.GetFirstObject()
if obj == None:
print "Object is none"
return None
while obj:
Delete_Textag_No_Material(obj)
obj = GetNextObject(obj)
doc.EndUndo()
c4d.EventAdd()
return
if __name__=='__main__':
main()
GetNextObject(obj):
シーン内の最初のオブジェクトから最後のオブジェクトまで階層を走査する関数です.
Delete_Textag_No_Material(obj):
objのタグを調べてマテリアルがないテクスチャタグを削除していきます.
tag = obj.GetFirstTag()
読み方そのままですが,オブジェクトの最初のタグを取得します.
while内でそのオブジェクトのタグがなくなるまでチェックしていきます.
while tag:
if tag.GetType() == c4d.Ttexture:
print tag.GetType()
if not tag[c4d.TEXTURETAG_MATERIAL]:
tempTag = tag.GetNext()
doc.AddUndo(c4d.UNDOTYPE_DELETE, tag)
tag.Remove()
else:
tempTag = tag.GetNext()
else:
tempTag = tag.GetNext()
tag = tempTag
if not tag[c4d.TEXTURETAG_MATERIAL]:
もしテクスチャタグであれば,そのテクスチャタグにマテリアルがアサインされているかを確認します.
tempTag = tag.GetNext()
もしマテリアルがない場合(None)は,削除するまえにtemTag変数に自身の次のタグを代入しておきます.次のテクスチャタグがない場合は,Noneが代入されます.
doc.AddUndo(c4d.UNDOTYPE_DELETE, tag)
tagを削除する前にAddUndo関数を使ってUndoを記録しておきます.
tag.Remove()
tagを削除します.
tempTag = tag.GetNext()
tag = tempTag
タグが削除された場合も,削除されなかった場合もtemTagに代入された次のタグを,tagに代入します.tempTag(次のタグ)がNoneならwhileを抜けます.
すべてのオブジェクトを走査していきます.
doc.EndUndo()
c4d.EventAdd()
最後にStarUndo()に対応するEndUndo()を追加し,c4d.EventAdd()で終了します.