Import Shots for mu

pull/5/head
ChristopheSeux 2024-03-26 17:54:03 +01:00
parent ac14fe5ba9
commit dae9d55494
5 changed files with 159 additions and 19 deletions

View File

@ -39,9 +39,6 @@ def register():
bpy.app.handlers.frame_change_post.append(update_text_strips) bpy.app.handlers.frame_change_post.append(update_text_strips)
bpy.app.handlers.render_pre.append(update_text_strips) bpy.app.handlers.render_pre.append(update_text_strips)
if bpy.app.background:
return
for module in modules: for module in modules:
module.register() module.register()
@ -60,9 +57,6 @@ def unregister():
# print(f"!-- {e} --!") # print(f"!-- {e} --!")
# print(f"No preview collection found. {ASSET_PREVIEWS} can't be remove.") # print(f"No preview collection found. {ASSET_PREVIEWS} can't be remove.")
if bpy.app.background:
return
bpy.app.handlers.frame_change_post.remove(set_active_strip) bpy.app.handlers.frame_change_post.remove(set_active_strip)
for module in reversed(modules): for module in reversed(modules):
module.unregister() module.unregister()

View File

@ -2,21 +2,21 @@
from pathlib import Path from pathlib import Path
import bpy import bpy
from bpy.types import Operator from bpy.types import Operator, UIList
from bpy.props import (CollectionProperty, BoolProperty, EnumProperty, StringProperty) from bpy.props import (CollectionProperty, BoolProperty, EnumProperty, StringProperty)
from vse_toolbox.constants import (EDITS, EDIT_SUFFIXES, MOVIES, MOVIE_SUFFIXES, from vse_toolbox.constants import (EDITS, EDIT_SUFFIXES, MOVIES, MOVIE_SUFFIXES,
SOUNDS, SOUND_SUFFIXES) SOUNDS, SOUND_SUFFIXES)
from vse_toolbox.sequencer_utils import (clean_sequencer, import_edit, import_movie, from vse_toolbox.sequencer_utils import (clean_sequencer, import_edit, import_movie,
import_sound, get_strips) import_sound, get_strips, get_channel_index)
from vse_toolbox.bl_utils import get_scene_settings from vse_toolbox.bl_utils import get_scene_settings
from vse_toolbox.file_utils import install_module from vse_toolbox.file_utils import install_module
class VSETB_OT_auto_select_files(Operator): class VSETB_OT_auto_select_files(Operator):
bl_idname = "import.auto_select_files" bl_idname = "vse_toolbox.auto_select_files"
bl_label = "Auto Select" bl_label = "Auto Select"
bl_description = "Auto Select Files" bl_description = "Auto Select Files"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
@ -107,7 +107,7 @@ class VSETB_OT_import_files(Operator):
layout.use_property_decorate = False layout.use_property_decorate = False
col = layout.column(align=True) col = layout.column(align=True)
col.operator('import.auto_select_files', text='Auto Select') col.operator('vse_toolbox.auto_select_files', text='Auto Select')
row = layout.row(heading="Import Edit", align=True) row = layout.row(heading="Import Edit", align=True)
row.prop(self, 'import_edit') row.prop(self, 'import_edit')
@ -190,9 +190,102 @@ class VSETB_OT_import_files(Operator):
return {"FINISHED"} return {"FINISHED"}
class VSETB_UL_import_task(UIList):
def draw_item(self, context, layout, data, item, icon, active_data,
active_propname, index):
layout.prop(item, 'import_enabled', text='')
layout.label(text=item.name)
class VSETB_OT_import_shots(Operator):
bl_idname = "vse_toolbox.import_shots"
bl_label = "Import Shots"
bl_description = "Import Shots for disk or tracker"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
return True
def execute(self, context):
scn = context.scene
settings = get_scene_settings()
project = settings.active_project
from gadget import Project
p = Project.from_env()
p.shots.fetch()
tasks = [t for t in project.task_types if t.import_enabled]
for i, task_type in enumerate(tasks):
channel_index = 9 + i
scn.sequence_editor.channels[channel_index].name = task_type.name
# Create Channels:
scn.sequence_editor.channels[9]
for strip in get_strips('Shots'):
for i, task_type in enumerate(tasks):
shot = p.shots[strip.name]
versions = shot.tasks[task_type.name].outputs[0].versions.fetch()
if versions:
print(versions[-1])
imported_strip = import_movie(versions[-1].path)
imported_strip.frame_start = strip.frame_start
if imported_strip.frame_final_duration != strip.frame_final_duration:
print(f'strip {strip.name} has different duration')
imported_strip.color_tag = 'COLOR_03'
imported_strip.frame_final_end = strip.frame_final_end
imported_strip.channel = get_channel_index(task_type.name)
print(get_channel_index(task_type.name), imported_strip.channel)
else:
print(f'No movie for {strip.name} of task {task_type.name}')
# for task_type in tasks:
# for strip in get_strips(task_type.name):
# strip.channel = get_channel_index(task_type.name)
return {'FINISHED'}
def draw(self, context):
settings = get_scene_settings()
project = settings.active_project
layout = self.layout
col = layout.column(align=False)
col.use_property_split = True
col.use_property_decorate = False
row = col.row(align=True)
row.prop(project, "import_source", text='Source', expand=True)
row = col.row(align=True)
row.prop(project, 'import_task', text='Import Tasks')
if project.import_task == 'SELECTED':
col.use_property_split = False
col.template_list("VSETB_UL_import_task", "import_task", project, "task_types", project, "task_type_index", rows=8)
def invoke(self, context, event):
scn = context.scene
settings = get_scene_settings()
project = settings.active_project
return context.window_manager.invoke_props_dialog(self)
classes = ( classes = (
VSETB_UL_import_task,
VSETB_OT_auto_select_files, VSETB_OT_auto_select_files,
VSETB_OT_import_files, VSETB_OT_import_files,
VSETB_OT_import_shots,
) )
def register(): def register():

