diff --git a/constants.py b/constants.py index 14b265c..3b5945e 100644 --- a/constants.py +++ b/constants.py @@ -27,4 +27,6 @@ TASK_ITEMS = [] ASSET_PREVIEWS = bpy.utils.previews.new() -CASTING_BUFFER = CONFIG_DIR / 'casting.json' \ No newline at end of file +CASTING_BUFFER = CONFIG_DIR / 'casting.json' + +SPREADSHEET = [] \ No newline at end of file diff --git a/file_utils.py b/file_utils.py index 752c239..6db3700 100644 --- a/file_utils.py +++ b/file_utils.py @@ -140,4 +140,13 @@ def open_file(filepath, env=None, select=False): cmd += [str(filepath)] - subprocess.Popen(cmd, env=env) \ No newline at end of file + subprocess.Popen(cmd, env=env) + +def parse(string, template): + template = re.sub(r'{index:(.+?)}', r'(?P.+)', template) + reg = re.sub(r'{(.+?)}', r'(?P<_\1>.+)', template) + + values = list(re.search(reg, string).groups()) + keys = re.findall(r'{(.+?)}', template) + ['index'] + + return dict(zip(keys, values)) diff --git a/operators/casting.py b/operators/casting.py index d769a9c..90df794 100644 --- a/operators/casting.py +++ b/operators/casting.py @@ -210,6 +210,7 @@ class VSETB_OT_casting_move(Operator): return {"FINISHED"} + class VSETB_OT_copy_casting(Operator): bl_idname = "vse_toolbox.copy_casting" bl_label = "Copy Casting" diff --git a/operators/spreadsheet.py b/operators/spreadsheet.py index 414e75b..efff8e8 100644 --- a/operators/spreadsheet.py +++ b/operators/spreadsheet.py @@ -6,15 +6,18 @@ from datetime import datetime import os from pathlib import Path +from io import StringIO + import bpy from bpy.types import (Operator, Menu, OperatorFileListElement) from bpy.props import (EnumProperty, StringProperty, CollectionProperty) from bl_operators.presets import AddPresetBase -from vse_toolbox.sequencer_utils import (get_strips, get_strip_sequence_name) +from vse_toolbox.sequencer_utils import (get_strips, get_strip_sequence_name, get_channel_index) from vse_toolbox.bl_utils import (get_addon_prefs, get_scene_settings) -from vse_toolbox.file_utils import (open_file, install_module, fuzzy_match) +from vse_toolbox.file_utils import (open_file, install_module, fuzzy_match, norm_str) +from vse_toolbox.constants import SPREADSHEET class VSETB_MT_export_spreadsheet_presets(Menu): @@ -146,10 +149,12 @@ class VSETB_OT_spreadsheet_from_clipboard(Operator): import_cells = project.spreadsheet_import.cells import_cells.clear() + SPREADSHEET.clear() + spreadsheet = context.window_manager.clipboard cell_types = project.get_cell_types() - rows = list(csv.reader(spreadsheet.splitlines(), delimiter='\t')) + rows = list(csv.reader(StringIO(spreadsheet), delimiter='\t')) for cell_name in rows[0]: if not cell_name: continue @@ -161,7 +166,10 @@ class VSETB_OT_spreadsheet_from_clipboard(Operator): project.spreadsheet_import.use_custom_cells = True + SPREADSHEET.extend(rows) + return {"FINISHED"} + class VSETB_OT_import_spreadsheet(Operator): bl_idname = "vse_toolbox.import_spreadsheet" @@ -252,6 +260,121 @@ class VSETB_OT_import_spreadsheet(Operator): col.separator() def execute(self, context): + scn = context.scene + settings = get_scene_settings() + project = settings.active_project + spreadsheet = project.spreadsheet_import + sequencer = scn.sequence_editor.sequences + + # Import Edit + nb_frames_cell = next((c for c in spreadsheet.cells if c.import_name=='Nb Frames'), None) + + channel = get_channel_index('Shots') + + header = SPREADSHEET[0] + + cell_types = project.get_cell_types() + cell_names = {k: spreadsheet.cells[k].import_name for k in header if k} + + separator = spreadsheet.separator.replace('\\n', '\n').replace('\\t', '\t').replace('\\r', '\r') + + + + + + frame_start = scn.frame_start + for row in SPREADSHEET[1:]: + cell_data = {cell_names[k]: v for k, v in zip(header, row) if k} + #cell_data = {k: v for k, v in zip(header, row)} + shot_name = cell_data['Shot'] + nb_frames = int(cell_data['Nb Frames']) + + strip = next((s for s in sequencer if s.vsetb_strip_settings.source_name == shot_name), None) + + print("shot_name", shot_name, strip) + + if spreadsheet.update_edit and nb_frames_cell.enabled: + print('Import Edit') + + #print(frame_start, nb_frames, type(nb_frames)) + frame_end = frame_start + nb_frames + + if strip: + if frame_start != strip.frame_final_start or frame_end !=strip.frame_final_end: + print(f'The strip {strip.name} is updated with new range') + + strip.frame_final_start = frame_start + strip.frame_final_end = frame_end + else: + strip = sequencer.new_effect( + name=shot_name, + type='COLOR', + channel=channel, + frame_start=frame_start, + frame_end=frame_end, + ) + + strip.blend_alpha = 0.0 + strip.select = False + strip.vsetb_strip_settings.source_name = shot_name + + frame_start += nb_frames + + if not strip: + self.report({"WARNING"}, f'No strip found with source name {shot_name}, update the edit') + + strip_settings = strip.vsetb_strip_settings + + if spreadsheet.import_casting: + strip_settings.casting.clear() + + for cell_name, cell_value in zip(header, row): + if not cell_name: + continue + + cell = spreadsheet.cells[cell_name] + if not cell.enabled: + continue + + cell_type = cell_types[cell.import_name] + + if cell.import_name == 'Description' and spreadsheet.import_custom_data: + strip_settings.description = cell_value + + elif cell_type == 'METADATA' and spreadsheet.import_custom_data: + setattr(strip_settings.metadata, cell.import_name, cell_value) + + if cell_type == 'ASSET_TYPE' and spreadsheet.import_casting: + + print(cell_value) + asset_names = cell_value.split('\n') + + # Clear the list of assets + #for asset_casting in list(strip_settings.casting): + # if asset_casting.asset.asset_type == cell_name: + # strip_settings.casting.remove(asset_casting) + for asset_name in asset_names: + if not asset_name: + continue + + print(asset_name) + + asset = next((a for a in project.assets if norm_str(a.tracker_name) == norm_str(asset_name)), None) + if asset: + item = strip_settings.casting.add() + item.name = asset.name + item.id = asset.id + item['_name'] = asset.label + + strip_settings.casting.update() + else: + self.report({'WARNING'}, f'Asset {asset_name} not found in Project') + + + + + + return {"FINISHED"} diff --git a/sequencer_utils.py b/sequencer_utils.py index 96411c4..7e41de3 100644 --- a/sequencer_utils.py +++ b/sequencer_utils.py @@ -8,7 +8,7 @@ import bpy from bpy.app.handlers import persistent from vse_toolbox.bl_utils import get_scene_settings, get_strip_settings -from vse_toolbox.file_utils import install_module +from vse_toolbox.file_utils import install_module, parse from vse_toolbox.constants import SOUND_SUFFIXES #import multiprocessing #from multiprocessing.pool import ThreadPool @@ -130,10 +130,24 @@ def set_channels(): def get_strip_render_path(strip, template): scn = bpy.context.scene + settings = get_scene_settings() + project = settings.active_project + suffix = Path(scn.render.frame_path()).suffix - render_path = template.format(strip_name=strip.name, ext=suffix[1:]) + + strip_data = parse(strip.name, template=project.shot_template) + + print(strip_data) + + index = int(strip_data['index']) + + sequence = get_strip_sequence_name(strip) + render_path = template.format(episode=project.episode_name, sequence=sequence, + strip=strip.name, index=index, ext=suffix[1:]) + return Path(os.path.abspath(bpy.path.abspath(render_path))) + ''' # def render_strip_background(blender_path, filepath, start, end, output): # cmd = [ diff --git a/ui/panels.py b/ui/panels.py index 7d861a6..ce5d2c0 100644 --- a/ui/panels.py +++ b/ui/panels.py @@ -68,6 +68,23 @@ class VSETB_PT_main(VSETB_main, Panel): # Rename +class VSETB_PT_strip(Panel): + bl_space_type = "SEQUENCE_EDITOR" + bl_region_type = "UI" + bl_category = "Strip" + bl_label = "VSE ToolBox" + #bl_order = 0 + + def draw(self, context): + prefs = get_addon_prefs() + layout = self.layout + settings = get_strip_settings() + + layout.use_property_split = True + layout.use_property_decorate = False + + layout.prop(settings, 'source_name', text='Source Name') + class VSETB_PT_sequencer(VSETB_main, Panel): bl_label = "Sequencer" @@ -324,6 +341,7 @@ classes = ( VSETB_PT_metadata, VSETB_PT_presets, VSETB_PT_exports, + VSETB_PT_strip ) def register(): diff --git a/ui/properties.py b/ui/properties.py index 6bae9ab..7bf9e40 100644 --- a/ui/properties.py +++ b/ui/properties.py @@ -265,7 +265,7 @@ class Project(PropertyGroup): project = settings.active_project cell_types = {} - cell_names = ['Sequence', 'Shot', 'Frames', 'Description'] + cell_names = ['Sequence', 'Shot', 'Nb Frames', 'Description'] if project.type == 'TVSHOW': cell_names.insert(0, 'Episode') @@ -283,7 +283,7 @@ class Project(PropertyGroup): def set_spreadsheet(self): - cell_names = ['Sequence', 'Shot', 'Frames', 'Description'] + cell_names = ['Sequence', 'Shot', 'Nb Frames', 'Description'] if self.type == 'TVSHOW': cell_names.insert(0, 'Episode') @@ -418,7 +418,7 @@ class VSETB_UL_spreadsheet_import(UIList): enabled = False elif item_type == 'ASSET_TYPE' and not project.spreadsheet_import.import_casting: enabled = False - elif item.import_name == 'Frames' and not project.spreadsheet_import.update_edit: + elif item.import_name == 'Nb Frames' and not project.spreadsheet_import.update_edit: enabled = False layout.enabled = enabled