Blender で Python スクリプト：オブジェクトを操作する

# Blender で Python スクリプト：オブジェクトを操作する

こんにちは、@studio_meowtoon です。今回は、Windows 11 環境の Blender のオブジェクトを、VS Code に記述した Python スクリプトから操作する方法を紹介します。  
![python_in_blender.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206449/f8243cd9-1431-3429-d4cd-a5f353c7013a.png)

## Blender と VS Code のセットアップ

Blender をインストールする手順と VS Code からデバッグする方法は、以前のこちらの記事を参照して頂けます。

https://qiita.com/studio_meowtoon/items/2c6c7c7bc9931b537c78

:::note info
Blender には Python スクリプトを記述するテキストエディタの機能を備えていますが、**VS Code と連携**するとさらに快適にコードが記述できます😋
:::

## Blender と VS Code の連携について

Blender 側の記述

```py:Blender のテキストエディタ
import importlib
import debug
importlib.reload(debug)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206449/e46b7d9f-6c6a-bfe6-ba60-18e014d0ad7f.png)

VS Code 側の記述
※ debug.py というファイル名は任意です。※モジュール名になります

```py:VS Code のテキストエディタ (debug.py)
import ptvsd
ptvsd.enable_attach()
ptvsd.wait_for_attach()

# ここに確認したいコードを記述します。

hoge = "hoge" # 例) ※デバッグ ブレークに使います。
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206449/2c422666-8947-2cce-702a-584d34280a29.png)

```mermaid
sequenceDiagram
    participant Blender
    participant VS Code
    Blender ->> VS Code: import debug.py
    VS Code -->> Blender:　attach by port 5678
```

:::note warn
Blender から debug.py ファイル(モジュール)を import します。debug.py では 5678 ポートで実行中の **Blender プロセスにアタッチ**します。
:::

## オブジェクトの情報を表示する

Blender オブジェクトの一覧を表示してみます。

```py:VS Code (debug.py の一部)
import bpy

for ob in bpy.data.objects:
    print(ob.name)
```

出力結果

```sh:VS Code デバッグコンソール
Camera
Cube
Light
```

カメラ、キューブ、ライトオブジェクトが存在することが分かります。  

次に、実体があるオブジェクトを一覧表示してみます。
※タイプが MESH のものを指定します。

```py:VS Code (debug.py の一部)
import bpy

for ob in bpy.data.objects:
    if ob.type == "MESH":
        print(ob.name)
```

出力結果

```sh:VS Code デバッグコンソール
Cube
```

メッシュオブジェクトは Cube だけだと分かります。

Blender 画面の一覧を表示してみます。

```py:VS Code (debug.py の一部)
import bpy

for ob in bpy.data.screens:
    print(ob.name)
```

出力結果

```sh:VS Code デバッグコンソール
Animation
Compositing
Layout
Modeling
Rendering
Scripting
Sculpting
Shading
Texture Paint
UV Editing
```

画面の一覧が表示されます。
※設定状況によって内容は異なります。

:::note info
ここまでの手順で、Blender プロセスに VS Code からアタッチし、オブジェクトの情報を取得、表示することができました😋
:::

## オブジェクトを操作する

VS Code から Blender の Cube を操作してみます。

:::note warn
この先、VS Code でのデバッグ動作が特に必要でない場合には、ptvsd ライブラリのデバッグアタッチを無効にすることもできます。具体的には以下のようにコードをコメントアウトします。
:::

```py::VS Code (debug.py の一部)
# import bpy
# import ptvsd
# ptvsd.enable_attach()
# ptvsd.wait_for_attach()
```

Blender でのオブジェクト表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206449/270c52f8-c5cf-e5bd-d2e0-af7198ade881.png)
Cube を取得して移動します。

```py:VS Code (debug.py の一部)
import bpy

ob = bpy.data.objects['Cube']
ob.location = (3, -2, 0)
```

Blender でのオブジェクト表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206449/08eb1775-9f49-8700-5f10-bb6c20a9fe7f.png)
Blender の Cube オブジェクトが移動しました。

Cube を回転してみます。

```py:VS Code (debug.py の一部)
import math
import bpy

ob = bpy.data.objects['Cube']
ob.rotation_euler = (math.radians(45.0), 0, 0)
```

Blender でのオブジェクト表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206449/6d78d105-72c3-20ec-c279-0f6ba6f2e421.png)
Blender の Cube オブジェクトが回転しました。

Cube を拡縮してみます。

```py:VS Code (debug.py の一部)
import bpy

ob = bpy.data.objects['Cube']
ob.scale = (2.0, 0.5, 3.0)
```

Blender でのオブジェクト表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206449/a0f1343f-83ff-6588-18f1-78d4881bd565.png)
Blender の Cube オブジェクトが拡縮されました。

Cube の色を変えてみます。

```py:VS Code (debug.py の一部)
import bpy

ob = bpy.data.objects['Cube']
ob.data.materials[0].node_tree.nodes["Principled BSDF"].inputs[0].default_value = (0, 1, 0, 1)
```

Blender でのオブジェクト表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206449/bc66e3f8-59a0-e6ea-8d56-cb98c2e98165.png)
Blender の Cube オブジェクトの色が変わりました。

Cube を元に戻します。

