diff --git a/scripts-blender/addons/blender_kitsu/playblast/core.py b/scripts-blender/addons/blender_kitsu/playblast/core.py index 0da6342e..b0417491 100644 --- a/scripts-blender/addons/blender_kitsu/playblast/core.py +++ b/scripts-blender/addons/blender_kitsu/playblast/core.py @@ -3,9 +3,10 @@ from pathlib import Path import contextlib -from blender_kitsu import ( - prefs, -) +from blender_kitsu import prefs, cache +from blender_kitsu.logger import LoggerFactory + +logger = LoggerFactory.getLogger() @contextlib.contextmanager @@ -255,3 +256,49 @@ def playblast_user_shading_settings(self, context, file_path): # Make opengl render. bpy.ops.render.opengl(animation=True) return output_path + + +def set_frame_range_in(frame_in: int) -> dict: + shot = cache.shot_active_pull_update() + shot.data["3d_start"] = frame_in + shot.update() + return shot + + +def get_frame_range(): # TODO return type + active_shot = cache.shot_active_get() + if not active_shot: + return + + # Pull update for shot. + cache.shot_active_pull_update() + if "3d_start" not in active_shot.data: + logger.warning( + "Failed to check frame range. Shot %s missing '3d_start' attribute on server", + active_shot.name, + ) + return + frame_in = int(active_shot.data["3d_start"]) + frame_out = int(active_shot.data["3d_start"]) + int(active_shot.nb_frames) - 1 + return frame_in, frame_out + + +def check_frame_range(context) -> bool: + """ + Compare the current scene's frame range with that of the active shot on kitsu. + If there's a mismatch, set kitsu_error.frame_range -> True. This will enable + a warning in the Animation Tools Tab UI. + """ + try: + frame_in, frame_out = get_frame_range() + except TypeError: + return + scene = context.scene + + if frame_in == scene.frame_start and frame_out == scene.frame_end: + scene.kitsu_error.frame_range = False + return True + + scene.kitsu_error.frame_range = True + logger.warning("Current frame range is outdated!") + return False diff --git a/scripts-blender/addons/blender_kitsu/playblast/ops.py b/scripts-blender/addons/blender_kitsu/playblast/ops.py index a9ab3273..d9d00e8e 100644 --- a/scripts-blender/addons/blender_kitsu/playblast/ops.py +++ b/scripts-blender/addons/blender_kitsu/playblast/ops.py @@ -44,7 +44,7 @@ from blender_kitsu.playblast.core import ( playblast_with_shading_settings, playblast_user_shading_settings, ) -from blender_kitsu.playblast import opsdata +from blender_kitsu.playblast import opsdata, core logger = LoggerFactory.getLogger() @@ -348,6 +348,8 @@ class KITSU_OT_push_frame_range(bpy.types.Operator): bl_options = {"REGISTER", "UNDO"} bl_description = "Adjusts the start frame of animation file." + frame_start = None + @classmethod def poll(cls, context: bpy.types.Context) -> bool: return bool(prefs.session_auth(context) and cache.shot_active_get()) @@ -356,16 +358,22 @@ class KITSU_OT_push_frame_range(bpy.types.Operator): layout = self.layout col = layout.column(align=True) col.label(text="Set 3d_start using current scene frame start.") - col.label(text=f"New Frame Start: {context.scene.frame_start}", icon="ERROR") + col.label(text=f"New Frame Start: {self.frame_start}", icon="ERROR") def execute(self, context: bpy.types.Context) -> Set[str]: - shot = cache.shot_active_pull_update() - shot.data["3d_start"] = context.scene.frame_start - shot.update() - self.report({"INFO"}, f"Updated frame range offset {context.scene.frame_start}") + core.set_frame_range_in(self.frame_start) + self.report({"INFO"}, f"Updated frame range offset {self.frame_start}") return {"FINISHED"} def invoke(self, context: bpy.types.Context, event: bpy.types.Event) -> Set[str]: + self.frame_start = context.scene.frame_start + frame_in, _ = core.get_frame_range() + if frame_in == self.frame_start: + self.report( + {"INFO"}, + f"Sever's 'Frame In' already matches current Scene's 'Frame Start' {self.frame_start}", + ) + return {"FINISHED"} return context.window_manager.invoke_props_dialog(self, width=500) @@ -383,23 +391,10 @@ class KITSU_OT_pull_frame_range(bpy.types.Operator): return bool(prefs.session_auth(context) and cache.shot_active_get()) def execute(self, context: bpy.types.Context) -> Set[str]: - active_shot = cache.shot_active_pull_update() - - if "3d_start" not in active_shot.data: - self.report( - {"ERROR"}, - f"Failed to pull frame range. Shot {active_shot.name} missing '3d_start'.", - ) - return {"CANCELLED"} - - frame_in = int(active_shot.data["3d_start"]) - frame_out = int(active_shot.data["3d_start"]) + int(active_shot.nb_frames) - 1 + frame_in, frame_out = core.get_frame_range() # Check if current frame range matches the one for active shot. - if ( - frame_in == context.scene.frame_start - and frame_out == context.scene.frame_end - ): + if core.check_frame_range(context): self.report({"INFO"}, f"Frame range already up to date") return {"FINISHED"} @@ -407,14 +402,36 @@ class KITSU_OT_pull_frame_range(bpy.types.Operator): context.scene.frame_start = frame_in context.scene.frame_end = frame_out - # Update error prop. - context.scene.kitsu_error.frame_range = False - + if not core.check_frame_range(context): + self.report( + {"ERROR"}, f"Failed to update frame range to {frame_in} - {frame_out}" + ) + return {"CANCELLED"} # Log. self.report({"INFO"}, f"Updated frame range {frame_in} - {frame_out}") return {"FINISHED"} +class KITSU_OT_check_frame_range(bpy.types.Operator): + bl_idname = "kitsu.check_frame_range" + bl_label = "Check Frame Range" + bl_options = {"REGISTER", "UNDO"} + bl_description = ( + "Checks frame range of active shot from the server matches current file" + ) + + @classmethod + def poll(cls, context: bpy.types.Context) -> bool: + return bool(prefs.session_auth(context) and cache.shot_active_get()) + + def execute(self, context: bpy.types.Context) -> Set[str]: + if core.check_frame_range(context): + self.report({"INFO"}, f"Frame Range is accurate") + return {"FINISHED"} + self.report({"ERROR"}, f"Failed: Frame Range Check") + return {"CANCELLED"} + + class KITSU_OT_playblast_increment_playblast_version(bpy.types.Operator): bl_idname = "kitsu.anim_increment_playblast_version" bl_label = "Add Version Increment" @@ -443,37 +460,38 @@ def load_post_handler_init_version_model(dummy: Any) -> None: opsdata.init_playblast_file_model(bpy.context) +def draw_frame_range_warning(self, context): + active_shot = cache.shot_active_get() + layout = self.layout + layout.alert = True + layout.label( + text="Frame Range on server does not match the active shot. Please 'pull' the correct frame range from the server" + ) + layout.label( + text=f" File Frame Range: {context.scene.frame_start}-{context.scene.frame_end}" + ) + if active_shot: + layout.label( + text=f' Server Frame Range: {int(active_shot.data["3d_start"])}-{int(active_shot.data["3d_start"]) + int(active_shot.nb_frames) - 1}' + ) + else: + layout.label(text=f' Server Frame Range: not found') + + layout.operator("kitsu.pull_frame_range", icon='TRIA_DOWN') + + @persistent def load_post_handler_check_frame_range(dummy: Any) -> None: - """ - Compare the current scene's frame range with that of the active shot on kitsu. - If there's a mismatch, set kitsu_error.frame_range -> True. This will enable - a warning in the Animation Tools Tab UI. - """ + # Only show if kitsu context is detected active_shot = cache.shot_active_get() if not active_shot: return - - # Pull update for shot. - cache.shot_active_pull_update() - - if "3d_start" not in active_shot.data: - logger.warning( - "Failed to check frame range. Shot %s missing '3d_start' attribute on server", - active_shot.name, + if not core.check_frame_range(bpy.context): + bpy.context.window_manager.popup_menu( + draw_frame_range_warning, + title="Warning: Frame Range Error.", + icon='ERROR', ) - return - frame_in = int(active_shot.data["3d_start"]) - frame_out = int(active_shot.data["3d_start"]) + int(active_shot.nb_frames) - 1 - if ( - frame_in == bpy.context.scene.frame_start - and frame_out == bpy.context.scene.frame_end - ): - bpy.context.scene.kitsu_error.frame_range = False - return - - bpy.context.scene.kitsu_error.frame_range = True - logger.warning("Current frame range is outdated!") @persistent @@ -506,6 +524,7 @@ classes = [ KITSU_OT_playblast_increment_playblast_version, KITSU_OT_pull_frame_range, KITSU_OT_push_frame_range, + KITSU_OT_check_frame_range, ] diff --git a/scripts-blender/addons/blender_kitsu/ui.py b/scripts-blender/addons/blender_kitsu/ui.py index f01146f5..62681bc9 100644 --- a/scripts-blender/addons/blender_kitsu/ui.py +++ b/scripts-blender/addons/blender_kitsu/ui.py @@ -50,10 +50,10 @@ def draw_error_invalid_playblast_root_dir( def draw_error_frame_range_outdated( box: bpy.types.UILayout, ) -> bpy.types.UILayout: - row = box.row(align=True) + row.alert = True row.label(text="Frame Range Outdated") - row.operator("kitsu.pull_frame_range", icon="FILE_REFRESH") + row.operator("kitsu.pull_frame_range", icon="TRIA_DOWN") def draw_error_invalid_render_preset_dir(