Blender×Python理解への道 ～序章 普段使う機能をPythonで書くとどうなるの？～

# 導入 (Blender × Pythonを勉強したい経緯)

普段はエンジニアだったり、趣味でラップを作ったりしているBuzzWordsという者です。
自作楽曲のMVにBlenderを使ったりしているのですが、仕事が忙しい中、手動でオブジェクトを作っていくのは大変だなぁと思うわけです。

そこで、本業であるプログラミングを活用して効率化していけるように、知見などをまとめていきたいと思います。
急がば回れってやつですね。
(なお、完全な個人メモです。)

以下がBlender × Pythonの公式ドキュメント。

https://docs.blender.org/api/current/index.html

序章では、普段Blenderで使う機能をPythonで書くとどうなるの？
というのを整理して、気楽に手を動かすための足掛かりにしたいです。


# Hello World (立方体を配置する)

プログラミングの取っ掛かりとして、
Hello Worldという文字列をログ出力してニッコリする奴があるのですが、
Blender版のそれは立方体の表示かなと思ったのでやってみます。

(まずは、デフォルトの立方体をクリック ⇒ xキーで削除して、)
画面の上部の「モデリング」「スカルプト」「UV編集」……のメニューにマウスを下スクロールすると、横スクロールになって「**スクリプト作成**」が出て来るのでクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3978339/5a293104-9ec8-6d3e-c192-02977f01b06f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3978339/0f12c93d-ee81-42bb-3807-c038a68e1025.png)

「+新規」ボタンから新しいスクリプトを作成。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3978339/6cf398d3-4089-c09b-1c80-035021f64f71.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3978339/7d76f27d-ba1d-3799-9465-f12a8bf7c942.png)

テキスト入力をするところに、以下を貼り付けてみてください。

``` Python
import bpy

# 立方体を追加
bpy.ops.mesh.primitive_cube_add(location=(0, 0, 0))
```
再生ボタンをクリックすると、立方体が作成されると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3978339/352f31a1-d9db-0a58-e29b-3cc2611bb36e.png)
(上記のスクリプトを再生ボタンで実行した後の画面。)

:::note warn
キーボードを入力しても文字が入らない場合には、マウスがエディタの中に入っているか注意。
Blender全般として、ショートカットキーが発動するのはマウスがオンな所に対してらしい。
:::

シンプルですね。
ということで、追加系のUIとPythonメソッドの対応をざっくり眺めてみましょう。

# 追加UIとPythonメソッドの対応表
Blenderの操作画面上だとShift + Aで何かを追加するための選択肢が出るのですが、
そこで表示される追加項目に対応するPythonメソッドを見ていきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3978339/2e8f94e5-b06a-afa6-6a6e-2ca5e5d11b1c.png)


:::note info
xxxxxxのところには具体的な値
:::
(とりあえず、よく使いそうなやつだけ)
| 名前 | Pythonメソッド |
|-:|:-|
| メッシュ | bpy.ops.mesh.primitive_xxxxxx_add |
| カーブ | bpy.ops.curve.primitive_xxxxxx_curve_add |
| メタボール | bpy.ops.object.metaball_add |
| テキスト | bpy.ops.object.text_add |
| ボリューム | bpy.ops.object.volume_add |
| アーマチュア | bpy.ops.object.armature_add |
| ライト | bpy.ops.object.light_add |
| カメラ | bpy.ops.object.camera_add |

## メッシュ
メッシュと呼ばれる基本的な図形です。
**bpy.ops.mesh.primitive_xxxxxx_add**のxxxxxx部分を差し替えた名前になるそうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3978339/38dad457-7112-0e33-2215-bea0eba5a59c.png)

