export background
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
from vse_toolbox.operators import (addon, casting, imports, render, sequencer,
|
||||
from vse_toolbox.operators import (addon, casting, imports, exports, sequencer,
|
||||
spreadsheet, tracker)
|
||||
|
||||
modules = (
|
||||
addon,
|
||||
casting,
|
||||
imports,
|
||||
render,
|
||||
exports,
|
||||
sequencer,
|
||||
spreadsheet,
|
||||
tracker
|
||||
|
||||
+35
-9
@@ -2,7 +2,7 @@
|
||||
import json
|
||||
|
||||
import bpy
|
||||
from bpy.types import PropertyGroup, Operator
|
||||
from bpy.types import Context, Event, PropertyGroup, Operator
|
||||
from bpy.props import (CollectionProperty, EnumProperty, StringProperty)
|
||||
|
||||
from vse_toolbox.constants import CASTING_BUFFER
|
||||
@@ -249,15 +249,27 @@ class VSETB_OT_copy_casting(Operator):
|
||||
class VSETB_OT_paste_casting(Operator):
|
||||
bl_idname = "vse_toolbox.paste_casting"
|
||||
bl_label = "Paste Casting"
|
||||
bl_description = "Paste Casting to active strip"
|
||||
bl_description = "Paste Casting to active strip (ctrl|shift: Add, alt:Remove)"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
mode : EnumProperty(items=[(m, m.title(), '') for m in ('REPLACE', 'ADD', 'REMOVE')])
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
active_strip = context.scene.sequence_editor.active_strip
|
||||
if active_strip:
|
||||
return True
|
||||
|
||||
def invoke(self, context, event):
|
||||
self.mode = 'REPLACE'
|
||||
|
||||
if event.ctrl or event.shift:
|
||||
self.mode = 'ADD'
|
||||
elif event.alt:
|
||||
self.mode = 'REMOVE'
|
||||
|
||||
return self.execute(context)
|
||||
|
||||
def execute(self, context):
|
||||
scn = context.scene
|
||||
strip_settings = get_strip_settings()
|
||||
@@ -267,19 +279,33 @@ class VSETB_OT_paste_casting(Operator):
|
||||
return {"CANCELLED"}
|
||||
|
||||
casting_datas = json.loads(CASTING_BUFFER.read_text())
|
||||
casting_ids = set(c['id'] for c in casting_datas)
|
||||
|
||||
for strip in context.selected_sequences:
|
||||
strip_settings = strip.vsetb_strip_settings
|
||||
strip.vsetb_strip_settings.casting.clear()
|
||||
|
||||
if self.mode == 'REPLACE':
|
||||
strip.vsetb_strip_settings.casting.clear()
|
||||
|
||||
for casting_data in casting_datas:
|
||||
|
||||
item = strip.vsetb_strip_settings.casting.add()
|
||||
if self.mode == 'REMOVE':
|
||||
|
||||
for asset_casting in strip_settings.casting:
|
||||
index = list(strip_settings.casting).index(asset_casting)
|
||||
if asset_casting.id in casting_ids:
|
||||
strip_settings.casting.remove(index)
|
||||
|
||||
item.name = casting_data['name']
|
||||
item.id = casting_data['id']
|
||||
item['_name'] = casting_data['_name']
|
||||
if strip_settings.casting_index != 0:
|
||||
strip_settings.casting_index -= 1
|
||||
|
||||
strip_settings.casting.update()
|
||||
else:
|
||||
item = strip.vsetb_strip_settings.casting.add()
|
||||
|
||||
item.name = casting_data['name']
|
||||
item.id = casting_data['id']
|
||||
item['_name'] = casting_data['_name']
|
||||
|
||||
strip_settings.casting.update()
|
||||
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
|
||||
import time
|
||||
import re
|
||||
from pathlib import Path
|
||||
import os
|
||||
|
||||
import bpy
|
||||
from bpy.types import Operator
|
||||
from bpy.props import BoolProperty
|
||||
|
||||
from vse_toolbox.sequencer_utils import (get_strips, render_strip)
|
||||
from vse_toolbox.bl_utils import (get_scene_settings, background_render)
|
||||
from vse_toolbox.file_utils import install_module
|
||||
|
||||
|
||||
|
||||
class VSETB_OT_render(Operator):
|
||||
bl_idname = "vse_toolbox.strips_render"
|
||||
bl_label = "Render Shots Strips"
|
||||
bl_description = "Render Shots Strips"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
#selected_only : BoolProperty(name="Selected Only", default=False)
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
settings = get_scene_settings()
|
||||
return settings.active_project
|
||||
|
||||
def invoke(self, context, event):
|
||||
scn = context.scene
|
||||
settings = get_scene_settings()
|
||||
|
||||
return context.window_manager.invoke_props_dialog(self)
|
||||
|
||||
def draw(self, context):
|
||||
scn = context.scene
|
||||
settings = get_scene_settings()
|
||||
|
||||
layout = self.layout
|
||||
col = layout.column()
|
||||
#col.use_property_split = True
|
||||
#col.use_property_decorate = False
|
||||
|
||||
col.prop(settings.active_project, "render_single_file")
|
||||
row = col.row()
|
||||
row.enabled = settings.active_project.render_single_file
|
||||
row.prop(settings.active_project, "render_template")
|
||||
|
||||
col.separator()
|
||||
col.prop(settings.active_project, "render_per_strip")
|
||||
row = col.row()
|
||||
row.enabled = settings.active_project.render_per_strip
|
||||
row.prop(settings.active_project, "render_strip_template")
|
||||
|
||||
#col.prop(settings, 'channel', text='Channel')
|
||||
#col.prop(self, 'selected_only')
|
||||
|
||||
def execute(self, context):
|
||||
scn = context.scene
|
||||
settings = get_scene_settings()
|
||||
project = settings.active_project
|
||||
|
||||
format_data = {**settings.format_data, **project.format_data}
|
||||
|
||||
start_time = time.perf_counter()
|
||||
if project.render_single_file:
|
||||
render_path = project.render_template.format(**format_data)
|
||||
background_render(output=render_path)
|
||||
|
||||
if project.render_per_strip:
|
||||
for strip in get_strips(channel='Shots', selected_only=True):
|
||||
strip_settings = strip.vsetb_strip_settings
|
||||
strip_data = {**format_data, **strip_settings.format_data}
|
||||
strip_render_path = project.render_strip_template.format(**strip_data)
|
||||
render_strip(strip, strip_render_path)
|
||||
|
||||
self.report({"INFO"}, f'Strips rendered in {time.perf_counter()-start_time} seconds')
|
||||
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class VSETB_OT_export_edl(Operator):
|
||||
bl_idname = "vse_toolbox.export_edl"
|
||||
bl_label = "Export Edl"
|
||||
bl_description = "Export Edl"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
#selected_only : BoolProperty(name="Selected Only", default=False)
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
settings = get_scene_settings()
|
||||
return settings.active_project
|
||||
|
||||
def invoke(self, context, event):
|
||||
scn = context.scene
|
||||
settings = get_scene_settings()
|
||||
|
||||
return context.window_manager.invoke_props_dialog(self)
|
||||
|
||||
def draw(self, context):
|
||||
scn = context.scene
|
||||
settings = get_scene_settings()
|
||||
|
||||
layout = self.layout
|
||||
col = layout.column()
|
||||
col.use_property_split = True
|
||||
col.use_property_decorate = False
|
||||
#col.prop(settings, 'channel', text='Channel')
|
||||
#col.prop(self, 'selected_only')
|
||||
|
||||
col.prop(settings.active_project, "export_edl_template")
|
||||
|
||||
def execute(self, context):
|
||||
opentimelineio = install_module('opentimelineio')
|
||||
|
||||
from opentimelineio.schema import (Clip, Timeline, Track, ExternalReference)
|
||||
from opentimelineio.opentime import (RationalTime, TimeRange)
|
||||
|
||||
start_time = time.perf_counter()
|
||||
|
||||
scn = context.scene
|
||||
settings = get_scene_settings()
|
||||
fps = scn.render.fps
|
||||
|
||||
project = settings.active_project
|
||||
|
||||
format_data = {**settings.format_data, **project.format_data}
|
||||
output_edl = project.export_edl_template.format(**format_data)
|
||||
output_edl = os.path.abspath(bpy.path.abspath(output_edl))
|
||||
output_edl = Path(output_edl)
|
||||
|
||||
|
||||
timeline = Timeline(output_edl.stem)
|
||||
track = Track(f"Track 1")
|
||||
track.kind = "Video"
|
||||
|
||||
timeline.tracks.append(track)
|
||||
|
||||
for strip in get_strips(channel='Shots', selected_only=False):
|
||||
strip_data = {**format_data, **strip.vsetb_strip_settings.format_data}
|
||||
strip_render_path = project.render_strip_template.format(**strip_data)
|
||||
|
||||
clip = Clip(Path(strip_render_path).name)
|
||||
|
||||
clip.metadata.setdefault("cmx_3600", {})
|
||||
clip.metadata['cmx_3600']['reel'] = strip.name
|
||||
#clip.metadata['cmx_3600']['flags'] = 'IS_CLIP'
|
||||
|
||||
#clip.media_reference = ExternalReference(f'//render/{strip.name}.mov')
|
||||
#clip.media_reference.name = strip.name
|
||||
|
||||
#clip.available_range = TimeRange(RationalTime(0, fps), RationalTime(strip.frame_duration, fps))
|
||||
clip.source_range = TimeRange(RationalTime(strip.frame_offset_start, fps), RationalTime(strip.frame_final_duration, fps))
|
||||
|
||||
track.append(clip)
|
||||
|
||||
output_edl.parent.mkdir(exist_ok=True, parents=True)
|
||||
|
||||
edl = opentimelineio.adapters.write_to_string(timeline, 'cmx_3600')
|
||||
output_edl.write_text(edl)
|
||||
#opentimelineio.adapters.write_to_file(timeline, str(output_edl), 'cmx_3600')
|
||||
|
||||
self.report({"INFO"}, f'Edl Exported in {time.perf_counter()-start_time} seconds')
|
||||
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
|
||||
|
||||
classes = (
|
||||
VSETB_OT_render,
|
||||
VSETB_OT_export_edl
|
||||
)
|
||||
|
||||
def register():
|
||||
for cls in classes:
|
||||
bpy.utils.register_class(cls)
|
||||
|
||||
def unregister():
|
||||
for cls in reversed(classes):
|
||||
bpy.utils.unregister_class(cls)
|
||||
@@ -1,70 +0,0 @@
|
||||
|
||||
import time
|
||||
|
||||
import bpy
|
||||
from bpy.types import Operator
|
||||
|
||||
from vse_toolbox.sequencer_utils import (get_strips, render_strips)
|
||||
from vse_toolbox.bl_utils import get_scene_settings
|
||||
|
||||
|
||||
|
||||
class VSETB_OT_render(Operator):
|
||||
bl_idname = "vse_toolbox.strips_render"
|
||||
bl_label = "Render Shots Strips"
|
||||
bl_description = "Render Shots Strips"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
#selected_only : BoolProperty(name="Selected Only", default=False)
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
settings = get_scene_settings()
|
||||
return settings.active_project
|
||||
|
||||
def invoke(self, context, event):
|
||||
scn = context.scene
|
||||
settings = get_scene_settings()
|
||||
|
||||
return context.window_manager.invoke_props_dialog(self)
|
||||
|
||||
def draw(self, context):
|
||||
scn = context.scene
|
||||
settings = get_scene_settings()
|
||||
|
||||
layout = self.layout
|
||||
col = layout.column()
|
||||
col.use_property_split = True
|
||||
col.use_property_decorate = False
|
||||
#col.prop(settings, 'channel', text='Channel')
|
||||
#col.prop(self, 'selected_only')
|
||||
|
||||
col.prop(settings.active_project, "render_template")
|
||||
|
||||
def execute(self, context):
|
||||
scn = context.scene
|
||||
settings = get_scene_settings()
|
||||
strips = get_strips(channel='Shots', selected_only=True)
|
||||
|
||||
start_time = time.perf_counter()
|
||||
render_strips(strips, settings.active_project.render_template)
|
||||
|
||||
self.report({"INFO"}, f'Strips rendered in {time.perf_counter()-start_time} seconds')
|
||||
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
classes = (
|
||||
VSETB_OT_render,
|
||||
)
|
||||
|
||||
def register():
|
||||
for cls in classes:
|
||||
bpy.utils.register_class(cls)
|
||||
|
||||
def unregister():
|
||||
for cls in reversed(classes):
|
||||
bpy.utils.unregister_class(cls)
|
||||
+53
-14
@@ -171,6 +171,40 @@ class VSETB_OT_spreadsheet_from_clipboard(Operator):
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class VSETB_OT_spreadsheet_to_clipboard(Operator):
|
||||
bl_idname = "vse_toolbox.spreadsheet_to_clipboard"
|
||||
bl_label = "Copy Spreadsheet to clipboard"
|
||||
bl_description = "Copy Spreadsheet to clipboard"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
scn = context.scene
|
||||
project = get_scene_settings().active_project
|
||||
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(StringIO(spreadsheet), delimiter='\t'))
|
||||
for cell_name in rows[0]:
|
||||
if not cell_name:
|
||||
continue
|
||||
|
||||
cell = import_cells.add()
|
||||
cell.name = cell_name
|
||||
cell.import_name = max(cell_types.keys(), key=lambda x: fuzzy_match(cell_name, x))
|
||||
cell.enabled = True
|
||||
|
||||
project.spreadsheet_import.use_custom_cells = True
|
||||
|
||||
SPREADSHEET.extend(rows)
|
||||
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class VSETB_OT_import_spreadsheet(Operator):
|
||||
bl_idname = "vse_toolbox.import_spreadsheet"
|
||||
bl_label = "Import Spreadsheet"
|
||||
@@ -368,13 +402,7 @@ class VSETB_OT_import_spreadsheet(Operator):
|
||||
|
||||
strip_settings.casting.update()
|
||||
else:
|
||||
self.report({'WARNING'}, f'Asset {asset_name} not found in Project')
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
self.report({'WARNING'}, f'Asset {asset_name} not found in Project')
|
||||
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -446,12 +474,13 @@ class VSETB_OT_export_spreadsheet(Operator):
|
||||
row.prop(spreadsheet, 'show_settings', text='', icon='PREFERENCES')
|
||||
if spreadsheet.show_settings:
|
||||
col.prop(spreadsheet, "separator", expand=True, text='Separator')
|
||||
if spreadsheet.format == 'CSV':
|
||||
if spreadsheet.format == 'csv':
|
||||
col.prop(spreadsheet, "delimiter", expand=True, text='Delimiter')
|
||||
|
||||
col.separator()
|
||||
col.prop(spreadsheet, 'open_folder', text='Open Folder')
|
||||
col.prop(spreadsheet, 'export_path', text='Export Path')
|
||||
if spreadsheet.format != 'Clipboard':
|
||||
col.separator()
|
||||
col.prop(spreadsheet, 'open_folder', text='Open Folder')
|
||||
col.prop(spreadsheet, 'export_path', text='Export Path')
|
||||
|
||||
def execute(self, context):
|
||||
#self.report({'ERROR'}, f'Export not implemented yet.')
|
||||
@@ -499,7 +528,7 @@ class VSETB_OT_export_spreadsheet(Operator):
|
||||
row += [strip.name]
|
||||
elif cell.field_name == 'DESCRIPTION':
|
||||
row += [strip.vsetb_strip_settings.description]
|
||||
elif cell.field_name == 'FRAMES':
|
||||
elif cell.field_name == 'NB_FRAMES':
|
||||
row += [strip.frame_final_duration]
|
||||
|
||||
rows.append(row)
|
||||
@@ -531,14 +560,14 @@ class VSETB_OT_export_spreadsheet(Operator):
|
||||
#2023_04_11_kitsu_boris_ep01_shots
|
||||
export_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
if spreadsheet.format == 'CSV':
|
||||
if spreadsheet.format == 'csv':
|
||||
print('Writing .csv file to', export_path)
|
||||
with open(str(export_path), 'w', newline='\n', encoding='utf-8') as f:
|
||||
writer = csv.writer(f, delimiter=spreadsheet.delimiter)
|
||||
for row in rows:
|
||||
writer.writerow(row)
|
||||
|
||||
elif spreadsheet.format == 'XLSX':
|
||||
elif spreadsheet.format == 'xlsx':
|
||||
try:
|
||||
import openpyxl
|
||||
except ModuleNotFoundError:
|
||||
@@ -558,6 +587,15 @@ class VSETB_OT_export_spreadsheet(Operator):
|
||||
|
||||
# Save the file
|
||||
workbook.save(str(export_path))
|
||||
|
||||
elif spreadsheet.format == 'Clipboard':
|
||||
csv_buffer = StringIO()
|
||||
|
||||
# Write CSV data to the StringIO buffer
|
||||
csv_writer = csv.writer(csv_buffer, delimiter='\t')
|
||||
csv_writer.writerows(rows)
|
||||
|
||||
context.window_manager.clipboard = csv_buffer.getvalue()
|
||||
|
||||
if spreadsheet.open_folder:
|
||||
open_file(export_path, select=True)
|
||||
@@ -570,6 +608,7 @@ classes = (
|
||||
VSETB_MT_export_spreadsheet_presets,
|
||||
VSETB_OT_spreadsheet_from_file,
|
||||
VSETB_OT_spreadsheet_from_clipboard,
|
||||
VSETB_OT_spreadsheet_to_clipboard,
|
||||
VSETB_OT_spreadsheet_cell_move,
|
||||
VSETB_OT_export_spreadsheet,
|
||||
VSETB_OT_import_spreadsheet
|
||||
|
||||
Reference in New Issue
Block a user