From e5eec7f558e20e138fa532c3a881c27fa89d39d7 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 16 Apr 2024 22:53:09 +0800 Subject: [PATCH] update the settings and code tweaks for creating project --- .../hosts/substancepainter/api/lib.py | 36 +++++++ .../plugins/load/load_mesh.py | 79 ++++---------- .../server/settings/load_plugins.py | 102 ++++++++++++++++++ .../substancepainter/server/settings/main.py | 81 +------------- 4 files changed, 160 insertions(+), 138 deletions(-) create mode 100644 server_addon/substancepainter/server/settings/load_plugins.py diff --git a/client/ayon_core/hosts/substancepainter/api/lib.py b/client/ayon_core/hosts/substancepainter/api/lib.py index 64c39943ce..e344076222 100644 --- a/client/ayon_core/hosts/substancepainter/api/lib.py +++ b/client/ayon_core/hosts/substancepainter/api/lib.py @@ -640,3 +640,39 @@ def prompt_new_file_with_mesh(mesh_filepath): return return project_mesh + + +def convert_substance_object_to_python(subst_proj_option="default"): + if subst_proj_option == "default": + return substance_painter.project.ProjectWorkflow.Default + elif subst_proj_option == "uvTile": + return substance_painter.project.ProjectWorkflow.UVTile + elif subst_proj_option == "textureSetPerUVTile": + return substance_painter.project.ProjectWorkflow.TextureSetPerUVTile + elif subst_proj_option == "PerFragment": + return substance_painter.project.TangentSpace.PerFragment + elif subst_proj_option == "PerVertex": + return substance_painter.project.TangentSpace.PerVertex + elif subst_proj_option == "DirectX": + return substance_painter.project.NormalMapFormat.DirectX + elif subst_proj_option == "OpenGL": + return substance_painter.project.NormalMapFormat.OpenGL + else: + raise ValueError( + f"Unsupported Substance Objects: {subst_proj_option}") + + +def parse_substance_attributes_setting(template_name, project_templates): + attributes_data = {} + for template in project_templates: + if template["name"] == template_name: + attributes_data.update(template) + attributes_data["normal_map_format"] = convert_substance_object_to_python( + subst_proj_option=attributes_data["normal_map_format"]) + attributes_data["project_workflow"] = convert_substance_object_to_python( + subst_proj_option=attributes_data["project_workflow"]) + attributes_data["tangent_space_mode"] = convert_substance_object_to_python( + subst_proj_option=attributes_data["tangent_space_mode"]) + attributes_data.pop("name") + attributes_data.pop("preserve_strokes") + return attributes_data diff --git a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py index 03f47eb451..563d6eb6e1 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -9,20 +9,14 @@ from ayon_core.hosts.substancepainter.api.pipeline import ( set_container_metadata, remove_container_metadata ) -from ayon_core.hosts.substancepainter.api.lib import prompt_new_file_with_mesh +from ayon_core.hosts.substancepainter.api.lib import ( + prompt_new_file_with_mesh, + parse_substance_attributes_setting +) import substance_painter.project -def get_uv_workflow(uv_option="default"): - if uv_option == "default": - return substance_painter.project.ProjectWorkflow.Default - elif uv_option == "uvTile": - return substance_painter.project.ProjectWorkflow.UVTile - else: - return substance_painter.project.ProjectWorkflow.TextureSetPerUVTile - - class SubstanceLoadProjectMesh(load.LoaderPlugin): """Load mesh for project""" @@ -33,74 +27,37 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): order = -10 icon = "code-fork" color = "orange" + project_templates = [] @classmethod def get_options(cls, contexts): - project_uv_workflow_items = { - substance_painter.project.ProjectWorkflow.Default: "default", - substance_painter.project.ProjectWorkflow.UVTile: "uvTile", - substance_painter.project.ProjectWorkflow.TextureSetPerUVTile: "textureSetPerUVTile" # noqa - } + template_enum = [template["name"] for template in cls.project_templates] return [ - BoolDef("preserve_strokes", - default=True, - label="Preserve Strokes", - tooltip=("Preserve strokes positions on mesh.\n" - "(only relevant when loading into " - "existing project)")), - BoolDef("import_cameras", - default=True, - label="Import Cameras", - tooltip="Import cameras from the mesh file." - ), - EnumDef("texture_resolution", - items=[128, 256, 512, 1024, 2048, 4096], - default=1024, - label="Texture Resolution", - tooltip="Set texture resolution when creating new project"), - EnumDef("project_uv_workflow", - items=["default", "uvTile", "textureSetPerUVTile"], + EnumDef("project_template", + items=template_enum, default="default", - label="UV Workflow", - tooltip="Set UV workflow when creating new project") + label="Project Template") ] def load(self, context, name, namespace, options=None): # Get user inputs - import_cameras = options.get("import_cameras", True) - preserve_strokes = options.get("preserve_strokes", True) - texture_resolution = options.get("texture_resolution", 1024) - uv_option = options.get("project_uv_workflow", "default") - uv_workflow = get_uv_workflow(uv_option=uv_option) - sp_settings = substance_painter.project.Settings( - default_texture_resolution=texture_resolution, - import_cameras=import_cameras, - project_workflow=uv_workflow - ) + template_name = options.get("project_template", "default") + template_settings = parse_substance_attributes_setting(template_name, self.project_templates) + sp_settings = substance_painter.project.Settings(**template_settings) if not substance_painter.project.is_open(): # Allow to 'initialize' a new project path = self.filepath_from_context(context) - # TODO: improve the prompt dialog function to not - # only works for simple polygon scene - result = prompt_new_file_with_mesh(mesh_filepath=path) - if not result: - if not substance_painter.project.is_open(): - self.log.info("User cancelled new project prompt." - "Creating new project directly from" - " Substance Painter API Instead.") - settings = substance_painter.project.create( - mesh_file_path=path, settings=sp_settings - ) - else: - self.log.info("The project is already created after " - "the new project prompt action") + settings = substance_painter.project.create( + mesh_file_path=path, settings=sp_settings + ) else: # Reload the mesh + # TODO: fix the hardcoded when the preset setting in SP addon. settings = substance_painter.project.MeshReloadingSettings( - import_cameras=import_cameras, - preserve_strokes=preserve_strokes + import_cameras=True, + preserve_strokes=True ) def on_mesh_reload(status: substance_painter.project.ReloadMeshStatus): # noqa diff --git a/server_addon/substancepainter/server/settings/load_plugins.py b/server_addon/substancepainter/server/settings/load_plugins.py new file mode 100644 index 0000000000..4d3e64f0b6 --- /dev/null +++ b/server_addon/substancepainter/server/settings/load_plugins.py @@ -0,0 +1,102 @@ +from ayon_server.settings import BaseSettingsModel, SettingsField + + +def normal_map_format_enum(): + return [ + {"label": "DirectX", "value": "DirectX"}, + {"label": "OpenGL", "value": "OpenGL"}, + ] + + +def tangent_space_enum(): + return [ + {"label": "PerFragment", "value": "PerFragment"}, + {"label": "PerVertex", "value": "PerVertex"}, + ] + + +def uv_workflow_enum(): + return [ + {"label": "Default", "value": "default"}, + {"label": "UV Tile", "value": "uvTile"}, + {"label": "Texture Set Per UV Tile", + "value": "textureSetPerUVTile"} + ] + + +def document_resolution_enum(): + return [ + {"label": "128", "value": 128}, + {"label": "256", "value": 256}, + {"label": "512", "value": 512}, + {"label": "1024", "value": 1024}, + {"label": "2048", "value": 2048}, + {"label": "4096", "value": 4096} + ] + + +class ProjectTemplatesModel(BaseSettingsModel): + _layout = "expanded" + name: str = SettingsField("default", title="Template Name") + default_texture_resolution: int = SettingsField( + 1024, enum_resolver=document_resolution_enum, + title="Document Resolution", + description=("Set texture resolution when " + "creating new project.") + ) + import_cameras: bool = SettingsField( + True, title="Import Cameras", + description="Import cameras from the mesh file.") + normal_map_format: str = SettingsField( + "DirectX", enum_resolver=normal_map_format_enum, + title="Normal Map Format", + description=("Set normal map format when " + "creating new project.") + ) + project_workflow: str = SettingsField( + "default", enum_resolver=uv_workflow_enum, + title="UV Tile Settings", + description=("Set UV workflow when " + "creating new project.") + ) + tangent_space_mode: str = SettingsField( + "PerFragment", enum_resolver=tangent_space_enum, + title="Tangent Space", + description=("An option to compute tangent space " + "when creating new project.") + ) + preserve_strokes: bool = SettingsField( + True, title="Preserve Strokes", + description=("Preserve strokes positions on mesh.\n" + "(only relevant when loading into " + "existing project)") + ) + + +class ProjectTemplateSettingModel(BaseSettingsModel): + project_templates: list[ProjectTemplatesModel] = SettingsField( + default_factory=ProjectTemplatesModel, + title="Project Templates" +) + + +class LoadersModel(BaseSettingsModel): + SubstanceLoadProjectMesh: ProjectTemplateSettingModel = SettingsField( + default_factory=ProjectTemplateSettingModel, + title="Load Mesh" + ) + + +DEFAULT_LOADER_SETTINGS = { + "SubstanceLoadProjectMesh":{ + "project_templates": [{ + "name": "default", + "default_texture_resolution": 1024, + "import_cameras": True, + "normal_map_format": "DirectX", + "project_workflow": "default", + "tangent_space_mode": "PerFragment", + "preserve_strokes": True + }] + } +} diff --git a/server_addon/substancepainter/server/settings/main.py b/server_addon/substancepainter/server/settings/main.py index 20cf6d77b2..93523fd650 100644 --- a/server_addon/substancepainter/server/settings/main.py +++ b/server_addon/substancepainter/server/settings/main.py @@ -1,77 +1,6 @@ from ayon_server.settings import BaseSettingsModel, SettingsField from .imageio import ImageIOSettings, DEFAULT_IMAGEIO_SETTINGS - - -def normal_map_format_enum(): - return [ - {"label": "DirectX", "value": "DirectX"}, - {"label": "OpenGL", "value": "OpenGL"}, - ] - - -def tangent_space_enum(): - return [ - {"label": "PerFragment", "value": "PerFragment"}, - {"label": "PerVertex", "value": "PerVertex"}, - ] - - -def uv_workflow_enum(): - return [ - {"label": "Default", "value": "default"}, - {"label": "UV Tile", "value": "uvTile"}, - {"label": "Texture Set Per UV Tile", - "value": "textureSetPerUVTile"} - ] - - -def document_resolution_enum(): - return [ - {"label": "128", "value": 128}, - {"label": "256", "value": 256}, - {"label": "512", "value": 512}, - {"label": "1024", "value": 1024}, - {"label": "2048", "value": 2048}, - {"label": "4096", "value": 4096} - ] - - -class ProjectTemplatesModel(BaseSettingsModel): - _layout = "expanded" - name: str = SettingsField(title="Template Name") - document_resolution: int = SettingsField( - 1024, enum_resolver=document_resolution_enum, - title="Document Resolution", - description=("Set texture resolution when " - "creating new project.") - ) - normal_map_format: str = SettingsField( - "DirectX", enum_resolver=normal_map_format_enum, - title="Normal Map Format", - description=("Set normal map format when " - "creating new project.") - ) - tangent_space: str = SettingsField( - "PerFragment", enum_resolver=tangent_space_enum, - title="Tangent Space", - description=("An option to compute tangent space " - "when creating new project.") - ) - uv_workflow: str = SettingsField( - "default", enum_resolver=uv_workflow_enum, - title="UV Tile Settings", - description=("Set UV workflow when " - "creating new project.") - ) - import_cameras: bool = SettingsField( - True, title="Import Cameras", - description="Import cameras from the mesh file.") - preserve_strokes: bool = SettingsField( - True, title="Preserve Strokes", - description=("Preserve strokes positions on mesh.\n" - "(only relevant when loading into " - "existing project)") - ) +from .load_plugins import LoadersModel, DEFAULT_LOADER_SETTINGS class ShelvesSettingsModel(BaseSettingsModel): @@ -89,14 +18,12 @@ class SubstancePainterSettings(BaseSettingsModel): default_factory=list, title="Shelves" ) - project_templates: list[ProjectTemplatesModel] = SettingsField( - default_factory=ProjectTemplatesModel, - title="Project Templates" - ) + load: LoadersModel = SettingsField( + default_factory=DEFAULT_LOADER_SETTINGS, title="Loaders") DEFAULT_SPAINTER_SETTINGS = { "imageio": DEFAULT_IMAGEIO_SETTINGS, "shelves": [], - "project_templates": [], + "load": DEFAULT_LOADER_SETTINGS, }