| メッシュ名 | Pythonメソッド |
|-:|:-|
| 平面 | bpy.ops.mesh.primitive_plane_add |
| 立方体 | bpy.ops.mesh.primitive_cube_add |
| 円 | bpy.ops.mesh.primitive_circle_add |
| UV球 | bpy.ops.mesh.primitive_uv_sphere_add |
| ICO球 | bpy.ops.mesh.primitive_ico_sphere_add |
| 円柱 | bpy.ops.mesh.primitive_cylinder_add |
| 円錐 | bpy.ops.mesh.primitive_cone_add |
| トーラス(ドーナツ型) | bpy.ops.mesh.primitive_torus_add |
| グリッド | bpy.ops.mesh.primitive_grid_add |
| モンキー | bpy.ops.mesh.primitive_monkey_add |



## カーブ
いろんな曲線です。
**bpy.ops.curve.primitive_xxxxxx_curve_add**のxxxxxx部分を差し替えた名前になるそうです。

| カーブ名 | Pythonメソッド |
|-:|:-|
| ベジェ | bpy.ops.curve.primitive_bezier_curve_add |
| 円 | bpy.ops.curve.primitive_circle_add |
| NURBSカーブ | bpy.ops.curve.primitive_nurbs_curve_add |
| NURBS円 | bpy.ops.curve.primitive_nurbs_circle_add |
| パス | bpy.ops.curve.primitive_path_add |
| ファー | (未対応？) |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3978339/e96b014e-d07b-87b1-db42-b63cb4daecd0.png)


## テキスト
文字も入れられます。
以下、正真正銘のHello, World!をするサンプルコード。

``` Python
import bpy

# テキストオブジェクトを追加
bpy.ops.object.text_add(location=(0, 0, 0))

# 追加したテキストオブジェクトを取得
text_object = bpy.context.object

# テキストの内容を変更
text_object.data.body = "Hello, World!"
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3978339/91b6f014-cd02-a991-6211-0bcc5f5105ad.png)


## メタボール
図形をくっつけて何かを作れるやつ。
メタボールは他と違い、**bpy.ops.object.metaball_add**メソッドの**type**オプションで使い分ける。
``` python
import bpy

# メタボール（ボール）を追加
bpy.ops.object.metaball_add(type='BALL', location=(0, 0, 0))
```

| TYPE | 値 |
|-:|:-|
| ボール | BALL |
| カプセル | CAPSULE |
| 平面 | PLANE |
| 楕円体 | ELLIPSOID |
| 立方体 | CUBE |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3978339/b4085625-8f74-224e-4d86-7bcbd59ffb28.png)


## ライト

ライトもメソッドは共通な方式で、**bpy.ops.object.light_add**メソッドを使用する。
**type**オプションで使い分ける。
``` python
import bpy

# ポイントライトを追加
bpy.ops.object.light_add(type='POINT', location=(0, 0, 0))
```
| TYPE | 値 |
|-:|:-|
| ポイント | POINT |
| サン | SUN |
| スポット | SPOT |
| エリア | AREA |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3978339/d621b7b1-8c27-52fc-58cf-3c63fbb10bfc.png)



# (余談)過去の作品例
ちなみに、以下は過去のBlender作品集の一部です。

①ローポリカー。Godot Engineというゲームエンジンに食わせて走らせてます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3978339/030aaf0c-110b-c994-e412-c420a65fdee3.png)


②刀です。呪術廻戦の完結記念に乙骨くんっぽい感じに作りました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3978339/103d8f77-0d6f-2f59-6df7-b92e3af208de.png)

暗殺教室10周年記念にナイフも作ったりと武器が多め？
![暗殺教室_ナイフ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3978339/1119267c-e03c-ca2f-b83b-17aa855d2f32.png)


③大規模な作品例で昔に住んでた寮。公式の資料を基に考察・推定しまくりました。
テクスチャの大半は灰ならしさん様様。
![day10_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3978339/6fe2456d-3509-46ee-0df6-7ba1769ea3db.png)
Godot Engineで動かしたりもしている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3978339/a0f9e7eb-e427-eb34-b5e5-ece2b083344e.png)

素人が手動で作るとこんなクオリティですっていうことで。



(参考)
Blenderテクスチャ界の父(母？)
灰ならしさんの本についての紹介ページです。

https://hainarashi.hatenablog.com/entry/20221214/1671016036

(Blender4対応の最新版もあるらしいけど持っていない。)