From f08443f844f1857a109e2342c37492f7f5018057 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 21 May 2024 17:45:57 +0800 Subject: [PATCH 01/25] supports exporting layer stack with specific channel & output with specific channel --- .../hosts/substancepainter/api/lib.py | 57 +++++++++++++++++++ .../plugins/create/create_textures.py | 39 +++++++++++-- .../publish/collect_textureset_images.py | 6 +- .../plugins/publish/extract_textures.py | 29 ++++++---- 4 files changed, 113 insertions(+), 18 deletions(-) diff --git a/client/ayon_core/hosts/substancepainter/api/lib.py b/client/ayon_core/hosts/substancepainter/api/lib.py index 64c39943ce..df70a72b13 100644 --- a/client/ayon_core/hosts/substancepainter/api/lib.py +++ b/client/ayon_core/hosts/substancepainter/api/lib.py @@ -3,6 +3,8 @@ import re import json from collections import defaultdict +import contextlib +import substance_painter as sp import substance_painter.project import substance_painter.resource import substance_painter.js @@ -640,3 +642,58 @@ def prompt_new_file_with_mesh(mesh_filepath): return return project_mesh + + +def get_export_presets_by_filtering(export_preset_name, channel_type_list): + new_maps = [] + + export_presets = get_export_presets() + resource_presets = substance_painter.export.list_resource_export_presets() + preset = next((preset for preset in resource_presets + if preset.resource_id.name == ( + export_presets[export_preset_name])), None) + + if preset is not None: + maps = preset.list_output_maps() + for channel_map in maps: + for n in channel_type_list: + if n in channel_map["fileName"]: + new_maps.append(channel_map) + # Create a new preset + return { + "exportPresets": [ + { + "name": export_preset_name, + "maps": new_maps + } + ], + } + return {} + + +@contextlib.contextmanager +def supsend_publish_layer_stack(node_ids, channel_type): + all_selected_nodes = [] + opacity_set_list = [] + stack = sp.textureset.get_active_stack() + stack_root_layers = sp.layerstack.get_root_layer_nodes(stack) + if node_ids and channel_type: + for node_id in node_ids: + node = sp.layerstack.get_node_by_uid(int(node_id)) + all_selected_nodes.append(node) + filtered_nodes = [node for node in stack_root_layers + if node not in all_selected_nodes] + for node in filtered_nodes: + for channel in channel_type: + chan = getattr(sp.textureset.ChannelType, channel) + opacity_set_list.append((chan, node.get_opacity(chan))) + try: + for node in filtered_nodes: + for channel, _ in opacity_set_list: + node.set_opacity(0.0, channel) + yield + finally: + for node in filtered_nodes: + for channel, opacity in opacity_set_list: + node.set_opacity(opacity, channel) + diff --git a/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py b/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py index f46afadb5a..d36bf76568 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py +++ b/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- """Creator plugin for creating textures.""" - from ayon_core.pipeline import CreatedInstance, Creator, CreatorError from ayon_core.lib import ( EnumDef, @@ -18,6 +17,7 @@ from ayon_core.hosts.substancepainter.api.pipeline import ( from ayon_core.hosts.substancepainter.api.lib import get_export_presets import substance_painter.project +import substance_painter as sp class CreateTextures(Creator): @@ -42,10 +42,20 @@ class CreateTextures(Creator): "exportFileFormat", "exportSize", "exportPadding", - "exportDilationDistance" + "exportDilationDistance", + "useCustomExportPreset", + "exportChannel" ]: if key in pre_create_data: creator_attributes[key] = pre_create_data[key] + #TODO: add the layer stack option + if sp.application.version_info()[0] >= 10 or ( + pre_create_data.get("use_selection")): + stack = sp.textureset.get_active_stack() + + instance_data["selected_node_id"] = [ + node_number.uid() for node_number in + sp.layerstack.get_selected_nodes(stack)] instance = self.create_instance_in_context(product_name, instance_data) @@ -88,8 +98,25 @@ class CreateTextures(Creator): return instance def get_instance_attr_defs(self): - + layer_stack_channel_enum = ["BaseColor", "Metallic", "Roughness", + "Normal", "Height", "Specular", + "SpecularEdgeColor", "Emissive", "Opacity", + "Displacement", "Glossiness", "Anisotropylevel", + "AO", "Anisotropyangle", "Transmissive", + "Reflection", "Diffuse", "Ior", + "Specularlevel", "BlendingMask", "Translucency", + "Scattering", "ScatterColor", "SheenOpacity", + "SheenRoughness", "SheenColor", "CoatOpacity", + "CoatColor", "CoatRoughness", "CoatSpecularLevel", + "CoatNormal"] return [ + EnumDef("exportChannel", + items=layer_stack_channel_enum, + multiselection=True, + default=None, + label="Export Channel(s)", + tooltip="Choose the channel which you " + "want to solely export"), EnumDef("exportPresetUrl", items=get_export_presets(), label="Output Template"), @@ -149,7 +176,6 @@ class CreateTextures(Creator): }, default=None, label="Size"), - EnumDef("exportPadding", items={ "passthrough": "No padding (passthrough)", @@ -172,4 +198,7 @@ class CreateTextures(Creator): def get_pre_create_attr_defs(self): # Use same attributes as for instance attributes - return self.get_instance_attr_defs() + return [ + BoolDef("use_selection", label="Use selection", + tooltip="Select Layer Stack(s) for exporting") + ] + self.get_instance_attr_defs() diff --git a/client/ayon_core/hosts/substancepainter/plugins/publish/collect_textureset_images.py b/client/ayon_core/hosts/substancepainter/plugins/publish/collect_textureset_images.py index 20aaa56993..b90e77db80 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/publish/collect_textureset_images.py +++ b/client/ayon_core/hosts/substancepainter/plugins/publish/collect_textureset_images.py @@ -8,6 +8,7 @@ import substance_painter.textureset from ayon_core.pipeline import publish from ayon_core.hosts.substancepainter.api.lib import ( get_parsed_export_maps, + get_export_presets_by_filtering, strip_template ) from ayon_core.pipeline.create import get_product_name @@ -207,5 +208,8 @@ class CollectTextureSet(pyblish.api.InstancePlugin): for key, value in dict(parameters).items(): if value is None: parameters.pop(key) - + channel_layer = creator_attrs.get("exportChannel", []) + if channel_layer: + maps = get_export_presets_by_filtering(preset_url, channel_layer) + config.update(maps) return config diff --git a/client/ayon_core/hosts/substancepainter/plugins/publish/extract_textures.py b/client/ayon_core/hosts/substancepainter/plugins/publish/extract_textures.py index 0fa7b52f45..973a62de7a 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/publish/extract_textures.py +++ b/client/ayon_core/hosts/substancepainter/plugins/publish/extract_textures.py @@ -1,6 +1,6 @@ import substance_painter.export - from ayon_core.pipeline import KnownPublishError, publish +from ayon_core.hosts.substancepainter.api.lib import supsend_publish_layer_stack class ExtractTextures(publish.Extractor, @@ -25,19 +25,24 @@ class ExtractTextures(publish.Extractor, def process(self, instance): config = instance.data["exportConfig"] - result = substance_painter.export.export_project_textures(config) + creator_attrs = instance.data["creator_attributes"] + export_channel = creator_attrs.get("exportChannel", []) + node_ids = instance.data.get("selected_node_id", []) - if result.status != substance_painter.export.ExportStatus.Success: - raise KnownPublishError( - "Failed to export texture set: {}".format(result.message) - ) + with supsend_publish_layer_stack(node_ids, export_channel): + result = substance_painter.export.export_project_textures(config) - # Log what files we generated - for (texture_set_name, stack_name), maps in result.textures.items(): - # Log our texture outputs - self.log.info(f"Exported stack: {texture_set_name} {stack_name}") - for texture_map in maps: - self.log.info(f"Exported texture: {texture_map}") + if result.status != substance_painter.export.ExportStatus.Success: + raise KnownPublishError( + "Failed to export texture set: {}".format(result.message) + ) + + # Log what files we generated + for (texture_set_name, stack_name), maps in result.textures.items(): + # Log our texture outputs + self.log.info(f"Exported stack: {texture_set_name} {stack_name}") + for texture_map in maps: + self.log.info(f"Exported texture: {texture_map}") # We'll insert the color space data for each image instance that we # added into this texture set. The collector couldn't do so because From f3b1d345453bb4ea64325cb1c5a006dca0b28b40 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 22 May 2024 19:23:59 +0800 Subject: [PATCH 02/25] check substance version when adding use selection into setting & tooltips edition for export channel --- .../plugins/create/create_textures.py | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py b/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py index d36bf76568..402550b3e8 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py +++ b/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py @@ -16,8 +16,8 @@ from ayon_core.hosts.substancepainter.api.pipeline import ( ) from ayon_core.hosts.substancepainter.api.lib import get_export_presets +import substance_painter import substance_painter.project -import substance_painter as sp class CreateTextures(Creator): @@ -49,13 +49,12 @@ class CreateTextures(Creator): if key in pre_create_data: creator_attributes[key] = pre_create_data[key] #TODO: add the layer stack option - if sp.application.version_info()[0] >= 10 or ( - pre_create_data.get("use_selection")): - stack = sp.textureset.get_active_stack() + if pre_create_data.get("use_selection"): + stack = substance_painter.textureset.get_active_stack() - instance_data["selected_node_id"] = [ - node_number.uid() for node_number in - sp.layerstack.get_selected_nodes(stack)] + instance_data["selected_node_id"] = [ + node_number.uid() for node_number in + substance_painter.layerstack.get_selected_nodes(stack)] instance = self.create_instance_in_context(product_name, instance_data) @@ -116,7 +115,9 @@ class CreateTextures(Creator): default=None, label="Export Channel(s)", tooltip="Choose the channel which you " - "want to solely export"), + "want to solely export. The value " + "is 'None' by default which exports " + "all channels"), EnumDef("exportPresetUrl", items=get_export_presets(), label="Output Template"), @@ -198,7 +199,10 @@ class CreateTextures(Creator): def get_pre_create_attr_defs(self): # Use same attributes as for instance attributes - return [ - BoolDef("use_selection", label="Use selection", - tooltip="Select Layer Stack(s) for exporting") - ] + self.get_instance_attr_defs() + selection_list = [] + if substance_painter.application.version_info()[0] >= 10: + selection_list = [ + BoolDef("use_selection", label="Use selection", + tooltip="Select Layer Stack(s) for exporting") + ] + return selection_list + self.get_instance_attr_defs() From 597f4a24a3a5b09d99e86c446508b856f7b62c00 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 22 May 2024 19:24:43 +0800 Subject: [PATCH 03/25] code clean up & rename the contextmanager function to set_layer_stack_opacity --- .../hosts/substancepainter/api/lib.py | 90 ++++++++++++------- 1 file changed, 60 insertions(+), 30 deletions(-) diff --git a/client/ayon_core/hosts/substancepainter/api/lib.py b/client/ayon_core/hosts/substancepainter/api/lib.py index df70a72b13..d98b7bca1a 100644 --- a/client/ayon_core/hosts/substancepainter/api/lib.py +++ b/client/ayon_core/hosts/substancepainter/api/lib.py @@ -4,7 +4,7 @@ import json from collections import defaultdict import contextlib -import substance_painter as sp +import substance_painter import substance_painter.project import substance_painter.resource import substance_painter.js @@ -645,47 +645,77 @@ def prompt_new_file_with_mesh(mesh_filepath): def get_export_presets_by_filtering(export_preset_name, channel_type_list): + """Function to get export presets included with specific channels + requested by users. + + Args: + export_preset_name (str): Name of export preset + channel_type_list (list): A list of channel type requested by users + + Returns: + dict: export preset data + """ + new_maps = [] export_presets = get_export_presets() + export_preset_nice_name = export_presets[export_preset_name] resource_presets = substance_painter.export.list_resource_export_presets() - preset = next((preset for preset in resource_presets - if preset.resource_id.name == ( - export_presets[export_preset_name])), None) + preset = next( + ( + preset for preset in resource_presets + if preset.resource_id.name == export_preset_nice_name + ), None + ) + if preset is None: + return {} + maps = preset.list_output_maps() + for channel_map in maps: + for n in channel_type_list: + if not channel_map.get("fileName"): + continue - if preset is not None: - maps = preset.list_output_maps() - for channel_map in maps: - for n in channel_type_list: - if n in channel_map["fileName"]: - new_maps.append(channel_map) - # Create a new preset - return { - "exportPresets": [ - { - "name": export_preset_name, - "maps": new_maps - } - ], - } - return {} + if n in channel_map["fileName"]: + new_maps.append(channel_map) + # Create a new preset + return { + "exportPresets": [ + { + "name": export_preset_name, + "maps": new_maps + } + ], + } @contextlib.contextmanager -def supsend_publish_layer_stack(node_ids, channel_type): +def set_layer_stack_opacity(node_ids, channel_type): + """Function to set the opacity of the layer stack during + context + Args: + node_ids (list): A list of substance painter node ids + channel_type (list): A list of channel types + """ + all_selected_nodes = [] opacity_set_list = [] - stack = sp.textureset.get_active_stack() - stack_root_layers = sp.layerstack.get_root_layer_nodes(stack) - if node_ids and channel_type: - for node_id in node_ids: - node = sp.layerstack.get_node_by_uid(int(node_id)) - all_selected_nodes.append(node) - filtered_nodes = [node for node in stack_root_layers - if node not in all_selected_nodes] + stack = substance_painter.textureset.get_active_stack() + stack_root_layers = ( + substance_painter.layerstack.get_root_layer_nodes(stack) + ) + # Do nothing + if not node_ids or not channel_type: + yield + return + + for node_id in node_ids: + node = substance_painter.layerstack.get_node_by_uid(int(node_id)) + all_selected_nodes.append(node) + filtered_nodes = {node for node in stack_root_layers + if node not in all_selected_nodes} for node in filtered_nodes: for channel in channel_type: - chan = getattr(sp.textureset.ChannelType, channel) + chan = getattr(substance_painter.textureset.ChannelType, channel) opacity_set_list.append((chan, node.get_opacity(chan))) try: for node in filtered_nodes: From 2dd6c12390c7e3a1bb257a9e3c0ae85c848e9e87 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 22 May 2024 19:25:10 +0800 Subject: [PATCH 04/25] rename the contextlib function --- .../substancepainter/plugins/publish/extract_textures.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/hosts/substancepainter/plugins/publish/extract_textures.py b/client/ayon_core/hosts/substancepainter/plugins/publish/extract_textures.py index 973a62de7a..361ad788ca 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/publish/extract_textures.py +++ b/client/ayon_core/hosts/substancepainter/plugins/publish/extract_textures.py @@ -1,6 +1,6 @@ import substance_painter.export from ayon_core.pipeline import KnownPublishError, publish -from ayon_core.hosts.substancepainter.api.lib import supsend_publish_layer_stack +from ayon_core.hosts.substancepainter.api.lib import set_layer_stack_opacity class ExtractTextures(publish.Extractor, @@ -29,7 +29,7 @@ class ExtractTextures(publish.Extractor, export_channel = creator_attrs.get("exportChannel", []) node_ids = instance.data.get("selected_node_id", []) - with supsend_publish_layer_stack(node_ids, export_channel): + with set_layer_stack_opacity(node_ids, export_channel): result = substance_painter.export.export_project_textures(config) if result.status != substance_painter.export.ExportStatus.Success: From 9570d0baae3893bc9de594762f8e9d8c0abface8 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 22 May 2024 22:11:57 +0800 Subject: [PATCH 05/25] use dict as item values for export channel settings --- .../plugins/create/create_textures.py | 42 +++++++++++++------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py b/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py index 402550b3e8..a75aaf7cd3 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py +++ b/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py @@ -97,20 +97,38 @@ class CreateTextures(Creator): return instance def get_instance_attr_defs(self): - layer_stack_channel_enum = ["BaseColor", "Metallic", "Roughness", - "Normal", "Height", "Specular", - "SpecularEdgeColor", "Emissive", "Opacity", - "Displacement", "Glossiness", "Anisotropylevel", - "AO", "Anisotropyangle", "Transmissive", - "Reflection", "Diffuse", "Ior", - "Specularlevel", "BlendingMask", "Translucency", - "Scattering", "ScatterColor", "SheenOpacity", - "SheenRoughness", "SheenColor", "CoatOpacity", - "CoatColor", "CoatRoughness", "CoatSpecularLevel", - "CoatNormal"] return [ EnumDef("exportChannel", - items=layer_stack_channel_enum, + items={ + "BaseColor": "Base Color", + "Metallic": "Metallic", + "Roughness": "Roughness", + "SpecularEdgeColor": "Specular Edge Color", + "Emissive": "Emissive", + "Opacity": "Opacity", + "Displacement": "Displacement", + "Glossiness": "Glossiness", + "Anisotropylevel": "Anisotropy Level", + "AO": "Ambient Occulsion", + "Anisotropyangle": "Anisotropy Angle", + "Transmissive": "Transmissive", + "Reflection": "Reflection", + "Diffuse": "Diffuse", + "Ior": "Index of Refraction", + "Specularlevel": "Specular Level", + "BlendingMask": "Blending Mask", + "Translucency": "Translucency", + "Scattering": "Scattering", + "ScatterColor": "Scatter Color", + "SheenOpacity": "Sheen Opacity", + "SheenRoughness": "Sheen Roughness", + "SheenColor": "Sheen Color", + "CoatOpacity": "Coat Opacity", + "CoatColor": "Coat Color", + "CoatRoughness": "Coat Roughness", + "CoatSpecularLevel": "Coat Specular Level", + "CoatNormal": "Coat Normal", + }, multiselection=True, default=None, label="Export Channel(s)", From a97a33af6eea5b76daa34046491cb0cce7132ac9 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 23 May 2024 18:21:37 +0800 Subject: [PATCH 06/25] add channel mapping setting into ayon project setting --- .../plugins/create/create_textures.py | 45 +++++---------- server_addon/substancepainter/package.py | 2 +- .../server/settings/creator_plugins.py | 56 +++++++++++++++++++ .../substancepainter/server/settings/main.py | 5 ++ 4 files changed, 75 insertions(+), 33 deletions(-) create mode 100644 server_addon/substancepainter/server/settings/creator_plugins.py diff --git a/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py b/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py index a75aaf7cd3..3a6387d71d 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py +++ b/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py @@ -28,9 +28,14 @@ class CreateTextures(Creator): icon = "picture-o" default_variant = "Main" + channel_mapping = [] + + def apply_settings(self, project_settings): + settings = project_settings["substancepainter"].get("create") # noqa + self.channel_mapping = settings["CreateTextures"].get("channel_mapping") + def create(self, product_name, instance_data, pre_create_data): - if not substance_painter.project.is_open(): raise CreatorError("Can't create a Texture Set instance without " "an open project.") @@ -48,7 +53,7 @@ class CreateTextures(Creator): ]: if key in pre_create_data: creator_attributes[key] = pre_create_data[key] - #TODO: add the layer stack option + if pre_create_data.get("use_selection"): stack = substance_painter.textureset.get_active_stack() @@ -97,38 +102,14 @@ class CreateTextures(Creator): return instance def get_instance_attr_defs(self): + export_channel_enum = { + item["value"]: item["name"] + for item in self.channel_mapping + } + return [ EnumDef("exportChannel", - items={ - "BaseColor": "Base Color", - "Metallic": "Metallic", - "Roughness": "Roughness", - "SpecularEdgeColor": "Specular Edge Color", - "Emissive": "Emissive", - "Opacity": "Opacity", - "Displacement": "Displacement", - "Glossiness": "Glossiness", - "Anisotropylevel": "Anisotropy Level", - "AO": "Ambient Occulsion", - "Anisotropyangle": "Anisotropy Angle", - "Transmissive": "Transmissive", - "Reflection": "Reflection", - "Diffuse": "Diffuse", - "Ior": "Index of Refraction", - "Specularlevel": "Specular Level", - "BlendingMask": "Blending Mask", - "Translucency": "Translucency", - "Scattering": "Scattering", - "ScatterColor": "Scatter Color", - "SheenOpacity": "Sheen Opacity", - "SheenRoughness": "Sheen Roughness", - "SheenColor": "Sheen Color", - "CoatOpacity": "Coat Opacity", - "CoatColor": "Coat Color", - "CoatRoughness": "Coat Roughness", - "CoatSpecularLevel": "Coat Specular Level", - "CoatNormal": "Coat Normal", - }, + items=export_channel_enum, multiselection=True, default=None, label="Export Channel(s)", diff --git a/server_addon/substancepainter/package.py b/server_addon/substancepainter/package.py index d445b0059f..bd71e1d67d 100644 --- a/server_addon/substancepainter/package.py +++ b/server_addon/substancepainter/package.py @@ -1,3 +1,3 @@ name = "substancepainter" title = "Substance Painter" -version = "0.1.1" +version = "0.1.2" diff --git a/server_addon/substancepainter/server/settings/creator_plugins.py b/server_addon/substancepainter/server/settings/creator_plugins.py new file mode 100644 index 0000000000..b16c9504aa --- /dev/null +++ b/server_addon/substancepainter/server/settings/creator_plugins.py @@ -0,0 +1,56 @@ +from ayon_server.settings import BaseSettingsModel, SettingsField + + +class ChannelMappingItemModel(BaseSettingsModel): + _layout = "compact" + name: str = SettingsField(title="Channel Type") + value: str = SettingsField(title="Channel Name") + + +class CreateTextureModel(BaseSettingsModel): + channel_mapping: list[ChannelMappingItemModel] = SettingsField( + default_factory=list, title="Channel Mapping") + + +class CreatorsModel(BaseSettingsModel): + CreateTextures: CreateTextureModel = SettingsField( + default_factory=CreateTextureModel, + title="Create Textures" + ) + + +DEFAULT_CREATOR_SETTINGS = { + "CreateTextures": { + "channel_mapping": [ + {"name": "Base Color", "value": "BaseColor"}, + {"name": "Metallic", "value": "Metallic"}, + {"name": "Specular Edge Color", + "value": "SpecularEdgeColor"}, + {"name": "Opacity", "value": "Opacity"}, + {"name": "Displacement", "value": "Displacement"}, + {"name": "Glossiness", "value": "Glossiness"}, + {"name": "Anisotropy Level", + "value": "Anisotropylevel"}, + {"name": "Ambient Occulsion", "value": "AO"}, + {"name": "Anisotropy Angle", + "value": "Anisotropyangle"}, + {"name": "Transmissive", "value": "Transmissive"}, + {"name": "Reflection", "value": "Reflection"}, + {"name": "Diffuse", "value": "Diffuse"}, + {"name": "Index of Refraction", "value": "Ior"}, + {"name": "Specular Level", "value": "Specularlevel"}, + {"name": "Blending Mask", "value": "BlendingMask"}, + {"name": "Translucency", "value": "Translucency"}, + {"name": "Scattering", "value": "Scattering"}, + {"name": "Scatter Color", "value": "ScatterColor"}, + {"name": "Sheen Opacity", "value": "SheenOpacity"}, + {"name": "Sheen Color", "value": "SheenColor"}, + {"name": "Coat Opacity", "value": "CoatOpacity"}, + {"name": "Coat Color", "value": "CoatColor"}, + {"name": "Coat Roughness", "value": "CoatRoughness"}, + {"name": "CoatSpecularLevel", + "value": "Coat Specular Level"}, + {"name": "CoatNormal", "value": "Coat Normal"} + ], + } +} \ No newline at end of file diff --git a/server_addon/substancepainter/server/settings/main.py b/server_addon/substancepainter/server/settings/main.py index 93523fd650..9a13d2c32f 100644 --- a/server_addon/substancepainter/server/settings/main.py +++ b/server_addon/substancepainter/server/settings/main.py @@ -1,5 +1,6 @@ from ayon_server.settings import BaseSettingsModel, SettingsField from .imageio import ImageIOSettings, DEFAULT_IMAGEIO_SETTINGS +from .creator_plugins import CreatorsModel, DEFAULT_CREATOR_SETTINGS from .load_plugins import LoadersModel, DEFAULT_LOADER_SETTINGS @@ -18,6 +19,8 @@ class SubstancePainterSettings(BaseSettingsModel): default_factory=list, title="Shelves" ) + create: CreatorsModel = SettingsField( + default_factory=DEFAULT_CREATOR_SETTINGS, title="Creators") load: LoadersModel = SettingsField( default_factory=DEFAULT_LOADER_SETTINGS, title="Loaders") @@ -25,5 +28,7 @@ class SubstancePainterSettings(BaseSettingsModel): DEFAULT_SPAINTER_SETTINGS = { "imageio": DEFAULT_IMAGEIO_SETTINGS, "shelves": [], + "create": DEFAULT_CREATOR_SETTINGS, "load": DEFAULT_LOADER_SETTINGS, + } From ced2ac05d059fa36726c1dd2b66ee89f4dbefae5 Mon Sep 17 00:00:00 2001 From: Kayla Man <64118225+moonyuet@users.noreply.github.com> Date: Thu, 23 May 2024 19:22:49 +0800 Subject: [PATCH 07/25] Update client/ayon_core/hosts/substancepainter/api/lib.py Co-authored-by: Roy Nieterau --- .../ayon_core/hosts/substancepainter/api/lib.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/client/ayon_core/hosts/substancepainter/api/lib.py b/client/ayon_core/hosts/substancepainter/api/lib.py index d98b7bca1a..4fb586a8d6 100644 --- a/client/ayon_core/hosts/substancepainter/api/lib.py +++ b/client/ayon_core/hosts/substancepainter/api/lib.py @@ -656,20 +656,18 @@ def get_export_presets_by_filtering(export_preset_name, channel_type_list): dict: export preset data """ - new_maps = [] - export_presets = get_export_presets() export_preset_nice_name = export_presets[export_preset_name] resource_presets = substance_painter.export.list_resource_export_presets() - preset = next( - ( - preset for preset in resource_presets - if preset.resource_id.name == export_preset_nice_name - ), None - ) - if preset is None: + for preset in resource_presets: + if preset.resource_id.name == export_preset_nice_name: + break + else: + # No matching preset found return {} + maps = preset.list_output_maps() + new_maps = [] for channel_map in maps: for n in channel_type_list: if not channel_map.get("fileName"): From d9705392a6f16ba6f0c0e71781417348a117aaee Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 23 May 2024 19:54:46 +0800 Subject: [PATCH 08/25] code tweaks - big roy's comment --- .../hosts/substancepainter/api/lib.py | 74 ++++++++----------- .../plugins/create/create_textures.py | 6 +- .../publish/collect_textureset_images.py | 7 +- 3 files changed, 41 insertions(+), 46 deletions(-) diff --git a/client/ayon_core/hosts/substancepainter/api/lib.py b/client/ayon_core/hosts/substancepainter/api/lib.py index 4fb586a8d6..e92a730b28 100644 --- a/client/ayon_core/hosts/substancepainter/api/lib.py +++ b/client/ayon_core/hosts/substancepainter/api/lib.py @@ -644,67 +644,57 @@ def prompt_new_file_with_mesh(mesh_filepath): return project_mesh -def get_export_presets_by_filtering(export_preset_name, channel_type_list): - """Function to get export presets included with specific channels - requested by users. +def get_export_preset_by_name(preset_name: str) -> substance_painter.export.Resource: + export_presets= get_export_presets() + preset_full_name = export_presets[preset_name] + for export_preset in substance_painter.export.list_resource_export_presets(): + if export_preset.resource_id.name == preset_full_name: + return export_preset - Args: - export_preset_name (str): Name of export preset - channel_type_list (list): A list of channel type requested by users - Returns: - dict: export preset data - """ +def get_export_preset_with_filtered_maps( + export_preset: substance_painter.export.Resource, + channel_type_names: list[str]) -> dict: + filtered_maps = [] + for output_map in export_preset.list_output_maps(): + output_filename = output_map.get("fileName") + if not output_filename: + continue - export_presets = get_export_presets() - export_preset_nice_name = export_presets[export_preset_name] - resource_presets = substance_painter.export.list_resource_export_presets() - for preset in resource_presets: - if preset.resource_id.name == export_preset_nice_name: - break - else: - # No matching preset found - return {} - - maps = preset.list_output_maps() - new_maps = [] - for channel_map in maps: - for n in channel_type_list: - if not channel_map.get("fileName"): - continue - - if n in channel_map["fileName"]: - new_maps.append(channel_map) + if any( + channel_type_name in output_filename + for channel_type_name in channel_type_names + ): + filtered_maps.append(output_map) # Create a new preset return { "exportPresets": [ { - "name": export_preset_name, - "maps": new_maps + "name": export_preset.resource_id.name, + "maps": filtered_maps } ], } @contextlib.contextmanager -def set_layer_stack_opacity(node_ids, channel_type): +def set_layer_stack_opacity(node_ids, channel_types): """Function to set the opacity of the layer stack during context Args: node_ids (list): A list of substance painter node ids - channel_type (list): A list of channel types + channel_types (list): A list of channel types """ - + # Do nothing + if not node_ids or not channel_types: + yield + return all_selected_nodes = [] - opacity_set_list = [] + original_opacity_values = [] stack = substance_painter.textureset.get_active_stack() stack_root_layers = ( substance_painter.layerstack.get_root_layer_nodes(stack) ) - # Do nothing - if not node_ids or not channel_type: - yield - return for node_id in node_ids: node = substance_painter.layerstack.get_node_by_uid(int(node_id)) @@ -712,16 +702,16 @@ def set_layer_stack_opacity(node_ids, channel_type): filtered_nodes = {node for node in stack_root_layers if node not in all_selected_nodes} for node in filtered_nodes: - for channel in channel_type: + for channel in channel_types: chan = getattr(substance_painter.textureset.ChannelType, channel) - opacity_set_list.append((chan, node.get_opacity(chan))) + original_opacity_values.append((chan, node.get_opacity(chan))) try: for node in filtered_nodes: - for channel, _ in opacity_set_list: + for channel, _ in original_opacity_values: node.set_opacity(0.0, channel) yield finally: for node in filtered_nodes: - for channel, opacity in opacity_set_list: + for channel, opacity in original_opacity_values: node.set_opacity(opacity, channel) diff --git a/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py b/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py index 3a6387d71d..044561af6c 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py +++ b/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py @@ -31,8 +31,10 @@ class CreateTextures(Creator): channel_mapping = [] def apply_settings(self, project_settings): - settings = project_settings["substancepainter"].get("create") # noqa - self.channel_mapping = settings["CreateTextures"].get("channel_mapping") + settings = project_settings["substancepainter"].get("create", []) # noqa + if settings: + self.channel_mapping = settings["CreateTextures"].get( + "channel_mapping", []) def create(self, product_name, instance_data, pre_create_data): diff --git a/client/ayon_core/hosts/substancepainter/plugins/publish/collect_textureset_images.py b/client/ayon_core/hosts/substancepainter/plugins/publish/collect_textureset_images.py index b90e77db80..31740840c6 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/publish/collect_textureset_images.py +++ b/client/ayon_core/hosts/substancepainter/plugins/publish/collect_textureset_images.py @@ -8,7 +8,8 @@ import substance_painter.textureset from ayon_core.pipeline import publish from ayon_core.hosts.substancepainter.api.lib import ( get_parsed_export_maps, - get_export_presets_by_filtering, + get_export_preset_by_name, + get_export_preset_with_filtered_maps, strip_template ) from ayon_core.pipeline.create import get_product_name @@ -210,6 +211,8 @@ class CollectTextureSet(pyblish.api.InstancePlugin): parameters.pop(key) channel_layer = creator_attrs.get("exportChannel", []) if channel_layer: - maps = get_export_presets_by_filtering(preset_url, channel_layer) + export_preset_nice_name = get_export_preset_by_name(preset_url) + maps = get_export_preset_with_filtered_maps( + export_preset_nice_name, channel_layer) config.update(maps) return config From e9a56f356d9d93d6cd2bcb1abb151781866704e3 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 23 May 2024 19:59:15 +0800 Subject: [PATCH 09/25] implement backward compatibility for the channel setting in creator --- .../hosts/substancepainter/api/lib.py | 37 +++++++++++++++++++ .../plugins/create/create_textures.py | 14 ++++--- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/client/ayon_core/hosts/substancepainter/api/lib.py b/client/ayon_core/hosts/substancepainter/api/lib.py index e92a730b28..43765e7bdd 100644 --- a/client/ayon_core/hosts/substancepainter/api/lib.py +++ b/client/ayon_core/hosts/substancepainter/api/lib.py @@ -13,6 +13,43 @@ import substance_painter.export from qtpy import QtGui, QtWidgets, QtCore +def get_channel_map_enum(): + """Function to get channel map items value. + For backward compatibility only. Will be removed after + client addon migration + """ + return { + "BaseColor": "Base Color", + "Metallic": "Metallic", + "Roughness": "Roughness", + "SpecularEdgeColor": "Specular Edge Color", + "Emissive": "Emissive", + "Opacity": "Opacity", + "Displacement": "Displacement", + "Glossiness": "Glossiness", + "Anisotropylevel": "Anisotropy Level", + "AO": "Ambient Occulsion", + "Anisotropyangle": "Anisotropy Angle", + "Transmissive": "Transmissive", + "Reflection": "Reflection", + "Diffuse": "Diffuse", + "Ior": "Index of Refraction", + "Specularlevel": "Specular Level", + "BlendingMask": "Blending Mask", + "Translucency": "Translucency", + "Scattering": "Scattering", + "ScatterColor": "Scatter Color", + "SheenOpacity": "Sheen Opacity", + "SheenRoughness": "Sheen Roughness", + "SheenColor": "Sheen Color", + "CoatOpacity": "Coat Opacity", + "CoatColor": "Coat Color", + "CoatRoughness": "Coat Roughness", + "CoatSpecularLevel": "Coat Specular Level", + "CoatNormal": "Coat Normal", + } + + def get_export_presets(): """Return Export Preset resource URLs for all available Export Presets. diff --git a/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py b/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py index 044561af6c..ca766d3ce9 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py +++ b/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py @@ -14,7 +14,9 @@ from ayon_core.hosts.substancepainter.api.pipeline import ( set_instances, remove_instance ) -from ayon_core.hosts.substancepainter.api.lib import get_export_presets +from ayon_core.hosts.substancepainter.api.lib import ( + get_export_presets, get_channel_map_enum +) import substance_painter import substance_painter.project @@ -35,6 +37,8 @@ class CreateTextures(Creator): if settings: self.channel_mapping = settings["CreateTextures"].get( "channel_mapping", []) + else: + self.channel_mapping = get_channel_map_enum() def create(self, product_name, instance_data, pre_create_data): @@ -200,10 +204,10 @@ class CreateTextures(Creator): def get_pre_create_attr_defs(self): # Use same attributes as for instance attributes - selection_list = [] + attr_defs = [] if substance_painter.application.version_info()[0] >= 10: - selection_list = [ + attr_defs.append( BoolDef("use_selection", label="Use selection", tooltip="Select Layer Stack(s) for exporting") - ] - return selection_list + self.get_instance_attr_defs() + ) + return attr_defs + self.get_instance_attr_defs() From b70e0b304b9e08854875ae38316606086b019a8a Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 23 May 2024 20:08:23 +0800 Subject: [PATCH 10/25] renaming filtered_nodes to excluded_nodes & make sure the code implmentation in creator doesn't break the integration --- .../ayon_core/hosts/substancepainter/api/lib.py | 17 +++++++++-------- .../plugins/create/create_textures.py | 14 +++++++------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/client/ayon_core/hosts/substancepainter/api/lib.py b/client/ayon_core/hosts/substancepainter/api/lib.py index 43765e7bdd..0b5a328cb8 100644 --- a/client/ayon_core/hosts/substancepainter/api/lib.py +++ b/client/ayon_core/hosts/substancepainter/api/lib.py @@ -726,29 +726,30 @@ def set_layer_stack_opacity(node_ids, channel_types): if not node_ids or not channel_types: yield return - all_selected_nodes = [] - original_opacity_values = [] + stack = substance_painter.textureset.get_active_stack() stack_root_layers = ( substance_painter.layerstack.get_root_layer_nodes(stack) ) - + all_selected_nodes = [] for node_id in node_ids: node = substance_painter.layerstack.get_node_by_uid(int(node_id)) all_selected_nodes.append(node) - filtered_nodes = {node for node in stack_root_layers - if node not in all_selected_nodes} - for node in filtered_nodes: + excluded_nodes = {node for node in stack_root_layers + if node not in all_selected_nodes} + + original_opacity_values = [] + for node in excluded_nodes: for channel in channel_types: chan = getattr(substance_painter.textureset.ChannelType, channel) original_opacity_values.append((chan, node.get_opacity(chan))) try: - for node in filtered_nodes: + for node in excluded_nodes: for channel, _ in original_opacity_values: node.set_opacity(0.0, channel) yield finally: - for node in filtered_nodes: + for node in excluded_nodes: for channel, opacity in original_opacity_values: node.set_opacity(opacity, channel) diff --git a/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py b/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py index ca766d3ce9..04b471f24d 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py +++ b/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py @@ -15,7 +15,8 @@ from ayon_core.hosts.substancepainter.api.pipeline import ( remove_instance ) from ayon_core.hosts.substancepainter.api.lib import ( - get_export_presets, get_channel_map_enum + get_export_presets, + get_channel_map_enum ) import substance_painter @@ -35,8 +36,11 @@ class CreateTextures(Creator): def apply_settings(self, project_settings): settings = project_settings["substancepainter"].get("create", []) # noqa if settings: - self.channel_mapping = settings["CreateTextures"].get( + self.channel_mapping = { + item["value"]: item["name"] + for item in settings["CreateTextures"].get( "channel_mapping", []) + } else: self.channel_mapping = get_channel_map_enum() @@ -108,14 +112,10 @@ class CreateTextures(Creator): return instance def get_instance_attr_defs(self): - export_channel_enum = { - item["value"]: item["name"] - for item in self.channel_mapping - } return [ EnumDef("exportChannel", - items=export_channel_enum, + items=self.channel_mapping, multiselection=True, default=None, label="Export Channel(s)", From 63398b1c61cafe089731e739f1b93513cec31d42 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 23 May 2024 20:19:58 +0800 Subject: [PATCH 11/25] make sure the code doesn't break the integration --- .../ayon_core/hosts/substancepainter/api/lib.py | 7 ++----- .../plugins/create/create_textures.py | 16 +++++++++------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/client/ayon_core/hosts/substancepainter/api/lib.py b/client/ayon_core/hosts/substancepainter/api/lib.py index 0b5a328cb8..edf7851aa0 100644 --- a/client/ayon_core/hosts/substancepainter/api/lib.py +++ b/client/ayon_core/hosts/substancepainter/api/lib.py @@ -681,7 +681,7 @@ def prompt_new_file_with_mesh(mesh_filepath): return project_mesh -def get_export_preset_by_name(preset_name: str) -> substance_painter.export.Resource: +def get_export_preset_by_name(preset_name: str): export_presets= get_export_presets() preset_full_name = export_presets[preset_name] for export_preset in substance_painter.export.list_resource_export_presets(): @@ -689,9 +689,7 @@ def get_export_preset_by_name(preset_name: str) -> substance_painter.export.Reso return export_preset -def get_export_preset_with_filtered_maps( - export_preset: substance_painter.export.Resource, - channel_type_names: list[str]) -> dict: +def get_export_preset_with_filtered_maps(export_preset, channel_type_names): filtered_maps = [] for output_map in export_preset.list_output_maps(): output_filename = output_map.get("fileName") @@ -752,4 +750,3 @@ def set_layer_stack_opacity(node_ids, channel_types): for node in excluded_nodes: for channel, opacity in original_opacity_values: node.set_opacity(opacity, channel) - diff --git a/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py b/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py index 04b471f24d..36dd9d6dba 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py +++ b/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py @@ -36,13 +36,8 @@ class CreateTextures(Creator): def apply_settings(self, project_settings): settings = project_settings["substancepainter"].get("create", []) # noqa if settings: - self.channel_mapping = { - item["value"]: item["name"] - for item in settings["CreateTextures"].get( + self.channel_mapping = settings["CreateTextures"].get( "channel_mapping", []) - } - else: - self.channel_mapping = get_channel_map_enum() def create(self, product_name, instance_data, pre_create_data): @@ -112,10 +107,17 @@ class CreateTextures(Creator): return instance def get_instance_attr_defs(self): + if self.channel_mapping: + export_channel_enum = { + item["value"]: item["name"] + for item in self.channel_mapping + } + else: + export_channel_enum = get_channel_map_enum() return [ EnumDef("exportChannel", - items=self.channel_mapping, + items=export_channel_enum, multiselection=True, default=None, label="Export Channel(s)", From b57854784f9d0aff4fb7116d5f0aa58ac39b8059 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 23 May 2024 20:37:01 +0800 Subject: [PATCH 12/25] make sure the export channel filtering function is working --- .../hosts/substancepainter/api/lib.py | 52 ++++++++++++------- .../publish/collect_textureset_images.py | 7 +-- 2 files changed, 35 insertions(+), 24 deletions(-) diff --git a/client/ayon_core/hosts/substancepainter/api/lib.py b/client/ayon_core/hosts/substancepainter/api/lib.py index edf7851aa0..f026425f24 100644 --- a/client/ayon_core/hosts/substancepainter/api/lib.py +++ b/client/ayon_core/hosts/substancepainter/api/lib.py @@ -681,32 +681,46 @@ def prompt_new_file_with_mesh(mesh_filepath): return project_mesh -def get_export_preset_by_name(preset_name: str): - export_presets= get_export_presets() - preset_full_name = export_presets[preset_name] - for export_preset in substance_painter.export.list_resource_export_presets(): - if export_preset.resource_id.name == preset_full_name: - return export_preset +def get_export_presets_by_filtering(export_preset_name, channel_type_names): + """Function to get export presets included with specific channels + requested by users. + Args: + export_preset_name (str): Name of export preset + channel_type_list (list): A list of channel type requested by users -def get_export_preset_with_filtered_maps(export_preset, channel_type_names): - filtered_maps = [] - for output_map in export_preset.list_output_maps(): - output_filename = output_map.get("fileName") - if not output_filename: - continue + Returns: + dict: export preset data + """ - if any( - channel_type_name in output_filename - for channel_type_name in channel_type_names - ): - filtered_maps.append(output_map) + target_maps = [] + + export_presets = get_export_presets() + export_preset_nice_name = export_presets[export_preset_name] + resource_presets = substance_painter.export.list_resource_export_presets() + preset = next( + ( + preset for preset in resource_presets + if preset.resource_id.name == export_preset_nice_name + ), None + ) + if preset is None: + return {} + + maps = preset.list_output_maps() + for channel_map in maps: + for channel_name in channel_type_names: + if not channel_map.get("fileName"): + continue + + if channel_name in channel_map["fileName"]: + target_maps.append(channel_map) # Create a new preset return { "exportPresets": [ { - "name": export_preset.resource_id.name, - "maps": filtered_maps + "name": export_preset_name, + "maps": target_maps } ], } diff --git a/client/ayon_core/hosts/substancepainter/plugins/publish/collect_textureset_images.py b/client/ayon_core/hosts/substancepainter/plugins/publish/collect_textureset_images.py index 31740840c6..b90e77db80 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/publish/collect_textureset_images.py +++ b/client/ayon_core/hosts/substancepainter/plugins/publish/collect_textureset_images.py @@ -8,8 +8,7 @@ import substance_painter.textureset from ayon_core.pipeline import publish from ayon_core.hosts.substancepainter.api.lib import ( get_parsed_export_maps, - get_export_preset_by_name, - get_export_preset_with_filtered_maps, + get_export_presets_by_filtering, strip_template ) from ayon_core.pipeline.create import get_product_name @@ -211,8 +210,6 @@ class CollectTextureSet(pyblish.api.InstancePlugin): parameters.pop(key) channel_layer = creator_attrs.get("exportChannel", []) if channel_layer: - export_preset_nice_name = get_export_preset_by_name(preset_url) - maps = get_export_preset_with_filtered_maps( - export_preset_nice_name, channel_layer) + maps = get_export_presets_by_filtering(preset_url, channel_layer) config.update(maps) return config From f3033a08f8ad926a420902b8ed797f404a0674f4 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 23 May 2024 22:27:46 +0800 Subject: [PATCH 13/25] rename channel name to channel map --- .../substancepainter/server/settings/creator_plugins.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server_addon/substancepainter/server/settings/creator_plugins.py b/server_addon/substancepainter/server/settings/creator_plugins.py index b16c9504aa..363ed7fe88 100644 --- a/server_addon/substancepainter/server/settings/creator_plugins.py +++ b/server_addon/substancepainter/server/settings/creator_plugins.py @@ -4,7 +4,7 @@ from ayon_server.settings import BaseSettingsModel, SettingsField class ChannelMappingItemModel(BaseSettingsModel): _layout = "compact" name: str = SettingsField(title="Channel Type") - value: str = SettingsField(title="Channel Name") + value: str = SettingsField(title="Channel Map") class CreateTextureModel(BaseSettingsModel): From cc600bd930e2dd26f7f8356b89f0c69f6628cae8 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 23 May 2024 23:20:37 +0800 Subject: [PATCH 14/25] add roughness, roughness, height option into the channel_mapping --- .../substancepainter/server/settings/creator_plugins.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server_addon/substancepainter/server/settings/creator_plugins.py b/server_addon/substancepainter/server/settings/creator_plugins.py index 363ed7fe88..9ba7684d30 100644 --- a/server_addon/substancepainter/server/settings/creator_plugins.py +++ b/server_addon/substancepainter/server/settings/creator_plugins.py @@ -24,6 +24,9 @@ DEFAULT_CREATOR_SETTINGS = { "channel_mapping": [ {"name": "Base Color", "value": "BaseColor"}, {"name": "Metallic", "value": "Metallic"}, + {"name": "Roughness", "value": "Roughness"}, + {"name": "Normal", "value": "Normal"}, + {"name": "Height", "value": "Height"}, {"name": "Specular Edge Color", "value": "SpecularEdgeColor"}, {"name": "Opacity", "value": "Opacity"}, From 6d03f7bd87b1e1e76fa3b158f0baf01c945de54f Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 24 May 2024 20:05:17 +0800 Subject: [PATCH 15/25] support to validate the texture maps filtering when no texture map after filtering to export the image instance --- .../plugins/publish/validate_ouput_maps.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py b/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py index 720771994c..b69308abd4 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py +++ b/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py @@ -25,16 +25,22 @@ class ValidateOutputMaps(pyblish.api.InstancePlugin): def process(self, instance): config = instance.data["exportConfig"] - + creator_attrs = instance.data["creator_attributes"] # Substance Painter API does not allow to query the actual output maps # it will generate without actually exporting the files. So we try to # generate the smallest size / fastest export as possible config = copy.deepcopy(config) + if creator_attrs.get("exportChannel", []): + for export_preset in config.get("exportPresets", {}): + if not export_preset.get("maps"): + raise PublishValidationError( + "No Texture Map Exported with texture set:{}.".format( + instance.name) + ) parameters = config["exportParameters"][0]["parameters"] parameters["sizeLog2"] = [1, 1] # output 2x2 images (smallest) parameters["paddingAlgorithm"] = "passthrough" # no dilation (faster) parameters["dithering"] = False # no dithering (faster) - result = substance_painter.export.export_project_textures(config) if result.status != substance_painter.export.ExportStatus.Success: raise PublishValidationError( From fb2e41c9d8be87cc87127fcd3105137655d9d01c Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 24 May 2024 21:46:27 +0800 Subject: [PATCH 16/25] support to validate multiple export channel filtering --- .../plugins/publish/validate_ouput_maps.py | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py b/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py index b69308abd4..9ea3be8c31 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py +++ b/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py @@ -30,13 +30,27 @@ class ValidateOutputMaps(pyblish.api.InstancePlugin): # it will generate without actually exporting the files. So we try to # generate the smallest size / fastest export as possible config = copy.deepcopy(config) - if creator_attrs.get("exportChannel", []): - for export_preset in config.get("exportPresets", {}): - if not export_preset.get("maps"): - raise PublishValidationError( - "No Texture Map Exported with texture set:{}.".format( - instance.name) - ) + export_channel = creator_attrs.get("exportChannel", []) + tmp_export_channel = copy.deepcopy(export_channel) + if export_channel: + for export_preset in config.get("exportPresets", {}): + if not export_preset.get("maps", {}): + raise PublishValidationError( + "No Texture Map Exported with texture set:{}.".format( + instance.name) + ) + map_names = [channel_map["fileName"] for channel_map + in export_preset["maps"]] + for channel in tmp_export_channel: + for map_name in map_names: + if channel in map_name: + tmp_export_channel.remove(channel) + if tmp_export_channel: + raise PublishValidationError( + "No Channel(s) {} found in the texture set:{}".format( + tmp_export_channel, instance.name + )) + parameters = config["exportParameters"][0]["parameters"] parameters["sizeLog2"] = [1, 1] # output 2x2 images (smallest) parameters["paddingAlgorithm"] = "passthrough" # no dilation (faster) From bd3be3695476e41bfec6fc4221d26f7f944f2e90 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 24 May 2024 22:25:32 +0800 Subject: [PATCH 17/25] edit error message --- .../substancepainter/plugins/publish/validate_ouput_maps.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py b/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py index 9ea3be8c31..143acee3f5 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py +++ b/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py @@ -47,7 +47,7 @@ class ValidateOutputMaps(pyblish.api.InstancePlugin): tmp_export_channel.remove(channel) if tmp_export_channel: raise PublishValidationError( - "No Channel(s) {} found in the texture set:{}".format( + "No Channel(s){} found in the texture set:{}".format( tmp_export_channel, instance.name )) From 339eea017e4f0699d3480194e906df9ba4a577de Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 24 May 2024 23:16:32 +0800 Subject: [PATCH 18/25] improve the validation on invalid channel function --- .../plugins/publish/validate_ouput_maps.py | 69 +++++++++++++------ 1 file changed, 47 insertions(+), 22 deletions(-) diff --git a/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py b/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py index 143acee3f5..31201e6c3b 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py +++ b/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py @@ -25,32 +25,17 @@ class ValidateOutputMaps(pyblish.api.InstancePlugin): def process(self, instance): config = instance.data["exportConfig"] - creator_attrs = instance.data["creator_attributes"] + # Substance Painter API does not allow to query the actual output maps # it will generate without actually exporting the files. So we try to # generate the smallest size / fastest export as possible config = copy.deepcopy(config) - export_channel = creator_attrs.get("exportChannel", []) - tmp_export_channel = copy.deepcopy(export_channel) - if export_channel: - for export_preset in config.get("exportPresets", {}): - if not export_preset.get("maps", {}): - raise PublishValidationError( - "No Texture Map Exported with texture set:{}.".format( - instance.name) - ) - map_names = [channel_map["fileName"] for channel_map - in export_preset["maps"]] - for channel in tmp_export_channel: - for map_name in map_names: - if channel in map_name: - tmp_export_channel.remove(channel) - if tmp_export_channel: - raise PublishValidationError( - "No Channel(s){} found in the texture set:{}".format( - tmp_export_channel, instance.name - )) - + invalid_channels = self.get_invalid_channels(instance, config) + if invalid_channels: + raise PublishValidationError( + "No Channel(s){} found in the texture set:{}".format( + invalid_channels, instance.name + )) parameters = config["exportParameters"][0]["parameters"] parameters["sizeLog2"] = [1, 1] # output 2x2 images (smallest) parameters["paddingAlgorithm"] = "passthrough" # no dilation (faster) @@ -128,3 +113,43 @@ class ValidateOutputMaps(pyblish.api.InstancePlugin): message=message, title="Missing output maps" ) + + + def get_invalid_channels(self, instance, config): + """Function to get invalid channel(s) from export channel + filtering + + Args: + instance (pyblish.api.Instance): Instance + config (dict): export config + + Raises: + PublishValidationError: raise Publish Validation + Error if any invalid channel(s) found + + Returns: + list: invalid channel(s) + """ + creator_attrs = instance.data["creator_attributes"] + export_channel = creator_attrs.get("exportChannel", []) + tmp_export_channel = copy.deepcopy(export_channel) + invalid_channel = [] + if export_channel: + for export_preset in config.get("exportPresets", {}): + if not export_preset.get("maps", {}): + raise PublishValidationError( + "No Texture Map Exported with texture set:{}.".format( + instance.name) + ) + map_names = [channel_map["fileName"] for channel_map + in export_preset["maps"]] + for channel in tmp_export_channel: + found = False + for map_name in map_names: + if channel in map_name: + found = True + break # Exit the inner loop once a match is found + if not found: + invalid_channel.append(channel) + + return invalid_channel From 0ebda1d45cd70ad5b67a6ab8d20453d87239aa5f Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 28 May 2024 20:08:11 +0800 Subject: [PATCH 19/25] code tweaks and clean up --BigRoy's comment --- .../hosts/substancepainter/api/lib.py | 49 +++---------------- .../plugins/create/create_textures.py | 34 +++++++++++-- .../plugins/publish/validate_ouput_maps.py | 8 ++- 3 files changed, 42 insertions(+), 49 deletions(-) diff --git a/client/ayon_core/hosts/substancepainter/api/lib.py b/client/ayon_core/hosts/substancepainter/api/lib.py index f026425f24..c89f87ebb9 100644 --- a/client/ayon_core/hosts/substancepainter/api/lib.py +++ b/client/ayon_core/hosts/substancepainter/api/lib.py @@ -13,43 +13,6 @@ import substance_painter.export from qtpy import QtGui, QtWidgets, QtCore -def get_channel_map_enum(): - """Function to get channel map items value. - For backward compatibility only. Will be removed after - client addon migration - """ - return { - "BaseColor": "Base Color", - "Metallic": "Metallic", - "Roughness": "Roughness", - "SpecularEdgeColor": "Specular Edge Color", - "Emissive": "Emissive", - "Opacity": "Opacity", - "Displacement": "Displacement", - "Glossiness": "Glossiness", - "Anisotropylevel": "Anisotropy Level", - "AO": "Ambient Occulsion", - "Anisotropyangle": "Anisotropy Angle", - "Transmissive": "Transmissive", - "Reflection": "Reflection", - "Diffuse": "Diffuse", - "Ior": "Index of Refraction", - "Specularlevel": "Specular Level", - "BlendingMask": "Blending Mask", - "Translucency": "Translucency", - "Scattering": "Scattering", - "ScatterColor": "Scatter Color", - "SheenOpacity": "Sheen Opacity", - "SheenRoughness": "Sheen Roughness", - "SheenColor": "Sheen Color", - "CoatOpacity": "Coat Opacity", - "CoatColor": "Coat Color", - "CoatRoughness": "Coat Roughness", - "CoatSpecularLevel": "Coat Specular Level", - "CoatNormal": "Coat Normal", - } - - def get_export_presets(): """Return Export Preset resource URLs for all available Export Presets. @@ -731,8 +694,9 @@ def set_layer_stack_opacity(node_ids, channel_types): """Function to set the opacity of the layer stack during context Args: - node_ids (list): A list of substance painter node ids - channel_types (list): A list of channel types + node_ids (list[int]): Substance painter root layer node ids + channel_types (list[str]): Channel type names as defined as + attributes in `substance_painter.textureset.ChannelType` """ # Do nothing if not node_ids or not channel_types: @@ -747,8 +711,11 @@ def set_layer_stack_opacity(node_ids, channel_types): for node_id in node_ids: node = substance_painter.layerstack.get_node_by_uid(int(node_id)) all_selected_nodes.append(node) - excluded_nodes = {node for node in stack_root_layers - if node not in all_selected_nodes} + node_ids = set(node_ids) # lookup + excluded_nodes = [ + node for node in stack_root_layers + if node.uid() not in node_ids + ] original_opacity_values = [] for node in excluded_nodes: diff --git a/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py b/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py index 36dd9d6dba..a9b26c62c6 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py +++ b/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py @@ -15,8 +15,7 @@ from ayon_core.hosts.substancepainter.api.pipeline import ( remove_instance ) from ayon_core.hosts.substancepainter.api.lib import ( - get_export_presets, - get_channel_map_enum + get_export_presets ) import substance_painter @@ -113,7 +112,36 @@ class CreateTextures(Creator): for item in self.channel_mapping } else: - export_channel_enum = get_channel_map_enum() + export_channel_enum = { + "BaseColor": "Base Color", + "Metallic": "Metallic", + "Roughness": "Roughness", + "SpecularEdgeColor": "Specular Edge Color", + "Emissive": "Emissive", + "Opacity": "Opacity", + "Displacement": "Displacement", + "Glossiness": "Glossiness", + "Anisotropylevel": "Anisotropy Level", + "AO": "Ambient Occulsion", + "Anisotropyangle": "Anisotropy Angle", + "Transmissive": "Transmissive", + "Reflection": "Reflection", + "Diffuse": "Diffuse", + "Ior": "Index of Refraction", + "Specularlevel": "Specular Level", + "BlendingMask": "Blending Mask", + "Translucency": "Translucency", + "Scattering": "Scattering", + "ScatterColor": "Scatter Color", + "SheenOpacity": "Sheen Opacity", + "SheenRoughness": "Sheen Roughness", + "SheenColor": "Sheen Color", + "CoatOpacity": "Coat Opacity", + "CoatColor": "Coat Color", + "CoatRoughness": "Coat Roughness", + "CoatSpecularLevel": "Coat Specular Level", + "CoatNormal": "Coat Normal", + } return [ EnumDef("exportChannel", diff --git a/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py b/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py index 31201e6c3b..777031b1ad 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py +++ b/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py @@ -114,7 +114,6 @@ class ValidateOutputMaps(pyblish.api.InstancePlugin): title="Missing output maps" ) - def get_invalid_channels(self, instance, config): """Function to get invalid channel(s) from export channel filtering @@ -144,12 +143,11 @@ class ValidateOutputMaps(pyblish.api.InstancePlugin): map_names = [channel_map["fileName"] for channel_map in export_preset["maps"]] for channel in tmp_export_channel: - found = False + # Check if channel is found in at least one map for map_name in map_names: if channel in map_name: - found = True - break # Exit the inner loop once a match is found - if not found: + break + else: invalid_channel.append(channel) return invalid_channel From 119428bcdb1b6d181957ccd1039f6b167e3bf6b3 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 28 May 2024 20:18:42 +0800 Subject: [PATCH 20/25] improve publish validation message --- .../plugins/publish/validate_ouput_maps.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py b/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py index 777031b1ad..3a49cd86d0 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py +++ b/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py @@ -31,11 +31,18 @@ class ValidateOutputMaps(pyblish.api.InstancePlugin): # generate the smallest size / fastest export as possible config = copy.deepcopy(config) invalid_channels = self.get_invalid_channels(instance, config) + msg = [] if invalid_channels: + bullet_point_invalid_statement = "\n".join( + "- {}".format(message) for _, message + in invalid_channels + ) + report = ( + "Invalid Channel Maps found.\n\n" + f"{bullet_point_invalid_statement}\n\n" + ) raise PublishValidationError( - "No Channel(s){} found in the texture set:{}".format( - invalid_channels, instance.name - )) + report, title="Invalid Channel Maps") parameters = config["exportParameters"][0]["parameters"] parameters["sizeLog2"] = [1, 1] # output 2x2 images (smallest) parameters["paddingAlgorithm"] = "passthrough" # no dilation (faster) @@ -132,6 +139,7 @@ class ValidateOutputMaps(pyblish.api.InstancePlugin): creator_attrs = instance.data["creator_attributes"] export_channel = creator_attrs.get("exportChannel", []) tmp_export_channel = copy.deepcopy(export_channel) + invalid_message = [] invalid_channel = [] if export_channel: for export_preset in config.get("exportPresets", {}): @@ -148,6 +156,9 @@ class ValidateOutputMaps(pyblish.api.InstancePlugin): if channel in map_name: break else: + invalid_message.append( + f"Channel map {channel} found " + "in the export_preset") invalid_channel.append(channel) - return invalid_channel + return invalid_channel, invalid_message From 447edbee03bdc139a8e37ee1192ebf03da81fedf Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 28 May 2024 20:20:23 +0800 Subject: [PATCH 21/25] cosmetic fix --- .../substancepainter/plugins/publish/validate_ouput_maps.py | 1 - 1 file changed, 1 deletion(-) diff --git a/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py b/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py index 3a49cd86d0..64445319d9 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py +++ b/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py @@ -31,7 +31,6 @@ class ValidateOutputMaps(pyblish.api.InstancePlugin): # generate the smallest size / fastest export as possible config = copy.deepcopy(config) invalid_channels = self.get_invalid_channels(instance, config) - msg = [] if invalid_channels: bullet_point_invalid_statement = "\n".join( "- {}".format(message) for _, message From 5f950b72184bea5f8c74601e4b9e5d5c6147deb0 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 28 May 2024 20:49:31 +0800 Subject: [PATCH 22/25] improve debug msg --- .../plugins/publish/validate_ouput_maps.py | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py b/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py index 64445319d9..bf04d118db 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py +++ b/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py @@ -32,16 +32,10 @@ class ValidateOutputMaps(pyblish.api.InstancePlugin): config = copy.deepcopy(config) invalid_channels = self.get_invalid_channels(instance, config) if invalid_channels: - bullet_point_invalid_statement = "\n".join( - "- {}".format(message) for _, message - in invalid_channels - ) - report = ( - "Invalid Channel Maps found.\n\n" - f"{bullet_point_invalid_statement}\n\n" - ) raise PublishValidationError( - report, title="Invalid Channel Maps") + "No Channel(s): {} found in the texture set {}".format( + invalid_channels, instance.name + )) parameters = config["exportParameters"][0]["parameters"] parameters["sizeLog2"] = [1, 1] # output 2x2 images (smallest) parameters["paddingAlgorithm"] = "passthrough" # no dilation (faster) @@ -138,7 +132,6 @@ class ValidateOutputMaps(pyblish.api.InstancePlugin): creator_attrs = instance.data["creator_attributes"] export_channel = creator_attrs.get("exportChannel", []) tmp_export_channel = copy.deepcopy(export_channel) - invalid_message = [] invalid_channel = [] if export_channel: for export_preset in config.get("exportPresets", {}): @@ -155,9 +148,6 @@ class ValidateOutputMaps(pyblish.api.InstancePlugin): if channel in map_name: break else: - invalid_message.append( - f"Channel map {channel} found " - "in the export_preset") invalid_channel.append(channel) - return invalid_channel, invalid_message + return invalid_channel From a392567e55402296fb2c8aa05dc83245647cdc90 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 28 May 2024 20:50:29 +0800 Subject: [PATCH 23/25] improve debug msg --- .../substancepainter/plugins/publish/validate_ouput_maps.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py b/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py index bf04d118db..36b4aeddd2 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py +++ b/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py @@ -33,7 +33,7 @@ class ValidateOutputMaps(pyblish.api.InstancePlugin): invalid_channels = self.get_invalid_channels(instance, config) if invalid_channels: raise PublishValidationError( - "No Channel(s): {} found in the texture set {}".format( + "Invalid Channel(s): {} found in the texture set {}".format( invalid_channels, instance.name )) parameters = config["exportParameters"][0]["parameters"] From 3b074c91820606948a622f4e653b7688d49093e9 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 29 May 2024 08:13:12 +0800 Subject: [PATCH 24/25] code tweaks - big roy's comment --- client/ayon_core/hosts/substancepainter/api/lib.py | 6 +----- .../substancepainter/plugins/create/create_textures.py | 4 +--- .../plugins/publish/collect_textureset_images.py | 4 ++-- .../substancepainter/plugins/publish/validate_ouput_maps.py | 4 ++-- 4 files changed, 6 insertions(+), 12 deletions(-) diff --git a/client/ayon_core/hosts/substancepainter/api/lib.py b/client/ayon_core/hosts/substancepainter/api/lib.py index c89f87ebb9..e409605d07 100644 --- a/client/ayon_core/hosts/substancepainter/api/lib.py +++ b/client/ayon_core/hosts/substancepainter/api/lib.py @@ -645,7 +645,7 @@ def prompt_new_file_with_mesh(mesh_filepath): def get_export_presets_by_filtering(export_preset_name, channel_type_names): - """Function to get export presets included with specific channels + """Return export presets included with specific channels requested by users. Args: @@ -707,10 +707,6 @@ def set_layer_stack_opacity(node_ids, channel_types): stack_root_layers = ( substance_painter.layerstack.get_root_layer_nodes(stack) ) - all_selected_nodes = [] - for node_id in node_ids: - node = substance_painter.layerstack.get_node_by_uid(int(node_id)) - all_selected_nodes.append(node) node_ids = set(node_ids) # lookup excluded_nodes = [ node for node in stack_root_layers diff --git a/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py b/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py index a9b26c62c6..34826240a3 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py +++ b/client/ayon_core/hosts/substancepainter/plugins/create/create_textures.py @@ -14,9 +14,7 @@ from ayon_core.hosts.substancepainter.api.pipeline import ( set_instances, remove_instance ) -from ayon_core.hosts.substancepainter.api.lib import ( - get_export_presets -) +from ayon_core.hosts.substancepainter.api.lib import get_export_presets import substance_painter import substance_painter.project diff --git a/client/ayon_core/hosts/substancepainter/plugins/publish/collect_textureset_images.py b/client/ayon_core/hosts/substancepainter/plugins/publish/collect_textureset_images.py index b90e77db80..f7837e5106 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/publish/collect_textureset_images.py +++ b/client/ayon_core/hosts/substancepainter/plugins/publish/collect_textureset_images.py @@ -8,7 +8,7 @@ import substance_painter.textureset from ayon_core.pipeline import publish from ayon_core.hosts.substancepainter.api.lib import ( get_parsed_export_maps, - get_export_presets_by_filtering, + get_filtered_export_preset, strip_template ) from ayon_core.pipeline.create import get_product_name @@ -210,6 +210,6 @@ class CollectTextureSet(pyblish.api.InstancePlugin): parameters.pop(key) channel_layer = creator_attrs.get("exportChannel", []) if channel_layer: - maps = get_export_presets_by_filtering(preset_url, channel_layer) + maps = get_filtered_export_preset(preset_url, channel_layer) config.update(maps) return config diff --git a/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py b/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py index 36b4aeddd2..3293e7f204 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py +++ b/client/ayon_core/hosts/substancepainter/plugins/publish/validate_ouput_maps.py @@ -33,7 +33,7 @@ class ValidateOutputMaps(pyblish.api.InstancePlugin): invalid_channels = self.get_invalid_channels(instance, config) if invalid_channels: raise PublishValidationError( - "Invalid Channel(s): {} found in the texture set {}".format( + "Invalid Channel(s): {} found in texture set {}".format( invalid_channels, instance.name )) parameters = config["exportParameters"][0]["parameters"] @@ -137,7 +137,7 @@ class ValidateOutputMaps(pyblish.api.InstancePlugin): for export_preset in config.get("exportPresets", {}): if not export_preset.get("maps", {}): raise PublishValidationError( - "No Texture Map Exported with texture set:{}.".format( + "No Texture Map Exported with texture set: {}.".format( instance.name) ) map_names = [channel_map["fileName"] for channel_map From eeb454432baa37dd4a2b58d5b5df6cd77413509a Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 29 May 2024 08:14:47 +0800 Subject: [PATCH 25/25] code tweaks - big roy's comment --- client/ayon_core/hosts/substancepainter/api/lib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/substancepainter/api/lib.py b/client/ayon_core/hosts/substancepainter/api/lib.py index e409605d07..0ae3932f58 100644 --- a/client/ayon_core/hosts/substancepainter/api/lib.py +++ b/client/ayon_core/hosts/substancepainter/api/lib.py @@ -644,7 +644,7 @@ def prompt_new_file_with_mesh(mesh_filepath): return project_mesh -def get_export_presets_by_filtering(export_preset_name, channel_type_names): +def get_filtered_export_preset(export_preset_name, channel_type_names): """Return export presets included with specific channels requested by users.