py-modeの追加

xyzzypython用のモードを追加する手順をメモしておきます。

ダウンロード

http://www.geocities.co.jp/Milano-Cat/2067/xyzzy.html#py-mode からダウンロードします。自分の場合は、py-mode-20070407.zip でした。展開したファイルの中身をxyzzyディレクトリにコピーします。

バイトコンパイル

M-x byte-compile-file (py-mode.lのパス) を実行します。
.xyzzyに以下のコードを追記して xyzzy.wxp を削除したら、次回xyzzy起動時に再設定されます。(Windows XPの場合)

;;Python
(load-library "py-mode")
(push '("\\.py$" . py-mode) *auto-mode-alist*)

インデントはタブに設定(グローバル設定)

pythonの場合、通常、インデントは必ずタブで行う必要があるので、そのように設定します。間違ってスペースになっていても見た目で気づくことが不可能なので、注意すべきポイントです。
py-mode.lを開き、下記の部分を修正して、py-mode.lをバイトコンパイルしなおします。

(defvar *py-indent-tabs-mode* t) # nilをtに変更.

※なんでnilになってるんだろ・・。

インデントはタブに設定(ローカル設定)


何らかの都合で開いているテキストファイルのみで「タブをタブコードで入れたい」場合には、上図のように設定します。

BlenderでPythonプラグイン#1(調査編)

Blenderではプラグインpythonで書くことができるらしいし、実際配布されているBlenderパッケージに入っているプラグインはほとんどがpythonで書かれている。
(例:うちの場合、次のディレクトリにプラグインが入っています→C:\Program Files\Blender Foundation\Blender\.blender\scripts)

とりあえずファイル作成のスクリプト

上記リンクのうち「Python‚̉º‚Á’[」を参考にして、以下のコードを書いて、保存、実行([Alt]+[p])してみる。

print "Hello, python!"

file_export = open( "blend-export.txt", "w" )
file_export.write("test from blender.\n")
file_export.close()

コンソールに、Hello, python! と表示され、blend-export.txt ファイルには test from blender. と書き出された。

シーンの情報取得の第一歩

次に、このヘルプを見ながらテストを始めてみる。The Blender Python API Reference 日本語版
pythonもよく分かっていないのだけど、いくつかのページを見ているとなんとなく様子が見えてくる。多分こんな感じ、と書いた次のコードもそれなりに動いてくれた。

import Blender
from Blender import *
print "=== PRINT SCENE OBJECTS NAME ==="

for obj in Blender.Scene.GetCurrent().getChildren():
	print obj.getName()

これを初期画面で実行すると、コンソールには次のように表示されました。

=== PRINT SCENE OBJECTS NAME ===
Cube
Lamp
Camera

なんとなく良い感じに進んでいます。

BlenderでPythonプラグイン#2(Exporterの基礎完成)

もともと入っているプラグインをごそごそ見て回っていると、なんとなくメッシュ情報の取得手順が見えてきました。
どうやら、BPyMesh というデフォルトで入っているユーティリティを使うようです。
で、下記のようなスクリプトで試してみます。

import Blender
from Blender import *
import BPyMesh
print "=== PRINT SCENE OBJECTS NAME ==="

for obj in Blender.Scene.GetCurrent().getChildren():
	print obj.getName()+" ("+obj.getType()+")"
	if obj.getType() == "Mesh":
		mesh = BPyMesh.getMeshFromObject(obj)
		if not mesh:
			continue
		print " " + str(len(mesh.verts)) + " vertices."
		for v in mesh.verts:
			print "  v["+str(v.co[0])+","+str(v.co[1])+","+str(v.co[2])+"]"

これをデフォルトシーンに適用すると、次のような出力が得られました。

=== PRINT SCENE OBJECTS NAME ===
Cube (Mesh)
 8 vertices.
  v[1.0,0.999999940395,-1.0]
  v[1.0,-1.0,-1.0]
  v[-1.00000011921,-0.999999821186,-1.0]
  v[-0.999999642372,1.00000035763,-1.0]
  v[1.00000047684,0.999999463558,1.0]
  v[0.999999344349,-1.00000059605,1.0]
  v[-1.00000035763,-0.999999642372,1.0]
  v[-0.999999940395,1.0,1.0]
Lamp (Lamp)
Camera (Camera)

あとはコードの整形、書き出すフォーマットをちょっと修正すればいろいろ使えそうです。
調べる前は不安だったけど、たった1,2時間でここまでできれば十分実用に耐えそうですね、blender
pythonのコードはインデントが多くなり勝ちなので、ちょっと見づらくなるのも何とかしたいなー。関数化、とかか?