オブジェクトをサクッと円形状に複数コピーしたい
Blenderでは「メッシュオブジェクトを円形状にコピーする」にはやや手間がかかります。一般的にはこんな感じ。
- オブジェクトを配置
- EDITモードへ
- 移動
- OBJECTモードへ
- 回転軸に対して任意の角度をつける
- Emptyオブジェクトを回転軸の中心に配置
- Arrayモディファイアを追加
- Object OffsetにEmptyを指定
- Countを設定
(↑Blenderを使ったことのある方には伝わるはず)
他にもCurveに沿わせてArrayモディファイアを適用するなんて方法もありますね。いずれにせよ手間がかかります。
なので、その手のアドオンがあります。
ありがたいことに、世の中にはこういうのを開発してくださっている方がたくさんいます。絵作りに集中するなら利用すればOKです。
でもね、「どーせなら自分で作ってみたいじゃん?」と思っちゃった(笑)
やりたいことはFast Carveでいう「Circle Array」の機能そのもの。
- サイドバーに専用のPanelを作る。項目は以下。
- 対象オブジェクト
- 複製する中心の半径
- 複製する個数
- 実行ボタン
- Panelに指定された情報をもとにArrayする。
Blender 2.8になって、Classの命名規則ができたりAPIの変更もあったりと、多くの変更点があるようです。
そこでアドオンを作る前段として、「単に円形状にコピーする」ためのPythonスクリプトを組みました。
ソースコード
''' 選択したオブジェクトを円形にArrayするスクリプト(30度毎、計12個複製) ''' import bpy # Add-on化の際、パネルから指定する予定のデータ(仮設定) LOCATION = -5 COUNT = 12 # Array数 ROTATION_AXIS = 0 # 0:X軸/1:Y軸/2:Z軸 ANGLE = -0.523599 # 30度 def trans_object(): try: # Array化するオブジェクトのコンテクストを取得する(=選択しているオブジェクト) ob = bpy.context.object if ob.select_get(): # 移動と回転 bpy.ops.object.mode_set(mode='EDIT') bpy.ops.transform.translate( value=(0, 0, LOCATION), orient_type='GLOBAL', orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)), orient_matrix_type='GLOBAL', constraint_axis=(False, False, True), mirror=True, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1 ) # X軸に回転 ob.rotation_euler[ROTATION_AXIS] = ANGLE bpy.ops.object.mode_set(mode='OBJECT') else: print("Plese target object") except AttributeError: print("Plese target object") def add_array_modifier(): # Array化するオブジェクト名を取得する(=選択しているオブジェクト) ob = bpy.context.object target_obj_name = ob.name # カーソル位置(原点)に配置したEmptyを起点にArray化するためのEmptyオブジェクト bpy.ops.object.empty_add( type='PLAIN_AXES', view_align=False, location=(0, 0, 0) ) # Array化対象のオブジェクトをアクティブにする bpy.data.objects['Empty'].select_set(False) bpy.context.view_layer.objects.active = bpy.data.objects[target_obj_name] bpy.data.objects[target_obj_name].select_set(True) # Arrayモディファイアを追加する bpy.ops.object.modifier_add(type='ARRAY') bpy.context.object.modifiers['Array'].use_relative_offset = False bpy.context.object.modifiers['Array'].use_object_offset = True bpy.context.object.modifiers['Array'].offset_object = bpy.data.objects['Empty'] bpy.context.object.modifiers['Array'].count = COUNT if __name__ == "__main__": trans_object() add_array_modifier()
※エラー処理は組めてません
動作画面
苦労したところ
オブジェクトをアクティブにする方法がわからなかった
円形状に複製するためには、複製元のオブジェクトが回転軸となるEmptyオブジェクトを指定することで機能します。
しかし、Emptyの配置後は「Emptyが選択された状態(アクティブ)」になっていて、複製元のオブジェクトをアクティブにする方法がわかりませんでした。
解決策はソースコードの53行目。
bpy.data.objects['Empty'].select_set(False) bpy.context.view_layer.objects.active = bpy.data.objects[target_obj_name] bpy.data.objects[target_obj_name].select_set(True)
- Emptyの選択状態をOFF
- 複製元のオブジェクトをアクティブ
- 複製元のオブジェクトの選択状態をON
とすればOK。
アドオン化のためのToDo
(1)Emptyオブジェクトを追加する際、任意の名前を指定する方法
単純にAddするだけだと「Empty」という名前になってしまいます。アドオン化の際には任意のオブジェクト名にした方が衝突も起こりにくい。けど、任意のオブジェクト名にする方法がわかりませんでした。
(2)3D VIEWのSlidebarにPanelを作る方法
(3)そもそもアドオンを作るためのルールを知る(笑)
おわりに
Blenderでツールチップを表示してAPIを確認したり、本家リファレンスや英語サイトのQ&Aを見ながら「こんなのやりたいぞ」まで形にできました。
楽しかった!
標準機能を使って絵を作ることも楽しいけど、拡張機能を自分でも作れるUDEが欲しいので日々精進あるのみ。
僕はPhotographerとしてだけでなく、Creator、Engineerの3本柱で楽しく行きたいからね。楽しみながらやっていきます。