コンテンツへスキップ

Blender Pythonと関数プログラミング #1

blenderのpython用のapiを見てて、書いてみたくなったので始めてみました。僕自身のプログラミングスタイルはcommon lispの影響を強く受けてるものですし、haskellも好きだったので関数プログラミングのスタイルを使ってます。
多くの人のスタイル(手続き型言語のスタイル)と違ってきてるので、違いで混乱することもあるかもしれません。でも書けるようになれば生産性も変わりますよ。

早速書いてみよう

書いてみたのはuv spheres(球体)を使った格子状にオブジェクトを配置させるスクリプトです。最初だからこれで十分でしょう。以下に示していますが、コメントを除けば10行もいりません。

'''
uv_spheres.py / Copyright 2020 Yasuto Takenaka
'''
import bpy

def create_objs(locs):
    '''
    create uv spheres. 
    '''
    for l in locs:
        bpy.ops.mesh.primitive_uv_sphere_add(location=l)

def object_locs(n0,n,step=2):
    '''
    create a list of each location of objects.
    n0, n1 and step depend on the rule of the function, range. 
    '''
    return [(x,y,z) 
        for x in range(n0,n,step) for y in range(n0,n,step) for z in range(n0,n,step)]

def main():
    n0 = -4 # minimum number of locations
    n1 =  4 # maximum number of locations
    create_objs(object_locs(n0,n1))
        
main()Code language: Python (python)

これはblenderのscriptingモードのところに書いたスクリプトですね。(pythonの書きやすいやり方あるんですかね?普段はVSCODEを使ってるけど、blenderにVSCODEやVIMなどが使えて補完がやりやすかったらいいんですが、いい方法知りませんか?)

bpyというのはblenderのpython apiを使うときに必要なライブラリです。

関数の説明

  • create_objs : この関数はuv sphere(球体)を作成している。作成位置のリストを読み込んで処理をさせてます。これがuv sphereじゃなくてcubeやcilinder など独自に書き換えてみてください。いまはシンプルにしてるけど、抽象化する関数は後の記事で考えてます。
  • object_locs : これは作成するオブジェクトの位置のリストを作ってる関数です。この書き方は読まれてる方次第で見慣れないかもしれないですが、内包表記を使ってます。 リストを作成するときにはpythonの内包表記はかなり強力なもの です。(おまけにfor文より高速のようです。)細かな説明は検索して調べてほしいけど、これで3次元の位置をタプル(カッコで区切ったデータ)で作ってリストにしています。[(-4,-4,-4),(-4,-4,-2),…]という感じですね。
  • main : メイン関数です。最後に記述してスクリプトの中身を実行させています。ここでは、-4から4のx,y,z位置を2ステップごとに作ってリスト化したものを使って、オブジェクトを作成させています。基本的に関数を読み込んでおくくらいの動作です。

一つの関数のところにいくつもの動作をすることを記述すると、可読性も後に改造するときにもすごく扱いづらいものになります。このへんが関数プログラミングスタイルと多くの作成の仕方の手続き型プログラミングの違いなんです。

最後に

今回はこれだけです。まるで化学物質の固体分子で見てるような3DCGなんですけど、次はマテリアルの違いを条件で分けて見ると良いなと思ってます。if文を使って分けてしまうのも一つの手ですが、関数プログラミングスタイルなので、filterと高階関数を使って、分けることを考えてます。

blender pythonでのマテリアルの扱いがまだ不勉強なので、明日作れるかどうかはわからないです。

分け方のルールさえ決まっていれば、オブジェクトをfilterで分けてリスト化して、そのリストのオブジェクト一つ一つに変化させる関数を作るって方針ですね。

PS.
崩した体調も治ってきたので今月は今までよりブログを盛り上げたいですね。がんばりますよ!

最終更新日 : 2022-07-01