Export Csv
parent
299c240385
commit
02785f9ec0
|
@ -5,6 +5,12 @@ import importlib
|
||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
import time
|
import time
|
||||||
|
from pprint import pprint
|
||||||
|
import csv
|
||||||
|
from datetime import datetime
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
import vse_toolbox
|
import vse_toolbox
|
||||||
|
|
||||||
from bpy_extras.io_utils import ImportHelper
|
from bpy_extras.io_utils import ImportHelper
|
||||||
|
@ -77,20 +83,122 @@ class VSETB_OT_tracker_connect(Operator):
|
||||||
return {"CANCELLED"}
|
return {"CANCELLED"}
|
||||||
|
|
||||||
|
|
||||||
class VSETB_OT_export_csv(Operator):
|
class VSETB_OT_export_spreadsheet(Operator):
|
||||||
bl_idname = "vse_toolbox.export_csv"
|
bl_idname = "vse_toolbox.export_spreadsheet"
|
||||||
bl_label = "Set Scene"
|
bl_label = "Export Spreadsheet"
|
||||||
bl_description = "Set Scene for Breakdown"
|
bl_description = "Export Shot data in a table as a csv or an xlsl"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
|
format : EnumProperty(items=[(i, i, '') for i in ('CSV', 'XLSL')])
|
||||||
|
separator : StringProperty(default='\\n')
|
||||||
|
delimiter : StringProperty(default=';')
|
||||||
|
export_path : StringProperty(default='//export')
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def poll(cls, context):
|
def poll(cls, context):
|
||||||
return True
|
settings = get_scene_settings()
|
||||||
|
return settings.active_project
|
||||||
|
|
||||||
|
def invoke(self, context, event):
|
||||||
|
settings = get_scene_settings()
|
||||||
|
project = settings.active_project
|
||||||
|
|
||||||
|
return context.window_manager.invoke_props_dialog(self)
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
scn = context.scene
|
||||||
|
settings = get_scene_settings()
|
||||||
|
project = settings.active_project
|
||||||
|
|
||||||
|
layout = self.layout
|
||||||
|
|
||||||
|
row = layout.row()
|
||||||
|
row.template_list("VSETB_UL_spreadsheet", "spreadsheet", project, "spreadsheet", project, "spreadsheet_index", rows=8)
|
||||||
|
|
||||||
|
col_tool = row.column(align=True)
|
||||||
|
col_tool.operator('vse_toolbox.spreadsheet_move', icon='TRIA_UP', text="").direction = 'UP'
|
||||||
|
col_tool.operator('vse_toolbox.spreadsheet_move', icon='TRIA_DOWN', text="").direction = 'DOWN'
|
||||||
|
|
||||||
|
col = layout.column()
|
||||||
|
col.use_property_split = True
|
||||||
|
|
||||||
|
col.prop(self, "separator", expand=True, text='Separator')
|
||||||
|
row = col.row(align=True)
|
||||||
|
row.prop(self, "format", expand=True, text='Format')
|
||||||
|
if self.format == 'CSV':
|
||||||
|
col.prop(self, "delimiter", expand=True, text='Delimiter')
|
||||||
|
|
||||||
|
col.prop(self, 'export_path')
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
self.report({'ERROR'}, f'Export not implemented yet.')
|
#self.report({'ERROR'}, f'Export not implemented yet.')
|
||||||
|
prefs = get_addon_prefs()
|
||||||
|
settings = get_scene_settings()
|
||||||
|
project = settings.active_project
|
||||||
|
episode = settings.active_episode
|
||||||
|
|
||||||
return {"CANCELLED"}
|
cells = [cell for cell in project.spreadsheet if cell.enabled]
|
||||||
|
rows = []
|
||||||
|
|
||||||
|
# Header
|
||||||
|
rows.append([cell.export_name for cell in cells])
|
||||||
|
|
||||||
|
for strip in get_strips('Shots'):
|
||||||
|
row = []
|
||||||
|
for cell in cells:
|
||||||
|
if cell.is_metadata:
|
||||||
|
row += [getattr(strip.vsetb_strip_settings.metadata, cell.field_name)]
|
||||||
|
elif cell.field_name == 'EPISODE':
|
||||||
|
row += [settings.active_episode.name]
|
||||||
|
elif cell.field_name == 'SEQUENCE':
|
||||||
|
row += [get_strip_sequence_name(strip)]
|
||||||
|
elif cell.field_name == 'SHOT':
|
||||||
|
row += [strip.name]
|
||||||
|
elif cell.field_name == 'DESCRIPTION':
|
||||||
|
row += [strip.vsetb_strip_settings.description]
|
||||||
|
elif cell.field_name == 'FRAMES':
|
||||||
|
row += [strip.frame_final_duration]
|
||||||
|
|
||||||
|
rows.append(row)
|
||||||
|
|
||||||
|
#print(rows)
|
||||||
|
|
||||||
|
export_path = Path(os.path.abspath(bpy.path.abspath(self.export_path)))
|
||||||
|
export_name = export_path.name
|
||||||
|
|
||||||
|
if export_path.suffix or export_name.endswith('{ext}'):
|
||||||
|
export_path = export_path.parent
|
||||||
|
|
||||||
|
else: # It's a directory
|
||||||
|
if project.type == 'TVSHOW':
|
||||||
|
export_name = '{date}_{project}_{episode}_{tracker}_shots.{ext}'
|
||||||
|
else:
|
||||||
|
export_name = '{date}_{project}_{tracker}_shots.{ext}'
|
||||||
|
|
||||||
|
date = datetime.now().strftime('%Y_%m_%d')
|
||||||
|
project_name = project.name.replace(' ', '_').lower()
|
||||||
|
episode_name = episode.name.replace(' ', '_').lower() if episode else 'episode'
|
||||||
|
ext = self.format.lower()
|
||||||
|
|
||||||
|
export_name = export_name.format(date=date, project=project_name,
|
||||||
|
episode=episode_name, tracker=settings.tracker_name.lower(), ext=ext)
|
||||||
|
|
||||||
|
export_path = export_path / export_name
|
||||||
|
|
||||||
|
#2023_04_11_kitsu_boris_ep01_shots
|
||||||
|
export_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
print('Writing .csv file to', export_path)
|
||||||
|
with open(str(export_path), 'w', newline='\n', encoding='utf-8') as f:
|
||||||
|
writer = csv.writer(f)
|
||||||
|
for row in rows:
|
||||||
|
writer.writerow(row)
|
||||||
|
|
||||||
|
#if show_in_explorer:
|
||||||
|
# open_file(filepath, select=True)
|
||||||
|
|
||||||
|
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
def get_task_status_items(self, context):
|
def get_task_status_items(self, context):
|
||||||
|
@ -118,11 +226,12 @@ class VSETB_OT_upload_to_tracker(Operator):
|
||||||
bl_description = "Upload selected strip to tracker"
|
bl_description = "Upload selected strip to tracker"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
task: EnumProperty(items=get_task_type_items)
|
task : EnumProperty(items=get_task_type_items)
|
||||||
status: EnumProperty(items=get_task_status_items)
|
status : EnumProperty(items=get_task_status_items)
|
||||||
comment : StringProperty()
|
comment : StringProperty()
|
||||||
add_preview : BoolProperty(default=False)
|
add_preview : BoolProperty(default=True)
|
||||||
preview_mode : EnumProperty(items=[(m, m.title().replace('_', ' '), '') for m in ('ONLY_NEW', 'REPLACE', 'ADD')])
|
preview_mode : EnumProperty(items=[(m, m.title().replace('_', ' '), '') for m in ('ONLY_NEW', 'REPLACE', 'ADD')])
|
||||||
|
set_main_preview : BoolProperty(default=True)
|
||||||
casting : BoolProperty(default=True)
|
casting : BoolProperty(default=True)
|
||||||
custom_data : BoolProperty(default=True)
|
custom_data : BoolProperty(default=True)
|
||||||
|
|
||||||
|
@ -174,10 +283,8 @@ class VSETB_OT_upload_to_tracker(Operator):
|
||||||
sequence_name = get_strip_sequence_name(strip)
|
sequence_name = get_strip_sequence_name(strip)
|
||||||
shot_name = strip.name
|
shot_name = strip.name
|
||||||
sequence = tracker.get_sequence(sequence_name)
|
sequence = tracker.get_sequence(sequence_name)
|
||||||
|
|
||||||
|
|
||||||
metadata = strip.vsetb_strip_settings.metadata.to_dict()
|
metadata = strip.vsetb_strip_settings.metadata.to_dict()
|
||||||
print(metadata)
|
#print(metadata)
|
||||||
|
|
||||||
if not sequence:
|
if not sequence:
|
||||||
self.report({"INFO"}, f'Create sequence {sequence_name} in Kitsu')
|
self.report({"INFO"}, f'Create sequence {sequence_name} in Kitsu')
|
||||||
|
@ -198,49 +305,33 @@ class VSETB_OT_upload_to_tracker(Operator):
|
||||||
preview = None
|
preview = None
|
||||||
if self.add_preview:
|
if self.add_preview:
|
||||||
preview = Path(get_strip_render_path(strip, project.render_template))
|
preview = Path(get_strip_render_path(strip, project.render_template))
|
||||||
|
#print(preview)
|
||||||
if not preview.exists():
|
if not preview.exists():
|
||||||
preview = None
|
preview = None
|
||||||
|
|
||||||
elif task['last_comment'].get('previews'):
|
elif task.get('last_comment') and task['last_comment']['previews']:
|
||||||
if self.preview_mode == 'REPLACE':
|
if self.preview_mode == 'REPLACE':
|
||||||
tracker.remove_comment(task['last_comment'])
|
tracker.remove_comment(task['last_comment'])
|
||||||
elif self.preview_mode == 'ONLY_NEW':
|
elif self.preview_mode == 'ONLY_NEW':
|
||||||
preview = None
|
preview = None
|
||||||
|
|
||||||
if status != 'CURRENT' or preview:
|
#print(f'{preview=}')
|
||||||
tracker.new_comment(task, comment=self.comment, status=status, preview=preview)
|
#print(f'{status=}')
|
||||||
|
if status or preview:
|
||||||
|
tracker.new_comment(task, comment=self.comment, status=status, preview=preview, set_main_preview=self.set_main_preview)
|
||||||
|
|
||||||
if self.custom_data:
|
if self.custom_data:
|
||||||
tracker.update_data(shot, strip.vsetb_strip_settings.metadata.to_dict())
|
metadata = strip.vsetb_strip_settings.metadata.to_dict()
|
||||||
|
description = strip.vsetb_strip_settings.description
|
||||||
|
tracker.update_data(shot, metadata, frames=strip.frame_final_duration, description=description)
|
||||||
|
|
||||||
|
if self.casting:
|
||||||
|
casting = [{'asset_id': a.id, 'nb_occurences': a.instance} for a in strip.vsetb_strip_settings.casting]
|
||||||
|
tracker.update_casting(shot, casting)
|
||||||
|
|
||||||
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
# if add_to_kitsu:
|
|
||||||
# shot_name = T['shot_tracker_name'].fields['shot'].format(data['shot'])
|
|
||||||
# seq_name = T['sequence_tracker_name'].fields['sequence'].format(data['sequence'])
|
|
||||||
# sequence = p.sequences.add(seq_name)
|
|
||||||
# shot = sequence.shots.add(shot_name)
|
|
||||||
# animatic_task = shot.tasks.add('animatic')
|
|
||||||
|
|
||||||
# animatic_task.comments.new(
|
|
||||||
# comment=f'Reel edit v{version:03d}',
|
|
||||||
# status='done',
|
|
||||||
# preview=movie_output,
|
|
||||||
# set_main_preview=True
|
|
||||||
# )
|
|
||||||
|
|
||||||
# shot_data = {
|
|
||||||
# 'fps': int(FPS),
|
|
||||||
# 'frame_in': strip.frame_final_start,
|
|
||||||
# 'frame_out': strip.frame_final_end-1,
|
|
||||||
# 'nb_frames': strip.frame_final_duration
|
|
||||||
# }
|
|
||||||
|
|
||||||
# shot.update_data(shot_data)
|
|
||||||
|
|
||||||
# return {"CANCELLED"}
|
|
||||||
|
|
||||||
|
|
||||||
class VSETB_OT_auto_select_files(Operator):
|
class VSETB_OT_auto_select_files(Operator):
|
||||||
bl_idname = "import.auto_select_files"
|
bl_idname = "import.auto_select_files"
|
||||||
|
@ -485,9 +576,10 @@ class VSETB_OT_load_projects(Operator):
|
||||||
episode.id = episode_data['id']
|
episode.id = episode_data['id']
|
||||||
|
|
||||||
for metadata_data in tracker.get_shots_metadata(project_data):
|
for metadata_data in tracker.get_shots_metadata(project_data):
|
||||||
#print(metadata_data)
|
pprint(metadata_data)
|
||||||
metadata_type = project.metadata_types.add()
|
metadata_type = project.metadata_types.add()
|
||||||
metadata_type.name = metadata_data['field_name']
|
metadata_type.name = metadata_data['name']
|
||||||
|
metadata_type.field_name = metadata_data['field_name']
|
||||||
metadata_type['choices'] = metadata_data['choices']
|
metadata_type['choices'] = metadata_data['choices']
|
||||||
|
|
||||||
for status_data in tracker.get_task_statuses(project_data):
|
for status_data in tracker.get_task_statuses(project_data):
|
||||||
|
@ -502,12 +594,14 @@ class VSETB_OT_load_projects(Operator):
|
||||||
for asset_type_data in tracker.get_asset_types(project_data):
|
for asset_type_data in tracker.get_asset_types(project_data):
|
||||||
asset_type = project.asset_types.add()
|
asset_type = project.asset_types.add()
|
||||||
asset_type.name = asset_type_data['name']
|
asset_type.name = asset_type_data['name']
|
||||||
|
|
||||||
|
project.set_spreadsheet()
|
||||||
|
|
||||||
for project in settings.projects:
|
for project in settings.projects:
|
||||||
print(project.name, project.name.replace(' ', '_').upper(), old_project_name)
|
#print(project.name, project.name.replace(' ', '_').upper(), old_project_name)
|
||||||
if project.name.replace(' ', '_').upper() == old_project_name:
|
if project.name.replace(' ', '_').upper() == old_project_name:
|
||||||
|
|
||||||
print('Restore Project Name')
|
#print('Restore Project Name')
|
||||||
settings.project_name = project.name
|
settings.project_name = project.name
|
||||||
#else:
|
#else:
|
||||||
# print('Could Not restore Project Name')
|
# print('Could Not restore Project Name')
|
||||||
|
@ -545,8 +639,8 @@ class VSETB_OT_new_episode(Operator):
|
||||||
|
|
||||||
episode_name = settings.episode_template.format(index=int(self.episode_name))
|
episode_name = settings.episode_template.format(index=int(self.episode_name))
|
||||||
|
|
||||||
print(self.episode_name)
|
#print(self.episode_name)
|
||||||
print('episode_name: ', episode_name)
|
#print('episode_name: ', episode_name)
|
||||||
|
|
||||||
episode = tracker.get_episode(episode_name)
|
episode = tracker.get_episode(episode_name)
|
||||||
if episode:
|
if episode:
|
||||||
|
@ -805,11 +899,11 @@ class VSETB_OT_casting_remove(Operator):
|
||||||
|
|
||||||
class VSETB_OT_casting_move(Operator):
|
class VSETB_OT_casting_move(Operator):
|
||||||
bl_idname = "vse_toolbox.casting_move"
|
bl_idname = "vse_toolbox.casting_move"
|
||||||
bl_label = "Casting Actions"
|
bl_label = "Move Casting items"
|
||||||
bl_description = "Actions to Add, Remove, Move casting items"
|
bl_description = "Move Casting items"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
action: EnumProperty(
|
direction: EnumProperty(
|
||||||
items=(
|
items=(
|
||||||
('UP', "Up", ""),
|
('UP', "Up", ""),
|
||||||
('DOWN', "Down", ""),
|
('DOWN', "Down", ""),
|
||||||
|
@ -824,7 +918,7 @@ class VSETB_OT_casting_move(Operator):
|
||||||
if active_strip:
|
if active_strip:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def execute(self, context):
|
||||||
scn = context.scene
|
scn = context.scene
|
||||||
|
|
||||||
strip_settings = get_strip_settings()
|
strip_settings = get_strip_settings()
|
||||||
|
@ -835,12 +929,12 @@ class VSETB_OT_casting_move(Operator):
|
||||||
except IndexError:
|
except IndexError:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
if self.action == 'DOWN' and idx < len(strip_settings.casting) - 1:
|
if self.direction == 'DOWN' and idx < len(strip_settings.casting) - 1:
|
||||||
item_next = strip_settings.casting[idx+1].name
|
item_next = strip_settings.casting[idx+1].name
|
||||||
strip_settings.casting.move(idx, idx+1)
|
strip_settings.casting.move(idx, idx+1)
|
||||||
strip_settings.casting_index += 1
|
strip_settings.casting_index += 1
|
||||||
|
|
||||||
elif self.action == 'UP' and idx >= 1:
|
elif self.direction == 'UP' and idx >= 1:
|
||||||
item_prev = strip_settings.casting[idx-1].name
|
item_prev = strip_settings.casting[idx-1].name
|
||||||
strip_settings.casting.move(idx, idx-1)
|
strip_settings.casting.move(idx, idx-1)
|
||||||
strip_settings.casting_index -= 1
|
strip_settings.casting_index -= 1
|
||||||
|
@ -851,9 +945,45 @@ class VSETB_OT_casting_move(Operator):
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class VSETB_OT_spreadsheet_move(Operator):
|
||||||
|
bl_idname = "vse_toolbox.spreadsheet_move"
|
||||||
|
bl_label = "Move Spreadsheet items"
|
||||||
|
bl_description = "Move Spreadsheet items"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
|
direction: EnumProperty(
|
||||||
|
items=(
|
||||||
|
('UP', "Up", ""),
|
||||||
|
('DOWN', "Down", ""),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
scn = context.scene
|
||||||
|
project = get_scene_settings().active_project
|
||||||
|
|
||||||
|
idx = project.spreadsheet_index
|
||||||
|
|
||||||
|
try:
|
||||||
|
item = project.spreadsheet[idx]
|
||||||
|
except IndexError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
if self.direction == 'DOWN' and idx < len(project.spreadsheet) - 1:
|
||||||
|
item_next = project.spreadsheet[idx+1].name
|
||||||
|
project.spreadsheet.move(idx, idx+1)
|
||||||
|
project.spreadsheet_index += 1
|
||||||
|
|
||||||
|
elif self.direction == 'UP' and idx >= 1:
|
||||||
|
item_prev = project.spreadsheet[idx-1].name
|
||||||
|
project.spreadsheet.move(idx, idx-1)
|
||||||
|
project.spreadsheet_index -= 1
|
||||||
|
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
class VSETB_OT_copy_casting(Operator):
|
class VSETB_OT_copy_casting(Operator):
|
||||||
bl_idname = "vse_toolbox.copy_casting"
|
bl_idname = "vse_toolbox.copy_casting"
|
||||||
bl_label = "Casting Actions"
|
bl_label = "Copy Casting"
|
||||||
bl_description = "Copy Casting from active strip"
|
bl_description = "Copy Casting from active strip"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
|
@ -879,8 +1009,8 @@ class VSETB_OT_copy_casting(Operator):
|
||||||
|
|
||||||
class VSETB_OT_paste_casting(Operator):
|
class VSETB_OT_paste_casting(Operator):
|
||||||
bl_idname = "vse_toolbox.paste_casting"
|
bl_idname = "vse_toolbox.paste_casting"
|
||||||
bl_label = "Casting Actions"
|
bl_label = "Paste Casting"
|
||||||
bl_description = "Copy Casting from active strip"
|
bl_description = "Paste Casting to active strip"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -932,50 +1062,37 @@ class VSETB_OT_set_stamps(Operator):
|
||||||
|
|
||||||
bpy.ops.sequencer.select_all(action='DESELECT')
|
bpy.ops.sequencer.select_all(action='DESELECT')
|
||||||
|
|
||||||
crop_x = int(scn.render.resolution_x * 0.33)
|
crop_x = int(scn.render.resolution_x * 0.4)
|
||||||
crop_y = int(scn.render.resolution_y * 0.95)
|
crop_max_y = int(scn.render.resolution_y * 0.96)
|
||||||
|
crop_min_y = int(scn.render.resolution_y * 0.01)
|
||||||
|
|
||||||
|
stamp_params = dict(start=scn.frame_start, end=scn.frame_end,
|
||||||
|
font_size=22, y=0.015, box_margin=0.005, select=True, box_color=(0, 0, 0, 0.5))
|
||||||
|
|
||||||
# Project Name
|
# Project Name
|
||||||
project_strip_stamp = new_text_strip(
|
project_strip_stamp = new_text_strip('project_name_stamp', channel=1, **stamp_params,
|
||||||
'project_name_stamp', channel=1, start=scn.frame_start, end=scn.frame_end,
|
text=settings.active_project.name, x=0.01, align_x='LEFT', align_y='BOTTOM')
|
||||||
text=settings.active_project.name, font_size=24,
|
|
||||||
x=0.01, y=0.01, align_x='LEFT', align_y='BOTTOM', select=True,
|
|
||||||
box_color=(0, 0, 0, 0.5), box_margin=0.005,
|
|
||||||
)
|
|
||||||
|
|
||||||
project_strip_stamp.crop.max_x = crop_x * 2
|
project_strip_stamp.crop.max_x = crop_x * 2
|
||||||
project_strip_stamp.crop.max_y = crop_y
|
project_strip_stamp.crop.max_y = crop_max_y
|
||||||
|
project_strip_stamp.crop.min_y = crop_min_y
|
||||||
|
|
||||||
# Shot Name
|
# Shot Name
|
||||||
shot_strip_stamp = new_text_strip(
|
shot_strip_stamp = new_text_strip('shot_name_stamp', channel=2, **stamp_params,
|
||||||
f'shot_name_stamp', channel=2, start=scn.frame_start, end=scn.frame_end,
|
text='{active_shot_name}', align_y='BOTTOM')
|
||||||
text='{active_shot_name}', font_size=24,
|
|
||||||
y=0.01, align_y='BOTTOM', select=True,
|
|
||||||
box_color=(0, 0, 0, 0.5), box_margin=0.005,
|
|
||||||
)
|
|
||||||
|
|
||||||
shot_strip_stamp.crop.min_x = crop_x
|
shot_strip_stamp.crop.min_x = crop_x
|
||||||
shot_strip_stamp.crop.max_x = crop_x
|
shot_strip_stamp.crop.max_x = crop_x
|
||||||
shot_strip_stamp.crop.max_y = crop_y
|
shot_strip_stamp.crop.max_y = crop_max_y
|
||||||
|
shot_strip_stamp.crop.min_y = crop_min_y
|
||||||
|
|
||||||
# Frame Range
|
# Frame Range
|
||||||
frame_strip_stamp = new_text_strip(
|
frame_strip_stamp = new_text_strip('frame_range_stamp', channel=3, **stamp_params,
|
||||||
'frame_range_stamp', channel=3, start=scn.frame_start, end=scn.frame_end,
|
text='{active_shot_frame} / {active_shot_duration}', x=0.99, align_x='RIGHT', align_y='BOTTOM')
|
||||||
text='{active_shot_frame} / {active_shot_duration}', font_size=24,
|
|
||||||
x=0.99, y=0.01, align_x='RIGHT', align_y='BOTTOM', select=True,
|
|
||||||
box_color=(0, 0, 0, 0.5), box_margin=0.005,
|
|
||||||
)
|
|
||||||
|
|
||||||
frame_strip_stamp.crop.min_x = int(scn.render.resolution_x * 0.66)
|
frame_strip_stamp.crop.min_x = crop_x *2
|
||||||
frame_strip_stamp.crop.max_y = crop_y
|
frame_strip_stamp.crop.max_y = crop_max_y
|
||||||
# for shot_strip in get_strips('Shots'):
|
frame_strip_stamp.crop.min_y = crop_min_y
|
||||||
# # Shot Name
|
|
||||||
# shot_strip_stamp = new_text_strip(
|
|
||||||
# f'{shot_strip.name}_stamp', channel=3, start=shot_strip.frame_final_start, end=shot_strip.frame_final_end,
|
|
||||||
# text=shot_strip.name, font_size=24,
|
|
||||||
# y=0.01, align_y='BOTTOM', select=True,
|
|
||||||
# box_color=(0, 0, 0, 0.35), box_margin=0.005,
|
|
||||||
# )
|
|
||||||
|
|
||||||
bpy.ops.sequencer.meta_make()
|
bpy.ops.sequencer.meta_make()
|
||||||
stamps_strip = context.active_sequence_strip
|
stamps_strip = context.active_sequence_strip
|
||||||
|
@ -994,9 +1111,10 @@ classes = (
|
||||||
VSETB_OT_casting_add,
|
VSETB_OT_casting_add,
|
||||||
VSETB_OT_casting_remove,
|
VSETB_OT_casting_remove,
|
||||||
VSETB_OT_casting_move,
|
VSETB_OT_casting_move,
|
||||||
|
VSETB_OT_spreadsheet_move,
|
||||||
VSETB_OT_copy_casting,
|
VSETB_OT_copy_casting,
|
||||||
VSETB_OT_paste_casting,
|
VSETB_OT_paste_casting,
|
||||||
VSETB_OT_export_csv,
|
VSETB_OT_export_spreadsheet,
|
||||||
VSETB_OT_import_files,
|
VSETB_OT_import_files,
|
||||||
VSETB_OT_load_assets,
|
VSETB_OT_load_assets,
|
||||||
VSETB_OT_load_projects,
|
VSETB_OT_load_projects,
|
||||||
|
|
10
panels.py
10
panels.py
|
@ -170,7 +170,7 @@ class VSETB_PT_exports(VSETB_main, Panel):
|
||||||
bl_options = {'DEFAULT_CLOSED'}
|
bl_options = {'DEFAULT_CLOSED'}
|
||||||
|
|
||||||
def draw_header_preset(self, context):
|
def draw_header_preset(self, context):
|
||||||
self.layout.operator('vse_toolbox.export_csv', icon='EXPORT', text='', emboss=False)
|
self.layout.operator('vse_toolbox.export_spreadsheet', icon='EXPORT', text='', emboss=False)
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
prefs = get_addon_prefs()
|
prefs = get_addon_prefs()
|
||||||
|
@ -183,7 +183,7 @@ class VSETB_PT_exports(VSETB_main, Panel):
|
||||||
|
|
||||||
tracker_label = settings.tracker_name.title().replace('_', ' ')
|
tracker_label = settings.tracker_name.title().replace('_', ' ')
|
||||||
layout.operator('vse_toolbox.upload_to_tracker', text=f'Upload to {tracker_label}', icon='EXPORT')
|
layout.operator('vse_toolbox.upload_to_tracker', text=f'Upload to {tracker_label}', icon='EXPORT')
|
||||||
layout.operator('vse_toolbox.export_csv', text='Export csv', icon='SPREADSHEET')
|
layout.operator('vse_toolbox.export_spreadsheet', text='Export Spreadsheet', icon='SPREADSHEET')
|
||||||
|
|
||||||
|
|
||||||
class VSETB_PT_casting(VSETB_main, Panel):
|
class VSETB_PT_casting(VSETB_main, Panel):
|
||||||
|
@ -232,8 +232,8 @@ class VSETB_PT_casting(VSETB_main, Panel):
|
||||||
col_tool.operator('vse_toolbox.casting_add', icon='ADD', text="")
|
col_tool.operator('vse_toolbox.casting_add', icon='ADD', text="")
|
||||||
col_tool.operator('vse_toolbox.casting_remove', icon='REMOVE', text="")
|
col_tool.operator('vse_toolbox.casting_remove', icon='REMOVE', text="")
|
||||||
col_tool.separator()
|
col_tool.separator()
|
||||||
col_tool.operator('vse_toolbox.casting_move', icon='TRIA_UP', text="").action = 'UP'
|
col_tool.operator('vse_toolbox.casting_move', icon='TRIA_UP', text="").direction = 'UP'
|
||||||
col_tool.operator('vse_toolbox.casting_move', icon='TRIA_DOWN', text="").action = 'DOWN'
|
col_tool.operator('vse_toolbox.casting_move', icon='TRIA_DOWN', text="").direction = 'DOWN'
|
||||||
col_tool.separator()
|
col_tool.separator()
|
||||||
col_tool.operator('vse_toolbox.copy_casting', icon='COPYDOWN', text="")
|
col_tool.operator('vse_toolbox.copy_casting', icon='COPYDOWN', text="")
|
||||||
col_tool.operator('vse_toolbox.paste_casting', icon='PASTEDOWN', text="")
|
col_tool.operator('vse_toolbox.paste_casting', icon='PASTEDOWN', text="")
|
||||||
|
@ -259,6 +259,8 @@ class VSETB_PT_metadata(VSETB_main, Panel):
|
||||||
|
|
||||||
if not project:
|
if not project:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
layout.prop(strip_settings, 'description', text='DESCRIPTION')
|
||||||
|
|
||||||
#col = layout.column()
|
#col = layout.column()
|
||||||
for key in strip_settings.metadata.__annotations__.keys():
|
for key in strip_settings.metadata.__annotations__.keys():
|
||||||
|
|
112
properties.py
112
properties.py
|
@ -57,6 +57,28 @@ def get_tracker_items(self, context):
|
||||||
return [(norm_str(a.__name__, format=str.upper), a.__name__, "", i) for i, a in enumerate(TRACKERS)]
|
return [(norm_str(a.__name__, format=str.upper), a.__name__, "", i) for i, a in enumerate(TRACKERS)]
|
||||||
|
|
||||||
|
|
||||||
|
class CollectionPropertyGroup(PropertyGroup):
|
||||||
|
def __iter__(self):
|
||||||
|
return (v for v in self.values())
|
||||||
|
def props(self):
|
||||||
|
return [p for p in self.bl_rna.properties if p.identifier not in ('rna_type', 'name')]
|
||||||
|
|
||||||
|
def keys(self):
|
||||||
|
return [k for k in self.bl_rna.properties.keys() if k not in ('rna_type', 'name')]
|
||||||
|
|
||||||
|
def values(self):
|
||||||
|
return [getattr(self, k) for k in self.keys()]
|
||||||
|
|
||||||
|
def items(self):
|
||||||
|
return self.to_dict().items()
|
||||||
|
|
||||||
|
def to_dict(self, use_name=True):
|
||||||
|
if use_name:
|
||||||
|
return {p.name: getattr(self, p.identifier) for p in self.props()}
|
||||||
|
else:
|
||||||
|
return {k: getattr(self, k) for k in self.keys()}
|
||||||
|
|
||||||
|
|
||||||
class Asset(PropertyGroup):
|
class Asset(PropertyGroup):
|
||||||
name : StringProperty(default='')
|
name : StringProperty(default='')
|
||||||
id : StringProperty(default='')
|
id : StringProperty(default='')
|
||||||
|
@ -79,9 +101,6 @@ class Asset(PropertyGroup):
|
||||||
class AssetCasting(PropertyGroup):
|
class AssetCasting(PropertyGroup):
|
||||||
id : StringProperty(default='')
|
id : StringProperty(default='')
|
||||||
instance : IntProperty(default=1)
|
instance : IntProperty(default=1)
|
||||||
|
|
||||||
def __iter__(self):
|
|
||||||
return (getattr(self, p) for p in self.bl_rna.properties.keys() if p not in ('rna_type', 'name'))
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def asset(self):
|
def asset(self):
|
||||||
|
@ -89,8 +108,13 @@ class AssetCasting(PropertyGroup):
|
||||||
project = settings.active_project
|
project = settings.active_project
|
||||||
return project.assets.get(self.id)
|
return project.assets.get(self.id)
|
||||||
|
|
||||||
def to_dict(self):
|
|
||||||
return {k: v for k,v in self.items()}
|
class SpreadsheetCell(PropertyGroup):
|
||||||
|
export_name : StringProperty()
|
||||||
|
enabled : BoolProperty(default=True)
|
||||||
|
is_metadata : BoolProperty(default=False)
|
||||||
|
field_name : StringProperty()
|
||||||
|
#type : EnumProperty(items=[(t, t, "")] for t in ('METADATA', 'STRIP_DATA'))
|
||||||
|
|
||||||
|
|
||||||
class AssetType(PropertyGroup):
|
class AssetType(PropertyGroup):
|
||||||
|
@ -100,6 +124,7 @@ class AssetType(PropertyGroup):
|
||||||
class MetadataType(PropertyGroup):
|
class MetadataType(PropertyGroup):
|
||||||
choices = []
|
choices = []
|
||||||
choice : EnumProperty(items=lambda s, c: [(c, c.replace(' ', '_').upper(), '') for c in s['choices']])
|
choice : EnumProperty(items=lambda s, c: [(c, c.replace(' ', '_').upper(), '') for c in s['choices']])
|
||||||
|
field_name : bpy.props.StringProperty()
|
||||||
|
|
||||||
|
|
||||||
class TaskType(PropertyGroup):
|
class TaskType(PropertyGroup):
|
||||||
|
@ -110,11 +135,9 @@ class TaskStatus(PropertyGroup):
|
||||||
__annotations__ = {}
|
__annotations__ = {}
|
||||||
|
|
||||||
|
|
||||||
class Metadata(PropertyGroup):
|
class Metadata(CollectionPropertyGroup):
|
||||||
__annotations__ = {}
|
__annotations__ = {}
|
||||||
|
|
||||||
def to_dict(self):
|
|
||||||
return {p.name: getattr(self, p.identifier) for p in self.bl_rna.properties.keys() if p.name != 'RNA'}
|
|
||||||
|
|
||||||
class Episode(PropertyGroup):
|
class Episode(PropertyGroup):
|
||||||
id : StringProperty(default='')
|
id : StringProperty(default='')
|
||||||
|
@ -157,8 +180,30 @@ class Project(PropertyGroup):
|
||||||
task_types : CollectionProperty(type=TaskType)
|
task_types : CollectionProperty(type=TaskType)
|
||||||
task_statuses : CollectionProperty(type=TaskStatus)
|
task_statuses : CollectionProperty(type=TaskStatus)
|
||||||
|
|
||||||
|
spreadsheet : CollectionProperty(type=SpreadsheetCell)
|
||||||
|
spreadsheet_index : IntProperty(name='Spreadsheet Index', default=0)
|
||||||
|
|
||||||
type : StringProperty()
|
type : StringProperty()
|
||||||
|
|
||||||
|
def set_spreadsheet(self):
|
||||||
|
cell_names = ['Sequence', 'Shot', 'Frames', 'Description']
|
||||||
|
if self.type == 'TVSHOW':
|
||||||
|
cell_names.insert(0, 'Episode')
|
||||||
|
|
||||||
|
for cell_name in cell_names:
|
||||||
|
cell = self.spreadsheet.add()
|
||||||
|
cell.name = cell_name
|
||||||
|
cell.export_name = cell_name
|
||||||
|
cell.field_name = cell_name.upper()
|
||||||
|
|
||||||
|
for metadata_type in self.metadata_types:
|
||||||
|
cell = self.spreadsheet.add()
|
||||||
|
cell.name = metadata_type.name
|
||||||
|
cell.export_name = metadata_type.name
|
||||||
|
cell.field_name = metadata_type.field_name
|
||||||
|
cell.is_metadata = True
|
||||||
|
|
||||||
|
|
||||||
def set_strip_metadata(self):
|
def set_strip_metadata(self):
|
||||||
|
|
||||||
# Clear Metadatas
|
# Clear Metadatas
|
||||||
|
@ -167,16 +212,17 @@ class Project(PropertyGroup):
|
||||||
delattr(Metadata, attr)
|
delattr(Metadata, attr)
|
||||||
del Metadata.__annotations__[attr]
|
del Metadata.__annotations__[attr]
|
||||||
|
|
||||||
|
|
||||||
for metadata_type in self.metadata_types:
|
for metadata_type in self.metadata_types:
|
||||||
prop_name = metadata_type.name
|
field_name = metadata_type.field_name
|
||||||
if metadata_type.get('choices'):
|
name = metadata_type.name
|
||||||
prop = bpy.props.EnumProperty(items=[(c, c.replace(' ', '_').upper(), '') for c in ['/'] + metadata_type['choices']])
|
|
||||||
else:
|
|
||||||
prop = bpy.props.StringProperty()
|
|
||||||
|
|
||||||
Metadata.__annotations__[prop_name] = prop
|
if metadata_type.get('choices'):
|
||||||
setattr(Metadata, prop_name, prop)
|
prop = bpy.props.EnumProperty(items=[(c, c, '') for c in ['/'] + metadata_type['choices']], name=name)
|
||||||
|
else:
|
||||||
|
prop = bpy.props.StringProperty(name=name)
|
||||||
|
|
||||||
|
Metadata.__annotations__[field_name] = prop
|
||||||
|
setattr(Metadata, field_name, prop)
|
||||||
|
|
||||||
|
|
||||||
class VSETB_UL_casting(UIList):
|
class VSETB_UL_casting(UIList):
|
||||||
|
@ -240,7 +286,35 @@ class VSETB_UL_casting(UIList):
|
||||||
ordered = sort_items(_sort, lambda x: x[1].asset.label)
|
ordered = sort_items(_sort, lambda x: x[1].asset.label)
|
||||||
|
|
||||||
return filtered, ordered
|
return filtered, ordered
|
||||||
|
|
||||||
|
|
||||||
|
class VSETB_UL_spreadsheet(UIList):
|
||||||
|
def draw_item(self, context, layout, data, item, icon, active_data,
|
||||||
|
active_propname, index):
|
||||||
|
|
||||||
|
settings = get_scene_settings()
|
||||||
|
project = settings.active_project
|
||||||
|
|
||||||
|
layout.use_property_split = True
|
||||||
|
layout.use_property_decorate = False
|
||||||
|
|
||||||
|
row = layout.row(align=True)
|
||||||
|
row.alignment = 'LEFT'
|
||||||
|
|
||||||
|
row.prop(item, 'enabled', text='')
|
||||||
|
layout.label(text=item.name)
|
||||||
|
layout.prop(item, 'export_name', text='')
|
||||||
|
|
||||||
|
def draw_filter(self, context, layout):
|
||||||
|
row = layout.row()
|
||||||
|
|
||||||
|
subrow = row.row(align=True)
|
||||||
|
subrow.prop(self, "filter_name", text="")
|
||||||
|
subrow.prop(self, "use_filter_invert", text="", icon='ARROW_LEFTRIGHT')
|
||||||
|
|
||||||
|
subrow.separator()
|
||||||
|
subrow.prop(self, "order_by_type", text="Order by Type", icon='MESH_DATA')
|
||||||
|
|
||||||
|
|
||||||
class VSETB_PGT_scene_settings(PropertyGroup):
|
class VSETB_PGT_scene_settings(PropertyGroup):
|
||||||
|
|
||||||
|
@ -287,11 +361,13 @@ class VSETB_PGT_strip_settings(PropertyGroup):
|
||||||
casting_index : IntProperty(name='Casting Index', default=0)
|
casting_index : IntProperty(name='Casting Index', default=0)
|
||||||
source_name : StringProperty(name='')
|
source_name : StringProperty(name='')
|
||||||
metadata : PointerProperty(type=Metadata)
|
metadata : PointerProperty(type=Metadata)
|
||||||
|
description : StringProperty()
|
||||||
|
|
||||||
|
|
||||||
classes=(
|
classes=(
|
||||||
Asset,
|
Asset,
|
||||||
AssetCasting,
|
AssetCasting,
|
||||||
|
SpreadsheetCell,
|
||||||
AssetType,
|
AssetType,
|
||||||
TaskStatus,
|
TaskStatus,
|
||||||
Episode,
|
Episode,
|
||||||
|
@ -299,6 +375,7 @@ classes=(
|
||||||
MetadataType,
|
MetadataType,
|
||||||
TaskType,
|
TaskType,
|
||||||
Project,
|
Project,
|
||||||
|
VSETB_UL_spreadsheet,
|
||||||
VSETB_UL_casting,
|
VSETB_UL_casting,
|
||||||
VSETB_PGT_scene_settings,
|
VSETB_PGT_scene_settings,
|
||||||
VSETB_PGT_strip_settings,
|
VSETB_PGT_strip_settings,
|
||||||
|
@ -313,6 +390,7 @@ def load_handler(dummy):
|
||||||
settings = get_scene_settings()
|
settings = get_scene_settings()
|
||||||
if settings.active_project:
|
if settings.active_project:
|
||||||
settings.active_project.set_strip_metadata()
|
settings.active_project.set_strip_metadata()
|
||||||
|
#settings.active_project.set_spreadsheet()
|
||||||
os.environ['TRACKER_PROJECT_ID'] = settings.active_project.id
|
os.environ['TRACKER_PROJECT_ID'] = settings.active_project.id
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import urllib3
|
||||||
import traceback
|
import traceback
|
||||||
import time
|
import time
|
||||||
import uuid
|
import uuid
|
||||||
|
from pprint import pprint
|
||||||
|
|
||||||
from bpy.props import PointerProperty, StringProperty
|
from bpy.props import PointerProperty, StringProperty
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
@ -176,6 +177,20 @@ class Kitsu(Tracker):
|
||||||
|
|
||||||
return gazu.shot.get_shot_by_name(sequence, shot)
|
return gazu.shot.get_shot_by_name(sequence, shot)
|
||||||
|
|
||||||
|
def get_asset(self, asset, asset_type=None, project=None):
|
||||||
|
#print('get_asset', "name", name, 'asset_type', asset_type)
|
||||||
|
|
||||||
|
asset_id = self.get_id(asset)
|
||||||
|
if asset_id:
|
||||||
|
return asset_id
|
||||||
|
|
||||||
|
project = self.get_project(project)
|
||||||
|
asset_type = self.get_id(asset_type)
|
||||||
|
|
||||||
|
asset = gazu.asset.get_asset_by_name(project, asset, asset_type)
|
||||||
|
|
||||||
|
return asset
|
||||||
|
|
||||||
def get_assets(self, project=None):
|
def get_assets(self, project=None):
|
||||||
project = self.get_project(project)
|
project = self.get_project(project)
|
||||||
assets = gazu.asset.all_assets_for_project(project)
|
assets = gazu.asset.all_assets_for_project(project)
|
||||||
|
@ -327,10 +342,41 @@ class Kitsu(Tracker):
|
||||||
else:
|
else:
|
||||||
entity['data'].update(data)
|
entity['data'].update(data)
|
||||||
|
|
||||||
|
#pprint(entity)
|
||||||
entity_data = gazu.client.put(f"data/entities/{entity_id}", entity)
|
entity_data = gazu.client.put(f"data/entities/{entity_id}", entity)
|
||||||
|
|
||||||
|
|
||||||
return entity_data['data']
|
return entity_data['data']
|
||||||
|
|
||||||
|
def get_casting(self, shot, project=None):
|
||||||
|
project = self.get_project(project)
|
||||||
|
project_id = self.get_id(project)
|
||||||
|
return gazu.casting.get_shot_casting({'id': self.get_id(shot), 'project_id': project_id})
|
||||||
|
|
||||||
|
def update_casting(self, shot, casting, clear=True, project=None):
|
||||||
|
project = self.get_project(project)
|
||||||
|
shot_id = self.get_id(shot)
|
||||||
|
|
||||||
|
norm_casting = []
|
||||||
|
if clear is False:
|
||||||
|
norm_casting += self.get_casting(shot, project)
|
||||||
|
|
||||||
|
for asset in casting:
|
||||||
|
if isinstance(asset, dict) and 'asset_id' in asset: # It's an asset instance
|
||||||
|
asset_id = asset['asset_id']
|
||||||
|
nb_occurences = asset['nb_occurences']
|
||||||
|
else: # It's an asset
|
||||||
|
asset = self.get_asset(asset)
|
||||||
|
nb_occurences = 1
|
||||||
|
|
||||||
|
cast = next((c for c in norm_casting if c['asset_id'] == asset_id), None)
|
||||||
|
if cast:
|
||||||
|
cast['nb_occurences'] += 1
|
||||||
|
else:
|
||||||
|
norm_casting.append({'asset_id': asset_id, 'nb_occurences': nb_occurences})
|
||||||
|
|
||||||
|
return gazu.casting.update_shot_casting(project, shot_id, norm_casting)
|
||||||
|
|
||||||
def draw_prefs(self, layout):
|
def draw_prefs(self, layout):
|
||||||
layout.prop(self, 'url', text='Url')
|
layout.prop(self, 'url', text='Url')
|
||||||
layout.prop(self, 'login', text='Login')
|
layout.prop(self, 'login', text='Login')
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
import re
|
import re
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
import os
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
from bpy.app.handlers import persistent
|
from bpy.app.handlers import persistent
|
||||||
|
@ -125,12 +126,15 @@ def set_channels():
|
||||||
|
|
||||||
def get_strip_render_path(strip, template):
|
def get_strip_render_path(strip, template):
|
||||||
scn = bpy.context.scene
|
scn = bpy.context.scene
|
||||||
return template.format(strip_name=strip.name, ext=Path(scn.render.frame_path()).suffix)
|
suffix = Path(scn.render.frame_path()).suffix
|
||||||
|
render_path = template.format(strip_name=strip.name, ext=suffix[1:])
|
||||||
|
return Path(os.path.abspath(bpy.path.abspath(render_path)))
|
||||||
|
|
||||||
def render_strips(strips, template):
|
def render_strips(strips, template):
|
||||||
scn = bpy.context.scene
|
scn = bpy.context.scene
|
||||||
scene_start = scn.frame_start
|
scene_start = scn.frame_start
|
||||||
scene_end = scn.frame_end
|
scene_end = scn.frame_end
|
||||||
|
render_path = scn.render.filepath
|
||||||
|
|
||||||
for strip in strips:
|
for strip in strips:
|
||||||
#print(render_template, strip.name, path)
|
#print(render_template, strip.name, path)
|
||||||
|
@ -140,7 +144,8 @@ def render_strips(strips, template):
|
||||||
|
|
||||||
## render animatic
|
## render animatic
|
||||||
#strip_render_path = render_template.format(strip_name=strip.name, ext=Path(scn.render.frame_path()).suffix)
|
#strip_render_path = render_template.format(strip_name=strip.name, ext=Path(scn.render.frame_path()).suffix)
|
||||||
scn.render.filepath = get_strip_render_path(strip, template)
|
|
||||||
|
scn.render.filepath = str(get_strip_render_path(strip, template))
|
||||||
#print(scn.render.filepath)
|
#print(scn.render.filepath)
|
||||||
print(f'Render Strip to {scn.render.filepath}')
|
print(f'Render Strip to {scn.render.filepath}')
|
||||||
#bpy.ops.render.render(animation=True)
|
#bpy.ops.render.render(animation=True)
|
||||||
|
@ -149,6 +154,7 @@ def render_strips(strips, template):
|
||||||
|
|
||||||
scn.frame_start = scene_start
|
scn.frame_start = scene_start
|
||||||
scn.frame_end = scene_end
|
scn.frame_end = scene_end
|
||||||
|
scn.render.filepath = render_path
|
||||||
|
|
||||||
def import_edit(filepath, adapter="cmx_3600", clean_sequencer=False):
|
def import_edit(filepath, adapter="cmx_3600", clean_sequencer=False):
|
||||||
import opentimelineio as otio
|
import opentimelineio as otio
|
||||||
|
|
Loading…
Reference in New Issue