mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
Add Qt dialog to support users to choose their templates for project creation
This commit is contained in:
parent
38d6a34b9b
commit
d4fdf85306
3 changed files with 145 additions and 110 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue