mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
Merge branch 'develop' into enhancement/AY-1477_Use-custom-staging-dir-function-for-Houdini
This commit is contained in:
commit
5594529883
71 changed files with 389 additions and 203 deletions
|
|
@ -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)
|
||||
|
||||
|
|
@ -606,7 +605,7 @@ def prompt_new_file_with_mesh(mesh_filepath):
|
|||
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.
|
||||
|
|
@ -623,8 +622,6 @@ def prompt_new_file_with_mesh(mesh_filepath):
|
|||
"Failed to set mesh path with the prompt dialog:"
|
||||
f"{mesh_filepath}\n\n"
|
||||
"Creating new project directly with the mesh path instead.")
|
||||
else:
|
||||
dialog.done(dialog.Accepted)
|
||||
|
||||
new_action = _get_new_project_action()
|
||||
if not new_action:
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import copy
|
||||
from qtpy import QtWidgets, QtCore
|
||||
from ayon_core.pipeline import (
|
||||
load,
|
||||
get_representation_path,
|
||||
|
|
@ -8,10 +10,133 @@ 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
|
||||
|
||||
import substance_painter.project
|
||||
import qargparse
|
||||
|
||||
|
||||
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`
|
||||
|
||||
Args:
|
||||
substance_attr (str): The `substance_painter.project` attribute,
|
||||
for example "ProjectWorkflow.Default"
|
||||
|
||||
Returns:
|
||||
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("."):
|
||||
root = getattr(root, attr, None)
|
||||
if root is None:
|
||||
raise ValueError(
|
||||
"Substance Painter project attribute"
|
||||
f" does not exist: {substance_attr}")
|
||||
|
||||
return root
|
||||
|
||||
|
||||
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):
|
||||
"""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.configuration = None
|
||||
self.template_names = [template["name"] for template
|
||||
in project_templates]
|
||||
self.project_templates = project_templates
|
||||
|
||||
self.widgets = {
|
||||
"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.QDialogButtonBox(
|
||||
QtWidgets.QDialogButtonBox.Ok
|
||||
| QtWidgets.QDialogButtonBox.Cancel)
|
||||
}
|
||||
|
||||
self.widgets["template_options"].addItems(self.template_names)
|
||||
|
||||
template_name = self.widgets["template_options"].currentText()
|
||||
self._update_to_match_template(template_name)
|
||||
# Build clickboxes
|
||||
layout = QtWidgets.QHBoxLayout(self.widgets["clickbox"])
|
||||
layout.addWidget(self.widgets["import_cameras"])
|
||||
layout.addWidget(self.widgets["preserve_strokes"])
|
||||
# Build combobox
|
||||
layout = QtWidgets.QHBoxLayout(self.widgets["combobox"])
|
||||
layout.addWidget(self.widgets["template_options"])
|
||||
# Build buttons
|
||||
layout = QtWidgets.QHBoxLayout(self.widgets["buttons"])
|
||||
# Build layout.
|
||||
layout = QtWidgets.QVBoxLayout(self)
|
||||
layout.addWidget(self.widgets["label"])
|
||||
layout.addWidget(self.widgets["combobox"])
|
||||
layout.addWidget(self.widgets["clickbox"])
|
||||
layout.addWidget(self.widgets["buttons"])
|
||||
|
||||
self.widgets["template_options"].currentTextChanged.connect(
|
||||
self._update_to_match_template)
|
||||
self.widgets["buttons"].accepted.connect(self.on_accept)
|
||||
self.widgets["buttons"].rejected.connect(self.on_reject)
|
||||
|
||||
def on_accept(self):
|
||||
self.configuration = self.get_project_configuration()
|
||||
self.close()
|
||||
|
||||
def on_reject(self):
|
||||
self.close()
|
||||
|
||||
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_project_configuration(self):
|
||||
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["import_cameras"] = self.widgets["import_cameras"].isChecked()
|
||||
template["preserve_strokes"] = (
|
||||
self.widgets["preserve_strokes"].isChecked()
|
||||
)
|
||||
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.exec_()
|
||||
configuration = dialog.configuration
|
||||
dialog.deleteLater()
|
||||
return configuration
|
||||
|
||||
|
||||
class SubstanceLoadProjectMesh(load.LoaderPlugin):
|
||||
|
|
@ -25,48 +150,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."
|
||||
)
|
||||
]
|
||||
# Defined via settings
|
||||
project_templates = []
|
||||
|
||||
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)
|
||||
sp_settings = substance_painter.project.Settings(
|
||||
import_cameras=import_cameras
|
||||
)
|
||||
result = SubstanceProjectConfigurationWindow.prompt(
|
||||
self.project_templates)
|
||||
if not result:
|
||||
# cancelling loader action
|
||||
return
|
||||
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:
|
||||
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
|
||||
)
|
||||
|
||||
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
|
||||
)
|
||||
else:
|
||||
# Reload the mesh
|
||||
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
|
||||
|
|
@ -92,7 +204,7 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin):
|
|||
# from the user's original choice. We don't store 'preserve_strokes'
|
||||
# as we always preserve strokes on updates.
|
||||
container["options"] = {
|
||||
"import_cameras": import_cameras,
|
||||
"import_cameras": result["import_cameras"],
|
||||
}
|
||||
|
||||
set_container_metadata(project_mesh_object_name, container)
|
||||
|
|
|
|||
|
|
@ -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,30 @@ 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
|
||||
|
||||
# Find the row with latest date modified
|
||||
latest_index = max(
|
||||
(
|
||||
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
|
||||
selection_model = self._view.selectionModel()
|
||||
selection_model.select(
|
||||
latest_index,
|
||||
(
|
||||
QtCore.QItemSelectionModel.ClearAndSelect
|
||||
| QtCore.QItemSelectionModel.Current
|
||||
| QtCore.QItemSelectionModel.Rows
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
3
server_addon/aftereffects/package.py
Normal file
3
server_addon/aftereffects/package.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
name = "aftereffects"
|
||||
title = "AfterEffects"
|
||||
version = "0.1.3"
|
||||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Package declaring addon version."""
|
||||
__version__ = "0.1.3"
|
||||
3
server_addon/blender/package.py
Normal file
3
server_addon/blender/package.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
name = "blender"
|
||||
title = "Blender"
|
||||
version = "0.1.8"
|
||||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
__version__ = "0.1.8"
|
||||
3
server_addon/celaction/package.py
Normal file
3
server_addon/celaction/package.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
name = "celaction"
|
||||
title = "CelAction"
|
||||
version = "0.1.0"
|
||||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
__version__ = "0.1.0"
|
||||
3
server_addon/clockify/package.py
Normal file
3
server_addon/clockify/package.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
name = "clockify"
|
||||
title = "Clockify"
|
||||
version = "0.1.1"
|
||||
|
|
@ -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 = {}
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
__version__ = "0.1.1"
|
||||
|
|
@ -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(
|
||||
|
|
|
|||
3
server_addon/deadline/package.py
Normal file
3
server_addon/deadline/package.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
name = "deadline"
|
||||
title = "Deadline"
|
||||
version = "0.1.10"
|
||||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
__version__ = "0.1.10"
|
||||
3
server_addon/flame/package.py
Normal file
3
server_addon/flame/package.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
name = "flame"
|
||||
title = "Flame"
|
||||
version = "0.1.0"
|
||||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
__version__ = "0.1.0"
|
||||
3
server_addon/fusion/package.py
Normal file
3
server_addon/fusion/package.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
name = "fusion"
|
||||
title = "Fusion"
|
||||
version = "0.1.5"
|
||||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
__version__ = "0.1.5"
|
||||
3
server_addon/harmony/package.py
Normal file
3
server_addon/harmony/package.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
name = "harmony"
|
||||
title = "Harmony"
|
||||
version = "0.1.2"
|
||||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Package declaring addon version."""
|
||||
__version__ = "0.1.2"
|
||||
3
server_addon/hiero/package.py
Normal file
3
server_addon/hiero/package.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
name = "hiero"
|
||||
title = "Hiero"
|
||||
version = "0.1.2"
|
||||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
__version__ = "0.1.2"
|
||||
3
server_addon/houdini/package.py
Normal file
3
server_addon/houdini/package.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
name = "houdini"
|
||||
title = "Houdini"
|
||||
version = "0.2.12"
|
||||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
__version__ = "0.2.12"
|
||||
3
server_addon/max/package.py
Normal file
3
server_addon/max/package.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
name = "max"
|
||||
title = "Max"
|
||||
version = "0.1.7"
|
||||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
__version__ = "0.1.7"
|
||||
3
server_addon/maya/package.py
Normal file
3
server_addon/maya/package.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
name = "maya"
|
||||
title = "Maya"
|
||||
version = "0.1.16"
|
||||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Package declaring addon version."""
|
||||
__version__ = "0.1.16"
|
||||
3
server_addon/nuke/package.py
Normal file
3
server_addon/nuke/package.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
name = "nuke"
|
||||
title = "Nuke"
|
||||
version = "0.1.10"
|
||||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
__version__ = "0.1.10"
|
||||
3
server_addon/photoshop/package.py
Normal file
3
server_addon/photoshop/package.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
name = "photoshop"
|
||||
title = "Photoshop"
|
||||
version = "0.1.2"
|
||||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Package declaring addon version."""
|
||||
__version__ = "0.1.2"
|
||||
3
server_addon/resolve/package.py
Normal file
3
server_addon/resolve/package.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
name = "resolve"
|
||||
title = "DaVinci Resolve"
|
||||
version = "0.1.0"
|
||||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
__version__ = "0.1.0"
|
||||
|
|
@ -1 +0,0 @@
|
|||
__version__ = "0.1.1"
|
||||
3
server_addon/royalrender/package.py
Normal file
3
server_addon/royalrender/package.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
name = "royalrender"
|
||||
title = "Royal Render"
|
||||
version = "0.1.1"
|
||||
|
|
@ -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):
|
||||
3
server_addon/substancepainter/package.py
Normal file
3
server_addon/substancepainter/package.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
name = "substancepainter"
|
||||
title = "Substance Painter"
|
||||
version = "0.1.1"
|
||||
|
|
@ -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):
|
||||
|
|
|
|||
122
server_addon/substancepainter/server/settings/load_plugins.py
Normal file
122
server_addon/substancepainter/server/settings/load_plugins.py
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
from ayon_server.settings import BaseSettingsModel, SettingsField
|
||||
|
||||
|
||||
def normal_map_format_enum():
|
||||
return [
|
||||
{"label": "DirectX", "value": "NormalMapFormat.DirectX"},
|
||||
{"label": "OpenGL", "value": "NormalMapFormat.OpenGL"},
|
||||
]
|
||||
|
||||
|
||||
def tangent_space_enum():
|
||||
return [
|
||||
{"label": "Per Fragment", "value": "TangentSpace.PerFragment"},
|
||||
{"label": "Per Vertex", "value": "TangentSpace.PerVertex"},
|
||||
]
|
||||
|
||||
|
||||
def uv_workflow_enum():
|
||||
return [
|
||||
{"label": "Default", "value": "ProjectWorkflow.Default"},
|
||||
{"label": "UV Tile", "value": "ProjectWorkflow.UVTile"},
|
||||
{"label": "Texture Set Per UV Tile",
|
||||
"value": "ProjectWorkflow.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": "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
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
from ayon_server.settings import BaseSettingsModel, SettingsField
|
||||
from .imageio import ImageIOSettings, DEFAULT_IMAGEIO_SETTINGS
|
||||
from .load_plugins import LoadersModel, DEFAULT_LOADER_SETTINGS
|
||||
|
||||
|
||||
class ShelvesSettingsModel(BaseSettingsModel):
|
||||
|
|
@ -17,9 +18,12 @@ class SubstancePainterSettings(BaseSettingsModel):
|
|||
default_factory=list,
|
||||
title="Shelves"
|
||||
)
|
||||
load: LoadersModel = SettingsField(
|
||||
default_factory=DEFAULT_LOADER_SETTINGS, title="Loaders")
|
||||
|
||||
|
||||
DEFAULT_SPAINTER_SETTINGS = {
|
||||
"imageio": DEFAULT_IMAGEIO_SETTINGS,
|
||||
"shelves": []
|
||||
"shelves": [],
|
||||
"load": DEFAULT_LOADER_SETTINGS,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
__version__ = "0.1.0"
|
||||
3
server_addon/timers_manager/package.py
Normal file
3
server_addon/timers_manager/package.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
name = "timers_manager"
|
||||
title = "Timers Manager"
|
||||
version = "0.1.1"
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
__version__ = "0.1.1"
|
||||
3
server_addon/traypublisher/package.py
Normal file
3
server_addon/traypublisher/package.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
name = "traypublisher"
|
||||
title = "TrayPublisher"
|
||||
version = "0.1.4"
|
||||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Package declaring addon version."""
|
||||
__version__ = "0.1.4"
|
||||
3
server_addon/tvpaint/package.py
Normal file
3
server_addon/tvpaint/package.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
name = "tvpaint"
|
||||
title = "TVPaint"
|
||||
version = "0.1.2"
|
||||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
__version__ = "0.1.2"
|
||||
3
server_addon/unreal/package.py
Normal file
3
server_addon/unreal/package.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
name = "unreal"
|
||||
title = "Unreal"
|
||||
version = "0.1.0"
|
||||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
__version__ = "0.1.0"
|
||||
Loading…
Add table
Add a link
Reference in a new issue