Edited at

Cinema4D: マテリアルがアサインされていないテクスチャタグを削除するスクリプト

More than 1 year has passed since last update.

マテリアルがアサインされていないテクスチャタグをシーンの中から探してすべて削除するスクリプトを書きました.

テクスチャタグにマテリアルがアサインされていない場合,テクスチャタグがハテナマークになります.テクスチャタグには投影法などのデータが格納されているので,再利用することもありますが,不要であれば削除して整理させたいところです.これらの削除は標準機能でも出来ますが,オブジェクトマネージャのフィルタを使ったりする必要があるので,ボタン一発で出来ないかなと思ったのがきっかけです.

先に言っておきますが,十分なテストをしたわけではありません.もし使う場合は参考程度にしてください.

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()で終了します.