From b230da486112d08698a5437ddb2f70c88ece773d Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Fri, 28 Apr 2023 10:56:32 +0200 Subject: [PATCH 01/78] :recycle: change container to custom attrib modifier --- openpype/hosts/max/api/plugin.py | 93 +++++++++++++++++++++++++++----- 1 file changed, 80 insertions(+), 13 deletions(-) diff --git a/openpype/hosts/max/api/plugin.py b/openpype/hosts/max/api/plugin.py index b54568b360..213d6c04e0 100644 --- a/openpype/hosts/max/api/plugin.py +++ b/openpype/hosts/max/api/plugin.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- """3dsmax specific Avalon/Pyblish plugin definitions.""" from pymxs import runtime as rt +from typing import Union import six from abc import ABCMeta from openpype.pipeline import ( @@ -12,6 +13,59 @@ from openpype.lib import BoolDef from .lib import imprint, read, lsattr +MS_CUSTOM_ATTRIB = """attributes "openPypeData" +( + parameters main rollout:OPparams + ( + all_handles type:#maxObjectTab tabSize:0 tabSizeVariable:on + ) + + rollout OPparams "OP Parameters" + ( + listbox list_node "Node References" items:#() + button button_add "Add Selection" + + fn node_to_name the_node = + ( + handle = the_node.handle + obj_name = the_node.name + handle_name = obj_name + "<" + handle as string + ">" + return handle_name + ) + + on button_add pressed do + ( + current_selection = selectByName title:"Select Objects To Add To Container" buttontext:"Add" + temp_arr = #() + i_node_arr = #() + for c in current_selection do + ( + handle_name = node_to_name c + node_ref = NodeTransformMonitor node:c + append temp_arr handle_name + append i_node_arr node_ref + ) + all_handles = i_node_arr + list_node.items = temp_arr + ) + + on OPparams open do + ( + if all_handles.count != 0 do + ( + temp_arr = #() + for x in all_handles do + ( + print(x.node) + handle_name = node_to_name x.node + append temp_arr handle_name + ) + list_node.items = temp_arr + ) + ) + ) +)""" + class OpenPypeCreatorError(CreatorError): pass @@ -33,15 +87,25 @@ class MaxCreatorBase(object): return shared_data @staticmethod - def create_instance_node(node_name: str, parent: str = ""): - parent_node = rt.getNodeByName(parent) if parent else rt.rootScene - if not parent_node: - raise OpenPypeCreatorError(f"Specified parent {parent} not found") + def create_instance_node(node): + """Create instance node. - container = rt.container(name=node_name) - container.Parent = parent_node + If the supplied node is existing node, it will be used to hold the + instance, otherwise new node of type Dummy will be created. - return container + Args: + node (rt.MXSWrapperBase, str): Node or node name to use. + + Returns: + instance + """ + if isinstance(node, str): + node = rt.dummy(name=node) + + attrs = rt.execute(MS_CUSTOM_ATTRIB) + rt.custAttributes.add(node.baseObject, attrs) + + return node @six.add_metaclass(ABCMeta) @@ -60,8 +124,11 @@ class MaxCreator(Creator, MaxCreatorBase): instance_data, self ) - for node in self.selected_nodes: - node.Parent = instance_node + if pre_create_data.get("use_selection"): + print("adding selection") + print(rt.array(*self.selected_nodes)) + instance_node.openPypeData.all_nodes = rt.array( + *self.selected_nodes) self._add_instance_to_context(instance) imprint(instance_node.name, instance.data_to_store()) @@ -98,11 +165,11 @@ class MaxCreator(Creator, MaxCreatorBase): """ for instance in instances: - instance_node = rt.getNodeByName( - instance.data.get("instance_node")) - if instance_node: + if instance_node := rt.getNodeByName( + instance.data.get("instance_node") + ): rt.select(instance_node) - rt.execute(f'for o in selection do for c in o.children do c.parent = undefined') # noqa + rt.execute("for o in selection do for c in o.children do c.parent = undefined") # noqa rt.delete(instance_node) self._remove_instance_from_context(instance) From 63c7c1c2e9ed8002dff9f703852e2d9b53c08a6e Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Fri, 28 Apr 2023 12:43:34 +0200 Subject: [PATCH 02/78] :rotating_light: tabs to spaces --- openpype/hosts/max/api/plugin.py | 104 ++++++++++++++++--------------- 1 file changed, 54 insertions(+), 50 deletions(-) diff --git a/openpype/hosts/max/api/plugin.py b/openpype/hosts/max/api/plugin.py index 213d6c04e0..15fcc89c5f 100644 --- a/openpype/hosts/max/api/plugin.py +++ b/openpype/hosts/max/api/plugin.py @@ -12,60 +12,61 @@ from openpype.pipeline import ( from openpype.lib import BoolDef from .lib import imprint, read, lsattr - MS_CUSTOM_ATTRIB = """attributes "openPypeData" ( - parameters main rollout:OPparams - ( - all_handles type:#maxObjectTab tabSize:0 tabSizeVariable:on - ) + parameters main rollout:OPparams + ( + all_handles type:#maxObjectTab tabSize:0 tabSizeVariable:on + ) - rollout OPparams "OP Parameters" - ( - listbox list_node "Node References" items:#() - button button_add "Add Selection" + rollout OPparams "OP Parameters" + ( + listbox list_node "Node References" items:#() + button button_add "Add Selection" - fn node_to_name the_node = - ( - handle = the_node.handle - obj_name = the_node.name - handle_name = obj_name + "<" + handle as string + ">" - return handle_name - ) + fn node_to_name the_node = + ( + handle = the_node.handle + obj_name = the_node.name + handle_name = obj_name + "<" + handle as string + ">" + return handle_name + ) - on button_add pressed do - ( - current_selection = selectByName title:"Select Objects To Add To Container" buttontext:"Add" - temp_arr = #() - i_node_arr = #() - for c in current_selection do - ( - handle_name = node_to_name c - node_ref = NodeTransformMonitor node:c - append temp_arr handle_name - append i_node_arr node_ref - ) - all_handles = i_node_arr - list_node.items = temp_arr - ) + on button_add pressed do + ( + current_selection = selectByName title:"Select Objects To Add To + Container" buttontext:"Add" + temp_arr = #() + i_node_arr = #() + for c in current_selection do + ( + handle_name = node_to_name c + node_ref = NodeTransformMonitor node:c + append temp_arr handle_name + append i_node_arr node_ref + ) + all_handles = i_node_arr + list_node.items = temp_arr + ) - on OPparams open do - ( - if all_handles.count != 0 do - ( - temp_arr = #() - for x in all_handles do - ( - print(x.node) - handle_name = node_to_name x.node - append temp_arr handle_name - ) - list_node.items = temp_arr - ) - ) - ) + on OPparams open do + ( + if all_handles.count != 0 do + ( + temp_arr = #() + for x in all_handles do + ( + print(x.node) + handle_name = node_to_name x.node + append temp_arr handle_name + ) + list_node.items = temp_arr + ) + ) + ) )""" + class OpenPypeCreatorError(CreatorError): pass @@ -83,7 +84,8 @@ class MaxCreatorBase(object): shared_data["max_cached_subsets"][creator_id] = [i.name] else: shared_data[ - "max_cached_subsets"][creator_id].append(i.name) # noqa + "max_cached_subsets"][creator_id].append( + i.name) # noqa return shared_data @staticmethod @@ -138,7 +140,7 @@ class MaxCreator(Creator, MaxCreatorBase): def collect_instances(self): self.cache_subsets(self.collection_shared_data) for instance in self.collection_shared_data[ - "max_cached_subsets"].get(self.identifier, []): + "max_cached_subsets"].get(self.identifier, []): created_instance = CreatedInstance.from_existing( read(rt.getNodeByName(instance)), self ) @@ -166,10 +168,12 @@ class MaxCreator(Creator, MaxCreatorBase): """ for instance in instances: if instance_node := rt.getNodeByName( - instance.data.get("instance_node") + instance.data.get("instance_node") ): rt.select(instance_node) - rt.execute("for o in selection do for c in o.children do c.parent = undefined") # noqa + rt.execute( + "for o in selection do for c in o.children do c.parent = " + "undefined") # noqa rt.delete(instance_node) self._remove_instance_from_context(instance) From ca3b9f5e3042b4bf25bdcb0ec95815eba3e2a5fb Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Wed, 3 May 2023 18:48:41 +0200 Subject: [PATCH 03/78] :art: set references on modifier --- openpype/hosts/max/api/plugin.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/openpype/hosts/max/api/plugin.py b/openpype/hosts/max/api/plugin.py index 15fcc89c5f..52da23dc0a 100644 --- a/openpype/hosts/max/api/plugin.py +++ b/openpype/hosts/max/api/plugin.py @@ -102,7 +102,7 @@ class MaxCreatorBase(object): instance """ if isinstance(node, str): - node = rt.dummy(name=node) + node = rt.container(name=node) attrs = rt.execute(MS_CUSTOM_ATTRIB) rt.custAttributes.add(node.baseObject, attrs) @@ -127,10 +127,15 @@ class MaxCreator(Creator, MaxCreatorBase): self ) if pre_create_data.get("use_selection"): - print("adding selection") - print(rt.array(*self.selected_nodes)) - instance_node.openPypeData.all_nodes = rt.array( - *self.selected_nodes) + + node_list = [] + for i in self.selected_nodes: + node_ref = rt.NodeTransformMonitor(node=i) + node_list.append(node_ref) + + # Setting the property + rt.setProperty( + instance_node.openPypeData, "all_handles", node_list) self._add_instance_to_context(instance) imprint(instance_node.name, instance.data_to_store()) @@ -171,9 +176,7 @@ class MaxCreator(Creator, MaxCreatorBase): instance.data.get("instance_node") ): rt.select(instance_node) - rt.execute( - "for o in selection do for c in o.children do c.parent = " - "undefined") # noqa + rt.custAttributes.add(instance_node.baseObject, "openPypeData") rt.delete(instance_node) self._remove_instance_from_context(instance) From 37ce7fbc09fc1546dbc3ecc5620e5ba31d17b161 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Wed, 3 May 2023 18:49:04 +0200 Subject: [PATCH 04/78] :art: add members collector --- .../max/plugins/publish/collect_members.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 openpype/hosts/max/plugins/publish/collect_members.py diff --git a/openpype/hosts/max/plugins/publish/collect_members.py b/openpype/hosts/max/plugins/publish/collect_members.py new file mode 100644 index 0000000000..0b50ba0d8f --- /dev/null +++ b/openpype/hosts/max/plugins/publish/collect_members.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +"""Collect instance members""" +import pyblish.api +from pymxs import runtime as rt + + +class CollectMembers(pyblish.api.InstancePlugin): + """Collect Render for Deadline""" + + order = pyblish.api.CollectorOrder + 0.01 + label = "Collect Instance Members" + hosts = ['max'] + + def process(self, instance): + + if instance.data.get("instance_node"): + container = rt.GetNodeByName(instance.data["instance_node"]) + instance.data["members"] = [i.node for i in container.openPypeData.all_handles] From b52527b55f48babb3f677bb4534ecdeaf21fd9f6 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Wed, 3 May 2023 18:49:43 +0200 Subject: [PATCH 05/78] :recycle: switch the use to collected instance members --- .../max/plugins/publish/extract_camera_abc.py | 15 +- .../max/plugins/publish/extract_camera_fbx.py | 14 +- .../plugins/publish/extract_max_scene_raw.py | 14 +- .../max/plugins/publish/extract_model.py | 15 +- .../max/plugins/publish/extract_model_fbx.py | 15 +- .../max/plugins/publish/extract_model_obj.py | 15 +- .../max/plugins/publish/extract_model_usd.py | 43 ++--- .../max/plugins/publish/extract_pointcache.py | 14 +- .../max/plugins/publish/extract_pointcloud.py | 167 +++++++++++------- .../publish/validate_camera_contents.py | 22 +-- .../publish/validate_model_contents.py | 22 ++- .../publish/validate_no_max_content.py | 3 +- .../plugins/publish/validate_pointcloud.py | 128 ++++++-------- .../plugins/publish/validate_usd_plugin.py | 13 +- 14 files changed, 231 insertions(+), 269 deletions(-) diff --git a/openpype/hosts/max/plugins/publish/extract_camera_abc.py b/openpype/hosts/max/plugins/publish/extract_camera_abc.py index 8c23ff9878..b4f294fbf9 100644 --- a/openpype/hosts/max/plugins/publish/extract_camera_abc.py +++ b/openpype/hosts/max/plugins/publish/extract_camera_abc.py @@ -6,8 +6,7 @@ from openpype.pipeline import ( ) from pymxs import runtime as rt from openpype.hosts.max.api import ( - maintained_selection, - get_all_children + maintained_selection ) @@ -29,8 +28,6 @@ class ExtractCameraAlembic(publish.Extractor, start = float(instance.data.get("frameStartHandle", 1)) end = float(instance.data.get("frameEndHandle", 1)) - container = instance.data["instance_node"] - self.log.info("Extracting Camera ...") stagingdir = self.staging_dir(instance) @@ -38,8 +35,7 @@ class ExtractCameraAlembic(publish.Extractor, path = os.path.join(stagingdir, filename) # We run the render - self.log.info("Writing alembic '%s' to '%s'" % (filename, - stagingdir)) + self.log.info(f"Writing alembic '{filename}' to '{stagingdir}'") export_cmd = ( f""" @@ -57,8 +53,8 @@ exportFile @"{path}" #noPrompt selectedOnly:on using:AlembicExport with maintained_selection(): # select and export - rt.select(get_all_children(rt.getNodeByName(container))) - rt.execute(export_cmd) + rt.Select(instance.data["members"]) + rt.Execute(export_cmd) self.log.info("Performing Extraction ...") if "representations" not in instance.data: @@ -71,5 +67,4 @@ exportFile @"{path}" #noPrompt selectedOnly:on using:AlembicExport "stagingDir": stagingdir, } instance.data["representations"].append(representation) - self.log.info("Extracted instance '%s' to: %s" % (instance.name, - path)) + self.log.info(f"Extracted instance '{instance.name}' to: {path}") diff --git a/openpype/hosts/max/plugins/publish/extract_camera_fbx.py b/openpype/hosts/max/plugins/publish/extract_camera_fbx.py index 7e92f355ed..ffbd281c67 100644 --- a/openpype/hosts/max/plugins/publish/extract_camera_fbx.py +++ b/openpype/hosts/max/plugins/publish/extract_camera_fbx.py @@ -6,8 +6,7 @@ from openpype.pipeline import ( ) from pymxs import runtime as rt from openpype.hosts.max.api import ( - maintained_selection, - get_all_children + maintained_selection ) @@ -26,15 +25,13 @@ class ExtractCameraFbx(publish.Extractor, def process(self, instance): if not self.is_active(instance.data): return - container = instance.data["instance_node"] self.log.info("Extracting Camera ...") stagingdir = self.staging_dir(instance) filename = "{name}.fbx".format(**instance.data) filepath = os.path.join(stagingdir, filename) - self.log.info("Writing fbx file '%s' to '%s'" % (filename, - filepath)) + self.log.info(f"Writing fbx file '{filename}' to '{filepath}'") # Need to export: # Animation = True @@ -57,8 +54,8 @@ exportFile @"{filepath}" #noPrompt selectedOnly:true using:FBXEXP with maintained_selection(): # select and export - rt.select(get_all_children(rt.getNodeByName(container))) - rt.execute(fbx_export_cmd) + rt.Select(instance.data["members"]) + rt.Execute(fbx_export_cmd) self.log.info("Performing Extraction ...") if "representations" not in instance.data: @@ -71,5 +68,4 @@ exportFile @"{filepath}" #noPrompt selectedOnly:true using:FBXEXP "stagingDir": stagingdir, } instance.data["representations"].append(representation) - self.log.info("Extracted instance '%s' to: %s" % (instance.name, - filepath)) + self.log.info(f"Extracted instance '{instance.name}' to: {filepath}") diff --git a/openpype/hosts/max/plugins/publish/extract_max_scene_raw.py b/openpype/hosts/max/plugins/publish/extract_max_scene_raw.py index c14fcdbd0b..ed98922462 100644 --- a/openpype/hosts/max/plugins/publish/extract_max_scene_raw.py +++ b/openpype/hosts/max/plugins/publish/extract_max_scene_raw.py @@ -6,8 +6,7 @@ from openpype.pipeline import ( ) from pymxs import runtime as rt from openpype.hosts.max.api import ( - maintained_selection, - get_all_children + maintained_selection ) @@ -28,7 +27,6 @@ class ExtractMaxSceneRaw(publish.Extractor, def process(self, instance): if not self.is_active(instance.data): return - container = instance.data["instance_node"] # publish the raw scene for camera self.log.info("Extracting Raw Max Scene ...") @@ -37,8 +35,7 @@ class ExtractMaxSceneRaw(publish.Extractor, filename = "{name}.max".format(**instance.data) max_path = os.path.join(stagingdir, filename) - self.log.info("Writing max file '%s' to '%s'" % (filename, - max_path)) + self.log.info(f"Writing max file '{filename}' to '{max_path}'") if "representations" not in instance.data: instance.data["representations"] = [] @@ -46,8 +43,8 @@ class ExtractMaxSceneRaw(publish.Extractor, # saving max scene with maintained_selection(): # need to figure out how to select the camera - rt.select(get_all_children(rt.getNodeByName(container))) - rt.execute(f'saveNodes selection "{max_path}" quiet:true') + rt.Select(instance.data["members"]) + rt.Execute(f'saveNodes selection "{max_path}" quiet:true') self.log.info("Performing Extraction ...") @@ -58,5 +55,4 @@ class ExtractMaxSceneRaw(publish.Extractor, "stagingDir": stagingdir, } instance.data["representations"].append(representation) - self.log.info("Extracted instance '%s' to: %s" % (instance.name, - max_path)) + self.log.info(f"Extracted instance '{instance.name}' to: {max_path}") diff --git a/openpype/hosts/max/plugins/publish/extract_model.py b/openpype/hosts/max/plugins/publish/extract_model.py index 710ad5f97d..d0f7bb0410 100644 --- a/openpype/hosts/max/plugins/publish/extract_model.py +++ b/openpype/hosts/max/plugins/publish/extract_model.py @@ -6,8 +6,7 @@ from openpype.pipeline import ( ) from pymxs import runtime as rt from openpype.hosts.max.api import ( - maintained_selection, - get_all_children + maintained_selection ) @@ -27,8 +26,6 @@ class ExtractModel(publish.Extractor, if not self.is_active(instance.data): return - container = instance.data["instance_node"] - self.log.info("Extracting Geometry ...") stagingdir = self.staging_dir(instance) @@ -36,8 +33,7 @@ class ExtractModel(publish.Extractor, filepath = os.path.join(stagingdir, filename) # We run the render - self.log.info("Writing alembic '%s' to '%s'" % (filename, - stagingdir)) + self.log.info(f"Writing alembic '{filename}' to '{stagingdir}'") export_cmd = ( f""" @@ -56,8 +52,8 @@ exportFile @"{filepath}" #noPrompt selectedOnly:on using:AlembicExport with maintained_selection(): # select and export - rt.select(get_all_children(rt.getNodeByName(container))) - rt.execute(export_cmd) + rt.Select(instance.data["members"]) + rt.Execute(export_cmd) self.log.info("Performing Extraction ...") if "representations" not in instance.data: @@ -70,5 +66,4 @@ exportFile @"{filepath}" #noPrompt selectedOnly:on using:AlembicExport "stagingDir": stagingdir, } instance.data["representations"].append(representation) - self.log.info("Extracted instance '%s' to: %s" % (instance.name, - filepath)) + self.log.info(f"Extracted instance '{instance.name}' to: {filepath}") diff --git a/openpype/hosts/max/plugins/publish/extract_model_fbx.py b/openpype/hosts/max/plugins/publish/extract_model_fbx.py index ce58e8cc17..696974a703 100644 --- a/openpype/hosts/max/plugins/publish/extract_model_fbx.py +++ b/openpype/hosts/max/plugins/publish/extract_model_fbx.py @@ -6,8 +6,7 @@ from openpype.pipeline import ( ) from pymxs import runtime as rt from openpype.hosts.max.api import ( - maintained_selection, - get_all_children + maintained_selection ) @@ -27,16 +26,13 @@ class ExtractModelFbx(publish.Extractor, if not self.is_active(instance.data): return - container = instance.data["instance_node"] - self.log.info("Extracting Geometry ...") stagingdir = self.staging_dir(instance) filename = "{name}.fbx".format(**instance.data) filepath = os.path.join(stagingdir, filename) - self.log.info("Writing FBX '%s' to '%s'" % (filepath, - stagingdir)) + self.log.info(f"Writing FBX '{filepath}' to '{stagingdir}'") export_fbx_cmd = ( f""" @@ -56,8 +52,8 @@ exportFile @"{filepath}" #noPrompt selectedOnly:true using:FBXEXP with maintained_selection(): # select and export - rt.select(get_all_children(rt.getNodeByName(container))) - rt.execute(export_fbx_cmd) + rt.Select(instance.data["members"]) + rt.Execute(export_fbx_cmd) self.log.info("Performing Extraction ...") if "representations" not in instance.data: @@ -70,5 +66,4 @@ exportFile @"{filepath}" #noPrompt selectedOnly:true using:FBXEXP "stagingDir": stagingdir, } instance.data["representations"].append(representation) - self.log.info("Extracted instance '%s' to: %s" % (instance.name, - filepath)) + self.log.info(f"Extracted instance '{instance.name}' to: {filepath}") diff --git a/openpype/hosts/max/plugins/publish/extract_model_obj.py b/openpype/hosts/max/plugins/publish/extract_model_obj.py index 7bda237880..93896eea02 100644 --- a/openpype/hosts/max/plugins/publish/extract_model_obj.py +++ b/openpype/hosts/max/plugins/publish/extract_model_obj.py @@ -6,8 +6,7 @@ from openpype.pipeline import ( ) from pymxs import runtime as rt from openpype.hosts.max.api import ( - maintained_selection, - get_all_children + maintained_selection ) @@ -27,21 +26,18 @@ class ExtractModelObj(publish.Extractor, if not self.is_active(instance.data): return - container = instance.data["instance_node"] - self.log.info("Extracting Geometry ...") stagingdir = self.staging_dir(instance) filename = "{name}.obj".format(**instance.data) filepath = os.path.join(stagingdir, filename) - self.log.info("Writing OBJ '%s' to '%s'" % (filepath, - stagingdir)) + self.log.info(f"Writing OBJ '{filepath}' to '{stagingdir}'") with maintained_selection(): # select and export - rt.select(get_all_children(rt.getNodeByName(container))) - rt.execute(f'exportFile @"{filepath}" #noPrompt selectedOnly:true using:ObjExp') # noqa + rt.Select(instance.data["members"]) + rt.Execute(f'exportFile @"{filepath}" #noPrompt selectedOnly:true using:ObjExp') # noqa self.log.info("Performing Extraction ...") if "representations" not in instance.data: @@ -55,5 +51,4 @@ class ExtractModelObj(publish.Extractor, } instance.data["representations"].append(representation) - self.log.info("Extracted instance '%s' to: %s" % (instance.name, - filepath)) + self.log.info(f"Extracted instance '{instance.name}' to: {filepath}") diff --git a/openpype/hosts/max/plugins/publish/extract_model_usd.py b/openpype/hosts/max/plugins/publish/extract_model_usd.py index 0bed2d855e..ae250cae5a 100644 --- a/openpype/hosts/max/plugins/publish/extract_model_usd.py +++ b/openpype/hosts/max/plugins/publish/extract_model_usd.py @@ -26,31 +26,27 @@ class ExtractModelUSD(publish.Extractor, if not self.is_active(instance.data): return - container = instance.data["instance_node"] - self.log.info("Extracting Geometry ...") stagingdir = self.staging_dir(instance) asset_filename = "{name}.usda".format(**instance.data) asset_filepath = os.path.join(stagingdir, asset_filename) - self.log.info("Writing USD '%s' to '%s'" % (asset_filepath, - stagingdir)) + self.log.info(f"Writing USD '{asset_filepath}' to '{stagingdir}'") log_filename = "{name}.txt".format(**instance.data) log_filepath = os.path.join(stagingdir, log_filename) - self.log.info("Writing log '%s' to '%s'" % (log_filepath, - stagingdir)) + self.log.info(f"Writing log '{log_filepath}' to '{stagingdir}'") # get the nodes which need to be exported export_options = self.get_export_options(log_filepath) with maintained_selection(): # select and export - node_list = self.get_node_list(container) + node_list = instance.data["members"] rt.USDExporter.ExportFile(asset_filepath, exportOptions=export_options, - contentSource=rt.name("selected"), + contentSource=rt.Name("selected"), nodeList=node_list) self.log.info("Performing Extraction ...") @@ -73,25 +69,10 @@ class ExtractModelUSD(publish.Extractor, } instance.data["representations"].append(log_representation) - self.log.info("Extracted instance '%s' to: %s" % (instance.name, - asset_filepath)) + self.log.info(f"Extracted instance '{instance.name}' to: {asset_filepath}") - def get_node_list(self, container): - """ - Get the target nodes which are - the children of the container - """ - node_list = [] - - container_node = rt.getNodeByName(container) - target_node = container_node.Children - rt.select(target_node) - for sel in rt.selection: - node_list.append(sel) - - return node_list - - def get_export_options(self, log_path): + @staticmethod + def get_export_options(log_path): """Set Export Options for USD Exporter""" export_options = rt.USDExporter.createOptions() @@ -101,13 +82,13 @@ class ExtractModelUSD(publish.Extractor, export_options.Lights = False export_options.Cameras = False export_options.Materials = False - export_options.MeshFormat = rt.name('fromScene') - export_options.FileFormat = rt.name('ascii') - export_options.UpAxis = rt.name('y') - export_options.LogLevel = rt.name('info') + export_options.MeshFormat = rt.Name('fromScene') + export_options.FileFormat = rt.Name('ascii') + export_options.UpAxis = rt.Name('y') + export_options.LogLevel = rt.Name('info') export_options.LogPath = log_path export_options.PreserveEdgeOrientation = True - export_options.TimeMode = rt.name('current') + export_options.TimeMode = rt.Name('current') rt.USDexporter.UIOptions = export_options diff --git a/openpype/hosts/max/plugins/publish/extract_pointcache.py b/openpype/hosts/max/plugins/publish/extract_pointcache.py index 75d8a7972c..400d55d198 100644 --- a/openpype/hosts/max/plugins/publish/extract_pointcache.py +++ b/openpype/hosts/max/plugins/publish/extract_pointcache.py @@ -42,8 +42,7 @@ import pyblish.api from openpype.pipeline import publish from pymxs import runtime as rt from openpype.hosts.max.api import ( - maintained_selection, - get_all_children + maintained_selection ) @@ -57,17 +56,14 @@ class ExtractAlembic(publish.Extractor): start = float(instance.data.get("frameStartHandle", 1)) end = float(instance.data.get("frameEndHandle", 1)) - container = instance.data["instance_node"] - self.log.info("Extracting pointcache ...") parent_dir = self.staging_dir(instance) file_name = "{name}.abc".format(**instance.data) path = os.path.join(parent_dir, file_name) - # We run the render - self.log.info("Writing alembic '%s' to '%s'" % (file_name, - parent_dir)) + self.log.info( + f"Writing alembic '{file_name}' to '{parent_dir}'") abc_export_cmd = ( f""" @@ -85,8 +81,8 @@ exportFile @"{path}" #noPrompt selectedOnly:on using:AlembicExport with maintained_selection(): # select and export - rt.select(get_all_children(rt.getNodeByName(container))) - rt.execute(abc_export_cmd) + rt.Select(instance.data["members"]) + rt.Execute(abc_export_cmd) if "representations" not in instance.data: instance.data["representations"] = [] diff --git a/openpype/hosts/max/plugins/publish/extract_pointcloud.py b/openpype/hosts/max/plugins/publish/extract_pointcloud.py index e8d58ab713..5a85915967 100644 --- a/openpype/hosts/max/plugins/publish/extract_pointcloud.py +++ b/openpype/hosts/max/plugins/publish/extract_pointcloud.py @@ -9,13 +9,6 @@ from openpype.settings import get_project_settings from openpype.pipeline import legacy_io -def get_setting(project_setting=None): - project_setting = get_project_settings( - legacy_io.Session["AVALON_PROJECT"] - ) - return (project_setting["max"]["PointCloud"]) - - class ExtractPointCloud(publish.Extractor): """ Extract PRT format with tyFlow operators @@ -24,19 +17,20 @@ class ExtractPointCloud(publish.Extractor): Currently only works for the default partition setting Args: - export_particle(): sets up all job arguments for attributes - to be exported in MAXscript + self.export_particle(): sets up all job arguments for attributes + to be exported in MAXscript - get_operators(): get the export_particle operator + self.get_operators(): get the export_particle operator - get_custom_attr(): get all custom channel attributes from Openpype - setting and sets it as job arguments before exporting + self.get_custom_attr(): get all custom channel attributes from Openpype + setting and sets it as job arguments before exporting - get_files(): get the files with tyFlow naming convention - before publishing + self.get_files(): get the files with tyFlow naming convention + before publishing - partition_output_name(): get the naming with partition settings. - get_partition(): get partition value + self.partition_output_name(): get the naming with partition settings. + + self.get_partition(): get partition value """ @@ -46,6 +40,7 @@ class ExtractPointCloud(publish.Extractor): families = ["pointcloud"] def process(self, instance): + self.settings = self.get_setting(instance) start = int(instance.context.data.get("frameStart")) end = int(instance.context.data.get("frameEnd")) container = instance.data["instance_node"] @@ -56,12 +51,12 @@ class ExtractPointCloud(publish.Extractor): path = os.path.join(stagingdir, filename) with maintained_selection(): - job_args = self.export_particle(container, + job_args = self.export_particle(instance.data["members"], start, end, path) for job in job_args: - rt.execute(job) + rt.Execute(job) self.log.info("Performing Extraction ...") if "representations" not in instance.data: @@ -69,7 +64,7 @@ class ExtractPointCloud(publish.Extractor): self.log.info("Writing PRT with TyFlow Plugin...") filenames = self.get_files(container, path, start, end) - self.log.debug("filenames: {0}".format(filenames)) + self.log.debug(f"filenames: {filenames}") partition = self.partition_output_name(container) @@ -81,67 +76,87 @@ class ExtractPointCloud(publish.Extractor): "outputName": partition # partition value } instance.data["representations"].append(representation) - self.log.info("Extracted instance '%s' to: %s" % (instance.name, - path)) + self.log.info(f"Extracted instance '{instance.name}' to: {path}") def export_particle(self, - container, + members, start, end, filepath): + """Sets up all job arguments for attributes. + + Those attributes are to be exported in MAX Script. + + Args: + members (list): Member nodes of the instance. + start (int): Start frame. + end (int): End frame. + filepath (str): Path to PRT file. + + Returns: + list of arguments for MAX Script. + + """ job_args = [] - opt_list = self.get_operators(container) + opt_list = self.get_operators(members) for operator in opt_list: - start_frame = "{0}.frameStart={1}".format(operator, - start) + start_frame = f"{operator}.frameStart={start}" job_args.append(start_frame) - end_frame = "{0}.frameEnd={1}".format(operator, - end) + end_frame = f"{operator}.frameEnd={end}" job_args.append(end_frame) filepath = filepath.replace("\\", "/") - prt_filename = '{0}.PRTFilename="{1}"'.format(operator, - filepath) + prt_filename = f"{operator}.PRTFilename={filepath}" job_args.append(prt_filename) # Partition - mode = "{0}.PRTPartitionsMode=2".format(operator) + mode = f"{operator}.PRTPartitionsMode=2" job_args.append(mode) additional_args = self.get_custom_attr(operator) - for args in additional_args: - job_args.append(args) - - prt_export = "{0}.exportPRT()".format(operator) + job_args.extend(iter(additional_args)) + prt_export = f"{operator}.exportPRT()" job_args.append(prt_export) return job_args - def get_operators(self, container): - """Get Export Particles Operator""" + @staticmethod + def get_operators(members): + """Get Export Particles Operator. + Args: + members (list): Instance members. + + Returns: + list of particle operators + + """ opt_list = [] - node = rt.getNodebyName(container) - selection_list = list(node.Children) - for sel in selection_list: - obj = sel.baseobject + for member in members: + obj = member.baseobject # TODO: to see if it can be used maxscript instead - anim_names = rt.getsubanimnames(obj) + anim_names = rt.GetSubAnimNames(obj) for anim_name in anim_names: - sub_anim = rt.getsubanim(obj, anim_name) - boolean = rt.isProperty(sub_anim, "Export_Particles") - event_name = sub_anim.name + sub_anim = rt.GetSubAnim(obj, anim_name) + boolean = rt.IsProperty(sub_anim, "Export_Particles") if boolean: - opt = "${0}.{1}.export_particles".format(sel.name, - event_name) + event_name = sub_anim.Name + opt = f"${member.Name}.{event_name}.export_particles" opt_list.append(opt) return opt_list + @staticmethod + def get_setting(instance): + project_setting = get_project_settings( + instance.context.data["projectName"] + ) + return project_setting["max"]["PointCloud"] + def get_custom_attr(self, operator): """Get Custom Attributes""" custom_attr_list = [] - attr_settings = get_setting()["attribute"] + attr_settings = self.settings["attribute"] for key, value in attr_settings.items(): custom_attr = "{0}.PRTChannels_{1}=True".format(operator, value) @@ -157,14 +172,25 @@ class ExtractPointCloud(publish.Extractor): path, start_frame, end_frame): - """ - Note: - Set the filenames accordingly to the tyFlow file - naming extension for the publishing purpose + """Get file names for tyFlow. - Actual File Output from tyFlow: + Set the filenames accordingly to the tyFlow file + naming extension for the publishing purpose + + Actual File Output from tyFlow:: __partof..prt + e.g. tyFlow_cloth_CCCS_blobbyFill_001__part1of1_00004.prt + + Args: + container: Instance node. + path (str): Output directory. + start_frame (int): Start frame. + end_frame (int): End frame. + + Returns: + list of filenames + """ filenames = [] filename = os.path.basename(path) @@ -181,27 +207,36 @@ class ExtractPointCloud(publish.Extractor): return filenames def partition_output_name(self, container): - """ - Notes: - Partition output name set for mapping - the published file output + """Get partition output name. + + Partition output name set for mapping + the published file output. + + Todo: + Customizes the setting for the output. + + Args: + container: Instance node. + + Returns: + str: Partition name. - todo: - Customizes the setting for the output """ partition_count, partition_start = self.get_partition(container) - partition = "_part{:03}of{}".format(partition_start, - partition_count) - - return partition + return f"_part{partition_start:03}of{partition_count}" def get_partition(self, container): - """ - Get Partition Value + """Get Partition value. + + Args: + container: Instance node. + """ opt_list = self.get_operators(container) + # TODO: This looks strange? Iterating over + # the opt_list but returning from inside? for operator in opt_list: - count = rt.execute(f'{operator}.PRTPartitionsCount') - start = rt.execute(f'{operator}.PRTPartitionsFrom') + count = rt.Execute(f'{operator}.PRTPartitionsCount') + start = rt.Execute(f'{operator}.PRTPartitionsFrom') return count, start diff --git a/openpype/hosts/max/plugins/publish/validate_camera_contents.py b/openpype/hosts/max/plugins/publish/validate_camera_contents.py index c81e28a61f..a858092abd 100644 --- a/openpype/hosts/max/plugins/publish/validate_camera_contents.py +++ b/openpype/hosts/max/plugins/publish/validate_camera_contents.py @@ -18,30 +18,24 @@ class ValidateCameraContent(pyblish.api.InstancePlugin): "$Physical_Camera", "$Target"] def process(self, instance): - invalid = self.get_invalid(instance) - if invalid: - raise PublishValidationError("Camera instance must only include" - "camera (and camera target)") + if invalid := self.get_invalid(instance): + raise PublishValidationError(("Camera instance must only include" + "camera (and camera target). " + f"Invalid content {invalid}")) def get_invalid(self, instance): """ Get invalid nodes if the instance is not camera """ - invalid = list() + invalid = [] container = instance.data["instance_node"] - self.log.info("Validating look content for " - "{}".format(container)) + self.log.info(f"Validating camera content for {container}") - con = rt.getNodeByName(container) - selection_list = list(con.Children) + selection_list = instance.data["members"] for sel in selection_list: # to avoid Attribute Error from pymxs wrapper sel_tmp = str(sel) - found = False - for cam in self.camera_type: - if sel_tmp.startswith(cam): - found = True - break + found = any(sel_tmp.startswith(cam) for cam in self.camera_type) if not found: self.log.error("Camera not found") invalid.append(sel) diff --git a/openpype/hosts/max/plugins/publish/validate_model_contents.py b/openpype/hosts/max/plugins/publish/validate_model_contents.py index dd782674ff..b21c0184b0 100644 --- a/openpype/hosts/max/plugins/publish/validate_model_contents.py +++ b/openpype/hosts/max/plugins/publish/validate_model_contents.py @@ -17,28 +17,26 @@ class ValidateModelContent(pyblish.api.InstancePlugin): label = "Model Contents" def process(self, instance): - invalid = self.get_invalid(instance) - if invalid: - raise PublishValidationError("Model instance must only include" - "Geometry and Editable Mesh") + if invalid := self.get_invalid(instance): + raise PublishValidationError(("Model instance must only include" + "Geometry and Editable Mesh. " + f"Invalid types on: {invalid}")) def get_invalid(self, instance): """ Get invalid nodes if the instance is not camera """ - invalid = list() + invalid = [] container = instance.data["instance_node"] - self.log.info("Validating look content for " - "{}".format(container)) + self.log.info(f"Validating model content for {container}") - con = rt.getNodeByName(container) - selection_list = list(con.Children) or rt.getCurrentSelection() + selection_list = instance.data["members"] for sel in selection_list: - if rt.classOf(sel) in rt.Camera.classes: + if rt.ClassOf(sel) in rt.Camera.classes: invalid.append(sel) - if rt.classOf(sel) in rt.Light.classes: + if rt.ClassOf(sel) in rt.Light.classes: invalid.append(sel) - if rt.classOf(sel) in rt.Shape.classes: + if rt.ClassOf(sel) in rt.Shape.classes: invalid.append(sel) return invalid diff --git a/openpype/hosts/max/plugins/publish/validate_no_max_content.py b/openpype/hosts/max/plugins/publish/validate_no_max_content.py index c20a1968ed..ba4a6882c2 100644 --- a/openpype/hosts/max/plugins/publish/validate_no_max_content.py +++ b/openpype/hosts/max/plugins/publish/validate_no_max_content.py @@ -18,6 +18,5 @@ class ValidateMaxContents(pyblish.api.InstancePlugin): label = "Max Scene Contents" def process(self, instance): - container = rt.getNodeByName(instance.data["instance_node"]) - if not list(container.Children): + if not instance.data["members"]: raise PublishValidationError("No content found in the container") diff --git a/openpype/hosts/max/plugins/publish/validate_pointcloud.py b/openpype/hosts/max/plugins/publish/validate_pointcloud.py index f654058648..38d8226e41 100644 --- a/openpype/hosts/max/plugins/publish/validate_pointcloud.py +++ b/openpype/hosts/max/plugins/publish/validate_pointcloud.py @@ -9,11 +9,11 @@ def get_setting(project_setting=None): project_setting = get_project_settings( legacy_io.Session["AVALON_PROJECT"] ) - return (project_setting["max"]["PointCloud"]) + return project_setting["max"]["PointCloud"] class ValidatePointCloud(pyblish.api.InstancePlugin): - """Validate that workfile was saved.""" + """Validate that work file was saved.""" order = pyblish.api.ValidatorOrder families = ["pointcloud"] @@ -34,39 +34,37 @@ class ValidatePointCloud(pyblish.api.InstancePlugin): of export_particle operator """ - invalid = self.get_tyFlow_object(instance) - if invalid: - raise PublishValidationError("Non tyFlow object " - "found: {}".format(invalid)) - invalid = self.get_tyFlow_operator(instance) - if invalid: - raise PublishValidationError("tyFlow ExportParticle operator " - "not found: {}".format(invalid)) + report = [] + if invalid := self.get_tyflow_object(instance): + report.append(f"Non tyFlow object found: {invalid}") - invalid = self.validate_export_mode(instance) - if invalid: - raise PublishValidationError("The export mode is not at PRT") + if invalid := self.get_tyflow_operator(instance): + report.append( + f"tyFlow ExportParticle operator not found: {invalid}") - invalid = self.validate_partition_value(instance) - if invalid: - raise PublishValidationError("tyFlow Partition setting is " - "not at the default value") - invalid = self.validate_custom_attribute(instance) - if invalid: - raise PublishValidationError("Custom Attribute not found " - ":{}".format(invalid)) + if self.validate_export_mode(instance): + report.append("The export mode is not at PRT") - def get_tyFlow_object(self, instance): + if self.validate_partition_value(instance): + report.append(("tyFlow Partition setting is " + "not at the default value")) + + if invalid := self.validate_custom_attribute(instance): + report.append(("Custom Attribute not found " + f":{invalid}")) + + if report: + raise PublishValidationError + + def get_tyflow_object(self, instance): invalid = [] container = instance.data["instance_node"] - self.log.info("Validating tyFlow container " - "for {}".format(container)) + self.log.info(f"Validating tyFlow container for {container}") - con = rt.getNodeByName(container) - selection_list = list(con.Children) + selection_list = instance.data["members"] for sel in selection_list: sel_tmp = str(sel) - if rt.classOf(sel) in [rt.tyFlow, + if rt.ClassOf(sel) in [rt.tyFlow, rt.Editable_Mesh]: if "tyFlow" not in sel_tmp: invalid.append(sel) @@ -75,23 +73,20 @@ class ValidatePointCloud(pyblish.api.InstancePlugin): return invalid - def get_tyFlow_operator(self, instance): + def get_tyflow_operator(self, instance): invalid = [] container = instance.data["instance_node"] - self.log.info("Validating tyFlow object " - "for {}".format(container)) - - con = rt.getNodeByName(container) - selection_list = list(con.Children) + self.log.info(f"Validating tyFlow object for {container}") + selection_list = instance.data["members"] bool_list = [] for sel in selection_list: obj = sel.baseobject - anim_names = rt.getsubanimnames(obj) + anim_names = rt.GetSubAnimNames(obj) for anim_name in anim_names: # get all the names of the related tyFlow nodes - sub_anim = rt.getsubanim(obj, anim_name) + sub_anim = rt.GetSubAnim(obj, anim_name) # check if there is export particle operator - boolean = rt.isProperty(sub_anim, "Export_Particles") + boolean = rt.IsProperty(sub_anim, "Export_Particles") bool_list.append(str(boolean)) # if the export_particles property is not there # it means there is not a "Export Particle" operator @@ -104,21 +99,18 @@ class ValidatePointCloud(pyblish.api.InstancePlugin): def validate_custom_attribute(self, instance): invalid = [] container = instance.data["instance_node"] - self.log.info("Validating tyFlow custom " - "attributes for {}".format(container)) + self.log.info( + f"Validating tyFlow custom attributes for {container}") - con = rt.getNodeByName(container) - selection_list = list(con.Children) + selection_list = instance.data["members"] for sel in selection_list: obj = sel.baseobject - anim_names = rt.getsubanimnames(obj) + anim_names = rt.GetSubAnimNames(obj) for anim_name in anim_names: # get all the names of the related tyFlow nodes - sub_anim = rt.getsubanim(obj, anim_name) - # check if there is export particle operator - boolean = rt.isProperty(sub_anim, "Export_Particles") - event_name = sub_anim.name - if boolean: + sub_anim = rt.GetSubAnim(obj, anim_name) + if rt.IsProperty(sub_anim, "Export_Particles"): + event_name = sub_anim.name opt = "${0}.{1}.export_particles".format(sel.name, event_name) attributes = get_setting()["attribute"] @@ -126,39 +118,36 @@ class ValidatePointCloud(pyblish.api.InstancePlugin): custom_attr = "{0}.PRTChannels_{1}".format(opt, value) try: - rt.execute(custom_attr) + rt.Execute(custom_attr) except RuntimeError: - invalid.add(key) + invalid.append(key) return invalid def validate_partition_value(self, instance): invalid = [] container = instance.data["instance_node"] - self.log.info("Validating tyFlow partition " - "value for {}".format(container)) + self.log.info( + f"Validating tyFlow partition value for {container}") - con = rt.getNodeByName(container) - selection_list = list(con.Children) + selection_list = instance.data["members"] for sel in selection_list: obj = sel.baseobject - anim_names = rt.getsubanimnames(obj) + anim_names = rt.GetSubAnimNames(obj) for anim_name in anim_names: # get all the names of the related tyFlow nodes - sub_anim = rt.getsubanim(obj, anim_name) - # check if there is export particle operator - boolean = rt.isProperty(sub_anim, "Export_Particles") - event_name = sub_anim.name - if boolean: + sub_anim = rt.GetSubAnim(obj, anim_name) + if rt.IsProperty(sub_anim, "Export_Particles"): + event_name = sub_anim.name opt = "${0}.{1}.export_particles".format(sel.name, event_name) - count = rt.execute(f'{opt}.PRTPartitionsCount') + count = rt.Execute(f'{opt}.PRTPartitionsCount') if count != 100: invalid.append(count) - start = rt.execute(f'{opt}.PRTPartitionsFrom') + start = rt.Execute(f'{opt}.PRTPartitionsFrom') if start != 1: invalid.append(start) - end = rt.execute(f'{opt}.PRTPartitionsTo') + end = rt.Execute(f'{opt}.PRTPartitionsTo') if end != 1: invalid.append(end) @@ -167,24 +156,23 @@ class ValidatePointCloud(pyblish.api.InstancePlugin): def validate_export_mode(self, instance): invalid = [] container = instance.data["instance_node"] - self.log.info("Validating tyFlow export " - "mode for {}".format(container)) + self.log.info( + f"Validating tyFlow export mode for {container}") - con = rt.getNodeByName(container) + con = rt.GetNodeByName(container) selection_list = list(con.Children) for sel in selection_list: obj = sel.baseobject - anim_names = rt.getsubanimnames(obj) + anim_names = rt.GetSubAnimNames(obj) for anim_name in anim_names: # get all the names of the related tyFlow nodes - sub_anim = rt.getsubanim(obj, anim_name) + sub_anim = rt.GetSubAnim(obj, anim_name) # check if there is export particle operator - boolean = rt.isProperty(sub_anim, "Export_Particles") + boolean = rt.IsProperty(sub_anim, "Export_Particles") event_name = sub_anim.name if boolean: - opt = "${0}.{1}.export_particles".format(sel.name, - event_name) - export_mode = rt.execute(f'{opt}.exportMode') + opt = f"${sel.name}.{event_name}.export_particles" + export_mode = rt.Execute(f'{opt}.exportMode') if export_mode != 1: invalid.append(export_mode) diff --git a/openpype/hosts/max/plugins/publish/validate_usd_plugin.py b/openpype/hosts/max/plugins/publish/validate_usd_plugin.py index 747147020a..8f11d72567 100644 --- a/openpype/hosts/max/plugins/publish/validate_usd_plugin.py +++ b/openpype/hosts/max/plugins/publish/validate_usd_plugin.py @@ -14,21 +14,20 @@ class ValidateUSDPlugin(pyblish.api.InstancePlugin): label = "USD Plugin" def process(self, instance): - plugin_mgr = rt.pluginManager + plugin_mgr = rt.PluginManager plugin_count = plugin_mgr.pluginDllCount plugin_info = self.get_plugins(plugin_mgr, plugin_count) usd_import = "usdimport.dli" if usd_import not in plugin_info: - raise PublishValidationError("USD Plugin {}" - " not found".format(usd_import)) + raise PublishValidationError(f"USD Plugin {usd_import} not found") usd_export = "usdexport.dle" if usd_export not in plugin_info: - raise PublishValidationError("USD Plugin {}" - " not found".format(usd_export)) + raise PublishValidationError(f"USD Plugin {usd_export} not found") - def get_plugins(self, manager, count): - plugin_info_list = list() + @staticmethod + def get_plugins(manager, count): + plugin_info_list = [] for p in range(1, count + 1): plugin_info = manager.pluginDllName(p) plugin_info_list.append(plugin_info) From 7a0f18e27849b3a67db57f1af4905d58044488fe Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Wed, 3 May 2023 18:50:30 +0200 Subject: [PATCH 06/78] :rotating_light: Fix type case to match Python API --- openpype/hosts/max/api/lib.py | 38 +++++++++----------- openpype/hosts/max/api/lib_renderproducts.py | 4 +-- 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/openpype/hosts/max/api/lib.py b/openpype/hosts/max/api/lib.py index ad9a450cad..572d99c1cd 100644 --- a/openpype/hosts/max/api/lib.py +++ b/openpype/hosts/max/api/lib.py @@ -3,7 +3,7 @@ import json import six from pymxs import runtime as rt -from typing import Union +from typing import Union, Any, Dict import contextlib from openpype.pipeline.context_tools import ( @@ -16,15 +16,15 @@ JSON_PREFIX = "JSON::" def imprint(node_name: str, data: dict) -> bool: - node = rt.getNodeByName(node_name) + node = rt.GetNodeByName(node_name) if not node: return False for k, v in data.items(): if isinstance(v, (dict, list)): - rt.setUserProp(node, k, f'{JSON_PREFIX}{json.dumps(v)}') + rt.SetUserProp(node, k, f'{JSON_PREFIX}{json.dumps(v)}') else: - rt.setUserProp(node, k, v) + rt.SetUserProp(node, k, v) return True @@ -44,7 +44,7 @@ def lsattr( Returns: list of nodes. """ - root = rt.rootnode if root is None else rt.getNodeByName(root) + root = rt.RootNode if root is None else rt.GetNodeByName(root) def output_node(node, nodes): nodes.append(node) @@ -55,16 +55,16 @@ def lsattr( output_node(root, nodes) return [ n for n in nodes - if rt.getUserProp(n, attr) == value + if rt.GetUserProp(n, attr) == value ] if value else [ n for n in nodes - if rt.getUserProp(n, attr) + if rt.GetUserProp(n, attr) ] def read(container) -> dict: data = {} - props = rt.getUserPropBuffer(container) + props = rt.GetUserPropBuffer(container) # this shouldn't happen but let's guard against it anyway if not props: return data @@ -79,29 +79,25 @@ def read(container) -> dict: value = value.strip() if isinstance(value.strip(), six.string_types) and \ value.startswith(JSON_PREFIX): - try: + with contextlib.suppress(json.JSONDecodeError): value = json.loads(value[len(JSON_PREFIX):]) - except json.JSONDecodeError: - # not a json - pass - data[key.strip()] = value - data["instance_node"] = container.name + data["instance_node"] = container.Name return data @contextlib.contextmanager def maintained_selection(): - previous_selection = rt.getCurrentSelection() + previous_selection = rt.GetCurrentSelection() try: yield finally: if previous_selection: - rt.select(previous_selection) + rt.Select(previous_selection) else: - rt.select() + rt.Select() def get_all_children(parent, node_type=None): @@ -123,7 +119,7 @@ def get_all_children(parent, node_type=None): return children child_list = list_children(parent) - return ([x for x in child_list if rt.superClassOf(x) == node_type] + return ([x for x in child_list if rt.SuperClassOf(x) == node_type] if node_type else child_list) @@ -199,7 +195,7 @@ def reset_scene_resolution(): set_scene_resolution(width, height) -def get_frame_range() -> dict: +def get_frame_range() -> Union[Dict[str, Any], None]: """Get the current assets frame range and handles. Returns: @@ -242,7 +238,7 @@ def reset_frame_range(fps: bool = True): frame_start = frame_range["frameStart"] - int(frame_range["handleStart"]) frame_end = frame_range["frameEnd"] + int(frame_range["handleEnd"]) frange_cmd = f"animationRange = interval {frame_start} {frame_end}" - rt.execute(frange_cmd) + rt.Execute(frange_cmd) def set_context_setting(): @@ -270,5 +266,5 @@ def get_max_version(): #(25000, 62, 0, 25, 0, 0, 997, 2023, "") max_info[7] = max version date """ - max_info = rt.maxversion() + max_info = rt.MaxVersion() return max_info[7] diff --git a/openpype/hosts/max/api/lib_renderproducts.py b/openpype/hosts/max/api/lib_renderproducts.py index 350eb97661..e42686020a 100644 --- a/openpype/hosts/max/api/lib_renderproducts.py +++ b/openpype/hosts/max/api/lib_renderproducts.py @@ -91,7 +91,7 @@ class RenderProducts(object): """Get all the Arnold AOVs""" aovs = [] - amw = rt.MaxtoAOps.AOVsManagerWindow() + amw = rt.MaxToAOps.AOVsManagerWindow() aov_mgr = rt.renderers.current.AOVManager # Check if there is any aov group set in AOV manager aov_group_num = len(aov_mgr.drivers) @@ -114,7 +114,7 @@ class RenderProducts(object): """Get all the render element output files. """ render_dirname = [] - render_elem = rt.maxOps.GetCurRenderElementMgr() + render_elem = rt.MaxOps.GetCurRenderElementMgr() render_elem_num = render_elem.NumRenderElements() # get render elements from the renders for i in range(render_elem_num): From 6d84969457f930e4020633ab6ecfbfcf47d22afc Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Wed, 3 May 2023 19:06:22 +0200 Subject: [PATCH 07/78] :rotating_light: fix Hound :dog: --- openpype/hosts/max/api/plugin.py | 13 +++++-------- .../hosts/max/plugins/publish/collect_members.py | 4 +++- .../hosts/max/plugins/publish/extract_model_usd.py | 3 ++- .../max/plugins/publish/validate_camera_contents.py | 2 +- .../max/plugins/publish/validate_model_contents.py | 2 +- .../max/plugins/publish/validate_pointcloud.py | 6 +++--- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/openpype/hosts/max/api/plugin.py b/openpype/hosts/max/api/plugin.py index 52da23dc0a..39a17c29ef 100644 --- a/openpype/hosts/max/api/plugin.py +++ b/openpype/hosts/max/api/plugin.py @@ -144,10 +144,9 @@ class MaxCreator(Creator, MaxCreatorBase): def collect_instances(self): self.cache_subsets(self.collection_shared_data) - for instance in self.collection_shared_data[ - "max_cached_subsets"].get(self.identifier, []): + for instance in self.collection_shared_data["max_cached_subsets"].get(self.identifier, []): # noqa created_instance = CreatedInstance.from_existing( - read(rt.getNodeByName(instance)), self + read(rt.GetNodeByName(instance)), self ) self._add_instance_to_context(created_instance) @@ -172,12 +171,10 @@ class MaxCreator(Creator, MaxCreatorBase): """ for instance in instances: - if instance_node := rt.getNodeByName( - instance.data.get("instance_node") - ): - rt.select(instance_node) + if instance_node := rt.GetNodeByName(instance.data.get("instance_node")): # noqa + rt.Select(instance_node) rt.custAttributes.add(instance_node.baseObject, "openPypeData") - rt.delete(instance_node) + rt.Delete(instance_node) self._remove_instance_from_context(instance) diff --git a/openpype/hosts/max/plugins/publish/collect_members.py b/openpype/hosts/max/plugins/publish/collect_members.py index 0b50ba0d8f..4ceb6cdadf 100644 --- a/openpype/hosts/max/plugins/publish/collect_members.py +++ b/openpype/hosts/max/plugins/publish/collect_members.py @@ -15,4 +15,6 @@ class CollectMembers(pyblish.api.InstancePlugin): if instance.data.get("instance_node"): container = rt.GetNodeByName(instance.data["instance_node"]) - instance.data["members"] = [i.node for i in container.openPypeData.all_handles] + instance.data["members"] = [ + i.node for i in container.openPypeData.all_handles + ] diff --git a/openpype/hosts/max/plugins/publish/extract_model_usd.py b/openpype/hosts/max/plugins/publish/extract_model_usd.py index ae250cae5a..df1e7a4f02 100644 --- a/openpype/hosts/max/plugins/publish/extract_model_usd.py +++ b/openpype/hosts/max/plugins/publish/extract_model_usd.py @@ -69,7 +69,8 @@ class ExtractModelUSD(publish.Extractor, } instance.data["representations"].append(log_representation) - self.log.info(f"Extracted instance '{instance.name}' to: {asset_filepath}") + self.log.info( + f"Extracted instance '{instance.name}' to: {asset_filepath}") @staticmethod def get_export_options(log_path): diff --git a/openpype/hosts/max/plugins/publish/validate_camera_contents.py b/openpype/hosts/max/plugins/publish/validate_camera_contents.py index a858092abd..85be5d59fa 100644 --- a/openpype/hosts/max/plugins/publish/validate_camera_contents.py +++ b/openpype/hosts/max/plugins/publish/validate_camera_contents.py @@ -18,7 +18,7 @@ class ValidateCameraContent(pyblish.api.InstancePlugin): "$Physical_Camera", "$Target"] def process(self, instance): - if invalid := self.get_invalid(instance): + if invalid := self.get_invalid(instance): # noqa raise PublishValidationError(("Camera instance must only include" "camera (and camera target). " f"Invalid content {invalid}")) diff --git a/openpype/hosts/max/plugins/publish/validate_model_contents.py b/openpype/hosts/max/plugins/publish/validate_model_contents.py index b21c0184b0..1d834292b8 100644 --- a/openpype/hosts/max/plugins/publish/validate_model_contents.py +++ b/openpype/hosts/max/plugins/publish/validate_model_contents.py @@ -17,7 +17,7 @@ class ValidateModelContent(pyblish.api.InstancePlugin): label = "Model Contents" def process(self, instance): - if invalid := self.get_invalid(instance): + if invalid := self.get_invalid(instance): # noqa raise PublishValidationError(("Model instance must only include" "Geometry and Editable Mesh. " f"Invalid types on: {invalid}")) diff --git a/openpype/hosts/max/plugins/publish/validate_pointcloud.py b/openpype/hosts/max/plugins/publish/validate_pointcloud.py index 38d8226e41..e3a6face07 100644 --- a/openpype/hosts/max/plugins/publish/validate_pointcloud.py +++ b/openpype/hosts/max/plugins/publish/validate_pointcloud.py @@ -35,10 +35,10 @@ class ValidatePointCloud(pyblish.api.InstancePlugin): """ report = [] - if invalid := self.get_tyflow_object(instance): + if invalid := self.get_tyflow_object(instance): # noqa report.append(f"Non tyFlow object found: {invalid}") - if invalid := self.get_tyflow_operator(instance): + if invalid := self.get_tyflow_operator(instance): # noqa report.append( f"tyFlow ExportParticle operator not found: {invalid}") @@ -49,7 +49,7 @@ class ValidatePointCloud(pyblish.api.InstancePlugin): report.append(("tyFlow Partition setting is " "not at the default value")) - if invalid := self.validate_custom_attribute(instance): + if invalid := self.validate_custom_attribute(instance): # noqa report.append(("Custom Attribute not found " f":{invalid}")) From 1ec0b2aeac3ab160b96d02706177ccab016c29ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Samohel?= <33513211+antirotor@users.noreply.github.com> Date: Thu, 4 May 2023 11:29:28 +0200 Subject: [PATCH 08/78] Update openpype/hosts/max/plugins/publish/extract_pointcloud.py Co-authored-by: Kayla Man <64118225+moonyuet@users.noreply.github.com> --- openpype/hosts/max/plugins/publish/extract_pointcloud.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/max/plugins/publish/extract_pointcloud.py b/openpype/hosts/max/plugins/publish/extract_pointcloud.py index 5a85915967..1387d47563 100644 --- a/openpype/hosts/max/plugins/publish/extract_pointcloud.py +++ b/openpype/hosts/max/plugins/publish/extract_pointcloud.py @@ -132,7 +132,10 @@ class ExtractPointCloud(publish.Extractor): """ opt_list = [] for member in members: - obj = member.baseobject + node = rt.getNodeByName(member) + selection_list = list(node.Children) + for sel in selection_list: + obj = sel.baseobject # TODO: to see if it can be used maxscript instead anim_names = rt.GetSubAnimNames(obj) for anim_name in anim_names: From 5ced9885b1a79ccb8ad068366b186681304dc781 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Samohel?= <33513211+antirotor@users.noreply.github.com> Date: Thu, 4 May 2023 11:29:36 +0200 Subject: [PATCH 09/78] Update openpype/hosts/max/plugins/publish/extract_pointcloud.py Co-authored-by: Kayla Man <64118225+moonyuet@users.noreply.github.com> --- openpype/hosts/max/plugins/publish/extract_pointcloud.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/max/plugins/publish/extract_pointcloud.py b/openpype/hosts/max/plugins/publish/extract_pointcloud.py index 1387d47563..11fcdaaa38 100644 --- a/openpype/hosts/max/plugins/publish/extract_pointcloud.py +++ b/openpype/hosts/max/plugins/publish/extract_pointcloud.py @@ -137,7 +137,7 @@ class ExtractPointCloud(publish.Extractor): for sel in selection_list: obj = sel.baseobject # TODO: to see if it can be used maxscript instead - anim_names = rt.GetSubAnimNames(obj) + anim_names = rt.GetSubAnimNames(obj) for anim_name in anim_names: sub_anim = rt.GetSubAnim(obj, anim_name) boolean = rt.IsProperty(sub_anim, "Export_Particles") From 4193b3c277992d6686a3f4fc009465b684a8a2e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Samohel?= <33513211+antirotor@users.noreply.github.com> Date: Thu, 4 May 2023 11:29:51 +0200 Subject: [PATCH 10/78] Update openpype/hosts/max/plugins/publish/extract_pointcloud.py Co-authored-by: Kayla Man <64118225+moonyuet@users.noreply.github.com> --- openpype/hosts/max/plugins/publish/extract_pointcloud.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/max/plugins/publish/extract_pointcloud.py b/openpype/hosts/max/plugins/publish/extract_pointcloud.py index 11fcdaaa38..2063514455 100644 --- a/openpype/hosts/max/plugins/publish/extract_pointcloud.py +++ b/openpype/hosts/max/plugins/publish/extract_pointcloud.py @@ -138,7 +138,7 @@ class ExtractPointCloud(publish.Extractor): obj = sel.baseobject # TODO: to see if it can be used maxscript instead anim_names = rt.GetSubAnimNames(obj) - for anim_name in anim_names: + for anim_name in anim_names: sub_anim = rt.GetSubAnim(obj, anim_name) boolean = rt.IsProperty(sub_anim, "Export_Particles") if boolean: From 0065dc1056b8e5f548a18297b9f6858c06736d61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Samohel?= <33513211+antirotor@users.noreply.github.com> Date: Thu, 4 May 2023 11:29:58 +0200 Subject: [PATCH 11/78] Update openpype/hosts/max/plugins/publish/extract_pointcloud.py Co-authored-by: Kayla Man <64118225+moonyuet@users.noreply.github.com> --- openpype/hosts/max/plugins/publish/extract_pointcloud.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/max/plugins/publish/extract_pointcloud.py b/openpype/hosts/max/plugins/publish/extract_pointcloud.py index 2063514455..97f0b32eca 100644 --- a/openpype/hosts/max/plugins/publish/extract_pointcloud.py +++ b/openpype/hosts/max/plugins/publish/extract_pointcloud.py @@ -139,8 +139,8 @@ class ExtractPointCloud(publish.Extractor): # TODO: to see if it can be used maxscript instead anim_names = rt.GetSubAnimNames(obj) for anim_name in anim_names: - sub_anim = rt.GetSubAnim(obj, anim_name) - boolean = rt.IsProperty(sub_anim, "Export_Particles") + sub_anim = rt.GetSubAnim(obj, anim_name) + boolean = rt.IsProperty(sub_anim, "Export_Particles") if boolean: event_name = sub_anim.Name opt = f"${member.Name}.{event_name}.export_particles" From 6923f692057511ef7de985aecce37156e72de50a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Samohel?= <33513211+antirotor@users.noreply.github.com> Date: Thu, 4 May 2023 11:30:08 +0200 Subject: [PATCH 12/78] Update openpype/hosts/max/plugins/publish/extract_pointcloud.py Co-authored-by: Kayla Man <64118225+moonyuet@users.noreply.github.com> --- openpype/hosts/max/plugins/publish/extract_pointcloud.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/max/plugins/publish/extract_pointcloud.py b/openpype/hosts/max/plugins/publish/extract_pointcloud.py index 97f0b32eca..c04eef6604 100644 --- a/openpype/hosts/max/plugins/publish/extract_pointcloud.py +++ b/openpype/hosts/max/plugins/publish/extract_pointcloud.py @@ -141,7 +141,7 @@ class ExtractPointCloud(publish.Extractor): for anim_name in anim_names: sub_anim = rt.GetSubAnim(obj, anim_name) boolean = rt.IsProperty(sub_anim, "Export_Particles") - if boolean: + if boolean: event_name = sub_anim.Name opt = f"${member.Name}.{event_name}.export_particles" opt_list.append(opt) From 774672a0063e2ba3edd2f2e26492a6607169ce46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Samohel?= <33513211+antirotor@users.noreply.github.com> Date: Thu, 4 May 2023 11:30:17 +0200 Subject: [PATCH 13/78] Update openpype/hosts/max/plugins/publish/extract_pointcloud.py Co-authored-by: Kayla Man <64118225+moonyuet@users.noreply.github.com> --- openpype/hosts/max/plugins/publish/extract_pointcloud.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openpype/hosts/max/plugins/publish/extract_pointcloud.py b/openpype/hosts/max/plugins/publish/extract_pointcloud.py index c04eef6604..74265da7fb 100644 --- a/openpype/hosts/max/plugins/publish/extract_pointcloud.py +++ b/openpype/hosts/max/plugins/publish/extract_pointcloud.py @@ -43,7 +43,6 @@ class ExtractPointCloud(publish.Extractor): self.settings = self.get_setting(instance) start = int(instance.context.data.get("frameStart")) end = int(instance.context.data.get("frameEnd")) - container = instance.data["instance_node"] self.log.info("Extracting PRT...") stagingdir = self.staging_dir(instance) From 8d78288ccd3f3783c228eed131936d845ee0e333 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 4 May 2023 11:49:38 +0200 Subject: [PATCH 14/78] :heavy_plus_sign: bump hound flake8 version --- .hound.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.hound.yml b/.hound.yml index df9cdab64a..4e749ac2d8 100644 --- a/.hound.yml +++ b/.hound.yml @@ -1,3 +1,4 @@ flake8: + version: 6.0.0 enabled: true config_file: setup.cfg From fec92a6c34f9e25b01a8d0094b9f90f0080f8e9c Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 4 May 2023 11:49:38 +0200 Subject: [PATCH 15/78] Revert ":heavy_plus_sign: bump hound flake8 version" This reverts commit 8d78288ccd3f3783c228eed131936d845ee0e333. --- .hound.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.hound.yml b/.hound.yml index 4e749ac2d8..df9cdab64a 100644 --- a/.hound.yml +++ b/.hound.yml @@ -1,4 +1,3 @@ flake8: - version: 6.0.0 enabled: true config_file: setup.cfg From 49f9822b3fb0bda3dcbf8a7352b2133b361a6f41 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 4 May 2023 12:19:49 +0200 Subject: [PATCH 16/78] :recycle: try another linter --- .github/workflows/linting_pr.yml | 36 ++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .github/workflows/linting_pr.yml diff --git a/.github/workflows/linting_pr.yml b/.github/workflows/linting_pr.yml new file mode 100644 index 0000000000..8cc822df6e --- /dev/null +++ b/.github/workflows/linting_pr.yml @@ -0,0 +1,36 @@ +name: 📇 Linting PR + +on: + push: + branches: [ develop ] + pull_request: + branches: [ develop ] + +jobs: + linting: + runs-on: ubuntu-latest + steps: + - name: Black + uses: microsoft/action-python@0.6.3 + with: + black: false + + - name: Bandit + uses: microsoft/action-python@0.6.3 + with: + bandit: true + + - name: Pylint + uses: microsoft/action-python@0.6.3 + with: + pylint: true + + - name: Pyright + uses: microsoft/action-python@0.6.3 + with: + pyright: true + + - name: Flake8 + uses: microsoft/action-python@0.6.3 + with: + flake8: true From c1349c6e94296af7e141cfe8f4e26e0df708b279 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 4 May 2023 12:19:49 +0200 Subject: [PATCH 17/78] Revert ":recycle: try another linter" This reverts commit 49f9822b3fb0bda3dcbf8a7352b2133b361a6f41. --- .github/workflows/linting_pr.yml | 36 -------------------------------- 1 file changed, 36 deletions(-) delete mode 100644 .github/workflows/linting_pr.yml diff --git a/.github/workflows/linting_pr.yml b/.github/workflows/linting_pr.yml deleted file mode 100644 index 8cc822df6e..0000000000 --- a/.github/workflows/linting_pr.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: 📇 Linting PR - -on: - push: - branches: [ develop ] - pull_request: - branches: [ develop ] - -jobs: - linting: - runs-on: ubuntu-latest - steps: - - name: Black - uses: microsoft/action-python@0.6.3 - with: - black: false - - - name: Bandit - uses: microsoft/action-python@0.6.3 - with: - bandit: true - - - name: Pylint - uses: microsoft/action-python@0.6.3 - with: - pylint: true - - - name: Pyright - uses: microsoft/action-python@0.6.3 - with: - pyright: true - - - name: Flake8 - uses: microsoft/action-python@0.6.3 - with: - flake8: true From 27216b247bda55b9089896fe7494a1e54439201a Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 4 May 2023 12:43:48 +0200 Subject: [PATCH 18/78] :heavy_plus_sign: Test another linter --- .github/workflows/pr_linting.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .github/workflows/pr_linting.yml diff --git a/.github/workflows/pr_linting.yml b/.github/workflows/pr_linting.yml new file mode 100644 index 0000000000..418e5d9379 --- /dev/null +++ b/.github/workflows/pr_linting.yml @@ -0,0 +1,13 @@ +name: 📇 Code Linting + +on: + push: + branches: [ develop ] + +jobs: + - linting: + - name: wemake-python-styleguide + uses: wemake-services/wemake-python-styleguide@master + with: + reporter: 'github-pr-review' + GITHUB_TOKEN: "${{ secrets.YNPUT_BOT_TOKEN }}" From 0f7d552eb3a614ff799ace2aeb49427c7f84da27 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 4 May 2023 12:45:00 +0200 Subject: [PATCH 19/78] :recycle: linter events --- .github/workflows/pr_linting.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/pr_linting.yml b/.github/workflows/pr_linting.yml index 418e5d9379..3f53182be0 100644 --- a/.github/workflows/pr_linting.yml +++ b/.github/workflows/pr_linting.yml @@ -3,6 +3,8 @@ name: 📇 Code Linting on: push: branches: [ develop ] + pull_request: + branches: [ develop ] jobs: - linting: From 98a358b60ac47630b70f6c04e0a62c67fff92929 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 4 May 2023 12:49:26 +0200 Subject: [PATCH 20/78] :art: configure linting --- .github/workflows/pr_linting.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pr_linting.yml b/.github/workflows/pr_linting.yml index 3f53182be0..94574779d1 100644 --- a/.github/workflows/pr_linting.yml +++ b/.github/workflows/pr_linting.yml @@ -7,9 +7,11 @@ on: branches: [ develop ] jobs: - - linting: - - name: wemake-python-styleguide - uses: wemake-services/wemake-python-styleguide@master + lint: + runs-on: ubuntu-latest + steps: + - name: Code Check + - uses: wemake-services/wemake-python-styleguide@master with: reporter: 'github-pr-review' GITHUB_TOKEN: "${{ secrets.YNPUT_BOT_TOKEN }}" From 07dd4d0b0ade51aeff2e9f899daede0b0ed85e68 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 4 May 2023 12:52:00 +0200 Subject: [PATCH 21/78] :recycle: another hit on GH action configuration --- .github/workflows/pr_linting.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr_linting.yml b/.github/workflows/pr_linting.yml index 94574779d1..eb9afffcc2 100644 --- a/.github/workflows/pr_linting.yml +++ b/.github/workflows/pr_linting.yml @@ -7,11 +7,12 @@ on: branches: [ develop ] jobs: - lint: + linting: runs-on: ubuntu-latest steps: - name: Code Check - - uses: wemake-services/wemake-python-styleguide@master + uses: wemake-services/wemake-python-styleguide@master with: reporter: 'github-pr-review' + env: GITHUB_TOKEN: "${{ secrets.YNPUT_BOT_TOKEN }}" From 3e495bc88131d4938230ea105a0a8f245e3ccf55 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 4 May 2023 13:03:57 +0200 Subject: [PATCH 22/78] :art: set linting permissions and checkout --- .github/workflows/pr_linting.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/pr_linting.yml b/.github/workflows/pr_linting.yml index eb9afffcc2..1deeef4726 100644 --- a/.github/workflows/pr_linting.yml +++ b/.github/workflows/pr_linting.yml @@ -6,10 +6,15 @@ on: pull_request: branches: [ develop ] +permissions: + contents: read + pull-requests: write + jobs: linting: runs-on: ubuntu-latest steps: + - uses: actions/checkout@v3 - name: Code Check uses: wemake-services/wemake-python-styleguide@master with: From 00a2db65a12ebc888d09df2d4d8f6ba81a1ea972 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 4 May 2023 14:02:02 +0200 Subject: [PATCH 23/78] :recycle: fix container use in extractor --- .../hosts/max/plugins/publish/extract_pointcloud.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/max/plugins/publish/extract_pointcloud.py b/openpype/hosts/max/plugins/publish/extract_pointcloud.py index 74265da7fb..ee9e9693e9 100644 --- a/openpype/hosts/max/plugins/publish/extract_pointcloud.py +++ b/openpype/hosts/max/plugins/publish/extract_pointcloud.py @@ -6,7 +6,6 @@ from openpype.hosts.max.api import ( maintained_selection ) from openpype.settings import get_project_settings -from openpype.pipeline import legacy_io class ExtractPointCloud(publish.Extractor): @@ -62,10 +61,12 @@ class ExtractPointCloud(publish.Extractor): instance.data["representations"] = [] self.log.info("Writing PRT with TyFlow Plugin...") - filenames = self.get_files(container, path, start, end) + filenames = self.get_files( + instance.data["members"][0], path, start, end) self.log.debug(f"filenames: {filenames}") - partition = self.partition_output_name(container) + partition = self.partition_output_name( + instance.data["members"][0]) representation = { 'name': 'prt', @@ -141,9 +142,9 @@ class ExtractPointCloud(publish.Extractor): sub_anim = rt.GetSubAnim(obj, anim_name) boolean = rt.IsProperty(sub_anim, "Export_Particles") if boolean: - event_name = sub_anim.Name - opt = f"${member.Name}.{event_name}.export_particles" - opt_list.append(opt) + event_name = sub_anim.Name + opt = f"${member.Name}.{event_name}.export_particles" + opt_list.append(opt) return opt_list From cb24f2a9ba8c08b27980fa06e2cb83a2599173a9 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 4 May 2023 14:07:19 +0200 Subject: [PATCH 24/78] :art: configure linter --- .github/workflows/pr_linting.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .github/workflows/pr_linting.yml diff --git a/.github/workflows/pr_linting.yml b/.github/workflows/pr_linting.yml new file mode 100644 index 0000000000..1deeef4726 --- /dev/null +++ b/.github/workflows/pr_linting.yml @@ -0,0 +1,23 @@ +name: 📇 Code Linting + +on: + push: + branches: [ develop ] + pull_request: + branches: [ develop ] + +permissions: + contents: read + pull-requests: write + +jobs: + linting: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Code Check + uses: wemake-services/wemake-python-styleguide@master + with: + reporter: 'github-pr-review' + env: + GITHUB_TOKEN: "${{ secrets.YNPUT_BOT_TOKEN }}" From e608e7c808c22a09c118b4acad14c66543342b7e Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 4 May 2023 14:57:28 +0200 Subject: [PATCH 25/78] :art: limit to changed files path --- .github/workflows/pr_linting.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/pr_linting.yml b/.github/workflows/pr_linting.yml index 1deeef4726..1f6be64d31 100644 --- a/.github/workflows/pr_linting.yml +++ b/.github/workflows/pr_linting.yml @@ -15,9 +15,12 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 + - run: | + echo "_CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }} -- '*.py' | tr -s '\n' ' ' )" >> ${GITHUB_ENV} - name: Code Check uses: wemake-services/wemake-python-styleguide@master with: reporter: 'github-pr-review' + path: "${{ env._CHANGED_FILES }}" env: GITHUB_TOKEN: "${{ secrets.YNPUT_BOT_TOKEN }}" From 5829f647e548ab46be77a4caf7d704297419bbf8 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 4 May 2023 14:59:41 +0200 Subject: [PATCH 26/78] :art: limit --- .github/workflows/pr_linting.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/pr_linting.yml b/.github/workflows/pr_linting.yml index 1f6be64d31..59ac48aeb8 100644 --- a/.github/workflows/pr_linting.yml +++ b/.github/workflows/pr_linting.yml @@ -6,6 +6,8 @@ on: pull_request: branches: [ develop ] + workflow_dispatch: + permissions: contents: read pull-requests: write @@ -19,6 +21,7 @@ jobs: echo "_CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }} -- '*.py' | tr -s '\n' ' ' )" >> ${GITHUB_ENV} - name: Code Check uses: wemake-services/wemake-python-styleguide@master + if: ${{ env._CHANGED_FILES }} with: reporter: 'github-pr-review' path: "${{ env._CHANGED_FILES }}" From 6fb6762f34c0b972e5061b5bfcae1755a6bba895 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 4 May 2023 15:14:17 +0200 Subject: [PATCH 27/78] :recycle: limit using diff_context --- .github/workflows/pr_linting.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/pr_linting.yml b/.github/workflows/pr_linting.yml index 59ac48aeb8..64b6bc0da5 100644 --- a/.github/workflows/pr_linting.yml +++ b/.github/workflows/pr_linting.yml @@ -17,13 +17,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - run: | - echo "_CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }} -- '*.py' | tr -s '\n' ' ' )" >> ${GITHUB_ENV} - name: Code Check uses: wemake-services/wemake-python-styleguide@master - if: ${{ env._CHANGED_FILES }} with: reporter: 'github-pr-review' - path: "${{ env._CHANGED_FILES }}" + filter: 'diff_context' env: GITHUB_TOKEN: "${{ secrets.YNPUT_BOT_TOKEN }}" From da12ac16c56f4510309275ec764b708e1a62bdb0 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 4 May 2023 15:32:50 +0200 Subject: [PATCH 28/78] :art: solving changed list --- .github/workflows/pr_linting.yml | 38 +++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pr_linting.yml b/.github/workflows/pr_linting.yml index 64b6bc0da5..975c83e677 100644 --- a/.github/workflows/pr_linting.yml +++ b/.github/workflows/pr_linting.yml @@ -8,19 +8,55 @@ on: workflow_dispatch: +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number}} + cancel-in-progress: true + permissions: contents: read pull-requests: write jobs: + files_changed: + runs-on: ubuntu-latest + outputs: + changed_python: ${{ steps.changes.outputs.python }} + steps: + - uses: actions/checkout@master + if: github.event_name == 'push' + - uses: dorny/paths-filter@master + id: changes + with: + filters: | + cpp: + - ["lte/gateway/c/**", "orc8r/gateway/c/**", "lte/gateway/python/**"] + javascript: + - ["nms/**", "**/*.js"] + python: + - ["**/*.py"] + terraform: + - ["**/*.tf"] + linting: + needs: files_changed + if: ${{ needs.files_changed.outputs.changed_python == 'true' }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 + with: + ref: ${{ github.event.pull_request.head.ref }} + repository: ${{ github.event.pull_request.head.repo.full_name }} + fetch-depth: 0 + - name: Get changed Python files + id: py-changes + run: | + echo "py_files_list=$(git diff --name-only --diff-filter=ACMRT \ + ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }} \ + | grep .py$ | xargs)" >> $GITHUB_OUTPUT - name: Code Check uses: wemake-services/wemake-python-styleguide@master with: reporter: 'github-pr-review' - filter: 'diff_context' + path: ${{ steps.py-changes.outputs.py_files_list }} env: GITHUB_TOKEN: "${{ secrets.YNPUT_BOT_TOKEN }}" From a3a996d5a56787fa88cf0d92a2c39a6bf0f31fbd Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 4 May 2023 15:42:04 +0200 Subject: [PATCH 29/78] :bug: fix checkout action --- .github/workflows/pr_linting.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr_linting.yml b/.github/workflows/pr_linting.yml index 975c83e677..4f4f7c2585 100644 --- a/.github/workflows/pr_linting.yml +++ b/.github/workflows/pr_linting.yml @@ -22,7 +22,7 @@ jobs: outputs: changed_python: ${{ steps.changes.outputs.python }} steps: - - uses: actions/checkout@master + - uses: actions/checkout@v3 if: github.event_name == 'push' - uses: dorny/paths-filter@master id: changes From 65110ded4609f2b6d7a5ccf97bff097f91d370de Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 4 May 2023 15:43:32 +0200 Subject: [PATCH 30/78] :bug: fix checkout action --- .github/workflows/pr_linting.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr_linting.yml b/.github/workflows/pr_linting.yml index 975c83e677..4f4f7c2585 100644 --- a/.github/workflows/pr_linting.yml +++ b/.github/workflows/pr_linting.yml @@ -22,7 +22,7 @@ jobs: outputs: changed_python: ${{ steps.changes.outputs.python }} steps: - - uses: actions/checkout@master + - uses: actions/checkout@v3 if: github.event_name == 'push' - uses: dorny/paths-filter@master id: changes From 5ef4f4fb131f569da9aa0b5db50c66c0a99f86e8 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 4 May 2023 15:47:52 +0200 Subject: [PATCH 31/78] :bug: fix syntax --- .github/workflows/pr_linting.yml | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/.github/workflows/pr_linting.yml b/.github/workflows/pr_linting.yml index 4f4f7c2585..58f52bb313 100644 --- a/.github/workflows/pr_linting.yml +++ b/.github/workflows/pr_linting.yml @@ -21,21 +21,15 @@ jobs: runs-on: ubuntu-latest outputs: changed_python: ${{ steps.changes.outputs.python }} - steps: - - uses: actions/checkout@v3 - if: github.event_name == 'push' - - uses: dorny/paths-filter@master - id: changes - with: - filters: | - cpp: - - ["lte/gateway/c/**", "orc8r/gateway/c/**", "lte/gateway/python/**"] - javascript: - - ["nms/**", "**/*.js"] - python: - - ["**/*.py"] - terraform: - - ["**/*.tf"] + steps: + - uses: actions/checkout@v3 + if: github.event_name == 'push' + - uses: dorny/paths-filter@master + id: changes + with: + filters: | + python: + - ["**/*.py"] linting: needs: files_changed From 3497b03b7fc8cffadf597908e7f4bdde60f1ee0e Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 4 May 2023 15:50:49 +0200 Subject: [PATCH 32/78] :bug: fix syntax --- .github/workflows/pr_linting.yml | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/.github/workflows/pr_linting.yml b/.github/workflows/pr_linting.yml index 975c83e677..58f52bb313 100644 --- a/.github/workflows/pr_linting.yml +++ b/.github/workflows/pr_linting.yml @@ -21,21 +21,15 @@ jobs: runs-on: ubuntu-latest outputs: changed_python: ${{ steps.changes.outputs.python }} - steps: - - uses: actions/checkout@master - if: github.event_name == 'push' - - uses: dorny/paths-filter@master - id: changes - with: - filters: | - cpp: - - ["lte/gateway/c/**", "orc8r/gateway/c/**", "lte/gateway/python/**"] - javascript: - - ["nms/**", "**/*.js"] - python: - - ["**/*.py"] - terraform: - - ["**/*.tf"] + steps: + - uses: actions/checkout@v3 + if: github.event_name == 'push' + - uses: dorny/paths-filter@master + id: changes + with: + filters: | + python: + - ["**/*.py"] linting: needs: files_changed From 227075f1a918d3ddc7aea60a57f955558820171b Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 4 May 2023 16:07:32 +0200 Subject: [PATCH 33/78] :art: add WPS to pre-commit --- .pre-commit-config.yaml | 9 +++++++++ poetry.lock | 24 +++++++++++++++++++++--- pyproject.toml | 1 + 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index eec388924e..fe4c7e3da3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,3 +10,12 @@ repos: - id: check-added-large-files - id: no-commit-to-branch args: [ '--pattern', '^(?!((release|enhancement|feature|bugfix|documentation|tests|local|chore)\/[a-zA-Z0-9\-_]+)$).*' ] +- repo: local + hooks: + - id: flake8 + name: flake8 + description: WPS enforced flake8 + entry: flake8 + args: ["--config=setup.cfg"] + language: python + types: [python] diff --git a/poetry.lock b/poetry.lock index f71611cb6f..cbc4ac7b94 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry and should not be changed by hand. +# This file is automatically @generated by Poetry 1.4.0 and should not be changed by hand. [[package]] name = "acre" @@ -1456,11 +1456,13 @@ python-versions = ">=3.6" files = [ {file = "lief-0.12.3-cp310-cp310-macosx_10_14_arm64.whl", hash = "sha256:66724f337e6a36cea1a9380f13b59923f276c49ca837becae2e7be93a2e245d9"}, {file = "lief-0.12.3-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:6d18aafa2028587c98f6d4387bec94346e92f2b5a8a5002f70b1cf35b1c045cc"}, + {file = "lief-0.12.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d4f69d125caaa8d5ddb574f29cc83101e165ebea1a9f18ad042eb3544081a797"}, {file = "lief-0.12.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c078d6230279ffd3bca717c79664fb8368666f610b577deb24b374607936e9c1"}, {file = "lief-0.12.3-cp310-cp310-win32.whl", hash = "sha256:e3a6af926532d0aac9e7501946134513d63217bacba666e6f7f5a0b7e15ba236"}, {file = "lief-0.12.3-cp310-cp310-win_amd64.whl", hash = "sha256:0750b72e3aa161e1fb0e2e7f571121ae05d2428aafd742ff05a7656ad2288447"}, {file = "lief-0.12.3-cp311-cp311-macosx_10_14_arm64.whl", hash = "sha256:b5c123cb99a7879d754c059e299198b34e7e30e3b64cf22e8962013db0099f47"}, {file = "lief-0.12.3-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:8bc58fa26a830df6178e36f112cb2bbdd65deff593f066d2d51434ff78386ba5"}, + {file = "lief-0.12.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74ac6143ac6ccd813c9b068d9c5f1f9d55c8813c8b407387eb57de01c3db2d74"}, {file = "lief-0.12.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:04eb6b70d646fb5bd6183575928ee23715550f161f2832cbcd8c6ff2071fb408"}, {file = "lief-0.12.3-cp311-cp311-win32.whl", hash = "sha256:7e2d0a53c403769b04adcf8df92e83c5e25f9103a052aa7f17b0a9cf057735fb"}, {file = "lief-0.12.3-cp311-cp311-win_amd64.whl", hash = "sha256:7f6395c12ee1bc4a5162f567cba96d0c72dfb660e7902e84d4f3029daf14fe33"}, @@ -1480,6 +1482,7 @@ files = [ {file = "lief-0.12.3-cp38-cp38-win_amd64.whl", hash = "sha256:b00667257b43e93d94166c959055b6147d46d302598f3ee55c194b40414c89cc"}, {file = "lief-0.12.3-cp39-cp39-macosx_10_14_arm64.whl", hash = "sha256:e6a1b5b389090d524621c2455795e1262f62dc9381bedd96f0cd72b878c4066d"}, {file = "lief-0.12.3-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:ae773196df814202c0c51056163a1478941b299512b09660a3c37be3c7fac81e"}, + {file = "lief-0.12.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:66ddf88917ec7b00752687c476bb2771dc8ec19bd7e4c0dcff1f8ef774cad4e9"}, {file = "lief-0.12.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:4a47f410032c63ac3be051d963d0337d6b47f0e94bfe8e946ab4b6c428f4d0f8"}, {file = "lief-0.12.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbd11367c2259bd1131a6c8755dcde33314324de5ea029227bfbc7d3755871e6"}, {file = "lief-0.12.3-cp39-cp39-win32.whl", hash = "sha256:2ce53e311918c3e5b54c815ef420a747208d2a88200c41cd476f3dd1eb876bcf"}, @@ -2352,7 +2355,7 @@ files = [ cffi = ">=1.4.1" [package.extras] -docs = ["sphinx (>=1.6.5)", "sphinx_rtd_theme"] +docs = ["sphinx (>=1.6.5)", "sphinx-rtd-theme"] tests = ["hypothesis (>=3.27.0)", "pytest (>=3.2.1,!=3.3.0)"] [[package]] @@ -3245,6 +3248,21 @@ files = [ [package.dependencies] six = "*" +[[package]] +name = "wemake-python-styleguide" +version = "0.0.1" +description = "Opinionated styleguide that we use in wemake.services projects" +category = "dev" +optional = false +python-versions = "*" +files = [ + {file = "wemake-python-styleguide-0.0.1.tar.gz", hash = "sha256:e1f47a2be6aa79ca8a1cfbbbffdd67bf4df32b76306f4c3dd2a620a2af78e671"}, + {file = "wemake_python_styleguide-0.0.1-py2.py3-none-any.whl", hash = "sha256:505a19d82f9c4f450c6f06bb8c74d86c99cabcc4d5e6d8ea70e90b13b049f34f"}, +] + +[package.dependencies] +flake8 = "*" + [[package]] name = "wheel" version = "0.38.4" @@ -3462,4 +3480,4 @@ testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools" [metadata] lock-version = "2.0" python-versions = ">=3.9.1,<3.10" -content-hash = "02daca205796a0f29a0d9f50707544e6804f32027eba493cd2aa7f175a00dcea" +content-hash = "c566a959134559e2fccf9b17fc820956207c9d36a58195f48990b986114d7108" diff --git a/pyproject.toml b/pyproject.toml index 2f40d58f56..99e03daea1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -94,6 +94,7 @@ wheel = "*" enlighten = "*" # cool terminal progress bars toml = "^0.10.2" # for parsing pyproject.toml pre-commit = "*" +wemake-python-styleguide = "*" [tool.poetry.urls] "Bug Tracker" = "https://github.com/pypeclub/openpype/issues" From a6f3bbe0f4f653048e11d7ecbb282d7c7583ef53 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 4 May 2023 16:49:09 +0200 Subject: [PATCH 34/78] :wrench: update flake8 configuration --- setup.cfg | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 140 insertions(+), 4 deletions(-) diff --git a/setup.cfg b/setup.cfg index 10cca3eb3f..838c6bd4c5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,7 +1,6 @@ [flake8] -# ignore = D203 -ignore = BLK100, W504, W503 max-line-length = 79 +strictness = short exclude = .git, __pycache__, @@ -10,8 +9,145 @@ exclude = website, openpype/vendor, *deadline/repository/custom/plugins - max-complexity = 30 +ignore = + # line break before binary operator + W503, + # line break occurred after a binary operator + W504, + # wemake-python-styleguide warnings + # See https://wemake-python-stylegui.de/en/latest/pages/usage/violations/index.html for doc + # Found incorrect module name pattern + WPS102, + # Found wrong variable name + WPS110, + # Found too short name + WPS111, + # Found upper-case constant in a class + WPS115, + # Found module with too many imports + WPS201, + # Found too many module members + WPS202, + # Found overused expression + WPS204, + # Found too many local variables + WPS210, + # Found too many arguments + WPS211, + # Found too many return statements + WPS212, + # Found too many expressions + WPS213, + # Found too many methods + WPS214, + # Found too many await expressions + WPS217, + # Found line with high Jones Complexity + WPS221, + # Found too many `elif` branches + WPS223, + # Found string constant over-use + WPS226, + # Found too long try body length + WPS229, + # Found too many public instance attributes + WPS230, + # Found function with too much cognitive complexity + WPS231, + # Found module cognitive complexity that is too high + WPS232, + # Found too many imported names from a module + WPS235, + # Found too many raises in a function + WPS238, + # Found too deep nesting + WPS220, + # Found `f` string + WPS305, + # Found incorrect multi-line parameters + WPS317, + # Found extra indentation + WPS318, + # Found bracket in wrong position + WPS319, + # Found percent string formatting + WPS323, + # Found implicit string concatenation + WPS326, + # Found variables that are only used for `return` + WPS331, + # Found explicit string concatenation + WPS336, + # Found multiline conditions + WPS337, + # Found incorrect order of methods in a class + WPS338, + # Found line starting with a dot + WPS348, + # Found multiline loop + WPS352, + # Found incorrect unpacking target + WPS414, + # Found wrong keyword + WPS420, + # Found wrong function + WPS421, + # Found statement that has no effect + WPS428, + # Found nested function + WPS430, + # Found magic number + WPS432, + # Found protected attribute usage + WPS437, + # Found block variables overlap + WPS440, + # Found an infinite while loop + WPS457, + # Found a getter without a return value + WPS463, + # Found negated condition + WPS504, + # flake8-quotes warnings + # Remove bad quotes + Q000, + # Remove bad quotes from multiline string + Q001, + # Darglint warnings + # Incorrect indentation + DAR003, + # Excess parameter(s) in Docstring + DAR102, + # Excess exception(s) in Raises section + DAR402, + # pydocstyle warnings + # Missing docstring in __init_ + D107, + # White space formatting for doc strings + D2, + # First line should end with a period + D400, + # Others + # function name + N802, + # Found backslash that is used for line breaking + N400, + E501, + S105, + RST + +[isort] +profile=wemake +src_paths=isort,test +# isort configuration: +# https://github.com/timothycrosley/isort/wiki/isort-Settings +include_trailing_comma = true +use_parentheses = true +# See https://github.com/timothycrosley/isort#multi-line-output-modes +multi_line_output = 3 +# Is the same as 80 in flake8: +line_length = 79 [pylint.'MESSAGES CONTROL'] disable = no-member @@ -28,4 +164,4 @@ omit = /tests directory = ./coverage [tool:pytest] -norecursedirs = repos/* openpype/modules/ftrack/* \ No newline at end of file +norecursedirs = repos/* openpype/modules/ftrack/* From e1384a40b1b94a0f456d6cd4e01a63dd1e8a23e5 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 4 May 2023 17:46:31 +0200 Subject: [PATCH 35/78] :heavy_plus_sign: add isort and fix python black check --- poetry.lock | 2 +- pyproject.toml | 1 + setup.cfg | 4 +++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/poetry.lock b/poetry.lock index cbc4ac7b94..563f905fad 100644 --- a/poetry.lock +++ b/poetry.lock @@ -3480,4 +3480,4 @@ testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools" [metadata] lock-version = "2.0" python-versions = ">=3.9.1,<3.10" -content-hash = "c566a959134559e2fccf9b17fc820956207c9d36a58195f48990b986114d7108" +content-hash = "45e91b47f9e6697b0eb9fdbe76981f691d389ce74bc5a0e98d72e1109b39bc63" diff --git a/pyproject.toml b/pyproject.toml index 4bb80c060b..0d236aedc6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -95,6 +95,7 @@ enlighten = "*" # cool terminal progress bars toml = "^0.10.2" # for parsing pyproject.toml pre-commit = "*" wemake-python-styleguide = "*" +isort="*" [tool.poetry.urls] "Bug Tracker" = "https://github.com/pypeclub/openpype/issues" diff --git a/setup.cfg b/setup.cfg index 838c6bd4c5..7863a74894 100644 --- a/setup.cfg +++ b/setup.cfg @@ -135,7 +135,9 @@ ignore = N400, E501, S105, - RST + RST, + # Black would make changes error + BLK100, [isort] profile=wemake From ecc1ba12f0187c9d9e46e9a59e1749e90e7a6ed1 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 5 May 2023 13:22:23 +0800 Subject: [PATCH 36/78] bug fix the validator error --- .../hosts/max/plugins/create/create_camera.py | 8 +++-- .../max/plugins/create/create_maxScene.py | 8 +++-- .../max/plugins/create/create_pointcache.py | 11 ++++-- .../max/plugins/create/create_pointcloud.py | 8 +++-- .../hosts/max/plugins/create/create_render.py | 8 +++-- .../max/plugins/publish/extract_pointcloud.py | 34 +++++++++---------- .../plugins/publish/validate_pointcloud.py | 2 +- 7 files changed, 47 insertions(+), 32 deletions(-) diff --git a/openpype/hosts/max/plugins/create/create_camera.py b/openpype/hosts/max/plugins/create/create_camera.py index 91d0d4d3dc..ab5578a201 100644 --- a/openpype/hosts/max/plugins/create/create_camera.py +++ b/openpype/hosts/max/plugins/create/create_camera.py @@ -12,7 +12,6 @@ class CreateCamera(plugin.MaxCreator): def create(self, subset_name, instance_data, pre_create_data): from pymxs import runtime as rt - sel_obj = list(rt.selection) instance = super(CreateCamera, self).create( subset_name, instance_data, @@ -20,7 +19,10 @@ class CreateCamera(plugin.MaxCreator): container = rt.getNodeByName(instance.data.get("instance_node")) # TODO: Disable "Add to Containers?" Panel # parent the selected cameras into the container - for obj in sel_obj: - obj.parent = container + sel_obj = None + if self.selected_nodes: + sel_obj = list(self.selected_nodes) + for obj in sel_obj: + obj.parent = container # for additional work on the node: # instance_node = rt.getNodeByName(instance.get("instance_node")) diff --git a/openpype/hosts/max/plugins/create/create_maxScene.py b/openpype/hosts/max/plugins/create/create_maxScene.py index 7900336f32..2d6ea8c27b 100644 --- a/openpype/hosts/max/plugins/create/create_maxScene.py +++ b/openpype/hosts/max/plugins/create/create_maxScene.py @@ -12,7 +12,6 @@ class CreateMaxScene(plugin.MaxCreator): def create(self, subset_name, instance_data, pre_create_data): from pymxs import runtime as rt - sel_obj = list(rt.selection) instance = super(CreateMaxScene, self).create( subset_name, instance_data, @@ -20,7 +19,10 @@ class CreateMaxScene(plugin.MaxCreator): container = rt.getNodeByName(instance.data.get("instance_node")) # TODO: Disable "Add to Containers?" Panel # parent the selected cameras into the container - for obj in sel_obj: - obj.parent = container + sel_obj = None + if self.selected_nodes: + sel_obj = list(self.selected_nodes) + for obj in sel_obj: + obj.parent = container # for additional work on the node: # instance_node = rt.getNodeByName(instance.get("instance_node")) diff --git a/openpype/hosts/max/plugins/create/create_pointcache.py b/openpype/hosts/max/plugins/create/create_pointcache.py index 32f0838471..42aa743794 100644 --- a/openpype/hosts/max/plugins/create/create_pointcache.py +++ b/openpype/hosts/max/plugins/create/create_pointcache.py @@ -13,10 +13,17 @@ class CreatePointCache(plugin.MaxCreator): def create(self, subset_name, instance_data, pre_create_data): # from pymxs import runtime as rt - _ = super(CreatePointCache, self).create( + instance = super(CreatePointCache, self).create( subset_name, instance_data, pre_create_data) # type: CreatedInstance - + container = rt.getNodeByName(instance.data.get("instance_node")) + # TODO: Disable "Add to Containers?" Panel + # parent the selected cameras into the container + sel_obj = None + if self.selected_nodes: + sel_obj = list(self.selected_nodes) + for obj in sel_obj: + obj.parent = container # for additional work on the node: # instance_node = rt.getNodeByName(instance.get("instance_node")) diff --git a/openpype/hosts/max/plugins/create/create_pointcloud.py b/openpype/hosts/max/plugins/create/create_pointcloud.py index c83acac3df..e46bf30d1c 100644 --- a/openpype/hosts/max/plugins/create/create_pointcloud.py +++ b/openpype/hosts/max/plugins/create/create_pointcloud.py @@ -12,7 +12,6 @@ class CreatePointCloud(plugin.MaxCreator): def create(self, subset_name, instance_data, pre_create_data): from pymxs import runtime as rt - sel_obj = list(rt.selection) instance = super(CreatePointCloud, self).create( subset_name, instance_data, @@ -20,7 +19,10 @@ class CreatePointCloud(plugin.MaxCreator): container = rt.getNodeByName(instance.data.get("instance_node")) # TODO: Disable "Add to Containers?" Panel # parent the selected cameras into the container - for obj in sel_obj: - obj.parent = container + sel_obj = None + if self.selected_nodes: + sel_obj = list(self.selected_nodes) + for obj in sel_obj: + obj.parent = container # for additional work on the node: # instance_node = rt.getNodeByName(instance.get("instance_node")) diff --git a/openpype/hosts/max/plugins/create/create_render.py b/openpype/hosts/max/plugins/create/create_render.py index 269fff2e32..43d69fa320 100644 --- a/openpype/hosts/max/plugins/create/create_render.py +++ b/openpype/hosts/max/plugins/create/create_render.py @@ -13,7 +13,6 @@ class CreateRender(plugin.MaxCreator): def create(self, subset_name, instance_data, pre_create_data): from pymxs import runtime as rt - sel_obj = list(rt.selection) instance = super(CreateRender, self).create( subset_name, instance_data, @@ -22,8 +21,11 @@ class CreateRender(plugin.MaxCreator): container = rt.getNodeByName(container_name) # TODO: Disable "Add to Containers?" Panel # parent the selected cameras into the container - for obj in sel_obj: - obj.parent = container + sel_obj = None + if self.selected_nodes: + sel_obj = list(self.selected_nodes) + for obj in sel_obj: + obj.parent = container # for additional work on the node: # instance_node = rt.getNodeByName(instance.get("instance_node")) diff --git a/openpype/hosts/max/plugins/publish/extract_pointcloud.py b/openpype/hosts/max/plugins/publish/extract_pointcloud.py index ee9e9693e9..f85255bbf5 100644 --- a/openpype/hosts/max/plugins/publish/extract_pointcloud.py +++ b/openpype/hosts/max/plugins/publish/extract_pointcloud.py @@ -53,7 +53,9 @@ class ExtractPointCloud(publish.Extractor): start, end, path) + for job in job_args: + self.log.debug("job:{}".format(job)) rt.Execute(job) self.log.info("Performing Extraction ...") @@ -62,11 +64,11 @@ class ExtractPointCloud(publish.Extractor): self.log.info("Writing PRT with TyFlow Plugin...") filenames = self.get_files( - instance.data["members"][0], path, start, end) + instance.data["members"], path, start, end) self.log.debug(f"filenames: {filenames}") partition = self.partition_output_name( - instance.data["members"][0]) + instance.data["members"]) representation = { 'name': 'prt', @@ -105,7 +107,7 @@ class ExtractPointCloud(publish.Extractor): end_frame = f"{operator}.frameEnd={end}" job_args.append(end_frame) filepath = filepath.replace("\\", "/") - prt_filename = f"{operator}.PRTFilename={filepath}" + prt_filename = f"{operator}.PRTFilename='{filepath}'" job_args.append(prt_filename) # Partition @@ -113,7 +115,8 @@ class ExtractPointCloud(publish.Extractor): job_args.append(mode) additional_args = self.get_custom_attr(operator) - job_args.extend(iter(additional_args)) + for args in additional_args: + job_args.append(args) prt_export = f"{operator}.exportPRT()" job_args.append(prt_export) @@ -132,19 +135,16 @@ class ExtractPointCloud(publish.Extractor): """ opt_list = [] for member in members: - node = rt.getNodeByName(member) - selection_list = list(node.Children) - for sel in selection_list: - obj = sel.baseobject - # TODO: to see if it can be used maxscript instead - anim_names = rt.GetSubAnimNames(obj) - for anim_name in anim_names: - sub_anim = rt.GetSubAnim(obj, anim_name) - boolean = rt.IsProperty(sub_anim, "Export_Particles") - if boolean: - event_name = sub_anim.Name - opt = f"${member.Name}.{event_name}.export_particles" - opt_list.append(opt) + obj = member.baseobject + # TODO: to see if it can be used maxscript instead + anim_names = rt.GetSubAnimNames(obj) + for anim_name in anim_names: + sub_anim = rt.GetSubAnim(obj, anim_name) + boolean = rt.IsProperty(sub_anim, "Export_Particles") + if boolean: + event_name = sub_anim.Name + opt = f"${member.Name}.{event_name}.export_particles" + opt_list.append(opt) return opt_list diff --git a/openpype/hosts/max/plugins/publish/validate_pointcloud.py b/openpype/hosts/max/plugins/publish/validate_pointcloud.py index e3a6face07..e1c2151c9d 100644 --- a/openpype/hosts/max/plugins/publish/validate_pointcloud.py +++ b/openpype/hosts/max/plugins/publish/validate_pointcloud.py @@ -54,7 +54,7 @@ class ValidatePointCloud(pyblish.api.InstancePlugin): f":{invalid}")) if report: - raise PublishValidationError + raise PublishValidationError(f"{report}") def get_tyflow_object(self, instance): invalid = [] From cca37521e9de457e5b4b519f09aaa4d1851f4c3d Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 5 May 2023 13:34:18 +0800 Subject: [PATCH 37/78] refractor to the point cloud extractor and all creators --- openpype/hosts/max/plugins/create/create_camera.py | 7 +------ openpype/hosts/max/plugins/create/create_maxScene.py | 7 +------ openpype/hosts/max/plugins/create/create_model.py | 7 +------ openpype/hosts/max/plugins/create/create_pointcache.py | 9 ++------- openpype/hosts/max/plugins/create/create_pointcloud.py | 7 +------ openpype/hosts/max/plugins/publish/extract_pointcloud.py | 4 +--- 6 files changed, 7 insertions(+), 34 deletions(-) diff --git a/openpype/hosts/max/plugins/create/create_camera.py b/openpype/hosts/max/plugins/create/create_camera.py index ab5578a201..b949c91857 100644 --- a/openpype/hosts/max/plugins/create/create_camera.py +++ b/openpype/hosts/max/plugins/create/create_camera.py @@ -16,13 +16,8 @@ class CreateCamera(plugin.MaxCreator): subset_name, instance_data, pre_create_data) # type: CreatedInstance - container = rt.getNodeByName(instance.data.get("instance_node")) + _ = rt.getNodeByName(instance.data.get("instance_node")) # TODO: Disable "Add to Containers?" Panel # parent the selected cameras into the container - sel_obj = None - if self.selected_nodes: - sel_obj = list(self.selected_nodes) - for obj in sel_obj: - obj.parent = container # for additional work on the node: # instance_node = rt.getNodeByName(instance.get("instance_node")) diff --git a/openpype/hosts/max/plugins/create/create_maxScene.py b/openpype/hosts/max/plugins/create/create_maxScene.py index 2d6ea8c27b..bf03ee8c8a 100644 --- a/openpype/hosts/max/plugins/create/create_maxScene.py +++ b/openpype/hosts/max/plugins/create/create_maxScene.py @@ -16,13 +16,8 @@ class CreateMaxScene(plugin.MaxCreator): subset_name, instance_data, pre_create_data) # type: CreatedInstance - container = rt.getNodeByName(instance.data.get("instance_node")) + _ = rt.getNodeByName(instance.data.get("instance_node")) # TODO: Disable "Add to Containers?" Panel # parent the selected cameras into the container - sel_obj = None - if self.selected_nodes: - sel_obj = list(self.selected_nodes) - for obj in sel_obj: - obj.parent = container # for additional work on the node: # instance_node = rt.getNodeByName(instance.get("instance_node")) diff --git a/openpype/hosts/max/plugins/create/create_model.py b/openpype/hosts/max/plugins/create/create_model.py index e7ae3af9db..4f7fd491e4 100644 --- a/openpype/hosts/max/plugins/create/create_model.py +++ b/openpype/hosts/max/plugins/create/create_model.py @@ -16,13 +16,8 @@ class CreateModel(plugin.MaxCreator): subset_name, instance_data, pre_create_data) # type: CreatedInstance - container = rt.getNodeByName(instance.data.get("instance_node")) + _ = rt.getNodeByName(instance.data.get("instance_node")) # TODO: Disable "Add to Containers?" Panel # parent the selected cameras into the container - sel_obj = None - if self.selected_nodes: - sel_obj = list(self.selected_nodes) - for obj in sel_obj: - obj.parent = container # for additional work on the node: # instance_node = rt.getNodeByName(instance.get("instance_node")) diff --git a/openpype/hosts/max/plugins/create/create_pointcache.py b/openpype/hosts/max/plugins/create/create_pointcache.py index 42aa743794..aa22a92b25 100644 --- a/openpype/hosts/max/plugins/create/create_pointcache.py +++ b/openpype/hosts/max/plugins/create/create_pointcache.py @@ -11,19 +11,14 @@ class CreatePointCache(plugin.MaxCreator): icon = "gear" def create(self, subset_name, instance_data, pre_create_data): - # from pymxs import runtime as rt + from pymxs import runtime as rt instance = super(CreatePointCache, self).create( subset_name, instance_data, pre_create_data) # type: CreatedInstance - container = rt.getNodeByName(instance.data.get("instance_node")) + _ = rt.getNodeByName(instance.data.get("instance_node")) # TODO: Disable "Add to Containers?" Panel # parent the selected cameras into the container - sel_obj = None - if self.selected_nodes: - sel_obj = list(self.selected_nodes) - for obj in sel_obj: - obj.parent = container # for additional work on the node: # instance_node = rt.getNodeByName(instance.get("instance_node")) diff --git a/openpype/hosts/max/plugins/create/create_pointcloud.py b/openpype/hosts/max/plugins/create/create_pointcloud.py index e46bf30d1c..a8564ee118 100644 --- a/openpype/hosts/max/plugins/create/create_pointcloud.py +++ b/openpype/hosts/max/plugins/create/create_pointcloud.py @@ -16,13 +16,8 @@ class CreatePointCloud(plugin.MaxCreator): subset_name, instance_data, pre_create_data) # type: CreatedInstance - container = rt.getNodeByName(instance.data.get("instance_node")) + _ = rt.getNodeByName(instance.data.get("instance_node")) # TODO: Disable "Add to Containers?" Panel # parent the selected cameras into the container - sel_obj = None - if self.selected_nodes: - sel_obj = list(self.selected_nodes) - for obj in sel_obj: - obj.parent = container # for additional work on the node: # instance_node = rt.getNodeByName(instance.get("instance_node")) diff --git a/openpype/hosts/max/plugins/publish/extract_pointcloud.py b/openpype/hosts/max/plugins/publish/extract_pointcloud.py index f85255bbf5..c807885859 100644 --- a/openpype/hosts/max/plugins/publish/extract_pointcloud.py +++ b/openpype/hosts/max/plugins/publish/extract_pointcloud.py @@ -55,7 +55,6 @@ class ExtractPointCloud(publish.Extractor): path) for job in job_args: - self.log.debug("job:{}".format(job)) rt.Execute(job) self.log.info("Performing Extraction ...") @@ -107,8 +106,7 @@ class ExtractPointCloud(publish.Extractor): end_frame = f"{operator}.frameEnd={end}" job_args.append(end_frame) filepath = filepath.replace("\\", "/") - prt_filename = f"{operator}.PRTFilename='{filepath}'" - + prt_filename = f'{operator}.PRTFilename="{filepath}"' job_args.append(prt_filename) # Partition mode = f"{operator}.PRTPartitionsMode=2" From 932c807913e5f7bac4de5d4acffd8ede3c9a0c3d Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 5 May 2023 13:53:54 +0800 Subject: [PATCH 38/78] fix the bug shown in removing instance after refractoring --- openpype/hosts/max/api/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/max/api/plugin.py b/openpype/hosts/max/api/plugin.py index 39a17c29ef..a464d54b33 100644 --- a/openpype/hosts/max/api/plugin.py +++ b/openpype/hosts/max/api/plugin.py @@ -173,7 +173,7 @@ class MaxCreator(Creator, MaxCreatorBase): for instance in instances: if instance_node := rt.GetNodeByName(instance.data.get("instance_node")): # noqa rt.Select(instance_node) - rt.custAttributes.add(instance_node.baseObject, "openPypeData") + rt.execute(f'for o in selection do for c in o.children do c.parent = undefined') # noqa rt.Delete(instance_node) self._remove_instance_from_context(instance) From 2d26cc00ad2c9787b47ede9fc81a6289a6edc911 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Fri, 5 May 2023 15:52:47 +0200 Subject: [PATCH 39/78] :rotating_light: some style issues and refactoring --- .pre-commit-config.yaml | 12 ++++-- .../hosts/max/plugins/create/create_camera.py | 14 +------ .../max/plugins/create/create_maxScene.py | 14 +------ .../hosts/max/plugins/create/create_model.py | 14 +------ .../max/plugins/create/create_pointcache.py | 15 +------- .../max/plugins/create/create_pointcloud.py | 14 +------ .../hosts/max/plugins/create/create_render.py | 13 +++---- .../plugins/publish/validate_usd_plugin.py | 38 ++++++++++--------- setup.cfg | 2 + 9 files changed, 41 insertions(+), 95 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index fe4c7e3da3..9c03dc8ff0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,11 +10,15 @@ repos: - id: check-added-large-files - id: no-commit-to-branch args: [ '--pattern', '^(?!((release|enhancement|feature|bugfix|documentation|tests|local|chore)\/[a-zA-Z0-9\-_]+)$).*' ] -- repo: local - hooks: - - id: flake8 + +- repo: local + hooks: + - id: flake8 name: flake8 - description: WPS enforced flake8 + additional_dependencies: + - wemake-python-styleguide + - flake8 + description: Python style guide enforcement entry: flake8 args: ["--config=setup.cfg"] language: python diff --git a/openpype/hosts/max/plugins/create/create_camera.py b/openpype/hosts/max/plugins/create/create_camera.py index b949c91857..804d629ec7 100644 --- a/openpype/hosts/max/plugins/create/create_camera.py +++ b/openpype/hosts/max/plugins/create/create_camera.py @@ -1,23 +1,11 @@ # -*- coding: utf-8 -*- """Creator plugin for creating camera.""" from openpype.hosts.max.api import plugin -from openpype.pipeline import CreatedInstance class CreateCamera(plugin.MaxCreator): + """Creator plugin for Camera.""" identifier = "io.openpype.creators.max.camera" label = "Camera" family = "camera" icon = "gear" - - def create(self, subset_name, instance_data, pre_create_data): - from pymxs import runtime as rt - instance = super(CreateCamera, self).create( - subset_name, - instance_data, - pre_create_data) # type: CreatedInstance - _ = rt.getNodeByName(instance.data.get("instance_node")) - # TODO: Disable "Add to Containers?" Panel - # parent the selected cameras into the container - # for additional work on the node: - # instance_node = rt.getNodeByName(instance.get("instance_node")) diff --git a/openpype/hosts/max/plugins/create/create_maxScene.py b/openpype/hosts/max/plugins/create/create_maxScene.py index bf03ee8c8a..851e26dda2 100644 --- a/openpype/hosts/max/plugins/create/create_maxScene.py +++ b/openpype/hosts/max/plugins/create/create_maxScene.py @@ -1,23 +1,11 @@ # -*- coding: utf-8 -*- """Creator plugin for creating raw max scene.""" from openpype.hosts.max.api import plugin -from openpype.pipeline import CreatedInstance class CreateMaxScene(plugin.MaxCreator): + """Creator plugin for 3ds max scenes.""" identifier = "io.openpype.creators.max.maxScene" label = "Max Scene" family = "maxScene" icon = "gear" - - def create(self, subset_name, instance_data, pre_create_data): - from pymxs import runtime as rt - instance = super(CreateMaxScene, self).create( - subset_name, - instance_data, - pre_create_data) # type: CreatedInstance - _ = rt.getNodeByName(instance.data.get("instance_node")) - # TODO: Disable "Add to Containers?" Panel - # parent the selected cameras into the container - # for additional work on the node: - # instance_node = rt.getNodeByName(instance.get("instance_node")) diff --git a/openpype/hosts/max/plugins/create/create_model.py b/openpype/hosts/max/plugins/create/create_model.py index 4f7fd491e4..fc09d475ef 100644 --- a/openpype/hosts/max/plugins/create/create_model.py +++ b/openpype/hosts/max/plugins/create/create_model.py @@ -1,23 +1,11 @@ # -*- coding: utf-8 -*- """Creator plugin for model.""" from openpype.hosts.max.api import plugin -from openpype.pipeline import CreatedInstance class CreateModel(plugin.MaxCreator): + """Creator plugin for Model.""" identifier = "io.openpype.creators.max.model" label = "Model" family = "model" icon = "gear" - - def create(self, subset_name, instance_data, pre_create_data): - from pymxs import runtime as rt - instance = super(CreateModel, self).create( - subset_name, - instance_data, - pre_create_data) # type: CreatedInstance - _ = rt.getNodeByName(instance.data.get("instance_node")) - # TODO: Disable "Add to Containers?" Panel - # parent the selected cameras into the container - # for additional work on the node: - # instance_node = rt.getNodeByName(instance.get("instance_node")) diff --git a/openpype/hosts/max/plugins/create/create_pointcache.py b/openpype/hosts/max/plugins/create/create_pointcache.py index aa22a92b25..c2d11f4c32 100644 --- a/openpype/hosts/max/plugins/create/create_pointcache.py +++ b/openpype/hosts/max/plugins/create/create_pointcache.py @@ -1,24 +1,11 @@ # -*- coding: utf-8 -*- """Creator plugin for creating pointcache alembics.""" from openpype.hosts.max.api import plugin -from openpype.pipeline import CreatedInstance class CreatePointCache(plugin.MaxCreator): + """Creator plugin for Point caches.""" identifier = "io.openpype.creators.max.pointcache" label = "Point Cache" family = "pointcache" icon = "gear" - - def create(self, subset_name, instance_data, pre_create_data): - from pymxs import runtime as rt - - instance = super(CreatePointCache, self).create( - subset_name, - instance_data, - pre_create_data) # type: CreatedInstance - _ = rt.getNodeByName(instance.data.get("instance_node")) - # TODO: Disable "Add to Containers?" Panel - # parent the selected cameras into the container - # for additional work on the node: - # instance_node = rt.getNodeByName(instance.get("instance_node")) diff --git a/openpype/hosts/max/plugins/create/create_pointcloud.py b/openpype/hosts/max/plugins/create/create_pointcloud.py index a8564ee118..bc7706069d 100644 --- a/openpype/hosts/max/plugins/create/create_pointcloud.py +++ b/openpype/hosts/max/plugins/create/create_pointcloud.py @@ -1,23 +1,11 @@ # -*- coding: utf-8 -*- """Creator plugin for creating point cloud.""" from openpype.hosts.max.api import plugin -from openpype.pipeline import CreatedInstance class CreatePointCloud(plugin.MaxCreator): + """Creator plugin for Point Clouds.""" identifier = "io.openpype.creators.max.pointcloud" label = "Point Cloud" family = "pointcloud" icon = "gear" - - def create(self, subset_name, instance_data, pre_create_data): - from pymxs import runtime as rt - instance = super(CreatePointCloud, self).create( - subset_name, - instance_data, - pre_create_data) # type: CreatedInstance - _ = rt.getNodeByName(instance.data.get("instance_node")) - # TODO: Disable "Add to Containers?" Panel - # parent the selected cameras into the container - # for additional work on the node: - # instance_node = rt.getNodeByName(instance.get("instance_node")) diff --git a/openpype/hosts/max/plugins/create/create_render.py b/openpype/hosts/max/plugins/create/create_render.py index 43d69fa320..e9952c3124 100644 --- a/openpype/hosts/max/plugins/create/create_render.py +++ b/openpype/hosts/max/plugins/create/create_render.py @@ -1,24 +1,25 @@ # -*- coding: utf-8 -*- """Creator plugin for creating camera.""" from openpype.hosts.max.api import plugin -from openpype.pipeline import CreatedInstance from openpype.hosts.max.api.lib_rendersettings import RenderSettings class CreateRender(plugin.MaxCreator): + """Creator plugin for Renders.""" identifier = "io.openpype.creators.max.render" label = "Render" family = "maxrender" icon = "gear" def create(self, subset_name, instance_data, pre_create_data): - from pymxs import runtime as rt - instance = super(CreateRender, self).create( + """Plugin entry point.""" + from pymxs import runtime as rt # noqa: WPS433,I001 + instance = super().create( subset_name, instance_data, - pre_create_data) # type: CreatedInstance + pre_create_data) container_name = instance.data.get("instance_node") - container = rt.getNodeByName(container_name) + container = rt.GetNodeByName(container_name) # TODO: Disable "Add to Containers?" Panel # parent the selected cameras into the container sel_obj = None @@ -26,8 +27,6 @@ class CreateRender(plugin.MaxCreator): sel_obj = list(self.selected_nodes) for obj in sel_obj: obj.parent = container - # for additional work on the node: - # instance_node = rt.getNodeByName(instance.get("instance_node")) # set viewport camera for rendering(mandatory for deadline) RenderSettings().set_render_camera(sel_obj) diff --git a/openpype/hosts/max/plugins/publish/validate_usd_plugin.py b/openpype/hosts/max/plugins/publish/validate_usd_plugin.py index 8f11d72567..9957e62736 100644 --- a/openpype/hosts/max/plugins/publish/validate_usd_plugin.py +++ b/openpype/hosts/max/plugins/publish/validate_usd_plugin.py @@ -1,35 +1,37 @@ # -*- coding: utf-8 -*- -import pyblish.api +"""Validator for USD plugin.""" from openpype.pipeline import PublishValidationError +from pyblish.api import InstancePlugin, ValidatorOrder from pymxs import runtime as rt -class ValidateUSDPlugin(pyblish.api.InstancePlugin): - """Validates if USD plugin is installed or loaded in Max - """ +def get_plugins() -> list: + """Get plugin list from 3ds max.""" + manager = rt.PluginManager + count = manager.pluginDllCount + plugin_info_list = [] + for p in range(1, count + 1): + plugin_info = manager.pluginDllName(p) + plugin_info_list.append(plugin_info) - order = pyblish.api.ValidatorOrder - 0.01 + return plugin_info_list + + +class ValidateUSDPlugin(InstancePlugin): + """Validates if USD plugin is installed or loaded in 3ds max.""" + + order = ValidatorOrder - 0.01 families = ["model"] hosts = ["max"] label = "USD Plugin" def process(self, instance): - plugin_mgr = rt.PluginManager - plugin_count = plugin_mgr.pluginDllCount - plugin_info = self.get_plugins(plugin_mgr, - plugin_count) + """Plugin entry point.""" + + plugin_info = get_plugins() usd_import = "usdimport.dli" if usd_import not in plugin_info: raise PublishValidationError(f"USD Plugin {usd_import} not found") usd_export = "usdexport.dle" if usd_export not in plugin_info: raise PublishValidationError(f"USD Plugin {usd_export} not found") - - @staticmethod - def get_plugins(manager, count): - plugin_info_list = [] - for p in range(1, count + 1): - plugin_info = manager.pluginDllName(p) - plugin_info_list.append(plugin_info) - - return plugin_info_list diff --git a/setup.cfg b/setup.cfg index 7863a74894..1d57657a19 100644 --- a/setup.cfg +++ b/setup.cfg @@ -138,6 +138,8 @@ ignore = RST, # Black would make changes error BLK100, + # Imperative mood of the first line on docstrings + D401, [isort] profile=wemake From ac154303f3aaf6130492442c1c42496877006213 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Fri, 5 May 2023 17:23:42 +0200 Subject: [PATCH 40/78] :heavy_minus_sign: revert WPS tests --- .github/workflows/pr_linting.yml | 56 -------------------------------- .pre-commit-config.yaml | 13 -------- pyproject.toml | 2 -- 3 files changed, 71 deletions(-) delete mode 100644 .github/workflows/pr_linting.yml diff --git a/.github/workflows/pr_linting.yml b/.github/workflows/pr_linting.yml deleted file mode 100644 index 58f52bb313..0000000000 --- a/.github/workflows/pr_linting.yml +++ /dev/null @@ -1,56 +0,0 @@ -name: 📇 Code Linting - -on: - push: - branches: [ develop ] - pull_request: - branches: [ develop ] - - workflow_dispatch: - -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number}} - cancel-in-progress: true - -permissions: - contents: read - pull-requests: write - -jobs: - files_changed: - runs-on: ubuntu-latest - outputs: - changed_python: ${{ steps.changes.outputs.python }} - steps: - - uses: actions/checkout@v3 - if: github.event_name == 'push' - - uses: dorny/paths-filter@master - id: changes - with: - filters: | - python: - - ["**/*.py"] - - linting: - needs: files_changed - if: ${{ needs.files_changed.outputs.changed_python == 'true' }} - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - ref: ${{ github.event.pull_request.head.ref }} - repository: ${{ github.event.pull_request.head.repo.full_name }} - fetch-depth: 0 - - name: Get changed Python files - id: py-changes - run: | - echo "py_files_list=$(git diff --name-only --diff-filter=ACMRT \ - ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }} \ - | grep .py$ | xargs)" >> $GITHUB_OUTPUT - - name: Code Check - uses: wemake-services/wemake-python-styleguide@master - with: - reporter: 'github-pr-review' - path: ${{ steps.py-changes.outputs.py_files_list }} - env: - GITHUB_TOKEN: "${{ secrets.YNPUT_BOT_TOKEN }}" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9c03dc8ff0..eec388924e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,16 +10,3 @@ repos: - id: check-added-large-files - id: no-commit-to-branch args: [ '--pattern', '^(?!((release|enhancement|feature|bugfix|documentation|tests|local|chore)\/[a-zA-Z0-9\-_]+)$).*' ] - -- repo: local - hooks: - - id: flake8 - name: flake8 - additional_dependencies: - - wemake-python-styleguide - - flake8 - description: Python style guide enforcement - entry: flake8 - args: ["--config=setup.cfg"] - language: python - types: [python] diff --git a/pyproject.toml b/pyproject.toml index 0d236aedc6..003f6cf2d3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -94,8 +94,6 @@ wheel = "*" enlighten = "*" # cool terminal progress bars toml = "^0.10.2" # for parsing pyproject.toml pre-commit = "*" -wemake-python-styleguide = "*" -isort="*" [tool.poetry.urls] "Bug Tracker" = "https://github.com/pypeclub/openpype/issues" From 3822b8e7f24bbe9754793c77ced8d152fb172a02 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Mon, 8 May 2023 16:29:32 +0800 Subject: [PATCH 41/78] refractor the render creator --- openpype/hosts/max/plugins/create/create_render.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/openpype/hosts/max/plugins/create/create_render.py b/openpype/hosts/max/plugins/create/create_render.py index e9952c3124..136ca028ac 100644 --- a/openpype/hosts/max/plugins/create/create_render.py +++ b/openpype/hosts/max/plugins/create/create_render.py @@ -22,13 +22,9 @@ class CreateRender(plugin.MaxCreator): container = rt.GetNodeByName(container_name) # TODO: Disable "Add to Containers?" Panel # parent the selected cameras into the container - sel_obj = None - if self.selected_nodes: - sel_obj = list(self.selected_nodes) - for obj in sel_obj: - obj.parent = container - - # set viewport camera for rendering(mandatory for deadline) - RenderSettings().set_render_camera(sel_obj) + sel_obj = self.selected_nodes + if sel_obj: + # set viewport camera for rendering(mandatory for deadline) + RenderSettings().set_render_camera(sel_obj) # set output paths for rendering(mandatory for deadline) RenderSettings().render_output(container_name) From d485fdbecf432f4097a48c91d6e242b94c80a9a1 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Mon, 8 May 2023 16:31:15 +0800 Subject: [PATCH 42/78] hound fix --- openpype/hosts/max/plugins/create/create_render.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openpype/hosts/max/plugins/create/create_render.py b/openpype/hosts/max/plugins/create/create_render.py index 136ca028ac..2ea993494b 100644 --- a/openpype/hosts/max/plugins/create/create_render.py +++ b/openpype/hosts/max/plugins/create/create_render.py @@ -19,7 +19,6 @@ class CreateRender(plugin.MaxCreator): instance_data, pre_create_data) container_name = instance.data.get("instance_node") - container = rt.GetNodeByName(container_name) # TODO: Disable "Add to Containers?" Panel # parent the selected cameras into the container sel_obj = self.selected_nodes From d6d022989f5c2e8897abd27c3d80b4b5a23b5e77 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Mon, 8 May 2023 16:32:52 +0800 Subject: [PATCH 43/78] hound fix --- openpype/hosts/max/plugins/create/create_render.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openpype/hosts/max/plugins/create/create_render.py b/openpype/hosts/max/plugins/create/create_render.py index 2ea993494b..9b677a615f 100644 --- a/openpype/hosts/max/plugins/create/create_render.py +++ b/openpype/hosts/max/plugins/create/create_render.py @@ -13,7 +13,6 @@ class CreateRender(plugin.MaxCreator): def create(self, subset_name, instance_data, pre_create_data): """Plugin entry point.""" - from pymxs import runtime as rt # noqa: WPS433,I001 instance = super().create( subset_name, instance_data, From 8830e63fb010d4cea374bdbbf095d81078e08ac2 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Tue, 9 May 2023 10:38:14 +0200 Subject: [PATCH 44/78] :recycle: add/delete action from container --- openpype/hosts/max/api/plugin.py | 37 ++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/max/api/plugin.py b/openpype/hosts/max/api/plugin.py index a464d54b33..8df620b913 100644 --- a/openpype/hosts/max/api/plugin.py +++ b/openpype/hosts/max/api/plugin.py @@ -22,7 +22,8 @@ MS_CUSTOM_ATTRIB = """attributes "openPypeData" rollout OPparams "OP Parameters" ( listbox list_node "Node References" items:#() - button button_add "Add Selection" + button button_add "Add to Container" + button button_del "Delete from Container" fn node_to_name the_node = ( @@ -34,8 +35,8 @@ MS_CUSTOM_ATTRIB = """attributes "openPypeData" on button_add pressed do ( - current_selection = selectByName title:"Select Objects To Add To - Container" buttontext:"Add" + current_selection = selectByName title:"Select Objects to add to + the Container" buttontext:"Add" temp_arr = #() i_node_arr = #() for c in current_selection do @@ -45,8 +46,33 @@ MS_CUSTOM_ATTRIB = """attributes "openPypeData" append temp_arr handle_name append i_node_arr node_ref ) - all_handles = i_node_arr - list_node.items = temp_arr + all_handles = join i_node_arr all_handles + list_node.items = join temp_arr list_node.items + ) + + on button_del pressed do + ( + current_selection = selectByName title:"Select Objects to remove + from the Container" buttontext:"Remove" + temp_arr = #() + i_node_arr = #() + for c in current_selection do + ( + node_ref = NodeTransformMonitor node:c + handle_name = node_to_name c + idx = finditem all_handles node_ref + if idx do + ( + DeleteItem all_nodes idx + ) + idx = finditem list_node.items handle_name + if idx do + ( + DeleteItem list_node.items idx + ) + ) + all_handles = join i_node_arr all_handles + list_node.items = join temp_arr list_node.items ) on OPparams open do @@ -56,7 +82,6 @@ MS_CUSTOM_ATTRIB = """attributes "openPypeData" temp_arr = #() for x in all_handles do ( - print(x.node) handle_name = node_to_name x.node append temp_arr handle_name ) From 564da974b19f0c16c88b540d0c1fd5cf7b5864cc Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 9 May 2023 21:47:04 +0800 Subject: [PATCH 45/78] add up-versioning to the max loader --- .../hosts/max/plugins/load/load_camera_fbx.py | 31 ++++++++++++++++--- .../hosts/max/plugins/load/load_model_fbx.py | 8 +++++ .../hosts/max/plugins/load/load_model_obj.py | 3 ++ .../hosts/max/plugins/load/load_pointcache.py | 22 ++++++++++--- .../hosts/max/plugins/load/load_pointcloud.py | 14 ++++++--- 5 files changed, 64 insertions(+), 14 deletions(-) diff --git a/openpype/hosts/max/plugins/load/load_camera_fbx.py b/openpype/hosts/max/plugins/load/load_camera_fbx.py index 3a6947798e..183a6f5d45 100644 --- a/openpype/hosts/max/plugins/load/load_camera_fbx.py +++ b/openpype/hosts/max/plugins/load/load_camera_fbx.py @@ -4,7 +4,7 @@ from openpype.pipeline import ( get_representation_path ) from openpype.hosts.max.api.pipeline import containerise -from openpype.hosts.max.api import lib +from openpype.hosts.max.api import lib, maintained_selection class FbxLoader(load.LoaderPlugin): @@ -36,7 +36,13 @@ importFile @"{filepath}" #noPrompt using:FBXIMP self.log.debug(f"Executing command: {fbx_import_cmd}") rt.execute(fbx_import_cmd) - container_name = f"{name}_CON" + # create "missing" container for obj import + container = rt.container() + container.name = f"{name}" + + # get current selection + for selection in rt.getCurrentSelection(): + selection.Parent = container asset = rt.getNodeByName(f"{name}") @@ -48,15 +54,30 @@ importFile @"{filepath}" #noPrompt using:FBXIMP path = get_representation_path(representation) node = rt.getNodeByName(container["instance_node"]) + rt.select(node.Children) + fbx_reimport_cmd = ( + f""" - fbx_objects = self.get_container_children(node) - for fbx_object in fbx_objects: - fbx_object.source = path +FBXImporterSetParam "Animation" true +FBXImporterSetParam "Cameras" true +FBXImporterSetParam "AxisConversionMethod" true +FbxExporterSetParam "UpAxis" "Y" +FbxExporterSetParam "Preserveinstances" true + +importFile @"{path}" #noPrompt using:FBXIMP + """) + rt.execute(fbx_reimport_cmd) + + with maintained_selection(): + rt.select(node) lib.imprint(container["instance_node"], { "representation": str(representation["_id"]) }) + def switch(self, container, representation): + self.update(container, representation) + def remove(self, container): from pymxs import runtime as rt diff --git a/openpype/hosts/max/plugins/load/load_model_fbx.py b/openpype/hosts/max/plugins/load/load_model_fbx.py index 88b8f1ed89..b8485ca333 100644 --- a/openpype/hosts/max/plugins/load/load_model_fbx.py +++ b/openpype/hosts/max/plugins/load/load_model_fbx.py @@ -37,6 +37,14 @@ importFile @"{filepath}" #noPrompt using:FBXIMP self.log.debug(f"Executing command: {fbx_import_cmd}") rt.execute(fbx_import_cmd) + # create "missing" container for obj import + container = rt.container() + container.name = f"{name}" + + # get current selection + for selection in rt.getCurrentSelection(): + selection.Parent = container + asset = rt.getNodeByName(f"{name}") return containerise( diff --git a/openpype/hosts/max/plugins/load/load_model_obj.py b/openpype/hosts/max/plugins/load/load_model_obj.py index c55e462111..ae42e1f3d3 100644 --- a/openpype/hosts/max/plugins/load/load_model_obj.py +++ b/openpype/hosts/max/plugins/load/load_model_obj.py @@ -61,6 +61,9 @@ class ObjLoader(load.LoaderPlugin): "representation": str(representation["_id"]) }) + def switch(self, container, representation): + self.update(container, representation) + def remove(self, container): from pymxs import runtime as rt diff --git a/openpype/hosts/max/plugins/load/load_pointcache.py b/openpype/hosts/max/plugins/load/load_pointcache.py index b3e12adc7b..2001b78aba 100644 --- a/openpype/hosts/max/plugins/load/load_pointcache.py +++ b/openpype/hosts/max/plugins/load/load_pointcache.py @@ -9,7 +9,7 @@ from openpype.pipeline import ( load, get_representation_path ) from openpype.hosts.max.api.pipeline import containerise -from openpype.hosts.max.api import lib +from openpype.hosts.max.api import lib, maintained_selection class AbcLoader(load.LoaderPlugin): @@ -65,14 +65,26 @@ importFile @"{file_path}" #noPrompt path = get_representation_path(representation) node = rt.getNodeByName(container["instance_node"]) - alembic_objects = self.get_container_children(node, "AlembicObject") - for alembic_object in alembic_objects: - alembic_object.source = path - lib.imprint(container["instance_node"], { "representation": str(representation["_id"]) }) + rt.select(node.Children) + + for alembic in rt.selection: + abc = rt.getNodeByName(alembic.name) + rt.select(abc.Children) + for abc_con in rt.selection: + container = rt.getNodeByName(abc_con.name) + container.source = path + rt.select(container.Children) + for abc_obj in rt.selection: + alembic_obj = rt.getNodeByName(abc_obj.name) + alembic_obj.source = path + + with maintained_selection(): + rt.select(node) + def switch(self, container, representation): self.update(container, representation) diff --git a/openpype/hosts/max/plugins/load/load_pointcloud.py b/openpype/hosts/max/plugins/load/load_pointcloud.py index 27bc88b4f3..d4ae721c8a 100644 --- a/openpype/hosts/max/plugins/load/load_pointcloud.py +++ b/openpype/hosts/max/plugins/load/load_pointcloud.py @@ -3,7 +3,7 @@ from openpype.pipeline import ( load, get_representation_path ) from openpype.hosts.max.api.pipeline import containerise -from openpype.hosts.max.api import lib +from openpype.hosts.max.api import lib, maintained_selection class PointCloudLoader(load.LoaderPlugin): @@ -34,15 +34,21 @@ class PointCloudLoader(load.LoaderPlugin): path = get_representation_path(representation) node = rt.getNodeByName(container["instance_node"]) + rt.select(node.Children) + for prt in rt.selection: + prt_object = rt.getNodeByName(prt.name) + prt_object.filename = path - prt_objects = self.get_container_children(node) - for prt_object in prt_objects: - prt_object.source = path + with maintained_selection(): + rt.select(node) lib.imprint(container["instance_node"], { "representation": str(representation["_id"]) }) + def switch(self, container, representation): + self.update(container, representation) + def remove(self, container): """remove the container""" from pymxs import runtime as rt From da56583d198002865bcd9530c7b209c5b56ad66e Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 9 May 2023 21:48:33 +0800 Subject: [PATCH 46/78] select the member data before exporting usd in the usd extractor --- openpype/hosts/max/plugins/publish/extract_model_usd.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openpype/hosts/max/plugins/publish/extract_model_usd.py b/openpype/hosts/max/plugins/publish/extract_model_usd.py index df1e7a4f02..2500e6c905 100644 --- a/openpype/hosts/max/plugins/publish/extract_model_usd.py +++ b/openpype/hosts/max/plugins/publish/extract_model_usd.py @@ -44,6 +44,7 @@ class ExtractModelUSD(publish.Extractor, with maintained_selection(): # select and export node_list = instance.data["members"] + rt.select(node_list) rt.USDExporter.ExportFile(asset_filepath, exportOptions=export_options, contentSource=rt.Name("selected"), From 33335a3e89c0c4d96af93c8983c29160f59a6135 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 9 May 2023 23:25:37 +0800 Subject: [PATCH 47/78] fix the update and load function of the max scene loader --- .../hosts/max/plugins/load/load_max_scene.py | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/openpype/hosts/max/plugins/load/load_max_scene.py b/openpype/hosts/max/plugins/load/load_max_scene.py index 4b19cd671f..cffc4ae559 100644 --- a/openpype/hosts/max/plugins/load/load_max_scene.py +++ b/openpype/hosts/max/plugins/load/load_max_scene.py @@ -26,20 +26,16 @@ class MaxSceneLoader(load.LoaderPlugin): merge_before = { c for c in rt.rootNode.Children - if rt.classOf(c) == rt.Container } rt.mergeMaxFile(path) merge_after = { c for c in rt.rootNode.Children - if rt.classOf(c) == rt.Container } - max_containers = merge_after.difference(merge_before) - - if len(max_containers) != 1: - self.log.error("Something failed when loading.") - - max_container = max_containers.pop() + max_objects = merge_after.difference(merge_before) + max_container = rt.container(name=f"{name}") + for max_object in max_objects: + max_object.Parent = max_container return containerise( name, [max_container], context, loader=self.__class__.__name__) @@ -48,15 +44,30 @@ class MaxSceneLoader(load.LoaderPlugin): from pymxs import runtime as rt path = get_representation_path(representation) - node = rt.getNodeByName(container["instance_node"]) - max_objects = node.Children + node_name = container["instance_node"] + instance_name, _ = node_name.split("_") + merge_before = { + c for c in rt.rootNode.Children + } + rt.mergeMaxFile(path, + rt.Name("noRedraw"), + rt.Name("deleteOldDups"), + rt.Name("useSceneMtlDups")) + merge_after = { + c for c in rt.rootNode.Children + } + max_objects = merge_after.difference(merge_before) + container_node = rt.getNodeByName(instance_name) for max_object in max_objects: - max_object.source = path + max_object.Parent = container_node lib.imprint(container["instance_node"], { "representation": str(representation["_id"]) }) + def switch(self, container, representation): + self.update(container, representation) + def remove(self, container): from pymxs import runtime as rt From afb6bd9ba53f6fb030eaed635ae18d456a04e0d5 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 23 May 2023 00:57:15 +0800 Subject: [PATCH 48/78] restore the code in abc extractor --- openpype/hosts/max/plugins/publish/extract_camera_abc.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/max/plugins/publish/extract_camera_abc.py b/openpype/hosts/max/plugins/publish/extract_camera_abc.py index 0a4f64508a..d53c47fb51 100644 --- a/openpype/hosts/max/plugins/publish/extract_camera_abc.py +++ b/openpype/hosts/max/plugins/publish/extract_camera_abc.py @@ -19,8 +19,8 @@ class ExtractCameraAlembic(publish.Extractor, OptionalPyblishPluginMixin): def process(self, instance): if not self.is_active(instance.data): return - start = float(instance.data.get("frameStart", 1)) - end = float(instance.data.get("frameEnd", 1)) + start = float(instance.data.get("frameStartHandle", 1)) + end = float(instance.data.get("frameEndHandle", 1)) container = instance.data["instance_node"] From 63d820436599fb7f3dfe54b6d86b58cbb1e35639 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 23 May 2023 15:46:16 +0800 Subject: [PATCH 49/78] Jakub's comment --- openpype/hosts/max/plugins/create/create_render.py | 2 +- openpype/hosts/max/plugins/publish/extract_pointcloud.py | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/openpype/hosts/max/plugins/create/create_render.py b/openpype/hosts/max/plugins/create/create_render.py index 9b677a615f..4523d3d411 100644 --- a/openpype/hosts/max/plugins/create/create_render.py +++ b/openpype/hosts/max/plugins/create/create_render.py @@ -23,6 +23,6 @@ class CreateRender(plugin.MaxCreator): sel_obj = self.selected_nodes if sel_obj: # set viewport camera for rendering(mandatory for deadline) - RenderSettings().set_render_camera(sel_obj) + RenderSettings(self.project_settings).set_render_camera(sel_obj) # set output paths for rendering(mandatory for deadline) RenderSettings().render_output(container_name) diff --git a/openpype/hosts/max/plugins/publish/extract_pointcloud.py b/openpype/hosts/max/plugins/publish/extract_pointcloud.py index c807885859..9e1e7fdc72 100644 --- a/openpype/hosts/max/plugins/publish/extract_pointcloud.py +++ b/openpype/hosts/max/plugins/publish/extract_pointcloud.py @@ -5,7 +5,6 @@ from pymxs import runtime as rt from openpype.hosts.max.api import ( maintained_selection ) -from openpype.settings import get_project_settings class ExtractPointCloud(publish.Extractor): @@ -148,9 +147,7 @@ class ExtractPointCloud(publish.Extractor): @staticmethod def get_setting(instance): - project_setting = get_project_settings( - instance.context.data["projectName"] - ) + project_setting = instance.context.data["project_settings"] return project_setting["max"]["PointCloud"] def get_custom_attr(self, operator): From 8ac4cb499e9106c6f08b5beb2e933102a6b3ca3e Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Tue, 23 May 2023 15:50:07 +0200 Subject: [PATCH 50/78] :rotating_light: style changes --- openpype/hosts/max/api/lib.py | 20 ++- openpype/hosts/max/api/plugin.py | 52 ++++--- .../hosts/max/plugins/create/create_render.py | 5 +- .../hosts/max/plugins/load/load_camera_fbx.py | 30 ++-- .../hosts/max/plugins/load/load_max_scene.py | 37 ++--- openpype/hosts/max/plugins/load/load_model.py | 45 +++--- .../hosts/max/plugins/load/load_model_fbx.py | 34 ++-- .../hosts/max/plugins/load/load_model_obj.py | 40 +++-- .../hosts/max/plugins/load/load_model_usd.py | 28 ++-- .../hosts/max/plugins/load/load_pointcache.py | 52 +++---- .../hosts/max/plugins/load/load_pointcloud.py | 33 ++-- .../max/plugins/publish/collect_members.py | 7 +- .../max/plugins/publish/extract_camera_abc.py | 24 +-- .../max/plugins/publish/extract_camera_fbx.py | 22 ++- .../max/plugins/publish/extract_model_usd.py | 17 +- .../max/plugins/publish/extract_pointcloud.py | 13 +- .../publish/validate_model_contents.py | 3 +- poetry.lock | 24 +-- setup.cfg | 146 +----------------- 19 files changed, 221 insertions(+), 411 deletions(-) diff --git a/openpype/hosts/max/api/lib.py b/openpype/hosts/max/api/lib.py index 132896805f..5718d8f112 100644 --- a/openpype/hosts/max/api/lib.py +++ b/openpype/hosts/max/api/lib.py @@ -1,16 +1,13 @@ # -*- coding: utf-8 -*- """Library of functions useful for 3dsmax pipeline.""" -import json -import six -from pymxs import runtime as rt -from typing import Union, Any, Dict import contextlib +import json +from typing import Any, Dict, Union +import six from openpype.pipeline.context_tools import ( - get_current_project_asset, - get_current_project -) - + get_current_project, get_current_project_asset,) +from pymxs import runtime as rt JSON_PREFIX = "JSON::" @@ -22,7 +19,7 @@ def imprint(node_name: str, data: dict) -> bool: for k, v in data.items(): if isinstance(v, (dict, list)): - rt.SetUserProp(node, k, f'{JSON_PREFIX}{json.dumps(v)}') + rt.SetUserProp(node, k, f"{JSON_PREFIX}{json.dumps(v)}") else: rt.SetUserProp(node, k, v) @@ -171,7 +168,7 @@ def set_scene_resolution(width: int, height: int): """ # make sure the render dialog is closed # for the update of resolution - # Changing the Render Setup dialog settingsshould be done + # Changing the Render Setup dialog settings should be done # with the actual Render Setup dialog in a closed state. if rt.renderSceneDialog.isOpen(): rt.renderSceneDialog.close() @@ -179,6 +176,7 @@ def set_scene_resolution(width: int, height: int): rt.renderWidth = width rt.renderHeight = height + def reset_scene_resolution(): """Apply the scene resolution from the project definition @@ -248,7 +246,7 @@ def reset_frame_range(fps: bool = True): frange_cmd = ( f"animationRange = interval {frame_start_handle} {frame_end_handle}" ) - rt.execute(frange_cmd) + rt.Execute(frange_cmd) set_render_frame_range(frame_start_handle, frame_end_handle) diff --git a/openpype/hosts/max/api/plugin.py b/openpype/hosts/max/api/plugin.py index 8df620b913..583e9dc1fb 100644 --- a/openpype/hosts/max/api/plugin.py +++ b/openpype/hosts/max/api/plugin.py @@ -1,16 +1,14 @@ # -*- coding: utf-8 -*- """3dsmax specific Avalon/Pyblish plugin definitions.""" -from pymxs import runtime as rt -from typing import Union -import six from abc import ABCMeta -from openpype.pipeline import ( - CreatorError, - Creator, - CreatedInstance -) + +import six +from pymxs import runtime as rt + from openpype.lib import BoolDef -from .lib import imprint, read, lsattr +from openpype.pipeline import CreatedInstance, Creator, CreatorError + +from .lib import imprint, lsattr, read MS_CUSTOM_ATTRIB = """attributes "openPypeData" ( @@ -100,17 +98,18 @@ class MaxCreatorBase(object): @staticmethod def cache_subsets(shared_data): - if shared_data.get("max_cached_subsets") is None: - shared_data["max_cached_subsets"] = {} - cached_instances = lsattr("id", "pyblish.avalon.instance") - for i in cached_instances: - creator_id = rt.getUserProp(i, "creator_identifier") - if creator_id not in shared_data["max_cached_subsets"]: - shared_data["max_cached_subsets"][creator_id] = [i.name] - else: - shared_data[ - "max_cached_subsets"][creator_id].append( - i.name) # noqa + if shared_data.get("max_cached_subsets"): + return shared_data + + shared_data["max_cached_subsets"] = {} + cached_instances = lsattr("id", "pyblish.avalon.instance") + for i in cached_instances: + creator_id = rt.GetUserProp(i, "creator_identifier") + if creator_id not in shared_data["max_cached_subsets"]: + shared_data["max_cached_subsets"][creator_id] = [i.name] + else: + shared_data[ + "max_cached_subsets"][creator_id].append(i.name) return shared_data @staticmethod @@ -127,9 +126,9 @@ class MaxCreatorBase(object): instance """ if isinstance(node, str): - node = rt.container(name=node) + node = rt.Container(name=node) - attrs = rt.execute(MS_CUSTOM_ATTRIB) + attrs = rt.Execute(MS_CUSTOM_ATTRIB) rt.custAttributes.add(node.baseObject, attrs) return node @@ -141,7 +140,7 @@ class MaxCreator(Creator, MaxCreatorBase): def create(self, subset_name, instance_data, pre_create_data): if pre_create_data.get("use_selection"): - self.selected_nodes = rt.getCurrentSelection() + self.selected_nodes = rt.GetCurrentSelection() instance_node = self.create_instance_node(subset_name) instance_data["instance_node"] = instance_node.name @@ -196,9 +195,12 @@ class MaxCreator(Creator, MaxCreatorBase): """ for instance in instances: - if instance_node := rt.GetNodeByName(instance.data.get("instance_node")): # noqa + if instance_node := rt.GetNodeByName( + instance.data.get("instance_node")): rt.Select(instance_node) - rt.execute(f'for o in selection do for c in o.children do c.parent = undefined') # noqa + rt.Execute( + ("for o in selection do " + "for c in o.children do c.parent = undefined")) rt.Delete(instance_node) self._remove_instance_from_context(instance) diff --git a/openpype/hosts/max/plugins/create/create_render.py b/openpype/hosts/max/plugins/create/create_render.py index 4523d3d411..5b35453579 100644 --- a/openpype/hosts/max/plugins/create/create_render.py +++ b/openpype/hosts/max/plugins/create/create_render.py @@ -18,10 +18,7 @@ class CreateRender(plugin.MaxCreator): instance_data, pre_create_data) container_name = instance.data.get("instance_node") - # TODO: Disable "Add to Containers?" Panel - # parent the selected cameras into the container - sel_obj = self.selected_nodes - if sel_obj: + if sel_obj := self.selected_nodes: # set viewport camera for rendering(mandatory for deadline) RenderSettings(self.project_settings).set_render_camera(sel_obj) # set output paths for rendering(mandatory for deadline) diff --git a/openpype/hosts/max/plugins/load/load_camera_fbx.py b/openpype/hosts/max/plugins/load/load_camera_fbx.py index 35d7f4bad2..c51900dbb7 100644 --- a/openpype/hosts/max/plugins/load/load_camera_fbx.py +++ b/openpype/hosts/max/plugins/load/load_camera_fbx.py @@ -1,14 +1,12 @@ import os -from openpype.pipeline import ( - load, - get_representation_path -) -from openpype.hosts.max.api.pipeline import containerise + from openpype.hosts.max.api import lib, maintained_selection +from openpype.hosts.max.api.pipeline import containerise +from openpype.pipeline import get_representation_path, load class FbxLoader(load.LoaderPlugin): - """Fbx Loader""" + """Fbx Loader.""" families = ["camera"] representations = ["fbx"] @@ -24,17 +22,17 @@ class FbxLoader(load.LoaderPlugin): rt.FBXImporterSetParam("Camera", True) rt.FBXImporterSetParam("AxisConversionMethod", True) rt.FBXImporterSetParam("Preserveinstances", True) - rt.importFile( + rt.ImportFile( filepath, rt.name("noPrompt"), using=rt.FBXIMP) - container = rt.getNodeByName(f"{name}") + container = rt.GetNodeByName(f"{name}") if not container: - container = rt.container() + container = rt.Container() container.name = f"{name}" - for selection in rt.getCurrentSelection(): + for selection in rt.GetCurrentSelection(): selection.Parent = container return containerise( @@ -44,8 +42,8 @@ class FbxLoader(load.LoaderPlugin): from pymxs import runtime as rt path = get_representation_path(representation) - node = rt.getNodeByName(container["instance_node"]) - rt.select(node.Children) + node = rt.GetNodeByName(container["instance_node"]) + rt.Select(node.Children) fbx_reimport_cmd = ( f""" @@ -57,10 +55,10 @@ FbxExporterSetParam "Preserveinstances" true importFile @"{path}" #noPrompt using:FBXIMP """) - rt.execute(fbx_reimport_cmd) + rt.Execute(fbx_reimport_cmd) with maintained_selection(): - rt.select(node) + rt.Select(node) lib.imprint(container["instance_node"], { "representation": str(representation["_id"]) @@ -72,5 +70,5 @@ importFile @"{path}" #noPrompt using:FBXIMP def remove(self, container): from pymxs import runtime as rt - node = rt.getNodeByName(container["instance_node"]) - rt.delete(node) + node = rt.GetNodeByName(container["instance_node"]) + rt.Delete(node) diff --git a/openpype/hosts/max/plugins/load/load_max_scene.py b/openpype/hosts/max/plugins/load/load_max_scene.py index cffc4ae559..4d9367b16f 100644 --- a/openpype/hosts/max/plugins/load/load_max_scene.py +++ b/openpype/hosts/max/plugins/load/load_max_scene.py @@ -1,13 +1,12 @@ import os -from openpype.pipeline import ( - load, get_representation_path -) -from openpype.hosts.max.api.pipeline import containerise + from openpype.hosts.max.api import lib +from openpype.hosts.max.api.pipeline import containerise +from openpype.pipeline import get_representation_path, load class MaxSceneLoader(load.LoaderPlugin): - """Max Scene Loader""" + """Max Scene Loader.""" families = ["camera", "maxScene", @@ -24,16 +23,12 @@ class MaxSceneLoader(load.LoaderPlugin): # import the max scene by using "merge file" path = path.replace('\\', '/') - merge_before = { - c for c in rt.rootNode.Children - } - rt.mergeMaxFile(path) + merge_before = set(rt.RootNode.Children) + rt.MergeMaxFile(path) - merge_after = { - c for c in rt.rootNode.Children - } + merge_after = set(rt.RootNode.Children) max_objects = merge_after.difference(merge_before) - max_container = rt.container(name=f"{name}") + max_container = rt.Container(name=f"{name}") for max_object in max_objects: max_object.Parent = max_container @@ -46,18 +41,14 @@ class MaxSceneLoader(load.LoaderPlugin): path = get_representation_path(representation) node_name = container["instance_node"] instance_name, _ = node_name.split("_") - merge_before = { - c for c in rt.rootNode.Children - } - rt.mergeMaxFile(path, + merge_before = set(rt.RootNode.Children) + rt.MergeMaxFile(path, rt.Name("noRedraw"), rt.Name("deleteOldDups"), rt.Name("useSceneMtlDups")) - merge_after = { - c for c in rt.rootNode.Children - } + merge_after = set(rt.EootNode.Children) max_objects = merge_after.difference(merge_before) - container_node = rt.getNodeByName(instance_name) + container_node = rt.GetNodeByName(instance_name) for max_object in max_objects: max_object.Parent = container_node @@ -71,5 +62,5 @@ class MaxSceneLoader(load.LoaderPlugin): def remove(self, container): from pymxs import runtime as rt - node = rt.getNodeByName(container["instance_node"]) - rt.delete(node) + node = rt.GetNodeByName(container["instance_node"]) + rt.Delete(node) diff --git a/openpype/hosts/max/plugins/load/load_model.py b/openpype/hosts/max/plugins/load/load_model.py index 95ee014e07..662b9fcb87 100644 --- a/openpype/hosts/max/plugins/load/load_model.py +++ b/openpype/hosts/max/plugins/load/load_model.py @@ -1,11 +1,10 @@ import os -from openpype.pipeline import ( - load, get_representation_path -) -from openpype.hosts.max.api.pipeline import containerise + from openpype.hosts.max.api import lib from openpype.hosts.max.api.lib import maintained_selection +from openpype.hosts.max.api.pipeline import containerise +from openpype.pipeline import get_representation_path, load class ModelAbcLoader(load.LoaderPlugin): @@ -24,8 +23,8 @@ class ModelAbcLoader(load.LoaderPlugin): file_path = os.path.normpath(self.fname) abc_before = { - c for c in rt.rootNode.Children - if rt.classOf(c) == rt.AlembicContainer + c for c in rt.RootNode.Children + if rt.ClassOf(c) == rt.AlembicContainer } abc_import_cmd = (f""" @@ -38,11 +37,11 @@ importFile @"{file_path}" #noPrompt """) self.log.debug(f"Executing command: {abc_import_cmd}") - rt.execute(abc_import_cmd) + rt.Execute(abc_import_cmd) abc_after = { - c for c in rt.rootNode.Children - if rt.classOf(c) == rt.AlembicContainer + c for c in rt.RootNode.Children + if rt.ClassOf(c) == rt.AlembicContainer } # This should yield new AlembicContainer node @@ -59,22 +58,22 @@ importFile @"{file_path}" #noPrompt def update(self, container, representation): from pymxs import runtime as rt path = get_representation_path(representation) - node = rt.getNodeByName(container["instance_node"]) - rt.select(node.Children) + node = rt.GetNodeByName(container["instance_node"]) + rt.Select(node.Children) - for alembic in rt.selection: - abc = rt.getNodeByName(alembic.name) - rt.select(abc.Children) - for abc_con in rt.selection: - container = rt.getNodeByName(abc_con.name) + for alembic in rt.Selection: + abc = rt.GetNodeByName(alembic.name) + rt.Select(abc.Children) + for abc_con in rt.Selection: + container = rt.GetNodeByName(abc_con.name) container.source = path - rt.select(container.Children) - for abc_obj in rt.selection: - alembic_obj = rt.getNodeByName(abc_obj.name) + rt.Select(container.Children) + for abc_obj in rt.Selection: + alembic_obj = rt.GetNodeByName(abc_obj.name) alembic_obj.source = path with maintained_selection(): - rt.select(node) + rt.Select(node) lib.imprint(container["instance_node"], { "representation": str(representation["_id"]) @@ -86,8 +85,8 @@ importFile @"{file_path}" #noPrompt def remove(self, container): from pymxs import runtime as rt - node = rt.getNodeByName(container["instance_node"]) - rt.delete(node) + node = rt.GetNodeByName(container["instance_node"]) + rt.Delete(node) @staticmethod def get_container_children(parent, type_name): @@ -102,7 +101,7 @@ importFile @"{file_path}" #noPrompt filtered = [] for child in list_children(parent): - class_type = str(rt.classOf(child.baseObject)) + class_type = str(rt.ClassOf(child.baseObject)) if class_type == type_name: filtered.append(child) diff --git a/openpype/hosts/max/plugins/load/load_model_fbx.py b/openpype/hosts/max/plugins/load/load_model_fbx.py index 01e6acae12..2aef6f02c2 100644 --- a/openpype/hosts/max/plugins/load/load_model_fbx.py +++ b/openpype/hosts/max/plugins/load/load_model_fbx.py @@ -1,15 +1,13 @@ import os -from openpype.pipeline import ( - load, - get_representation_path -) -from openpype.hosts.max.api.pipeline import containerise + from openpype.hosts.max.api import lib from openpype.hosts.max.api.lib import maintained_selection +from openpype.hosts.max.api.pipeline import containerise +from openpype.pipeline import get_representation_path, load class FbxModelLoader(load.LoaderPlugin): - """Fbx Model Loader""" + """Fbx Model Loader.""" families = ["model"] representations = ["fbx"] @@ -24,17 +22,17 @@ class FbxModelLoader(load.LoaderPlugin): rt.FBXImporterSetParam("Animation", False) rt.FBXImporterSetParam("Cameras", False) rt.FBXImporterSetParam("Preserveinstances", True) - rt.importFile( + rt.ImportFile( filepath, - rt.name("noPrompt"), + rt.Name("noPrompt"), using=rt.FBXIMP) - container = rt.getNodeByName(f"{name}") + container = rt.GetNodeByName(name) if not container: - container = rt.container() - container.name = f"{name}" + container = rt.Container() + container.name = name - for selection in rt.getCurrentSelection(): + for selection in rt.GetCurrentSelection(): selection.Parent = container return containerise( @@ -44,8 +42,8 @@ class FbxModelLoader(load.LoaderPlugin): from pymxs import runtime as rt path = get_representation_path(representation) - node = rt.getNodeByName(container["instance_node"]) - rt.select(node.Children) + node = rt.GetNodeByName(container["instance_node"]) + rt.Select(node.Children) fbx_reimport_cmd = ( f""" FBXImporterSetParam "Animation" false @@ -56,10 +54,10 @@ FbxExporterSetParam "Preserveinstances" true importFile @"{path}" #noPrompt using:FBXIMP """) - rt.execute(fbx_reimport_cmd) + rt.Execute(fbx_reimport_cmd) with maintained_selection(): - rt.select(node) + rt.Select(node) lib.imprint(container["instance_node"], { "representation": str(representation["_id"]) @@ -71,5 +69,5 @@ importFile @"{path}" #noPrompt using:FBXIMP def remove(self, container): from pymxs import runtime as rt - node = rt.getNodeByName(container["instance_node"]) - rt.delete(node) + node = rt.GetNodeByName(container["instance_node"]) + rt.Delete(node) diff --git a/openpype/hosts/max/plugins/load/load_model_obj.py b/openpype/hosts/max/plugins/load/load_model_obj.py index ae42e1f3d3..77d4e08cfb 100644 --- a/openpype/hosts/max/plugins/load/load_model_obj.py +++ b/openpype/hosts/max/plugins/load/load_model_obj.py @@ -1,15 +1,13 @@ import os -from openpype.pipeline import ( - load, - get_representation_path -) -from openpype.hosts.max.api.pipeline import containerise + from openpype.hosts.max.api import lib from openpype.hosts.max.api.lib import maintained_selection +from openpype.hosts.max.api.pipeline import containerise +from openpype.pipeline import get_representation_path, load class ObjLoader(load.LoaderPlugin): - """Obj Loader""" + """Obj Loader.""" families = ["model"] representations = ["obj"] @@ -21,18 +19,18 @@ class ObjLoader(load.LoaderPlugin): from pymxs import runtime as rt filepath = os.path.normpath(self.fname) - self.log.debug(f"Executing command to import..") + self.log.debug("Executing command to import..") - rt.execute(f'importFile @"{filepath}" #noPrompt using:ObjImp') + rt.Execute(f'importFile @"{filepath}" #noPrompt using:ObjImp') # create "missing" container for obj import - container = rt.container() - container.name = f"{name}" + container = rt.Container() + container.name = name # get current selection - for selection in rt.getCurrentSelection(): + for selection in rt.GetCurrentSelection(): selection.Parent = container - asset = rt.getNodeByName(f"{name}") + asset = rt.GetNodeByName(name) return containerise( name, [asset], context, loader=self.__class__.__name__) @@ -42,20 +40,20 @@ class ObjLoader(load.LoaderPlugin): path = get_representation_path(representation) node_name = container["instance_node"] - node = rt.getNodeByName(node_name) + node = rt.GetNodeByName(node_name) instance_name, _ = node_name.split("_") - container = rt.getNodeByName(instance_name) - for n in container.Children: - rt.delete(n) + container = rt.GetNodeByName(instance_name) + for child in container.Children: + rt.Delete(child) - rt.execute(f'importFile @"{path}" #noPrompt using:ObjImp') + rt.Execute(f'importFile @"{path}" #noPrompt using:ObjImp') # get current selection - for selection in rt.getCurrentSelection(): + for selection in rt.GetCurrentSelection(): selection.Parent = container with maintained_selection(): - rt.select(node) + rt.Select(node) lib.imprint(node_name, { "representation": str(representation["_id"]) @@ -67,5 +65,5 @@ class ObjLoader(load.LoaderPlugin): def remove(self, container): from pymxs import runtime as rt - node = rt.getNodeByName(container["instance_node"]) - rt.delete(node) + node = rt.GetNodeByName(container["instance_node"]) + rt.Delete(node) diff --git a/openpype/hosts/max/plugins/load/load_model_usd.py b/openpype/hosts/max/plugins/load/load_model_usd.py index 143f91f40b..2b34669278 100644 --- a/openpype/hosts/max/plugins/load/load_model_usd.py +++ b/openpype/hosts/max/plugins/load/load_model_usd.py @@ -1,10 +1,9 @@ import os -from openpype.pipeline import ( - load, get_representation_path -) -from openpype.hosts.max.api.pipeline import containerise + from openpype.hosts.max.api import lib from openpype.hosts.max.api.lib import maintained_selection +from openpype.hosts.max.api.pipeline import containerise +from openpype.pipeline import get_representation_path, load class ModelUSDLoader(load.LoaderPlugin): @@ -19,6 +18,7 @@ class ModelUSDLoader(load.LoaderPlugin): def load(self, context, name=None, namespace=None, data=None): from pymxs import runtime as rt + # asset_filepath filepath = os.path.normpath(self.fname) import_options = rt.USDImporter.CreateOptions() @@ -27,11 +27,11 @@ class ModelUSDLoader(load.LoaderPlugin): log_filepath = filepath.replace(ext, "txt") rt.LogPath = log_filepath - rt.LogLevel = rt.name('info') + rt.LogLevel = rt.Name("info") rt.USDImporter.importFile(filepath, importOptions=import_options) - asset = rt.getNodeByName(f"{name}") + asset = rt.GetNodeByName(name) return containerise( name, [asset], context, loader=self.__class__.__name__) @@ -41,11 +41,11 @@ class ModelUSDLoader(load.LoaderPlugin): path = get_representation_path(representation) node_name = container["instance_node"] - node = rt.getNodeByName(node_name) + node = rt.GetNodeByName(node_name) for n in node.Children: for r in n.Children: - rt.delete(r) - rt.delete(n) + rt.Delete(r) + rt.Delete(n) instance_name, _ = node_name.split("_") import_options = rt.USDImporter.CreateOptions() @@ -54,15 +54,15 @@ class ModelUSDLoader(load.LoaderPlugin): log_filepath = path.replace(ext, "txt") rt.LogPath = log_filepath - rt.LogLevel = rt.name('info') + rt.LogLevel = rt.Name("info") rt.USDImporter.importFile(path, importOptions=import_options) - asset = rt.getNodeByName(f"{instance_name}") + asset = rt.GetNodeByName(instance_name) asset.Parent = node with maintained_selection(): - rt.select(node) + rt.Select(node) lib.imprint(node_name, { "representation": str(representation["_id"]) @@ -74,5 +74,5 @@ class ModelUSDLoader(load.LoaderPlugin): def remove(self, container): from pymxs import runtime as rt - node = rt.getNodeByName(container["instance_node"]) - rt.delete(node) + node = rt.GetNodeByName(container["instance_node"]) + rt.Delete(node) diff --git a/openpype/hosts/max/plugins/load/load_pointcache.py b/openpype/hosts/max/plugins/load/load_pointcache.py index 37cb6791db..4f7773d967 100644 --- a/openpype/hosts/max/plugins/load/load_pointcache.py +++ b/openpype/hosts/max/plugins/load/load_pointcache.py @@ -5,11 +5,10 @@ Because of limited api, alembics can be only loaded, but not easily updated. """ import os -from openpype.pipeline import ( - load, get_representation_path -) -from openpype.hosts.max.api.pipeline import containerise + from openpype.hosts.max.api import lib, maintained_selection +from openpype.hosts.max.api.pipeline import containerise +from openpype.pipeline import get_representation_path, load class AbcLoader(load.LoaderPlugin): @@ -30,29 +29,28 @@ class AbcLoader(load.LoaderPlugin): file_path = os.path.normpath(self.fname) abc_before = { - c for c in rt.rootNode.Children - if rt.classOf(c) == rt.AlembicContainer + c for c in rt.RootNode.Children + if rt.ClassOf(c) == rt.AlembicContainer } rt.AlembicImport.ImportToRoot = False rt.AlembicImport.StartFrame = True rt.AlembicImport.EndFrame = True - rt.importFile(file_path, rt.name("noPrompt")) + rt.ImportFile(file_path, rt.Name("noPrompt")) abc_after = { - c for c in rt.rootNode.Children - if rt.classOf(c) == rt.AlembicContainer + c for c in rt.RootNode.Children + if rt.ClassOf(c) == rt.AlembicContainer } # This should yield new AlembicContainer node abc_containers = abc_after.difference(abc_before) - if len(abc_containers) != 1: self.log.error("Something failed when loading.") abc_container = abc_containers.pop() - for abc in rt.getCurrentSelection(): + for abc in rt.GetCurrentSelection(): for cam_shape in abc.Children: cam_shape.playbackType = 2 @@ -63,27 +61,25 @@ class AbcLoader(load.LoaderPlugin): from pymxs import runtime as rt path = get_representation_path(representation) - node = rt.getNodeByName(container["instance_node"]) + node = rt.GetNodeByName(container["instance_node"]) lib.imprint(container["instance_node"], { "representation": str(representation["_id"]) }) - rt.select(node.Children) - - for alembic in rt.selection: - abc = rt.getNodeByName(alembic.name) - rt.select(abc.Children) - for abc_con in rt.selection: - container = rt.getNodeByName(abc_con.name) - container.source = path - rt.select(container.Children) - for abc_obj in rt.selection: - alembic_obj = rt.getNodeByName(abc_obj.name) - alembic_obj.source = path - with maintained_selection(): - rt.select(node) + rt.Select(node.Children) + + for alembic in rt.Selection: + abc = rt.GetNodeByName(alembic.name) + rt.Select(abc.Children) + for abc_con in rt.Selection: + container = rt.GetNodeByName(abc_con.name) + container.source = path + rt.Select(container.Children) + for abc_obj in rt.Selection: + alembic_obj = rt.GetNodeByName(abc_obj.name) + alembic_obj.source = path def switch(self, container, representation): self.update(container, representation) @@ -91,8 +87,8 @@ class AbcLoader(load.LoaderPlugin): def remove(self, container): from pymxs import runtime as rt - node = rt.getNodeByName(container["instance_node"]) - rt.delete(node) + node = rt.GetNodeByName(container["instance_node"]) + rt.Delete(node) @staticmethod def get_container_children(parent, type_name): diff --git a/openpype/hosts/max/plugins/load/load_pointcloud.py b/openpype/hosts/max/plugins/load/load_pointcloud.py index d4ae721c8a..8634e1d51f 100644 --- a/openpype/hosts/max/plugins/load/load_pointcloud.py +++ b/openpype/hosts/max/plugins/load/load_pointcloud.py @@ -1,13 +1,12 @@ import os -from openpype.pipeline import ( - load, get_representation_path -) -from openpype.hosts.max.api.pipeline import containerise + from openpype.hosts.max.api import lib, maintained_selection +from openpype.hosts.max.api.pipeline import containerise +from openpype.pipeline import get_representation_path, load class PointCloudLoader(load.LoaderPlugin): - """Point Cloud Loader""" + """Point Cloud Loader.""" families = ["pointcloud"] representations = ["prt"] @@ -23,7 +22,7 @@ class PointCloudLoader(load.LoaderPlugin): obj = rt.tyCache() obj.filename = filepath - prt_container = rt.getNodeByName(f"{obj.name}") + prt_container = rt.GetNodeByName(obj.name) return containerise( name, [prt_container], context, loader=self.__class__.__name__) @@ -33,18 +32,16 @@ class PointCloudLoader(load.LoaderPlugin): from pymxs import runtime as rt path = get_representation_path(representation) - node = rt.getNodeByName(container["instance_node"]) - rt.select(node.Children) - for prt in rt.selection: - prt_object = rt.getNodeByName(prt.name) - prt_object.filename = path - + node = rt.GetNodeByName(container["instance_node"]) with maintained_selection(): - rt.select(node) + rt.Select(node.Children) + for prt in rt.Selection: + prt_object = rt.GetNodeByName(prt.name) + prt_object.filename = path - lib.imprint(container["instance_node"], { - "representation": str(representation["_id"]) - }) + lib.imprint(container["instance_node"], { + "representation": str(representation["_id"]) + }) def switch(self, container, representation): self.update(container, representation) @@ -53,5 +50,5 @@ class PointCloudLoader(load.LoaderPlugin): """remove the container""" from pymxs import runtime as rt - node = rt.getNodeByName(container["instance_node"]) - rt.delete(node) + node = rt.GetNodeByName(container["instance_node"]) + rt.Delete(node) diff --git a/openpype/hosts/max/plugins/publish/collect_members.py b/openpype/hosts/max/plugins/publish/collect_members.py index 4ceb6cdadf..54020d7dae 100644 --- a/openpype/hosts/max/plugins/publish/collect_members.py +++ b/openpype/hosts/max/plugins/publish/collect_members.py @@ -1,11 +1,11 @@ # -*- coding: utf-8 -*- -"""Collect instance members""" +"""Collect instance members.""" import pyblish.api from pymxs import runtime as rt class CollectMembers(pyblish.api.InstancePlugin): - """Collect Render for Deadline""" + """Collect Render for Deadline.""" order = pyblish.api.CollectorOrder + 0.01 label = "Collect Instance Members" @@ -16,5 +16,6 @@ class CollectMembers(pyblish.api.InstancePlugin): if instance.data.get("instance_node"): container = rt.GetNodeByName(instance.data["instance_node"]) instance.data["members"] = [ - i.node for i in container.openPypeData.all_handles + member.node for member + in container.openPypeData.all_handles ] diff --git a/openpype/hosts/max/plugins/publish/extract_camera_abc.py b/openpype/hosts/max/plugins/publish/extract_camera_abc.py index d53c47fb51..c526de8960 100644 --- a/openpype/hosts/max/plugins/publish/extract_camera_abc.py +++ b/openpype/hosts/max/plugins/publish/extract_camera_abc.py @@ -1,14 +1,14 @@ import os + import pyblish.api -from openpype.pipeline import publish, OptionalPyblishPluginMixin from pymxs import runtime as rt -from openpype.hosts.max.api import maintained_selection, get_all_children + +from openpype.hosts.max.api import get_all_children, maintained_selection +from openpype.pipeline import OptionalPyblishPluginMixin, publish class ExtractCameraAlembic(publish.Extractor, OptionalPyblishPluginMixin): - """ - Extract Camera with AlembicExport - """ + """Extract Camera with AlembicExport.""" order = pyblish.api.ExtractorOrder - 0.1 label = "Extract Alembic Camera" @@ -31,20 +31,20 @@ class ExtractCameraAlembic(publish.Extractor, OptionalPyblishPluginMixin): path = os.path.join(stagingdir, filename) # We run the render - self.log.info("Writing alembic '%s' to '%s'" % (filename, stagingdir)) + self.log.info(f"Writing alembic '{filename}' to '{stagingdir}'") - rt.AlembicExport.ArchiveType = rt.name("ogawa") - rt.AlembicExport.CoordinateSystem = rt.name("maya") + rt.AlembicExport.ArchiveType = rt.Name("ogawa") + rt.AlembicExport.CoordinateSystem = rt.Name("maya") rt.AlembicExport.StartFrame = start rt.AlembicExport.EndFrame = end rt.AlembicExport.CustomAttributes = True with maintained_selection(): # select and export - rt.select(get_all_children(rt.getNodeByName(container))) - rt.exportFile( + rt.Select(get_all_children(rt.GetNodeByName(container))) + rt.ExportFile( path, - rt.name("noPrompt"), + rt.Name("noPrompt"), selectedOnly=True, using=rt.AlembicExport, ) @@ -62,4 +62,4 @@ class ExtractCameraAlembic(publish.Extractor, OptionalPyblishPluginMixin): "frameEnd": end, } instance.data["representations"].append(representation) - self.log.info("Extracted instance '%s' to: %s" % (instance.name, path)) + self.log.info(f"Extracted instance '{instance.name}' to: {path}") diff --git a/openpype/hosts/max/plugins/publish/extract_camera_fbx.py b/openpype/hosts/max/plugins/publish/extract_camera_fbx.py index 4b4b349e19..0c8a82dcaa 100644 --- a/openpype/hosts/max/plugins/publish/extract_camera_fbx.py +++ b/openpype/hosts/max/plugins/publish/extract_camera_fbx.py @@ -1,14 +1,14 @@ import os + import pyblish.api -from openpype.pipeline import publish, OptionalPyblishPluginMixin from pymxs import runtime as rt -from openpype.hosts.max.api import maintained_selection, get_all_children + +from openpype.hosts.max.api import get_all_children, maintained_selection +from openpype.pipeline import OptionalPyblishPluginMixin, publish class ExtractCameraFbx(publish.Extractor, OptionalPyblishPluginMixin): - """ - Extract Camera with FbxExporter - """ + """Extract Camera with FbxExporter.""" order = pyblish.api.ExtractorOrder - 0.2 label = "Extract Fbx Camera" @@ -26,7 +26,7 @@ class ExtractCameraFbx(publish.Extractor, OptionalPyblishPluginMixin): filename = "{name}.fbx".format(**instance.data) filepath = os.path.join(stagingdir, filename) - self.log.info("Writing fbx file '%s' to '%s'" % (filename, filepath)) + self.log.info(f"Writing fbx file '{filename}' to '{filepath}'") rt.FBXExporterSetParam("Animation", True) rt.FBXExporterSetParam("Cameras", True) @@ -36,10 +36,10 @@ class ExtractCameraFbx(publish.Extractor, OptionalPyblishPluginMixin): with maintained_selection(): # select and export - rt.select(get_all_children(rt.getNodeByName(container))) - rt.exportFile( + rt.Select(get_all_children(rt.GetNodeByName(container))) + rt.ExportFile( filepath, - rt.name("noPrompt"), + rt.Name("noPrompt"), selectedOnly=True, using=rt.FBXEXP, ) @@ -55,6 +55,4 @@ class ExtractCameraFbx(publish.Extractor, OptionalPyblishPluginMixin): "stagingDir": stagingdir, } instance.data["representations"].append(representation) - self.log.info( - "Extracted instance '%s' to: %s" % (instance.name, filepath) - ) + self.log.info(f"Extracted instance '{instance.name}' to: {filepath}") diff --git a/openpype/hosts/max/plugins/publish/extract_model_usd.py b/openpype/hosts/max/plugins/publish/extract_model_usd.py index 2500e6c905..da37c77bf7 100644 --- a/openpype/hosts/max/plugins/publish/extract_model_usd.py +++ b/openpype/hosts/max/plugins/publish/extract_model_usd.py @@ -1,20 +1,15 @@ import os + import pyblish.api -from openpype.pipeline import ( - publish, - OptionalPyblishPluginMixin -) from pymxs import runtime as rt -from openpype.hosts.max.api import ( - maintained_selection -) + +from openpype.hosts.max.api import maintained_selection +from openpype.pipeline import OptionalPyblishPluginMixin, publish class ExtractModelUSD(publish.Extractor, OptionalPyblishPluginMixin): - """ - Extract Geometry in USDA Format - """ + """Extract Geometry in USDA Format.""" order = pyblish.api.ExtractorOrder - 0.05 label = "Extract Geometry (USD)" @@ -44,7 +39,7 @@ class ExtractModelUSD(publish.Extractor, with maintained_selection(): # select and export node_list = instance.data["members"] - rt.select(node_list) + rt.Select(node_list) rt.USDExporter.ExportFile(asset_filepath, exportOptions=export_options, contentSource=rt.Name("selected"), diff --git a/openpype/hosts/max/plugins/publish/extract_pointcloud.py b/openpype/hosts/max/plugins/publish/extract_pointcloud.py index 9e1e7fdc72..618f9856fd 100644 --- a/openpype/hosts/max/plugins/publish/extract_pointcloud.py +++ b/openpype/hosts/max/plugins/publish/extract_pointcloud.py @@ -1,15 +1,15 @@ import os + import pyblish.api -from openpype.pipeline import publish from pymxs import runtime as rt -from openpype.hosts.max.api import ( - maintained_selection -) + +from openpype.hosts.max.api import maintained_selection +from openpype.pipeline import publish class ExtractPointCloud(publish.Extractor): """ - Extract PRT format with tyFlow operators + Extract PRT format with tyFlow operators. Notes: Currently only works for the default partition setting @@ -112,8 +112,7 @@ class ExtractPointCloud(publish.Extractor): job_args.append(mode) additional_args = self.get_custom_attr(operator) - for args in additional_args: - job_args.append(args) + job_args.extend(iter(additional_args)) prt_export = f"{operator}.exportPRT()" job_args.append(prt_export) diff --git a/openpype/hosts/max/plugins/publish/validate_model_contents.py b/openpype/hosts/max/plugins/publish/validate_model_contents.py index 1d834292b8..1ec08d9c5f 100644 --- a/openpype/hosts/max/plugins/publish/validate_model_contents.py +++ b/openpype/hosts/max/plugins/publish/validate_model_contents.py @@ -1,8 +1,9 @@ # -*- coding: utf-8 -*- import pyblish.api -from openpype.pipeline import PublishValidationError from pymxs import runtime as rt +from openpype.pipeline import PublishValidationError + class ValidateModelContent(pyblish.api.InstancePlugin): """Validates Model instance contents. diff --git a/poetry.lock b/poetry.lock index 563f905fad..f71611cb6f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.4.0 and should not be changed by hand. +# This file is automatically @generated by Poetry and should not be changed by hand. [[package]] name = "acre" @@ -1456,13 +1456,11 @@ python-versions = ">=3.6" files = [ {file = "lief-0.12.3-cp310-cp310-macosx_10_14_arm64.whl", hash = "sha256:66724f337e6a36cea1a9380f13b59923f276c49ca837becae2e7be93a2e245d9"}, {file = "lief-0.12.3-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:6d18aafa2028587c98f6d4387bec94346e92f2b5a8a5002f70b1cf35b1c045cc"}, - {file = "lief-0.12.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d4f69d125caaa8d5ddb574f29cc83101e165ebea1a9f18ad042eb3544081a797"}, {file = "lief-0.12.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c078d6230279ffd3bca717c79664fb8368666f610b577deb24b374607936e9c1"}, {file = "lief-0.12.3-cp310-cp310-win32.whl", hash = "sha256:e3a6af926532d0aac9e7501946134513d63217bacba666e6f7f5a0b7e15ba236"}, {file = "lief-0.12.3-cp310-cp310-win_amd64.whl", hash = "sha256:0750b72e3aa161e1fb0e2e7f571121ae05d2428aafd742ff05a7656ad2288447"}, {file = "lief-0.12.3-cp311-cp311-macosx_10_14_arm64.whl", hash = "sha256:b5c123cb99a7879d754c059e299198b34e7e30e3b64cf22e8962013db0099f47"}, {file = "lief-0.12.3-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:8bc58fa26a830df6178e36f112cb2bbdd65deff593f066d2d51434ff78386ba5"}, - {file = "lief-0.12.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74ac6143ac6ccd813c9b068d9c5f1f9d55c8813c8b407387eb57de01c3db2d74"}, {file = "lief-0.12.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:04eb6b70d646fb5bd6183575928ee23715550f161f2832cbcd8c6ff2071fb408"}, {file = "lief-0.12.3-cp311-cp311-win32.whl", hash = "sha256:7e2d0a53c403769b04adcf8df92e83c5e25f9103a052aa7f17b0a9cf057735fb"}, {file = "lief-0.12.3-cp311-cp311-win_amd64.whl", hash = "sha256:7f6395c12ee1bc4a5162f567cba96d0c72dfb660e7902e84d4f3029daf14fe33"}, @@ -1482,7 +1480,6 @@ files = [ {file = "lief-0.12.3-cp38-cp38-win_amd64.whl", hash = "sha256:b00667257b43e93d94166c959055b6147d46d302598f3ee55c194b40414c89cc"}, {file = "lief-0.12.3-cp39-cp39-macosx_10_14_arm64.whl", hash = "sha256:e6a1b5b389090d524621c2455795e1262f62dc9381bedd96f0cd72b878c4066d"}, {file = "lief-0.12.3-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:ae773196df814202c0c51056163a1478941b299512b09660a3c37be3c7fac81e"}, - {file = "lief-0.12.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:66ddf88917ec7b00752687c476bb2771dc8ec19bd7e4c0dcff1f8ef774cad4e9"}, {file = "lief-0.12.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:4a47f410032c63ac3be051d963d0337d6b47f0e94bfe8e946ab4b6c428f4d0f8"}, {file = "lief-0.12.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbd11367c2259bd1131a6c8755dcde33314324de5ea029227bfbc7d3755871e6"}, {file = "lief-0.12.3-cp39-cp39-win32.whl", hash = "sha256:2ce53e311918c3e5b54c815ef420a747208d2a88200c41cd476f3dd1eb876bcf"}, @@ -2355,7 +2352,7 @@ files = [ cffi = ">=1.4.1" [package.extras] -docs = ["sphinx (>=1.6.5)", "sphinx-rtd-theme"] +docs = ["sphinx (>=1.6.5)", "sphinx_rtd_theme"] tests = ["hypothesis (>=3.27.0)", "pytest (>=3.2.1,!=3.3.0)"] [[package]] @@ -3248,21 +3245,6 @@ files = [ [package.dependencies] six = "*" -[[package]] -name = "wemake-python-styleguide" -version = "0.0.1" -description = "Opinionated styleguide that we use in wemake.services projects" -category = "dev" -optional = false -python-versions = "*" -files = [ - {file = "wemake-python-styleguide-0.0.1.tar.gz", hash = "sha256:e1f47a2be6aa79ca8a1cfbbbffdd67bf4df32b76306f4c3dd2a620a2af78e671"}, - {file = "wemake_python_styleguide-0.0.1-py2.py3-none-any.whl", hash = "sha256:505a19d82f9c4f450c6f06bb8c74d86c99cabcc4d5e6d8ea70e90b13b049f34f"}, -] - -[package.dependencies] -flake8 = "*" - [[package]] name = "wheel" version = "0.38.4" @@ -3480,4 +3462,4 @@ testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools" [metadata] lock-version = "2.0" python-versions = ">=3.9.1,<3.10" -content-hash = "45e91b47f9e6697b0eb9fdbe76981f691d389ce74bc5a0e98d72e1109b39bc63" +content-hash = "02daca205796a0f29a0d9f50707544e6804f32027eba493cd2aa7f175a00dcea" diff --git a/setup.cfg b/setup.cfg index 1d57657a19..42cacdc93c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,7 @@ [flake8] +# ignore = D203 +ignore = BLK100, W504, W503 max-line-length = 79 -strictness = short exclude = .git, __pycache__, @@ -9,149 +10,8 @@ exclude = website, openpype/vendor, *deadline/repository/custom/plugins -max-complexity = 30 -ignore = - # line break before binary operator - W503, - # line break occurred after a binary operator - W504, - # wemake-python-styleguide warnings - # See https://wemake-python-stylegui.de/en/latest/pages/usage/violations/index.html for doc - # Found incorrect module name pattern - WPS102, - # Found wrong variable name - WPS110, - # Found too short name - WPS111, - # Found upper-case constant in a class - WPS115, - # Found module with too many imports - WPS201, - # Found too many module members - WPS202, - # Found overused expression - WPS204, - # Found too many local variables - WPS210, - # Found too many arguments - WPS211, - # Found too many return statements - WPS212, - # Found too many expressions - WPS213, - # Found too many methods - WPS214, - # Found too many await expressions - WPS217, - # Found line with high Jones Complexity - WPS221, - # Found too many `elif` branches - WPS223, - # Found string constant over-use - WPS226, - # Found too long try body length - WPS229, - # Found too many public instance attributes - WPS230, - # Found function with too much cognitive complexity - WPS231, - # Found module cognitive complexity that is too high - WPS232, - # Found too many imported names from a module - WPS235, - # Found too many raises in a function - WPS238, - # Found too deep nesting - WPS220, - # Found `f` string - WPS305, - # Found incorrect multi-line parameters - WPS317, - # Found extra indentation - WPS318, - # Found bracket in wrong position - WPS319, - # Found percent string formatting - WPS323, - # Found implicit string concatenation - WPS326, - # Found variables that are only used for `return` - WPS331, - # Found explicit string concatenation - WPS336, - # Found multiline conditions - WPS337, - # Found incorrect order of methods in a class - WPS338, - # Found line starting with a dot - WPS348, - # Found multiline loop - WPS352, - # Found incorrect unpacking target - WPS414, - # Found wrong keyword - WPS420, - # Found wrong function - WPS421, - # Found statement that has no effect - WPS428, - # Found nested function - WPS430, - # Found magic number - WPS432, - # Found protected attribute usage - WPS437, - # Found block variables overlap - WPS440, - # Found an infinite while loop - WPS457, - # Found a getter without a return value - WPS463, - # Found negated condition - WPS504, - # flake8-quotes warnings - # Remove bad quotes - Q000, - # Remove bad quotes from multiline string - Q001, - # Darglint warnings - # Incorrect indentation - DAR003, - # Excess parameter(s) in Docstring - DAR102, - # Excess exception(s) in Raises section - DAR402, - # pydocstyle warnings - # Missing docstring in __init_ - D107, - # White space formatting for doc strings - D2, - # First line should end with a period - D400, - # Others - # function name - N802, - # Found backslash that is used for line breaking - N400, - E501, - S105, - RST, - # Black would make changes error - BLK100, - # Imperative mood of the first line on docstrings - D401, -[isort] -profile=wemake -src_paths=isort,test -# isort configuration: -# https://github.com/timothycrosley/isort/wiki/isort-Settings -include_trailing_comma = true -use_parentheses = true -# See https://github.com/timothycrosley/isort#multi-line-output-modes -multi_line_output = 3 -# Is the same as 80 in flake8: -line_length = 79 +max-complexity = 30 [pylint.'MESSAGES CONTROL'] disable = no-member From 4a8d6f7e8c26d2e9b2439c1ce017eb784acbfa75 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 24 May 2023 00:42:34 +0800 Subject: [PATCH 51/78] remove custom attributes while removing instance --- openpype/hosts/max/api/plugin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/max/api/plugin.py b/openpype/hosts/max/api/plugin.py index 8df620b913..553031d72e 100644 --- a/openpype/hosts/max/api/plugin.py +++ b/openpype/hosts/max/api/plugin.py @@ -197,8 +197,8 @@ class MaxCreator(Creator, MaxCreatorBase): """ for instance in instances: if instance_node := rt.GetNodeByName(instance.data.get("instance_node")): # noqa - rt.Select(instance_node) - rt.execute(f'for o in selection do for c in o.children do c.parent = undefined') # noqa + count = rt.custAttributes.count(instance_node) + rt.custAttributes.delete(instance_node, count) rt.Delete(instance_node) self._remove_instance_from_context(instance) From 99fbc6dc3537115734b23b718cd04b050723495f Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 6 Jun 2023 21:43:22 +0800 Subject: [PATCH 52/78] refactor the redshiftproxy family --- openpype/hosts/max/plugins/create/create_redshift_proxy.py | 7 ------- .../hosts/max/plugins/publish/extract_redshift_proxy.py | 5 ++--- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/openpype/hosts/max/plugins/create/create_redshift_proxy.py b/openpype/hosts/max/plugins/create/create_redshift_proxy.py index 698ea82b69..6eb59f0a73 100644 --- a/openpype/hosts/max/plugins/create/create_redshift_proxy.py +++ b/openpype/hosts/max/plugins/create/create_redshift_proxy.py @@ -9,10 +9,3 @@ class CreateRedshiftProxy(plugin.MaxCreator): label = "Redshift Proxy" family = "redshiftproxy" icon = "gear" - - def create(self, subset_name, instance_data, pre_create_data): - - _ = super(CreateRedshiftProxy, self).create( - subset_name, - instance_data, - pre_create_data) # type: CreatedInstance diff --git a/openpype/hosts/max/plugins/publish/extract_redshift_proxy.py b/openpype/hosts/max/plugins/publish/extract_redshift_proxy.py index 3b44099609..8f76eef5ec 100644 --- a/openpype/hosts/max/plugins/publish/extract_redshift_proxy.py +++ b/openpype/hosts/max/plugins/publish/extract_redshift_proxy.py @@ -2,7 +2,7 @@ import os import pyblish.api from openpype.pipeline import publish from pymxs import runtime as rt -from openpype.hosts.max.api import maintained_selection +from openpype.hosts.max.api import get_all_children, maintained_selection class ExtractRedshiftProxy(publish.Extractor): @@ -30,8 +30,7 @@ class ExtractRedshiftProxy(publish.Extractor): with maintained_selection(): # select and export - con = rt.getNodeByName(container) - rt.select(con.Children) + rt.select(get_all_children(rt.getNodeByName(container))) # Redshift rsProxy command # rsProxy fp selected compress connectivity startFrame endFrame # camera warnExisting transformPivotToOrigin From a4e2b18636aa77fbc538fb2493169ce9b19261c1 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 6 Jun 2023 21:47:33 +0800 Subject: [PATCH 53/78] remove duplicated imported function --- openpype/hosts/max/plugins/load/load_model.py | 1 - openpype/hosts/max/plugins/load/load_model_fbx.py | 1 - openpype/hosts/max/plugins/load/load_pointcache.py | 2 -- 3 files changed, 4 deletions(-) diff --git a/openpype/hosts/max/plugins/load/load_model.py b/openpype/hosts/max/plugins/load/load_model.py index 0ec94ab074..58c6d3c889 100644 --- a/openpype/hosts/max/plugins/load/load_model.py +++ b/openpype/hosts/max/plugins/load/load_model.py @@ -3,7 +3,6 @@ from openpype.pipeline import load, get_representation_path from openpype.hosts.max.api.pipeline import containerise from openpype.hosts.max.api import lib from openpype.hosts.max.api.lib import maintained_selection -from openpype.pipeline import get_representation_path, load class ModelAbcLoader(load.LoaderPlugin): diff --git a/openpype/hosts/max/plugins/load/load_model_fbx.py b/openpype/hosts/max/plugins/load/load_model_fbx.py index ee7d04d5eb..663f79f9f5 100644 --- a/openpype/hosts/max/plugins/load/load_model_fbx.py +++ b/openpype/hosts/max/plugins/load/load_model_fbx.py @@ -3,7 +3,6 @@ from openpype.pipeline import load, get_representation_path from openpype.hosts.max.api.pipeline import containerise from openpype.hosts.max.api import lib from openpype.hosts.max.api.lib import maintained_selection -from openpype.pipeline import get_representation_path, load class FbxModelLoader(load.LoaderPlugin): diff --git a/openpype/hosts/max/plugins/load/load_pointcache.py b/openpype/hosts/max/plugins/load/load_pointcache.py index 8a51e86000..cadbe7cac2 100644 --- a/openpype/hosts/max/plugins/load/load_pointcache.py +++ b/openpype/hosts/max/plugins/load/load_pointcache.py @@ -6,10 +6,8 @@ Because of limited api, alembics can be only loaded, but not easily updated. """ import os from openpype.pipeline import load, get_representation_path - from openpype.hosts.max.api import lib, maintained_selection from openpype.hosts.max.api.pipeline import containerise -from openpype.pipeline import get_representation_path, load class AbcLoader(load.LoaderPlugin): From d345b3e1b178c45cdce4bca315a9d5ce0e69a88f Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 9 Jun 2023 14:29:32 +0800 Subject: [PATCH 54/78] select the object from the node references for extractions instead of selecting children of the container --- openpype/hosts/max/plugins/publish/collect_members.py | 1 + openpype/hosts/max/plugins/publish/extract_camera_abc.py | 5 +++-- openpype/hosts/max/plugins/publish/extract_camera_fbx.py | 5 +++-- openpype/hosts/max/plugins/publish/extract_max_scene_raw.py | 3 +-- openpype/hosts/max/plugins/publish/extract_model.py | 5 +++-- openpype/hosts/max/plugins/publish/extract_model_fbx.py | 5 +++-- openpype/hosts/max/plugins/publish/extract_model_obj.py | 5 +++-- openpype/hosts/max/plugins/publish/extract_pointcache.py | 5 +++-- openpype/hosts/max/plugins/publish/extract_redshift_proxy.py | 5 +++-- 9 files changed, 23 insertions(+), 16 deletions(-) diff --git a/openpype/hosts/max/plugins/publish/collect_members.py b/openpype/hosts/max/plugins/publish/collect_members.py index 54020d7dae..0acb4f408d 100644 --- a/openpype/hosts/max/plugins/publish/collect_members.py +++ b/openpype/hosts/max/plugins/publish/collect_members.py @@ -19,3 +19,4 @@ class CollectMembers(pyblish.api.InstancePlugin): member.node for member in container.openPypeData.all_handles ] + self.log.debug("{}".format(instance.data["members"])) diff --git a/openpype/hosts/max/plugins/publish/extract_camera_abc.py b/openpype/hosts/max/plugins/publish/extract_camera_abc.py index c526de8960..b42732e70d 100644 --- a/openpype/hosts/max/plugins/publish/extract_camera_abc.py +++ b/openpype/hosts/max/plugins/publish/extract_camera_abc.py @@ -3,7 +3,7 @@ import os import pyblish.api from pymxs import runtime as rt -from openpype.hosts.max.api import get_all_children, maintained_selection +from openpype.hosts.max.api import maintained_selection from openpype.pipeline import OptionalPyblishPluginMixin, publish @@ -41,7 +41,8 @@ class ExtractCameraAlembic(publish.Extractor, OptionalPyblishPluginMixin): with maintained_selection(): # select and export - rt.Select(get_all_children(rt.GetNodeByName(container))) + node_list = instance.data["members"] + rt.Select(node_list) rt.ExportFile( path, rt.Name("noPrompt"), diff --git a/openpype/hosts/max/plugins/publish/extract_camera_fbx.py b/openpype/hosts/max/plugins/publish/extract_camera_fbx.py index 0c8a82dcaa..06ac3da093 100644 --- a/openpype/hosts/max/plugins/publish/extract_camera_fbx.py +++ b/openpype/hosts/max/plugins/publish/extract_camera_fbx.py @@ -3,7 +3,7 @@ import os import pyblish.api from pymxs import runtime as rt -from openpype.hosts.max.api import get_all_children, maintained_selection +from openpype.hosts.max.api import maintained_selection from openpype.pipeline import OptionalPyblishPluginMixin, publish @@ -36,7 +36,8 @@ class ExtractCameraFbx(publish.Extractor, OptionalPyblishPluginMixin): with maintained_selection(): # select and export - rt.Select(get_all_children(rt.GetNodeByName(container))) + node_list = instance.data["members"] + rt.Select(node_list) rt.ExportFile( filepath, rt.Name("noPrompt"), diff --git a/openpype/hosts/max/plugins/publish/extract_max_scene_raw.py b/openpype/hosts/max/plugins/publish/extract_max_scene_raw.py index f0c2aff7f3..de5db9ab56 100644 --- a/openpype/hosts/max/plugins/publish/extract_max_scene_raw.py +++ b/openpype/hosts/max/plugins/publish/extract_max_scene_raw.py @@ -2,7 +2,6 @@ import os import pyblish.api from openpype.pipeline import publish, OptionalPyblishPluginMixin from pymxs import runtime as rt -from openpype.hosts.max.api import get_all_children class ExtractMaxSceneRaw(publish.Extractor, OptionalPyblishPluginMixin): @@ -33,7 +32,7 @@ class ExtractMaxSceneRaw(publish.Extractor, OptionalPyblishPluginMixin): if "representations" not in instance.data: instance.data["representations"] = [] - nodes = get_all_children(rt.getNodeByName(container)) + nodes = instance.data["members"] rt.saveNodes(nodes, max_path, quiet=True) self.log.info("Performing Extraction ...") diff --git a/openpype/hosts/max/plugins/publish/extract_model.py b/openpype/hosts/max/plugins/publish/extract_model.py index 4c7c98e2cc..c7ecf7efc9 100644 --- a/openpype/hosts/max/plugins/publish/extract_model.py +++ b/openpype/hosts/max/plugins/publish/extract_model.py @@ -2,7 +2,7 @@ import os import pyblish.api from openpype.pipeline import publish, OptionalPyblishPluginMixin from pymxs import runtime as rt -from openpype.hosts.max.api import maintained_selection, get_all_children +from openpype.hosts.max.api import maintained_selection class ExtractModel(publish.Extractor, OptionalPyblishPluginMixin): @@ -40,7 +40,8 @@ class ExtractModel(publish.Extractor, OptionalPyblishPluginMixin): with maintained_selection(): # select and export - rt.select(get_all_children(rt.getNodeByName(container))) + node_list = instance.data["members"] + rt.Select(node_list) rt.exportFile( filepath, rt.name("noPrompt"), diff --git a/openpype/hosts/max/plugins/publish/extract_model_fbx.py b/openpype/hosts/max/plugins/publish/extract_model_fbx.py index 815438d378..56c2cadd94 100644 --- a/openpype/hosts/max/plugins/publish/extract_model_fbx.py +++ b/openpype/hosts/max/plugins/publish/extract_model_fbx.py @@ -2,7 +2,7 @@ import os import pyblish.api from openpype.pipeline import publish, OptionalPyblishPluginMixin from pymxs import runtime as rt -from openpype.hosts.max.api import maintained_selection, get_all_children +from openpype.hosts.max.api import maintained_selection class ExtractModelFbx(publish.Extractor, OptionalPyblishPluginMixin): @@ -40,7 +40,8 @@ class ExtractModelFbx(publish.Extractor, OptionalPyblishPluginMixin): with maintained_selection(): # select and export - rt.select(get_all_children(rt.getNodeByName(container))) + node_list = instance.data["members"] + rt.Select(node_list) rt.exportFile( filepath, rt.name("noPrompt"), diff --git a/openpype/hosts/max/plugins/publish/extract_model_obj.py b/openpype/hosts/max/plugins/publish/extract_model_obj.py index ed3d68c990..4fde65cf22 100644 --- a/openpype/hosts/max/plugins/publish/extract_model_obj.py +++ b/openpype/hosts/max/plugins/publish/extract_model_obj.py @@ -2,7 +2,7 @@ import os import pyblish.api from openpype.pipeline import publish, OptionalPyblishPluginMixin from pymxs import runtime as rt -from openpype.hosts.max.api import maintained_selection, get_all_children +from openpype.hosts.max.api import maintained_selection class ExtractModelObj(publish.Extractor, OptionalPyblishPluginMixin): @@ -31,7 +31,8 @@ class ExtractModelObj(publish.Extractor, OptionalPyblishPluginMixin): with maintained_selection(): # select and export - rt.select(get_all_children(rt.getNodeByName(container))) + node_list = instance.data["members"] + rt.Select(node_list) rt.exportFile( filepath, rt.name("noPrompt"), diff --git a/openpype/hosts/max/plugins/publish/extract_pointcache.py b/openpype/hosts/max/plugins/publish/extract_pointcache.py index 8658cecb1b..6d1e8d03b4 100644 --- a/openpype/hosts/max/plugins/publish/extract_pointcache.py +++ b/openpype/hosts/max/plugins/publish/extract_pointcache.py @@ -41,7 +41,7 @@ import os import pyblish.api from openpype.pipeline import publish from pymxs import runtime as rt -from openpype.hosts.max.api import maintained_selection, get_all_children +from openpype.hosts.max.api import maintained_selection class ExtractAlembic(publish.Extractor): @@ -72,7 +72,8 @@ class ExtractAlembic(publish.Extractor): with maintained_selection(): # select and export - rt.select(get_all_children(rt.getNodeByName(container))) + node_list = instance.data["members"] + rt.Select(node_list) rt.exportFile( path, rt.name("noPrompt"), diff --git a/openpype/hosts/max/plugins/publish/extract_redshift_proxy.py b/openpype/hosts/max/plugins/publish/extract_redshift_proxy.py index 8f76eef5ec..ab569ecbcb 100644 --- a/openpype/hosts/max/plugins/publish/extract_redshift_proxy.py +++ b/openpype/hosts/max/plugins/publish/extract_redshift_proxy.py @@ -2,7 +2,7 @@ import os import pyblish.api from openpype.pipeline import publish from pymxs import runtime as rt -from openpype.hosts.max.api import get_all_children, maintained_selection +from openpype.hosts.max.api import maintained_selection class ExtractRedshiftProxy(publish.Extractor): @@ -30,7 +30,8 @@ class ExtractRedshiftProxy(publish.Extractor): with maintained_selection(): # select and export - rt.select(get_all_children(rt.getNodeByName(container))) + node_list = instance.data["members"] + rt.Select(node_list) # Redshift rsProxy command # rsProxy fp selected compress connectivity startFrame endFrame # camera warnExisting transformPivotToOrigin From e9d60c96f50e5a278aa602e80a6a7b677a8decf9 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Mon, 12 Jun 2023 12:44:12 +0200 Subject: [PATCH 55/78] :bug: handle cancelled dialog --- openpype/hosts/max/api/plugin.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openpype/hosts/max/api/plugin.py b/openpype/hosts/max/api/plugin.py index f52e78de70..5eb4eaf391 100644 --- a/openpype/hosts/max/api/plugin.py +++ b/openpype/hosts/max/api/plugin.py @@ -35,6 +35,7 @@ MS_CUSTOM_ATTRIB = """attributes "openPypeData" ( current_selection = selectByName title:"Select Objects to add to the Container" buttontext:"Add" + if current_selection == undefined then return False temp_arr = #() i_node_arr = #() for c in current_selection do @@ -52,8 +53,10 @@ MS_CUSTOM_ATTRIB = """attributes "openPypeData" ( current_selection = selectByName title:"Select Objects to remove from the Container" buttontext:"Remove" + if current_selection == undefined then return False temp_arr = #() i_node_arr = #() + for c in current_selection do ( node_ref = NodeTransformMonitor node:c From 0a0c374ee1fc874b4f5521a72cd5273b00082ec7 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 13 Jun 2023 18:26:31 +0800 Subject: [PATCH 56/78] removing the node references successfully in the parameter --- openpype/hosts/max/api/plugin.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/max/api/plugin.py b/openpype/hosts/max/api/plugin.py index 5eb4eaf391..6bf3756e72 100644 --- a/openpype/hosts/max/api/plugin.py +++ b/openpype/hosts/max/api/plugin.py @@ -72,13 +72,13 @@ MS_CUSTOM_ATTRIB = """attributes "openPypeData" DeleteItem list_node.items idx ) ) - all_handles = join i_node_arr all_handles - list_node.items = join temp_arr list_node.items + all_handles = i_node_arr + list_node.items = temp_arr ) on OPparams open do ( - if all_handles.count != 0 do + if all_handles.count != 0 then ( temp_arr = #() for x in all_handles do From 15dd1e13b6e37dce8dbc8d1f5d0262ea3639f412 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 13 Jun 2023 19:00:37 +0800 Subject: [PATCH 57/78] removing the node references successfully in the parameter --- openpype/hosts/max/api/plugin.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/max/api/plugin.py b/openpype/hosts/max/api/plugin.py index 6bf3756e72..3fa4fa55b1 100644 --- a/openpype/hosts/max/api/plugin.py +++ b/openpype/hosts/max/api/plugin.py @@ -56,6 +56,8 @@ MS_CUSTOM_ATTRIB = """attributes "openPypeData" if current_selection == undefined then return False temp_arr = #() i_node_arr = #() + new_temp_arr = #() + new_i_node_arr = #() for c in current_selection do ( @@ -65,15 +67,17 @@ MS_CUSTOM_ATTRIB = """attributes "openPypeData" if idx do ( DeleteItem all_nodes idx + for i in all_nodes do append new_i_node_arr i ) idx = finditem list_node.items handle_name if idx do ( DeleteItem list_node.items idx + for i in list_node.items do append new_temp_arr i ) ) - all_handles = i_node_arr - list_node.items = temp_arr + all_handles = new_i_node_arr + list_node.items = new_temp_arr ) on OPparams open do From fc4c4668d0dca05cd40c4b671a38f8ea8cd78d5b Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 13 Jun 2023 20:50:24 +0800 Subject: [PATCH 58/78] removing the node references successfully in the parameter --- openpype/hosts/max/api/plugin.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/openpype/hosts/max/api/plugin.py b/openpype/hosts/max/api/plugin.py index 3fa4fa55b1..be40a765fb 100644 --- a/openpype/hosts/max/api/plugin.py +++ b/openpype/hosts/max/api/plugin.py @@ -56,7 +56,6 @@ MS_CUSTOM_ATTRIB = """attributes "openPypeData" if current_selection == undefined then return False temp_arr = #() i_node_arr = #() - new_temp_arr = #() new_i_node_arr = #() for c in current_selection do @@ -73,11 +72,10 @@ MS_CUSTOM_ATTRIB = """attributes "openPypeData" if idx do ( DeleteItem list_node.items idx - for i in list_node.items do append new_temp_arr i ) ) all_handles = new_i_node_arr - list_node.items = new_temp_arr + list_node.items = temp_arr ) on OPparams open do From bfde7cba51e99fc2de2cb15b831e9c4910c21680 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 14 Jun 2023 14:02:01 +0800 Subject: [PATCH 59/78] fix the bug of not deleting instance with delete button lasted in Openpype attribute --- openpype/hosts/max/api/plugin.py | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/openpype/hosts/max/api/plugin.py b/openpype/hosts/max/api/plugin.py index be40a765fb..3427c85d98 100644 --- a/openpype/hosts/max/api/plugin.py +++ b/openpype/hosts/max/api/plugin.py @@ -57,25 +57,34 @@ MS_CUSTOM_ATTRIB = """attributes "openPypeData" temp_arr = #() i_node_arr = #() new_i_node_arr = #() + new_temp_arr = #() for c in current_selection do ( - node_ref = NodeTransformMonitor node:c + node_ref = NodeTransformMonitor node:c as string handle_name = node_to_name c - idx = finditem all_handles node_ref + tmp_all_handles = #() + for i in all_handles do + ( + tmp = i as string + append tmp_all_handles tmp + ) + print all_handles + print node_ref + idx = finditem tmp_all_handles node_ref if idx do ( - DeleteItem all_nodes idx - for i in all_nodes do append new_i_node_arr i + new_i_node_arr = DeleteItem all_handles idx + ) idx = finditem list_node.items handle_name if idx do ( - DeleteItem list_node.items idx + new_temp_arr = DeleteItem list_node.items idx ) ) - all_handles = new_i_node_arr - list_node.items = temp_arr + all_handles = join i_node_arr new_i_node_arr + list_node.items = join temp_arr new_temp_arr ) on OPparams open do From cb92481676bd1f9f9720e2489e04eaf3b73a8065 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 14 Jun 2023 14:02:29 +0800 Subject: [PATCH 60/78] fix the docstring --- openpype/hosts/max/plugins/publish/collect_members.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/max/plugins/publish/collect_members.py b/openpype/hosts/max/plugins/publish/collect_members.py index 0acb4f408d..812d82ff26 100644 --- a/openpype/hosts/max/plugins/publish/collect_members.py +++ b/openpype/hosts/max/plugins/publish/collect_members.py @@ -5,7 +5,7 @@ from pymxs import runtime as rt class CollectMembers(pyblish.api.InstancePlugin): - """Collect Render for Deadline.""" + """Collect Set Members.""" order = pyblish.api.CollectorOrder + 0.01 label = "Collect Instance Members" From b736c8c632157facc24cf9ac36bccfff8851d09a Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Wed, 14 Jun 2023 10:06:45 +0200 Subject: [PATCH 61/78] :recycle: remove debug prints --- openpype/hosts/max/api/plugin.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/openpype/hosts/max/api/plugin.py b/openpype/hosts/max/api/plugin.py index 3427c85d98..4fc852e2fe 100644 --- a/openpype/hosts/max/api/plugin.py +++ b/openpype/hosts/max/api/plugin.py @@ -69,8 +69,6 @@ MS_CUSTOM_ATTRIB = """attributes "openPypeData" tmp = i as string append tmp_all_handles tmp ) - print all_handles - print node_ref idx = finditem tmp_all_handles node_ref if idx do ( From 37e17f3ba03d6b0c101492d9d9a7da41be5fedc9 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 15 Jun 2023 14:52:41 +0800 Subject: [PATCH 62/78] bug fix the standin being not loaded when they are first loaded --- .../hosts/maya/plugins/load/load_arnold_standin.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/maya/plugins/load/load_arnold_standin.py b/openpype/hosts/maya/plugins/load/load_arnold_standin.py index 7c3a732389..dd2e8d0885 100644 --- a/openpype/hosts/maya/plugins/load/load_arnold_standin.py +++ b/openpype/hosts/maya/plugins/load/load_arnold_standin.py @@ -1,5 +1,6 @@ import os import clique +import time import maya.cmds as cmds @@ -35,9 +36,14 @@ class ArnoldStandinLoader(load.LoaderPlugin): color = "orange" def load(self, context, name, namespace, options): - - # Make sure to load arnold before importing `mtoa.ui.arnoldmenu` - cmds.loadPlugin("mtoa", quiet=True) + # Make sure user has loaded arnold before importing `mtoa.ui.arnoldmenu` + # and getting attribute from defaultArnoldRenderOption.operator + # Otherwises standins will not be loaded successfully for + # every first time using this loader after the build + if not cmds.pluginInfo("mtoa", query=True, loaded=True): + raise RuntimeError("Plugin 'mtoa' must be loaded" + " before using this loader") + # cmds.loadPlugin("mtoa", quiet=True) import mtoa.ui.arnoldmenu version = context['version'] From 9ba54ecace3a5554c737f83f489154a99d597a49 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 15 Jun 2023 15:09:40 +0800 Subject: [PATCH 63/78] hound fix --- openpype/hosts/maya/plugins/load/load_arnold_standin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/maya/plugins/load/load_arnold_standin.py b/openpype/hosts/maya/plugins/load/load_arnold_standin.py index dd2e8d0885..f41afefcf4 100644 --- a/openpype/hosts/maya/plugins/load/load_arnold_standin.py +++ b/openpype/hosts/maya/plugins/load/load_arnold_standin.py @@ -1,6 +1,5 @@ import os import clique -import time import maya.cmds as cmds @@ -36,7 +35,8 @@ class ArnoldStandinLoader(load.LoaderPlugin): color = "orange" def load(self, context, name, namespace, options): - # Make sure user has loaded arnold before importing `mtoa.ui.arnoldmenu` + # Make sure user has loaded arnold + # before importing `mtoa.ui.arnoldmenu` # and getting attribute from defaultArnoldRenderOption.operator # Otherwises standins will not be loaded successfully for # every first time using this loader after the build From b01424111aa579f95a77b3d0b39bace1e02a8a03 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 15 Jun 2023 21:25:41 +0800 Subject: [PATCH 64/78] roy's comment --- .../maya/plugins/load/load_arnold_standin.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/maya/plugins/load/load_arnold_standin.py b/openpype/hosts/maya/plugins/load/load_arnold_standin.py index f41afefcf4..a729e0bb06 100644 --- a/openpype/hosts/maya/plugins/load/load_arnold_standin.py +++ b/openpype/hosts/maya/plugins/load/load_arnold_standin.py @@ -23,6 +23,20 @@ def is_sequence(files): return sequence +def post_process(): + import maya.utils + from qtpy import QtWidgets + + # I'm not sure this would work, but it'd be the simplest trick to try + cmds.refresh(force=True) + + # I suspect this might work + maya.utils.processIdleEvents() + + # I suspect this one might work too but it's might be a hard to track whether it solves all cases (and whether the events were already submitted to Qt at that time this command starts to run) So I'd always try to avoid this when possible. + QtWidgets.QApplication.instance().processEvents() + + class ArnoldStandinLoader(load.LoaderPlugin): """Load as Arnold standin""" @@ -40,10 +54,13 @@ class ArnoldStandinLoader(load.LoaderPlugin): # and getting attribute from defaultArnoldRenderOption.operator # Otherwises standins will not be loaded successfully for # every first time using this loader after the build + """ if not cmds.pluginInfo("mtoa", query=True, loaded=True): raise RuntimeError("Plugin 'mtoa' must be loaded" " before using this loader") - # cmds.loadPlugin("mtoa", quiet=True) + """ + cmds.loadPlugin("mtoa", quiet=True) + post_process() import mtoa.ui.arnoldmenu version = context['version'] From 5bb476cfa439d168c4e5668c30bc7945f38713a7 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 15 Jun 2023 21:27:38 +0800 Subject: [PATCH 65/78] hound fix --- openpype/hosts/maya/plugins/load/load_arnold_standin.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/openpype/hosts/maya/plugins/load/load_arnold_standin.py b/openpype/hosts/maya/plugins/load/load_arnold_standin.py index a729e0bb06..9016359c2f 100644 --- a/openpype/hosts/maya/plugins/load/load_arnold_standin.py +++ b/openpype/hosts/maya/plugins/load/load_arnold_standin.py @@ -27,13 +27,8 @@ def post_process(): import maya.utils from qtpy import QtWidgets - # I'm not sure this would work, but it'd be the simplest trick to try cmds.refresh(force=True) - - # I suspect this might work maya.utils.processIdleEvents() - - # I suspect this one might work too but it's might be a hard to track whether it solves all cases (and whether the events were already submitted to Qt at that time this command starts to run) So I'd always try to avoid this when possible. QtWidgets.QApplication.instance().processEvents() From d077491617d2c1f8b95b7c86568a88c16ff290b5 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 15 Jun 2023 21:28:56 +0800 Subject: [PATCH 66/78] add docstring --- openpype/hosts/maya/plugins/load/load_arnold_standin.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openpype/hosts/maya/plugins/load/load_arnold_standin.py b/openpype/hosts/maya/plugins/load/load_arnold_standin.py index 9016359c2f..f45a070c85 100644 --- a/openpype/hosts/maya/plugins/load/load_arnold_standin.py +++ b/openpype/hosts/maya/plugins/load/load_arnold_standin.py @@ -24,6 +24,10 @@ def is_sequence(files): def post_process(): + """ + Make sure mtoa script finished loading + before the loader doing any action + """ import maya.utils from qtpy import QtWidgets From 2f95aab31efdd90dbdf0b899059d87416190e329 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 15 Jun 2023 22:31:55 +0800 Subject: [PATCH 67/78] clean up the code --- .../maya/plugins/load/load_arnold_standin.py | 33 +++++-------------- 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/openpype/hosts/maya/plugins/load/load_arnold_standin.py b/openpype/hosts/maya/plugins/load/load_arnold_standin.py index f45a070c85..1a582647cc 100644 --- a/openpype/hosts/maya/plugins/load/load_arnold_standin.py +++ b/openpype/hosts/maya/plugins/load/load_arnold_standin.py @@ -2,6 +2,7 @@ import os import clique import maya.cmds as cmds +import maya.utils from openpype.settings import get_project_settings from openpype.pipeline import ( @@ -23,19 +24,6 @@ def is_sequence(files): return sequence -def post_process(): - """ - Make sure mtoa script finished loading - before the loader doing any action - """ - import maya.utils - from qtpy import QtWidgets - - cmds.refresh(force=True) - maya.utils.processIdleEvents() - QtWidgets.QApplication.instance().processEvents() - - class ArnoldStandinLoader(load.LoaderPlugin): """Load as Arnold standin""" @@ -48,18 +36,15 @@ class ArnoldStandinLoader(load.LoaderPlugin): color = "orange" def load(self, context, name, namespace, options): - # Make sure user has loaded arnold - # before importing `mtoa.ui.arnoldmenu` - # and getting attribute from defaultArnoldRenderOption.operator - # Otherwises standins will not be loaded successfully for - # every first time using this loader after the build - """ if not cmds.pluginInfo("mtoa", query=True, loaded=True): - raise RuntimeError("Plugin 'mtoa' must be loaded" - " before using this loader") - """ - cmds.loadPlugin("mtoa", quiet=True) - post_process() + # Allow mtoa plugin load to process all its events + # because otherwise `defaultArnoldRenderOptions.operator` + # does not exist yet and some connections to the standin + # can't be correctly generated on create resulting in an error + cmds.loadPlugin("mtoa") + cmds.refresh(force=True) + maya.utils.processIdleEvents() + import mtoa.ui.arnoldmenu version = context['version'] From c388ee94636e7eac952d7cff5c067fc03173ecb4 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 16 Jun 2023 22:08:21 +0800 Subject: [PATCH 68/78] add collector to tray publisher for getting frame range data --- .../publish/collect_anatomy_frame_range.py | 33 +++++++++++++++++++ .../project_settings/traypublisher.json | 4 +++ .../schema_project_traypublisher.json | 4 +++ 3 files changed, 41 insertions(+) create mode 100644 openpype/plugins/publish/collect_anatomy_frame_range.py diff --git a/openpype/plugins/publish/collect_anatomy_frame_range.py b/openpype/plugins/publish/collect_anatomy_frame_range.py new file mode 100644 index 0000000000..71a5dcfeb0 --- /dev/null +++ b/openpype/plugins/publish/collect_anatomy_frame_range.py @@ -0,0 +1,33 @@ +import pyblish.api + + +class CollectAnatomyFrameRange(pyblish.api.InstancePlugin): + """Collect Frame Range specific Anatomy data. + + Plugin is running for all instances on context even not active instances. + """ + + order = pyblish.api.CollectorOrder + 0.491 + label = "Collect Anatomy Frame Range" + hosts = ["traypublisher"] + + def process(self, instance): + self.log.info("Collecting Anatomy frame range.") + asset_doc = instance.data.get("assetEntity") + if not asset_doc: + self.log.info("Missing required data..") + return + + asset_data = asset_doc["data"] + for key in ( + "fps", + "frameStart", + "frameEnd", + "handleStart", + "handleEnd" + ): + if key not in instance.data and key in asset_data: + value = asset_data[key] + instance.data[key] = value + + self.log.info("Anatomy frame range collection finished.") diff --git a/openpype/settings/defaults/project_settings/traypublisher.json b/openpype/settings/defaults/project_settings/traypublisher.json index 3a42c93515..6b8bdcfcc5 100644 --- a/openpype/settings/defaults/project_settings/traypublisher.json +++ b/openpype/settings/defaults/project_settings/traypublisher.json @@ -318,6 +318,10 @@ } }, "publish": { + "CollectAnatomyFrameRange": { + "enabled": true, + "active": true + }, "ValidateFrameRange": { "enabled": true, "optional": true, diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_traypublisher.json b/openpype/settings/entities/schemas/projects_schema/schema_project_traypublisher.json index 3703d82856..44442a07d4 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_traypublisher.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_traypublisher.json @@ -343,6 +343,10 @@ "type": "schema_template", "name": "template_validate_plugin", "template_data": [ + { + "key": "CollectAnatomyFrameRange", + "label": "Collect Anatomy frame range" + }, { "key": "ValidateFrameRange", "label": "Validate frame range" From ec8c70db272ae51bb7118d6c7f359dff953efc6d Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 16 Jun 2023 22:14:06 +0800 Subject: [PATCH 69/78] delete unrelated code --- .../publish/collect_anatomy_frame_range.py | 33 +++++++++++++++++++ .../project_settings/traypublisher.json | 4 +++ .../schema_project_traypublisher.json | 4 +++ 3 files changed, 41 insertions(+) create mode 100644 openpype/plugins/publish/collect_anatomy_frame_range.py diff --git a/openpype/plugins/publish/collect_anatomy_frame_range.py b/openpype/plugins/publish/collect_anatomy_frame_range.py new file mode 100644 index 0000000000..71a5dcfeb0 --- /dev/null +++ b/openpype/plugins/publish/collect_anatomy_frame_range.py @@ -0,0 +1,33 @@ +import pyblish.api + + +class CollectAnatomyFrameRange(pyblish.api.InstancePlugin): + """Collect Frame Range specific Anatomy data. + + Plugin is running for all instances on context even not active instances. + """ + + order = pyblish.api.CollectorOrder + 0.491 + label = "Collect Anatomy Frame Range" + hosts = ["traypublisher"] + + def process(self, instance): + self.log.info("Collecting Anatomy frame range.") + asset_doc = instance.data.get("assetEntity") + if not asset_doc: + self.log.info("Missing required data..") + return + + asset_data = asset_doc["data"] + for key in ( + "fps", + "frameStart", + "frameEnd", + "handleStart", + "handleEnd" + ): + if key not in instance.data and key in asset_data: + value = asset_data[key] + instance.data[key] = value + + self.log.info("Anatomy frame range collection finished.") diff --git a/openpype/settings/defaults/project_settings/traypublisher.json b/openpype/settings/defaults/project_settings/traypublisher.json index 3a42c93515..6b8bdcfcc5 100644 --- a/openpype/settings/defaults/project_settings/traypublisher.json +++ b/openpype/settings/defaults/project_settings/traypublisher.json @@ -318,6 +318,10 @@ } }, "publish": { + "CollectAnatomyFrameRange": { + "enabled": true, + "active": true + }, "ValidateFrameRange": { "enabled": true, "optional": true, diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_traypublisher.json b/openpype/settings/entities/schemas/projects_schema/schema_project_traypublisher.json index 3703d82856..44442a07d4 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_traypublisher.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_traypublisher.json @@ -343,6 +343,10 @@ "type": "schema_template", "name": "template_validate_plugin", "template_data": [ + { + "key": "CollectAnatomyFrameRange", + "label": "Collect Anatomy frame range" + }, { "key": "ValidateFrameRange", "label": "Validate frame range" From 00eab724a4dec7df938013349cdd5ecaa9fc5645 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 16 Jun 2023 22:15:58 +0800 Subject: [PATCH 70/78] delete unrelated code --- .../publish/collect_anatomy_frame_range.py | 33 ------------------- .../project_settings/traypublisher.json | 4 --- .../schema_project_traypublisher.json | 4 --- 3 files changed, 41 deletions(-) delete mode 100644 openpype/plugins/publish/collect_anatomy_frame_range.py diff --git a/openpype/plugins/publish/collect_anatomy_frame_range.py b/openpype/plugins/publish/collect_anatomy_frame_range.py deleted file mode 100644 index 71a5dcfeb0..0000000000 --- a/openpype/plugins/publish/collect_anatomy_frame_range.py +++ /dev/null @@ -1,33 +0,0 @@ -import pyblish.api - - -class CollectAnatomyFrameRange(pyblish.api.InstancePlugin): - """Collect Frame Range specific Anatomy data. - - Plugin is running for all instances on context even not active instances. - """ - - order = pyblish.api.CollectorOrder + 0.491 - label = "Collect Anatomy Frame Range" - hosts = ["traypublisher"] - - def process(self, instance): - self.log.info("Collecting Anatomy frame range.") - asset_doc = instance.data.get("assetEntity") - if not asset_doc: - self.log.info("Missing required data..") - return - - asset_data = asset_doc["data"] - for key in ( - "fps", - "frameStart", - "frameEnd", - "handleStart", - "handleEnd" - ): - if key not in instance.data and key in asset_data: - value = asset_data[key] - instance.data[key] = value - - self.log.info("Anatomy frame range collection finished.") diff --git a/openpype/settings/defaults/project_settings/traypublisher.json b/openpype/settings/defaults/project_settings/traypublisher.json index 6b8bdcfcc5..3a42c93515 100644 --- a/openpype/settings/defaults/project_settings/traypublisher.json +++ b/openpype/settings/defaults/project_settings/traypublisher.json @@ -318,10 +318,6 @@ } }, "publish": { - "CollectAnatomyFrameRange": { - "enabled": true, - "active": true - }, "ValidateFrameRange": { "enabled": true, "optional": true, diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_traypublisher.json b/openpype/settings/entities/schemas/projects_schema/schema_project_traypublisher.json index 44442a07d4..3703d82856 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_traypublisher.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_traypublisher.json @@ -343,10 +343,6 @@ "type": "schema_template", "name": "template_validate_plugin", "template_data": [ - { - "key": "CollectAnatomyFrameRange", - "label": "Collect Anatomy frame range" - }, { "key": "ValidateFrameRange", "label": "Validate frame range" From a2525bf9bb3040d3efc5bb222aab6cc2d9794547 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Mon, 19 Jun 2023 15:40:44 +0800 Subject: [PATCH 71/78] use getLastMergedNodes() in max_scene loader --- openpype/hosts/max/plugins/load/load_max_scene.py | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/openpype/hosts/max/plugins/load/load_max_scene.py b/openpype/hosts/max/plugins/load/load_max_scene.py index 4d9367b16f..e3fb34f5bc 100644 --- a/openpype/hosts/max/plugins/load/load_max_scene.py +++ b/openpype/hosts/max/plugins/load/load_max_scene.py @@ -22,12 +22,8 @@ class MaxSceneLoader(load.LoaderPlugin): path = os.path.normpath(self.fname) # import the max scene by using "merge file" path = path.replace('\\', '/') - - merge_before = set(rt.RootNode.Children) rt.MergeMaxFile(path) - - merge_after = set(rt.RootNode.Children) - max_objects = merge_after.difference(merge_before) + max_objects = rt.getLastMergedNodes() max_container = rt.Container(name=f"{name}") for max_object in max_objects: max_object.Parent = max_container @@ -40,15 +36,14 @@ class MaxSceneLoader(load.LoaderPlugin): path = get_representation_path(representation) node_name = container["instance_node"] - instance_name, _ = node_name.split("_") - merge_before = set(rt.RootNode.Children) + rt.MergeMaxFile(path, rt.Name("noRedraw"), rt.Name("deleteOldDups"), rt.Name("useSceneMtlDups")) - merge_after = set(rt.EootNode.Children) - max_objects = merge_after.difference(merge_before) - container_node = rt.GetNodeByName(instance_name) + + max_objects = rt.getLastMergedNodes() + container_node = rt.GetNodeByName(node_name) for max_object in max_objects: max_object.Parent = container_node From 3314c5f282539f6688ee24ee583e53e95c6c8e04 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Mon, 19 Jun 2023 21:57:30 +0800 Subject: [PATCH 72/78] use createOptions() for defaultArnoldRenderOptions --- openpype/hosts/maya/plugins/load/load_arnold_standin.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/maya/plugins/load/load_arnold_standin.py b/openpype/hosts/maya/plugins/load/load_arnold_standin.py index 1a582647cc..d71b40e877 100644 --- a/openpype/hosts/maya/plugins/load/load_arnold_standin.py +++ b/openpype/hosts/maya/plugins/load/load_arnold_standin.py @@ -42,8 +42,10 @@ class ArnoldStandinLoader(load.LoaderPlugin): # does not exist yet and some connections to the standin # can't be correctly generated on create resulting in an error cmds.loadPlugin("mtoa") - cmds.refresh(force=True) - maya.utils.processIdleEvents() + # create defaultArnoldRenderOptions for + # `defaultArnoldRenderOptions.operator`` + from mtoa.core import createOptions + createOptions() import mtoa.ui.arnoldmenu From 92c6cee333d08bb685574f896d33abc253a6d220 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Mon, 19 Jun 2023 21:58:31 +0800 Subject: [PATCH 73/78] hound fix --- openpype/hosts/maya/plugins/load/load_arnold_standin.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openpype/hosts/maya/plugins/load/load_arnold_standin.py b/openpype/hosts/maya/plugins/load/load_arnold_standin.py index d71b40e877..a12ecf8f9f 100644 --- a/openpype/hosts/maya/plugins/load/load_arnold_standin.py +++ b/openpype/hosts/maya/plugins/load/load_arnold_standin.py @@ -2,7 +2,6 @@ import os import clique import maya.cmds as cmds -import maya.utils from openpype.settings import get_project_settings from openpype.pipeline import ( From 3020ccd90abdf8528052c07eb437e4bd065721f1 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Mon, 19 Jun 2023 23:00:44 +0800 Subject: [PATCH 74/78] update docstring --- .../hosts/maya/plugins/load/load_arnold_standin.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/maya/plugins/load/load_arnold_standin.py b/openpype/hosts/maya/plugins/load/load_arnold_standin.py index a12ecf8f9f..a085f8d575 100644 --- a/openpype/hosts/maya/plugins/load/load_arnold_standin.py +++ b/openpype/hosts/maya/plugins/load/load_arnold_standin.py @@ -36,13 +36,11 @@ class ArnoldStandinLoader(load.LoaderPlugin): def load(self, context, name, namespace, options): if not cmds.pluginInfo("mtoa", query=True, loaded=True): - # Allow mtoa plugin load to process all its events - # because otherwise `defaultArnoldRenderOptions.operator` - # does not exist yet and some connections to the standin - # can't be correctly generated on create resulting in an error cmds.loadPlugin("mtoa") - # create defaultArnoldRenderOptions for - # `defaultArnoldRenderOptions.operator`` + # create defaultArnoldRenderOptions before creating aiStandin + # which tried to connect it. Since we load the plugin and directly + # create aiStandin without the defaultArnoldRenderOptions, + # here needs to create the render options for aiStandin creation. from mtoa.core import createOptions createOptions() From 4ffab0bb678855d2b963d63cb982c614099cf447 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Mon, 19 Jun 2023 23:20:08 +0800 Subject: [PATCH 75/78] update docstring --- openpype/hosts/maya/plugins/load/load_arnold_standin.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/maya/plugins/load/load_arnold_standin.py b/openpype/hosts/maya/plugins/load/load_arnold_standin.py index a085f8d575..38a7adfd7d 100644 --- a/openpype/hosts/maya/plugins/load/load_arnold_standin.py +++ b/openpype/hosts/maya/plugins/load/load_arnold_standin.py @@ -37,10 +37,10 @@ class ArnoldStandinLoader(load.LoaderPlugin): def load(self, context, name, namespace, options): if not cmds.pluginInfo("mtoa", query=True, loaded=True): cmds.loadPlugin("mtoa") - # create defaultArnoldRenderOptions before creating aiStandin - # which tried to connect it. Since we load the plugin and directly + # Create defaultArnoldRenderOptions before creating aiStandin + # which tries to connect it. Since we load the plugin and directly # create aiStandin without the defaultArnoldRenderOptions, - # here needs to create the render options for aiStandin creation. + # we need to create the render options for aiStandin creation. from mtoa.core import createOptions createOptions() From b365fc7534f14dc90ba183eca1e38b650eb7a836 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Samohel?= <33513211+antirotor@users.noreply.github.com> Date: Mon, 19 Jun 2023 18:37:33 +0200 Subject: [PATCH 76/78] Update openpype/hosts/max/api/plugin.py Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- openpype/hosts/max/api/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/max/api/plugin.py b/openpype/hosts/max/api/plugin.py index 4fc852e2fe..4c1dbb2810 100644 --- a/openpype/hosts/max/api/plugin.py +++ b/openpype/hosts/max/api/plugin.py @@ -110,7 +110,7 @@ class MaxCreatorBase(object): @staticmethod def cache_subsets(shared_data): - if shared_data.get("max_cached_subsets"): + if shared_data.get("max_cached_subsets") is not None: return shared_data shared_data["max_cached_subsets"] = {} From bc33407f28dcd99a22d6239031f52dc375ebeb41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Samohel?= <33513211+antirotor@users.noreply.github.com> Date: Mon, 19 Jun 2023 18:39:54 +0200 Subject: [PATCH 77/78] Update openpype/hosts/max/plugins/publish/extract_pointcloud.py Co-authored-by: Kayla Man <64118225+moonyuet@users.noreply.github.com> --- openpype/hosts/max/plugins/publish/extract_pointcloud.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/max/plugins/publish/extract_pointcloud.py b/openpype/hosts/max/plugins/publish/extract_pointcloud.py index 618f9856fd..583bbb6dbd 100644 --- a/openpype/hosts/max/plugins/publish/extract_pointcloud.py +++ b/openpype/hosts/max/plugins/publish/extract_pointcloud.py @@ -138,9 +138,9 @@ class ExtractPointCloud(publish.Extractor): sub_anim = rt.GetSubAnim(obj, anim_name) boolean = rt.IsProperty(sub_anim, "Export_Particles") if boolean: - event_name = sub_anim.Name - opt = f"${member.Name}.{event_name}.export_particles" - opt_list.append(opt) + event_name = sub_anim.Name + opt = f"${member.Name}.{event_name}.export_particles" + opt_list.append(opt) return opt_list From 203e29c45117668a4ed0281dc42e3893ae897d3f Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Mon, 19 Jun 2023 19:03:21 +0200 Subject: [PATCH 78/78] :rewind: in unrelated file --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 42cacdc93c..10cca3eb3f 100644 --- a/setup.cfg +++ b/setup.cfg @@ -28,4 +28,4 @@ omit = /tests directory = ./coverage [tool:pytest] -norecursedirs = repos/* openpype/modules/ftrack/* +norecursedirs = repos/* openpype/modules/ftrack/* \ No newline at end of file