363 lines
11 KiB
Python
363 lines
11 KiB
Python
|
|
import json
|
|
|
|
import bpy
|
|
from bpy.types import Context, Event, PropertyGroup, Operator
|
|
from bpy.props import (CollectionProperty, EnumProperty, StringProperty)
|
|
|
|
from vse_toolbox.constants import CASTING_BUFFER, ASSET_ITEMS
|
|
from vse_toolbox.sequencer_utils import get_strips
|
|
from vse_toolbox.bl_utils import (get_addon_prefs, get_scene_settings, get_strip_settings)
|
|
|
|
from time import perf_counter
|
|
|
|
class VSETB_OT_casting_replace(Operator):
|
|
bl_idname = "vse_toolbox.casting_replace"
|
|
bl_label = "Replace Asset"
|
|
bl_description = "Replace Asset of selected strips"
|
|
|
|
old_asset : StringProperty()
|
|
new_asset : StringProperty()
|
|
|
|
assets : CollectionProperty(type=PropertyGroup)
|
|
|
|
def execute(self, context):
|
|
prefs = get_addon_prefs()
|
|
settings = get_scene_settings()
|
|
|
|
new_asset = next(a for a in settings.active_project.assets if a.tracker_name == self.new_asset)
|
|
|
|
for strip in get_strips('Shots', selected_only=True):
|
|
strip_settings = strip.vsetb_strip_settings
|
|
for asset_casting in strip_settings.casting:
|
|
if asset_casting.asset.tracker_name == self.old_asset:
|
|
|
|
print(f'Replace casting on {strip.name}')
|
|
|
|
asset_casting.name = new_asset.name
|
|
asset_casting.id = new_asset.id
|
|
asset_casting['_name'] = new_asset.label
|
|
|
|
strip_settings.casting.update()
|
|
|
|
self.assets.clear()
|
|
|
|
return {'FINISHED'}
|
|
|
|
def invoke(self, context, event):
|
|
settings = get_scene_settings()
|
|
project = settings.active_project
|
|
|
|
self.assets.clear()
|
|
for asset in project.assets:
|
|
item = self.assets.add()
|
|
item.name = asset.tracker_name
|
|
|
|
strip = context.active_sequence_strip
|
|
asset_casting_index = strip.vsetb_strip_settings.casting_index
|
|
active_asset = strip.vsetb_strip_settings.casting[asset_casting_index].asset
|
|
|
|
self.old_asset = active_asset.tracker_name
|
|
self.new_asset = ''
|
|
|
|
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
|
|
col = layout.column()
|
|
col.use_property_split = True
|
|
col.prop_search(self, 'old_asset', self, 'assets', text='Old Asset', icon='ASSET_MANAGER')
|
|
col.prop_search(self, 'new_asset', self, 'assets', text='New Asset', icon='ASSET_MANAGER')
|
|
|
|
|
|
class VSETB_OT_casting_add(Operator):
|
|
bl_idname = "vse_toolbox.casting_add"
|
|
bl_label = "Casting Add"
|
|
bl_description = "Add Asset to Castin"
|
|
bl_options = {"REGISTER", "UNDO"}
|
|
bl_property = "asset_name"
|
|
|
|
asset_name : EnumProperty(name='', items=lambda s,c : ASSET_ITEMS)
|
|
#asset_name : EnumProperty(name='', items=get_scene_settings().active_project.get('asset_items', []))
|
|
@classmethod
|
|
def poll(cls, context):
|
|
active_strip = context.scene.sequence_editor.active_strip
|
|
if active_strip:
|
|
return True
|
|
|
|
def invoke(self, context, event):
|
|
context.window_manager.invoke_search_popup(self)
|
|
return {'FINISHED'}
|
|
|
|
def execute(self, context):
|
|
scn = context.scene
|
|
|
|
settings = get_scene_settings()
|
|
project = settings.active_project
|
|
asset = project.assets[self.asset_name]
|
|
|
|
strips = get_strips('Shots', selected_only=True)
|
|
for strip in strips:
|
|
#active_strip = scn.sequence_editor.active_strip
|
|
|
|
|
|
strip_settings = strip.vsetb_strip_settings
|
|
|
|
|
|
|
|
if strip_settings.casting.get(self.asset_name):
|
|
self.report({'WARNING'}, f"Asset {asset.label} already casted.")
|
|
return {"CANCELLED"}
|
|
|
|
item = strip_settings.casting.add()
|
|
item.name = asset.name
|
|
item.id = asset.id
|
|
item['_name'] = asset.label
|
|
|
|
strip_settings.casting.update()
|
|
|
|
self.report({"INFO"}, f'Item {asset.label} added in {len(strips)} shots')
|
|
|
|
return {"FINISHED"}
|
|
|
|
|
|
class VSETB_OT_casting_remove(Operator):
|
|
bl_idname = "vse_toolbox.casting_remove"
|
|
bl_label = "Remove Item from Casting"
|
|
bl_description = "Remove Item from Casting"
|
|
bl_options = {"REGISTER", "UNDO"}
|
|
|
|
@classmethod
|
|
def poll(cls, context):
|
|
active_strip = context.scene.sequence_editor.active_strip
|
|
if active_strip:
|
|
return True
|
|
|
|
def invoke(self, context, event):
|
|
scn = context.scene
|
|
|
|
settings = get_strip_settings()
|
|
asset_id = settings.active_casting.id
|
|
|
|
strips = get_strips('Shots', selected_only=True)
|
|
strips_modified = 0
|
|
for strip in strips:
|
|
strip_settings = strip.vsetb_strip_settings
|
|
|
|
for i, asset_casting in enumerate(list(strip_settings.casting)):
|
|
if asset_casting.id == asset_id:
|
|
strip_settings.casting.remove(i)
|
|
|
|
|
|
if strip_settings.casting_index != 0:
|
|
strip_settings.casting_index -= 1
|
|
|
|
strips_modified += 1
|
|
|
|
continue
|
|
|
|
if asset := settings.active_casting.asset:
|
|
name = asset.label
|
|
else:
|
|
name = settings.active_casting.get('_name', '')
|
|
|
|
|
|
self.report({"INFO"}, f'Item {name} removed in {strips_modified} shots')
|
|
|
|
return {"FINISHED"}
|
|
|
|
|
|
class VSETB_OT_casting_move(Operator):
|
|
bl_idname = "vse_toolbox.casting_move"
|
|
bl_label = "Move Casting items"
|
|
bl_description = "Move Casting items"
|
|
bl_options = {"REGISTER", "UNDO"}
|
|
|
|
direction: EnumProperty(
|
|
items=(
|
|
('UP', "Up", ""),
|
|
('DOWN', "Down", ""),
|
|
)
|
|
)
|
|
|
|
asset_name : StringProperty()
|
|
|
|
@classmethod
|
|
def poll(cls, context):
|
|
active_strip = context.scene.sequence_editor.active_strip
|
|
if active_strip:
|
|
return True
|
|
|
|
def execute(self, context):
|
|
scn = context.scene
|
|
|
|
strip_settings = get_strip_settings()
|
|
idx = strip_settings.casting_index
|
|
|
|
try:
|
|
item = strip_settings.casting[idx]
|
|
except IndexError:
|
|
pass
|
|
else:
|
|
if self.direction == 'DOWN' and idx < len(strip_settings.casting) - 1:
|
|
item_next = strip_settings.casting[idx+1].name
|
|
strip_settings.casting.move(idx, idx+1)
|
|
strip_settings.casting_index += 1
|
|
|
|
elif self.direction == 'UP' and idx >= 1:
|
|
item_prev = strip_settings.casting[idx-1].name
|
|
strip_settings.casting.move(idx, idx-1)
|
|
strip_settings.casting_index -= 1
|
|
|
|
info = f"Item {item.asset.label} moved to position {(item.asset.label, strip_settings.casting_index + 1)}"
|
|
self.report({'INFO'}, info)
|
|
|
|
return {"FINISHED"}
|
|
|
|
|
|
class VSETB_OT_copy_casting(Operator):
|
|
bl_idname = "vse_toolbox.copy_casting"
|
|
bl_label = "Copy Casting"
|
|
bl_description = "Copy Casting from active strip"
|
|
bl_options = {"REGISTER", "UNDO"}
|
|
|
|
@classmethod
|
|
def poll(cls, context):
|
|
active_strip = context.scene.sequence_editor.active_strip
|
|
strip_settings = get_strip_settings()
|
|
|
|
if active_strip and strip_settings.casting:
|
|
return True
|
|
|
|
def execute(self, context):
|
|
scn = context.scene
|
|
|
|
active_strip = scn.sequence_editor.active_strip
|
|
strip_settings = get_strip_settings()
|
|
|
|
datas = [c.to_dict() for c in strip_settings.casting]
|
|
CASTING_BUFFER.write_text(json.dumps(datas), encoding='utf-8')
|
|
|
|
return {"FINISHED"}
|
|
|
|
|
|
class VSETB_OT_paste_casting(Operator):
|
|
bl_idname = "vse_toolbox.paste_casting"
|
|
bl_label = "Paste Casting"
|
|
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()
|
|
|
|
if not CASTING_BUFFER.exists():
|
|
self.report({'ERROR'}, f'No Casting to copy.')
|
|
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
|
|
|
|
if self.mode == 'REPLACE':
|
|
strip.vsetb_strip_settings.casting.clear()
|
|
|
|
for casting_data in casting_datas:
|
|
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)
|
|
|
|
if strip_settings.casting_index != 0:
|
|
strip_settings.casting_index -= 1
|
|
|
|
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"}
|
|
|
|
|
|
class VSETB_OT_copy_metadata(Operator):
|
|
bl_idname = "vse_toolbox.copy_metadata"
|
|
bl_label = "Copy metadata to selected"
|
|
bl_description = "Copy Metadata to selected strips"
|
|
|
|
metadata : StringProperty()
|
|
|
|
@classmethod
|
|
def poll(cls, context):
|
|
return context.selected_sequences and context.active_sequence_strip
|
|
|
|
def execute(self, context):
|
|
prefs = get_addon_prefs()
|
|
settings = get_scene_settings()
|
|
project = settings.active_project
|
|
|
|
metadata = next((m.field_name for m in project.metadata_types if m.name == self.metadata), None)
|
|
|
|
if not metadata:
|
|
self.report({'ERROR'}, f'No Metadata named {self.metadata}')
|
|
|
|
active_strip = context.active_sequence_strip
|
|
metadata_value = getattr(active_strip.vsetb_strip_settings.metadata, metadata)
|
|
|
|
for strip in context.selected_sequences:
|
|
if strip == context.active_sequence_strip:
|
|
continue
|
|
|
|
setattr(strip.vsetb_strip_settings.metadata, metadata, metadata_value)
|
|
|
|
return {"FINISHED"}
|
|
|
|
|
|
classes = (
|
|
VSETB_OT_casting_add,
|
|
VSETB_OT_casting_remove,
|
|
VSETB_OT_casting_move,
|
|
VSETB_OT_copy_casting,
|
|
VSETB_OT_paste_casting,
|
|
VSETB_OT_casting_replace,
|
|
VSETB_OT_copy_metadata
|
|
)
|
|
|
|
def register():
|
|
for cls in classes:
|
|
bpy.utils.register_class(cls)
|
|
|
|
def unregister():
|
|
for cls in reversed(classes):
|
|
bpy.utils.unregister_class(cls) |