本日は Blender2.8 の調査枠です。
Blender 2.8 の Python API ドキュメントを少しずつ読みつつ試していきます。
前回記事の続きです。
bluebirdofoz.hatenablog.com
Blender 2.8 Python API Documentation
以下のページを日本語訳しつつ実際に試して記事を進めていきます。
docs.blender.org
docs.blender.org
今日は「落とし穴」の「スレッド化モジュールを使用したエラー」です。
スレッド化モジュールを使用したエラー
BlenderでのPythonスレッドは、スクリプトが終了する前にスレッドが終了したときにのみ適切に機能します。
例えば threading.join() を使用した場合です。
Blenderでサポートされているスレッドの例を次に示します。
import threading import time def prod(): print(threading.current_thread().name, "Starting") # do something vaguely useful import bpy from mathutils import Vector from random import random prod_vec = Vector((random() - 0.5, random() - 0.5, random() - 0.5)) print("Prodding", prod_vec) bpy.data.objects["Cube"].location += prod_vec time.sleep(random() + 1.0) # finish print(threading.current_thread().name, "Exiting") threads = [threading.Thread(name="Prod %d" % i, target=prod) for i in range(10)] print("Starting threads...") for t in threads: t.start() print("Waiting for threads to finish...") for t in threads: t.join()
次は1秒間に何回も実行され、デフォルトのキューブを連続的に移動する(サポートされていない)タイマーの例です。
import threading import time def func(): print("Running...") import bpy bpy.data.objects['Cube'].location.x += 0.05 def my_timer(): from threading import Timer t = Timer(0.1, my_timer) t.start() func() my_timer()
スクリプトが終了するとスレッドを実行したままにする上記のユースケースは、しばらくは動作するように見えます。
しかし、Blender自身の描画コードでランダムなクラッシュまたはエラーを引き起こすことになります。
これまでのところ、BlenderのPython統合スレッドを安全にする作業は行われていません。
そのため、スレッドが適切にサポートされるまで、これを使用しないでください。