diff --git a/pype/nukestudio/precomp_clip.py b/pype/nukestudio/precomp_clip.py index 9920a2aa31..426a13f0c7 100644 --- a/pype/nukestudio/precomp_clip.py +++ b/pype/nukestudio/precomp_clip.py @@ -1,6 +1,6 @@ -from hiero.core import * -from hiero.ui import * -import ft_utils +import hiero.core +import hiero.ui + import re import os @@ -11,31 +11,30 @@ def create_nk_script_clips(script_lst, seq=None): [{ 'path': 'P:/Jakub_testy_pipeline/test_v01.nk', 'name': 'test', - 'timeline_frame_in': 10, 'handles': 10, - 'source_start': 0, - 'source_end': 54, + 'handleStart': 15, # added asymetrically to handles + 'handleEnd': 10, # added asymetrically to handles + 'timelineIn': 16, + 'startFrame': 991, + 'endFrame': 1023, 'task': 'Comp-tracking', 'work_dir': 'VFX_PR', 'shot': '00010' }] ''' - env = ft_utils.Env() - proj = projects()[-1] + + proj = hiero.core.projects()[-1] root = proj.clipsBin() if not seq: - seq = Sequence('NewSequences') - root.addItem(BinItem(seq)) + seq = hiero.core.Sequence('NewSequences') + root.addItem(hiero.core.BinItem(seq)) # todo will ned to define this better # track = seq[1] # lazy example to get a destination# track clips_lst = [] for nk in script_lst: - task_short = env.task_codes[nk['task']] - script_file = task_short task_path = '/'.join([nk['work_dir'], nk['shot'], nk['task']]) bin = create_bin_in_project(task_path, proj) - task_path += script_file if nk['task'] not in seq.videoTracks(): track = hiero.core.VideoTrack(nk['task']) @@ -44,33 +43,63 @@ def create_nk_script_clips(script_lst, seq=None): track = seq.tracks(nk['task']) # create slip media - print nk['path'] - media = MediaSource(nk['path']) - print media - source = Clip(media) - print source + print("__ path: `{}`".format(nk['path'])) + + media = hiero.core.MediaSource(nk['path']) + media_in = int(media.startTime() or 0) + media_duration = int(media.duration() or 0) + + handle_start = nk.get("handleStart") or nk['handles'] + handle_end = nk.get("handleEnd") or nk['handles'] + + if media_in: + source_in = media_in + handle_start + else: + source_in = nk['startFrame'] + handle_start + + if media_duration: + source_out = (media_in + media_duration - 1) - handle_end + else: + source_out = nk['endFrame'] - handle_end + + print("__ media: `{}`".format(media)) + print("__ media_in: `{}`".format(media_in)) + print("__ media_duration : `{}`".format(media_duration)) + print("__ source_in: `{}`".format(source_in)) + print("__ source_out : `{}`".format(source_out)) + + source = hiero.core.Clip(media) + print("__ source : `{}`".format(source)) + print("__ source.sourceIn(): `{}`".format(source.sourceIn())) + name = os.path.basename(os.path.splitext(nk['path'])[0]) - split_name = split_by_client_version(name, env)[0] or name - print split_name - # print source + split_name = split_by_client_version(name)[0] or name + + print("__ split_name: `{}`".format(split_name)) + # add to bin as clip item items_in_bin = [b.name() for b in bin.items()] if split_name not in items_in_bin: - binItem = BinItem(source) + binItem = hiero.core.BinItem(source) bin.addItem(binItem) - print bin.items() + + print("__ bin.items(): `{}`".format(bin.items())) + new_source = [ item for item in bin.items() if split_name in item.name() ][0].items()[0].item() - print new_source + + print("__ new_source: `{}`".format(new_source)) + print("__ new_source: `{}`".format(new_source)) + # add to track as clip item - trackItem = TrackItem(split_name, TrackItem.kVideo) + trackItem = hiero.core.TrackItem(split_name, hiero.core.TrackItem.kVideo) trackItem.setSource(new_source) - trackItem.setSourceIn(nk['source_start'] + nk['handles']) - trackItem.setSourceOut(nk['source_end'] - nk['handles']) - trackItem.setTimelineIn(nk['source_start'] + nk['timeline_frame_in']) - trackItem.setTimelineOut( - (nk['source_end'] - (nk['handles'] * 2)) + nk['timeline_frame_in']) + trackItem.setSourceIn(source_in) + trackItem.setSourceOut(source_out) + trackItem.setSourceIn(source_in) + trackItem.setTimelineIn(nk['timelineIn']) + trackItem.setTimelineOut(nk['timelineIn'] + (source_out - source_in)) track.addTrackItem(trackItem) track.addTrackItem(trackItem) clips_lst.append(trackItem) @@ -86,7 +115,7 @@ def create_bin_in_project(bin_name='', project=''): if not project: # get the first loaded project - project = projects()[0] + project = hiero.core.projects()[-1] if not bin_name: return None if '/' in bin_name: @@ -103,7 +132,7 @@ def create_bin_in_project(bin_name='', project=''): bin = [bin for bin in clipsBin.bins() if b in bin.name()][0] done_bin_lst.append(bin) else: - create_bin = Bin(b) + create_bin = hiero.core.Bin(b) clipsBin.addItem(create_bin) done_bin_lst.append(create_bin) @@ -115,7 +144,7 @@ def create_bin_in_project(bin_name='', project=''): ][0] done_bin_lst.append(bin) else: - create_bin = Bin(b) + create_bin = hiero.core.Bin(b) done_bin_lst[i - 1].addItem(create_bin) done_bin_lst.append(create_bin) @@ -127,22 +156,33 @@ def create_bin_in_project(bin_name='', project=''): ][0] done_bin_lst.append(bin) else: - create_bin = Bin(b) + create_bin = hiero.core.Bin(b) done_bin_lst[i - 1].addItem(create_bin) done_bin_lst.append(create_bin) # print [bin.name() for bin in clipsBin.bins()] return done_bin_lst[-1] -def split_by_client_version(string, env=None): - if not env: - env = ft_utils.Env() - - client_letter, client_digits = env.get_version_type('client') - regex = "[/_.]" + client_letter + "\d+" +def split_by_client_version(string): + regex = r"[/_.]v\d+" try: matches = re.findall(regex, string, re.IGNORECASE) return string.split(matches[0]) - except Exception, e: - print e + except Exception as e: + print(e) return None + + +script_lst = [{ + 'path': 'C:/Users/hubert/_PYPE_testing/projects/D001_projectx/episodes/ep120/ep120sq01/120sh020/publish/plates/platesMain/v023/prjx_120sh020_platesMain_v023.nk', + 'name': '120sh020_platesMain', + 'handles': 10, + 'handleStart': 10, + 'handleEnd': 10, + 'timelineIn': 16, + 'startFrame': 991, + 'endFrame': 1023, + 'task': 'platesMain', + 'work_dir': 'shots', + 'shot': '120sh020' +}] diff --git a/pype/nukestudio/tags.py b/pype/nukestudio/tags.py index 8d1ec9e43a..e6c29a4f4e 100644 --- a/pype/nukestudio/tags.py +++ b/pype/nukestudio/tags.py @@ -37,11 +37,11 @@ def update_tag(tag, value): """ tag.setNote(value['note']) - tag.setIcon(value['icon']['path']) + tag.setIcon(str(value['icon']['path'])) mtd = tag.metadata() pres_mtd = value.get('metadata', None) if pres_mtd: - [mtd.setValue("tag.{}".format(k), v) + [mtd.setValue("tag.{}".format(str(k)), str(v)) for k, v in pres_mtd.items()] return tag diff --git a/pype/plugins/ftrack/publish/integrate_ftrack_api.py b/pype/plugins/ftrack/publish/integrate_ftrack_api.py index 2c35b974f9..87b14b612b 100644 --- a/pype/plugins/ftrack/publish/integrate_ftrack_api.py +++ b/pype/plugins/ftrack/publish/integrate_ftrack_api.py @@ -56,7 +56,15 @@ class IntegrateFtrackApi(pyblish.api.InstancePlugin): def process(self, instance): session = instance.context.data["ftrackSession"] - if instance.context.data.get("ftrackTask"): + if instance.data.get("ftrackTask"): + task = instance.data["ftrackTask"] + name = task + parent = task["parent"] + elif instance.data.get("ftrackEntity"): + task = None + name = instance.data.get("ftrackEntity")['name'] + parent = instance.data.get("ftrackEntity") + elif instance.context.data.get("ftrackTask"): task = instance.context.data["ftrackTask"] name = task parent = task["parent"] diff --git a/pype/plugins/ftrack/publish/integrate_ftrack_instances.py b/pype/plugins/ftrack/publish/integrate_ftrack_instances.py index a4624d7299..492271d844 100644 --- a/pype/plugins/ftrack/publish/integrate_ftrack_instances.py +++ b/pype/plugins/ftrack/publish/integrate_ftrack_instances.py @@ -25,7 +25,9 @@ class IntegrateFtrackInstance(pyblish.api.InstancePlugin): 'write': 'img', 'render': 'render', 'nukescript': 'comp', - 'review': 'mov'} + 'review': 'mov', + 'plates': 'img' + } def process(self, instance): self.log.debug('instance {}'.format(instance)) diff --git a/pype/plugins/ftrack/publish/integrate_hierarchy_ftrack.py b/pype/plugins/ftrack/publish/integrate_hierarchy_ftrack.py index 377e2d816e..b16eafabd9 100644 --- a/pype/plugins/ftrack/publish/integrate_hierarchy_ftrack.py +++ b/pype/plugins/ftrack/publish/integrate_hierarchy_ftrack.py @@ -45,7 +45,7 @@ class IntegrateHierarchyToFtrack(pyblish.api.ContextPlugin): def import_to_ftrack(self, input_data, parent=None): for entity_name in input_data: entity_data = input_data[entity_name] - entity_type = entity_data['entity_type'].capitalize() + entity_type = entity_data['entity_type'] if entity_type.lower() == 'project': query = 'Project where full_name is "{}"'.format(entity_name) @@ -85,8 +85,9 @@ class IntegrateHierarchyToFtrack(pyblish.api.ContextPlugin): 'Missing custom attribute') entity['custom_attributes'][key] = custom_attributes[key] + for instance in instances: - instance.data['ftrackShotId'] = entity['id'] + instance.data['ftrackEntity'] = entity self.session.commit() @@ -108,7 +109,7 @@ class IntegrateHierarchyToFtrack(pyblish.api.ContextPlugin): for task in tasks_to_create: self.create_task( name=task, - task_type=task.capitalize(), + task_type=task, parent=entity ) self.session.commit() diff --git a/pype/plugins/global/publish/cleanup.py b/pype/plugins/global/publish/cleanup.py index 68ec9a48ad..f31477faca 100644 --- a/pype/plugins/global/publish/cleanup.py +++ b/pype/plugins/global/publish/cleanup.py @@ -14,6 +14,8 @@ class CleanUp(pyblish.api.InstancePlugin): order = pyblish.api.IntegratorOrder + 10 label = "Clean Up" exclude_families = ["clip"] + optional = True + active = True def process(self, instance): if [ef for ef in self.exclude_families diff --git a/pype/plugins/global/publish/collect_assumed_destination.py b/pype/plugins/global/publish/collect_assumed_destination.py index fa6a3d9423..a04933b8c6 100644 --- a/pype/plugins/global/publish/collect_assumed_destination.py +++ b/pype/plugins/global/publish/collect_assumed_destination.py @@ -12,13 +12,15 @@ class CollectAssumedDestination(pyblish.api.ContextPlugin): exclude_families = ["clip"] def process(self, context): + for instance in context: + if [ef for ef in self.exclude_families + if ef in instance.data["family"]]: + self.log.info("Ignoring instance: {}".format(instance)) + return self.process_item(instance) def process_item(self, instance): - if [ef for ef in self.exclude_families - if instance.data["family"] in ef]: - return self.create_destination_template(instance) diff --git a/pype/plugins/global/publish/collect_presets.py b/pype/plugins/global/publish/collect_presets.py index 8edf9797de..58bb26e261 100644 --- a/pype/plugins/global/publish/collect_presets.py +++ b/pype/plugins/global/publish/collect_presets.py @@ -9,6 +9,21 @@ class CollectPresets(api.ContextPlugin): label = "Collect Presets" def process(self, context): - context.data["presets"] = config.get_presets() + presets = config.get_presets() + try: + # try if it is not in projects custom directory + # `{PYPE_PROJECT_CONFIGS}/[PROJECT_NAME]/init.json` + # init.json define preset names to be used + p_init = presets["init"] + presets["colorspace"] = presets["colorspace"][p_init["colorspace"]] + presets["dataflow"] = presets["dataflow"][p_init["dataflow"]] + except KeyError: + log.warning("No projects custom preset available...") + presets["colorspace"] = presets["colorspace"]["default"] + presets["dataflow"] = presets["dataflow"]["default"] + log.info("Presets `colorspace` and `dataflow` loaded from `default`...") + + context.data["presets"] = presets + self.log.info(context.data["presets"]) return diff --git a/pype/plugins/global/publish/integrate_assumed_destination.py b/pype/plugins/global/publish/integrate_assumed_destination.py index 03113cd3fc..758eca5a9f 100644 --- a/pype/plugins/global/publish/integrate_assumed_destination.py +++ b/pype/plugins/global/publish/integrate_assumed_destination.py @@ -13,14 +13,14 @@ class IntegrateAssumedDestination(pyblish.api.InstancePlugin): def process(self, instance): - self.create_destination_template(instance) + anatomy = instance.context.data['anatomy'] + + self.create_destination_template(instance, anatomy) template_data = instance.data["assumedTemplateData"] - # template = instance.data["template"] - - anatomy = instance.context.data['anatomy'] # self.log.info(anatomy.templates) anatomy_filled = anatomy.format(template_data) + # self.log.info(anatomy_filled) mock_template = anatomy_filled["publish"]["path"] @@ -30,7 +30,7 @@ class IntegrateAssumedDestination(pyblish.api.InstancePlugin): "resources") # Clean the path - mock_destination = os.path.abspath(os.path.normpath(mock_destination)) + mock_destination = os.path.abspath(os.path.normpath(mock_destination)).replace("\\", "/") # Define resource destination and transfers resources = instance.data.get("resources", list()) @@ -38,7 +38,7 @@ class IntegrateAssumedDestination(pyblish.api.InstancePlugin): for resource in resources: # Add destination to the resource - source_filename = os.path.basename(resource["source"]) + source_filename = os.path.basename(resource["source"]).replace("\\", "/") destination = os.path.join(mock_destination, source_filename) # Force forward slashes to fix issue with software unable @@ -53,13 +53,13 @@ class IntegrateAssumedDestination(pyblish.api.InstancePlugin): files = resource['files'] for fsrc in files: fname = os.path.basename(fsrc) - fdest = os.path.join(mock_destination, fname) + fdest = os.path.join(mock_destination, fname).replace("\\", "/") transfers.append([fsrc, fdest]) instance.data["resources"] = resources instance.data["transfers"] = transfers - def create_destination_template(self, instance): + def create_destination_template(self, instance, anatomy): """Create a filepath based on the current data available Example template: @@ -77,12 +77,13 @@ class IntegrateAssumedDestination(pyblish.api.InstancePlugin): self.log.info(subset_name) asset_name = instance.data["asset"] project_name = api.Session["AVALON_PROJECT"] + a_template = anatomy.templates project = io.find_one({"type": "project", "name": project_name}, projection={"config": True, "data": True}) - template = project["config"]["template"]["publish"] + template = a_template['publish']['path'] # anatomy = instance.context.data['anatomy'] asset = io.find_one({"type": "asset", @@ -112,10 +113,12 @@ class IntegrateAssumedDestination(pyblish.api.InstancePlugin): if instance.data.get('version'): version_number = int(instance.data.get('version')) + padding = int(a_template['render']['padding']) + hierarchy = asset['data']['parents'] if hierarchy: # hierarchy = os.path.sep.join(hierarchy) - hierarchy = os.path.join(*hierarchy) + hierarchy = "/".join(hierarchy) template_data = {"root": api.Session["AVALON_PROJECTS"], "project": {"name": project_name, @@ -124,6 +127,7 @@ class IntegrateAssumedDestination(pyblish.api.InstancePlugin): "family": instance.data['family'], "asset": asset_name, "subset": subset_name, + "frame": ('#' * padding), "version": version_number, "hierarchy": hierarchy, "representation": "TEMP"} diff --git a/pype/plugins/global/publish/integrate_new.py b/pype/plugins/global/publish/integrate_new.py index 0ffe84987b..c330654e41 100644 --- a/pype/plugins/global/publish/integrate_new.py +++ b/pype/plugins/global/publish/integrate_new.py @@ -59,7 +59,8 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): "review", "nukescript", "render", - "write" + "write", + "plates" ] exclude_families = ["clip"] @@ -80,6 +81,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): # Required environment variables PROJECT = api.Session["AVALON_PROJECT"] ASSET = instance.data.get("asset") or api.Session["AVALON_ASSET"] + TASK = instance.data.get("task") or api.Session["AVALON_TASK"] LOCATION = api.Session["AVALON_LOCATION"] context = instance.context @@ -159,6 +161,12 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): self.log.debug("Next version: v{0:03d}".format(next_version)) version_data = self.create_version_data(context, instance) + + version_data_instance = instance.data.get('versionData') + + if version_data_instance: + version_data.update(version_data_instance) + version = self.create_version(subset=subset, version_number=next_version, locations=[LOCATION], @@ -192,7 +200,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): "project": {"name": PROJECT, "code": project['data']['code']}, "silo": asset['silo'], - "task": api.Session["AVALON_TASK"], + "task": TASK, "asset": ASSET, "family": instance.data['family'], "subset": subset["name"], @@ -209,7 +217,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): if 'transfers' not in instance.data: instance.data['transfers'] = [] - for idx, repre in enumerate(instance.data["representations"]): + for idx, repre in enumerate(repres): # Collection # _______ @@ -226,7 +234,9 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): stagingdir = repre['stagingDir'] if repre.get('anatomy_template'): template_name = repre['anatomy_template'] - template = anatomy.templates[template_name]["path"] + template = os.path.normpath( + anatomy.templates[template_name]["path"]) + if isinstance(files, list): src_collections, remainder = clique.assemble(files) @@ -244,7 +254,9 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): "{padding}") % i anatomy_filled = anatomy.format(template_data) test_dest_files.append( - anatomy_filled[template_name]["path"]) + os.path.normpath( + anatomy_filled[template_name]["path"]) + ) self.log.debug( "test_dest_files: {}".format(str(test_dest_files))) @@ -253,7 +265,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): dst_head = dst_collection.format("{head}") dst_tail = dst_collection.format("{tail}") - instance.data["representations"][idx]['published_path'] = dst_collection.format() + repres[idx]['published_path'] = dst_collection.format() for i in src_collection.indexes: src_padding = src_collection.format("{padding}") % i @@ -264,10 +276,14 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): dst = "{0}{1}{2}".format(dst_head, dst_padding, dst_tail) src = os.path.join(stagingdir, src_file_name) - # src = src_file_name self.log.debug("source: {}".format(src)) instance.data["transfers"].append([src, dst]) + # for imagesequence version data + hashes = '#' * len(dst_padding) + dst = "{0}{1}{2}".format(dst_head, hashes, dst_tail) + + else: # Single file # _______ @@ -292,7 +308,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): dst = anatomy_filled[template_name]["path"] instance.data["transfers"].append([src, dst]) - instance.data["representations"][idx]['published_path'] = dst + repres[idx]['published_path'] = dst representation = { "schema": "pype:representation-2.0", @@ -308,7 +324,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): "root": root, "project": {"name": PROJECT, "code": project['data']['code']}, - 'task': api.Session["AVALON_TASK"], + 'task': TASK, "silo": asset['silo'], "asset": ASSET, "family": instance.data['family'], @@ -323,9 +339,10 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): instance.data['destination_list'] = destination_list representations.append(representation) - self.log.info("Registering {} items".format(len(representations))) - io.insert_many(representations) + self.log.debug("Representation: {}".format(representations)) + self.log.info("Registered {} items".format(len(representations))) + def integrate(self, instance): """Move the files @@ -339,7 +356,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): transfers = instance.data.get("transfers", list()) for src, dest in transfers: - self.log.info("Copying file .. {} -> {}".format(src, dest)) + self.log.debug("Copying file .. {} -> {}".format(src, dest)) self.copy_file(src, dest) # Produce hardlinked copies @@ -349,7 +366,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): # to ensure publishes remain safe and non-edited. hardlinks = instance.data.get("hardlinks", list()) for src, dest in hardlinks: - self.log.info("Hardlinking file .. {} -> {}".format(src, dest)) + self.log.debug("Hardlinking file .. {} -> {}".format(src, dest)) self.hardlink_file(src, dest) def copy_file(self, src, dst): diff --git a/pype/plugins/nuke/load/load_sequence.py b/pype/plugins/nuke/load/load_sequence.py index 2e35c9b4a5..45e476554a 100644 --- a/pype/plugins/nuke/load/load_sequence.py +++ b/pype/plugins/nuke/load/load_sequence.py @@ -75,8 +75,8 @@ def loader_shift(node, frame, relative=True): class LoadSequence(api.Loader): """Load image sequence into Nuke""" - families = ["write", "source"] - representations = ["exr", "dpx"] + families = ["write", "source", "plates"] + representations = ["exr", "dpx"] label = "Load sequence" order = -10 diff --git a/pype/plugins/nukestudio/_unused/collect_subsets.py b/pype/plugins/nukestudio/_unused/collect_subsets.py deleted file mode 100644 index b27a718f49..0000000000 --- a/pype/plugins/nukestudio/_unused/collect_subsets.py +++ /dev/null @@ -1,45 +0,0 @@ -from pyblish import api - - -class CollectClipSubsets(api.InstancePlugin): - """Collect Subsets from selected Clips, Tags, Preset.""" - - order = api.CollectorOrder + 0.01 - label = "Collect Subsets" - hosts = ["nukestudio"] - families = ['clip'] - - def process(self, instance): - tags = instance.data.get('tags', None) - presets = instance.context.data['presets'][ - instance.context.data['host']] - if tags: - self.log.info(tags) - - if presets: - self.log.info(presets) - - # get presets and tags - # iterate tags and get task family - # iterate tags and get host family - # iterate tags and get handles family - - instance = instance.context.create_instance(instance_name) - - instance.data.update({ - "subset": subset_name, - "stagingDir": staging_dir, - "task": task, - "representation": ext[1:], - "host": host, - "asset": asset_name, - "label": label, - "name": name, - # "hierarchy": hierarchy, - # "parents": parents, - "family": family, - "families": [families, 'ftrack'], - "publish": True, - # "files": files_list - }) - instances.append(instance) diff --git a/pype/plugins/nukestudio/_unused/extract_tasks.py b/pype/plugins/nukestudio/_unused/extract_tasks.py index 29c1350cc9..3e6ef9b71c 100644 --- a/pype/plugins/nukestudio/_unused/extract_tasks.py +++ b/pype/plugins/nukestudio/_unused/extract_tasks.py @@ -7,7 +7,7 @@ class ExtractTasks(api.InstancePlugin): order = api.ExtractorOrder label = "Tasks" hosts = ["nukestudio"] - families = ["trackItem.task"] + families = ["clip"] optional = True def filelink(self, src, dst): diff --git a/pype/plugins/nukestudio/_unused/subset-representations_logic.txt b/pype/plugins/nukestudio/_unused/subset-representations_logic.txt new file mode 100644 index 0000000000..dcb7815276 --- /dev/null +++ b/pype/plugins/nukestudio/_unused/subset-representations_logic.txt @@ -0,0 +1,26 @@ +- tags get tasks + +- collect_subset(instance): + - gets presets for subset by tasks + - creates instances for comp .nk, plates (main instance converted to plates) + - add families: + - .nk compositing script [workfile, ftrack] + - plates [plates] + - audio [audio] + +- extract_submit_frameserver(instance) + - families [plates] + - adds .nk script created only for encoding (plates write) no color correction + - adds .nk script created only for encoding (mov write) + - add .nk script created only for encoding (jpg, thumbnail) + - _______ + - from hiero.ui.nuke_bridge import FnNsFrameServer + - FnNsFrameServer.renderFrames(nks, "1-10", "Write_exr", ["main"]) + - dict(script(str), framerange(str), writeNode(str), views(list)) + +# next step ######################################################## +- submit_exporting_task(instance) + - families [workfile] + - create compositing scripts + - create inventory containers for Reads + - create publishable write nodes diff --git a/pype/plugins/nukestudio/publish/collect_clips.py b/pype/plugins/nukestudio/publish/collect_clips.py index 117ceea603..7dcf1795a0 100644 --- a/pype/plugins/nukestudio/publish/collect_clips.py +++ b/pype/plugins/nukestudio/publish/collect_clips.py @@ -10,9 +10,9 @@ class CollectClips(api.ContextPlugin): def process(self, context): projectdata = context.data["projectData"] + version = context.data.get("version", "001") data = {} for item in context.data.get("selection", []): - self.log.debug("__ item: {}".format(item)) # Skip audio track items # Try/Except is to handle items types, like EffectTrackItem try: @@ -22,8 +22,11 @@ class CollectClips(api.ContextPlugin): except: continue - data[item.name()] = { + track = item.parent() + instance_name = "{0}_{1}".format(track.name(), item.name()) + data[instance_name] = { "item": item, + "track": track.name(), "startFrame": int(item.timelineIn()), "endFrame": int(item.timelineOut()) } @@ -32,11 +35,15 @@ class CollectClips(api.ContextPlugin): family = "clip" context.create_instance( name=key, - subset="{0}{1}".format(family, 'Default'), asset=value["item"].name(), item=value["item"], family=family, + families=[], startFrame=value["startFrame"], endFrame=value["endFrame"], - handles=projectdata['handles'] + handles=projectdata['handles'], + handleStart=0, + handleEnd=0, + version=version, + track=value["track"] ) diff --git a/pype/plugins/nukestudio/publish/collect_current_file.py b/pype/plugins/nukestudio/publish/collect_current_file.py index 010d4e15ab..13a263966a 100644 --- a/pype/plugins/nukestudio/publish/collect_current_file.py +++ b/pype/plugins/nukestudio/publish/collect_current_file.py @@ -1,5 +1,5 @@ import pyblish.api - +import pype.api as pype class CollectCurrentFile(pyblish.api.ContextPlugin): """Inject the current working file into context""" @@ -10,5 +10,7 @@ class CollectCurrentFile(pyblish.api.ContextPlugin): """Todo, inject the current working file""" project = context.data('activeProject') - context.set_data('currentFile', value=project.path()) + context.data["currentFile"] = path = project.path() + context.data["version"] = pype.get_version_from_path(path) self.log.info("currentFile: {}".format(context.data["currentFile"])) + self.log.info("version: {}".format(context.data["version"])) diff --git a/pype/plugins/nukestudio/publish/collect_handles.py b/pype/plugins/nukestudio/publish/collect_handles.py index cb20f97442..c148550a1a 100644 --- a/pype/plugins/nukestudio/publish/collect_handles.py +++ b/pype/plugins/nukestudio/publish/collect_handles.py @@ -35,18 +35,12 @@ class CollectClipHandles(api.InstancePlugin): t_args = json.loads(t_args.replace("'", "\"")) # add in start if 'start' in t_args['where']: - hs = instance.data.get('handle_start') - if not hs: - instance.data['handle_start'] = 0 - instance.data['handle_start'] += t_value + instance.data["handleStart"] += t_value self.log.info("Collected Handle Start: `{}`".format( - instance.data['handle_start'])) + instance.data["handleStart"])) # add in end if 'end' in t_args['where']: - hs = instance.data.get('handle_end') - if not hs: - instance.data['handle_end'] = 0 - instance.data['handle_end'] += t_value + instance.data["handleEnd"] += t_value self.log.info("Collected Handle End: `{}`".format( - instance.data['handle_end'])) + instance.data["handleEnd"])) diff --git a/pype/plugins/nukestudio/publish/collect_hierarchy_context.py b/pype/plugins/nukestudio/publish/collect_hierarchy_context.py index f8fef24f81..4426127eb4 100644 --- a/pype/plugins/nukestudio/publish/collect_hierarchy_context.py +++ b/pype/plugins/nukestudio/publish/collect_hierarchy_context.py @@ -37,6 +37,10 @@ class CollectHierarchyInstance(pyblish.api.InstancePlugin): clip = instance.data["item"] asset = instance.data.get("asset") + # create asset_names conversion table + if not context.data.get("assetsSharedHierarchy"): + context.data["assetsSharedHierarchy"] = dict() + # build data for inner nukestudio project property data = { "sequence": context.data['activeSequence'].name().replace(' ', '_'), @@ -65,17 +69,23 @@ class CollectHierarchyInstance(pyblish.api.InstancePlugin): # if shot in template then remove it if "shot" in template.lower(): - instance.data["asset"] = [t for t in template.split('/')][-1] + instance.data["asset"] = [ + t for t in template.split('/')][-1] template = "/".join([t for t in template.split('/')][0:-1]) # take template from Tag.note and break it into parts + template_split = template.split("/") patern = re.compile(r"\{([a-z]*?)\}") - par_split = [patern.findall(t)[0] + par_split = [patern.findall(t) for t in template.split("/")] # format all {} in two layers for k, v in t_metadata.items(): new_k = k.split(".")[1] + + # ignore all help strings + if 'help' in k: + continue # self.log.info("__ new_k: `{}`".format(new_k)) try: # first try all data and context data to @@ -91,7 +101,8 @@ class CollectHierarchyInstance(pyblish.api.InstancePlugin): # if any is matching then convert to entity_types if p_match_i: - parent = self.convert_to_entity(new_k, new_v) + parent = self.convert_to_entity( + new_k, template_split[p_match_i[0]]) parents.insert(p_match_i[0], parent) except Exception: d_metadata[new_k] = v @@ -102,6 +113,10 @@ class CollectHierarchyInstance(pyblish.api.InstancePlugin): # lastly fill those individual properties itno # format the string with collected data + parents = [{"entityName": p["entityName"].format( + **d_metadata), "entityType": p["entityType"]} + for p in parents] + hierarchy = template.format( **d_metadata) @@ -111,12 +126,17 @@ class CollectHierarchyInstance(pyblish.api.InstancePlugin): assert not hd, "Only one Hierarchy Tag is \ allowed. Clip: `{}`".format(asset) + assetsSharedHierarchy = { + asset: { + "asset": instance.data["asset"], + "hierarchy": hierarchy, + "parents": parents + }} # add formated hierarchy path into instance data instance.data["hierarchy"] = hierarchy instance.data["parents"] = parents - self.log.debug("__ hierarchy.format: {}".format(hierarchy)) - self.log.debug("__ parents: {}".format(parents)) - self.log.debug("__ d_metadata: {}".format(d_metadata)) + context.data["assetsSharedHierarchy"].update( + assetsSharedHierarchy) class CollectHierarchyContext(pyblish.api.ContextPlugin): @@ -132,21 +152,36 @@ class CollectHierarchyContext(pyblish.api.ContextPlugin): if key in new_dict and isinstance(ex_dict[key], dict): new_dict[key] = self.update_dict(ex_dict[key], new_dict[key]) else: - new_dict[key] = ex_dict[key] + if ex_dict.get(key) and new_dict.get(key): + continue + else: + new_dict[key] = ex_dict[key] + return new_dict def process(self, context): instances = context[:] # create hierarchyContext attr if context has none - self.log.debug("__ instances: {}".format(context[:])) temp_context = {} for instance in instances: if 'projectfile' in instance.data.get('family', ''): continue - in_info = {} name = instance.data["asset"] + + # inject assetsSharedHierarchy to other plates types + assets_shared = context.data.get("assetsSharedHierarchy") + + if assets_shared: + s_asset_data = assets_shared.get(name) + if s_asset_data: + name = instance.data["asset"] = s_asset_data["asset"] + instance.data["parents"] = s_asset_data["parents"] + instance.data["hierarchy"] = s_asset_data["hierarchy"] + + + in_info = {} # suppose that all instances are Shots in_info['entity_type'] = 'Shot' @@ -172,7 +207,6 @@ class CollectHierarchyContext(pyblish.api.ContextPlugin): actual = next_dict temp_context = self.update_dict(temp_context, actual) - self.log.debug(temp_context) # TODO: 100% sure way of get project! Will be Name or Code? project_name = avalon.Session["AVALON_PROJECT"] diff --git a/pype/plugins/nukestudio/publish/collect_subsets.py b/pype/plugins/nukestudio/publish/collect_subsets.py new file mode 100644 index 0000000000..8f81c68668 --- /dev/null +++ b/pype/plugins/nukestudio/publish/collect_subsets.py @@ -0,0 +1,194 @@ +from pyblish import api +from copy import deepcopy + + +class CollectClipSubsets(api.InstancePlugin): + """Collect Subsets from selected Clips, Tags, Preset.""" + + order = api.CollectorOrder + 0.102 + label = "Collect Subsets" + hosts = ["nukestudio"] + families = ['clip'] + + def process(self, instance): + context = instance.context + + asset_name = instance.data["asset"] + + # get all subsets from tags and match them with nks_presets > + # > looks to rules for tasks, subsets, representations + subsets_collection = self.get_subsets_from_presets(instance) + + # iterate trough subsets and create instances + for subset, attrs in subsets_collection.items(): + self.log.info((subset, attrs)) + # create families + item = instance.data["item"] + family = instance.data["family"] + families = attrs["families"] + [str(subset)] + task = attrs["task"] + subset = "{0}{1}".format( + subset, + instance.data.get("subsetType") or "Default") + instance_name = "{0}_{1}_{2}".format(asset_name, task, subset) + self.log.info("Creating instance with name: {}".format( + instance_name)) + + # get handles + handles = int(instance.data["handles"]) + handle_start = int(instance.data["handleStart"] + handles) + handle_end = int(instance.data["handleEnd"] + handles) + + # get timeline frames + timeline_in = int(item.timelineIn()) + timeline_out = int(item.timelineOut()) + + # frame-ranges with handles + timeline_frame_start = timeline_in - handle_start + timeline_frame_end = timeline_out + handle_end + + # creating comp frame range + frame_start = instance.data["frameStart"] - handle_start + frame_end = frame_start + \ + (timeline_frame_end - timeline_frame_start) + + # get sequence from context, and fps + sequence = context.data["activeSequence"] + fps = int(str(sequence.framerate())) + + context.create_instance( + name=instance_name, + subset=subset, + asset=asset_name, + track=instance.data.get("track"), + item=item, + task=task, + family=family, + families=families, + frameStart=frame_start, + startFrame=frame_start, + endFrame=frame_end, + timelineIn=timeline_in, + timelineOut=timeline_out, + timelineInHandles=timeline_frame_start, + timelineOutHandles=timeline_frame_end, + fps=fps, + handles=instance.data["handles"], + handleStart=handle_start, + handleEnd=handle_end, + attributes=attrs, + version=instance.data["version"], + hierarchy=instance.data.get("hierarchy", None), + parents=instance.data.get("parents", None), + publish=True + ) + + # removing original instance + context.remove(instance) + + def get_subsets_from_presets(self, instance): + + family = instance.data["family"] + # get presets and tags + tag_tasks = instance.data["tasks"] + presets = instance.context.data['presets'] + nks_presets = presets[instance.context.data['host']] + family_default_preset = nks_presets["asset_default"].get(family) + + if family_default_preset: + frame_start = family_default_preset.get("fstart", 1) + instance.data["frameStart"] = int(frame_start) + + # get specific presets + pr_host_tasks = deepcopy( + nks_presets["rules_tasks"]).get("hostTasks", None) + pr_host_subsets = deepcopy( + nks_presets["rules_tasks"]).get("hostSubsets", None) + + subsets_collect = dict() + # iterate tags and collect subset properities from presets + for task in tag_tasks: + try: + # get host for task + host = None + host = [h for h, tasks in pr_host_tasks.items() + if task in tasks][0] + except IndexError: + pass + + try: + # get subsets for task + subsets = None + subsets = pr_host_subsets[host] + except KeyError: + pass + + if not subsets: + continue + + # get subsets for task + for sub in subsets: + # get specific presets + pr_subsets = deepcopy(nks_presets["rules_subsets"]) + pr_representations = deepcopy( + nks_presets["rules_representations"]) + + # initialise collection dictionary + subs_data = dict() + + # gets subset properities + subs_data[sub] = None + subs_data[sub] = pr_subsets.get(sub, None) + + # gets representation if in keys + if subs_data[sub] and ( + "representation" in subs_data[sub].keys() + ): + repr_name = subs_data[sub]["representation"] + + # owerwrite representation key with values from preset + subs_data[sub]["representation"] = pr_representations[ + repr_name + ] + subs_data[sub]["representation"]["name"] = repr_name + + # gets nodes and presets data if in keys + # gets nodes if any + if subs_data[sub] and ( + "nodes" in subs_data[sub].keys() + ): + # iterate trough each node + for k in subs_data[sub]["nodes"]: + pr_node = k + pr_family = subs_data[sub]["nodes"][k]["family"] + + # create attribute dict for later filling + subs_data[sub]["nodes"][k]["attributes"] = dict() + + # iterate presets for the node + for p, path in subs_data[sub]["nodes"][k][ + "presets"].items(): + + # adds node type and family for preset path + nPath = path + [pr_node, pr_family] + + # create basic iternode to be wolked trough until + # found presets at the end + iternode = presets[p] + for part in nPath: + iternode = iternode[part] + + iternode = {k: v for k, v in iternode.items() + if not k.startswith("_")} + # adds found preset to attributes of the node + subs_data[sub]["nodes"][k][ + "attributes"].update(iternode) + + # removes preset key + subs_data[sub]["nodes"][k].pop("presets") + + # add all into dictionary + subs_data[sub]["task"] = task.lower() + subsets_collect.update(subs_data) + + return subsets_collect diff --git a/pype/plugins/nukestudio/publish/collect_tag_types.py b/pype/plugins/nukestudio/publish/collect_tag_types.py new file mode 100644 index 0000000000..7393df9cad --- /dev/null +++ b/pype/plugins/nukestudio/publish/collect_tag_types.py @@ -0,0 +1,34 @@ +from pyblish import api + + +class CollectClipTagTypes(api.InstancePlugin): + """Collect Types from Tags of selected track items.""" + + order = api.CollectorOrder + 0.007 + label = "Collect Plate Type from Tag" + hosts = ["nukestudio"] + families = ['clip'] + + def process(self, instance): + # gets tags + tags = instance.data["tags"] + + subset_names = list() + for t in tags: + t_metadata = dict(t["metadata"]) + t_family = t_metadata.get("tag.family", "") + + # gets only task family tags and collect labels + if "plate" in t_family: + t_type = t_metadata.get("tag.type", "") + t_order = t_metadata.get("tag.order", "") + subset_type = "{0}{1}".format( + t_type.capitalize(), t_order) + subset_names.append(subset_type) + + if subset_names: + instance.data["subsetType"] = subset_names[0] + + self.log.info("Collected Plate Types from Tags: `{}`".format( + instance.data["subsetType"])) + return diff --git a/pype/plugins/nukestudio/publish/extract_audio.py b/pype/plugins/nukestudio/publish/extract_audio.py new file mode 100644 index 0000000000..17ef882690 --- /dev/null +++ b/pype/plugins/nukestudio/publish/extract_audio.py @@ -0,0 +1,62 @@ +from pyblish import api +import pype + +class ExtractAudioFile(pype.api.Extractor): + """Extracts audio subset file""" + + order = api.ExtractorOrder + label = "Extract Subset Audio" + hosts = ["nukestudio"] + families = ["clip", "audio"] + match = api.Intersection + optional = True + active = False + + def process(self, instance): + import os + + from hiero.exporters.FnExportUtil import writeSequenceAudioWithHandles + + item = instance.data["item"] + context = instance.context + + self.log.debug("creating staging dir") + self.staging_dir(instance) + + staging_dir = instance.data["stagingDir"] + + # get handles from context + handles = instance.data["handles"] + handle_start = instance.data["handleStart"] + handles + handle_end = instance.data["handleEnd"] + handles + + # get sequence from context + sequence = context.data["activeSequence"] + + # path to wav file + audio_file = os.path.join( + staging_dir, "{0}.wav".format(instance.data["subset"]) + ) + + # export audio to disk + writeSequenceAudioWithHandles( + audio_file, + sequence, + item.timelineIn(), + item.timelineOut(), + handle_start, + handle_end + ) + + # add to representations + if not instance.data.get("representations"): + instance.data["representations"] = list() + + representation = { + 'files': [audio_file], + 'stagingDir': staging_dir, + 'name': "wav", + 'ext': ".wav" + } + + instance.data["representations"].append(representation) diff --git a/pype/plugins/nukestudio/publish/extract_plates.py b/pype/plugins/nukestudio/publish/extract_plates.py new file mode 100644 index 0000000000..b722f6d6f0 --- /dev/null +++ b/pype/plugins/nukestudio/publish/extract_plates.py @@ -0,0 +1,239 @@ +from pyblish import api +import pype + + +class ExtractPlates(pype.api.Extractor): + """Extracts plates""" + + order = api.ExtractorOrder + label = "Extract Plates" + hosts = ["nukestudio"] + families = ["plates"] + + def process(self, instance): + import os + import hiero.core + from hiero.ui.nuke_bridge import FnNsFrameServer + + # add to representations + if not instance.data.get("representations"): + instance.data["representations"] = list() + + repr_data = dict() + context = instance.context + anatomy = context.data.get("anatomy", None) + padding = int(anatomy.templates['render']['padding']) + + name = instance.data["subset"] + asset = instance.data["asset"] + track = instance.data["track"] + family = instance.data["family"] + families = instance.data["families"] + attrs = instance.data["attributes"] + version = instance.data["version"] + + # staging dir creation + self.log.debug("creating staging dir") + self.staging_dir(instance) + + staging_dir = instance.data['stagingDir'] + + Nuke_writer = hiero.core.nuke.ScriptWriter() + + item = instance.data["item"] + + # get handles + handles = int(instance.data["handles"]) + handle_start = int(instance.data["handleStart"]) + handle_end = int(instance.data["handleEnd"]) + + # get timeline frames + timeline_in = int(instance.data["timelineIn"]) + timeline_out = int(instance.data["timelineOut"]) + + # frame-ranges with handles + timeline_frame_start = int(instance.data["timelineInHandles"]) + timeline_frame_end = int(instance.data["timelineOutHandles"]) + + # creating comp frame range + frame_start = int(instance.data["startFrame"]) + frame_end = int(instance.data["endFrame"]) + + # get colorspace + colorspace = instance.context.data["colorspace"] + + # get sequence from context, and fps + fps = int(instance.data["fps"]) + + # test output + self.log.debug("__ handles: {}".format(handles)) + self.log.debug("__ handle_start: {}".format(handle_start)) + self.log.debug("__ handle_end: {}".format(handle_end)) + self.log.debug("__ timeline_in: {}".format(timeline_in)) + self.log.debug("__ timeline_out: {}".format(timeline_out)) + self.log.debug("__ timeline_frame_start: {}".format( + timeline_frame_start)) + self.log.debug("__ timeline_frame_end: {}".format(timeline_frame_end)) + self.log.debug("__ frame_start: {}".format(frame_start)) + self.log.debug("__ frame_end: {}".format(frame_end)) + self.log.debug("__ colorspace: {}".format(colorspace)) + self.log.debug("__ track: {}".format(track)) + self.log.debug("__ fps: {}".format(fps)) + + # Generate Nuke script + write_name = "Write_out" + + # root node + root_node = hiero.core.nuke.RootNode( + frame_start, + frame_end, + fps=fps + ) + + root_node.addProjectSettings(colorspace) + + # create write node and link it to root node + Nuke_writer.addNode(root_node) + '''TrackItem.addToNukeScript(script=, firstFrame=None, additionalNodes=[], additionalNodesCallback=None, includeRetimes=False, retimeMethod=None, startHandle=None, endHandle=None, colourTransform=None, offset=0, nodeLabel=None, includeAnnotations=False, includeEffects=True, outputToSequenceFormat=False)''' + item.addToNukeScript( + script=Nuke_writer, + firstFrame=frame_start, + includeRetimes=attrs["includeRetimes"], + retimeMethod=attrs["retimeMethod"], + startHandle=handle_start, + endHandle=handle_end, + includeEffects=attrs["includeEffects"], + includeAnnotations=attrs["includeAnnotations"] + ) + + write_knobs = attrs["nodes"]["write"]["attributes"] + + # TODO: take template from anatomy + nukescript_file = "{asset}_{name}_v{version}.{ext}".format( + asset=asset, + name=name, + version=version, + ext="nk" + ) + nukescript_path = os.path.join( + staging_dir, nukescript_file + ) + + # TODO: take template from anatomy + output_file = "{asset}_{name}_v{version}.%0{padding}d.{ext}".format( + asset=asset, + name=name, + version=version, + padding=padding, + ext=write_knobs["file_type"] + ) + output_path = os.path.join( + staging_dir, output_file + ) + + write_node = hiero.core.nuke.WriteNode(output_path.replace("\\", "/")) + write_node.setKnob("name", write_name) + write_node.setKnob("file_type", write_knobs["file_type"]) + for knob, value in write_knobs.items(): + write_node.setKnob(knob, value) + + Nuke_writer.addNode(write_node) + + Nuke_writer.writeToDisk(nukescript_path) + + # test prints + self.log.debug("__ output_file: {}".format(output_file)) + self.log.debug("__ output_path: {}".format(output_path)) + self.log.debug("__ nukescript_file: {}".format(nukescript_file)) + self.log.debug("__ nukescript_path: {}".format(nukescript_path)) + self.log.debug("__ write_knobs: {}".format(write_knobs)) + self.log.debug("__ write_name: {}".format(write_name)) + self.log.debug("__ Nuke_writer: {}".format(Nuke_writer)) + + # create rendering arguments for FnNsFrameServer + _args = [ + nukescript_path, + "{}-{}".format(frame_start, frame_end), + write_name, + ["main"] + ] + + # add to data of representation + repr_data.update({ + "handles": handles, + "handleStart": handle_start, + "handleEnd": handle_end, + "timelineIn": timeline_in, + "timelineOut": timeline_out, + "timelineInHandles": timeline_frame_start, + "timelineOutHandles": timeline_frame_end, + "compFrameIn": frame_start, + "compFrameOut": frame_end, + "fps": fps, + "colorspace": write_knobs["colorspace"], + "nukeScriptFileName": nukescript_file, + "nukeWriteFileName": output_file, + "nukeWriteName": write_name, + "FnNsFrameServer_renderFrames_args": str(_args), + "family": family, + "families": families, + "asset": asset, + "subset": name, + "track": track, + "version": int(version) + }) + + # adding representation for nukescript + nk_representation = { + 'files': nukescript_file, + 'stagingDir': staging_dir, + 'name': "nk", + 'ext': "nk", + "data": repr_data + } + instance.data["representations"].append(nk_representation) + + # adding representation for plates + plates_representation = { + 'files': [output_file % i for i in range( + frame_start, (frame_end + 1), 1)], + 'stagingDir': staging_dir, + 'name': write_knobs["file_type"], + 'ext': write_knobs["file_type"], + "data": repr_data + } + instance.data["representations"].append(plates_representation) + + # adding checking file to context for ExtractPlateCheck(context) plugin + context.data["platesCheck"] = os.path.join( + staging_dir, output_file % frame_end + ) + + if not context.data.get("frameServerRenderQueue"): + context.data["frameServerRenderQueue"] = list() + + # add to render queue list + context.data["frameServerRenderQueue"].append(_args) + + # test prints + self.log.debug("__ before family: {}".format(family)) + self.log.debug("__ before families: {}".format(families)) + + # this is just workaround because 'clip' family is filtered + instance.data["family"] = families[-1] + instance.data["families"].append(family) + + # testing families + family = instance.data["family"] + families = instance.data["families"] + + # test prints repr_data + self.log.debug("__ repr_data: {}".format(repr_data)) + self.log.debug("__ nk_representation: {}".format(nk_representation)) + self.log.debug("__ plates_representation: {}".format( + plates_representation)) + self.log.debug("__ after family: {}".format(family)) + self.log.debug("__ after families: {}".format(families)) + + # this will do FnNsFrameServer + FnNsFrameServer.renderFrames(*_args) diff --git a/pype/plugins/nukestudio/publish/extract_plates_waiting.py b/pype/plugins/nukestudio/publish/extract_plates_waiting.py new file mode 100644 index 0000000000..dbedddead8 --- /dev/null +++ b/pype/plugins/nukestudio/publish/extract_plates_waiting.py @@ -0,0 +1,30 @@ +from pyblish import api +import os +import time + + +class ExtractPlateCheck(api.ContextPlugin): + """Collect all Track items selection.""" + + order = api.ExtractorOrder + 0.01 + label = "Plates Export Waiting" + hosts = ["nukestudio"] + families = ["plates"] + + def process(self, context): + + plate_path = context.data.get("platesCheck", None) + + self.log.info("Chacking plate: `{}`".format(plate_path)) + + if not plate_path: + return + + while not os.path.exists(plate_path): + self.log.info("Waiting for plates to be rendered") + time.sleep(5) + + if os.path.isfile(plate_path): + self.log.info("Plates were rendered: `{}`".format(plate_path)) + else: + raise ValueError("%s isn't a file!" % plate_path) diff --git a/pype/plugins/nukestudio/publish/extract_review.py b/pype/plugins/nukestudio/publish/extract_review.py deleted file mode 100644 index 537988e0ad..0000000000 --- a/pype/plugins/nukestudio/publish/extract_review.py +++ /dev/null @@ -1,101 +0,0 @@ -from pyblish import api - - -class ExtractReview(api.InstancePlugin): - """Extracts movie for review""" - - order = api.ExtractorOrder - label = "NukeStudio Review" - optional = True - hosts = ["nukestudio"] - families = ["review"] - - def process(self, instance): - import os - import time - - import hiero.core - from hiero.exporters.FnExportUtil import writeSequenceAudioWithHandles - - nukeWriter = hiero.core.nuke.ScriptWriter() - - item = instance.data["item"] - - handles = instance.data["handles"] - - sequence = item.parent().parent() - - output_path = os.path.abspath( - os.path.join( - instance.context.data["currentFile"], "..", "workspace" - ) - ) - - # Generate audio - audio_file = os.path.join( - output_path, "{0}.wav".format(instance.data["name"]) - ) - - writeSequenceAudioWithHandles( - audio_file, - sequence, - item.timelineIn(), - item.timelineOut(), - handles, - handles - ) - - # Generate Nuke script - root_node = hiero.core.nuke.RootNode( - item.timelineIn() - handles, - item.timelineOut() + handles, - fps=sequence.framerate() - ) - - root_node.addProjectSettings(instance.context.data["colorspace"]) - - nukeWriter.addNode(root_node) - - item.addToNukeScript( - script=nukeWriter, - includeRetimes=True, - retimeMethod="Frame", - startHandle=handles, - endHandle=handles - ) - - movie_path = os.path.join( - output_path, "{0}.mov".format(instance.data["name"]) - ) - write_node = hiero.core.nuke.WriteNode(movie_path.replace("\\", "/")) - self.log.info("__ write_node: {0}".format(write_node)) - write_node.setKnob("file_type", "mov") - write_node.setKnob("colorspace", instance.context.data["colorspace"]["lutSettingFloat"]) - write_node.setKnob("meta_codec", "ap4h") - write_node.setKnob("mov64_codec", "ap4h") - write_node.setKnob("mov64_bitrate", 400000) - write_node.setKnob("mov64_bitrate_tolerance", 40000000) - write_node.setKnob("mov64_quality_min", 2) - write_node.setKnob("mov64_quality_max", 31) - write_node.setKnob("mov64_gop_size", 12) - write_node.setKnob("mov64_b_frames", 0) - write_node.setKnob("raw", True ) - write_node.setKnob("mov64_audiofile", audio_file.replace("\\", "/")) - write_node.setKnob("mov32_fps", sequence.framerate()) - nukeWriter.addNode(write_node) - - nukescript_path = movie_path.replace(".mov", ".nk") - nukeWriter.writeToDisk(nukescript_path) - - process = hiero.core.nuke.executeNukeScript( - nukescript_path, - open(movie_path.replace(".mov", ".log"), "w") - ) - - while process.poll() is None: - time.sleep(0.5) - - assert os.path.exists(movie_path), "Creating review failed." - - instance.data["output_path"] = movie_path - instance.data["review_family"] = "mov" diff --git a/setup/nukestudio/hiero_plugin_path/Icons/1_add_handles_end.png b/setup/nukestudio/hiero_plugin_path/Icons/1_add_handles_end.png new file mode 100644 index 0000000000..31c41d1ac6 Binary files /dev/null and b/setup/nukestudio/hiero_plugin_path/Icons/1_add_handles_end.png differ diff --git a/setup/nukestudio/hiero_plugin_path/Icons/2D.png b/setup/nukestudio/hiero_plugin_path/Icons/2D.png deleted file mode 100644 index 69a22ad815..0000000000 Binary files a/setup/nukestudio/hiero_plugin_path/Icons/2D.png and /dev/null differ diff --git a/setup/nukestudio/hiero_plugin_path/Icons/2_add_handles.png b/setup/nukestudio/hiero_plugin_path/Icons/2_add_handles.png new file mode 100644 index 0000000000..ab911c5ebc Binary files /dev/null and b/setup/nukestudio/hiero_plugin_path/Icons/2_add_handles.png differ diff --git a/setup/nukestudio/hiero_plugin_path/Icons/3D.png b/setup/nukestudio/hiero_plugin_path/Icons/3D.png index b3a4af9e24..4ace8911df 100644 Binary files a/setup/nukestudio/hiero_plugin_path/Icons/3D.png and b/setup/nukestudio/hiero_plugin_path/Icons/3D.png differ diff --git a/setup/nukestudio/hiero_plugin_path/Icons/3_add_handles_start.png b/setup/nukestudio/hiero_plugin_path/Icons/3_add_handles_start.png new file mode 100644 index 0000000000..4cdc09b541 Binary files /dev/null and b/setup/nukestudio/hiero_plugin_path/Icons/3_add_handles_start.png differ diff --git a/setup/nukestudio/hiero_plugin_path/Icons/4_2D.png b/setup/nukestudio/hiero_plugin_path/Icons/4_2D.png new file mode 100644 index 0000000000..418272517f Binary files /dev/null and b/setup/nukestudio/hiero_plugin_path/Icons/4_2D.png differ diff --git a/setup/nukestudio/hiero_plugin_path/Icons/add_handles.png b/setup/nukestudio/hiero_plugin_path/Icons/add_handles.png deleted file mode 100644 index 9c8be0d207..0000000000 Binary files a/setup/nukestudio/hiero_plugin_path/Icons/add_handles.png and /dev/null differ diff --git a/setup/nukestudio/hiero_plugin_path/Icons/add_handles_end.png b/setup/nukestudio/hiero_plugin_path/Icons/add_handles_end.png deleted file mode 100644 index 3885925f99..0000000000 Binary files a/setup/nukestudio/hiero_plugin_path/Icons/add_handles_end.png and /dev/null differ diff --git a/setup/nukestudio/hiero_plugin_path/Icons/add_handles_start.png b/setup/nukestudio/hiero_plugin_path/Icons/add_handles_start.png deleted file mode 100644 index ecfd2c2621..0000000000 Binary files a/setup/nukestudio/hiero_plugin_path/Icons/add_handles_start.png and /dev/null differ diff --git a/setup/nukestudio/hiero_plugin_path/Icons/edit.png b/setup/nukestudio/hiero_plugin_path/Icons/edit.png index b0f4c436ec..e0ba3c102f 100644 Binary files a/setup/nukestudio/hiero_plugin_path/Icons/edit.png and b/setup/nukestudio/hiero_plugin_path/Icons/edit.png differ diff --git a/setup/nukestudio/hiero_plugin_path/Icons/hierarchy.png b/setup/nukestudio/hiero_plugin_path/Icons/hierarchy.png index 55b4f9843b..68ea352885 100644 Binary files a/setup/nukestudio/hiero_plugin_path/Icons/hierarchy.png and b/setup/nukestudio/hiero_plugin_path/Icons/hierarchy.png differ diff --git a/setup/nukestudio/hiero_plugin_path/Icons/layers.psd b/setup/nukestudio/hiero_plugin_path/Icons/layers.psd new file mode 100644 index 0000000000..20ba0e81b0 Binary files /dev/null and b/setup/nukestudio/hiero_plugin_path/Icons/layers.psd differ diff --git a/setup/nukestudio/hiero_plugin_path/Icons/lense.png b/setup/nukestudio/hiero_plugin_path/Icons/lense.png new file mode 100644 index 0000000000..2eb2da982f Binary files /dev/null and b/setup/nukestudio/hiero_plugin_path/Icons/lense.png differ diff --git a/setup/nukestudio/hiero_plugin_path/Icons/lense1.png b/setup/nukestudio/hiero_plugin_path/Icons/lense1.png new file mode 100644 index 0000000000..f76354f48c Binary files /dev/null and b/setup/nukestudio/hiero_plugin_path/Icons/lense1.png differ diff --git a/setup/nukestudio/hiero_plugin_path/Icons/z_layer_bg.png b/setup/nukestudio/hiero_plugin_path/Icons/z_layer_bg.png new file mode 100644 index 0000000000..d01fe683e5 Binary files /dev/null and b/setup/nukestudio/hiero_plugin_path/Icons/z_layer_bg.png differ diff --git a/setup/nukestudio/hiero_plugin_path/Icons/z_layer_fg.png b/setup/nukestudio/hiero_plugin_path/Icons/z_layer_fg.png new file mode 100644 index 0000000000..a1d5751622 Binary files /dev/null and b/setup/nukestudio/hiero_plugin_path/Icons/z_layer_fg.png differ diff --git a/setup/nukestudio/hiero_plugin_path/Icons/z_layer_main.png b/setup/nukestudio/hiero_plugin_path/Icons/z_layer_main.png new file mode 100644 index 0000000000..0fe806d86e Binary files /dev/null and b/setup/nukestudio/hiero_plugin_path/Icons/z_layer_main.png differ