add generic templates
This commit is contained in:
+79
-26
@@ -7,7 +7,7 @@ from tempfile import gettempdir
|
||||
|
||||
import bpy
|
||||
from bpy.types import Operator, UIList
|
||||
from bpy.props import (CollectionProperty, BoolProperty, EnumProperty, StringProperty)
|
||||
from bpy.props import (CollectionProperty, BoolProperty, EnumProperty, StringProperty, IntProperty)
|
||||
|
||||
from vse_toolbox.constants import (EDITS, EDIT_SUFFIXES, MOVIES, MOVIE_SUFFIXES,
|
||||
SOUNDS, SOUND_SUFFIXES)
|
||||
@@ -16,8 +16,8 @@ from vse_toolbox.sequencer_utils import (clean_sequencer, import_edit, import_mo
|
||||
import_sound, get_strips, get_channel_index, get_empty_channel, scale_clip_to_fit)
|
||||
|
||||
from vse_toolbox.bl_utils import (get_scene_settings, get_addon_prefs, get_scene_settings)
|
||||
from vse_toolbox.file_utils import install_module, parse, find_last
|
||||
#from vse_toolbox.template import Template
|
||||
from vse_toolbox.file_utils import install_module, parse, find_last, expand
|
||||
|
||||
|
||||
class VSETB_OT_auto_select_files(Operator):
|
||||
bl_idname = "vse_toolbox.auto_select_files"
|
||||
@@ -254,6 +254,38 @@ class VSETB_OT_unselect_task(Operator):
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class VSETB_OT_add_import_template(Operator):
|
||||
bl_idname = "vse_toolbox.add_import_template"
|
||||
bl_label = "Add Template"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
scn = context.scene
|
||||
settings = get_scene_settings()
|
||||
project = settings.active_project
|
||||
|
||||
project.import_shots.video_templates.add()
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class VSETB_OT_remove_import_template(Operator):
|
||||
bl_idname = "vse_toolbox.remove_import_template"
|
||||
bl_label = "Remove Template"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
index : IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
scn = context.scene
|
||||
settings = get_scene_settings()
|
||||
project = settings.active_project
|
||||
|
||||
project.import_shots.video_templates.remove(self.index)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
def get_sequence_items(self, context):
|
||||
settings = get_scene_settings()
|
||||
project = settings.active_project
|
||||
@@ -351,6 +383,9 @@ class VSETB_OT_import_shots(Operator):
|
||||
if not last_comment:
|
||||
return
|
||||
|
||||
last_preview = last_comment['previews'][0]
|
||||
|
||||
ext = last_preview['extension']
|
||||
shot_name = shot['name']
|
||||
sequence_name = f"{shot['sequence_name']}_"
|
||||
if shot_name.startswith(sequence_name):
|
||||
@@ -358,10 +393,9 @@ class VSETB_OT_import_shots(Operator):
|
||||
|
||||
preview_dir = self.get_preview_dir()
|
||||
|
||||
filepath = Path(preview_dir, f'{sequence_name}{shot_name}_{task_type.name}')
|
||||
filepath = Path(preview_dir, f'{sequence_name}{shot_name}_{task_type.name}.{ext}')
|
||||
filepath.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
last_preview = last_comment['previews'][0]
|
||||
tracker.download_preview_file(last_preview, str(filepath))
|
||||
|
||||
return filepath
|
||||
@@ -378,17 +412,20 @@ class VSETB_OT_import_shots(Operator):
|
||||
settings = get_scene_settings()
|
||||
project = settings.active_project
|
||||
import_shots = project.import_shots
|
||||
project_templates = {t.name: t.value for t in project.templates}
|
||||
|
||||
pattern = Path(
|
||||
import_shots.shot_folder_template,
|
||||
import_shots.import_video_template)
|
||||
for template in [import_shots.video_template] + list(import_shots.video_templates.keys()):
|
||||
|
||||
template = expand(template, **project_templates)
|
||||
|
||||
# Normalize name in snake_case for now
|
||||
sequence = sequence.name.lower().replace(' ', '_')
|
||||
shot = parse(project.shot_template, shot_name)['shot']
|
||||
task = task_type.name.lower().replace(' ', '_')
|
||||
format_data = project.format_data
|
||||
format_data.update(parse(project.sequence_template, sequence.name))
|
||||
format_data.update(parse(project.shot_template, shot_name))
|
||||
# Normalize name in snake_case for now
|
||||
format_data.update(task=task_type.name.lower().replace(' ', '_'))
|
||||
|
||||
return find_last(pattern, sequence=sequence, shot=shot, task=task)
|
||||
if last_preview := find_last(template, **format_data):
|
||||
return last_preview
|
||||
|
||||
def execute(self, context):
|
||||
scn = context.scene
|
||||
@@ -405,6 +442,9 @@ class VSETB_OT_import_shots(Operator):
|
||||
|
||||
conformed = False
|
||||
|
||||
scn.sequence_editor_clear()
|
||||
scn.sequence_editor_create()
|
||||
|
||||
self.set_sequencer_channels([t.name for t in task_types])
|
||||
frame_index = 1
|
||||
for sequence in sequences:
|
||||
@@ -412,6 +452,7 @@ class VSETB_OT_import_shots(Operator):
|
||||
sequence_start = frame_index
|
||||
for shot_data in shots_data:
|
||||
frames = int(shot_data['nb_frames'])
|
||||
frame_end = frame_index + frames
|
||||
|
||||
strip = scn.sequence_editor.sequences.new_effect(
|
||||
name=shot_data['name'],
|
||||
@@ -425,25 +466,23 @@ class VSETB_OT_import_shots(Operator):
|
||||
|
||||
for task_type in task_types:
|
||||
if import_shots.import_source == 'DISK':
|
||||
preview = self.find_shot_preview(sequence, shot_data['name'], task_type)
|
||||
#print(videos)
|
||||
#return {"FINISHED"}
|
||||
|
||||
preview = self.find_shot_preview(sequence, shot_data['name'], task_type)
|
||||
else:
|
||||
preview = self.download_preview(task_type, shot_data)
|
||||
if not preview:
|
||||
print(f'No preview found for shot {shot_data["name"]}')
|
||||
|
||||
if not preview:
|
||||
print(f'No preview found for shot {shot_data["name"]}')
|
||||
continue
|
||||
|
||||
print(f'Loading Preview from {preview}')
|
||||
|
||||
# Load Video
|
||||
channel_index = get_channel_index(f'{task_type.name} Video')
|
||||
video_clip = import_movie(preview)
|
||||
video_clip.frame_start = frame_index
|
||||
video_clip = import_movie(preview, frame_start=frame_index, frame_end=frame_end)
|
||||
video_clip.channel = channel_index
|
||||
|
||||
if video_clip.frame_offset_end:
|
||||
video_clip.color_tag = 'COLOR_01'
|
||||
|
||||
if not conformed:
|
||||
self.conform_render(video_clip)
|
||||
conformed = True
|
||||
@@ -453,8 +492,10 @@ class VSETB_OT_import_shots(Operator):
|
||||
# Load Audio
|
||||
channel_index = get_channel_index(f'{task_type.name} Audio')
|
||||
audio_clip = import_sound(preview, frame_start=frame_index,
|
||||
frame_end=video_clip.frame_final_end)
|
||||
frame_end=frame_end)
|
||||
audio_clip.channel = channel_index
|
||||
if video_clip.frame_offset_end:
|
||||
audio_clip.color_tag = 'COLOR_01'
|
||||
|
||||
frame_index += frames
|
||||
|
||||
@@ -471,6 +512,8 @@ class VSETB_OT_import_shots(Operator):
|
||||
scn.frame_start = 1
|
||||
scn.frame_end = frame_index -1
|
||||
|
||||
#bpy.ops.vse_toolbox.set_stamps()
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
def draw(self, context):
|
||||
@@ -489,8 +532,16 @@ class VSETB_OT_import_shots(Operator):
|
||||
|
||||
if import_shots.import_source == 'DISK':
|
||||
#col.prop(import_shots, "sequence_dir_template", text='Sequence Dir')
|
||||
col.prop(import_shots, "shot_folder_template", text='Shot Folder')
|
||||
col.prop(import_shots, "import_video_template", text='Video')
|
||||
#col.prop(import_shots, "shot_folder_template", text='Shot Folder')
|
||||
row = col.row(align=True)
|
||||
row.prop(import_shots, "video_template", text='')
|
||||
row.operator("vse_toolbox.add_import_template", text='', icon='ADD')
|
||||
|
||||
for i, template in enumerate(import_shots.video_templates):
|
||||
row = col.row(align=True)
|
||||
row.prop(template, "name", text='')
|
||||
row.operator("vse_toolbox.remove_import_template", text='', icon='REMOVE').index=i
|
||||
|
||||
col.separator()
|
||||
else:
|
||||
col.prop(import_shots, "previews_folder", text='Previews Folder')
|
||||
@@ -579,7 +630,7 @@ class VSETB_OT_import_shots(Operator):
|
||||
# self.report({"ERROR"}, "Save your Blender file first")
|
||||
# return {"CANCELLED"}
|
||||
|
||||
return context.window_manager.invoke_props_dialog(self, width=400)
|
||||
return context.window_manager.invoke_props_dialog(self, width=350)
|
||||
|
||||
def check(self, context):
|
||||
return True
|
||||
@@ -590,6 +641,8 @@ classes = (
|
||||
VSETB_OT_unselect_sequence,
|
||||
VSETB_OT_unselect_task,
|
||||
VSETB_OT_select_task,
|
||||
VSETB_OT_add_import_template,
|
||||
VSETB_OT_remove_import_template,
|
||||
VSETB_UL_import_task,
|
||||
VSETB_OT_auto_select_files,
|
||||
VSETB_OT_import_files,
|
||||
|
||||
Reference in New Issue
Block a user