本日は Blender2.8 の調査枠です。
Blender 2.8 の Python API ドキュメントを少しずつ読みつつ試していきます。
前回記事の続きです。
bluebirdofoz.hatenablog.com
Blender 2.8 Python API Documentation
以下のページを日本語訳しつつ実際に試して記事を進めていきます。
docs.blender.org
docs.blender.org
今日は「落とし穴」の「編集モード/メモリアクセス」と「配列の再割り当て」です。
編集モード/メモリアクセス
編集モードの切替 bpy.ops.object.mode_set(mode='EDIT')/ bpy.ops.object.mode_set(mode='OBJECT') はオブジェクトデータを再割り当てします。
メッシュ頂点/ポリゴン/ UV座標、アーマチュア骨、カーブポイントなどへの参照は、編集モードを切り替えた後にアクセスすることはできません。
再アクセスできるのはデータへの参照のみです。
以下の例はクラッシュします。
mesh = bpy.context.active_object.data polygons = mesh.polygons bpy.ops.object.mode_set(mode='EDIT') bpy.ops.object.mode_set(mode='OBJECT') # this will crash print(polygons)
編集モードを切り替えた後は、オブジェクトデータに再アクセスする必要があります。
以下の例は、上記のクラッシュを回避する方法です。
mesh = bpy.context.active_object.data polygons = mesh.polygons bpy.ops.object.mode_set(mode='EDIT') bpy.ops.object.mode_set(mode='OBJECT') # polygons have been re-allocated polygons = mesh.polygons print(polygons)
この種の問題は、オブジェクトデータを再割り当てする関数で発生する可能性があります。
編集モードを切り替えるときは最も一般的な例です。
配列の再割り当て
以下の操作を行うと、データを格納する配列が内部的に再割り当てされます。
・カーブに新しいポイントを追加する。
・メッシュに頂点/エッジ/ポリゴンを追加する。
bpy.ops.curve.primitive_bezier_curve_add() points = bpy.context.object.data.splines[0].bezier_points point = bpy.context.object.data.splines[0].bezier_points[0] bpy.context.object.data.splines[0].bezier_points.add(len(points)-1) # this will crash! point.co = 1.0, 2.0, 3.0
・成功例
これは以下の対策で回避できます。
・新しい変数を追加した後にポイント変数を再割り当てする。
・ポイント自体ではなくポイントにインデックスを設定する。
最良の方法は、問題を完全に回避するため、すべてのポイントを一度にカーブに追加することです。
これは配列の再割り当てを心配する必要がなく、より高速であることを意味します。
(追加されたすべてのポイントに配列全体を再割り当てするのは非効率的であるため)