From 0c8af1f7b6e7b3e27e0b9230abb4ecddc92d4bf2 Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Thu, 23 Sep 2021 11:10:36 +0200 Subject: [PATCH 01/25] add collector --- .../maya/plugins/publish/collect_loaded_plugin.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 openpype/hosts/maya/plugins/publish/collect_loaded_plugin.py diff --git a/openpype/hosts/maya/plugins/publish/collect_loaded_plugin.py b/openpype/hosts/maya/plugins/publish/collect_loaded_plugin.py new file mode 100644 index 0000000000..2624bcfd6b --- /dev/null +++ b/openpype/hosts/maya/plugins/publish/collect_loaded_plugin.py @@ -0,0 +1,15 @@ +import pyblish.api +import avalon.api +from maya import cmds + + +class CollectLoadedPlugin(pyblish.api.ContextPlugin): + """Collect loaded plugins""" + + order = pyblish.api.CollectorOrder + label = "Loaded Plugins" + hosts = ["maya"] + + def process(self, context): + + context.data["loadedPlugins"] = cmds.pluginInfo(query=True, listPlugins=True) From d4827bcc7aecadbce4c8430cf379456e28f01afc Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Thu, 23 Sep 2021 11:10:47 +0200 Subject: [PATCH 02/25] add validator --- .../plugins/publish/validate_loaded_plugin.py | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 openpype/hosts/maya/plugins/publish/validate_loaded_plugin.py diff --git a/openpype/hosts/maya/plugins/publish/validate_loaded_plugin.py b/openpype/hosts/maya/plugins/publish/validate_loaded_plugin.py new file mode 100644 index 0000000000..81f40abcc3 --- /dev/null +++ b/openpype/hosts/maya/plugins/publish/validate_loaded_plugin.py @@ -0,0 +1,39 @@ +import pyblish.api +import maya.cmds as cmds +import openpype.api +from openpype import lib + + +class ValidateLoadedPlugin(pyblish.api.ContextPlugin): + """Ensure there are no unauthorized loaded plugins""" + + label = "Loaded Plugin" + order = pyblish.api.ValidatorOrder + host = ["maya"] + actions = [openpype.api.RepairContextAction] + + @classmethod + def get_invalid(cls, context): + + invalid = [] + + for plugin in context.data.get("loadedPlugins"): + if plugin not in cls.authorized_plugins: + invalid.append(plugin) + + return invalid + + def process(self, context): + + invalid = self.get_invalid(context) + if invalid: + raise RuntimeError( + "Found forbidden plugin name: {}".format(", ".join(invalid)) + ) + + @classmethod + def repair(cls, context): + """Unload forbidden plugins""" + + for plugin in cls.get_invalid(context): + cmds.unloadPlugin(plugin, force=True) From 9b712d5a62e4c526daf9c002acbfc81ed12b70fc Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Thu, 23 Sep 2021 11:11:02 +0200 Subject: [PATCH 03/25] add openpype settings --- .../defaults/project_settings/maya.json | 49 +++++++++++++++++++ .../schemas/schema_maya_publish.json | 21 ++++++++ 2 files changed, 70 insertions(+) diff --git a/openpype/settings/defaults/project_settings/maya.json b/openpype/settings/defaults/project_settings/maya.json index 3540c3eb29..b19d544fed 100644 --- a/openpype/settings/defaults/project_settings/maya.json +++ b/openpype/settings/defaults/project_settings/maya.json @@ -169,6 +169,55 @@ "enabled": false, "attributes": {} }, + "ValidateLoadedPlugin": { + "enabled": false, + "authorized_plugins": [ + "stereoCamera", + "svgFileTranslator", + "invertShape", + "mayaHIK", + "GamePipeline", + "curveWarp", + "tiffFloatReader", + "MASH", + "poseInterpolator", + "ATFPlugin", + "hairPhysicalShader", + "cacheEvaluator", + "ikSpringSolver", + "ik2Bsolver", + "xgenToolkit", + "AbcExport", + "retargeterNodes", + "gameFbxExporter", + "VectorRender", + "OpenEXRLoader", + "lookdevKit", + "Unfold3D", + "Type", + "mayaCharacterization", + "meshReorder", + "modelingToolkit", + "MayaMuscle", + "rotateHelper", + "dx11Shader", + "matrixNodes", + "AbcImport", + "autoLoader", + "deformerEvaluator", + "sceneAssembly", + "gpuCache", + "OneClick", + "shaderFXPlugin", + "objExport", + "renderSetup", + "GPUBuiltInDeformer", + "ArubaTessellator", + "quatNodes", + "fbxmaya", + "Turtle" + ] + }, "ValidateRenderSettings": { "arnold_render_attributes": [], "vray_render_attributes": [], diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_publish.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_publish.json index 89cd30aed0..e2df6654f2 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_publish.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_publish.json @@ -82,6 +82,27 @@ ] }, + { + "type": "dict", + "collapsible": true, + "key": "ValidateLoadedPlugin", + "label": "Validate Loaded Plugin", + "checkbox_key": "enabled", + "children": [ + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "list", + "key": "authorized_plugins", + "label": "Authorized plugins", + "object_type": "text" + } + ] + }, + { "type": "dict", "collapsible": true, From 13ae6dac3197cc5d91d66c05063a244a91b11c05 Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Thu, 23 Sep 2021 11:23:25 +0200 Subject: [PATCH 04/25] Fix unused import and line too long --- .../hosts/maya/plugins/publish/collect_loaded_plugin.py | 6 ++++-- .../hosts/maya/plugins/publish/validate_loaded_plugin.py | 2 -- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/collect_loaded_plugin.py b/openpype/hosts/maya/plugins/publish/collect_loaded_plugin.py index 2624bcfd6b..7ee7021962 100644 --- a/openpype/hosts/maya/plugins/publish/collect_loaded_plugin.py +++ b/openpype/hosts/maya/plugins/publish/collect_loaded_plugin.py @@ -1,5 +1,4 @@ import pyblish.api -import avalon.api from maya import cmds @@ -12,4 +11,7 @@ class CollectLoadedPlugin(pyblish.api.ContextPlugin): def process(self, context): - context.data["loadedPlugins"] = cmds.pluginInfo(query=True, listPlugins=True) + context.data["loadedPlugins"] = cmds.pluginInfo( + query=True, + listPlugins=True, + ) diff --git a/openpype/hosts/maya/plugins/publish/validate_loaded_plugin.py b/openpype/hosts/maya/plugins/publish/validate_loaded_plugin.py index 81f40abcc3..7798cbab4e 100644 --- a/openpype/hosts/maya/plugins/publish/validate_loaded_plugin.py +++ b/openpype/hosts/maya/plugins/publish/validate_loaded_plugin.py @@ -1,8 +1,6 @@ import pyblish.api import maya.cmds as cmds import openpype.api -from openpype import lib - class ValidateLoadedPlugin(pyblish.api.ContextPlugin): """Ensure there are no unauthorized loaded plugins""" From e729204cb81063283c1a296b11c5878272ee4d55 Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Thu, 23 Sep 2021 11:24:50 +0200 Subject: [PATCH 05/25] fix syntax --- openpype/hosts/maya/plugins/publish/validate_loaded_plugin.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openpype/hosts/maya/plugins/publish/validate_loaded_plugin.py b/openpype/hosts/maya/plugins/publish/validate_loaded_plugin.py index 7798cbab4e..01705e8b13 100644 --- a/openpype/hosts/maya/plugins/publish/validate_loaded_plugin.py +++ b/openpype/hosts/maya/plugins/publish/validate_loaded_plugin.py @@ -2,6 +2,7 @@ import pyblish.api import maya.cmds as cmds import openpype.api + class ValidateLoadedPlugin(pyblish.api.ContextPlugin): """Ensure there are no unauthorized loaded plugins""" From 0b7ae4f7358257d412500aa747659e3a447fb562 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 23 Sep 2021 14:53:38 +0200 Subject: [PATCH 06/25] nuke: adding exception for `farm` rendering --- openpype/hosts/nuke/api/lib.py | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/nuke/api/lib.py b/openpype/hosts/nuke/api/lib.py index 8948cb4d78..ab4c992719 100644 --- a/openpype/hosts/nuke/api/lib.py +++ b/openpype/hosts/nuke/api/lib.py @@ -295,7 +295,7 @@ def add_button_write_to_read(node): def create_write_node(name, data, input=None, prenodes=None, - review=True, linked_knobs=None): + review=True, linked_knobs=None, farm=True): ''' Creating write node which is group node Arguments: @@ -421,7 +421,15 @@ def create_write_node(name, data, input=None, prenodes=None, )) continue - if knob and value: + if not knob and not value: + continue + + log.info((knob, value)) + + if isinstance(value, str): + if "[" in value: + now_node[knob].setExpression(value) + else: now_node[knob].setValue(value) # connect to previous node @@ -466,7 +474,7 @@ def create_write_node(name, data, input=None, prenodes=None, # imprinting group node anlib.set_avalon_knob_data(GN, data["avalon"]) anlib.add_publish_knob(GN) - add_rendering_knobs(GN) + add_rendering_knobs(GN, farm) if review: add_review_knob(GN) @@ -526,7 +534,7 @@ def create_write_node(name, data, input=None, prenodes=None, return GN -def add_rendering_knobs(node): +def add_rendering_knobs(node, farm=True): ''' Adds additional rendering knobs to given node Arguments: @@ -535,9 +543,13 @@ def add_rendering_knobs(node): Return: node (obj): with added knobs ''' + knob_options = [ + "Use existing frames", "Local"] + if farm: + knob_options.append("On farm") + if "render" not in node.knobs(): - knob = nuke.Enumeration_Knob("render", "", [ - "Use existing frames", "Local", "On farm"]) + knob = nuke.Enumeration_Knob("render", "", knob_options) knob.clearFlag(nuke.STARTLINE) node.addKnob(knob) return node From a403e4afdf6abaf27e6f77bca5277d20bd0e986d Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 23 Sep 2021 14:54:48 +0200 Subject: [PATCH 07/25] nuke: adding still render family workflow --- .../nuke/plugins/create/create_write_still.py | 142 ++++++++++++++++++ .../hosts/nuke/plugins/load/load_image.py | 4 +- .../plugins/publish/extract_render_local.py | 29 +++- .../nuke/plugins/publish/precollect_writes.py | 7 +- .../publish/validate_rendered_frames.py | 5 +- openpype/plugins/publish/integrate_new.py | 1 + .../defaults/project_anatomy/imageio.json | 40 ++++- .../defaults/project_settings/nuke.json | 6 +- 8 files changed, 218 insertions(+), 16 deletions(-) create mode 100644 openpype/hosts/nuke/plugins/create/create_write_still.py diff --git a/openpype/hosts/nuke/plugins/create/create_write_still.py b/openpype/hosts/nuke/plugins/create/create_write_still.py new file mode 100644 index 0000000000..1178928652 --- /dev/null +++ b/openpype/hosts/nuke/plugins/create/create_write_still.py @@ -0,0 +1,142 @@ +from collections import OrderedDict +from openpype.hosts.nuke.api import ( + plugin, + lib) +import nuke + + +class CreateWriteStill(plugin.PypeCreator): + # change this to template preset + name = "WriteStillFrame" + label = "Create Write Still Image" + hosts = ["nuke"] + n_class = "Write" + family = "still" + icon = "image" + defaults = [ + "ImageFrame{:0>4}".format(nuke.frame()), + "MPFrame{:0>4}".format(nuke.frame()), + "LayoutFrame{:0>4}".format(nuke.frame()) + ] + + def __init__(self, *args, **kwargs): + super(CreateWriteStill, self).__init__(*args, **kwargs) + + data = OrderedDict() + + data["family"] = self.family + data["families"] = self.n_class + + for k, v in self.data.items(): + if k not in data.keys(): + data.update({k: v}) + + self.data = data + self.nodes = nuke.selectedNodes() + self.log.debug("_ self.data: '{}'".format(self.data)) + + def process(self): + + inputs = [] + outputs = [] + instance = nuke.toNode(self.data["subset"]) + selected_node = None + + # use selection + if (self.options or {}).get("useSelection"): + nodes = self.nodes + + if not (len(nodes) < 2): + msg = ("Select only one node. " + "The node you want to connect to, " + "or tick off `Use selection`") + self.log.error(msg) + nuke.message(msg) + return + + if len(nodes) == 0: + msg = ( + "No nodes selected. Please select a single node to connect" + " to or tick off `Use selection`" + ) + self.log.error(msg) + nuke.message(msg) + return + + selected_node = nodes[0] + inputs = [selected_node] + outputs = selected_node.dependent() + + if instance: + if (instance.name() in selected_node.name()): + selected_node = instance.dependencies()[0] + + # if node already exist + if instance: + # collect input / outputs + inputs = instance.dependencies() + outputs = instance.dependent() + selected_node = inputs[0] + # remove old one + nuke.delete(instance) + + # recreate new + write_data = { + "nodeclass": self.n_class, + "families": [self.family], + "avalon": self.data + } + + # add creator data + creator_data = {"creator": self.__class__.__name__} + self.data.update(creator_data) + write_data.update(creator_data) + + + self.log.info("Adding template path from plugin") + write_data.update({ + "fpath_template": ("{work}/renders/nuke/{subset}" + "/{subset}.{ext}")}) + + _prenodes = [ + { + "name": "FrameHold01", + "class": "FrameHold", + "knobs": [ + ("first_frame", nuke.frame()) + ], + "dependent": None + } + ] + + write_node = lib.create_write_node( + self.name, + write_data, + input=selected_node, + review=False, + prenodes=_prenodes, + farm=False, + linked_knobs=["channels", "___", "first", "last", "use_limit"]) + + # relinking to collected connections + for i, input in enumerate(inputs): + write_node.setInput(i, input) + + write_node.autoplace() + + for output in outputs: + output.setInput(0, write_node) + + # link frame hold to group node + write_node.begin() + for n in nuke.allNodes(): + # get write node + if n.Class() in "Write": + w_node = n + write_node.end() + + w_node["use_limit"].setValue(True) + w_node["first"].setValue(nuke.frame()) + w_node["last"].setValue(nuke.frame()) + + return write_node diff --git a/openpype/hosts/nuke/plugins/load/load_image.py b/openpype/hosts/nuke/plugins/load/load_image.py index 8bc266f01b..afd1a173b6 100644 --- a/openpype/hosts/nuke/plugins/load/load_image.py +++ b/openpype/hosts/nuke/plugins/load/load_image.py @@ -12,8 +12,8 @@ from openpype.hosts.nuke.api.lib import ( class LoadImage(api.Loader): """Load still image into Nuke""" - families = ["render", "source", "plate", "review", "image"] - representations = ["exr", "dpx", "jpg", "jpeg", "png", "psd"] + families = ["render", "source", "plate", "review", "image", "still"] + representations = ["exr", "dpx", "jpg", "jpeg", "png", "psd", "tiff"] label = "Load Image" order = -10 diff --git a/openpype/hosts/nuke/plugins/publish/extract_render_local.py b/openpype/hosts/nuke/plugins/publish/extract_render_local.py index 49609f70e0..253fc5e6a3 100644 --- a/openpype/hosts/nuke/plugins/publish/extract_render_local.py +++ b/openpype/hosts/nuke/plugins/publish/extract_render_local.py @@ -17,7 +17,7 @@ class NukeRenderLocal(openpype.api.Extractor): order = pyblish.api.ExtractorOrder label = "Render Local" hosts = ["nuke"] - families = ["render.local", "prerender.local"] + families = ["render.local", "prerender.local", "still.local"] def process(self, instance): families = instance.data["families"] @@ -66,13 +66,23 @@ class NukeRenderLocal(openpype.api.Extractor): instance.data["representations"] = [] collected_frames = os.listdir(out_dir) - repre = { - 'name': ext, - 'ext': ext, - 'frameStart': "%0{}d".format(len(str(last_frame))) % first_frame, - 'files': collected_frames, - "stagingDir": out_dir - } + + if len(collected_frames) == 1: + repre = { + 'name': ext, + 'ext': ext, + 'files': collected_frames.pop(), + "stagingDir": out_dir + } + else: + repre = { + 'name': ext, + 'ext': ext, + 'frameStart': "%0{}d".format( + len(str(last_frame))) % first_frame, + 'files': collected_frames, + "stagingDir": out_dir + } instance.data["representations"].append(repre) self.log.info("Extracted instance '{0}' to: {1}".format( @@ -89,6 +99,9 @@ class NukeRenderLocal(openpype.api.Extractor): instance.data['family'] = 'prerender' families.remove('prerender.local') families.insert(0, "prerender") + elif "still.local" in families: + instance.data['family'] = 'still' + families.remove('still.local') instance.data["families"] = families collections, remainder = clique.assemble(collected_frames) diff --git a/openpype/hosts/nuke/plugins/publish/precollect_writes.py b/openpype/hosts/nuke/plugins/publish/precollect_writes.py index 47189c31fc..4d9bf26457 100644 --- a/openpype/hosts/nuke/plugins/publish/precollect_writes.py +++ b/openpype/hosts/nuke/plugins/publish/precollect_writes.py @@ -64,7 +64,7 @@ class CollectNukeWrites(pyblish.api.InstancePlugin): ) if [fm for fm in _families_test - if fm in ["render", "prerender"]]: + if fm in ["render", "prerender", "still"]]: if "representations" not in instance.data: instance.data["representations"] = list() @@ -100,7 +100,10 @@ class CollectNukeWrites(pyblish.api.InstancePlugin): frame_start_str, frame_slate_str) collected_frames.insert(0, slate_frame) - representation['files'] = collected_frames + if collected_frames_len == 1: + representation['files'] = collected_frames.pop() + else: + representation['files'] = collected_frames instance.data["representations"].append(representation) except Exception: instance.data["representations"].append(representation) diff --git a/openpype/hosts/nuke/plugins/publish/validate_rendered_frames.py b/openpype/hosts/nuke/plugins/publish/validate_rendered_frames.py index 0c88014649..29faf867d2 100644 --- a/openpype/hosts/nuke/plugins/publish/validate_rendered_frames.py +++ b/openpype/hosts/nuke/plugins/publish/validate_rendered_frames.py @@ -55,7 +55,7 @@ class ValidateRenderedFrames(pyblish.api.InstancePlugin): """ Validates file output. """ order = pyblish.api.ValidatorOrder + 0.1 - families = ["render", "prerender"] + families = ["render", "prerender", "still"] label = "Validate rendered frame" hosts = ["nuke", "nukestudio"] @@ -71,6 +71,9 @@ class ValidateRenderedFrames(pyblish.api.InstancePlugin): self.log.error(msg) raise ValidationException(msg) + if isinstance(repre["files"], str): + return + collections, remainder = clique.assemble(repre["files"]) self.log.info("collections: {}".format(str(collections))) self.log.info("remainder: {}".format(str(remainder))) diff --git a/openpype/plugins/publish/integrate_new.py b/openpype/plugins/publish/integrate_new.py index 3bff3ff79c..13815d5dd5 100644 --- a/openpype/plugins/publish/integrate_new.py +++ b/openpype/plugins/publish/integrate_new.py @@ -86,6 +86,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): "source", "matchmove", "image", + "still", "source", "assembly", "fbx", diff --git a/openpype/settings/defaults/project_anatomy/imageio.json b/openpype/settings/defaults/project_anatomy/imageio.json index fcebc876f5..38313a3d84 100644 --- a/openpype/settings/defaults/project_anatomy/imageio.json +++ b/openpype/settings/defaults/project_anatomy/imageio.json @@ -124,9 +124,47 @@ "value": "True" } ] + }, + { + "plugins": [ + "CreateWriteStill" + ], + "nukeNodeClass": "Write", + "knobs": [ + { + "name": "file_type", + "value": "tiff" + }, + { + "name": "datatype", + "value": "16 bit" + }, + { + "name": "compression", + "value": "Deflate" + }, + { + "name": "tile_color", + "value": "0x23ff00ff" + }, + { + "name": "channels", + "value": "rgb" + }, + { + "name": "colorspace", + "value": "sRGB" + }, + { + "name": "create_directories", + "value": "True" + } + ] } ], - "customNodes": [] + "customNodes": [ + + ] }, "regexInputs": { "inputs": [ diff --git a/openpype/settings/defaults/project_settings/nuke.json b/openpype/settings/defaults/project_settings/nuke.json index ac35349415..0ea6c47027 100644 --- a/openpype/settings/defaults/project_settings/nuke.json +++ b/openpype/settings/defaults/project_settings/nuke.json @@ -119,7 +119,8 @@ "render", "prerender", "review", - "image" + "image", + "still" ], "representations": [ "exr", @@ -127,7 +128,8 @@ "jpg", "jpeg", "png", - "psd" + "psd", + "tiff" ], "node_name_template": "{class_name}_{ext}" }, From c643431aa87308c4db740e5df649490f811cfecd Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 23 Sep 2021 15:03:38 +0200 Subject: [PATCH 08/25] hound: suggestions --- openpype/hosts/nuke/plugins/create/create_write_still.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/nuke/plugins/create/create_write_still.py b/openpype/hosts/nuke/plugins/create/create_write_still.py index 1178928652..eebb5613c3 100644 --- a/openpype/hosts/nuke/plugins/create/create_write_still.py +++ b/openpype/hosts/nuke/plugins/create/create_write_still.py @@ -17,7 +17,7 @@ class CreateWriteStill(plugin.PypeCreator): "ImageFrame{:0>4}".format(nuke.frame()), "MPFrame{:0>4}".format(nuke.frame()), "LayoutFrame{:0>4}".format(nuke.frame()) - ] + ] def __init__(self, *args, **kwargs): super(CreateWriteStill, self).__init__(*args, **kwargs) @@ -92,11 +92,10 @@ class CreateWriteStill(plugin.PypeCreator): self.data.update(creator_data) write_data.update(creator_data) - self.log.info("Adding template path from plugin") write_data.update({ - "fpath_template": ("{work}/renders/nuke/{subset}" - "/{subset}.{ext}")}) + "fpath_template": ( + "{work}/renders/nuke/{subset}/{subset}.{ext}")}) _prenodes = [ { From 01e5145134490156698cc31b0294f1194f81fd59 Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Fri, 24 Sep 2021 11:28:54 +0100 Subject: [PATCH 09/25] Use CRF for burnin when available - passing ffmpeg cmd from review to burnin. --- openpype/plugins/publish/extract_burnin.py | 3 ++- openpype/plugins/publish/extract_review.py | 3 ++- openpype/scripts/otio_burnin.py | 28 +++++++++++++++------- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/openpype/plugins/publish/extract_burnin.py b/openpype/plugins/publish/extract_burnin.py index 625125321c..e386f97551 100644 --- a/openpype/plugins/publish/extract_burnin.py +++ b/openpype/plugins/publish/extract_burnin.py @@ -226,7 +226,8 @@ class ExtractBurnin(openpype.api.Extractor): "options": copy.deepcopy(burnin_options), "values": burnin_values, "full_input_path": temp_data["full_input_paths"][0], - "first_frame": temp_data["first_frame"] + "first_frame": temp_data["first_frame"], + "ffmpeg_cmd": new_repre.get("ffmpeg_cmd", "") } self.log.debug( diff --git a/openpype/plugins/publish/extract_review.py b/openpype/plugins/publish/extract_review.py index f5d6789dd4..a2d1b4dbfc 100644 --- a/openpype/plugins/publish/extract_review.py +++ b/openpype/plugins/publish/extract_review.py @@ -241,7 +241,8 @@ class ExtractReview(pyblish.api.InstancePlugin): "outputName": output_name, "outputDef": output_def, "frameStartFtrack": temp_data["output_frame_start"], - "frameEndFtrack": temp_data["output_frame_end"] + "frameEndFtrack": temp_data["output_frame_end"], + "ffmpeg_cmd": subprcs_cmd }) # Force to pop these key if are in new repre diff --git a/openpype/scripts/otio_burnin.py b/openpype/scripts/otio_burnin.py index dc8d60cb37..5b48a4f3f4 100644 --- a/openpype/scripts/otio_burnin.py +++ b/openpype/scripts/otio_burnin.py @@ -69,7 +69,7 @@ def get_fps(str_value): return str(fps) -def _prores_codec_args(ffprobe_data): +def _prores_codec_args(ffprobe_data, ffmpeg_cmd): output = [] tags = ffprobe_data.get("tags") or {} @@ -108,13 +108,22 @@ def _prores_codec_args(ffprobe_data): return output -def _h264_codec_args(ffprobe_data): +def _h264_codec_args(ffprobe_data, ffmpeg_cmd): output = [] output.extend(["-codec:v", "h264"]) + args = ffmpeg_cmd.split(" ") + crf = "" + for count, arg in enumerate(args): + if arg == "-crf": + crf = args[count + 1] + break + if crf: + output.extend(["-crf", crf]) + bit_rate = ffprobe_data.get("bit_rate") - if bit_rate: + if bit_rate and not crf: output.extend(["-b:v", bit_rate]) pix_fmt = ffprobe_data.get("pix_fmt") @@ -127,15 +136,15 @@ def _h264_codec_args(ffprobe_data): return output -def get_codec_args(ffprobe_data): +def get_codec_args(ffprobe_data, ffmpeg_cmd): codec_name = ffprobe_data.get("codec_name") # Codec "prores" if codec_name == "prores": - return _prores_codec_args(ffprobe_data) + return _prores_codec_args(ffprobe_data, ffmpeg_cmd) # Codec "h264" if codec_name == "h264": - return _h264_codec_args(ffprobe_data) + return _h264_codec_args(ffprobe_data, ffmpeg_cmd) output = [] if codec_name: @@ -469,7 +478,7 @@ def example(input_path, output_path): def burnins_from_data( input_path, output_path, data, codec_data=None, options=None, burnin_values=None, overwrite=True, - full_input_path=None, first_frame=None + full_input_path=None, first_frame=None, ffmpeg_cmd=None ): """This method adds burnins to video/image file based on presets setting. @@ -647,7 +656,7 @@ def burnins_from_data( else: ffprobe_data = burnin._streams[0] - ffmpeg_args.extend(get_codec_args(ffprobe_data)) + ffmpeg_args.extend(get_codec_args(ffprobe_data, ffmpeg_cmd)) # Use group one (same as `-intra` argument, which is deprecated) ffmpeg_args_str = " ".join(ffmpeg_args) @@ -670,6 +679,7 @@ if __name__ == "__main__": options=in_data.get("options"), burnin_values=in_data.get("values"), full_input_path=in_data.get("full_input_path"), - first_frame=in_data.get("first_frame") + first_frame=in_data.get("first_frame"), + ffmpeg_cmd=in_data.get("ffmpeg_cmd") ) print("* Burnin script has finished") From 5d70ab2a0e9d4dd43c50c454fcdda449f3b5e346 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 27 Sep 2021 13:42:52 +0200 Subject: [PATCH 10/25] store context task type to context data --- openpype/plugins/publish/collect_avalon_entities.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/openpype/plugins/publish/collect_avalon_entities.py b/openpype/plugins/publish/collect_avalon_entities.py index 0b6423818e..a6120d42fe 100644 --- a/openpype/plugins/publish/collect_avalon_entities.py +++ b/openpype/plugins/publish/collect_avalon_entities.py @@ -22,6 +22,7 @@ class CollectAvalonEntities(pyblish.api.ContextPlugin): io.install() project_name = api.Session["AVALON_PROJECT"] asset_name = api.Session["AVALON_ASSET"] + task_name = api.Session["AVALON_TASK"] project_entity = io.find_one({ "type": "project", @@ -48,6 +49,12 @@ class CollectAvalonEntities(pyblish.api.ContextPlugin): data = asset_entity['data'] + # Task type + asset_tasks = data.get("tasks") or {} + task_info = asset_tasks.get(task_name) or {} + task_type = task_info.get("type") + context.data["taskType"] = task_type + frame_start = data.get("frameStart") if frame_start is None: frame_start = 1 From f58cacb716c0968a3eaa2acea9258c81b7368fbf Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 27 Sep 2021 15:47:17 +0200 Subject: [PATCH 11/25] validate intent has settings and can work on more hosts --- openpype/plugins/publish/validate_intent.py | 53 +++++++++++++++---- .../defaults/project_settings/global.json | 4 ++ .../schemas/schema_global_publish.json | 53 +++++++++++++++++++ 3 files changed, 99 insertions(+), 11 deletions(-) diff --git a/openpype/plugins/publish/validate_intent.py b/openpype/plugins/publish/validate_intent.py index 80bcb0e164..23d57bb2b7 100644 --- a/openpype/plugins/publish/validate_intent.py +++ b/openpype/plugins/publish/validate_intent.py @@ -1,5 +1,7 @@ -import pyblish.api import os +import pyblish.api + +from openpype.lib import filter_profiles class ValidateIntent(pyblish.api.ContextPlugin): @@ -12,20 +14,49 @@ class ValidateIntent(pyblish.api.ContextPlugin): order = pyblish.api.ValidatorOrder label = "Validate Intent" - # TODO: this should be off by default and only activated viac config - tasks = ["animation"] - hosts = ["harmony"] - if os.environ.get("AVALON_TASK") not in tasks: - active = False + enabled = False + + # Can be modified by settings + profiles = [{ + "hosts": [], + "task_types": [], + "tasks": [], + "validate": False + }] def process(self, context): + # Skip if there are no profiles + validate = True + if self.profiles: + # Collect data from context + task_name = context.data.get("task") + task_type = context.data.get("taskType") + host_name = context.data.get("hostName") + + filter_data = { + "hosts": host_name, + "task_types": task_type, + "tasks": task_name + } + matching_profile = filter_profiles( + self.profiles, filter_data, logger=self.log + ) + if matching_profile: + validate = matching_profile["validate"] + + if not validate: + self.log.debug(( + "Validation of intent was skipped." + " Matching profile for current context disabled validation." + )) + return + msg = ( "Please make sure that you select the intent of this publish." ) - intent = context.data.get("intent") - self.log.debug(intent) - assert intent, msg - + intent = context.data.get("intent") or {} + self.log.debug(str(intent)) intent_value = intent.get("value") - assert intent is not "", msg + if not intent_value: + raise AssertionError(msg) diff --git a/openpype/settings/defaults/project_settings/global.json b/openpype/settings/defaults/project_settings/global.json index 8cc8d28e5f..0374ab9066 100644 --- a/openpype/settings/defaults/project_settings/global.json +++ b/openpype/settings/defaults/project_settings/global.json @@ -8,6 +8,10 @@ "enabled": true, "optional": false }, + "ValidateIntent": { + "enabled": false, + "profiles": [] + }, "IntegrateHeroVersion": { "enabled": true, "optional": true, diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json index e59d22aa89..8613743ef2 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json @@ -44,6 +44,59 @@ } ] }, + { + "type": "dict", + "label": "Validate Intent", + "key": "ValidateIntent", + "is_group": true, + "checkbox_key": "enabled", + "children": [ + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "label", + "label": "Validate if Publishing intent was selected. It is possible to disable validation for specific publishing context with profiles." + }, + { + "type": "list", + "collapsible": true, + "key": "profiles", + "object_type": { + "type": "dict", + "children": [ + { + "key": "hosts", + "label": "Host names", + "type": "hosts-enum", + "multiselection": true + }, + { + "key": "task_types", + "label": "Task types", + "type": "task-types-enum" + }, + { + "key": "tasks", + "label": "Task names", + "type": "list", + "object_type": "text" + }, + { + "type": "separator" + }, + { + "key": "validate", + "label": "Validate", + "type": "boolean" + } + ] + } + } + ] + }, { "type": "dict", "collapsible": true, From eeda206278a5cc4d0a627513798394ef326907cb Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 27 Sep 2021 18:07:26 +0200 Subject: [PATCH 12/25] ValidateInstanceInContext was split into 2 separated plugins with own settings in maya and nuke host --- .../publish/validate_instance_in_context.py | 57 +++------ .../publish/validate_instance_in_context.py | 110 ++++++++++++++++++ .../defaults/project_settings/maya.json | 5 + .../defaults/project_settings/nuke.json | 5 + .../schemas/schema_maya_publish.json | 10 ++ .../schemas/schema_nuke_publish.json | 10 ++ 6 files changed, 157 insertions(+), 40 deletions(-) rename openpype/{ => hosts/maya}/plugins/publish/validate_instance_in_context.py (65%) create mode 100644 openpype/hosts/nuke/plugins/publish/validate_instance_in_context.py diff --git a/openpype/plugins/publish/validate_instance_in_context.py b/openpype/hosts/maya/plugins/publish/validate_instance_in_context.py similarity index 65% rename from openpype/plugins/publish/validate_instance_in_context.py rename to openpype/hosts/maya/plugins/publish/validate_instance_in_context.py index 61b4d82027..7b8c335062 100644 --- a/openpype/plugins/publish/validate_instance_in_context.py +++ b/openpype/hosts/maya/plugins/publish/validate_instance_in_context.py @@ -5,6 +5,8 @@ from __future__ import absolute_import import pyblish.api import openpype.api +from maya import cmds + class SelectInvalidInstances(pyblish.api.Action): """Select invalid instances in Outliner.""" @@ -18,13 +20,12 @@ class SelectInvalidInstances(pyblish.api.Action): # Get the errored instances failed = [] for result in context.data["results"]: - if result["error"] is None: - continue - if result["instance"] is None: - continue - if result["instance"] in failed: - continue - if result["plugin"] != plugin: + if ( + result["error"] is None + or result["instance"] is None + or result["instance"] in failed + or result["plugin"] != plugin + ): continue failed.append(result["instance"]) @@ -44,25 +45,10 @@ class SelectInvalidInstances(pyblish.api.Action): self.deselect() def select(self, instances): - if "nuke" in pyblish.api.registered_hosts(): - import avalon.nuke.lib - import nuke - avalon.nuke.lib.select_nodes( - [nuke.toNode(str(x)) for x in instances] - ) - - if "maya" in pyblish.api.registered_hosts(): - from maya import cmds - cmds.select(instances, replace=True, noExpand=True) + cmds.select(instances, replace=True, noExpand=True) def deselect(self): - if "nuke" in pyblish.api.registered_hosts(): - import avalon.nuke.lib - avalon.nuke.lib.reset_selection() - - if "maya" in pyblish.api.registered_hosts(): - from maya import cmds - cmds.select(deselect=True) + cmds.select(deselect=True) class RepairSelectInvalidInstances(pyblish.api.Action): @@ -92,23 +78,14 @@ class RepairSelectInvalidInstances(pyblish.api.Action): context_asset = context.data["assetEntity"]["name"] for instance in instances: - if "nuke" in pyblish.api.registered_hosts(): - import openpype.hosts.nuke.api as nuke_api - origin_node = instance[0] - nuke_api.lib.recreate_instance( - origin_node, avalon_data={"asset": context_asset} - ) - else: - self.set_attribute(instance, context_asset) + self.set_attribute(instance, context_asset) def set_attribute(self, instance, context_asset): - if "maya" in pyblish.api.registered_hosts(): - from maya import cmds - cmds.setAttr( - instance.data.get("name") + ".asset", - context_asset, - type="string" - ) + cmds.setAttr( + instance.data.get("name") + ".asset", + context_asset, + type="string" + ) class ValidateInstanceInContext(pyblish.api.InstancePlugin): @@ -124,7 +101,7 @@ class ValidateInstanceInContext(pyblish.api.InstancePlugin): order = openpype.api.ValidateContentsOrder label = "Instance in same Context" optional = True - hosts = ["maya", "nuke"] + hosts = ["maya"] actions = [SelectInvalidInstances, RepairSelectInvalidInstances] def process(self, instance): diff --git a/openpype/hosts/nuke/plugins/publish/validate_instance_in_context.py b/openpype/hosts/nuke/plugins/publish/validate_instance_in_context.py new file mode 100644 index 0000000000..ddf46a0873 --- /dev/null +++ b/openpype/hosts/nuke/plugins/publish/validate_instance_in_context.py @@ -0,0 +1,110 @@ +# -*- coding: utf-8 -*- +"""Validate if instance asset is the same as context asset.""" +from __future__ import absolute_import + +import nuke + +import pyblish.api +import openpype.api +import avalon.nuke.lib +import openpype.hosts.nuke.api as nuke_api + + +class SelectInvalidInstances(pyblish.api.Action): + """Select invalid instances in Outliner.""" + + label = "Select Instances" + icon = "briefcase" + on = "failed" + + def process(self, context, plugin): + """Process invalid validators and select invalid instances.""" + # Get the errored instances + failed = [] + for result in context.data["results"]: + if ( + result["error"] is None + or result["instance"] is None + or result["instance"] in failed + or result["plugin"] != plugin + ): + continue + + failed.append(result["instance"]) + + # Apply pyblish.logic to get the instances for the plug-in + instances = pyblish.api.instances_by_plugin(failed, plugin) + + if instances: + self.log.info( + "Selecting invalid nodes: %s" % ", ".join( + [str(x) for x in instances] + ) + ) + self.select(instances) + else: + self.log.info("No invalid nodes found.") + self.deselect() + + def select(self, instances): + avalon.nuke.lib.select_nodes( + [nuke.toNode(str(x)) for x in instances] + ) + + def deselect(self): + avalon.nuke.lib.reset_selection() + + +class RepairSelectInvalidInstances(pyblish.api.Action): + """Repair the instance asset.""" + + label = "Repair" + icon = "wrench" + on = "failed" + + def process(self, context, plugin): + # Get the errored instances + failed = [] + for result in context.data["results"]: + if ( + result["error"] is None + or result["instance"] is None + or result["instance"] in failed + or result["plugin"] != plugin + ): + continue + + failed.append(result["instance"]) + + # Apply pyblish.logic to get the instances for the plug-in + instances = pyblish.api.instances_by_plugin(failed, plugin) + + context_asset = context.data["assetEntity"]["name"] + for instance in instances: + origin_node = instance[0] + nuke_api.lib.recreate_instance( + origin_node, avalon_data={"asset": context_asset} + ) + + +class ValidateInstanceInContext(pyblish.api.InstancePlugin): + """Validator to check if instance asset match context asset. + + When working in per-shot style you always publish data in context of + current asset (shot). This validator checks if this is so. It is optional + so it can be disabled when needed. + + Action on this validator will select invalid instances in Outliner. + """ + + order = openpype.api.ValidateContentsOrder + label = "Instance in same Context" + hosts = ["nuke"] + actions = [SelectInvalidInstances, RepairSelectInvalidInstances] + optional = True + + def process(self, instance): + asset = instance.data.get("asset") + context_asset = instance.context.data["assetEntity"]["name"] + msg = "{} has asset {}".format(instance.name, asset) + assert asset == context_asset, msg diff --git a/openpype/settings/defaults/project_settings/maya.json b/openpype/settings/defaults/project_settings/maya.json index 3540c3eb29..13d417581e 100644 --- a/openpype/settings/defaults/project_settings/maya.json +++ b/openpype/settings/defaults/project_settings/maya.json @@ -156,6 +156,11 @@ "CollectMayaRender": { "sync_workfile_version": false }, + "ValidateInstanceInContext": { + "enabled": true, + "optional": true, + "active": true + }, "ValidateContainers": { "enabled": true, "optional": true, diff --git a/openpype/settings/defaults/project_settings/nuke.json b/openpype/settings/defaults/project_settings/nuke.json index ac35349415..9254e0c8f6 100644 --- a/openpype/settings/defaults/project_settings/nuke.json +++ b/openpype/settings/defaults/project_settings/nuke.json @@ -38,6 +38,11 @@ "render" ] }, + "ValidateInstanceInContext": { + "enabled": true, + "optional": true, + "active": true + }, "ValidateContainers": { "enabled": true, "optional": true, diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_publish.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_publish.json index 89cd30aed0..b5b035b9e6 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_publish.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_publish.json @@ -28,6 +28,16 @@ "type": "label", "label": "Validators" }, + { + "type": "schema_template", + "name": "template_publish_plugin", + "template_data": [ + { + "key": "ValidateInstanceInContext", + "label": "Validate Instance In Context" + } + ] + }, { "type": "schema_template", "name": "template_publish_plugin", diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_nuke_publish.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_nuke_publish.json index c73453f8aa..74b2592d29 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_nuke_publish.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_nuke_publish.json @@ -50,6 +50,16 @@ "type": "label", "label": "Validators" }, + { + "type": "schema_template", + "name": "template_publish_plugin", + "template_data": [ + { + "key": "ValidateInstanceInContext", + "label": "Validate Instance In Context" + } + ] + }, { "type": "schema_template", "name": "template_publish_plugin", From 55dfb0817c0874d5a87ac9bd53c10ebeac108dc4 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 27 Sep 2021 18:07:40 +0200 Subject: [PATCH 13/25] start stop timer plugins use settings from context --- openpype/plugins/publish/start_timer.py | 3 +-- openpype/plugins/publish/stop_timer.py | 4 +--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/openpype/plugins/publish/start_timer.py b/openpype/plugins/publish/start_timer.py index 6312294bf1..112d92bef0 100644 --- a/openpype/plugins/publish/start_timer.py +++ b/openpype/plugins/publish/start_timer.py @@ -1,6 +1,5 @@ import pyblish.api -from openpype.api import get_system_settings from openpype.lib import change_timer_to_current_context @@ -10,6 +9,6 @@ class StartTimer(pyblish.api.ContextPlugin): hosts = ["*"] def process(self, context): - modules_settings = get_system_settings()["modules"] + modules_settings = context.data["system_settings"]["modules"] if modules_settings["timers_manager"]["disregard_publishing"]: change_timer_to_current_context() diff --git a/openpype/plugins/publish/stop_timer.py b/openpype/plugins/publish/stop_timer.py index 5c939b5f1b..414e43a3c4 100644 --- a/openpype/plugins/publish/stop_timer.py +++ b/openpype/plugins/publish/stop_timer.py @@ -3,8 +3,6 @@ import requests import pyblish.api -from openpype.api import get_system_settings - class StopTimer(pyblish.api.ContextPlugin): label = "Stop Timer" @@ -12,7 +10,7 @@ class StopTimer(pyblish.api.ContextPlugin): hosts = ["*"] def process(self, context): - modules_settings = get_system_settings()["modules"] + modules_settings = context.data["system_settings"]["modules"] if modules_settings["timers_manager"]["disregard_publishing"]: webserver_url = os.environ.get("OPENPYPE_WEBSERVER_URL") rest_api_url = "{}/timers_manager/stop_timer".format(webserver_url) From 7e925f94f4089b4cbfd040c3eb2a614c1719db3c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 27 Sep 2021 18:08:05 +0200 Subject: [PATCH 14/25] moved sceneinventory import to method where is used --- openpype/plugins/publish/validate_containers.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openpype/plugins/publish/validate_containers.py b/openpype/plugins/publish/validate_containers.py index 52df493451..784221c3b6 100644 --- a/openpype/plugins/publish/validate_containers.py +++ b/openpype/plugins/publish/validate_containers.py @@ -1,7 +1,5 @@ import pyblish.api - import openpype.lib -from avalon.tools import cbsceneinventory class ShowInventory(pyblish.api.Action): @@ -11,7 +9,9 @@ class ShowInventory(pyblish.api.Action): on = "failed" def process(self, context, plugin): - cbsceneinventory.show() + from avalon.tools import sceneinventory + + sceneinventory.show() class ValidateContainers(pyblish.api.ContextPlugin): From d6ebdd9280abe8b13748548cb58cbb54e6f3988c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 27 Sep 2021 18:20:16 +0200 Subject: [PATCH 15/25] added active to validate version plugin --- openpype/plugins/publish/validate_version.py | 3 +++ openpype/settings/defaults/project_settings/global.json | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/openpype/plugins/publish/validate_version.py b/openpype/plugins/publish/validate_version.py index 6701041541..927e024476 100644 --- a/openpype/plugins/publish/validate_version.py +++ b/openpype/plugins/publish/validate_version.py @@ -12,6 +12,9 @@ class ValidateVersion(pyblish.api.InstancePlugin): label = "Validate Version" hosts = ["nuke", "maya", "blender", "standalonepublisher"] + optional = False + active = True + def process(self, instance): version = instance.data.get("version") latest_version = instance.data.get("latestVersion") diff --git a/openpype/settings/defaults/project_settings/global.json b/openpype/settings/defaults/project_settings/global.json index 0374ab9066..d311d9611e 100644 --- a/openpype/settings/defaults/project_settings/global.json +++ b/openpype/settings/defaults/project_settings/global.json @@ -6,7 +6,8 @@ }, "ValidateVersion": { "enabled": true, - "optional": false + "optional": false, + "active": true }, "ValidateIntent": { "enabled": false, From d75a1062b9708629496d6c4e634408c0a1928cf0 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 28 Sep 2021 15:18:17 +0200 Subject: [PATCH 16/25] change variable from 'ffmpeg_cmd' to 'source_ffmpeg_cmd' --- openpype/scripts/otio_burnin.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/openpype/scripts/otio_burnin.py b/openpype/scripts/otio_burnin.py index 5b48a4f3f4..da9cab1290 100644 --- a/openpype/scripts/otio_burnin.py +++ b/openpype/scripts/otio_burnin.py @@ -69,7 +69,7 @@ def get_fps(str_value): return str(fps) -def _prores_codec_args(ffprobe_data, ffmpeg_cmd): +def _prores_codec_args(ffprobe_data, source_ffmpeg_cmd): output = [] tags = ffprobe_data.get("tags") or {} @@ -108,12 +108,12 @@ def _prores_codec_args(ffprobe_data, ffmpeg_cmd): return output -def _h264_codec_args(ffprobe_data, ffmpeg_cmd): +def _h264_codec_args(ffprobe_data, source_ffmpeg_cmd): output = [] output.extend(["-codec:v", "h264"]) - args = ffmpeg_cmd.split(" ") + args = source_ffmpeg_cmd.split(" ") crf = "" for count, arg in enumerate(args): if arg == "-crf": @@ -136,15 +136,15 @@ def _h264_codec_args(ffprobe_data, ffmpeg_cmd): return output -def get_codec_args(ffprobe_data, ffmpeg_cmd): +def get_codec_args(ffprobe_data, source_ffmpeg_cmd): codec_name = ffprobe_data.get("codec_name") # Codec "prores" if codec_name == "prores": - return _prores_codec_args(ffprobe_data, ffmpeg_cmd) + return _prores_codec_args(ffprobe_data, source_ffmpeg_cmd) # Codec "h264" if codec_name == "h264": - return _h264_codec_args(ffprobe_data, ffmpeg_cmd) + return _h264_codec_args(ffprobe_data, source_ffmpeg_cmd) output = [] if codec_name: @@ -478,7 +478,7 @@ def example(input_path, output_path): def burnins_from_data( input_path, output_path, data, codec_data=None, options=None, burnin_values=None, overwrite=True, - full_input_path=None, first_frame=None, ffmpeg_cmd=None + full_input_path=None, first_frame=None, source_ffmpeg_cmd=None ): """This method adds burnins to video/image file based on presets setting. @@ -656,7 +656,7 @@ def burnins_from_data( else: ffprobe_data = burnin._streams[0] - ffmpeg_args.extend(get_codec_args(ffprobe_data, ffmpeg_cmd)) + ffmpeg_args.extend(get_codec_args(ffprobe_data, source_ffmpeg_cmd)) # Use group one (same as `-intra` argument, which is deprecated) ffmpeg_args_str = " ".join(ffmpeg_args) @@ -680,6 +680,6 @@ if __name__ == "__main__": burnin_values=in_data.get("values"), full_input_path=in_data.get("full_input_path"), first_frame=in_data.get("first_frame"), - ffmpeg_cmd=in_data.get("ffmpeg_cmd") + source_ffmpeg_cmd=in_data.get("ffmpeg_cmd") ) print("* Burnin script has finished") From 2207f6f6a53f119d46e81e11dbc2efda7c96d3f9 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 28 Sep 2021 15:18:55 +0200 Subject: [PATCH 17/25] reuse more source arguments and skip using source bitrate --- openpype/scripts/otio_burnin.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/openpype/scripts/otio_burnin.py b/openpype/scripts/otio_burnin.py index da9cab1290..184d7689e3 100644 --- a/openpype/scripts/otio_burnin.py +++ b/openpype/scripts/otio_burnin.py @@ -113,18 +113,19 @@ def _h264_codec_args(ffprobe_data, source_ffmpeg_cmd): output.extend(["-codec:v", "h264"]) - args = source_ffmpeg_cmd.split(" ") - crf = "" - for count, arg in enumerate(args): - if arg == "-crf": - crf = args[count + 1] - break - if crf: - output.extend(["-crf", crf]) - - bit_rate = ffprobe_data.get("bit_rate") - if bit_rate and not crf: - output.extend(["-b:v", bit_rate]) + # Use arguments from source if are available source arguments + if source_ffmpeg_cmd: + copy_args = ( + "-crf", + "-b:v", "-vb", + "-minrate", "-minrate:", + "-maxrate", "-maxrate:", + "-bufsize", "-bufsize:" + ) + args = source_ffmpeg_cmd.split(" ") + for idx, arg in enumerate(args): + if arg in copy_args: + output.extend([arg, args[idx + 1]]) pix_fmt = ffprobe_data.get("pix_fmt") if pix_fmt: From 5d59712e0d44b140dbdfd5fa91f6623aaab26283 Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Tue, 28 Sep 2021 17:14:59 +0200 Subject: [PATCH 18/25] remove collector --- .../plugins/publish/collect_loaded_plugin.py | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 openpype/hosts/maya/plugins/publish/collect_loaded_plugin.py diff --git a/openpype/hosts/maya/plugins/publish/collect_loaded_plugin.py b/openpype/hosts/maya/plugins/publish/collect_loaded_plugin.py deleted file mode 100644 index 7ee7021962..0000000000 --- a/openpype/hosts/maya/plugins/publish/collect_loaded_plugin.py +++ /dev/null @@ -1,17 +0,0 @@ -import pyblish.api -from maya import cmds - - -class CollectLoadedPlugin(pyblish.api.ContextPlugin): - """Collect loaded plugins""" - - order = pyblish.api.CollectorOrder - label = "Loaded Plugins" - hosts = ["maya"] - - def process(self, context): - - context.data["loadedPlugins"] = cmds.pluginInfo( - query=True, - listPlugins=True, - ) From 536d6f000ecdb21fa4dfa9af8ac9c5f9fd0c6edd Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Tue, 28 Sep 2021 17:50:35 +0200 Subject: [PATCH 19/25] add option for whitelist native maya plugins --- .../plugins/publish/validate_loaded_plugin.py | 13 ++++- .../defaults/project_settings/maya.json | 48 +------------------ .../schemas/schema_maya_publish.json | 5 ++ 3 files changed, 18 insertions(+), 48 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/validate_loaded_plugin.py b/openpype/hosts/maya/plugins/publish/validate_loaded_plugin.py index 01705e8b13..444aeb24c1 100644 --- a/openpype/hosts/maya/plugins/publish/validate_loaded_plugin.py +++ b/openpype/hosts/maya/plugins/publish/validate_loaded_plugin.py @@ -1,6 +1,7 @@ import pyblish.api import maya.cmds as cmds import openpype.api +import os class ValidateLoadedPlugin(pyblish.api.ContextPlugin): @@ -15,9 +16,16 @@ class ValidateLoadedPlugin(pyblish.api.ContextPlugin): def get_invalid(cls, context): invalid = [] + loaded_plugin = cmds.pluginInfo(query=True, listPlugins=True) + # get variable from OpenPype settings + whitelist_native_plugins = cls.whitelist_native_plugins + authorized_plugins = cls.authorized_plugins or [] - for plugin in context.data.get("loadedPlugins"): - if plugin not in cls.authorized_plugins: + for plugin in loaded_plugin: + if not whitelist_native_plugins and os.getenv('MAYA_LOCATION') \ + in cmds.pluginInfo(plugin, query=True, path=True): + continue + if plugin not in authorized_plugins: invalid.append(plugin) return invalid @@ -35,4 +43,5 @@ class ValidateLoadedPlugin(pyblish.api.ContextPlugin): """Unload forbidden plugins""" for plugin in cls.get_invalid(context): + cmds.pluginInfo(plugin, edit=True, autoload=False) cmds.unloadPlugin(plugin, force=True) diff --git a/openpype/settings/defaults/project_settings/maya.json b/openpype/settings/defaults/project_settings/maya.json index b19d544fed..56496e05d0 100644 --- a/openpype/settings/defaults/project_settings/maya.json +++ b/openpype/settings/defaults/project_settings/maya.json @@ -171,52 +171,8 @@ }, "ValidateLoadedPlugin": { "enabled": false, - "authorized_plugins": [ - "stereoCamera", - "svgFileTranslator", - "invertShape", - "mayaHIK", - "GamePipeline", - "curveWarp", - "tiffFloatReader", - "MASH", - "poseInterpolator", - "ATFPlugin", - "hairPhysicalShader", - "cacheEvaluator", - "ikSpringSolver", - "ik2Bsolver", - "xgenToolkit", - "AbcExport", - "retargeterNodes", - "gameFbxExporter", - "VectorRender", - "OpenEXRLoader", - "lookdevKit", - "Unfold3D", - "Type", - "mayaCharacterization", - "meshReorder", - "modelingToolkit", - "MayaMuscle", - "rotateHelper", - "dx11Shader", - "matrixNodes", - "AbcImport", - "autoLoader", - "deformerEvaluator", - "sceneAssembly", - "gpuCache", - "OneClick", - "shaderFXPlugin", - "objExport", - "renderSetup", - "GPUBuiltInDeformer", - "ArubaTessellator", - "quatNodes", - "fbxmaya", - "Turtle" - ] + "whitelist_native_plugins": false, + "authorized_plugins": [] }, "ValidateRenderSettings": { "arnold_render_attributes": [], diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_publish.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_publish.json index e2df6654f2..8379f04556 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_publish.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_publish.json @@ -94,6 +94,11 @@ "key": "enabled", "label": "Enabled" }, + { + "type": "boolean", + "key": "whitelist_native_plugins", + "label": "Whitelist Maya Native Plugins" + }, { "type": "list", "key": "authorized_plugins", From cd05b01f053f5c491452142e6d9bc9bab6d1f4e8 Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Tue, 28 Sep 2021 17:54:56 +0200 Subject: [PATCH 20/25] flake8 E125 correction --- openpype/hosts/maya/plugins/publish/validate_loaded_plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/maya/plugins/publish/validate_loaded_plugin.py b/openpype/hosts/maya/plugins/publish/validate_loaded_plugin.py index 444aeb24c1..9306d8ce15 100644 --- a/openpype/hosts/maya/plugins/publish/validate_loaded_plugin.py +++ b/openpype/hosts/maya/plugins/publish/validate_loaded_plugin.py @@ -23,7 +23,7 @@ class ValidateLoadedPlugin(pyblish.api.ContextPlugin): for plugin in loaded_plugin: if not whitelist_native_plugins and os.getenv('MAYA_LOCATION') \ - in cmds.pluginInfo(plugin, query=True, path=True): + in cmds.pluginInfo(plugin, query=True, path=True): continue if plugin not in authorized_plugins: invalid.append(plugin) From b866f2ed78e1865e4c10a412e368e0dc18d9373e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 29 Sep 2021 07:59:53 +0000 Subject: [PATCH 21/25] Bump pywin32 from 300 to 301 Bumps [pywin32](https://github.com/mhammond/pywin32) from 300 to 301. - [Release notes](https://github.com/mhammond/pywin32/releases) - [Changelog](https://github.com/mhammond/pywin32/blob/main/CHANGES.txt) - [Commits](https://github.com/mhammond/pywin32/commits) --- updated-dependencies: - dependency-name: pywin32 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- poetry.lock | 47 +++++++++++++++++++++++++++++++++++------------ pyproject.toml | 2 +- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/poetry.lock b/poetry.lock index bc308d63e9..c30631340a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1090,7 +1090,7 @@ python-versions = "*" [[package]] name = "pywin32" -version = "300" +version = "301" description = "Python for Window Extensions" category = "main" optional = false @@ -1499,7 +1499,7 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pyt [metadata] lock-version = "1.1" python-versions = "3.7.*" -content-hash = "63ab0f15fa9d40931622f71ad6e8d5810e1f9b7ef5d27e1d9a8d00caad767c1d" +content-hash = "ed6430d2ba01f108a15e585629bf7b01ab47fed4217b93d336e9877273ab29e7" [metadata.files] acre = [] @@ -1904,12 +1904,22 @@ log4mongo = [ {file = "log4mongo-1.7.0.tar.gz", hash = "sha256:dc374617206162a0b14167fbb5feac01dbef587539a235dadba6200362984a68"}, ] markupsafe = [ + {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-win32.whl", hash = "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-win32.whl", hash = "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567"}, @@ -1918,14 +1928,21 @@ markupsafe = [ {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9"}, {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6"}, {file = "MarkupSafe-2.0.1-cp38-cp38-win32.whl", hash = "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64"}, {file = "MarkupSafe-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833"}, {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26"}, @@ -1935,6 +1952,9 @@ markupsafe = [ {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135"}, {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902"}, {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6"}, {file = "MarkupSafe-2.0.1-cp39-cp39-win32.whl", hash = "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74"}, {file = "MarkupSafe-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8"}, {file = "MarkupSafe-2.0.1.tar.gz", hash = "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a"}, @@ -2211,6 +2231,7 @@ pynput = [ ] pyobjc-core = [ {file = "pyobjc-core-7.3.tar.gz", hash = "sha256:5081aedf8bb40aac1a8ad95adac9e44e148a882686ded614adf46bb67fd67574"}, + {file = "pyobjc_core-7.3-1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a1f1e6b457127cbf2b5bd2b94520a7c89fb590b739911eadb2b0499a3a5b0e6f"}, {file = "pyobjc_core-7.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4e93ad769a20b908778fe950f62a843a6d8f0fa71996e5f3cc9fab5ae7d17771"}, {file = "pyobjc_core-7.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:9f63fd37bbf3785af4ddb2f86cad5ca81c62cfc7d1c0099637ca18343c3656c1"}, {file = "pyobjc_core-7.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e9b1311f72f2e170742a7ee3a8149f52c35158dc024a21e88d6f1e52ba5d718b"}, @@ -2219,6 +2240,7 @@ pyobjc-core = [ ] pyobjc-framework-cocoa = [ {file = "pyobjc-framework-Cocoa-7.3.tar.gz", hash = "sha256:b18d05e7a795a3455ad191c3e43d6bfa673c2a4fd480bb1ccf57191051b80b7e"}, + {file = "pyobjc_framework_Cocoa-7.3-1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1e31376806e5de883a1d7c7c87d9ff2a8b09fc05d267e0dfce6e42409fb70c67"}, {file = "pyobjc_framework_Cocoa-7.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9edffdfa6dd1f71f21b531c3e61fdd3e4d5d3bf6c5a528c98e88828cd60bac11"}, {file = "pyobjc_framework_Cocoa-7.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:35a6340437a4e0109a302150b7d1f6baf57004ccf74834f9e6062fcafe2fd8d7"}, {file = "pyobjc_framework_Cocoa-7.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7c3886f2608ab3ed02482f8b2ebf9f782b324c559e84b52cfd92dba8a1109872"}, @@ -2227,6 +2249,7 @@ pyobjc-framework-cocoa = [ ] pyobjc-framework-quartz = [ {file = "pyobjc-framework-Quartz-7.3.tar.gz", hash = "sha256:98812844c34262def980bdf60923a875cd43428a8375b6fd53bd2cd800eccf0b"}, + {file = "pyobjc_framework_Quartz-7.3-1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1139bc6874c0f8b58f0b8602015e0994198bc506a6bcec1071208de32b55ed26"}, {file = "pyobjc_framework_Quartz-7.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1ef18f5a16511ded65980bf4f5983ea5d35c88224dbad1b3112abd29c60413ea"}, {file = "pyobjc_framework_Quartz-7.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3b41eec8d4b10c7c7e011e2f9051367f5499ef315ba52dfbae573c3a2e05469c"}, {file = "pyobjc_framework_Quartz-7.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c65456ed045dfe1711d0298734e5a3ad670f8c770f7eb3b19979256c388bdd2"}, @@ -2300,16 +2323,16 @@ pytz = [ {file = "pytz-2021.1.tar.gz", hash = "sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da"}, ] pywin32 = [ - {file = "pywin32-300-cp35-cp35m-win32.whl", hash = "sha256:1c204a81daed2089e55d11eefa4826c05e604d27fe2be40b6bf8db7b6a39da63"}, - {file = "pywin32-300-cp35-cp35m-win_amd64.whl", hash = "sha256:350c5644775736351b77ba68da09a39c760d75d2467ecec37bd3c36a94fbed64"}, - {file = "pywin32-300-cp36-cp36m-win32.whl", hash = "sha256:a3b4c48c852d4107e8a8ec980b76c94ce596ea66d60f7a697582ea9dce7e0db7"}, - {file = "pywin32-300-cp36-cp36m-win_amd64.whl", hash = "sha256:27a30b887afbf05a9cbb05e3ffd43104a9b71ce292f64a635389dbad0ed1cd85"}, - {file = "pywin32-300-cp37-cp37m-win32.whl", hash = "sha256:d7e8c7efc221f10d6400c19c32a031add1c4a58733298c09216f57b4fde110dc"}, - {file = "pywin32-300-cp37-cp37m-win_amd64.whl", hash = "sha256:8151e4d7a19262d6694162d6da85d99a16f8b908949797fd99c83a0bfaf5807d"}, - {file = "pywin32-300-cp38-cp38-win32.whl", hash = "sha256:fbb3b1b0fbd0b4fc2a3d1d81fe0783e30062c1abed1d17c32b7879d55858cfae"}, - {file = "pywin32-300-cp38-cp38-win_amd64.whl", hash = "sha256:60a8fa361091b2eea27f15718f8eb7f9297e8d51b54dbc4f55f3d238093d5190"}, - {file = "pywin32-300-cp39-cp39-win32.whl", hash = "sha256:638b68eea5cfc8def537e43e9554747f8dee786b090e47ead94bfdafdb0f2f50"}, - {file = "pywin32-300-cp39-cp39-win_amd64.whl", hash = "sha256:b1609ce9bd5c411b81f941b246d683d6508992093203d4eb7f278f4ed1085c3f"}, + {file = "pywin32-301-cp35-cp35m-win32.whl", hash = "sha256:93367c96e3a76dfe5003d8291ae16454ca7d84bb24d721e0b74a07610b7be4a7"}, + {file = "pywin32-301-cp35-cp35m-win_amd64.whl", hash = "sha256:9635df6998a70282bd36e7ac2a5cef9ead1627b0a63b17c731312c7a0daebb72"}, + {file = "pywin32-301-cp36-cp36m-win32.whl", hash = "sha256:c866f04a182a8cb9b7855de065113bbd2e40524f570db73ef1ee99ff0a5cc2f0"}, + {file = "pywin32-301-cp36-cp36m-win_amd64.whl", hash = "sha256:dafa18e95bf2a92f298fe9c582b0e205aca45c55f989937c52c454ce65b93c78"}, + {file = "pywin32-301-cp37-cp37m-win32.whl", hash = "sha256:98f62a3f60aa64894a290fb7494bfa0bfa0a199e9e052e1ac293b2ad3cd2818b"}, + {file = "pywin32-301-cp37-cp37m-win_amd64.whl", hash = "sha256:fb3b4933e0382ba49305cc6cd3fb18525df7fd96aa434de19ce0878133bf8e4a"}, + {file = "pywin32-301-cp38-cp38-win32.whl", hash = "sha256:88981dd3cfb07432625b180f49bf4e179fb8cbb5704cd512e38dd63636af7a17"}, + {file = "pywin32-301-cp38-cp38-win_amd64.whl", hash = "sha256:8c9d33968aa7fcddf44e47750e18f3d034c3e443a707688a008a2e52bbef7e96"}, + {file = "pywin32-301-cp39-cp39-win32.whl", hash = "sha256:595d397df65f1b2e0beaca63a883ae6d8b6df1cdea85c16ae85f6d2e648133fe"}, + {file = "pywin32-301-cp39-cp39-win_amd64.whl", hash = "sha256:87604a4087434cd814ad8973bd47d6524bd1fa9e971ce428e76b62a5e0860fdf"}, ] pywin32-ctypes = [ {file = "pywin32-ctypes-0.2.0.tar.gz", hash = "sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942"}, diff --git a/pyproject.toml b/pyproject.toml index baa897cc81..158b969095 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,7 +55,7 @@ speedcopy = "^2.1" six = "^1.15" semver = "^2.13.0" # for version resolution wsrpc_aiohttp = "^3.1.1" # websocket server -pywin32 = { version = "300", markers = "sys_platform == 'win32'" } +pywin32 = { version = "301", markers = "sys_platform == 'win32'" } jinxed = [ { version = "^1.0.1", markers = "sys_platform == 'darwin'" }, { version = "^1.0.1", markers = "sys_platform == 'linux'" } From 8c53b3f1ce0129ee91f6d2430138cbb8e91f4c0c Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 30 Sep 2021 12:12:32 +0200 Subject: [PATCH 22/25] removing `still` family for integration keeping only `image` family --- openpype/hosts/nuke/plugins/load/load_image.py | 2 +- openpype/hosts/nuke/plugins/publish/extract_render_local.py | 2 +- openpype/hosts/nuke/plugins/publish/precollect_writes.py | 3 +++ openpype/settings/defaults/project_settings/nuke.json | 3 +-- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/nuke/plugins/load/load_image.py b/openpype/hosts/nuke/plugins/load/load_image.py index afd1a173b6..9b8bc43d12 100644 --- a/openpype/hosts/nuke/plugins/load/load_image.py +++ b/openpype/hosts/nuke/plugins/load/load_image.py @@ -12,7 +12,7 @@ from openpype.hosts.nuke.api.lib import ( class LoadImage(api.Loader): """Load still image into Nuke""" - families = ["render", "source", "plate", "review", "image", "still"] + families = ["render", "source", "plate", "review", "image"] representations = ["exr", "dpx", "jpg", "jpeg", "png", "psd", "tiff"] label = "Load Image" diff --git a/openpype/hosts/nuke/plugins/publish/extract_render_local.py b/openpype/hosts/nuke/plugins/publish/extract_render_local.py index 253fc5e6a3..bc7b41c733 100644 --- a/openpype/hosts/nuke/plugins/publish/extract_render_local.py +++ b/openpype/hosts/nuke/plugins/publish/extract_render_local.py @@ -100,7 +100,7 @@ class NukeRenderLocal(openpype.api.Extractor): families.remove('prerender.local') families.insert(0, "prerender") elif "still.local" in families: - instance.data['family'] = 'still' + instance.data['family'] = 'image' families.remove('still.local') instance.data["families"] = families diff --git a/openpype/hosts/nuke/plugins/publish/precollect_writes.py b/openpype/hosts/nuke/plugins/publish/precollect_writes.py index 4d9bf26457..189f28f7c6 100644 --- a/openpype/hosts/nuke/plugins/publish/precollect_writes.py +++ b/openpype/hosts/nuke/plugins/publish/precollect_writes.py @@ -102,6 +102,9 @@ class CollectNukeWrites(pyblish.api.InstancePlugin): if collected_frames_len == 1: representation['files'] = collected_frames.pop() + if "still" in _families_test: + instance.data['family'] = 'image' + instance.data["families"].remove('still') else: representation['files'] = collected_frames instance.data["representations"].append(representation) diff --git a/openpype/settings/defaults/project_settings/nuke.json b/openpype/settings/defaults/project_settings/nuke.json index 0ea6c47027..aa59c5bcfd 100644 --- a/openpype/settings/defaults/project_settings/nuke.json +++ b/openpype/settings/defaults/project_settings/nuke.json @@ -119,8 +119,7 @@ "render", "prerender", "review", - "image", - "still" + "image" ], "representations": [ "exr", From df154cb8a013f846e311ac5d2efb47d9818c726e Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 30 Sep 2021 12:14:41 +0200 Subject: [PATCH 23/25] remove `still` family from integrate new --- openpype/plugins/publish/integrate_new.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openpype/plugins/publish/integrate_new.py b/openpype/plugins/publish/integrate_new.py index 13815d5dd5..3bff3ff79c 100644 --- a/openpype/plugins/publish/integrate_new.py +++ b/openpype/plugins/publish/integrate_new.py @@ -86,7 +86,6 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): "source", "matchmove", "image", - "still", "source", "assembly", "fbx", From 8eab5e09b1ae2e9078a2519348517d439def741b Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Thu, 30 Sep 2021 18:47:25 +0200 Subject: [PATCH 24/25] Fix docstring on extract review --- openpype/plugins/publish/extract_review.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/plugins/publish/extract_review.py b/openpype/plugins/publish/extract_review.py index f5d6789dd4..a60dbfcf8b 100644 --- a/openpype/plugins/publish/extract_review.py +++ b/openpype/plugins/publish/extract_review.py @@ -30,8 +30,8 @@ class ExtractReview(pyblish.api.InstancePlugin): otherwise the representation is ignored. All new representations are created and encoded by ffmpeg following - presets found in `pype-config/presets/plugins/global/ - publish.json:ExtractReview:outputs`. + presets found in OpenPype Settings interface at + `project_settings/global/publish/ExtractReview/profiles:outputs`. """ label = "Extract Review" From d543203344055a525c11924da73d1fbf304d7a3c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 1 Oct 2021 11:15:38 +0200 Subject: [PATCH 25/25] use template_publish_plugin for validate version --- .../schemas/schema_global_publish.json | 20 +++++-------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json index 8613743ef2..c50f383f02 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json @@ -25,22 +25,12 @@ ] }, { - "type": "dict", - "collapsible": true, - "checkbox_key": "enabled", - "key": "ValidateVersion", - "label": "Validate Version", - "is_group": true, - "children": [ + "type": "schema_template", + "name": "template_publish_plugin", + "template_data": [ { - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "boolean", - "key": "optional", - "label": "Optional" + "key": "ValidateVersion", + "label": "Validate Version" } ] },