背景
Blender の plugin(addon)を作りたいが, pure Python だと遅くなるのが見込めるため C++ native module を作りたい.
構成
Blender 2.93 LTS(Python 3.9)を想定します.
- pybind11(最新版)
- Python interpreter, library は Blender のを使います
- Python header files は Python ソースコードから取得します.
にあるように, Blender のパッケージには native module ビルドに必要な Python ヘッダファイルがありません.
Linux であれば apt とかで入れるのも手ですが, Windows, Linux, macOS でのビルドを考える場合, Blender と同じバージョンのソースコードを拾ってきて, 自前 repo にヘッダファイルだけ追加して対応するのが面倒が無くてよいでしょう.
(pyconfig.h だけ Blender パッケージのを使う)
CMakeLists.txt
add_subdirectory(${PROJECT_SOURCE_DIR}/external/pybind11 pybind11_build)
set(SOURCES binding.cc)
pybind11_add_module(mymodule ${SOURCES})
# For Python.h header files.
# Assume Blender 2.93 LTS(Python 3.9)
target_include_directories(mymodule PRIVATE ${PROJECT_SOURCE_DIR}/python3.9/Include)
という感じで, target_include_directories
で Python.h
へのヘッダパスを追加してあげればいけます!
cmake bootstrap
# Set path to blender's python
PYTHON_EXE=$HOME/local/blender-2.93.1-linux-x64/2.93/python/bin/python3.9
curdir=`pwd`
builddir=${curdir}/build
rm -rf ${builddir}
mkdir ${builddir}
cd ${builddir} && CXX=clang++ CC=clang cmake \
-DPYTHON_EXECUTABLE=${PYTHON_EXE}
..
のように PYTHON_EXECUTABLE
指定で cmake 処理します.
アドイン(module)の置き場所
USER に入れるのが楽でしょうか.
Linux だと
~/.config/blender/2.93/scripts/addons/modules
になります.
探索パスは Blender Python コンソールで
>>> import sys
>>> sys.path
で確認できます.
注意点として, USER
フォルダの場合, scripts/addons/modules
はデフォルトでは作られないため, 自前でフォルダを作る必要があります. またフォルダを作った場合 Blender を再起動しないと module ファイルを見つけてくれません.
あとは Blender の Python から
>>> import mymodule
などとすればインポートできるはずです!
C++ から bpy など Blender API へのアクセス
ありがとうございます.
最近の Blender は numpy(もどき?)が標準でついたので, たとえばメッシュデータは numpy 配列にして一括アクセス... みたいにすると, C++ で頑張らずとも Python レイヤーでも高速に処理できるやも?(要検証)