[[開発ノウハウ集]] * <2014/02/13> matrix_worldの話 [#v4ef28e1] - obj.matrix_worldは、locationおよびrotationから自動的に計算される。 - ただしlocationやrotationを変更してからmatrix_worldが更新されるまでには''タイムラグがある''。 - bpy.context.scene.update() を呼ぶとすぐに再計算される。 - ''ただし、それでも非表示のレイヤに存在するオブジェクトのmatrix_worldは更新されないので注意!'' * <2014/01/09> modal operator使用時にキー入力がもたつく問題 [#scc864db] spbを起動するとconsoleやtext editorでキー入力がもたつく事がある(キーを押しても文字が入力されない事がある)。同じ文字を複数回打ったあとに別の文字を打った時に発生しやすい模様。 これはspb固有の問題ではなく、blenderのmodal operatorをtimerとして使う場合(modal関数がPASS_THROUGHを返すことになる)に必ず起きる。blender自体のバグなのかも。 - '''→ blenderのバグだった模様。開発版では修正された ''' -- https://developer.blender.org/rBdeab0d10402b59652ec5e19836856eb238af863e * <2014/12/27> bpyとマルチスレッド [#ab8ee7ac] バックグラウンドで回り続けるようなスレッドからbpyにアクセスすることは、サポート外の使用法であるらしい(pythonから作られたthreadであっても)。もし行った場合はblenderが落ちたりblender終了時に正常終了できなかったりする可能性がある。 - http://www.blender.org/documentation/blender_python_api_2_69_7/info_gotcha.html -- ''Strange errors using ‘threading’ module'' を参照のこと。 そのような目的にはmodal operatorを使うことが推奨されている。 * bpy.data.object の寿命,比較,Undo時の挙動 [#j9e562f1] obj = bpy.data.objects['Name'] 上記で取得できる obj の同一性を調べるには == を使うこと.isではダメ. ''ただし'' 同じオブジェクトから取得したobjであっても,==で同一になるとは限らない.==は bpy.data.objects['Name'].as_pointer() の同一性をチェックしてると思われるが,このポインタは(Blenderシーン上で同じオブジェクトであっても)必ずしも一定していない. 例えば Undo(C-z)時にはポインタが変わる(BlenderはUndo時にオブジェクトのポインタ群をまるごとPush/Popしてるからだと思われる). したがって''Undoの前後で同じオブジェクトから取得した bpy.object 同士は,==を使っても同一判定されない''. Blender Objectの名前は一意なので,名前を保持しておいていちいちbpy.data.objectsから引いたほうがいいのかも. ~ なお,対応するオブジェクトをDeleteした後に obj にアクセスするとBlenderが落ちるので注意.~ Undo(C-z)を行なってobjのポインタが無効になった後でも同様に落ちるので気をつけること. * Addメニューに独自の拡張を加える [#z743503e] INFO_MT_addクラスを上書きすればよい. ただ,コードをコピペするとblenderが更新されても変わらなくなってしまう(古いコードで上書きしてしまうことになるので). できれば上書き前の関数を退避しておく形をとりたい. import bl_ui.space_info from bpy.types import Menu info_mt_add_draw = bl_ui.space_info.INFO_MT_add.draw # 上書き前の関数を退避 class INFO_MT_add(Menu): bl_label = "Add" def draw(self, context): info_mt_add_draw(self, context) # 上書き前の関数をまず実行 layout = self.layout layout.separator() # ここから独自拡張 layout.menu("INFO_MT_spr_add", icon='OUTLINER_OB_MESH') class INFO_MT_spr_add(Menu): bl_idname = "INFO_MT_spr_add" bl_label = "Springhead" def draw(self, context): layout = self.layout layout.operator_context = 'EXEC_REGION_WIN' layout.operator("spr.add_solid_box", icon='MESH_CUBE', text="Solid Box") * シーンに変更があったことを検出する [#k9a44588] object.is_updated は scene_update_pre / scene_update_post の中でしか有効でないようなので注意(それ以外のタイミングで参照してもFalseである). import bpy def scene_update(context): if bpy.data.objects.is_updated: print("One or more objects were updated!") for ob in bpy.data.objects: if ob.is_updated: print("=>", ob.name) bpy.app.handlers.scene_update_post.append(scene_update) (from http://wiki.blender.org/index.php/Dev:2.6/Source/Render/UpdateAPI ) * プロパティの作成と編集 [#p3a212e8] - プロパティ -- http://www.blender.org/documentation/blender_python_api_2_57_release/bpy.props.html -- http://www.blender.org/documentation/blender_python_api_2_70a_release/bpy.props.html - レイアウト -- http://www.blender.org/documentation/blender_python_api_2_57_release/bpy.types.UILayout.html -- http://www.blender.org/documentation/blender_python_api_2_70a_release/bpy.types.UILayout.html - Panelのdraw中ではプロパティを変更することができない.