2012年6月6日水曜日

Pythonスクリプト講座

前の記事のコメントにオブジェクトが使用している材質が知りたいというのがあったので、これを調べるPythonスクリプトを作ってみました。

下のコードをスクリプトエディタ内にコピーして実行してみてください。使用している材質の名前がスクリプトエディタ下側のログに出力されます。(コード上をダブルクリックしてからCtrl+Cでコピーすると改行も保持されるようです。ペースト後、最後の行に改行を入れてから[EOF]が行の先頭にくるようにして実行してください)

# Check materials used in the current object
doc = MQSystem.getDocument()
obj = doc.object[doc.currentObjectIndex]

nm = doc.numMaterial
uselist = [0] * nm
nonmat = 0

nf = obj.numFace
for x in range(0,nf):
    if obj.face[x].numVertex >= 0:
        if obj.face[x].material >= 0:
            uselist[obj.face[x].material] += 1
        else:
            nonmat += 1

MQSystem.println("Used materials in the current object:")
for x in range(0,nm):
    if uselist[x] > 0:
        MQSystem.println("  " + doc.material[x].name)
if nonmat > 0:
    MQSystem.println("  non-material")


さて、プログラム経験のない人だとこのコードを見ただけでどうなっているのかさっぱり、と思われるかもしれませんが、基本的な文法だけでも理解してしまえばスクリプトはそんなに難しくありません。

Pythonは1行ごとに処理が行われるので、1行ずつ順に見ていけばわかるということです。

まず1行目は単なるコメントです。先頭に#がついているので、その行は内容を解説するだけで処理としては特に意味のないものとなります。

2行目ではMQSystem.getDocument()でドキュメントを取得し、左辺にあるdoc変数に格納します。Pythonでは新しい変数を使うときに前もって宣言する必要はありません。いきなり使用できます。

3行目でそのドキュメント内にあるカレントオブジェクトを取得しています。doc.currentObjectIndexはオブジェクトの番号で、doc.object[番号]の形式で記述するとその番号に該当するオブジェクトが取得されます。取得したオブジェクトは左辺のobj変数に格納します。

4行目は見やすくするための単なる改行で、特に意味はありません。

5行目では材質の数を取得し、nm変数に代入しています。6行目ではuselistに中身がすべて0のnm個の数値のリストを生成しています。このuselistはどの材質が何個の面で使用されたかを調べるために後で使用します。7行目は未着色面、つまりどの材質も割り当てられていない面の数を調べるための変数nonmatを初期化しています。

9行目で変数nmにオブジェクト内の面の数を代入し、10行目のfor文でその個数分だけ処理を繰り返すことを指定します。以降の繰り替し処理はタブで字下げ(インデント)を行います。変数xは0から始まり、処理が繰り返されるごとに変数xの値が1つずつ増えていきます。xがnmと同じ数になるまで繰り返されます。

11行のif文ではx番目の面が使用する頂点数を調べます。obj.face[x].numVertexの値が0個の場合、その面は既に削除されたことになるので、0より大きい場合のみ以降の処理を行います。

12行目ではx番目の面が使用している材質の番号を調べます。obj.face[x].materialの値が0以上の場合は13行目でuselistリスト内のその番号に該当する数値を1つ増やします。これにより、どの材質が何個の面で使用されているかが把握できるようになります。

面が未着色面の場合はobj.face[x].materialが-1になるので、14行目のelse:以降に書かれた処理が行われることになり、15行目でnonmat変数の数値を1つ増やします。

17行目では字下げが行われていないので、上のif文もfor文からも抜けたことになります。for文の繰り返し処理が終わってからこの行の処理が行われます。MQSystem.printlnを実行すると、括弧内に記載された文字列がログに出力されます。

18行は繰り返し処理のfor文です。材質の個数分だけ以降の処理を行います。 19行目でuselist[x]の個数を調べます。x番目の材質が割り当てられている面の数が0より大きい場合、20行目でその材質の名前をログに出力します。

21行はfor文の繰り返しが終わって、次は未着色面の数を調べます。nonmat変数が0より大きければ、22行目で文字列"non-material"をログ出力します。


以上でスクリプトの処理は終了です。既存のスクリプトを何も考えずにそのまま実行するだけでもいいのですが、1行1行をちゃんと理解していけばスクリプトは決して難しくありません。既存のスクリプトを改良しながら理解を進めていけば、ちょっとした処理くらいは自分で書けるようになります。そうなるとツールの使い勝手が大きく上がることもあるので、最初覚えるのが面倒でも決して損することはありません。Scriptsフォルダにはいくつかサンプルのスクリプトが入っているので、それも参考にするといいと思います。