らんだむな記憶

blogというものを体験してみようか!的なー

Blender with python(3)

Blenderが分からんけど、それはBlender入門(2.7版)でゆるりと読んでいくとして...。

pythonAPIはどうやっているんだろう?Help|gt;Python API Referenceを開く。
Oops... 2.75a用のページがNot foundだ。2.75用のページで代用。
Blender Documentation Contents — Blender 2.75.0 c6b042b - API documentation

あれ?

import bpy

ってもう不要かな?bpy.pyが見つからないし、Scripting windowにも

Builtin Modules:     bpy, bpy.data, bpy.ops, bpy.props, bpy.types, bpy.context, bpy.utils, bgl, blf, mathutils

とか表示されている。python.exeの中に抱きかかえているのかな?

>>> for obj in bpy.data.objects:
...     print(obj.name)
...     
Camera
Cube
Lamp

いま画面にあるオブジェクトの名前かな?

>>> c = bpy.data.objects['Cube']
>>> print(c.location)
<Vector (0.0000, -0.2268, 0.0000)>

>>> print(c.location)
<Vector (-1.6572, -4.0958, -0.0948)>

>>> print(c.location)
<Vector (0.6942, 4.1529, 2.2780)>

最初からある箱を動かしながら「Cube」という名前の物体の位置を出力すると変わる。

>>> bpy.ops.mesh.primitive_cube_add(location=(0,0,0))
{'FINISHED'}

でボックスが追加できた。

>>> for obj in bpy.data.objects:
...     print(obj.name)
...     
Camera
Cube
Cube.001
Lamp

あぁ、「Cube.001」って名前が勝手についてるのか。
これをヒントにreference Mesh Operators — Blender 2.75.0 c6b042b - API documentation を見ると、

bpy.ops.mesh.primitive_cube_add(radius=1.0, view_align=False, enter_editmode=False, location=(0.0, 0.0, 0.0), rotation=(0.0, 0.0, 0.0), layers=(False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False))

素晴らしい引数の個数だ。

>>> bpy.ops.mesh.primitive_cube_add(radius=5,location=(0,0,0))
{'FINISHED'}

でけぇ箱ができたwww
箱のradiusって何だ?立方体の一辺のことか?

>>> for m in bpy.data.meshes:
...     print(m)
...     
<bpy_struct, Mesh("Cube")>
<bpy_struct, Mesh("Cube.001")>
<bpy_struct, Mesh("Cube.002")>

ふむ。<bpy_struct, Object("Cube")>と<bpy_struct, Mesh("Cube")>とは何が違うのかな?

Dev:JA/2.5/Py/API/Overview - BlenderWikiおっと半端なく難しい!

あれ?よく考えると、Blenderのオブジェクトとしてキューブという型のオブジェクトなんてないのかな?8個の頂点を持つポリゴン扱い??

>>> for v in c.data.vertices: print(v.co)
... 
<Vector (1.0000, 1.0000, -1.0000)>
<Vector (1.0000, -1.0000, -1.0000)>
<Vector (-1.0000, -1.0000, -1.0000)>
<Vector (-1.0000, 1.0000, -1.0000)>
<Vector (1.0000, 1.0000, 1.0000)>
<Vector (1.0000, -1.0000, 1.0000)>
<Vector (-1.0000, -1.0000, 1.0000)>
<Vector (-1.0000, 1.0000, 1.0000)>

ふむ...。

>>> c.data.vertices[0].co.x += 1

おー歪む歪む。
ならば、

for z in range(5):
    bpy.ops.mesh.primitive_cube_add(radius=0.5,location=(0.0, 0.0, z))

これで五重塔!?キューブの場合のradiusとは、一辺の半分のようだ。0.5にしとけば、一辺は1.0になるっぽい。中心から面への距離と考えても良いのかな?そっちのほうが「半径」っぽいかもしれない。

邪魔なオブジェクトを削除したいな。

for obj in bpy.data.objects:
    if obj.name != "Camera" and obj.name != "Lamp":
        bpy.data.objects.remove( bpy.data.objects[obj.name] )
for m in bpy.data.meshes:
    if m.name != "Camera" and m.name != "Lamp":
        bpy.data.meshes.remove( bpy.data.meshes[m.name] )

どっちでやってもユーザが使ってるからダメとか言われる...。
画面上のオブジェクトを右クリックで選択してから「Delete」すれば通るな。まだよく分からん。とりあえず綺麗になった。

for a in range(5):
    bpy.ops.mesh.primitive_cube_add(radius=0.5,location=(a, a, a))

で謎階段。キューブの作り方はなんとなく分かってきた。

調子に乗ってみよう。
http://www.wakayama-u.ac.jp/~tokoi/lecture/shori1/15.htmlを参考に、pythonテキストエディタを開いて、以下を書いて右クリックメニューから「Run Script」... やばい。応答がなくなった...。固まった!? と思ったら暫くして動き出した。うーん。結構重いのかな?

import bpy

class CircleRenderer:
    def __init__(self, radius):
        self.radius = radius

    def render(self):
        center_x = self.radius
        center_y = self.radius

        adjust = 0.3

        for x in range(self.radius * 2 + 1 - 1):
            for y in range(self.radius * 2 + 1 - 1):
                if (x - center_x) ** 2 + (y - center_y) ** 2 <= (self.radius + adjust) ** 2:
                    bpy.ops.mesh.primitive_cube_add(radius=0.5,location=(x, y, 0))

CircleRenderer(20).render()

以下が記念撮影!
f:id:derwind:20150712215409p:plain