本日はBlender枠です。
今年はBlenderのアドオン開発も進めていましたが、アドオンを使用する際にPyhonの外部パッケージを使用したい場合はBlenderの環境にインストールを行う必要があります。
今回はBlenderのアドオンをインストールする際にチェックしてパッケージが存在しない場合自動でインストールするプログラムを書きます。
〇スクリプトの作成
このスクリプトをinit.pyとします。この名前はBlenderアドオンにおいてアドオン実行時のエントリーポイントとして使用されます。
つまりアドオンをインストールした際にはこの名前のPythonが実行されるということです。
import bpy
import os
import re
import subprocess
bl_info = {
"name": "HarmonyKeys",
"blender": (4, 0, 0), #Blender4.0での運用を想定
"category": "Animation",
}
def register():
result = check_library()
if result:
print("music21 is installed")
else:
install_dependency()
def unregister():
print("Goodbye World")
def check_library():
try:
import music21#今回はmusic21のライブラリで実験
return True
except ImportError:
return False
def install_dependency():
blender_exec_path = bpy.app.binary_path
blender_version = bpy.app.version
major_version = str(blender_version[0]) # 整数を文字列に変換
minor_version = str(blender_version[1]) # 整数を文字列に変換
blender_install_dir = os.path.dirname(blender_exec_path)
python_path = blender_install_dir + '\\' + major_version + '.' + minor_version + '\\python'
current_script_path = os.path.realpath(__file__)
current_script_dir = os.path.dirname(current_script_path)
bat_file_path = os.path.join(current_script_dir, 'dependency.bat')
with open(bat_file_path, 'r') as f:
content = f.read()
print("読み込んだテキスト: ", content)#Debug
# <>で囲まれた部分を見つける
pattern = r'<(.*?)>'
matches = re.findall(pattern, content)
# 見つけた部分を書き換える
new_content = content
for match in matches:
new_content = new_content.replace('<' + match + '>', python_path)
with open(bat_file_path, 'w') as f:
f.write(new_content)
print("書き込んだテキスト: ", new_content)
subprocess.call(bat_file_path)
init.pyと同階層にbatファイルを作成します。 今回はdependency.batとしています。この名前はinit.py内のbatファイル名と一致させます。

dependency.batの中身はこちらです。
@echo off set PYTHON_PATH=<blender_python_path.txt> pip install music21
アドオンとして提供する場合ユーザーのlocal環境によってパスが変わるため、ここではinit.pyと同階層に配置しているbatファイルを取得しています。
方法としてはinit.py実行時に自身のパスを取得して、同階層にアプロ―ローチするという形です。 この方法であればPythonスクリプトとバッチファイルが同階層にあればどのような環境下でもbatファイルのパスを取得できます。
〇アドオンとして登録
アドオンとして登録するためにinit.pyとバッチファイルを含んだフォルダを.zip化します。
これをBlender側でアドオンとしてインストールすることでinit.pyの処理が実行されます。
本日は以上です。