オブジェクトの選択【第 3 回 Python × Blender】

今回は Blender のオブジェクトを Python スクリプトで選択する方法について書いていきたいと思います。



Blender のオブジェクトは一度に複数選択することができ、それらを一斉に操作することも可能です。



色々実験していくために、まず拙記事PythonBlender を動かすには?はじめの一歩(for Mac)【第 1 回 Python × Blender】』で説明したようにターミナルで Blender を起動し、スクリプティングインターフェースに切り替えデフォルトで置かれている立方体をキー "X" で delete し、以下の Python スクリプトを Text Editor に打ち込んで実行しましょう。
tamaki-py.hatenablog.com

import bpy

for i in range(33):
    x = -8 + i/2
    for j in range(33):
        y = -8 + j/2
        bpy.ops.mesh.primitive_cube_add(radius = 0.25, location=(x,y,(x*x-y*y)/10))

すると、3D Viewport にはこんな感じに複数の立方体が双曲面に沿って配置されます。
f:id:tamaki_py:20190526183758p:plain



このとき 3D Viewport 内で適当な立方体にカーソルを合わせ、右クリックしてみましょう。オレンジ色にハイライトされ選択できるはずです。さらに "Shift" キーを押しながら他の立方体を右クリックすると複数の立方体を選択できます。



複数の立方体を選択したままの状態で Interactive Console にbpy.context.selected_objectsを入力してみましょう。bpyモジュールのオーバービューの記事でも少し紹介したように、bpy.contextサブモジュールは各オブジェクトの Blender における状態(今回の場合選択されている状態)に基づくリストを取り出すのに便利です。今回のbpy.context.selected_objectsは、選択した全てのオブジェクトを取り出します。
f:id:tamaki_py:20190526184612p:plain
tamaki-py.hatenablog.com



すると Interactive Console にはだいたい以下のような結果が返されるはずです。

[bpy.data.objects['Cube.1066'], bpy.data.objects['Cube.1065'], bpy.data.objects['Cube.1064'], bpy.data.objects['Cube.1063'], bpy.data.objects['Cube.1062'], bpy.data.objects['Cube.1061']]

これによるとCube.番号の形で名付けられた立方体オブジェクトのうちいくつかが選択されたのだとわかります。



実際にbpy.dataドキュメンテーションを見ると、確かにこのbpy.data.objectsというオブジェクトobjのリストに対しfor文で、それぞれのオブジェクトの名前obj.nameprintしています。

import bpy


# print all objects
for obj in bpy.data.objects:
    print(obj.name)


#以下略

docs.blender.org



すると以下のような Python のリスト内包表記によって、選択されているオブジェクトの名前のリスト・位置のリストそれぞれを得ることができることもわかるでしょう。

import bpy

name_list = [obj.name for obj in bpy.context.selected_objects] #選択されたオブジェクトの名前のリスト
location_list = [obj.location for obj in bpy.context.selected_objects] #選択されたオブジェクトの位置のリスト


では最後に先ほど配置した立方体のうち、z 座標が負になっているような立方体は全て削除し、z 座標が正になっているような立方体はその z 座標を +5 移動させる Python スクリプトを実行してみましょう。

import bpy


# 一度全ての選択を解除
bpy.ops.object.select_all(action='DESELECT')

# z 座標が負のオブジェクトを選択状態にする
for obj in bpy.data.objects:
    if obj.location[2] < 0:
        obj.select = True

# 選択状態にあるオブジェクトを全て削除
bpy.ops.object.delete()

# 全ての選択を解除
bpy.ops.object.select_all(action='DESELECT')

# z 座標が正のオブジェクトを選択状態にする
for obj in bpy.data.objects:
    if obj.location[2] > 0:
        obj.select = True

# 選択状態にあるオブジェクトの z 座標を全て +5
bpy.ops.transform.translate(value=(0,0,+5))

実行結果は以下のようになります。
f:id:tamaki_py:20190526185325p:plain
実際に z 座標が正だった立方体オブジェクトはスクリプト実行後でも選択されたまま(オレンジ色にハイライトされたまま)になっています。
f:id:tamaki_py:20190526185546p:plain



今日はここまでです🐟