From c4f049f64e411071bd41f3ff3ddc7d3c4e5e6225 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 18 Feb 2020 11:39:32 +0100 Subject: [PATCH 01/19] fix(nk): validator of rendered frames failed if slate were missing --- pype/plugins/nuke/publish/validate_rendered_frames.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pype/plugins/nuke/publish/validate_rendered_frames.py b/pype/plugins/nuke/publish/validate_rendered_frames.py index 169ea1ecb5..8a8bf3cc5e 100644 --- a/pype/plugins/nuke/publish/validate_rendered_frames.py +++ b/pype/plugins/nuke/publish/validate_rendered_frames.py @@ -76,7 +76,8 @@ class ValidateRenderedFrames(pyblish.api.InstancePlugin): 'len(collection.indexes): {}'.format(collected_frames_len) ) - if "slate" in instance.data["families"]: + if ("slate" in instance.data["families"]) \ + and (frame_length != collected_frames_len): collected_frames_len -= 1 assert (collected_frames_len == frame_length), ( From cc1c176ef0f398b3fa7463c92a28a1365ff15471 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 18 Feb 2020 14:53:47 +0100 Subject: [PATCH 02/19] feat(nk): dealing with slate if `render` family in write collector --- pype/plugins/nuke/publish/collect_writes.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/pype/plugins/nuke/publish/collect_writes.py b/pype/plugins/nuke/publish/collect_writes.py index bf1c6a4b66..c3e408341e 100644 --- a/pype/plugins/nuke/publish/collect_writes.py +++ b/pype/plugins/nuke/publish/collect_writes.py @@ -41,7 +41,10 @@ class CollectNukeWrites(pyblish.api.InstancePlugin): handle_end = instance.context.data["handleEnd"] first_frame = int(nuke.root()["first_frame"].getValue()) last_frame = int(nuke.root()["last_frame"].getValue()) - + frame_length = int( + last_frame - first_frame + 1 + ) + if node["use_limit"].getValue(): handles = 0 first_frame = int(node["first"].getValue()) @@ -82,8 +85,17 @@ class CollectNukeWrites(pyblish.api.InstancePlugin): collected_frames = [f for f in os.listdir(output_dir) if ext in f] if collected_frames: - representation['frameStart'] = "%0{}d".format( + collected_frames_len = len(collected_frames) + frame_start_str = "%0{}d".format( len(str(last_frame))) % first_frame + representation['frameStart'] = frame_start_str + if "slate" in instance.data["families"] \ + and (frame_length != collected_frames_len): + frame_slate_str = "%0{}d".format( + len(str(last_frame))) % (first_frame - 1) + slate_frame = collected_frames[0].replace( + frame_start_str, frame_slate_str) + collected_frames.insert(0, slate_frame) representation['files'] = collected_frames instance.data["representations"].append(representation) except Exception: From 20a3e054452406db1fab8e190f02a0944c0170c9 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 18 Feb 2020 14:54:49 +0100 Subject: [PATCH 03/19] fix(nk): rendering slate frame to imagesequence --- .../plugins/nuke/publish/extract_slate_frame.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/pype/plugins/nuke/publish/extract_slate_frame.py b/pype/plugins/nuke/publish/extract_slate_frame.py index 4d43f38859..488f9bd31d 100644 --- a/pype/plugins/nuke/publish/extract_slate_frame.py +++ b/pype/plugins/nuke/publish/extract_slate_frame.py @@ -33,6 +33,7 @@ class ExtractSlateFrame(pype.api.Extractor): self.render_slate(instance) def render_slate(self, instance): + node_subset_name = instance.data.get("name", None) node = instance[0] # group node self.log.info("Creating staging dir...") @@ -47,6 +48,10 @@ class ExtractSlateFrame(pype.api.Extractor): self.log.info( "StagingDir `{0}`...".format(instance.data["stagingDir"])) + frame_length = int( + instance.data["frameEnd"] - instance.data["frameStart"] + 1 + ) + temporary_nodes = [] collection = instance.data.get("collection", None) @@ -56,10 +61,16 @@ class ExtractSlateFrame(pype.api.Extractor): "{head}{padding}{tail}")) fhead = collection.format("{head}") + collected_frames_len = int(len(collection.indexes)) + # get first and last frame first_frame = min(collection.indexes) - 1 - - if "slate" in instance.data["families"]: + self.log.info('frame_length: {}'.format(frame_length)) + self.log.info( + 'len(collection.indexes): {}'.format(collected_frames_len) + ) + if ("slate" in instance.data["families"]) \ + and (frame_length != collected_frames_len): first_frame += 1 last_frame = first_frame @@ -103,6 +114,8 @@ class ExtractSlateFrame(pype.api.Extractor): # Render frames nuke.execute(write_node.name(), int(first_frame), int(last_frame)) + # also render slate as sequence frame + nuke.execute(node_subset_name, int(first_frame), int(last_frame)) self.log.debug( "slate frame path: {}".format(instance.data["slateFrame"])) From 73c94459b82414bb87f8a1c2b9c9bb52d3ab810f Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 18 Feb 2020 16:30:38 +0100 Subject: [PATCH 04/19] fix(nk, global): slate workflow on farm and local improvements --- .../global/publish/collect_filesequences.py | 3 +- pype/plugins/global/publish/extract_burnin.py | 40 +++++++++++-------- pype/plugins/nuke/publish/collect_writes.py | 13 +++++- 3 files changed, 36 insertions(+), 20 deletions(-) diff --git a/pype/plugins/global/publish/collect_filesequences.py b/pype/plugins/global/publish/collect_filesequences.py index 8b42606e4a..44098b6008 100644 --- a/pype/plugins/global/publish/collect_filesequences.py +++ b/pype/plugins/global/publish/collect_filesequences.py @@ -158,7 +158,6 @@ class CollectRenderedFrames(pyblish.api.ContextPlugin): os.environ.update(session) instance = metadata.get("instance") if instance: - instance_family = instance.get("family") pixel_aspect = instance.get("pixelAspect", 1) resolution_width = instance.get("resolutionWidth", 1920) resolution_height = instance.get("resolutionHeight", 1080) @@ -168,7 +167,6 @@ class CollectRenderedFrames(pyblish.api.ContextPlugin): slate_frame = instance.get("slateFrame") version = instance.get("version") - else: # Search in directory data = dict() @@ -217,6 +215,7 @@ class CollectRenderedFrames(pyblish.api.ContextPlugin): families.append("render2d") if families_data and "slate" in families_data: families.append("slate") + families.append("slate.farm") if data.get("attachTo"): # we need to attach found collections to existing diff --git a/pype/plugins/global/publish/extract_burnin.py b/pype/plugins/global/publish/extract_burnin.py index e50ba891d2..55896fc742 100644 --- a/pype/plugins/global/publish/extract_burnin.py +++ b/pype/plugins/global/publish/extract_burnin.py @@ -32,6 +32,10 @@ class ExtractBurnin(pype.api.Extractor): frame_end = int(instance.data.get("frameEnd") or 1) duration = frame_end - frame_start + 1 + if "slate.farm" in instance.data["families"]: + frame_start += 1 + duration -= 1 + prep_data = { "username": instance.context.data['user'], "asset": os.environ['AVALON_ASSET'], @@ -48,22 +52,6 @@ class ExtractBurnin(pype.api.Extractor): datetime_data = instance.context.data.get("datetimeData") or {} prep_data.update(datetime_data) - slate_frame_start = frame_start - slate_frame_end = frame_end - slate_duration = duration - - # exception for slate workflow - if "slate" in instance.data["families"]: - slate_frame_start = frame_start - 1 - slate_frame_end = frame_end - slate_duration = slate_frame_end - slate_frame_start + 1 - - prep_data.update({ - "slate_frame_start": slate_frame_start, - "slate_frame_end": slate_frame_end, - "slate_duration": slate_duration - }) - # Update data with template data template_data = instance.data.get("assumedTemplateData") or {} prep_data.update(template_data) @@ -111,6 +99,26 @@ class ExtractBurnin(pype.api.Extractor): filled_anatomy = anatomy.format_all(_prep_data) _prep_data["anatomy"] = filled_anatomy.get_solved() + # dealing with slates + slate_frame_start = frame_start + slate_frame_end = frame_end + slate_duration = duration + + # exception for slate workflow + if ("slate" in instance.data["families"]): + if "slate-frame" in repre.get("tags", []): + slate_frame_start = frame_start - 1 + slate_frame_end = frame_end + slate_duration = duration + 1 + + self.log.debug("__1 slate_frame_start: {}".format(slate_frame_start)) + + _prep_data.update({ + "slate_frame_start": slate_frame_start, + "slate_frame_end": slate_frame_end, + "slate_duration": slate_duration + }) + burnin_data = { "input": full_movie_path.replace("\\", "/"), "codec": repre.get("codec", []), diff --git a/pype/plugins/nuke/publish/collect_writes.py b/pype/plugins/nuke/publish/collect_writes.py index c3e408341e..1afda6bc6c 100644 --- a/pype/plugins/nuke/publish/collect_writes.py +++ b/pype/plugins/nuke/publish/collect_writes.py @@ -44,7 +44,7 @@ class CollectNukeWrites(pyblish.api.InstancePlugin): frame_length = int( last_frame - first_frame + 1 ) - + if node["use_limit"].getValue(): handles = 0 first_frame = int(node["first"].getValue()) @@ -89,13 +89,22 @@ class CollectNukeWrites(pyblish.api.InstancePlugin): frame_start_str = "%0{}d".format( len(str(last_frame))) % first_frame representation['frameStart'] = frame_start_str + + # in case slate is expected and not yet rendered + self.log.debug("_ frame_length: {}".format(frame_length)) + self.log.debug( + "_ collected_frames_len: {}".format( + collected_frames_len)) + # this will only run if slate frame is not already + # rendered from previews publishes if "slate" in instance.data["families"] \ - and (frame_length != collected_frames_len): + and (frame_length == collected_frames_len): frame_slate_str = "%0{}d".format( len(str(last_frame))) % (first_frame - 1) slate_frame = collected_frames[0].replace( frame_start_str, frame_slate_str) collected_frames.insert(0, slate_frame) + representation['files'] = collected_frames instance.data["representations"].append(representation) except Exception: From cf6f213a967724d1fb879583ce6068ad2e5afe5c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 24 Feb 2020 15:18:01 +0100 Subject: [PATCH 05/19] added fixes of crashing sync to avalon event from develop to master --- pype/ftrack/events/event_sync_to_avalon.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/pype/ftrack/events/event_sync_to_avalon.py b/pype/ftrack/events/event_sync_to_avalon.py index 49ac50c1db..cfeec248fb 100644 --- a/pype/ftrack/events/event_sync_to_avalon.py +++ b/pype/ftrack/events/event_sync_to_avalon.py @@ -28,7 +28,7 @@ class SyncToAvalonEvent(BaseEvent): ignore_entTypes = [ "socialfeed", "socialnotification", "note", "assetversion", "job", "user", "reviewsessionobject", "timer", - "timelog", "auth_userrole", "appointment" + "timelog", "auth_userrole", "appointment", "notelabellink" ] ignore_ent_types = ["Milestone"] ignore_keys = ["statusid", "thumbid"] @@ -1545,6 +1545,14 @@ class SyncToAvalonEvent(BaseEvent): entity_type_conf_ids[entity_type] = configuration_id break + if not configuration_id: + self.log.warning( + "BUG REPORT: Missing configuration for `{} < {} >`".format( + entity_type, ent_info["entityType"] + ) + ) + continue + _entity_key = collections.OrderedDict({ "configuration_id": configuration_id, "entity_id": ftrack_id From c55a8c0ec6c62ca1735a2b8e712f0c6136c169d4 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 26 Feb 2020 09:43:47 +0100 Subject: [PATCH 06/19] entityTypes are not ignored but are specified which will be processed --- pype/ftrack/events/event_sync_to_avalon.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/pype/ftrack/events/event_sync_to_avalon.py b/pype/ftrack/events/event_sync_to_avalon.py index cfeec248fb..bb4bba1324 100644 --- a/pype/ftrack/events/event_sync_to_avalon.py +++ b/pype/ftrack/events/event_sync_to_avalon.py @@ -25,11 +25,7 @@ class SyncToAvalonEvent(BaseEvent): dbcon = DbConnector() - ignore_entTypes = [ - "socialfeed", "socialnotification", "note", - "assetversion", "job", "user", "reviewsessionobject", "timer", - "timelog", "auth_userrole", "appointment", "notelabellink" - ] + interest_entTypes = ["show", "task"] ignore_ent_types = ["Milestone"] ignore_keys = ["statusid", "thumbid"] @@ -477,7 +473,7 @@ class SyncToAvalonEvent(BaseEvent): found_actions = set() for ent_info in entities_info: entityType = ent_info["entityType"] - if entityType in self.ignore_entTypes: + if entityType not in self.interest_entTypes: continue entity_type = ent_info.get("entity_type") From d51cc4b2ec9284592bb454d921904bd4c7f3880b Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 26 Feb 2020 13:53:06 +0100 Subject: [PATCH 07/19] don't care about missing proj mainly when prepare projects is launched --- pype/ftrack/events/event_sync_to_avalon.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/pype/ftrack/events/event_sync_to_avalon.py b/pype/ftrack/events/event_sync_to_avalon.py index bb4bba1324..6f6e86ee20 100644 --- a/pype/ftrack/events/event_sync_to_avalon.py +++ b/pype/ftrack/events/event_sync_to_avalon.py @@ -102,9 +102,10 @@ class SyncToAvalonEvent(BaseEvent): if self._avalon_ents_by_id is None: self._avalon_ents_by_id = {} proj, ents = self.avalon_entities - self._avalon_ents_by_id[proj["_id"]] = proj - for ent in ents: - self._avalon_ents_by_id[ent["_id"]] = ent + if proj: + self._avalon_ents_by_id[proj["_id"]] = proj + for ent in ents: + self._avalon_ents_by_id[ent["_id"]] = ent return self._avalon_ents_by_id @property @@ -124,13 +125,14 @@ class SyncToAvalonEvent(BaseEvent): if self._avalon_ents_by_ftrack_id is None: self._avalon_ents_by_ftrack_id = {} proj, ents = self.avalon_entities - ftrack_id = proj["data"]["ftrackId"] - self._avalon_ents_by_ftrack_id[ftrack_id] = proj - for ent in ents: - ftrack_id = ent["data"].get("ftrackId") - if ftrack_id is None: - continue - self._avalon_ents_by_ftrack_id[ftrack_id] = ent + if proj: + ftrack_id = proj["data"]["ftrackId"] + self._avalon_ents_by_ftrack_id[ftrack_id] = proj + for ent in ents: + ftrack_id = ent["data"].get("ftrackId") + if ftrack_id is None: + continue + self._avalon_ents_by_ftrack_id[ftrack_id] = ent return self._avalon_ents_by_ftrack_id @property From 54cc0781932af210e7346316795da53395ecbb54 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 26 Feb 2020 15:14:35 +0100 Subject: [PATCH 08/19] allow create project structure for project managers --- pype/ftrack/actions/action_create_project_structure.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/ftrack/actions/action_create_project_structure.py b/pype/ftrack/actions/action_create_project_structure.py index 4589802f3a..6124ebe843 100644 --- a/pype/ftrack/actions/action_create_project_structure.py +++ b/pype/ftrack/actions/action_create_project_structure.py @@ -19,7 +19,7 @@ class CreateProjectFolders(BaseAction): #: Action description. description = 'Creates folder structure' #: roles that are allowed to register this action - role_list = ['Pypeclub', 'Administrator'] + role_list = ['Pypeclub', 'Administrator', 'Project Manager'] icon = '{}/ftrack/action_icons/CreateProjectFolders.svg'.format( os.environ.get('PYPE_STATICS_SERVER', '') ) From efd9305438e6de93afe8fb25d28af419dc1cd6e3 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 9 Mar 2020 17:02:37 +0100 Subject: [PATCH 09/19] status factory is initialized before checker thread starts --- pype/ftrack/ftrack_server/sub_event_status.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pype/ftrack/ftrack_server/sub_event_status.py b/pype/ftrack/ftrack_server/sub_event_status.py index 1a15a1f28d..d3e6a3d647 100644 --- a/pype/ftrack/ftrack_server/sub_event_status.py +++ b/pype/ftrack/ftrack_server/sub_event_status.py @@ -369,13 +369,6 @@ def main(args): # store socket connection object ObjectFactory.sock = sock - statuse_names = { - "main": "Main process", - "storer": "Event Storer", - "processor": "Event Processor" - } - - ObjectFactory.status_factory = StatusFactory(statuse_names) ObjectFactory.status_factory["main"].update(server_info) _returncode = 0 try: @@ -429,6 +422,13 @@ if __name__ == "__main__": signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) + statuse_names = { + "main": "Main process", + "storer": "Event Storer", + "processor": "Event Processor" + } + ObjectFactory.status_factory = StatusFactory(statuse_names) + checker_thread = OutputChecker() ObjectFactory.checker_thread = checker_thread checker_thread.start() From a206b8fe7ad2c9ce121de8ca635cce6ca54f150d Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Wed, 11 Mar 2020 17:37:57 +0100 Subject: [PATCH 10/19] hotfix: add textures family to integrator --- pype/plugins/global/publish/integrate_new.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pype/plugins/global/publish/integrate_new.py b/pype/plugins/global/publish/integrate_new.py index 1d061af173..aa214f36cb 100644 --- a/pype/plugins/global/publish/integrate_new.py +++ b/pype/plugins/global/publish/integrate_new.py @@ -80,7 +80,8 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): "matchmove", "image" "source", - "assembly" + "assembly", + "textures" ] exclude_families = ["clip"] db_representation_context_keys = [ From 02014e20cfec96ba2f188c2d21c2522dca2ebf0a Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 12 Mar 2020 11:22:53 +0100 Subject: [PATCH 11/19] fix(global): maya is collecting fps as string --- .../global/publish/collect_instance_anatomy_data.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pype/plugins/global/publish/collect_instance_anatomy_data.py b/pype/plugins/global/publish/collect_instance_anatomy_data.py index 4afcac118c..06a25b7c8a 100644 --- a/pype/plugins/global/publish/collect_instance_anatomy_data.py +++ b/pype/plugins/global/publish/collect_instance_anatomy_data.py @@ -110,11 +110,13 @@ class CollectInstanceAnatomyData(pyblish.api.InstancePlugin): pixel_aspect = instance.data.get("pixelAspect") if pixel_aspect: - anatomy_data["pixel_aspect"] = float("{:0.2f}".format(pixel_aspect)) + anatomy_data["pixel_aspect"] = float("{:0.2f}".format( + float(pixel_aspect))) fps = instance.data.get("fps") - if resolution_height: - anatomy_data["fps"] = float("{:0.2f}".format(fps)) + if fps: + anatomy_data["fps"] = float("{:0.2f}".format( + float(fps))) instance.data["projectEntity"] = project_entity instance.data["assetEntity"] = asset_entity From 6caa339d8254a65583e032cff9edfa90df82164b Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 13 Mar 2020 12:04:46 +0100 Subject: [PATCH 12/19] feat(global): adding no handles to extract burnin --- pype/plugins/global/publish/extract_burnin.py | 33 +++++++++++++++---- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/pype/plugins/global/publish/extract_burnin.py b/pype/plugins/global/publish/extract_burnin.py index 008bebb271..3d5de28153 100644 --- a/pype/plugins/global/publish/extract_burnin.py +++ b/pype/plugins/global/publish/extract_burnin.py @@ -4,7 +4,6 @@ import copy import pype.api import pyblish -from pypeapp import config class ExtractBurnin(pype.api.Extractor): @@ -30,6 +29,8 @@ class ExtractBurnin(pype.api.Extractor): 'version', instance.context.data.get('version')) frame_start = int(instance.data.get("frameStart") or 0) frame_end = int(instance.data.get("frameEnd") or 1) + handle_start = instance.data.get("handleStart") + handle_end = instance.data.get("handleEnd") duration = frame_end - frame_start + 1 prep_data = copy.deepcopy(instance.data["anatomyData"]) @@ -59,6 +60,9 @@ class ExtractBurnin(pype.api.Extractor): is_sequence = "sequence" in repre.get("tags", []) + # no handles switch from profile tags + no_handles = "no-handles" in repre.get("tags", []) + stagingdir = repre["stagingDir"] filename = "{0}".format(repre["files"]) @@ -90,17 +94,32 @@ class ExtractBurnin(pype.api.Extractor): filled_anatomy = anatomy.format_all(_prep_data) _prep_data["anatomy"] = filled_anatomy.get_solved() + # copy frame range variables + frame_start_cp = frame_start + frame_end_cp = frame_end + duration_cp = duration + + if no_handles: + frame_start_cp = frame_start + handle_start + frame_end_cp = frame_end - handle_end + duration_cp = frame_end_cp - frame_start_cp + 1 + _prep_data.update({ + "frame_start": frame_start_cp, + "frame_end": frame_end_cp, + "duration": duration_cp, + }) + # dealing with slates - slate_frame_start = frame_start - slate_frame_end = frame_end - slate_duration = duration + slate_frame_start = frame_start_cp + slate_frame_end = frame_end_cp + slate_duration = duration_cp # exception for slate workflow if ("slate" in instance.data["families"]): if "slate-frame" in repre.get("tags", []): - slate_frame_start = frame_start - 1 - slate_frame_end = frame_end - slate_duration = duration + 1 + slate_frame_start = frame_start_cp - 1 + slate_frame_end = frame_end_cp + slate_duration = duration_cp + 1 self.log.debug("__1 slate_frame_start: {}".format(slate_frame_start)) From 0123c8c5776fc97887a7202082c4d27f84253004 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 13 Mar 2020 12:11:35 +0100 Subject: [PATCH 13/19] feat(global): extract review no handles tag --- pype/plugins/global/publish/extract_review.py | 45 +++++++++++++++---- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/pype/plugins/global/publish/extract_review.py b/pype/plugins/global/publish/extract_review.py index f5dba108c5..c7f286c3e2 100644 --- a/pype/plugins/global/publish/extract_review.py +++ b/pype/plugins/global/publish/extract_review.py @@ -31,12 +31,17 @@ class ExtractReview(pyblish.api.InstancePlugin): output_profiles = self.outputs or {} inst_data = instance.data - fps = inst_data.get("fps") - start_frame = inst_data.get("frameStart") - resolution_width = inst_data.get("resolutionWidth", to_width) - resolution_height = inst_data.get("resolutionHeight", to_height) + fps = float(inst_data.get("fps")) + frame_start = inst_data.get("frameStart") + frame_end = inst_data.get("frameEnd") + handle_start = inst_data.get("handleStart") + handle_end = inst_data.get("handleEnd") pixel_aspect = inst_data.get("pixelAspect", 1) self.log.debug("Families In: `{}`".format(inst_data["families"])) + self.log.debug("__ frame_start: {}".format(frame_start)) + self.log.debug("__ frame_end: {}".format(frame_end)) + self.log.debug("__ handle_start: {}".format(handle_start)) + self.log.debug("__ handle_end: {}".format(handle_end)) # get representation and loop them representations = inst_data["representations"] @@ -73,6 +78,9 @@ class ExtractReview(pyblish.api.InstancePlugin): is_sequence = ("sequence" in p_tags) and (ext in ( "png", "jpg", "jpeg")) + # no handles switch from profile tags + no_handles = "no-handles" in p_tags + self.log.debug("Profile name: {}".format(name)) if not ext: @@ -142,6 +150,7 @@ class ExtractReview(pyblish.api.InstancePlugin): self.log.info("new_tags: `{}`".format(new_tags)) input_args = [] + output_args = [] # overrides output file input_args.append("-y") @@ -152,12 +161,20 @@ class ExtractReview(pyblish.api.InstancePlugin): # necessary input data # adds start arg only if image sequence if isinstance(repre["files"], list): + if frame_start != repre.get("detectedStart", frame_start): + frame_start = repre.get("detectedStart") + + # exclude handle if no handles defined + if no_handles: + frame_start += handle_start - if start_frame != repre.get("detectedStart", start_frame): - start_frame = repre.get("detectedStart") input_args.append( "-start_number {0} -framerate {1}".format( - start_frame, fps)) + frame_start, fps)) + else: + if no_handles: + start_sec = float(handle_start) / fps + input_args.append("-ss {:0.2f}".format(start_sec)) input_args.append("-i {}".format(full_input_path)) @@ -191,7 +208,6 @@ class ExtractReview(pyblish.api.InstancePlugin): ] ) - output_args = [] codec_args = profile.get('codec', []) output_args.extend(codec_args) # preset's output data @@ -238,6 +254,13 @@ class ExtractReview(pyblish.api.InstancePlugin): # In case audio is longer than video. output_args.append("-shortest") + if no_handles: + duration_sec = float( + (frame_end - ( + frame_start + handle_start + ) + 1) - handle_end) / fps + output_args.append("-t {:0.2f}".format(duration_sec)) + # output filename output_args.append(full_output_path) @@ -321,6 +344,7 @@ class ExtractReview(pyblish.api.InstancePlugin): self.log.debug( "_ output_args: `{}`".format(output_args)) + if is_sequence: stg_dir = os.path.dirname(full_output_path) @@ -358,7 +382,10 @@ class ExtractReview(pyblish.api.InstancePlugin): "stagingDir": stg_dir, "files": os.listdir(stg_dir) }) - + if no_handles: + repre_new.update({ + "outputName": name + "_noHandles" + }) if repre_new.get('preview'): repre_new.pop("preview") if repre_new.get('thumbnail'): From 76cb3b37e27b70840b999ceff69df02551078ef5 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 13 Mar 2020 16:42:25 +0100 Subject: [PATCH 14/19] fix(global): adding back resolution attribtes wrong commitment had erased them --- pype/plugins/global/publish/extract_review.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pype/plugins/global/publish/extract_review.py b/pype/plugins/global/publish/extract_review.py index c7f286c3e2..81d7e1668a 100644 --- a/pype/plugins/global/publish/extract_review.py +++ b/pype/plugins/global/publish/extract_review.py @@ -37,6 +37,8 @@ class ExtractReview(pyblish.api.InstancePlugin): handle_start = inst_data.get("handleStart") handle_end = inst_data.get("handleEnd") pixel_aspect = inst_data.get("pixelAspect", 1) + resolution_width = inst_data.get("resolutionWidth", self.to_width) + resolution_height = inst_data.get("resolutionHeight", self.to_height) self.log.debug("Families In: `{}`".format(inst_data["families"])) self.log.debug("__ frame_start: {}".format(frame_start)) self.log.debug("__ frame_end: {}".format(frame_end)) @@ -344,7 +346,6 @@ class ExtractReview(pyblish.api.InstancePlugin): self.log.debug( "_ output_args: `{}`".format(output_args)) - if is_sequence: stg_dir = os.path.dirname(full_output_path) From d484e5108c034edcc6d84de6038a23e10753f481 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 13 Mar 2020 18:02:52 +0100 Subject: [PATCH 15/19] fix(global): self.to_width and height is in another PR --- pype/plugins/global/publish/extract_review.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pype/plugins/global/publish/extract_review.py b/pype/plugins/global/publish/extract_review.py index 81d7e1668a..d03de6ad61 100644 --- a/pype/plugins/global/publish/extract_review.py +++ b/pype/plugins/global/publish/extract_review.py @@ -37,8 +37,8 @@ class ExtractReview(pyblish.api.InstancePlugin): handle_start = inst_data.get("handleStart") handle_end = inst_data.get("handleEnd") pixel_aspect = inst_data.get("pixelAspect", 1) - resolution_width = inst_data.get("resolutionWidth", self.to_width) - resolution_height = inst_data.get("resolutionHeight", self.to_height) + resolution_width = inst_data.get("resolutionWidth", to_width) + resolution_height = inst_data.get("resolutionHeight", to_height) self.log.debug("Families In: `{}`".format(inst_data["families"])) self.log.debug("__ frame_start: {}".format(frame_start)) self.log.debug("__ frame_end: {}".format(frame_end)) From ba55689b4339212e545a4c5da88800f5d362bd2a Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Fri, 13 Mar 2020 20:02:06 +0100 Subject: [PATCH 16/19] fall back to context handles if not present in instance --- pype/plugins/global/publish/collect_avalon_entities.py | 5 +++++ pype/plugins/global/publish/extract_burnin.py | 8 ++++++-- pype/plugins/global/publish/extract_review.py | 7 +++++-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/pype/plugins/global/publish/collect_avalon_entities.py b/pype/plugins/global/publish/collect_avalon_entities.py index a429b3fc84..a4f14421f2 100644 --- a/pype/plugins/global/publish/collect_avalon_entities.py +++ b/pype/plugins/global/publish/collect_avalon_entities.py @@ -45,3 +45,8 @@ class CollectAvalonEntities(pyblish.api.ContextPlugin): context.data["projectEntity"] = project_entity context.data["assetEntity"] = asset_entity + + data = asset_entity['data'] + context.data['handles'] = int(data.get("handles", 0)) + context.data["handleStart"] = int(data.get( "handleStart", 0)) + context.data["handleEnd"] = int(data.get("handleEnd", 0)) diff --git a/pype/plugins/global/publish/extract_burnin.py b/pype/plugins/global/publish/extract_burnin.py index 3d5de28153..faecbb47a7 100644 --- a/pype/plugins/global/publish/extract_burnin.py +++ b/pype/plugins/global/publish/extract_burnin.py @@ -25,12 +25,16 @@ class ExtractBurnin(pype.api.Extractor): if "representations" not in instance.data: raise RuntimeError("Burnin needs already created mov to work on.") + context_data = instance.context.data + version = instance.data.get( 'version', instance.context.data.get('version')) frame_start = int(instance.data.get("frameStart") or 0) frame_end = int(instance.data.get("frameEnd") or 1) - handle_start = instance.data.get("handleStart") - handle_end = instance.data.get("handleEnd") + handle_start = instance.data.get("handleStart", + context_data.get("handleStart")) + handle_end = instance.data.get("handleEnd", + context_data.get("handleEnd")) duration = frame_end - frame_start + 1 prep_data = copy.deepcopy(instance.data["anatomyData"]) diff --git a/pype/plugins/global/publish/extract_review.py b/pype/plugins/global/publish/extract_review.py index d03de6ad61..7f88a89004 100644 --- a/pype/plugins/global/publish/extract_review.py +++ b/pype/plugins/global/publish/extract_review.py @@ -31,11 +31,14 @@ class ExtractReview(pyblish.api.InstancePlugin): output_profiles = self.outputs or {} inst_data = instance.data + context_data = instance.context.data fps = float(inst_data.get("fps")) frame_start = inst_data.get("frameStart") frame_end = inst_data.get("frameEnd") - handle_start = inst_data.get("handleStart") - handle_end = inst_data.get("handleEnd") + handle_start = inst_data.get("handleStart", + context_data.get("handleStart")) + handle_end = inst_data.get("handleEnd", + context_data.get("handleEnd")) pixel_aspect = inst_data.get("pixelAspect", 1) resolution_width = inst_data.get("resolutionWidth", to_width) resolution_height = inst_data.get("resolutionHeight", to_height) From 300ea97f1ecbce5c6f73761cae469b948b862af8 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Fri, 13 Mar 2020 20:32:29 +0100 Subject: [PATCH 17/19] move handles collection to global plugins --- .../global/publish/collect_avalon_entities.py | 6 ++--- .../nuke/publish/collect_asset_info.py | 25 ------------------- 2 files changed, 3 insertions(+), 28 deletions(-) delete mode 100644 pype/plugins/nuke/publish/collect_asset_info.py diff --git a/pype/plugins/global/publish/collect_avalon_entities.py b/pype/plugins/global/publish/collect_avalon_entities.py index a4f14421f2..20899361c5 100644 --- a/pype/plugins/global/publish/collect_avalon_entities.py +++ b/pype/plugins/global/publish/collect_avalon_entities.py @@ -30,7 +30,7 @@ class CollectAvalonEntities(pyblish.api.ContextPlugin): assert project_entity, ( "Project '{0}' was not found." ).format(project_name) - self.log.debug("Collected Project entity \"{}\"".format(project_entity)) + self.log.debug("Collected Project \"{}\"".format(project_entity)) asset_entity = io.find_one({ "type": "asset", @@ -41,12 +41,12 @@ class CollectAvalonEntities(pyblish.api.ContextPlugin): "No asset found by the name '{0}' in project '{1}'" ).format(asset_name, project_name) - self.log.debug("Collected Asset entity \"{}\"".format(asset_entity)) + self.log.debug("Collected Asset \"{}\"".format(asset_entity)) context.data["projectEntity"] = project_entity context.data["assetEntity"] = asset_entity data = asset_entity['data'] context.data['handles'] = int(data.get("handles", 0)) - context.data["handleStart"] = int(data.get( "handleStart", 0)) + context.data["handleStart"] = int(data.get("handleStart", 0)) context.data["handleEnd"] = int(data.get("handleEnd", 0)) diff --git a/pype/plugins/nuke/publish/collect_asset_info.py b/pype/plugins/nuke/publish/collect_asset_info.py deleted file mode 100644 index 8a8791ec36..0000000000 --- a/pype/plugins/nuke/publish/collect_asset_info.py +++ /dev/null @@ -1,25 +0,0 @@ -from avalon import api, io -import pyblish.api - - -class CollectAssetInfo(pyblish.api.ContextPlugin): - """Collect framerate.""" - - order = pyblish.api.CollectorOrder - label = "Collect Asset Info" - hosts = [ - "nuke", - "nukeassist" - ] - - def process(self, context): - asset_data = io.find_one({ - "type": "asset", - "name": api.Session["AVALON_ASSET"] - }) - self.log.info("asset_data: {}".format(asset_data)) - - context.data['handles'] = int(asset_data["data"].get("handles", 0)) - context.data["handleStart"] = int(asset_data["data"].get( - "handleStart", 0)) - context.data["handleEnd"] = int(asset_data["data"].get("handleEnd", 0)) From 7bd4182c30243ecb0f7e3803eb3157f62859f658 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Fri, 13 Mar 2020 20:32:51 +0100 Subject: [PATCH 18/19] remove handles from ftrack frame range --- pype/plugins/global/publish/extract_review.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/pype/plugins/global/publish/extract_review.py b/pype/plugins/global/publish/extract_review.py index 7f88a89004..fa29fd2fe0 100644 --- a/pype/plugins/global/publish/extract_review.py +++ b/pype/plugins/global/publish/extract_review.py @@ -12,7 +12,8 @@ class ExtractReview(pyblish.api.InstancePlugin): otherwise the representation is ignored. All new represetnations are created and encoded by ffmpeg following - presets found in `pype-config/presets/plugins/global/publish.json:ExtractReview:outputs`. To change the file extension + presets found in `pype-config/presets/plugins/global/ + publish.json:ExtractReview:outputs`. To change the file extension filter values use preset's attributes `ext_filter` """ @@ -171,7 +172,8 @@ class ExtractReview(pyblish.api.InstancePlugin): # exclude handle if no handles defined if no_handles: - frame_start += handle_start + frame_start_no_handles = frame_start + handle_start + frame_end_no_handles = frame_end - handle_end input_args.append( "-start_number {0} -framerate {1}".format( @@ -180,6 +182,8 @@ class ExtractReview(pyblish.api.InstancePlugin): if no_handles: start_sec = float(handle_start) / fps input_args.append("-ss {:0.2f}".format(start_sec)) + frame_start_no_handles += handle_start + frame_end_no_handles -= handle_end input_args.append("-i {}".format(full_input_path)) @@ -379,7 +383,7 @@ class ExtractReview(pyblish.api.InstancePlugin): "codec": codec_args, "_profile": profile, "resolutionHeight": resolution_height, - "resolutionWidth": resolution_width, + "resolutionWidth": resolution_width }) if is_sequence: repre_new.update({ @@ -388,7 +392,9 @@ class ExtractReview(pyblish.api.InstancePlugin): }) if no_handles: repre_new.update({ - "outputName": name + "_noHandles" + "outputName": name + "_noHandles", + "startFrameReview": frame_start_no_handles, + "endFrameReview": frame_end_no_handles }) if repre_new.get('preview'): repre_new.pop("preview") From 47f04e0fbaf3acf2f8cc1302674573f1aa3c6f6a Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Fri, 13 Mar 2020 20:41:28 +0100 Subject: [PATCH 19/19] fix frame range on review --- pype/plugins/global/publish/extract_review.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pype/plugins/global/publish/extract_review.py b/pype/plugins/global/publish/extract_review.py index fa29fd2fe0..23e582edd2 100644 --- a/pype/plugins/global/publish/extract_review.py +++ b/pype/plugins/global/publish/extract_review.py @@ -182,8 +182,8 @@ class ExtractReview(pyblish.api.InstancePlugin): if no_handles: start_sec = float(handle_start) / fps input_args.append("-ss {:0.2f}".format(start_sec)) - frame_start_no_handles += handle_start - frame_end_no_handles -= handle_end + frame_start_no_handles = frame_start + handle_start + frame_end_no_handles = frame_end - handle_end input_args.append("-i {}".format(full_input_path))