Skip to content
This repository has been archived by the owner on Sep 20, 2024. It is now read-only.

After Effects: added SubsetManager #1234

Merged
merged 1 commit into from
Mar 31, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions pype/modules/websocket_server/hosts/aftereffects.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ async def sceneinventory_route(self):
async def projectmanager_route(self):
self._tool_route("projectmanager")

async def subsetmanager_route(self):
self._tool_route("subsetmanager")

def _tool_route(self, tool_name):
"""The address accessed when clicking on the buttons."""
partial_method = functools.partial(aftereffects.show, tool_name)
Expand Down
41 changes: 40 additions & 1 deletion pype/modules/websocket_server/stubs/aftereffects_server_stub.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ class AfterEffectsServerStub():
is opened).
'self.websocketserver.call' is used as async wrapper
"""
PUBLISH_ICON = '\u2117 '
LOADED_ICON = '\u25bc'

def __init__(self):
self.websocketserver = WebSocketServer.get_instance()
Expand All @@ -61,7 +63,7 @@ def get_metadata(self):
by Creator.

Returns:
(dict)
(list)
"""
res = self.websocketserver.call(self.client.call
('AfterEffects.get_metadata')
Expand Down Expand Up @@ -212,6 +214,19 @@ def get_selected_items(self, comps, folders=False, footages=False):
)
return self._to_records(res)

def get_item(self, item_id):
"""
Returns metadata for particular 'item_id' or None

Args:
item_id (int, or string)
"""
for item in self.get_items(True, True, True):
if str(item.id) == str(item_id):
return item

return None

def import_file(self, path, item_name, import_options=None):
"""
Imports file as a FootageItem. Used in Loader
Expand Down Expand Up @@ -272,6 +287,30 @@ def delete_item(self, item_id):
item_id=item_id
))

def remove_instance(self, instance_id):
"""
Removes instance with 'instance_id' from file's metadata and
saves them.

Keep matching item in file though.

Args:
instance_id(string): instance uuid
"""
cleaned_data = []

for instance in self.get_metadata():
uuid_val = instance.get("uuid")
if not uuid_val:
uuid_val = instance.get("members")[0] # legacy
if uuid_val != instance_id:
cleaned_data.append(instance)

payload = json.dumps(cleaned_data, indent=4)
self.websocketserver.call(self.client.call
('AfterEffects.imprint', payload=payload)
)

def is_saved(self):
# TODO
return True
Expand Down
31 changes: 21 additions & 10 deletions pype/plugins/aftereffects/create/create_render.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@


class CreateRender(pype.api.Creator):
"""Render folder for publish."""
"""Render folder for publish.

Creates subsets in format 'familyTaskSubsetname',
eg 'renderCompositingMain'.

Create only single instance from composition at a time.
"""

name = "renderDefault"
label = "Render on Farm"
Expand All @@ -20,7 +26,7 @@ def process(self):
items = stub.get_selected_items(comps=True,
folders=False,
footages=False)
else:
if len(items) > 1:
self._show_msg("Please select only single composition at time.")
return False

Expand All @@ -30,15 +36,20 @@ def process(self):
"one composition.")
return False

for item in items:
existing_subsets = [instance['subset'].lower()
for instance in aftereffects.list_instances()]

item = items.pop()
if self.name.lower() in existing_subsets:
txt = "Instance with name \"{}\" already exists.".format(self.name)
if self.name.lower() == item.name.lower():
self._show_msg(txt)
return False
self.data["members"] = [item.id]
stub.imprint(item, self.data)
stub.set_label_color(item.id, 14) # Cyan options 0 - 16
stub.rename_item(item, self.data["subset"])
self._show_msg(txt)
return False

self.data["members"] = [item.id]
self.data["uuid"] = item.id # for SubsetManager
stub.imprint(item, self.data)
stub.set_label_color(item.id, 14) # Cyan options 0 - 16
stub.rename_item(item, stub.PUBLISH_ICON + self.data["subset"])

def _show_msg(self, txt):
msg = Qt.QtWidgets.QMessageBox()
Expand Down
5 changes: 3 additions & 2 deletions pype/plugins/aftereffects/load/load_background.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ def load(self, context, name=None, namespace=None, data=None):
"{}_{}".format(context["asset"]["name"], name))

layers = get_background_layers(self.fname)
comp = stub.import_background(None, comp_name, layers)
comp = stub.import_background(None, stub.LOADED_ICON + comp_name,
layers)

if not comp:
self.log.warning(
Expand Down Expand Up @@ -72,7 +73,7 @@ def update(self, container, representation):

layers = get_background_layers(path)
comp = stub.reload_background(container["members"][1],
comp_name,
stub.LOADED_ICON + comp_name,
layers)

# update container
Expand Down
5 changes: 3 additions & 2 deletions pype/plugins/aftereffects/load/load_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ def load(self, context, name=None, namespace=None, data=None):
if '.psd' in file:
import_options['ImportAsType'] = 'ImportAsType.COMP'

comp = stub.import_file(self.fname, comp_name, import_options)
comp = stub.import_file(self.fname, stub.LOADED_ICON + comp_name,
import_options)

if not comp:
self.log.warning(
Expand Down Expand Up @@ -87,7 +88,7 @@ def update(self, container, representation):
layer_name = container["namespace"]
path = api.get_representation_path(representation)
# with aftereffects.maintained_selection(): # TODO
stub.replace_item(layer, path, layer_name)
stub.replace_item(layer, path, stub.LOADED_ICON + layer_name)
stub.imprint(
layer, {"representation": str(representation["_id"]),
"name": context["subset"],
Expand Down