はじめに

Blender + python で無料、お手軽、高画質、かつほぼフルスクリプト制御な3次元作図を目指す。基本的には個人的なメモ・備忘録。

Blender + python とは?

このサイトの前提・目的・対象

  • プログラミングは出来るけど pythonBlender は使ったことがないという人が、このサイトを見ることで1時間以内になんとなく作図できるようにする
  • サイトは逆引きリファレンス的に使えるようにする。各項目は次エントリ(↓)に。
  • 科学論文に必要な図が描けるようにする。(概念図、データの可視化、視覚刺激など)
  • 使用 OS は WindowsXPLinux (Kubuntu 7.10)。でも環境依存な部分はそんなにないはず。
  • Blender 2.45。python 2.5。

このサイトが(当面は)目的・対象として「いない」こと

 (でも Blender + python で出来ること)

  • モデリング一般。
  • お行儀の良いプログラミング。
  • ゲーム作り。
  • アニメーション。

目次


スタートアップ

    http://d.hatena.ne.jp/pyblender/20080404/



逆引きリファレンス
 (注:スタートアップ(↑)の知識を前提とする。)

    http://d.hatena.ne.jp/pyblender/20080414/http://d.hatena.ne.jp/pyblender/20080414/http://d.hatena.ne.jp/pyblender/20080414/

    http://d.hatena.ne.jp/pyblender/20080415

    http://d.hatena.ne.jp/pyblender/20080416

    http://d.hatena.ne.jp/pyblender/20080417



外部リソース

  The Blender Python API Reference 日本語版
  (moritaさん)


  The Official Blender Model Repository

通過点を指定して曲線を描く


 ==暫定版==


 通過点を直接指定して曲線を描く方法が判らないので、 Bezier 曲線の機能を使って無理矢理描く。たぶんもっとうまい方法があるはず?

import math

#### Define some functions ####
def pbez(v):
  return BezTriple.New(v.x, v.y, v.z, v.x, v.y, v.z, v.x, v.y, v.z)

def passcurve(plist):
  cu = Curve.New()

  cu.appendNurb(pbez(plist[0]))
  cu_nurb = cu[0]

  for p in plist[1:]:
    cu_nurb.append(pbez(p))

  cu.flag = 1
  cu.bevresol = 6

  scn = Scene.GetCurrent()
  ob = scn.objects.new(cu)
  return ob


#### Set passing points (a list of 3D points)####
plist = []

for t in range(300):
	p = Vector(t*0.01, math.sin(t*0.1), math.cos(t*0.1))
	plist.append(v)


ob = passcurve(plist)


曲線(Curve)の詳細はこちら→ Module Curve


 これで太さ 0 (?)の曲線が出来る(けどレンダリングしても見えない)。太さを変えるには曲線を選択した上で「Editing」パネル−「Curve and Surface」の Bevel Depth の値を変更する*1



 更に「Edit Mode」にして「Curve Tools」から Convert「Poly」にすると object が軽くなってレンダリングが速くなる(たぶん)。





 もうちょっと遊んでみる。(Lorenz attactor)

*1:python から直接この値を変更する手段が見つからず。

MRI 等からのデータを滑らかにする。


 MRI や CT で撮ったデータをそのまま読み込んで使うと画素数によっては滑らかに見えないときがある。



 これを滑らかにする。


 ob を object だとすると

m = ob.getData(mesh=True)

for e in m.edges:
	e.sel = 1
m.remDoubles(0.01)

for f in m.faces:
	f.smooth = 1

m.smooth()

Redraw()

 重複するデータ点を消し、平滑化する。




メッシュ(Mesh)の詳細はこちら→ Module Mesh

ステレオ画像を作る。


 カメラの位置を少しずらすことで、ステレオ写真両眼視差を利用した立体画像)的なことをする。



(交差法で立体的に見えるはず。モデルは The Official Blender Model Repositorysebi さんが公開されているものを使用。)


 cam をカメラオブジェクトだとして、

from Blender.Mathutils import *

fp = Vector(0, -1.5, 1.5)
camdist = 10
camazimuth = 40.0
camelevation = 30.0

vec = Vector(camdist, 0, 0)
rzmat = RotationMatrix(camzimuth, 3, 'z')
rymat = RotationMatrix(camelevation, 3, 'y')

cam.loc = fp + rzmat*rymat*vec
cam.RotX = (90.0 - camelevation)*3.1416/180
cam.RotZ = (90.0 - camazimuth)*3.1416/180


 指定するのは

fp: 注視点の3次元座標
camdist: 注視点からカメラまでの距離
camazimuth: カメラの方位角 (degree)
camelavation: カメラの仰角 (degree)


 方位角を数度(〜3度ぐらい? 距離やカメラの設定にもよる。)ずらして2枚レンダリングすることでステレオ画像を作ることが出来る。



数学関数集(Mathutils)の詳細はこちら→ Module Mathutils

領域色分割・エッジ強調をする。


 特殊用途(?)として、オブジェクトや図地を色で分割する。あるいはエッジを強調する。


 元画像
 



 色分割。

 mmat を Object に関連付けられた Material として(モノに属性(色や透明度)を付ける。参照)

mmat.mode |= Material.Modes.SHADELESS





 エッジ強調。

context = scene.getRenderingContext()

context.edgeIntensity(200)
context.enableToonShading(True)




シーン(Scene)の詳細はこちら→ Module Scene
レンダー(Render)の詳細はこちら→ Module Render


      • -

 今のところ透明なモノにエッジをつけることは出来ない。API のドキュメントには Render モジュールに EnableEdgeAll という関数があり、

Scene.Render.EnableEdgeAll()


とすることで透明なモノにもエッジをつけることが可能と書いてあるのだけど、この関数自体が少なくとも Windows 版 ver. 2.45 では実装されていない。

背景色を変える(透過背景にする)。

w = World.New('myworld')
w.setCurrent()
w.skytype = 0
w.hor = [0.3, 0.6, 1.0]

 新しい世界(World)を作成し、その世界を使用する。「.hor」で背景の RGB 値を指定。タプル("()")ではなくてリスト("[]")であることに注意。



世界(World)の詳細はこちら→ Module World



 図を透過背景にするには

scene = Scene.GetCurrent()
context = scene.getRenderingContext()

context.enableRGBAColor()
context.enablePremultiply()

context.render()

 現在のシーン(scene)からレンダリングに関するインスタンス(context)を取得。context を通じて透過色を有効にする。



シーン(Scene)の詳細はこちら→ Module Scene
レンダー(Render)の詳細はこちら→ Module Render