- 2019/8 Blender-2.8はEEVEEがデフォルトなので
bpy.ops.render.render()
が落ちる件 - 2019/7 既存の記事とタイトルが被っていたので変更
- 2019/7 リライト
bpy.pyd
(GUIの無いpythonモジュールとしてのblender)のビルドとインストール方法。
環境
- Windows-10(64bit)
- Python-3.7(64bit)
- Blender-2.80
準備
- visualstudio2019
- git
- svn(scoop install sliksvn など)
普通にBlenderをビルドする
blenderビルドの細かい手順については
を参照してください。
モジュールとしてBlenderをビルドする
上記の記事のところまでできたとして、そこから変更する部分を説明します。
CMakeでオプションを以下のように変更する
- WITH_PYTHON_INSTALL=OFF
- WITH_PYTHON_MODULE=ON
ビルドがうまくいかない原因になるライブラリを取り除きます
- WITH_AUDASPACE=OFF
- WITH_OPENCOLLADA=OFF (リンクエラー xml.lib dllmain libcmt.lib)
変更して、configure して generateし、cmakeの install
ターゲットを実行する。
buildだけだと(dllのコピーと 2.80
フォルダの生成が為されません)
ビルドできた bpy.pyd
と必要なファイルをPython3に対してインストールする。
下記のファイルをビルドフォルダから python37 フォルダにコピーします。
- PYTHON_DIR/lib/site-packages
- blender.pth
- PYTHON_DIR/lib/site-packages/blender
- bpy.pyd(本体)
- dll
- pdb(デバッグ用)
- PYTHON_DIR/2.80
- (blenderの実行時に使われるスクリプトなど)
手順を python スクリプトにしました。
import os
import pathlib
import glob
import shutil
PY_DIR = pathlib.Path('C:/Python37')
BL_DIR = PY_DIR / 'Lib/site-packages/blender'
if __name__ == '__main__':
os.chdir('blender_build/bin/Release') # install.py実行パスからの相対パス
#os.chdir('blender_build/bin/RelWithDebInfo') # 実行パスからの相対パス
with (PY_DIR / 'Lib/site-packages/blender.pth').open('w') as w:
w.write("blender")
BL_DIR.mkdir(parents=True, exist_ok=True)
shutil.copy('bpy.pyd', BL_DIR)
for f in glob.glob('*.dll'):
print(f'{f} => {BL_DIR / f}')
shutil.copy(f, BL_DIR / f)
for f in glob.glob('*.pdb'):
print(f'{f} => {BL_DIR / f}')
shutil.copy(f, BL_DIR / f)
python37 = BL_DIR / 'python37.dll'
if python37.exists():
python37.unlink()
dst = PY_DIR / '2.80'
if dst.exists():
print(f'remove {dst}')
shutil.rmtree(dst)
print(f'copy {dst}')
shutil.copytree('2.80', dst)
実行する
import bpy
print(bpy)
# <module 'bpy' from 'PYTHON_DIR\\lib\\site-packages\\blender\\bpy.pyd'>
これがPythonで実行できれば動くと思う
終了時に、
Error: Not freed memory blocks: 8, total unfreed memory 0.010223 MB
が出るけどこれは気にしなくてよいのではないか。
使い方
主に、バッチ実行か addon 開発用途になると思う。
レンダリングする
CYCLES にする。
import bpy
bpy.context.scene.render.engine = 'CYCLES' # デフォルトがEEVEEでOpenGLが無いので落ちる
bpy.ops.render.render()
bpy.data.images['Render Result'].save_render(filepath='image.png')
blendファイルを開いてシーンにアクセスする
import bpy
import pathlib
here = pathlib.Path(__file__).absolute().parent
monkey = here / 'monkey.blend'
# open
bpy.ops.wm.open_mainfile(filepath=str(monkey))
# object
for o in bpy.context.scene.objects:
print(o)
<bpy_struct, Object("Suzanne")>
blendファイルを開いてシーンにアクセスできた。
memo
# contextからobjectを得る
o = bpy.context.scene.objects[0]:
# objectからデータブロックを得る
data= o.data
print(isinstance(data, bpy.types.Mesh))
VSCode でインテリセンスが効くようにする
blender-2.80 向けに生成してみる。
さくっとエラー回避。
--- a/python_api/pypredef_gen.py
+++ b/python_api/pypredef_gen.py
@@ -999,7 +999,7 @@ def bpy2predef(BASEPATH, title):
structs, funcs, ops, props = rna_info.BuildRNAInfo()
#open the file:
filepath = os.path.join(BASEPATH, "bpy.py")
- file = open(filepath, "w")
+ file = open(filepath, "w", encoding='utf-8')
fw = file.write
#Start the file:
definition = doc2definition(title,"") #skip the leading spaces at the first line...
@@ -1093,9 +1093,9 @@ def rna2predef(BASEPATH):
import bgl as module
pymodule2predef(BASEPATH, "bgl", module, "Open GL functions (bgl)")
- if "aud" in INCLUDE_MODULES:
- import aud as module
- pymodule2predef(BASEPATH, "aud", module, "Audio System (aud)")
+ # if "aud" in INCLUDE_MODULES:
+ # import aud as module
+ # pymodule2predef(BASEPATH, "aud", module, "Audio System (aud)")
if "bmesh" in INCLUDE_MODULES:
import bmesh as module
出てきたフォルダをvscodeのユーザー設定に追加。
"python.autoComplete.extraPaths": ["path_to_pypredef"]
関数の引数に型注釈を付けて blender の型のインテリセンスが出るようになった。
Debugする(C++の方を)
- slnをRelWithDebugInfoでビルドする(Debugだと Python37_d の方にリンクされてやりづらい)
- インストールする
- 適当なプロジェクトをデバッグ設定して
F5
する
作業ディレクトリは hello.py を配置したフォルダ。
// line:610
GHOST_TSuccess GHOST_ActivateOpenGLContext(GHOST_ContextHandle contexthandle)
{
GHOST_IContext *context = (GHOST_IContext *)contexthandle; // これが nullptr
return context->activateDrawingContext();
}
わかるときもある。