2007年11月28日水曜日

blender - python マテリアル一掃失敗

blenderのマテリアル管理は、「マテリアルからのリンクをすべて消さない限り、マテリアルが消えない」という仕様ゆえ、結構適当になりがちで、気づいたら使ってないはずのマテリアルがリストに入ってるのではないでしょうか?自分は気づいたら、一番最初にBlenderはじめたころのマテリアルが、現在作ってるモデルに入ってたので苦労して消しました。

これをスクリプトで一掃できるようになったら便利だなー。

ということで調べ始めたのですが、予想通り(?)ダメでした。現在のスクリプト仕様では、Nodeにアクセスできないので、Nodeのリンクがどうしても消せないのです。じゃあ、発想を転換して、直接.blendファイルから一掃すればいいんじゃないか?ということでBlenderのソースコードを初☆漁り。

…1時間経過。ファイルフォーマット周辺見てみたんですが、かなり複雑で(あたりまえか)、再帰繰り返して読み込みがんばってる感じでした。しかし、有名なオープンソースのプロジェクトだけあって、コードがきれい。俺は、C言語の1000行以上のコードは、友人の研究の手伝いで扱った、ゴミみたいな、うねりプログラム@先輩が残して行ったものしか見たことないので、あまりの違いようで、軽く感動。

さて、さらに漁っていると、pythonのファイル群の中に「Node.c/h」を発見。おっ!と思って見てみたら、全体がifdef-endifで括ってあって、パッチ当てないと動かないよ、と書いてあった。今後に期待。

というわけで、気長に待ってたら、そのうち中の人がNode対応してくれそう?な感じだったので、諦めましたorz

以下、使ってないマテリアルからリンクを消すスクリプト(未完成)

import Blender
from Blender import *

scene = Blender.Scene.GetCurrent()
meshes = [ob for ob in scene.objects if ob.type == 'Mesh']

# ----------------------------------
# get unused materials
# return list of Material
# ----------------------------------
def getUnusedMaterials(meshes):
# get all materials
allMats = Material.Get()

# delete used material from allMats
for mesh in meshes:
for mat in mesh.getData().getMaterials():
for m in allMats:
if (m == mat):
allMats.remove(m)
return allMats

# ----------------------------------
# delete links from materials
# !incomplete(node links etc)!
# ----------------------------------
def deleteLinks(materials):
for mat in materials:
mat.clearIpo()
mat.clearScriptLinks()
for i in range(9):
mat.clearTexture(i)


# ----------------------------------
# execute
# ----------------------------------

mats = getUnusedMaterials(meshes)
print mats
deleteLinks(mats)

2 件のコメント:

tibra さんのコメント...

最初マテリアルの削除ができなくて3時間くらい格闘した覚えがあります^^;

んん?その使ってないマテリアルからリンクを消すスクリプトはMaterialSortとは違う感じですか?
http://keines.gozaru.jp/blender/python/MaterialSort.html

個人的に、ActionEditor等で前後に変化のない無駄なキーフレームを一掃してくるスクリプトとかあればなぁと思います・・・・と遠回しににお願いしてみるw

uimac さんのコメント...

>MaterialSort
おぉ、そんなものが!
でも、目指してるのはちょっと違うかもです。これだとメッシュに適用中のマテリアルは消えてくれるんですが、マテリアルにノードとかFaceUserとか追加して、自分でメッシュからDeleteした後の(メッシュに適用されてない)マテアリアルが消せない。。

>無駄なキーフレームを一掃してくるスクリプト
あったら便利ですね~!後でがんばってみます。