Merge branch 'develop' into enhancement/maya_workfile_templates_refactor

This commit is contained in:
Ondřej Samohel 2024-05-03 17:42:36 +02:00 committed by GitHub
commit 8ea550dbb3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 125 additions and 30 deletions

View file

@ -51,13 +51,12 @@ def open_file(filepath):
project = hiero.core.projects()[-1] project = hiero.core.projects()[-1]
# open project file # Close previous project if its different to the current project.
hiero.core.openProject(filepath.replace(os.path.sep, "/")) filepath = filepath.replace(os.path.sep, "/")
if project.path().replace(os.path.sep, "/") != filepath:
# close previous project # open project file
project.close() hiero.core.openProject(filepath)
project.close()
return True return True

View file

@ -2,7 +2,7 @@ import os
import json import json
from ayon_core.pipeline import publish from ayon_core.pipeline import publish
from ayon_core.hosts.maya.api.lib import extract_alembic from ayon_core.hosts.maya.api.alembic import extract_alembic
from maya import cmds from maya import cmds

View file

@ -3,8 +3,8 @@ import os
from maya import cmds from maya import cmds
from ayon_core.pipeline import publish from ayon_core.pipeline import publish
from ayon_core.hosts.maya.api.alembic import extract_alembic
from ayon_core.hosts.maya.api.lib import ( from ayon_core.hosts.maya.api.lib import (
extract_alembic,
suspended_refresh, suspended_refresh,
maintained_selection, maintained_selection,
iter_visible_nodes_in_range iter_visible_nodes_in_range

View file

@ -5,8 +5,8 @@ import os
from maya import cmds # noqa from maya import cmds # noqa
from ayon_core.pipeline import publish from ayon_core.pipeline import publish
from ayon_core.hosts.maya.api.alembic import extract_alembic
from ayon_core.hosts.maya.api.lib import ( from ayon_core.hosts.maya.api.lib import (
extract_alembic,
suspended_refresh, suspended_refresh,
maintained_selection maintained_selection
) )

View file

@ -10,6 +10,7 @@ from ayon_core.pipeline.publish import (
RepairAction, RepairAction,
ValidateContentsOrder, ValidateContentsOrder,
PublishValidationError, PublishValidationError,
OptionalPyblishPluginMixin
) )
from ayon_core.hosts.maya.api import lib from ayon_core.hosts.maya.api import lib
from ayon_core.hosts.maya.api.lib_rendersettings import RenderSettings from ayon_core.hosts.maya.api.lib_rendersettings import RenderSettings
@ -37,7 +38,8 @@ def get_redshift_image_format_labels():
return mel.eval("{0}={0}".format(var)) return mel.eval("{0}={0}".format(var))
class ValidateRenderSettings(pyblish.api.InstancePlugin): class ValidateRenderSettings(pyblish.api.InstancePlugin,
OptionalPyblishPluginMixin):
"""Validates the global render settings """Validates the global render settings
* File Name Prefix must start with: `<Scene>` * File Name Prefix must start with: `<Scene>`
@ -55,7 +57,7 @@ class ValidateRenderSettings(pyblish.api.InstancePlugin):
* Frame Padding must be: * Frame Padding must be:
* default: 4 * default: 4
* Animation must be toggle on, in Render Settings - Common tab: * Animation must be toggled on, in Render Settings - Common tab:
* vray: Animation on standard of specific * vray: Animation on standard of specific
* arnold: Frame / Animation ext: Any choice without "(Single Frame)" * arnold: Frame / Animation ext: Any choice without "(Single Frame)"
* redshift: Animation toggled on * redshift: Animation toggled on
@ -67,10 +69,11 @@ class ValidateRenderSettings(pyblish.api.InstancePlugin):
""" """
order = ValidateContentsOrder order = ValidateContentsOrder
label = "Render Settings" label = "Validate Render Settings"
hosts = ["maya"] hosts = ["maya"]
families = ["renderlayer"] families = ["renderlayer"]
actions = [RepairAction] actions = [RepairAction]
optional = True
ImagePrefixes = { ImagePrefixes = {
'mentalray': 'defaultRenderGlobals.imageFilePrefix', 'mentalray': 'defaultRenderGlobals.imageFilePrefix',
@ -112,6 +115,8 @@ class ValidateRenderSettings(pyblish.api.InstancePlugin):
DEFAULT_PREFIX = "<Scene>/<RenderLayer>/<RenderLayer>_<RenderPass>" DEFAULT_PREFIX = "<Scene>/<RenderLayer>/<RenderLayer>_<RenderPass>"
def process(self, instance): def process(self, instance):
if not self.is_active(instance.data):
return
invalid = self.get_invalid(instance) invalid = self.get_invalid(instance)
if invalid: if invalid:

View file

@ -260,11 +260,11 @@ class UEProjectGenerationWorker(UEWorker):
self.failed.emit(msg, return_code) self.failed.emit(msg, return_code)
raise RuntimeError(msg) raise RuntimeError(msg)
# ensure we have PySide2 installed in engine # ensure we have PySide2/6 installed in engine
self.progress.emit(0) self.progress.emit(0)
self.stage_begin.emit( self.stage_begin.emit(
(f"Checking PySide2 installation... {stage_count} " (f"Checking Qt bindings installation... {stage_count} "
f" out of {stage_count}")) f" out of {stage_count}"))
python_path = None python_path = None
if platform.system().lower() == "windows": if platform.system().lower() == "windows":
@ -287,11 +287,30 @@ class UEProjectGenerationWorker(UEWorker):
msg = f"Unreal Python not found at {python_path}" msg = f"Unreal Python not found at {python_path}"
self.failed.emit(msg, 1) self.failed.emit(msg, 1)
raise RuntimeError(msg) raise RuntimeError(msg)
pyside_cmd = [python_path.as_posix(),
"-m", pyside_version = "PySide2"
"pip", ue_version = self.ue_version.split(".")
"install", if int(ue_version[0]) == 5 and int(ue_version[1]) >= 4:
"pyside2"] # Use PySide6 6.6.3 because 6.7.0 had a bug
# - 'QPushButton' can't be added to 'QBoxLayout'
pyside_version = "PySide6==6.6.3"
site_packages_prefix = python_path.parent.as_posix()
pyside_cmd = [
python_path.as_posix(),
"-m", "pip",
"install",
"--ignore-installed",
pyside_version,
]
if platform.system().lower() == "windows":
pyside_cmd += ["--target", site_packages_prefix]
print(f"--- Installing {pyside_version} ...")
print(" ".join(pyside_cmd))
pyside_install = subprocess.Popen(pyside_cmd, pyside_install = subprocess.Popen(pyside_cmd,
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
@ -306,8 +325,8 @@ class UEProjectGenerationWorker(UEWorker):
return_code = pyside_install.wait() return_code = pyside_install.wait()
if return_code and return_code != 0: if return_code and return_code != 0:
msg = ("Failed to create the project! " msg = (f"Failed to create the project! {return_code} "
"The installation of PySide2 has failed!") f"The installation of {pyside_version} has failed!: {pyside_install}")
self.failed.emit(msg, return_code) self.failed.emit(msg, return_code)
raise RuntimeError(msg) raise RuntimeError(msg)

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View file

@ -106,7 +106,7 @@ line-ending = "auto"
[tool.codespell] [tool.codespell]
# Ignore words that are not in the dictionary. # Ignore words that are not in the dictionary.
ignore-words-list = "ayon,ynput,parms,parm,hda,developpement" ignore-words-list = "ayon,ynput,parms,parm,hda,developpement,ue"
skip = "./.*,./package/*,*/vendor/*,*/unreal/integration/*,*/aftereffects/api/extension/js/libs/*" skip = "./.*,./package/*,*/vendor/*,*/unreal/integration/*,*/aftereffects/api/extension/js/libs/*"
count = true count = true

View file

@ -110,6 +110,26 @@ class ApplicationsAddon(AYONAddon, IPluginPaths):
] ]
} }
def launch_application(
self, app_name, project_name, folder_path, task_name
):
"""Launch application.
Args:
app_name (str): Full application name e.g. 'maya/2024'.
project_name (str): Project name.
folder_path (str): Folder path.
task_name (str): Task name.
"""
app_manager = self.get_applications_manager()
return app_manager.launch(
app_name,
project_name=project_name,
folder_path=folder_path,
task_name=task_name,
)
# --- CLI --- # --- CLI ---
def cli(self, addon_click_group): def cli(self, addon_click_group):
main_group = click_wrap.group( main_group = click_wrap.group(
@ -134,6 +154,17 @@ class ApplicationsAddon(AYONAddon, IPluginPaths):
default=None default=None
) )
) )
(
main_group.command(
self._cli_launch_applications,
name="launch",
help="Launch application"
)
.option("--app", required=True, help="Application name")
.option("--project", required=True, help="Project name")
.option("--folder", required=True, help="Folder path")
.option("--task", required=True, help="Task name")
)
# Convert main command to click object and add it to parent group # Convert main command to click object and add it to parent group
addon_click_group.add_command( addon_click_group.add_command(
main_group.to_click_obj() main_group.to_click_obj()
@ -171,3 +202,15 @@ class ApplicationsAddon(AYONAddon, IPluginPaths):
with open(output_json_path, "w") as file_stream: with open(output_json_path, "w") as file_stream:
json.dump(env, file_stream, indent=4) json.dump(env, file_stream, indent=4)
def _cli_launch_applications(self, project, folder, task, app):
"""Launch application.
Args:
project (str): Project name.
folder (str): Folder path.
task (str): Task name.
app (str): Full application name e.g. 'maya/2024'.
"""
self.launch_application(app, project, folder, task)

View file

@ -1,6 +1,6 @@
name = "applications" name = "applications"
title = "Applications" title = "Applications"
version = "0.2.0" version = "0.2.1"
ayon_server_version = ">=1.0.7" ayon_server_version = ">=1.0.7"
ayon_launcher_version = ">=1.0.2" ayon_launcher_version = ">=1.0.2"

View file

@ -1271,6 +1271,28 @@
} }
] ]
}, },
"equalizer": {
"enabled": true,
"label": "3DEqualizer",
"icon": "{}/app_icons/3de4.png",
"host_name": "equalizer",
"environment": "{}",
"variants": [
{
"name": "7-1v2",
"label": "7.1v2",
"use_python_2": false,
"executables": {
"windows": [
"C:\\Program Files\\3DE4_win64_r7.1v2\\bin\\3DE4.exe"
],
"darwin": [],
"linux": []
},
"environment": "{}"
}
]
},
"additional_apps": [] "additional_apps": []
} }
} }

