From 3770eb69b653f31292faee388ed416f7bf8a171f Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Tue, 29 Mar 2022 18:34:34 +0300 Subject: [PATCH 01/88] add rstex function --- .../maya/plugins/publish/extract_look.py | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index a8893072d0..1516495278 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -6,6 +6,7 @@ import json import tempfile import contextlib import subprocess +from openpype.lib.vendor_bin_utils import find_executable from collections import OrderedDict from maya import cmds # noqa @@ -42,6 +43,58 @@ def find_paths_by_hash(texture_hash): return io.distinct(key, {"type": "version"}) +def rstex(source, *args): + """Make `.rstexbin` using `redshiftTextureProcessor` + with some default settings. + + This function requires the `REDSHIFT_COREDATAPATH` + to be in `PATH`. + + Args: + source (str): Path to source file. + *args: Additional arguments for `redshiftTextureProcessor`. + + Returns: + str: Output of `redshiftTextureProcessor` command. + + """ + if "REDSHIFT_COREDATAPATH" not in os.environ: + raise RuntimeError("Must have Redshift available.") + + redshift_bin_path = os.path.join( + os.environ["REDSHIFT_COREDATAPATH"], + "bin", + "redshiftTextureProcessor" + ) + + texture_processor_path = find_executable(redshift_bin_path) + + cmd = [ + texture_processor_path, + escape_space(source), + + ] + + cmd.extend(args) + + cmd = " ".join(cmd) + + CREATE_NO_WINDOW = 0x08000000 + kwargs = dict(args=cmd, stderr=subprocess.STDOUT) + + if sys.platform == "win32": + kwargs["creationflags"] = CREATE_NO_WINDOW + try: + out = subprocess.check_output(**kwargs) + except subprocess.CalledProcessError as exc: + print(exc) + import traceback + + traceback.print_exc() + raise + return out + + def maketx(source, destination, *args): """Make `.tx` using `maketx` with some default settings. From 72b45229e943c419083e243ae27a540373edd6e2 Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Tue, 29 Mar 2022 19:23:25 +0300 Subject: [PATCH 02/88] fix style warnings --- openpype/hosts/maya/plugins/publish/extract_look.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 1516495278..6102b311a3 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -65,10 +65,10 @@ def rstex(source, *args): os.environ["REDSHIFT_COREDATAPATH"], "bin", "redshiftTextureProcessor" - ) + ) texture_processor_path = find_executable(redshift_bin_path) - + cmd = [ texture_processor_path, escape_space(source), @@ -83,7 +83,7 @@ def rstex(source, *args): kwargs = dict(args=cmd, stderr=subprocess.STDOUT) if sys.platform == "win32": - kwargs["creationflags"] = CREATE_NO_WINDOW + kwargs["creationflags"] = CREATE_NO_WINDOW try: out = subprocess.check_output(**kwargs) except subprocess.CalledProcessError as exc: From e65a1ea7d144abdcd0681641b45c50d11e903405 Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Tue, 29 Mar 2022 19:45:00 +0300 Subject: [PATCH 03/88] remove extra line --- openpype/hosts/maya/plugins/publish/extract_look.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 6102b311a3..cd647a6733 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -71,8 +71,7 @@ def rstex(source, *args): cmd = [ texture_processor_path, - escape_space(source), - + escape_space(source), ] cmd.extend(args) From 2406f78f4717451c2408a21b0f36bd66bd4ec95b Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Tue, 29 Mar 2022 19:45:49 +0300 Subject: [PATCH 04/88] fix trailing whitespace --- openpype/hosts/maya/plugins/publish/extract_look.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index cd647a6733..fb90d7538b 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -71,7 +71,7 @@ def rstex(source, *args): cmd = [ texture_processor_path, - escape_space(source), + escape_space(source), ] cmd.extend(args) From be840d3a8b8b786c3fdfb56ab8ef7577c04747f3 Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Mon, 4 Apr 2022 15:50:33 +0300 Subject: [PATCH 05/88] add exectuable path finder function --- openpype/lib/vendor_bin_utils.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/openpype/lib/vendor_bin_utils.py b/openpype/lib/vendor_bin_utils.py index 23e28ea304..c30a1ee709 100644 --- a/openpype/lib/vendor_bin_utils.py +++ b/openpype/lib/vendor_bin_utils.py @@ -120,6 +120,26 @@ def get_oiio_tools_path(tool="oiiotool"): return find_executable(os.path.join(oiio_dir, tool)) +def get_redshift_tool(tool_name): + """Path to redshift texture processor. + + On Windows it adds .exe extension if missing from tool argument. + + Args: + tool (string): Tool name. + + Returns: + str: Full path to redshift texture processor executable. + """ + redshift_tool_path = os.path.join( + os.environ["REDSHIFT_COREDATAPATH"], + "bin", + tool_name + ) + + return find_executable(redshift_tool_path) + + def get_ffmpeg_tool_path(tool="ffmpeg"): """Path to vendorized FFmpeg executable. From d4b8d47b18ed1605cdffa9a635586b40e29a6adf Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Mon, 4 Apr 2022 15:51:31 +0300 Subject: [PATCH 06/88] use redshift tool finder in extractor --- openpype/hosts/maya/plugins/publish/extract_look.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index fb90d7538b..6ce3a981f4 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -6,7 +6,7 @@ import json import tempfile import contextlib import subprocess -from openpype.lib.vendor_bin_utils import find_executable +from openpype.lib.vendor_bin_utils import get_redshift_tool from collections import OrderedDict from maya import cmds # noqa @@ -61,13 +61,7 @@ def rstex(source, *args): if "REDSHIFT_COREDATAPATH" not in os.environ: raise RuntimeError("Must have Redshift available.") - redshift_bin_path = os.path.join( - os.environ["REDSHIFT_COREDATAPATH"], - "bin", - "redshiftTextureProcessor" - ) - - texture_processor_path = find_executable(redshift_bin_path) + texture_processor_path = get_redshift_tool("TextureProcessor") cmd = [ texture_processor_path, From abc299e86eea14ec425c07e46c5af51551cf1a3e Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Tue, 5 Apr 2022 20:00:54 +0300 Subject: [PATCH 07/88] Add redshift texture processing option to schema --- .../schemas/projects_schema/schemas/schema_maya_create.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_create.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_create.json index 0544b4bab7..b0bd46d20f 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_create.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_create.json @@ -21,6 +21,11 @@ "key": "make_tx", "label": "Make tx files" }, + { + "type": "boolean", + "key": "rstex", + "label": "Make Redshift texture files" + }, { "type": "list", "key": "defaults", From 640415a0959bbc67f0e516b2363c4998b5d74508 Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Tue, 5 Apr 2022 20:18:42 +0300 Subject: [PATCH 08/88] adjust key name --- .../schemas/projects_schema/schemas/schema_maya_create.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_create.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_create.json index b0bd46d20f..bf3c9b3fe8 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_create.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_create.json @@ -23,7 +23,7 @@ }, { "type": "boolean", - "key": "rstex", + "key": "rs_tex", "label": "Make Redshift texture files" }, { From 0bcf353c82df569dc4bab517f3f2713f05f29b71 Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Tue, 5 Apr 2022 20:26:47 +0300 Subject: [PATCH 09/88] add redshift texture create option to look creator --- openpype/hosts/maya/plugins/create/create_look.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/maya/plugins/create/create_look.py b/openpype/hosts/maya/plugins/create/create_look.py index 56e2640919..c190a73ade 100644 --- a/openpype/hosts/maya/plugins/create/create_look.py +++ b/openpype/hosts/maya/plugins/create/create_look.py @@ -12,6 +12,7 @@ class CreateLook(plugin.Creator): family = "look" icon = "paint-brush" make_tx = True + rs_tex = False def __init__(self, *args, **kwargs): super(CreateLook, self).__init__(*args, **kwargs) @@ -20,6 +21,7 @@ class CreateLook(plugin.Creator): # Whether to automatically convert the textures to .tx upon publish. self.data["maketx"] = self.make_tx - + # Whether to automatically convert the textures to .rstex upon publish. + self.data["rstex"] = self.rs_tex # Enable users to force a copy. self.data["forceCopy"] = False From 7bbf381c6e8fbd6a12a9ecf58d891f15d0e5ad83 Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Tue, 5 Apr 2022 20:29:54 +0300 Subject: [PATCH 10/88] add rs_tex option to schema defaults --- openpype/settings/defaults/project_settings/maya.json | 1 + 1 file changed, 1 insertion(+) diff --git a/openpype/settings/defaults/project_settings/maya.json b/openpype/settings/defaults/project_settings/maya.json index 19d9a95595..7c09fa7891 100644 --- a/openpype/settings/defaults/project_settings/maya.json +++ b/openpype/settings/defaults/project_settings/maya.json @@ -34,6 +34,7 @@ "CreateLook": { "enabled": true, "make_tx": true, + "rs_tex": false, "defaults": [ "Main" ] From 078775e9b6bb5e814d1f284202419760853e631a Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Tue, 5 Apr 2022 21:16:02 +0300 Subject: [PATCH 11/88] add rstex variable to process_resources --- openpype/hosts/maya/plugins/publish/extract_look.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 6ce3a981f4..11f62ab80b 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -363,7 +363,8 @@ class ExtractLook(openpype.api.Extractor): # be the input file to multiple nodes. resources = instance.data["resources"] do_maketx = instance.data.get("maketx", False) - + # Option to convert textures to native redshift textures + do_rstex = instance.data.get("rstex", False) # Collect all unique files used in the resources files_metadata = {} for resource in resources: From 6ac5cd4a4a5efad533512b9deea45fe0bba4532a Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Fri, 8 Apr 2022 07:22:49 +0300 Subject: [PATCH 12/88] Add redshift texture processing flag --- openpype/hosts/maya/plugins/publish/extract_look.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 11f62ab80b..87e6625653 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -396,6 +396,7 @@ class ExtractLook(openpype.api.Extractor): source, mode, texture_hash = self._process_texture( filepath, + do_rstex, do_maketx, staging=staging_dir, linearize=linearize, @@ -487,7 +488,7 @@ class ExtractLook(openpype.api.Extractor): resources_dir, basename + ext ) - def _process_texture(self, filepath, do_maketx, staging, linearize, force): + def _process_texture(self, filepath, do_rstex, do_maketx, staging, linearize, force): """Process a single texture file on disk for publishing. This will: 1. Check whether it's already published, if so it will do hardlink From c43ec04003c7763d82d62944cc36c62512f11fb4 Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Fri, 8 Apr 2022 07:50:49 +0300 Subject: [PATCH 13/88] add redshift processor call to generate .rstexbin --- openpype/hosts/maya/plugins/publish/extract_look.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 87e6625653..6ce8ff6052 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -548,6 +548,10 @@ class ExtractLook(openpype.api.Extractor): return converted, COPY, texture_hash + self.log.info("Generating .rstexbin file for %s .." % filepath) + # Generates Redshift optimized textures using Redshift processor + if do_rstex: + rstex(filepath) return filepath, COPY, texture_hash From 92c1ac7342d94889abb79a71a9be8b8750d7fba7 Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Tue, 19 Apr 2022 21:33:11 +0300 Subject: [PATCH 14/88] refactor convertor function to abstract class and inherited class --- .../maya/plugins/publish/extract_look.py | 75 +++++++++++-------- 1 file changed, 43 insertions(+), 32 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index e0a5bff56c..7f23663721 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- """Maya look extractor.""" +from abc import ABC, abstractmethod import os import sys import json @@ -43,50 +44,60 @@ def find_paths_by_hash(texture_hash): key = "data.sourceHashes.{0}".format(texture_hash) return io.distinct(key, {"type": "version"}) +class TextureProcessor(metaclass=ABC.ABCMeta): + def __init__(self): + #TODO: Figure out design for predetermined objects to be initialized. + + @abstractmethod + def process(self, filepath): -def rstex(source, *args): - """Make `.rstexbin` using `redshiftTextureProcessor` - with some default settings. + - This function requires the `REDSHIFT_COREDATAPATH` - to be in `PATH`. +class MakeRSTexBin(TextureProcessor): + + def process(source, *args): + """Make `.rstexbin` using `redshiftTextureProcessor` + with some default settings. - Args: - source (str): Path to source file. - *args: Additional arguments for `redshiftTextureProcessor`. + This function requires the `REDSHIFT_COREDATAPATH` + to be in `PATH`. - Returns: - str: Output of `redshiftTextureProcessor` command. + Args: + source (str): Path to source file. + *args: Additional arguments for `redshiftTextureProcessor`. - """ - if "REDSHIFT_COREDATAPATH" not in os.environ: - raise RuntimeError("Must have Redshift available.") + Returns: + str: Output of `redshiftTextureProcessor` command. - texture_processor_path = get_redshift_tool("TextureProcessor") + """ + if "REDSHIFT_COREDATAPATH" not in os.environ: + raise RuntimeError("Must have Redshift available.") - cmd = [ - texture_processor_path, - escape_space(source), - ] + texture_processor_path = get_redshift_tool("TextureProcessor") - cmd.extend(args) + cmd = [ + texture_processor_path, + escape_space(source), + ] - cmd = " ".join(cmd) + cmd.extend(args) - CREATE_NO_WINDOW = 0x08000000 - kwargs = dict(args=cmd, stderr=subprocess.STDOUT) + cmd = " ".join(cmd) - if sys.platform == "win32": - kwargs["creationflags"] = CREATE_NO_WINDOW - try: - out = subprocess.check_output(**kwargs) - except subprocess.CalledProcessError as exc: - print(exc) - import traceback + CREATE_NO_WINDOW = 0x08000000 + kwargs = dict(args=cmd, stderr=subprocess.STDOUT) - traceback.print_exc() - raise - return out + if sys.platform == "win32": + kwargs["creationflags"] = CREATE_NO_WINDOW + try: + processed_filepath = subprocess.check_output(**kwargs) + except subprocess.CalledProcessError as exc: + print(exc) + import traceback + + traceback.print_exc() + raise + return processed_filepath def maketx(source, destination, *args): From 74f2c78415b091cdbc9bd447549d20dc0b796235 Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Tue, 19 Apr 2022 21:34:26 +0300 Subject: [PATCH 15/88] refactor tx conversion into class --- .../maya/plugins/publish/extract_look.py | 92 +++++++++---------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 7f23663721..54ab7b7877 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -99,65 +99,65 @@ class MakeRSTexBin(TextureProcessor): raise return processed_filepath +class MakeTX(TextureProcessor): + def process(source, destination, *args): + """Make `.tx` using `maketx` with some default settings. -def maketx(source, destination, *args): - """Make `.tx` using `maketx` with some default settings. + The settings are based on default as used in Arnold's + txManager in the scene. + This function requires the `maketx` executable to be + on the `PATH`. - The settings are based on default as used in Arnold's - txManager in the scene. - This function requires the `maketx` executable to be - on the `PATH`. + Args: + source (str): Path to source file. + destination (str): Writing destination path. + *args: Additional arguments for `maketx`. - Args: - source (str): Path to source file. - destination (str): Writing destination path. - *args: Additional arguments for `maketx`. + Returns: + str: Output of `maketx` command. - Returns: - str: Output of `maketx` command. + """ + from openpype.lib import get_oiio_tools_path - """ - from openpype.lib import get_oiio_tools_path + maketx_path = get_oiio_tools_path("maketx") - maketx_path = get_oiio_tools_path("maketx") + if not os.path.exists(maketx_path): + print( + "OIIO tool not found in {}".format(maketx_path)) + raise AssertionError("OIIO tool not found") - if not os.path.exists(maketx_path): - print( - "OIIO tool not found in {}".format(maketx_path)) - raise AssertionError("OIIO tool not found") + cmd = [ + maketx_path, + "-v", # verbose + "-u", # update mode + # unpremultiply before conversion (recommended when alpha present) + "--unpremult", + "--checknan", + # use oiio-optimized settings for tile-size, planarconfig, metadata + "--oiio", + "--filter lanczos3", + ] - cmd = [ - maketx_path, - "-v", # verbose - "-u", # update mode - # unpremultiply before conversion (recommended when alpha present) - "--unpremult", - "--checknan", - # use oiio-optimized settings for tile-size, planarconfig, metadata - "--oiio", - "--filter lanczos3", - ] + cmd.extend(args) + cmd.extend(["-o", escape_space(destination), escape_space(source)]) - cmd.extend(args) - cmd.extend(["-o", escape_space(destination), escape_space(source)]) + cmd = " ".join(cmd) - cmd = " ".join(cmd) + CREATE_NO_WINDOW = 0x08000000 # noqa + kwargs = dict(args=cmd, stderr=subprocess.STDOUT) - CREATE_NO_WINDOW = 0x08000000 # noqa - kwargs = dict(args=cmd, stderr=subprocess.STDOUT) + if sys.platform == "win32": + kwargs["creationflags"] = CREATE_NO_WINDOW + try: + processed_filepath = subprocess.check_output(**kwargs) + except subprocess.CalledProcessError as exc: + print(exc) + import traceback - if sys.platform == "win32": - kwargs["creationflags"] = CREATE_NO_WINDOW - try: - out = subprocess.check_output(**kwargs) - except subprocess.CalledProcessError as exc: - print(exc) - import traceback + traceback.print_exc() + raise - traceback.print_exc() - raise - - return out + return processed_filepath @contextlib.contextmanager From 7b1346e300c047654d6378c300916a4ac76acf56 Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Tue, 19 Apr 2022 21:41:48 +0300 Subject: [PATCH 16/88] add processor list and adjust logic for more options later --- openpype/hosts/maya/plugins/publish/extract_look.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 54ab7b7877..4b77a47729 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -374,9 +374,15 @@ class ExtractLook(openpype.api.Extractor): # might be included more than once amongst the resources as they could # be the input file to multiple nodes. resources = instance.data["resources"] + # Specify texture processing executables to activate + processors = [] do_maketx = instance.data.get("maketx", False) + if do_maketx: + processors.append(MakeTX) # Option to convert textures to native redshift textures do_rstex = instance.data.get("rstex", False) + if do_rstex: + processors.append(MakeRSTexBin) # Collect all unique files used in the resources files_metadata = {} for resource in resources: From 0100ea5bf8496915875ad0f7ca90ec1bd93e88de Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Tue, 7 Jun 2022 15:46:30 +0300 Subject: [PATCH 17/88] Move redshift tool finder function to extractor. --- .../maya/plugins/publish/extract_look.py | 29 +++++++++++++++---- openpype/lib/vendor_bin_utils.py | 20 ------------- 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 92d8f5ab17..357f7a4430 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -8,7 +8,7 @@ import tempfile import platform import contextlib import subprocess -from openpype.lib.vendor_bin_utils import get_redshift_tool +from openpype.lib.vendor_bin_utils import find_executable from collections import OrderedDict from maya import cmds # noqa @@ -46,15 +46,13 @@ def find_paths_by_hash(texture_hash): class TextureProcessor(metaclass=ABC.ABCMeta): def __init__(self): - #TODO: Figure out design for predetermined objects to be initialized. - + #TODO: Figure out design for predetermined objects to be initialized. + @abstractmethod def process(self, filepath): - class MakeRSTexBin(TextureProcessor): - def process(source, *args): """Make `.rstexbin` using `redshiftTextureProcessor` with some default settings. @@ -99,6 +97,7 @@ class MakeRSTexBin(TextureProcessor): raise return processed_filepath + class MakeTX(TextureProcessor): def process(source, destination, *args): """Make `.tx` using `maketx` with some default settings. @@ -603,3 +602,23 @@ class ExtractModelRenderSets(ExtractLook): self.scene_type = self.scene_type_prefix + self.scene_type return typ + + +def get_redshift_tool(tool_name): + """Path to redshift texture processor. + + On Windows it adds .exe extension if missing from tool argument. + + Args: + tool (string): Tool name. + + Returns: + str: Full path to redshift texture processor executable. + """ + redshift_tool_path = os.path.join( + os.environ["REDSHIFT_COREDATAPATH"], + "bin", + tool_name + ) + + return find_executable(redshift_tool_path) diff --git a/openpype/lib/vendor_bin_utils.py b/openpype/lib/vendor_bin_utils.py index cdc1290400..e5ab2872a0 100644 --- a/openpype/lib/vendor_bin_utils.py +++ b/openpype/lib/vendor_bin_utils.py @@ -123,26 +123,6 @@ def get_oiio_tools_path(tool="oiiotool"): return find_executable(os.path.join(oiio_dir, tool)) -def get_redshift_tool(tool_name): - """Path to redshift texture processor. - - On Windows it adds .exe extension if missing from tool argument. - - Args: - tool (string): Tool name. - - Returns: - str: Full path to redshift texture processor executable. - """ - redshift_tool_path = os.path.join( - os.environ["REDSHIFT_COREDATAPATH"], - "bin", - tool_name - ) - - return find_executable(redshift_tool_path) - - def get_ffmpeg_tool_path(tool="ffmpeg"): """Path to vendorized FFmpeg executable. From 2102e4f4fa86778542d96e9758dbb12967b6b762 Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Tue, 7 Jun 2022 15:46:50 +0300 Subject: [PATCH 18/88] Add variable for redshift os path. --- openpype/hosts/maya/plugins/publish/extract_look.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 357f7a4430..69d7eb78af 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -615,8 +615,10 @@ def get_redshift_tool(tool_name): Returns: str: Full path to redshift texture processor executable. """ + redshift_os_path = os.environ["REDSHIFT_COREDATAPATH"] + redshift_tool_path = os.path.join( - os.environ["REDSHIFT_COREDATAPATH"], + redshift_os_path, "bin", tool_name ) From 406ac826e018ffcac07aa9145f5c532b86ddfd27 Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Tue, 7 Jun 2022 16:09:53 +0300 Subject: [PATCH 19/88] Style fix --- openpype/hosts/maya/plugins/publish/extract_look.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 69d7eb78af..2e83af1437 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -46,7 +46,7 @@ def find_paths_by_hash(texture_hash): class TextureProcessor(metaclass=ABC.ABCMeta): def __init__(self): - #TODO: Figure out design for predetermined objects to be initialized. + # TODO: Figure out design for predetermined objects to be initialized. @abstractmethod def process(self, filepath): From 710ed3a889ee3d7043501d514d0cc3be3e8d571e Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Wed, 8 Jun 2022 10:37:46 +0300 Subject: [PATCH 20/88] Start moving processors logic. --- .../maya/plugins/publish/extract_look.py | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 2e83af1437..cce2643dba 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -44,6 +44,7 @@ def find_paths_by_hash(texture_hash): key = "data.sourceHashes.{0}".format(texture_hash) return legacy_io.distinct(key, {"type": "version"}) + class TextureProcessor(metaclass=ABC.ABCMeta): def __init__(self): # TODO: Figure out design for predetermined objects to be initialized. @@ -51,6 +52,8 @@ class TextureProcessor(metaclass=ABC.ABCMeta): @abstractmethod def process(self, filepath): + return processed_texture_path + class MakeRSTexBin(TextureProcessor): def process(source, *args): @@ -373,15 +376,6 @@ class ExtractLook(openpype.api.Extractor): # might be included more than once amongst the resources as they could # be the input file to multiple nodes. resources = instance.data["resources"] - # Specify texture processing executables to activate - processors = [] - do_maketx = instance.data.get("maketx", False) - if do_maketx: - processors.append(MakeTX) - # Option to convert textures to native redshift textures - do_rstex = instance.data.get("rstex", False) - if do_rstex: - processors.append(MakeRSTexBin) # Collect all unique files used in the resources files_metadata = {} for resource in resources: @@ -420,8 +414,7 @@ class ExtractLook(openpype.api.Extractor): source, mode, texture_hash = self._process_texture( filepath, - do_rstex, - do_maketx, + processors, staging=staging_dir, linearize=linearize, force=force_copy @@ -514,7 +507,7 @@ class ExtractLook(openpype.api.Extractor): resources_dir, basename + ext ) - def _process_texture(self, filepath, do_rstex, do_maketx, staging, linearize, force): + def _process_texture(self, filepath, processors, staging, linearize, force): """Process a single texture file on disk for publishing. This will: 1. Check whether it's already published, if so it will do hardlink @@ -546,7 +539,17 @@ class ExtractLook(openpype.api.Extractor): ("Paths not found on disk, " "skipping hardlink: %s") % (existing,) ) - + texture_files = self.collect_text + # Specify texture processing executables to activate + processors = [] + do_maketx = instance.data.get("maketx", False) + if do_maketx: + processors.append(MakeTX) + # Option to convert textures to native redshift textures + do_rstex = instance.data.get("rstex", False) + if do_rstex: + processors.append(MakeRSTexBin) + if do_maketx and ext != ".tx": # Produce .tx file in staging if source file is not .tx converted = os.path.join(staging, "resources", fname + ".tx") From 68caaa7528882654077a208b835a712f3e319850 Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Thu, 9 Jun 2022 10:56:26 +0300 Subject: [PATCH 21/88] move function --- .../maya/plugins/publish/extract_look.py | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index cce2643dba..d6c3588280 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -24,6 +24,28 @@ COPY = 1 HARDLINK = 2 +def get_redshift_tool(tool_name): + """Path to redshift texture processor. + + On Windows it adds .exe extension if missing from tool argument. + + Args: + tool (string): Tool name. + + Returns: + str: Full path to redshift texture processor executable. + """ + redshift_os_path = os.environ["REDSHIFT_COREDATAPATH"] + + redshift_tool_path = os.path.join( + redshift_os_path, + "bin", + tool_name + ) + + return find_executable(redshift_tool_path) + + def escape_space(path): """Ensure path is enclosed by quotes to allow paths with spaces""" return '"{}"'.format(path) if " " in path else path @@ -605,25 +627,3 @@ class ExtractModelRenderSets(ExtractLook): self.scene_type = self.scene_type_prefix + self.scene_type return typ - - -def get_redshift_tool(tool_name): - """Path to redshift texture processor. - - On Windows it adds .exe extension if missing from tool argument. - - Args: - tool (string): Tool name. - - Returns: - str: Full path to redshift texture processor executable. - """ - redshift_os_path = os.environ["REDSHIFT_COREDATAPATH"] - - redshift_tool_path = os.path.join( - redshift_os_path, - "bin", - tool_name - ) - - return find_executable(redshift_tool_path) From 29b69bcbb805702080fe54e52505fe09a3741f99 Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Thu, 9 Jun 2022 20:47:26 +0300 Subject: [PATCH 22/88] Class cleanup --- openpype/hosts/maya/plugins/publish/extract_look.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index d7b179daf2..be31deeb6e 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -69,12 +69,12 @@ def find_paths_by_hash(texture_hash): class TextureProcessor(metaclass=ABC.ABCMeta): def __init__(self): - # TODO: Figure out design for predetermined objects to be initialized. + pass @abstractmethod def process(self, filepath): - return processed_texture_path + pass class MakeRSTexBin(TextureProcessor): @@ -544,8 +544,7 @@ class ExtractLook(openpype.api.Extractor): fname, ext = os.path.splitext(os.path.basename(filepath)) args = [] - if do_maketx: - args.append("maketx") + texture_hash = openpype.api.source_hash(filepath, *args) # If source has been published before with the same settings, @@ -571,7 +570,7 @@ class ExtractLook(openpype.api.Extractor): do_rstex = instance.data.get("rstex", False) if do_rstex: processors.append(MakeRSTexBin) - + if do_maketx and ext != ".tx": # Produce .tx file in staging if source file is not .tx converted = os.path.join(staging, "resources", fname + ".tx") From e78314ca92283b38fd05d8995aeb9c06b460277e Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Thu, 9 Jun 2022 20:49:07 +0300 Subject: [PATCH 23/88] Remove unused maketx code. --- .../maya/plugins/publish/extract_look.py | 27 ------------------- 1 file changed, 27 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index be31deeb6e..3e1f91f5b7 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -544,7 +544,6 @@ class ExtractLook(openpype.api.Extractor): fname, ext = os.path.splitext(os.path.basename(filepath)) args = [] - texture_hash = openpype.api.source_hash(filepath, *args) # If source has been published before with the same settings, @@ -571,32 +570,6 @@ class ExtractLook(openpype.api.Extractor): if do_rstex: processors.append(MakeRSTexBin) - if do_maketx and ext != ".tx": - # Produce .tx file in staging if source file is not .tx - converted = os.path.join(staging, "resources", fname + ".tx") - - if linearize: - self.log.info("tx: converting sRGB -> linear") - colorconvert = "--colorconvert sRGB linear" - else: - colorconvert = "" - - # Ensure folder exists - if not os.path.exists(os.path.dirname(converted)): - os.makedirs(os.path.dirname(converted)) - - self.log.info("Generating .tx file for %s .." % filepath) - maketx( - filepath, - converted, - # Include `source-hash` as string metadata - "-sattrib", - "sourceHash", - escape_space(texture_hash), - colorconvert, - ) - - return converted, COPY, texture_hash self.log.info("Generating .rstexbin file for %s .." % filepath) # Generates Redshift optimized textures using Redshift processor From 00d877e2dfca6b1e89a4b4d289b2621a6e8b2037 Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Thu, 9 Jun 2022 20:50:51 +0300 Subject: [PATCH 24/88] Move processors list --- .../maya/plugins/publish/extract_look.py | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 3e1f91f5b7..88c93a8e3b 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -433,7 +433,15 @@ class ExtractLook(openpype.api.Extractor): # if do_maketx: # color_space = "Raw" - + # Specify texture processing executables to activate + processors = [] + do_maketx = instance.data.get("maketx", False) + if do_maketx: + processors.append(MakeTX) + # Option to convert textures to native redshift textures + do_rstex = instance.data.get("rstex", False) + if do_rstex: + processors.append(MakeRSTexBin) source, mode, texture_hash = self._process_texture( filepath, processors, @@ -559,16 +567,6 @@ class ExtractLook(openpype.api.Extractor): ("Paths not found on disk, " "skipping hardlink: %s") % (existing,) ) - texture_files = self.collect_text - # Specify texture processing executables to activate - processors = [] - do_maketx = instance.data.get("maketx", False) - if do_maketx: - processors.append(MakeTX) - # Option to convert textures to native redshift textures - do_rstex = instance.data.get("rstex", False) - if do_rstex: - processors.append(MakeRSTexBin) self.log.info("Generating .rstexbin file for %s .." % filepath) From 2933e409c769f13afd0e1df778fdacd06cf7b848 Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Thu, 9 Jun 2022 20:59:19 +0300 Subject: [PATCH 25/88] Handle texture processing through processors separately --- openpype/hosts/maya/plugins/publish/extract_look.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 88c93a8e3b..73d661168a 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -442,6 +442,7 @@ class ExtractLook(openpype.api.Extractor): do_rstex = instance.data.get("rstex", False) if do_rstex: processors.append(MakeRSTexBin) + source, mode, texture_hash = self._process_texture( filepath, processors, @@ -567,12 +568,9 @@ class ExtractLook(openpype.api.Extractor): ("Paths not found on disk, " "skipping hardlink: %s") % (existing,) ) - - - self.log.info("Generating .rstexbin file for %s .." % filepath) - # Generates Redshift optimized textures using Redshift processor - if do_rstex: - rstex(filepath) + for processor in processors: + processor().process(filepath) + self.log.info("Generating .rstexbin file for %s .." % filepath) return filepath, COPY, texture_hash From b054175d6e834dabd7b3d8719eed901ab139062f Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Thu, 9 Jun 2022 21:06:02 +0300 Subject: [PATCH 26/88] Reorganize functionality for do_maketx to linearize properly. --- .../maya/plugins/publish/extract_look.py | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 73d661168a..e90f9759f9 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -426,23 +426,20 @@ class ExtractLook(openpype.api.Extractor): for filepath in files_metadata: linearize = False + + # Specify texture processing executables to activate + processors = [] + do_maketx = instance.data.get("maketx", False) + do_rstex = instance.data.get("rstex", False) + if do_maketx: + processors.append(MakeTX) + # Option to convert textures to native redshift textures + if do_rstex: + processors.append(MakeRSTexBin) if do_maketx and files_metadata[filepath]["color_space"].lower() == "srgb": # noqa: E501 linearize = True # set its file node to 'raw' as tx will be linearized files_metadata[filepath]["color_space"] = "Raw" - - # if do_maketx: - # color_space = "Raw" - # Specify texture processing executables to activate - processors = [] - do_maketx = instance.data.get("maketx", False) - if do_maketx: - processors.append(MakeTX) - # Option to convert textures to native redshift textures - do_rstex = instance.data.get("rstex", False) - if do_rstex: - processors.append(MakeRSTexBin) - source, mode, texture_hash = self._process_texture( filepath, processors, From fd3125deda242f2676f1262fffb4e93212ffa300 Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Thu, 9 Jun 2022 21:07:26 +0300 Subject: [PATCH 27/88] Style fixes --- openpype/hosts/maya/plugins/publish/extract_look.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index e90f9759f9..018e45a01f 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -436,6 +436,7 @@ class ExtractLook(openpype.api.Extractor): # Option to convert textures to native redshift textures if do_rstex: processors.append(MakeRSTexBin) + if do_maketx and files_metadata[filepath]["color_space"].lower() == "srgb": # noqa: E501 linearize = True # set its file node to 'raw' as tx will be linearized From 41e7ac78aa340d4af45c48b036fb3ccf39c56f79 Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Thu, 9 Jun 2022 22:11:12 +0300 Subject: [PATCH 28/88] adjust comment --- openpype/hosts/maya/plugins/publish/extract_look.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 018e45a01f..922e347561 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -568,7 +568,7 @@ class ExtractLook(openpype.api.Extractor): ) for processor in processors: processor().process(filepath) - self.log.info("Generating .rstexbin file for %s .." % filepath) + self.log.info("Generating texture file for %s .." % filepath) return filepath, COPY, texture_hash From 35be81615ee986b0b71482a8f13097fa469ab477 Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Fri, 10 Jun 2022 10:51:19 +0300 Subject: [PATCH 29/88] Fix returned filepath --- openpype/hosts/maya/plugins/publish/extract_look.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 922e347561..7693e91765 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -567,9 +567,9 @@ class ExtractLook(openpype.api.Extractor): "skipping hardlink: %s") % (existing,) ) for processor in processors: - processor().process(filepath) + processed_path = processor().process(filepath) self.log.info("Generating texture file for %s .." % filepath) - return filepath, COPY, texture_hash + return processed_path, COPY, texture_hash class ExtractModelRenderSets(ExtractLook): From cfb90934289a742572d93323d48df6ae061acdb7 Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Fri, 10 Jun 2022 20:32:58 +0300 Subject: [PATCH 30/88] Append processors check, append path return. --- openpype/hosts/maya/plugins/publish/extract_look.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 7693e91765..c72aede0d4 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -566,9 +566,13 @@ class ExtractLook(openpype.api.Extractor): ("Paths not found on disk, " "skipping hardlink: %s") % (existing,) ) - for processor in processors: - processed_path = processor().process(filepath) - self.log.info("Generating texture file for %s .." % filepath) + + if bool(processors): + for processor in processors: + processed_path = processor().process(filepath) + self.log.info("Generating texture file for %s .." % filepath) + return processed_path + return processed_path, COPY, texture_hash From eb9994484e94f9e595d95fac302da49cef986cc4 Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Fri, 10 Jun 2022 20:35:53 +0300 Subject: [PATCH 31/88] Style fix --- openpype/hosts/maya/plugins/publish/extract_look.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index c72aede0d4..6d8b6f1d8e 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -536,7 +536,7 @@ class ExtractLook(openpype.api.Extractor): resources_dir, basename + ext ) - def _process_texture(self, filepath, processors, staging, linearize, force): + def _process_texture(self, filepath, processors, staging, linearize, force): # noqa """Process a single texture file on disk for publishing. This will: 1. Check whether it's already published, if so it will do hardlink From e5fdd9e9302fe82620b5fb0c94c4ce1188c4a731 Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Tue, 26 Jul 2022 20:45:54 +0300 Subject: [PATCH 32/88] Syntax fix. --- openpype/hosts/maya/plugins/publish/extract_look.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 6d8b6f1d8e..3fe8139dd6 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """Maya look extractor.""" -from abc import ABC, abstractmethod +import abc import os import sys import json @@ -67,11 +67,11 @@ def find_paths_by_hash(texture_hash): return legacy_io.distinct(key, {"type": "version"}) -class TextureProcessor(metaclass=ABC.ABCMeta): +class TextureProcessor(abc.ABCMeta): def __init__(self): pass - @abstractmethod + @abc.abstractmethod def process(self, filepath): pass From ab14895753c72177ebdfc7ff4f6e8b0bb1eb68ec Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Tue, 26 Jul 2022 23:27:11 +0300 Subject: [PATCH 33/88] Change metaclass inheritance formatting to 2.7 --- openpype/hosts/maya/plugins/publish/extract_look.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 3fe8139dd6..be6d863878 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """Maya look extractor.""" -import abc +from abc import ABCMeta, abstractmethod import os import sys import json @@ -67,11 +67,13 @@ def find_paths_by_hash(texture_hash): return legacy_io.distinct(key, {"type": "version"}) -class TextureProcessor(abc.ABCMeta): +class TextureProcessor(object): + __metaclass__ = ABCMeta + def __init__(self): pass - @abc.abstractmethod + @abstractmethod def process(self, filepath): pass From c471bbe71e20f09df30c1ea734a958f3a308e3f6 Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Wed, 27 Jul 2022 02:26:18 +0300 Subject: [PATCH 34/88] Fix inheritance with `six`, adjust processing code --- .../maya/plugins/publish/extract_look.py | 33 ++++++++++++++----- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index be6d863878..19e0bd9568 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- """Maya look extractor.""" from abc import ABCMeta, abstractmethod +import six import os import sys import json @@ -67,9 +68,9 @@ def find_paths_by_hash(texture_hash): return legacy_io.distinct(key, {"type": "version"}) -class TextureProcessor(object): - __metaclass__ = ABCMeta - +@six.add_metaclass(ABCMeta) +class TextureProcessor: + @abstractmethod def __init__(self): pass @@ -80,7 +81,10 @@ class TextureProcessor(object): class MakeRSTexBin(TextureProcessor): - def process(source, *args): + def __init__(self): + super(TextureProcessor, self).__init__() + + def process(self, source, *args): """Make `.rstexbin` using `redshiftTextureProcessor` with some default settings. @@ -126,7 +130,10 @@ class MakeRSTexBin(TextureProcessor): class MakeTX(TextureProcessor): - def process(source, destination, *args): + def __init__(self): + super(TextureProcessor, self).__init__() + + def process(self, source, destination, *args): """Make `.tx` using `maketx` with some default settings. The settings are based on default as used in Arnold's @@ -558,6 +565,10 @@ class ExtractLook(openpype.api.Extractor): # If source has been published before with the same settings, # then don't reprocess but hardlink from the original existing = find_paths_by_hash(texture_hash) + # if processors["do_maketx"]: + # Produce .tx file in staging if source file is not .tx + + if existing and not force: self.log.info("Found hash in database, preparing hardlink..") source = next((p for p in existing if os.path.exists(p)), None) @@ -571,9 +582,15 @@ class ExtractLook(openpype.api.Extractor): if bool(processors): for processor in processors: - processed_path = processor().process(filepath) - self.log.info("Generating texture file for %s .." % filepath) - return processed_path + if processor == MakeTX: + converted = os.path.join(staging, "resources", fname + ".tx") + processed_path = processor().process(converted, filepath) + self.log.info("Generating texture file for %s .." % filepath) # noqa + return processed_path + elif processor == MakeRSTexBin: + processed_path = processor().process(filepath) + self.log.info("Generating texture file for %s .." % filepath) # noqa + return processed_path return processed_path, COPY, texture_hash From 5f4d06baecce44fd735e1a26770f0a617c0284fb Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Wed, 27 Jul 2022 02:48:43 +0300 Subject: [PATCH 35/88] Remove unnecessary comment, style fixes. --- openpype/hosts/maya/plugins/publish/extract_look.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 19e0bd9568..bb4335a3d5 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -172,7 +172,7 @@ class MakeTX(TextureProcessor): ] cmd.extend(args) - cmd.extend(["-o", escape_space(destination), escape_space(source)]) + cmd.extend([escape_space(source), "-o", escape_space(destination)]) cmd = " ".join(cmd) @@ -188,6 +188,8 @@ class MakeTX(TextureProcessor): import traceback traceback.print_exc() + print(exc.returncode) + print(exc.output) raise return processed_filepath @@ -565,9 +567,6 @@ class ExtractLook(openpype.api.Extractor): # If source has been published before with the same settings, # then don't reprocess but hardlink from the original existing = find_paths_by_hash(texture_hash) - # if processors["do_maketx"]: - # Produce .tx file in staging if source file is not .tx - if existing and not force: self.log.info("Found hash in database, preparing hardlink..") @@ -583,8 +582,8 @@ class ExtractLook(openpype.api.Extractor): if bool(processors): for processor in processors: if processor == MakeTX: - converted = os.path.join(staging, "resources", fname + ".tx") - processed_path = processor().process(converted, filepath) + converted = os.path.join(staging, "resources", fname + ".tx") # noqa + processed_path = processor().process(filepath, converted) self.log.info("Generating texture file for %s .." % filepath) # noqa return processed_path elif processor == MakeRSTexBin: From 9b0cc4dfac23100fa3979b53418734c39399c5ca Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Mon, 1 Aug 2022 03:28:26 +0300 Subject: [PATCH 36/88] Continue refactor --- .../maya/plugins/publish/extract_look.py | 52 +++++++++++-------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 136b64a547..8d30268619 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -615,12 +615,29 @@ class ExtractLook(openpype.api.Extractor): ("Paths not found on disk, " "skipping hardlink: %s") % (existing,) ) + config_path = get_ocio_config_path("nuke-default") + color_config = "--colorconfig {0}".format(config_path) + # Ensure folder exists + if linearize: + self.log.info("tx: converting sRGB -> linear") + colorconvert = "--colorconvert sRGB linear" + else: + colorconvert = "" + + converted = os.path.join(staging, "resources", fname + ".tx") + if not os.path.exists(os.path.dirname(converted)): + os.makedirs(os.path.dirname(converted)) if bool(processors): for processor in processors: if processor == MakeTX: - converted = os.path.join(staging, "resources", fname + ".tx") # noqa - processed_path = processor().process(filepath, converted) + processed_path = processor().process(filepath, + converted, + "--sattrib", + "sourceHash %", + escape_space(texture_hash), # noqa + colorconvert, + color_config) self.log.info("Generating texture file for %s .." % filepath) # noqa return processed_path elif processor == MakeRSTexBin: @@ -628,27 +645,18 @@ class ExtractLook(openpype.api.Extractor): self.log.info("Generating texture file for %s .." % filepath) # noqa return processed_path - return processed_path, COPY, texture_hash - config_path = get_ocio_config_path("nuke-default") - color_config = "--colorconfig {0}".format(config_path) - # Ensure folder exists - if not os.path.exists(os.path.dirname(converted)): - os.makedirs(os.path.dirname(converted)) - - self.log.info("Generating .tx file for %s .." % filepath) - maketx( - filepath, - converted, - # Include `source-hash` as string metadata - "--sattrib", - "sourceHash", - escape_space(texture_hash), - colorconvert, - color_config - ) - - return converted, COPY, texture_hash + # self.log.info("Generating .tx file for %s .." % filepath) + # maketx( + # filepath, + # converted, + # # Include `source-hash` as string metadata + # "--sattrib", + # "sourceHash", + # escape_space(texture_hash), + # colorconvert, + # color_config + # ) return filepath, COPY, texture_hash From c35f1cfe3c295d7915e4a2b856f48ecae85cab38 Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Mon, 1 Aug 2022 04:09:09 +0300 Subject: [PATCH 37/88] Remove leftover code --- .../maya/plugins/publish/extract_look.py | 32 +------------------ 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 8d30268619..ecbb070916 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -114,27 +114,10 @@ class MakeRSTexBin(TextureProcessor): This function requires the `REDSHIFT_COREDATAPATH` to be in `PATH`. - cmd = [ - maketx_path, - "-v", # verbose - "-u", # update mode - # unpremultiply before conversion (recommended when alpha present) - "--unpremult", - "--checknan", - # use oiio-optimized settings for tile-size, planarconfig, metadata - "--oiio", - "--filter lanczos3", - escape_space(source) - ] Args: source (str): Path to source file. *args: Additional arguments for `redshiftTextureProcessor`. - cmd.extend(args) - cmd.extend(["-o", escape_space(destination)]) - Returns: - str: Output of `redshiftTextureProcessor` command. - """ if "REDSHIFT_COREDATAPATH" not in os.environ: raise RuntimeError("Must have Redshift available.") @@ -634,7 +617,7 @@ class ExtractLook(openpype.api.Extractor): processed_path = processor().process(filepath, converted, "--sattrib", - "sourceHash %", + "sourceHash", escape_space(texture_hash), # noqa colorconvert, color_config) @@ -645,19 +628,6 @@ class ExtractLook(openpype.api.Extractor): self.log.info("Generating texture file for %s .." % filepath) # noqa return processed_path - - # self.log.info("Generating .tx file for %s .." % filepath) - # maketx( - # filepath, - # converted, - # # Include `source-hash` as string metadata - # "--sattrib", - # "sourceHash", - # escape_space(texture_hash), - # colorconvert, - # color_config - # ) - return filepath, COPY, texture_hash From 099dfba8fa19dca4bc1cc9a30632f659854c9300 Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Mon, 1 Aug 2022 05:06:58 +0300 Subject: [PATCH 38/88] Fix return bug --- openpype/hosts/maya/plugins/publish/extract_look.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index ecbb070916..53b6dcbf35 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -622,11 +622,11 @@ class ExtractLook(openpype.api.Extractor): colorconvert, color_config) self.log.info("Generating texture file for %s .." % filepath) # noqa - return processed_path + return processed_path, COPY, texture_hash elif processor == MakeRSTexBin: processed_path = processor().process(filepath) self.log.info("Generating texture file for %s .." % filepath) # noqa - return processed_path + return processed_path, COPY, texture_hash return filepath, COPY, texture_hash From 8995dcdff4a9a6c5c951958fb71b99ee93b44029 Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Mon, 1 Aug 2022 12:26:44 +0300 Subject: [PATCH 39/88] Check for return value, adjust argument --- .../hosts/maya/plugins/publish/extract_look.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 53b6dcbf35..48af644326 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- """Maya look extractor.""" from abc import ABCMeta, abstractmethod + import six import os import sys @@ -189,10 +190,11 @@ class MakeTX(TextureProcessor): # use oiio-optimized settings for tile-size, planarconfig, metadata "--oiio", "--filter lanczos3", + escape_space(source) ] cmd.extend(args) - cmd.extend([escape_space(source), "-o", escape_space(destination)]) + cmd.extend(["-o", escape_space(destination)]) cmd = " ".join(cmd) @@ -620,13 +622,21 @@ class ExtractLook(openpype.api.Extractor): "sourceHash", escape_space(texture_hash), # noqa colorconvert, - color_config) + color_config, + ) self.log.info("Generating texture file for %s .." % filepath) # noqa - return processed_path, COPY, texture_hash + self.log.info(converted) + if processed_path: + return processed_path + else: + self.log.info("maketx has returned nothing") elif processor == MakeRSTexBin: processed_path = processor().process(filepath) self.log.info("Generating texture file for %s .." % filepath) # noqa - return processed_path, COPY, texture_hash + if processed_path: + return processed_path + else: + self.log.info("redshift texture converter has returned nothing") # noqa return filepath, COPY, texture_hash From 3cd7fd503c0cb94ef3f4da86a3c465ff6bc26cb1 Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Mon, 15 Aug 2022 04:23:24 +0300 Subject: [PATCH 40/88] Fix assignment bug, remove unnecessary class sugar --- openpype/hosts/maya/plugins/publish/extract_look.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 48af644326..c092e2ac25 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -94,7 +94,7 @@ def find_paths_by_hash(texture_hash): @six.add_metaclass(ABCMeta) class TextureProcessor: - @abstractmethod + def __init__(self): pass @@ -106,7 +106,7 @@ class TextureProcessor: class MakeRSTexBin(TextureProcessor): def __init__(self): - super(TextureProcessor, self).__init__() + super(MakeRSTexBin, self).__init__() def process(self, source, *args): """Make `.rstexbin` using `redshiftTextureProcessor` @@ -152,7 +152,7 @@ class MakeRSTexBin(TextureProcessor): class MakeTX(TextureProcessor): def __init__(self): - super(TextureProcessor, self).__init__() + super(MakeTX, self).__init__() def process(self, source, destination, *args): """Make `.tx` using `maketx` with some default settings. @@ -627,18 +627,18 @@ class ExtractLook(openpype.api.Extractor): self.log.info("Generating texture file for %s .." % filepath) # noqa self.log.info(converted) if processed_path: - return processed_path + return processed_path, COPY, texture_hash else: self.log.info("maketx has returned nothing") elif processor == MakeRSTexBin: processed_path = processor().process(filepath) self.log.info("Generating texture file for %s .." % filepath) # noqa if processed_path: - return processed_path + return processed_path, COPY, texture_hash else: self.log.info("redshift texture converter has returned nothing") # noqa - return filepath, COPY, texture_hash + return processed_path, COPY, texture_hash class ExtractModelRenderSets(ExtractLook): From 9ec42cb4376e0e14eb990cfd22c6a9f1c38e0575 Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Tue, 23 Aug 2022 13:05:37 +0300 Subject: [PATCH 41/88] Fix bugs --- .../hosts/maya/plugins/publish/extract_look.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 52751eea81..19765d4396 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -125,7 +125,7 @@ class MakeRSTexBin(TextureProcessor): if "REDSHIFT_COREDATAPATH" not in os.environ: raise RuntimeError("Must have Redshift available.") - texture_processor_path = get_redshift_tool("TextureProcessor") + texture_processor_path = get_redshift_tool("redshiftTextureProcessor") cmd = [ texture_processor_path, @@ -142,14 +142,14 @@ class MakeRSTexBin(TextureProcessor): if sys.platform == "win32": kwargs["creationflags"] = CREATE_NO_WINDOW try: - processed_filepath = subprocess.check_output(**kwargs) + subprocess.check_output(**kwargs) except subprocess.CalledProcessError as exc: print(exc) import traceback traceback.print_exc() raise - return processed_filepath + return source class MakeTX(TextureProcessor): @@ -206,7 +206,7 @@ class MakeTX(TextureProcessor): if sys.platform == "win32": kwargs["creationflags"] = CREATE_NO_WINDOW try: - processed_filepath = subprocess.check_output(**kwargs) + subprocess.check_output(**kwargs) except subprocess.CalledProcessError as exc: print(exc) import traceback @@ -216,7 +216,7 @@ class MakeTX(TextureProcessor): print(exc.output) raise - return processed_filepath + return destination @contextlib.contextmanager @@ -629,7 +629,7 @@ class ExtractLook(openpype.api.Extractor): if bool(processors): for processor in processors: - if processor == MakeTX: + if processor is MakeTX: processed_path = processor().process(filepath, converted, "--sattrib", @@ -644,7 +644,7 @@ class ExtractLook(openpype.api.Extractor): return processed_path, COPY, texture_hash else: self.log.info("maketx has returned nothing") - elif processor == MakeRSTexBin: + elif processor is MakeRSTexBin: processed_path = processor().process(filepath) self.log.info("Generating texture file for %s .." % filepath) # noqa if processed_path: From cc62035e1be2e02d38c3e1972bd37f458f70eb83 Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Tue, 23 Aug 2022 13:22:59 +0300 Subject: [PATCH 42/88] Fix destination finding for copying resrouce. --- .../maya/plugins/publish/extract_look.py | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 19765d4396..7f79867cea 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -483,9 +483,15 @@ class ExtractLook(openpype.api.Extractor): linearize=linearize, force=force_copy ) - destination = self.resource_destination(instance, - source, - do_maketx) + for processor in processors: + if processor is MakeTX: + destination = self.resource_destination( + instance, source, MakeTX + ) + elif processor is MakeRSTexBin: + destination = self.resource_destination( + instance, source, MakeRSTexBin + ) # Force copy is specified. if force_copy: @@ -512,9 +518,15 @@ class ExtractLook(openpype.api.Extractor): if source not in destinations: # Cache destination as source resource might be included # multiple times - destinations[source] = self.resource_destination( - instance, source, do_maketx - ) + for processor in processors: + if processor is MakeTX: + destinations[source] = self.resource_destination( + instance, source, MakeTX + ) + elif processor is MakeRSTexBin: + destinations[source] = self.resource_destination( + instance, source, MakeRSTexBin + ) # Preserve color space values (force value after filepath change) # This will also trigger in the same order at end of context to @@ -555,7 +567,7 @@ class ExtractLook(openpype.api.Extractor): "attrRemap": remap, } - def resource_destination(self, instance, filepath, do_maketx): + def resource_destination(self, instance, filepath, processor): """Get resource destination path. This is utility function to change path if resource file name is @@ -564,7 +576,7 @@ class ExtractLook(openpype.api.Extractor): Args: instance: Current Instance. filepath (str): Resource path - do_maketx (bool): Flag if resource is processed by `maketx`. + processor: Texture processor converting resource. Returns: str: Path to resource file @@ -576,8 +588,10 @@ class ExtractLook(openpype.api.Extractor): basename, ext = os.path.splitext(os.path.basename(filepath)) # If `maketx` then the texture will always end with .tx - if do_maketx: + if processor == MakeTX: ext = ".tx" + elif processor == MakeRSTexBin: + ext = ".rstexbin" return os.path.join( resources_dir, basename + ext From ad8177cee3c7ee6241b995b781b9dc93fead19b1 Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Tue, 23 Aug 2022 16:10:44 +0300 Subject: [PATCH 43/88] Removed submodule vendor/configs/OpenColorIO-Configs --- vendor/configs/OpenColorIO-Configs | 1 - 1 file changed, 1 deletion(-) delete mode 160000 vendor/configs/OpenColorIO-Configs diff --git a/vendor/configs/OpenColorIO-Configs b/vendor/configs/OpenColorIO-Configs deleted file mode 160000 index 0bb079c08b..0000000000 --- a/vendor/configs/OpenColorIO-Configs +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 0bb079c08be410030669cbf5f19ff869b88af953 From 590538eb128dc8e7e8e6eee0b8d16ab593530e5e Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Tue, 4 Oct 2022 11:07:09 +0300 Subject: [PATCH 44/88] Fix import bug --- openpype/hosts/maya/plugins/publish/extract_look.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 7e640c375d..f3128306ee 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -11,13 +11,14 @@ import platform import contextlib import subprocess from openpype.lib.vendor_bin_utils import find_executable +from openpype.lib import source_hash from collections import OrderedDict from maya import cmds # noqa import pyblish.api -from openpype.lib import source_hash, run_subprocess + from openpype.pipeline import legacy_io, publish from openpype.hosts.maya.api import lib @@ -93,7 +94,6 @@ def find_paths_by_hash(texture_hash): key = "data.sourceHashes.{0}".format(texture_hash) return legacy_io.distinct(key, {"type": "version"}) - @six.add_metaclass(ABCMeta) class TextureProcessor: @@ -612,7 +612,7 @@ class ExtractLook(publish.Extractor): fname, ext = os.path.splitext(os.path.basename(filepath)) args = [] - texture_hash = openpype.api.source_hash(filepath, *args) + texture_hash = source_hash(filepath, *args) # If source has been published before with the same settings, # then don't reprocess but hardlink from the original From 035281fa4c939e6e56d356a97535cf837cc933a2 Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Tue, 4 Oct 2022 11:08:27 +0300 Subject: [PATCH 45/88] Style fix --- openpype/hosts/maya/plugins/publish/extract_look.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index f3128306ee..6b0fe36d8f 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -94,6 +94,7 @@ def find_paths_by_hash(texture_hash): key = "data.sourceHashes.{0}".format(texture_hash) return legacy_io.distinct(key, {"type": "version"}) + @six.add_metaclass(ABCMeta) class TextureProcessor: From 18435fa7065065d8446c3b0448f664f9ef4a8123 Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Tue, 4 Oct 2022 14:11:30 +0300 Subject: [PATCH 46/88] Add validation to check for texture --- .../plugins/publish/validate_look_contents.py | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/openpype/hosts/maya/plugins/publish/validate_look_contents.py b/openpype/hosts/maya/plugins/publish/validate_look_contents.py index 53501d11e5..837e8ea3a2 100644 --- a/openpype/hosts/maya/plugins/publish/validate_look_contents.py +++ b/openpype/hosts/maya/plugins/publish/validate_look_contents.py @@ -1,6 +1,7 @@ import pyblish.api import openpype.hosts.maya.api.action from openpype.pipeline.publish import ValidateContentsOrder +from maya import cmds # noqa class ValidateLookContents(pyblish.api.InstancePlugin): @@ -85,6 +86,7 @@ class ValidateLookContents(pyblish.api.InstancePlugin): invalid.add(instance.name) return list(invalid) + @classmethod def validate_looks(cls, instance): @@ -112,3 +114,23 @@ class ValidateLookContents(pyblish.api.InstancePlugin): invalid.append(node) return invalid + + @classmethod + def validate_renderer(cls, instance): + + renderer = cmds.getAttr( + 'defaultRenderGlobals.currentRenderer').lower() + do_maketx = instance.data.get("maketx", False) + do_rstex = instance.data.get("rstex", False) + processors = [] + + if do_maketx: + processors.append('arnold') + if do_rstex: + processors.append('redshift') + + for processor in processors: + if processor == renderer: + continue + else: + cls.log.error("Converted texture does not match current renderer.") # noqa From 3728ce0a586820bd0e7619dd7acc5cff82e0f918 Mon Sep 17 00:00:00 2001 From: Allan Ihsan Date: Tue, 4 Oct 2022 14:16:54 +0300 Subject: [PATCH 47/88] Style fix --- openpype/hosts/maya/plugins/publish/validate_look_contents.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/maya/plugins/publish/validate_look_contents.py b/openpype/hosts/maya/plugins/publish/validate_look_contents.py index 837e8ea3a2..5e242ed3d2 100644 --- a/openpype/hosts/maya/plugins/publish/validate_look_contents.py +++ b/openpype/hosts/maya/plugins/publish/validate_look_contents.py @@ -119,7 +119,7 @@ class ValidateLookContents(pyblish.api.InstancePlugin): def validate_renderer(cls, instance): renderer = cmds.getAttr( - 'defaultRenderGlobals.currentRenderer').lower() + 'defaultRenderGlobals.currentRenderer').lower() do_maketx = instance.data.get("maketx", False) do_rstex = instance.data.get("rstex", False) processors = [] From 2baabed6be7eb6977cb7fcb0d69b7c79e1b18327 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 24 Mar 2023 18:50:09 +0100 Subject: [PATCH 48/88] Work in progress extract look cleanup - Fix file hashing so it includes arguments to maketx - Fix maketx destination colorspace when OCIO is enabled - Use pre-collected colorspaces of the resources instead of trying to retrieve again - Fix colorspace attributes being reinterpreted by maya on export (fix remapping) - Fix support for checking config path of maya default OCIO config (due to using `lib.get_color_management_preferences` which remaps that path) --- .../maya/plugins/publish/extract_look.py | 413 ++++++++++-------- 1 file changed, 220 insertions(+), 193 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 447c9a615c..5c03aa5a5a 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -149,22 +149,6 @@ class ExtractLook(publish.Extractor): scene_type = "ma" look_data_type = "json" - @staticmethod - def get_renderer_name(): - """Get renderer name from Maya. - - Returns: - str: Renderer name. - - """ - renderer = cmds.getAttr( - "defaultRenderGlobals.currentRenderer" - ).lower() - # handle various renderman names - if renderer.startswith("renderman"): - renderer = "renderman" - return renderer - def get_maya_scene_type(self, instance): """Get Maya scene type from settings. @@ -209,11 +193,9 @@ class ExtractLook(publish.Extractor): maya_path = os.path.join(dir_path, maya_fname) json_path = os.path.join(dir_path, json_fname) - self.log.info("Performing extraction..") - # Remove all members of the sets so they are not included in the # exported file by accident - self.log.info("Extract sets (%s) ..." % _scene_type) + self.log.info("Processing sets..") lookdata = instance.data["lookData"] relationships = lookdata["relationships"] sets = list(relationships.keys()) @@ -221,6 +203,7 @@ class ExtractLook(publish.Extractor): self.log.info("No sets found") return + self.log.debug("Processing resources..") results = self.process_resources(instance, staging_dir=dir_path) transfers = results["fileTransfers"] hardlinks = results["fileHardlinks"] @@ -228,6 +211,7 @@ class ExtractLook(publish.Extractor): remap = results["attrRemap"] # Extract in correct render layer + self.log.info("Extracting look maya scene file: {}".format(maya_path)) layer = instance.data.get("renderlayer", "defaultRenderLayer") with lib.renderlayer(layer): # TODO: Ensure membership edits don't become renderlayer overrides @@ -299,40 +283,39 @@ class ExtractLook(publish.Extractor): # Source hash for the textures instance.data["sourceHashes"] = hashes - """ - self.log.info("Returning colorspaces to their original values ...") - for attr, value in remap.items(): - self.log.info(" - {}: {}".format(attr, value)) - cmds.setAttr(attr, value, type="string") - """ self.log.info("Extracted instance '%s' to: %s" % (instance.name, maya_path)) - def process_resources(self, instance, staging_dir): + def _set_resource_result_colorspace(self, resource, colorspace): + """Update resource resulting colorspace after texture processing""" + if "result_colorspace" in resource: + if resource["result_colorspace"] == colorspace: + return + + self.log.warning( + "Resource already has a resulting colorspace but is now " + "being overridden to a new one: {} -> {}".format( + resource["result_colorspace"], colorspace + ) + ) + resource["result_colorspace"] = colorspace + + def process_resources(self, instance, staging_dir): + """Process all resources in the instance. + + It is assumed that all resources are nodes using file textures. + + Extract the textures to transfer, possibly convert with maketx and + remap the node paths to the destination path. Note that a source + might be included more than once amongst the resources as they could + be the input file to multiple nodes. + + """ - # Extract the textures to transfer, possibly convert with maketx and - # remap the node paths to the destination path. Note that a source - # might be included more than once amongst the resources as they could - # be the input file to multiple nodes. resources = instance.data["resources"] do_maketx = instance.data.get("maketx", False) + color_management = lib.get_color_management_preferences() - # Collect all unique files used in the resources - files_metadata = {} - for resource in resources: - # Preserve color space values (force value after filepath change) - # This will also trigger in the same order at end of context to - # ensure after context it's still the original value. - color_space = resource.get("color_space") - - for f in resource["files"]: - files_metadata[os.path.normpath(f)] = { - "color_space": color_space} - - # Process the resource files - transfers = [] - hardlinks = [] - hashes = {} # Temporary fix to NOT create hardlinks on windows machines if platform.system().lower() == "windows": self.log.info( @@ -342,58 +325,83 @@ class ExtractLook(publish.Extractor): else: force_copy = instance.data.get("forceCopy", False) - for filepath in files_metadata: - - linearize = False - # if OCIO color management enabled - # it won't take the condition of the files_metadata - - ocio_maya = cmds.colorManagementPrefs(q=True, - cmConfigFileEnabled=True, - cmEnabled=True) - - if do_maketx and not ocio_maya: - if files_metadata[filepath]["color_space"].lower() == "srgb": # noqa: E501 - linearize = True - # set its file node to 'raw' as tx will be linearized - files_metadata[filepath]["color_space"] = "Raw" - - # if do_maketx: - # color_space = "Raw" - - source, mode, texture_hash = self._process_texture( - filepath, - resource, - do_maketx, - staging=staging_dir, - linearize=linearize, - force=force_copy - ) - destination = self.resource_destination(instance, - source, - do_maketx) - - # Force copy is specified. - if force_copy: - mode = COPY - - if mode == COPY: - transfers.append((source, destination)) - self.log.info('file will be copied {} -> {}'.format( - source, destination)) - elif mode == HARDLINK: - hardlinks.append((source, destination)) - self.log.info('file will be hardlinked {} -> {}'.format( - source, destination)) - - # Store the hashes from hash to destination to include in the - # database - hashes[texture_hash] = destination - - # Remap the resources to the destination path (change node attributes) + # Process all resource's individual files + processed_files = {} + transfers = [] + hardlinks = [] + hashes = {} destinations = {} - remap = OrderedDict() # needs to be ordered, see color space values + remap = OrderedDict() for resource in resources: + colorspace = resource["color_space"] + + for filepath in resource["files"]: + filepath = os.path.normpath(filepath) + + if filepath in processed_files: + # The file was already processed, likely due to usage by + # another resource in the scene. We confirm here it + # didn't do color spaces different than the current + # resource. + processed_file = processed_files[filepath] + processed_colorspace = processed_file["color_space"] + processed_result_colorspace = processed_file["result_color_space"] + self.log.debug( + "File was already processed. Likely used by another " + "resource too: {}".format(filepath) + ) + + if colorspace != processed_file["color_space"]: + self.log.warning( + "File was already processed but using another" + "colorspace: {} <-> {}" + "".format(colorspace, processed_colorspace)) + + self._set_resource_result_colorspace( + resource, colorspace=processed_result_colorspace + ) + continue + + texture_result = self._process_texture( + filepath, + do_maketx=do_maketx, + staging_dir=staging_dir, + force_copy=force_copy, + color_management=color_management, + colorspace=colorspace + ) + source, mode, texture_hash, result_colorspace = texture_result + destination = self.resource_destination(instance, + source, + do_maketx) + + # Set the resulting color space on the resource + self._set_resource_result_colorspace( + resource, colorspace=result_colorspace + ) + + processed_files[filepath] = { + "color_space": colorspace, + "result_color_space": result_colorspace, + } + + # Force copy is specified. + if force_copy: + mode = COPY + + if mode == COPY: + transfers.append((source, destination)) + self.log.info('file will be copied {} -> {}'.format( + source, destination)) + elif mode == HARDLINK: + hardlinks.append((source, destination)) + self.log.info('file will be hardlinked {} -> {}'.format( + source, destination)) + + # Store the hashes from hash to destination to include in the + # database + hashes[texture_hash] = destination + source = os.path.normpath(resource["source"]) if source not in destinations: # Cache destination as source resource might be included @@ -402,35 +410,23 @@ class ExtractLook(publish.Extractor): instance, source, do_maketx ) + # Set up remapping attributes for the node during the publish + # The order of these can be important if one attribute directly + # affects another, e.g. we set colorspace after filepath because + # maya sometimes tries to guess the colorspace when changing + # filepaths (which is avoidable, but we don't want to have those + # attributes changed in the resulting publish) + # Remap filepath to publish destination + filepath_attr = resource["attribute"] + remap[filepath_attr] = destinations[source] + # Preserve color space values (force value after filepath change) # This will also trigger in the same order at end of context to # ensure after context it's still the original value. - color_space_attr = resource["node"] + ".colorSpace" - try: - color_space = cmds.getAttr(color_space_attr) - except ValueError: - # node doesn't have color space attribute - color_space = "Raw" - else: - # get the resolved files - metadata = files_metadata.get(source) - # if the files are unresolved from `source` - # assume color space from the first file of - # the resource - if not metadata: - first_file = next(iter(resource.get( - "files", [])), None) - if not first_file: - continue - first_filepath = os.path.normpath(first_file) - metadata = files_metadata[first_filepath] - if metadata["color_space"] == "Raw": - # set color space to raw if we linearized it - color_space = "Raw" - # Remap file node filename to destination - remap[color_space_attr] = color_space - attr = resource["attribute"] - remap[attr] = destinations[source] + node = resource["node"] + if cmds.attributeQuery("colorSpace", node=node, exists=True): + color_space_attr = "{}.colorSpace".format(node) + remap[color_space_attr] = resource["result_color_space"] self.log.info("Finished remapping destinations ...") @@ -469,91 +465,115 @@ class ExtractLook(publish.Extractor): resources_dir, basename + ext ) - def _process_texture(self, filepath, resource, - do_maketx, staging, linearize, force): - """Process a single texture file on disk for publishing. - This will: - 1. Check whether it's already published, if so it will do hardlink - 2. If not published and maketx is enabled, generate a new .tx file. - 3. Compute the destination path for the source file. - Args: - filepath (str): The source file path to process. - do_maketx (bool): Whether to produce a .tx file - Returns: - """ - - fname, ext = os.path.splitext(os.path.basename(filepath)) - - args = [] - if do_maketx: - args.append("maketx") - texture_hash = source_hash(filepath, *args) + def _get_existing_hashed_texture(self, texture_hash): + """Return the first found filepath from a texture hash""" # If source has been published before with the same settings, # then don't reprocess but hardlink from the original existing = find_paths_by_hash(texture_hash) - if existing and not force: + if existing: self.log.info("Found hash in database, preparing hardlink..") source = next((p for p in existing if os.path.exists(p)), None) if source: return source, HARDLINK, texture_hash else: self.log.warning( - ("Paths not found on disk, " - "skipping hardlink: %s") % (existing,) + "Paths not found on disk, " + "skipping hardlink: {}".format(existing) ) + def _process_texture(self, + filepath, + do_maketx, + staging_dir, + force_copy, + color_management, + colorspace): + """Process a single texture file on disk for publishing. + This will: + 1. Check whether it's already published, if so it will do hardlink + 2. If not published and maketx is enabled, generate a new .tx file. + 3. Compute the destination path for the source file. + + Args: + filepath (str): The source file path to process. + do_maketx (bool): Whether to produce a .tx file + staging_dir (str): The staging directory to write to. + force_copy (bool): Whether to force a copy even if a file hash + might have existed already in the project, otherwise + hardlinking the existing file is allowed. + color_management (dict): Maya's Color Management settings from + `lib.get_color_management_preferences` + colorspace (str): The source colorspace of the resources this + texture belongs to. + + Returns: + tuple: (filepath, copy_mode, texture_hash, result_colorspace) + """ + + fname, ext = os.path.splitext(os.path.basename(filepath)) + + # Note: The texture hash is only reliable if we include any potential + # conversion arguments provide to e.g. `maketx` + args = [] + hash_args = [] + if do_maketx and ext != ".tx": - # Produce .tx file in staging if source file is not .tx - converted = os.path.join(staging, "resources", fname + ".tx") - additional_args = [ + # Define .tx filepath in staging if source file is not .tx + converted = os.path.join(staging_dir, "resources", fname + ".tx") + + if color_management["enabled"]: + config_path = color_management["config"] + if not os.path.exists(config_path): + raise RuntimeError("OCIO config not found at: " + "{}".format(config_path)) + + render_colorspace = color_management["rendering_space"] + + self.log.info("tx: converting colorspace {0} " + "-> {1}".format(colorspace, render_colorspace)) + args.extend(["--colorconvert", colorspace, render_colorspace]) + args.extend(["--colorconfig", config_path]) + + else: + # We can't rely on the colorspace attribute when not + # in color managed mode because the collected color space + # is the color space attribute of the file node which can be + # any string whatsoever but only appears disabled in Attribute + # Editor. We assume we're always converting to linear/Raw if + # the source file is assumed to be sRGB. + render_colorspace = "linear" + if _has_arnold(): + img_info = image_info(filepath) + color_space = guess_colorspace(img_info) + if color_space.lower() == "sRGB": + self.log.info("tx: converting sRGB -> linear") + args.extend(["--colorconvert", "sRGB", "Raw"]) + else: + self.log.info("tx: texture's colorspace " + "is already linear") + else: + self.log.warning("tx: cannot guess the colorspace, " + "color conversion won't be available!") + + hash_args.append("maketx") + hash_args.extend(args) + + texture_hash = source_hash(filepath, *args) + + if not force_copy: + existing = self._get_existing_hashed_texture(filepath) + if existing: + return existing + + # Exclude these additional arguments from the hashing because + # it is the hash itself + args.extend([ "--sattrib", "sourceHash", texture_hash - ] - if linearize: - if cmds.colorManagementPrefs(query=True, cmEnabled=True): - render_colorspace = cmds.colorManagementPrefs(query=True, - renderingSpaceName=True) # noqa - config_path = cmds.colorManagementPrefs(query=True, - configFilePath=True) # noqa - if not os.path.exists(config_path): - raise RuntimeError("No OCIO config path found!") + ]) - color_space_attr = resource["node"] + ".colorSpace" - try: - color_space = cmds.getAttr(color_space_attr) - except ValueError: - # node doesn't have color space attribute - if _has_arnold(): - img_info = image_info(filepath) - color_space = guess_colorspace(img_info) - else: - color_space = "Raw" - self.log.info("tx: converting {0} -> {1}".format(color_space, render_colorspace)) # noqa - - additional_args.extend(["--colorconvert", - color_space, - render_colorspace]) - else: - - if _has_arnold(): - img_info = image_info(filepath) - color_space = guess_colorspace(img_info) - if color_space == "sRGB": - self.log.info("tx: converting sRGB -> linear") - additional_args.extend(["--colorconvert", - "sRGB", - "Raw"]) - else: - self.log.info("tx: texture's colorspace " - "is already linear") - else: - self.log.warning("cannot guess the colorspace" - "color conversion won't be available!") # noqa - - - additional_args.extend(["--colorconfig", config_path]) # Ensure folder exists if not os.path.exists(os.path.dirname(converted)): os.makedirs(os.path.dirname(converted)) @@ -562,13 +582,20 @@ class ExtractLook(publish.Extractor): maketx( filepath, converted, - additional_args, + args, self.log ) - return converted, COPY, texture_hash + return converted, COPY, texture_hash, render_colorspace - return filepath, COPY, texture_hash + # No special treatment for this file + texture_hash = source_hash(filepath) + if not force_copy: + existing = self._get_existing_hashed_texture(filepath) + if existing: + return existing + + return filepath, COPY, texture_hash, colorspace class ExtractModelRenderSets(ExtractLook): From c7e12b5184b39738d9225504de89054938754720 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 24 Mar 2023 19:39:51 +0100 Subject: [PATCH 49/88] Cosmetics --- openpype/hosts/maya/plugins/publish/extract_look.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 5c03aa5a5a..a067e63339 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -344,8 +344,6 @@ class ExtractLook(publish.Extractor): # didn't do color spaces different than the current # resource. processed_file = processed_files[filepath] - processed_colorspace = processed_file["color_space"] - processed_result_colorspace = processed_file["result_color_space"] self.log.debug( "File was already processed. Likely used by another " "resource too: {}".format(filepath) @@ -355,10 +353,12 @@ class ExtractLook(publish.Extractor): self.log.warning( "File was already processed but using another" "colorspace: {} <-> {}" - "".format(colorspace, processed_colorspace)) + "".format(colorspace, + processed_file["color_space"])) self._set_resource_result_colorspace( - resource, colorspace=processed_result_colorspace + resource, + colorspace=processed_file["result_color_space"] ) continue From b37c15f58215bbdb51227e690cf3dde0cd0fdd96 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Sat, 25 Mar 2023 10:52:44 +0100 Subject: [PATCH 50/88] More WIP refactoring for TextureProcessors --- .../maya/plugins/publish/extract_look.py | 295 +++++++++--------- 1 file changed, 148 insertions(+), 147 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index b21ce72296..7515fdeb8c 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -26,37 +26,6 @@ COPY = 1 HARDLINK = 2 -def _has_arnold(): - """Return whether the arnold package is available and can be imported.""" - try: - import arnold # noqa: F401 - return True - except (ImportError, ModuleNotFoundError): - return False - - -def get_redshift_tool(tool_name): - """Path to redshift texture processor. - - On Windows it adds .exe extension if missing from tool argument. - - Args: - tool (string): Tool name. - - Returns: - str: Full path to redshift texture processor executable. - """ - redshift_os_path = os.environ["REDSHIFT_COREDATAPATH"] - - redshift_tool_path = os.path.join( - redshift_os_path, - "bin", - tool_name - ) - - return find_executable(redshift_tool_path) - - def find_paths_by_hash(texture_hash): """Find the texture hash key in the dictionary. @@ -75,17 +44,26 @@ def find_paths_by_hash(texture_hash): @six.add_metaclass(ABCMeta) class TextureProcessor: - def __init__(self, log=None): if log is None: log = logging.getLogger(self.__class___.__name__) + self.log = log @abstractmethod - def process(self, filepath): - + def apply_settings(self, system_settings, project_settings): pass + @abstractmethod + def process(self, + source, + colorspace, + color_management, + staging_dir): + pass + + # TODO: Warning this only supports Py3.3+ @staticmethod + @abstractmethod def get_extension(): pass @@ -93,10 +71,11 @@ class TextureProcessor: class MakeRSTexBin(TextureProcessor): """Make `.rstexbin` using `redshiftTextureProcessor`""" - def __init__(self): - super(MakeRSTexBin, self).__init__() - - def process(self, source, *args): + def process(self, + source, + colorspace, + color_management, + staging_dir): """ with some default settings. @@ -105,24 +84,22 @@ class MakeRSTexBin(TextureProcessor): Args: source (str): Path to source file. - *args: Additional arguments for `redshiftTextureProcessor`. """ if "REDSHIFT_COREDATAPATH" not in os.environ: raise RuntimeError("Must have Redshift available.") - texture_processor_path = get_redshift_tool("redshiftTextureProcessor") + texture_processor_path = self.get_redshift_tool( + "redshiftTextureProcessor" + ) if not texture_processor_path: - raise KnownPublishError("Must have Redshift available.", - title="Make RSTexBin texture") + raise KnownPublishError("Must have Redshift available.") subprocess_args = [ texture_processor_path, source ] - subprocess_args.extend(args) - self.log.debug(" ".join(subprocess_args)) try: out = run_subprocess(subprocess_args) @@ -131,18 +108,43 @@ class MakeRSTexBin(TextureProcessor): exc_info=True) raise + # TODO: Implement correct return values return out @staticmethod def get_extension(): return ".rstexbin" + @staticmethod + def get_redshift_tool(tool_name): + """Path to redshift texture processor. + + On Windows it adds .exe extension if missing from tool argument. + + Args: + tool (string): Tool name. + + Returns: + str: Full path to redshift texture processor executable. + """ + redshift_os_path = os.environ["REDSHIFT_COREDATAPATH"] + + redshift_tool_path = os.path.join( + redshift_os_path, + "bin", + tool_name + ) + + return find_executable(redshift_tool_path) + class MakeTX(TextureProcessor): - def __init__(self): - super(MakeTX, self).__init__() - def process(self, source, destination, *args): + def process(self, + source, + colorspace, + color_management, + staging_dir): """Make `.tx` using `maketx` with some default settings. The settings are based on default as used in Arnold's @@ -152,8 +154,6 @@ class MakeTX(TextureProcessor): Args: source (str): Path to source file. - destination (str): Writing destination path. - *args: Additional arguments for `maketx`. Returns: str: Output of `maketx` command. @@ -164,9 +164,78 @@ class MakeTX(TextureProcessor): maketx_path = get_oiio_tools_path("maketx") if not maketx_path: - print( - "OIIO tool not found in {}".format(maketx_path)) - raise AssertionError("OIIO tool not found") + raise AssertionError( + "OIIO 'maketx' tool not found. Result: {}".format(maketx_path) + ) + + # Define .tx filepath in staging if source file is not .tx + fname, ext = os.path.splitext(os.path.basename(source)) + if ext == ".tx": + # TODO: Implement this fallback + # Do nothing if the source file is already a .tx file. + # return source, COPY, texture_hash, render_colorspace + pass + + args = [] + if color_management["enabled"]: + config_path = color_management["config"] + if not os.path.exists(config_path): + raise RuntimeError("OCIO config not found at: " + "{}".format(config_path)) + + render_colorspace = color_management["rendering_space"] + + self.log.info("tx: converting colorspace {0} " + "-> {1}".format(colorspace, + render_colorspace)) + args.extend(["--colorconvert", colorspace, render_colorspace]) + args.extend(["--colorconfig", config_path]) + + else: + # We can't rely on the colorspace attribute when not in color + # managed mode because the collected color space is the color space + # attribute of the file node which can be any string whatsoever + # but only appears disabled in Attribute Editor. We assume we're + # always converting to linear/Raw if the source file is assumed to + # be sRGB. + # TODO Without color management do we even know we can do + # "colorconvert" and what config does that end up using since + # colorconvert is a OCIO command line flag for maketx. + # Also, Raw != linear? + render_colorspace = "linear" + if self._has_arnold(): + img_info = image_info(source) + color_space = guess_colorspace(img_info) + if color_space.lower() == "sRGB": + self.log.info("tx: converting sRGB -> linear") + args.extend(["--colorconvert", "sRGB", "Raw"]) + else: + self.log.info("tx: texture's colorspace " + "is already linear") + else: + self.log.warning("tx: cannot guess the colorspace, " + "color conversion won't be " + "available!") + + args.append("maketx") + args.extend(args) + + texture_hash = source_hash(source, *args) + + # Exclude these additional arguments from the hashing because + # it is the hash itself + args.extend([ + "--sattrib", + "sourceHash", + texture_hash + ]) + + # Ensure folder exists + converted = os.path.join(staging_dir, "resources", fname + ".tx") + if not os.path.exists(os.path.dirname(converted)): + os.makedirs(os.path.dirname(converted)) + + self.log.info("Generating .tx file for %s .." % source) subprocess_args = [ maketx_path, @@ -186,18 +255,27 @@ class MakeTX(TextureProcessor): self.log.debug(" ".join(subprocess_args)) try: - out = run_subprocess(subprocess_args) + run_subprocess(subprocess_args) except Exception: self.log.error("Texture maketx conversion failed", exc_info=True) raise - return out + return converted, COPY, texture_hash, render_colorspace @staticmethod def get_extension(): return ".tx" + @staticmethod + def _has_arnold(): + """Return whether the arnold package is available and importable.""" + try: + import arnold # noqa: F401 + return True + except (ImportError, ModuleNotFoundError): + return False + @contextlib.contextmanager def no_workspace_dir(): @@ -565,7 +643,7 @@ class ExtractLook(publish.Extractor): basename, ext = os.path.splitext(os.path.basename(filepath)) # Get extension from the last processor - for processors in reversed(processors): + for processor in reversed(processors): ext = processor.get_extension() self.log.debug("Processor {} defined extension: " "{}".format(processor, ext)) @@ -620,7 +698,6 @@ class ExtractLook(publish.Extractor): Returns: tuple: (filepath, copy_mode, texture_hash, result_colorspace) """ - fname, ext = os.path.splitext(os.path.basename(filepath)) # Note: The texture hash is only reliable if we include any potential # conversion arguments provide to e.g. `maketx` @@ -629,104 +706,28 @@ class ExtractLook(publish.Extractor): if len(processors) > 1: raise KnownPublishError( - "More than one texture processor not supported" + "More than one texture processor not supported. " + "Current processors enabled: {}".format(processors) ) # TODO: Make all processors take the same arguments for processor in processors: - if processor is MakeTX: - processed_path = processor().process(filepath, - converted, - "--sattrib", - "sourceHash", - escape_space(texture_hash), # noqa - colorconvert, - color_config, - ) - self.log.info("Generating texture file for %s .." % filepath) # noqa - self.log.info(converted) - if processed_path: - return processed_path, COPY, texture_hash - else: - self.log.info("maketx has returned nothing") - elif processor is MakeRSTexBin: - processed_path = processor().process(filepath) - self.log.info("Generating texture file for %s .." % filepath) # noqa - if processed_path: - return processed_path, COPY, texture_hash - else: - self.log.info("redshift texture converter has returned nothing") # noqa + self.log.debug("Processing texture {} with processor {}".format( + filepath, processor + )) - # TODO: continue this refactoring to processor - if do_maketx and ext != ".tx": - # Define .tx filepath in staging if source file is not .tx - converted = os.path.join(staging_dir, "resources", fname + ".tx") + processed_result = processor.process(filepath, + colorspace, + color_management) + if not processed_result: + raise RuntimeError("Texture Processor {} returned " + "no result.".format(processor)) - if color_management["enabled"]: - config_path = color_management["config"] - if not os.path.exists(config_path): - raise RuntimeError("OCIO config not found at: " - "{}".format(config_path)) + processed_path, processed_texture_hash = processed_result + self.log.info("Generated processed " + "texture: {}".format(processed_path)) - render_colorspace = color_management["rendering_space"] - - self.log.info("tx: converting colorspace {0} " - "-> {1}".format(colorspace, render_colorspace)) - args.extend(["--colorconvert", colorspace, render_colorspace]) - args.extend(["--colorconfig", config_path]) - - else: - # We can't rely on the colorspace attribute when not - # in color managed mode because the collected color space - # is the color space attribute of the file node which can be - # any string whatsoever but only appears disabled in Attribute - # Editor. We assume we're always converting to linear/Raw if - # the source file is assumed to be sRGB. - render_colorspace = "linear" - if _has_arnold(): - img_info = image_info(filepath) - color_space = guess_colorspace(img_info) - if color_space.lower() == "sRGB": - self.log.info("tx: converting sRGB -> linear") - args.extend(["--colorconvert", "sRGB", "Raw"]) - else: - self.log.info("tx: texture's colorspace " - "is already linear") - else: - self.log.warning("tx: cannot guess the colorspace, " - "color conversion won't be available!") - - hash_args.append("maketx") - hash_args.extend(args) - - texture_hash = source_hash(filepath, *args) - - if not force_copy: - existing = self._get_existing_hashed_texture(filepath) - if existing: - return existing - - # Exclude these additional arguments from the hashing because - # it is the hash itself - args.extend([ - "--sattrib", - "sourceHash", - texture_hash - ]) - - # Ensure folder exists - if not os.path.exists(os.path.dirname(converted)): - os.makedirs(os.path.dirname(converted)) - - self.log.info("Generating .tx file for %s .." % filepath) - maketx( - filepath, - converted, - args, - self.log - ) - - return converted, COPY, texture_hash, render_colorspace + return processed_path, COPY, processed_texture_hash # No special treatment for this file texture_hash = source_hash(filepath) From a6a392e9640b1028fe5f1e199df5bb0d96c4f570 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Sat, 25 Mar 2023 12:32:35 +0100 Subject: [PATCH 51/88] Allow maketx with color management enabled --- .../publish/validate_look_color_space.py | 26 ------------------- 1 file changed, 26 deletions(-) delete mode 100644 openpype/hosts/maya/plugins/publish/validate_look_color_space.py diff --git a/openpype/hosts/maya/plugins/publish/validate_look_color_space.py b/openpype/hosts/maya/plugins/publish/validate_look_color_space.py deleted file mode 100644 index b1bdeb7541..0000000000 --- a/openpype/hosts/maya/plugins/publish/validate_look_color_space.py +++ /dev/null @@ -1,26 +0,0 @@ -from maya import cmds - -import pyblish.api -from openpype.pipeline.publish import ValidateContentsOrder -from openpype.pipeline import PublishValidationError - - -class ValidateMayaColorSpace(pyblish.api.InstancePlugin): - """ - Check if the OCIO Color Management and maketx options - enabled at the same time - """ - - order = ValidateContentsOrder - families = ['look'] - hosts = ['maya'] - label = 'Color Management with maketx' - - def process(self, instance): - ocio_maya = cmds.colorManagementPrefs(q=True, - cmConfigFileEnabled=True, - cmEnabled=True) - maketx = instance.data["maketx"] - - if ocio_maya and maketx: - raise PublishValidationError("Maya is color managed and maketx option is on. OpenPype doesn't support this combination yet.") # noqa From 6b841253d7e33d194db4e4cd3804952a819631b9 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Sat, 25 Mar 2023 14:26:22 +0100 Subject: [PATCH 52/88] Fix hash args --- openpype/hosts/maya/plugins/publish/extract_look.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 7515fdeb8c..c8339a1335 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -217,10 +217,9 @@ class MakeTX(TextureProcessor): "color conversion won't be " "available!") - args.append("maketx") - args.extend(args) - - texture_hash = source_hash(source, *args) + hash_args = ["maketx"] + hash_args.extend(args) + texture_hash = source_hash(source, *hash_args) # Exclude these additional arguments from the hashing because # it is the hash itself From 44c0009e728921076bbfdad59fca0b834261b01c Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Sat, 25 Mar 2023 14:37:33 +0100 Subject: [PATCH 53/88] Allow to configure extra arguments in OP settings for `maketx` --- .../maya/plugins/publish/extract_look.py | 34 ++++++++++++++++--- .../defaults/project_settings/maya.json | 3 ++ .../schemas/schema_maya_publish.json | 16 +++++++++ 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index c8339a1335..2951261cd6 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -139,13 +139,31 @@ class MakeRSTexBin(TextureProcessor): class MakeTX(TextureProcessor): + """Make `.tx` using `maketx` with some default settings.""" + + def __init__(self, log=None): + super(MakeTX, self).__init__(log=log) + self.extra_args = [] + + def apply_settings(self, system_settings, project_settings): + # Allow extra maketx arguments from project settings + extra_args_dict = ( + project_settings["maya"]["publish"] + .get("ExtractLook", {}) + .get("maketx_arguments", {}) + ) + extra_args = [] + for flag, value in extra_args_dict.items(): + extra_args.append(flag) + extra_args.append(value) + self.extra_args = extra_args def process(self, source, colorspace, color_management, staging_dir): - """Make `.tx` using `maketx` with some default settings. + """ The settings are based on default as used in Arnold's txManager in the scene. @@ -154,6 +172,10 @@ class MakeTX(TextureProcessor): Args: source (str): Path to source file. + colorspace (str): Colorspace of the source file. + color_management (dict): Maya Color management data from + `lib.get_color_management_preferences` + staging_dir (str): Output directory to write to. Returns: str: Output of `maketx` command. @@ -230,9 +252,9 @@ class MakeTX(TextureProcessor): ]) # Ensure folder exists - converted = os.path.join(staging_dir, "resources", fname + ".tx") - if not os.path.exists(os.path.dirname(converted)): - os.makedirs(os.path.dirname(converted)) + destination = os.path.join(staging_dir, "resources", fname + ".tx") + if not os.path.exists(os.path.dirname(destination)): + os.makedirs(os.path.dirname(destination)) self.log.info("Generating .tx file for %s .." % source) @@ -250,6 +272,8 @@ class MakeTX(TextureProcessor): ] subprocess_args.extend(args) + if self.extra_args: + subprocess_args.extend(self.extra_args) subprocess_args.extend(["-o", destination]) self.log.debug(" ".join(subprocess_args)) @@ -260,7 +284,7 @@ class MakeTX(TextureProcessor): exc_info=True) raise - return converted, COPY, texture_hash, render_colorspace + return destination, COPY, texture_hash, render_colorspace @staticmethod def get_extension(): diff --git a/openpype/settings/defaults/project_settings/maya.json b/openpype/settings/defaults/project_settings/maya.json index ef327fbd6b..502dbda870 100644 --- a/openpype/settings/defaults/project_settings/maya.json +++ b/openpype/settings/defaults/project_settings/maya.json @@ -925,6 +925,9 @@ "enabled": true, "active": true, "ogsfx_path": "/maya2glTF/PBR/shaders/glTF_PBR.ogsfx" + }, + "ExtractLook": { + "maketx_arguments": {} } }, "load": { 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 5a66f8a513..da12dde6b2 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 @@ -996,6 +996,22 @@ "label": "GLSL Shader Directory" } ] + }, + { + "type": "dict", + "collapsible": true, + "key": "ExtractLook", + "label": "Extract Look", + "children": [ + { + "key": "maketx_arguments", + "label": "Extra arguments for maketx command line", + "type": "dict-modifiable", + "object_type": { + "type": "text" + } + } + ] } ] } From c181d3ff2e14a3797a274ce9e90c1c08f21cac5f Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Sat, 25 Mar 2023 14:54:19 +0100 Subject: [PATCH 54/88] Intialize texture processors with applied settings --- .../maya/plugins/publish/extract_look.py | 36 +++++++++++-------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 2951261cd6..9777f14f11 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -402,6 +402,25 @@ class ExtractLook(publish.Extractor): self.log.info("No sets found") return + # Specify texture processing executables to activate + # TODO: Load these more dynamically once we support more processors + processors = [] + context = instance.context + for key, Processor in { + # Instance data key to texture processor mapping + "maketx": MakeTX, + "rstex": MakeRSTexBin + }.items(): + if instance.data.get(key, False): + processor = Processor() + processor.apply_settings(context.data["system_settings"], + context.data["project_settings"]) + processors.append(processor) + + if processors: + self.log.debug("Collected texture processors: " + "{}".format(processors)) + self.log.debug("Processing resources..") results = self.process_resources(instance, staging_dir=dir_path) transfers = results["fileTransfers"] @@ -499,7 +518,7 @@ class ExtractLook(publish.Extractor): ) resource["result_colorspace"] = colorspace - def process_resources(self, instance, staging_dir): + def process_resources(self, instance, staging_dir, processors): """Process all resources in the instance. It is assumed that all resources are nodes using file textures. @@ -512,7 +531,6 @@ class ExtractLook(publish.Extractor): """ resources = instance.data["resources"] - do_maketx = instance.data.get("maketx", False) color_management = lib.get_color_management_preferences() # Temporary fix to NOT create hardlinks on windows machines @@ -532,14 +550,6 @@ class ExtractLook(publish.Extractor): destinations = {} remap = OrderedDict() - # Specify texture processing executables to activate - processors = [] - if instance.data.get("maketx", False): - processors.append(MakeTX) - # Option to convert textures to native redshift textures - if instance.data.get("rstex", False): - processors.append(MakeRSTexBin) - for resource in resources: colorspace = resource["color_space"] @@ -724,9 +734,6 @@ class ExtractLook(publish.Extractor): # Note: The texture hash is only reliable if we include any potential # conversion arguments provide to e.g. `maketx` - args = [] - hash_args = [] - if len(processors) > 1: raise KnownPublishError( "More than one texture processor not supported. " @@ -741,7 +748,8 @@ class ExtractLook(publish.Extractor): processed_result = processor.process(filepath, colorspace, - color_management) + color_management, + staging_dir) if not processed_result: raise RuntimeError("Texture Processor {} returned " "no result.".format(processor)) From e83708a3fb5da5710142578a4d433643ef529c89 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Sat, 25 Mar 2023 14:54:52 +0100 Subject: [PATCH 55/88] Cosmetics --- openpype/hosts/maya/plugins/publish/extract_look.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 9777f14f11..632c64014f 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -149,8 +149,7 @@ class MakeTX(TextureProcessor): # Allow extra maketx arguments from project settings extra_args_dict = ( project_settings["maya"]["publish"] - .get("ExtractLook", {}) - .get("maketx_arguments", {}) + .get("ExtractLook", {}).get("maketx_arguments", {}) ) extra_args = [] for flag, value in extra_args_dict.items(): From d8c763c191f46448cfdbbc17c8939f1c6bf7f9fd Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Sat, 25 Mar 2023 14:56:15 +0100 Subject: [PATCH 56/88] Include extra args in maketx texture hash --- openpype/hosts/maya/plugins/publish/extract_look.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 632c64014f..41377bb8f6 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -238,8 +238,11 @@ class MakeTX(TextureProcessor): "color conversion won't be " "available!") + # Note: The texture hash is only reliable if we include any potential + # conversion arguments provide to e.g. `maketx` hash_args = ["maketx"] hash_args.extend(args) + hash_args.extend(self.extra_args) texture_hash = source_hash(source, *hash_args) # Exclude these additional arguments from the hashing because @@ -731,8 +734,6 @@ class ExtractLook(publish.Extractor): tuple: (filepath, copy_mode, texture_hash, result_colorspace) """ - # Note: The texture hash is only reliable if we include any potential - # conversion arguments provide to e.g. `maketx` if len(processors) > 1: raise KnownPublishError( "More than one texture processor not supported. " From ba1d0c570ab4a20417a450dd2c5c030ac3f4901d Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Sat, 25 Mar 2023 15:01:03 +0100 Subject: [PATCH 57/88] Fix arguments --- openpype/hosts/maya/plugins/publish/extract_look.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 41377bb8f6..77cf0d8a83 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -424,7 +424,9 @@ class ExtractLook(publish.Extractor): "{}".format(processors)) self.log.debug("Processing resources..") - results = self.process_resources(instance, staging_dir=dir_path) + results = self.process_resources(instance, + staging_dir=dir_path, + processors=processors) transfers = results["fileTransfers"] hardlinks = results["fileHardlinks"] hashes = results["fileHashes"] From 0fa5eab7c904ab497274c37c6d0a8dfc38015f36 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Sat, 25 Mar 2023 20:29:49 +0100 Subject: [PATCH 58/88] Implement TextureResult dataclass + fix publishing with and without `maketx` --- .../maya/plugins/publish/extract_look.py | 106 ++++++++++++------ 1 file changed, 72 insertions(+), 34 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 77cf0d8a83..b166e85e7a 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -10,6 +10,7 @@ import tempfile import platform import contextlib from collections import OrderedDict +import attr from maya import cmds # noqa @@ -26,6 +27,19 @@ COPY = 1 HARDLINK = 2 +@attr.s +class TextureResult: + # Path to the file + path = attr.ib() + # Colorspace of the resulting texture. This might not be the input + # colorspace of the texture if a TextureProcessor has processed the file. + colorspace = attr.ib() + # Hash generated for the texture using openpype.lib.source_hash + file_hash = attr.ib() + # The transfer mode, e.g. COPY or HARDLINK + transfer_mode = attr.ib() + + def find_paths_by_hash(texture_hash): """Find the texture hash key in the dictionary. @@ -46,7 +60,7 @@ def find_paths_by_hash(texture_hash): class TextureProcessor: def __init__(self, log=None): if log is None: - log = logging.getLogger(self.__class___.__name__) + log = logging.getLogger(self.__class__.__name__) self.log = log @abstractmethod @@ -67,6 +81,10 @@ class TextureProcessor: def get_extension(): pass + def __repr__(self): + # Log instance as class name + return self.__class__.__name__ + class MakeRSTexBin(TextureProcessor): """Make `.rstexbin` using `redshiftTextureProcessor`""" @@ -100,6 +118,9 @@ class MakeRSTexBin(TextureProcessor): source ] + hash_args = ["rstex"] + texture_hash = source_hash(source, *hash_args) + self.log.debug(" ".join(subprocess_args)) try: out = run_subprocess(subprocess_args) @@ -108,8 +129,12 @@ class MakeRSTexBin(TextureProcessor): exc_info=True) raise - # TODO: Implement correct return values - return out + return TextureResult( + path=out, + file_hash=texture_hash, + colorspace=colorspace, + transfer_mode=COPY + ) @staticmethod def get_extension(): @@ -192,10 +217,13 @@ class MakeTX(TextureProcessor): # Define .tx filepath in staging if source file is not .tx fname, ext = os.path.splitext(os.path.basename(source)) if ext == ".tx": - # TODO: Implement this fallback # Do nothing if the source file is already a .tx file. - # return source, COPY, texture_hash, render_colorspace - pass + return TextureResult( + path=source, + file_hash=None, # todo: unknown texture hash? + colorspace=colorspace, + transfer_mode=COPY + ) args = [] if color_management["enabled"]: @@ -286,7 +314,12 @@ class MakeTX(TextureProcessor): exc_info=True) raise - return destination, COPY, texture_hash, render_colorspace + return TextureResult( + path=destination, + file_hash=texture_hash, + colorspace=render_colorspace, + transfer_mode=COPY + ) @staticmethod def get_extension(): @@ -510,17 +543,17 @@ class ExtractLook(publish.Extractor): def _set_resource_result_colorspace(self, resource, colorspace): """Update resource resulting colorspace after texture processing""" - if "result_colorspace" in resource: - if resource["result_colorspace"] == colorspace: + if "result_color_space" in resource: + if resource["result_color_space"] == colorspace: return self.log.warning( "Resource already has a resulting colorspace but is now " "being overridden to a new one: {} -> {}".format( - resource["result_colorspace"], colorspace + resource["result_color_space"], colorspace ) ) - resource["result_colorspace"] = colorspace + resource["result_color_space"] = colorspace def process_resources(self, instance, staging_dir, processors): """Process all resources in the instance. @@ -592,37 +625,33 @@ class ExtractLook(publish.Extractor): color_management=color_management, colorspace=colorspace ) - source, mode, texture_hash, result_colorspace = texture_result + source = texture_result.path destination = self.resource_destination(instance, - source, + texture_result.path, processors) # Set the resulting color space on the resource self._set_resource_result_colorspace( - resource, colorspace=result_colorspace + resource, colorspace=texture_result.colorspace ) processed_files[filepath] = { "color_space": colorspace, - "result_color_space": result_colorspace, + "result_color_space": texture_result.colorspace, } - # Force copy is specified. - if force_copy: - mode = COPY - - if mode == COPY: + if force_copy or texture_result.transfer_mode == COPY: transfers.append((source, destination)) self.log.info('file will be copied {} -> {}'.format( source, destination)) - elif mode == HARDLINK: + elif texture_result.transfer_mode == HARDLINK: hardlinks.append((source, destination)) self.log.info('file will be hardlinked {} -> {}'.format( source, destination)) # Store the hashes from hash to destination to include in the # database - hashes[texture_hash] = destination + hashes[texture_result.file_hash] = destination source = os.path.normpath(resource["source"]) if source not in destinations: @@ -697,10 +726,9 @@ class ExtractLook(publish.Extractor): # then don't reprocess but hardlink from the original existing = find_paths_by_hash(texture_hash) if existing: - self.log.info("Found hash in database, preparing hardlink..") source = next((p for p in existing if os.path.exists(p)), None) if source: - return source, HARDLINK, texture_hash + return source else: self.log.warning( "Paths not found on disk, " @@ -722,7 +750,7 @@ class ExtractLook(publish.Extractor): Args: filepath (str): The source file path to process. - processors (list): List of TexProcessor processing the texture + processors (list): List of TextureProcessor processing the texture staging_dir (str): The staging directory to write to. force_copy (bool): Whether to force a copy even if a file hash might have existed already in the project, otherwise @@ -733,7 +761,7 @@ class ExtractLook(publish.Extractor): texture belongs to. Returns: - tuple: (filepath, copy_mode, texture_hash, result_colorspace) + TextureResult: The texture result information. """ if len(processors) > 1: @@ -742,7 +770,6 @@ class ExtractLook(publish.Extractor): "Current processors enabled: {}".format(processors) ) - # TODO: Make all processors take the same arguments for processor in processors: self.log.debug("Processing texture {} with processor {}".format( filepath, processor @@ -755,21 +782,32 @@ class ExtractLook(publish.Extractor): if not processed_result: raise RuntimeError("Texture Processor {} returned " "no result.".format(processor)) - - processed_path, processed_texture_hash = processed_result self.log.info("Generated processed " - "texture: {}".format(processed_path)) + "texture: {}".format(processed_result.path)) - return processed_path, COPY, processed_texture_hash + # TODO: Currently all processors force copy instead of allowing + # hardlinks using source hashes. This should be refactored + return processed_result - # No special treatment for this file + # No texture processing for this file texture_hash = source_hash(filepath) if not force_copy: existing = self._get_existing_hashed_texture(filepath) if existing: - return existing + self.log.info("Found hash in database, preparing hardlink..") + return TextureResult( + path=filepath, + file_hash=texture_hash, + colorspace=colorspace, + transfer_mode=HARDLINK + ) - return filepath, COPY, texture_hash, colorspace + return TextureResult( + path=filepath, + file_hash=texture_hash, + colorspace=colorspace, + transfer_mode=COPY + ) class ExtractModelRenderSets(ExtractLook): From 81b5d771270b27849ee322d09c06e9ee75cd4f73 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Sat, 25 Mar 2023 20:42:34 +0100 Subject: [PATCH 59/88] Cleanup, fix Py2 compatibility --- .../maya/plugins/publish/extract_look.py | 47 ++++++++++++++----- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index b166e85e7a..dd59cd7dcc 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -63,7 +63,6 @@ class TextureProcessor: log = logging.getLogger(self.__class__.__name__) self.log = log - @abstractmethod def apply_settings(self, system_settings, project_settings): pass @@ -73,11 +72,28 @@ class TextureProcessor: colorspace, color_management, staging_dir): + """Process the `source` texture. + + Must be implemented on inherited class. + + This must always return a TextureResult even when it does not generate + a texture. If it doesn't generate a texture then it should return a + TextureResult using the input path and colorspace. + + Args: + source (str): Path to source file. + colorspace (str): Colorspace of the source file. + color_management (dict): Maya Color management data from + `lib.get_color_management_preferences` + staging_dir (str): Output directory to write to. + + Returns: + TextureResult: The resulting texture information. + + """ pass - # TODO: Warning this only supports Py3.3+ @staticmethod - @abstractmethod def get_extension(): pass @@ -164,7 +180,12 @@ class MakeRSTexBin(TextureProcessor): class MakeTX(TextureProcessor): - """Make `.tx` using `maketx` with some default settings.""" + """Make `.tx` using `maketx` with some default settings. + + Some hardcoded arguments passed to `maketx` are based on the defaults used + in Arnold's txManager tool. + + """ def __init__(self, log=None): super(MakeTX, self).__init__(log=log) @@ -187,12 +208,10 @@ class MakeTX(TextureProcessor): colorspace, color_management, staging_dir): - """ + """Process the texture. - The settings are based on default as used in Arnold's - txManager in the scene. This function requires the `maketx` executable to be - on the `PATH`. + available in the OIIO tool. Args: source (str): Path to source file. @@ -202,7 +221,7 @@ class MakeTX(TextureProcessor): staging_dir (str): Output directory to write to. Returns: - str: Output of `maketx` command. + TextureResult: The resulting texture information. """ from openpype.lib import get_oiio_tools_path @@ -474,7 +493,7 @@ class ExtractLook(publish.Extractor): # To avoid Maya trying to automatically remap the file # textures relative to the `workspace -directory` we force # it to a fake temporary workspace. This fixes textures - # getting incorrectly remapped. (LKD-17, PLN-101) + # getting incorrectly remapped. with no_workspace_dir(): with lib.attribute_values(remap): with lib.maintained_selection(): @@ -710,9 +729,11 @@ class ExtractLook(publish.Extractor): # Get extension from the last processor for processor in reversed(processors): - ext = processor.get_extension() - self.log.debug("Processor {} defined extension: " - "{}".format(processor, ext)) + processor_ext = processor.get_extension() + if processor_ext: + self.log.debug("Processor {} defined extension: " + "{}".format(processor, ext)) + ext = processor_ext break return os.path.join( From 16e5bb630f015f7deaa9a86e592cfe8f34fb94ac Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Sun, 26 Mar 2023 20:30:35 +0200 Subject: [PATCH 60/88] Cleanup --- openpype/hosts/maya/plugins/publish/extract_look.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index dd59cd7dcc..2368295bf4 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -441,8 +441,6 @@ class ExtractLook(publish.Extractor): dir_path = self.staging_dir(instance) maya_fname = "{0}.{1}".format(instance.name, self.scene_type) json_fname = "{0}.{1}".format(instance.name, self.look_data_type) - - # Make texture dump folder maya_path = os.path.join(dir_path, maya_fname) json_path = os.path.join(dir_path, json_fname) From b340f6a57ca0ae9c22c29e0e2efebe23e8685df8 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Sun, 26 Mar 2023 20:51:10 +0200 Subject: [PATCH 61/88] Clarify more about the issue in logging message + minor cleanup --- .../hosts/maya/plugins/publish/extract_look.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 2368295bf4..b68d8ae545 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -623,10 +623,14 @@ class ExtractLook(publish.Extractor): if colorspace != processed_file["color_space"]: self.log.warning( - "File was already processed but using another" - "colorspace: {} <-> {}" - "".format(colorspace, - processed_file["color_space"])) + "File '{}' was already processed using colorspace " + "'{}' instead of the current resource's " + "colorspace '{}'. The already processed texture " + "result's colorspace '{}' will be used." + "".format(filepath, + colorspace, + processed_file["color_space"], + processed_file["result_color_space"])) self._set_resource_result_colorspace( resource, @@ -642,7 +646,6 @@ class ExtractLook(publish.Extractor): color_management=color_management, colorspace=colorspace ) - source = texture_result.path destination = self.resource_destination(instance, texture_result.path, processors) @@ -657,6 +660,7 @@ class ExtractLook(publish.Extractor): "result_color_space": texture_result.colorspace, } + source = texture_result.path if force_copy or texture_result.transfer_mode == COPY: transfers.append((source, destination)) self.log.info('file will be copied {} -> {}'.format( From 81e25eb3a30a4ad801f09ff528458f5ba309e4fb Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Sun, 26 Mar 2023 21:06:50 +0200 Subject: [PATCH 62/88] Move caching into one place --- .../maya/plugins/publish/extract_look.py | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index b68d8ae545..2e268749a0 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -596,14 +596,23 @@ class ExtractLook(publish.Extractor): else: force_copy = instance.data.get("forceCopy", False) + destinations_cache = {} + + def get_resource_destination_cached(path): + """Get resource destination with cached result per filepath""" + if path not in destinations_cache: + self.get_resource_destination(path, + instance.data["resourcesDir"], + processors) + destinations_cache[path] = destination + return destinations_cache[path] + # Process all resource's individual files processed_files = {} transfers = [] hardlinks = [] hashes = {} - destinations = {} remap = OrderedDict() - for resource in resources: colorspace = resource["color_space"] @@ -646,9 +655,6 @@ class ExtractLook(publish.Extractor): color_management=color_management, colorspace=colorspace ) - destination = self.resource_destination(instance, - texture_result.path, - processors) # Set the resulting color space on the resource self._set_resource_result_colorspace( @@ -661,6 +667,7 @@ class ExtractLook(publish.Extractor): } source = texture_result.path + destination = get_resource_destination_cached(source) if force_copy or texture_result.transfer_mode == COPY: transfers.append((source, destination)) self.log.info('file will be copied {} -> {}'.format( @@ -674,14 +681,6 @@ class ExtractLook(publish.Extractor): # database hashes[texture_result.file_hash] = destination - source = os.path.normpath(resource["source"]) - if source not in destinations: - # Cache destination as source resource might be included - # multiple times - destinations[source] = self.resource_destination( - instance, source, processors - ) - # Set up remapping attributes for the node during the publish # The order of these can be important if one attribute directly # affects another, e.g. we set colorspace after filepath because @@ -690,7 +689,9 @@ class ExtractLook(publish.Extractor): # attributes changed in the resulting publish) # Remap filepath to publish destination filepath_attr = resource["attribute"] - remap[filepath_attr] = destinations[source] + remap[filepath_attr] = get_resource_destination_cached( + resource["source"] + ) # Preserve color space values (force value after filepath change) # This will also trigger in the same order at end of context to @@ -709,23 +710,21 @@ class ExtractLook(publish.Extractor): "attrRemap": remap, } - def resource_destination(self, instance, filepath, processors): + def get_resource_destination(self, filepath, resources_dir, processors): """Get resource destination path. This is utility function to change path if resource file name is changed by some external tool like `maketx`. Args: - instance: Current Instance. - filepath (str): Resource path - processor: Texture processors converting resource. + filepath (str): Resource source path + resources_dir (str): Destination dir for resources in publish. + processors (list): Texture processors converting resource. Returns: str: Path to resource file """ - resources_dir = instance.data["resourcesDir"] - # Compute destination location basename, ext = os.path.splitext(os.path.basename(filepath)) From 03e5ff92ea3d6d229d7b91640852eead7628a356 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Sun, 26 Mar 2023 21:07:38 +0200 Subject: [PATCH 63/88] Fix typo --- openpype/hosts/maya/plugins/publish/extract_look.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 2e268749a0..f846b4ee3d 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -601,9 +601,8 @@ class ExtractLook(publish.Extractor): def get_resource_destination_cached(path): """Get resource destination with cached result per filepath""" if path not in destinations_cache: - self.get_resource_destination(path, - instance.data["resourcesDir"], - processors) + destination = self.get_resource_destination( + path, instance.data["resourcesDir"], processors) destinations_cache[path] = destination return destinations_cache[path] From 2917ee27750384a3c952ced17e257fa99d48aeb8 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Sun, 26 Mar 2023 21:10:57 +0200 Subject: [PATCH 64/88] Fix logging --- openpype/hosts/maya/plugins/publish/extract_look.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index f846b4ee3d..d5d8da04e7 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -730,9 +730,11 @@ class ExtractLook(publish.Extractor): # Get extension from the last processor for processor in reversed(processors): processor_ext = processor.get_extension() - if processor_ext: - self.log.debug("Processor {} defined extension: " - "{}".format(processor, ext)) + if processor_ext and ext != processor_ext: + self.log.debug("Processor {} overrides extension to '{}' " + "for path: {}".format(processor, + processor_ext, + filepath)) ext = processor_ext break From 00e5f220f4fd664ecd00cc7cae4fefab6984f89c Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Sun, 26 Mar 2023 21:12:37 +0200 Subject: [PATCH 65/88] Add todo --- openpype/hosts/maya/plugins/publish/extract_look.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index d5d8da04e7..33ba4cc7a3 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -687,6 +687,11 @@ class ExtractLook(publish.Extractor): # filepaths (which is avoidable, but we don't want to have those # attributes changed in the resulting publish) # Remap filepath to publish destination + # TODO It would be much better if we could use the destination path + # from the actual processed texture results, but since the + # attribute will need to preserve tokens like , etc for + # now we will define the output path from the attribute value + # including the tokens to persist them. filepath_attr = resource["attribute"] remap[filepath_attr] = get_resource_destination_cached( resource["source"] From 35f76a2365d76aa97ca32a5591e831662dcd4029 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 27 Mar 2023 10:20:02 +0200 Subject: [PATCH 66/88] Fix Redshift .rstexbin support --- openpype/hosts/maya/plugins/publish/extract_look.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 33ba4cc7a3..46eb940879 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -137,16 +137,21 @@ class MakeRSTexBin(TextureProcessor): hash_args = ["rstex"] texture_hash = source_hash(source, *hash_args) + # Redshift stores the output texture next to the input but with + # the extension replaced to `.rstexbin + basename, ext = os.path.splitext(source) + destination = "{}{}".format(basename, self.get_extension()) + self.log.debug(" ".join(subprocess_args)) try: - out = run_subprocess(subprocess_args) + run_subprocess(subprocess_args) except Exception: self.log.error("Texture .rstexbin conversion failed", exc_info=True) raise return TextureResult( - path=out, + path=destination, file_hash=texture_hash, colorspace=colorspace, transfer_mode=COPY From 95fcce48bd3a2476a89bf2823fb1abcaa8b1d056 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 27 Mar 2023 10:22:33 +0200 Subject: [PATCH 67/88] Move `REDSHIFT_COREDATAPATH` environment check to `get_redshift_tool` --- openpype/hosts/maya/plugins/publish/extract_look.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 46eb940879..ad9ba34224 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -120,9 +120,6 @@ class MakeRSTexBin(TextureProcessor): source (str): Path to source file. """ - if "REDSHIFT_COREDATAPATH" not in os.environ: - raise RuntimeError("Must have Redshift available.") - texture_processor_path = self.get_redshift_tool( "redshiftTextureProcessor" ) @@ -173,10 +170,11 @@ class MakeRSTexBin(TextureProcessor): Returns: str: Full path to redshift texture processor executable. """ - redshift_os_path = os.environ["REDSHIFT_COREDATAPATH"] + if "REDSHIFT_COREDATAPATH" not in os.environ: + raise RuntimeError("Must have Redshift available.") redshift_tool_path = os.path.join( - redshift_os_path, + os.environ["REDSHIFT_COREDATAPATH"], "bin", tool_name ) From 9773cbbedc5224b130badee8a734d090c76aee33 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 27 Mar 2023 10:27:13 +0200 Subject: [PATCH 68/88] Cleanup --- .../maya/plugins/publish/extract_look.py | 92 ++++++++++--------- 1 file changed, 47 insertions(+), 45 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index ad9ba34224..4e04999e7e 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -29,6 +29,7 @@ HARDLINK = 2 @attr.s class TextureResult: + """The resulting texture of a processed file for a resource""" # Path to the file path = attr.ib() # Colorspace of the resulting texture. This might not be the input @@ -56,6 +57,38 @@ def find_paths_by_hash(texture_hash): return legacy_io.distinct(key, {"type": "version"}) +@contextlib.contextmanager +def no_workspace_dir(): + """Force maya to a fake temporary workspace directory. + + Note: This is not maya.cmds.workspace 'rootDirectory' but the 'directory' + + This helps to avoid Maya automatically remapping image paths to files + relative to the currently set directory. + + """ + + # Store current workspace + original = cmds.workspace(query=True, directory=True) + + # Set a fake workspace + fake_workspace_dir = tempfile.mkdtemp() + cmds.workspace(directory=fake_workspace_dir) + + try: + yield + finally: + try: + cmds.workspace(directory=original) + except RuntimeError: + # If the original workspace directory didn't exist either + # ignore the fact that it fails to reset it to the old path + pass + + # Remove the temporary directory + os.rmdir(fake_workspace_dir) + + @six.add_metaclass(ABCMeta) class TextureProcessor: def __init__(self, log=None): @@ -64,6 +97,16 @@ class TextureProcessor: self.log = log def apply_settings(self, system_settings, project_settings): + """Apply OpenPype system/project settings to the TextureProcessor + + Args: + system_settings (dict): OpenPype system settings + project_settings (dict): OpenPype project settings + + Returns: + None + + """ pass @abstractmethod @@ -110,16 +153,7 @@ class MakeRSTexBin(TextureProcessor): colorspace, color_management, staging_dir): - """ - with some default settings. - This function requires the `REDSHIFT_COREDATAPATH` - to be in `PATH`. - - Args: - source (str): Path to source file. - - """ texture_processor_path = self.get_redshift_tool( "redshiftTextureProcessor" ) @@ -135,7 +169,7 @@ class MakeRSTexBin(TextureProcessor): texture_hash = source_hash(source, *hash_args) # Redshift stores the output texture next to the input but with - # the extension replaced to `.rstexbin + # the extension replaced to `.rstexbin` basename, ext = os.path.splitext(source) destination = "{}{}".format(basename, self.get_extension()) @@ -165,7 +199,7 @@ class MakeRSTexBin(TextureProcessor): On Windows it adds .exe extension if missing from tool argument. Args: - tool (string): Tool name. + tool_name (string): Tool name. Returns: str: Full path to redshift texture processor executable. @@ -213,8 +247,8 @@ class MakeTX(TextureProcessor): staging_dir): """Process the texture. - This function requires the `maketx` executable to be - available in the OIIO tool. + This function requires the `maketx` executable to be available in an + OpenImageIO toolset detectable by OpenPype. Args: source (str): Path to source file. @@ -357,38 +391,6 @@ class MakeTX(TextureProcessor): return False -@contextlib.contextmanager -def no_workspace_dir(): - """Force maya to a fake temporary workspace directory. - - Note: This is not maya.cmds.workspace 'rootDirectory' but the 'directory' - - This helps to avoid Maya automatically remapping image paths to files - relative to the currently set directory. - - """ - - # Store current workspace - original = cmds.workspace(query=True, directory=True) - - # Set a fake workspace - fake_workspace_dir = tempfile.mkdtemp() - cmds.workspace(directory=fake_workspace_dir) - - try: - yield - finally: - try: - cmds.workspace(directory=original) - except RuntimeError: - # If the original workspace directory didn't exist either - # ignore the fact that it fails to reset it to the old path - pass - - # Remove the temporary directory - os.rmdir(fake_workspace_dir) - - class ExtractLook(publish.Extractor): """Extract Look (Maya Scene + JSON) From 7f4fe957bc43d6290b63cdc86d4b4844fcd435c4 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 27 Mar 2023 12:02:44 +0200 Subject: [PATCH 69/88] Move `get_oiio_tools_path` import to top of file --- openpype/hosts/maya/plugins/publish/extract_look.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 4e04999e7e..e0869b73e6 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -17,7 +17,7 @@ from maya import cmds # noqa import pyblish.api from openpype.lib.vendor_bin_utils import find_executable -from openpype.lib import source_hash, run_subprocess +from openpype.lib import source_hash, run_subprocess, get_oiio_tools_path from openpype.pipeline import legacy_io, publish, KnownPublishError from openpype.hosts.maya.api import lib from openpype.hosts.maya.api.lib import image_info, guess_colorspace @@ -261,7 +261,6 @@ class MakeTX(TextureProcessor): TextureResult: The resulting texture information. """ - from openpype.lib import get_oiio_tools_path maketx_path = get_oiio_tools_path("maketx") From 39d68780670c2333c0d39ef083331723b501c28d Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 27 Mar 2023 12:30:31 +0200 Subject: [PATCH 70/88] Support flags without values for extra `maketx` arguments - Add todo for hardcoded maketx arguments - Add sourceHash argument at end to increase readability of the log --- .../maya/plugins/publish/extract_look.py | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index e0869b73e6..41d34a7ead 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -236,8 +236,16 @@ class MakeTX(TextureProcessor): ) extra_args = [] for flag, value in extra_args_dict.items(): + if not flag: + self.log.debug("Ignoring empty flag from `maketx_arguments` " + "setting..") + continue + extra_args.append(flag) - extra_args.append(value) + if value.strip(): + # There might be flags without values like --opaque-detect + extra_args.append(value) + self.extra_args = extra_args def process(self, @@ -328,14 +336,6 @@ class MakeTX(TextureProcessor): hash_args.extend(self.extra_args) texture_hash = source_hash(source, *hash_args) - # Exclude these additional arguments from the hashing because - # it is the hash itself - args.extend([ - "--sattrib", - "sourceHash", - texture_hash - ]) - # Ensure folder exists destination = os.path.join(staging_dir, "resources", fname + ".tx") if not os.path.exists(os.path.dirname(destination)): @@ -347,9 +347,12 @@ class MakeTX(TextureProcessor): maketx_path, "-v", # verbose "-u", # update mode + # --checknan doesn't influence the output file but aborts the + # conversion if it finds any. So we can avoid need + "--checknan", + # todo: --unpremult, --oiio, --filter should be in the file hash # unpremultiply before conversion (recommended when alpha present) "--unpremult", - "--checknan", # use oiio-optimized settings for tile-size, planarconfig, metadata "--oiio", "--filter", "lanczos3", @@ -359,6 +362,15 @@ class MakeTX(TextureProcessor): subprocess_args.extend(args) if self.extra_args: subprocess_args.extend(self.extra_args) + + # Add source hash attribute after other arguments for log readability + # Note: argument is excluding from the hash since it is the hash itself + subprocess_args.extend([ + "--sattrib", + "sourceHash", + texture_hash + ]) + subprocess_args.extend(["-o", destination]) self.log.debug(" ".join(subprocess_args)) From db27765637f0213cab4d4d2b8a89d2fb2f147ecd Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 27 Mar 2023 12:31:01 +0200 Subject: [PATCH 71/88] Grammar --- openpype/hosts/maya/plugins/publish/extract_look.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 41d34a7ead..f3d0790e22 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -364,7 +364,7 @@ class MakeTX(TextureProcessor): subprocess_args.extend(self.extra_args) # Add source hash attribute after other arguments for log readability - # Note: argument is excluding from the hash since it is the hash itself + # Note: argument is excluded from the hash since it is the hash itself subprocess_args.extend([ "--sattrib", "sourceHash", From 7dfaa5b4f4cbf4b8e821d0b4af2e78bc5d7bee97 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 27 Mar 2023 12:36:59 +0200 Subject: [PATCH 72/88] Add maketx hardcoded flags to the file hash --- .../hosts/maya/plugins/publish/extract_look.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index f3d0790e22..be3de13b37 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -288,7 +288,15 @@ class MakeTX(TextureProcessor): transfer_mode=COPY ) - args = [] + # Hardcoded default arguments for maketx conversion based on Arnold's + # txManager in Maya + args = [ + # unpremultiply before conversion (recommended when alpha present) + "--unpremult", + # use oiio-optimized settings for tile-size, planarconfig, metadata + "--oiio", + "--filter", "lanczos3", + ] if color_management["enabled"]: config_path = color_management["config"] if not os.path.exists(config_path): @@ -348,14 +356,8 @@ class MakeTX(TextureProcessor): "-v", # verbose "-u", # update mode # --checknan doesn't influence the output file but aborts the - # conversion if it finds any. So we can avoid need + # conversion if it finds any. So we can avoid it for the file hash "--checknan", - # todo: --unpremult, --oiio, --filter should be in the file hash - # unpremultiply before conversion (recommended when alpha present) - "--unpremult", - # use oiio-optimized settings for tile-size, planarconfig, metadata - "--oiio", - "--filter", "lanczos3", source ] From 3444660a982b13cf798b575e9ebecf8f85f49f05 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 27 Mar 2023 13:20:26 +0200 Subject: [PATCH 73/88] Convert to "linear" because it's always available in OIIO if OCIO is disabled or no valid config is found - If OCIO is not enabled (or cannot find a valid configuration, OIIO will at least be able to convert among linear, sRGB, and Rec709.) --- openpype/hosts/maya/plugins/publish/extract_look.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index be3de13b37..5b9b0777a0 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -316,19 +316,15 @@ class MakeTX(TextureProcessor): # managed mode because the collected color space is the color space # attribute of the file node which can be any string whatsoever # but only appears disabled in Attribute Editor. We assume we're - # always converting to linear/Raw if the source file is assumed to + # always converting to linear if the source file is assumed to # be sRGB. - # TODO Without color management do we even know we can do - # "colorconvert" and what config does that end up using since - # colorconvert is a OCIO command line flag for maketx. - # Also, Raw != linear? render_colorspace = "linear" if self._has_arnold(): img_info = image_info(source) color_space = guess_colorspace(img_info) if color_space.lower() == "sRGB": self.log.info("tx: converting sRGB -> linear") - args.extend(["--colorconvert", "sRGB", "Raw"]) + args.extend(["--colorconvert", "sRGB", render_colorspace]) else: self.log.info("tx: texture's colorspace " "is already linear") From 6f015d6d64278b696f861b0b85284ed9e4ca9417 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 27 Mar 2023 13:31:33 +0200 Subject: [PATCH 74/88] Cleanup/refactor based on @fabiaserra comments --- .../maya/plugins/publish/extract_look.py | 39 +++++++++---------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 5b9b0777a0..daf6735660 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -91,6 +91,9 @@ def no_workspace_dir(): @six.add_metaclass(ABCMeta) class TextureProcessor: + + extension = None + def __init__(self, log=None): if log is None: log = logging.getLogger(self.__class__.__name__) @@ -136,10 +139,6 @@ class TextureProcessor: """ pass - @staticmethod - def get_extension(): - pass - def __repr__(self): # Log instance as class name return self.__class__.__name__ @@ -148,6 +147,8 @@ class TextureProcessor: class MakeRSTexBin(TextureProcessor): """Make `.rstexbin` using `redshiftTextureProcessor`""" + extension = ".rstexbin" + def process(self, source, colorspace, @@ -171,7 +172,7 @@ class MakeRSTexBin(TextureProcessor): # Redshift stores the output texture next to the input but with # the extension replaced to `.rstexbin` basename, ext = os.path.splitext(source) - destination = "{}{}".format(basename, self.get_extension()) + destination = "{}{}".format(basename, self.extension) self.log.debug(" ".join(subprocess_args)) try: @@ -188,10 +189,6 @@ class MakeRSTexBin(TextureProcessor): transfer_mode=COPY ) - @staticmethod - def get_extension(): - return ".rstexbin" - @staticmethod def get_redshift_tool(tool_name): """Path to redshift texture processor. @@ -224,6 +221,8 @@ class MakeTX(TextureProcessor): """ + extension = ".tx" + def __init__(self, log=None): super(MakeTX, self).__init__(log=log) self.extra_args = [] @@ -335,15 +334,13 @@ class MakeTX(TextureProcessor): # Note: The texture hash is only reliable if we include any potential # conversion arguments provide to e.g. `maketx` - hash_args = ["maketx"] - hash_args.extend(args) - hash_args.extend(self.extra_args) + hash_args = ["maketx"] + args + self.extra_args texture_hash = source_hash(source, *hash_args) # Ensure folder exists - destination = os.path.join(staging_dir, "resources", fname + ".tx") - if not os.path.exists(os.path.dirname(destination)): - os.makedirs(os.path.dirname(destination)) + resources_dir = os.path.join(staging_dir, "resources") + if not os.path.exists(resources_dir): + os.makedirs(resources_dir) self.log.info("Generating .tx file for %s .." % source) @@ -369,6 +366,7 @@ class MakeTX(TextureProcessor): texture_hash ]) + destination = os.path.join(resources_dir, fname + ".tx") subprocess_args.extend(["-o", destination]) self.log.debug(" ".join(subprocess_args)) @@ -386,10 +384,6 @@ class MakeTX(TextureProcessor): transfer_mode=COPY ) - @staticmethod - def get_extension(): - return ".tx" - @staticmethod def _has_arnold(): """Return whether the arnold package is available and importable.""" @@ -748,7 +742,7 @@ class ExtractLook(publish.Extractor): # Get extension from the last processor for processor in reversed(processors): - processor_ext = processor.get_extension() + processor_ext = processor.extension if processor_ext and ext != processor_ext: self.log.debug("Processor {} overrides extension to '{}' " "for path: {}".format(processor, @@ -785,9 +779,12 @@ class ExtractLook(publish.Extractor): color_management, colorspace): """Process a single texture file on disk for publishing. + This will: 1. Check whether it's already published, if so it will do hardlink - 2. If not published and maketx is enabled, generate a new .tx file. + (if the texture hash is found and force copy is not enabled) + 2. It will process the texture using the supplied texture + processors like MakeTX and MakeRSTexBin if enabled. 3. Compute the destination path for the source file. Args: From e11d1f279ac03da71158075b1793b7b673303cab Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 27 Mar 2023 13:46:33 +0200 Subject: [PATCH 75/88] Add assumption for some file formats to be sRGB: `.png`, `.jpeg` and `.jpg` --- .../maya/plugins/publish/extract_look.py | 36 +++++++++++++------ 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index daf6735660..9c360c8dd4 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -26,6 +26,10 @@ from openpype.hosts.maya.api.lib import image_info, guess_colorspace COPY = 1 HARDLINK = 2 +# File formats we will assume are sRGB when Maya Color Management is disabled +# Currently only used for `maketx` color conversion logic +NONLINEAR_FILE_FORMATS = {".png", ".jpeg", ".jpg"} + @attr.s class TextureResult: @@ -311,6 +315,7 @@ class MakeTX(TextureProcessor): args.extend(["--colorconfig", config_path]) else: + self.log.debug("Maya color management is disabled..") # We can't rely on the colorspace attribute when not in color # managed mode because the collected color space is the color space # attribute of the file node which can be any string whatsoever @@ -318,19 +323,28 @@ class MakeTX(TextureProcessor): # always converting to linear if the source file is assumed to # be sRGB. render_colorspace = "linear" - if self._has_arnold(): + assumed_input_colorspace = "linear" + if ext.lower() in NONLINEAR_FILE_FORMATS: + assumed_input_colorspace = "sRGB" + elif self._has_arnold(): + # Assume colorspace based on input image bit-depth img_info = image_info(source) - color_space = guess_colorspace(img_info) - if color_space.lower() == "sRGB": - self.log.info("tx: converting sRGB -> linear") - args.extend(["--colorconvert", "sRGB", render_colorspace]) - else: - self.log.info("tx: texture's colorspace " - "is already linear") + assumed_input_colorspace = guess_colorspace(img_info) else: - self.log.warning("tx: cannot guess the colorspace, " - "color conversion won't be " - "available!") + self.log.warning("tx: cannot guess the colorspace, a linear " + "colorspace will be assumed for file: " + "{}".format(source)) + + if assumed_input_colorspace == "sRGB": + self.log.info("tx: converting sRGB -> linear") + args.extend(["--colorconvert", "sRGB", render_colorspace]) + elif assumed_input_colorspace == "linear": + self.log.info("tx: texture's colorspace " + "is already linear") + else: + self.log.warning("Unexpected texture color space: {} " + "(expected either 'linear' or 'sRGB')" + "".format(assumed_input_colorspace)) # Note: The texture hash is only reliable if we include any potential # conversion arguments provide to e.g. `maketx` From bf60e7370453831d4ee3f89a32fd435091450ef3 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 27 Mar 2023 13:47:26 +0200 Subject: [PATCH 76/88] Remove `.png` from nonlinear formats assumption because apparently they can be 32-bit --- openpype/hosts/maya/plugins/publish/extract_look.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 9c360c8dd4..c68ce56fcc 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -28,7 +28,7 @@ HARDLINK = 2 # File formats we will assume are sRGB when Maya Color Management is disabled # Currently only used for `maketx` color conversion logic -NONLINEAR_FILE_FORMATS = {".png", ".jpeg", ".jpg"} +NONLINEAR_FILE_FORMATS = {".jpeg", ".jpg"} @attr.s From 5ed6c29eee6531eaa5dde107a98a777ce091f232 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 27 Mar 2023 15:23:14 +0200 Subject: [PATCH 77/88] Mimic Arnold tx manager behavior whenever maya color management is disabled - Do no color conversion when color management is disabled --- .../maya/plugins/publish/extract_look.py | 42 +++++-------------- 1 file changed, 11 insertions(+), 31 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index c68ce56fcc..7405eb1a9f 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -315,36 +315,10 @@ class MakeTX(TextureProcessor): args.extend(["--colorconfig", config_path]) else: - self.log.debug("Maya color management is disabled..") - # We can't rely on the colorspace attribute when not in color - # managed mode because the collected color space is the color space - # attribute of the file node which can be any string whatsoever - # but only appears disabled in Attribute Editor. We assume we're - # always converting to linear if the source file is assumed to - # be sRGB. - render_colorspace = "linear" - assumed_input_colorspace = "linear" - if ext.lower() in NONLINEAR_FILE_FORMATS: - assumed_input_colorspace = "sRGB" - elif self._has_arnold(): - # Assume colorspace based on input image bit-depth - img_info = image_info(source) - assumed_input_colorspace = guess_colorspace(img_info) - else: - self.log.warning("tx: cannot guess the colorspace, a linear " - "colorspace will be assumed for file: " - "{}".format(source)) - - if assumed_input_colorspace == "sRGB": - self.log.info("tx: converting sRGB -> linear") - args.extend(["--colorconvert", "sRGB", render_colorspace]) - elif assumed_input_colorspace == "linear": - self.log.info("tx: texture's colorspace " - "is already linear") - else: - self.log.warning("Unexpected texture color space: {} " - "(expected either 'linear' or 'sRGB')" - "".format(assumed_input_colorspace)) + # Maya Color management is disabled. We cannot rely on an OCIO + self.log.debug("tx: Maya color management is disabled. No color " + "conversion will be applied to .tx conversion for: " + "{}".format(source)) # Note: The texture hash is only reliable if we include any potential # conversion arguments provide to e.g. `maketx` @@ -383,9 +357,15 @@ class MakeTX(TextureProcessor): destination = os.path.join(resources_dir, fname + ".tx") subprocess_args.extend(["-o", destination]) + # We want to make sure we are explicit about what OCIO config gets + # used. So when we supply no --colorconfig flag that no fallback to + # an OCIO env var occurs. + env = os.environ.copy() + env.pop("OCIO", None) + self.log.debug(" ".join(subprocess_args)) try: - run_subprocess(subprocess_args) + run_subprocess(subprocess_args, env=env) except Exception: self.log.error("Texture maketx conversion failed", exc_info=True) From 2cb03b75b74ee145dba5f28b90f09861fe7b350a Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 27 Mar 2023 15:35:03 +0200 Subject: [PATCH 78/88] Clean up imports a bit. --- .../maya/plugins/publish/extract_look.py | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 7405eb1a9f..e939992454 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -1,26 +1,24 @@ # -*- coding: utf-8 -*- """Maya look extractor.""" -import logging from abc import ABCMeta, abstractmethod - -import six -import os -import json -import tempfile -import platform -import contextlib from collections import OrderedDict +import contextlib +import json +import logging +import os +import platform +import tempfile +import six import attr -from maya import cmds # noqa - import pyblish.api +from maya import cmds # noqa + from openpype.lib.vendor_bin_utils import find_executable from openpype.lib import source_hash, run_subprocess, get_oiio_tools_path from openpype.pipeline import legacy_io, publish, KnownPublishError from openpype.hosts.maya.api import lib -from openpype.hosts.maya.api.lib import image_info, guess_colorspace # Modes for transfer COPY = 1 From 108bcd8f27acd3d6b632c9df969357f1cee9773b Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 27 Mar 2023 15:37:27 +0200 Subject: [PATCH 79/88] Fix missing variable declaration --- openpype/hosts/maya/plugins/publish/extract_look.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index e939992454..9599f9f809 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -317,6 +317,8 @@ class MakeTX(TextureProcessor): self.log.debug("tx: Maya color management is disabled. No color " "conversion will be applied to .tx conversion for: " "{}".format(source)) + # Assume linear + render_colorspace = "linear" # Note: The texture hash is only reliable if we include any potential # conversion arguments provide to e.g. `maketx` From 22dbc4e4fa5227db80fda932f4b9b10a76ba64bd Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 27 Mar 2023 15:40:33 +0200 Subject: [PATCH 80/88] Remove unused variable `NONLINEAR_FILE_FORMATS` --- openpype/hosts/maya/plugins/publish/extract_look.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 9599f9f809..1e339542d7 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -24,10 +24,6 @@ from openpype.hosts.maya.api import lib COPY = 1 HARDLINK = 2 -# File formats we will assume are sRGB when Maya Color Management is disabled -# Currently only used for `maketx` color conversion logic -NONLINEAR_FILE_FORMATS = {".jpeg", ".jpg"} - @attr.s class TextureResult: From 421048083164e549a69bdc16e248b33d7cc0c71f Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 29 Mar 2023 12:51:07 +0200 Subject: [PATCH 81/88] Refactor ExtractLook maketx argument in settings to more structured arguments/parameters --- .../maya/plugins/publish/extract_look.py | 20 +++++++++---------- .../defaults/project_settings/maya.json | 2 +- .../schemas/schema_maya_publish.json | 17 ++++++++++++++-- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 1e339542d7..93054e5fbb 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -227,21 +227,21 @@ class MakeTX(TextureProcessor): def apply_settings(self, system_settings, project_settings): # Allow extra maketx arguments from project settings - extra_args_dict = ( + args_settings = ( project_settings["maya"]["publish"] - .get("ExtractLook", {}).get("maketx_arguments", {}) + .get("ExtractLook", {}).get("maketx_arguments", []) ) extra_args = [] - for flag, value in extra_args_dict.items(): - if not flag: - self.log.debug("Ignoring empty flag from `maketx_arguments` " - "setting..") + for arg_data in args_settings: + argument = arg_data["argument"] + parameters = arg_data["parameters"] + if not argument: + self.log.debug("Ignoring empty parameter from " + "`maketx_arguments` setting..") continue - extra_args.append(flag) - if value.strip(): - # There might be flags without values like --opaque-detect - extra_args.append(value) + extra_args.append(argument) + extra_args.extend(parameters) self.extra_args = extra_args diff --git a/openpype/settings/defaults/project_settings/maya.json b/openpype/settings/defaults/project_settings/maya.json index 26dd66770f..8f5a3c75ab 100644 --- a/openpype/settings/defaults/project_settings/maya.json +++ b/openpype/settings/defaults/project_settings/maya.json @@ -928,7 +928,7 @@ "ogsfx_path": "/maya2glTF/PBR/shaders/glTF_PBR.ogsfx" }, "ExtractLook": { - "maketx_arguments": {} + "maketx_arguments": [] } }, "load": { 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 da12dde6b2..7ced375cb5 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 @@ -1004,11 +1004,24 @@ "label": "Extract Look", "children": [ { + "type": "list", "key": "maketx_arguments", "label": "Extra arguments for maketx command line", - "type": "dict-modifiable", "object_type": { - "type": "text" + "type": "dict", + "children": [ + { + "key": "argument", + "label": "Argument", + "type": "text" + }, + { + "key": "parameters", + "label": "Parameters", + "type": "list", + "object_type": "text" + } + ] } } ] From 3fae1f852194ee0b7ce69ca584c2f4605a3e1147 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 30 Mar 2023 13:59:22 +0200 Subject: [PATCH 82/88] Just some grammar tweaks --- openpype/client/entities.py | 8 +-- openpype/client/notes.md | 4 +- openpype/client/operations.py | 10 ++-- openpype/host/dirmap.py | 4 +- openpype/host/host.py | 6 +-- openpype/host/interfaces.py | 8 +-- .../api/extension/jsx/hostscript.jsx | 2 +- openpype/hosts/aftereffects/api/ws_stub.py | 2 +- openpype/hosts/blender/api/ops.py | 2 +- .../plugins/publish/extract_playblast.py | 2 +- openpype/hosts/flame/api/lib.py | 4 +- openpype/hosts/flame/api/pipeline.py | 2 +- openpype/hosts/flame/api/plugin.py | 54 +++++++++---------- .../hosts/flame/api/scripts/wiretap_com.py | 2 +- openpype/hosts/flame/api/utils.py | 2 +- openpype/hosts/flame/hooks/pre_flame_setup.py | 2 +- .../flame/plugins/create/create_shot_clip.py | 2 +- .../hosts/flame/plugins/load/load_clip.py | 6 +-- .../flame/plugins/load/load_clip_batch.py | 8 +-- .../publish/collect_timeline_instances.py | 4 +- .../publish/extract_subset_resources.py | 4 +- .../plugins/publish/integrate_batch_group.py | 2 +- openpype/hosts/harmony/api/README.md | 8 +-- openpype/hosts/harmony/api/TB_sceneOpened.js | 10 ++-- openpype/hosts/harmony/api/lib.py | 6 +-- openpype/hosts/harmony/api/server.py | 2 +- .../harmony/vendor/OpenHarmony/README.md | 6 +-- .../harmony/vendor/OpenHarmony/openHarmony.js | 8 +-- .../openHarmony/openHarmony_actions.js | 6 +-- .../openHarmony/openHarmony_application.js | 6 +-- .../openHarmony/openHarmony_attribute.js | 8 +-- .../openHarmony/openHarmony_backdrop.js | 4 +- .../openHarmony/openHarmony_color.js | 6 +-- .../openHarmony/openHarmony_column.js | 4 +- .../openHarmony/openHarmony_database.js | 4 +- .../openHarmony/openHarmony_dialog.js | 18 +++---- .../openHarmony/openHarmony_drawing.js | 18 +++---- .../openHarmony/openHarmony_element.js | 4 +- .../openHarmony/openHarmony_file.js | 6 +-- .../openHarmony/openHarmony_frame.js | 10 ++-- .../openHarmony/openHarmony_list.js | 6 +-- .../openHarmony/openHarmony_math.js | 16 +++--- .../openHarmony/openHarmony_metadata.js | 4 +- .../openHarmony/openHarmony_misc.js | 6 +-- .../openHarmony/openHarmony_network.js | 8 +-- .../openHarmony/openHarmony_node.js | 22 ++++---- .../openHarmony/openHarmony_nodeLink.js | 24 ++++----- .../vendor/OpenHarmony/openHarmony_tools.js | 8 +-- .../harmony/vendor/OpenHarmony/package.json | 2 +- openpype/hosts/hiero/api/__init__.py | 2 +- openpype/hosts/hiero/api/pipeline.py | 4 +- openpype/hosts/hiero/api/plugin.py | 26 ++++----- openpype/hosts/houdini/api/plugin.py | 2 +- openpype/hosts/houdini/api/shelves.py | 2 +- .../houdini/plugins/create/convert_legacy.py | 4 +- openpype/hosts/maya/api/commands.py | 2 +- openpype/hosts/maya/api/lib_renderproducts.py | 4 +- .../maya/api/workfile_template_builder.py | 4 +- openpype/hosts/maya/plugins/load/actions.py | 2 +- .../maya/plugins/load/load_arnold_standin.py | 2 +- .../publish/collect_multiverse_look.py | 2 +- .../maya/plugins/publish/extract_look.py | 2 +- .../publish/extract_multiverse_usd_over.py | 2 +- .../plugins/publish/reset_xgen_attributes.py | 2 +- .../publish/validate_camera_attributes.py | 2 +- .../plugins/publish/validate_maya_units.py | 4 +- .../publish/validate_mvlook_contents.py | 2 +- .../publish/validate_renderlayer_aovs.py | 4 +- .../validate_transform_naming_suffix.py | 2 +- openpype/hosts/nuke/api/lib.py | 18 +++---- openpype/hosts/nuke/api/plugin.py | 4 +- openpype/hosts/nuke/api/utils.py | 2 +- .../nuke/api/workfile_template_builder.py | 10 ++-- .../nuke/plugins/create/convert_legacy.py | 2 +- .../nuke/plugins/create/create_source.py | 2 +- .../nuke/plugins/publish/collect_writes.py | 2 +- .../nuke/plugins/publish/validate_backdrop.py | 2 +- .../photoshop/api/extension/host/index.jsx | 6 +-- openpype/hosts/resolve/api/lib.py | 6 +-- openpype/hosts/resolve/api/menu_style.qss | 2 +- openpype/hosts/resolve/api/plugin.py | 16 +++--- .../publish/collect_bulk_mov_instances.py | 4 +- .../plugins/publish/collect_context.py | 4 +- .../plugins/publish/collect_editorial.py | 2 +- .../plugins/publish/validate_frame_ranges.py | 2 +- openpype/hosts/traypublisher/api/editorial.py | 38 ++++++------- .../plugins/create/create_editorial.py | 14 ++--- .../publish/collect_simple_instances.py | 2 +- .../help/validate_layers_visibility.xml | 2 +- .../help/validate_workfile_metadata.xml | 2 +- .../help/validate_workfile_project_name.xml | 2 +- .../plugins/publish/validate_asset_name.py | 2 +- openpype/hosts/unreal/api/pipeline.py | 2 +- .../Source/OpenPype/Private/OpenPypeLib.cpp | 2 +- .../Public/Commandlets/OPActionResult.h | 12 ++--- .../Source/OpenPype/Private/OpenPypeLib.cpp | 2 +- .../Public/Commandlets/OPActionResult.h | 12 ++--- .../hosts/unreal/plugins/load/load_camera.py | 2 +- openpype/hosts/webpublisher/lib.py | 2 +- openpype/lib/applications.py | 2 +- openpype/lib/attribute_definitions.py | 6 +-- openpype/lib/events.py | 2 +- openpype/lib/execute.py | 2 +- openpype/lib/file_transaction.py | 2 +- openpype/lib/transcoding.py | 6 +-- openpype/lib/vendor_bin_utils.py | 4 +- openpype/modules/base.py | 14 ++--- openpype/modules/clockify/clockify_api.py | 2 +- openpype/modules/clockify/clockify_module.py | 2 +- openpype/modules/clockify/widgets.py | 2 +- .../plugins/publish/submit_nuke_deadline.py | 2 +- .../plugins/publish/submit_publish_job.py | 16 +++--- .../action_clone_review_session.py | 2 +- .../action_create_review_session.py | 2 +- .../action_prepare_project.py | 2 +- .../action_tranfer_hierarchical_values.py | 4 +- .../event_next_task_update.py | 2 +- .../event_push_frame_values_to_task.py | 2 +- .../event_radio_buttons.py | 2 +- .../event_sync_to_avalon.py | 14 ++--- .../event_task_to_parent_status.py | 4 +- .../event_user_assigment.py | 4 +- .../event_version_to_task_statuses.py | 2 +- .../action_batch_task_creation.py | 2 +- .../action_create_cust_attrs.py | 6 +-- .../action_create_folders.py | 2 +- .../action_delete_asset.py | 2 +- .../action_delete_old_versions.py | 4 +- .../event_handlers_user/action_delivery.py | 2 +- .../action_fill_workfile_attr.py | 2 +- .../event_handlers_user/action_job_killer.py | 6 +-- .../action_prepare_project.py | 4 +- .../ftrack/event_handlers_user/action_rv.py | 2 +- .../ftrack/event_handlers_user/action_seed.py | 10 ++-- .../action_store_thumbnails_to_avalon.py | 2 +- .../ftrack/ftrack_server/event_server_cli.py | 6 +-- openpype/modules/ftrack/lib/avalon_sync.py | 12 ++--- .../modules/ftrack/lib/custom_attributes.py | 2 +- .../ftrack/lib/ftrack_action_handler.py | 2 +- .../modules/ftrack/lib/ftrack_base_handler.py | 4 +- .../publish/collect_custom_attributes_data.py | 2 +- .../plugins/publish/integrate_ftrack_api.py | 2 +- .../publish/integrate_hierarchy_ftrack.py | 2 +- openpype/modules/ftrack/tray/ftrack_tray.py | 2 +- openpype/modules/interfaces.py | 2 +- openpype/modules/settings_action.py | 6 +-- openpype/pipeline/colorspace.py | 2 +- openpype/plugins/publish/extract_review.py | 2 +- .../schemas/schema_global_publish.json | 2 +- .../publisher/widgets/validations_widget.py | 4 +- 150 files changed, 412 insertions(+), 412 deletions(-) diff --git a/openpype/client/entities.py b/openpype/client/entities.py index c415be8816..7054658c64 100644 --- a/openpype/client/entities.py +++ b/openpype/client/entities.py @@ -3,7 +3,7 @@ Goal is that most of functions here are called on (or with) an object that has project name as a context (e.g. on 'ProjectEntity'?). -+ We will need more specific functions doing wery specific queires really fast. ++ We will need more specific functions doing very specific queries really fast. """ import re @@ -193,7 +193,7 @@ def _get_assets( be found. asset_names (Iterable[str]): Name assets that should be found. parent_ids (Iterable[Union[str, ObjectId]]): Parent asset ids. - standard (bool): Query standart assets (type 'asset'). + standard (bool): Query standard assets (type 'asset'). archived (bool): Query archived assets (type 'archived_asset'). fields (Iterable[str]): Fields that should be returned. All fields are returned if 'None' is passed. @@ -1185,7 +1185,7 @@ def get_representations( standard=True, fields=None ): - """Representaion entities data from one project filtered by filters. + """Representation entities data from one project filtered by filters. Filters are additive (all conditions must pass to return subset). @@ -1231,7 +1231,7 @@ def get_archived_representations( names_by_version_ids=None, fields=None ): - """Archived representaion entities data from project with applied filters. + """Archived representation entities data from project with applied filters. Filters are additive (all conditions must pass to return subset). diff --git a/openpype/client/notes.md b/openpype/client/notes.md index a261b86eca..59743892eb 100644 --- a/openpype/client/notes.md +++ b/openpype/client/notes.md @@ -2,7 +2,7 @@ ## Reason Preparation for OpenPype v4 server. Goal is to remove direct mongo calls in code to prepare a little bit for different source of data for code before. To start think about database calls less as mongo calls but more universally. To do so was implemented simple wrapper around database calls to not use pymongo specific code. -Current goal is not to make universal database model which can be easily replaced with any different source of data but to make it close as possible. Current implementation of OpenPype is too tighly connected to pymongo and it's abilities so we're trying to get closer with long term changes that can be used even in current state. +Current goal is not to make universal database model which can be easily replaced with any different source of data but to make it close as possible. Current implementation of OpenPype is too tightly connected to pymongo and it's abilities so we're trying to get closer with long term changes that can be used even in current state. ## Queries Query functions don't use full potential of mongo queries like very specific queries based on subdictionaries or unknown structures. We try to avoid these calls as much as possible because they'll probably won't be available in future. If it's really necessary a new function can be added but only if it's reasonable for overall logic. All query functions were moved to `~/client/entities.py`. Each function has arguments with available filters and possible reduce of returned keys for each entity. @@ -14,7 +14,7 @@ Changes are a little bit complicated. Mongo has many options how update can happ Create operations expect already prepared document data, for that are prepared functions creating skeletal structures of documents (do not fill all required data), except `_id` all data should be right. Existence of entity is not validated so if the same creation operation is send n times it will create the entity n times which can cause issues. ### Update -Update operation require entity id and keys that should be changed, update dictionary must have {"key": value}. If value should be set in nested dictionary the key must have also all subkeys joined with dot `.` (e.g. `{"data": {"fps": 25}}` -> `{"data.fps": 25}`). To simplify update dictionaries were prepared functions which does that for you, their name has template `prepare__update_data` - they work on comparison of previous document and new document. If there is missing function for requested entity type it is because we didn't need it yet and require implementaion. +Update operation require entity id and keys that should be changed, update dictionary must have {"key": value}. If value should be set in nested dictionary the key must have also all subkeys joined with dot `.` (e.g. `{"data": {"fps": 25}}` -> `{"data.fps": 25}`). To simplify update dictionaries were prepared functions which does that for you, their name has template `prepare__update_data` - they work on comparison of previous document and new document. If there is missing function for requested entity type it is because we didn't need it yet and require implementation. ### Delete Delete operation need entity id. Entity will be deleted from mongo. diff --git a/openpype/client/operations.py b/openpype/client/operations.py index fd639c34a7..ef48f2a1c4 100644 --- a/openpype/client/operations.py +++ b/openpype/client/operations.py @@ -368,7 +368,7 @@ def prepare_workfile_info_update_data(old_doc, new_doc, replace=True): class AbstractOperation(object): """Base operation class. - Opration represent a call into database. The call can create, change or + Operation represent a call into database. The call can create, change or remove data. Args: @@ -409,7 +409,7 @@ class AbstractOperation(object): pass def to_data(self): - """Convert opration to data that can be converted to json or others. + """Convert operation to data that can be converted to json or others. Warning: Current state returns ObjectId objects which cannot be parsed by @@ -428,7 +428,7 @@ class AbstractOperation(object): class CreateOperation(AbstractOperation): - """Opeartion to create an entity. + """Operation to create an entity. Args: project_name (str): On which project operation will happen. @@ -485,7 +485,7 @@ class CreateOperation(AbstractOperation): class UpdateOperation(AbstractOperation): - """Opeartion to update an entity. + """Operation to update an entity. Args: project_name (str): On which project operation will happen. @@ -552,7 +552,7 @@ class UpdateOperation(AbstractOperation): class DeleteOperation(AbstractOperation): - """Opeartion to delete an entity. + """Operation to delete an entity. Args: project_name (str): On which project operation will happen. diff --git a/openpype/host/dirmap.py b/openpype/host/dirmap.py index 1d084cccad..42bf80ecec 100644 --- a/openpype/host/dirmap.py +++ b/openpype/host/dirmap.py @@ -2,7 +2,7 @@ Idea for current dirmap implementation was used from Maya where is possible to enter source and destination roots and maya will try each found source -in referenced file replace with each destionation paths. First path which +in referenced file replace with each destination paths. First path which exists is used. """ @@ -183,7 +183,7 @@ class HostDirmap(object): project_name, remote_site ) # dirmap has sense only with regular disk provider, in the workfile - # wont be root on cloud or sftp provider + # won't be root on cloud or sftp provider if remote_provider != "local_drive": remote_site = "studio" for root_name, active_site_dir in active_overrides.items(): diff --git a/openpype/host/host.py b/openpype/host/host.py index d2335c0062..630fb873a8 100644 --- a/openpype/host/host.py +++ b/openpype/host/host.py @@ -18,7 +18,7 @@ class HostBase(object): Compared to 'avalon' concept: What was before considered as functions in host implementation folder. The host implementation should primarily care about adding ability of creation - (mark subsets to be published) and optionaly about referencing published + (mark subsets to be published) and optionally about referencing published representations as containers. Host may need extend some functionality like working with workfiles @@ -129,9 +129,9 @@ class HostBase(object): """Get current context information. This method should be used to get current context of host. Usage of - this method can be crutial for host implementations in DCCs where + this method can be crucial for host implementations in DCCs where can be opened multiple workfiles at one moment and change of context - can't be catched properly. + can't be caught properly. Default implementation returns values from 'legacy_io.Session'. diff --git a/openpype/host/interfaces.py b/openpype/host/interfaces.py index 999aefd254..39581a3c69 100644 --- a/openpype/host/interfaces.py +++ b/openpype/host/interfaces.py @@ -81,7 +81,7 @@ class ILoadHost: @abstractmethod def get_containers(self): - """Retreive referenced containers from scene. + """Retrieve referenced containers from scene. This can be implemented in hosts where referencing can be used. @@ -191,7 +191,7 @@ class IWorkfileHost: @abstractmethod def get_current_workfile(self): - """Retreive path to current opened file. + """Retrieve path to current opened file. Returns: str: Path to file which is currently opened. @@ -220,7 +220,7 @@ class IWorkfileHost: Default implementation keeps workdir untouched. Warnings: - We must handle this modification with more sofisticated way because + We must handle this modification with more sophisticated way because this can't be called out of DCC so opening of last workfile (calculated before DCC is launched) is complicated. Also breaking defined work template is not a good idea. @@ -302,7 +302,7 @@ class IPublishHost: required methods. Returns: - list[str]: Missing method implementations for new publsher + list[str]: Missing method implementations for new publisher workflow. """ diff --git a/openpype/hosts/aftereffects/api/extension/jsx/hostscript.jsx b/openpype/hosts/aftereffects/api/extension/jsx/hostscript.jsx index 9b211207de..5c1d163439 100644 --- a/openpype/hosts/aftereffects/api/extension/jsx/hostscript.jsx +++ b/openpype/hosts/aftereffects/api/extension/jsx/hostscript.jsx @@ -504,7 +504,7 @@ function addItemAsLayerToComp(comp_id, item_id, found_comp){ * Args: * comp_id (int): id of target composition * item_id (int): FootageItem.id - * found_comp (CompItem, optional): to limit quering if + * found_comp (CompItem, optional): to limit querying if * comp already found previously */ var comp = found_comp || app.project.itemByID(comp_id); diff --git a/openpype/hosts/aftereffects/api/ws_stub.py b/openpype/hosts/aftereffects/api/ws_stub.py index e5d6d9ed89..f094c7fa2a 100644 --- a/openpype/hosts/aftereffects/api/ws_stub.py +++ b/openpype/hosts/aftereffects/api/ws_stub.py @@ -80,7 +80,7 @@ class AfterEffectsServerStub(): Get complete stored JSON with metadata from AE.Metadata.Label field. - It contains containers loaded by any Loader OR instances creted + It contains containers loaded by any Loader OR instances created by Creator. Returns: diff --git a/openpype/hosts/blender/api/ops.py b/openpype/hosts/blender/api/ops.py index 158c32fb5a..91cbfe524f 100644 --- a/openpype/hosts/blender/api/ops.py +++ b/openpype/hosts/blender/api/ops.py @@ -24,7 +24,7 @@ from .workio import OpenFileCacher PREVIEW_COLLECTIONS: Dict = dict() # This seems like a good value to keep the Qt app responsive and doesn't slow -# down Blender. At least on macOS I the interace of Blender gets very laggy if +# down Blender. At least on macOS I the interface of Blender gets very laggy if # you make it smaller. TIMER_INTERVAL: float = 0.01 if platform.system() == "Windows" else 0.1 diff --git a/openpype/hosts/blender/plugins/publish/extract_playblast.py b/openpype/hosts/blender/plugins/publish/extract_playblast.py index 8dc2f66c22..5c3a138c3a 100644 --- a/openpype/hosts/blender/plugins/publish/extract_playblast.py +++ b/openpype/hosts/blender/plugins/publish/extract_playblast.py @@ -50,7 +50,7 @@ class ExtractPlayblast(publish.Extractor): # get isolate objects list isolate = instance.data("isolate", None) - # get ouput path + # get output path stagingdir = self.staging_dir(instance) filename = instance.name path = os.path.join(stagingdir, filename) diff --git a/openpype/hosts/flame/api/lib.py b/openpype/hosts/flame/api/lib.py index 6aca5c5ce6..ab713aed84 100644 --- a/openpype/hosts/flame/api/lib.py +++ b/openpype/hosts/flame/api/lib.py @@ -773,7 +773,7 @@ class MediaInfoFile(object): if logger: self.log = logger - # test if `dl_get_media_info` paht exists + # test if `dl_get_media_info` path exists self._validate_media_script_path() # derivate other feed variables @@ -993,7 +993,7 @@ class MediaInfoFile(object): def _validate_media_script_path(self): if not os.path.isfile(self.MEDIA_SCRIPT_PATH): - raise IOError("Media Scirpt does not exist: `{}`".format( + raise IOError("Media Script does not exist: `{}`".format( self.MEDIA_SCRIPT_PATH)) def _generate_media_info_file(self, fpath, feed_ext, feed_dir): diff --git a/openpype/hosts/flame/api/pipeline.py b/openpype/hosts/flame/api/pipeline.py index 3a23389961..d6fbf750ba 100644 --- a/openpype/hosts/flame/api/pipeline.py +++ b/openpype/hosts/flame/api/pipeline.py @@ -38,7 +38,7 @@ def install(): pyblish.register_plugin_path(PUBLISH_PATH) register_loader_plugin_path(LOAD_PATH) register_creator_plugin_path(CREATE_PATH) - log.info("OpenPype Flame plug-ins registred ...") + log.info("OpenPype Flame plug-ins registered ...") # register callback for switching publishable pyblish.register_callback("instanceToggled", on_pyblish_instance_toggled) diff --git a/openpype/hosts/flame/api/plugin.py b/openpype/hosts/flame/api/plugin.py index 983d7486b3..df8c1ac887 100644 --- a/openpype/hosts/flame/api/plugin.py +++ b/openpype/hosts/flame/api/plugin.py @@ -157,7 +157,7 @@ class CreatorWidget(QtWidgets.QDialog): # convert label text to normal capitalized text with spaces label_text = self.camel_case_split(text) - # assign the new text to lable widget + # assign the new text to label widget label = QtWidgets.QLabel(label_text) label.setObjectName("LineLabel") @@ -345,8 +345,8 @@ class PublishableClip: "track": "sequence", } - # parents search patern - parents_search_patern = r"\{([a-z]*?)\}" + # parents search pattern + parents_search_pattern = r"\{([a-z]*?)\}" # default templates for non-ui use rename_default = False @@ -445,7 +445,7 @@ class PublishableClip: return self.current_segment def _populate_segment_default_data(self): - """ Populate default formating data from segment. """ + """ Populate default formatting data from segment. """ self.current_segment_default_data = { "_folder_": "shots", @@ -538,7 +538,7 @@ class PublishableClip: if not self.index_from_segment: self.count_steps *= self.rename_index - hierarchy_formating_data = {} + hierarchy_formatting_data = {} hierarchy_data = deepcopy(self.hierarchy_data) _data = self.current_segment_default_data.copy() if self.ui_inputs: @@ -552,7 +552,7 @@ class PublishableClip: # mark review layer if self.review_track and ( self.review_track not in self.review_track_default): - # if review layer is defined and not the same as defalut + # if review layer is defined and not the same as default self.review_layer = self.review_track # shot num calculate @@ -578,13 +578,13 @@ class PublishableClip: # fill up pythonic expresisons in hierarchy data for k, _v in hierarchy_data.items(): - hierarchy_formating_data[k] = _v["value"].format(**_data) + hierarchy_formatting_data[k] = _v["value"].format(**_data) else: # if no gui mode then just pass default data - hierarchy_formating_data = hierarchy_data + hierarchy_formatting_data = hierarchy_data tag_hierarchy_data = self._solve_tag_hierarchy_data( - hierarchy_formating_data + hierarchy_formatting_data ) tag_hierarchy_data.update({"heroTrack": True}) @@ -615,27 +615,27 @@ class PublishableClip: # in case track name and subset name is the same then add if self.subset_name == self.track_name: _hero_data["subset"] = self.subset - # assing data to return hierarchy data to tag + # assign data to return hierarchy data to tag tag_hierarchy_data = _hero_data break # add data to return data dict self.marker_data.update(tag_hierarchy_data) - def _solve_tag_hierarchy_data(self, hierarchy_formating_data): + def _solve_tag_hierarchy_data(self, hierarchy_formatting_data): """ Solve marker data from hierarchy data and templates. """ # fill up clip name and hierarchy keys - hierarchy_filled = self.hierarchy.format(**hierarchy_formating_data) - clip_name_filled = self.clip_name.format(**hierarchy_formating_data) + hierarchy_filled = self.hierarchy.format(**hierarchy_formatting_data) + clip_name_filled = self.clip_name.format(**hierarchy_formatting_data) # remove shot from hierarchy data: is not needed anymore - hierarchy_formating_data.pop("shot") + hierarchy_formatting_data.pop("shot") return { "newClipName": clip_name_filled, "hierarchy": hierarchy_filled, "parents": self.parents, - "hierarchyData": hierarchy_formating_data, + "hierarchyData": hierarchy_formatting_data, "subset": self.subset, "family": self.subset_family, "families": [self.family] @@ -650,17 +650,17 @@ class PublishableClip: type ) - # first collect formating data to use for formating template - formating_data = {} + # first collect formatting data to use for formatting template + formatting_data = {} for _k, _v in self.hierarchy_data.items(): value = _v["value"].format( **self.current_segment_default_data) - formating_data[_k] = value + formatting_data[_k] = value return { "entity_type": entity_type, "entity_name": template.format( - **formating_data + **formatting_data ) } @@ -668,9 +668,9 @@ class PublishableClip: """ Create parents and return it in list. """ self.parents = [] - patern = re.compile(self.parents_search_patern) + pattern = re.compile(self.parents_search_pattern) - par_split = [(patern.findall(t).pop(), t) + par_split = [(pattern.findall(t).pop(), t) for t in self.hierarchy.split("/")] for type, template in par_split: @@ -902,22 +902,22 @@ class OpenClipSolver(flib.MediaInfoFile): ): return - formating_data = self._update_formating_data( + formatting_data = self._update_formatting_data( layerName=layer_name, layerUID=layer_uid ) name_obj.text = StringTemplate( self.layer_rename_template - ).format(formating_data) + ).format(formatting_data) - def _update_formating_data(self, **kwargs): - """ Updating formating data for layer rename + def _update_formatting_data(self, **kwargs): + """ Updating formatting data for layer rename Attributes: - key=value (optional): will be included to formating data + key=value (optional): will be included to formatting data as {key: value} Returns: - dict: anatomy context data for formating + dict: anatomy context data for formatting """ self.log.debug(">> self.clip_data: {}".format(self.clip_data)) clip_name_obj = self.clip_data.find("name") diff --git a/openpype/hosts/flame/api/scripts/wiretap_com.py b/openpype/hosts/flame/api/scripts/wiretap_com.py index 4825ff4386..a74172c405 100644 --- a/openpype/hosts/flame/api/scripts/wiretap_com.py +++ b/openpype/hosts/flame/api/scripts/wiretap_com.py @@ -203,7 +203,7 @@ class WireTapCom(object): list: all available volumes in server Rises: - AttributeError: unable to get any volumes childs from server + AttributeError: unable to get any volumes children from server """ root = WireTapNodeHandle(self._server, "/volumes") children_num = WireTapInt(0) diff --git a/openpype/hosts/flame/api/utils.py b/openpype/hosts/flame/api/utils.py index fb8bdee42d..80a5c47e89 100644 --- a/openpype/hosts/flame/api/utils.py +++ b/openpype/hosts/flame/api/utils.py @@ -108,7 +108,7 @@ def _sync_utility_scripts(env=None): shutil.copy2(src, dst) except (PermissionError, FileExistsError) as msg: log.warning( - "Not able to coppy to: `{}`, Problem with: `{}`".format( + "Not able to copy to: `{}`, Problem with: `{}`".format( dst, msg ) diff --git a/openpype/hosts/flame/hooks/pre_flame_setup.py b/openpype/hosts/flame/hooks/pre_flame_setup.py index 713daf1031..8034885c47 100644 --- a/openpype/hosts/flame/hooks/pre_flame_setup.py +++ b/openpype/hosts/flame/hooks/pre_flame_setup.py @@ -153,7 +153,7 @@ class FlamePrelaunch(PreLaunchHook): def _add_pythonpath(self): pythonpath = self.launch_context.env.get("PYTHONPATH") - # separate it explicity by `;` that is what we use in settings + # separate it explicitly by `;` that is what we use in settings new_pythonpath = self.flame_pythonpath.split(os.pathsep) new_pythonpath += pythonpath.split(os.pathsep) diff --git a/openpype/hosts/flame/plugins/create/create_shot_clip.py b/openpype/hosts/flame/plugins/create/create_shot_clip.py index 4fb041a4b2..b01354c313 100644 --- a/openpype/hosts/flame/plugins/create/create_shot_clip.py +++ b/openpype/hosts/flame/plugins/create/create_shot_clip.py @@ -209,7 +209,7 @@ class CreateShotClip(opfapi.Creator): "type": "QComboBox", "label": "Subset Name", "target": "ui", - "toolTip": "chose subset name patern, if [ track name ] is selected, name of track layer will be used", # noqa + "toolTip": "chose subset name pattern, if [ track name ] is selected, name of track layer will be used", # noqa "order": 0}, "subsetFamily": { "value": ["plate", "take"], diff --git a/openpype/hosts/flame/plugins/load/load_clip.py b/openpype/hosts/flame/plugins/load/load_clip.py index 25b31c94a3..dfb2d2b6f0 100644 --- a/openpype/hosts/flame/plugins/load/load_clip.py +++ b/openpype/hosts/flame/plugins/load/load_clip.py @@ -61,9 +61,9 @@ class LoadClip(opfapi.ClipLoader): self.layer_rename_template = self.layer_rename_template.replace( "output", "representation") - formating_data = deepcopy(context["representation"]["context"]) + formatting_data = deepcopy(context["representation"]["context"]) clip_name = StringTemplate(self.clip_name_template).format( - formating_data) + formatting_data) # convert colorspace with ocio to flame mapping # in imageio flame section @@ -88,7 +88,7 @@ class LoadClip(opfapi.ClipLoader): "version": "v{:0>3}".format(version_name), "layer_rename_template": self.layer_rename_template, "layer_rename_patterns": self.layer_rename_patterns, - "context_data": formating_data + "context_data": formatting_data } self.log.debug(pformat( loading_context diff --git a/openpype/hosts/flame/plugins/load/load_clip_batch.py b/openpype/hosts/flame/plugins/load/load_clip_batch.py index 86bc0f8f1e..5c5a77f0d0 100644 --- a/openpype/hosts/flame/plugins/load/load_clip_batch.py +++ b/openpype/hosts/flame/plugins/load/load_clip_batch.py @@ -58,11 +58,11 @@ class LoadClipBatch(opfapi.ClipLoader): self.layer_rename_template = self.layer_rename_template.replace( "output", "representation") - formating_data = deepcopy(context["representation"]["context"]) - formating_data["batch"] = self.batch.name.get_value() + formatting_data = deepcopy(context["representation"]["context"]) + formatting_data["batch"] = self.batch.name.get_value() clip_name = StringTemplate(self.clip_name_template).format( - formating_data) + formatting_data) # convert colorspace with ocio to flame mapping # in imageio flame section @@ -88,7 +88,7 @@ class LoadClipBatch(opfapi.ClipLoader): "version": "v{:0>3}".format(version_name), "layer_rename_template": self.layer_rename_template, "layer_rename_patterns": self.layer_rename_patterns, - "context_data": formating_data + "context_data": formatting_data } self.log.debug(pformat( loading_context diff --git a/openpype/hosts/flame/plugins/publish/collect_timeline_instances.py b/openpype/hosts/flame/plugins/publish/collect_timeline_instances.py index 76d48dded2..23fdf5e785 100644 --- a/openpype/hosts/flame/plugins/publish/collect_timeline_instances.py +++ b/openpype/hosts/flame/plugins/publish/collect_timeline_instances.py @@ -203,7 +203,7 @@ class CollectTimelineInstances(pyblish.api.ContextPlugin): self._get_xml_preset_attrs( attributes, split) - # add xml overides resolution to instance data + # add xml overrides resolution to instance data xml_overrides = attributes["xml_overrides"] if xml_overrides.get("width"): attributes.update({ @@ -284,7 +284,7 @@ class CollectTimelineInstances(pyblish.api.ContextPlugin): self.log.debug("__ head: `{}`".format(head)) self.log.debug("__ tail: `{}`".format(tail)) - # HACK: it is here to serve for versions bellow 2021.1 + # HACK: it is here to serve for versions below 2021.1 if not any([head, tail]): retimed_attributes = get_media_range_with_retimes( otio_clip, handle_start, handle_end) diff --git a/openpype/hosts/flame/plugins/publish/extract_subset_resources.py b/openpype/hosts/flame/plugins/publish/extract_subset_resources.py index 5082217db0..a7979ab4d5 100644 --- a/openpype/hosts/flame/plugins/publish/extract_subset_resources.py +++ b/openpype/hosts/flame/plugins/publish/extract_subset_resources.py @@ -227,7 +227,7 @@ class ExtractSubsetResources(publish.Extractor): self.hide_others( exporting_clip, segment_name, s_track_name) - # change name patern + # change name pattern name_patern_xml = ( "__{}.").format( unique_name) @@ -358,7 +358,7 @@ class ExtractSubsetResources(publish.Extractor): representation_data["stagingDir"] = n_stage_dir files = n_files - # add files to represetation but add + # add files to representation but add # imagesequence as list if ( # first check if path in files is not mov extension diff --git a/openpype/hosts/flame/plugins/publish/integrate_batch_group.py b/openpype/hosts/flame/plugins/publish/integrate_batch_group.py index 4d45f67ded..4f3945bb0f 100644 --- a/openpype/hosts/flame/plugins/publish/integrate_batch_group.py +++ b/openpype/hosts/flame/plugins/publish/integrate_batch_group.py @@ -50,7 +50,7 @@ class IntegrateBatchGroup(pyblish.api.InstancePlugin): self._load_clip_to_context(instance, bgroup) def _add_nodes_to_batch_with_links(self, instance, task_data, batch_group): - # get write file node properties > OrederDict because order does mater + # get write file node properties > OrederDict because order does matter write_pref_data = self._get_write_prefs(instance, task_data) batch_nodes = [ diff --git a/openpype/hosts/harmony/api/README.md b/openpype/hosts/harmony/api/README.md index b39f900886..12f21f551a 100644 --- a/openpype/hosts/harmony/api/README.md +++ b/openpype/hosts/harmony/api/README.md @@ -432,11 +432,11 @@ copy_files = """function copyFile(srcFilename, dstFilename) import_files = """function %s_import_files() { - var PNGTransparencyMode = 0; // Premultiplied wih Black - var TGATransparencyMode = 0; // Premultiplied wih Black - var SGITransparencyMode = 0; // Premultiplied wih Black + var PNGTransparencyMode = 0; // Premultiplied with Black + var TGATransparencyMode = 0; // Premultiplied with Black + var SGITransparencyMode = 0; // Premultiplied with Black var LayeredPSDTransparencyMode = 1; // Straight - var FlatPSDTransparencyMode = 2; // Premultiplied wih White + var FlatPSDTransparencyMode = 2; // Premultiplied with White function getUniqueColumnName( column_prefix ) { diff --git a/openpype/hosts/harmony/api/TB_sceneOpened.js b/openpype/hosts/harmony/api/TB_sceneOpened.js index e7cd555332..6614f14f9e 100644 --- a/openpype/hosts/harmony/api/TB_sceneOpened.js +++ b/openpype/hosts/harmony/api/TB_sceneOpened.js @@ -142,10 +142,10 @@ function Client() { }; /** - * Process recieved request. This will eval recieved function and produce + * Process received request. This will eval received function and produce * results. * @function - * @param {object} request - recieved request JSON + * @param {object} request - received request JSON * @return {object} result of evaled function. */ self.processRequest = function(request) { @@ -245,7 +245,7 @@ function Client() { var request = JSON.parse(to_parse); var mid = request.message_id; // self.logDebug('[' + mid + '] - Request: ' + '\n' + JSON.stringify(request)); - self.logDebug('[' + mid + '] Recieved.'); + self.logDebug('[' + mid + '] Received.'); request.result = self.processRequest(request); self.logDebug('[' + mid + '] Processing done.'); @@ -286,8 +286,8 @@ function Client() { /** Harmony 21.1 doesn't have QDataStream anymore. This means we aren't able to write bytes into QByteArray so we had - modify how content lenght is sent do the server. - Content lenght is sent as string of 8 char convertible into integer + modify how content length is sent do the server. + Content length is sent as string of 8 char convertible into integer (instead of 0x00000001[4 bytes] > "000000001"[8 bytes]) */ var codec_name = new QByteArray().append("UTF-8"); diff --git a/openpype/hosts/harmony/api/lib.py b/openpype/hosts/harmony/api/lib.py index e1e77bfbee..8048705dc8 100644 --- a/openpype/hosts/harmony/api/lib.py +++ b/openpype/hosts/harmony/api/lib.py @@ -394,7 +394,7 @@ def get_scene_data(): "function": "AvalonHarmony.getSceneData" })["result"] except json.decoder.JSONDecodeError: - # Means no sceen metadata has been made before. + # Means no scene metadata has been made before. return {} except KeyError: # Means no existing scene metadata has been made. @@ -465,7 +465,7 @@ def imprint(node_id, data, remove=False): Example: >>> from openpype.hosts.harmony.api import lib >>> node = "Top/Display" - >>> data = {"str": "someting", "int": 1, "float": 0.32, "bool": True} + >>> data = {"str": "something", "int": 1, "float": 0.32, "bool": True} >>> lib.imprint(layer, data) """ scene_data = get_scene_data() @@ -550,7 +550,7 @@ def save_scene(): method prevents this double request and safely saves the scene. """ - # Need to turn off the backgound watcher else the communication with + # Need to turn off the background watcher else the communication with # the server gets spammed with two requests at the same time. scene_path = send( {"function": "AvalonHarmony.saveScene"})["result"] diff --git a/openpype/hosts/harmony/api/server.py b/openpype/hosts/harmony/api/server.py index ecf339d91b..04048e5c84 100644 --- a/openpype/hosts/harmony/api/server.py +++ b/openpype/hosts/harmony/api/server.py @@ -61,7 +61,7 @@ class Server(threading.Thread): "module": (str), # Module of method. "method" (str), # Name of method in module. "args" (list), # Arguments to pass to method. - "kwargs" (dict), # Keywork arguments to pass to method. + "kwargs" (dict), # Keyword arguments to pass to method. "reply" (bool), # Optional wait for method completion. } """ diff --git a/openpype/hosts/harmony/vendor/OpenHarmony/README.md b/openpype/hosts/harmony/vendor/OpenHarmony/README.md index 7c77fbfcfa..064afca86c 100644 --- a/openpype/hosts/harmony/vendor/OpenHarmony/README.md +++ b/openpype/hosts/harmony/vendor/OpenHarmony/README.md @@ -6,7 +6,7 @@ Ever tried to make a simple script for toonboom Harmony, then got stumped by the Toonboom Harmony is a very powerful software, with hundreds of functions and tools, and it unlocks a great amount of possibilities for animation studios around the globe. And... being the produce of the hard work of a small team forced to prioritise, it can also be a bit rustic at times! -We are users at heart, animators and riggers, who just want to interact with the software as simply as possible. Simplicity is at the heart of the design of openHarmony. But we also are developpers, and we made the library for people like us who can't resist tweaking the software and bend it in all possible ways, and are looking for powerful functions to help them do it. +We are users at heart, animators and riggers, who just want to interact with the software as simply as possible. Simplicity is at the heart of the design of openHarmony. But we also are developers, and we made the library for people like us who can't resist tweaking the software and bend it in all possible ways, and are looking for powerful functions to help them do it. This library's aim is to create a more direct way to interact with Toonboom through scripts, by providing a more intuitive way to access its elements, and help with the cumbersome and repetitive tasks as well as help unlock untapped potential in its many available systems. So we can go from having to do things like this: @@ -78,7 +78,7 @@ All you have to do is call : ```javascript include("openHarmony.js"); ``` -at the beggining of your script. +at the beginning of your script. You can ask your users to download their copy of the library and store it alongside, or bundle it as you wish as long as you include the license file provided on this repository. @@ -129,7 +129,7 @@ Check that the environment variable `LIB_OPENHARMONY_PATH` is set correctly to t ## How to add openHarmony to vscode intellisense for autocompletion Although not fully supported, you can get most of the autocompletion features to work by adding the following lines to a `jsconfig.json` file placed at the root of your working folder. -The paths need to be relative which means the openHarmony source code must be placed directly in your developping environnement. +The paths need to be relative which means the openHarmony source code must be placed directly in your developping environment. For example, if your working folder contains the openHarmony source in a folder called `OpenHarmony` and your working scripts in a folder called `myScripts`, place the `jsconfig.json` file at the root of the folder and add these lines to the file: diff --git a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony.js b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony.js index 530c0902c5..ae65d32a2b 100644 --- a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony.js +++ b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony.js @@ -4,7 +4,7 @@ // openHarmony Library // // -// Developped by Mathieu Chaptel, Chris Fourney +// Developed by Mathieu Chaptel, Chris Fourney // // // This library is an open source implementation of a Document Object Model @@ -16,7 +16,7 @@ // and by hiding the heavy lifting required by the official API. // // This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is garanteed to work. Feel free to contribute +// function has been implemented or is guaranteed to work. Feel free to contribute // improvements to its official github. If you do make sure you follow the provided // template and naming conventions and document your new methods properly. // @@ -78,7 +78,7 @@ * $.log("hello"); // prints out a message to the MessageLog. * var myPoint = new $.oPoint(0,0,0); // create a new class instance from an openHarmony class. * - * // function members of the $ objects get published to the global scope, which means $ can be ommited + * // function members of the $ objects get published to the global scope, which means $ can be omitted * * log("hello"); * var myPoint = new oPoint(0,0,0); // This is all valid @@ -118,7 +118,7 @@ Object.defineProperty( $, "directory", { /** - * Wether Harmony is run with the interface or simply from command line + * Whether Harmony is run with the interface or simply from command line */ Object.defineProperty( $, "batchMode", { get: function(){ diff --git a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_actions.js b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_actions.js index ad1efc91be..a54f74e147 100644 --- a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_actions.js +++ b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_actions.js @@ -4,7 +4,7 @@ // openHarmony Library // // -// Developped by Mathieu Chaptel, Chris Fourney +// Developed by Mathieu Chaptel, Chris Fourney // // // This library is an open source implementation of a Document Object Model @@ -16,7 +16,7 @@ // and by hiding the heavy lifting required by the official API. // // This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is garanteed to work. Feel free to contribute +// function has been implemented or is guaranteed to work. Feel free to contribute // improvements to its official github. If you do make sure you follow the provided // template and naming conventions and document your new methods properly. // @@ -67,7 +67,7 @@ * @hideconstructor * @namespace * @example - * // To check wether an action is available, call the synthax: + * // To check whether an action is available, call the synthax: * Action.validate (, ); * * // To launch an action, call the synthax: diff --git a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_application.js b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_application.js index 9e9acb766c..5809cee694 100644 --- a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_application.js +++ b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_application.js @@ -4,7 +4,7 @@ // openHarmony Library // // -// Developped by Mathieu Chaptel, Chris Fourney +// Developed by Mathieu Chaptel, Chris Fourney // // // This library is an open source implementation of a Document Object Model @@ -16,7 +16,7 @@ // and by hiding the heavy lifting required by the official API. // // This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is garanteed to work. Feel free to contribute +// function has been implemented or is guaranteed to work. Feel free to contribute // improvements to its official github. If you do make sure you follow the provided // template and naming conventions and document your new methods properly. // @@ -409,7 +409,7 @@ $.oApp.prototype.getToolByName = function(toolName){ /** - * returns the list of stencils useable by the specified tool + * returns the list of stencils usable by the specified tool * @param {$.oTool} tool the tool object we want valid stencils for * @return {$.oStencil[]} the list of stencils compatible with the specified tool */ diff --git a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_attribute.js b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_attribute.js index d4d2d791ae..fa044d5b74 100644 --- a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_attribute.js +++ b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_attribute.js @@ -4,7 +4,7 @@ // openHarmony Library v0.01 // // -// Developped by Mathieu Chaptel, Chris Fourney... +// Developed by Mathieu Chaptel, Chris Fourney... // // // This library is an open source implementation of a Document Object Model @@ -16,7 +16,7 @@ // and by hiding the heavy lifting required by the official API. // // This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is garanteed to work. Feel free to contribute +// function has been implemented or is guaranteed to work. Feel free to contribute // improvements to its official github. If you do make sure you follow the provided // template and naming conventions and document your new methods properly. // @@ -338,7 +338,7 @@ Object.defineProperty($.oAttribute.prototype, "useSeparate", { * Returns the default value of the attribute for most keywords * @name $.oAttribute#defaultValue * @type {bool} - * @todo switch the implentation to types? + * @todo switch the implementation to types? * @example * // to reset an attribute to its default value: * // (mostly used for position/angle/skew parameters of pegs and drawing nodes) @@ -449,7 +449,7 @@ $.oAttribute.prototype.getLinkedColumns = function(){ /** * Recursively sets an attribute to the same value as another. Both must have the same keyword. - * @param {bool} [duplicateColumns=false] In the case that the attribute has a column, wether to duplicate the column before linking + * @param {bool} [duplicateColumns=false] In the case that the attribute has a column, whether to duplicate the column before linking * @private */ $.oAttribute.prototype.setToAttributeValue = function(attributeToCopy, duplicateColumns){ diff --git a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_backdrop.js b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_backdrop.js index c98e194539..1d359f93c4 100644 --- a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_backdrop.js +++ b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_backdrop.js @@ -4,7 +4,7 @@ // openHarmony Library // // -// Developped by Mathieu Chaptel, Chris Fourney +// Developed by Mathieu Chaptel, Chris Fourney // // // This library is an open source implementation of a Document Object Model @@ -16,7 +16,7 @@ // and by hiding the heavy lifting required by the official API. // // This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is garanteed to work. Feel free to contribute +// function has been implemented or is guaranteed to work. Feel free to contribute // improvements to its official github. If you do make sure you follow the provided // template and naming conventions and document your new methods properly. // diff --git a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_color.js b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_color.js index 7726be6cd6..ff06688e66 100644 --- a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_color.js +++ b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_color.js @@ -4,7 +4,7 @@ // openHarmony Library // // -// Developped by Mathieu Chaptel, Chris Fourney +// Developed by Mathieu Chaptel, Chris Fourney // // // This library is an open source implementation of a Document Object Model @@ -16,7 +16,7 @@ // and by hiding the heavy lifting required by the official API. // // This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is garanteed to work. Feel free to contribute +// function has been implemented or is guaranteed to work. Feel free to contribute // improvements to its official github. If you do make sure you follow the provided // template and naming conventions and document your new methods properly. // @@ -158,7 +158,7 @@ $.oColorValue.prototype.fromColorString = function (hexString){ /** - * Uses a color integer (used in backdrops) and parses the INT; applies the RGBA components of the INT to thos oColorValue + * Uses a color integer (used in backdrops) and parses the INT; applies the RGBA components of the INT to the oColorValue * @param { int } colorInt 24 bit-shifted integer containing RGBA values */ $.oColorValue.prototype.parseColorFromInt = function(colorInt){ diff --git a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_column.js b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_column.js index 1b73c7943e..f73309049e 100644 --- a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_column.js +++ b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_column.js @@ -4,7 +4,7 @@ // openHarmony Library // // -// Developped by Mathieu Chaptel, Chris Fourney +// Developed by Mathieu Chaptel, Chris Fourney // // // This library is an open source implementation of a Document Object Model @@ -16,7 +16,7 @@ // and by hiding the heavy lifting required by the official API. // // This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is garanteed to work. Feel free to contribute +// function has been implemented or is guaranteed to work. Feel free to contribute // improvements to its official github. If you do make sure you follow the provided // template and naming conventions and document your new methods properly. // diff --git a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_database.js b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_database.js index 73964c5c38..5440b92875 100644 --- a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_database.js +++ b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_database.js @@ -4,7 +4,7 @@ // openHarmony Library // // -// Developped by Mathieu Chaptel, Chris Fourney +// Developed by Mathieu Chaptel, Chris Fourney // // // This library is an open source implementation of a Document Object Model @@ -16,7 +16,7 @@ // and by hiding the heavy lifting required by the official API. // // This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is garanteed to work. Feel free to contribute +// function has been implemented or is guaranteed to work. Feel free to contribute // improvements to its official github. If you do make sure you follow the provided // template and naming conventions and document your new methods properly. // diff --git a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_dialog.js b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_dialog.js index a6e16ecb78..3ab78b87d6 100644 --- a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_dialog.js +++ b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_dialog.js @@ -5,7 +5,7 @@ // openHarmony Library // // -// Developped by Mathieu Chaptel, Chris Fourney +// Developed by Mathieu Chaptel, Chris Fourney // // // This library is an open source implementation of a Document Object Model @@ -17,7 +17,7 @@ // and by hiding the heavy lifting required by the official API. // // This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is garanteed to work. Feel free to contribute +// function has been implemented or is guaranteed to work. Feel free to contribute // improvements to its official github. If you do make sure you follow the provided // template and naming conventions and document your new methods properly. // @@ -250,7 +250,7 @@ $.oDialog.prototype.prompt = function( labelText, title, prefilledText){ /** * Prompts with a file selector window * @param {string} [text="Select a file:"] The title of the confirmation dialog. - * @param {string} [filter="*"] The filter for the file type and/or file name that can be selected. Accepts wildcard charater "*". + * @param {string} [filter="*"] The filter for the file type and/or file name that can be selected. Accepts wildcard character "*". * @param {string} [getExisting=true] Whether to select an existing file or a save location * @param {string} [acceptMultiple=false] Whether or not selecting more than one file is ok. Is ignored if getExisting is falses. * @param {string} [startDirectory] The directory showed at the opening of the dialog. @@ -327,14 +327,14 @@ $.oDialog.prototype.browseForFolder = function(text, startDirectory){ * @constructor * @classdesc An simple progress dialog to display the progress of a task. * To react to the user clicking the cancel button, connect a function to $.oProgressDialog.canceled() signal. - * When $.batchmode is true, the progress will be outputed as a "Progress : value/range" string to the Harmony stdout. + * When $.batchmode is true, the progress will be outputted as a "Progress : value/range" string to the Harmony stdout. * @param {string} [labelText] The text displayed above the progress bar. * @param {string} [range=100] The maximum value that represents a full progress bar. * @param {string} [title] The title of the dialog * @param {bool} [show=false] Whether to immediately show the dialog. * * @property {bool} wasCanceled Whether the progress bar was cancelled. - * @property {$.oSignal} canceled A Signal emited when the dialog is canceled. Can be connected to a callback. + * @property {$.oSignal} canceled A Signal emitted when the dialog is canceled. Can be connected to a callback. */ $.oProgressDialog = function( labelText, range, title, show ){ if (typeof title === 'undefined') var title = "Progress"; @@ -608,7 +608,7 @@ $.oPieMenu = function( name, widgets, show, minAngle, maxAngle, radius, position this.maxAngle = maxAngle; this.globalCenter = position; - // how wide outisde the icons is the slice drawn + // how wide outside the icons is the slice drawn this._circleMargin = 30; // set these values before calling show() to customize the menu appearance @@ -974,7 +974,7 @@ $.oPieMenu.prototype.getMenuRadius = function(){ var _minRadius = UiLoader.dpiScale(30); var _speed = 10; // the higher the value, the slower the progression - // hyperbolic tangent function to determin the radius + // hyperbolic tangent function to determine the radius var exp = Math.exp(2*itemsNumber/_speed); var _radius = ((exp-1)/(exp+1))*_maxRadius+_minRadius; @@ -1383,7 +1383,7 @@ $.oActionButton.prototype.activate = function(){ * This class is a subclass of QPushButton and all the methods from that class are available to modify this button. * @param {string} paletteName The name of the palette that contains the color * @param {string} colorName The name of the color (if more than one is present, will pick the first match) - * @param {bool} showName Wether to display the name of the color on the button + * @param {bool} showName Whether to display the name of the color on the button * @param {QWidget} parent The parent QWidget for the button. Automatically set during initialisation of the menu. * */ @@ -1437,7 +1437,7 @@ $.oColorButton.prototype.activate = function(){ * @name $.oScriptButton * @constructor * @classdescription This subclass of QPushButton provides an easy way to create a button for a widget that will launch a function from another script file.
- * The buttons created this way automatically load the icon named after the script if it finds one named like the funtion in a script-icons folder next to the script file.
+ * The buttons created this way automatically load the icon named after the script if it finds one named like the function in a script-icons folder next to the script file.
* It will also automatically set the callback to lanch the function from the script.
* This class is a subclass of QPushButton and all the methods from that class are available to modify this button. * @param {string} scriptFile The path to the script file that will be launched diff --git a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_drawing.js b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_drawing.js index bad735f237..6f2bc19c0c 100644 --- a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_drawing.js +++ b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_drawing.js @@ -4,7 +4,7 @@ // openHarmony Library // // -// Developped by Mathieu Chaptel, Chris Fourney +// Developed by Mathieu Chaptel, Chris Fourney // // // This library is an open source implementation of a Document Object Model @@ -16,7 +16,7 @@ // and by hiding the heavy lifting required by the official API. // // This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is garanteed to work. Feel free to contribute +// function has been implemented or is guaranteed to work. Feel free to contribute // improvements to its official github. If you do make sure you follow the provided // template and naming conventions and document your new methods properly. // @@ -426,7 +426,7 @@ Object.defineProperty($.oDrawing.prototype, 'drawingData', { /** * Import a given file into an existing drawing. * @param {$.oFile} file The path to the file - * @param {bool} [convertToTvg=false] Wether to convert the bitmap to the tvg format (this doesn't vectorise the drawing) + * @param {bool} [convertToTvg=false] Whether to convert the bitmap to the tvg format (this doesn't vectorise the drawing) * * @return { $.oFile } the oFile object pointing to the drawing file after being it has been imported into the element folder. */ @@ -878,8 +878,8 @@ $.oArtLayer.prototype.drawCircle = function(center, radius, lineStyle, fillStyle * @param {$.oVertex[]} path an array of $.oVertex objects that describe a path. * @param {$.oLineStyle} [lineStyle] the line style to draw with. (By default, will use the current stencil selection) * @param {$.oFillStyle} [fillStyle] the fill information for the path. (By default, will use the current palette selection) - * @param {bool} [polygon] Wether bezier handles should be created for the points in the path (ignores "onCurve" properties of oVertex from path) - * @param {bool} [createUnderneath] Wether the new shape will appear on top or underneath the contents of the layer. (not working yet) + * @param {bool} [polygon] Whether bezier handles should be created for the points in the path (ignores "onCurve" properties of oVertex from path) + * @param {bool} [createUnderneath] Whether the new shape will appear on top or underneath the contents of the layer. (not working yet) */ $.oArtLayer.prototype.drawShape = function(path, lineStyle, fillStyle, polygon, createUnderneath){ if (typeof fillStyle === 'undefined') var fillStyle = new this.$.oFillStyle(); @@ -959,7 +959,7 @@ $.oArtLayer.prototype.drawContour = function(path, fillStyle){ * @param {float} width the width of the rectangle. * @param {float} height the height of the rectangle. * @param {$.oLineStyle} lineStyle a line style to use for the rectangle stroke. - * @param {$.oFillStyle} fillStyle a fill style to use for the rectange fill. + * @param {$.oFillStyle} fillStyle a fill style to use for the rectangle fill. * @returns {$.oShape} the shape containing the added stroke. */ $.oArtLayer.prototype.drawRectangle = function(x, y, width, height, lineStyle, fillStyle){ @@ -1514,7 +1514,7 @@ Object.defineProperty($.oStroke.prototype, "path", { /** - * The oVertex that are on the stroke (Bezier handles exluded.) + * The oVertex that are on the stroke (Bezier handles excluded.) * The first is repeated at the last position when the stroke is closed. * @name $.oStroke#points * @type {$.oVertex[]} @@ -1583,7 +1583,7 @@ Object.defineProperty($.oStroke.prototype, "style", { /** - * wether the stroke is a closed shape. + * whether the stroke is a closed shape. * @name $.oStroke#closed * @type {bool} */ @@ -1919,7 +1919,7 @@ $.oContour.prototype.toString = function(){ * @constructor * @classdesc * The $.oVertex class represents a single control point on a stroke. This class is used to get the index of the point in the stroke path sequence, as well as its position as a float along the stroke's length. - * The onCurve property describes wether this control point is a bezier handle or a point on the curve. + * The onCurve property describes whether this control point is a bezier handle or a point on the curve. * * @param {$.oStroke} stroke the stroke that this vertex belongs to * @param {float} x the x coordinate of the vertex, in drawing space diff --git a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_element.js b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_element.js index ed50d6e50b..b64c8169ec 100644 --- a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_element.js +++ b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_element.js @@ -4,7 +4,7 @@ // openHarmony Library v0.01 // // -// Developped by Mathieu Chaptel, Chris Fourney... +// Developed by Mathieu Chaptel, Chris Fourney... // // // This library is an open source implementation of a Document Object Model @@ -16,7 +16,7 @@ // and by hiding the heavy lifting required by the official API. // // This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is garanteed to work. Feel free to contribute +// function has been implemented or is guaranteed to work. Feel free to contribute // improvements to its official github. If you do make sure you follow the provided // template and naming conventions and document your new methods properly. // diff --git a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_file.js b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_file.js index 14dafa3b63..50e4b0d475 100644 --- a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_file.js +++ b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_file.js @@ -4,7 +4,7 @@ // openHarmony Library // // -// Developped by Mathieu Chaptel, Chris Fourney +// Developed by Mathieu Chaptel, Chris Fourney // // // This library is an open source implementation of a Document Object Model @@ -16,7 +16,7 @@ // and by hiding the heavy lifting required by the official API. // // This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is garanteed to work. Feel free to contribute +// function has been implemented or is guaranteed to work. Feel free to contribute // improvements to its official github. If you do make sure you follow the provided // template and naming conventions and document your new methods properly. // @@ -509,7 +509,7 @@ Object.defineProperty($.oFile.prototype, 'fullName', { /** - * The name of the file without extenstion. + * The name of the file without extension. * @name $.oFile#name * @type {string} */ diff --git a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_frame.js b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_frame.js index 37bdede02a..e1d1dd7fad 100644 --- a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_frame.js +++ b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_frame.js @@ -4,7 +4,7 @@ // openHarmony Library // // -// Developped by Mathieu Chaptel, Chris Fourney +// Developed by Mathieu Chaptel, Chris Fourney // // // This library is an open source implementation of a Document Object Model @@ -16,7 +16,7 @@ // and by hiding the heavy lifting required by the official API. // // This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is garanteed to work. Feel free to contribute +// function has been implemented or is guaranteed to work. Feel free to contribute // improvements to its official github. If you do make sure you follow the provided // template and naming conventions and document your new methods properly. // @@ -263,7 +263,7 @@ Object.defineProperty($.oFrame.prototype, 'duration', { return _sceneLength; } - // walk up the frames of the scene to the next keyFrame to determin duration + // walk up the frames of the scene to the next keyFrame to determine duration var _frames = this.column.frames for (var i=this.frameNumber+1; i<_sceneLength; i++){ if (_frames[i].isKeyframe) return _frames[i].frameNumber - _startFrame; @@ -426,7 +426,7 @@ Object.defineProperty($.oFrame.prototype, 'velocity', { * easeIn : a $.oPoint object representing the left handle for bezier columns, or a {point, ease} object for ease columns. * easeOut : a $.oPoint object representing the left handle for bezier columns, or a {point, ease} object for ease columns. * continuity : the type of bezier used by the point. - * constant : wether the frame is interpolated or a held value. + * constant : whether the frame is interpolated or a held value. * @name $.oFrame#ease * @type {oPoint/object} */ @@ -520,7 +520,7 @@ Object.defineProperty($.oFrame.prototype, 'easeOut', { /** - * Determines the frame's continuity setting. Can take the values "CORNER", (two independant bezier handles on each side), "SMOOTH"(handles are aligned) or "STRAIGHT" (no handles and in straight lines). + * Determines the frame's continuity setting. Can take the values "CORNER", (two independent bezier handles on each side), "SMOOTH"(handles are aligned) or "STRAIGHT" (no handles and in straight lines). * @name $.oFrame#continuity * @type {string} */ diff --git a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_list.js b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_list.js index 9d02b1c2aa..63a5c0eeb8 100644 --- a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_list.js +++ b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_list.js @@ -4,7 +4,7 @@ // openHarmony Library v0.01 // // -// Developped by Mathieu Chaptel, Chris Fourney... +// Developed by Mathieu Chaptel, Chris Fourney... // // // This library is an open source implementation of a Document Object Model @@ -16,7 +16,7 @@ // and by hiding the heavy lifting required by the official API. // // This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is garanteed to work. Feel free to contribute +// function has been implemented or is guaranteed to work. Feel free to contribute // improvements to its official github. If you do make sure you follow the provided // template and naming conventions and document your new methods properly. // @@ -516,5 +516,5 @@ Object.defineProperty($.oList.prototype, 'toString', { -//Needs all filtering, limiting. mapping, pop, concat, join, ect +//Needs all filtering, limiting. mapping, pop, concat, join, etc //Speed up by finessing the way it extends and tracks the enumerable properties. \ No newline at end of file diff --git a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_math.js b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_math.js index c0d4ca99a7..06bfb51f30 100644 --- a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_math.js +++ b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_math.js @@ -4,7 +4,7 @@ // openHarmony Library // // -// Developped by Mathieu Chaptel, Chris Fourney +// Developed by Mathieu Chaptel, Chris Fourney // // // This library is an open source implementation of a Document Object Model @@ -16,7 +16,7 @@ // and by hiding the heavy lifting required by the official API. // // This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is garanteed to work. Feel free to contribute +// function has been implemented or is guaranteed to work. Feel free to contribute // improvements to its official github. If you do make sure you follow the provided // template and naming conventions and document your new methods properly. // @@ -193,7 +193,7 @@ $.oPoint.prototype.pointSubtract = function( sub_pt ){ /** * Subtracts the point to the coordinates of the current oPoint and returns a new oPoint with the result. * @param {$.oPoint} point The point to subtract to this point. - * @returns {$.oPoint} a new independant oPoint. + * @returns {$.oPoint} a new independent oPoint. */ $.oPoint.prototype.subtractPoint = function( point ){ var x = this.x - point.x; @@ -298,9 +298,9 @@ $.oPoint.prototype.convertToWorldspace = function(){ /** - * Linearily Interpolate between this (0.0) and the provided point (1.0) + * Linearly Interpolate between this (0.0) and the provided point (1.0) * @param {$.oPoint} point The target point at 100% - * @param {double} perc 0-1.0 value to linearily interp + * @param {double} perc 0-1.0 value to linearly interp * * @return: { $.oPoint } The interpolated value. */ @@ -410,9 +410,9 @@ $.oBox.prototype.include = function(box){ /** - * Checks wether the box contains another $.oBox. + * Checks whether the box contains another $.oBox. * @param {$.oBox} box The $.oBox to check for. - * @param {bool} [partial=false] wether to accept partially contained boxes. + * @param {bool} [partial=false] whether to accept partially contained boxes. */ $.oBox.prototype.contains = function(box, partial){ if (typeof partial === 'undefined') var partial = false; @@ -537,7 +537,7 @@ $.oMatrix.prototype.toString = function(){ * @classdesc The $.oVector is a replacement for the Vector3d objects of Harmony. * @param {float} x a x coordinate for this vector. * @param {float} y a y coordinate for this vector. - * @param {float} [z=0] a z coordinate for this vector. If ommited, will be set to 0 and vector will be 2D. + * @param {float} [z=0] a z coordinate for this vector. If omitted, will be set to 0 and vector will be 2D. */ $.oVector = function(x, y, z){ if (typeof z === "undefined" || isNaN(z)) var z = 0; diff --git a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_metadata.js b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_metadata.js index c19e6d12f4..29afeb522c 100644 --- a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_metadata.js +++ b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_metadata.js @@ -4,7 +4,7 @@ // openHarmony Library v0.01 // // -// Developped by Mathieu Chaptel, Chris Fourney... +// Developed by Mathieu Chaptel, Chris Fourney... // // // This library is an open source implementation of a Document Object Model @@ -16,7 +16,7 @@ // and by hiding the heavy lifting required by the official API. // // This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is garanteed to work. Feel free to contribute +// function has been implemented or is guaranteed to work. Feel free to contribute // improvements to its official github. If you do make sure you follow the provided // template and naming conventions and document your new methods properly. // diff --git a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_misc.js b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_misc.js index fec5d32816..6ef75f5560 100644 --- a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_misc.js +++ b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_misc.js @@ -4,7 +4,7 @@ // openHarmony Library v0.01 // // -// Developped by Mathieu Chaptel, Chris Fourney... +// Developed by Mathieu Chaptel, Chris Fourney... // // // This library is an open source implementation of a Document Object Model @@ -16,7 +16,7 @@ // and by hiding the heavy lifting required by the official API. // // This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is garanteed to work. Feel free to contribute +// function has been implemented or is guaranteed to work. Feel free to contribute // improvements to its official github. If you do make sure you follow the provided // template and naming conventions and document your new methods properly. // @@ -54,7 +54,7 @@ /** - * The $.oUtils helper class -- providing generic utilities. Doesn't need instanciation. + * The $.oUtils helper class -- providing generic utilities. Doesn't need instantiation. * @classdesc $.oUtils utility Class */ $.oUtils = function(){ diff --git a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_network.js b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_network.js index a4476d7591..2a6aa3519a 100644 --- a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_network.js +++ b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_network.js @@ -4,7 +4,7 @@ // openHarmony Library v0.01 // // -// Developped by Mathieu Chaptel, Chris Fourney... +// Developed by Mathieu Chaptel, Chris Fourney... // // // This library is an open source implementation of a Document Object Model @@ -16,7 +16,7 @@ // and by hiding the heavy lifting required by the official API. // // This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is garanteed to work. Feel free to contribute +// function has been implemented or is guaranteed to work. Feel free to contribute // improvements to its official github. If you do make sure you follow the provided // template and naming conventions and document your new methods properly. // @@ -87,7 +87,7 @@ $.oNetwork = function( ){ * @param {function} callback_func Providing a callback function prevents blocking, and will respond on this function. The callback function is in form func( results ){} * @param {bool} use_json In the event of a JSON api, this will return an object converted from the returned JSON. * - * @return: {string/object} The resulting object/string from the query -- otherwise a bool as false when an error occured.. + * @return: {string/object} The resulting object/string from the query -- otherwise a bool as false when an error occurred.. */ $.oNetwork.prototype.webQuery = function ( address, callback_func, use_json ){ if (typeof callback_func === 'undefined') var callback_func = false; @@ -272,7 +272,7 @@ $.oNetwork.prototype.webQuery = function ( address, callback_func, use_json ){ * @param {function} path The local file path to save the download. * @param {bool} replace Replace the file if it exists. * - * @return: {string/object} The resulting object/string from the query -- otherwise a bool as false when an error occured.. + * @return: {string/object} The resulting object/string from the query -- otherwise a bool as false when an error occurred.. */ $.oNetwork.prototype.downloadSingle = function ( address, path, replace ){ if (typeof replace === 'undefined') var replace = false; diff --git a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_node.js b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_node.js index 5590d7b7e9..deb1854357 100644 --- a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_node.js +++ b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_node.js @@ -4,7 +4,7 @@ // openHarmony Library // // -// Developped by Mathieu Chaptel, Chris Fourney +// Developed by Mathieu Chaptel, Chris Fourney // // // This library is an open source implementation of a Document Object Model @@ -16,7 +16,7 @@ // and by hiding the heavy lifting required by the official API. // // This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is garanteed to work. Feel free to contribute +// function has been implemented or is guaranteed to work. Feel free to contribute // improvements to its official github. If you do make sure you follow the provided // template and naming conventions and document your new methods properly. // @@ -562,7 +562,7 @@ Object.defineProperty($.oNode.prototype, 'height', { /** - * The list of oNodeLinks objects descibing the connections to the inport of this node, in order of inport. + * The list of oNodeLinks objects describing the connections to the inport of this node, in order of inport. * @name $.oNode#inLinks * @readonly * @deprecated returns $.oNodeLink instances but $.oLink is preferred. Use oNode.getInLinks() instead. @@ -658,7 +658,7 @@ Object.defineProperty($.oNode.prototype, 'outPorts', { /** - * The list of oNodeLinks objects descibing the connections to the outports of this node, in order of outport. + * The list of oNodeLinks objects describing the connections to the outports of this node, in order of outport. * @name $.oNode#outLinks * @readonly * @type {$.oNodeLink[]} @@ -1666,7 +1666,7 @@ $.oNode.prototype.refreshAttributes = function( ){ * It represents peg nodes in the scene. * @constructor * @augments $.oNode - * @classdesc Peg Moudle Class + * @classdesc Peg Module Class * @param {string} path Path to the node in the network. * @param {oScene} oSceneObject Access to the oScene object of the DOM. */ @@ -1886,7 +1886,7 @@ $.oDrawingNode.prototype.getDrawingAtFrame = function(frameNumber){ /** - * Gets the list of palettes containing colors used by a drawing node. This only gets palettes with the first occurence of the colors. + * Gets the list of palettes containing colors used by a drawing node. This only gets palettes with the first occurrence of the colors. * @return {$.oPalette[]} The palettes that contain the color IDs used by the drawings of the node. */ $.oDrawingNode.prototype.getUsedPalettes = function(){ @@ -1968,7 +1968,7 @@ $.oDrawingNode.prototype.unlinkPalette = function(oPaletteObject){ * Duplicates a node by creating an independent copy. * @param {string} [newName] The new name for the duplicated node. * @param {oPoint} [newPosition] The new position for the duplicated node. - * @param {bool} [duplicateElement] Wether to also duplicate the element. + * @param {bool} [duplicateElement] Whether to also duplicate the element. */ $.oDrawingNode.prototype.duplicate = function(newName, newPosition, duplicateElement){ if (typeof newPosition === 'undefined') var newPosition = this.nodePosition; @@ -2464,7 +2464,7 @@ $.oGroupNode.prototype.getNodeByName = function(name){ * Returns all the nodes of a certain type in the group. * Pass a value to recurse to look into the groups as well. * @param {string} typeName The type of the nodes. - * @param {bool} recurse Wether to look inside the groups. + * @param {bool} recurse Whether to look inside the groups. * * @return {$.oNode[]} The nodes found. */ @@ -2626,7 +2626,7 @@ $.oGroupNode.prototype.orderNodeView = function(recurse){ * * peg.linkOutNode(drawingNode); * - * //through all this we didn't specify nodePosition parameters so we'll sort evertything at once + * //through all this we didn't specify nodePosition parameters so we'll sort everything at once * * sceneRoot.orderNodeView(); * @@ -3333,7 +3333,7 @@ $.oGroupNode.prototype.importImageAsTVG = function(path, alignment, nodePosition * imports an image sequence as a node into the current group. * @param {$.oFile[]} imagePaths a list of paths to the images to import (can pass a list of strings or $.oFile) * @param {number} [exposureLength=1] the number of frames each drawing should be exposed at. If set to 0/false, each drawing will use the numbering suffix of the file to set its frame. - * @param {boolean} [convertToTvg=false] wether to convert the files to tvg during import + * @param {boolean} [convertToTvg=false] whether to convert the files to tvg during import * @param {string} [alignment="ASIS"] the alignment to apply to the node * @param {$.oPoint} [nodePosition] the position of the node in the nodeview * @@ -3346,7 +3346,7 @@ $.oGroupNode.prototype.importImageSequence = function(imagePaths, exposureLength if (typeof extendScene === 'undefined') var extendScene = false; - // match anything but capture trailing numbers and separates punctuation preceeding it + // match anything but capture trailing numbers and separates punctuation preceding it var numberingRe = /(.*?)([\W_]+)?(\d*)$/i; // sanitize imagePaths diff --git a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_nodeLink.js b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_nodeLink.js index 279a871691..07a4d147da 100644 --- a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_nodeLink.js +++ b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony/openHarmony_nodeLink.js @@ -4,7 +4,7 @@ // openHarmony Library v0.01 // // -// Developped by Mathieu Chaptel, Chris Fourney... +// Developed by Mathieu Chaptel, Chris Fourney... // // // This library is an open source implementation of a Document Object Model @@ -16,7 +16,7 @@ // and by hiding the heavy lifting required by the official API. // // This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is garanteed to work. Feel free to contribute +// function has been implemented or is guaranteed to work. Feel free to contribute // improvements to its official github. If you do make sure you follow the provided // template and naming conventions and document your new methods properly. // @@ -174,7 +174,7 @@ Object.defineProperty($.oNodeLink.prototype, 'outNode', { return; } - this.apply(); // do we really want to apply everytime we set? + this.apply(); // do we really want to apply every time we set? } }); @@ -198,7 +198,7 @@ Object.defineProperty($.oNodeLink.prototype, 'inNode', { return; } - this.apply(); // do we really want to apply everytime we set? + this.apply(); // do we really want to apply every time we set? } }); @@ -222,7 +222,7 @@ Object.defineProperty($.oNodeLink.prototype, 'outPort', { return; } - this.apply(); // do we really want to apply everytime we set? + this.apply(); // do we really want to apply every time we set? } }); @@ -256,7 +256,7 @@ Object.defineProperty($.oNodeLink.prototype, 'inPort', { return; } - this.apply(); // do we really want to apply everytime we set? + this.apply(); // do we really want to apply every time we set? } }); @@ -983,7 +983,7 @@ $.oNodeLink.prototype.validate = function ( ) { * @return {bool} Whether the connection is a valid connection that exists currently in the node system. */ $.oNodeLink.prototype.validateUpwards = function( inport, outportProvided ) { - //IN THE EVENT OUTNODE WASNT PROVIDED. + //IN THE EVENT OUTNODE WASN'T PROVIDED. this.path = this.findInputPath( this._inNode, inport, [] ); if( !this.path || this.path.length == 0 ){ return false; @@ -1173,7 +1173,7 @@ Object.defineProperty($.oLink.prototype, 'outPort', { /** - * The index of the link comming out of the out-port. + * The index of the link coming out of the out-port. *
In the event this value wasn't known by the link object but the link is actually connected, the correct value will be found. * @name $.oLink#outLink * @readonly @@ -1323,7 +1323,7 @@ $.oLink.prototype.getValidLink = function(createOutPorts, createInPorts){ /** - * Attemps to connect a link. Will guess the ports if not provided. + * Attempts to connect a link. Will guess the ports if not provided. * @return {bool} */ $.oLink.prototype.connect = function(){ @@ -1623,11 +1623,11 @@ $.oLinkPath.prototype.findExistingPath = function(){ /** - * Gets a link object from two nodes that can be succesfully connected. Provide port numbers if there are specific requirements to match. If a link already exists, it will be returned. + * Gets a link object from two nodes that can be successfully connected. Provide port numbers if there are specific requirements to match. If a link already exists, it will be returned. * @param {$.oNode} start The node from which the link originates. * @param {$.oNode} end The node at which the link ends. - * @param {int} [outPort] A prefered out-port for the link to use. - * @param {int} [inPort] A prefered in-port for the link to use. + * @param {int} [outPort] A preferred out-port for the link to use. + * @param {int} [inPort] A preferred in-port for the link to use. * * @return {$.oLink} the valid $.oLink object. Returns null if no such link could be created (for example if the node's in-port is already linked) */ diff --git a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony_tools.js b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony_tools.js index 57d4a63e96..9014929fc4 100644 --- a/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony_tools.js +++ b/openpype/hosts/harmony/vendor/OpenHarmony/openHarmony_tools.js @@ -4,7 +4,7 @@ // openHarmony Library v0.01 // // -// Developped by Mathieu Chaptel, ... +// Developed by Mathieu Chaptel, ... // // // This library is an open source implementation of a Document Object Model @@ -16,7 +16,7 @@ // and by hiding the heavy lifting required by the official API. // // This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is garanteed to work. Feel free to contribute +// function has been implemented or is guaranteed to work. Feel free to contribute // improvements to its official github. If you do make sure you follow the provided // template and naming conventions and document your new methods properly. // @@ -212,7 +212,7 @@ function openHarmony_toolInstaller(){ //---------------------------------------------- - //-- GET THE FILE CONTENTS IN A DIRCTORY ON GIT + //-- GET THE FILE CONTENTS IN A DIRECTORY ON GIT this.recurse_files = function( contents, arr_files ){ with( context.$.global ){ try{ @@ -501,7 +501,7 @@ function openHarmony_toolInstaller(){ var download_item = item["download_url"]; var query = $.network.webQuery( download_item, false, false ); if( query ){ - //INSTALL TYPES ARE script, package, ect. + //INSTALL TYPES ARE script, package, etc. if( install_types[ m.install_cache[ item["url"] ] ] ){ m.installLabel.text = install_types[ m.install_cache[ item["url"] ] ]; diff --git a/openpype/hosts/harmony/vendor/OpenHarmony/package.json b/openpype/hosts/harmony/vendor/OpenHarmony/package.json index c62ecbc9d8..7a535cdcf6 100644 --- a/openpype/hosts/harmony/vendor/OpenHarmony/package.json +++ b/openpype/hosts/harmony/vendor/OpenHarmony/package.json @@ -1,7 +1,7 @@ { "name": "openharmony", "version": "0.0.1", - "description": "An Open Source Imlementation of a Document Object Model for the Toonboom Harmony scripting interface", + "description": "An Open Source Implementation of a Document Object Model for the Toonboom Harmony scripting interface", "main": "openHarmony.js", "scripts": { "test": "$", diff --git a/openpype/hosts/hiero/api/__init__.py b/openpype/hosts/hiero/api/__init__.py index 1fa40c9f74..b95c0fe1d7 100644 --- a/openpype/hosts/hiero/api/__init__.py +++ b/openpype/hosts/hiero/api/__init__.py @@ -108,7 +108,7 @@ __all__ = [ "apply_colorspace_project", "apply_colorspace_clips", "get_sequence_pattern_and_padding", - # depricated + # deprecated "get_track_item_pype_tag", "set_track_item_pype_tag", "get_track_item_pype_data", diff --git a/openpype/hosts/hiero/api/pipeline.py b/openpype/hosts/hiero/api/pipeline.py index 4ab73e7d19..d88aeac810 100644 --- a/openpype/hosts/hiero/api/pipeline.py +++ b/openpype/hosts/hiero/api/pipeline.py @@ -193,8 +193,8 @@ def parse_container(item, validate=True): return # convert the data to list and validate them for _, obj_data in _data.items(): - cotnainer = data_to_container(item, obj_data) - return_list.append(cotnainer) + container = data_to_container(item, obj_data) + return_list.append(container) return return_list else: _data = lib.get_trackitem_openpype_data(item) diff --git a/openpype/hosts/hiero/api/plugin.py b/openpype/hosts/hiero/api/plugin.py index 5ca901caaa..a3f8a6c524 100644 --- a/openpype/hosts/hiero/api/plugin.py +++ b/openpype/hosts/hiero/api/plugin.py @@ -411,7 +411,7 @@ class ClipLoader: self.with_handles = options.get("handles") or bool( options.get("handles") is True) # try to get value from options or evaluate key value for `load_how` - self.sequencial_load = options.get("sequencially") or bool( + self.sequencial_load = options.get("sequentially") or bool( "Sequentially in order" in options.get("load_how", "")) # try to get value from options or evaluate key value for `load_to` self.new_sequence = options.get("newSequence") or bool( @@ -836,7 +836,7 @@ class PublishClip: # increasing steps by index of rename iteration self.count_steps *= self.rename_index - hierarchy_formating_data = {} + hierarchy_formatting_data = {} hierarchy_data = deepcopy(self.hierarchy_data) _data = self.track_item_default_data.copy() if self.ui_inputs: @@ -871,13 +871,13 @@ class PublishClip: # fill up pythonic expresisons in hierarchy data for k, _v in hierarchy_data.items(): - hierarchy_formating_data[k] = _v["value"].format(**_data) + hierarchy_formatting_data[k] = _v["value"].format(**_data) else: # if no gui mode then just pass default data - hierarchy_formating_data = hierarchy_data + hierarchy_formatting_data = hierarchy_data tag_hierarchy_data = self._solve_tag_hierarchy_data( - hierarchy_formating_data + hierarchy_formatting_data ) tag_hierarchy_data.update({"heroTrack": True}) @@ -905,20 +905,20 @@ class PublishClip: # add data to return data dict self.tag_data.update(tag_hierarchy_data) - def _solve_tag_hierarchy_data(self, hierarchy_formating_data): + def _solve_tag_hierarchy_data(self, hierarchy_formatting_data): """ Solve tag data from hierarchy data and templates. """ # fill up clip name and hierarchy keys - hierarchy_filled = self.hierarchy.format(**hierarchy_formating_data) - clip_name_filled = self.clip_name.format(**hierarchy_formating_data) + hierarchy_filled = self.hierarchy.format(**hierarchy_formatting_data) + clip_name_filled = self.clip_name.format(**hierarchy_formatting_data) # remove shot from hierarchy data: is not needed anymore - hierarchy_formating_data.pop("shot") + hierarchy_formatting_data.pop("shot") return { "newClipName": clip_name_filled, "hierarchy": hierarchy_filled, "parents": self.parents, - "hierarchyData": hierarchy_formating_data, + "hierarchyData": hierarchy_formatting_data, "subset": self.subset, "family": self.subset_family, "families": [self.data["family"]] @@ -934,16 +934,16 @@ class PublishClip: ) # first collect formatting data to use for formatting template - formating_data = {} + formatting_data = {} for _k, _v in self.hierarchy_data.items(): value = _v["value"].format( **self.track_item_default_data) - formating_data[_k] = value + formatting_data[_k] = value return { "entity_type": entity_type, "entity_name": template.format( - **formating_data + **formatting_data ) } diff --git a/openpype/hosts/houdini/api/plugin.py b/openpype/hosts/houdini/api/plugin.py index f0985973a6..340a7f0770 100644 --- a/openpype/hosts/houdini/api/plugin.py +++ b/openpype/hosts/houdini/api/plugin.py @@ -60,7 +60,7 @@ class Creator(LegacyCreator): def process(self): instance = super(CreateEpicNode, self, process() - # Set paramaters for Alembic node + # Set parameters for Alembic node instance.setParms( {"sop_path": "$HIP/%s.abc" % self.nodes[0]} ) diff --git a/openpype/hosts/houdini/api/shelves.py b/openpype/hosts/houdini/api/shelves.py index ebd668e9e4..6e0f367f62 100644 --- a/openpype/hosts/houdini/api/shelves.py +++ b/openpype/hosts/houdini/api/shelves.py @@ -69,7 +69,7 @@ def generate_shelves(): mandatory_attributes = {'label', 'script'} for tool_definition in shelf_definition.get('tools_list'): - # We verify that the name and script attibutes of the tool + # We verify that the name and script attributes of the tool # are set if not all( tool_definition[key] for key in mandatory_attributes diff --git a/openpype/hosts/houdini/plugins/create/convert_legacy.py b/openpype/hosts/houdini/plugins/create/convert_legacy.py index 4b8041b4f5..e549c9dc26 100644 --- a/openpype/hosts/houdini/plugins/create/convert_legacy.py +++ b/openpype/hosts/houdini/plugins/create/convert_legacy.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -"""Convertor for legacy Houdini subsets.""" +"""Converter for legacy Houdini subsets.""" from openpype.pipeline.create.creator_plugins import SubsetConvertorPlugin from openpype.hosts.houdini.api.lib import imprint @@ -7,7 +7,7 @@ from openpype.hosts.houdini.api.lib import imprint class HoudiniLegacyConvertor(SubsetConvertorPlugin): """Find and convert any legacy subsets in the scene. - This Convertor will find all legacy subsets in the scene and will + This Converter will find all legacy subsets in the scene and will transform them to the current system. Since the old subsets doesn't retain any information about their original creators, the only mapping we can do is based on their families. diff --git a/openpype/hosts/maya/api/commands.py b/openpype/hosts/maya/api/commands.py index 018340d86c..3e31875fd8 100644 --- a/openpype/hosts/maya/api/commands.py +++ b/openpype/hosts/maya/api/commands.py @@ -69,7 +69,7 @@ def _resolution_from_document(doc): resolution_width = doc["data"].get("resolution_width") resolution_height = doc["data"].get("resolution_height") - # Make sure both width and heigh are set + # Make sure both width and height are set if resolution_width is None or resolution_height is None: cmds.warning( "No resolution information found for \"{}\"".format(doc["name"]) diff --git a/openpype/hosts/maya/api/lib_renderproducts.py b/openpype/hosts/maya/api/lib_renderproducts.py index a54256c59a..324496c964 100644 --- a/openpype/hosts/maya/api/lib_renderproducts.py +++ b/openpype/hosts/maya/api/lib_renderproducts.py @@ -339,7 +339,7 @@ class ARenderProducts: aov_tokens = ["", ""] def match_last(tokens, text): - """regex match the last occurence from a list of tokens""" + """regex match the last occurrence from a list of tokens""" pattern = "(?:.*)({})".format("|".join(tokens)) return re.search(pattern, text, re.IGNORECASE) @@ -1051,7 +1051,7 @@ class RenderProductsRedshift(ARenderProducts): def get_files(self, product): # When outputting AOVs we need to replace Redshift specific AOV tokens # with Maya render tokens for generating file sequences. We validate to - # a specific AOV fileprefix so we only need to accout for one + # a specific AOV fileprefix so we only need to account for one # replacement. if not product.multipart and product.driver: file_prefix = self._get_attr(product.driver + ".filePrefix") diff --git a/openpype/hosts/maya/api/workfile_template_builder.py b/openpype/hosts/maya/api/workfile_template_builder.py index 90ab6e21e0..4bee0664ef 100644 --- a/openpype/hosts/maya/api/workfile_template_builder.py +++ b/openpype/hosts/maya/api/workfile_template_builder.py @@ -33,7 +33,7 @@ class MayaTemplateBuilder(AbstractTemplateBuilder): get_template_preset implementation) Returns: - bool: Wether the template was succesfully imported or not + bool: Whether the template was successfully imported or not """ if cmds.objExists(PLACEHOLDER_SET): @@ -116,7 +116,7 @@ class MayaPlaceholderLoadPlugin(PlaceholderPlugin, PlaceholderLoadMixin): placeholder_name_parts = placeholder_data["builder_type"].split("_") pos = 1 - # add famlily in any + # add family in any placeholder_family = placeholder_data["family"] if placeholder_family: placeholder_name_parts.insert(pos, placeholder_family) diff --git a/openpype/hosts/maya/plugins/load/actions.py b/openpype/hosts/maya/plugins/load/actions.py index 2574624dbb..ba69debc40 100644 --- a/openpype/hosts/maya/plugins/load/actions.py +++ b/openpype/hosts/maya/plugins/load/actions.py @@ -118,7 +118,7 @@ class ImportMayaLoader(load.LoaderPlugin): "clean_import", label="Clean import", default=False, - help="Should all occurences of cbId be purged?" + help="Should all occurrences of cbId be purged?" ) ] diff --git a/openpype/hosts/maya/plugins/load/load_arnold_standin.py b/openpype/hosts/maya/plugins/load/load_arnold_standin.py index 11a2bd1966..21b2246f6c 100644 --- a/openpype/hosts/maya/plugins/load/load_arnold_standin.py +++ b/openpype/hosts/maya/plugins/load/load_arnold_standin.py @@ -180,7 +180,7 @@ class ArnoldStandinLoader(load.LoaderPlugin): proxy_basename, proxy_path = self._get_proxy_path(path) # Whether there is proxy or so, we still update the string operator. - # If no proxy exists, the string operator wont replace anything. + # If no proxy exists, the string operator won't replace anything. cmds.setAttr( string_replace_operator + ".match", "resources/" + proxy_basename, diff --git a/openpype/hosts/maya/plugins/publish/collect_multiverse_look.py b/openpype/hosts/maya/plugins/publish/collect_multiverse_look.py index a7cb14855b..33fc7a025f 100644 --- a/openpype/hosts/maya/plugins/publish/collect_multiverse_look.py +++ b/openpype/hosts/maya/plugins/publish/collect_multiverse_look.py @@ -255,7 +255,7 @@ class CollectMultiverseLookData(pyblish.api.InstancePlugin): Searches through the overrides finding all material overrides. From there it extracts the shading group and then finds all texture files in the shading group network. It also checks for mipmap versions of texture files - and adds them to the resouces to get published. + and adds them to the resources to get published. """ diff --git a/openpype/hosts/maya/plugins/publish/extract_look.py b/openpype/hosts/maya/plugins/publish/extract_look.py index 447c9a615c..0572073d7d 100644 --- a/openpype/hosts/maya/plugins/publish/extract_look.py +++ b/openpype/hosts/maya/plugins/publish/extract_look.py @@ -95,7 +95,7 @@ def maketx(source, destination, args, logger): try: out = run_subprocess(subprocess_args) except Exception: - logger.error("Maketx converion failed", exc_info=True) + logger.error("Maketx conversion failed", exc_info=True) raise return out diff --git a/openpype/hosts/maya/plugins/publish/extract_multiverse_usd_over.py b/openpype/hosts/maya/plugins/publish/extract_multiverse_usd_over.py index 0628623e88..cf610ac6b4 100644 --- a/openpype/hosts/maya/plugins/publish/extract_multiverse_usd_over.py +++ b/openpype/hosts/maya/plugins/publish/extract_multiverse_usd_over.py @@ -102,7 +102,7 @@ class ExtractMultiverseUsdOverride(publish.Extractor): long=True) self.log.info("Collected object {}".format(members)) - # TODO: Deal with asset, composition, overide with options. + # TODO: Deal with asset, composition, override with options. import multiverse time_opts = None diff --git a/openpype/hosts/maya/plugins/publish/reset_xgen_attributes.py b/openpype/hosts/maya/plugins/publish/reset_xgen_attributes.py index b90885663c..d8e8554b68 100644 --- a/openpype/hosts/maya/plugins/publish/reset_xgen_attributes.py +++ b/openpype/hosts/maya/plugins/publish/reset_xgen_attributes.py @@ -30,7 +30,7 @@ class ResetXgenAttributes(pyblish.api.InstancePlugin): cmds.setAttr(palette + ".xgExportAsDelta", True) # Need to save the scene, cause the attribute changes above does not - # mark the scene as modified so user can exit without commiting the + # mark the scene as modified so user can exit without committing the # changes. self.log.info("Saving changes.") cmds.file(save=True) diff --git a/openpype/hosts/maya/plugins/publish/validate_camera_attributes.py b/openpype/hosts/maya/plugins/publish/validate_camera_attributes.py index bd1529e252..13ea53a357 100644 --- a/openpype/hosts/maya/plugins/publish/validate_camera_attributes.py +++ b/openpype/hosts/maya/plugins/publish/validate_camera_attributes.py @@ -8,7 +8,7 @@ from openpype.pipeline.publish import ValidateContentsOrder class ValidateCameraAttributes(pyblish.api.InstancePlugin): """Validates Camera has no invalid attribute keys or values. - The Alembic file format does not a specifc subset of attributes as such + The Alembic file format does not a specific subset of attributes as such we validate that no values are set there as the output will not match the current scene. For example the preScale, film offsets and film roll. diff --git a/openpype/hosts/maya/plugins/publish/validate_maya_units.py b/openpype/hosts/maya/plugins/publish/validate_maya_units.py index 357dde692c..011df0846c 100644 --- a/openpype/hosts/maya/plugins/publish/validate_maya_units.py +++ b/openpype/hosts/maya/plugins/publish/validate_maya_units.py @@ -34,7 +34,7 @@ class ValidateMayaUnits(pyblish.api.ContextPlugin): fps = context.data.get('fps') - # TODO repace query with using 'context.data["assetEntity"]' + # TODO replace query with using 'context.data["assetEntity"]' asset_doc = get_current_project_asset() asset_fps = mayalib.convert_to_maya_fps(asset_doc["data"]["fps"]) @@ -86,7 +86,7 @@ class ValidateMayaUnits(pyblish.api.ContextPlugin): cls.log.debug(current_linear) cls.log.info("Setting time unit to match project") - # TODO repace query with using 'context.data["assetEntity"]' + # TODO replace query with using 'context.data["assetEntity"]' asset_doc = get_current_project_asset() asset_fps = asset_doc["data"]["fps"] mayalib.set_scene_fps(asset_fps) diff --git a/openpype/hosts/maya/plugins/publish/validate_mvlook_contents.py b/openpype/hosts/maya/plugins/publish/validate_mvlook_contents.py index e583c1edba..36971bb144 100644 --- a/openpype/hosts/maya/plugins/publish/validate_mvlook_contents.py +++ b/openpype/hosts/maya/plugins/publish/validate_mvlook_contents.py @@ -42,7 +42,7 @@ class ValidateMvLookContents(pyblish.api.InstancePlugin): resources = instance.data.get("resources", []) for resource in resources: files = resource["files"] - self.log.debug("Resouce '{}', files: [{}]".format(resource, files)) + self.log.debug("Resource '{}', files: [{}]".format(resource, files)) node = resource["node"] if len(files) == 0: self.log.error("File node '{}' uses no or non-existing " diff --git a/openpype/hosts/maya/plugins/publish/validate_renderlayer_aovs.py b/openpype/hosts/maya/plugins/publish/validate_renderlayer_aovs.py index 6b6fb03eec..7919a6eaa1 100644 --- a/openpype/hosts/maya/plugins/publish/validate_renderlayer_aovs.py +++ b/openpype/hosts/maya/plugins/publish/validate_renderlayer_aovs.py @@ -37,8 +37,8 @@ class ValidateRenderLayerAOVs(pyblish.api.InstancePlugin): project_name = legacy_io.active_project() asset_doc = instance.data["assetEntity"] - render_passses = instance.data.get("renderPasses", []) - for render_pass in render_passses: + render_passes = instance.data.get("renderPasses", []) + for render_pass in render_passes: is_valid = self.validate_subset_registered( project_name, asset_doc, render_pass ) diff --git a/openpype/hosts/maya/plugins/publish/validate_transform_naming_suffix.py b/openpype/hosts/maya/plugins/publish/validate_transform_naming_suffix.py index 0147aa8a52..b2a83a80fb 100644 --- a/openpype/hosts/maya/plugins/publish/validate_transform_naming_suffix.py +++ b/openpype/hosts/maya/plugins/publish/validate_transform_naming_suffix.py @@ -21,7 +21,7 @@ class ValidateTransformNamingSuffix(pyblish.api.InstancePlugin): - nurbsSurface: _NRB - locator: _LOC - null/group: _GRP - Suffices can also be overriden by project settings. + Suffices can also be overridden by project settings. .. warning:: This grabs the first child shape as a reference and doesn't use the diff --git a/openpype/hosts/nuke/api/lib.py b/openpype/hosts/nuke/api/lib.py index 2a14096f0e..157a02b9aa 100644 --- a/openpype/hosts/nuke/api/lib.py +++ b/openpype/hosts/nuke/api/lib.py @@ -148,7 +148,7 @@ def get_main_window(): def set_node_data(node, knobname, data): """Write data to node invisible knob - Will create new in case it doesnt exists + Will create new in case it doesn't exists or update the one already created. Args: @@ -506,7 +506,7 @@ def get_avalon_knob_data(node, prefix="avalon:", create=True): try: # check if data available on the node test = node[AVALON_DATA_GROUP].value() - log.debug("Only testing if data avalable: `{}`".format(test)) + log.debug("Only testing if data available: `{}`".format(test)) except NameError as e: # if it doesn't then create it log.debug("Creating avalon knob: `{}`".format(e)) @@ -908,11 +908,11 @@ def get_view_process_node(): continue if not ipn_node: - # in case a Viewer node is transfered from + # in case a Viewer node is transferred from # different workfile with old values raise NameError(( "Input process node name '{}' set in " - "Viewer '{}' is does't exists in nodes" + "Viewer '{}' is doesn't exists in nodes" ).format(ipn, v_.name())) ipn_node.setSelected(True) @@ -1662,7 +1662,7 @@ def create_write_node_legacy( tile_color = _data.get("tile_color", "0xff0000ff") GN["tile_color"].setValue(tile_color) - # overrie knob values from settings + # override knob values from settings for knob in knob_overrides: knob_type = knob["type"] knob_name = knob["name"] @@ -2117,7 +2117,7 @@ class WorkfileSettings(object): write_node[knob["name"]].setValue(value) except TypeError: log.warning( - "Legacy workflow didnt work, switching to current") + "Legacy workflow didn't work, switching to current") set_node_knobs_from_settings( write_node, nuke_imageio_writes["knobs"]) @@ -2543,7 +2543,7 @@ def reset_selection(): def select_nodes(nodes): - """Selects all inputed nodes + """Selects all inputted nodes Arguments: nodes (list): nuke nodes to be selected @@ -2560,7 +2560,7 @@ def launch_workfiles_app(): Trigger to show workfiles tool on application launch. Can be executed only once all other calls are ignored. - Workfiles tool show is deffered after application initialization using + Workfiles tool show is deferred after application initialization using QTimer. """ @@ -2581,7 +2581,7 @@ def launch_workfiles_app(): # Show workfiles tool using timer # - this will be probably triggered during initialization in that case # the application is not be able to show uis so it must be - # deffered using timer + # deferred using timer # - timer should be processed when initialization ends # When applications starts to process events. timer = QtCore.QTimer() diff --git a/openpype/hosts/nuke/api/plugin.py b/openpype/hosts/nuke/api/plugin.py index aec87be5ab..cc3af2a38f 100644 --- a/openpype/hosts/nuke/api/plugin.py +++ b/openpype/hosts/nuke/api/plugin.py @@ -594,7 +594,7 @@ class ExporterReview(object): Defaults to None. range (bool, optional): flag for adding ranges. Defaults to False. - custom_tags (list[str], optional): user inputed custom tags. + custom_tags (list[str], optional): user inputted custom tags. Defaults to None. """ add_tags = tags or [] @@ -1110,7 +1110,7 @@ class AbstractWriteRender(OpenPypeCreator): def is_legacy(self): """Check if it needs to run legacy code - In case where `type` key is missing in singe + In case where `type` key is missing in single knob it is legacy project anatomy. Returns: diff --git a/openpype/hosts/nuke/api/utils.py b/openpype/hosts/nuke/api/utils.py index 6bcb752dd1..2b3c35c23a 100644 --- a/openpype/hosts/nuke/api/utils.py +++ b/openpype/hosts/nuke/api/utils.py @@ -87,7 +87,7 @@ def bake_gizmos_recursively(in_group=None): def colorspace_exists_on_node(node, colorspace_name): """ Check if colorspace exists on node - Look through all options in the colorpsace knob, and see if we have an + Look through all options in the colorspace knob, and see if we have an exact match to one of the items. Args: diff --git a/openpype/hosts/nuke/api/workfile_template_builder.py b/openpype/hosts/nuke/api/workfile_template_builder.py index fb0afb3d55..cf85a5ea05 100644 --- a/openpype/hosts/nuke/api/workfile_template_builder.py +++ b/openpype/hosts/nuke/api/workfile_template_builder.py @@ -42,7 +42,7 @@ class NukeTemplateBuilder(AbstractTemplateBuilder): get_template_preset implementation) Returns: - bool: Wether the template was successfully imported or not + bool: Whether the template was successfully imported or not """ # TODO check if the template is already imported @@ -222,7 +222,7 @@ class NukePlaceholderLoadPlugin(NukePlaceholderPlugin, PlaceholderLoadMixin): self._imprint_siblings(placeholder) if placeholder.data["nb_children"] == 0: - # save initial nodes postions and dimensions, update them + # save initial nodes positions and dimensions, update them # and set inputs and outputs of loaded nodes self._imprint_inits() @@ -231,7 +231,7 @@ class NukePlaceholderLoadPlugin(NukePlaceholderPlugin, PlaceholderLoadMixin): elif placeholder.data["siblings"]: # create copies of placeholder siblings for the new loaded nodes, - # set their inputs and outpus and update all nodes positions and + # set their inputs and outputs and update all nodes positions and # dimensions and siblings names siblings = get_nodes_by_names(placeholder.data["siblings"]) @@ -632,7 +632,7 @@ class NukePlaceholderCreatePlugin( self._imprint_siblings(placeholder) if placeholder.data["nb_children"] == 0: - # save initial nodes postions and dimensions, update them + # save initial nodes positions and dimensions, update them # and set inputs and outputs of created nodes self._imprint_inits() @@ -641,7 +641,7 @@ class NukePlaceholderCreatePlugin( elif placeholder.data["siblings"]: # create copies of placeholder siblings for the new created nodes, - # set their inputs and outpus and update all nodes positions and + # set their inputs and outputs and update all nodes positions and # dimensions and siblings names siblings = get_nodes_by_names(placeholder.data["siblings"]) diff --git a/openpype/hosts/nuke/plugins/create/convert_legacy.py b/openpype/hosts/nuke/plugins/create/convert_legacy.py index d7341c625f..c143e4cb27 100644 --- a/openpype/hosts/nuke/plugins/create/convert_legacy.py +++ b/openpype/hosts/nuke/plugins/create/convert_legacy.py @@ -39,7 +39,7 @@ class LegacyConverted(SubsetConvertorPlugin): break if legacy_found: - # if not item do not add legacy instance convertor + # if not item do not add legacy instance converter self.add_convertor_item("Convert legacy instances") def convert(self): diff --git a/openpype/hosts/nuke/plugins/create/create_source.py b/openpype/hosts/nuke/plugins/create/create_source.py index 06cf4e6cbf..57504b5d53 100644 --- a/openpype/hosts/nuke/plugins/create/create_source.py +++ b/openpype/hosts/nuke/plugins/create/create_source.py @@ -85,4 +85,4 @@ class CreateSource(NukeCreator): raise NukeCreatorError("Creator error: No active selection") else: NukeCreatorError( - "Creator error: only supprted with active selection") + "Creator error: only supported with active selection") diff --git a/openpype/hosts/nuke/plugins/publish/collect_writes.py b/openpype/hosts/nuke/plugins/publish/collect_writes.py index 0008a756bc..536a0698f3 100644 --- a/openpype/hosts/nuke/plugins/publish/collect_writes.py +++ b/openpype/hosts/nuke/plugins/publish/collect_writes.py @@ -189,7 +189,7 @@ class CollectNukeWrites(pyblish.api.InstancePlugin, }) # make sure rendered sequence on farm will - # be used for exctract review + # be used for extract review if not instance.data["review"]: instance.data["useSequenceForReview"] = False diff --git a/openpype/hosts/nuke/plugins/publish/validate_backdrop.py b/openpype/hosts/nuke/plugins/publish/validate_backdrop.py index 208d4a2498..5f4a5c3ab0 100644 --- a/openpype/hosts/nuke/plugins/publish/validate_backdrop.py +++ b/openpype/hosts/nuke/plugins/publish/validate_backdrop.py @@ -48,7 +48,7 @@ class SelectCenterInNodeGraph(pyblish.api.Action): class ValidateBackdrop(pyblish.api.InstancePlugin): """ Validate amount of nodes on backdrop node in case user - forgoten to add nodes above the publishing backdrop node. + forgotten to add nodes above the publishing backdrop node. """ order = pyblish.api.ValidatorOrder diff --git a/openpype/hosts/photoshop/api/extension/host/index.jsx b/openpype/hosts/photoshop/api/extension/host/index.jsx index 2acec1ebc1..e2711fb960 100644 --- a/openpype/hosts/photoshop/api/extension/host/index.jsx +++ b/openpype/hosts/photoshop/api/extension/host/index.jsx @@ -199,7 +199,7 @@ function getActiveDocumentName(){ function getActiveDocumentFullName(){ /** * Returns file name of active document with file path. - * activeDocument.fullName returns path in URI (eg /c/.. insted of c:/) + * activeDocument.fullName returns path in URI (eg /c/.. instead of c:/) * */ if (documents.length == 0){ return null; @@ -225,7 +225,7 @@ function getSelectedLayers(doc) { * Returns json representation of currently selected layers. * Works in three steps - 1) creates new group with selected layers * 2) traverses this group - * 3) deletes newly created group, not neede + * 3) deletes newly created group, not needed * Bit weird, but Adobe.. **/ if (doc == null){ @@ -284,7 +284,7 @@ function selectLayers(selectedLayers){ existing_ids.push(existing_layers[y]["id"]); } for (var i = 0; i < selectedLayers.length; i++) { - // a check to see if the id stil exists + // a check to see if the id still exists var id = selectedLayers[i]; if(existing_ids.toString().indexOf(id)>=0){ layers[i] = charIDToTypeID( "Lyr " ); diff --git a/openpype/hosts/resolve/api/lib.py b/openpype/hosts/resolve/api/lib.py index f41eb36caf..b3ad20df39 100644 --- a/openpype/hosts/resolve/api/lib.py +++ b/openpype/hosts/resolve/api/lib.py @@ -250,7 +250,7 @@ def create_timeline_item(media_pool_item: object, media_pool_item, timeline) assert output_timeline_item, AssertionError( - "Track Item with name `{}` doesnt exist on the timeline: `{}`".format( + "Track Item with name `{}` doesn't exist on the timeline: `{}`".format( clip_name, timeline.GetName() )) return output_timeline_item @@ -571,7 +571,7 @@ def create_compound_clip(clip_data, name, folder): # Set current folder to input media_pool_folder: mp.SetCurrentFolder(folder) - # check if clip doesnt exist already: + # check if clip doesn't exist already: clips = folder.GetClipList() cct = next((c for c in clips if c.GetName() in name), None) @@ -582,7 +582,7 @@ def create_compound_clip(clip_data, name, folder): # Create empty timeline in current folder and give name: cct = mp.CreateEmptyTimeline(name) - # check if clip doesnt exist already: + # check if clip doesn't exist already: clips = folder.GetClipList() cct = next((c for c in clips if c.GetName() in name), None) diff --git a/openpype/hosts/resolve/api/menu_style.qss b/openpype/hosts/resolve/api/menu_style.qss index d2d3d1ed37..3d51c7139f 100644 --- a/openpype/hosts/resolve/api/menu_style.qss +++ b/openpype/hosts/resolve/api/menu_style.qss @@ -61,7 +61,7 @@ QVBoxLayout { background-color: #282828; } -#Devider { +#Divider { border: 1px solid #090909; background-color: #585858; } diff --git a/openpype/hosts/resolve/api/plugin.py b/openpype/hosts/resolve/api/plugin.py index 77e30149fd..4fa73e82cd 100644 --- a/openpype/hosts/resolve/api/plugin.py +++ b/openpype/hosts/resolve/api/plugin.py @@ -715,7 +715,7 @@ class PublishClip: # increasing steps by index of rename iteration self.count_steps *= self.rename_index - hierarchy_formating_data = dict() + hierarchy_formatting_data = dict() _data = self.timeline_item_default_data.copy() if self.ui_inputs: # adding tag metadata from ui @@ -749,13 +749,13 @@ class PublishClip: # fill up pythonic expresisons in hierarchy data for k, _v in self.hierarchy_data.items(): - hierarchy_formating_data[k] = _v["value"].format(**_data) + hierarchy_formatting_data[k] = _v["value"].format(**_data) else: # if no gui mode then just pass default data - hierarchy_formating_data = self.hierarchy_data + hierarchy_formatting_data = self.hierarchy_data tag_hierarchy_data = self._solve_tag_hierarchy_data( - hierarchy_formating_data + hierarchy_formatting_data ) tag_hierarchy_data.update({"heroTrack": True}) @@ -793,17 +793,17 @@ class PublishClip: self.tag_data.update({"reviewTrack": None}) - def _solve_tag_hierarchy_data(self, hierarchy_formating_data): + def _solve_tag_hierarchy_data(self, hierarchy_formatting_data): """ Solve tag data from hierarchy data and templates. """ # fill up clip name and hierarchy keys - hierarchy_filled = self.hierarchy.format(**hierarchy_formating_data) - clip_name_filled = self.clip_name.format(**hierarchy_formating_data) + hierarchy_filled = self.hierarchy.format(**hierarchy_formatting_data) + clip_name_filled = self.clip_name.format(**hierarchy_formatting_data) return { "newClipName": clip_name_filled, "hierarchy": hierarchy_filled, "parents": self.parents, - "hierarchyData": hierarchy_formating_data, + "hierarchyData": hierarchy_formatting_data, "subset": self.subset, "family": self.subset_family, "families": ["clip"] diff --git a/openpype/hosts/standalonepublisher/plugins/publish/collect_bulk_mov_instances.py b/openpype/hosts/standalonepublisher/plugins/publish/collect_bulk_mov_instances.py index 7925b0ecf3..6c3b0c3efd 100644 --- a/openpype/hosts/standalonepublisher/plugins/publish/collect_bulk_mov_instances.py +++ b/openpype/hosts/standalonepublisher/plugins/publish/collect_bulk_mov_instances.py @@ -83,9 +83,9 @@ class CollectBulkMovInstances(pyblish.api.InstancePlugin): self.log.info(f"Created new instance: {instance_name}") - def convertor(value): + def converter(value): return str(value) self.log.debug("Instance data: {}".format( - json.dumps(new_instance.data, indent=4, default=convertor) + json.dumps(new_instance.data, indent=4, default=converter) )) diff --git a/openpype/hosts/standalonepublisher/plugins/publish/collect_context.py b/openpype/hosts/standalonepublisher/plugins/publish/collect_context.py index 2bf3917e2f..a7746530e7 100644 --- a/openpype/hosts/standalonepublisher/plugins/publish/collect_context.py +++ b/openpype/hosts/standalonepublisher/plugins/publish/collect_context.py @@ -104,7 +104,7 @@ class CollectContextDataSAPublish(pyblish.api.ContextPlugin): if repr.get(k): repr.pop(k) - # convert files to list if it isnt + # convert files to list if it isn't if not isinstance(files, (tuple, list)): files = [files] @@ -174,7 +174,7 @@ class CollectContextDataSAPublish(pyblish.api.ContextPlugin): continue files = repre["files"] - # Convert files to list if it isnt + # Convert files to list if it isn't if not isinstance(files, (tuple, list)): files = [files] diff --git a/openpype/hosts/standalonepublisher/plugins/publish/collect_editorial.py b/openpype/hosts/standalonepublisher/plugins/publish/collect_editorial.py index 8633d4bf9d..391cace761 100644 --- a/openpype/hosts/standalonepublisher/plugins/publish/collect_editorial.py +++ b/openpype/hosts/standalonepublisher/plugins/publish/collect_editorial.py @@ -116,7 +116,7 @@ class CollectEditorial(pyblish.api.InstancePlugin): kwargs = {} if extension == ".edl": # EDL has no frame rate embedded so needs explicit - # frame rate else 24 is asssumed. + # frame rate else 24 is assumed. kwargs["rate"] = get_current_project_asset()["data"]["fps"] instance.data["otio_timeline"] = otio.adapters.read_from_file( diff --git a/openpype/hosts/standalonepublisher/plugins/publish/validate_frame_ranges.py b/openpype/hosts/standalonepublisher/plugins/publish/validate_frame_ranges.py index 074c62ea0e..e46fbe6098 100644 --- a/openpype/hosts/standalonepublisher/plugins/publish/validate_frame_ranges.py +++ b/openpype/hosts/standalonepublisher/plugins/publish/validate_frame_ranges.py @@ -29,7 +29,7 @@ class ValidateFrameRange(pyblish.api.InstancePlugin): for pattern in self.skip_timelines_check): self.log.info("Skipping for {} task".format(instance.data["task"])) - # TODO repace query with using 'instance.data["assetEntity"]' + # TODO replace query with using 'instance.data["assetEntity"]' asset_data = get_current_project_asset(instance.data["asset"])["data"] frame_start = asset_data["frameStart"] frame_end = asset_data["frameEnd"] diff --git a/openpype/hosts/traypublisher/api/editorial.py b/openpype/hosts/traypublisher/api/editorial.py index 293db542a9..e8f76bd314 100644 --- a/openpype/hosts/traypublisher/api/editorial.py +++ b/openpype/hosts/traypublisher/api/editorial.py @@ -8,10 +8,10 @@ from openpype.pipeline.create import CreatorError class ShotMetadataSolver: """ Solving hierarchical metadata - Used during editorial publishing. Works with imput + Used during editorial publishing. Works with input clip name and settings defining python formatable template. Settings also define searching patterns - and its token keys used for formating in templates. + and its token keys used for formatting in templates. """ NO_DECOR_PATERN = re.compile(r"\{([a-z]*?)\}") @@ -40,13 +40,13 @@ class ShotMetadataSolver: """Shot renaming function Args: - data (dict): formating data + data (dict): formatting data Raises: CreatorError: If missing keys Returns: - str: formated new name + str: formatted new name """ shot_rename_template = self.shot_rename[ "shot_rename_template"] @@ -58,7 +58,7 @@ class ShotMetadataSolver: "Make sure all keys in settings are correct:: \n\n" f"From template string {shot_rename_template} > " f"`{_E}` has no equivalent in \n" - f"{list(data.keys())} input formating keys!" + f"{list(data.keys())} input formatting keys!" )) def _generate_tokens(self, clip_name, source_data): @@ -68,7 +68,7 @@ class ShotMetadataSolver: Args: clip_name (str): name of clip in editorial - source_data (dict): data for formating + source_data (dict): data for formatting Raises: CreatorError: if missing key @@ -106,14 +106,14 @@ class ShotMetadataSolver: return output_data def _create_parents_from_settings(self, parents, data): - """Formating parent components. + """formatting parent components. Args: parents (list): list of dict parent components - data (dict): formating data + data (dict): formatting data Raises: - CreatorError: missing formating key + CreatorError: missing formatting key CreatorError: missing token key KeyError: missing parent token @@ -126,7 +126,7 @@ class ShotMetadataSolver: # fill parent keys data template from anatomy data try: - _parent_tokens_formating_data = { + _parent_tokens_formatting_data = { parent_token["name"]: parent_token["value"].format(**data) for parent_token in hierarchy_parents } @@ -143,17 +143,17 @@ class ShotMetadataSolver: for _index, _parent in enumerate( shot_hierarchy["parents_path"].split("/") ): - # format parent token with value which is formated + # format parent token with value which is formatted try: parent_name = _parent.format( - **_parent_tokens_formating_data) + **_parent_tokens_formatting_data) except KeyError as _E: raise CreatorError(( "Make sure all keys in settings are correct : \n\n" f"`{_E}` from template string " f"{shot_hierarchy['parents_path']}, " f" has no equivalent in \n" - f"{list(_parent_tokens_formating_data.keys())} parents" + f"{list(_parent_tokens_formatting_data.keys())} parents" )) parent_token_name = ( @@ -225,7 +225,7 @@ class ShotMetadataSolver: visual_hierarchy = [asset_doc] current_doc = asset_doc - # looping trought all available visual parents + # looping through all available visual parents # if they are not available anymore than it breaks while True: visual_parent_id = current_doc["data"]["visualParent"] @@ -288,7 +288,7 @@ class ShotMetadataSolver: Args: clip_name (str): clip name - source_data (dict): formating data + source_data (dict): formatting data Returns: (str, dict): shot name and hierarchy data @@ -301,19 +301,19 @@ class ShotMetadataSolver: # match clip to shot name at start shot_name = clip_name - # parse all tokens and generate formating data - formating_data = self._generate_tokens(shot_name, source_data) + # parse all tokens and generate formatting data + formatting_data = self._generate_tokens(shot_name, source_data) # generate parents from selected asset parents = self._get_parents_from_selected_asset(asset_doc, project_doc) if self.shot_rename["enabled"]: - shot_name = self._rename_template(formating_data) + shot_name = self._rename_template(formatting_data) self.log.info(f"Renamed shot name: {shot_name}") if self.shot_hierarchy["enabled"]: parents = self._create_parents_from_settings( - parents, formating_data) + parents, formatting_data) if self.shot_add_tasks: tasks = self._generate_tasks_from_settings( diff --git a/openpype/hosts/traypublisher/plugins/create/create_editorial.py b/openpype/hosts/traypublisher/plugins/create/create_editorial.py index 73be43444e..0630dfb3da 100644 --- a/openpype/hosts/traypublisher/plugins/create/create_editorial.py +++ b/openpype/hosts/traypublisher/plugins/create/create_editorial.py @@ -260,7 +260,7 @@ or updating already created. Publishing will create OTIO file. ) if not first_otio_timeline: - # assing otio timeline for multi file to layer + # assign otio timeline for multi file to layer first_otio_timeline = otio_timeline # create otio editorial instance @@ -283,7 +283,7 @@ or updating already created. Publishing will create OTIO file. Args: subset_name (str): name of subset - data (dict): instnance data + data (dict): instance data sequence_path (str): path to sequence file media_path (str): path to media file otio_timeline (otio.Timeline): otio timeline object @@ -315,7 +315,7 @@ or updating already created. Publishing will create OTIO file. kwargs = {} if extension == ".edl": # EDL has no frame rate embedded so needs explicit - # frame rate else 24 is asssumed. + # frame rate else 24 is assumed. kwargs["rate"] = fps kwargs["ignore_timecode_mismatch"] = True @@ -358,7 +358,7 @@ or updating already created. Publishing will create OTIO file. sequence_file_name, first_otio_timeline=None ): - """Helping function fro creating clip instance + """Helping function for creating clip instance Args: otio_timeline (otio.Timeline): otio timeline object @@ -527,7 +527,7 @@ or updating already created. Publishing will create OTIO file. Args: otio_clip (otio.Clip): otio clip object - preset (dict): sigle family preset + preset (dict): single family preset instance_data (dict): instance data parenting_data (dict): shot instance parent data @@ -767,7 +767,7 @@ or updating already created. Publishing will create OTIO file. ] def _validate_clip_for_processing(self, otio_clip): - """Validate otio clip attribues + """Validate otio clip attributes Args: otio_clip (otio.Clip): otio clip object @@ -843,7 +843,7 @@ or updating already created. Publishing will create OTIO file. single_item=False, label="Media files", ), - # TODO: perhpas better would be timecode and fps input + # TODO: perhaps better would be timecode and fps input NumberDef( "timeline_offset", default=0, diff --git a/openpype/hosts/traypublisher/plugins/publish/collect_simple_instances.py b/openpype/hosts/traypublisher/plugins/publish/collect_simple_instances.py index 183195a515..c081216481 100644 --- a/openpype/hosts/traypublisher/plugins/publish/collect_simple_instances.py +++ b/openpype/hosts/traypublisher/plugins/publish/collect_simple_instances.py @@ -14,7 +14,7 @@ class CollectSettingsSimpleInstances(pyblish.api.InstancePlugin): There is also possibility to have reviewable representation which can be stored under 'reviewable' attribute stored on instance data. If there was - already created representation with the same files as 'revieable' containes + already created representation with the same files as 'reviewable' contains Representations can be marked for review and in that case is also added 'review' family to instance families. For review can be marked only one diff --git a/openpype/hosts/tvpaint/plugins/publish/help/validate_layers_visibility.xml b/openpype/hosts/tvpaint/plugins/publish/help/validate_layers_visibility.xml index e7be735888..5832c74350 100644 --- a/openpype/hosts/tvpaint/plugins/publish/help/validate_layers_visibility.xml +++ b/openpype/hosts/tvpaint/plugins/publish/help/validate_layers_visibility.xml @@ -1,7 +1,7 @@ -Layers visiblity +Layers visibility ## All layers are not visible Layers visibility was changed during publishing which caused that all layers for subset "{instance_name}" are hidden. diff --git a/openpype/hosts/tvpaint/plugins/publish/help/validate_workfile_metadata.xml b/openpype/hosts/tvpaint/plugins/publish/help/validate_workfile_metadata.xml index 7397f6ef0b..0fc03c2948 100644 --- a/openpype/hosts/tvpaint/plugins/publish/help/validate_workfile_metadata.xml +++ b/openpype/hosts/tvpaint/plugins/publish/help/validate_workfile_metadata.xml @@ -11,7 +11,7 @@ Your scene does not contain metadata about {missing_metadata}. Resave the scene using Workfiles tool or hit the "Repair" button on the right. -### How this could happend? +### How this could happen? You're using scene file that was not created using Workfiles tool. diff --git a/openpype/hosts/tvpaint/plugins/publish/help/validate_workfile_project_name.xml b/openpype/hosts/tvpaint/plugins/publish/help/validate_workfile_project_name.xml index c4ffafc8b5..bb57e93bf2 100644 --- a/openpype/hosts/tvpaint/plugins/publish/help/validate_workfile_project_name.xml +++ b/openpype/hosts/tvpaint/plugins/publish/help/validate_workfile_project_name.xml @@ -13,7 +13,7 @@ If the workfile belongs to project "{env_project_name}" then use Workfiles tool Otherwise close TVPaint and launch it again from project you want to publish in. -### How this could happend? +### How this could happen? You've opened workfile from different project. You've opened TVPaint on a task from "{env_project_name}" then you've opened TVPaint again on task from "{workfile_project_name}" without closing the TVPaint. Because TVPaint can run only once the project didn't change. diff --git a/openpype/hosts/tvpaint/plugins/publish/validate_asset_name.py b/openpype/hosts/tvpaint/plugins/publish/validate_asset_name.py index d7984ce971..9347960d3f 100644 --- a/openpype/hosts/tvpaint/plugins/publish/validate_asset_name.py +++ b/openpype/hosts/tvpaint/plugins/publish/validate_asset_name.py @@ -38,7 +38,7 @@ class ValidateAssetName( OptionalPyblishPluginMixin, pyblish.api.ContextPlugin ): - """Validate assset name present on instance. + """Validate asset name present on instance. Asset name on instance should be the same as context's. """ diff --git a/openpype/hosts/unreal/api/pipeline.py b/openpype/hosts/unreal/api/pipeline.py index 8a5a459194..1a7c626984 100644 --- a/openpype/hosts/unreal/api/pipeline.py +++ b/openpype/hosts/unreal/api/pipeline.py @@ -306,7 +306,7 @@ def imprint(node, data): def show_tools_popup(): """Show popup with tools. - Popup will disappear on click or loosing focus. + Popup will disappear on click or losing focus. """ from openpype.hosts.unreal.api import tools_ui diff --git a/openpype/hosts/unreal/integration/UE_4.7/OpenPype/Source/OpenPype/Private/OpenPypeLib.cpp b/openpype/hosts/unreal/integration/UE_4.7/OpenPype/Source/OpenPype/Private/OpenPypeLib.cpp index 008025e816..34faba1f49 100644 --- a/openpype/hosts/unreal/integration/UE_4.7/OpenPype/Source/OpenPype/Private/OpenPypeLib.cpp +++ b/openpype/hosts/unreal/integration/UE_4.7/OpenPype/Source/OpenPype/Private/OpenPypeLib.cpp @@ -31,7 +31,7 @@ bool UOpenPypeLib::SetFolderColor(const FString& FolderPath, const FLinearColor& } /** - * Returns all poperties on given object + * Returns all properties on given object * @param cls - class * @return TArray of properties */ diff --git a/openpype/hosts/unreal/integration/UE_4.7/OpenPype/Source/OpenPype/Public/Commandlets/OPActionResult.h b/openpype/hosts/unreal/integration/UE_4.7/OpenPype/Source/OpenPype/Public/Commandlets/OPActionResult.h index c960bbf190..322a23a3e8 100644 --- a/openpype/hosts/unreal/integration/UE_4.7/OpenPype/Source/OpenPype/Public/Commandlets/OPActionResult.h +++ b/openpype/hosts/unreal/integration/UE_4.7/OpenPype/Source/OpenPype/Public/Commandlets/OPActionResult.h @@ -16,7 +16,7 @@ /** * @brief This enum values are humanly readable mapping of error codes. * Here should be all error codes to be possible find what went wrong. -* TODO: In the future should exists an web document where is mapped error code & what problem occured & how to repair it... +* TODO: In the future a web document should exists with the mapped error code & what problem occurred & how to repair it... */ UENUM() namespace EOP_ActionResult @@ -27,11 +27,11 @@ namespace EOP_ActionResult ProjectNotCreated, ProjectNotLoaded, ProjectNotSaved, - //....Here insert another values + //....Here insert another values //Do not remove! //Usable for looping through enum values - __Last UMETA(Hidden) + __Last UMETA(Hidden) }; } @@ -63,10 +63,10 @@ public: private: /** @brief Action status */ - EOP_ActionResult::Type Status; + EOP_ActionResult::Type Status; /** @brief Optional reason of fail */ - FText Reason; + FText Reason; public: /** @@ -77,7 +77,7 @@ public: EOP_ActionResult::Type& GetStatus(); FText& GetReason(); -private: +private: void TryLog() const; }; diff --git a/openpype/hosts/unreal/integration/UE_5.0/OpenPype/Source/OpenPype/Private/OpenPypeLib.cpp b/openpype/hosts/unreal/integration/UE_5.0/OpenPype/Source/OpenPype/Private/OpenPypeLib.cpp index 008025e816..34faba1f49 100644 --- a/openpype/hosts/unreal/integration/UE_5.0/OpenPype/Source/OpenPype/Private/OpenPypeLib.cpp +++ b/openpype/hosts/unreal/integration/UE_5.0/OpenPype/Source/OpenPype/Private/OpenPypeLib.cpp @@ -31,7 +31,7 @@ bool UOpenPypeLib::SetFolderColor(const FString& FolderPath, const FLinearColor& } /** - * Returns all poperties on given object + * Returns all properties on given object * @param cls - class * @return TArray of properties */ diff --git a/openpype/hosts/unreal/integration/UE_5.0/OpenPype/Source/OpenPype/Public/Commandlets/OPActionResult.h b/openpype/hosts/unreal/integration/UE_5.0/OpenPype/Source/OpenPype/Public/Commandlets/OPActionResult.h index c960bbf190..322a23a3e8 100644 --- a/openpype/hosts/unreal/integration/UE_5.0/OpenPype/Source/OpenPype/Public/Commandlets/OPActionResult.h +++ b/openpype/hosts/unreal/integration/UE_5.0/OpenPype/Source/OpenPype/Public/Commandlets/OPActionResult.h @@ -16,7 +16,7 @@ /** * @brief This enum values are humanly readable mapping of error codes. * Here should be all error codes to be possible find what went wrong. -* TODO: In the future should exists an web document where is mapped error code & what problem occured & how to repair it... +* TODO: In the future a web document should exists with the mapped error code & what problem occurred & how to repair it... */ UENUM() namespace EOP_ActionResult @@ -27,11 +27,11 @@ namespace EOP_ActionResult ProjectNotCreated, ProjectNotLoaded, ProjectNotSaved, - //....Here insert another values + //....Here insert another values //Do not remove! //Usable for looping through enum values - __Last UMETA(Hidden) + __Last UMETA(Hidden) }; } @@ -63,10 +63,10 @@ public: private: /** @brief Action status */ - EOP_ActionResult::Type Status; + EOP_ActionResult::Type Status; /** @brief Optional reason of fail */ - FText Reason; + FText Reason; public: /** @@ -77,7 +77,7 @@ public: EOP_ActionResult::Type& GetStatus(); FText& GetReason(); -private: +private: void TryLog() const; }; diff --git a/openpype/hosts/unreal/plugins/load/load_camera.py b/openpype/hosts/unreal/plugins/load/load_camera.py index ca6b0ce736..2496440e5f 100644 --- a/openpype/hosts/unreal/plugins/load/load_camera.py +++ b/openpype/hosts/unreal/plugins/load/load_camera.py @@ -171,7 +171,7 @@ class CameraLoader(plugin.Loader): project_name = legacy_io.active_project() # TODO refactor - # - Creationg of hierarchy should be a function in unreal integration + # - Creating of hierarchy should be a function in unreal integration # - it's used in multiple loaders but must not be loader's logic # - hard to say what is purpose of the loop # - variables does not match their meaning diff --git a/openpype/hosts/webpublisher/lib.py b/openpype/hosts/webpublisher/lib.py index 4bc3f1db80..b207f85b46 100644 --- a/openpype/hosts/webpublisher/lib.py +++ b/openpype/hosts/webpublisher/lib.py @@ -30,7 +30,7 @@ def parse_json(path): Returns: (dict) or None if unparsable Raises: - AsssertionError if 'path' doesn't exist + AssertionError if 'path' doesn't exist """ path = path.strip('\"') assert os.path.isfile(path), ( diff --git a/openpype/lib/applications.py b/openpype/lib/applications.py index 127d31d042..8adae34827 100644 --- a/openpype/lib/applications.py +++ b/openpype/lib/applications.py @@ -969,7 +969,7 @@ class ApplicationLaunchContext: """Helper to collect application launch hooks from addons. Module have to have implemented 'get_launch_hook_paths' method which - can expect appliction as argument or nothing. + can expect application as argument or nothing. Returns: List[str]: Paths to launch hook directories. diff --git a/openpype/lib/attribute_definitions.py b/openpype/lib/attribute_definitions.py index b5cd15f41a..6054d2a92a 100644 --- a/openpype/lib/attribute_definitions.py +++ b/openpype/lib/attribute_definitions.py @@ -9,7 +9,7 @@ from abc import ABCMeta, abstractmethod, abstractproperty import six import clique -# Global variable which store attribude definitions by type +# Global variable which store attribute definitions by type # - default types are registered on import _attr_defs_by_type = {} @@ -93,7 +93,7 @@ class AbstractAttrDefMeta(ABCMeta): @six.add_metaclass(AbstractAttrDefMeta) class AbstractAttrDef(object): - """Abstraction of attribute definiton. + """Abstraction of attribute definition. Each attribute definition must have implemented validation and conversion method. @@ -427,7 +427,7 @@ class EnumDef(AbstractAttrDef): """Enumeration of single item from items. Args: - items: Items definition that can be coverted using + items: Items definition that can be converted using 'prepare_enum_items'. default: Default value. Must be one key(value) from passed items. """ diff --git a/openpype/lib/events.py b/openpype/lib/events.py index 096201312f..bed00fe659 100644 --- a/openpype/lib/events.py +++ b/openpype/lib/events.py @@ -156,7 +156,7 @@ class EventCallback(object): self._enabled = enabled def deregister(self): - """Calling this funcion will cause that callback will be removed.""" + """Calling this function will cause that callback will be removed.""" # Fake reference self._ref_valid = False diff --git a/openpype/lib/execute.py b/openpype/lib/execute.py index 6f9a095285..834394b02f 100644 --- a/openpype/lib/execute.py +++ b/openpype/lib/execute.py @@ -163,7 +163,7 @@ def run_subprocess(*args, **kwargs): def clean_envs_for_openpype_process(env=None): - """Modify environemnts that may affect OpenPype process. + """Modify environments that may affect OpenPype process. Main reason to implement this function is to pop PYTHONPATH which may be affected by in-host environments. diff --git a/openpype/lib/file_transaction.py b/openpype/lib/file_transaction.py index 81332a8891..80f4e81f2c 100644 --- a/openpype/lib/file_transaction.py +++ b/openpype/lib/file_transaction.py @@ -130,7 +130,7 @@ class FileTransaction(object): path_same = self._same_paths(src, dst) if path_same: self.log.debug( - "Source and destionation are same files {} -> {}".format( + "Source and destination are same files {} -> {}".format( src, dst)) continue diff --git a/openpype/lib/transcoding.py b/openpype/lib/transcoding.py index 799693554f..57968b3700 100644 --- a/openpype/lib/transcoding.py +++ b/openpype/lib/transcoding.py @@ -540,7 +540,7 @@ def convert_for_ffmpeg( continue # Remove attributes that have string value longer than allowed length - # for ffmpeg or when containt unallowed symbols + # for ffmpeg or when contain unallowed symbols erase_reason = "Missing reason" erase_attribute = False if len(attr_value) > MAX_FFMPEG_STRING_LEN: @@ -680,7 +680,7 @@ def convert_input_paths_for_ffmpeg( continue # Remove attributes that have string value longer than allowed - # length for ffmpeg or when containt unallowed symbols + # length for ffmpeg or when containing unallowed symbols erase_reason = "Missing reason" erase_attribute = False if len(attr_value) > MAX_FFMPEG_STRING_LEN: @@ -968,7 +968,7 @@ def _ffmpeg_dnxhd_codec_args(stream_data, source_ffmpeg_cmd): if source_ffmpeg_cmd: # Define bitrate arguments bit_rate_args = ("-b:v", "-vb",) - # Seprate the two variables in case something else should be copied + # Separate the two variables in case something else should be copied # from source command copy_args = [] copy_args.extend(bit_rate_args) diff --git a/openpype/lib/vendor_bin_utils.py b/openpype/lib/vendor_bin_utils.py index e5deb7a6b2..f27c78d486 100644 --- a/openpype/lib/vendor_bin_utils.py +++ b/openpype/lib/vendor_bin_utils.py @@ -260,7 +260,7 @@ def _oiio_executable_validation(filepath): that it can be executed. For that is used '--help' argument which is fast and does not need any other inputs. - Any possible crash of missing libraries or invalid build should be catched. + Any possible crash of missing libraries or invalid build should be caught. Main reason is to validate if executable can be executed on OS just running which can be issue ob linux machines. @@ -329,7 +329,7 @@ def _ffmpeg_executable_validation(filepath): that it can be executed. For that is used '-version' argument which is fast and does not need any other inputs. - Any possible crash of missing libraries or invalid build should be catched. + Any possible crash of missing libraries or invalid build should be caught. Main reason is to validate if executable can be executed on OS just running which can be issue ob linux machines. diff --git a/openpype/modules/base.py b/openpype/modules/base.py index 0fd21492e8..730585212b 100644 --- a/openpype/modules/base.py +++ b/openpype/modules/base.py @@ -472,7 +472,7 @@ class OpenPypeModule: Args: application (Application): Application that is launched. - env (dict): Current environemnt variables. + env (dict): Current environment variables. """ pass @@ -622,7 +622,7 @@ class ModulesManager: # Check if class is abstract (Developing purpose) if inspect.isabstract(modules_item): - # Find missing implementations by convetion on `abc` module + # Find missing implementations by convention on `abc` module not_implemented = [] for attr_name in dir(modules_item): attr = getattr(modules_item, attr_name, None) @@ -708,13 +708,13 @@ class ModulesManager: ] def collect_global_environments(self): - """Helper to collect global enviornment variabled from modules. + """Helper to collect global environment variabled from modules. Returns: dict: Global environment variables from enabled modules. Raises: - AssertionError: Gobal environment variables must be unique for + AssertionError: Global environment variables must be unique for all modules. """ module_envs = {} @@ -1174,7 +1174,7 @@ class TrayModulesManager(ModulesManager): def get_module_settings_defs(): - """Check loaded addons/modules for existence of thei settings definition. + """Check loaded addons/modules for existence of their settings definition. Check if OpenPype addon/module as python module has class that inherit from `ModuleSettingsDef` in python module variables (imported @@ -1204,7 +1204,7 @@ def get_module_settings_defs(): continue if inspect.isabstract(attr): - # Find missing implementations by convetion on `abc` module + # Find missing implementations by convention on `abc` module not_implemented = [] for attr_name in dir(attr): attr = getattr(attr, attr_name, None) @@ -1293,7 +1293,7 @@ class BaseModuleSettingsDef: class ModuleSettingsDef(BaseModuleSettingsDef): - """Settings definiton with separated system and procect settings parts. + """Settings definition with separated system and procect settings parts. Reduce conditions that must be checked and adds predefined methods for each case. diff --git a/openpype/modules/clockify/clockify_api.py b/openpype/modules/clockify/clockify_api.py index 80979c83ab..47af002f7a 100644 --- a/openpype/modules/clockify/clockify_api.py +++ b/openpype/modules/clockify/clockify_api.py @@ -247,7 +247,7 @@ class ClockifyAPI: current_timer = self.get_in_progress() # Check if is currently run another times and has same values - # DO not restart the timer, if it is already running for curent task + # DO not restart the timer, if it is already running for current task if current_timer: current_timer_hierarchy = current_timer.get("description") current_project_id = current_timer.get("projectId") diff --git a/openpype/modules/clockify/clockify_module.py b/openpype/modules/clockify/clockify_module.py index 200a268ad7..b6efec7907 100644 --- a/openpype/modules/clockify/clockify_module.py +++ b/openpype/modules/clockify/clockify_module.py @@ -76,7 +76,7 @@ class ClockifyModule(OpenPypeModule, ITrayModule, IPluginPaths): return def get_plugin_paths(self): - """Implementaton of IPluginPaths to get plugin paths.""" + """Implementation of IPluginPaths to get plugin paths.""" actions_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), "launcher_actions" ) diff --git a/openpype/modules/clockify/widgets.py b/openpype/modules/clockify/widgets.py index 8c28f38b6e..86e67569f2 100644 --- a/openpype/modules/clockify/widgets.py +++ b/openpype/modules/clockify/widgets.py @@ -34,7 +34,7 @@ class MessageWidget(QtWidgets.QWidget): def _ui_layout(self, messages): if not messages: - messages = ["*Misssing messages (This is a bug)*", ] + messages = ["*Missing messages (This is a bug)*", ] elif not isinstance(messages, (tuple, list)): messages = [messages, ] diff --git a/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py b/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py index cc069cf51a..0c899a500c 100644 --- a/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py @@ -66,7 +66,7 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin, ), NumberDef( "concurrency", - label="Concurency", + label="Concurrency", default=cls.concurrent_tasks, decimals=0, minimum=1, diff --git a/openpype/modules/deadline/plugins/publish/submit_publish_job.py b/openpype/modules/deadline/plugins/publish/submit_publish_job.py index 0d0698c21f..f6a794fbc0 100644 --- a/openpype/modules/deadline/plugins/publish/submit_publish_job.py +++ b/openpype/modules/deadline/plugins/publish/submit_publish_job.py @@ -85,10 +85,10 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): These jobs are dependent on a deadline or muster job submission prior to this plug-in. - - In case of Deadline, it creates dependend job on farm publishing + - In case of Deadline, it creates dependent job on farm publishing rendered image sequence. - - In case of Muster, there is no need for such thing as dependend job, + - In case of Muster, there is no need for such thing as dependent job, post action will be executed and rendered sequence will be published. Options in instance.data: @@ -108,7 +108,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): - publishJobState (str, Optional): "Active" or "Suspended" This defaults to "Suspended" - - expectedFiles (list or dict): explained bellow + - expectedFiles (list or dict): explained below """ @@ -158,7 +158,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): # regex for finding frame number in string R_FRAME_NUMBER = re.compile(r'.+\.(?P[0-9]+)\..+') - # mapping of instance properties to be transfered to new instance for every + # mapping of instance properties to be transferred to new instance for every # specified family instance_transfer = { "slate": ["slateFrames", "slate"], @@ -398,7 +398,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): continue r_col.indexes.remove(frame) - # now we need to translate published names from represenation + # now we need to translate published names from representation # back. This is tricky, right now we'll just use same naming # and only switch frame numbers resource_files = [] @@ -535,7 +535,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): if preview: new_instance["review"] = True - # create represenation + # create representation if isinstance(col, (list, tuple)): files = [os.path.basename(f) for f in col] else: @@ -748,7 +748,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): # type: (pyblish.api.Instance) -> None """Process plugin. - Detect type of renderfarm submission and create and post dependend job + Detect type of renderfarm submission and create and post dependent job in case of Deadline. It creates json file with metadata needed for publishing in directory of render. @@ -986,7 +986,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): instances = [instance_skeleton_data] # if we are attaching to other subsets, create copy of existing - # instances, change data to match thats subset and replace + # instances, change data to match its subset and replace # existing instances with modified data if instance.data.get("attachTo"): self.log.info("Attaching render to subset:") diff --git a/openpype/modules/ftrack/event_handlers_server/action_clone_review_session.py b/openpype/modules/ftrack/event_handlers_server/action_clone_review_session.py index 1ad7a17785..333228c699 100644 --- a/openpype/modules/ftrack/event_handlers_server/action_clone_review_session.py +++ b/openpype/modules/ftrack/event_handlers_server/action_clone_review_session.py @@ -44,7 +44,7 @@ def clone_review_session(session, entity): class CloneReviewSession(ServerAction): '''Generate Client Review action - `label` a descriptive string identifing your action. + `label` a descriptive string identifying your action. `varaint` To group actions together, give them the same label and specify a unique variant per action. `identifier` a unique identifier for your action. diff --git a/openpype/modules/ftrack/event_handlers_server/action_create_review_session.py b/openpype/modules/ftrack/event_handlers_server/action_create_review_session.py index 21382007a0..42a279e333 100644 --- a/openpype/modules/ftrack/event_handlers_server/action_create_review_session.py +++ b/openpype/modules/ftrack/event_handlers_server/action_create_review_session.py @@ -230,7 +230,7 @@ class CreateDailyReviewSessionServerAction(ServerAction): if not today_session_name: continue - # Find matchin review session + # Find matching review session project_review_sessions = review_sessions_by_project_id[project_id] todays_session = None yesterdays_session = None diff --git a/openpype/modules/ftrack/event_handlers_server/action_prepare_project.py b/openpype/modules/ftrack/event_handlers_server/action_prepare_project.py index 332648cd02..02231cbe3c 100644 --- a/openpype/modules/ftrack/event_handlers_server/action_prepare_project.py +++ b/openpype/modules/ftrack/event_handlers_server/action_prepare_project.py @@ -124,7 +124,7 @@ class PrepareProjectServer(ServerAction): root_items.append({ "type": "label", "value": ( - "

