基本的なメッシュ変形【第 11 回 Python × Blender】

前回 Blender の 3D オブジェクトのメッシュ(頂点・辺・面)の選択方法について書きました。
tamaki-py.hatenablog.com



今回はその選択したメッシュに対し基本的な変換(移動・回転など)を施してみたいと思います。



実は、第 7 回で説明したオブジェクトの変換に用いるbpy.ops.transformクラスの関数が、メッシュの変換に対してそのまま用いることができます。
tamaki-py.hatenablog.com



以下の Python サンプルスクリプトは 3 回立方体オブジェクトを作成し、

  • 1 回目はある面をbpy.ops.transform.rotate()で回転
  • 2 回目はある辺をbpy.ops.transform.translate()で移動
  • 3 回目はある頂点をbpy.ops.transform.translate()で移動

してみた結果となっています。

import bpy
import bmesh
import math


'''数学定数.'''
# 円周率.
pi = math.pi


'''オブジェクトモードから始めなければなりません. scene が empty(空)であるときスクリプトは動きません.'''
# オブジェクトモードに変更.
bpy.ops.object.mode_set(mode='OBJECT')
# 全てのオブジェクトを選択.
bpy.ops.object.select_all(action='SELECT')
# 選択された全てのオブジェクトを削除.
bpy.ops.object.delete()


'''立方体を作成し, 編集モードに切り替え.'''
# 立方体を配置.
bpy.ops.mesh.primitive_cube_add(radius=0.5, location=(0, 0, 0))
# 編集モードに切り替え.
bpy.ops.object.mode_set(mode='EDIT')
# 全てのメッシュを非選択状態にする.
bpy.ops.mesh.select_all(action='DESELECT')


'''面モードにし, 一つの面を回転させる.'''
# 面モードに設定.
bpy.ops.mesh.select_mode(type="FACE")
# bmesh オブジェクトのインスタンス化.
b_mesh = bmesh.from_edit_mesh(bpy.context.object.data)
# 面番号 5 の面を選択.
b_mesh.faces.ensure_lookup_table()
b_mesh.faces[5].select = True
# 面番号 0 の面を z 軸周りに 45° 回転させる.
bpy.ops.transform.rotate(value=pi / 4, axis=(0, 0, 1))


'''他の立方体を作成し, 再度編集モードに切り替え.'''
# オブジェクトモードに変更しないと新たなオブジェクトは配置できない.
bpy.ops.object.mode_set(mode='OBJECT')
# 立方体を配置.
bpy.ops.mesh.primitive_cube_add(radius=0.5, location=(0, 2, 0))
# 編集モードに切り替え.
bpy.ops.object.mode_set(mode='EDIT')
# 全てのメッシュを非選択状態にする.
bpy.ops.mesh.select_all(action='DESELECT')


'''辺モードにし, 一つの辺を動かす.'''
# 辺モードに設定.
bpy.ops.mesh.select_mode(type="EDGE")
# bmesh オブジェクトのインスタンス化.
b_mesh = bmesh.from_edit_mesh(bpy.context.object.data)
# 辺番号 2 の辺を選択.
b_mesh.edges.ensure_lookup_table()
b_mesh.edges[2].select = True
# 辺番号 2 の辺を z 方向に 1 移動させる.
bpy.ops.transform.translate(value=(0, 0, 1))


'''他の立方体を作成し, 再度編集モードに切り替え.'''
# オブジェクトモードに変更しないと新たなオブジェクトは配置できない.
bpy.ops.object.mode_set(mode='OBJECT')
# 立方体を配置.
bpy.ops.mesh.primitive_cube_add(radius=0.5, location=(0, -2, 0))
# 編集モードに切り替え.
bpy.ops.object.mode_set(mode='EDIT')
# 全てのメッシュを非選択状態にする.
bpy.ops.mesh.select_all(action='DESELECT')


'''頂点モードにし, 一つの頂点を動かす.'''
# 頂点モードに設定.
bpy.ops.mesh.select_mode(type="VERT")
# bmesh オブジェクトのインスタンス化.
b_mesh = bmesh.from_edit_mesh(bpy.context.object.data)
# 頂点番号 7 の頂点を選択.
b_mesh.verts.ensure_lookup_table()
b_mesh.verts[7].select = True
# 頂点番号 7 の頂点を (-1/3, -1/3, -1/3)移動させる.
bpy.ops.transform.translate(value=(-1/3, -1/3, -1/3))

実行結果は以下のようになるはずです。
f:id:tamaki_py:20190603223517p:plain