Blender Kitsu: Add Import Edit Render Operator for Shots #236
@ -4,25 +4,32 @@ import re
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def edit_export_get_latest(context: bpy.types.Context):
|
||||
"""Find latest export in editorial export directory"""
|
||||
addon_prefs = prefs.addon_prefs_get(context)
|
||||
def edit_render_get_latest(context: bpy.types.Context):
|
||||
"""Find latest render in editorial render directory"""
|
||||
|
||||
edit_export_path = Path(addon_prefs.edit_export_dir)
|
||||
|
||||
files_list = [
|
||||
f
|
||||
for f in edit_export_path.iterdir()
|
||||
if f.is_file()
|
||||
and edit_export_is_valid_edit_name(addon_prefs.edit_export_file_pattern, f.name)
|
||||
]
|
||||
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_export_is_valid_edit_name(file_pattern: str, filename: str) -> bool:
|
||||
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_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_render_file_pattern, f.name)
|
||||
]
|
||||
return files_list
|
||||
|
||||
|
||||
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)
|
||||
@ -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_render_import_latest(
|
||||
context: bpy.types.Context, shot
|
||||
) -> list[bpy.types.Sequence]: # TODO add info to shot
|
||||
"""Loads latest render from editorial department"""
|
||||
addon_prefs = prefs.addon_prefs_get(context)
|
||||
strip_channel = 1
|
||||
latest_file = edit_render_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_render_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
|
||||
|
@ -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_render_import_latest, edit_renders_get_all, edit_render_get_latest
|
||||
|
||||
logger = LoggerFactory.getLogger()
|
||||
|
||||
@ -17,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)
|
||||
@ -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
|
||||
|
||||
@ -146,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
|
||||
@ -195,10 +197,139 @@ 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 = (
|
||||
"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
|
||||
_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_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
|
||||
|
||||
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_renders_get_all(context)
|
||||
if all_edit_render_paths == []:
|
||||
self.report(
|
||||
{"WARNING"},
|
||||
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"}
|
||||
|
||||
# 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_render_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,
|
||||
]
|
||||
|
||||
|
||||
|
@ -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_render_dir)
|
||||
|
||||
# Is None if invalid.
|
||||
if addon_prefs.edit_export_dir == "" or not edit_export_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"
|
||||
)
|
||||
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")
|
||||
|
@ -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():
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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()
|
||||
@ -358,57 +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
|
||||
)
|
||||
|
||||
@ -487,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)
|
||||
@ -524,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()
|
||||
@ -571,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
|
||||
|
||||
@ -611,15 +614,6 @@ class KITSU_addon_preferences(bpy.types.AddonPreferences):
|
||||
|
||||
return True
|
||||
|
||||
@property
|
||||
def is_editorial_dir_valid(self) -> bool:
|
||||
if edit_export_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:
|
||||
"""
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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_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()
|
||||
|
Loading…
Reference in New Issue
Block a user