NOTE: Roots are crutial for path filling" + "

NOTE: Roots are crucial for path filling" " (and creating folder structure).

" ) }) diff --git a/openpype/modules/ftrack/event_handlers_server/action_tranfer_hierarchical_values.py b/openpype/modules/ftrack/event_handlers_server/action_tranfer_hierarchical_values.py index d160b7200d..f6899843a3 100644 --- a/openpype/modules/ftrack/event_handlers_server/action_tranfer_hierarchical_values.py +++ b/openpype/modules/ftrack/event_handlers_server/action_tranfer_hierarchical_values.py @@ -12,7 +12,7 @@ from openpype_modules.ftrack.lib.avalon_sync import create_chunks class TransferHierarchicalValues(ServerAction): - """Transfer values across hierarhcical attributes. + """Transfer values across hierarchical attributes. Aalso gives ability to convert types meanwhile. That is limited to conversions between numbers and strings @@ -67,7 +67,7 @@ class TransferHierarchicalValues(ServerAction): "type": "label", "value": ( "Didn't found custom attributes" - " that can be transfered." + " that can be transferred." ) }] } diff --git a/openpype/modules/ftrack/event_handlers_server/event_next_task_update.py b/openpype/modules/ftrack/event_handlers_server/event_next_task_update.py index a65ae46545..a100c34f67 100644 --- a/openpype/modules/ftrack/event_handlers_server/event_next_task_update.py +++ b/openpype/modules/ftrack/event_handlers_server/event_next_task_update.py @@ -279,7 +279,7 @@ class NextTaskUpdate(BaseEvent): except Exception: session.rollback() self.log.warning( - "\"{}\" status couldnt be set to \"{}\"".format( + "\"{}\" status couldn't be set to \"{}\"".format( ent_path, new_status["name"] ), exc_info=True diff --git a/openpype/modules/ftrack/event_handlers_server/event_push_frame_values_to_task.py b/openpype/modules/ftrack/event_handlers_server/event_push_frame_values_to_task.py index 0f10145c06..ed630ad59d 100644 --- a/openpype/modules/ftrack/event_handlers_server/event_push_frame_values_to_task.py +++ b/openpype/modules/ftrack/event_handlers_server/event_push_frame_values_to_task.py @@ -394,7 +394,7 @@ class PushHierValuesToNonHierEvent(BaseEvent): project_id: str, entities_info: list[dict[str, Any]] ): - """Proces changes in single project. + """Process changes in single project. Args: session (ftrack_api.Session): Ftrack session. diff --git a/openpype/modules/ftrack/event_handlers_server/event_radio_buttons.py b/openpype/modules/ftrack/event_handlers_server/event_radio_buttons.py index 99ad3aec37..358a8d2310 100644 --- a/openpype/modules/ftrack/event_handlers_server/event_radio_buttons.py +++ b/openpype/modules/ftrack/event_handlers_server/event_radio_buttons.py @@ -7,7 +7,7 @@ class RadioButtons(BaseEvent): ignore_me = True def launch(self, session, event): - '''Provides a readio button behaviour to any bolean attribute in + '''Provides a radio button behaviour to any boolean attribute in radio_button group.''' # start of event procedure ---------------------------------- diff --git a/openpype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py b/openpype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py index 0058a428e3..0aa0b9f9f5 100644 --- a/openpype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py +++ b/openpype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py @@ -787,7 +787,7 @@ class SyncToAvalonEvent(BaseEvent): # Filter updates where name is changing for ftrack_id, ent_info in updated.items(): ent_keys = ent_info["keys"] - # Seprate update info from rename + # Separate update info from rename if "name" not in ent_keys: continue @@ -827,7 +827,7 @@ class SyncToAvalonEvent(BaseEvent): # 5.) Process updated self.process_updated() time_6 = time.time() - # 6.) Process changes in hierarchy or hier custom attribues + # 6.) Process changes in hierarchy or hier custom attributes self.process_hier_cleanup() time_7 = time.time() self.process_task_updates() @@ -1094,7 +1094,7 @@ class SyncToAvalonEvent(BaseEvent): def check_names_synchronizable(self, names): """Check if entities with specific names are importable. - This check should happend after removing entity or renaming entity. + This check should happen after removing entity or renaming entity. When entity was removed or renamed then it's name is possible to sync. """ joined_passed_names = ", ".join( @@ -1743,7 +1743,7 @@ class SyncToAvalonEvent(BaseEvent): def process_moved(self): """ - Handles moved entities to different place in hiearchy. + Handles moved entities to different place in hierarchy. (Not tasks - handled separately.) """ if not self.ftrack_moved: @@ -1792,7 +1792,7 @@ class SyncToAvalonEvent(BaseEvent): self.log.warning("{} <{}>".format(error_msg, ent_path)) continue - # THIS MUST HAPPEND AFTER CREATING NEW ENTITIES !!!! + # THIS MUST HAPPEN AFTER CREATING NEW ENTITIES !!!! # - because may be moved to new created entity if "data" not in self.updates[mongo_id]: self.updates[mongo_id]["data"] = {} @@ -2323,7 +2323,7 @@ class SyncToAvalonEvent(BaseEvent): items.append("{} - \"{}\"".format(ent_path, value)) self.report_items["error"][fps_msg] = items - # Get dictionary with not None hierarchical values to pull to childs + # Get dictionary with not None hierarchical values to pull to children project_values = {} for key, value in ( entities_dict[ftrack_project_id]["hier_attrs"].items() @@ -2460,7 +2460,7 @@ class SyncToAvalonEvent(BaseEvent): def update_entities(self): """ Update Avalon entities by mongo bulk changes. - Expects self.updates which are transfered to $set part of update + Expects self.updates which are transferred to $set part of update command. Resets self.updates afterwards. """ diff --git a/openpype/modules/ftrack/event_handlers_server/event_task_to_parent_status.py b/openpype/modules/ftrack/event_handlers_server/event_task_to_parent_status.py index a0e039926e..25fa3b0535 100644 --- a/openpype/modules/ftrack/event_handlers_server/event_task_to_parent_status.py +++ b/openpype/modules/ftrack/event_handlers_server/event_task_to_parent_status.py @@ -291,7 +291,7 @@ class TaskStatusToParent(BaseEvent): except Exception: session.rollback() self.log.warning( - "\"{}\" status couldnt be set to \"{}\"".format( + "\"{}\" status couldn't be set to \"{}\"".format( ent_path, new_status["name"] ), exc_info=True @@ -399,7 +399,7 @@ class TaskStatusToParent(BaseEvent): # For cases there are multiple tasks in changes # - task status which match any new status item by order in the - # list `single_match` is preffered + # list `single_match` is preferred best_order = len(single_match) best_order_status = None for task_entity in task_entities: diff --git a/openpype/modules/ftrack/event_handlers_server/event_user_assigment.py b/openpype/modules/ftrack/event_handlers_server/event_user_assigment.py index c4e48b92f0..9539a34f5e 100644 --- a/openpype/modules/ftrack/event_handlers_server/event_user_assigment.py +++ b/openpype/modules/ftrack/event_handlers_server/event_user_assigment.py @@ -10,11 +10,11 @@ from openpype_modules.ftrack.lib.avalon_sync import CUST_ATTR_ID_KEY class UserAssigmentEvent(BaseEvent): """ - This script will intercept user assigment / de-assigment event and + This script will intercept user assignment / de-assignment event and run shell script, providing as much context as possible. It expects configuration file ``presets/ftrack/user_assigment_event.json``. - In it, you define paths to scripts to be run for user assigment event and + In it, you define paths to scripts to be run for user assignment event and for user-deassigment:: { "add": [ diff --git a/openpype/modules/ftrack/event_handlers_server/event_version_to_task_statuses.py b/openpype/modules/ftrack/event_handlers_server/event_version_to_task_statuses.py index e36c3eecd9..fb40fd6417 100644 --- a/openpype/modules/ftrack/event_handlers_server/event_version_to_task_statuses.py +++ b/openpype/modules/ftrack/event_handlers_server/event_version_to_task_statuses.py @@ -102,7 +102,7 @@ class VersionToTaskStatus(BaseEvent): asset_version_entities.append(asset_version) task_ids.add(asset_version["task_id"]) - # Skipt if `task_ids` are empty + # Skip if `task_ids` are empty if not task_ids: return diff --git a/openpype/modules/ftrack/event_handlers_user/action_batch_task_creation.py b/openpype/modules/ftrack/event_handlers_user/action_batch_task_creation.py index c7fb1af98b..06d572601d 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_batch_task_creation.py +++ b/openpype/modules/ftrack/event_handlers_user/action_batch_task_creation.py @@ -7,7 +7,7 @@ from openpype_modules.ftrack.lib import BaseAction, statics_icon class BatchTasksAction(BaseAction): '''Batch Tasks action - `label` a descriptive string identifing your action. + `label` a descriptive string identifying your action. `varaint` To group actions together, give them the same label and specify a unique variant per action. `identifier` a unique identifier for your action. diff --git a/openpype/modules/ftrack/event_handlers_user/action_create_cust_attrs.py b/openpype/modules/ftrack/event_handlers_user/action_create_cust_attrs.py index c19cfd1502..471a8c4182 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_create_cust_attrs.py +++ b/openpype/modules/ftrack/event_handlers_user/action_create_cust_attrs.py @@ -82,9 +82,9 @@ config (dictionary) write_security_roles/read_security_roles (array of strings) - default: ["ALL"] - strings should be role names (e.g.: ["API", "Administrator"]) - - if set to ["ALL"] - all roles will be availabled + - if set to ["ALL"] - all roles will be available - if first is 'except' - roles will be set to all except roles in array - - Warning: Be carefull with except - roles can be different by company + - Warning: Be careful with except - roles can be different by company - example: write_security_roles = ["except", "User"] read_security_roles = ["ALL"] # (User is can only read) @@ -500,7 +500,7 @@ class CustomAttributes(BaseAction): data = {} # Get key, label, type data.update(self.get_required(cust_attr_data)) - # Get hierachical/ entity_type/ object_id + # Get hierarchical/ entity_type/ object_id data.update(self.get_entity_type(cust_attr_data)) # Get group, default, security roles data.update(self.get_optional(cust_attr_data)) diff --git a/openpype/modules/ftrack/event_handlers_user/action_create_folders.py b/openpype/modules/ftrack/event_handlers_user/action_create_folders.py index 9806f83773..cbeff5343f 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_create_folders.py +++ b/openpype/modules/ftrack/event_handlers_user/action_create_folders.py @@ -51,7 +51,7 @@ class CreateFolders(BaseAction): }, { "type": "label", - "value": "With all chilren entities" + "value": "With all children entities" }, { "name": "children_included", diff --git a/openpype/modules/ftrack/event_handlers_user/action_delete_asset.py b/openpype/modules/ftrack/event_handlers_user/action_delete_asset.py index 03d029b0c1..72a5efbcfe 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_delete_asset.py +++ b/openpype/modules/ftrack/event_handlers_user/action_delete_asset.py @@ -18,7 +18,7 @@ class DeleteAssetSubset(BaseAction): # Action label. label = "Delete Asset/Subsets" # Action description. - description = "Removes from Avalon with all childs and asset from Ftrack" + description = "Removes from Avalon with all children and asset from Ftrack" icon = statics_icon("ftrack", "action_icons", "DeleteAsset.svg") settings_key = "delete_asset_subset" diff --git a/openpype/modules/ftrack/event_handlers_user/action_delete_old_versions.py b/openpype/modules/ftrack/event_handlers_user/action_delete_old_versions.py index c543dc8834..ec14c6918b 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_delete_old_versions.py +++ b/openpype/modules/ftrack/event_handlers_user/action_delete_old_versions.py @@ -27,7 +27,7 @@ class DeleteOldVersions(BaseAction): variant = "- Delete old versions" description = ( "Delete files from older publishes so project can be" - " archived with only lates versions." + " archived with only latest versions." ) icon = statics_icon("ftrack", "action_icons", "OpenPypeAdmin.svg") @@ -307,7 +307,7 @@ class DeleteOldVersions(BaseAction): file_path, seq_path = self.path_from_represenation(repre, anatomy) if file_path is None: self.log.warning(( - "Could not format path for represenation \"{}\"" + "Could not format path for representation \"{}\"" ).format(str(repre))) continue diff --git a/openpype/modules/ftrack/event_handlers_user/action_delivery.py b/openpype/modules/ftrack/event_handlers_user/action_delivery.py index a400c8f5f0..559de3a24d 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_delivery.py +++ b/openpype/modules/ftrack/event_handlers_user/action_delivery.py @@ -601,7 +601,7 @@ class Delivery(BaseAction): return self.report(report_items) def report(self, report_items): - """Returns dict with final status of delivery (succes, fail etc.).""" + """Returns dict with final status of delivery (success, fail etc.).""" items = [] for msg, _items in report_items.items(): diff --git a/openpype/modules/ftrack/event_handlers_user/action_fill_workfile_attr.py b/openpype/modules/ftrack/event_handlers_user/action_fill_workfile_attr.py index fb1cdf340e..36d29db96b 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_fill_workfile_attr.py +++ b/openpype/modules/ftrack/event_handlers_user/action_fill_workfile_attr.py @@ -246,7 +246,7 @@ class FillWorkfileAttributeAction(BaseAction): project_name = project_entity["full_name"] - # Find matchin asset documents and map them by ftrack task entities + # Find matching asset documents and map them by ftrack task entities # - result stored to 'asset_docs_with_task_entities' is list with # tuple `(asset document, [task entitis, ...])` # Quety all asset documents diff --git a/openpype/modules/ftrack/event_handlers_user/action_job_killer.py b/openpype/modules/ftrack/event_handlers_user/action_job_killer.py index f489c0c54c..dd68c75f84 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_job_killer.py +++ b/openpype/modules/ftrack/event_handlers_user/action_job_killer.py @@ -54,14 +54,14 @@ class JobKiller(BaseAction): for job in jobs: try: data = json.loads(job["data"]) - desctiption = data["description"] + description = data["description"] except Exception: - desctiption = "*No description*" + description = "*No description*" user_id = job["user_id"] username = usernames_by_id.get(user_id) or "Unknown user" created = job["created_at"].strftime('%d.%m.%Y %H:%M:%S') label = "{} - {} - {}".format( - username, desctiption, created + username, description, created ) item_label = { "type": "label", diff --git a/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py b/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py index e825198180..19d5701e08 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py +++ b/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py @@ -24,7 +24,7 @@ class PrepareProjectLocal(BaseAction): settings_key = "prepare_project" - # Key to store info about trigerring create folder structure + # Key to store info about triggering create folder structure create_project_structure_key = "create_folder_structure" create_project_structure_identifier = "create.project.structure" item_splitter = {"type": "label", "value": "---"} @@ -146,7 +146,7 @@ class PrepareProjectLocal(BaseAction): root_items.append({ "type": "label", "value": ( - "