View File

@ -1,12 +1,12 @@
from os.path import expandvars
import bpy import bpy
from bpy.types import Operator from bpy.types import Operator
from bpy.props import (BoolProperty, StringProperty) from bpy.props import (BoolProperty, StringProperty)
from vse_toolbox.sequencer_utils import (get_strips, rename_strips, set_channels, from vse_toolbox.sequencer_utils import (get_strips, rename_strips, set_channels,
get_channel_index, new_text_strip, get_strip_at) get_channel_index, new_text_strip, get_strip_at, get_channel_name)
from vse_toolbox.bl_utils import get_scene_settings from vse_toolbox.bl_utils import get_scene_settings, get_strip_settings
class VSETB_OT_rename(Operator): class VSETB_OT_rename(Operator):
@ -269,6 +269,32 @@ class VSETB_OT_next_shot(Operator):
return {"FINISHED"} return {"FINISHED"}
class VSETB_OT_open_shot_dir(Operator):
bl_idname = "vse_toolbox.open_shot_dir"
bl_label = "Open Shot Dir"
bl_description = "Open Shot Dir"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
strip = context.active_sequence_strip
return strip and get_channel_name(strip) == 'Shots'
def execute(self, context):
strip = context.active_sequence_strip
settings = get_scene_settings()
project = settings.active_project
strip_settings = get_strip_settings()
format_data = {**settings.format_data, **project.format_data, **strip_settings.format_data}
shot_dir_template = expandvars(project.shot_dir_template)
shot_dir_path = shot_dir_template.format(**format_data)
bpy.ops.wm.path_open(filepath=shot_dir_path)
return {"FINISHED"}
addon_keymaps = [] addon_keymaps = []
def register_keymaps(): def register_keymaps():
@ -304,7 +330,8 @@ classes = (
VSETB_OT_set_stamps, VSETB_OT_set_stamps,
VSETB_OT_show_waveform, VSETB_OT_show_waveform,
VSETB_OT_previous_shot, VSETB_OT_previous_shot,
VSETB_OT_next_shot VSETB_OT_next_shot,
VSETB_OT_open_shot_dir
) )
def register(): def register():

View File

