MRが楽しい

MRやVRについて学習したことを書き残す

BlenderのPythonスクリプト実行で別ファイルの関数を利用する

本日は Blender の技術調査枠です。
Blender で別ファイルにまとめた自作関数を利用する方法をまとめます。

Pythonでの参照方法

前回の記事で Python スクリプトで同ディレクトリ、または、別ディレクトリの Python スクリプトを参照する方法をまとめました。
bluebirdofoz.hatenablog.com

しかし Blenderスクリプト実行でこの方法をそのまま用いると、他のファイルの参照に失敗します。
f:id:bluebirdofoz:20190323142825j:plain

__file__ で実行中の Ptyhon スクリプトのファイルパスを取得してみます。
すると、読み込んだ位置とは全く異なるパスで実行されていることが分かります。
f:id:bluebirdofoz:20190323142835j:plain

解決方法

解決方法の1つとして Ptyhon スクリプトを読み込んだディレクトリをシステムパスに加える方法があります。
この方法ならば Python スクリプトにコードを加えるだけで対処でき、Blenderディレクトリパスを意識する必要がありません。

Python スクリプトの読み込み元のファイルパスは Blender が所持しています。
bpy.data.texts の情報を取得して読み込み元のディレクトリを取得します。

コードを以下のように修正しました。
・Main.py

## Blenderで実行するpythonスクリプト
# システムアクセス用ライブラリのインポート
import sys, os
# blenderライブラリのインポート
import bpy

## エディタ実行時に追加ライブラリを参照するため
## ファイル読み込みディレクトリをシステムパスに追加する
# 自身のファイル名を取得
script_filename = os.path.basename(__file__)
# Blenderの読み込みファイルリストからファイルパスを取得
script_filepath = bpy.data.texts[script_filename].filepath
# 読み込み元のディレクトリパスを取得
script_dirpath = os.path.dirname(script_filepath)
# 読み込み元のディレクトリパスをシステムパスに追加
sys.path += [script_dirpath]

# 追加ライブラリのインポート
from BlenderLib import addmesh

# 実行指定で呼び出されているかチェック
if __name__ == "__main__":
    addmesh.make_cube_mesh()

呼び出し先の関数は以下のような Cube を作成するスクリプトとしました。
・addmesh.py

# bpyインポート
import bpy
# math インポート
import math

# メッシュオブジェクトの作成
# 引数
# 戻り値
def make_cube_mesh():
  # Cubeオブジェクトを作成する
  bpy.ops.mesh.primitive_cube_add(\
    # 配置場所の指定
    location=( 0, 0, 3 ),\
    # 回転の指定
    rotation=( math.pi/3, 0, 0 ),\
  )
  # 作成したオブジェクトの参照を取得する
  ob = bpy.context.scene.objects.active
  # 名前を変更する
  ob.name='MakeCube'
  # スケールを変更する
  ob.scale=( 1, 1, 1 )
  # 選択状態を解除する
  ob.select=False
  return

Main.py のディレクトリに BlenderLib ディレクトリを作成し、BlenderLib 配下に addmesh.py をコピーします。
f:id:bluebirdofoz:20190323144805j:plain

Main.py を Blender で読み込んで[スクリプト実行]を行うと……。
f:id:bluebirdofoz:20190323142852j:plain
スクリプトが実行されました。成功です。
Blenderテキストエディタ―から Python スクリプトを利用する際は覚えておくと便利です。