From c5ccf8a3904dd9a2dbe5c14538044e39fe89dece Mon Sep 17 00:00:00 2001 From: moonyuet Date: Wed, 10 Apr 2024 23:24:28 +0800 Subject: [PATCH 01/65] add texture resolution setting when loading mesh to set up project in substance painter --- .../plugins/load/load_mesh.py | 43 +++++++++++-------- 1 file changed, 26 insertions(+), 17 deletions(-) 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 d940d7b05c..07b53fb85c 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -2,6 +2,7 @@ from ayon_core.pipeline import ( load, get_representation_path, ) +from ayon_core.lib import BoolDef, EnumDef from ayon_core.pipeline.load import LoadError from ayon_core.hosts.substancepainter.api.pipeline import ( imprint_container, @@ -11,7 +12,6 @@ from ayon_core.hosts.substancepainter.api.pipeline import ( from ayon_core.hosts.substancepainter.api.lib import prompt_new_file_with_mesh import substance_painter.project -import qargparse class SubstanceLoadProjectMesh(load.LoaderPlugin): @@ -25,26 +25,35 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): icon = "code-fork" color = "orange" - options = [ - qargparse.Boolean( - "preserve_strokes", - default=True, - help="Preserve strokes positions on mesh.\n" - "(only relevant when loading into existing project)" - ), - qargparse.Boolean( - "import_cameras", - default=True, - help="Import cameras from the mesh file." - ) - ] + @classmethod + def get_options(cls, contexts): + 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 for the project") + ] - def load(self, context, name, namespace, data): + def load(self, context, name, namespace, options=None): # Get user inputs - import_cameras = data.get("import_cameras", True) - preserve_strokes = data.get("preserve_strokes", True) + import_cameras = options.get("import_cameras", True) + preserve_strokes = options.get("preserve_strokes", True) + texture_resolution = options.get("texture_resolution", 1024) sp_settings = substance_painter.project.Settings( + default_texture_resolution=texture_resolution, import_cameras=import_cameras ) if not substance_painter.project.is_open(): From 6758a2a7c57ceb4f9d8e707506321830a478b7ae Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 11 Apr 2024 18:17:36 +0800 Subject: [PATCH 02/65] add the boolean options to allow user to set the project setting by their own --- client/ayon_core/hosts/substancepainter/api/lib.py | 6 +++--- .../hosts/substancepainter/plugins/load/load_mesh.py | 9 ++++++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/client/ayon_core/hosts/substancepainter/api/lib.py b/client/ayon_core/hosts/substancepainter/api/lib.py index 1cb480b552..95d45da436 100644 --- a/client/ayon_core/hosts/substancepainter/api/lib.py +++ b/client/ayon_core/hosts/substancepainter/api/lib.py @@ -549,7 +549,7 @@ def _get_new_project_action(): return new_action -def prompt_new_file_with_mesh(mesh_filepath): +def prompt_new_file_with_mesh(mesh_filepath, allow_user_setting=True): """Prompts the user for a new file using Substance Painter's own dialog. This will set the mesh path to load to the given mesh and disables the @@ -586,7 +586,6 @@ def prompt_new_file_with_mesh(mesh_filepath): # TODO: find a way to improve the process event to # load more complicated mesh app.processEvents(QtCore.QEventLoop.ExcludeUserInputEvents, 3000) - file_dialog.done(file_dialog.Accepted) app.processEvents(QtCore.QEventLoop.AllEvents) @@ -624,7 +623,8 @@ def prompt_new_file_with_mesh(mesh_filepath): f"{mesh_filepath}\n\n" "Creating new project directly with the mesh path instead.") else: - dialog.done(dialog.Accepted) + if not allow_user_setting: + dialog.done(dialog.Accepted) new_action = _get_new_project_action() if not new_action: 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 07b53fb85c..8809f3b5bf 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -28,6 +28,11 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): @classmethod def get_options(cls, contexts): return [ + BoolDef("allow_user_setting", + default=True, + label="Allow User Setting", + tooltip=("Allow user to set up the project" + " by their own\n")), BoolDef("preserve_strokes", default=True, label="Preserve Strokes", @@ -49,6 +54,7 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): def load(self, context, name, namespace, options=None): # Get user inputs + allow_user_setting = options.get("allow_user_setting", True) import_cameras = options.get("import_cameras", True) preserve_strokes = options.get("preserve_strokes", True) texture_resolution = options.get("texture_resolution", 1024) @@ -61,7 +67,8 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): 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) + result = prompt_new_file_with_mesh( + mesh_filepath=path, allow_user_setting=allow_user_setting) if not result: self.log.info("User cancelled new project prompt." "Creating new project directly from" From be4d65c3d234826ab56d5b5276f35fde55e87d90 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 11 Apr 2024 18:26:31 +0800 Subject: [PATCH 03/65] cosmetic fix --- .../ayon_core/hosts/substancepainter/plugins/load/load_mesh.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 8809f3b5bf..b355400233 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -48,7 +48,7 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): items=[128, 256, 512, 1024, 2048, 4096], default=1024, label="Texture Resolution", - tooltip="Set texture resolution for the project") + tooltip="Set texture resolution when creating new project") ] def load(self, context, name, namespace, options=None): From 1229311d679283e2d8b93e0881b3d85126955da8 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 12 Apr 2024 00:20:05 +0800 Subject: [PATCH 04/65] commit to test on the triggering different file format and file size --- client/ayon_core/hosts/substancepainter/api/lib.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/hosts/substancepainter/api/lib.py b/client/ayon_core/hosts/substancepainter/api/lib.py index 95d45da436..b1aed5d4f3 100644 --- a/client/ayon_core/hosts/substancepainter/api/lib.py +++ b/client/ayon_core/hosts/substancepainter/api/lib.py @@ -577,7 +577,7 @@ def prompt_new_file_with_mesh(mesh_filepath, allow_user_setting=True): assert isinstance(file_dialog, QtWidgets.QFileDialog) # Quickly hide the dialog - file_dialog.hide() + # file_dialog.hide() app.processEvents(QtCore.QEventLoop.ExcludeUserInputEvents, 1000) file_dialog.setDirectory(os.path.dirname(mesh_filepath)) @@ -586,7 +586,7 @@ def prompt_new_file_with_mesh(mesh_filepath, allow_user_setting=True): # TODO: find a way to improve the process event to # load more complicated mesh app.processEvents(QtCore.QEventLoop.ExcludeUserInputEvents, 3000) - file_dialog.done(file_dialog.Accepted) + # file_dialog.done(file_dialog.Accepted) app.processEvents(QtCore.QEventLoop.AllEvents) def _setup_prompt(): From ede44ea0fba00303dd56986e5b6ab7920182bc08 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 12 Apr 2024 17:00:02 +0800 Subject: [PATCH 05/65] specific the time for the process event --- client/ayon_core/hosts/substancepainter/api/lib.py | 11 ++++------- .../hosts/substancepainter/plugins/load/load_mesh.py | 3 +-- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/client/ayon_core/hosts/substancepainter/api/lib.py b/client/ayon_core/hosts/substancepainter/api/lib.py index b1aed5d4f3..64c39943ce 100644 --- a/client/ayon_core/hosts/substancepainter/api/lib.py +++ b/client/ayon_core/hosts/substancepainter/api/lib.py @@ -549,7 +549,7 @@ def _get_new_project_action(): return new_action -def prompt_new_file_with_mesh(mesh_filepath, allow_user_setting=True): +def prompt_new_file_with_mesh(mesh_filepath): """Prompts the user for a new file using Substance Painter's own dialog. This will set the mesh path to load to the given mesh and disables the @@ -577,7 +577,7 @@ def prompt_new_file_with_mesh(mesh_filepath, allow_user_setting=True): assert isinstance(file_dialog, QtWidgets.QFileDialog) # Quickly hide the dialog - # file_dialog.hide() + file_dialog.hide() app.processEvents(QtCore.QEventLoop.ExcludeUserInputEvents, 1000) file_dialog.setDirectory(os.path.dirname(mesh_filepath)) @@ -586,7 +586,7 @@ def prompt_new_file_with_mesh(mesh_filepath, allow_user_setting=True): # TODO: find a way to improve the process event to # load more complicated mesh app.processEvents(QtCore.QEventLoop.ExcludeUserInputEvents, 3000) - # file_dialog.done(file_dialog.Accepted) + file_dialog.done(file_dialog.Accepted) app.processEvents(QtCore.QEventLoop.AllEvents) def _setup_prompt(): @@ -605,7 +605,7 @@ def prompt_new_file_with_mesh(mesh_filepath, allow_user_setting=True): mesh_select.setVisible(False) # Ensure UI is visually up-to-date - app.processEvents(QtCore.QEventLoop.ExcludeUserInputEvents) + app.processEvents(QtCore.QEventLoop.ExcludeUserInputEvents, 8000) # Trigger the 'select file' dialog to set the path and have the # new file dialog to use the path. @@ -622,9 +622,6 @@ def prompt_new_file_with_mesh(mesh_filepath, allow_user_setting=True): "Failed to set mesh path with the prompt dialog:" f"{mesh_filepath}\n\n" "Creating new project directly with the mesh path instead.") - else: - if not allow_user_setting: - dialog.done(dialog.Accepted) new_action = _get_new_project_action() if not new_action: 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 6a521493db..89dbcdbddd 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -67,8 +67,7 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): 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, allow_user_setting=allow_user_setting) + result = prompt_new_file_with_mesh(mesh_filepath=path) if not result: self.log.info("User cancelled new project prompt." "Creating new project directly from" From dada34d6f4bb6b263298dfd5a4c91fd73f47b31c Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 12 Apr 2024 17:00:35 +0800 Subject: [PATCH 06/65] remove allow user settings --- .../hosts/substancepainter/plugins/load/load_mesh.py | 6 ------ 1 file changed, 6 deletions(-) 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 89dbcdbddd..ad81309957 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -28,11 +28,6 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): @classmethod def get_options(cls, contexts): return [ - BoolDef("allow_user_setting", - default=True, - label="Allow User Setting", - tooltip=("Allow user to set up the project" - " by their own\n")), BoolDef("preserve_strokes", default=True, label="Preserve Strokes", @@ -54,7 +49,6 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): def load(self, context, name, namespace, options=None): # Get user inputs - allow_user_setting = options.get("allow_user_setting", True) import_cameras = options.get("import_cameras", True) preserve_strokes = options.get("preserve_strokes", True) texture_resolution = options.get("texture_resolution", 1024) From 74bc0102c829bfad88bbad6d40f8dee6da972447 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 12 Apr 2024 18:23:33 +0800 Subject: [PATCH 07/65] add supports for udim settings in mesh loader --- .../substancepainter/plugins/load/load_mesh.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) 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 ad81309957..562ccc1f80 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -27,6 +27,11 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): @classmethod def get_options(cls, contexts): + project_workflow_option = { + substance_painter.project.ProjectWorkflow.Default: "default", + substance_painter.project.ProjectWorkflow.UVTile: "uvTile", + substance_painter.project.ProjectWorkflow.TextureSetPerUVTile: "textureSetPerUVTile" # noqa + } return [ BoolDef("preserve_strokes", default=True, @@ -43,7 +48,12 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): items=[128, 256, 512, 1024, 2048, 4096], default=1024, label="Texture Resolution", - tooltip="Set texture resolution when creating new project") + tooltip="Set texture resolution when creating new project"), + EnumDef("project_uv_workflow", + items=project_workflow_option, + default="default", + label="UV Workflow", + tooltip="Set UV workflow when creating new project") ] def load(self, context, name, namespace, options=None): @@ -52,9 +62,11 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): import_cameras = options.get("import_cameras", True) preserve_strokes = options.get("preserve_strokes", True) texture_resolution = options.get("texture_resolution", 1024) + uv_workflow = options.get("project_uv_workflow", "default") sp_settings = substance_painter.project.Settings( default_texture_resolution=texture_resolution, - import_cameras=import_cameras + import_cameras=import_cameras, + project_workflow=uv_workflow ) if not substance_painter.project.is_open(): # Allow to 'initialize' a new project From ef71dad1d35f025627645e2c63033fd51c0be861 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Mon, 15 Apr 2024 17:37:43 +0800 Subject: [PATCH 08/65] rename project_uv_workflow_items --- .../hosts/substancepainter/plugins/load/load_mesh.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 562ccc1f80..0816a67b6a 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -27,7 +27,7 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): @classmethod def get_options(cls, contexts): - project_workflow_option = { + project_uv_workflow_items = { substance_painter.project.ProjectWorkflow.Default: "default", substance_painter.project.ProjectWorkflow.UVTile: "uvTile", substance_painter.project.ProjectWorkflow.TextureSetPerUVTile: "textureSetPerUVTile" # noqa @@ -50,7 +50,7 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): label="Texture Resolution", tooltip="Set texture resolution when creating new project"), EnumDef("project_uv_workflow", - items=project_workflow_option, + items=project_uv_workflow_items, default="default", label="UV Workflow", tooltip="Set UV workflow when creating new project") From f2a9eedbda9fca088629a0fa95be4771b6365680 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Mon, 15 Apr 2024 21:27:40 +0800 Subject: [PATCH 09/65] fix the default settings not being able to be cased as python instance --- .../plugins/load/load_mesh.py | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) 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 0816a67b6a..03f47eb451 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -14,6 +14,15 @@ from ayon_core.hosts.substancepainter.api.lib import prompt_new_file_with_mesh 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""" @@ -50,7 +59,7 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): label="Texture Resolution", tooltip="Set texture resolution when creating new project"), EnumDef("project_uv_workflow", - items=project_uv_workflow_items, + items=["default", "uvTile", "textureSetPerUVTile"], default="default", label="UV Workflow", tooltip="Set UV workflow when creating new project") @@ -62,7 +71,8 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): import_cameras = options.get("import_cameras", True) preserve_strokes = options.get("preserve_strokes", True) texture_resolution = options.get("texture_resolution", 1024) - uv_workflow = options.get("project_uv_workflow", "default") + 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, @@ -75,12 +85,16 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): # only works for simple polygon scene result = prompt_new_file_with_mesh(mesh_filepath=path) if not result: - 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 - ) + 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") else: # Reload the mesh From 64a26e21874681102e73cd434de95699f6ac6b09 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 16 Apr 2024 17:40:18 +0800 Subject: [PATCH 10/65] update server-addon settings for template --- .../substancepainter/server/settings/main.py | 79 ++++++++++++++++++- .../substancepainter/server/version.py | 2 +- 2 files changed, 79 insertions(+), 2 deletions(-) diff --git a/server_addon/substancepainter/server/settings/main.py b/server_addon/substancepainter/server/settings/main.py index f80fa9fe1e..20cf6d77b2 100644 --- a/server_addon/substancepainter/server/settings/main.py +++ b/server_addon/substancepainter/server/settings/main.py @@ -2,6 +2,78 @@ 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)") + ) + + class ShelvesSettingsModel(BaseSettingsModel): _layout = "compact" name: str = SettingsField(title="Name") @@ -17,9 +89,14 @@ class SubstancePainterSettings(BaseSettingsModel): default_factory=list, title="Shelves" ) + project_templates: list[ProjectTemplatesModel] = SettingsField( + default_factory=ProjectTemplatesModel, + title="Project Templates" + ) DEFAULT_SPAINTER_SETTINGS = { "imageio": DEFAULT_IMAGEIO_SETTINGS, - "shelves": [] + "shelves": [], + "project_templates": [], } diff --git a/server_addon/substancepainter/server/version.py b/server_addon/substancepainter/server/version.py index 3dc1f76bc6..485f44ac21 100644 --- a/server_addon/substancepainter/server/version.py +++ b/server_addon/substancepainter/server/version.py @@ -1 +1 @@ -__version__ = "0.1.0" +__version__ = "0.1.1" From e5eec7f558e20e138fa532c3a881c27fa89d39d7 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 16 Apr 2024 22:53:09 +0800 Subject: [PATCH 11/65] 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, } From 9aea94bf1fcfa90f8bc539e138ee8e75b42f8380 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 16 Apr 2024 22:55:29 +0800 Subject: [PATCH 12/65] add todo to remember to fix the hard code --- .../hosts/substancepainter/plugins/load/load_mesh.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) 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 563d6eb6e1..631af88eb5 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -2,17 +2,15 @@ from ayon_core.pipeline import ( load, get_representation_path, ) -from ayon_core.lib import BoolDef, EnumDef +from ayon_core.lib import EnumDef from ayon_core.pipeline.load import LoadError from ayon_core.hosts.substancepainter.api.pipeline import ( imprint_container, set_container_metadata, remove_container_metadata ) -from ayon_core.hosts.substancepainter.api.lib import ( - prompt_new_file_with_mesh, - parse_substance_attributes_setting -) +from ayon_core.hosts.substancepainter.api.lib import parse_substance_attributes_setting + import substance_painter.project @@ -83,8 +81,9 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): # We want store some options for updating to keep consistent behavior # from the user's original choice. We don't store 'preserve_strokes' # as we always preserve strokes on updates. + # TODO: update the code container["options"] = { - "import_cameras": import_cameras, + "import_cameras": True, } set_container_metadata(project_mesh_object_name, container) From 878fc9cf2c3fb7a0c5639590993176add3563c41 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 16 Apr 2024 23:28:05 +0800 Subject: [PATCH 13/65] update the attributes options for reloading mesh --- .../hosts/substancepainter/api/lib.py | 47 +++++++++++++++++++ .../plugins/load/load_mesh.py | 17 ++++--- 2 files changed, 57 insertions(+), 7 deletions(-) diff --git a/client/ayon_core/hosts/substancepainter/api/lib.py b/client/ayon_core/hosts/substancepainter/api/lib.py index e344076222..f95e47f99d 100644 --- a/client/ayon_core/hosts/substancepainter/api/lib.py +++ b/client/ayon_core/hosts/substancepainter/api/lib.py @@ -643,6 +643,21 @@ def prompt_new_file_with_mesh(mesh_filepath): def convert_substance_object_to_python(subst_proj_option="default"): + """Function to convert substance C++ objects to python instance. + It is made to avoid any possible ValueError when C++ objects casting + as python instance. + + Args: + subst_proj_option (str, optional): Substance project option. + Defaults to "default". + + Raises: + ValueError: Raise Error when unsupported Substance + Project was detected + + Returns: + python instance: converted python instance of the C++ objects. + """ if subst_proj_option == "default": return substance_painter.project.ProjectWorkflow.Default elif subst_proj_option == "uvTile": @@ -663,6 +678,16 @@ def convert_substance_object_to_python(subst_proj_option="default"): def parse_substance_attributes_setting(template_name, project_templates): + """Function to parse the dictionary from the AYON setting to be used + as the attributes for Substance Project Creation + + Args: + template_name (str): name of the template from the setting + project_templates (dict): project template data from the setting + + Returns: + dict: data to be used as attributes for Substance Project Creation + """ attributes_data = {} for template in project_templates: if template["name"] == template_name: @@ -676,3 +701,25 @@ def parse_substance_attributes_setting(template_name, project_templates): attributes_data.pop("name") attributes_data.pop("preserve_strokes") return attributes_data + + +def parse_subst_attrs_reloading_mesh(template_name, project_templates): + """Function to parse the substances attributes ('import_cameras' + and 'preserve_strokes') for reloading mesh + with the existing projects. + + Args: + template_name (str): name of the template from the setting + project_templates (dict): project template data from the setting + + Returns: + dict: data to be used as attributes for reloading mesh with the + existing project + """ + attributes_data = {} + for template in project_templates: + if template["name"] == template_name: + for key, value in template.items(): + if isinstance(value, bool): + attributes_data.update({key: value}) + 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 631af88eb5..49f11251c9 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -9,7 +9,10 @@ from ayon_core.hosts.substancepainter.api.pipeline import ( set_container_metadata, remove_container_metadata ) -from ayon_core.hosts.substancepainter.api.lib import parse_substance_attributes_setting +from ayon_core.hosts.substancepainter.api.lib import ( + parse_substance_attributes_setting, + parse_subst_attrs_reloading_mesh +) import substance_painter.project @@ -41,7 +44,8 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): # Get user inputs template_name = options.get("project_template", "default") - template_settings = parse_substance_attributes_setting(template_name, self.project_templates) + 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 @@ -52,11 +56,10 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): ) else: # Reload the mesh + mesh_settings = parse_subst_attrs_reloading_mesh( + template_name, self.project_templates) # TODO: fix the hardcoded when the preset setting in SP addon. - settings = substance_painter.project.MeshReloadingSettings( - import_cameras=True, - preserve_strokes=True - ) + settings = substance_painter.project.MeshReloadingSettings(**mesh_settings) def on_mesh_reload(status: substance_painter.project.ReloadMeshStatus): # noqa if status == substance_painter.project.ReloadMeshStatus.SUCCESS: # noqa @@ -83,7 +86,7 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): # as we always preserve strokes on updates. # TODO: update the code container["options"] = { - "import_cameras": True, + "import_cameras": template_settings["import_cameras"], } set_container_metadata(project_mesh_object_name, container) From d4fdf8530605ca4f03957415f48d99eef292d11b Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 17 Apr 2024 22:45:47 +0800 Subject: [PATCH 14/65] Add Qt dialog to support users to choose their templates for project creation --- .../hosts/substancepainter/api/lib.py | 83 ----------- .../plugins/load/load_mesh.py | 136 +++++++++++++++--- .../server/settings/load_plugins.py | 36 +++-- 3 files changed, 145 insertions(+), 110 deletions(-) diff --git a/client/ayon_core/hosts/substancepainter/api/lib.py b/client/ayon_core/hosts/substancepainter/api/lib.py index f95e47f99d..64c39943ce 100644 --- a/client/ayon_core/hosts/substancepainter/api/lib.py +++ b/client/ayon_core/hosts/substancepainter/api/lib.py @@ -640,86 +640,3 @@ def prompt_new_file_with_mesh(mesh_filepath): return return project_mesh - - -def convert_substance_object_to_python(subst_proj_option="default"): - """Function to convert substance C++ objects to python instance. - It is made to avoid any possible ValueError when C++ objects casting - as python instance. - - Args: - subst_proj_option (str, optional): Substance project option. - Defaults to "default". - - Raises: - ValueError: Raise Error when unsupported Substance - Project was detected - - Returns: - python instance: converted python instance of the C++ objects. - """ - 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): - """Function to parse the dictionary from the AYON setting to be used - as the attributes for Substance Project Creation - - Args: - template_name (str): name of the template from the setting - project_templates (dict): project template data from the setting - - Returns: - dict: data to be used as attributes for Substance Project Creation - """ - 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 - - -def parse_subst_attrs_reloading_mesh(template_name, project_templates): - """Function to parse the substances attributes ('import_cameras' - and 'preserve_strokes') for reloading mesh - with the existing projects. - - Args: - template_name (str): name of the template from the setting - project_templates (dict): project template data from the setting - - Returns: - dict: data to be used as attributes for reloading mesh with the - existing project - """ - attributes_data = {} - for template in project_templates: - if template["name"] == template_name: - for key, value in template.items(): - if isinstance(value, bool): - attributes_data.update({key: value}) - 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 49f11251c9..b377cf9a1d 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -1,23 +1,130 @@ +from qtpy import QtWidgets, QtCore from ayon_core.pipeline import ( load, get_representation_path, ) -from ayon_core.lib import EnumDef from ayon_core.pipeline.load import LoadError from ayon_core.hosts.substancepainter.api.pipeline import ( imprint_container, set_container_metadata, remove_container_metadata ) -from ayon_core.hosts.substancepainter.api.lib import ( - parse_substance_attributes_setting, - parse_subst_attrs_reloading_mesh -) - import substance_painter.project +def _convert(subst_attr): + """Function to convert substance C++ objects to python instance. + It is made to avoid any possible ValueError when C++ objects casting + as python instance. + + Args: + subst_attr (str): Substance attributes + + Raises: + ValueError: Raise Error when unsupported Substance + Project was detected + + Returns: + python instance: converted python instance of the C++ objects. + """ + if subst_attr in {"Default", "UVTile", "TextureSetPerUVTile"}: + return getattr(substance_painter.project.ProjectWorkflow, subst_attr) + elif subst_attr in {"PerFragment", "PerVertex"}: + return getattr(substance_painter.project.TangentSpace, subst_attr) + elif subst_attr in {"DirectX", "OpenGL"}: + return getattr(substance_painter.project.NormalMapFormat, subst_attr) + else: + raise ValueError( + f"Unsupported Substance Objects: {subst_attr}") + + +def parse_substance_attributes_setting(template_name, project_templates): + """Function to parse the dictionary from the AYON setting to be used + as the attributes for Substance Project Creation + + Args: + template_name (str): name of the template from the setting + project_templates (dict): project template data from the setting + + Returns: + dict: data to be used as attributes for Substance Project Creation + """ + attributes_data = {} + for template in project_templates: + if template["name"] == template_name: + attributes_data.update(template) + attributes_data["normal_map_format"] = _convert( + attributes_data["normal_map_format"]) + attributes_data["project_workflow"] = _convert( + attributes_data["project_workflow"]) + attributes_data["tangent_space_mode"] = _convert( + attributes_data["tangent_space_mode"]) + attributes_data.pop("name") + attributes_data.pop("preserve_strokes") + return attributes_data + + +def parse_subst_attrs_reloading_mesh(template_name, project_templates): + """Function to parse the substances attributes ('import_cameras' + and 'preserve_strokes') for reloading mesh + with the existing projects. + + Args: + template_name (str): name of the template from the setting + project_templates (dict): project template data from the setting + + Returns: + dict: data to be used as attributes for reloading mesh with the + existing project + """ + attributes_data = {} + for template in project_templates: + if template["name"] == template_name: + for key, value in template.items(): + if isinstance(value, bool): + attributes_data.update({key: value}) + return attributes_data + + +class SubstanceProjectConfigurationWindow(QtWidgets.QDialog): + """The pop-up dialog allows users to choose material + duplicate options for importing Max objects when updating + or switching assets. + """ + def __init__(self, project_templates): + super(SubstanceProjectConfigurationWindow, self).__init__() + self.setWindowFlags(self.windowFlags() | QtCore.Qt.FramelessWindowHint) + + self.template_name = None + self.project_templates = project_templates + + self.widgets = { + "label": QtWidgets.QLabel("Project Configuration"), + "template_options": QtWidgets.QComboBox(), + "buttons": QtWidgets.QWidget(), + "okButton": QtWidgets.QPushButton("Ok"), + } + for template in project_templates: + self.widgets["template_options"].addItem(template) + # Build buttons. + layout = QtWidgets.QHBoxLayout(self.widgets["buttons"]) + layout.addWidget(self.widgets["template_options"]) + layout.addWidget(self.widgets["okButton"]) + # Build layout. + layout = QtWidgets.QVBoxLayout(self) + layout.addWidget(self.widgets["label"]) + layout.addWidget(self.widgets["buttons"]) + + self.widgets["okButton"].pressed.connect(self.on_ok_pressed) + + def on_ok_pressed(self): + self.template_name = ( + self.widgets["template_options"].currentText() + ) + self.close() + + class SubstanceLoadProjectMesh(load.LoaderPlugin): """Load mesh for project""" @@ -30,20 +137,13 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): color = "orange" project_templates = [] - @classmethod - def get_options(cls, contexts): - template_enum = [template["name"] for template in cls.project_templates] - return [ - EnumDef("project_template", - items=template_enum, - default="default", - label="Project Template") - ] - def load(self, context, name, namespace, options=None): - # Get user inputs - template_name = options.get("project_template", "default") + template_enum = [template["name"] for template in self.project_templates] + window = SubstanceProjectConfigurationWindow(template_enum) + window.exec_() + template_name = window.template_name + template_settings = parse_substance_attributes_setting( template_name, self.project_templates) sp_settings = substance_painter.project.Settings(**template_settings) diff --git a/server_addon/substancepainter/server/settings/load_plugins.py b/server_addon/substancepainter/server/settings/load_plugins.py index 4d3e64f0b6..294ecfcef6 100644 --- a/server_addon/substancepainter/server/settings/load_plugins.py +++ b/server_addon/substancepainter/server/settings/load_plugins.py @@ -10,17 +10,17 @@ def normal_map_format_enum(): def tangent_space_enum(): return [ - {"label": "PerFragment", "value": "PerFragment"}, - {"label": "PerVertex", "value": "PerVertex"}, + {"label": "Per Fragment", "value": "PerFragment"}, + {"label": "Per Vertex", "value": "PerVertex"}, ] def uv_workflow_enum(): return [ - {"label": "Default", "value": "default"}, - {"label": "UV Tile", "value": "uvTile"}, + {"label": "Default", "value": "Default"}, + {"label": "UV Tile", "value": "UVTile"}, {"label": "Texture Set Per UV Tile", - "value": "textureSetPerUVTile"} + "value": "TextureSetPerUVTile"} ] @@ -54,7 +54,7 @@ class ProjectTemplatesModel(BaseSettingsModel): "creating new project.") ) project_workflow: str = SettingsField( - "default", enum_resolver=uv_workflow_enum, + "Default", enum_resolver=uv_workflow_enum, title="UV Tile Settings", description=("Set UV workflow when " "creating new project.") @@ -90,11 +90,29 @@ class LoadersModel(BaseSettingsModel): DEFAULT_LOADER_SETTINGS = { "SubstanceLoadProjectMesh":{ "project_templates": [{ - "name": "default", - "default_texture_resolution": 1024, + "name": "2K(Default)", + "default_texture_resolution": 2048, "import_cameras": True, "normal_map_format": "DirectX", - "project_workflow": "default", + "project_workflow": "Default", + "tangent_space_mode": "PerFragment", + "preserve_strokes": True + }, + { + "name": "2K(UV tile)", + "default_texture_resolution": 2048, + "import_cameras": True, + "normal_map_format": "DirectX", + "project_workflow": "UVTile", + "tangent_space_mode": "PerFragment", + "preserve_strokes": True + }, + { + "name": "4K(Custom)", + "default_texture_resolution": 4096, + "import_cameras": True, + "normal_map_format": "OpenGL", + "project_workflow": "UVTile", "tangent_space_mode": "PerFragment", "preserve_strokes": True }] From 81bdaf9915b51e1b6f41cb95cbab703def72c19e Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 18 Apr 2024 00:06:33 +0800 Subject: [PATCH 15/65] optimize the codes and the settings for loading mesh more smoothly --- .../plugins/load/load_mesh.py | 95 ++++++------------- .../server/settings/load_plugins.py | 14 +-- 2 files changed, 35 insertions(+), 74 deletions(-) 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 b377cf9a1d..8f23600216 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -13,10 +13,10 @@ from ayon_core.hosts.substancepainter.api.pipeline import ( import substance_painter.project -def _convert(subst_attr): +def _convert(substance_attr): """Function to convert substance C++ objects to python instance. - It is made to avoid any possible ValueError when C++ objects casting - as python instance. + It is made to avoid any possible ValueError when C++ objects is + converted to the Substance Painter Python API equivalent objects. Args: subst_attr (str): Substance attributes @@ -28,63 +28,21 @@ def _convert(subst_attr): Returns: python instance: converted python instance of the C++ objects. """ - if subst_attr in {"Default", "UVTile", "TextureSetPerUVTile"}: - return getattr(substance_painter.project.ProjectWorkflow, subst_attr) - elif subst_attr in {"PerFragment", "PerVertex"}: - return getattr(substance_painter.project.TangentSpace, subst_attr) - elif subst_attr in {"DirectX", "OpenGL"}: - return getattr(substance_painter.project.NormalMapFormat, subst_attr) - else: - raise ValueError( - f"Unsupported Substance Objects: {subst_attr}") + root = substance_painter.project + for attr in substance_attr.split("."): + root = getattr(root, attr, None) + if root is None: + raise ValueError( + f"Substance Painter project attribute does not exist: {substance_attr}") + + return root -def parse_substance_attributes_setting(template_name, project_templates): - """Function to parse the dictionary from the AYON setting to be used - as the attributes for Substance Project Creation - - Args: - template_name (str): name of the template from the setting - project_templates (dict): project template data from the setting - - Returns: - dict: data to be used as attributes for Substance Project Creation - """ - attributes_data = {} - for template in project_templates: - if template["name"] == template_name: - attributes_data.update(template) - attributes_data["normal_map_format"] = _convert( - attributes_data["normal_map_format"]) - attributes_data["project_workflow"] = _convert( - attributes_data["project_workflow"]) - attributes_data["tangent_space_mode"] = _convert( - attributes_data["tangent_space_mode"]) - attributes_data.pop("name") - attributes_data.pop("preserve_strokes") - return attributes_data - - -def parse_subst_attrs_reloading_mesh(template_name, project_templates): - """Function to parse the substances attributes ('import_cameras' - and 'preserve_strokes') for reloading mesh - with the existing projects. - - Args: - template_name (str): name of the template from the setting - project_templates (dict): project template data from the setting - - Returns: - dict: data to be used as attributes for reloading mesh with the - existing project - """ - attributes_data = {} - for template in project_templates: - if template["name"] == template_name: - for key, value in template.items(): - if isinstance(value, bool): - attributes_data.update({key: value}) - return attributes_data +def get_template_by_name(name: str, templates: list[dict]) -> dict: + return next( + template for template in templates + if template["name"] == name + ) class SubstanceProjectConfigurationWindow(QtWidgets.QDialog): @@ -139,14 +97,18 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): def load(self, context, name, namespace, options=None): # Get user inputs + print(self.project_templates) template_enum = [template["name"] for template in self.project_templates] window = SubstanceProjectConfigurationWindow(template_enum) window.exec_() template_name = window.template_name - - template_settings = parse_substance_attributes_setting( - template_name, self.project_templates) - sp_settings = substance_painter.project.Settings(**template_settings) + template = get_template_by_name(template_name, self.project_templates) + sp_settings = substance_painter.project.Settings( + normal_map_format=_convert(template["normal_map_format"]), + project_workflow=_convert(template["project_workflow"]), + tangent_space_mode=_convert(template["tangent_space_mode"]), + default_texture_resolution=template["default_texture_resolution"] + ) if not substance_painter.project.is_open(): # Allow to 'initialize' a new project path = self.filepath_from_context(context) @@ -156,10 +118,9 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): ) else: # Reload the mesh - mesh_settings = parse_subst_attrs_reloading_mesh( - template_name, self.project_templates) - # TODO: fix the hardcoded when the preset setting in SP addon. - settings = substance_painter.project.MeshReloadingSettings(**mesh_settings) + settings = substance_painter.project.MeshReloadingSettings( + import_cameras=template["import_cameras"], + preserve_strokes=template["preserve_strokes"]) def on_mesh_reload(status: substance_painter.project.ReloadMeshStatus): # noqa if status == substance_painter.project.ReloadMeshStatus.SUCCESS: # noqa @@ -186,7 +147,7 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): # as we always preserve strokes on updates. # TODO: update the code container["options"] = { - "import_cameras": template_settings["import_cameras"], + "import_cameras": template["import_cameras"], } set_container_metadata(project_mesh_object_name, container) diff --git a/server_addon/substancepainter/server/settings/load_plugins.py b/server_addon/substancepainter/server/settings/load_plugins.py index 294ecfcef6..b404ad4316 100644 --- a/server_addon/substancepainter/server/settings/load_plugins.py +++ b/server_addon/substancepainter/server/settings/load_plugins.py @@ -3,24 +3,24 @@ from ayon_server.settings import BaseSettingsModel, SettingsField def normal_map_format_enum(): return [ - {"label": "DirectX", "value": "DirectX"}, - {"label": "OpenGL", "value": "OpenGL"}, + {"label": "DirectX", "value": "NormalMapFormat.DirectX"}, + {"label": "OpenGL", "value": "NormalMapFormat.OpenGL"}, ] def tangent_space_enum(): return [ - {"label": "Per Fragment", "value": "PerFragment"}, - {"label": "Per Vertex", "value": "PerVertex"}, + {"label": "Per Fragment", "value": "TangentSpace.PerFragment"}, + {"label": "Per Vertex", "value": "TangentSpace.PerVertex"}, ] def uv_workflow_enum(): return [ - {"label": "Default", "value": "Default"}, - {"label": "UV Tile", "value": "UVTile"}, + {"label": "Default", "value": "ProjectWorkflow.Default"}, + {"label": "UV Tile", "value": "ProjectWorkflow.UVTile"}, {"label": "Texture Set Per UV Tile", - "value": "TextureSetPerUVTile"} + "value": "ProjectWorkflow.TextureSetPerUVTile"} ] From 425f7cbd89c3ac695b39373b9283df3b83de410b Mon Sep 17 00:00:00 2001 From: Kayla Man <64118225+moonyuet@users.noreply.github.com> Date: Thu, 18 Apr 2024 13:13:55 +0800 Subject: [PATCH 16/65] Update server_addon/substancepainter/server/settings/load_plugins.py Co-authored-by: Roy Nieterau --- .../server/settings/load_plugins.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/server_addon/substancepainter/server/settings/load_plugins.py b/server_addon/substancepainter/server/settings/load_plugins.py index b404ad4316..ed9b6f0d64 100644 --- a/server_addon/substancepainter/server/settings/load_plugins.py +++ b/server_addon/substancepainter/server/settings/load_plugins.py @@ -93,27 +93,27 @@ DEFAULT_LOADER_SETTINGS = { "name": "2K(Default)", "default_texture_resolution": 2048, "import_cameras": True, - "normal_map_format": "DirectX", - "project_workflow": "Default", - "tangent_space_mode": "PerFragment", + "normal_map_format": "NormalMapFormat.DirectX", + "project_workflow": "ProjectWorkflow.Default", + "tangent_space_mode": "TangentSpace.PerFragment", "preserve_strokes": True }, { "name": "2K(UV tile)", "default_texture_resolution": 2048, "import_cameras": True, - "normal_map_format": "DirectX", - "project_workflow": "UVTile", - "tangent_space_mode": "PerFragment", + "normal_map_format": "NormalMapFormat.DirectX", + "project_workflow": "ProjectWorkflow.UVTile", + "tangent_space_mode": "TangentSpace.PerFragment", "preserve_strokes": True }, { "name": "4K(Custom)", "default_texture_resolution": 4096, "import_cameras": True, - "normal_map_format": "OpenGL", - "project_workflow": "UVTile", - "tangent_space_mode": "PerFragment", + "normal_map_format": "NormalMapFormat.OpenGL", + "project_workflow": "ProjectWorkflow.UVTile", + "tangent_space_mode": "TangentSpace.PerFragment", "preserve_strokes": True }] } From 53627d34d3762ca2ec2396f315ff7515b93a1993 Mon Sep 17 00:00:00 2001 From: Kayla Man <64118225+moonyuet@users.noreply.github.com> Date: Thu, 18 Apr 2024 13:14:15 +0800 Subject: [PATCH 17/65] Update client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py Co-authored-by: Roy Nieterau --- .../plugins/load/load_mesh.py | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) 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 8f23600216..7af0d71a1d 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -14,19 +14,22 @@ import substance_painter.project def _convert(substance_attr): - """Function to convert substance C++ objects to python instance. - It is made to avoid any possible ValueError when C++ objects is - converted to the Substance Painter Python API equivalent objects. + """Return Substance Painter Python API Project attribute from string. + + This converts a string like "ProjectWorkflow.Default" to for example + the Substance Painter Python API equivalent object, like: + `substance_painter.project.ProjectWorkflow.Default` Args: - subst_attr (str): Substance attributes - - Raises: - ValueError: Raise Error when unsupported Substance - Project was detected + substance_attr (str): The `substance_painter.project` attribute, + for example "ProjectWorkflow.Default" Returns: - python instance: converted python instance of the C++ objects. + Any: Substance Python API object of the project attribute. + + Raises: + ValueError: If attribute does not exist on the + `substance_painter.project` python api. """ root = substance_painter.project for attr in substance_attr.split("."): From ca442c52cd18b0594a80af53c129ca5c567e440b Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 18 Apr 2024 14:00:14 +0800 Subject: [PATCH 18/65] remove print function --- .../ayon_core/hosts/substancepainter/plugins/load/load_mesh.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 7af0d71a1d..16a525b279 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -99,8 +99,8 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): project_templates = [] def load(self, context, name, namespace, options=None): + # Get user inputs - print(self.project_templates) template_enum = [template["name"] for template in self.project_templates] window = SubstanceProjectConfigurationWindow(template_enum) window.exec_() From 5bb61efab28c09fdaa51a2965e019e58e07c20e6 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 18 Apr 2024 14:50:56 +0800 Subject: [PATCH 19/65] cosmetic fix --- .../plugins/load/load_mesh.py | 6 +- .../server/settings/load_plugins.py | 62 ++++++++++--------- 2 files changed, 36 insertions(+), 32 deletions(-) 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 16a525b279..b3f0109942 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -36,7 +36,8 @@ def _convert(substance_attr): root = getattr(root, attr, None) if root is None: raise ValueError( - f"Substance Painter project attribute does not exist: {substance_attr}") + "Substance Painter project attribute" + f" does not exist: {substance_attr}") return root @@ -101,7 +102,8 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): def load(self, context, name, namespace, options=None): # Get user inputs - template_enum = [template["name"] for template in self.project_templates] + template_enum = [template["name"] for template + in self.project_templates] window = SubstanceProjectConfigurationWindow(template_enum) window.exec_() template_name = window.template_name diff --git a/server_addon/substancepainter/server/settings/load_plugins.py b/server_addon/substancepainter/server/settings/load_plugins.py index ed9b6f0d64..e6b2fd86c3 100644 --- a/server_addon/substancepainter/server/settings/load_plugins.py +++ b/server_addon/substancepainter/server/settings/load_plugins.py @@ -74,10 +74,10 @@ class ProjectTemplatesModel(BaseSettingsModel): class ProjectTemplateSettingModel(BaseSettingsModel): - project_templates: list[ProjectTemplatesModel] = SettingsField( + project_templates: list[ProjectTemplatesModel] = SettingsField( default_factory=ProjectTemplatesModel, title="Project Templates" -) + ) class LoadersModel(BaseSettingsModel): @@ -88,33 +88,35 @@ class LoadersModel(BaseSettingsModel): DEFAULT_LOADER_SETTINGS = { - "SubstanceLoadProjectMesh":{ - "project_templates": [{ - "name": "2K(Default)", - "default_texture_resolution": 2048, - "import_cameras": True, - "normal_map_format": "NormalMapFormat.DirectX", - "project_workflow": "ProjectWorkflow.Default", - "tangent_space_mode": "TangentSpace.PerFragment", - "preserve_strokes": True - }, - { - "name": "2K(UV tile)", - "default_texture_resolution": 2048, - "import_cameras": True, - "normal_map_format": "NormalMapFormat.DirectX", - "project_workflow": "ProjectWorkflow.UVTile", - "tangent_space_mode": "TangentSpace.PerFragment", - "preserve_strokes": True - }, - { - "name": "4K(Custom)", - "default_texture_resolution": 4096, - "import_cameras": True, - "normal_map_format": "NormalMapFormat.OpenGL", - "project_workflow": "ProjectWorkflow.UVTile", - "tangent_space_mode": "TangentSpace.PerFragment", - "preserve_strokes": True - }] + "SubstanceLoadProjectMesh": { + "project_templates": [ + { + "name": "2K(Default)", + "default_texture_resolution": 2048, + "import_cameras": True, + "normal_map_format": "NormalMapFormat.DirectX", + "project_workflow": "ProjectWorkflow.Default", + "tangent_space_mode": "TangentSpace.PerFragment", + "preserve_strokes": True + }, + { + "name": "2K(UV tile)", + "default_texture_resolution": 2048, + "import_cameras": True, + "normal_map_format": "NormalMapFormat.DirectX", + "project_workflow": "ProjectWorkflow.UVTile", + "tangent_space_mode": "TangentSpace.PerFragment", + "preserve_strokes": True + }, + { + "name": "4K(Custom)", + "default_texture_resolution": 4096, + "import_cameras": True, + "normal_map_format": "NormalMapFormat.OpenGL", + "project_workflow": "ProjectWorkflow.UVTile", + "tangent_space_mode": "TangentSpace.PerFragment", + "preserve_strokes": True + } + ] } } From f7c8a23d98729dd462bf60026682bfa3f2e09ae6 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 18 Apr 2024 21:23:23 +0800 Subject: [PATCH 20/65] add import cameras and perserve strokes into the project configuration dialog --- .../plugins/load/load_mesh.py | 29 +++++++++++++++---- .../server/settings/load_plugins.py | 21 ++------------ 2 files changed, 26 insertions(+), 24 deletions(-) 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 b3f0109942..2560bd96ae 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -58,29 +58,44 @@ class SubstanceProjectConfigurationWindow(QtWidgets.QDialog): super(SubstanceProjectConfigurationWindow, self).__init__() self.setWindowFlags(self.windowFlags() | QtCore.Qt.FramelessWindowHint) + self.import_cameras = False + self.preserve_strokes = False self.template_name = None self.project_templates = project_templates self.widgets = { "label": QtWidgets.QLabel("Project Configuration"), "template_options": QtWidgets.QComboBox(), - "buttons": QtWidgets.QWidget(), + "import_cameras": QtWidgets.QCheckBox("Improve Cameras"), + "preserve_strokes": QtWidgets.QCheckBox("Preserve Strokes"), + "clickbox": QtWidgets.QWidget(), + "combobox": QtWidgets.QWidget(), "okButton": QtWidgets.QPushButton("Ok"), } for template in project_templates: self.widgets["template_options"].addItem(template) + + # Build clickboxes + layout = QtWidgets.QHBoxLayout(self.widgets["clickbox"]) + layout.addWidget(self.widgets["import_cameras"]) + layout.addWidget(self.widgets["preserve_strokes"]) # Build buttons. - layout = QtWidgets.QHBoxLayout(self.widgets["buttons"]) + layout = QtWidgets.QHBoxLayout(self.widgets["combobox"]) layout.addWidget(self.widgets["template_options"]) layout.addWidget(self.widgets["okButton"]) # Build layout. layout = QtWidgets.QVBoxLayout(self) layout.addWidget(self.widgets["label"]) - layout.addWidget(self.widgets["buttons"]) + layout.addWidget(self.widgets["clickbox"]) + layout.addWidget(self.widgets["combobox"]) self.widgets["okButton"].pressed.connect(self.on_ok_pressed) def on_ok_pressed(self): + if self.widgets["import_cameras"].isChecked(): + self.import_cameras = True + if self.widgets["preserve_strokes"].isChecked(): + self.preserve_strokes = True self.template_name = ( self.widgets["template_options"].currentText() ) @@ -107,6 +122,8 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): window = SubstanceProjectConfigurationWindow(template_enum) window.exec_() template_name = window.template_name + import_cameras = window.import_cameras + preserve_strokes = window.preserve_strokes template = get_template_by_name(template_name, self.project_templates) sp_settings = substance_painter.project.Settings( normal_map_format=_convert(template["normal_map_format"]), @@ -124,8 +141,8 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): else: # Reload the mesh settings = substance_painter.project.MeshReloadingSettings( - import_cameras=template["import_cameras"], - preserve_strokes=template["preserve_strokes"]) + import_cameras=import_cameras, + preserve_strokes=preserve_strokes) def on_mesh_reload(status: substance_painter.project.ReloadMeshStatus): # noqa if status == substance_painter.project.ReloadMeshStatus.SUCCESS: # noqa @@ -152,7 +169,7 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): # as we always preserve strokes on updates. # TODO: update the code container["options"] = { - "import_cameras": template["import_cameras"], + "import_cameras": import_cameras, } set_container_metadata(project_mesh_object_name, container) diff --git a/server_addon/substancepainter/server/settings/load_plugins.py b/server_addon/substancepainter/server/settings/load_plugins.py index e6b2fd86c3..e5519c9773 100644 --- a/server_addon/substancepainter/server/settings/load_plugins.py +++ b/server_addon/substancepainter/server/settings/load_plugins.py @@ -44,9 +44,6 @@ class ProjectTemplatesModel(BaseSettingsModel): 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", @@ -65,12 +62,6 @@ class ProjectTemplatesModel(BaseSettingsModel): 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): @@ -93,29 +84,23 @@ DEFAULT_LOADER_SETTINGS = { { "name": "2K(Default)", "default_texture_resolution": 2048, - "import_cameras": True, "normal_map_format": "NormalMapFormat.DirectX", "project_workflow": "ProjectWorkflow.Default", - "tangent_space_mode": "TangentSpace.PerFragment", - "preserve_strokes": True + "tangent_space_mode": "TangentSpace.PerFragment" }, { "name": "2K(UV tile)", "default_texture_resolution": 2048, - "import_cameras": True, "normal_map_format": "NormalMapFormat.DirectX", "project_workflow": "ProjectWorkflow.UVTile", - "tangent_space_mode": "TangentSpace.PerFragment", - "preserve_strokes": True + "tangent_space_mode": "TangentSpace.PerFragment" }, { "name": "4K(Custom)", "default_texture_resolution": 4096, - "import_cameras": True, "normal_map_format": "NormalMapFormat.OpenGL", "project_workflow": "ProjectWorkflow.UVTile", - "tangent_space_mode": "TangentSpace.PerFragment", - "preserve_strokes": True + "tangent_space_mode": "TangentSpace.PerFragment" } ] } From 5875016e5f3b9094de3c24a80fd7c8f650e059f6 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 18 Apr 2024 22:06:38 +0800 Subject: [PATCH 21/65] import cameras instead of improve camertas --- .../ayon_core/hosts/substancepainter/plugins/load/load_mesh.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 2560bd96ae..8536914095 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -66,7 +66,7 @@ class SubstanceProjectConfigurationWindow(QtWidgets.QDialog): self.widgets = { "label": QtWidgets.QLabel("Project Configuration"), "template_options": QtWidgets.QComboBox(), - "import_cameras": QtWidgets.QCheckBox("Improve Cameras"), + "import_cameras": QtWidgets.QCheckBox("Import Cameras"), "preserve_strokes": QtWidgets.QCheckBox("Preserve Strokes"), "clickbox": QtWidgets.QWidget(), "combobox": QtWidgets.QWidget(), From d5b0f2274837f9cec8c9d74433e3cc57bf513d1f Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 19 Apr 2024 16:07:54 +0800 Subject: [PATCH 22/65] redesign the dialog with ok & cancel button and links the boolean options to the AYON settings --- .../plugins/load/load_mesh.py | 65 ++++++++++++++++--- .../server/settings/load_plugins.py | 21 +++++- 2 files changed, 73 insertions(+), 13 deletions(-) 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 8536914095..42a3e5b5b2 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -61,35 +61,70 @@ class SubstanceProjectConfigurationWindow(QtWidgets.QDialog): self.import_cameras = False self.preserve_strokes = False self.template_name = None + self.template_names = [template["name"] for template + in project_templates] self.project_templates = project_templates self.widgets = { - "label": QtWidgets.QLabel("Project Configuration"), + "label": QtWidgets.QLabel( + "Select your template for project configuration"), "template_options": QtWidgets.QComboBox(), "import_cameras": QtWidgets.QCheckBox("Import Cameras"), "preserve_strokes": QtWidgets.QCheckBox("Preserve Strokes"), "clickbox": QtWidgets.QWidget(), "combobox": QtWidgets.QWidget(), + "buttons": QtWidgets.QWidget(), "okButton": QtWidgets.QPushButton("Ok"), + "cancelButton": QtWidgets.QPushButton("Cancel") } - for template in project_templates: + for template in self.template_names: self.widgets["template_options"].addItem(template) + template_name = self.widgets["template_options"].currentText() + + self.import_cameras = next(template["import_cameras"] for + template in self.project_templates + if template["name"] == template_name) + self.preserve_strokes = next(template["preserve_strokes"] for + template in self.project_templates + if template["name"] == template_name) + self.widgets["import_cameras"].setChecked(self.import_cameras) + self.widgets["preserve_strokes"].setChecked(self.preserve_strokes) + # Build clickboxes layout = QtWidgets.QHBoxLayout(self.widgets["clickbox"]) layout.addWidget(self.widgets["import_cameras"]) layout.addWidget(self.widgets["preserve_strokes"]) - # Build buttons. + # Build combobox layout = QtWidgets.QHBoxLayout(self.widgets["combobox"]) layout.addWidget(self.widgets["template_options"]) + + # Build buttons + layout = QtWidgets.QHBoxLayout(self.widgets["buttons"]) layout.addWidget(self.widgets["okButton"]) + layout.addWidget(self.widgets["cancelButton"]) + # Build layout. layout = QtWidgets.QVBoxLayout(self) layout.addWidget(self.widgets["label"]) layout.addWidget(self.widgets["clickbox"]) layout.addWidget(self.widgets["combobox"]) + layout.addWidget(self.widgets["buttons"]) + self.widgets["template_options"].currentTextChanged.connect( + self.on_options_changed) self.widgets["okButton"].pressed.connect(self.on_ok_pressed) + self.widgets["cancelButton"].pressed.connect(self.on_cancel_pressed) + + def on_options_changed(self, value): + self.import_cameras = next(template["import_cameras"] for + template in self.project_templates + if template["name"] == value) + self.preserve_strokes = next(template["preserve_strokes"] for + template in self.project_templates + if template["name"] == value) + self.widgets["import_cameras"].setChecked(self.import_cameras) + self.widgets["preserve_strokes"].setChecked(self.preserve_strokes) def on_ok_pressed(self): if self.widgets["import_cameras"].isChecked(): @@ -101,6 +136,16 @@ class SubstanceProjectConfigurationWindow(QtWidgets.QDialog): ) self.close() + def on_cancel_pressed(self): + self.template_name = None + self.close() + + @classmethod + def prompt(cls, templates): + dialog = cls(templates) + dialog.exec_() + return dialog + class SubstanceLoadProjectMesh(load.LoaderPlugin): """Load mesh for project""" @@ -117,13 +162,12 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): def load(self, context, name, namespace, options=None): # Get user inputs - template_enum = [template["name"] for template - in self.project_templates] - window = SubstanceProjectConfigurationWindow(template_enum) - window.exec_() - template_name = window.template_name - import_cameras = window.import_cameras - preserve_strokes = window.preserve_strokes + result = SubstanceProjectConfigurationWindow.prompt( + self.project_templates) + template_name = result.template_name + if template_name is None: + return + import_cameras = result.import_cameras template = get_template_by_name(template_name, self.project_templates) sp_settings = substance_painter.project.Settings( normal_map_format=_convert(template["normal_map_format"]), @@ -140,6 +184,7 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): ) else: # Reload the mesh + preserve_strokes = result.preserve_strokes settings = substance_painter.project.MeshReloadingSettings( import_cameras=import_cameras, preserve_strokes=preserve_strokes) diff --git a/server_addon/substancepainter/server/settings/load_plugins.py b/server_addon/substancepainter/server/settings/load_plugins.py index e5519c9773..e6b2fd86c3 100644 --- a/server_addon/substancepainter/server/settings/load_plugins.py +++ b/server_addon/substancepainter/server/settings/load_plugins.py @@ -44,6 +44,9 @@ class ProjectTemplatesModel(BaseSettingsModel): 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", @@ -62,6 +65,12 @@ class ProjectTemplatesModel(BaseSettingsModel): 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): @@ -84,23 +93,29 @@ DEFAULT_LOADER_SETTINGS = { { "name": "2K(Default)", "default_texture_resolution": 2048, + "import_cameras": True, "normal_map_format": "NormalMapFormat.DirectX", "project_workflow": "ProjectWorkflow.Default", - "tangent_space_mode": "TangentSpace.PerFragment" + "tangent_space_mode": "TangentSpace.PerFragment", + "preserve_strokes": True }, { "name": "2K(UV tile)", "default_texture_resolution": 2048, + "import_cameras": True, "normal_map_format": "NormalMapFormat.DirectX", "project_workflow": "ProjectWorkflow.UVTile", - "tangent_space_mode": "TangentSpace.PerFragment" + "tangent_space_mode": "TangentSpace.PerFragment", + "preserve_strokes": True }, { "name": "4K(Custom)", "default_texture_resolution": 4096, + "import_cameras": True, "normal_map_format": "NormalMapFormat.OpenGL", "project_workflow": "ProjectWorkflow.UVTile", - "tangent_space_mode": "TangentSpace.PerFragment" + "tangent_space_mode": "TangentSpace.PerFragment", + "preserve_strokes": True } ] } From e362b11184923a0404fb315771be4a7a768d3b7a Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 19 Apr 2024 16:15:22 +0800 Subject: [PATCH 23/65] refactor the repetitive code into a function --- .../plugins/load/load_mesh.py | 30 ++++++++----------- 1 file changed, 12 insertions(+), 18 deletions(-) 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 42a3e5b5b2..f6abfabaf9 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -81,16 +81,7 @@ class SubstanceProjectConfigurationWindow(QtWidgets.QDialog): self.widgets["template_options"].addItem(template) template_name = self.widgets["template_options"].currentText() - - self.import_cameras = next(template["import_cameras"] for - template in self.project_templates - if template["name"] == template_name) - self.preserve_strokes = next(template["preserve_strokes"] for - template in self.project_templates - if template["name"] == template_name) - self.widgets["import_cameras"].setChecked(self.import_cameras) - self.widgets["preserve_strokes"].setChecked(self.preserve_strokes) - + self.get_boolean_setting(template_name) # Build clickboxes layout = QtWidgets.QHBoxLayout(self.widgets["clickbox"]) layout.addWidget(self.widgets["import_cameras"]) @@ -117,14 +108,7 @@ class SubstanceProjectConfigurationWindow(QtWidgets.QDialog): self.widgets["cancelButton"].pressed.connect(self.on_cancel_pressed) def on_options_changed(self, value): - self.import_cameras = next(template["import_cameras"] for - template in self.project_templates - if template["name"] == value) - self.preserve_strokes = next(template["preserve_strokes"] for - template in self.project_templates - if template["name"] == value) - self.widgets["import_cameras"].setChecked(self.import_cameras) - self.widgets["preserve_strokes"].setChecked(self.preserve_strokes) + self.get_boolean_setting(value) def on_ok_pressed(self): if self.widgets["import_cameras"].isChecked(): @@ -140,6 +124,16 @@ class SubstanceProjectConfigurationWindow(QtWidgets.QDialog): self.template_name = None self.close() + def get_boolean_setting(self, template_name): + self.import_cameras = next(template["import_cameras"] for + template in self.project_templates + if template["name"] == template_name) + self.preserve_strokes = next(template["preserve_strokes"] for + template in self.project_templates + if template["name"] == template_name) + self.widgets["import_cameras"].setChecked(self.import_cameras) + self.widgets["preserve_strokes"].setChecked(self.preserve_strokes) + @classmethod def prompt(cls, templates): dialog = cls(templates) From e4b5da7850f9036c74308b7cae227ef8798a06eb Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 19 Apr 2024 16:26:41 +0800 Subject: [PATCH 24/65] move combobox before the checkboxes in the popup dialog --- .../ayon_core/hosts/substancepainter/plugins/load/load_mesh.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 f6abfabaf9..2ba5b10034 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -98,8 +98,8 @@ class SubstanceProjectConfigurationWindow(QtWidgets.QDialog): # Build layout. layout = QtWidgets.QVBoxLayout(self) layout.addWidget(self.widgets["label"]) - layout.addWidget(self.widgets["clickbox"]) layout.addWidget(self.widgets["combobox"]) + layout.addWidget(self.widgets["clickbox"]) layout.addWidget(self.widgets["buttons"]) self.widgets["template_options"].currentTextChanged.connect( From 289d21250d3ef63a2dc2e39466b07af1f10ccef3 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 19 Apr 2024 17:24:42 +0800 Subject: [PATCH 25/65] updating the dialog functions --- .../plugins/load/load_mesh.py | 46 +++++++++++-------- 1 file changed, 28 insertions(+), 18 deletions(-) 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 2ba5b10034..601e723f1f 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -73,9 +73,9 @@ class SubstanceProjectConfigurationWindow(QtWidgets.QDialog): "preserve_strokes": QtWidgets.QCheckBox("Preserve Strokes"), "clickbox": QtWidgets.QWidget(), "combobox": QtWidgets.QWidget(), - "buttons": QtWidgets.QWidget(), - "okButton": QtWidgets.QPushButton("Ok"), - "cancelButton": QtWidgets.QPushButton("Cancel") + "buttons": QtWidgets.QDialogButtonBox( + QtWidgets.QDialogButtonBox.Ok + | QtWidgets.QDialogButtonBox.Cancel) } for template in self.template_names: self.widgets["template_options"].addItem(template) @@ -92,9 +92,6 @@ class SubstanceProjectConfigurationWindow(QtWidgets.QDialog): # Build buttons layout = QtWidgets.QHBoxLayout(self.widgets["buttons"]) - layout.addWidget(self.widgets["okButton"]) - layout.addWidget(self.widgets["cancelButton"]) - # Build layout. layout = QtWidgets.QVBoxLayout(self) layout.addWidget(self.widgets["label"]) @@ -104,8 +101,8 @@ class SubstanceProjectConfigurationWindow(QtWidgets.QDialog): self.widgets["template_options"].currentTextChanged.connect( self.on_options_changed) - self.widgets["okButton"].pressed.connect(self.on_ok_pressed) - self.widgets["cancelButton"].pressed.connect(self.on_cancel_pressed) + self.widgets["buttons"].accepted.connect(self.on_ok_pressed) + self.widgets["buttons"].rejected.connect(self.on_cancel_pressed) def on_options_changed(self, value): self.get_boolean_setting(value) @@ -134,10 +131,24 @@ class SubstanceProjectConfigurationWindow(QtWidgets.QDialog): self.widgets["import_cameras"].setChecked(self.import_cameras) self.widgets["preserve_strokes"].setChecked(self.preserve_strokes) + + def get_result(self): + import copy + templates = self.project_templates + name = self.template_name + if not name: + return None + template = get_template_by_name(name, templates) + template = copy.deepcopy(template) # do not edit the original + template["import_cameras"] = self.widgets["import_cameras"].isChecked() + template["preserve_strokes"] = self.widgets["preserve_strokes"].isChecked() + return template + @classmethod def prompt(cls, templates): dialog = cls(templates) dialog.exec_() + return dialog @@ -157,17 +168,16 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): # Get user inputs result = SubstanceProjectConfigurationWindow.prompt( - self.project_templates) - template_name = result.template_name - if template_name is None: + self.project_templates).get_result() + if result is None: return - import_cameras = result.import_cameras - template = get_template_by_name(template_name, self.project_templates) + import_cameras = result["import_cameras"] sp_settings = substance_painter.project.Settings( - normal_map_format=_convert(template["normal_map_format"]), - project_workflow=_convert(template["project_workflow"]), - tangent_space_mode=_convert(template["tangent_space_mode"]), - default_texture_resolution=template["default_texture_resolution"] + normal_map_format=_convert(result["normal_map_format"]), + import_cameras=result["import_cameras"], + project_workflow=_convert(result["project_workflow"]), + tangent_space_mode=_convert(result["tangent_space_mode"]), + default_texture_resolution=result["default_texture_resolution"] ) if not substance_painter.project.is_open(): # Allow to 'initialize' a new project @@ -178,7 +188,7 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): ) else: # Reload the mesh - preserve_strokes = result.preserve_strokes + preserve_strokes = result["preserve_cameras"] settings = substance_painter.project.MeshReloadingSettings( import_cameras=import_cameras, preserve_strokes=preserve_strokes) From 70b11f9a50dcea4571d6155fc98483d77a289222 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 19 Apr 2024 17:26:04 +0800 Subject: [PATCH 26/65] cosmetic fix --- .../ayon_core/hosts/substancepainter/plugins/load/load_mesh.py | 1 - 1 file changed, 1 deletion(-) 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 601e723f1f..b74c6ca08b 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -131,7 +131,6 @@ class SubstanceProjectConfigurationWindow(QtWidgets.QDialog): self.widgets["import_cameras"].setChecked(self.import_cameras) self.widgets["preserve_strokes"].setChecked(self.preserve_strokes) - def get_result(self): import copy templates = self.project_templates From cdfe59fd18270951d1ba6ac9a4ca5afe40ea5573 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 19 Apr 2024 17:27:34 +0800 Subject: [PATCH 27/65] add comment to explain the action --- .../ayon_core/hosts/substancepainter/plugins/load/load_mesh.py | 2 ++ 1 file changed, 2 insertions(+) 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 b74c6ca08b..4148c8ab8a 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -136,6 +136,8 @@ class SubstanceProjectConfigurationWindow(QtWidgets.QDialog): templates = self.project_templates name = self.template_name if not name: + # if user close the dialog, + # template name would be None return None template = get_template_by_name(name, templates) template = copy.deepcopy(template) # do not edit the original From 41e4af06da3d7e9cb77d273ce112c168046dd870 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 19 Apr 2024 18:04:57 +0800 Subject: [PATCH 28/65] updating the code with big roy's feedback --- .../plugins/load/load_mesh.py | 65 +++++++++---------- 1 file changed, 30 insertions(+), 35 deletions(-) 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 4148c8ab8a..de99dcbc95 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -1,3 +1,4 @@ +import copy from qtpy import QtWidgets, QtCore from ayon_core.pipeline import ( load, @@ -77,11 +78,11 @@ class SubstanceProjectConfigurationWindow(QtWidgets.QDialog): QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel) } - for template in self.template_names: - self.widgets["template_options"].addItem(template) + + self.widgets["template_options"].addItem(self.template_names) template_name = self.widgets["template_options"].currentText() - self.get_boolean_setting(template_name) + self._update_to_match_template(template_name) # Build clickboxes layout = QtWidgets.QHBoxLayout(self.widgets["clickbox"]) layout.addWidget(self.widgets["import_cameras"]) @@ -100,14 +101,14 @@ class SubstanceProjectConfigurationWindow(QtWidgets.QDialog): layout.addWidget(self.widgets["buttons"]) self.widgets["template_options"].currentTextChanged.connect( - self.on_options_changed) - self.widgets["buttons"].accepted.connect(self.on_ok_pressed) - self.widgets["buttons"].rejected.connect(self.on_cancel_pressed) + self._update_to_match_template) + self.widgets["buttons"].accepted.connect(self.on_accept) + self.widgets["buttons"].rejected.connect(self.on_reject) def on_options_changed(self, value): self.get_boolean_setting(value) - def on_ok_pressed(self): + def on_accept(self): if self.widgets["import_cameras"].isChecked(): self.import_cameras = True if self.widgets["preserve_strokes"].isChecked(): @@ -117,32 +118,28 @@ class SubstanceProjectConfigurationWindow(QtWidgets.QDialog): ) self.close() - def on_cancel_pressed(self): - self.template_name = None + def on_reject(self): self.close() - def get_boolean_setting(self, template_name): - self.import_cameras = next(template["import_cameras"] for - template in self.project_templates - if template["name"] == template_name) - self.preserve_strokes = next(template["preserve_strokes"] for - template in self.project_templates - if template["name"] == template_name) - self.widgets["import_cameras"].setChecked(self.import_cameras) - self.widgets["preserve_strokes"].setChecked(self.preserve_strokes) + def _update_to_match_template(self, template_name): + template = get_template_by_name(template_name, self.project_templates) + self.widgets["import_cameras"].setChecked(template["import_cameras"]) + self.widgets["preserve_strokes"].setChecked( + template["preserve_strokes"]) - def get_result(self): - import copy + def get_project_configuration(self): templates = self.project_templates - name = self.template_name - if not name: - # if user close the dialog, - # template name would be None + if not self.template_name: return None - template = get_template_by_name(name, templates) + template = get_template_by_name(self.template_name, templates) template = copy.deepcopy(template) # do not edit the original template["import_cameras"] = self.widgets["import_cameras"].isChecked() template["preserve_strokes"] = self.widgets["preserve_strokes"].isChecked() + for key in template.keys(): + if key in ["normal_map_format", + "project_workflow", + "tangent_space_mode"]: + template[key] = _convert(template[key]) return template @classmethod @@ -150,7 +147,7 @@ class SubstanceProjectConfigurationWindow(QtWidgets.QDialog): dialog = cls(templates) dialog.exec_() - return dialog + return dialog.get_project_configuration() class SubstanceLoadProjectMesh(load.LoaderPlugin): @@ -169,15 +166,14 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): # Get user inputs result = SubstanceProjectConfigurationWindow.prompt( - self.project_templates).get_result() + self.project_templates) if result is None: return - import_cameras = result["import_cameras"] sp_settings = substance_painter.project.Settings( - normal_map_format=_convert(result["normal_map_format"]), + normal_map_format=result["normal_map_format"], import_cameras=result["import_cameras"], - project_workflow=_convert(result["project_workflow"]), - tangent_space_mode=_convert(result["tangent_space_mode"]), + project_workflow=result["project_workflow"], + tangent_space_mode=result["tangent_space_mode"], default_texture_resolution=result["default_texture_resolution"] ) if not substance_painter.project.is_open(): @@ -189,10 +185,9 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): ) else: # Reload the mesh - preserve_strokes = result["preserve_cameras"] settings = substance_painter.project.MeshReloadingSettings( - import_cameras=import_cameras, - preserve_strokes=preserve_strokes) + import_cameras=result["import_cameras"], + preserve_strokes=result["preserve_strokes"]) def on_mesh_reload(status: substance_painter.project.ReloadMeshStatus): # noqa if status == substance_painter.project.ReloadMeshStatus.SUCCESS: # noqa @@ -219,7 +214,7 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): # as we always preserve strokes on updates. # TODO: update the code container["options"] = { - "import_cameras": import_cameras, + "import_cameras": result["import_cameras"], } set_container_metadata(project_mesh_object_name, container) From bb225a3f66841d2487be8168a7b412ea335ef7f5 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 19 Apr 2024 18:33:03 +0800 Subject: [PATCH 29/65] clean up the dialog code --- .../plugins/load/load_mesh.py | 30 +++++-------------- 1 file changed, 8 insertions(+), 22 deletions(-) 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 de99dcbc95..623f5a175f 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -59,9 +59,7 @@ class SubstanceProjectConfigurationWindow(QtWidgets.QDialog): super(SubstanceProjectConfigurationWindow, self).__init__() self.setWindowFlags(self.windowFlags() | QtCore.Qt.FramelessWindowHint) - self.import_cameras = False - self.preserve_strokes = False - self.template_name = None + self.configuration = None self.template_names = [template["name"] for template in project_templates] self.project_templates = project_templates @@ -79,7 +77,7 @@ class SubstanceProjectConfigurationWindow(QtWidgets.QDialog): | QtWidgets.QDialogButtonBox.Cancel) } - self.widgets["template_options"].addItem(self.template_names) + self.widgets["template_options"].addItems(self.template_names) template_name = self.widgets["template_options"].currentText() self._update_to_match_template(template_name) @@ -90,7 +88,6 @@ class SubstanceProjectConfigurationWindow(QtWidgets.QDialog): # Build combobox layout = QtWidgets.QHBoxLayout(self.widgets["combobox"]) layout.addWidget(self.widgets["template_options"]) - # Build buttons layout = QtWidgets.QHBoxLayout(self.widgets["buttons"]) # Build layout. @@ -105,17 +102,8 @@ class SubstanceProjectConfigurationWindow(QtWidgets.QDialog): self.widgets["buttons"].accepted.connect(self.on_accept) self.widgets["buttons"].rejected.connect(self.on_reject) - def on_options_changed(self, value): - self.get_boolean_setting(value) - def on_accept(self): - if self.widgets["import_cameras"].isChecked(): - self.import_cameras = True - if self.widgets["preserve_strokes"].isChecked(): - self.preserve_strokes = True - self.template_name = ( - self.widgets["template_options"].currentText() - ) + self.configuration = self.get_project_configuration() self.close() def on_reject(self): @@ -129,9 +117,8 @@ class SubstanceProjectConfigurationWindow(QtWidgets.QDialog): def get_project_configuration(self): templates = self.project_templates - if not self.template_name: - return None - template = get_template_by_name(self.template_name, templates) + template_name = self.widgets["template_options"].currentText() + template = get_template_by_name(template_name, templates) template = copy.deepcopy(template) # do not edit the original template["import_cameras"] = self.widgets["import_cameras"].isChecked() template["preserve_strokes"] = self.widgets["preserve_strokes"].isChecked() @@ -147,7 +134,7 @@ class SubstanceProjectConfigurationWindow(QtWidgets.QDialog): dialog = cls(templates) dialog.exec_() - return dialog.get_project_configuration() + return dialog.configuration class SubstanceLoadProjectMesh(load.LoaderPlugin): @@ -167,15 +154,14 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): # Get user inputs result = SubstanceProjectConfigurationWindow.prompt( self.project_templates) - if result is None: - return sp_settings = substance_painter.project.Settings( - normal_map_format=result["normal_map_format"], import_cameras=result["import_cameras"], + normal_map_format=result["normal_map_format"], project_workflow=result["project_workflow"], tangent_space_mode=result["tangent_space_mode"], default_texture_resolution=result["default_texture_resolution"] ) + print(sp_settings) if not substance_painter.project.is_open(): # Allow to 'initialize' a new project path = self.filepath_from_context(context) From a46489edc38f9cd2ff9adf3ab8101a6cf76f1e79 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 19 Apr 2024 19:15:46 +0800 Subject: [PATCH 30/65] add deleteLater() after dialog.exec_ --- .../substancepainter/plugins/load/load_mesh.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) 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 623f5a175f..b103ef8e8f 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -16,7 +16,7 @@ import substance_painter.project def _convert(substance_attr): """Return Substance Painter Python API Project attribute from string. - + This converts a string like "ProjectWorkflow.Default" to for example the Substance Painter Python API equivalent object, like: `substance_painter.project.ProjectWorkflow.Default` @@ -122,16 +122,16 @@ class SubstanceProjectConfigurationWindow(QtWidgets.QDialog): template = copy.deepcopy(template) # do not edit the original template["import_cameras"] = self.widgets["import_cameras"].isChecked() template["preserve_strokes"] = self.widgets["preserve_strokes"].isChecked() - for key in template.keys(): - if key in ["normal_map_format", - "project_workflow", - "tangent_space_mode"]: - template[key] = _convert(template[key]) + for key in ["normal_map_format", + "project_workflow", + "tangent_space_mode"]: + template[key] = _convert(template[key]) return template @classmethod def prompt(cls, templates): dialog = cls(templates) + dialog.deleteLater() dialog.exec_() return dialog.configuration @@ -147,6 +147,8 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): order = -10 icon = "code-fork" color = "orange" + + # Defined via settings project_templates = [] def load(self, context, name, namespace, options=None): @@ -161,7 +163,6 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): tangent_space_mode=result["tangent_space_mode"], default_texture_resolution=result["default_texture_resolution"] ) - print(sp_settings) if not substance_painter.project.is_open(): # Allow to 'initialize' a new project path = self.filepath_from_context(context) From 7b68bb84983888e492e03c7fcd8ee2a881b8acd4 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 19 Apr 2024 19:17:46 +0800 Subject: [PATCH 31/65] ensure to have no error after pressing cancel button --- .../hosts/substancepainter/plugins/load/load_mesh.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 b103ef8e8f..8e61a8c4e5 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -131,8 +131,8 @@ class SubstanceProjectConfigurationWindow(QtWidgets.QDialog): @classmethod def prompt(cls, templates): dialog = cls(templates) - dialog.deleteLater() dialog.exec_() + dialog.deleteLater() return dialog.configuration @@ -156,6 +156,8 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): # Get user inputs result = SubstanceProjectConfigurationWindow.prompt( self.project_templates) + if not result: + return sp_settings = substance_painter.project.Settings( import_cameras=result["import_cameras"], normal_map_format=result["normal_map_format"], From dd11cf95caa2eb0faec7d3f2348ed2a00adf216c Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 19 Apr 2024 19:18:23 +0800 Subject: [PATCH 32/65] add comment on the condition on checking result variable --- .../ayon_core/hosts/substancepainter/plugins/load/load_mesh.py | 1 + 1 file changed, 1 insertion(+) 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 8e61a8c4e5..a6d8aef3c0 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -157,6 +157,7 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): result = SubstanceProjectConfigurationWindow.prompt( self.project_templates) if not result: + # cancelling loader action return sp_settings = substance_painter.project.Settings( import_cameras=result["import_cameras"], From 369321b18c30f93e46b044bd57cf7623cba4f44a Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 19 Apr 2024 19:43:40 +0800 Subject: [PATCH 33/65] cosmetic fix --- .../hosts/substancepainter/plugins/load/load_mesh.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) 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 a6d8aef3c0..0764789b66 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -121,10 +121,12 @@ class SubstanceProjectConfigurationWindow(QtWidgets.QDialog): template = get_template_by_name(template_name, templates) template = copy.deepcopy(template) # do not edit the original template["import_cameras"] = self.widgets["import_cameras"].isChecked() - template["preserve_strokes"] = self.widgets["preserve_strokes"].isChecked() + template["preserve_strokes"] = ( + self.widgets["preserve_strokes"].isChecked() + ) for key in ["normal_map_format", - "project_workflow", - "tangent_space_mode"]: + "project_workflow", + "tangent_space_mode"]: template[key] = _convert(template[key]) return template From 9173e77e3066232e97a3335f2577de7180148f69 Mon Sep 17 00:00:00 2001 From: Kayla Man <64118225+moonyuet@users.noreply.github.com> Date: Fri, 19 Apr 2024 20:23:08 +0800 Subject: [PATCH 34/65] Update client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py Co-authored-by: Roy Nieterau --- .../hosts/substancepainter/plugins/load/load_mesh.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 0764789b66..1a5ca1aec3 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -134,9 +134,9 @@ class SubstanceProjectConfigurationWindow(QtWidgets.QDialog): def prompt(cls, templates): dialog = cls(templates) dialog.exec_() + configuration = dialog.configuration dialog.deleteLater() - - return dialog.configuration + return configuration class SubstanceLoadProjectMesh(load.LoaderPlugin): From 7ebdeeae26230e164f6c7451f8e56657fac1c05d Mon Sep 17 00:00:00 2001 From: Kayla Man <64118225+moonyuet@users.noreply.github.com> Date: Fri, 19 Apr 2024 20:23:19 +0800 Subject: [PATCH 35/65] cosmetic Co-authored-by: Roy Nieterau --- .../ayon_core/hosts/substancepainter/plugins/load/load_mesh.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 1a5ca1aec3..e5cfa469ed 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -119,7 +119,7 @@ class SubstanceProjectConfigurationWindow(QtWidgets.QDialog): templates = self.project_templates template_name = self.widgets["template_options"].currentText() template = get_template_by_name(template_name, templates) - template = copy.deepcopy(template) # do not edit the original + template = copy.deepcopy(template) # do not edit the original template["import_cameras"] = self.widgets["import_cameras"].isChecked() template["preserve_strokes"] = ( self.widgets["preserve_strokes"].isChecked() From 0ec9d1e99365e009d82c2ecc28fb78210a3300a3 Mon Sep 17 00:00:00 2001 From: Kayla Man <64118225+moonyuet@users.noreply.github.com> Date: Fri, 19 Apr 2024 20:23:36 +0800 Subject: [PATCH 36/65] Remove unnecessary comment Co-authored-by: Roy Nieterau --- .../ayon_core/hosts/substancepainter/plugins/load/load_mesh.py | 1 - 1 file changed, 1 deletion(-) 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 e5cfa469ed..6a67f5c686 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -204,7 +204,6 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): # We want store some options for updating to keep consistent behavior # from the user's original choice. We don't store 'preserve_strokes' # as we always preserve strokes on updates. - # TODO: update the code container["options"] = { "import_cameras": result["import_cameras"], } From efd0e0774deaa7a76c45cc9be039f71bea95dbfb Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 19 Apr 2024 21:43:47 +0800 Subject: [PATCH 37/65] move sp_setting into if condition --- .../substancepainter/plugins/load/load_mesh.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) 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 6a67f5c686..d5aac1191c 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -161,17 +161,16 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin): if not result: # cancelling loader action return - sp_settings = substance_painter.project.Settings( - import_cameras=result["import_cameras"], - normal_map_format=result["normal_map_format"], - project_workflow=result["project_workflow"], - tangent_space_mode=result["tangent_space_mode"], - default_texture_resolution=result["default_texture_resolution"] - ) if not substance_painter.project.is_open(): # Allow to 'initialize' a new project path = self.filepath_from_context(context) - + sp_settings = substance_painter.project.Settings( + import_cameras=result["import_cameras"], + normal_map_format=result["normal_map_format"], + project_workflow=result["project_workflow"], + tangent_space_mode=result["tangent_space_mode"], + default_texture_resolution=result["default_texture_resolution"] + ) settings = substance_painter.project.create( mesh_file_path=path, settings=sp_settings ) From 814220e64a665ac38f051cfe5f09e5c9cf3e9295 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 22 Apr 2024 14:24:23 +0200 Subject: [PATCH 38/65] unreal uses package.py --- server_addon/unreal/package.py | 3 +++ server_addon/unreal/server/__init__.py | 6 ------ server_addon/unreal/server/version.py | 1 - 3 files changed, 3 insertions(+), 7 deletions(-) create mode 100644 server_addon/unreal/package.py delete mode 100644 server_addon/unreal/server/version.py diff --git a/server_addon/unreal/package.py b/server_addon/unreal/package.py new file mode 100644 index 0000000000..cab89ca873 --- /dev/null +++ b/server_addon/unreal/package.py @@ -0,0 +1,3 @@ +name = "unreal" +title = "Unreal" +version = "0.1.0" diff --git a/server_addon/unreal/server/__init__.py b/server_addon/unreal/server/__init__.py index a5f3e9597d..751560b623 100644 --- a/server_addon/unreal/server/__init__.py +++ b/server_addon/unreal/server/__init__.py @@ -2,17 +2,11 @@ from typing import Type from ayon_server.addons import BaseServerAddon -from .version import __version__ from .settings import UnrealSettings, DEFAULT_VALUES class UnrealAddon(BaseServerAddon): - name = "unreal" - title = "Unreal" - version = __version__ settings_model: Type[UnrealSettings] = UnrealSettings - frontend_scopes = {} - services = {} async def get_default_settings(self): settings_model_cls = self.get_settings_model() diff --git a/server_addon/unreal/server/version.py b/server_addon/unreal/server/version.py deleted file mode 100644 index 3dc1f76bc6..0000000000 --- a/server_addon/unreal/server/version.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = "0.1.0" From 36c4bc8667632772b4802dd8c6962bacfd5310c0 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 22 Apr 2024 14:24:34 +0200 Subject: [PATCH 39/65] tvpaint uses package.py --- server_addon/tvpaint/package.py | 3 +++ server_addon/tvpaint/server/__init__.py | 4 ---- server_addon/tvpaint/server/version.py | 1 - 3 files changed, 3 insertions(+), 5 deletions(-) create mode 100644 server_addon/tvpaint/package.py delete mode 100644 server_addon/tvpaint/server/version.py diff --git a/server_addon/tvpaint/package.py b/server_addon/tvpaint/package.py new file mode 100644 index 0000000000..2be3164f4a --- /dev/null +++ b/server_addon/tvpaint/package.py @@ -0,0 +1,3 @@ +name = "tvpaint" +title = "TVPaint" +version = "0.1.2" diff --git a/server_addon/tvpaint/server/__init__.py b/server_addon/tvpaint/server/__init__.py index 033d7d3792..658dcf0bb6 100644 --- a/server_addon/tvpaint/server/__init__.py +++ b/server_addon/tvpaint/server/__init__.py @@ -2,14 +2,10 @@ from typing import Type from ayon_server.addons import BaseServerAddon -from .version import __version__ from .settings import TvpaintSettings, DEFAULT_VALUES class TvpaintAddon(BaseServerAddon): - name = "tvpaint" - title = "TVPaint" - version = __version__ settings_model: Type[TvpaintSettings] = TvpaintSettings async def get_default_settings(self): diff --git a/server_addon/tvpaint/server/version.py b/server_addon/tvpaint/server/version.py deleted file mode 100644 index b3f4756216..0000000000 --- a/server_addon/tvpaint/server/version.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = "0.1.2" From 7184ee5c5ca8c2d7dc1b2784b094afe6e1d7632b Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 22 Apr 2024 14:24:51 +0200 Subject: [PATCH 40/65] traypublisher uses package.py --- server_addon/traypublisher/package.py | 3 +++ server_addon/traypublisher/server/__init__.py | 5 ----- server_addon/traypublisher/server/version.py | 3 --- 3 files changed, 3 insertions(+), 8 deletions(-) create mode 100644 server_addon/traypublisher/package.py delete mode 100644 server_addon/traypublisher/server/version.py diff --git a/server_addon/traypublisher/package.py b/server_addon/traypublisher/package.py new file mode 100644 index 0000000000..4ca8ae9fd3 --- /dev/null +++ b/server_addon/traypublisher/package.py @@ -0,0 +1,3 @@ +name = "traypublisher" +title = "TrayPublisher" +version = "0.1.4" diff --git a/server_addon/traypublisher/server/__init__.py b/server_addon/traypublisher/server/__init__.py index e6f079609f..830f325ac0 100644 --- a/server_addon/traypublisher/server/__init__.py +++ b/server_addon/traypublisher/server/__init__.py @@ -1,14 +1,9 @@ from ayon_server.addons import BaseServerAddon -from .version import __version__ from .settings import TraypublisherSettings, DEFAULT_TRAYPUBLISHER_SETTING class Traypublisher(BaseServerAddon): - name = "traypublisher" - title = "TrayPublisher" - version = __version__ - settings_model = TraypublisherSettings async def get_default_settings(self): diff --git a/server_addon/traypublisher/server/version.py b/server_addon/traypublisher/server/version.py deleted file mode 100644 index de699158fd..0000000000 --- a/server_addon/traypublisher/server/version.py +++ /dev/null @@ -1,3 +0,0 @@ -# -*- coding: utf-8 -*- -"""Package declaring addon version.""" -__version__ = "0.1.4" From 76482b3bfbde769232f89383b9d071e11dfe6a89 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 22 Apr 2024 14:25:02 +0200 Subject: [PATCH 41/65] timers manager uses package.py --- server_addon/timers_manager/package.py | 3 +++ server_addon/timers_manager/server/__init__.py | 4 ---- server_addon/timers_manager/server/version.py | 1 - 3 files changed, 3 insertions(+), 5 deletions(-) create mode 100644 server_addon/timers_manager/package.py delete mode 100644 server_addon/timers_manager/server/version.py diff --git a/server_addon/timers_manager/package.py b/server_addon/timers_manager/package.py new file mode 100644 index 0000000000..bd6b81b4b7 --- /dev/null +++ b/server_addon/timers_manager/package.py @@ -0,0 +1,3 @@ +name = "timers_manager" +title = "Timers Manager" +version = "0.1.1" diff --git a/server_addon/timers_manager/server/__init__.py b/server_addon/timers_manager/server/__init__.py index 29f9d47370..32e83d295c 100644 --- a/server_addon/timers_manager/server/__init__.py +++ b/server_addon/timers_manager/server/__init__.py @@ -2,12 +2,8 @@ from typing import Type from ayon_server.addons import BaseServerAddon -from .version import __version__ from .settings import TimersManagerSettings class TimersManagerAddon(BaseServerAddon): - name = "timers_manager" - version = __version__ - title = "Timers Manager" settings_model: Type[TimersManagerSettings] = TimersManagerSettings diff --git a/server_addon/timers_manager/server/version.py b/server_addon/timers_manager/server/version.py deleted file mode 100644 index 485f44ac21..0000000000 --- a/server_addon/timers_manager/server/version.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = "0.1.1" From 41b95ff1869f2abdc1b5f702eda898e2e566c6c1 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 22 Apr 2024 14:25:12 +0200 Subject: [PATCH 42/65] substancepainter uses package.py --- server_addon/substancepainter/package.py | 3 +++ server_addon/substancepainter/server/__init__.py | 4 ---- server_addon/substancepainter/server/version.py | 1 - 3 files changed, 3 insertions(+), 5 deletions(-) create mode 100644 server_addon/substancepainter/package.py delete mode 100644 server_addon/substancepainter/server/version.py diff --git a/server_addon/substancepainter/package.py b/server_addon/substancepainter/package.py new file mode 100644 index 0000000000..a064d80fd7 --- /dev/null +++ b/server_addon/substancepainter/package.py @@ -0,0 +1,3 @@ +name = "substancepainter" +title = "Substance Painter" +version = "0.1.0" diff --git a/server_addon/substancepainter/server/__init__.py b/server_addon/substancepainter/server/__init__.py index 2bf808d508..f6cd51e610 100644 --- a/server_addon/substancepainter/server/__init__.py +++ b/server_addon/substancepainter/server/__init__.py @@ -2,14 +2,10 @@ from typing import Type from ayon_server.addons import BaseServerAddon -from .version import __version__ from .settings import SubstancePainterSettings, DEFAULT_SPAINTER_SETTINGS class SubstancePainterAddon(BaseServerAddon): - name = "substancepainter" - title = "Substance Painter" - version = __version__ settings_model: Type[SubstancePainterSettings] = SubstancePainterSettings async def get_default_settings(self): diff --git a/server_addon/substancepainter/server/version.py b/server_addon/substancepainter/server/version.py deleted file mode 100644 index 3dc1f76bc6..0000000000 --- a/server_addon/substancepainter/server/version.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = "0.1.0" From 10823b40a9f7ae35f27e60ead1301b7612edfb88 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 22 Apr 2024 14:25:33 +0200 Subject: [PATCH 43/65] resolve uses package.py --- server_addon/resolve/package.py | 3 +++ server_addon/resolve/server/__init__.py | 6 ------ server_addon/resolve/server/version.py | 1 - 3 files changed, 3 insertions(+), 7 deletions(-) create mode 100644 server_addon/resolve/package.py delete mode 100644 server_addon/resolve/server/version.py diff --git a/server_addon/resolve/package.py b/server_addon/resolve/package.py new file mode 100644 index 0000000000..cf92413bce --- /dev/null +++ b/server_addon/resolve/package.py @@ -0,0 +1,3 @@ +name = "resolve" +title = "DaVinci Resolve" +version = "0.1.0" diff --git a/server_addon/resolve/server/__init__.py b/server_addon/resolve/server/__init__.py index a84180d0f5..35d2db19e4 100644 --- a/server_addon/resolve/server/__init__.py +++ b/server_addon/resolve/server/__init__.py @@ -2,17 +2,11 @@ from typing import Type from ayon_server.addons import BaseServerAddon -from .version import __version__ from .settings import ResolveSettings, DEFAULT_VALUES class ResolveAddon(BaseServerAddon): - name = "resolve" - title = "DaVinci Resolve" - version = __version__ settings_model: Type[ResolveSettings] = ResolveSettings - frontend_scopes = {} - services = {} async def get_default_settings(self): settings_model_cls = self.get_settings_model() diff --git a/server_addon/resolve/server/version.py b/server_addon/resolve/server/version.py deleted file mode 100644 index 3dc1f76bc6..0000000000 --- a/server_addon/resolve/server/version.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = "0.1.0" From 8749bdea3c7d34006b536c1c944ef05b5ab23271 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 22 Apr 2024 14:25:42 +0200 Subject: [PATCH 44/65] photoshop uses package.py --- server_addon/photoshop/package.py | 3 +++ server_addon/photoshop/server/__init__.py | 5 ----- server_addon/photoshop/server/version.py | 3 --- 3 files changed, 3 insertions(+), 8 deletions(-) create mode 100644 server_addon/photoshop/package.py delete mode 100644 server_addon/photoshop/server/version.py diff --git a/server_addon/photoshop/package.py b/server_addon/photoshop/package.py new file mode 100644 index 0000000000..25615529d1 --- /dev/null +++ b/server_addon/photoshop/package.py @@ -0,0 +1,3 @@ +name = "photoshop" +title = "Photoshop" +version = "0.1.2" diff --git a/server_addon/photoshop/server/__init__.py b/server_addon/photoshop/server/__init__.py index 3a45f7a809..86d1025a2d 100644 --- a/server_addon/photoshop/server/__init__.py +++ b/server_addon/photoshop/server/__init__.py @@ -1,14 +1,9 @@ from ayon_server.addons import BaseServerAddon from .settings import PhotoshopSettings, DEFAULT_PHOTOSHOP_SETTING -from .version import __version__ class Photoshop(BaseServerAddon): - name = "photoshop" - title = "Photoshop" - version = __version__ - settings_model = PhotoshopSettings async def get_default_settings(self): diff --git a/server_addon/photoshop/server/version.py b/server_addon/photoshop/server/version.py deleted file mode 100644 index df0c92f1e2..0000000000 --- a/server_addon/photoshop/server/version.py +++ /dev/null @@ -1,3 +0,0 @@ -# -*- coding: utf-8 -*- -"""Package declaring addon version.""" -__version__ = "0.1.2" From 8c6c5deca201e3875c809eb05f6225b65136a61c Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 22 Apr 2024 14:25:51 +0200 Subject: [PATCH 45/65] nuke uses package.py --- server_addon/nuke/package.py | 3 +++ server_addon/nuke/server/__init__.py | 4 ---- server_addon/nuke/server/version.py | 1 - 3 files changed, 3 insertions(+), 5 deletions(-) create mode 100644 server_addon/nuke/package.py delete mode 100644 server_addon/nuke/server/version.py diff --git a/server_addon/nuke/package.py b/server_addon/nuke/package.py new file mode 100644 index 0000000000..9630c370bc --- /dev/null +++ b/server_addon/nuke/package.py @@ -0,0 +1,3 @@ +name = "nuke" +title = "Nuke" +version = "0.1.10" diff --git a/server_addon/nuke/server/__init__.py b/server_addon/nuke/server/__init__.py index 032ceea5fb..aeb5e36675 100644 --- a/server_addon/nuke/server/__init__.py +++ b/server_addon/nuke/server/__init__.py @@ -2,14 +2,10 @@ from typing import Type from ayon_server.addons import BaseServerAddon -from .version import __version__ from .settings import NukeSettings, DEFAULT_VALUES class NukeAddon(BaseServerAddon): - name = "nuke" - title = "Nuke" - version = __version__ settings_model: Type[NukeSettings] = NukeSettings async def get_default_settings(self): diff --git a/server_addon/nuke/server/version.py b/server_addon/nuke/server/version.py deleted file mode 100644 index 569b1212f7..0000000000 --- a/server_addon/nuke/server/version.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = "0.1.10" From d5100a1cc56ac6667d885b1c5f2586c4d17bc6e6 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 22 Apr 2024 14:26:01 +0200 Subject: [PATCH 46/65] maya uses package.py --- server_addon/maya/package.py | 3 +++ server_addon/maya/server/__init__.py | 4 ---- server_addon/maya/server/version.py | 3 --- 3 files changed, 3 insertions(+), 7 deletions(-) create mode 100644 server_addon/maya/package.py delete mode 100644 server_addon/maya/server/version.py diff --git a/server_addon/maya/package.py b/server_addon/maya/package.py new file mode 100644 index 0000000000..00f28d901e --- /dev/null +++ b/server_addon/maya/package.py @@ -0,0 +1,3 @@ +name = "maya" +title = "Maya" +version = "0.1.16" diff --git a/server_addon/maya/server/__init__.py b/server_addon/maya/server/__init__.py index 8784427dcf..6dda2cdd77 100644 --- a/server_addon/maya/server/__init__.py +++ b/server_addon/maya/server/__init__.py @@ -2,13 +2,9 @@ from ayon_server.addons import BaseServerAddon from .settings.main import MayaSettings, DEFAULT_MAYA_SETTING -from .version import __version__ class MayaAddon(BaseServerAddon): - name = "maya" - title = "Maya" - version = __version__ settings_model = MayaSettings async def get_default_settings(self): diff --git a/server_addon/maya/server/version.py b/server_addon/maya/server/version.py deleted file mode 100644 index c1b7ff9d79..0000000000 --- a/server_addon/maya/server/version.py +++ /dev/null @@ -1,3 +0,0 @@ -# -*- coding: utf-8 -*- -"""Package declaring addon version.""" -__version__ = "0.1.16" From 73782cf148d03e85fb5ee9a870296065e4cd0cdc Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 22 Apr 2024 14:26:10 +0200 Subject: [PATCH 47/65] 3dsmax uses package.py --- server_addon/max/package.py | 3 +++ server_addon/max/server/__init__.py | 4 ---- server_addon/max/server/version.py | 1 - 3 files changed, 3 insertions(+), 5 deletions(-) create mode 100644 server_addon/max/package.py delete mode 100644 server_addon/max/server/version.py diff --git a/server_addon/max/package.py b/server_addon/max/package.py new file mode 100644 index 0000000000..fb1f1b3050 --- /dev/null +++ b/server_addon/max/package.py @@ -0,0 +1,3 @@ +name = "max" +title = "Max" +version = "0.1.7" diff --git a/server_addon/max/server/__init__.py b/server_addon/max/server/__init__.py index 31c694a084..d03b29d249 100644 --- a/server_addon/max/server/__init__.py +++ b/server_addon/max/server/__init__.py @@ -2,14 +2,10 @@ from typing import Type from ayon_server.addons import BaseServerAddon -from .version import __version__ from .settings import MaxSettings, DEFAULT_VALUES class MaxAddon(BaseServerAddon): - name = "max" - title = "Max" - version = __version__ settings_model: Type[MaxSettings] = MaxSettings async def get_default_settings(self): diff --git a/server_addon/max/server/version.py b/server_addon/max/server/version.py deleted file mode 100644 index f1380eede2..0000000000 --- a/server_addon/max/server/version.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = "0.1.7" From 0e7c112d8d9628fd66ca91a93be2771fc23f3b84 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 22 Apr 2024 14:26:24 +0200 Subject: [PATCH 48/65] houdini uses package.py --- server_addon/houdini/package.py | 3 +++ server_addon/houdini/server/__init__.py | 4 ---- server_addon/houdini/server/version.py | 1 - 3 files changed, 3 insertions(+), 5 deletions(-) create mode 100644 server_addon/houdini/package.py delete mode 100644 server_addon/houdini/server/version.py diff --git a/server_addon/houdini/package.py b/server_addon/houdini/package.py new file mode 100644 index 0000000000..4b72af2a89 --- /dev/null +++ b/server_addon/houdini/package.py @@ -0,0 +1,3 @@ +name = "houdini" +title = "Houdini" +version = "0.2.12" diff --git a/server_addon/houdini/server/__init__.py b/server_addon/houdini/server/__init__.py index 870ec2d0b7..8c1ffcb0b3 100644 --- a/server_addon/houdini/server/__init__.py +++ b/server_addon/houdini/server/__init__.py @@ -2,14 +2,10 @@ from typing import Type from ayon_server.addons import BaseServerAddon -from .version import __version__ from .settings import HoudiniSettings, DEFAULT_VALUES class Houdini(BaseServerAddon): - name = "houdini" - title = "Houdini" - version = __version__ settings_model: Type[HoudiniSettings] = HoudiniSettings async def get_default_settings(self): diff --git a/server_addon/houdini/server/version.py b/server_addon/houdini/server/version.py deleted file mode 100644 index b5c9b6cb71..0000000000 --- a/server_addon/houdini/server/version.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = "0.2.12" From 85fe7f0de73708b5e113d6b37e4a560526b43800 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 22 Apr 2024 14:26:31 +0200 Subject: [PATCH 49/65] hiero uses package.py --- server_addon/hiero/package.py | 3 +++ server_addon/hiero/server/__init__.py | 6 ------ server_addon/hiero/server/version.py | 1 - 3 files changed, 3 insertions(+), 7 deletions(-) create mode 100644 server_addon/hiero/package.py delete mode 100644 server_addon/hiero/server/version.py diff --git a/server_addon/hiero/package.py b/server_addon/hiero/package.py new file mode 100644 index 0000000000..cabe68eb68 --- /dev/null +++ b/server_addon/hiero/package.py @@ -0,0 +1,3 @@ +name = "hiero" +title = "Hiero" +version = "0.1.2" diff --git a/server_addon/hiero/server/__init__.py b/server_addon/hiero/server/__init__.py index d0f9bcefc3..3db78eafd7 100644 --- a/server_addon/hiero/server/__init__.py +++ b/server_addon/hiero/server/__init__.py @@ -2,17 +2,11 @@ from typing import Type from ayon_server.addons import BaseServerAddon -from .version import __version__ from .settings import HieroSettings, DEFAULT_VALUES class HieroAddon(BaseServerAddon): - name = "hiero" - title = "Hiero" - version = __version__ settings_model: Type[HieroSettings] = HieroSettings - frontend_scopes = {} - services = {} async def get_default_settings(self): settings_model_cls = self.get_settings_model() diff --git a/server_addon/hiero/server/version.py b/server_addon/hiero/server/version.py deleted file mode 100644 index b3f4756216..0000000000 --- a/server_addon/hiero/server/version.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = "0.1.2" From 2b1e67c88f1a01aa39b3b1ef20f7109991b45b43 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 22 Apr 2024 14:26:38 +0200 Subject: [PATCH 50/65] harmony uses package.py --- server_addon/harmony/package.py | 3 +++ server_addon/harmony/server/__init__.py | 5 ----- server_addon/harmony/server/version.py | 3 --- 3 files changed, 3 insertions(+), 8 deletions(-) create mode 100644 server_addon/harmony/package.py delete mode 100644 server_addon/harmony/server/version.py diff --git a/server_addon/harmony/package.py b/server_addon/harmony/package.py new file mode 100644 index 0000000000..83e88e7d57 --- /dev/null +++ b/server_addon/harmony/package.py @@ -0,0 +1,3 @@ +name = "harmony" +title = "Harmony" +version = "0.1.2" diff --git a/server_addon/harmony/server/__init__.py b/server_addon/harmony/server/__init__.py index 4ecda1989e..154618241e 100644 --- a/server_addon/harmony/server/__init__.py +++ b/server_addon/harmony/server/__init__.py @@ -1,14 +1,9 @@ from ayon_server.addons import BaseServerAddon from .settings import HarmonySettings, DEFAULT_HARMONY_SETTING -from .version import __version__ class Harmony(BaseServerAddon): - name = "harmony" - title = "Harmony" - version = __version__ - settings_model = HarmonySettings async def get_default_settings(self): diff --git a/server_addon/harmony/server/version.py b/server_addon/harmony/server/version.py deleted file mode 100644 index df0c92f1e2..0000000000 --- a/server_addon/harmony/server/version.py +++ /dev/null @@ -1,3 +0,0 @@ -# -*- coding: utf-8 -*- -"""Package declaring addon version.""" -__version__ = "0.1.2" From a1c3e57709862c015f568f37a92cadc026c083ef Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 22 Apr 2024 14:26:46 +0200 Subject: [PATCH 51/65] fusion uses package.py --- server_addon/fusion/package.py | 3 +++ server_addon/fusion/server/__init__.py | 6 ------ server_addon/fusion/server/version.py | 1 - 3 files changed, 3 insertions(+), 7 deletions(-) create mode 100644 server_addon/fusion/package.py delete mode 100644 server_addon/fusion/server/version.py diff --git a/server_addon/fusion/package.py b/server_addon/fusion/package.py new file mode 100644 index 0000000000..9e7a46df2c --- /dev/null +++ b/server_addon/fusion/package.py @@ -0,0 +1,3 @@ +name = "fusion" +title = "Fusion" +version = "0.1.5" diff --git a/server_addon/fusion/server/__init__.py b/server_addon/fusion/server/__init__.py index 4d43f28812..0456cfd5ee 100644 --- a/server_addon/fusion/server/__init__.py +++ b/server_addon/fusion/server/__init__.py @@ -2,17 +2,11 @@ from typing import Type from ayon_server.addons import BaseServerAddon -from .version import __version__ from .settings import FusionSettings, DEFAULT_VALUES class FusionAddon(BaseServerAddon): - name = "fusion" - title = "Fusion" - version = __version__ settings_model: Type[FusionSettings] = FusionSettings - frontend_scopes = {} - services = {} async def get_default_settings(self): settings_model_cls = self.get_settings_model() diff --git a/server_addon/fusion/server/version.py b/server_addon/fusion/server/version.py deleted file mode 100644 index 1276d0254f..0000000000 --- a/server_addon/fusion/server/version.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = "0.1.5" From 78e1c08fac15da24f41d8109db52ebf6a13e5f10 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 22 Apr 2024 14:26:52 +0200 Subject: [PATCH 52/65] flame uses package.py --- server_addon/flame/package.py | 3 +++ server_addon/flame/server/__init__.py | 6 ------ server_addon/flame/server/version.py | 1 - 3 files changed, 3 insertions(+), 7 deletions(-) create mode 100644 server_addon/flame/package.py delete mode 100644 server_addon/flame/server/version.py diff --git a/server_addon/flame/package.py b/server_addon/flame/package.py new file mode 100644 index 0000000000..8c077ed91d --- /dev/null +++ b/server_addon/flame/package.py @@ -0,0 +1,3 @@ +name = "flame" +title = "Flame" +version = "0.1.0" diff --git a/server_addon/flame/server/__init__.py b/server_addon/flame/server/__init__.py index 7d5eb3960f..4aa46617ee 100644 --- a/server_addon/flame/server/__init__.py +++ b/server_addon/flame/server/__init__.py @@ -2,17 +2,11 @@ from typing import Type from ayon_server.addons import BaseServerAddon -from .version import __version__ from .settings import FlameSettings, DEFAULT_VALUES class FlameAddon(BaseServerAddon): - name = "flame" - title = "Flame" - version = __version__ settings_model: Type[FlameSettings] = FlameSettings - frontend_scopes = {} - services = {} async def get_default_settings(self): settings_model_cls = self.get_settings_model() diff --git a/server_addon/flame/server/version.py b/server_addon/flame/server/version.py deleted file mode 100644 index 3dc1f76bc6..0000000000 --- a/server_addon/flame/server/version.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = "0.1.0" From 286156d1ff0ec5f47600b4040442576130d09aef Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 22 Apr 2024 14:27:01 +0200 Subject: [PATCH 53/65] deadline uses package.py --- server_addon/deadline/package.py | 3 +++ server_addon/deadline/server/__init__.py | 4 ---- server_addon/deadline/server/version.py | 1 - 3 files changed, 3 insertions(+), 5 deletions(-) create mode 100644 server_addon/deadline/package.py delete mode 100644 server_addon/deadline/server/version.py diff --git a/server_addon/deadline/package.py b/server_addon/deadline/package.py new file mode 100644 index 0000000000..944797fea6 --- /dev/null +++ b/server_addon/deadline/package.py @@ -0,0 +1,3 @@ +name = "deadline" +title = "Deadline" +version = "0.1.10" diff --git a/server_addon/deadline/server/__init__.py b/server_addon/deadline/server/__init__.py index 36d04189a9..e7dcb7d347 100644 --- a/server_addon/deadline/server/__init__.py +++ b/server_addon/deadline/server/__init__.py @@ -2,14 +2,10 @@ from typing import Type from ayon_server.addons import BaseServerAddon -from .version import __version__ from .settings import DeadlineSettings, DEFAULT_VALUES class Deadline(BaseServerAddon): - name = "deadline" - title = "Deadline" - version = __version__ settings_model: Type[DeadlineSettings] = DeadlineSettings async def get_default_settings(self): diff --git a/server_addon/deadline/server/version.py b/server_addon/deadline/server/version.py deleted file mode 100644 index 569b1212f7..0000000000 --- a/server_addon/deadline/server/version.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = "0.1.10" From 35c4176c3d9b23a430e0182e04bc5be1c0feadd8 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 22 Apr 2024 14:27:13 +0200 Subject: [PATCH 54/65] clockify uses package.py --- server_addon/clockify/package.py | 3 +++ server_addon/clockify/server/__init__.py | 6 ------ server_addon/clockify/server/version.py | 1 - 3 files changed, 3 insertions(+), 7 deletions(-) create mode 100644 server_addon/clockify/package.py delete mode 100644 server_addon/clockify/server/version.py diff --git a/server_addon/clockify/package.py b/server_addon/clockify/package.py new file mode 100644 index 0000000000..bcf9425b3f --- /dev/null +++ b/server_addon/clockify/package.py @@ -0,0 +1,3 @@ +name = "clockify" +title = "Clockify" +version = "0.1.1" diff --git a/server_addon/clockify/server/__init__.py b/server_addon/clockify/server/__init__.py index 0fa453fdf4..11bbfed261 100644 --- a/server_addon/clockify/server/__init__.py +++ b/server_addon/clockify/server/__init__.py @@ -2,14 +2,8 @@ from typing import Type from ayon_server.addons import BaseServerAddon -from .version import __version__ from .settings import ClockifySettings class ClockifyAddon(BaseServerAddon): - name = "clockify" - title = "Clockify" - version = __version__ settings_model: Type[ClockifySettings] = ClockifySettings - frontend_scopes = {} - services = {} diff --git a/server_addon/clockify/server/version.py b/server_addon/clockify/server/version.py deleted file mode 100644 index 485f44ac21..0000000000 --- a/server_addon/clockify/server/version.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = "0.1.1" From 2b957195198ebf2ccef6747b43e0af2fbcbffd0d Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 22 Apr 2024 14:27:22 +0200 Subject: [PATCH 55/65] celaction uses package.py --- server_addon/celaction/package.py | 3 +++ server_addon/celaction/server/__init__.py | 6 ------ server_addon/celaction/server/version.py | 1 - 3 files changed, 3 insertions(+), 7 deletions(-) create mode 100644 server_addon/celaction/package.py delete mode 100644 server_addon/celaction/server/version.py diff --git a/server_addon/celaction/package.py b/server_addon/celaction/package.py new file mode 100644 index 0000000000..2b11a8630f --- /dev/null +++ b/server_addon/celaction/package.py @@ -0,0 +1,3 @@ +name = "celaction" +title = "CelAction" +version = "0.1.0" diff --git a/server_addon/celaction/server/__init__.py b/server_addon/celaction/server/__init__.py index 90d3dbaa01..e3769a4b7f 100644 --- a/server_addon/celaction/server/__init__.py +++ b/server_addon/celaction/server/__init__.py @@ -2,17 +2,11 @@ from typing import Type from ayon_server.addons import BaseServerAddon -from .version import __version__ from .settings import CelActionSettings, DEFAULT_VALUES class CelActionAddon(BaseServerAddon): - name = "celaction" - title = "CelAction" - version = __version__ settings_model: Type[CelActionSettings] = CelActionSettings - frontend_scopes = {} - services = {} async def get_default_settings(self): settings_model_cls = self.get_settings_model() diff --git a/server_addon/celaction/server/version.py b/server_addon/celaction/server/version.py deleted file mode 100644 index 3dc1f76bc6..0000000000 --- a/server_addon/celaction/server/version.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = "0.1.0" From ce42a71555a1d3f3a399a668f9b4bb7eeb489699 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 22 Apr 2024 14:27:32 +0200 Subject: [PATCH 56/65] blender uses package.py --- server_addon/blender/package.py | 3 +++ server_addon/blender/server/__init__.py | 6 ------ server_addon/blender/server/version.py | 1 - 3 files changed, 3 insertions(+), 7 deletions(-) create mode 100644 server_addon/blender/package.py delete mode 100644 server_addon/blender/server/version.py diff --git a/server_addon/blender/package.py b/server_addon/blender/package.py new file mode 100644 index 0000000000..667076e533 --- /dev/null +++ b/server_addon/blender/package.py @@ -0,0 +1,3 @@ +name = "blender" +title = "Blender" +version = "0.1.8" diff --git a/server_addon/blender/server/__init__.py b/server_addon/blender/server/__init__.py index a7d6cb4400..b274e3bc29 100644 --- a/server_addon/blender/server/__init__.py +++ b/server_addon/blender/server/__init__.py @@ -2,17 +2,11 @@ from typing import Type from ayon_server.addons import BaseServerAddon -from .version import __version__ from .settings import BlenderSettings, DEFAULT_VALUES class BlenderAddon(BaseServerAddon): - name = "blender" - title = "Blender" - version = __version__ settings_model: Type[BlenderSettings] = BlenderSettings - frontend_scopes = {} - services = {} async def get_default_settings(self): settings_model_cls = self.get_settings_model() diff --git a/server_addon/blender/server/version.py b/server_addon/blender/server/version.py deleted file mode 100644 index 9cb17e7976..0000000000 --- a/server_addon/blender/server/version.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = "0.1.8" From acaafa9b66b16fe243ee8e49f8afe1eacc9d8221 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 22 Apr 2024 14:27:42 +0200 Subject: [PATCH 57/65] aftereffects uses package.py --- server_addon/aftereffects/package.py | 3 +++ server_addon/aftereffects/server/__init__.py | 5 ----- server_addon/aftereffects/server/version.py | 3 --- 3 files changed, 3 insertions(+), 8 deletions(-) create mode 100644 server_addon/aftereffects/package.py delete mode 100644 server_addon/aftereffects/server/version.py diff --git a/server_addon/aftereffects/package.py b/server_addon/aftereffects/package.py new file mode 100644 index 0000000000..a680b37602 --- /dev/null +++ b/server_addon/aftereffects/package.py @@ -0,0 +1,3 @@ +name = "aftereffects" +title = "AfterEffects" +version = "0.1.3" diff --git a/server_addon/aftereffects/server/__init__.py b/server_addon/aftereffects/server/__init__.py index e14e76e9db..76e6d5b2eb 100644 --- a/server_addon/aftereffects/server/__init__.py +++ b/server_addon/aftereffects/server/__init__.py @@ -1,14 +1,9 @@ from ayon_server.addons import BaseServerAddon from .settings import AfterEffectsSettings, DEFAULT_AFTEREFFECTS_SETTING -from .version import __version__ class AfterEffects(BaseServerAddon): - name = "aftereffects" - title = "AfterEffects" - version = __version__ - settings_model = AfterEffectsSettings async def get_default_settings(self): diff --git a/server_addon/aftereffects/server/version.py b/server_addon/aftereffects/server/version.py deleted file mode 100644 index e57ad00718..0000000000 --- a/server_addon/aftereffects/server/version.py +++ /dev/null @@ -1,3 +0,0 @@ -# -*- coding: utf-8 -*- -"""Package declaring addon version.""" -__version__ = "0.1.3" From bc9a0dc59801b1a86b48d2b00fc7419e9ed548f6 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 22 Apr 2024 14:27:51 +0200 Subject: [PATCH 58/65] royal render uses package.py --- server_addon/royal_render/package.py | 3 +++ server_addon/royal_render/server/__init__.py | 4 ---- server_addon/royal_render/server/version.py | 1 - 3 files changed, 3 insertions(+), 5 deletions(-) create mode 100644 server_addon/royal_render/package.py delete mode 100644 server_addon/royal_render/server/version.py diff --git a/server_addon/royal_render/package.py b/server_addon/royal_render/package.py new file mode 100644 index 0000000000..1fdea4abbb --- /dev/null +++ b/server_addon/royal_render/package.py @@ -0,0 +1,3 @@ +name = "royalrender" +title = "Royal Render" +version = "0.1.1" diff --git a/server_addon/royal_render/server/__init__.py b/server_addon/royal_render/server/__init__.py index c5f0aafa00..5b10678136 100644 --- a/server_addon/royal_render/server/__init__.py +++ b/server_addon/royal_render/server/__init__.py @@ -2,14 +2,10 @@ from typing import Type from ayon_server.addons import BaseServerAddon -from .version import __version__ from .settings import RoyalRenderSettings, DEFAULT_VALUES class RoyalRenderAddon(BaseServerAddon): - name = "royalrender" - version = __version__ - title = "Royal Render" settings_model: Type[RoyalRenderSettings] = RoyalRenderSettings async def get_default_settings(self): diff --git a/server_addon/royal_render/server/version.py b/server_addon/royal_render/server/version.py deleted file mode 100644 index 485f44ac21..0000000000 --- a/server_addon/royal_render/server/version.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = "0.1.1" From e669563a2ef62d71ece87d8d2640c710406de047 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 22 Apr 2024 14:28:11 +0200 Subject: [PATCH 59/65] renamed royal_render folder to royalrender --- server_addon/{royal_render => royalrender}/package.py | 0 server_addon/{royal_render => royalrender}/server/__init__.py | 0 server_addon/{royal_render => royalrender}/server/settings.py | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename server_addon/{royal_render => royalrender}/package.py (100%) rename server_addon/{royal_render => royalrender}/server/__init__.py (100%) rename server_addon/{royal_render => royalrender}/server/settings.py (100%) diff --git a/server_addon/royal_render/package.py b/server_addon/royalrender/package.py similarity index 100% rename from server_addon/royal_render/package.py rename to server_addon/royalrender/package.py diff --git a/server_addon/royal_render/server/__init__.py b/server_addon/royalrender/server/__init__.py similarity index 100% rename from server_addon/royal_render/server/__init__.py rename to server_addon/royalrender/server/__init__.py diff --git a/server_addon/royal_render/server/settings.py b/server_addon/royalrender/server/settings.py similarity index 100% rename from server_addon/royal_render/server/settings.py rename to server_addon/royalrender/server/settings.py From 233794df9752b09e5f1823d91078354db5391263 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 22 Apr 2024 14:29:52 +0200 Subject: [PATCH 60/65] simplified package creation --- server_addon/create_ayon_addons.py | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/server_addon/create_ayon_addons.py b/server_addon/create_ayon_addons.py index bfd601af07..79b9aa5450 100644 --- a/server_addon/create_ayon_addons.py +++ b/server_addon/create_ayon_addons.py @@ -245,12 +245,8 @@ def create_addon_package( keep_source: bool, ): src_package_py = addon_dir / "package.py" - package = None - if src_package_py.exists(): - package = import_filepath(src_package_py) - addon_version = package.version - else: - addon_version = get_addon_version(addon_dir) + package = import_filepath(src_package_py) + addon_version = package.version addon_output_dir = output_dir / addon_dir.name / addon_version if addon_output_dir.exists(): @@ -259,18 +255,7 @@ def create_addon_package( # Copy server content dst_package_py = addon_output_dir / "package.py" - if package is not None: - shutil.copy(src_package_py, dst_package_py) - else: - addon_name = addon_dir.name - if addon_name == "royal_render": - addon_name = "royalrender" - package_py_content = PACKAGE_PY_TEMPLATE.format( - addon_name=addon_name, addon_version=addon_version - ) - - with open(dst_package_py, "w+") as pkg_py: - pkg_py.write(package_py_content) + shutil.copy(src_package_py, dst_package_py) server_dir = addon_dir / "server" shutil.copytree( From 6f1228ad42779bd654716a1cf4d6bac52a26dea0 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 22 Apr 2024 15:01:08 +0200 Subject: [PATCH 61/65] Fix #397: Always refresh workfiles tool on show Note: this also refreshes when the window is minimized and then brought up again --- .../ayon_core/tools/workfiles/widgets/window.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/client/ayon_core/tools/workfiles/widgets/window.py b/client/ayon_core/tools/workfiles/widgets/window.py index 8a2617d270..1cfae7ec90 100644 --- a/client/ayon_core/tools/workfiles/widgets/window.py +++ b/client/ayon_core/tools/workfiles/widgets/window.py @@ -118,11 +118,11 @@ class WorkfilesToolWindow(QtWidgets.QWidget): overlay_invalid_host = InvalidHostOverlay(self) overlay_invalid_host.setVisible(False) - first_show_timer = QtCore.QTimer() - first_show_timer.setSingleShot(True) - first_show_timer.setInterval(50) + show_timer = QtCore.QTimer() + show_timer.setSingleShot(True) + show_timer.setInterval(50) - first_show_timer.timeout.connect(self._on_first_show) + show_timer.timeout.connect(self._on_show) controller.register_event_callback( "save_as.finished", @@ -159,7 +159,7 @@ class WorkfilesToolWindow(QtWidgets.QWidget): self._tasks_widget = tasks_widget self._side_panel = side_panel - self._first_show_timer = first_show_timer + self._show_timer = show_timer self._post_init() @@ -287,9 +287,9 @@ class WorkfilesToolWindow(QtWidgets.QWidget): def showEvent(self, event): super(WorkfilesToolWindow, self).showEvent(event) + self._show_timer.start() if self._first_show: self._first_show = False - self._first_show_timer.start() self.setStyleSheet(style.load_stylesheet()) def keyPressEvent(self, event): @@ -303,9 +303,8 @@ class WorkfilesToolWindow(QtWidgets.QWidget): pass - def _on_first_show(self): - if not self._controller_refreshed: - self.refresh() + def _on_show(self): + self.refresh() def _on_file_text_filter_change(self, text): self._files_widget.set_text_filter(text) From 17390f839a2ce4a72cb347966f7174aab2b10424 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 22 Apr 2024 16:26:09 +0200 Subject: [PATCH 62/65] select latest workfile after model refresh --- .../widgets/files_widget_workarea.py | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/client/ayon_core/tools/workfiles/widgets/files_widget_workarea.py b/client/ayon_core/tools/workfiles/widgets/files_widget_workarea.py index 6a1572deb2..47b04d36fe 100644 --- a/client/ayon_core/tools/workfiles/widgets/files_widget_workarea.py +++ b/client/ayon_core/tools/workfiles/widgets/files_widget_workarea.py @@ -20,6 +20,8 @@ class WorkAreaFilesModel(QtGui.QStandardItemModel): controller (AbstractWorkfilesFrontend): The control object. """ + refreshed = QtCore.Signal() + def __init__(self, controller): super(WorkAreaFilesModel, self).__init__() @@ -163,6 +165,12 @@ class WorkAreaFilesModel(QtGui.QStandardItemModel): self._fill_items() def _fill_items(self): + try: + self._fill_items_impl() + finally: + self.refreshed.emit() + + def _fill_items_impl(self): folder_id = self._selected_folder_id task_id = self._selected_task_id if not folder_id or not task_id: @@ -285,6 +293,7 @@ class WorkAreaFilesWidget(QtWidgets.QWidget): selection_model.selectionChanged.connect(self._on_selection_change) view.double_clicked.connect(self._on_mouse_double_click) view.customContextMenuRequested.connect(self._on_context_menu) + model.refreshed.connect(self._on_model_refresh) controller.register_event_callback( "expected_selection_changed", @@ -298,6 +307,7 @@ class WorkAreaFilesWidget(QtWidgets.QWidget): self._controller = controller self._published_mode = False + self._change_selection_on_refresh = True def set_published_mode(self, published_mode): """Set the published mode. @@ -379,7 +389,9 @@ class WorkAreaFilesWidget(QtWidgets.QWidget): if not workfile_info["current"]: return + self._change_selection_on_refresh = False self._model.refresh() + self._change_selection_on_refresh = True workfile_name = workfile_info["name"] if ( @@ -394,3 +406,24 @@ class WorkAreaFilesWidget(QtWidgets.QWidget): self._controller.expected_workfile_selected( event["folder"]["id"], event["task"]["name"], workfile_name ) + + def _on_model_refresh(self): + if ( + not self._change_selection_on_refresh + or self._proxy_model.rowCount() < 1 + ): + return + + first_index = self._proxy_model.index(0, 0) + last_index = self._proxy_model.index( + 0, self._proxy_model.columnCount() - 1 + ) + selection = QtCore.QItemSelection(first_index, last_index) + seleciton_model = self._view.selectionModel() + seleciton_model.select( + selection, + ( + QtCore.QItemSelectionModel.ClearAndSelect + | QtCore.QItemSelectionModel.Current + ) + ) From 7cd9ec8a8dedf9a508b109df783ebaccb6f16a05 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 23 Apr 2024 00:30:46 +0200 Subject: [PATCH 63/65] Select index by latest date modified --- .../workfiles/widgets/files_widget_workarea.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/client/ayon_core/tools/workfiles/widgets/files_widget_workarea.py b/client/ayon_core/tools/workfiles/widgets/files_widget_workarea.py index 47b04d36fe..39abbfe739 100644 --- a/client/ayon_core/tools/workfiles/widgets/files_widget_workarea.py +++ b/client/ayon_core/tools/workfiles/widgets/files_widget_workarea.py @@ -414,16 +414,20 @@ class WorkAreaFilesWidget(QtWidgets.QWidget): ): return - first_index = self._proxy_model.index(0, 0) - last_index = self._proxy_model.index( - 0, self._proxy_model.columnCount() - 1 + # Find the row with latest date modified + latest_index = max( + (self._proxy_model.index(i, 0) for + i in range(self._proxy_model.rowCount())), + key=lambda model_index: model_index.date(DATE_MODIFIED_ROLE) ) - selection = QtCore.QItemSelection(first_index, last_index) - seleciton_model = self._view.selectionModel() - seleciton_model.select( - selection, + + # Select row of latest modified + selection_model = self._view.selectionModel() + selection_model.select( + latest_index, ( QtCore.QItemSelectionModel.ClearAndSelect | QtCore.QItemSelectionModel.Current + | QtCore.QItemSelectionModel.Rows ) ) From f6411be0c26623502efe1e59ba66c2b894c27d71 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 24 Apr 2024 01:36:42 +0200 Subject: [PATCH 64/65] Update client/ayon_core/tools/workfiles/widgets/files_widget_workarea.py Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- .../tools/workfiles/widgets/files_widget_workarea.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/client/ayon_core/tools/workfiles/widgets/files_widget_workarea.py b/client/ayon_core/tools/workfiles/widgets/files_widget_workarea.py index 39abbfe739..fe6abee951 100644 --- a/client/ayon_core/tools/workfiles/widgets/files_widget_workarea.py +++ b/client/ayon_core/tools/workfiles/widgets/files_widget_workarea.py @@ -416,9 +416,11 @@ class WorkAreaFilesWidget(QtWidgets.QWidget): # Find the row with latest date modified latest_index = max( - (self._proxy_model.index(i, 0) for - i in range(self._proxy_model.rowCount())), - key=lambda model_index: model_index.date(DATE_MODIFIED_ROLE) + ( + self._proxy_model.index(idx, 0) + for idx in range(self._proxy_model.rowCount()) + ), + key=lambda model_index: model_index.data(DATE_MODIFIED_ROLE) ) # Select row of latest modified From 7ef499e5a56c670faf3f9d7857089f5a2d81c207 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Thu, 25 Apr 2024 10:09:18 +0200 Subject: [PATCH 65/65] change substance painter version --- server_addon/substancepainter/package.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server_addon/substancepainter/package.py b/server_addon/substancepainter/package.py index a064d80fd7..d445b0059f 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.0" +version = "0.1.1"