View file

@ -190,6 +190,8 @@ class ApplicationsSettings(BaseSettingsModel):
default_factory=AppGroupWithPython, title="OpenRV") default_factory=AppGroupWithPython, title="OpenRV")
zbrush: AppGroup = SettingsField( zbrush: AppGroup = SettingsField(
default_factory=AppGroupWithPython, title="Zbrush") default_factory=AppGroupWithPython, title="Zbrush")
equalizer: AppGroup = SettingsField(
default_factory=AppGroupWithPython, title="3DEqualizer")
additional_apps: list[AdditionalAppGroup] = SettingsField( additional_apps: list[AdditionalAppGroup] = SettingsField(
default_factory=list, title="Additional Applications") default_factory=list, title="Additional Applications")

View file

@ -1,3 +1,3 @@
name = "deadline" name = "deadline"
title = "Deadline" title = "Deadline"
version = "0.1.10" version = "0.1.11"

View file

@ -191,7 +191,6 @@ class NukeSubmitDeadlineModel(BaseSettingsModel):
@validator( @validator(
"limit_groups", "limit_groups",
"env_allowed_keys",
"env_search_replace_values") "env_search_replace_values")
def validate_unique_names(cls, value): def validate_unique_names(cls, value):
ensure_unique_names(value) ensure_unique_names(value)

View file

@ -229,7 +229,7 @@ class ValidateAttributesModel(BaseSettingsModel):
if not success: if not success:
raise BadRequestException( raise BadRequestException(
"The attibutes can't be parsed as json object" "The attributes can't be parsed as json object"
) )
return value return value
@ -265,7 +265,7 @@ class ValidateUnrealStaticMeshNameModel(BaseSettingsModel):
enabled: bool = SettingsField(title="ValidateUnrealStaticMeshName") enabled: bool = SettingsField(title="ValidateUnrealStaticMeshName")
optional: bool = SettingsField(title="Optional") optional: bool = SettingsField(title="Optional")
validate_mesh: bool = SettingsField(title="Validate mesh names") validate_mesh: bool = SettingsField(title="Validate mesh names")
validate_collision: bool = SettingsField(title="Validate collison names") validate_collision: bool = SettingsField(title="Validate collision names")
class ValidateCycleErrorModel(BaseSettingsModel): class ValidateCycleErrorModel(BaseSettingsModel):
@ -288,7 +288,7 @@ class ValidatePluginPathAttributesModel(BaseSettingsModel):
and the node attribute is <b>abc_file</b> and the node attribute is <b>abc_file</b>
""" """
enabled: bool = True enabled: bool = SettingsField(title="Enabled")
optional: bool = SettingsField(title="Optional") optional: bool = SettingsField(title="Optional")
active: bool = SettingsField(title="Active") active: bool = SettingsField(title="Active")
attribute: list[ValidatePluginPathAttributesAttrModel] = SettingsField( attribute: list[ValidatePluginPathAttributesAttrModel] = SettingsField(
@ -310,6 +310,9 @@ class RendererAttributesModel(BaseSettingsModel):
class ValidateRenderSettingsModel(BaseSettingsModel): class ValidateRenderSettingsModel(BaseSettingsModel):
enabled: bool = SettingsField(title="Enabled")
optional: bool = SettingsField(title="Optional")
active: bool = SettingsField(title="Active")
arnold_render_attributes: list[RendererAttributesModel] = SettingsField( arnold_render_attributes: list[RendererAttributesModel] = SettingsField(
default_factory=list, title="Arnold Render Attributes") default_factory=list, title="Arnold Render Attributes")
vray_render_attributes: list[RendererAttributesModel] = SettingsField( vray_render_attributes: list[RendererAttributesModel] = SettingsField(
@ -613,7 +616,7 @@ class ExtractGPUCacheModel(BaseSettingsModel):
title="Optimize Animations For Motion Blur" title="Optimize Animations For Motion Blur"
) )
writeMaterials: bool = SettingsField(title="Write Materials") writeMaterials: bool = SettingsField(title="Write Materials")
useBaseTessellation: bool = SettingsField(title="User Base Tesselation") useBaseTessellation: bool = SettingsField(title="User Based Tessellation")
class PublishersModel(BaseSettingsModel): class PublishersModel(BaseSettingsModel):
@ -1171,6 +1174,9 @@ DEFAULT_PUBLISH_SETTINGS = {
] ]
}, },
"ValidateRenderSettings": { "ValidateRenderSettings": {
"enabled": True,
"active": True,
"optional": False,
"arnold_render_attributes": [], "arnold_render_attributes": [],
"vray_render_attributes": [], "vray_render_attributes": [],
"redshift_render_attributes": [], "redshift_render_attributes": [],