From 4111cb613ce58dbaf179b80710e8b50f05515280 Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Mon, 19 Feb 2024 13:18:23 -0500 Subject: [PATCH 1/6] Add Operator to Import Latest Editorial Render --- .../addons/blender_kitsu/edit/core.py | 63 ++++++++- .../addons/blender_kitsu/edit/ops.py | 131 +++++++++++++++++- .../addons/blender_kitsu/edit/ui.py | 32 ++++- .../blender_kitsu/shot_builder/editorial.py | 53 ------- .../addons/blender_kitsu/shot_builder/ops.py | 2 +- 5 files changed, 218 insertions(+), 63 deletions(-) delete mode 100644 scripts-blender/addons/blender_kitsu/shot_builder/editorial.py diff --git a/scripts-blender/addons/blender_kitsu/edit/core.py b/scripts-blender/addons/blender_kitsu/edit/core.py index a23dabd2..b3a41bdd 100644 --- a/scripts-blender/addons/blender_kitsu/edit/core.py +++ b/scripts-blender/addons/blender_kitsu/edit/core.py @@ -6,6 +6,16 @@ from pathlib import Path def edit_export_get_latest(context: bpy.types.Context): """Find latest export in editorial export directory""" + + files_list = edit_exports_get_all(context) + if len(files_list) >= 1: + files_list = sorted(files_list, reverse=True) + return files_list[0] + return None + + +def edit_exports_get_all(context: bpy.types.Context): + """Find latest export in editorial export directory""" addon_prefs = prefs.addon_prefs_get(context) edit_export_path = Path(addon_prefs.edit_export_dir) @@ -16,10 +26,7 @@ def edit_export_get_latest(context: bpy.types.Context): if f.is_file() and edit_export_is_valid_edit_name(addon_prefs.edit_export_file_pattern, f.name) ] - if len(files_list) >= 1: - files_list = sorted(files_list, reverse=True) - return files_list[0] - return None + return files_list def edit_export_is_valid_edit_name(file_pattern: str, filename: str) -> bool: @@ -31,3 +38,51 @@ def edit_export_is_valid_edit_name(file_pattern: str, filename: str) -> bool: if match: return True return False + + +def edit_export_import_latest( + context: bpy.types.Context, shot +) -> list[bpy.types.Sequence]: # TODO add info to shot + """Loads latest export from editorial department""" + addon_prefs = prefs.addon_prefs_get(context) + strip_channel = 1 + latest_file = edit_export_get_latest(context) + if not latest_file: + return None + # Check if Kitsu server returned empty shot + if shot.id == '': + return None + strip_filepath = latest_file.as_posix() + strip_frame_start = addon_prefs.shot_builder_frame_offset + + scene = context.scene + if not scene.sequence_editor: + scene.sequence_editor_create() + seq_editor = scene.sequence_editor + movie_strip = seq_editor.sequences.new_movie( + latest_file.name, + strip_filepath, + strip_channel + 1, + strip_frame_start, + fit_method="ORIGINAL", + ) + sound_strip = seq_editor.sequences.new_sound( + latest_file.name, + strip_filepath, + strip_channel, + strip_frame_start, + ) + new_strips = [movie_strip, sound_strip] + + # Update shift frame range prop. + frame_in = shot.data.get("frame_in") + frame_3d_start = shot.get_3d_start() + frame_3d_offset = frame_3d_start - addon_prefs.shot_builder_frame_offset + edit_export_offset = addon_prefs.edit_export_frame_offset + + # Set sequence strip start kitsu data. + for strip in new_strips: + strip.frame_start = ( + -frame_in + (strip_frame_start * 2) + frame_3d_offset + edit_export_offset + ) + return new_strips diff --git a/scripts-blender/addons/blender_kitsu/edit/ops.py b/scripts-blender/addons/blender_kitsu/edit/ops.py index 124cbcc2..ac659e1c 100644 --- a/scripts-blender/addons/blender_kitsu/edit/ops.py +++ b/scripts-blender/addons/blender_kitsu/edit/ops.py @@ -1,12 +1,14 @@ import bpy +from bpy.types import Sequence, Context import os -from typing import Set +from typing import Set, List from pathlib import Path from .. import cache, prefs, util from ..types import Task, TaskStatus from ..playblast.core import override_render_path, override_render_format from . import opsdata from ..logger import LoggerFactory +from .core import edit_export_import_latest, edit_exports_get_all, edit_export_get_latest logger = LoggerFactory.getLogger() @@ -52,7 +54,7 @@ class KITSU_OT_edit_render_publish(bpy.types.Operator): cls.poll_message_set("Edit Render Directory is Invalid, see Add-On preferences") return False if not addon_prefs.is_edit_render_pattern_valid: - cls.poll_message_set("Edit Export File Pattern is Invalid, see Add-On preferences") + cls.poll_message_set("Edit Render File Pattern is Invalid, see Add-On preferences") return False return True @@ -195,10 +197,135 @@ class KITSU_OT_edit_render_increment_version(bpy.types.Operator): return {"FINISHED"} +class KITSU_OT_edit_render_import_latest(bpy.types.Operator): + bl_idname = "kitsu.edit_render_import_latest" + bl_label = "Import Latest Edit Render" + bl_description = "" # TODO + + _existing_edit_renders = [] + _removed_movie = 0 + _removed_audio = 0 + _latest_render_name = "" + + @classmethod + def poll(cls, context: bpy.types.Context) -> bool: + if not prefs.session_auth(context): + cls.poll_message_set("Login to a Kitsu Server") + return False + if not cache.project_active_get(): + cls.poll_message_set("Select an active project") + return False + if cache.shot_active_get().id == "": + cls.poll_message_set("Please set an active shot in Kitsu Context UI") + return False + if not prefs.addon_prefs_get(context).is_edit_render_root_valid: + cls.poll_message_set("Edit Render Directory is Invalid, see Add-On Preferences") + return False + return True + + def get_filepath(self, strip): + if hasattr(strip, "filepath"): + return strip.filepath + if hasattr(strip, "sound"): + return strip.sound.filepath + + def compare_strip_to_path(self, strip: Sequence, compare_path: Path) -> bool: + strip_path = Path(bpy.path.abspath(self.get_filepath(strip))) + return bool(compare_path.absolute() == strip_path.absolute()) + + def compare_strip_to_paths(self, strip: Sequence, compare_paths: List[Path]) -> bool: + for compare_path in compare_paths: + if self.compare_strip_to_path(strip, compare_path): + return True + return False + + def get_existing_edit_renders( + self, context: Context, all_edit_render_paths: List[Path] + ) -> List[Sequence]: + sequences = context.scene.sequence_editor.sequences + + # Collect Existing Edit Renders + for strip in sequences: + if self.compare_strip_to_paths(strip, all_edit_render_paths): + self._existing_edit_renders.append(strip) + return self._existing_edit_renders + + def check_if_latest_edit_render_is_imported(self, context: Context) -> bool: + # Check if latest edit render is already loaded. + for strip in self._existing_edit_renders: + latest_edit_render_path = edit_export_get_latest(context) + if self.compare_strip_to_path(strip, latest_edit_render_path): + self._latest_render_name = latest_edit_render_path.name + return True + + def remove_existing_edit_renders(self, context: Context) -> None: + # Remove Existing Strips to make way for new Strip + sequences = context.scene.sequence_editor.sequences + for strip in self._existing_edit_renders: + if strip.type == "MOVIE": + self._removed_movie += 1 + if strip.type == "SOUND": + self._removed_audio += 1 + sequences.remove(strip) + + def execute(self, context: bpy.types.Context) -> Set[str]: + # Reset Values + self._existing_edit_renders = [] + self._removed_movie = 0 + self._removed_audio = 0 + self._latest_render_name = "" + + addon_prefs = prefs.addon_prefs_get(context) + + # Get paths to all edit renders + all_edit_render_paths = edit_exports_get_all(context) + if all_edit_render_paths == []: + self.report( + {"WARNING"}, + f"No Edit Renders found in '{addon_prefs.edit_export_dir}' using pattern '{addon_prefs.edit_export_file_pattern}' See Add-On Preferences", + ) + return {"CANCELLED"} + + # Collect all existing edit renders + self.get_existing_edit_renders(context, all_edit_render_paths) + + # Stop latest render is already imported + if self.check_if_latest_edit_render_is_imported(context): + self.report( + {"WARNING"}, + f"Latest Editorial Render already loaded '{self._latest_render_name}'", + ) + return {"CANCELLED"} + + # Remove old edit renders + self.remove_existing_edit_renders(context) + + # Import new edit render + shot = cache.shot_active_get() + strips = edit_export_import_latest(context, shot) + + if strips is None: + self.report({"WARNING"}, f"Loaded Latest Editorial Render failed to import!") + return {"CANCELLED"} + + # Report. + if self._removed_movie > 0 or self._removed_audio > 0: + removed_msg = ( + f"Removed {self._removed_movie} Movie Strips and {self._removed_audio} Audio Strips" + ) + self.report( + {"INFO"}, f"Loaded Latest Editorial Render, '{strips[0].name}'. {removed_msg}" + ) + else: + self.report({"INFO"}, f"Loaded Latest Editorial Render, '{strips[0].name}'") + return {"FINISHED"} + + classes = [ KITSU_OT_edit_render_publish, KITSU_OT_edit_render_set_version, KITSU_OT_edit_render_increment_version, + KITSU_OT_edit_render_import_latest, ] diff --git a/scripts-blender/addons/blender_kitsu/edit/ui.py b/scripts-blender/addons/blender_kitsu/edit/ui.py index 3fcb1163..c48f51aa 100644 --- a/scripts-blender/addons/blender_kitsu/edit/ui.py +++ b/scripts-blender/addons/blender_kitsu/edit/ui.py @@ -6,6 +6,7 @@ from .ops import ( KITSU_OT_edit_render_set_version, KITSU_OT_edit_render_increment_version, KITSU_OT_edit_render_publish, + KITSU_OT_edit_render_import_latest, ) from ..generic.ops import KITSU_OT_open_path @@ -71,9 +72,34 @@ class KITSU_PT_edit_render_publish(bpy.types.Panel): ) -classes = [ - KITSU_PT_edit_render_publish, -] +class KITSU_PT_edit_render_tools(bpy.types.Panel): + """ + Panel in sequence editor that exposes a set of tools that are used to load the latest edit + """ + + bl_category = "Kitsu" + bl_label = "General Tools" + bl_space_type = "SEQUENCE_EDITOR" + bl_region_type = "UI" + bl_options = {"DEFAULT_CLOSED"} + bl_order = 50 + + @classmethod + def poll(cls, context: bpy.types.Context) -> bool: + if not prefs.session_auth(context): + return False + + if not (context_core.is_sequence_context() or context_core.is_shot_context()): + return False + return True + + def draw(self, context: bpy.types.Context) -> None: + box = self.layout.box() + box.label(text="General", icon="MODIFIER") + box.operator(KITSU_OT_edit_render_import_latest.bl_idname) + + +classes = [KITSU_PT_edit_render_publish, KITSU_PT_edit_render_tools] def register(): diff --git a/scripts-blender/addons/blender_kitsu/shot_builder/editorial.py b/scripts-blender/addons/blender_kitsu/shot_builder/editorial.py deleted file mode 100644 index f23a572b..00000000 --- a/scripts-blender/addons/blender_kitsu/shot_builder/editorial.py +++ /dev/null @@ -1,53 +0,0 @@ -import bpy -from .. import prefs -from pathlib import Path -import re -from ..edit import core as edit_core - - -def edit_export_import_latest( - context: bpy.types.Context, shot -) -> list[bpy.types.Sequence]: # TODO add info to shot - """Loads latest export from editorial department""" - addon_prefs = prefs.addon_prefs_get(context) - strip_channel = 1 - latest_file = edit_core.edit_export_get_latest(context) - if not latest_file: - return None - # Check if Kitsu server returned empty shot - if shot.id == '': - return None - strip_filepath = latest_file.as_posix() - strip_frame_start = addon_prefs.shot_builder_frame_offset - - scene = context.scene - if not scene.sequence_editor: - scene.sequence_editor_create() - seq_editor = scene.sequence_editor - movie_strip = seq_editor.sequences.new_movie( - latest_file.name, - strip_filepath, - strip_channel + 1, - strip_frame_start, - fit_method="ORIGINAL", - ) - sound_strip = seq_editor.sequences.new_sound( - latest_file.name, - strip_filepath, - strip_channel, - strip_frame_start, - ) - new_strips = [movie_strip, sound_strip] - - # Update shift frame range prop. - frame_in = shot.data.get("frame_in") - frame_3d_start = shot.get_3d_start() - frame_3d_offset = frame_3d_start - addon_prefs.shot_builder_frame_offset - edit_export_offset = addon_prefs.edit_export_frame_offset - - # Set sequence strip start kitsu data. - for strip in new_strips: - strip.frame_start = ( - -frame_in + (strip_frame_start * 2) + frame_3d_offset + edit_export_offset - ) - return new_strips diff --git a/scripts-blender/addons/blender_kitsu/shot_builder/ops.py b/scripts-blender/addons/blender_kitsu/shot_builder/ops.py index a9798015..0f91fd60 100644 --- a/scripts-blender/addons/blender_kitsu/shot_builder/ops.py +++ b/scripts-blender/addons/blender_kitsu/shot_builder/ops.py @@ -16,7 +16,7 @@ from .core import ( ) from ..context import core as context_core -from .editorial import edit_export_import_latest +from ..edit.core import edit_export_import_latest from .file_save import save_shot_builder_file from .template import replace_workspace_with_template from .assets import get_shot_assets -- 2.30.2 From 09dec7d779dba7f283c8a48484551024ff51bf9e Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Mon, 19 Feb 2024 13:23:14 -0500 Subject: [PATCH 2/6] Rename Edit Core Functions to Use Common Naming "Edit Render" --- .../addons/blender_kitsu/edit/core.py | 24 +++++++++---------- .../addons/blender_kitsu/edit/ops.py | 10 ++++---- .../addons/blender_kitsu/edit/opsdata.py | 6 ++--- scripts-blender/addons/blender_kitsu/prefs.py | 4 ++-- .../addons/blender_kitsu/shot_builder/ops.py | 4 ++-- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/scripts-blender/addons/blender_kitsu/edit/core.py b/scripts-blender/addons/blender_kitsu/edit/core.py index b3a41bdd..a9abe0ba 100644 --- a/scripts-blender/addons/blender_kitsu/edit/core.py +++ b/scripts-blender/addons/blender_kitsu/edit/core.py @@ -4,32 +4,32 @@ import re from pathlib import Path -def edit_export_get_latest(context: bpy.types.Context): - """Find latest export in editorial export directory""" +def edit_render_get_latest(context: bpy.types.Context): + """Find latest render in editorial render directory""" - files_list = edit_exports_get_all(context) + files_list = edit_renders_get_all(context) if len(files_list) >= 1: files_list = sorted(files_list, reverse=True) return files_list[0] return None -def edit_exports_get_all(context: bpy.types.Context): - """Find latest export in editorial export directory""" +def edit_renders_get_all(context: bpy.types.Context): + """Find latest render in editorial render directory""" addon_prefs = prefs.addon_prefs_get(context) - edit_export_path = Path(addon_prefs.edit_export_dir) + edit_render_path = Path(addon_prefs.edit_export_dir) files_list = [ f - for f in edit_export_path.iterdir() + for f in edit_render_path.iterdir() if f.is_file() - and edit_export_is_valid_edit_name(addon_prefs.edit_export_file_pattern, f.name) + and edit_render_is_valid_edit_name(addon_prefs.edit_export_file_pattern, f.name) ] return files_list -def edit_export_is_valid_edit_name(file_pattern: str, filename: str) -> bool: +def edit_render_is_valid_edit_name(file_pattern: str, filename: str) -> bool: """Verify file name matches file pattern set in preferences""" # Prevents un-expected matches file_pattern = re.escape(file_pattern) @@ -40,13 +40,13 @@ def edit_export_is_valid_edit_name(file_pattern: str, filename: str) -> bool: return False -def edit_export_import_latest( +def edit_render_import_latest( context: bpy.types.Context, shot ) -> list[bpy.types.Sequence]: # TODO add info to shot - """Loads latest export from editorial department""" + """Loads latest render from editorial department""" addon_prefs = prefs.addon_prefs_get(context) strip_channel = 1 - latest_file = edit_export_get_latest(context) + latest_file = edit_render_get_latest(context) if not latest_file: return None # Check if Kitsu server returned empty shot diff --git a/scripts-blender/addons/blender_kitsu/edit/ops.py b/scripts-blender/addons/blender_kitsu/edit/ops.py index ac659e1c..ab1deb96 100644 --- a/scripts-blender/addons/blender_kitsu/edit/ops.py +++ b/scripts-blender/addons/blender_kitsu/edit/ops.py @@ -8,7 +8,7 @@ from ..types import Task, TaskStatus from ..playblast.core import override_render_path, override_render_format from . import opsdata from ..logger import LoggerFactory -from .core import edit_export_import_latest, edit_exports_get_all, edit_export_get_latest +from .core import edit_render_import_latest, edit_renders_get_all, edit_render_get_latest logger = LoggerFactory.getLogger() @@ -19,7 +19,7 @@ class KITSU_OT_edit_render_publish(bpy.types.Operator): bl_description = ( "Renders current VSE Edit as .mp4" "Saves the set version to disk and uploads it to Kitsu with the specified " - "comment and task type. Overrides some render settings during export. " + "comment and task type. Overrides some render settings during render. " ) task_status: bpy.props.EnumProperty(name="Task Status", items=cache.get_all_task_statuses_enum) @@ -253,7 +253,7 @@ class KITSU_OT_edit_render_import_latest(bpy.types.Operator): def check_if_latest_edit_render_is_imported(self, context: Context) -> bool: # Check if latest edit render is already loaded. for strip in self._existing_edit_renders: - latest_edit_render_path = edit_export_get_latest(context) + latest_edit_render_path = edit_render_get_latest(context) if self.compare_strip_to_path(strip, latest_edit_render_path): self._latest_render_name = latest_edit_render_path.name return True @@ -278,7 +278,7 @@ class KITSU_OT_edit_render_import_latest(bpy.types.Operator): addon_prefs = prefs.addon_prefs_get(context) # Get paths to all edit renders - all_edit_render_paths = edit_exports_get_all(context) + all_edit_render_paths = edit_renders_get_all(context) if all_edit_render_paths == []: self.report( {"WARNING"}, @@ -302,7 +302,7 @@ class KITSU_OT_edit_render_import_latest(bpy.types.Operator): # Import new edit render shot = cache.shot_active_get() - strips = edit_export_import_latest(context, shot) + strips = edit_render_import_latest(context, shot) if strips is None: self.report({"WARNING"}, f"Loaded Latest Editorial Render failed to import!") diff --git a/scripts-blender/addons/blender_kitsu/edit/opsdata.py b/scripts-blender/addons/blender_kitsu/edit/opsdata.py index d0781731..94029386 100644 --- a/scripts-blender/addons/blender_kitsu/edit/opsdata.py +++ b/scripts-blender/addons/blender_kitsu/edit/opsdata.py @@ -43,17 +43,17 @@ def init_edit_render_file_model( addon_prefs = prefs.addon_prefs_get(context) kitsu_props = context.scene.kitsu - edit_export_dir = Path(addon_prefs.edit_export_dir) + edit_render_dir = Path(addon_prefs.edit_export_dir) # Is None if invalid. - if addon_prefs.edit_export_dir == "" or not edit_export_dir.exists(): + if addon_prefs.edit_export_dir == "" or not edit_render_dir.exists(): logger.error( "Failed to initialize edit render file model. Invalid path. Check addon preferences" ) return EDIT_RENDER_FILE_MODEL.reset() - EDIT_RENDER_FILE_MODEL.root_path = edit_export_dir + EDIT_RENDER_FILE_MODEL.root_path = edit_render_dir if not EDIT_RENDER_FILE_MODEL.versions: EDIT_RENDER_FILE_MODEL.append_item("v001") diff --git a/scripts-blender/addons/blender_kitsu/prefs.py b/scripts-blender/addons/blender_kitsu/prefs.py index 1abe75d2..0aa67a9d 100644 --- a/scripts-blender/addons/blender_kitsu/prefs.py +++ b/scripts-blender/addons/blender_kitsu/prefs.py @@ -41,7 +41,7 @@ from .auth.ops import ( ) from .context.ops import KITSU_OT_con_productions_load from .lookdev.prefs import LOOKDEV_preferences -from .edit.core import edit_export_get_latest +from .edit.core import edit_render_get_latest logger = LoggerFactory.getLogger() @@ -613,7 +613,7 @@ class KITSU_addon_preferences(bpy.types.AddonPreferences): @property def is_editorial_dir_valid(self) -> bool: - if edit_export_get_latest(bpy.context) is None: + if edit_render_get_latest(bpy.context) is None: logger.error( "Failed to initialize editorial export file model. Invalid path/pattern. Check addon preferences" ) diff --git a/scripts-blender/addons/blender_kitsu/shot_builder/ops.py b/scripts-blender/addons/blender_kitsu/shot_builder/ops.py index 0f91fd60..97c45f59 100644 --- a/scripts-blender/addons/blender_kitsu/shot_builder/ops.py +++ b/scripts-blender/addons/blender_kitsu/shot_builder/ops.py @@ -16,7 +16,7 @@ from .core import ( ) from ..context import core as context_core -from ..edit.core import edit_export_import_latest +from ..edit.core import edit_render_import_latest from .file_save import save_shot_builder_file from .template import replace_workspace_with_template from .assets import get_shot_assets @@ -236,7 +236,7 @@ class KITSU_OT_build_new_shot(bpy.types.Operator): link_task_type_output_collections(shot, task_type) if bkglobals.LOAD_EDITORIAL_REF.get(task_type_short_name): - edit_export_import_latest(context, shot) + edit_render_import_latest(context, shot) # Run Hooks hooks_instance = Hooks() -- 2.30.2 From 5ddc8331b09749963f1d1c6625e932ccac2bb3b0 Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Mon, 19 Feb 2024 13:29:12 -0500 Subject: [PATCH 3/6] Add Hack for Edit Render File pattern in Gold Production --- scripts-blender/addons/blender_kitsu/prefs.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts-blender/addons/blender_kitsu/prefs.py b/scripts-blender/addons/blender_kitsu/prefs.py index 0aa67a9d..26ff5311 100644 --- a/scripts-blender/addons/blender_kitsu/prefs.py +++ b/scripts-blender/addons/blender_kitsu/prefs.py @@ -390,6 +390,9 @@ class KITSU_addon_preferences(bpy.types.AddonPreferences): active_project = cache.project_active_get() if get_safely_string_prop(self, 'edit_export_file_pattern') == "" and active_project: proj_name = active_project.name.replace(' ', bkglobals.SPACE_REPLACER).lower() + # HACK for Project Gold at Blender Studio + if proj_name == "project_gold": + return f"gold-edit-v###.mp4" return f"{proj_name}-edit-v###.mp4" return get_safely_string_prop(self, 'edit_export_file_pattern') -- 2.30.2 From 0ed5621edd908a0324b49b3b173275d1113766be Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Mon, 19 Feb 2024 14:08:28 -0500 Subject: [PATCH 4/6] Rename "Edit Export" in Preferences to "Edit Render" --- .../addons/blender_kitsu/edit/core.py | 6 +- .../addons/blender_kitsu/edit/ops.py | 4 +- .../addons/blender_kitsu/edit/opsdata.py | 4 +- scripts-blender/addons/blender_kitsu/prefs.py | 71 ++++++++----------- .../addons/blender_kitsu/propsdata.py | 6 +- 5 files changed, 41 insertions(+), 50 deletions(-) diff --git a/scripts-blender/addons/blender_kitsu/edit/core.py b/scripts-blender/addons/blender_kitsu/edit/core.py index a9abe0ba..56b588ce 100644 --- a/scripts-blender/addons/blender_kitsu/edit/core.py +++ b/scripts-blender/addons/blender_kitsu/edit/core.py @@ -18,13 +18,13 @@ def edit_renders_get_all(context: bpy.types.Context): """Find latest render in editorial render directory""" addon_prefs = prefs.addon_prefs_get(context) - edit_render_path = Path(addon_prefs.edit_export_dir) + edit_render_path = Path(addon_prefs.edit_render_dir) files_list = [ f for f in edit_render_path.iterdir() if f.is_file() - and edit_render_is_valid_edit_name(addon_prefs.edit_export_file_pattern, f.name) + and edit_render_is_valid_edit_name(addon_prefs.edit_render_file_pattern, f.name) ] return files_list @@ -78,7 +78,7 @@ def edit_render_import_latest( frame_in = shot.data.get("frame_in") frame_3d_start = shot.get_3d_start() frame_3d_offset = frame_3d_start - addon_prefs.shot_builder_frame_offset - edit_export_offset = addon_prefs.edit_export_frame_offset + edit_export_offset = addon_prefs.edit_render_frame_offset # Set sequence strip start kitsu data. for strip in new_strips: diff --git a/scripts-blender/addons/blender_kitsu/edit/ops.py b/scripts-blender/addons/blender_kitsu/edit/ops.py index ab1deb96..6194ad2b 100644 --- a/scripts-blender/addons/blender_kitsu/edit/ops.py +++ b/scripts-blender/addons/blender_kitsu/edit/ops.py @@ -148,7 +148,7 @@ class KITSU_OT_edit_render_set_version(bpy.types.Operator): @classmethod def poll(cls, context: bpy.types.Context) -> bool: addon_prefs = prefs.addon_prefs_get(context) - return bool(addon_prefs.edit_export_dir != "") + return bool(addon_prefs.edit_render_dir != "") def execute(self, context: bpy.types.Context) -> Set[str]: kitsu_props = context.scene.kitsu @@ -282,7 +282,7 @@ class KITSU_OT_edit_render_import_latest(bpy.types.Operator): if all_edit_render_paths == []: self.report( {"WARNING"}, - f"No Edit Renders found in '{addon_prefs.edit_export_dir}' using pattern '{addon_prefs.edit_export_file_pattern}' See Add-On Preferences", + f"No Edit Renders found in '{addon_prefs.edit_render_dir}' using pattern '{addon_prefs.edit_render_file_pattern}' See Add-On Preferences", ) return {"CANCELLED"} diff --git a/scripts-blender/addons/blender_kitsu/edit/opsdata.py b/scripts-blender/addons/blender_kitsu/edit/opsdata.py index 94029386..8637f6c4 100644 --- a/scripts-blender/addons/blender_kitsu/edit/opsdata.py +++ b/scripts-blender/addons/blender_kitsu/edit/opsdata.py @@ -43,10 +43,10 @@ def init_edit_render_file_model( addon_prefs = prefs.addon_prefs_get(context) kitsu_props = context.scene.kitsu - edit_render_dir = Path(addon_prefs.edit_export_dir) + edit_render_dir = Path(addon_prefs.edit_render_dir) # Is None if invalid. - if addon_prefs.edit_export_dir == "" or not edit_render_dir.exists(): + if addon_prefs.edit_render_dir == "" or not edit_render_dir.exists(): logger.error( "Failed to initialize edit render file model. Invalid path. Check addon preferences" ) diff --git a/scripts-blender/addons/blender_kitsu/prefs.py b/scripts-blender/addons/blender_kitsu/prefs.py index 26ff5311..d39074fa 100644 --- a/scripts-blender/addons/blender_kitsu/prefs.py +++ b/scripts-blender/addons/blender_kitsu/prefs.py @@ -358,60 +358,60 @@ class KITSU_addon_preferences(bpy.types.AddonPreferences): subtype='DIR_PATH', ) - def set_edit_export_dir(self, input): - self['edit_export_dir'] = input + def set_edit_render_dir(self, input): + self['edit_render_dir'] = input return - def get_edit_export_dir( + def get_edit_render_dir( self, ) -> str: - if get_safely_string_prop(self, 'edit_export_dir') == "" and self.project_root_path: + if get_safely_string_prop(self, 'edit_render_dir') == "" and self.project_root_path: dir = self.project_root_path.joinpath("shared/editorial/export/") if dir.exists(): return dir.as_posix() - return get_safely_string_prop(self, 'edit_export_dir') + return get_safely_string_prop(self, 'edit_render_dir') - edit_export_dir: bpy.props.StringProperty( # type: ignore - name="Editorial Export Directory", + edit_render_dir: bpy.props.StringProperty( # type: ignore + name="Render Directory", options={"HIDDEN", "SKIP_SAVE"}, - description="Directory path to editorial's export folder containing storyboard/animatic exports. Path should be similar to '~/shared-{proj_name}/editorial/export/'", + description="Directory path to editorial's render folder containing storyboard/animatic renders. Path should be similar to '~/shared-{proj_name}/editorial/export/'", subtype="DIR_PATH", - get=get_edit_export_dir, - set=set_edit_export_dir, + get=get_edit_render_dir, + set=set_edit_render_dir, ) - def set_edit_export_file_pattern(self, input): - self['edit_export_file_pattern'] = input + def set_edit_render_file_pattern(self, input): + self['edit_render_file_pattern'] = input return - def get_edit_export_file_pattern( + def get_edit_render_file_pattern( self, ) -> str: active_project = cache.project_active_get() - if get_safely_string_prop(self, 'edit_export_file_pattern') == "" and active_project: + if get_safely_string_prop(self, 'edit_render_file_pattern') == "" and active_project: proj_name = active_project.name.replace(' ', bkglobals.SPACE_REPLACER).lower() # HACK for Project Gold at Blender Studio if proj_name == "project_gold": return f"gold-edit-v###.mp4" return f"{proj_name}-edit-v###.mp4" - return get_safely_string_prop(self, 'edit_export_file_pattern') + return get_safely_string_prop(self, 'edit_render_file_pattern') - edit_export_file_pattern: bpy.props.StringProperty( # type: ignore - name="Editorial Export File Pattern", + edit_render_file_pattern: bpy.props.StringProperty( # type: ignore + name="Render File Pattern", options={"HIDDEN", "SKIP_SAVE"}, description=( - "File pattern for latest editorial export file. " + "File pattern for latest editorial render file. " "Typically '{proj_name}-edit-v###.mp4' where # represents a number. " "Pattern must contain exactly v### representing the version, pattern must end in .mp4" ), default="", - get=get_edit_export_file_pattern, - set=set_edit_export_file_pattern, + get=get_edit_render_file_pattern, + set=set_edit_render_file_pattern, ) - edit_export_frame_offset: bpy.props.IntProperty( # type: ignore - name="Editorial Export Offset", - description="Shift Editorial Export by this frame-range after set-up.", + edit_render_frame_offset: bpy.props.IntProperty( # type: ignore + name="Render Offset", + description="Shift Editorial Render by this frame-range after import", default=-101, # HARD CODED FOR GOLD PROJECTS BLENDER FILM ) @@ -490,11 +490,11 @@ class KITSU_addon_preferences(bpy.types.AddonPreferences): # Editorial Settings box = col.box() - box.label(text="Video Sequence Editor", icon="SEQ_SEQUENCER") - box.row().prop(self, "edit_export_dir") + box.label(text="Editorial", icon="SEQ_SEQUENCER") + box.row().prop(self, "edit_render_dir") file_pattern_row = box.row(align=True) file_pattern_row.alert = not self.is_edit_render_pattern_valid - file_pattern_row.prop(self, "edit_export_file_pattern") + file_pattern_row.prop(self, "edit_render_file_pattern") # Lookdev tools settings. self.lookdev.draw(context, col) @@ -527,7 +527,7 @@ class KITSU_addon_preferences(bpy.types.AddonPreferences): # Shot_Builder settings. box = col.box() box.label(text="Shot Builder", icon="MOD_BUILD") - box.row().prop(self, "edit_export_frame_offset") + box.row().prop(self, "edit_render_frame_offset") box.row().prop(self, "shot_builder_show_advanced") if self.shot_builder_show_advanced: start_frame_row = box.row() @@ -574,17 +574,17 @@ class KITSU_addon_preferences(bpy.types.AddonPreferences): @property def is_edit_render_root_valid(self) -> bool: - if self.edit_export_dir.strip() == "": + if self.edit_render_dir.strip() == "": return False - if not Path(self.edit_export_dir).exists(): + if not Path(self.edit_render_dir).exists(): return False return True @property def is_edit_render_pattern_valid(self) -> bool: - if not self.edit_export_file_pattern.endswith(".mp4"): + if not self.edit_render_file_pattern.endswith(".mp4"): return False - if not "###" in self.edit_export_file_pattern: + if not "###" in self.edit_render_file_pattern: return False return True @@ -614,15 +614,6 @@ class KITSU_addon_preferences(bpy.types.AddonPreferences): return True - @property - def is_editorial_dir_valid(self) -> bool: - if edit_render_get_latest(bpy.context) is None: - logger.error( - "Failed to initialize editorial export file model. Invalid path/pattern. Check addon preferences" - ) - return False - return True - def session_get(context: bpy.types.Context) -> Session: """ diff --git a/scripts-blender/addons/blender_kitsu/propsdata.py b/scripts-blender/addons/blender_kitsu/propsdata.py index e2c43a00..58ffb36c 100644 --- a/scripts-blender/addons/blender_kitsu/propsdata.py +++ b/scripts-blender/addons/blender_kitsu/propsdata.py @@ -170,12 +170,12 @@ def get_playblast_file(self: Any) -> str: def get_edit_render_file(self: Any) -> str: addon_prefs = prefs.addon_prefs_get(bpy.context) - if not bool(addon_prefs.edit_export_dir): + if not bool(addon_prefs.edit_render_dir): return "" version = self.edit_render_version - file_pattern = addon_prefs.edit_export_file_pattern + file_pattern = addon_prefs.edit_render_file_pattern file_name = file_pattern.replace('v###', version) - return Path(addon_prefs.edit_export_dir).joinpath(file_name).as_posix() + return Path(addon_prefs.edit_render_dir).joinpath(file_name).as_posix() _active_category_cache_init: bool = False -- 2.30.2 From f847ef1954c728468dd8def0d5f60dd085736102 Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Mon, 19 Feb 2024 14:15:05 -0500 Subject: [PATCH 5/6] Hide Playblast Panel in VSE Unless Context is Sequence Editor --- scripts-blender/addons/blender_kitsu/playblast/ui.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scripts-blender/addons/blender_kitsu/playblast/ui.py b/scripts-blender/addons/blender_kitsu/playblast/ui.py index c7128ae2..72a5d11a 100644 --- a/scripts-blender/addons/blender_kitsu/playblast/ui.py +++ b/scripts-blender/addons/blender_kitsu/playblast/ui.py @@ -121,6 +121,12 @@ class KITSU_PT_vi3d_playblast(bpy.types.Panel): class KITSU_PT_seq_playblast(KITSU_PT_vi3d_playblast): bl_space_type = "SEQUENCE_EDITOR" + @classmethod + def poll(cls, context: bpy.types.Context) -> bool: + if not context_core.is_sequence_context(): + return False + return bool(prefs.session_auth(context)) + classes = (KITSU_PT_seq_playblast, KITSU_PT_vi3d_playblast) -- 2.30.2 From e81591c1bed4d572343ac6d23c0e2999b3cab017 Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Mon, 19 Feb 2024 14:41:18 -0500 Subject: [PATCH 6/6] Add Description to "Import Latest Edit Render" --- scripts-blender/addons/blender_kitsu/edit/ops.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts-blender/addons/blender_kitsu/edit/ops.py b/scripts-blender/addons/blender_kitsu/edit/ops.py index 6194ad2b..e14de2a6 100644 --- a/scripts-blender/addons/blender_kitsu/edit/ops.py +++ b/scripts-blender/addons/blender_kitsu/edit/ops.py @@ -200,7 +200,11 @@ class KITSU_OT_edit_render_increment_version(bpy.types.Operator): class KITSU_OT_edit_render_import_latest(bpy.types.Operator): bl_idname = "kitsu.edit_render_import_latest" bl_label = "Import Latest Edit Render" - bl_description = "" # TODO + bl_description = ( + "Find and import the latest editorial render found in the Editorial Render Directory for the current shot. " + "Will only Import if the latest render is not already imported. " + "Will remove any previous renders currently in the file's Video Sequence Editor" + ) _existing_edit_renders = [] _removed_movie = 0 -- 2.30.2