NOTE: Roots are crutial for path filling" + "

NOTE: Roots are crucial for path filling" " (and creating folder structure).

" ) }) diff --git a/openpype/modules/ftrack/event_handlers_user/action_rv.py b/openpype/modules/ftrack/event_handlers_user/action_rv.py index d05f0c47f6..39cf33d605 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_rv.py +++ b/openpype/modules/ftrack/event_handlers_user/action_rv.py @@ -66,7 +66,7 @@ class RVAction(BaseAction): def get_components_from_entity(self, session, entity, components): """Get components from various entity types. - The components dictionary is modifid in place, so nothing is returned. + The components dictionary is modified in place, so nothing is returned. Args: entity (Ftrack entity) diff --git a/openpype/modules/ftrack/event_handlers_user/action_seed.py b/openpype/modules/ftrack/event_handlers_user/action_seed.py index 4021d70c0a..657cd07a9f 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_seed.py +++ b/openpype/modules/ftrack/event_handlers_user/action_seed.py @@ -325,8 +325,8 @@ class SeedDebugProject(BaseAction): ): index = 0 - self.log.debug("*** Commiting Assets") - self.log.debug("Commiting entities. {}/{}".format( + self.log.debug("*** Committing Assets") + self.log.debug("Committing entities. {}/{}".format( created_entities, to_create_length )) self.session.commit() @@ -414,8 +414,8 @@ class SeedDebugProject(BaseAction): ): index = 0 - self.log.debug("*** Commiting Shots") - self.log.debug("Commiting entities. {}/{}".format( + self.log.debug("*** Committing Shots") + self.log.debug("Committing entities. {}/{}".format( created_entities, to_create_length )) self.session.commit() @@ -423,7 +423,7 @@ class SeedDebugProject(BaseAction): def temp_commit(self, index, created_entities, to_create_length): if index < self.max_entities_created_at_one_commit: return False - self.log.debug("Commiting {} entities. {}/{}".format( + self.log.debug("Committing {} entities. {}/{}".format( index, created_entities, to_create_length )) self.session.commit() diff --git a/openpype/modules/ftrack/event_handlers_user/action_store_thumbnails_to_avalon.py b/openpype/modules/ftrack/event_handlers_user/action_store_thumbnails_to_avalon.py index 8748f426bd..c9e0901623 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_store_thumbnails_to_avalon.py +++ b/openpype/modules/ftrack/event_handlers_user/action_store_thumbnails_to_avalon.py @@ -184,7 +184,7 @@ class StoreThumbnailsToAvalon(BaseAction): self.db_con.install() for entity in entities: - # Skip if entity is not AssetVersion (never should happend, but..) + # Skip if entity is not AssetVersion (should never happen, but..) if entity.entity_type.lower() != "assetversion": continue diff --git a/openpype/modules/ftrack/ftrack_server/event_server_cli.py b/openpype/modules/ftrack/ftrack_server/event_server_cli.py index ad7ffd8e25..77f479ee20 100644 --- a/openpype/modules/ftrack/ftrack_server/event_server_cli.py +++ b/openpype/modules/ftrack/ftrack_server/event_server_cli.py @@ -33,7 +33,7 @@ class MongoPermissionsError(Exception): """Is used when is created multiple objects of same RestApi class.""" def __init__(self, message=None): if not message: - message = "Exiting because have issue with acces to MongoDB" + message = "Exiting because have issue with access to MongoDB" super().__init__(message) @@ -340,7 +340,7 @@ def main_loop(ftrack_url): return 1 # ====== STORER ======= - # Run backup thread which does not requeire mongo to work + # Run backup thread which does not require mongo to work if storer_thread is None: if storer_failed_count < max_fail_count: storer_thread = socket_thread.SocketThread( @@ -399,7 +399,7 @@ def main_loop(ftrack_url): elif not processor_thread.is_alive(): if processor_thread.mongo_error: raise Exception( - "Exiting because have issue with acces to MongoDB" + "Exiting because have issue with access to MongoDB" ) processor_thread.join() processor_thread = None diff --git a/openpype/modules/ftrack/lib/avalon_sync.py b/openpype/modules/ftrack/lib/avalon_sync.py index 0341c25717..08dcf2e671 100644 --- a/openpype/modules/ftrack/lib/avalon_sync.py +++ b/openpype/modules/ftrack/lib/avalon_sync.py @@ -891,7 +891,7 @@ class SyncEntitiesFactory: parent_dict = self.entities_dict.get(parent_id, {}) for child_id in parent_dict.get("children", []): - # keep original `remove` value for all childs + # keep original `remove` value for all children _remove = (remove is True) if not _remove: if self.entities_dict[child_id]["avalon_attrs"].get( @@ -1191,8 +1191,8 @@ class SyncEntitiesFactory: avalon_hier = [] for item in items: value = item["value"] - # WARNING It is not possible to propage enumerate hierachical - # attributes with multiselection 100% right. Unseting all values + # WARNING It is not possible to propagate enumerate hierarchical + # attributes with multiselection 100% right. Unsetting all values # will cause inheritance from parent. if ( value is None @@ -1231,7 +1231,7 @@ class SyncEntitiesFactory: items.append("{} - \"{}\"".format(ent_path, value)) self.report_items["error"][fps_msg] = items - # Get dictionary with not None hierarchical values to pull to childs + # Get dictionary with not None hierarchical values to pull to children top_id = self.ft_project_id project_values = {} for key, value in self.entities_dict[top_id]["hier_attrs"].items(): @@ -1749,7 +1749,7 @@ class SyncEntitiesFactory: # TODO logging ent_path = self.get_ent_path(ftrack_id) msg = ( - " It is not possible" + " It is not possible" " to change the hierarchy of an entity or it's parents," " if it already contained published data." ) @@ -2584,7 +2584,7 @@ class SyncEntitiesFactory: # # ent_dict = self.entities_dict[found_by_name_id] - # TODO report - CRITICAL entity with same name alread exists in + # TODO report - CRITICAL entity with same name already exists in # different hierarchy - can't recreate entity continue diff --git a/openpype/modules/ftrack/lib/custom_attributes.py b/openpype/modules/ftrack/lib/custom_attributes.py index 2f53815368..3e40bb02f2 100644 --- a/openpype/modules/ftrack/lib/custom_attributes.py +++ b/openpype/modules/ftrack/lib/custom_attributes.py @@ -65,7 +65,7 @@ def get_openpype_attr(session, split_hierarchical=True, query_keys=None): cust_attrs_query = ( "select {}" " from CustomAttributeConfiguration" - # Kept `pype` for Backwards Compatiblity + # Kept `pype` for Backwards Compatibility " where group.name in (\"pype\", \"{}\")" ).format(", ".join(query_keys), CUST_ATTR_GROUP) all_avalon_attr = session.query(cust_attrs_query).all() diff --git a/openpype/modules/ftrack/lib/ftrack_action_handler.py b/openpype/modules/ftrack/lib/ftrack_action_handler.py index b24fe5f12a..07b3a780a2 100644 --- a/openpype/modules/ftrack/lib/ftrack_action_handler.py +++ b/openpype/modules/ftrack/lib/ftrack_action_handler.py @@ -12,7 +12,7 @@ def statics_icon(*icon_statics_file_parts): class BaseAction(BaseHandler): '''Custom Action base class - `label` a descriptive string identifing your action. + `label` a descriptive string identifying your action. `varaint` To group actions together, give them the same label and specify a unique variant per action. diff --git a/openpype/modules/ftrack/lib/ftrack_base_handler.py b/openpype/modules/ftrack/lib/ftrack_base_handler.py index c0b03f8a41..55400c22ab 100644 --- a/openpype/modules/ftrack/lib/ftrack_base_handler.py +++ b/openpype/modules/ftrack/lib/ftrack_base_handler.py @@ -30,7 +30,7 @@ class PreregisterException(Exception): class BaseHandler(object): '''Custom Action base class -