画像の更新のために手動で更新をするのも煩わしいので
データの更新を検出して再読み込みをさせるアドオンを作成しました
その使用法とPhotoshopの便利な機能「画像アセット」について解説したいと思います
Photoshopの「画像アセット」
Photoshopにはレイヤにつけた名前に従って自動的に画像を書き出す機能があります。例えば グループレイヤに01.png 02.pngと名前をつけておくと
PSDの保存されている場所にPSDの名前に-assetsとついたフォルダが作られて
それぞれのグループを統合した画像で 01.png 02.png といった感じに出力されます
PSDのレイヤを編集するとその都度変更が自動出力されます
Web用の機能なので 3Dのテクスチャ用で出力できる種類はPNGのみですが
自動的に出力されるのは便利かと思います。
ファイルの名前の付け方によっては 画像を縮小したりもできます
Blenderの自動更新アドオン
さて、冒頭に話をした自動更新アドオンです。Blenderに読み込んでいる画像ファイルの更新を検出して再読み込みします
他にも同様な機能なものはあるようですが、ミニマムな構成にしてみました。
長いデータなので boothにダウンロード用ファイルを登録しました
bl_info = { "name" : "AutoReloadImage", "author" : "Yukimituki", "description" : "", "blender" : (2, 80, 0), "version" : (0, 0, 1), "location" : "", "warning" : "", "category" : "Image" } import bpy import os from bpy.types import ( PropertyGroup, AddonPreferences, ) class IMAGE_PT_AutoReload(bpy.types.Panel): bl_idname = "autoreload.panel" bl_label = "Reload Images" bl_space_type = "IMAGE_EDITOR" bl_region_type = "UI" bl_category = "Image" # 描画の定義 def draw(self, context): layout = self.layout row = layout.row() row.prop(context.scene, "imageassets_autoreload_time") row = layout.row() row.prop(context.scene, "imageassets_autoreload_active") row = layout.row() row.operator("image.reloadbutton") class ModalTimerOperator(bpy.types.Operator): """Operator which runs its self from a timer""" bl_idname = "wm.modal_timer_operator" bl_label = "Modal Timer Operator" _timer = None asset_dic = {} def __init__(self): asset_dic = self.asset_dic self.asset_dic = set_asset_dic(asset_dic) def modal(self, context, event): #check ImageEditor panel value if not context.scene.imageassets_autoreload_active: context.window_manager.event_timer_remove(self._timer) return {'FINISHED'} if event.type == 'TIMER': asset_dic = self.asset_dic reload_assets(asset_dic) self.asset_dic = set_asset_dic(asset_dic) return {'PASS_THROUGH'} def execute(self, context): wm = context.window_manager reload_cycle = context.scene.imageassets_autoreload_time self._timer = wm.event_timer_add(reload_cycle, window=context.window) wm.modal_handler_add(self) self.asset_dic = set_asset_dic({}) return {'RUNNING_MODAL'} def cancel(self, context): wm = context.window_manager wm.event_timer_remove(self._timer) #手動リロード処理 class OBJECT_OT_reloadbutton(bpy.types.Operator): bl_idname = "image.reloadbutton" bl_label = "Manually update" def execute(self, context): for img in bpy.data.images: #only single image file if img.type != 'IMAGE': continue img.reload() set_asset_dic({}) return {'FINISHED'} #自動リロード処理 def reload_assets(asset_dic): for image_obj in asset_dic: try: #only single image file if image_obj.type != 'IMAGE': continue image_path = bpy.path.abspath(image_obj.filepath) #チェック時にファイル保存が重なると一時的にファイルが認識できないため if os.path.lexists(image_path) == False: continue #更新時刻の取得 get modefied time mod_time = os.stat(image_path).st_mtime_ns if mod_time != asset_dic[image_obj]: image_obj.reload() asset_dic[image_obj] = mod_time print("reload:%s" % image_obj.name ) except:pass #ファイル内のイメージデータブロックの情報を記録 def set_asset_dic(asset_dic): if len(bpy.data.images) == len(asset_dic): return(asset_dic) for img in bpy.data.images: if img.type != 'IMAGE': image_path = bpy.path.abspath(img.filepath) #get modefied time as nanosec(int) asset_dic[img] = os.stat(image_path).st_mtime_ns else:asset_dic[img] = 0 return(asset_dic) def update_bool_func(self, context): if context.scene.imageassets_autoreload_active: bpy.ops.wm.modal_timer_operator() classes = ( ModalTimerOperator, IMAGE_PT_AutoReload, OBJECT_OT_reloadbutton ) #アドオンとして機能させるための情報の登録 def register(): #properties Scene = bpy.types.Scene props = bpy.props Scene.imageassets_autoreload_active = props.BoolProperty(name="Auto Reload", description="", default=False, update = update_bool_func) Scene.imageassets_autoreload_time = props.IntProperty(name="Reload Cycle",description="", default=10 ) #classes for cls in classes: bpy.utils.register_class(cls) #アドオンを停止させた時に情報の削除 def unregister(): #properties Scene = bpy.types.Scene props = bpy.props del Scene.imageassets_autoreload_active del Scene.imageassets_autoreload_time #classes for cls in classes: bpy.utils.unregister_class(cls) if __name__ == "__main__": register()
(Blender2.8用ですが5行目の "blender" : (2, 80, 0),の数字を(2,29,0)に書き換えることで2.79でも動作します )
アドオンとして読み込むと
画像エディッタやUVエディッタの画像タブに「Reload Images」の項目が出ます
このコメントはブログの管理者によって削除されました。
返信削除