[[開発ノウハウ集]]

* 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 )