```py:VS Code (debug.py の一部)
import math
import bpy

ob = bpy.data.objects['Cube']
ob.location = (0, 0, 0)
ob.rotation_euler = (0, 0, 0)
ob.scale = (1.0, 1.0, 1.0)
ob.data.materials[0].node_tree.nodes["Principled BSDF"].inputs[0].default_value = (1, 1, 1, 1)
```

Blender でのオブジェクト表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206449/989961fa-a80e-3aa6-ec3b-b730068df22c.png)
Blender の Cube オブジェクトが最初の状態に戻りました。

:::note info
ここまでの手順で、Blender のオブジェクトを VS Code に記述したコードから操作することができました😋
:::

## アニメーションを作成する

これまでに紹介した操作を応用して、Blender の Cube オブジェクトを VS Code の Python から操作して内容をキーフレームに登録し、アニメーションを作成します。

```py:VS Code (debug.py の一部)
import math
import bpy

ob = bpy.data.objects['Cube']
mat = ob.data.materials[0].node_tree.nodes["Principled BSDF"].inputs[0]

# 0f
ob.location = (0, 0, 0)
ob.rotation_euler = (0, 0, 0)
ob.scale = (1, 1, 1)
ob.keyframe_insert('location', frame = 0)
ob.keyframe_insert('rotation_euler', frame = 0)
ob.keyframe_insert('scale', frame = 0)
mat.default_value = (1, 1, 1, 1) # white
mat.keyframe_insert('default_value', frame = 0)

# 12f
ob.location = (2, -3, 4)
ob.rotation_euler = (math.radians(45.0), 0, 0)
ob.scale = (1.5, 2, 3)
ob.keyframe_insert('location', frame = 12)
ob.keyframe_insert('rotation_euler', frame = 12)
ob.keyframe_insert('scale', frame = 12)
mat.default_value = (0, 1, 0, 1) # green
mat.keyframe_insert('default_value', frame = 12)

# 24f
ob.location = (-2, 2, -1)
ob.rotation_euler = (0, math.radians(45.0), 0)
ob.scale = (0.75, 1, 0.5)
ob.keyframe_insert('location', frame = 24)
ob.keyframe_insert('rotation_euler', frame = 24)
ob.keyframe_insert('scale', frame = 24)
mat.default_value = (1, 0, 0, 1) # red
mat.keyframe_insert('default_value', frame = 24)

# 36f
ob.location = (3, -2, 3)
ob.rotation_euler = (0, 0, math.radians(45.0))
ob.scale = (3, -2, 5)
ob.keyframe_insert('location', frame = 36)
ob.keyframe_insert('rotation_euler', frame = 36)
ob.keyframe_insert('scale', frame = 36)
mat.default_value = (0, 0, 1, 1) # blue
mat.keyframe_insert('default_value', frame = 36)

# 48f
ob.location = (0, 0, 0)
ob.rotation_euler = (0, 0, 0)
ob.scale = (1, 1, 1)
ob.keyframe_insert('location', frame = 48)
ob.keyframe_insert('rotation_euler', frame = 48)
ob.keyframe_insert('scale', frame = 48)
mat.default_value = (1, 1, 1, 1)
mat.keyframe_insert('default_value', frame = 48)

# frame end
bpy.context.scene.frame_preview_end = 49
bpy.data.scenes['Scene'].frame_end = 49
```

VS Code から Python スクリプトでアニメーションを作成したのち、Blender の 「Animation」タブを選択し、下部ペインの再生ボタンからアニメーションを再生できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206449/46fc96c6-c60e-2012-67ad-56b8677f58db.png)
![cube_anime_001.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206449/8407eb96-0a37-1bf8-ee54-418372ccd100.gif)

:::note info
ここまでの手順で、Blender のオブジェクトを VS Code に記述したコードから操作してアニメーションを作成することができました😋
:::

## アニメーションをレンダリングする

さらに、アニメーションをレンダリングして動画ファイルとして出力してみます。

```py:VS Code (debug.py の一部)
import bpy

# render settings
bpy.context.scene.render.filepath = 'C:\\tmp\\cube_anime.mp4'
bpy.context.scene.render.image_settings.file_format = 'FFMPEG'
bpy.context.scene.render.ffmpeg.format = 'MPEG4'
bpy.context.scene.render.ffmpeg.codec = 'H264'

# animation settings
bpy.context.scene.frame_start = 0
bpy.context.scene.frame_end = 49

# render execution
bpy.ops.render.render(animation=True)
```

出力した動画
![cube_anime_002.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206449/801927b3-2668-f5c3-c48b-5dcd6bc8c8f8.gif)

:::note info
ここまでの手順で、VS Code に記述したコードから、Brender のアニメーションをレンダリングして動画ファイルとして出力する操作することができました😋
:::

## まとめ

+ VS Code で記述した Python コードから、Blender のオブジェクトを操作することができました。
+ また、スクリプトから Blender アニメーションをレンダリングして動画ファイルとして出力することができました。

どうでしたか？ Window 11 の VS Code で、Blender の Python スクリプトを開発する環境を手軽に構築することができます、ぜひお試しください。今後も Python / Blender の開発環境などを紹介していきますので、ぜひお楽しみにしてください。