BlenderのAdd-on開発環境をdevcontainerで作る
概要
Blender の Add-on 開発環境を、 VSCode の devcontainer 機能で作ったら結構いい感じだったので紹介する。
ちなみにこの記事に記載するコードは、私が作った Thanos[1] という Add-on から抜粋している。もし全体を見たい場合は以下からどうぞ。
書くこと
- Blender Add-on 開発に向けた devcontainer の設定方法
- 併せて設定しておくと便利な Tips
書かないこと
- devcontainer 機能自体の説明(代わりに公式のチュートリアルとかを見てね)
- Blender Add-on 自体の作り方(Blender Python 完全ガイドが詳しくておすすめかも)
結論
.devcontainer/devcontainer.json
に以下を記載して、devcontainer を起動すると大体いい感じになるはず。 src/
直下に Add-on の __init__.py
がある想定。
{
"name": "blender",
"workspaceFolder": "/config/${localWorkspaceFolderBasename}",
"workspaceMount": "source=${localWorkspaceFolder},target=/config/${localWorkspaceFolderBasename},type=bind",
"remoteUser": "kasm-user", // created by linuxserver/blender
"image": "lscr.io/linuxserver/blender:4.0.2-ls99",
"overrideCommand": false,
"forwardPorts": [
3000,
3001
],
"containerEnv": {
// specify the same value as your local environement
"PUID": "1000", // id -u
"PGID": "1000", // id -g
"TZ": "Etc/UTC" // cat /etc/timezone
},
"features": {
"ghcr.io/devcontainers/features/git:1": {}
},
"postCreateCommand": "/blender/4.0/python/bin/python3.10 -m pip install fake-bpy-module-4.0 && sudo ln -s $(pwd)/src /blender/4.0/scripts/addons/myaddon",
"customizations": {
"vscode": {
"extensions": [
"ms-python.python",
"ms-python.black-formatter"
],
"settings": {
"python.defaultInterpreterPath": "/blender/4.0/python/bin/python3.10"
}
}
}
}
以下ではこだわりポイントを抜粋して補足する。
linuxserver/blender
{
"image": "lscr.io/linuxserver/blender:4.0.2-ls99"
}
これが Blender を含む Docker イメージ。以下の二択で迷ったが、 v4 以降もサポートしていそうな前者を採用した。
devcontainer として起動した上で localhost:3000
をブラウザで開くと Blender を操作することができる。VSCode 上で Add-on をコーディングしながら、たまにブラウザ上の Blender で動作確認するのが基本的な開発サイクルになる。
ちなみにそもそも Docker を利用しようと思った動機は、気軽に壊せる Blender 環境がほしかったから。そういう意味では portable 版の Blender を使うという方向性も考えられた(スクショの .zip
のやつ)。結局 Docker の方が便利という結論に至ったけれど。
補完の設定
{
"postCreateCommand": "/blender/4.0/python/bin/python3.10 -m pip install fake-bpy-module-4.0 && ... 略 ...",
"customizations": {
"vscode": {
"extensions": [
"ms-python.python"
],
"settings": {
"python.defaultInterpreterPath": "/blender/4.0/python/bin/python3.10"
}
}
}
}
補完が効くかどうかって開発効率に大きく影響するので、上記でその設定をしている。
ms-python.python は VSCode で Python を書く人ならみんな使っている拡張機能だと思うので説明は省略。
fake-bpy-module というのが、Blender API まわりの補完を可能にする優れもの。
Add-on の install
{
"postCreateCommand": " ... 略 ... && sudo ln -s $(pwd)/src /blender/4.0/scripts/addons/myaddon",
}
Blender が Add-on を格納するディレクトリに、開発中の Add-on に向けたシンボリックリンクを張っている。これによって、開発中の Add-on が install された扱いになって便利。
注意点は、 Add-on の有効化まではされていないので preferences から手動でチェックする必要があること。
また、コードの変更を反映させたいときは Menu Search (F3
) から reload script を忘れずに行うこと[2]。
その他 Tips
以下では devcontainer.json
以外で設定しておくと便利なものを紹介する。
テストの設定
テスト用の Python ファイルを用意して .vscode/tasks.json
に以下を記載しておくと便利。
{
"version": "2.0.0",
"tasks": [
{
"label": "e2e test",
"type": "shell",
"command": "blender",
"args": [
"--background",
"--python",
"./tests/e2e.py"
],
"group": "test",
"presentation": {
"reveal": "always",
"panel": "new"
}
}
]
}
これは Blender に ./tests/e2e.py
を実行させるタスクの定義。タスクを定義することによって、 VSCode のコマンドパレットから実行できるようになる。
e2e.py
には、開発した Add-on のオペレータを実行して想定通りの結果か確認する、という処理を書いておく想定。 Thanos の場合は以下のような内容。
e2e.py
import bpy
import bmesh
import addon_utils
# 準備
addon_utils.enable("myaddon") # Add-on有効化
bpy.ops.mesh.primitive_cube_add() # テスト対象の立方体を追加
bpy.ops.object.mode_set(mode="EDIT") # 編集モードへ
bpy.context.scene.tool_settings.mesh_select_mode = [True, False, False] # 頂点選択モード
bpy.ops.mesh.select_all(action="SELECT") # 全選択
# オペレータ実行
bpy.ops.thanos.snap_fingers()
# 結果を記録
me = bpy.context.object.data
bm = bmesh.from_edit_mesh(me)
expected = 4 # 頂点は4個(半分)になるのが期待値
actual = len(bm.verts)
# 後始末
bm.free()
bpy.ops.object.mode_set(mode="OBJECT") # オブジェクトモードへ戻る
bpy.ops.object.delete() # テスト対象の立方体を削除
# アサーション
if actual != expected:
raise Exception(f"expected {expected}, actual {actual}")
タスクを定義するのは必須ではなくて、ターミナルで blender --background --python ./tests/e2e.py
を実行しても構わない。もしくはスクショのように Blender でファイルを開いて実行することもできる。
ローカルでのテストに加えて、リモートに push する度に GitHub Actions などでもテストできるとよい。以下はその例。
on: [push]
jobs:
test:
runs-on: ubuntu-latest
container:
image: lscr.io/linuxserver/blender:4.0.2-ls99
steps:
- uses: actions/checkout@v4
- run: ln -s $(pwd)/src /blender/4.0/scripts/addons/myaddon
- run: blender --background --python-exit-code 1 --python tests/e2e.py
zip にまとめる設定
Add-on が複数ファイルからなる場合は、 zip にしないと Blender から install できない(devcontainer の外で動作確認したいときや配布したいときに困る)。 GitHub Actions で以下を設定しておくと push の度に zip が artifact として保存されて便利。
on: [push]
jobs:
artifact:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Blender から install しやすいようにディレクトリの深さを調整
# src/ の直下に __init__.py がある想定
- run: |
mkdir -p artifact
mv src artifact/thanos
- uses: actions/upload-artifact@v4
with:
name: thanos
path: artifact/
最後に
個人的には100点満点中、70点くらいの開発環境ができたなという印象。少し不満が残ったのは以下のような点。
- Docker で起動した Blender の動作が若干もっさりしていたこと(動作確認程度なら問題ないが、がっつりモデリングするにはちょっと厳しそう)
- debug 機能が充実していないこと(Blender Development という VSCode 拡張機能を使う場合と比べて)
とはいえ devcontainer は便利なので、しばらく Add-on の開発はこの構成でやってみようかなという気持ち。
Discussion