@ -3,7 +3,7 @@
from pathlib import Path from pathlib import Path
import bpy import bpy
from bpy.types import Panel from bpy.types import Panel, Menu
from bl_ui.utils import PresetPanel from bl_ui.utils import PresetPanel
from vse_toolbox.bl_utils import (get_addon_prefs, get_scene_settings, get_strip_settings) from vse_toolbox.bl_utils import (get_addon_prefs, get_scene_settings, get_strip_settings)
@ -185,6 +185,7 @@ class VSETB_PT_imports(VSETB_main, Panel):
#row = col.row(align=True) #row = col.row(align=True)
#col.operator('vse_toolbox.import_files', text='Import', icon='IMPORT') #col.operator('vse_toolbox.import_files', text='Import', icon='IMPORT')
col.operator('vse_toolbox.import_spreadsheet', text='Import Spreadsheet', icon='SPREADSHEET') col.operator('vse_toolbox.import_spreadsheet', text='Import Spreadsheet', icon='SPREADSHEET')
col.operator("vse_toolbox.import_shots", text='Import Shots', icon="FILE_MOVIE")
class VSETB_PT_presets(PresetPanel, Panel): class VSETB_PT_presets(PresetPanel, Panel):
@ -396,6 +397,20 @@ def context_menu_prop(self, context):
layout.operator('vse_toolbox.copy_metadata', icon='PASTEDOWN', text='Copy metadata to selected').metadata = button_prop.name layout.operator('vse_toolbox.copy_metadata', icon='PASTEDOWN', text='Copy metadata to selected').metadata = button_prop.name
class VSETB_MT_main_menu(Menu):
bl_label = "Vse Toolbox"
def draw(self, context):
layout = self.layout
layout.operator('vse_toolbox.open_shot_dir', text='Open Shot', icon='FILE_FOLDER')
def draw_vse_toolbox_menu(self, context):
self.layout.menu("VSETB_MT_main_menu")
classes = ( classes = (
VSETB_PT_main, VSETB_PT_main,
VSETB_PT_imports, VSETB_PT_imports,
@ -406,7 +421,8 @@ classes = (
VSETB_PT_comments, VSETB_PT_comments,
VSETB_PT_presets, VSETB_PT_presets,
VSETB_PT_exports, VSETB_PT_exports,
VSETB_PT_strip VSETB_PT_strip,
VSETB_MT_main_menu
) )
def register(): def register():
@ -414,9 +430,11 @@ def register():
bpy.utils.register_class(cls) bpy.utils.register_class(cls)
bpy.types.UI_MT_button_context_menu.append(context_menu_prop) bpy.types.UI_MT_button_context_menu.append(context_menu_prop)
bpy.types.SEQUENCER_MT_editor_menus.append(draw_vse_toolbox_menu)
def unregister(): def unregister():
for cls in reversed(classes): for cls in reversed(classes):
bpy.utils.unregister_class(cls) bpy.utils.unregister_class(cls)
bpy.types.UI_MT_button_context_menu.remove(context_menu_prop) bpy.types.UI_MT_button_context_menu.remove(context_menu_prop)
bpy.types.SEQUENCER_MT_editor_menus.remove(draw_vse_toolbox_menu)

View File

@ -109,6 +109,7 @@ class MetadataType(PropertyGroup):
class TaskType(PropertyGroup): class TaskType(PropertyGroup):
color : FloatVectorProperty(subtype='COLOR') color : FloatVectorProperty(subtype='COLOR')
import_enabled : BoolProperty(default=False)
class TaskStatus(PropertyGroup): class TaskStatus(PropertyGroup):
@ -297,6 +298,7 @@ class Project(PropertyGroup):
asset_types : CollectionProperty(type=AssetType) asset_types : CollectionProperty(type=AssetType)
metadata_types : CollectionProperty(type=MetadataType) metadata_types : CollectionProperty(type=MetadataType)
task_types : CollectionProperty(type=TaskType) task_types : CollectionProperty(type=TaskType)
task_type_index : IntProperty()
task_statuses : CollectionProperty(type=TaskStatus) task_statuses : CollectionProperty(type=TaskStatus)
spreadsheet_import: PointerProperty(type=SpreadsheetImport) spreadsheet_import: PointerProperty(type=SpreadsheetImport)
@ -304,6 +306,12 @@ class Project(PropertyGroup):
type : StringProperty() type : StringProperty()
import_source: EnumProperty(items=[(i, i.title(), '') for i in ('DISK', 'TRACKER')])
import_task: EnumProperty(items=[(i, i.title(), '') for i in ('LAST', 'SELECTED', 'ALL')], default='LAST')
shot_dir_template: StringProperty(
name="Shot Template", default="$PROJECT_ROOT/sequences/{sequence}/sh{index:04d}")
@property @property
def active_episode(self): def active_episode(self):
return self.episodes.get(self.episode_name) return self.episodes.get(self.episode_name)
@ -582,7 +590,7 @@ class VSETB_PGT_scene_settings(PropertyGroup):
shot_channel_name : StringProperty( shot_channel_name : StringProperty(
name="Shot Channel Name", default="Shots") name="Shot Channel Name", default="Shots")
@property @property
def active_project(self): def active_project(self):
settings = get_scene_settings() settings = get_scene_settings()