mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 12:54:40 +01:00
AYON: Addon settings in OpenPype (#5347)
* copied addons from 'ayon-addon-settings' * added AE, photoshop and harmony addon * moved openpype to subfolder * cleanup repository files * updated create package script and README.md * formatting fixes * added cli flags to be able keep server structure * print progress and output dir * another formatting fixes
This commit is contained in:
parent
e6d9697e23
commit
2b37b8af48
167 changed files with 15525 additions and 146 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -37,7 +37,7 @@ Temporary Items
|
|||
###########
|
||||
/build
|
||||
/dist/
|
||||
/server_addon/package/*
|
||||
/server_addon/packages/*
|
||||
|
||||
/vendor/bin/*
|
||||
/vendor/python/*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# OpenPype addon for AYON server
|
||||
Convert openpype into AYON addon which can be installed on AYON server. The versioning of the addon is following versioning of OpenPype.
|
||||
# Addons for AYON server
|
||||
Preparation of AYON addons based on OpenPype codebase. The output is a bunch of zip files in `./packages` directory that can be uploaded to AYON server. One of the packages is `openpype` which is OpenPype code converted to AYON addon. The addon is must have requirement to be able to use `ayon-launcher`. The versioning of `openpype` addon is following versioning of OpenPype. The other addons contain only settings models.
|
||||
|
||||
## Intro
|
||||
OpenPype is transitioning to AYON, a dedicated server with its own database, moving away from MongoDB. During this transition period, OpenPype will remain compatible with both MongoDB and AYON. However, we will gradually update the codebase to align with AYON's data structure and separate individual components into addons.
|
||||
|
|
@ -11,11 +11,24 @@ Since the implementation of the AYON Launcher is not yet fully completed, we wil
|
|||
During this transitional period, the AYON Launcher addon will be a requirement as the entry point for using the AYON Launcher.
|
||||
|
||||
## How to start
|
||||
There is a `create_ayon_addon.py` python file which contains logic how to create server addon from OpenPype codebase. Just run the code.
|
||||
There is a `create_ayon_addons.py` python file which contains logic how to create server addon from OpenPype codebase. Just run the code.
|
||||
```shell
|
||||
./.poetry/bin/poetry run python ./server_addon/create_ayon_addon.py
|
||||
./.poetry/bin/poetry run python ./server_addon/create_ayon_addons.py
|
||||
```
|
||||
|
||||
It will create directory `./package/openpype/<OpenPype version>/*` folder with all files necessary for AYON server. You can then copy `./package/openpype/` to server addons, or zip the folder and upload it to AYON server. Restart server to update addons information, add the addon version to server bundle and set the bundle for production or staging usage.
|
||||
It will create directory `./packages/<addon name>.zip` files for AYON server. You can then copy upload the zip files to AYON server. Restart server to update addons information, add the addon version to server bundle and set the bundle for production or staging usage.
|
||||
|
||||
Once addon is on server and is enabled, you can just run AYON launcher. Content will be downloaded and used automatically.
|
||||
|
||||
### Additional arguments
|
||||
Additional arguments are useful for development purposes.
|
||||
|
||||
To skip zip creation to keep only server ready folder structure, pass `--skip-zip` argument.
|
||||
```shell
|
||||
./.poetry/bin/poetry run python ./server_addon/create_ayon_addons.py --skip-zip
|
||||
```
|
||||
|
||||
To create both zips and keep folder structure, pass `--keep-sources` argument.
|
||||
```shell
|
||||
./.poetry/bin/poetry run python ./server_addon/create_ayon_addons.py --keep-sources
|
||||
```
|
||||
|
|
|
|||
202
server_addon/aftereffects/LICENSE
Normal file
202
server_addon/aftereffects/LICENSE
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
4
server_addon/aftereffects/README.md
Normal file
4
server_addon/aftereffects/README.md
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
AfterEffects Addon
|
||||
===============
|
||||
|
||||
Integration with Adobe AfterEffects.
|
||||
15
server_addon/aftereffects/server/__init__.py
Normal file
15
server_addon/aftereffects/server/__init__.py
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
from ayon_server.addons import BaseServerAddon
|
||||
|
||||
from .settings import AfterEffectsSettings, DEFAULT_AFTEREFFECTS_SETTING
|
||||
from .version import __version__
|
||||
|
||||
|
||||
class AfterEffects(BaseServerAddon):
|
||||
name = "aftereffects"
|
||||
version = __version__
|
||||
|
||||
settings_model = AfterEffectsSettings
|
||||
|
||||
async def get_default_settings(self):
|
||||
settings_model_cls = self.get_settings_model()
|
||||
return settings_model_cls(**DEFAULT_AFTEREFFECTS_SETTING)
|
||||
10
server_addon/aftereffects/server/settings/__init__.py
Normal file
10
server_addon/aftereffects/server/settings/__init__.py
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
from .main import (
|
||||
AfterEffectsSettings,
|
||||
DEFAULT_AFTEREFFECTS_SETTING,
|
||||
)
|
||||
|
||||
|
||||
__all__ = (
|
||||
"AfterEffectsSettings",
|
||||
"DEFAULT_AFTEREFFECTS_SETTING",
|
||||
)
|
||||
16
server_addon/aftereffects/server/settings/creator_plugins.py
Normal file
16
server_addon/aftereffects/server/settings/creator_plugins.py
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
from pydantic import Field
|
||||
|
||||
from ayon_server.settings import BaseSettingsModel
|
||||
|
||||
|
||||
class CreateRenderPlugin(BaseSettingsModel):
|
||||
mark_for_review: bool = Field(True, title="Review")
|
||||
defaults: list[str] = Field(default_factory=list,
|
||||
title="Default Variants")
|
||||
|
||||
|
||||
class AfterEffectsCreatorPlugins(BaseSettingsModel):
|
||||
RenderCreator: CreateRenderPlugin = Field(
|
||||
title="Create Render",
|
||||
default_factory=CreateRenderPlugin,
|
||||
)
|
||||
48
server_addon/aftereffects/server/settings/imageio.py
Normal file
48
server_addon/aftereffects/server/settings/imageio.py
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
from pydantic import Field, validator
|
||||
from ayon_server.settings import BaseSettingsModel
|
||||
from ayon_server.settings.validators import ensure_unique_names
|
||||
|
||||
|
||||
class ImageIOConfigModel(BaseSettingsModel):
|
||||
override_global_config: bool = Field(
|
||||
False,
|
||||
title="Override global OCIO config"
|
||||
)
|
||||
filepath: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Config path"
|
||||
)
|
||||
|
||||
|
||||
class ImageIOFileRuleModel(BaseSettingsModel):
|
||||
name: str = Field("", title="Rule name")
|
||||
pattern: str = Field("", title="Regex pattern")
|
||||
colorspace: str = Field("", title="Colorspace name")
|
||||
ext: str = Field("", title="File extension")
|
||||
|
||||
|
||||
class ImageIOFileRulesModel(BaseSettingsModel):
|
||||
activate_host_rules: bool = Field(False)
|
||||
rules: list[ImageIOFileRuleModel] = Field(
|
||||
default_factory=list,
|
||||
title="Rules"
|
||||
)
|
||||
|
||||
@validator("rules")
|
||||
def validate_unique_outputs(cls, value):
|
||||
ensure_unique_names(value)
|
||||
return value
|
||||
|
||||
|
||||
class AfterEffectsImageIOModel(BaseSettingsModel):
|
||||
activate_host_color_management: bool = Field(
|
||||
True, title="Enable Color Management"
|
||||
)
|
||||
ocio_config: ImageIOConfigModel = Field(
|
||||
default_factory=ImageIOConfigModel,
|
||||
title="OCIO config"
|
||||
)
|
||||
file_rules: ImageIOFileRulesModel = Field(
|
||||
default_factory=ImageIOFileRulesModel,
|
||||
title="File Rules"
|
||||
)
|
||||
62
server_addon/aftereffects/server/settings/main.py
Normal file
62
server_addon/aftereffects/server/settings/main.py
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
from pydantic import Field
|
||||
from ayon_server.settings import BaseSettingsModel
|
||||
|
||||
from .imageio import AfterEffectsImageIOModel
|
||||
from .creator_plugins import AfterEffectsCreatorPlugins
|
||||
from .publish_plugins import AfterEffectsPublishPlugins
|
||||
from .workfile_builder import WorkfileBuilderPlugin
|
||||
|
||||
|
||||
class AfterEffectsSettings(BaseSettingsModel):
|
||||
"""AfterEffects Project Settings."""
|
||||
|
||||
imageio: AfterEffectsImageIOModel = Field(
|
||||
default_factory=AfterEffectsImageIOModel,
|
||||
title="OCIO config"
|
||||
)
|
||||
create: AfterEffectsCreatorPlugins = Field(
|
||||
default_factory=AfterEffectsCreatorPlugins,
|
||||
title="Creator plugins"
|
||||
)
|
||||
|
||||
publish: AfterEffectsPublishPlugins = Field(
|
||||
default_factory=AfterEffectsPublishPlugins,
|
||||
title="Publish plugins"
|
||||
)
|
||||
|
||||
workfile_builder: WorkfileBuilderPlugin = Field(
|
||||
default_factory=WorkfileBuilderPlugin,
|
||||
title="Workfile Builder"
|
||||
)
|
||||
|
||||
|
||||
DEFAULT_AFTEREFFECTS_SETTING = {
|
||||
"create": {
|
||||
"RenderCreator": {
|
||||
"mark_for_review": True,
|
||||
"defaults": [
|
||||
"Main"
|
||||
]
|
||||
}
|
||||
},
|
||||
"publish": {
|
||||
"CollectReview": {
|
||||
"enabled": True
|
||||
},
|
||||
"ValidateSceneSettings": {
|
||||
"enabled": True,
|
||||
"optional": True,
|
||||
"active": True,
|
||||
"skip_resolution_check": [
|
||||
".*"
|
||||
],
|
||||
"skip_timelines_check": [
|
||||
".*"
|
||||
]
|
||||
}
|
||||
},
|
||||
"workfile_builder": {
|
||||
"create_first_version": False,
|
||||
"custom_templates": []
|
||||
}
|
||||
}
|
||||
36
server_addon/aftereffects/server/settings/publish_plugins.py
Normal file
36
server_addon/aftereffects/server/settings/publish_plugins.py
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
from pydantic import Field
|
||||
|
||||
from ayon_server.settings import BaseSettingsModel
|
||||
|
||||
|
||||
class CollectReviewPluginModel(BaseSettingsModel):
|
||||
enabled: bool = Field(True, title="Enabled")
|
||||
|
||||
|
||||
class ValidateSceneSettingsPlugin(BaseSettingsModel):
|
||||
"""Validate naming of products and layers""" #
|
||||
_isGroup = True
|
||||
enabled: bool = True
|
||||
optional: bool = Field(False, title="Optional")
|
||||
active: bool = Field(True, title="Active")
|
||||
|
||||
skip_resolution_check: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Skip Resolution Check for Tasks"
|
||||
)
|
||||
|
||||
skip_timelines_check: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Skip Timeline Check for Tasks"
|
||||
)
|
||||
|
||||
|
||||
class AfterEffectsPublishPlugins(BaseSettingsModel):
|
||||
CollectReview: CollectReviewPluginModel = Field(
|
||||
default_facotory=CollectReviewPluginModel,
|
||||
title="Collect Review"
|
||||
)
|
||||
ValidateSceneSettings: ValidateSceneSettingsPlugin = Field(
|
||||
title="Validate Scene Settings",
|
||||
default_factory=ValidateSceneSettingsPlugin,
|
||||
)
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
from pydantic import Field
|
||||
|
||||
from ayon_server.settings import BaseSettingsModel, MultiplatformPathModel
|
||||
|
||||
|
||||
class CustomBuilderTemplate(BaseSettingsModel):
|
||||
task_types: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Task types",
|
||||
)
|
||||
template_path: MultiplatformPathModel = Field(
|
||||
default_factory=MultiplatformPathModel
|
||||
)
|
||||
|
||||
|
||||
class WorkfileBuilderPlugin(BaseSettingsModel):
|
||||
_title = "Workfile Builder"
|
||||
create_first_version: bool = Field(
|
||||
False,
|
||||
title="Create first workfile"
|
||||
)
|
||||
|
||||
custom_templates: list[CustomBuilderTemplate] = Field(
|
||||
default_factory=CustomBuilderTemplate
|
||||
)
|
||||
3
server_addon/aftereffects/server/version.py
Normal file
3
server_addon/aftereffects/server/version.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Package declaring addon version."""
|
||||
__version__ = "0.1.0"
|
||||
153
server_addon/applications/server/__init__.py
Normal file
153
server_addon/applications/server/__init__.py
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
import os
|
||||
import json
|
||||
import copy
|
||||
|
||||
from ayon_server.addons import BaseServerAddon
|
||||
from ayon_server.lib.postgres import Postgres
|
||||
|
||||
from .version import __version__
|
||||
from .settings import ApplicationsAddonSettings, DEFAULT_VALUES
|
||||
|
||||
|
||||
def get_enum_items_from_groups(groups):
|
||||
label_by_name = {}
|
||||
for group in groups:
|
||||
group_name = group["name"]
|
||||
group_label = group["label"] or group_name
|
||||
for variant in group["variants"]:
|
||||
variant_name = variant["name"]
|
||||
if not variant_name:
|
||||
continue
|
||||
variant_label = variant["label"] or variant_name
|
||||
full_name = f"{group_name}/{variant_name}"
|
||||
full_label = f"{group_label} {variant_label}"
|
||||
label_by_name[full_name] = full_label
|
||||
enum_items = []
|
||||
for full_name in sorted(label_by_name):
|
||||
enum_items.append(
|
||||
{"value": full_name, "label": label_by_name[full_name]}
|
||||
)
|
||||
return enum_items
|
||||
|
||||
|
||||
class ApplicationsAddon(BaseServerAddon):
|
||||
name = "applications"
|
||||
version = __version__
|
||||
settings_model = ApplicationsAddonSettings
|
||||
|
||||
async def get_default_settings(self):
|
||||
applications_path = os.path.join(self.addon_dir, "applications.json")
|
||||
tools_path = os.path.join(self.addon_dir, "tools.json")
|
||||
default_values = copy.deepcopy(DEFAULT_VALUES)
|
||||
with open(applications_path, "r") as stream:
|
||||
default_values.update(json.load(stream))
|
||||
|
||||
with open(tools_path, "r") as stream:
|
||||
default_values.update(json.load(stream))
|
||||
|
||||
return self.get_settings_model()(**default_values)
|
||||
|
||||
async def setup(self):
|
||||
need_restart = await self.create_applications_attribute()
|
||||
if need_restart:
|
||||
self.request_server_restart()
|
||||
|
||||
async def create_applications_attribute(self) -> bool:
|
||||
"""Make sure there are required attributes which ftrack addon needs.
|
||||
|
||||
Returns:
|
||||
bool: 'True' if an attribute was created or updated.
|
||||
"""
|
||||
|
||||
settings_model = await self.get_studio_settings()
|
||||
studio_settings = settings_model.dict()
|
||||
applications = studio_settings["applications"]
|
||||
_applications = applications.pop("additional_apps")
|
||||
for name, value in applications.items():
|
||||
value["name"] = name
|
||||
_applications.append(value)
|
||||
|
||||
query = "SELECT name, position, scope, data from public.attributes"
|
||||
|
||||
apps_attrib_name = "applications"
|
||||
tools_attrib_name = "tools"
|
||||
|
||||
apps_enum = get_enum_items_from_groups(_applications)
|
||||
tools_enum = get_enum_items_from_groups(studio_settings["tool_groups"])
|
||||
apps_attribute_data = {
|
||||
"type": "list_of_strings",
|
||||
"title": "Applications",
|
||||
"enum": apps_enum
|
||||
}
|
||||
tools_attribute_data = {
|
||||
"type": "list_of_strings",
|
||||
"title": "Tools",
|
||||
"enum": tools_enum
|
||||
}
|
||||
apps_scope = ["project"]
|
||||
tools_scope = ["project", "folder", "task"]
|
||||
|
||||
apps_match_position = None
|
||||
apps_matches = False
|
||||
tools_match_position = None
|
||||
tools_matches = False
|
||||
position = 1
|
||||
async for row in Postgres.iterate(query):
|
||||
position += 1
|
||||
if row["name"] == apps_attrib_name:
|
||||
# Check if scope is matching ftrack addon requirements
|
||||
if (
|
||||
set(row["scope"]) == set(apps_scope)
|
||||
and row["data"].get("enum") == apps_enum
|
||||
):
|
||||
apps_matches = True
|
||||
apps_match_position = row["position"]
|
||||
|
||||
elif row["name"] == tools_attrib_name:
|
||||
if (
|
||||
set(row["scope"]) == set(tools_scope)
|
||||
and row["data"].get("enum") == tools_enum
|
||||
):
|
||||
tools_matches = True
|
||||
tools_match_position = row["position"]
|
||||
|
||||
if apps_matches and tools_matches:
|
||||
return False
|
||||
|
||||
postgre_query = "\n".join((
|
||||
"INSERT INTO public.attributes",
|
||||
" (name, position, scope, data)",
|
||||
"VALUES",
|
||||
" ($1, $2, $3, $4)",
|
||||
"ON CONFLICT (name)",
|
||||
"DO UPDATE SET",
|
||||
" scope = $3,",
|
||||
" data = $4",
|
||||
))
|
||||
if not apps_matches:
|
||||
# Reuse position from found attribute
|
||||
if apps_match_position is None:
|
||||
apps_match_position = position
|
||||
position += 1
|
||||
|
||||
await Postgres.execute(
|
||||
postgre_query,
|
||||
apps_attrib_name,
|
||||
apps_match_position,
|
||||
apps_scope,
|
||||
apps_attribute_data,
|
||||
)
|
||||
|
||||
if not tools_matches:
|
||||
if tools_match_position is None:
|
||||
tools_match_position = position
|
||||
position += 1
|
||||
|
||||
await Postgres.execute(
|
||||
postgre_query,
|
||||
tools_attrib_name,
|
||||
tools_match_position,
|
||||
tools_scope,
|
||||
tools_attribute_data,
|
||||
)
|
||||
return True
|
||||
1125
server_addon/applications/server/applications.json
Normal file
1125
server_addon/applications/server/applications.json
Normal file
File diff suppressed because it is too large
Load diff
201
server_addon/applications/server/settings.py
Normal file
201
server_addon/applications/server/settings.py
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
import json
|
||||
from pydantic import Field, validator
|
||||
|
||||
from ayon_server.settings import BaseSettingsModel, ensure_unique_names
|
||||
from ayon_server.exceptions import BadRequestException
|
||||
|
||||
|
||||
def validate_json_dict(value):
|
||||
if not value.strip():
|
||||
return "{}"
|
||||
try:
|
||||
converted_value = json.loads(value)
|
||||
success = isinstance(converted_value, dict)
|
||||
except json.JSONDecodeError as exc:
|
||||
print(exc)
|
||||
success = False
|
||||
|
||||
if not success:
|
||||
raise BadRequestException(
|
||||
"Environment's can't be parsed as json object"
|
||||
)
|
||||
return value
|
||||
|
||||
|
||||
class MultiplatformStrList(BaseSettingsModel):
|
||||
windows: list[str] = Field(default_factory=list, title="Windows")
|
||||
linux: list[str] = Field(default_factory=list, title="Linux")
|
||||
darwin: list[str] = Field(default_factory=list, title="MacOS")
|
||||
|
||||
|
||||
class AppVariant(BaseSettingsModel):
|
||||
name: str = Field("", title="Name")
|
||||
label: str = Field("", title="Label")
|
||||
executables: MultiplatformStrList = Field(
|
||||
default_factory=MultiplatformStrList, title="Executables"
|
||||
)
|
||||
arguments: MultiplatformStrList = Field(
|
||||
default_factory=MultiplatformStrList, title="Arguments"
|
||||
)
|
||||
environment: str = Field("{}", title="Environment", widget="textarea")
|
||||
|
||||
@validator("environment")
|
||||
def validate_json(cls, value):
|
||||
return validate_json_dict(value)
|
||||
|
||||
|
||||
class AppVariantWithPython(AppVariant):
|
||||
use_python_2: bool = Field(False, title="Use Python 2")
|
||||
|
||||
|
||||
class AppGroup(BaseSettingsModel):
|
||||
enabled: bool = Field(True)
|
||||
label: str = Field("", title="Label")
|
||||
host_name: str = Field("", title="Host name")
|
||||
icon: str = Field("", title="Icon")
|
||||
environment: str = Field("{}", title="Environment", widget="textarea")
|
||||
|
||||
variants: list[AppVariant] = Field(
|
||||
default_factory=list,
|
||||
title="Variants",
|
||||
description="Different variants of the applications",
|
||||
section="Variants",
|
||||
)
|
||||
|
||||
@validator("variants")
|
||||
def validate_unique_name(cls, value):
|
||||
ensure_unique_names(value)
|
||||
return value
|
||||
|
||||
|
||||
class AppGroupWithPython(AppGroup):
|
||||
variants: list[AppVariantWithPython] = Field(
|
||||
default_factory=list,
|
||||
title="Variants",
|
||||
description="Different variants of the applications",
|
||||
section="Variants",
|
||||
)
|
||||
|
||||
|
||||
class AdditionalAppGroup(BaseSettingsModel):
|
||||
enabled: bool = Field(True)
|
||||
name: str = Field("", title="Name")
|
||||
label: str = Field("", title="Label")
|
||||
host_name: str = Field("", title="Host name")
|
||||
icon: str = Field("", title="Icon")
|
||||
environment: str = Field("{}", title="Environment", widget="textarea")
|
||||
|
||||
variants: list[AppVariantWithPython] = Field(
|
||||
default_factory=list,
|
||||
title="Variants",
|
||||
description="Different variants of the applications",
|
||||
section="Variants",
|
||||
)
|
||||
|
||||
@validator("variants")
|
||||
def validate_unique_name(cls, value):
|
||||
ensure_unique_names(value)
|
||||
return value
|
||||
|
||||
|
||||
class ToolVariantModel(BaseSettingsModel):
|
||||
name: str = Field("", title="Name")
|
||||
label: str = Field("", title="Label")
|
||||
host_names: list[str] = Field(default_factory=list, title="Hosts")
|
||||
# TODO use applications enum if possible
|
||||
app_variants: list[str] = Field(default_factory=list, title="Applications")
|
||||
environment: str = Field("{}", title="Environments", widget="textarea")
|
||||
|
||||
@validator("environment")
|
||||
def validate_json(cls, value):
|
||||
return validate_json_dict(value)
|
||||
|
||||
|
||||
class ToolGroupModel(BaseSettingsModel):
|
||||
name: str = Field("", title="Name")
|
||||
label: str = Field("", title="Label")
|
||||
environment: str = Field("{}", title="Environments", widget="textarea")
|
||||
variants: list[ToolVariantModel] = Field(
|
||||
default_factory=ToolVariantModel
|
||||
)
|
||||
|
||||
@validator("environment")
|
||||
def validate_json(cls, value):
|
||||
return validate_json_dict(value)
|
||||
|
||||
@validator("variants")
|
||||
def validate_unique_name(cls, value):
|
||||
ensure_unique_names(value)
|
||||
return value
|
||||
|
||||
|
||||
class ApplicationsSettings(BaseSettingsModel):
|
||||
"""Applications settings"""
|
||||
|
||||
maya: AppGroupWithPython = Field(
|
||||
default_factory=AppGroupWithPython, title="Autodesk Maya")
|
||||
adsk_3dsmax: AppGroupWithPython = Field(
|
||||
default_factory=AppGroupWithPython, title="Autodesk 3ds Max")
|
||||
flame: AppGroupWithPython = Field(
|
||||
default_factory=AppGroupWithPython, title="Autodesk Flame")
|
||||
nuke: AppGroupWithPython = Field(
|
||||
default_factory=AppGroupWithPython, title="Nuke")
|
||||
nukeassist: AppGroupWithPython = Field(
|
||||
default_factory=AppGroupWithPython, title="Nuke Assist")
|
||||
nukex: AppGroupWithPython = Field(
|
||||
default_factory=AppGroupWithPython, title="Nuke X")
|
||||
nukestudio: AppGroupWithPython = Field(
|
||||
default_factory=AppGroupWithPython, title="Nuke Studio")
|
||||
hiero: AppGroupWithPython = Field(
|
||||
default_factory=AppGroupWithPython, title="Hiero")
|
||||
fusion: AppGroup = Field(
|
||||
default_factory=AppGroupWithPython, title="Fusion")
|
||||
resolve: AppGroupWithPython = Field(
|
||||
default_factory=AppGroupWithPython, title="Resolve")
|
||||
houdini: AppGroupWithPython = Field(
|
||||
default_factory=AppGroupWithPython, title="Houdini")
|
||||
blender: AppGroup = Field(
|
||||
default_factory=AppGroupWithPython, title="Blender")
|
||||
harmony: AppGroup = Field(
|
||||
default_factory=AppGroupWithPython, title="Harmony")
|
||||
tvpaint: AppGroup = Field(
|
||||
default_factory=AppGroupWithPython, title="TVPaint")
|
||||
photoshop: AppGroup = Field(
|
||||
default_factory=AppGroupWithPython, title="Adobe Photoshop")
|
||||
aftereffects: AppGroup = Field(
|
||||
default_factory=AppGroupWithPython, title="Adobe After Effects")
|
||||
celaction: AppGroup = Field(
|
||||
default_factory=AppGroupWithPython, title="Celaction 2D")
|
||||
unreal: AppGroup = Field(
|
||||
default_factory=AppGroupWithPython, title="Unreal Editor")
|
||||
additional_apps: list[AdditionalAppGroup] = Field(
|
||||
default_factory=list, title="Additional Applications")
|
||||
|
||||
@validator("additional_apps")
|
||||
def validate_unique_name(cls, value):
|
||||
ensure_unique_names(value)
|
||||
return value
|
||||
|
||||
|
||||
class ApplicationsAddonSettings(BaseSettingsModel):
|
||||
applications: ApplicationsSettings = Field(
|
||||
default_factory=ApplicationsSettings,
|
||||
title="Applications",
|
||||
scope=["studio"]
|
||||
)
|
||||
tool_groups: list[ToolGroupModel] = Field(
|
||||
default_factory=list,
|
||||
scope=["studio"]
|
||||
)
|
||||
only_available: bool = Field(
|
||||
True, title="Show only available applications")
|
||||
|
||||
@validator("tool_groups")
|
||||
def validate_unique_name(cls, value):
|
||||
ensure_unique_names(value)
|
||||
return value
|
||||
|
||||
|
||||
DEFAULT_VALUES = {
|
||||
"only_available": False
|
||||
}
|
||||
55
server_addon/applications/server/tools.json
Normal file
55
server_addon/applications/server/tools.json
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
{
|
||||
"tool_groups": [
|
||||
{
|
||||
"environment": "{\n \"MTOA\": \"{STUDIO_SOFTWARE}/arnold/mtoa_{MAYA_VERSION}_{MTOA_VERSION}\",\n \"MAYA_RENDER_DESC_PATH\": \"{MTOA}\",\n \"MAYA_MODULE_PATH\": \"{MTOA}\",\n \"ARNOLD_PLUGIN_PATH\": \"{MTOA}/shaders\",\n \"MTOA_EXTENSIONS_PATH\": {\n \"darwin\": \"{MTOA}/extensions\",\n \"linux\": \"{MTOA}/extensions\",\n \"windows\": \"{MTOA}/extensions\"\n },\n \"MTOA_EXTENSIONS\": {\n \"darwin\": \"{MTOA}/extensions\",\n \"linux\": \"{MTOA}/extensions\",\n \"windows\": \"{MTOA}/extensions\"\n },\n \"DYLD_LIBRARY_PATH\": {\n \"darwin\": \"{MTOA}/bin\"\n },\n \"PATH\": {\n \"windows\": \"{PATH};{MTOA}/bin\"\n }\n}",
|
||||
"name": "mtoa",
|
||||
"label": "Autodesk Arnold",
|
||||
"variants": [
|
||||
{
|
||||
"host_names": [],
|
||||
"app_variants": [],
|
||||
"environment": "{\n \"MTOA_VERSION\": \"3.2\"\n}",
|
||||
"name": "3-2",
|
||||
"label": "3.2"
|
||||
},
|
||||
{
|
||||
"host_names": [],
|
||||
"app_variants": [],
|
||||
"environment": "{\n \"MTOA_VERSION\": \"3.1\"\n}",
|
||||
"name": "3-1",
|
||||
"label": "3.1"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"environment": "{}",
|
||||
"name": "vray",
|
||||
"label": "Chaos Group Vray",
|
||||
"variants": []
|
||||
},
|
||||
{
|
||||
"environment": "{}",
|
||||
"name": "yeti",
|
||||
"label": "Peregrine Labs Yeti",
|
||||
"variants": []
|
||||
},
|
||||
{
|
||||
"environment": "{}",
|
||||
"name": "renderman",
|
||||
"label": "Pixar Renderman",
|
||||
"variants": [
|
||||
{
|
||||
"host_names": [
|
||||
"maya"
|
||||
],
|
||||
"app_variants": [
|
||||
"maya/2022"
|
||||
],
|
||||
"environment": "{\n \"RFMTREE\": {\n \"windows\": \"C:\\\\Program Files\\\\Pixar\\\\RenderManForMaya-24.3\",\n \"darwin\": \"/Applications/Pixar/RenderManForMaya-24.3\",\n \"linux\": \"/opt/pixar/RenderManForMaya-24.3\"\n },\n \"RMANTREE\": {\n \"windows\": \"C:\\\\Program Files\\\\Pixar\\\\RenderManProServer-24.3\",\n \"darwin\": \"/Applications/Pixar/RenderManProServer-24.3\",\n \"linux\": \"/opt/pixar/RenderManProServer-24.3\"\n }\n}",
|
||||
"name": "24-3-maya",
|
||||
"label": "24.3 RFM"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
1
server_addon/applications/server/version.py
Normal file
1
server_addon/applications/server/version.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
__version__ = "0.1.0"
|
||||
19
server_addon/blender/server/__init__.py
Normal file
19
server_addon/blender/server/__init__.py
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
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()
|
||||
return settings_model_cls(**DEFAULT_VALUES)
|
||||
10
server_addon/blender/server/settings/__init__.py
Normal file
10
server_addon/blender/server/settings/__init__.py
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
from .main import (
|
||||
BlenderSettings,
|
||||
DEFAULT_VALUES,
|
||||
)
|
||||
|
||||
|
||||
__all__ = (
|
||||
"BlenderSettings",
|
||||
"DEFAULT_VALUES",
|
||||
)
|
||||
48
server_addon/blender/server/settings/imageio.py
Normal file
48
server_addon/blender/server/settings/imageio.py
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
from pydantic import Field, validator
|
||||
from ayon_server.settings import BaseSettingsModel
|
||||
from ayon_server.settings.validators import ensure_unique_names
|
||||
|
||||
|
||||
class ImageIOConfigModel(BaseSettingsModel):
|
||||
override_global_config: bool = Field(
|
||||
False,
|
||||
title="Override global OCIO config"
|
||||
)
|
||||
filepath: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Config path"
|
||||
)
|
||||
|
||||
|
||||
class ImageIOFileRuleModel(BaseSettingsModel):
|
||||
name: str = Field("", title="Rule name")
|
||||
pattern: str = Field("", title="Regex pattern")
|
||||
colorspace: str = Field("", title="Colorspace name")
|
||||
ext: str = Field("", title="File extension")
|
||||
|
||||
|
||||
class ImageIOFileRulesModel(BaseSettingsModel):
|
||||
activate_host_rules: bool = Field(False)
|
||||
rules: list[ImageIOFileRuleModel] = Field(
|
||||
default_factory=list,
|
||||
title="Rules"
|
||||
)
|
||||
|
||||
@validator("rules")
|
||||
def validate_unique_outputs(cls, value):
|
||||
ensure_unique_names(value)
|
||||
return value
|
||||
|
||||
|
||||
class BlenderImageIOModel(BaseSettingsModel):
|
||||
activate_host_color_management: bool = Field(
|
||||
True, title="Enable Color Management"
|
||||
)
|
||||
ocio_config: ImageIOConfigModel = Field(
|
||||
default_factory=ImageIOConfigModel,
|
||||
title="OCIO config"
|
||||
)
|
||||
file_rules: ImageIOFileRulesModel = Field(
|
||||
default_factory=ImageIOFileRulesModel,
|
||||
title="File Rules"
|
||||
)
|
||||
53
server_addon/blender/server/settings/main.py
Normal file
53
server_addon/blender/server/settings/main.py
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
from pydantic import Field
|
||||
from ayon_server.settings import (
|
||||
BaseSettingsModel,
|
||||
TemplateWorkfileBaseOptions,
|
||||
)
|
||||
|
||||
from .imageio import BlenderImageIOModel
|
||||
from .publish_plugins import (
|
||||
PublishPuginsModel,
|
||||
DEFAULT_BLENDER_PUBLISH_SETTINGS
|
||||
)
|
||||
|
||||
|
||||
class UnitScaleSettingsModel(BaseSettingsModel):
|
||||
enabled: bool = Field(True, title="Enabled")
|
||||
apply_on_opening: bool = Field(
|
||||
False, title="Apply on Opening Existing Files")
|
||||
base_file_unit_scale: float = Field(
|
||||
1.0, title="Base File Unit Scale"
|
||||
)
|
||||
|
||||
|
||||
class BlenderSettings(BaseSettingsModel):
|
||||
unit_scale_settings: UnitScaleSettingsModel = Field(
|
||||
default_factory=UnitScaleSettingsModel,
|
||||
title="Set Unit Scale"
|
||||
)
|
||||
imageio: BlenderImageIOModel = Field(
|
||||
default_factory=BlenderImageIOModel,
|
||||
title="Color Management (ImageIO)"
|
||||
)
|
||||
workfile_builder: TemplateWorkfileBaseOptions = Field(
|
||||
default_factory=TemplateWorkfileBaseOptions,
|
||||
title="Workfile Builder"
|
||||
)
|
||||
publish: PublishPuginsModel = Field(
|
||||
default_factory=PublishPuginsModel,
|
||||
title="Publish Plugins"
|
||||
)
|
||||
|
||||
|
||||
DEFAULT_VALUES = {
|
||||
"unit_scale_settings": {
|
||||
"enabled": True,
|
||||
"apply_on_opening": False,
|
||||
"base_file_unit_scale": 0.01
|
||||
},
|
||||
"publish": DEFAULT_BLENDER_PUBLISH_SETTINGS,
|
||||
"workfile_builder": {
|
||||
"create_first_version": False,
|
||||
"custom_templates": []
|
||||
}
|
||||
}
|
||||
273
server_addon/blender/server/settings/publish_plugins.py
Normal file
273
server_addon/blender/server/settings/publish_plugins.py
Normal file
|
|
@ -0,0 +1,273 @@
|
|||
import json
|
||||
from pydantic import Field, validator
|
||||
from ayon_server.exceptions import BadRequestException
|
||||
from ayon_server.settings import BaseSettingsModel
|
||||
|
||||
|
||||
def validate_json_dict(value):
|
||||
if not value.strip():
|
||||
return "{}"
|
||||
try:
|
||||
converted_value = json.loads(value)
|
||||
success = isinstance(converted_value, dict)
|
||||
except json.JSONDecodeError:
|
||||
success = False
|
||||
|
||||
if not success:
|
||||
raise BadRequestException(
|
||||
"Environment's can't be parsed as json object"
|
||||
)
|
||||
return value
|
||||
|
||||
|
||||
class ValidatePluginModel(BaseSettingsModel):
|
||||
enabled: bool = Field(True)
|
||||
optional: bool = Field(title="Optional")
|
||||
active: bool = Field(title="Active")
|
||||
|
||||
|
||||
class ExtractBlendModel(BaseSettingsModel):
|
||||
enabled: bool = Field(True)
|
||||
optional: bool = Field(title="Optional")
|
||||
active: bool = Field(title="Active")
|
||||
families: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Families"
|
||||
)
|
||||
|
||||
|
||||
class ExtractPlayblastModel(BaseSettingsModel):
|
||||
enabled: bool = Field(True)
|
||||
optional: bool = Field(title="Optional")
|
||||
active: bool = Field(title="Active")
|
||||
presets: str = Field("", title="Presets", widget="textarea")
|
||||
|
||||
@validator("presets")
|
||||
def validate_json(cls, value):
|
||||
return validate_json_dict(value)
|
||||
|
||||
|
||||
class PublishPuginsModel(BaseSettingsModel):
|
||||
ValidateCameraZeroKeyframe: ValidatePluginModel = Field(
|
||||
default_factory=ValidatePluginModel,
|
||||
title="Validate Camera Zero Keyframe",
|
||||
section="Validators"
|
||||
)
|
||||
ValidateMeshHasUvs: ValidatePluginModel = Field(
|
||||
default_factory=ValidatePluginModel,
|
||||
title="Validate Mesh Has Uvs"
|
||||
)
|
||||
ValidateMeshNoNegativeScale: ValidatePluginModel = Field(
|
||||
default_factory=ValidatePluginModel,
|
||||
title="Validate Mesh No Negative Scale"
|
||||
)
|
||||
ValidateTransformZero: ValidatePluginModel = Field(
|
||||
default_factory=ValidatePluginModel,
|
||||
title="Validate Transform Zero"
|
||||
)
|
||||
ValidateNoColonsInName: ValidatePluginModel = Field(
|
||||
default_factory=ValidatePluginModel,
|
||||
title="Validate No Colons In Name"
|
||||
)
|
||||
ExtractBlend: ExtractBlendModel = Field(
|
||||
default_factory=ExtractBlendModel,
|
||||
title="Extract Blend",
|
||||
section="Extractors"
|
||||
)
|
||||
ExtractFBX: ValidatePluginModel = Field(
|
||||
default_factory=ValidatePluginModel,
|
||||
title="Extract FBX"
|
||||
)
|
||||
ExtractABC: ValidatePluginModel = Field(
|
||||
default_factory=ValidatePluginModel,
|
||||
title="Extract ABC"
|
||||
)
|
||||
ExtractBlendAnimation: ValidatePluginModel = Field(
|
||||
default_factory=ValidatePluginModel,
|
||||
title="Extract Blend Animation"
|
||||
)
|
||||
ExtractAnimationFBX: ValidatePluginModel = Field(
|
||||
default_factory=ValidatePluginModel,
|
||||
title="Extract Animation FBX"
|
||||
)
|
||||
ExtractCamera: ValidatePluginModel = Field(
|
||||
default_factory=ValidatePluginModel,
|
||||
title="Extract Camera"
|
||||
)
|
||||
ExtractLayout: ValidatePluginModel = Field(
|
||||
default_factory=ValidatePluginModel,
|
||||
title="Extract Layout"
|
||||
)
|
||||
ExtractThumbnail: ExtractPlayblastModel = Field(
|
||||
default_factory=ExtractPlayblastModel,
|
||||
title="Extract Thumbnail"
|
||||
)
|
||||
ExtractPlayblast: ExtractPlayblastModel = Field(
|
||||
default_factory=ExtractPlayblastModel,
|
||||
title="Extract Playblast"
|
||||
)
|
||||
|
||||
|
||||
DEFAULT_BLENDER_PUBLISH_SETTINGS = {
|
||||
"ValidateCameraZeroKeyframe": {
|
||||
"enabled": True,
|
||||
"optional": True,
|
||||
"active": True
|
||||
},
|
||||
"ValidateMeshHasUvs": {
|
||||
"enabled": True,
|
||||
"optional": True,
|
||||
"active": True
|
||||
},
|
||||
"ValidateMeshNoNegativeScale": {
|
||||
"enabled": True,
|
||||
"optional": False,
|
||||
"active": True
|
||||
},
|
||||
"ValidateTransformZero": {
|
||||
"enabled": True,
|
||||
"optional": False,
|
||||
"active": True
|
||||
},
|
||||
"ValidateNoColonsInName": {
|
||||
"enabled": True,
|
||||
"optional": False,
|
||||
"active": True
|
||||
},
|
||||
"ExtractBlend": {
|
||||
"enabled": True,
|
||||
"optional": True,
|
||||
"active": True,
|
||||
"families": [
|
||||
"model",
|
||||
"camera",
|
||||
"rig",
|
||||
"action",
|
||||
"layout"
|
||||
]
|
||||
},
|
||||
"ExtractFBX": {
|
||||
"enabled": True,
|
||||
"optional": True,
|
||||
"active": False
|
||||
},
|
||||
"ExtractABC": {
|
||||
"enabled": True,
|
||||
"optional": True,
|
||||
"active": False
|
||||
},
|
||||
"ExtractBlendAnimation": {
|
||||
"enabled": True,
|
||||
"optional": True,
|
||||
"active": True
|
||||
},
|
||||
"ExtractAnimationFBX": {
|
||||
"enabled": True,
|
||||
"optional": True,
|
||||
"active": False
|
||||
},
|
||||
"ExtractCamera": {
|
||||
"enabled": True,
|
||||
"optional": True,
|
||||
"active": True
|
||||
},
|
||||
"ExtractLayout": {
|
||||
"enabled": True,
|
||||
"optional": True,
|
||||
"active": False
|
||||
},
|
||||
"ExtractThumbnail": {
|
||||
"enabled": True,
|
||||
"optional": True,
|
||||
"active": True,
|
||||
"presets": json.dumps(
|
||||
{
|
||||
"model": {
|
||||
"image_settings": {
|
||||
"file_format": "JPEG",
|
||||
"color_mode": "RGB",
|
||||
"quality": 100
|
||||
},
|
||||
"display_options": {
|
||||
"shading": {
|
||||
"light": "STUDIO",
|
||||
"studio_light": "Default",
|
||||
"type": "SOLID",
|
||||
"color_type": "OBJECT",
|
||||
"show_xray": False,
|
||||
"show_shadows": False,
|
||||
"show_cavity": True
|
||||
},
|
||||
"overlay": {
|
||||
"show_overlays": False
|
||||
}
|
||||
}
|
||||
},
|
||||
"rig": {
|
||||
"image_settings": {
|
||||
"file_format": "JPEG",
|
||||
"color_mode": "RGB",
|
||||
"quality": 100
|
||||
},
|
||||
"display_options": {
|
||||
"shading": {
|
||||
"light": "STUDIO",
|
||||
"studio_light": "Default",
|
||||
"type": "SOLID",
|
||||
"color_type": "OBJECT",
|
||||
"show_xray": True,
|
||||
"show_shadows": False,
|
||||
"show_cavity": False
|
||||
},
|
||||
"overlay": {
|
||||
"show_overlays": True,
|
||||
"show_ortho_grid": False,
|
||||
"show_floor": False,
|
||||
"show_axis_x": False,
|
||||
"show_axis_y": False,
|
||||
"show_axis_z": False,
|
||||
"show_text": False,
|
||||
"show_stats": False,
|
||||
"show_cursor": False,
|
||||
"show_annotation": False,
|
||||
"show_extras": False,
|
||||
"show_relationship_lines": False,
|
||||
"show_outline_selected": False,
|
||||
"show_motion_paths": False,
|
||||
"show_object_origins": False,
|
||||
"show_bones": True
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
indent=4,
|
||||
)
|
||||
},
|
||||
"ExtractPlayblast": {
|
||||
"enabled": True,
|
||||
"optional": True,
|
||||
"active": True,
|
||||
"presets": json.dumps(
|
||||
{
|
||||
"default": {
|
||||
"image_settings": {
|
||||
"file_format": "PNG",
|
||||
"color_mode": "RGB",
|
||||
"color_depth": "8",
|
||||
"compression": 15
|
||||
},
|
||||
"display_options": {
|
||||
"shading": {
|
||||
"type": "MATERIAL",
|
||||
"render_pass": "COMBINED"
|
||||
},
|
||||
"overlay": {
|
||||
"show_overlays": False
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
indent=4
|
||||
)
|
||||
}
|
||||
}
|
||||
1
server_addon/blender/server/version.py
Normal file
1
server_addon/blender/server/version.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
__version__ = "0.1.0"
|
||||
19
server_addon/celaction/server/__init__.py
Normal file
19
server_addon/celaction/server/__init__.py
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
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()
|
||||
return settings_model_cls(**DEFAULT_VALUES)
|
||||
48
server_addon/celaction/server/imageio.py
Normal file
48
server_addon/celaction/server/imageio.py
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
from pydantic import Field, validator
|
||||
from ayon_server.settings import BaseSettingsModel
|
||||
from ayon_server.settings.validators import ensure_unique_names
|
||||
|
||||
|
||||
class ImageIOConfigModel(BaseSettingsModel):
|
||||
override_global_config: bool = Field(
|
||||
False,
|
||||
title="Override global OCIO config"
|
||||
)
|
||||
filepath: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Config path"
|
||||
)
|
||||
|
||||
|
||||
class ImageIOFileRuleModel(BaseSettingsModel):
|
||||
name: str = Field("", title="Rule name")
|
||||
pattern: str = Field("", title="Regex pattern")
|
||||
colorspace: str = Field("", title="Colorspace name")
|
||||
ext: str = Field("", title="File extension")
|
||||
|
||||
|
||||
class ImageIOFileRulesModel(BaseSettingsModel):
|
||||
activate_host_rules: bool = Field(False)
|
||||
rules: list[ImageIOFileRuleModel] = Field(
|
||||
default_factory=list,
|
||||
title="Rules"
|
||||
)
|
||||
|
||||
@validator("rules")
|
||||
def validate_unique_outputs(cls, value):
|
||||
ensure_unique_names(value)
|
||||
return value
|
||||
|
||||
|
||||
class CelActionImageIOModel(BaseSettingsModel):
|
||||
activate_host_color_management: bool = Field(
|
||||
True, title="Enable Color Management"
|
||||
)
|
||||
ocio_config: ImageIOConfigModel = Field(
|
||||
default_factory=ImageIOConfigModel,
|
||||
title="OCIO config"
|
||||
)
|
||||
file_rules: ImageIOFileRulesModel = Field(
|
||||
default_factory=ImageIOFileRulesModel,
|
||||
title="File Rules"
|
||||
)
|
||||
92
server_addon/celaction/server/settings.py
Normal file
92
server_addon/celaction/server/settings.py
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
from pydantic import Field
|
||||
from ayon_server.settings import BaseSettingsModel
|
||||
from .imageio import CelActionImageIOModel
|
||||
|
||||
|
||||
class CollectRenderPathModel(BaseSettingsModel):
|
||||
output_extension: str = Field(
|
||||
"",
|
||||
title="Output render file extension"
|
||||
)
|
||||
anatomy_template_key_render_files: str = Field(
|
||||
"",
|
||||
title="Anatomy template key: render files"
|
||||
)
|
||||
anatomy_template_key_metadata: str = Field(
|
||||
"",
|
||||
title="Anatomy template key: metadata job file"
|
||||
)
|
||||
|
||||
|
||||
def _workfile_submit_overrides():
|
||||
return [
|
||||
{
|
||||
"value": "render_chunk",
|
||||
"label": "Pass chunk size"
|
||||
},
|
||||
{
|
||||
"value": "frame_range",
|
||||
"label": "Pass frame range"
|
||||
},
|
||||
{
|
||||
"value": "resolution",
|
||||
"label": "Pass resolution"
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
class WorkfileModel(BaseSettingsModel):
|
||||
submission_overrides: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Submission workfile overrides",
|
||||
enum_resolver=_workfile_submit_overrides
|
||||
)
|
||||
|
||||
|
||||
class PublishPuginsModel(BaseSettingsModel):
|
||||
CollectRenderPath: CollectRenderPathModel = Field(
|
||||
default_factory=CollectRenderPathModel,
|
||||
title="Collect Render Path"
|
||||
)
|
||||
|
||||
|
||||
class CelActionSettings(BaseSettingsModel):
|
||||
imageio: CelActionImageIOModel = Field(
|
||||
default_factory=CelActionImageIOModel,
|
||||
title="Color Management (ImageIO)"
|
||||
)
|
||||
workfile: WorkfileModel = Field(
|
||||
title="Workfile"
|
||||
)
|
||||
publish: PublishPuginsModel = Field(
|
||||
default_factory=PublishPuginsModel,
|
||||
title="Publish plugins",
|
||||
)
|
||||
|
||||
|
||||
DEFAULT_VALUES = {
|
||||
"imageio": {
|
||||
"ocio_config": {
|
||||
"enabled": False,
|
||||
"filepath": []
|
||||
},
|
||||
"file_rules": {
|
||||
"enabled": False,
|
||||
"rules": []
|
||||
}
|
||||
},
|
||||
"workfile": {
|
||||
"submission_overrides": [
|
||||
"render_chunk",
|
||||
"frame_range",
|
||||
"resolution"
|
||||
]
|
||||
},
|
||||
"publish": {
|
||||
"CollectRenderPath": {
|
||||
"output_extension": "png",
|
||||
"anatomy_template_key_render_files": "render",
|
||||
"anatomy_template_key_metadata": "render"
|
||||
}
|
||||
}
|
||||
}
|
||||
1
server_addon/celaction/server/version.py
Normal file
1
server_addon/celaction/server/version.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
__version__ = "0.1.0"
|
||||
15
server_addon/clockify/server/__init__.py
Normal file
15
server_addon/clockify/server/__init__.py
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
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 = {}
|
||||
9
server_addon/clockify/server/settings.py
Normal file
9
server_addon/clockify/server/settings.py
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
from pydantic import Field
|
||||
from ayon_server.settings import BaseSettingsModel
|
||||
|
||||
|
||||
class ClockifySettings(BaseSettingsModel):
|
||||
workspace_name: str = Field(
|
||||
"",
|
||||
title="Workspace name"
|
||||
)
|
||||
1
server_addon/clockify/server/version.py
Normal file
1
server_addon/clockify/server/version.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
__version__ = "0.1.0"
|
||||
14
server_addon/core/server/__init__.py
Normal file
14
server_addon/core/server/__init__.py
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
from ayon_server.addons import BaseServerAddon
|
||||
|
||||
from .version import __version__
|
||||
from .settings import CoreSettings, DEFAULT_VALUES
|
||||
|
||||
|
||||
class CoreAddon(BaseServerAddon):
|
||||
name = "core"
|
||||
version = __version__
|
||||
settings_model = CoreSettings
|
||||
|
||||
async def get_default_settings(self):
|
||||
settings_model_cls = self.get_settings_model()
|
||||
return settings_model_cls(**DEFAULT_VALUES)
|
||||
7
server_addon/core/server/settings/__init__.py
Normal file
7
server_addon/core/server/settings/__init__.py
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
from .main import CoreSettings, DEFAULT_VALUES
|
||||
|
||||
|
||||
__all__ = (
|
||||
"CoreSettings",
|
||||
"DEFAULT_VALUES",
|
||||
)
|
||||
160
server_addon/core/server/settings/main.py
Normal file
160
server_addon/core/server/settings/main.py
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
import json
|
||||
from pydantic import Field, validator
|
||||
from ayon_server.settings import (
|
||||
BaseSettingsModel,
|
||||
MultiplatformPathListModel,
|
||||
ensure_unique_names,
|
||||
)
|
||||
from ayon_server.exceptions import BadRequestException
|
||||
|
||||
from .publish_plugins import PublishPuginsModel, DEFAULT_PUBLISH_VALUES
|
||||
from .tools import GlobalToolsModel, DEFAULT_TOOLS_VALUES
|
||||
|
||||
|
||||
class ImageIOFileRuleModel(BaseSettingsModel):
|
||||
name: str = Field("", title="Rule name")
|
||||
pattern: str = Field("", title="Regex pattern")
|
||||
colorspace: str = Field("", title="Colorspace name")
|
||||
ext: str = Field("", title="File extension")
|
||||
|
||||
|
||||
class CoreImageIOFileRulesModel(BaseSettingsModel):
|
||||
activate_global_file_rules: bool = Field(False)
|
||||
rules: list[ImageIOFileRuleModel] = Field(
|
||||
default_factory=list,
|
||||
title="Rules"
|
||||
)
|
||||
|
||||
@validator("rules")
|
||||
def validate_unique_outputs(cls, value):
|
||||
ensure_unique_names(value)
|
||||
return value
|
||||
|
||||
|
||||
class CoreImageIOConfigModel(BaseSettingsModel):
|
||||
filepath: list[str] = Field(default_factory=list, title="Config path")
|
||||
|
||||
|
||||
class CoreImageIOBaseModel(BaseSettingsModel):
|
||||
activate_global_color_management: bool = Field(
|
||||
False,
|
||||
title="Override global OCIO config"
|
||||
)
|
||||
ocio_config: CoreImageIOConfigModel = Field(
|
||||
default_factory=CoreImageIOConfigModel, title="OCIO config"
|
||||
)
|
||||
file_rules: CoreImageIOFileRulesModel = Field(
|
||||
default_factory=CoreImageIOFileRulesModel, title="File Rules"
|
||||
)
|
||||
|
||||
|
||||
class CoreSettings(BaseSettingsModel):
|
||||
studio_name: str = Field("", title="Studio name")
|
||||
studio_code: str = Field("", title="Studio code")
|
||||
environments: str = Field(
|
||||
"{}",
|
||||
title="Global environment variables",
|
||||
widget="textarea",
|
||||
scope=["studio"],
|
||||
)
|
||||
tools: GlobalToolsModel = Field(
|
||||
default_factory=GlobalToolsModel,
|
||||
title="Tools"
|
||||
)
|
||||
imageio: CoreImageIOBaseModel = Field(
|
||||
default_factory=CoreImageIOBaseModel,
|
||||
title="Color Management (ImageIO)"
|
||||
)
|
||||
publish: PublishPuginsModel = Field(
|
||||
default_factory=PublishPuginsModel,
|
||||
title="Publish plugins"
|
||||
)
|
||||
project_plugins: MultiplatformPathListModel = Field(
|
||||
default_factory=MultiplatformPathListModel,
|
||||
title="Additional Project Plugin Paths",
|
||||
)
|
||||
project_folder_structure: str = Field(
|
||||
"{}",
|
||||
widget="textarea",
|
||||
title="Project folder structure",
|
||||
section="---"
|
||||
)
|
||||
project_environments: str = Field(
|
||||
"{}",
|
||||
widget="textarea",
|
||||
title="Project environments",
|
||||
section="---"
|
||||
)
|
||||
|
||||
@validator(
|
||||
"environments",
|
||||
"project_folder_structure",
|
||||
"project_environments")
|
||||
def validate_json(cls, value):
|
||||
if not value.strip():
|
||||
return "{}"
|
||||
try:
|
||||
converted_value = json.loads(value)
|
||||
success = isinstance(converted_value, dict)
|
||||
except json.JSONDecodeError:
|
||||
success = False
|
||||
|
||||
if not success:
|
||||
raise BadRequestException(
|
||||
"Environment's can't be parsed as json object"
|
||||
)
|
||||
return value
|
||||
|
||||
|
||||
DEFAULT_VALUES = {
|
||||
"imageio": {
|
||||
"activate_global_color_management": False,
|
||||
"ocio_config": {
|
||||
"filepath": [
|
||||
"{BUILTIN_OCIO_ROOT}/aces_1.2/config.ocio",
|
||||
"{BUILTIN_OCIO_ROOT}/nuke-default/config.ocio"
|
||||
]
|
||||
},
|
||||
"file_rules": {
|
||||
"activate_global_file_rules": False,
|
||||
"rules": [
|
||||
{
|
||||
"name": "example",
|
||||
"pattern": ".*(beauty).*",
|
||||
"colorspace": "ACES - ACEScg",
|
||||
"ext": "exr"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"studio_name": "",
|
||||
"studio_code": "",
|
||||
"environments": "{}",
|
||||
"tools": DEFAULT_TOOLS_VALUES,
|
||||
"publish": DEFAULT_PUBLISH_VALUES,
|
||||
"project_folder_structure": json.dumps({
|
||||
"__project_root__": {
|
||||
"prod": {},
|
||||
"resources": {
|
||||
"footage": {
|
||||
"plates": {},
|
||||
"offline": {}
|
||||
},
|
||||
"audio": {},
|
||||
"art_dept": {}
|
||||
},
|
||||
"editorial": {},
|
||||
"assets": {
|
||||
"characters": {},
|
||||
"locations": {}
|
||||
},
|
||||
"shots": {}
|
||||
}
|
||||
}, indent=4),
|
||||
"project_plugins": {
|
||||
"windows": [],
|
||||
"darwin": [],
|
||||
"linux": []
|
||||
},
|
||||
"project_environments": "{}"
|
||||
}
|
||||
959
server_addon/core/server/settings/publish_plugins.py
Normal file
959
server_addon/core/server/settings/publish_plugins.py
Normal file
|
|
@ -0,0 +1,959 @@
|
|||
from pydantic import Field, validator
|
||||
|
||||
from ayon_server.settings import (
|
||||
BaseSettingsModel,
|
||||
MultiplatformPathModel,
|
||||
normalize_name,
|
||||
ensure_unique_names,
|
||||
task_types_enum,
|
||||
)
|
||||
|
||||
from ayon_server.types import ColorRGBA_uint8
|
||||
|
||||
|
||||
class ValidateBaseModel(BaseSettingsModel):
|
||||
_isGroup = True
|
||||
enabled: bool = Field(True)
|
||||
optional: bool = Field(True, title="Optional")
|
||||
active: bool = Field(True, title="Active")
|
||||
|
||||
|
||||
class CollectAnatomyInstanceDataModel(BaseSettingsModel):
|
||||
_isGroup = True
|
||||
follow_workfile_version: bool = Field(
|
||||
True, title="Collect Anatomy Instance Data"
|
||||
)
|
||||
|
||||
|
||||
class CollectAudioModel(BaseSettingsModel):
|
||||
_isGroup = True
|
||||
enabled: bool = Field(True)
|
||||
audio_product_name: str = Field(
|
||||
"", title="Name of audio variant"
|
||||
)
|
||||
|
||||
|
||||
class CollectSceneVersionModel(BaseSettingsModel):
|
||||
_isGroup = True
|
||||
hosts: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Host names"
|
||||
)
|
||||
skip_hosts_headless_publish: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Skip for host if headless publish"
|
||||
)
|
||||
|
||||
|
||||
class CollectCommentPIModel(BaseSettingsModel):
|
||||
enabled: bool = Field(True)
|
||||
families: list[str] = Field(default_factory=list, title="Families")
|
||||
|
||||
|
||||
class CollectFramesFixDefModel(BaseSettingsModel):
|
||||
enabled: bool = Field(True)
|
||||
rewrite_version_enable: bool = Field(
|
||||
True,
|
||||
title="Show 'Rewrite latest version' toggle"
|
||||
)
|
||||
|
||||
|
||||
class ValidateIntentProfile(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
hosts: list[str] = Field(default_factory=list, title="Host names")
|
||||
task_types: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Task types",
|
||||
enum_resolver=task_types_enum
|
||||
)
|
||||
tasks: list[str] = Field(default_factory=list, title="Task names")
|
||||
# TODO This was 'validate' in v3
|
||||
validate_intent: bool = Field(True, title="Validate")
|
||||
|
||||
|
||||
class ValidateIntentModel(BaseSettingsModel):
|
||||
"""Validate if Publishing intent was selected.
|
||||
|
||||
It is possible to disable validation for specific publishing context
|
||||
with profiles.
|
||||
"""
|
||||
|
||||
_isGroup = True
|
||||
enabled: bool = Field(False)
|
||||
profiles: list[ValidateIntentProfile] = Field(default_factory=list)
|
||||
|
||||
|
||||
class ExtractThumbnailFFmpegModel(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
input: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="FFmpeg input arguments"
|
||||
)
|
||||
output: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="FFmpeg input arguments"
|
||||
)
|
||||
|
||||
|
||||
class ExtractThumbnailModel(BaseSettingsModel):
|
||||
_isGroup = True
|
||||
enabled: bool = Field(True)
|
||||
ffmpeg_args: ExtractThumbnailFFmpegModel = Field(
|
||||
default_factory=ExtractThumbnailFFmpegModel
|
||||
)
|
||||
|
||||
|
||||
def _extract_oiio_transcoding_type():
|
||||
return [
|
||||
{"value": "colorspace", "label": "Use Colorspace"},
|
||||
{"value": "display", "label": "Use Display&View"}
|
||||
]
|
||||
|
||||
|
||||
class OIIOToolArgumentsModel(BaseSettingsModel):
|
||||
additional_command_args: list[str] = Field(
|
||||
default_factory=list, title="Arguments")
|
||||
|
||||
|
||||
class ExtractOIIOTranscodeOutputModel(BaseSettingsModel):
|
||||
extension: str = Field("", title="Extension")
|
||||
transcoding_type: str = Field(
|
||||
"colorspace",
|
||||
title="Transcoding type",
|
||||
enum_resolver=_extract_oiio_transcoding_type
|
||||
)
|
||||
colorspace: str = Field("", title="Colorspace")
|
||||
display: str = Field("", title="Display")
|
||||
view: str = Field("", title="View")
|
||||
oiiotool_args: OIIOToolArgumentsModel = Field(
|
||||
default_factory=OIIOToolArgumentsModel,
|
||||
title="OIIOtool arguments")
|
||||
|
||||
tags: list[str] = Field(default_factory=list, title="Tags")
|
||||
custom_tags: list[str] = Field(default_factory=list, title="Custom Tags")
|
||||
|
||||
|
||||
class ExtractOIIOTranscodeProfileModel(BaseSettingsModel):
|
||||
product_types: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Product types"
|
||||
)
|
||||
hosts: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Host names"
|
||||
)
|
||||
task_types: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Task types",
|
||||
enum_resolver=task_types_enum
|
||||
)
|
||||
task_names: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Task names"
|
||||
)
|
||||
product_names: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Product names"
|
||||
)
|
||||
delete_original: bool = Field(
|
||||
True,
|
||||
title="Delete Original Representation"
|
||||
)
|
||||
outputs: list[ExtractOIIOTranscodeOutputModel] = Field(
|
||||
default_factory=list,
|
||||
title="Output Definitions",
|
||||
)
|
||||
|
||||
|
||||
class ExtractOIIOTranscodeModel(BaseSettingsModel):
|
||||
enabled: bool = Field(True)
|
||||
profiles: list[ExtractOIIOTranscodeProfileModel] = Field(
|
||||
default_factory=list, title="Profiles"
|
||||
)
|
||||
|
||||
|
||||
# --- [START] Extract Review ---
|
||||
class ExtractReviewFFmpegModel(BaseSettingsModel):
|
||||
video_filters: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Video filters"
|
||||
)
|
||||
audio_filters: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Audio filters"
|
||||
)
|
||||
input: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Input arguments"
|
||||
)
|
||||
output: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Output arguments"
|
||||
)
|
||||
|
||||
|
||||
def extract_review_filter_enum():
|
||||
return [
|
||||
{
|
||||
"value": "everytime",
|
||||
"label": "Always"
|
||||
},
|
||||
{
|
||||
"value": "single_frame",
|
||||
"label": "Only if input has 1 image frame"
|
||||
},
|
||||
{
|
||||
"value": "multi_frame",
|
||||
"label": "Only if input is video or sequence of frames"
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
class ExtractReviewFilterModel(BaseSettingsModel):
|
||||
families: list[str] = Field(default_factory=list, title="Families")
|
||||
product_names: list[str] = Field(
|
||||
default_factory=list, title="Product names")
|
||||
custom_tags: list[str] = Field(default_factory=list, title="Custom Tags")
|
||||
single_frame_filter: str = Field(
|
||||
"everytime",
|
||||
description=(
|
||||
"Use output <b>always</b> / only if input <b>is 1 frame</b>"
|
||||
" image / only if has <b>2+ frames</b> or <b>is video</b>"
|
||||
),
|
||||
enum_resolver=extract_review_filter_enum
|
||||
)
|
||||
|
||||
|
||||
class ExtractReviewLetterBox(BaseSettingsModel):
|
||||
enabled: bool = Field(True)
|
||||
ratio: float = Field(
|
||||
0.0,
|
||||
title="Ratio",
|
||||
ge=0.0,
|
||||
le=10000.0
|
||||
)
|
||||
fill_color: ColorRGBA_uint8 = Field(
|
||||
(0, 0, 0, 0.0),
|
||||
title="Fill Color"
|
||||
)
|
||||
line_thickness: int = Field(
|
||||
0,
|
||||
title="Line Thickness",
|
||||
ge=0,
|
||||
le=1000
|
||||
)
|
||||
line_color: ColorRGBA_uint8 = Field(
|
||||
(0, 0, 0, 0.0),
|
||||
title="Line Color"
|
||||
)
|
||||
|
||||
|
||||
class ExtractReviewOutputDefModel(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
name: str = Field("", title="Name")
|
||||
ext: str = Field("", title="Output extension")
|
||||
# TODO use some different source of tags
|
||||
tags: list[str] = Field(default_factory=list, title="Tags")
|
||||
burnins: list[str] = Field(
|
||||
default_factory=list, title="Link to a burnin by name"
|
||||
)
|
||||
ffmpeg_args: ExtractReviewFFmpegModel = Field(
|
||||
default_factory=ExtractReviewFFmpegModel,
|
||||
title="FFmpeg arguments"
|
||||
)
|
||||
filter: ExtractReviewFilterModel = Field(
|
||||
default_factory=ExtractReviewFilterModel,
|
||||
title="Additional output filtering"
|
||||
)
|
||||
overscan_crop: str = Field(
|
||||
"",
|
||||
title="Overscan crop",
|
||||
description=(
|
||||
"Crop input overscan. See the documentation for more information."
|
||||
)
|
||||
)
|
||||
overscan_color: ColorRGBA_uint8 = Field(
|
||||
(0, 0, 0, 0.0),
|
||||
title="Overscan color",
|
||||
description=(
|
||||
"Overscan color is used when input aspect ratio is not"
|
||||
" same as output aspect ratio."
|
||||
)
|
||||
)
|
||||
width: int = Field(
|
||||
0,
|
||||
ge=0,
|
||||
le=100000,
|
||||
title="Output width",
|
||||
description=(
|
||||
"Width and Height must be both set to higher"
|
||||
" value than 0 else source resolution is used."
|
||||
)
|
||||
)
|
||||
height: int = Field(
|
||||
0,
|
||||
title="Output height",
|
||||
ge=0,
|
||||
le=100000,
|
||||
)
|
||||
scale_pixel_aspect: bool = Field(
|
||||
True,
|
||||
title="Scale pixel aspect",
|
||||
description=(
|
||||
"Rescale input when it's pixel aspect ratio is not 1."
|
||||
" Usefull for anamorph reviews."
|
||||
)
|
||||
)
|
||||
bg_color: ColorRGBA_uint8 = Field(
|
||||
(0, 0, 0, 0.0),
|
||||
description=(
|
||||
"Background color is used only when input have transparency"
|
||||
" and Alpha is higher than 0."
|
||||
),
|
||||
title="Background color",
|
||||
)
|
||||
letter_box: ExtractReviewLetterBox = Field(
|
||||
default_factory=ExtractReviewLetterBox,
|
||||
title="Letter Box"
|
||||
)
|
||||
|
||||
@validator("name")
|
||||
def validate_name(cls, value):
|
||||
"""Ensure name does not contain weird characters"""
|
||||
return normalize_name(value)
|
||||
|
||||
|
||||
class ExtractReviewProfileModel(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
product_types: list[str] = Field(
|
||||
default_factory=list, title="Product types"
|
||||
)
|
||||
# TODO use hosts enum
|
||||
hosts: list[str] = Field(
|
||||
default_factory=list, title="Host names"
|
||||
)
|
||||
outputs: list[ExtractReviewOutputDefModel] = Field(
|
||||
default_factory=list, title="Output Definitions"
|
||||
)
|
||||
|
||||
@validator("outputs")
|
||||
def validate_unique_outputs(cls, value):
|
||||
ensure_unique_names(value)
|
||||
return value
|
||||
|
||||
|
||||
class ExtractReviewModel(BaseSettingsModel):
|
||||
_isGroup = True
|
||||
enabled: bool = Field(True)
|
||||
profiles: list[ExtractReviewProfileModel] = Field(
|
||||
default_factory=list,
|
||||
title="Profiles"
|
||||
)
|
||||
# --- [END] Extract Review ---
|
||||
|
||||
|
||||
# --- [Start] Extract Burnin ---
|
||||
class ExtractBurninOptionsModel(BaseSettingsModel):
|
||||
font_size: int = Field(0, ge=0, title="Font size")
|
||||
font_color: ColorRGBA_uint8 = Field(
|
||||
(255, 255, 255, 1.0),
|
||||
title="Font color"
|
||||
)
|
||||
bg_color: ColorRGBA_uint8 = Field(
|
||||
(0, 0, 0, 1.0),
|
||||
title="Background color"
|
||||
)
|
||||
x_offset: int = Field(0, title="X Offset")
|
||||
y_offset: int = Field(0, title="Y Offset")
|
||||
bg_padding: int = Field(0, title="Padding around text")
|
||||
font_filepath: MultiplatformPathModel = Field(
|
||||
default_factory=MultiplatformPathModel,
|
||||
title="Font file path"
|
||||
)
|
||||
|
||||
|
||||
class ExtractBurninDefFilter(BaseSettingsModel):
|
||||
families: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Families"
|
||||
)
|
||||
tags: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Tags"
|
||||
)
|
||||
|
||||
|
||||
class ExtractBurninDef(BaseSettingsModel):
|
||||
_isGroup = True
|
||||
_layout = "expanded"
|
||||
name: str = Field("")
|
||||
TOP_LEFT: str = Field("", topic="Top Left")
|
||||
TOP_CENTERED: str = Field("", topic="Top Centered")
|
||||
TOP_RIGHT: str = Field("", topic="Top Right")
|
||||
BOTTOM_LEFT: str = Field("", topic="Bottom Left")
|
||||
BOTTOM_CENTERED: str = Field("", topic="Bottom Centered")
|
||||
BOTTOM_RIGHT: str = Field("", topic="Bottom Right")
|
||||
filter: ExtractBurninDefFilter = Field(
|
||||
default_factory=ExtractBurninDefFilter,
|
||||
title="Additional filtering"
|
||||
)
|
||||
|
||||
@validator("name")
|
||||
def validate_name(cls, value):
|
||||
"""Ensure name does not contain weird characters"""
|
||||
return normalize_name(value)
|
||||
|
||||
|
||||
class ExtractBurninProfile(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
product_types: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Produt types"
|
||||
)
|
||||
hosts: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Host names"
|
||||
)
|
||||
task_types: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Task types",
|
||||
enum_resolver=task_types_enum
|
||||
)
|
||||
task_names: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Task names"
|
||||
)
|
||||
product_names: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Product names"
|
||||
)
|
||||
burnins: list[ExtractBurninDef] = Field(
|
||||
default_factory=list,
|
||||
title="Burnins"
|
||||
)
|
||||
|
||||
@validator("burnins")
|
||||
def validate_unique_outputs(cls, value):
|
||||
ensure_unique_names(value)
|
||||
|
||||
return value
|
||||
|
||||
|
||||
class ExtractBurninModel(BaseSettingsModel):
|
||||
_isGroup = True
|
||||
enabled: bool = Field(True)
|
||||
options: ExtractBurninOptionsModel = Field(
|
||||
default_factory=ExtractBurninOptionsModel,
|
||||
title="Burnin formatting options"
|
||||
)
|
||||
profiles: list[ExtractBurninProfile] = Field(
|
||||
default_factory=list,
|
||||
title="Profiles"
|
||||
)
|
||||
# --- [END] Extract Burnin ---
|
||||
|
||||
|
||||
class PreIntegrateThumbnailsProfile(BaseSettingsModel):
|
||||
_isGroup = True
|
||||
product_types: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Product types",
|
||||
)
|
||||
hosts: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Hosts",
|
||||
)
|
||||
task_types: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Task types",
|
||||
enum_resolver=task_types_enum
|
||||
)
|
||||
product_names: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Product names",
|
||||
)
|
||||
integrate_thumbnail: bool = Field(True)
|
||||
|
||||
|
||||
class PreIntegrateThumbnailsModel(BaseSettingsModel):
|
||||
"""Explicitly set if Thumbnail representation should be integrated.
|
||||
|
||||
If no matching profile set, existing state from Host implementation
|
||||
is kept.
|
||||
"""
|
||||
|
||||
_isGroup = True
|
||||
enabled: bool = Field(True)
|
||||
integrate_profiles: list[PreIntegrateThumbnailsProfile] = Field(
|
||||
default_factory=list,
|
||||
title="Integrate profiles"
|
||||
)
|
||||
|
||||
|
||||
class IntegrateProductGroupProfile(BaseSettingsModel):
|
||||
product_types: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Product types"
|
||||
)
|
||||
hosts: list[str] = Field(default_factory=list, title="Hosts")
|
||||
task_types: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Task types",
|
||||
enum_resolver=task_types_enum
|
||||
)
|
||||
tasks: list[str] = Field(default_factory=list, title="Task names")
|
||||
template: str = Field("", title="Template")
|
||||
|
||||
|
||||
class IntegrateProductGroupModel(BaseSettingsModel):
|
||||
"""Group published products by filtering logic.
|
||||
|
||||
Set all published instances as a part of specific group named according
|
||||
to 'Template'.
|
||||
|
||||
Implemented all variants of placeholders '{task}', '{product[type]}',
|
||||
'{host}', '{product[name]}', '{renderlayer}'.
|
||||
"""
|
||||
|
||||
_isGroup = True
|
||||
product_grouping_profiles: list[IntegrateProductGroupProfile] = Field(
|
||||
default_factory=list,
|
||||
title="Product group profiles"
|
||||
)
|
||||
|
||||
|
||||
class IntegrateANProductGroupProfileModel(BaseSettingsModel):
|
||||
product_types: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Product types"
|
||||
)
|
||||
hosts: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Hosts"
|
||||
)
|
||||
task_types: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Task types",
|
||||
enum_resolver=task_types_enum
|
||||
)
|
||||
tasks: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Task names"
|
||||
)
|
||||
template: str = Field("", title="Template")
|
||||
|
||||
|
||||
class IntegrateANTemplateNameProfileModel(BaseSettingsModel):
|
||||
product_types: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Product types"
|
||||
)
|
||||
hosts: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Hosts"
|
||||
)
|
||||
task_types: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Task types",
|
||||
enum_resolver=task_types_enum
|
||||
)
|
||||
tasks: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Task names"
|
||||
)
|
||||
template_name: str = Field("", title="Template name")
|
||||
|
||||
|
||||
class IntegrateHeroTemplateNameProfileModel(BaseSettingsModel):
|
||||
product_types: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Product types"
|
||||
)
|
||||
hosts: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Hosts"
|
||||
)
|
||||
task_types: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Task types",
|
||||
enum_resolver=task_types_enum
|
||||
)
|
||||
task_names: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Task names"
|
||||
)
|
||||
template_name: str = Field("", title="Template name")
|
||||
|
||||
|
||||
class IntegrateHeroVersionModel(BaseSettingsModel):
|
||||
_isGroup = True
|
||||
enabled: bool = Field(True)
|
||||
optional: bool = Field(False, title="Optional")
|
||||
active: bool = Field(True, title="Active")
|
||||
families: list[str] = Field(default_factory=list, title="Families")
|
||||
# TODO remove when removed from client code
|
||||
template_name_profiles: list[IntegrateHeroTemplateNameProfileModel] = (
|
||||
Field(
|
||||
default_factory=list,
|
||||
title="Template name profiles"
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class CleanUpModel(BaseSettingsModel):
|
||||
_isGroup = True
|
||||
paterns: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Patterns (regex)"
|
||||
)
|
||||
remove_temp_renders: bool = Field(False, title="Remove Temp renders")
|
||||
|
||||
|
||||
class CleanUpFarmModel(BaseSettingsModel):
|
||||
_isGroup = True
|
||||
enabled: bool = Field(True)
|
||||
|
||||
|
||||
class PublishPuginsModel(BaseSettingsModel):
|
||||
CollectAnatomyInstanceData: CollectAnatomyInstanceDataModel = Field(
|
||||
default_factory=CollectAnatomyInstanceDataModel,
|
||||
title="Collect Anatomy Instance Data"
|
||||
)
|
||||
CollectAudio: CollectAudioModel = Field(
|
||||
default_factory=CollectAudioModel,
|
||||
title="Collect Audio"
|
||||
)
|
||||
CollectSceneVersion: CollectSceneVersionModel = Field(
|
||||
default_factory=CollectSceneVersionModel,
|
||||
title="Collect Version from Workfile"
|
||||
)
|
||||
collect_comment_per_instance: CollectCommentPIModel = Field(
|
||||
default_factory=CollectCommentPIModel,
|
||||
title="Collect comment per instance",
|
||||
)
|
||||
CollectFramesFixDef: CollectFramesFixDefModel = Field(
|
||||
default_factory=CollectFramesFixDefModel,
|
||||
title="Collect Frames to Fix",
|
||||
)
|
||||
ValidateEditorialAssetName: ValidateBaseModel = Field(
|
||||
default_factory=ValidateBaseModel,
|
||||
title="Validate Editorial Asset Name"
|
||||
)
|
||||
ValidateVersion: ValidateBaseModel = Field(
|
||||
default_factory=ValidateBaseModel,
|
||||
title="Validate Version"
|
||||
)
|
||||
ValidateIntent: ValidateIntentModel = Field(
|
||||
default_factory=ValidateIntentModel,
|
||||
title="Validate Intent"
|
||||
)
|
||||
ExtractThumbnail: ExtractThumbnailModel = Field(
|
||||
default_factory=ExtractThumbnailModel,
|
||||
title="Extract Thumbnail"
|
||||
)
|
||||
ExtractOIIOTranscode: ExtractOIIOTranscodeModel = Field(
|
||||
default_factory=ExtractOIIOTranscodeModel,
|
||||
title="Extract OIIO Transcode"
|
||||
)
|
||||
ExtractReview: ExtractReviewModel = Field(
|
||||
default_factory=ExtractReviewModel,
|
||||
title="Extract Review"
|
||||
)
|
||||
ExtractBurnin: ExtractBurninModel = Field(
|
||||
default_factory=ExtractBurninModel,
|
||||
title="Extract Burnin"
|
||||
)
|
||||
PreIntegrateThumbnails: PreIntegrateThumbnailsModel = Field(
|
||||
default_factory=PreIntegrateThumbnailsModel,
|
||||
title="Override Integrate Thumbnail Representations"
|
||||
)
|
||||
IntegrateProductGroup: IntegrateProductGroupModel = Field(
|
||||
default_factory=IntegrateProductGroupModel,
|
||||
title="Integrate Product Group"
|
||||
)
|
||||
IntegrateHeroVersion: IntegrateHeroVersionModel = Field(
|
||||
default_factory=IntegrateHeroVersionModel,
|
||||
title="Integrate Hero Version"
|
||||
)
|
||||
CleanUp: CleanUpModel = Field(
|
||||
default_factory=CleanUpModel,
|
||||
title="Clean Up"
|
||||
)
|
||||
CleanUpFarm: CleanUpFarmModel = Field(
|
||||
default_factory=CleanUpFarmModel,
|
||||
title="Clean Up Farm"
|
||||
)
|
||||
|
||||
|
||||
DEFAULT_PUBLISH_VALUES = {
|
||||
"CollectAnatomyInstanceData": {
|
||||
"follow_workfile_version": False
|
||||
},
|
||||
"CollectAudio": {
|
||||
"enabled": False,
|
||||
"audio_product_name": "audioMain"
|
||||
},
|
||||
"CollectSceneVersion": {
|
||||
"hosts": [
|
||||
"aftereffects",
|
||||
"blender",
|
||||
"celaction",
|
||||
"fusion",
|
||||
"harmony",
|
||||
"hiero",
|
||||
"houdini",
|
||||
"maya",
|
||||
"nuke",
|
||||
"photoshop",
|
||||
"resolve",
|
||||
"tvpaint"
|
||||
],
|
||||
"skip_hosts_headless_publish": []
|
||||
},
|
||||
"collect_comment_per_instance": {
|
||||
"enabled": False,
|
||||
"families": []
|
||||
},
|
||||
"CollectFramesFixDef": {
|
||||
"enabled": True,
|
||||
"rewrite_version_enable": True
|
||||
},
|
||||
"ValidateEditorialAssetName": {
|
||||
"enabled": True,
|
||||
"optional": False,
|
||||
"active": True
|
||||
},
|
||||
"ValidateVersion": {
|
||||
"enabled": True,
|
||||
"optional": False,
|
||||
"active": True
|
||||
},
|
||||
"ValidateIntent": {
|
||||
"enabled": False,
|
||||
"profiles": []
|
||||
},
|
||||
"ExtractThumbnail": {
|
||||
"enabled": True,
|
||||
"ffmpeg_args": {
|
||||
"input": [
|
||||
"-apply_trc gamma22"
|
||||
],
|
||||
"output": []
|
||||
}
|
||||
},
|
||||
"ExtractOIIOTranscode": {
|
||||
"enabled": True,
|
||||
"profiles": []
|
||||
},
|
||||
"ExtractReview": {
|
||||
"enabled": True,
|
||||
"profiles": [
|
||||
{
|
||||
"product_types": [],
|
||||
"hosts": [],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "png",
|
||||
"ext": "png",
|
||||
"tags": [
|
||||
"ftrackreview",
|
||||
"kitsureview"
|
||||
],
|
||||
"burnins": [],
|
||||
"ffmpeg_args": {
|
||||
"video_filters": [],
|
||||
"audio_filters": [],
|
||||
"input": [],
|
||||
"output": []
|
||||
},
|
||||
"filter": {
|
||||
"families": [
|
||||
"render",
|
||||
"review",
|
||||
"ftrack"
|
||||
],
|
||||
"product_names": [],
|
||||
"custom_tags": [],
|
||||
"single_frame_filter": "single_frame"
|
||||
},
|
||||
"overscan_crop": "",
|
||||
"overscan_color": [0, 0, 0, 1.0],
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"scale_pixel_aspect": True,
|
||||
"bg_color": [0, 0, 0, 0.0],
|
||||
"letter_box": {
|
||||
"enabled": False,
|
||||
"ratio": 0.0,
|
||||
"fill_color": [0, 0, 0, 1.0],
|
||||
"line_thickness": 0,
|
||||
"line_color": [255, 0, 0, 1.0]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "h264",
|
||||
"ext": "mp4",
|
||||
"tags": [
|
||||
"burnin",
|
||||
"ftrackreview",
|
||||
"kitsureview"
|
||||
],
|
||||
"burnins": [],
|
||||
"ffmpeg_args": {
|
||||
"video_filters": [],
|
||||
"audio_filters": [],
|
||||
"input": [
|
||||
"-apply_trc gamma22"
|
||||
],
|
||||
"output": [
|
||||
"-pix_fmt yuv420p",
|
||||
"-crf 18",
|
||||
"-intra"
|
||||
]
|
||||
},
|
||||
"filter": {
|
||||
"families": [
|
||||
"render",
|
||||
"review",
|
||||
"ftrack"
|
||||
],
|
||||
"product_names": [],
|
||||
"custom_tags": [],
|
||||
"single_frame_filter": "multi_frame"
|
||||
},
|
||||
"overscan_crop": "",
|
||||
"overscan_color": [0, 0, 0, 1.0],
|
||||
"width": 0,
|
||||
"height": 0,
|
||||
"scale_pixel_aspect": True,
|
||||
"bg_color": [0, 0, 0, 0.0],
|
||||
"letter_box": {
|
||||
"enabled": False,
|
||||
"ratio": 0.0,
|
||||
"fill_color": [0, 0, 0, 1.0],
|
||||
"line_thickness": 0,
|
||||
"line_color": [255, 0, 0, 1.0]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"ExtractBurnin": {
|
||||
"enabled": True,
|
||||
"options": {
|
||||
"font_size": 42,
|
||||
"font_color": [255, 255, 255, 1.0],
|
||||
"bg_color": [0, 0, 0, 0.5],
|
||||
"x_offset": 5,
|
||||
"y_offset": 5,
|
||||
"bg_padding": 5,
|
||||
"font_filepath": {
|
||||
"windows": "",
|
||||
"darwin": "",
|
||||
"linux": ""
|
||||
}
|
||||
},
|
||||
"profiles": [
|
||||
{
|
||||
"product_types": [],
|
||||
"hosts": [],
|
||||
"task_types": [],
|
||||
"task_names": [],
|
||||
"product_names": [],
|
||||
"burnins": [
|
||||
{
|
||||
"name": "burnin",
|
||||
"TOP_LEFT": "{yy}-{mm}-{dd}",
|
||||
"TOP_CENTERED": "",
|
||||
"TOP_RIGHT": "{anatomy[version]}",
|
||||
"BOTTOM_LEFT": "{username}",
|
||||
"BOTTOM_CENTERED": "{folder[name]}",
|
||||
"BOTTOM_RIGHT": "{frame_start}-{current_frame}-{frame_end}",
|
||||
"filter": {
|
||||
"families": [],
|
||||
"tags": []
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"product_types": ["review"],
|
||||
"hosts": [
|
||||
"maya",
|
||||
"houdini",
|
||||
"max"
|
||||
],
|
||||
"task_types": [],
|
||||
"task_names": [],
|
||||
"product_names": [],
|
||||
"burnins": [
|
||||
{
|
||||
"name": "focal_length_burnin",
|
||||
"TOP_LEFT": "{yy}-{mm}-{dd}",
|
||||
"TOP_CENTERED": "{focalLength:.2f} mm",
|
||||
"TOP_RIGHT": "{anatomy[version]}",
|
||||
"BOTTOM_LEFT": "{username}",
|
||||
"BOTTOM_CENTERED": "{folder[name]}",
|
||||
"BOTTOM_RIGHT": "{frame_start}-{current_frame}-{frame_end}",
|
||||
"filter": {
|
||||
"families": [],
|
||||
"tags": []
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"PreIntegrateThumbnails": {
|
||||
"enabled": True,
|
||||
"integrate_profiles": []
|
||||
},
|
||||
"IntegrateProductGroup": {
|
||||
"product_grouping_profiles": [
|
||||
{
|
||||
"product_types": [],
|
||||
"hosts": [],
|
||||
"task_types": [],
|
||||
"tasks": [],
|
||||
"template": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
"IntegrateHeroVersion": {
|
||||
"enabled": True,
|
||||
"optional": True,
|
||||
"active": True,
|
||||
"families": [
|
||||
"model",
|
||||
"rig",
|
||||
"look",
|
||||
"pointcache",
|
||||
"animation",
|
||||
"setdress",
|
||||
"layout",
|
||||
"mayaScene",
|
||||
"simpleUnrealTexture"
|
||||
],
|
||||
"template_name_profiles": [
|
||||
{
|
||||
"product_types": [
|
||||
"simpleUnrealTexture"
|
||||
],
|
||||
"hosts": [
|
||||
"standalonepublisher"
|
||||
],
|
||||
"task_types": [],
|
||||
"task_names": [],
|
||||
"template_name": "simpleUnrealTextureHero"
|
||||
}
|
||||
]
|
||||
},
|
||||
"CleanUp": {
|
||||
"paterns": [],
|
||||
"remove_temp_renders": False
|
||||
},
|
||||
"CleanUpFarm": {
|
||||
"enabled": False
|
||||
}
|
||||
}
|
||||
506
server_addon/core/server/settings/tools.py
Normal file
506
server_addon/core/server/settings/tools.py
Normal file
|
|
@ -0,0 +1,506 @@
|
|||
from pydantic import Field, validator
|
||||
from ayon_server.settings import (
|
||||
BaseSettingsModel,
|
||||
normalize_name,
|
||||
ensure_unique_names,
|
||||
task_types_enum,
|
||||
)
|
||||
|
||||
|
||||
class ProductTypeSmartSelectModel(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
name: str = Field("", title="Product type")
|
||||
task_names: list[str] = Field(default_factory=list, title="Task names")
|
||||
|
||||
@validator("name")
|
||||
def normalize_value(cls, value):
|
||||
return normalize_name(value)
|
||||
|
||||
|
||||
class ProductNameProfile(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
product_types: list[str] = Field(
|
||||
default_factory=list, title="Product types"
|
||||
)
|
||||
hosts: list[str] = Field(default_factory=list, title="Hosts")
|
||||
task_types: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Task types",
|
||||
enum_resolver=task_types_enum
|
||||
)
|
||||
tasks: list[str] = Field(default_factory=list, title="Task names")
|
||||
template: str = Field("", title="Template")
|
||||
|
||||
|
||||
class CreatorToolModel(BaseSettingsModel):
|
||||
# TODO this was dynamic dictionary '{name: task_names}'
|
||||
product_types_smart_select: list[ProductTypeSmartSelectModel] = Field(
|
||||
default_factory=list,
|
||||
title="Create Smart Select"
|
||||
)
|
||||
product_name_profiles: list[ProductNameProfile] = Field(
|
||||
default_factory=list,
|
||||
title="Product name profiles"
|
||||
)
|
||||
|
||||
@validator("product_types_smart_select")
|
||||
def validate_unique_name(cls, value):
|
||||
ensure_unique_names(value)
|
||||
return value
|
||||
|
||||
|
||||
class WorkfileTemplateProfile(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
task_types: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Task types",
|
||||
enum_resolver=task_types_enum
|
||||
)
|
||||
# TODO this should use hosts enum
|
||||
hosts: list[str] = Field(default_factory=list, title="Hosts")
|
||||
# TODO this was using project anatomy template name
|
||||
workfile_template: str = Field("", title="Workfile template")
|
||||
|
||||
|
||||
class LastWorkfileOnStartupProfile(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
# TODO this should use hosts enum
|
||||
hosts: list[str] = Field(default_factory=list, title="Hosts")
|
||||
task_types: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Task types",
|
||||
enum_resolver=task_types_enum
|
||||
)
|
||||
tasks: list[str] = Field(default_factory=list, title="Task names")
|
||||
enabled: bool = Field(True, title="Enabled")
|
||||
use_last_published_workfile: bool = Field(
|
||||
True, title="Use last published workfile"
|
||||
)
|
||||
|
||||
|
||||
class WorkfilesToolOnStartupProfile(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
# TODO this should use hosts enum
|
||||
hosts: list[str] = Field(default_factory=list, title="Hosts")
|
||||
task_types: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Task types",
|
||||
enum_resolver=task_types_enum
|
||||
)
|
||||
tasks: list[str] = Field(default_factory=list, title="Task names")
|
||||
enabled: bool = Field(True, title="Enabled")
|
||||
|
||||
|
||||
class ExtraWorkFoldersProfile(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
# TODO this should use hosts enum
|
||||
hosts: list[str] = Field(default_factory=list, title="Hosts")
|
||||
task_types: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Task types",
|
||||
enum_resolver=task_types_enum
|
||||
)
|
||||
task_names: list[str] = Field(default_factory=list, title="Task names")
|
||||
folders: list[str] = Field(default_factory=list, title="Folders")
|
||||
|
||||
|
||||
class WorkfilesLockProfile(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
# TODO this should use hosts enum
|
||||
host_names: list[str] = Field(default_factory=list, title="Hosts")
|
||||
enabled: bool = Field(True, title="Enabled")
|
||||
|
||||
|
||||
class WorkfilesToolModel(BaseSettingsModel):
|
||||
workfile_template_profiles: list[WorkfileTemplateProfile] = Field(
|
||||
default_factory=list,
|
||||
title="Workfile template profiles"
|
||||
)
|
||||
last_workfile_on_startup: list[LastWorkfileOnStartupProfile] = Field(
|
||||
default_factory=list,
|
||||
title="Open last workfile on launch"
|
||||
)
|
||||
open_workfile_tool_on_startup: list[WorkfilesToolOnStartupProfile] = Field(
|
||||
default_factory=list,
|
||||
title="Open workfile tool on launch"
|
||||
)
|
||||
extra_folders: list[ExtraWorkFoldersProfile] = Field(
|
||||
default_factory=list,
|
||||
title="Extra work folders"
|
||||
)
|
||||
workfile_lock_profiles: list[WorkfilesLockProfile] = Field(
|
||||
default_factory=list,
|
||||
title="Workfile lock profiles"
|
||||
)
|
||||
|
||||
|
||||
def _product_types_enum():
|
||||
return [
|
||||
"action",
|
||||
"animation",
|
||||
"assembly",
|
||||
"audio",
|
||||
"backgroundComp",
|
||||
"backgroundLayout",
|
||||
"camera",
|
||||
"editorial",
|
||||
"gizmo",
|
||||
"image",
|
||||
"layout",
|
||||
"look",
|
||||
"matchmove",
|
||||
"mayaScene",
|
||||
"model",
|
||||
"nukenodes",
|
||||
"plate",
|
||||
"pointcache",
|
||||
"prerender",
|
||||
"redshiftproxy",
|
||||
"reference",
|
||||
"render",
|
||||
"review",
|
||||
"rig",
|
||||
"setdress",
|
||||
"take",
|
||||
"usdShade",
|
||||
"vdbcache",
|
||||
"vrayproxy",
|
||||
"workfile",
|
||||
"xgen",
|
||||
"yetiRig",
|
||||
"yeticache"
|
||||
]
|
||||
|
||||
|
||||
class LoaderProductTypeFilterProfile(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
# TODO this should use hosts enum
|
||||
hosts: list[str] = Field(default_factory=list, title="Hosts")
|
||||
task_types: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Task types",
|
||||
enum_resolver=task_types_enum
|
||||
)
|
||||
is_include: bool = Field(True, title="Exclude / Include")
|
||||
filter_product_types: list[str] = Field(
|
||||
default_factory=list,
|
||||
enum_resolver=_product_types_enum
|
||||
)
|
||||
|
||||
|
||||
class LoaderToolModel(BaseSettingsModel):
|
||||
product_type_filter_profiles: list[LoaderProductTypeFilterProfile] = Field(
|
||||
default_factory=list,
|
||||
title="Product type filtering"
|
||||
)
|
||||
|
||||
|
||||
class PublishTemplateNameProfile(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
product_types: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Product types"
|
||||
)
|
||||
# TODO this should use hosts enum
|
||||
hosts: list[str] = Field(default_factory=list, title="Hosts")
|
||||
task_types: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Task types",
|
||||
enum_resolver=task_types_enum
|
||||
)
|
||||
task_names: list[str] = Field(default_factory=list, title="Task names")
|
||||
template_name: str = Field("", title="Template name")
|
||||
|
||||
|
||||
class CustomStagingDirProfileModel(BaseSettingsModel):
|
||||
active: bool = Field(True, title="Is active")
|
||||
hosts: list[str] = Field(default_factory=list, title="Host names")
|
||||
task_types: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Task types",
|
||||
enum_resolver=task_types_enum
|
||||
)
|
||||
task_names: list[str] = Field(
|
||||
default_factory=list, title="Task names"
|
||||
)
|
||||
product_types: list[str] = Field(
|
||||
default_factory=list, title="Product types"
|
||||
)
|
||||
product_names: list[str] = Field(
|
||||
default_factory=list, title="Product names"
|
||||
)
|
||||
custom_staging_dir_persistent: bool = Field(
|
||||
False, title="Custom Staging Folder Persistent"
|
||||
)
|
||||
template_name: str = Field("", title="Template Name")
|
||||
|
||||
|
||||
class PublishToolModel(BaseSettingsModel):
|
||||
template_name_profiles: list[PublishTemplateNameProfile] = Field(
|
||||
default_factory=list,
|
||||
title="Template name profiles"
|
||||
)
|
||||
hero_template_name_profiles: list[PublishTemplateNameProfile] = Field(
|
||||
default_factory=list,
|
||||
title="Hero template name profiles"
|
||||
)
|
||||
custom_staging_dir_profiles: list[CustomStagingDirProfileModel] = Field(
|
||||
default_factory=list,
|
||||
title="Custom Staging Dir Profiles"
|
||||
)
|
||||
|
||||
|
||||
class GlobalToolsModel(BaseSettingsModel):
|
||||
creator: CreatorToolModel = Field(
|
||||
default_factory=CreatorToolModel,
|
||||
title="Creator"
|
||||
)
|
||||
Workfiles: WorkfilesToolModel = Field(
|
||||
default_factory=WorkfilesToolModel,
|
||||
title="Workfiles"
|
||||
)
|
||||
loader: LoaderToolModel = Field(
|
||||
default_factory=LoaderToolModel,
|
||||
title="Loader"
|
||||
)
|
||||
publish: PublishToolModel = Field(
|
||||
default_factory=PublishToolModel,
|
||||
title="Publish"
|
||||
)
|
||||
|
||||
|
||||
DEFAULT_TOOLS_VALUES = {
|
||||
"creator": {
|
||||
"product_types_smart_select": [
|
||||
{
|
||||
"name": "Render",
|
||||
"task_names": [
|
||||
"light",
|
||||
"render"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Model",
|
||||
"task_names": [
|
||||
"model"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Layout",
|
||||
"task_names": [
|
||||
"layout"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Look",
|
||||
"task_names": [
|
||||
"look"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Rig",
|
||||
"task_names": [
|
||||
"rigging",
|
||||
"rig"
|
||||
]
|
||||
}
|
||||
],
|
||||
"product_name_profiles": [
|
||||
{
|
||||
"product_types": [],
|
||||
"hosts": [],
|
||||
"task_types": [],
|
||||
"tasks": [],
|
||||
"template": "{product[type]}{variant}"
|
||||
},
|
||||
{
|
||||
"product_types": [
|
||||
"workfile"
|
||||
],
|
||||
"hosts": [],
|
||||
"task_types": [],
|
||||
"tasks": [],
|
||||
"template": "{product[type]}{Task[name]}"
|
||||
},
|
||||
{
|
||||
"product_types": [
|
||||
"render"
|
||||
],
|
||||
"hosts": [],
|
||||
"task_types": [],
|
||||
"tasks": [],
|
||||
"template": "{product[type]}{Task[name]}{Variant}"
|
||||
},
|
||||
{
|
||||
"product_types": [
|
||||
"renderLayer",
|
||||
"renderPass"
|
||||
],
|
||||
"hosts": [
|
||||
"tvpaint"
|
||||
],
|
||||
"task_types": [],
|
||||
"tasks": [],
|
||||
"template": "{product[type]}{Task[name]}_{Renderlayer}_{Renderpass}"
|
||||
},
|
||||
{
|
||||
"product_types": [
|
||||
"review",
|
||||
"workfile"
|
||||
],
|
||||
"hosts": [
|
||||
"aftereffects",
|
||||
"tvpaint"
|
||||
],
|
||||
"task_types": [],
|
||||
"tasks": [],
|
||||
"template": "{product[type]}{Task[name]}"
|
||||
},
|
||||
{
|
||||
"product_types": ["render"],
|
||||
"hosts": [
|
||||
"aftereffects"
|
||||
],
|
||||
"task_types": [],
|
||||
"tasks": [],
|
||||
"template": "{product[type]}{Task[name]}{Composition}{Variant}"
|
||||
},
|
||||
{
|
||||
"product_types": [
|
||||
"staticMesh"
|
||||
],
|
||||
"hosts": [
|
||||
"maya"
|
||||
],
|
||||
"task_types": [],
|
||||
"tasks": [],
|
||||
"template": "S_{folder[name]}{variant}"
|
||||
},
|
||||
{
|
||||
"product_types": [
|
||||
"skeletalMesh"
|
||||
],
|
||||
"hosts": [
|
||||
"maya"
|
||||
],
|
||||
"task_types": [],
|
||||
"tasks": [],
|
||||
"template": "SK_{folder[name]}{variant}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"Workfiles": {
|
||||
"workfile_template_profiles": [
|
||||
{
|
||||
"task_types": [],
|
||||
"hosts": [],
|
||||
"workfile_template": "work"
|
||||
},
|
||||
{
|
||||
"task_types": [],
|
||||
"hosts": [
|
||||
"unreal"
|
||||
],
|
||||
"workfile_template": "work_unreal"
|
||||
}
|
||||
],
|
||||
"last_workfile_on_startup": [
|
||||
{
|
||||
"hosts": [],
|
||||
"task_types": [],
|
||||
"tasks": [],
|
||||
"enabled": True,
|
||||
"use_last_published_workfile": False
|
||||
}
|
||||
],
|
||||
"open_workfile_tool_on_startup": [
|
||||
{
|
||||
"hosts": [],
|
||||
"task_types": [],
|
||||
"tasks": [],
|
||||
"enabled": False
|
||||
}
|
||||
],
|
||||
"extra_folders": [],
|
||||
"workfile_lock_profiles": []
|
||||
},
|
||||
"loader": {
|
||||
"product_type_filter_profiles": [
|
||||
{
|
||||
"hosts": [],
|
||||
"task_types": [],
|
||||
"is_include": True,
|
||||
"filter_product_types": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"publish": {
|
||||
"template_name_profiles": [
|
||||
{
|
||||
"product_types": [],
|
||||
"hosts": [],
|
||||
"task_types": [],
|
||||
"task_names": [],
|
||||
"template_name": "publish"
|
||||
},
|
||||
{
|
||||
"product_types": [
|
||||
"review",
|
||||
"render",
|
||||
"prerender"
|
||||
],
|
||||
"hosts": [],
|
||||
"task_types": [],
|
||||
"task_names": [],
|
||||
"template_name": "publish_render"
|
||||
},
|
||||
{
|
||||
"product_types": [
|
||||
"simpleUnrealTexture"
|
||||
],
|
||||
"hosts": [
|
||||
"standalonepublisher"
|
||||
],
|
||||
"task_types": [],
|
||||
"task_names": [],
|
||||
"template_name": "publish_simpleUnrealTexture"
|
||||
},
|
||||
{
|
||||
"product_types": [
|
||||
"staticMesh",
|
||||
"skeletalMesh"
|
||||
],
|
||||
"hosts": [
|
||||
"maya"
|
||||
],
|
||||
"task_types": [],
|
||||
"task_names": [],
|
||||
"template_name": "publish_maya2unreal"
|
||||
},
|
||||
{
|
||||
"product_types": [
|
||||
"online"
|
||||
],
|
||||
"hosts": [
|
||||
"traypublisher"
|
||||
],
|
||||
"task_types": [],
|
||||
"task_names": [],
|
||||
"template_name": "publish_online"
|
||||
}
|
||||
],
|
||||
"hero_template_name_profiles": [
|
||||
{
|
||||
"product_types": [
|
||||
"simpleUnrealTexture"
|
||||
],
|
||||
"hosts": [
|
||||
"standalonepublisher"
|
||||
],
|
||||
"task_types": [],
|
||||
"task_names": [],
|
||||
"template_name": "hero_simpleUnrealTextureHero"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
1
server_addon/core/server/version.py
Normal file
1
server_addon/core/server/version.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
__version__ = "0.1.0"
|
||||
|
|
@ -1,140 +0,0 @@
|
|||
import os
|
||||
import re
|
||||
import shutil
|
||||
import zipfile
|
||||
import collections
|
||||
from pathlib import Path
|
||||
from typing import Any, Optional, Iterable
|
||||
|
||||
# Patterns of directories to be skipped for server part of addon
|
||||
IGNORE_DIR_PATTERNS: list[re.Pattern] = [
|
||||
re.compile(pattern)
|
||||
for pattern in {
|
||||
# Skip directories starting with '.'
|
||||
r"^\.",
|
||||
# Skip any pycache folders
|
||||
"^__pycache__$"
|
||||
}
|
||||
]
|
||||
|
||||
# Patterns of files to be skipped for server part of addon
|
||||
IGNORE_FILE_PATTERNS: list[re.Pattern] = [
|
||||
re.compile(pattern)
|
||||
for pattern in {
|
||||
# Skip files starting with '.'
|
||||
# NOTE this could be an issue in some cases
|
||||
r"^\.",
|
||||
# Skip '.pyc' files
|
||||
r"\.pyc$"
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
def _value_match_regexes(value: str, regexes: Iterable[re.Pattern]) -> bool:
|
||||
return any(
|
||||
regex.search(value)
|
||||
for regex in regexes
|
||||
)
|
||||
|
||||
|
||||
def find_files_in_subdir(
|
||||
src_path: str,
|
||||
ignore_file_patterns: Optional[list[re.Pattern]] = None,
|
||||
ignore_dir_patterns: Optional[list[re.Pattern]] = None
|
||||
):
|
||||
"""Find all files to copy in subdirectories of given path.
|
||||
|
||||
All files that match any of the patterns in 'ignore_file_patterns' will
|
||||
be skipped and any directories that match any of the patterns in
|
||||
'ignore_dir_patterns' will be skipped with all subfiles.
|
||||
|
||||
Args:
|
||||
src_path (str): Path to directory to search in.
|
||||
ignore_file_patterns (Optional[list[re.Pattern]]): List of regexes
|
||||
to match files to ignore.
|
||||
ignore_dir_patterns (Optional[list[re.Pattern]]): List of regexes
|
||||
to match directories to ignore.
|
||||
|
||||
Returns:
|
||||
list[tuple[str, str]]: List of tuples with path to file and parent
|
||||
directories relative to 'src_path'.
|
||||
"""
|
||||
|
||||
if ignore_file_patterns is None:
|
||||
ignore_file_patterns = IGNORE_FILE_PATTERNS
|
||||
|
||||
if ignore_dir_patterns is None:
|
||||
ignore_dir_patterns = IGNORE_DIR_PATTERNS
|
||||
output: list[tuple[str, str]] = []
|
||||
|
||||
hierarchy_queue = collections.deque()
|
||||
hierarchy_queue.append((src_path, []))
|
||||
while hierarchy_queue:
|
||||
item: tuple[str, str] = hierarchy_queue.popleft()
|
||||
dirpath, parents = item
|
||||
for name in os.listdir(dirpath):
|
||||
path = os.path.join(dirpath, name)
|
||||
if os.path.isfile(path):
|
||||
if not _value_match_regexes(name, ignore_file_patterns):
|
||||
items = list(parents)
|
||||
items.append(name)
|
||||
output.append((path, os.path.sep.join(items)))
|
||||
continue
|
||||
|
||||
if not _value_match_regexes(name, ignore_dir_patterns):
|
||||
items = list(parents)
|
||||
items.append(name)
|
||||
hierarchy_queue.append((path, items))
|
||||
|
||||
return output
|
||||
|
||||
|
||||
def main():
|
||||
openpype_addon_dir = Path(os.path.dirname(os.path.abspath(__file__)))
|
||||
server_dir = openpype_addon_dir / "server"
|
||||
package_root = openpype_addon_dir / "package"
|
||||
pyproject_path = openpype_addon_dir / "client" / "pyproject.toml"
|
||||
|
||||
root_dir = openpype_addon_dir.parent
|
||||
openpype_dir = root_dir / "openpype"
|
||||
version_path = openpype_dir / "version.py"
|
||||
|
||||
# Read version
|
||||
version_content: dict[str, Any] = {}
|
||||
with open(str(version_path), "r") as stream:
|
||||
exec(stream.read(), version_content)
|
||||
addon_version: str = version_content["__version__"]
|
||||
|
||||
output_dir = package_root / "openpype" / addon_version
|
||||
private_dir = output_dir / "private"
|
||||
|
||||
# Make sure package dir is empty
|
||||
if package_root.exists():
|
||||
shutil.rmtree(str(package_root))
|
||||
# Make sure output dir is created
|
||||
output_dir.mkdir(parents=True)
|
||||
|
||||
# Copy version
|
||||
shutil.copy(str(version_path), str(output_dir))
|
||||
for subitem in server_dir.iterdir():
|
||||
shutil.copy(str(subitem), str(output_dir / subitem.name))
|
||||
|
||||
# Make sure private dir exists
|
||||
private_dir.mkdir(parents=True)
|
||||
|
||||
# Copy pyproject.toml
|
||||
shutil.copy(
|
||||
str(pyproject_path),
|
||||
(private_dir / pyproject_path.name)
|
||||
)
|
||||
|
||||
# Zip client
|
||||
zip_filepath = private_dir / "client.zip"
|
||||
with zipfile.ZipFile(zip_filepath, "w", zipfile.ZIP_DEFLATED) as zipf:
|
||||
# Add client code content to zip
|
||||
for path, sub_path in find_files_in_subdir(str(openpype_dir)):
|
||||
zipf.write(path, f"{openpype_dir.name}/{sub_path}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
279
server_addon/create_ayon_addons.py
Normal file
279
server_addon/create_ayon_addons.py
Normal file
|
|
@ -0,0 +1,279 @@
|
|||
import os
|
||||
import sys
|
||||
import re
|
||||
import json
|
||||
import shutil
|
||||
import zipfile
|
||||
import platform
|
||||
import collections
|
||||
from pathlib import Path
|
||||
from typing import Any, Optional, Iterable
|
||||
|
||||
# Patterns of directories to be skipped for server part of addon
|
||||
IGNORE_DIR_PATTERNS: list[re.Pattern] = [
|
||||
re.compile(pattern)
|
||||
for pattern in {
|
||||
# Skip directories starting with '.'
|
||||
r"^\.",
|
||||
# Skip any pycache folders
|
||||
"^__pycache__$"
|
||||
}
|
||||
]
|
||||
|
||||
# Patterns of files to be skipped for server part of addon
|
||||
IGNORE_FILE_PATTERNS: list[re.Pattern] = [
|
||||
re.compile(pattern)
|
||||
for pattern in {
|
||||
# Skip files starting with '.'
|
||||
# NOTE this could be an issue in some cases
|
||||
r"^\.",
|
||||
# Skip '.pyc' files
|
||||
r"\.pyc$"
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
class ZipFileLongPaths(zipfile.ZipFile):
|
||||
"""Allows longer paths in zip files.
|
||||
|
||||
Regular DOS paths are limited to MAX_PATH (260) characters, including
|
||||
the string's terminating NUL character.
|
||||
That limit can be exceeded by using an extended-length path that
|
||||
starts with the '\\?\' prefix.
|
||||
"""
|
||||
_is_windows = platform.system().lower() == "windows"
|
||||
|
||||
def _extract_member(self, member, tpath, pwd):
|
||||
if self._is_windows:
|
||||
tpath = os.path.abspath(tpath)
|
||||
if tpath.startswith("\\\\"):
|
||||
tpath = "\\\\?\\UNC\\" + tpath[2:]
|
||||
else:
|
||||
tpath = "\\\\?\\" + tpath
|
||||
|
||||
return super(ZipFileLongPaths, self)._extract_member(
|
||||
member, tpath, pwd
|
||||
)
|
||||
|
||||
|
||||
def _value_match_regexes(value: str, regexes: Iterable[re.Pattern]) -> bool:
|
||||
return any(
|
||||
regex.search(value)
|
||||
for regex in regexes
|
||||
)
|
||||
|
||||
|
||||
def find_files_in_subdir(
|
||||
src_path: str,
|
||||
ignore_file_patterns: Optional[list[re.Pattern]] = None,
|
||||
ignore_dir_patterns: Optional[list[re.Pattern]] = None
|
||||
):
|
||||
"""Find all files to copy in subdirectories of given path.
|
||||
|
||||
All files that match any of the patterns in 'ignore_file_patterns' will
|
||||
be skipped and any directories that match any of the patterns in
|
||||
'ignore_dir_patterns' will be skipped with all subfiles.
|
||||
|
||||
Args:
|
||||
src_path (str): Path to directory to search in.
|
||||
ignore_file_patterns (Optional[list[re.Pattern]]): List of regexes
|
||||
to match files to ignore.
|
||||
ignore_dir_patterns (Optional[list[re.Pattern]]): List of regexes
|
||||
to match directories to ignore.
|
||||
|
||||
Returns:
|
||||
list[tuple[str, str]]: List of tuples with path to file and parent
|
||||
directories relative to 'src_path'.
|
||||
"""
|
||||
|
||||
if ignore_file_patterns is None:
|
||||
ignore_file_patterns = IGNORE_FILE_PATTERNS
|
||||
|
||||
if ignore_dir_patterns is None:
|
||||
ignore_dir_patterns = IGNORE_DIR_PATTERNS
|
||||
output: list[tuple[str, str]] = []
|
||||
|
||||
hierarchy_queue = collections.deque()
|
||||
hierarchy_queue.append((src_path, []))
|
||||
while hierarchy_queue:
|
||||
item: tuple[str, str] = hierarchy_queue.popleft()
|
||||
dirpath, parents = item
|
||||
for name in os.listdir(dirpath):
|
||||
path = os.path.join(dirpath, name)
|
||||
if os.path.isfile(path):
|
||||
if not _value_match_regexes(name, ignore_file_patterns):
|
||||
items = list(parents)
|
||||
items.append(name)
|
||||
output.append((path, os.path.sep.join(items)))
|
||||
continue
|
||||
|
||||
if not _value_match_regexes(name, ignore_dir_patterns):
|
||||
items = list(parents)
|
||||
items.append(name)
|
||||
hierarchy_queue.append((path, items))
|
||||
|
||||
return output
|
||||
|
||||
|
||||
def read_addon_version(version_path: Path) -> str:
|
||||
# Read version
|
||||
version_content: dict[str, Any] = {}
|
||||
with open(str(version_path), "r") as stream:
|
||||
exec(stream.read(), version_content)
|
||||
return version_content["__version__"]
|
||||
|
||||
|
||||
def get_addon_version(addon_dir: Path) -> str:
|
||||
return read_addon_version(addon_dir / "server" / "version.py")
|
||||
|
||||
|
||||
def create_addon_zip(
|
||||
output_dir: Path,
|
||||
addon_name: str,
|
||||
addon_version: str,
|
||||
keep_source: bool
|
||||
):
|
||||
zip_filepath = output_dir / f"{addon_name}.zip"
|
||||
addon_output_dir = output_dir / addon_name / addon_version
|
||||
with ZipFileLongPaths(zip_filepath, "w", zipfile.ZIP_DEFLATED) as zipf:
|
||||
zipf.writestr(
|
||||
"manifest.json",
|
||||
json.dumps({
|
||||
"addon_name": addon_name,
|
||||
"addon_version": addon_version
|
||||
})
|
||||
)
|
||||
# Add client code content to zip
|
||||
src_root = os.path.normpath(str(addon_output_dir.absolute()))
|
||||
src_root_offset = len(src_root) + 1
|
||||
for root, _, filenames in os.walk(str(addon_output_dir)):
|
||||
rel_root = ""
|
||||
if root != src_root:
|
||||
rel_root = root[src_root_offset:]
|
||||
|
||||
for filename in filenames:
|
||||
src_path = os.path.join(root, filename)
|
||||
if rel_root:
|
||||
dst_path = os.path.join("addon", rel_root, filename)
|
||||
else:
|
||||
dst_path = os.path.join("addon", filename)
|
||||
zipf.write(src_path, dst_path)
|
||||
|
||||
if not keep_source:
|
||||
shutil.rmtree(str(output_dir / addon_name))
|
||||
|
||||
|
||||
def create_openpype_package(
|
||||
addon_dir: Path,
|
||||
output_dir: Path,
|
||||
root_dir: Path,
|
||||
create_zip: bool,
|
||||
keep_source: bool
|
||||
):
|
||||
server_dir = addon_dir / "server"
|
||||
pyproject_path = addon_dir / "client" / "pyproject.toml"
|
||||
|
||||
openpype_dir = root_dir / "openpype"
|
||||
version_path = openpype_dir / "version.py"
|
||||
addon_version = read_addon_version(version_path)
|
||||
|
||||
addon_output_dir = output_dir / "openpype" / addon_version
|
||||
private_dir = addon_output_dir / "private"
|
||||
# Make sure dir exists
|
||||
addon_output_dir.mkdir(parents=True)
|
||||
private_dir.mkdir(parents=True)
|
||||
|
||||
# Copy version
|
||||
shutil.copy(str(version_path), str(addon_output_dir))
|
||||
for subitem in server_dir.iterdir():
|
||||
shutil.copy(str(subitem), str(addon_output_dir / subitem.name))
|
||||
|
||||
# Copy pyproject.toml
|
||||
shutil.copy(
|
||||
str(pyproject_path),
|
||||
(private_dir / pyproject_path.name)
|
||||
)
|
||||
|
||||
# Zip client
|
||||
zip_filepath = private_dir / "client.zip"
|
||||
with ZipFileLongPaths(zip_filepath, "w", zipfile.ZIP_DEFLATED) as zipf:
|
||||
# Add client code content to zip
|
||||
for path, sub_path in find_files_in_subdir(str(openpype_dir)):
|
||||
zipf.write(path, f"{openpype_dir.name}/{sub_path}")
|
||||
|
||||
if create_zip:
|
||||
create_addon_zip(output_dir, "openpype", addon_version, keep_source)
|
||||
|
||||
|
||||
def create_addon_package(
|
||||
addon_dir: Path,
|
||||
output_dir: Path,
|
||||
create_zip: bool,
|
||||
keep_source: bool
|
||||
):
|
||||
server_dir = addon_dir / "server"
|
||||
addon_version = get_addon_version(addon_dir)
|
||||
|
||||
addon_output_dir = output_dir / addon_dir.name / addon_version
|
||||
if addon_output_dir.exists():
|
||||
shutil.rmtree(str(addon_output_dir))
|
||||
addon_output_dir.mkdir(parents=True)
|
||||
|
||||
# Copy server content
|
||||
src_root = os.path.normpath(str(server_dir.absolute()))
|
||||
src_root_offset = len(src_root) + 1
|
||||
for root, _, filenames in os.walk(str(server_dir)):
|
||||
dst_root = addon_output_dir
|
||||
if root != src_root:
|
||||
rel_root = root[src_root_offset:]
|
||||
dst_root = dst_root / rel_root
|
||||
|
||||
dst_root.mkdir(parents=True, exist_ok=True)
|
||||
for filename in filenames:
|
||||
src_path = os.path.join(root, filename)
|
||||
shutil.copy(src_path, str(dst_root))
|
||||
|
||||
if create_zip:
|
||||
create_addon_zip(
|
||||
output_dir, addon_dir.name, addon_version, keep_source
|
||||
)
|
||||
|
||||
|
||||
def main(create_zip=True, keep_source=False):
|
||||
current_dir = Path(os.path.dirname(os.path.abspath(__file__)))
|
||||
root_dir = current_dir.parent
|
||||
output_dir = current_dir / "packages"
|
||||
print("Package creation started...")
|
||||
|
||||
# Make sure package dir is empty
|
||||
if output_dir.exists():
|
||||
shutil.rmtree(str(output_dir))
|
||||
# Make sure output dir is created
|
||||
output_dir.mkdir(parents=True)
|
||||
|
||||
for addon_dir in current_dir.iterdir():
|
||||
if not addon_dir.is_dir():
|
||||
continue
|
||||
|
||||
server_dir = addon_dir / "server"
|
||||
if not server_dir.exists():
|
||||
continue
|
||||
|
||||
if addon_dir.name == "openpype":
|
||||
create_openpype_package(
|
||||
addon_dir, output_dir, root_dir, create_zip, keep_source
|
||||
)
|
||||
|
||||
else:
|
||||
create_addon_package(
|
||||
addon_dir, output_dir, create_zip, keep_source
|
||||
)
|
||||
|
||||
print(f"- package '{addon_dir.name}' created")
|
||||
print(f"Package creation finished. Output directory: {output_dir}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
create_zip = "--skip-zip" not in sys.argv
|
||||
keep_sources = "--keep-sources" in sys.argv
|
||||
main(create_zip, keep_sources)
|
||||
17
server_addon/deadline/server/__init__.py
Normal file
17
server_addon/deadline/server/__init__.py
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
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):
|
||||
settings_model_cls = self.get_settings_model()
|
||||
return settings_model_cls(**DEFAULT_VALUES)
|
||||
10
server_addon/deadline/server/settings/__init__.py
Normal file
10
server_addon/deadline/server/settings/__init__.py
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
from .main import (
|
||||
DeadlineSettings,
|
||||
DEFAULT_VALUES,
|
||||
)
|
||||
|
||||
|
||||
__all__ = (
|
||||
"DeadlineSettings",
|
||||
"DEFAULT_VALUES",
|
||||
)
|
||||
48
server_addon/deadline/server/settings/main.py
Normal file
48
server_addon/deadline/server/settings/main.py
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
from pydantic import Field, validator
|
||||
|
||||
from ayon_server.settings import BaseSettingsModel, ensure_unique_names
|
||||
|
||||
from .publish_plugins import (
|
||||
PublishPluginsModel,
|
||||
DEFAULT_DEADLINE_PLUGINS_SETTINGS
|
||||
)
|
||||
|
||||
|
||||
class ServerListSubmodel(BaseSettingsModel):
|
||||
_layout = "compact"
|
||||
name: str = Field(title="Name")
|
||||
value: str = Field(title="Value")
|
||||
|
||||
|
||||
class DeadlineSettings(BaseSettingsModel):
|
||||
deadline_urls: list[ServerListSubmodel] = Field(
|
||||
default_factory=list,
|
||||
title="System Deadline Webservice URLs",
|
||||
)
|
||||
|
||||
deadline_servers: list[str] = Field(
|
||||
title="Project deadline servers",
|
||||
section="---")
|
||||
|
||||
publish: PublishPluginsModel = Field(
|
||||
default_factory=PublishPluginsModel,
|
||||
title="Publish Plugins",
|
||||
)
|
||||
|
||||
@validator("deadline_urls")
|
||||
def validate_unique_names(cls, value):
|
||||
ensure_unique_names(value)
|
||||
return value
|
||||
|
||||
|
||||
DEFAULT_VALUES = {
|
||||
"deadline_urls": [
|
||||
{
|
||||
"name": "default",
|
||||
"value": "http://127.0.0.1:8082"
|
||||
}
|
||||
],
|
||||
# TODO: this needs to be dynamic from "deadline_urls"
|
||||
"deadline_servers": [],
|
||||
"publish": DEFAULT_DEADLINE_PLUGINS_SETTINGS
|
||||
}
|
||||
435
server_addon/deadline/server/settings/publish_plugins.py
Normal file
435
server_addon/deadline/server/settings/publish_plugins.py
Normal file
|
|
@ -0,0 +1,435 @@
|
|||
from pydantic import Field, validator
|
||||
|
||||
from ayon_server.settings import BaseSettingsModel, ensure_unique_names
|
||||
|
||||
|
||||
class CollectDefaultDeadlineServerModel(BaseSettingsModel):
|
||||
"""Settings for event handlers running in ftrack service."""
|
||||
|
||||
pass_mongo_url: bool = Field(title="Pass Mongo url to job")
|
||||
|
||||
|
||||
class CollectDeadlinePoolsModel(BaseSettingsModel):
|
||||
"""Settings Deadline default pools."""
|
||||
|
||||
primary_pool: str = Field(title="Primary Pool")
|
||||
|
||||
secondary_pool: str = Field(title="Secondary Pool")
|
||||
|
||||
|
||||
class ValidateExpectedFilesModel(BaseSettingsModel):
|
||||
enabled: bool = Field(True, title="Enabled")
|
||||
active: bool = Field(True, title="Active")
|
||||
allow_user_override: bool = Field(
|
||||
True, title="Allow user change frame range"
|
||||
)
|
||||
families: list[str] = Field(
|
||||
default_factory=list, title="Trigger on families"
|
||||
)
|
||||
targets: list[str] = Field(
|
||||
default_factory=list, title="Trigger for plugins"
|
||||
)
|
||||
|
||||
|
||||
def tile_assembler_enum():
|
||||
"""Return a list of value/label dicts for the enumerator.
|
||||
|
||||
Returning a list of dicts is used to allow for a custom label to be
|
||||
displayed in the UI.
|
||||
"""
|
||||
return [
|
||||
{
|
||||
"value": "DraftTileAssembler",
|
||||
"label": "Draft Tile Assembler"
|
||||
},
|
||||
{
|
||||
"value": "OpenPypeTileAssembler",
|
||||
"label": "Open Image IO"
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
class ScenePatchesSubmodel(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
name: str = Field(title="Patch name")
|
||||
regex: str = Field(title="Patch regex")
|
||||
line: str = Field(title="Patch line")
|
||||
|
||||
|
||||
class MayaSubmitDeadlineModel(BaseSettingsModel):
|
||||
"""Maya deadline submitter settings."""
|
||||
|
||||
enabled: bool = Field(title="Enabled")
|
||||
optional: bool = Field(title="Optional")
|
||||
active: bool = Field(title="Active")
|
||||
use_published: bool = Field(title="Use Published scene")
|
||||
import_reference: bool = Field(title="Use Scene with Imported Reference")
|
||||
asset_dependencies: bool = Field(title="Use Asset dependencies")
|
||||
priority: int = Field(title="Priority")
|
||||
tile_priority: int = Field(title="Tile Priority")
|
||||
group: str = Field(title="Group")
|
||||
limit: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Limit Groups"
|
||||
)
|
||||
tile_assembler_plugin: str = Field(
|
||||
title="Tile Assembler Plugin",
|
||||
enum_resolver=tile_assembler_enum,
|
||||
)
|
||||
jobInfo: str = Field(
|
||||
title="Additional JobInfo data",
|
||||
widget="textarea",
|
||||
)
|
||||
pluginInfo: str = Field(
|
||||
title="Additional PluginInfo data",
|
||||
widget="textarea",
|
||||
)
|
||||
|
||||
scene_patches: list[ScenePatchesSubmodel] = Field(
|
||||
default_factory=list,
|
||||
title="Scene patches",
|
||||
)
|
||||
strict_error_checking: bool = Field(
|
||||
title="Disable Strict Error Check profiles"
|
||||
)
|
||||
|
||||
@validator("limit", "scene_patches")
|
||||
def validate_unique_names(cls, value):
|
||||
ensure_unique_names(value)
|
||||
return value
|
||||
|
||||
|
||||
class MaxSubmitDeadlineModel(BaseSettingsModel):
|
||||
enabled: bool = Field(True)
|
||||
optional: bool = Field(title="Optional")
|
||||
active: bool = Field(title="Active")
|
||||
use_published: bool = Field(title="Use Published scene")
|
||||
priority: int = Field(title="Priority")
|
||||
chunk_size: int = Field(title="Frame per Task")
|
||||
group: str = Field("", title="Group Name")
|
||||
|
||||
|
||||
class EnvSearchReplaceSubmodel(BaseSettingsModel):
|
||||
_layout = "compact"
|
||||
name: str = Field(title="Name")
|
||||
value: str = Field(title="Value")
|
||||
|
||||
|
||||
class LimitGroupsSubmodel(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
name: str = Field(title="Name")
|
||||
value: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Limit Groups"
|
||||
)
|
||||
|
||||
|
||||
class FusionSubmitDeadlineModel(BaseSettingsModel):
|
||||
enabled: bool = Field(True, title="Enabled")
|
||||
optional: bool = Field(False, title="Optional")
|
||||
active: bool = Field(True, title="Active")
|
||||
priority: int = Field(50, title="Priority")
|
||||
chunk_size: int = Field(10, title="Frame per Task")
|
||||
concurrent_tasks: int = Field(1, title="Number of concurrent tasks")
|
||||
group: str = Field("", title="Group Name")
|
||||
|
||||
|
||||
class NukeSubmitDeadlineModel(BaseSettingsModel):
|
||||
"""Nuke deadline submitter settings."""
|
||||
|
||||
enabled: bool = Field(title="Enabled")
|
||||
optional: bool = Field(title="Optional")
|
||||
active: bool = Field(title="Active")
|
||||
priority: int = Field(title="Priority")
|
||||
chunk_size: int = Field(title="Chunk Size")
|
||||
concurrent_tasks: int = Field(title="Number of concurrent tasks")
|
||||
group: str = Field(title="Group")
|
||||
department: str = Field(title="Department")
|
||||
use_gpu: bool = Field(title="Use GPU")
|
||||
|
||||
env_allowed_keys: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Allowed environment keys"
|
||||
)
|
||||
|
||||
env_search_replace_values: list[EnvSearchReplaceSubmodel] = Field(
|
||||
default_factory=list,
|
||||
title="Search & replace in environment values",
|
||||
)
|
||||
|
||||
limit_groups: list[LimitGroupsSubmodel] = Field(
|
||||
default_factory=list,
|
||||
title="Limit Groups",
|
||||
)
|
||||
|
||||
@validator("limit_groups", "env_allowed_keys", "env_search_replace_values")
|
||||
def validate_unique_names(cls, value):
|
||||
ensure_unique_names(value)
|
||||
return value
|
||||
|
||||
|
||||
class HarmonySubmitDeadlineModel(BaseSettingsModel):
|
||||
"""Harmony deadline submitter settings."""
|
||||
|
||||
enabled: bool = Field(title="Enabled")
|
||||
optional: bool = Field(title="Optional")
|
||||
active: bool = Field(title="Active")
|
||||
use_published: bool = Field(title="Use Published scene")
|
||||
priority: int = Field(title="Priority")
|
||||
chunk_size: int = Field(title="Chunk Size")
|
||||
group: str = Field(title="Group")
|
||||
department: str = Field(title="Department")
|
||||
|
||||
|
||||
class AfterEffectsSubmitDeadlineModel(BaseSettingsModel):
|
||||
"""After Effects deadline submitter settings."""
|
||||
|
||||
enabled: bool = Field(title="Enabled")
|
||||
optional: bool = Field(title="Optional")
|
||||
active: bool = Field(title="Active")
|
||||
use_published: bool = Field(title="Use Published scene")
|
||||
priority: int = Field(title="Priority")
|
||||
chunk_size: int = Field(title="Chunk Size")
|
||||
group: str = Field(title="Group")
|
||||
department: str = Field(title="Department")
|
||||
multiprocess: bool = Field(title="Optional")
|
||||
|
||||
|
||||
class CelactionSubmitDeadlineModel(BaseSettingsModel):
|
||||
enabled: bool = Field(True, title="Enabled")
|
||||
deadline_department: str = Field("", title="Deadline apartment")
|
||||
deadline_priority: int = Field(50, title="Deadline priority")
|
||||
deadline_pool: str = Field("", title="Deadline pool")
|
||||
deadline_pool_secondary: str = Field("", title="Deadline pool (secondary)")
|
||||
deadline_group: str = Field("", title="Deadline Group")
|
||||
deadline_chunk_size: int = Field(10, title="Deadline Chunk size")
|
||||
deadline_job_delay: str = Field(
|
||||
"", title="Delay job (timecode dd:hh:mm:ss)"
|
||||
)
|
||||
|
||||
|
||||
class AOVFilterSubmodel(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
name: str = Field(title="Host")
|
||||
value: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="AOV regex"
|
||||
)
|
||||
|
||||
|
||||
class ProcessSubmittedJobOnFarmModel(BaseSettingsModel):
|
||||
"""Process submitted job on farm."""
|
||||
|
||||
enabled: bool = Field(title="Enabled")
|
||||
deadline_department: str = Field(title="Department")
|
||||
deadline_pool: str = Field(title="Pool")
|
||||
deadline_group: str = Field(title="Group")
|
||||
deadline_chunk_size: int = Field(title="Chunk Size")
|
||||
deadline_priority: int = Field(title="Priority")
|
||||
publishing_script: str = Field(title="Publishing script path")
|
||||
skip_integration_repre_list: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Skip integration of representation with ext"
|
||||
)
|
||||
aov_filter: list[AOVFilterSubmodel] = Field(
|
||||
default_factory=list,
|
||||
title="Reviewable products filter",
|
||||
)
|
||||
|
||||
@validator("aov_filter", "skip_integration_repre_list")
|
||||
def validate_unique_names(cls, value):
|
||||
ensure_unique_names(value)
|
||||
return value
|
||||
|
||||
|
||||
class PublishPluginsModel(BaseSettingsModel):
|
||||
CollectDefaultDeadlineServer: CollectDefaultDeadlineServerModel = Field(
|
||||
default_factory=CollectDefaultDeadlineServerModel,
|
||||
title="Default Deadline Webservice")
|
||||
CollectDefaultDeadlineServer: CollectDefaultDeadlineServerModel = Field(
|
||||
default_factory=CollectDefaultDeadlineServerModel,
|
||||
title="Default Deadline Webservice")
|
||||
CollectDeadlinePools: CollectDeadlinePoolsModel = Field(
|
||||
default_factory=CollectDeadlinePoolsModel,
|
||||
title="Default Pools")
|
||||
ValidateExpectedFiles: ValidateExpectedFilesModel = Field(
|
||||
default_factory=ValidateExpectedFilesModel,
|
||||
title="Validate Expected Files"
|
||||
)
|
||||
MayaSubmitDeadline: MayaSubmitDeadlineModel = Field(
|
||||
default_factory=MayaSubmitDeadlineModel,
|
||||
title="Maya Submit to deadline")
|
||||
MaxSubmitDeadline: MaxSubmitDeadlineModel = Field(
|
||||
default_factory=MaxSubmitDeadlineModel,
|
||||
title="Max Submit to deadline")
|
||||
FusionSubmitDeadline: FusionSubmitDeadlineModel = Field(
|
||||
default_factory=FusionSubmitDeadlineModel,
|
||||
title="Fusion submit to Deadline")
|
||||
NukeSubmitDeadline: NukeSubmitDeadlineModel = Field(
|
||||
default_factory=NukeSubmitDeadlineModel,
|
||||
title="Nuke Submit to deadline")
|
||||
HarmonySubmitDeadline: HarmonySubmitDeadlineModel = Field(
|
||||
default_factory=HarmonySubmitDeadlineModel,
|
||||
title="Harmony Submit to deadline")
|
||||
AfterEffectsSubmitDeadline: AfterEffectsSubmitDeadlineModel = Field(
|
||||
default_factory=AfterEffectsSubmitDeadlineModel,
|
||||
title="After Effects to deadline")
|
||||
CelactionSubmitDeadline: CelactionSubmitDeadlineModel = Field(
|
||||
default_factory=CelactionSubmitDeadlineModel,
|
||||
title="Celaction Submit Deadline"
|
||||
)
|
||||
ProcessSubmittedJobOnFarm: ProcessSubmittedJobOnFarmModel = Field(
|
||||
default_factory=ProcessSubmittedJobOnFarmModel,
|
||||
title="Process submitted job on farm.")
|
||||
|
||||
|
||||
DEFAULT_DEADLINE_PLUGINS_SETTINGS = {
|
||||
"CollectDefaultDeadlineServer": {
|
||||
"pass_mongo_url": True
|
||||
},
|
||||
"CollectDeadlinePools": {
|
||||
"primary_pool": "",
|
||||
"secondary_pool": ""
|
||||
},
|
||||
"ValidateExpectedFiles": {
|
||||
"enabled": True,
|
||||
"active": True,
|
||||
"allow_user_override": True,
|
||||
"families": [
|
||||
"render"
|
||||
],
|
||||
"targets": [
|
||||
"deadline"
|
||||
]
|
||||
},
|
||||
"MayaSubmitDeadline": {
|
||||
"enabled": True,
|
||||
"optional": False,
|
||||
"active": True,
|
||||
"tile_assembler_plugin": "DraftTileAssembler",
|
||||
"use_published": True,
|
||||
"import_reference": False,
|
||||
"asset_dependencies": True,
|
||||
"strict_error_checking": True,
|
||||
"priority": 50,
|
||||
"tile_priority": 50,
|
||||
"group": "none",
|
||||
"limit": [],
|
||||
# this used to be empty dict
|
||||
"jobInfo": "",
|
||||
# this used to be empty dict
|
||||
"pluginInfo": "",
|
||||
"scene_patches": []
|
||||
},
|
||||
"MaxSubmitDeadline": {
|
||||
"enabled": True,
|
||||
"optional": False,
|
||||
"active": True,
|
||||
"use_published": True,
|
||||
"priority": 50,
|
||||
"chunk_size": 10,
|
||||
"group": "none"
|
||||
},
|
||||
"FusionSubmitDeadline": {
|
||||
"enabled": True,
|
||||
"optional": False,
|
||||
"active": True,
|
||||
"priority": 50,
|
||||
"chunk_size": 10,
|
||||
"concurrent_tasks": 1,
|
||||
"group": ""
|
||||
},
|
||||
"NukeSubmitDeadline": {
|
||||
"enabled": True,
|
||||
"optional": False,
|
||||
"active": True,
|
||||
"priority": 50,
|
||||
"chunk_size": 10,
|
||||
"concurrent_tasks": 1,
|
||||
"group": "",
|
||||
"department": "",
|
||||
"use_gpu": True,
|
||||
"env_allowed_keys": [],
|
||||
"env_search_replace_values": [],
|
||||
"limit_groups": []
|
||||
},
|
||||
"HarmonySubmitDeadline": {
|
||||
"enabled": True,
|
||||
"optional": False,
|
||||
"active": True,
|
||||
"use_published": True,
|
||||
"priority": 50,
|
||||
"chunk_size": 10000,
|
||||
"group": "",
|
||||
"department": ""
|
||||
},
|
||||
"AfterEffectsSubmitDeadline": {
|
||||
"enabled": True,
|
||||
"optional": False,
|
||||
"active": True,
|
||||
"use_published": True,
|
||||
"priority": 50,
|
||||
"chunk_size": 10000,
|
||||
"group": "",
|
||||
"department": "",
|
||||
"multiprocess": True
|
||||
},
|
||||
"CelactionSubmitDeadline": {
|
||||
"enabled": True,
|
||||
"deadline_department": "",
|
||||
"deadline_priority": 50,
|
||||
"deadline_pool": "",
|
||||
"deadline_pool_secondary": "",
|
||||
"deadline_group": "",
|
||||
"deadline_chunk_size": 10,
|
||||
"deadline_job_delay": "00:00:00:00"
|
||||
},
|
||||
"ProcessSubmittedJobOnFarm": {
|
||||
"enabled": True,
|
||||
"deadline_department": "",
|
||||
"deadline_pool": "",
|
||||
"deadline_group": "",
|
||||
"deadline_chunk_size": 1,
|
||||
"deadline_priority": 50,
|
||||
"publishing_script": "",
|
||||
"skip_integration_repre_list": [],
|
||||
"aov_filter": [
|
||||
{
|
||||
"name": "maya",
|
||||
"value": [
|
||||
".*([Bb]eauty).*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "aftereffects",
|
||||
"value": [
|
||||
".*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "celaction",
|
||||
"value": [
|
||||
".*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "harmony",
|
||||
"value": [
|
||||
".*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "max",
|
||||
"value": [
|
||||
".*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "fusion",
|
||||
"value": [
|
||||
".*"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
1
server_addon/deadline/server/version.py
Normal file
1
server_addon/deadline/server/version.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
__version__ = "0.1.0"
|
||||
19
server_addon/flame/server/__init__.py
Normal file
19
server_addon/flame/server/__init__.py
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
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()
|
||||
return settings_model_cls(**DEFAULT_VALUES)
|
||||
10
server_addon/flame/server/settings/__init__.py
Normal file
10
server_addon/flame/server/settings/__init__.py
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
from .main import (
|
||||
FlameSettings,
|
||||
DEFAULT_VALUES,
|
||||
)
|
||||
|
||||
|
||||
__all__ = (
|
||||
"FlameSettings",
|
||||
"DEFAULT_VALUES",
|
||||
)
|
||||
120
server_addon/flame/server/settings/create_plugins.py
Normal file
120
server_addon/flame/server/settings/create_plugins.py
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
from pydantic import Field
|
||||
from ayon_server.settings import BaseSettingsModel
|
||||
|
||||
|
||||
class CreateShotClipModel(BaseSettingsModel):
|
||||
hierarchy: str = Field(
|
||||
"shot",
|
||||
title="Shot parent hierarchy",
|
||||
section="Shot Hierarchy And Rename Settings"
|
||||
)
|
||||
useShotName: bool = Field(
|
||||
True,
|
||||
title="Use Shot Name",
|
||||
)
|
||||
clipRename: bool = Field(
|
||||
False,
|
||||
title="Rename clips",
|
||||
)
|
||||
clipName: str = Field(
|
||||
"{sequence}{shot}",
|
||||
title="Clip name template"
|
||||
)
|
||||
segmentIndex: bool = Field(
|
||||
True,
|
||||
title="Accept segment order"
|
||||
)
|
||||
countFrom: int = Field(
|
||||
10,
|
||||
title="Count sequence from"
|
||||
)
|
||||
countSteps: int = Field(
|
||||
10,
|
||||
title="Stepping number"
|
||||
)
|
||||
|
||||
folder: str = Field(
|
||||
"shots",
|
||||
title="{folder}",
|
||||
section="Shot Template Keywords"
|
||||
)
|
||||
episode: str = Field(
|
||||
"ep01",
|
||||
title="{episode}"
|
||||
)
|
||||
sequence: str = Field(
|
||||
"a",
|
||||
title="{sequence}"
|
||||
)
|
||||
track: str = Field(
|
||||
"{_track_}",
|
||||
title="{track}"
|
||||
)
|
||||
shot: str = Field(
|
||||
"####",
|
||||
title="{shot}"
|
||||
)
|
||||
|
||||
vSyncOn: bool = Field(
|
||||
False,
|
||||
title="Enable Vertical Sync",
|
||||
section="Vertical Synchronization Of Attributes"
|
||||
)
|
||||
|
||||
workfileFrameStart: int = Field(
|
||||
1001,
|
||||
title="Workfiles Start Frame",
|
||||
section="Shot Attributes"
|
||||
)
|
||||
handleStart: int = Field(
|
||||
10,
|
||||
title="Handle start (head)"
|
||||
)
|
||||
handleEnd: int = Field(
|
||||
10,
|
||||
title="Handle end (tail)"
|
||||
)
|
||||
includeHandles: bool = Field(
|
||||
False,
|
||||
title="Enable handles including"
|
||||
)
|
||||
retimedHandles: bool = Field(
|
||||
True,
|
||||
title="Enable retimed handles"
|
||||
)
|
||||
retimedFramerange: bool = Field(
|
||||
True,
|
||||
title="Enable retimed shot frameranges"
|
||||
)
|
||||
|
||||
|
||||
class CreatePuginsModel(BaseSettingsModel):
|
||||
CreateShotClip: CreateShotClipModel = Field(
|
||||
default_factory=CreateShotClipModel,
|
||||
title="Create Shot Clip"
|
||||
)
|
||||
|
||||
|
||||
DEFAULT_CREATE_SETTINGS = {
|
||||
"CreateShotClip": {
|
||||
"hierarchy": "{folder}/{sequence}",
|
||||
"useShotName": True,
|
||||
"clipRename": False,
|
||||
"clipName": "{sequence}{shot}",
|
||||
"segmentIndex": True,
|
||||
"countFrom": 10,
|
||||
"countSteps": 10,
|
||||
"folder": "shots",
|
||||
"episode": "ep01",
|
||||
"sequence": "a",
|
||||
"track": "{_track_}",
|
||||
"shot": "####",
|
||||
"vSyncOn": False,
|
||||
"workfileFrameStart": 1001,
|
||||
"handleStart": 5,
|
||||
"handleEnd": 5,
|
||||
"includeHandles": False,
|
||||
"retimedHandles": True,
|
||||
"retimedFramerange": True
|
||||
}
|
||||
}
|
||||
130
server_addon/flame/server/settings/imageio.py
Normal file
130
server_addon/flame/server/settings/imageio.py
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
from pydantic import Field, validator
|
||||
from ayon_server.settings import BaseSettingsModel, ensure_unique_names
|
||||
|
||||
|
||||
class ImageIOFileRuleModel(BaseSettingsModel):
|
||||
name: str = Field("", title="Rule name")
|
||||
pattern: str = Field("", title="Regex pattern")
|
||||
colorspace: str = Field("", title="Colorspace name")
|
||||
ext: str = Field("", title="File extension")
|
||||
|
||||
|
||||
class ImageIOFileRulesModel(BaseSettingsModel):
|
||||
activate_host_rules: bool = Field(False)
|
||||
rules: list[ImageIOFileRuleModel] = Field(
|
||||
default_factory=list,
|
||||
title="Rules"
|
||||
)
|
||||
|
||||
@validator("rules")
|
||||
def validate_unique_outputs(cls, value):
|
||||
ensure_unique_names(value)
|
||||
return value
|
||||
|
||||
|
||||
class ImageIORemappingRulesModel(BaseSettingsModel):
|
||||
host_native_name: str = Field(
|
||||
title="Application native colorspace name"
|
||||
)
|
||||
ocio_name: str = Field(title="OCIO colorspace name")
|
||||
|
||||
|
||||
class ImageIORemappingModel(BaseSettingsModel):
|
||||
rules: list[ImageIORemappingRulesModel] = Field(
|
||||
default_factory=list
|
||||
)
|
||||
|
||||
|
||||
class ImageIOConfigModel(BaseSettingsModel):
|
||||
override_global_config: bool = Field(
|
||||
False,
|
||||
title="Override global OCIO config"
|
||||
)
|
||||
filepath: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Config path"
|
||||
)
|
||||
|
||||
|
||||
class ProfileNamesMappingInputsModel(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
|
||||
flameName: str = Field("", title="Flame name")
|
||||
ocioName: str = Field("", title="OCIO name")
|
||||
|
||||
|
||||
class ProfileNamesMappingModel(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
|
||||
inputs: list[ProfileNamesMappingInputsModel] = Field(
|
||||
default_factory=list,
|
||||
title="Profile names mapping"
|
||||
)
|
||||
|
||||
|
||||
class ImageIOProjectModel(BaseSettingsModel):
|
||||
colourPolicy: str = Field(
|
||||
"ACES 1.1",
|
||||
title="Colour Policy (name or path)",
|
||||
section="Project"
|
||||
)
|
||||
frameDepth: str = Field(
|
||||
"16-bit fp",
|
||||
title="Image Depth"
|
||||
)
|
||||
fieldDominance: str = Field(
|
||||
"PROGRESSIVE",
|
||||
title="Field Dominance"
|
||||
)
|
||||
|
||||
|
||||
class FlameImageIOModel(BaseSettingsModel):
|
||||
_isGroup = True
|
||||
activate_host_color_management: bool = Field(
|
||||
True, title="Enable Color Management"
|
||||
)
|
||||
remapping: ImageIORemappingModel = Field(
|
||||
title="Remapping colorspace names",
|
||||
default_factory=ImageIORemappingModel
|
||||
)
|
||||
ocio_config: ImageIOConfigModel = Field(
|
||||
default_factory=ImageIOConfigModel,
|
||||
title="OCIO config"
|
||||
)
|
||||
file_rules: ImageIOFileRulesModel = Field(
|
||||
default_factory=ImageIOFileRulesModel,
|
||||
title="File Rules"
|
||||
)
|
||||
# NOTE 'project' attribute was expanded to this model but that caused
|
||||
# inconsistency with v3 settings and harder conversion handling
|
||||
# - it can be moved back but keep in mind that it must be handled in v3
|
||||
# conversion script too
|
||||
project: ImageIOProjectModel = Field(
|
||||
default_factory=ImageIOProjectModel,
|
||||
title="Project"
|
||||
)
|
||||
profilesMapping: ProfileNamesMappingModel = Field(
|
||||
default_factory=ProfileNamesMappingModel,
|
||||
title="Profile names mapping"
|
||||
)
|
||||
|
||||
|
||||
DEFAULT_IMAGEIO_SETTINGS = {
|
||||
"project": {
|
||||
"colourPolicy": "ACES 1.1",
|
||||
"frameDepth": "16-bit fp",
|
||||
"fieldDominance": "PROGRESSIVE"
|
||||
},
|
||||
"profilesMapping": {
|
||||
"inputs": [
|
||||
{
|
||||
"flameName": "ACEScg",
|
||||
"ocioName": "ACES - ACEScg"
|
||||
},
|
||||
{
|
||||
"flameName": "Rec.709 video",
|
||||
"ocioName": "Output - Rec.709"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
99
server_addon/flame/server/settings/loader_plugins.py
Normal file
99
server_addon/flame/server/settings/loader_plugins.py
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
from ayon_server.settings import Field, BaseSettingsModel
|
||||
|
||||
|
||||
class LoadClipModel(BaseSettingsModel):
|
||||
enabled: bool = Field(True)
|
||||
|
||||
product_types: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Product types"
|
||||
)
|
||||
reel_group_name: str = Field(
|
||||
"OpenPype_Reels",
|
||||
title="Reel group name"
|
||||
)
|
||||
reel_name: str = Field(
|
||||
"Loaded",
|
||||
title="Reel name"
|
||||
)
|
||||
|
||||
clip_name_template: str = Field(
|
||||
"{folder[name]}_{product[name]}<_{output}>",
|
||||
title="Clip name template"
|
||||
)
|
||||
layer_rename_template: str = Field("", title="Layer name template")
|
||||
layer_rename_patterns: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Layer rename patters",
|
||||
)
|
||||
|
||||
|
||||
class LoadClipBatchModel(BaseSettingsModel):
|
||||
enabled: bool = Field(True)
|
||||
product_types: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Product types"
|
||||
)
|
||||
reel_name: str = Field(
|
||||
"OP_LoadedReel",
|
||||
title="Reel name"
|
||||
)
|
||||
clip_name_template: str = Field(
|
||||
"{batch}_{folder[name]}_{product[name]}<_{output}>",
|
||||
title="Clip name template"
|
||||
)
|
||||
layer_rename_template: str = Field("", title="Layer name template")
|
||||
layer_rename_patterns: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Layer rename patters",
|
||||
)
|
||||
|
||||
|
||||
class LoaderPluginsModel(BaseSettingsModel):
|
||||
LoadClip: LoadClipModel = Field(
|
||||
default_factory=LoadClipModel,
|
||||
title="Load Clip"
|
||||
)
|
||||
LoadClipBatch: LoadClipBatchModel = Field(
|
||||
default_factory=LoadClipBatchModel,
|
||||
title="Load as clip to current batch"
|
||||
)
|
||||
|
||||
|
||||
DEFAULT_LOADER_SETTINGS = {
|
||||
"LoadClip": {
|
||||
"enabled": True,
|
||||
"product_types": [
|
||||
"render2d",
|
||||
"source",
|
||||
"plate",
|
||||
"render",
|
||||
"review"
|
||||
],
|
||||
"reel_group_name": "OpenPype_Reels",
|
||||
"reel_name": "Loaded",
|
||||
"clip_name_template": "{folder[name]}_{product[name]}<_{output}>",
|
||||
"layer_rename_template": "{folder[name]}_{product[name]}<_{output}>",
|
||||
"layer_rename_patterns": [
|
||||
"rgb",
|
||||
"rgba"
|
||||
]
|
||||
},
|
||||
"LoadClipBatch": {
|
||||
"enabled": True,
|
||||
"product_types": [
|
||||
"render2d",
|
||||
"source",
|
||||
"plate",
|
||||
"render",
|
||||
"review"
|
||||
],
|
||||
"reel_name": "OP_LoadedReel",
|
||||
"clip_name_template": "{batch}_{folder[name]}_{product[name]}<_{output}>",
|
||||
"layer_rename_template": "{folder[name]}_{product[name]}<_{output}>",
|
||||
"layer_rename_patterns": [
|
||||
"rgb",
|
||||
"rgba"
|
||||
]
|
||||
}
|
||||
}
|
||||
33
server_addon/flame/server/settings/main.py
Normal file
33
server_addon/flame/server/settings/main.py
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
from ayon_server.settings import Field, BaseSettingsModel
|
||||
|
||||
from .imageio import FlameImageIOModel, DEFAULT_IMAGEIO_SETTINGS
|
||||
from .create_plugins import CreatePuginsModel, DEFAULT_CREATE_SETTINGS
|
||||
from .publish_plugins import PublishPuginsModel, DEFAULT_PUBLISH_SETTINGS
|
||||
from .loader_plugins import LoaderPluginsModel, DEFAULT_LOADER_SETTINGS
|
||||
|
||||
|
||||
class FlameSettings(BaseSettingsModel):
|
||||
imageio: FlameImageIOModel = Field(
|
||||
default_factory=FlameImageIOModel,
|
||||
title="Color Management (ImageIO)"
|
||||
)
|
||||
create: CreatePuginsModel = Field(
|
||||
default_factory=CreatePuginsModel,
|
||||
title="Create plugins"
|
||||
)
|
||||
publish: PublishPuginsModel = Field(
|
||||
default_factory=PublishPuginsModel,
|
||||
title="Publish plugins"
|
||||
)
|
||||
load: LoaderPluginsModel = Field(
|
||||
default_factory=LoaderPluginsModel,
|
||||
title="Loader plugins"
|
||||
)
|
||||
|
||||
|
||||
DEFAULT_VALUES = {
|
||||
"imageio": DEFAULT_IMAGEIO_SETTINGS,
|
||||
"create": DEFAULT_CREATE_SETTINGS,
|
||||
"publish": DEFAULT_PUBLISH_SETTINGS,
|
||||
"load": DEFAULT_LOADER_SETTINGS
|
||||
}
|
||||
190
server_addon/flame/server/settings/publish_plugins.py
Normal file
190
server_addon/flame/server/settings/publish_plugins.py
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
from ayon_server.settings import Field, BaseSettingsModel, task_types_enum
|
||||
|
||||
|
||||
class XMLPresetAttrsFromCommentsModel(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
name: str = Field("", title="Attribute name")
|
||||
type: str = Field(
|
||||
default_factory=str,
|
||||
title="Attribute type",
|
||||
enum_resolver=lambda: ["number", "float", "string"]
|
||||
)
|
||||
|
||||
|
||||
class AddTasksModel(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
name: str = Field("", title="Task name")
|
||||
type: str = Field(
|
||||
default_factory=str,
|
||||
title="Task type",
|
||||
enum_resolver=task_types_enum
|
||||
)
|
||||
create_batch_group: bool = Field(
|
||||
True,
|
||||
title="Create batch group"
|
||||
)
|
||||
|
||||
|
||||
class CollectTimelineInstancesModel(BaseSettingsModel):
|
||||
_isGroup = True
|
||||
|
||||
xml_preset_attrs_from_comments: list[XMLPresetAttrsFromCommentsModel] = Field(
|
||||
default_factory=list,
|
||||
title="XML presets attributes parsable from segment comments"
|
||||
)
|
||||
add_tasks: list[AddTasksModel] = Field(
|
||||
default_factory=list,
|
||||
title="Add tasks"
|
||||
)
|
||||
|
||||
|
||||
class ExportPresetsMappingModel(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
|
||||
name: str = Field(
|
||||
...,
|
||||
title="Name"
|
||||
)
|
||||
active: bool = Field(True, title="Is active")
|
||||
export_type: str = Field(
|
||||
"File Sequence",
|
||||
title="Eport clip type",
|
||||
enum_resolver=lambda: ["Movie", "File Sequence", "Sequence Publish"]
|
||||
)
|
||||
ext: str = Field("exr", title="Output extension")
|
||||
xml_preset_file: str = Field(
|
||||
"OpenEXR (16-bit fp DWAA).xml",
|
||||
title="XML preset file (with ext)"
|
||||
)
|
||||
colorspace_out: str = Field(
|
||||
"ACES - ACEScg",
|
||||
title="Output color (imageio)"
|
||||
)
|
||||
# TODO remove when resolved or v3 is not a thing anymore
|
||||
# NOTE next 4 attributes were grouped under 'other_parameters' but that
|
||||
# created inconsistency with v3 settings and harder conversion handling
|
||||
# - it can be moved back but keep in mind that it must be handled in v3
|
||||
# conversion script too
|
||||
xml_preset_dir: str = Field(
|
||||
"",
|
||||
title="XML preset directory"
|
||||
)
|
||||
parsed_comment_attrs: bool = Field(
|
||||
True,
|
||||
title="Parsed comment attributes"
|
||||
)
|
||||
representation_add_range: bool = Field(
|
||||
True,
|
||||
title="Add range to representation name"
|
||||
)
|
||||
representation_tags: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Representation tags"
|
||||
)
|
||||
load_to_batch_group: bool = Field(
|
||||
True,
|
||||
title="Load to batch group reel"
|
||||
)
|
||||
batch_group_loader_name: str = Field(
|
||||
"LoadClipBatch",
|
||||
title="Use loader name"
|
||||
)
|
||||
filter_path_regex: str = Field(
|
||||
".*",
|
||||
title="Regex in clip path"
|
||||
)
|
||||
|
||||
|
||||
class ExtractProductResourcesModel(BaseSettingsModel):
|
||||
_isGroup = True
|
||||
|
||||
keep_original_representation: bool = Field(
|
||||
False,
|
||||
title="Publish clip's original media"
|
||||
)
|
||||
export_presets_mapping: list[ExportPresetsMappingModel] = Field(
|
||||
default_factory=list,
|
||||
title="Export presets mapping"
|
||||
)
|
||||
|
||||
|
||||
class IntegrateBatchGroupModel(BaseSettingsModel):
|
||||
enabled: bool = Field(
|
||||
False,
|
||||
title="Enabled"
|
||||
)
|
||||
|
||||
|
||||
class PublishPuginsModel(BaseSettingsModel):
|
||||
CollectTimelineInstances: CollectTimelineInstancesModel = Field(
|
||||
default_factory=CollectTimelineInstancesModel,
|
||||
title="Collect Timeline Instances"
|
||||
)
|
||||
|
||||
ExtractProductResources: ExtractProductResourcesModel = Field(
|
||||
default_factory=ExtractProductResourcesModel,
|
||||
title="Extract Product Resources"
|
||||
)
|
||||
|
||||
IntegrateBatchGroup: IntegrateBatchGroupModel = Field(
|
||||
default_factory=IntegrateBatchGroupModel,
|
||||
title="IntegrateBatchGroup"
|
||||
)
|
||||
|
||||
|
||||
DEFAULT_PUBLISH_SETTINGS = {
|
||||
"CollectTimelineInstances": {
|
||||
"xml_preset_attrs_from_comments": [
|
||||
{
|
||||
"name": "width",
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"name": "height",
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"name": "pixelRatio",
|
||||
"type": "float"
|
||||
},
|
||||
{
|
||||
"name": "resizeType",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "resizeFilter",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"add_tasks": [
|
||||
{
|
||||
"name": "compositing",
|
||||
"type": "Compositing",
|
||||
"create_batch_group": True
|
||||
}
|
||||
]
|
||||
},
|
||||
"ExtractProductResources": {
|
||||
"keep_original_representation": False,
|
||||
"export_presets_mapping": [
|
||||
{
|
||||
"name": "exr16fpdwaa",
|
||||
"active": True,
|
||||
"export_type": "File Sequence",
|
||||
"ext": "exr",
|
||||
"xml_preset_file": "OpenEXR (16-bit fp DWAA).xml",
|
||||
"colorspace_out": "ACES - ACEScg",
|
||||
"xml_preset_dir": "",
|
||||
"parsed_comment_attrs": True,
|
||||
"representation_add_range": True,
|
||||
"representation_tags": [],
|
||||
"load_to_batch_group": True,
|
||||
"batch_group_loader_name": "LoadClipBatch",
|
||||
"filter_path_regex": ".*"
|
||||
}
|
||||
]
|
||||
},
|
||||
"IntegrateBatchGroup": {
|
||||
"enabled": False
|
||||
}
|
||||
}
|
||||
1
server_addon/flame/server/version.py
Normal file
1
server_addon/flame/server/version.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
__version__ = "0.1.0"
|
||||
19
server_addon/fusion/server/__init__.py
Normal file
19
server_addon/fusion/server/__init__.py
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
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()
|
||||
return settings_model_cls(**DEFAULT_VALUES)
|
||||
48
server_addon/fusion/server/imageio.py
Normal file
48
server_addon/fusion/server/imageio.py
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
from pydantic import Field, validator
|
||||
from ayon_server.settings import BaseSettingsModel
|
||||
from ayon_server.settings.validators import ensure_unique_names
|
||||
|
||||
|
||||
class ImageIOConfigModel(BaseSettingsModel):
|
||||
override_global_config: bool = Field(
|
||||
False,
|
||||
title="Override global OCIO config"
|
||||
)
|
||||
filepath: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Config path"
|
||||
)
|
||||
|
||||
|
||||
class ImageIOFileRuleModel(BaseSettingsModel):
|
||||
name: str = Field("", title="Rule name")
|
||||
pattern: str = Field("", title="Regex pattern")
|
||||
colorspace: str = Field("", title="Colorspace name")
|
||||
ext: str = Field("", title="File extension")
|
||||
|
||||
|
||||
class ImageIOFileRulesModel(BaseSettingsModel):
|
||||
activate_host_rules: bool = Field(False)
|
||||
rules: list[ImageIOFileRuleModel] = Field(
|
||||
default_factory=list,
|
||||
title="Rules"
|
||||
)
|
||||
|
||||
@validator("rules")
|
||||
def validate_unique_outputs(cls, value):
|
||||
ensure_unique_names(value)
|
||||
return value
|
||||
|
||||
|
||||
class FusionImageIOModel(BaseSettingsModel):
|
||||
activate_host_color_management: bool = Field(
|
||||
True, title="Enable Color Management"
|
||||
)
|
||||
ocio_config: ImageIOConfigModel = Field(
|
||||
default_factory=ImageIOConfigModel,
|
||||
title="OCIO config"
|
||||
)
|
||||
file_rules: ImageIOFileRulesModel = Field(
|
||||
default_factory=ImageIOFileRulesModel,
|
||||
title="File Rules"
|
||||
)
|
||||
95
server_addon/fusion/server/settings.py
Normal file
95
server_addon/fusion/server/settings.py
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
from pydantic import Field
|
||||
from ayon_server.settings import (
|
||||
BaseSettingsModel,
|
||||
)
|
||||
|
||||
from .imageio import FusionImageIOModel
|
||||
|
||||
|
||||
class CopyFusionSettingsModel(BaseSettingsModel):
|
||||
copy_path: str = Field("", title="Local Fusion profile directory")
|
||||
copy_status: bool = Field(title="Copy profile on first launch")
|
||||
force_sync: bool = Field(title="Resync profile on each launch")
|
||||
|
||||
|
||||
def _create_saver_instance_attributes_enum():
|
||||
return [
|
||||
{
|
||||
"value": "reviewable",
|
||||
"label": "Reviewable"
|
||||
},
|
||||
{
|
||||
"value": "farm_rendering",
|
||||
"label": "Farm rendering"
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
class CreateSaverPluginModel(BaseSettingsModel):
|
||||
_isGroup = True
|
||||
temp_rendering_path_template: str = Field(
|
||||
"", title="Temporary rendering path template"
|
||||
)
|
||||
default_variants: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Default variants"
|
||||
)
|
||||
instance_attributes: list[str] = Field(
|
||||
default_factory=list,
|
||||
enum_resolver=_create_saver_instance_attributes_enum,
|
||||
title="Instance attributes"
|
||||
)
|
||||
|
||||
|
||||
class CreatPluginsModel(BaseSettingsModel):
|
||||
CreateSaver: CreateSaverPluginModel = Field(
|
||||
default_factory=CreateSaverPluginModel,
|
||||
title="Create Saver"
|
||||
)
|
||||
|
||||
|
||||
class FusionSettings(BaseSettingsModel):
|
||||
imageio: FusionImageIOModel = Field(
|
||||
default_factory=FusionImageIOModel,
|
||||
title="Color Management (ImageIO)"
|
||||
)
|
||||
copy_fusion_settings: CopyFusionSettingsModel = Field(
|
||||
default_factory=CopyFusionSettingsModel,
|
||||
title="Local Fusion profile settings"
|
||||
)
|
||||
create: CreatPluginsModel = Field(
|
||||
default_factory=CreatPluginsModel,
|
||||
title="Creator plugins"
|
||||
)
|
||||
|
||||
|
||||
DEFAULT_VALUES = {
|
||||
"imageio": {
|
||||
"ocio_config": {
|
||||
"enabled": False,
|
||||
"filepath": []
|
||||
},
|
||||
"file_rules": {
|
||||
"enabled": False,
|
||||
"rules": []
|
||||
}
|
||||
},
|
||||
"copy_fusion_settings": {
|
||||
"copy_path": "~/.openpype/hosts/fusion/profiles",
|
||||
"copy_status": False,
|
||||
"force_sync": False
|
||||
},
|
||||
"create": {
|
||||
"CreateSaver": {
|
||||
"temp_rendering_path_template": "{workdir}/renders/fusion/{product[name]}/{product[name]}.{frame}.{ext}",
|
||||
"default_variants": [
|
||||
"Main",
|
||||
"Mask"
|
||||
],
|
||||
"instance_attributes": [
|
||||
"reviewable",
|
||||
"farm_rendering"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
1
server_addon/fusion/server/version.py
Normal file
1
server_addon/fusion/server/version.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
__version__ = "0.1.0"
|
||||
202
server_addon/harmony/LICENSE
Normal file
202
server_addon/harmony/LICENSE
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
4
server_addon/harmony/README.md
Normal file
4
server_addon/harmony/README.md
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
ToonBoom Harmony Addon
|
||||
===============
|
||||
|
||||
Integration with ToonBoom Harmony.
|
||||
15
server_addon/harmony/server/__init__.py
Normal file
15
server_addon/harmony/server/__init__.py
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
from ayon_server.addons import BaseServerAddon
|
||||
|
||||
from .settings import HarmonySettings, DEFAULT_HARMONY_SETTING
|
||||
from .version import __version__
|
||||
|
||||
|
||||
class Harmony(BaseServerAddon):
|
||||
name = "harmony"
|
||||
version = __version__
|
||||
|
||||
settings_model = HarmonySettings
|
||||
|
||||
async def get_default_settings(self):
|
||||
settings_model_cls = self.get_settings_model()
|
||||
return settings_model_cls(**DEFAULT_HARMONY_SETTING)
|
||||
10
server_addon/harmony/server/settings/__init__.py
Normal file
10
server_addon/harmony/server/settings/__init__.py
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
from .main import (
|
||||
HarmonySettings,
|
||||
DEFAULT_HARMONY_SETTING,
|
||||
)
|
||||
|
||||
|
||||
__all__ = (
|
||||
"HarmonySettings",
|
||||
"DEFAULT_HARMONY_SETTING",
|
||||
)
|
||||
55
server_addon/harmony/server/settings/imageio.py
Normal file
55
server_addon/harmony/server/settings/imageio.py
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
from pydantic import Field, validator
|
||||
from ayon_server.settings import BaseSettingsModel
|
||||
from ayon_server.settings.validators import ensure_unique_names
|
||||
|
||||
|
||||
class ImageIOConfigModel(BaseSettingsModel):
|
||||
override_global_config: bool = Field(
|
||||
False,
|
||||
title="Override global OCIO config"
|
||||
)
|
||||
filepath: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Config path"
|
||||
)
|
||||
|
||||
|
||||
class ImageIOFileRuleModel(BaseSettingsModel):
|
||||
name: str = Field("", title="Rule name")
|
||||
pattern: str = Field("", title="Regex pattern")
|
||||
colorspace: str = Field("", title="Colorspace name")
|
||||
ext: str = Field("", title="File extension")
|
||||
|
||||
|
||||
class ImageIOFileRulesModel(BaseSettingsModel):
|
||||
activate_host_rules: bool = Field(False)
|
||||
rules: list[ImageIOFileRuleModel] = Field(
|
||||
default_factory=list,
|
||||
title="Rules"
|
||||
)
|
||||
|
||||
@validator("rules")
|
||||
def validate_unique_outputs(cls, value):
|
||||
ensure_unique_names(value)
|
||||
return value
|
||||
|
||||
|
||||
class ImageIORemappingRulesModel(BaseSettingsModel):
|
||||
host_native_name: str = Field(
|
||||
title="Application native colorspace name"
|
||||
)
|
||||
ocio_name: str = Field(title="OCIO colorspace name")
|
||||
|
||||
|
||||
class HarmonyImageIOModel(BaseSettingsModel):
|
||||
activate_host_color_management: bool = Field(
|
||||
True, title="Enable Color Management"
|
||||
)
|
||||
ocio_config: ImageIOConfigModel = Field(
|
||||
default_factory=ImageIOConfigModel,
|
||||
title="OCIO config"
|
||||
)
|
||||
file_rules: ImageIOFileRulesModel = Field(
|
||||
default_factory=ImageIOFileRulesModel,
|
||||
title="File Rules"
|
||||
)
|
||||
20
server_addon/harmony/server/settings/load.py
Normal file
20
server_addon/harmony/server/settings/load.py
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
from pydantic import Field
|
||||
from ayon_server.settings import BaseSettingsModel
|
||||
|
||||
|
||||
class ImageSequenceLoaderModel(BaseSettingsModel):
|
||||
family: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Families"
|
||||
)
|
||||
representations: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Representations"
|
||||
)
|
||||
|
||||
|
||||
class HarmonyLoadModel(BaseSettingsModel):
|
||||
ImageSequenceLoader: ImageSequenceLoaderModel = Field(
|
||||
default_factory=ImageSequenceLoaderModel,
|
||||
title="Load Image Sequence"
|
||||
)
|
||||
68
server_addon/harmony/server/settings/main.py
Normal file
68
server_addon/harmony/server/settings/main.py
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
from pydantic import Field
|
||||
from ayon_server.settings import BaseSettingsModel
|
||||
|
||||
from .imageio import HarmonyImageIOModel
|
||||
from .load import HarmonyLoadModel
|
||||
from .publish_plugins import HarmonyPublishPlugins
|
||||
|
||||
|
||||
class HarmonySettings(BaseSettingsModel):
|
||||
"""Harmony Project Settings."""
|
||||
|
||||
imageio: HarmonyImageIOModel = Field(
|
||||
default_factory=HarmonyImageIOModel,
|
||||
title="OCIO config"
|
||||
)
|
||||
load: HarmonyLoadModel = Field(
|
||||
default_factory=HarmonyLoadModel,
|
||||
title="Loader plugins"
|
||||
)
|
||||
publish: HarmonyPublishPlugins = Field(
|
||||
default_factory=HarmonyPublishPlugins,
|
||||
title="Publish plugins"
|
||||
)
|
||||
|
||||
|
||||
DEFAULT_HARMONY_SETTING = {
|
||||
"load": {
|
||||
"ImageSequenceLoader": {
|
||||
"family": [
|
||||
"shot",
|
||||
"render",
|
||||
"image",
|
||||
"plate",
|
||||
"reference"
|
||||
],
|
||||
"representations": [
|
||||
"jpeg",
|
||||
"png",
|
||||
"jpg"
|
||||
]
|
||||
}
|
||||
},
|
||||
"publish": {
|
||||
"CollectPalettes": {
|
||||
"allowed_tasks": [
|
||||
".*"
|
||||
]
|
||||
},
|
||||
"ValidateAudio": {
|
||||
"enabled": True,
|
||||
"optional": True,
|
||||
"active": True
|
||||
},
|
||||
"ValidateContainers": {
|
||||
"enabled": True,
|
||||
"optional": True,
|
||||
"active": True
|
||||
},
|
||||
"ValidateSceneSettings": {
|
||||
"enabled": True,
|
||||
"optional": True,
|
||||
"active": True,
|
||||
"frame_check_filter": [],
|
||||
"skip_resolution_check": [],
|
||||
"skip_timelines_check": []
|
||||
}
|
||||
}
|
||||
}
|
||||
76
server_addon/harmony/server/settings/publish_plugins.py
Normal file
76
server_addon/harmony/server/settings/publish_plugins.py
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
from pydantic import Field
|
||||
|
||||
from ayon_server.settings import BaseSettingsModel
|
||||
|
||||
|
||||
class CollectPalettesPlugin(BaseSettingsModel):
|
||||
"""Set regular expressions to filter triggering on specific task names. '.*' means on all.""" # noqa
|
||||
|
||||
allowed_tasks: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Allowed tasks"
|
||||
)
|
||||
|
||||
|
||||
class ValidateAudioPlugin(BaseSettingsModel):
|
||||
"""Check if scene contains audio track.""" #
|
||||
_isGroup = True
|
||||
enabled: bool = True
|
||||
optional: bool = Field(False, title="Optional")
|
||||
active: bool = Field(True, title="Active")
|
||||
|
||||
|
||||
class ValidateContainersPlugin(BaseSettingsModel):
|
||||
"""Check if loaded container is scene are latest versions."""
|
||||
_isGroup = True
|
||||
enabled: bool = True
|
||||
optional: bool = Field(False, title="Optional")
|
||||
active: bool = Field(True, title="Active")
|
||||
|
||||
|
||||
class ValidateSceneSettingsPlugin(BaseSettingsModel):
|
||||
"""Validate if FrameStart, FrameEnd and Resolution match shot data in DB.
|
||||
Use regular expressions to limit validations only on particular asset
|
||||
or task names."""
|
||||
_isGroup = True
|
||||
enabled: bool = True
|
||||
optional: bool = Field(False, title="Optional")
|
||||
active: bool = Field(True, title="Active")
|
||||
|
||||
frame_check_filter: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Skip Frame check for Assets with name containing"
|
||||
)
|
||||
|
||||
skip_resolution_check: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Skip Resolution Check for Tasks"
|
||||
)
|
||||
|
||||
skip_timelines_check: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Skip Timeline Check for Tasks"
|
||||
)
|
||||
|
||||
|
||||
class HarmonyPublishPlugins(BaseSettingsModel):
|
||||
|
||||
CollectPalettes: CollectPalettesPlugin = Field(
|
||||
title="Collect Palettes",
|
||||
default_factory=CollectPalettesPlugin,
|
||||
)
|
||||
|
||||
ValidateAudio: ValidateAudioPlugin = Field(
|
||||
title="Validate Audio",
|
||||
default_factory=ValidateAudioPlugin,
|
||||
)
|
||||
|
||||
ValidateContainers: ValidateContainersPlugin = Field(
|
||||
title="Validate Containers",
|
||||
default_factory=ValidateContainersPlugin,
|
||||
)
|
||||
|
||||
ValidateSceneSettings: ValidateSceneSettingsPlugin = Field(
|
||||
title="Validate Scene Settings",
|
||||
default_factory=ValidateSceneSettingsPlugin,
|
||||
)
|
||||
3
server_addon/harmony/server/version.py
Normal file
3
server_addon/harmony/server/version.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Package declaring addon version."""
|
||||
__version__ = "0.1.1"
|
||||
19
server_addon/hiero/server/__init__.py
Normal file
19
server_addon/hiero/server/__init__.py
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
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()
|
||||
return settings_model_cls(**DEFAULT_VALUES)
|
||||
10
server_addon/hiero/server/settings/__init__.py
Normal file
10
server_addon/hiero/server/settings/__init__.py
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
from .main import (
|
||||
HieroSettings,
|
||||
DEFAULT_VALUES,
|
||||
)
|
||||
|
||||
|
||||
__all__ = (
|
||||
"HieroSettings",
|
||||
"DEFAULT_VALUES",
|
||||
)
|
||||
98
server_addon/hiero/server/settings/common.py
Normal file
98
server_addon/hiero/server/settings/common.py
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
from pydantic import Field
|
||||
from ayon_server.settings import BaseSettingsModel
|
||||
from ayon_server.types import (
|
||||
ColorRGBA_float,
|
||||
ColorRGB_uint8
|
||||
)
|
||||
|
||||
|
||||
class Vector2d(BaseSettingsModel):
|
||||
_layout = "compact"
|
||||
|
||||
x: float = Field(1.0, title="X")
|
||||
y: float = Field(1.0, title="Y")
|
||||
|
||||
|
||||
class Vector3d(BaseSettingsModel):
|
||||
_layout = "compact"
|
||||
|
||||
x: float = Field(1.0, title="X")
|
||||
y: float = Field(1.0, title="Y")
|
||||
z: float = Field(1.0, title="Z")
|
||||
|
||||
|
||||
def formatable_knob_type_enum():
|
||||
return [
|
||||
{"value": "text", "label": "Text"},
|
||||
{"value": "number", "label": "Number"},
|
||||
{"value": "decimal_number", "label": "Decimal number"},
|
||||
{"value": "2d_vector", "label": "2D vector"},
|
||||
# "3D vector"
|
||||
]
|
||||
|
||||
|
||||
class Formatable(BaseSettingsModel):
|
||||
_layout = "compact"
|
||||
|
||||
template: str = Field(
|
||||
"",
|
||||
placeholder="""{{key}} or {{key}};{{key}}""",
|
||||
title="Template"
|
||||
)
|
||||
to_type: str = Field(
|
||||
"Text",
|
||||
title="To Knob type",
|
||||
enum_resolver=formatable_knob_type_enum,
|
||||
)
|
||||
|
||||
|
||||
knob_types_enum = [
|
||||
{"value": "text", "label": "Text"},
|
||||
{"value": "formatable", "label": "Formate from template"},
|
||||
{"value": "color_gui", "label": "Color GUI"},
|
||||
{"value": "boolean", "label": "Boolean"},
|
||||
{"value": "number", "label": "Number"},
|
||||
{"value": "decimal_number", "label": "Decimal number"},
|
||||
{"value": "vector_2d", "label": "2D vector"},
|
||||
{"value": "vector_3d", "label": "3D vector"},
|
||||
{"value": "color", "label": "Color"}
|
||||
]
|
||||
|
||||
|
||||
class KnobModel(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
|
||||
type: str = Field(
|
||||
title="Type",
|
||||
description="Switch between different knob types",
|
||||
enum_resolver=lambda: knob_types_enum,
|
||||
conditionalEnum=True
|
||||
)
|
||||
name: str = Field(
|
||||
title="Name",
|
||||
placeholder="Name"
|
||||
)
|
||||
text: str = Field("", title="Value")
|
||||
color_gui: ColorRGB_uint8 = Field(
|
||||
(0, 0, 255),
|
||||
title="RGB Uint8",
|
||||
)
|
||||
boolean: bool = Field(False, title="Value")
|
||||
number: int = Field(0, title="Value")
|
||||
decimal_number: float = Field(0.0, title="Value")
|
||||
vector_2d: Vector2d = Field(
|
||||
default_factory=Vector2d,
|
||||
title="Value"
|
||||
)
|
||||
vector_3d: Vector3d = Field(
|
||||
default_factory=Vector3d,
|
||||
title="Value"
|
||||
)
|
||||
color: ColorRGBA_float = Field(
|
||||
(0.0, 0.0, 1.0, 1.0),
|
||||
title="RGBA Float"
|
||||
)
|
||||
formatable: Formatable = Field(
|
||||
default_factory=Formatable,
|
||||
title="Value"
|
||||
)
|
||||
97
server_addon/hiero/server/settings/create_plugins.py
Normal file
97
server_addon/hiero/server/settings/create_plugins.py
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
from pydantic import Field
|
||||
from ayon_server.settings import BaseSettingsModel
|
||||
|
||||
|
||||
class CreateShotClipModels(BaseSettingsModel):
|
||||
hierarchy: str = Field(
|
||||
"{folder}/{sequence}",
|
||||
title="Shot parent hierarchy",
|
||||
section="Shot Hierarchy And Rename Settings"
|
||||
)
|
||||
clipRename: bool = Field(
|
||||
True,
|
||||
title="Rename clips"
|
||||
)
|
||||
clipName: str = Field(
|
||||
"{track}{sequence}{shot}",
|
||||
title="Clip name template"
|
||||
)
|
||||
countFrom: int = Field(
|
||||
10,
|
||||
title="Count sequence from"
|
||||
)
|
||||
countSteps: int = Field(
|
||||
10,
|
||||
title="Stepping number"
|
||||
)
|
||||
|
||||
folder: str = Field(
|
||||
"shots",
|
||||
title="{folder}",
|
||||
section="Shot Template Keywords"
|
||||
)
|
||||
episode: str = Field(
|
||||
"ep01",
|
||||
title="{episode}"
|
||||
)
|
||||
sequence: str = Field(
|
||||
"sq01",
|
||||
title="{sequence}"
|
||||
)
|
||||
track: str = Field(
|
||||
"{_track_}",
|
||||
title="{track}"
|
||||
)
|
||||
shot: str = Field(
|
||||
"sh###",
|
||||
title="{shot}"
|
||||
)
|
||||
|
||||
vSyncOn: bool = Field(
|
||||
False,
|
||||
title="Enable Vertical Sync",
|
||||
section="Vertical Synchronization Of Attributes"
|
||||
)
|
||||
|
||||
workfileFrameStart: int = Field(
|
||||
1001,
|
||||
title="Workfiles Start Frame",
|
||||
section="Shot Attributes"
|
||||
)
|
||||
handleStart: int = Field(
|
||||
10,
|
||||
title="Handle start (head)"
|
||||
)
|
||||
handleEnd: int = Field(
|
||||
10,
|
||||
title="Handle end (tail)"
|
||||
)
|
||||
|
||||
|
||||
class CreatorPluginsSettings(BaseSettingsModel):
|
||||
CreateShotClip: CreateShotClipModels = Field(
|
||||
default_factory=CreateShotClipModels,
|
||||
title="Create Shot Clip"
|
||||
)
|
||||
|
||||
|
||||
DEFAULT_CREATE_SETTINGS = {
|
||||
"create": {
|
||||
"CreateShotClip": {
|
||||
"hierarchy": "{folder}/{sequence}",
|
||||
"clipRename": True,
|
||||
"clipName": "{track}{sequence}{shot}",
|
||||
"countFrom": 10,
|
||||
"countSteps": 10,
|
||||
"folder": "shots",
|
||||
"episode": "ep01",
|
||||
"sequence": "sq01",
|
||||
"track": "{_track_}",
|
||||
"shot": "sh###",
|
||||
"vSyncOn": False,
|
||||
"workfileFrameStart": 1001,
|
||||
"handleStart": 10,
|
||||
"handleEnd": 10
|
||||
}
|
||||
}
|
||||
}
|
||||
19
server_addon/hiero/server/settings/filters.py
Normal file
19
server_addon/hiero/server/settings/filters.py
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
from pydantic import Field, validator
|
||||
from ayon_server.settings import BaseSettingsModel, ensure_unique_names
|
||||
|
||||
|
||||
class PublishGUIFilterItemModel(BaseSettingsModel):
|
||||
_layout = "compact"
|
||||
name: str = Field(title="Name")
|
||||
value: bool = Field(True, title="Active")
|
||||
|
||||
|
||||
class PublishGUIFiltersModel(BaseSettingsModel):
|
||||
_layout = "compact"
|
||||
name: str = Field(title="Name")
|
||||
value: list[PublishGUIFilterItemModel] = Field(default_factory=list)
|
||||
|
||||
@validator("value")
|
||||
def validate_unique_outputs(cls, value):
|
||||
ensure_unique_names(value)
|
||||
return value
|
||||
169
server_addon/hiero/server/settings/imageio.py
Normal file
169
server_addon/hiero/server/settings/imageio.py
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
from pydantic import Field, validator
|
||||
|
||||
from ayon_server.settings import (
|
||||
BaseSettingsModel,
|
||||
ensure_unique_names,
|
||||
)
|
||||
|
||||
|
||||
def ocio_configs_switcher_enum():
|
||||
return [
|
||||
{"value": "nuke-default", "label": "nuke-default"},
|
||||
{"value": "spi-vfx", "label": "spi-vfx"},
|
||||
{"value": "spi-anim", "label": "spi-anim"},
|
||||
{"value": "aces_0.1.1", "label": "aces_0.1.1"},
|
||||
{"value": "aces_0.7.1", "label": "aces_0.7.1"},
|
||||
{"value": "aces_1.0.1", "label": "aces_1.0.1"},
|
||||
{"value": "aces_1.0.3", "label": "aces_1.0.3"},
|
||||
{"value": "aces_1.1", "label": "aces_1.1"},
|
||||
{"value": "aces_1.2", "label": "aces_1.2"},
|
||||
{"value": "aces_1.3", "label": "aces_1.3"},
|
||||
{"value": "custom", "label": "custom"}
|
||||
]
|
||||
|
||||
|
||||
class WorkfileColorspaceSettings(BaseSettingsModel):
|
||||
"""Hiero workfile colorspace preset. """
|
||||
"""# TODO: enhance settings with host api:
|
||||
we need to add mapping to resolve properly keys.
|
||||
Hiero is excpecting camel case key names,
|
||||
but for better code consistency we are using snake_case:
|
||||
|
||||
ocio_config = ocioConfigName
|
||||
working_space_name = workingSpace
|
||||
int_16_name = sixteenBitLut
|
||||
int_8_name = eightBitLut
|
||||
float_name = floatLut
|
||||
log_name = logLut
|
||||
viewer_name = viewerLut
|
||||
thumbnail_name = thumbnailLut
|
||||
"""
|
||||
|
||||
ocioConfigName: str = Field(
|
||||
title="OpenColorIO Config",
|
||||
description="Switch between OCIO configs",
|
||||
enum_resolver=ocio_configs_switcher_enum,
|
||||
conditionalEnum=True
|
||||
)
|
||||
workingSpace: str = Field(
|
||||
title="Working Space"
|
||||
)
|
||||
viewerLut: str = Field(
|
||||
title="Viewer"
|
||||
)
|
||||
eightBitLut: str = Field(
|
||||
title="8-bit files"
|
||||
)
|
||||
sixteenBitLut: str = Field(
|
||||
title="16-bit files"
|
||||
)
|
||||
logLut: str = Field(
|
||||
title="Log files"
|
||||
)
|
||||
floatLut: str = Field(
|
||||
title="Float files"
|
||||
)
|
||||
thumbnailLut: str = Field(
|
||||
title="Thumnails"
|
||||
)
|
||||
monitorOutLut: str = Field(
|
||||
title="Monitor"
|
||||
)
|
||||
|
||||
|
||||
class ClipColorspaceRulesItems(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
|
||||
regex: str = Field("", title="Regex expression")
|
||||
colorspace: str = Field("", title="Colorspace")
|
||||
|
||||
|
||||
class RegexInputsModel(BaseSettingsModel):
|
||||
inputs: list[ClipColorspaceRulesItems] = Field(
|
||||
default_factory=list,
|
||||
title="Inputs"
|
||||
)
|
||||
|
||||
|
||||
class ImageIOConfigModel(BaseSettingsModel):
|
||||
override_global_config: bool = Field(
|
||||
False,
|
||||
title="Override global OCIO config"
|
||||
)
|
||||
filepath: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Config path"
|
||||
)
|
||||
|
||||
|
||||
class ImageIOFileRuleModel(BaseSettingsModel):
|
||||
name: str = Field("", title="Rule name")
|
||||
pattern: str = Field("", title="Regex pattern")
|
||||
colorspace: str = Field("", title="Colorspace name")
|
||||
ext: str = Field("", title="File extension")
|
||||
|
||||
|
||||
class ImageIOFileRulesModel(BaseSettingsModel):
|
||||
activate_host_rules: bool = Field(False)
|
||||
rules: list[ImageIOFileRuleModel] = Field(
|
||||
default_factory=list,
|
||||
title="Rules"
|
||||
)
|
||||
|
||||
@validator("rules")
|
||||
def validate_unique_outputs(cls, value):
|
||||
ensure_unique_names(value)
|
||||
return value
|
||||
|
||||
|
||||
class ImageIOSettings(BaseSettingsModel):
|
||||
"""Hiero color management project settings. """
|
||||
_isGroup: bool = True
|
||||
activate_host_color_management: bool = Field(
|
||||
True, title="Enable Color Management"
|
||||
)
|
||||
ocio_config: ImageIOConfigModel = Field(
|
||||
default_factory=ImageIOConfigModel,
|
||||
title="OCIO config"
|
||||
)
|
||||
file_rules: ImageIOFileRulesModel = Field(
|
||||
default_factory=ImageIOFileRulesModel,
|
||||
title="File Rules"
|
||||
)
|
||||
workfile: WorkfileColorspaceSettings = Field(
|
||||
default_factory=WorkfileColorspaceSettings,
|
||||
title="Workfile"
|
||||
)
|
||||
"""# TODO: enhance settings with host api:
|
||||
- old settings are using `regexInputs` key but we
|
||||
need to rename to `regex_inputs`
|
||||
- no need for `inputs` middle part. It can stay
|
||||
directly on `regex_inputs`
|
||||
"""
|
||||
regexInputs: RegexInputsModel = Field(
|
||||
default_factory=RegexInputsModel,
|
||||
title="Assign colorspace to clips via rules"
|
||||
)
|
||||
|
||||
|
||||
DEFAULT_IMAGEIO_SETTINGS = {
|
||||
"workfile": {
|
||||
"ocioConfigName": "nuke-default",
|
||||
"workingSpace": "linear",
|
||||
"viewerLut": "sRGB",
|
||||
"eightBitLut": "sRGB",
|
||||
"sixteenBitLut": "sRGB",
|
||||
"logLut": "Cineon",
|
||||
"floatLut": "linear",
|
||||
"thumbnailLut": "sRGB",
|
||||
"monitorOutLut": "sRGB"
|
||||
},
|
||||
"regexInputs": {
|
||||
"inputs": [
|
||||
{
|
||||
"regex": "[^-a-zA-Z0-9](plateRef).*(?=mp4)",
|
||||
"colorspace": "sRGB"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
38
server_addon/hiero/server/settings/loader_plugins.py
Normal file
38
server_addon/hiero/server/settings/loader_plugins.py
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
from pydantic import Field
|
||||
from ayon_server.settings import BaseSettingsModel
|
||||
|
||||
|
||||
class LoadClipModel(BaseSettingsModel):
|
||||
enabled: bool = Field(
|
||||
True,
|
||||
title="Enabled"
|
||||
)
|
||||
product_types: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Product types"
|
||||
)
|
||||
clip_name_template: str = Field(
|
||||
title="Clip name template"
|
||||
)
|
||||
|
||||
|
||||
class LoaderPuginsModel(BaseSettingsModel):
|
||||
LoadClip: LoadClipModel = Field(
|
||||
default_factory=LoadClipModel,
|
||||
title="Load Clip"
|
||||
)
|
||||
|
||||
|
||||
DEFAULT_LOADER_PLUGINS_SETTINGS = {
|
||||
"LoadClip": {
|
||||
"enabled": True,
|
||||
"product_types": [
|
||||
"render2d",
|
||||
"source",
|
||||
"plate",
|
||||
"render",
|
||||
"review"
|
||||
],
|
||||
"clip_name_template": "{folder[name]}_{product[name]}_{representation}"
|
||||
}
|
||||
}
|
||||
64
server_addon/hiero/server/settings/main.py
Normal file
64
server_addon/hiero/server/settings/main.py
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
from pydantic import Field
|
||||
|
||||
from ayon_server.settings import BaseSettingsModel
|
||||
|
||||
from .imageio import (
|
||||
ImageIOSettings,
|
||||
DEFAULT_IMAGEIO_SETTINGS
|
||||
)
|
||||
from .create_plugins import (
|
||||
CreatorPluginsSettings,
|
||||
DEFAULT_CREATE_SETTINGS
|
||||
)
|
||||
from .loader_plugins import (
|
||||
LoaderPuginsModel,
|
||||
DEFAULT_LOADER_PLUGINS_SETTINGS
|
||||
)
|
||||
from .publish_plugins import (
|
||||
PublishPuginsModel,
|
||||
DEFAULT_PUBLISH_PLUGIN_SETTINGS
|
||||
)
|
||||
from .scriptsmenu import (
|
||||
ScriptsmenuSettings,
|
||||
DEFAULT_SCRIPTSMENU_SETTINGS
|
||||
)
|
||||
from .filters import PublishGUIFilterItemModel
|
||||
|
||||
|
||||
class HieroSettings(BaseSettingsModel):
|
||||
"""Nuke addon settings."""
|
||||
|
||||
imageio: ImageIOSettings = Field(
|
||||
default_factory=ImageIOSettings,
|
||||
title="Color Management (imageio)",
|
||||
)
|
||||
|
||||
create: CreatorPluginsSettings = Field(
|
||||
default_factory=CreatorPluginsSettings,
|
||||
title="Creator Plugins",
|
||||
)
|
||||
load: LoaderPuginsModel = Field(
|
||||
default_factory=LoaderPuginsModel,
|
||||
title="Loader plugins"
|
||||
)
|
||||
publish: PublishPuginsModel = Field(
|
||||
default_factory=PublishPuginsModel,
|
||||
title="Publish plugins"
|
||||
)
|
||||
scriptsmenu: ScriptsmenuSettings = Field(
|
||||
default_factory=ScriptsmenuSettings,
|
||||
title="Scripts Menu Definition",
|
||||
)
|
||||
filters: list[PublishGUIFilterItemModel] = Field(
|
||||
default_factory=list
|
||||
)
|
||||
|
||||
|
||||
DEFAULT_VALUES = {
|
||||
"imageio": DEFAULT_IMAGEIO_SETTINGS,
|
||||
"create": DEFAULT_CREATE_SETTINGS,
|
||||
"load": DEFAULT_LOADER_PLUGINS_SETTINGS,
|
||||
"publish": DEFAULT_PUBLISH_PLUGIN_SETTINGS,
|
||||
"scriptsmenu": DEFAULT_SCRIPTSMENU_SETTINGS,
|
||||
"filters": [],
|
||||
}
|
||||
48
server_addon/hiero/server/settings/publish_plugins.py
Normal file
48
server_addon/hiero/server/settings/publish_plugins.py
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
from pydantic import Field
|
||||
from ayon_server.settings import BaseSettingsModel
|
||||
|
||||
|
||||
class CollectInstanceVersionModel(BaseSettingsModel):
|
||||
enabled: bool = Field(
|
||||
True,
|
||||
title="Enabled"
|
||||
)
|
||||
|
||||
|
||||
class ExtractReviewCutUpVideoModel(BaseSettingsModel):
|
||||
enabled: bool = Field(
|
||||
True,
|
||||
title="Enabled"
|
||||
)
|
||||
tags_addition: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Additional tags"
|
||||
)
|
||||
|
||||
|
||||
class PublishPuginsModel(BaseSettingsModel):
|
||||
CollectInstanceVersion: CollectInstanceVersionModel = Field(
|
||||
default_factory=CollectInstanceVersionModel,
|
||||
title="Collect Instance Version"
|
||||
)
|
||||
"""# TODO: enhance settings with host api:
|
||||
Rename class name and plugin name
|
||||
to match title (it makes more sense)
|
||||
"""
|
||||
ExtractReviewCutUpVideo: ExtractReviewCutUpVideoModel = Field(
|
||||
default_factory=ExtractReviewCutUpVideoModel,
|
||||
title="Exctract Review Trim"
|
||||
)
|
||||
|
||||
|
||||
DEFAULT_PUBLISH_PLUGIN_SETTINGS = {
|
||||
"CollectInstanceVersion": {
|
||||
"enabled": False,
|
||||
},
|
||||
"ExtractReviewCutUpVideo": {
|
||||
"enabled": True,
|
||||
"tags_addition": [
|
||||
"review"
|
||||
]
|
||||
}
|
||||
}
|
||||
41
server_addon/hiero/server/settings/scriptsmenu.py
Normal file
41
server_addon/hiero/server/settings/scriptsmenu.py
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
from pydantic import Field
|
||||
from ayon_server.settings import BaseSettingsModel
|
||||
|
||||
|
||||
class ScriptsmenuSubmodel(BaseSettingsModel):
|
||||
"""Item Definition"""
|
||||
_isGroup = True
|
||||
|
||||
type: str = Field(title="Type")
|
||||
command: str = Field(title="Command")
|
||||
sourcetype: str = Field(title="Source Type")
|
||||
title: str = Field(title="Title")
|
||||
tooltip: str = Field(title="Tooltip")
|
||||
|
||||
|
||||
class ScriptsmenuSettings(BaseSettingsModel):
|
||||
"""Nuke script menu project settings."""
|
||||
_isGroup = True
|
||||
|
||||
"""# TODO: enhance settings with host api:
|
||||
- in api rename key `name` to `menu_name`
|
||||
"""
|
||||
name: str = Field(title="Menu name")
|
||||
definition: list[ScriptsmenuSubmodel] = Field(
|
||||
default_factory=list,
|
||||
title="Definition",
|
||||
description="Scriptmenu Items Definition")
|
||||
|
||||
|
||||
DEFAULT_SCRIPTSMENU_SETTINGS = {
|
||||
"name": "OpenPype Tools",
|
||||
"definition": [
|
||||
{
|
||||
"type": "action",
|
||||
"sourcetype": "python",
|
||||
"title": "OpenPype Docs",
|
||||
"command": "import webbrowser;webbrowser.open(url='https://openpype.io/docs/artist_hosts_hiero')",
|
||||
"tooltip": "Open the OpenPype Hiero user doc page"
|
||||
}
|
||||
]
|
||||
}
|
||||
1
server_addon/hiero/server/version.py
Normal file
1
server_addon/hiero/server/version.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
__version__ = "0.1.0"
|
||||
17
server_addon/houdini/server/__init__.py
Normal file
17
server_addon/houdini/server/__init__.py
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
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):
|
||||
settings_model_cls = self.get_settings_model()
|
||||
return settings_model_cls(**DEFAULT_VALUES)
|
||||
10
server_addon/houdini/server/settings/__init__.py
Normal file
10
server_addon/houdini/server/settings/__init__.py
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
from .main import (
|
||||
HoudiniSettings,
|
||||
DEFAULT_VALUES,
|
||||
)
|
||||
|
||||
|
||||
__all__ = (
|
||||
"HoudiniSettings",
|
||||
"DEFAULT_VALUES",
|
||||
)
|
||||
48
server_addon/houdini/server/settings/imageio.py
Normal file
48
server_addon/houdini/server/settings/imageio.py
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
from pydantic import Field, validator
|
||||
from ayon_server.settings import BaseSettingsModel
|
||||
from ayon_server.settings.validators import ensure_unique_names
|
||||
|
||||
|
||||
class ImageIOConfigModel(BaseSettingsModel):
|
||||
override_global_config: bool = Field(
|
||||
False,
|
||||
title="Override global OCIO config"
|
||||
)
|
||||
filepath: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Config path"
|
||||
)
|
||||
|
||||
|
||||
class ImageIOFileRuleModel(BaseSettingsModel):
|
||||
name: str = Field("", title="Rule name")
|
||||
pattern: str = Field("", title="Regex pattern")
|
||||
colorspace: str = Field("", title="Colorspace name")
|
||||
ext: str = Field("", title="File extension")
|
||||
|
||||
|
||||
class ImageIOFileRulesModel(BaseSettingsModel):
|
||||
activate_host_rules: bool = Field(False)
|
||||
rules: list[ImageIOFileRuleModel] = Field(
|
||||
default_factory=list,
|
||||
title="Rules"
|
||||
)
|
||||
|
||||
@validator("rules")
|
||||
def validate_unique_outputs(cls, value):
|
||||
ensure_unique_names(value)
|
||||
return value
|
||||
|
||||
|
||||
class HoudiniImageIOModel(BaseSettingsModel):
|
||||
activate_host_color_management: bool = Field(
|
||||
True, title="Enable Color Management"
|
||||
)
|
||||
ocio_config: ImageIOConfigModel = Field(
|
||||
default_factory=ImageIOConfigModel,
|
||||
title="OCIO config"
|
||||
)
|
||||
file_rules: ImageIOFileRulesModel = Field(
|
||||
default_factory=ImageIOFileRulesModel,
|
||||
title="File Rules"
|
||||
)
|
||||
79
server_addon/houdini/server/settings/main.py
Normal file
79
server_addon/houdini/server/settings/main.py
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
from pydantic import Field
|
||||
from ayon_server.settings import (
|
||||
BaseSettingsModel,
|
||||
MultiplatformPathModel,
|
||||
MultiplatformPathListModel,
|
||||
)
|
||||
|
||||
from .imageio import HoudiniImageIOModel
|
||||
from .publish_plugins import (
|
||||
PublishPluginsModel,
|
||||
CreatePluginsModel,
|
||||
DEFAULT_HOUDINI_PUBLISH_SETTINGS,
|
||||
DEFAULT_HOUDINI_CREATE_SETTINGS
|
||||
)
|
||||
|
||||
|
||||
class ShelfToolsModel(BaseSettingsModel):
|
||||
name: str = Field(title="Name")
|
||||
help: str = Field(title="Help text")
|
||||
script: MultiplatformPathModel = Field(
|
||||
default_factory=MultiplatformPathModel,
|
||||
title="Script Path "
|
||||
)
|
||||
icon: MultiplatformPathModel = Field(
|
||||
default_factory=MultiplatformPathModel,
|
||||
title="Icon Path "
|
||||
)
|
||||
|
||||
|
||||
class ShelfDefinitionModel(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
shelf_name: str = Field(title="Shelf name")
|
||||
tools_list: list[ShelfToolsModel] = Field(
|
||||
default_factory=list,
|
||||
title="Shelf Tools"
|
||||
)
|
||||
|
||||
|
||||
class ShelvesModel(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
shelf_set_name: str = Field(title="Shelfs set name")
|
||||
|
||||
shelf_set_source_path: MultiplatformPathListModel = Field(
|
||||
default_factory=MultiplatformPathListModel,
|
||||
title="Shelf Set Path (optional)"
|
||||
)
|
||||
|
||||
shelf_definition: list[ShelfDefinitionModel] = Field(
|
||||
default_factory=list,
|
||||
title="Shelf Definitions"
|
||||
)
|
||||
|
||||
|
||||
class HoudiniSettings(BaseSettingsModel):
|
||||
imageio: HoudiniImageIOModel = Field(
|
||||
default_factory=HoudiniImageIOModel,
|
||||
title="Color Management (ImageIO)"
|
||||
)
|
||||
shelves: list[ShelvesModel] = Field(
|
||||
default_factory=list,
|
||||
title="Houdini Scripts Shelves",
|
||||
)
|
||||
|
||||
publish: PublishPluginsModel = Field(
|
||||
default_factory=PublishPluginsModel,
|
||||
title="Publish Plugins",
|
||||
)
|
||||
|
||||
create: CreatePluginsModel = Field(
|
||||
default_factory=CreatePluginsModel,
|
||||
title="Creator Plugins",
|
||||
)
|
||||
|
||||
|
||||
DEFAULT_VALUES = {
|
||||
"shelves": [],
|
||||
"create": DEFAULT_HOUDINI_CREATE_SETTINGS,
|
||||
"publish": DEFAULT_HOUDINI_PUBLISH_SETTINGS
|
||||
}
|
||||
150
server_addon/houdini/server/settings/publish_plugins.py
Normal file
150
server_addon/houdini/server/settings/publish_plugins.py
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
from pydantic import Field
|
||||
|
||||
from ayon_server.settings import BaseSettingsModel
|
||||
|
||||
|
||||
# Creator Plugins
|
||||
class CreatorModel(BaseSettingsModel):
|
||||
enabled: bool = Field(title="Enabled")
|
||||
defaults: list[str] = Field(title="Default Products")
|
||||
|
||||
|
||||
class CreateArnoldAssModel(BaseSettingsModel):
|
||||
enabled: bool = Field(title="Enabled")
|
||||
defaults: list[str] = Field(title="Default Products")
|
||||
ext: str = Field(Title="Extension")
|
||||
|
||||
|
||||
class CreatePluginsModel(BaseSettingsModel):
|
||||
CreateArnoldAss: CreateArnoldAssModel = Field(
|
||||
default_factory=CreateArnoldAssModel,
|
||||
title="Create Alembic Camera")
|
||||
CreateAlembicCamera: CreatorModel = Field(
|
||||
default_factory=CreatorModel,
|
||||
title="Create Alembic Camera")
|
||||
CreateCompositeSequence: CreatorModel = Field(
|
||||
default_factory=CreatorModel,
|
||||
title="Create Composite Sequence")
|
||||
CreatePointCache: CreatorModel = Field(
|
||||
default_factory=CreatorModel,
|
||||
title="Create Point Cache")
|
||||
CreateRedshiftROP: CreatorModel = Field(
|
||||
default_factory=CreatorModel,
|
||||
title="Create RedshiftROP")
|
||||
CreateRemotePublish: CreatorModel = Field(
|
||||
default_factory=CreatorModel,
|
||||
title="Create Remote Publish")
|
||||
CreateVDBCache: CreatorModel = Field(
|
||||
default_factory=CreatorModel,
|
||||
title="Create VDB Cache")
|
||||
CreateUSD: CreatorModel = Field(
|
||||
default_factory=CreatorModel,
|
||||
title="Create USD")
|
||||
CreateUSDModel: CreatorModel = Field(
|
||||
default_factory=CreatorModel,
|
||||
title="Create USD model")
|
||||
USDCreateShadingWorkspace: CreatorModel = Field(
|
||||
default_factory=CreatorModel,
|
||||
title="Create USD shading workspace")
|
||||
CreateUSDRender: CreatorModel = Field(
|
||||
default_factory=CreatorModel,
|
||||
title="Create USD render")
|
||||
|
||||
|
||||
DEFAULT_HOUDINI_CREATE_SETTINGS = {
|
||||
"CreateArnoldAss": {
|
||||
"enabled": True,
|
||||
"defaults": [],
|
||||
"ext": ".ass"
|
||||
},
|
||||
"CreateAlembicCamera": {
|
||||
"enabled": True,
|
||||
"defaults": []
|
||||
},
|
||||
"CreateCompositeSequence": {
|
||||
"enabled": True,
|
||||
"defaults": []
|
||||
},
|
||||
"CreatePointCache": {
|
||||
"enabled": True,
|
||||
"defaults": []
|
||||
},
|
||||
"CreateRedshiftROP": {
|
||||
"enabled": True,
|
||||
"defaults": []
|
||||
},
|
||||
"CreateRemotePublish": {
|
||||
"enabled": True,
|
||||
"defaults": []
|
||||
},
|
||||
"CreateVDBCache": {
|
||||
"enabled": True,
|
||||
"defaults": []
|
||||
},
|
||||
"CreateUSD": {
|
||||
"enabled": False,
|
||||
"defaults": []
|
||||
},
|
||||
"CreateUSDModel": {
|
||||
"enabled": False,
|
||||
"defaults": []
|
||||
},
|
||||
"USDCreateShadingWorkspace": {
|
||||
"enabled": False,
|
||||
"defaults": []
|
||||
},
|
||||
"CreateUSDRender": {
|
||||
"enabled": False,
|
||||
"defaults": []
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Publish Plugins
|
||||
class ValidateWorkfilePathsModel(BaseSettingsModel):
|
||||
enabled: bool = Field(title="Enabled")
|
||||
optional: bool = Field(title="Optional")
|
||||
node_types: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Node Types"
|
||||
)
|
||||
prohibited_vars: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Prohibited Variables"
|
||||
)
|
||||
|
||||
|
||||
class ValidateContainersModel(BaseSettingsModel):
|
||||
enabled: bool = Field(title="Enabled")
|
||||
optional: bool = Field(title="Optional")
|
||||
active: bool = Field(title="Active")
|
||||
|
||||
|
||||
class PublishPluginsModel(BaseSettingsModel):
|
||||
ValidateWorkfilePaths: ValidateWorkfilePathsModel = Field(
|
||||
default_factory=ValidateWorkfilePathsModel,
|
||||
title="Validate workfile paths settings.")
|
||||
ValidateContainers: ValidateContainersModel = Field(
|
||||
default_factory=ValidateContainersModel,
|
||||
title="Validate Latest Containers.")
|
||||
|
||||
|
||||
DEFAULT_HOUDINI_PUBLISH_SETTINGS = {
|
||||
"ValidateWorkfilePaths": {
|
||||
"enabled": True,
|
||||
"optional": True,
|
||||
"node_types": [
|
||||
"file",
|
||||
"alembic"
|
||||
],
|
||||
"prohibited_vars": [
|
||||
"$HIP",
|
||||
"$JOB"
|
||||
]
|
||||
},
|
||||
"ValidateContainers": {
|
||||
"enabled": True,
|
||||
"optional": True,
|
||||
"active": True
|
||||
}
|
||||
}
|
||||
1
server_addon/houdini/server/version.py
Normal file
1
server_addon/houdini/server/version.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
__version__ = "0.1.0"
|
||||
19
server_addon/kitsu/server/__init__.py
Normal file
19
server_addon/kitsu/server/__init__.py
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
from typing import Type
|
||||
|
||||
from ayon_server.addons import BaseServerAddon
|
||||
|
||||
from .version import __version__
|
||||
from .settings import KitsuSettings, DEFAULT_VALUES
|
||||
|
||||
|
||||
class KitsuAddon(BaseServerAddon):
|
||||
name = "kitsu"
|
||||
title = "Kitsu"
|
||||
version = __version__
|
||||
settings_model: Type[KitsuSettings] = KitsuSettings
|
||||
frontend_scopes = {}
|
||||
services = {}
|
||||
|
||||
async def get_default_settings(self):
|
||||
settings_model_cls = self.get_settings_model()
|
||||
return settings_model_cls(**DEFAULT_VALUES)
|
||||
111
server_addon/kitsu/server/settings.py
Normal file
111
server_addon/kitsu/server/settings.py
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
from pydantic import Field
|
||||
from ayon_server.settings import BaseSettingsModel
|
||||
|
||||
|
||||
class EntityPattern(BaseSettingsModel):
|
||||
episode: str = Field(title="Episode")
|
||||
sequence: str = Field(title="Sequence")
|
||||
shot: str = Field(title="Shot")
|
||||
|
||||
|
||||
def _status_change_cond_enum():
|
||||
return [
|
||||
{"value": "equal", "label": "Equal"},
|
||||
{"value": "not_equal", "label": "Not equal"}
|
||||
]
|
||||
|
||||
|
||||
class StatusChangeCondition(BaseSettingsModel):
|
||||
condition: str = Field(
|
||||
"equal",
|
||||
enum_resolver=_status_change_cond_enum,
|
||||
title="Condition"
|
||||
)
|
||||
short_name: str = Field("", title="Short name")
|
||||
|
||||
|
||||
class StatusChangeProductTypeRequirementModel(BaseSettingsModel):
|
||||
condition: str = Field(
|
||||
"equal",
|
||||
enum_resolver=_status_change_cond_enum,
|
||||
title="Condition"
|
||||
)
|
||||
product_type: str = Field("", title="Product type")
|
||||
|
||||
|
||||
class StatusChangeConditionsModel(BaseSettingsModel):
|
||||
status_conditions: list[StatusChangeCondition] = Field(
|
||||
default_factory=list,
|
||||
title="Status conditions"
|
||||
)
|
||||
product_type_requirements: list[StatusChangeProductTypeRequirementModel] = Field(
|
||||
default_factory=list,
|
||||
title="Product type requirements")
|
||||
|
||||
|
||||
class CustomCommentTemplateModel(BaseSettingsModel):
|
||||
enabled: bool = Field(True)
|
||||
comment_template: str = Field("", title="Custom comment")
|
||||
|
||||
|
||||
class IntegrateKitsuNotes(BaseSettingsModel):
|
||||
"""Kitsu supports markdown and here you can create a custom comment template.
|
||||
|
||||
You can use data from your publishing instance's data.
|
||||
"""
|
||||
|
||||
set_status_note: bool = Field(title="Set status on note")
|
||||
note_status_shortname: str = Field(title="Note shortname")
|
||||
status_change_conditions: StatusChangeConditionsModel = Field(
|
||||
default_factory=StatusChangeConditionsModel,
|
||||
title="Status change conditions"
|
||||
)
|
||||
custom_comment_template: CustomCommentTemplateModel = Field(
|
||||
default_factory=CustomCommentTemplateModel,
|
||||
title="Custom Comment Template",
|
||||
)
|
||||
|
||||
|
||||
class PublishPlugins(BaseSettingsModel):
|
||||
IntegrateKitsuNote: IntegrateKitsuNotes = Field(
|
||||
default_factory=IntegrateKitsuNotes,
|
||||
title="Integrate Kitsu Note"
|
||||
)
|
||||
|
||||
|
||||
class KitsuSettings(BaseSettingsModel):
|
||||
server: str = Field(
|
||||
"",
|
||||
title="Kitsu Server"
|
||||
)
|
||||
entities_naming_pattern: EntityPattern = Field(
|
||||
default_factory=EntityPattern,
|
||||
title="Entities naming pattern"
|
||||
)
|
||||
publish: PublishPlugins = Field(
|
||||
default_factory=PublishPlugins,
|
||||
title="Publish plugins"
|
||||
)
|
||||
|
||||
|
||||
DEFAULT_VALUES = {
|
||||
"entities_naming_pattern": {
|
||||
"episode": "E##",
|
||||
"sequence": "SQ##",
|
||||
"shot": "SH##"
|
||||
},
|
||||
"publish": {
|
||||
"IntegrateKitsuNote": {
|
||||
"set_status_note": False,
|
||||
"note_status_shortname": "wfa",
|
||||
"status_change_conditions": {
|
||||
"status_conditions": [],
|
||||
"product_type_requirements": []
|
||||
},
|
||||
"custom_comment_template": {
|
||||
"enabled": False,
|
||||
"comment_template": "{comment}\n\n| | |\n|--|--|\n| version| `{version}` |\n| product type | `{product[type]}` |\n| name | `{name}` |"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1
server_addon/kitsu/server/version.py
Normal file
1
server_addon/kitsu/server/version.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
__version__ = "0.1.0"
|
||||
201
server_addon/maya/LICENCE
Normal file
201
server_addon/maya/LICENCE
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
4
server_addon/maya/README.md
Normal file
4
server_addon/maya/README.md
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
Maya Integration Addon
|
||||
======================
|
||||
|
||||
WIP
|
||||
16
server_addon/maya/server/__init__.py
Normal file
16
server_addon/maya/server/__init__.py
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
"""Maya Addon Module"""
|
||||
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):
|
||||
settings_model_cls = self.get_settings_model()
|
||||
return settings_model_cls(**DEFAULT_MAYA_SETTING)
|
||||
0
server_addon/maya/server/settings/__init__.py
Normal file
0
server_addon/maya/server/settings/__init__.py
Normal file
408
server_addon/maya/server/settings/creators.py
Normal file
408
server_addon/maya/server/settings/creators.py
Normal file
|
|
@ -0,0 +1,408 @@
|
|||
from pydantic import Field
|
||||
|
||||
from ayon_server.settings import BaseSettingsModel
|
||||
|
||||
|
||||
class CreateLookModel(BaseSettingsModel):
|
||||
enabled: bool = Field(title="Enabled")
|
||||
make_tx: bool = Field(title="Make tx files")
|
||||
rs_tex: bool = Field(title="Make Redshift texture files")
|
||||
defaults: list[str] = Field(
|
||||
default_factory=["Main"], title="Default Products"
|
||||
)
|
||||
|
||||
|
||||
class BasicCreatorModel(BaseSettingsModel):
|
||||
enabled: bool = Field(title="Enabled")
|
||||
defaults: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Default Products"
|
||||
)
|
||||
|
||||
|
||||
class CreateUnrealStaticMeshModel(BaseSettingsModel):
|
||||
enabled: bool = Field(title="Enabled")
|
||||
defaults: list[str] = Field(
|
||||
default_factory=["", "_Main"],
|
||||
title="Default Products"
|
||||
)
|
||||
static_mesh_prefixes: str = Field("S", title="Static Mesh Prefix")
|
||||
collision_prefixes: list[str] = Field(
|
||||
default_factory=["UBX", "UCP", "USP", "UCX"],
|
||||
title="Collision Prefixes"
|
||||
)
|
||||
|
||||
|
||||
class CreateUnrealSkeletalMeshModel(BaseSettingsModel):
|
||||
enabled: bool = Field(title="Enabled")
|
||||
defaults: list[str] = Field(default_factory=[], title="Default Products")
|
||||
joint_hints: str = Field("jnt_org", title="Joint root hint")
|
||||
|
||||
|
||||
class CreateMultiverseLookModel(BaseSettingsModel):
|
||||
enabled: bool = Field(title="Enabled")
|
||||
publish_mip_map: bool = Field(title="publish_mip_map")
|
||||
|
||||
|
||||
class BasicExportMeshModel(BaseSettingsModel):
|
||||
enabled: bool = Field(title="Enabled")
|
||||
write_color_sets: bool = Field(title="Write Color Sets")
|
||||
write_face_sets: bool = Field(title="Write Face Sets")
|
||||
defaults: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Default Products"
|
||||
)
|
||||
|
||||
|
||||
class CreateAnimationModel(BaseSettingsModel):
|
||||
enabled: bool = Field(title="Enabled")
|
||||
write_color_sets: bool = Field(title="Write Color Sets")
|
||||
write_face_sets: bool = Field(title="Write Face Sets")
|
||||
include_parent_hierarchy: bool = Field(
|
||||
title="Include Parent Hierarchy")
|
||||
include_user_defined_attributes: bool = Field(
|
||||
title="Include User Defined Attributes")
|
||||
defaults: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Default Products"
|
||||
)
|
||||
|
||||
|
||||
class CreatePointCacheModel(BaseSettingsModel):
|
||||
enabled: bool = Field(title="Enabled")
|
||||
write_color_sets: bool = Field(title="Write Color Sets")
|
||||
write_face_sets: bool = Field(title="Write Face Sets")
|
||||
include_user_defined_attributes: bool = Field(
|
||||
title="Include User Defined Attributes"
|
||||
)
|
||||
defaults: list[str] = Field(
|
||||
default_factory=["Main"],
|
||||
title="Default Products"
|
||||
)
|
||||
|
||||
|
||||
class CreateProxyAlembicModel(BaseSettingsModel):
|
||||
enabled: bool = Field(title="Enabled")
|
||||
write_color_sets: bool = Field(title="Write Color Sets")
|
||||
write_face_sets: bool = Field(title="Write Face Sets")
|
||||
defaults: list[str] = Field(
|
||||
default_factory=["Main"],
|
||||
title="Default Products"
|
||||
)
|
||||
|
||||
|
||||
class CreateAssModel(BasicCreatorModel):
|
||||
expandProcedurals: bool = Field(title="Expand Procedurals")
|
||||
motionBlur: bool = Field(title="Motion Blur")
|
||||
motionBlurKeys: int = Field(2, title="Motion Blur Keys")
|
||||
motionBlurLength: float = Field(0.5, title="Motion Blur Length")
|
||||
maskOptions: bool = Field(title="Mask Options")
|
||||
maskCamera: bool = Field(title="Mask Camera")
|
||||
maskLight: bool = Field(title="Mask Light")
|
||||
maskShape: bool = Field(title="Mask Shape")
|
||||
maskShader: bool = Field(title="Mask Shader")
|
||||
maskOverride: bool = Field(title="Mask Override")
|
||||
maskDriver: bool = Field(title="Mask Driver")
|
||||
maskFilter: bool = Field(title="Mask Filter")
|
||||
maskColor_manager: bool = Field(title="Mask Color Manager")
|
||||
maskOperator: bool = Field(title="Mask Operator")
|
||||
|
||||
|
||||
class CreateReviewModel(BasicCreatorModel):
|
||||
useMayaTimeline: bool = Field(title="Use Maya Timeline for Frame Range.")
|
||||
|
||||
|
||||
class CreateVrayProxyModel(BaseSettingsModel):
|
||||
enabled: bool = Field(True)
|
||||
vrmesh: bool = Field(title="VrMesh")
|
||||
alembic: bool = Field(title="Alembic")
|
||||
defaults: list[str] = Field(default_factory=list, title="Default Products")
|
||||
|
||||
|
||||
class CreatorsModel(BaseSettingsModel):
|
||||
CreateLook: CreateLookModel = Field(
|
||||
default_factory=CreateLookModel,
|
||||
title="Create Look"
|
||||
)
|
||||
CreateRender: BasicCreatorModel = Field(
|
||||
default_factory=BasicCreatorModel,
|
||||
title="Create Render"
|
||||
)
|
||||
# "-" is not compatible in the new model
|
||||
CreateUnrealStaticMesh: CreateUnrealStaticMeshModel = Field(
|
||||
default_factory=CreateUnrealStaticMeshModel,
|
||||
title="Create Unreal_Static Mesh"
|
||||
)
|
||||
# "-" is not compatible in the new model
|
||||
CreateUnrealSkeletalMesh: CreateUnrealSkeletalMeshModel = Field(
|
||||
default_factory=CreateUnrealSkeletalMeshModel,
|
||||
title="Create Unreal_Skeletal Mesh"
|
||||
)
|
||||
CreateMultiverseLook: CreateMultiverseLookModel = Field(
|
||||
default_factory=CreateMultiverseLookModel,
|
||||
title="Create Multiverse Look"
|
||||
)
|
||||
CreateAnimation: CreateAnimationModel = Field(
|
||||
default_factory=CreateAnimationModel,
|
||||
title="Create Animation"
|
||||
)
|
||||
CreateModel: BasicExportMeshModel = Field(
|
||||
default_factory=BasicExportMeshModel,
|
||||
title="Create Model"
|
||||
)
|
||||
CreatePointCache: CreatePointCacheModel = Field(
|
||||
default_factory=CreatePointCacheModel,
|
||||
title="Create Point Cache"
|
||||
)
|
||||
CreateProxyAlembic: CreateProxyAlembicModel = Field(
|
||||
default_factory=CreateProxyAlembicModel,
|
||||
title="Create Proxy Alembic"
|
||||
)
|
||||
CreateMultiverseUsd: BasicCreatorModel = Field(
|
||||
default_factory=BasicCreatorModel,
|
||||
title="Create Multiverse USD"
|
||||
)
|
||||
CreateMultiverseUsdComp: BasicCreatorModel = Field(
|
||||
default_factory=BasicCreatorModel,
|
||||
title="Create Multiverse USD Composition"
|
||||
)
|
||||
CreateMultiverseUsdOver: BasicCreatorModel = Field(
|
||||
default_factory=BasicCreatorModel,
|
||||
title="Create Multiverse USD Override"
|
||||
)
|
||||
CreateAss: CreateAssModel = Field(
|
||||
default_factory=CreateAssModel,
|
||||
title="Create Ass"
|
||||
)
|
||||
CreateAssembly: BasicCreatorModel = Field(
|
||||
default_factory=BasicCreatorModel,
|
||||
title="Create Assembly"
|
||||
)
|
||||
CreateCamera: BasicCreatorModel = Field(
|
||||
default_factory=BasicCreatorModel,
|
||||
title="Create Camera"
|
||||
)
|
||||
CreateLayout: BasicCreatorModel = Field(
|
||||
default_factory=BasicCreatorModel,
|
||||
title="Create Layout"
|
||||
)
|
||||
CreateMayaScene: BasicCreatorModel = Field(
|
||||
default_factory=BasicCreatorModel,
|
||||
title="Create Maya Scene"
|
||||
)
|
||||
CreateRenderSetup: BasicCreatorModel = Field(
|
||||
default_factory=BasicCreatorModel,
|
||||
title="Create Render Setup"
|
||||
)
|
||||
CreateReview: CreateReviewModel = Field(
|
||||
default_factory=CreateReviewModel,
|
||||
title="Create Review"
|
||||
)
|
||||
CreateRig: BasicCreatorModel = Field(
|
||||
default_factory=BasicCreatorModel,
|
||||
title="Create Rig"
|
||||
)
|
||||
CreateSetDress: BasicCreatorModel = Field(
|
||||
default_factory=BasicCreatorModel,
|
||||
title="Create Set Dress"
|
||||
)
|
||||
CreateVrayProxy: CreateVrayProxyModel = Field(
|
||||
default_factory=CreateVrayProxyModel,
|
||||
title="Create VRay Proxy"
|
||||
)
|
||||
CreateVRayScene: BasicCreatorModel = Field(
|
||||
default_factory=BasicCreatorModel,
|
||||
title="Create VRay Scene"
|
||||
)
|
||||
CreateYetiRig: BasicCreatorModel = Field(
|
||||
default_factory=BasicCreatorModel,
|
||||
title="Create Yeti Rig"
|
||||
)
|
||||
|
||||
|
||||
DEFAULT_CREATORS_SETTINGS = {
|
||||
"CreateLook": {
|
||||
"enabled": True,
|
||||
"make_tx": True,
|
||||
"rs_tex": False,
|
||||
"defaults": [
|
||||
"Main"
|
||||
]
|
||||
},
|
||||
"CreateRender": {
|
||||
"enabled": True,
|
||||
"defaults": [
|
||||
"Main"
|
||||
]
|
||||
},
|
||||
"CreateUnrealStaticMesh": {
|
||||
"enabled": True,
|
||||
"defaults": [
|
||||
"",
|
||||
"_Main"
|
||||
],
|
||||
"static_mesh_prefix": "S",
|
||||
"collision_prefixes": [
|
||||
"UBX",
|
||||
"UCP",
|
||||
"USP",
|
||||
"UCX"
|
||||
]
|
||||
},
|
||||
"CreateUnrealSkeletalMesh": {
|
||||
"enabled": True,
|
||||
"defaults": [],
|
||||
"joint_hints": "jnt_org"
|
||||
},
|
||||
"CreateMultiverseLook": {
|
||||
"enabled": True,
|
||||
"publish_mip_map": True
|
||||
},
|
||||
"CreateAnimation": {
|
||||
"enabled": False,
|
||||
"write_color_sets": False,
|
||||
"write_face_sets": False,
|
||||
"include_parent_hierarchy": False,
|
||||
"include_user_defined_attributes": False,
|
||||
"defaults": [
|
||||
"Main"
|
||||
]
|
||||
},
|
||||
"CreateModel": {
|
||||
"enabled": True,
|
||||
"write_color_sets": False,
|
||||
"write_face_sets": False,
|
||||
"defaults": [
|
||||
"Main",
|
||||
"Proxy",
|
||||
"Sculpt"
|
||||
]
|
||||
},
|
||||
"CreatePointCache": {
|
||||
"enabled": True,
|
||||
"write_color_sets": False,
|
||||
"write_face_sets": False,
|
||||
"include_user_defined_attributes": False,
|
||||
"defaults": [
|
||||
"Main"
|
||||
]
|
||||
},
|
||||
"CreateProxyAlembic": {
|
||||
"enabled": True,
|
||||
"write_color_sets": False,
|
||||
"write_face_sets": False,
|
||||
"defaults": [
|
||||
"Main"
|
||||
]
|
||||
},
|
||||
"CreateMultiverseUsd": {
|
||||
"enabled": True,
|
||||
"defaults": [
|
||||
"Main"
|
||||
]
|
||||
},
|
||||
"CreateMultiverseUsdComp": {
|
||||
"enabled": True,
|
||||
"defaults": [
|
||||
"Main"
|
||||
]
|
||||
},
|
||||
"CreateMultiverseUsdOver": {
|
||||
"enabled": True,
|
||||
"defaults": [
|
||||
"Main"
|
||||
]
|
||||
},
|
||||
"CreateAss": {
|
||||
"enabled": True,
|
||||
"defaults": [
|
||||
"Main"
|
||||
],
|
||||
"expandProcedurals": False,
|
||||
"motionBlur": True,
|
||||
"motionBlurKeys": 2,
|
||||
"motionBlurLength": 0.5,
|
||||
"maskOptions": False,
|
||||
"maskCamera": False,
|
||||
"maskLight": False,
|
||||
"maskShape": False,
|
||||
"maskShader": False,
|
||||
"maskOverride": False,
|
||||
"maskDriver": False,
|
||||
"maskFilter": False,
|
||||
"maskColor_manager": False,
|
||||
"maskOperator": False
|
||||
},
|
||||
"CreateAssembly": {
|
||||
"enabled": True,
|
||||
"defaults": [
|
||||
"Main"
|
||||
]
|
||||
},
|
||||
"CreateCamera": {
|
||||
"enabled": True,
|
||||
"defaults": [
|
||||
"Main"
|
||||
]
|
||||
},
|
||||
"CreateLayout": {
|
||||
"enabled": True,
|
||||
"defaults": [
|
||||
"Main"
|
||||
]
|
||||
},
|
||||
"CreateMayaScene": {
|
||||
"enabled": True,
|
||||
"defaults": [
|
||||
"Main"
|
||||
]
|
||||
},
|
||||
"CreateRenderSetup": {
|
||||
"enabled": True,
|
||||
"defaults": [
|
||||
"Main"
|
||||
]
|
||||
},
|
||||
"CreateReview": {
|
||||
"enabled": True,
|
||||
"defaults": [
|
||||
"Main"
|
||||
],
|
||||
"useMayaTimeline": True
|
||||
},
|
||||
"CreateRig": {
|
||||
"enabled": True,
|
||||
"defaults": [
|
||||
"Main",
|
||||
"Sim",
|
||||
"Cloth"
|
||||
]
|
||||
},
|
||||
"CreateSetDress": {
|
||||
"enabled": True,
|
||||
"defaults": [
|
||||
"Main",
|
||||
"Anim"
|
||||
]
|
||||
},
|
||||
"CreateVrayProxy": {
|
||||
"enabled": True,
|
||||
"vrmesh": True,
|
||||
"alembic": True,
|
||||
"defaults": [
|
||||
"Main"
|
||||
]
|
||||
},
|
||||
"CreateVRayScene": {
|
||||
"enabled": True,
|
||||
"defaults": [
|
||||
"Main"
|
||||
]
|
||||
},
|
||||
"CreateYetiRig": {
|
||||
"enabled": True,
|
||||
"defaults": [
|
||||
"Main"
|
||||
]
|
||||
}
|
||||
}
|
||||
429
server_addon/maya/server/settings/explicit_plugins_loading.py
Normal file
429
server_addon/maya/server/settings/explicit_plugins_loading.py
Normal file
|
|
@ -0,0 +1,429 @@
|
|||
from pydantic import Field
|
||||
|
||||
from ayon_server.settings import BaseSettingsModel
|
||||
|
||||
|
||||
class PluginsModel(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
enabled: bool = Field(title="Enabled")
|
||||
name: str = Field("", title="Name")
|
||||
|
||||
|
||||
class ExplicitPluginsLoadingModel(BaseSettingsModel):
|
||||
"""Maya Explicit Plugins Loading."""
|
||||
_isGroup: bool = True
|
||||
enabled: bool = Field(title="enabled")
|
||||
plugins_to_load: list[PluginsModel] = Field(
|
||||
default_factory=list, title="Plugins To Load"
|
||||
)
|
||||
|
||||
|
||||
DEFAULT_EXPLITCIT_PLUGINS_LOADING_SETTINGS = {
|
||||
"enabled": False,
|
||||
"plugins_to_load": [
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "AbcBullet"
|
||||
},
|
||||
{
|
||||
"enabled": True,
|
||||
"name": "AbcExport"
|
||||
},
|
||||
{
|
||||
"enabled": True,
|
||||
"name": "AbcImport"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "animImportExport"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "ArubaTessellator"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "ATFPlugin"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "atomImportExport"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "AutodeskPacketFile"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "autoLoader"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "bifmeshio"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "bifrostGraph"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "bifrostshellnode"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "bifrostvisplugin"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "blast2Cmd"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "bluePencil"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "Boss"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "bullet"
|
||||
},
|
||||
{
|
||||
"enabled": True,
|
||||
"name": "cacheEvaluator"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "cgfxShader"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "cleanPerFaceAssignment"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "clearcoat"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "convertToComponentTags"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "curveWarp"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "ddsFloatReader"
|
||||
},
|
||||
{
|
||||
"enabled": True,
|
||||
"name": "deformerEvaluator"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "dgProfiler"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "drawUfe"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "dx11Shader"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "fbxmaya"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "fltTranslator"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "freeze"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "Fur"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "gameFbxExporter"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "gameInputDevice"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "GamePipeline"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "gameVertexCount"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "geometryReport"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "geometryTools"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "glslShader"
|
||||
},
|
||||
{
|
||||
"enabled": True,
|
||||
"name": "GPUBuiltInDeformer"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "gpuCache"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "hairPhysicalShader"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "ik2Bsolver"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "ikSpringSolver"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "invertShape"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "lges"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "lookdevKit"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "MASH"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "matrixNodes"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "mayaCharacterization"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "mayaHIK"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "MayaMuscle"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "mayaUsdPlugin"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "mayaVnnPlugin"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "melProfiler"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "meshReorder"
|
||||
},
|
||||
{
|
||||
"enabled": True,
|
||||
"name": "modelingToolkit"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "mtoa"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "mtoh"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "nearestPointOnMesh"
|
||||
},
|
||||
{
|
||||
"enabled": True,
|
||||
"name": "objExport"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "OneClick"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "OpenEXRLoader"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "pgYetiMaya"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "pgyetiVrayMaya"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "polyBoolean"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "poseInterpolator"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "quatNodes"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "randomizerDevice"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "redshift4maya"
|
||||
},
|
||||
{
|
||||
"enabled": True,
|
||||
"name": "renderSetup"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "retargeterNodes"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "RokokoMotionLibrary"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "rotateHelper"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "sceneAssembly"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "shaderFXPlugin"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "shotCamera"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "snapTransform"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "stage"
|
||||
},
|
||||
{
|
||||
"enabled": True,
|
||||
"name": "stereoCamera"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "stlTranslator"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "studioImport"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "Substance"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "substancelink"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "substancemaya"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "substanceworkflow"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "svgFileTranslator"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "sweep"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "testify"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "tiffFloatReader"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "timeSliderBookmark"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "Turtle"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "Type"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "udpDevice"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "ufeSupport"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "Unfold3D"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "VectorRender"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "vrayformaya"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "vrayvolumegrid"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "xgenToolkit"
|
||||
},
|
||||
{
|
||||
"enabled": False,
|
||||
"name": "xgenVray"
|
||||
}
|
||||
]
|
||||
}
|
||||
126
server_addon/maya/server/settings/imageio.py
Normal file
126
server_addon/maya/server/settings/imageio.py
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
"""Providing models and setting values for image IO in Maya.
|
||||
|
||||
Note: Names were changed to get rid of the versions in class names.
|
||||
"""
|
||||
from pydantic import Field, validator
|
||||
|
||||
from ayon_server.settings import BaseSettingsModel, ensure_unique_names
|
||||
|
||||
|
||||
class ImageIOConfigModel(BaseSettingsModel):
|
||||
override_global_config: bool = Field(
|
||||
False,
|
||||
title="Override global OCIO config"
|
||||
)
|
||||
filepath: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Config path"
|
||||
)
|
||||
|
||||
|
||||
class ImageIOFileRuleModel(BaseSettingsModel):
|
||||
name: str = Field("", title="Rule name")
|
||||
pattern: str = Field("", title="Regex pattern")
|
||||
colorspace: str = Field("", title="Colorspace name")
|
||||
ext: str = Field("", title="File extension")
|
||||
|
||||
|
||||
class ImageIOFileRulesModel(BaseSettingsModel):
|
||||
activate_host_rules: bool = Field(False)
|
||||
rules: list[ImageIOFileRuleModel] = Field(
|
||||
default_factory=list,
|
||||
title="Rules"
|
||||
)
|
||||
|
||||
@validator("rules")
|
||||
def validate_unique_outputs(cls, value):
|
||||
ensure_unique_names(value)
|
||||
return value
|
||||
|
||||
|
||||
class ColorManagementPreferenceV2Model(BaseSettingsModel):
|
||||
"""Color Management Preference v2 (Maya 2022+)."""
|
||||
_layout = "expanded"
|
||||
|
||||
enabled: bool = Field(True, title="Use Color Management Preference v2")
|
||||
|
||||
renderSpace: str = Field(title="Rendering Space")
|
||||
displayName: str = Field(title="Display")
|
||||
viewName: str = Field(title="View")
|
||||
|
||||
|
||||
class ColorManagementPreferenceModel(BaseSettingsModel):
|
||||
"""Color Management Preference (legacy)."""
|
||||
_layout = "expanded"
|
||||
|
||||
renderSpace: str = Field(title="Rendering Space")
|
||||
viewTransform: str = Field(title="Viewer Transform ")
|
||||
|
||||
|
||||
class WorkfileImageIOModel(BaseSettingsModel):
|
||||
enabled: bool = Field(True, title="Enabled")
|
||||
renderSpace: str = Field(title="Rendering Space")
|
||||
displayName: str = Field(title="Display")
|
||||
viewName: str = Field(title="View")
|
||||
|
||||
|
||||
class ImageIOSettings(BaseSettingsModel):
|
||||
"""Maya color management project settings.
|
||||
|
||||
Todo: What to do with color management preferences version?
|
||||
"""
|
||||
|
||||
_isGroup: bool = True
|
||||
activate_host_color_management: bool = Field(
|
||||
True, title="Enable Color Management"
|
||||
)
|
||||
ocio_config: ImageIOConfigModel = Field(
|
||||
default_factory=ImageIOConfigModel,
|
||||
title="OCIO config"
|
||||
)
|
||||
file_rules: ImageIOFileRulesModel = Field(
|
||||
default_factory=ImageIOFileRulesModel,
|
||||
title="File Rules"
|
||||
)
|
||||
workfile: WorkfileImageIOModel = Field(
|
||||
default_factory=WorkfileImageIOModel,
|
||||
title="Workfile"
|
||||
)
|
||||
# Deprecated
|
||||
colorManagementPreference_v2: ColorManagementPreferenceV2Model = Field(
|
||||
default_factory=ColorManagementPreferenceV2Model,
|
||||
title="Color Management Preference v2 (Maya 2022+)"
|
||||
)
|
||||
colorManagementPreference: ColorManagementPreferenceModel = Field(
|
||||
default_factory=ColorManagementPreferenceModel,
|
||||
title="Color Management Preference (legacy)"
|
||||
)
|
||||
|
||||
|
||||
DEFAULT_IMAGEIO_SETTINGS = {
|
||||
"activate_host_color_management": True,
|
||||
"ocio_config": {
|
||||
"override_global_config": False,
|
||||
"filepath": []
|
||||
},
|
||||
"file_rules": {
|
||||
"activate_host_rules": False,
|
||||
"rules": []
|
||||
},
|
||||
"workfile": {
|
||||
"enabled": False,
|
||||
"renderSpace": "ACES - ACEScg",
|
||||
"displayName": "ACES",
|
||||
"viewName": "sRGB"
|
||||
},
|
||||
"colorManagementPreference_v2": {
|
||||
"enabled": True,
|
||||
"renderSpace": "ACEScg",
|
||||
"displayName": "sRGB",
|
||||
"viewName": "ACES 1.0 SDR-video"
|
||||
},
|
||||
"colorManagementPreference": {
|
||||
"renderSpace": "scene-linear Rec 709/sRGB",
|
||||
"viewTransform": "sRGB gamma"
|
||||
}
|
||||
}
|
||||
30
server_addon/maya/server/settings/include_handles.py
Normal file
30
server_addon/maya/server/settings/include_handles.py
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
from pydantic import Field
|
||||
|
||||
from ayon_server.settings import BaseSettingsModel, task_types_enum
|
||||
|
||||
|
||||
class IncludeByTaskTypeModel(BaseSettingsModel):
|
||||
task_type: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Task types",
|
||||
enum_resolver=task_types_enum
|
||||
)
|
||||
include_handles: bool = Field(True, title="Include handles")
|
||||
|
||||
|
||||
class IncludeHandlesModel(BaseSettingsModel):
|
||||
"""Maya dirmap settings."""
|
||||
# _layout = "expanded"
|
||||
include_handles_default: bool = Field(
|
||||
True, title="Include handles by default"
|
||||
)
|
||||
per_task_type: list[IncludeByTaskTypeModel] = Field(
|
||||
default_factory=list,
|
||||
title="Include/exclude handles by task type"
|
||||
)
|
||||
|
||||
|
||||
DEFAULT_INCLUDE_HANDLES = {
|
||||
"include_handles_default": False,
|
||||
"per_task_type": []
|
||||
}
|
||||
115
server_addon/maya/server/settings/loaders.py
Normal file
115
server_addon/maya/server/settings/loaders.py
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
from pydantic import Field
|
||||
|
||||
from ayon_server.settings import BaseSettingsModel
|
||||
from ayon_server.types import ColorRGBA_uint8
|
||||
|
||||
|
||||
class ColorsSetting(BaseSettingsModel):
|
||||
model: ColorRGBA_uint8 = Field(
|
||||
(209, 132, 30, 1.0), title="Model:")
|
||||
rig: ColorRGBA_uint8 = Field(
|
||||
(59, 226, 235, 1.0), title="Rig:")
|
||||
pointcache: ColorRGBA_uint8 = Field(
|
||||
(94, 209, 30, 1.0), title="Pointcache:")
|
||||
animation: ColorRGBA_uint8 = Field(
|
||||
(94, 209, 30, 1.0), title="Animation:")
|
||||
ass: ColorRGBA_uint8 = Field(
|
||||
(249, 135, 53, 1.0), title="Arnold StandIn:")
|
||||
camera: ColorRGBA_uint8 = Field(
|
||||
(136, 114, 244, 1.0), title="Camera:")
|
||||
fbx: ColorRGBA_uint8 = Field(
|
||||
(215, 166, 255, 1.0), title="FBX:")
|
||||
mayaAscii: ColorRGBA_uint8 = Field(
|
||||
(67, 174, 255, 1.0), title="Maya Ascii:")
|
||||
mayaScene: ColorRGBA_uint8 = Field(
|
||||
(67, 174, 255, 1.0), title="Maya Scene:")
|
||||
setdress: ColorRGBA_uint8 = Field(
|
||||
(255, 250, 90, 1.0), title="Set Dress:")
|
||||
layout: ColorRGBA_uint8 = Field((
|
||||
255, 250, 90, 1.0), title="Layout:")
|
||||
vdbcache: ColorRGBA_uint8 = Field(
|
||||
(249, 54, 0, 1.0), title="VDB Cache:")
|
||||
vrayproxy: ColorRGBA_uint8 = Field(
|
||||
(255, 150, 12, 1.0), title="VRay Proxy:")
|
||||
vrayscene_layer: ColorRGBA_uint8 = Field(
|
||||
(255, 150, 12, 1.0), title="VRay Scene:")
|
||||
yeticache: ColorRGBA_uint8 = Field(
|
||||
(99, 206, 220, 1.0), title="Yeti Cache:")
|
||||
yetiRig: ColorRGBA_uint8 = Field(
|
||||
(0, 205, 125, 1.0), title="Yeti Rig:")
|
||||
|
||||
|
||||
class ReferenceLoaderModel(BaseSettingsModel):
|
||||
namespace: str = Field(title="Namespace")
|
||||
group_name: str = Field(title="Group name")
|
||||
display_handle: bool = Field(title="Display Handle On Load References")
|
||||
|
||||
|
||||
class LoadersModel(BaseSettingsModel):
|
||||
colors: ColorsSetting = Field(
|
||||
default_factory=ColorsSetting,
|
||||
title="Loaded Products Outliner Colors")
|
||||
|
||||
reference_loader: ReferenceLoaderModel = Field(
|
||||
default_factory=ReferenceLoaderModel,
|
||||
title="Reference Loader"
|
||||
)
|
||||
|
||||
|
||||
DEFAULT_LOADERS_SETTING = {
|
||||
"colors": {
|
||||
"model": [
|
||||
209, 132, 30, 1.0
|
||||
],
|
||||
"rig": [
|
||||
59, 226, 235, 1.0
|
||||
],
|
||||
"pointcache": [
|
||||
94, 209, 30, 1.0
|
||||
],
|
||||
"animation": [
|
||||
94, 209, 30, 1.0
|
||||
],
|
||||
"ass": [
|
||||
249, 135, 53, 1.0
|
||||
],
|
||||
"camera": [
|
||||
136, 114, 244, 1.0
|
||||
],
|
||||
"fbx": [
|
||||
215, 166, 255, 1.0
|
||||
],
|
||||
"mayaAscii": [
|
||||
67, 174, 255, 1.0
|
||||
],
|
||||
"mayaScene": [
|
||||
67, 174, 255, 1.0
|
||||
],
|
||||
"setdress": [
|
||||
255, 250, 90, 1.0
|
||||
],
|
||||
"layout": [
|
||||
255, 250, 90, 1.0
|
||||
],
|
||||
"vdbcache": [
|
||||
249, 54, 0, 1.0
|
||||
],
|
||||
"vrayproxy": [
|
||||
255, 150, 12, 1.0
|
||||
],
|
||||
"vrayscene_layer": [
|
||||
255, 150, 12, 1.0
|
||||
],
|
||||
"yeticache": [
|
||||
99, 206, 220, 1.0
|
||||
],
|
||||
"yetiRig": [
|
||||
0, 205, 125, 1.0
|
||||
]
|
||||
},
|
||||
"reference_loader": {
|
||||
"namespace": "{folder[name]}_{product[name]}_##_",
|
||||
"group_name": "_GRP",
|
||||
"display_handle": True
|
||||
}
|
||||
}
|
||||
139
server_addon/maya/server/settings/main.py
Normal file
139
server_addon/maya/server/settings/main.py
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
from pydantic import Field, validator
|
||||
from ayon_server.settings import BaseSettingsModel, ensure_unique_names
|
||||
from .imageio import ImageIOSettings, DEFAULT_IMAGEIO_SETTINGS
|
||||
from .maya_dirmap import MayaDirmapModel, DEFAULT_MAYA_DIRMAP_SETTINGS
|
||||
from .include_handles import IncludeHandlesModel, DEFAULT_INCLUDE_HANDLES
|
||||
from .explicit_plugins_loading import (
|
||||
ExplicitPluginsLoadingModel, DEFAULT_EXPLITCIT_PLUGINS_LOADING_SETTINGS
|
||||
)
|
||||
from .scriptsmenu import ScriptsmenuModel, DEFAULT_SCRIPTSMENU_SETTINGS
|
||||
from .render_settings import RenderSettingsModel, DEFAULT_RENDER_SETTINGS
|
||||
from .creators import CreatorsModel, DEFAULT_CREATORS_SETTINGS
|
||||
from .publishers import PublishersModel, DEFAULT_PUBLISH_SETTINGS
|
||||
from .loaders import LoadersModel, DEFAULT_LOADERS_SETTING
|
||||
from .workfile_build_settings import ProfilesModel, DEFAULT_WORKFILE_SETTING
|
||||
from .templated_workfile_settings import (
|
||||
TemplatedProfilesModel, DEFAULT_TEMPLATED_WORKFILE_SETTINGS
|
||||
)
|
||||
|
||||
|
||||
class ExtMappingItemModel(BaseSettingsModel):
|
||||
_layout = "compact"
|
||||
name: str = Field(title="Product type")
|
||||
value: str = Field(title="Extension")
|
||||
|
||||
|
||||
class PublishGUIFilterItemModel(BaseSettingsModel):
|
||||
_layout = "compact"
|
||||
name: str = Field(title="Name")
|
||||
value: bool = Field(True, title="Active")
|
||||
|
||||
|
||||
class PublishGUIFiltersModel(BaseSettingsModel):
|
||||
_layout = "compact"
|
||||
name: str = Field(title="Name")
|
||||
value: list[PublishGUIFilterItemModel] = Field(default_factory=list)
|
||||
|
||||
@validator("value")
|
||||
def validate_unique_outputs(cls, value):
|
||||
ensure_unique_names(value)
|
||||
return value
|
||||
|
||||
|
||||
class MayaSettings(BaseSettingsModel):
|
||||
"""Maya Project Settings."""
|
||||
|
||||
open_workfile_post_initialization: bool = Field(
|
||||
True, title="Open Workfile Post Initialization")
|
||||
explicit_plugins_loading: ExplicitPluginsLoadingModel = Field(
|
||||
default_factory=ExplicitPluginsLoadingModel,
|
||||
title="Explicit Plugins Loading")
|
||||
imageio: ImageIOSettings = Field(
|
||||
default_factory=ImageIOSettings, title="Color Management (imageio)")
|
||||
mel_workspace: str = Field(title="Maya MEL Workspace", widget="textarea")
|
||||
ext_mapping: list[ExtMappingItemModel] = Field(
|
||||
default_factory=list, title="Extension Mapping")
|
||||
maya_dirmap: MayaDirmapModel = Field(
|
||||
default_factory=MayaDirmapModel, title="Maya dirmap Settings")
|
||||
include_handles: IncludeHandlesModel = Field(
|
||||
default_factory=IncludeHandlesModel,
|
||||
title="Include/Exclude Handles in default playback & render range"
|
||||
)
|
||||
scriptsmenu: ScriptsmenuModel = Field(
|
||||
default_factory=ScriptsmenuModel, title="Scriptsmenu Settings")
|
||||
render_settings: RenderSettingsModel = Field(
|
||||
default_factory=RenderSettingsModel, title="Render Settings")
|
||||
create: CreatorsModel = Field(
|
||||
default_factory=CreatorsModel, title="Creators")
|
||||
publish: PublishersModel = Field(
|
||||
default_factory=PublishersModel, title="Publishers")
|
||||
load: LoadersModel = Field(
|
||||
default_factory=LoadersModel, title="Loaders")
|
||||
workfile_build: ProfilesModel = Field(
|
||||
default_factory=ProfilesModel, title="Workfile Build Settings")
|
||||
templated_workfile_build: TemplatedProfilesModel = Field(
|
||||
default_factory=TemplatedProfilesModel,
|
||||
title="Templated Workfile Build Settings")
|
||||
filters: list[PublishGUIFiltersModel] = Field(
|
||||
default_factory=list,
|
||||
title="Publish GUI Filters")
|
||||
|
||||
@validator("filters", "ext_mapping")
|
||||
def validate_unique_outputs(cls, value):
|
||||
ensure_unique_names(value)
|
||||
return value
|
||||
|
||||
|
||||
DEFAULT_MEL_WORKSPACE_SETTINGS = "\n".join((
|
||||
'workspace -fr "shaders" "renderData/shaders";',
|
||||
'workspace -fr "images" "renders/maya";',
|
||||
'workspace -fr "particles" "particles";',
|
||||
'workspace -fr "mayaAscii" "";',
|
||||
'workspace -fr "mayaBinary" "";',
|
||||
'workspace -fr "scene" "";',
|
||||
'workspace -fr "alembicCache" "cache/alembic";',
|
||||
'workspace -fr "renderData" "renderData";',
|
||||
'workspace -fr "sourceImages" "sourceimages";',
|
||||
'workspace -fr "fileCache" "cache/nCache";',
|
||||
'',
|
||||
))
|
||||
|
||||
DEFAULT_MAYA_SETTING = {
|
||||
"open_workfile_post_initialization": False,
|
||||
"explicit_plugins_loading": DEFAULT_EXPLITCIT_PLUGINS_LOADING_SETTINGS,
|
||||
"imageio": DEFAULT_IMAGEIO_SETTINGS,
|
||||
"mel_workspace": DEFAULT_MEL_WORKSPACE_SETTINGS,
|
||||
"ext_mapping": [
|
||||
{"name": "model", "value": "ma"},
|
||||
{"name": "mayaAscii", "value": "ma"},
|
||||
{"name": "camera", "value": "ma"},
|
||||
{"name": "rig", "value": "ma"},
|
||||
{"name": "workfile", "value": "ma"},
|
||||
{"name": "yetiRig", "value": "ma"}
|
||||
],
|
||||
# `maya_dirmap` was originally with dash - `maya-dirmap`
|
||||
"maya_dirmap": DEFAULT_MAYA_DIRMAP_SETTINGS,
|
||||
"include_handles": DEFAULT_INCLUDE_HANDLES,
|
||||
"scriptsmenu": DEFAULT_SCRIPTSMENU_SETTINGS,
|
||||
"render_settings": DEFAULT_RENDER_SETTINGS,
|
||||
"create": DEFAULT_CREATORS_SETTINGS,
|
||||
"publish": DEFAULT_PUBLISH_SETTINGS,
|
||||
"load": DEFAULT_LOADERS_SETTING,
|
||||
"workfile_build": DEFAULT_WORKFILE_SETTING,
|
||||
"templated_workfile_build": DEFAULT_TEMPLATED_WORKFILE_SETTINGS,
|
||||
"filters": [
|
||||
{
|
||||
"name": "preset 1",
|
||||
"value": [
|
||||
{"name": "ValidateNoAnimation", "value": False},
|
||||
{"name": "ValidateShapeDefaultNames", "value": False},
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "preset 2",
|
||||
"value": [
|
||||
{"name": "ValidateNoAnimation", "value": False},
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
40
server_addon/maya/server/settings/maya_dirmap.py
Normal file
40
server_addon/maya/server/settings/maya_dirmap.py
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
from pydantic import Field
|
||||
|
||||
from ayon_server.settings import BaseSettingsModel
|
||||
|
||||
|
||||
class MayaDirmapPathsSubmodel(BaseSettingsModel):
|
||||
_layout = "compact"
|
||||
source_path: list[str] = Field(
|
||||
default_factory=list, title="Source Paths"
|
||||
)
|
||||
destination_path: list[str] = Field(
|
||||
default_factory=list, title="Destination Paths"
|
||||
)
|
||||
|
||||
|
||||
class MayaDirmapModel(BaseSettingsModel):
|
||||
"""Maya dirmap settings."""
|
||||
# _layout = "expanded"
|
||||
_isGroup: bool = True
|
||||
|
||||
enabled: bool = Field(title="enabled")
|
||||
# Use ${} placeholder instead of absolute value of a root in
|
||||
# referenced filepaths.
|
||||
use_env_var_as_root: bool = Field(
|
||||
title="Use env var placeholder in referenced paths"
|
||||
)
|
||||
paths: MayaDirmapPathsSubmodel = Field(
|
||||
default_factory=MayaDirmapPathsSubmodel,
|
||||
title="Dirmap Paths"
|
||||
)
|
||||
|
||||
|
||||
DEFAULT_MAYA_DIRMAP_SETTINGS = {
|
||||
"use_env_var_as_root": False,
|
||||
"enabled": False,
|
||||
"paths": {
|
||||
"source-path": [],
|
||||
"destination-path": []
|
||||
}
|
||||
}
|
||||
382
server_addon/maya/server/settings/publish_playblast.py
Normal file
382
server_addon/maya/server/settings/publish_playblast.py
Normal file
|
|
@ -0,0 +1,382 @@
|
|||
from pydantic import Field, validator
|
||||
|
||||
from ayon_server.settings import (
|
||||
BaseSettingsModel,
|
||||
ensure_unique_names,
|
||||
task_types_enum,
|
||||
)
|
||||
from ayon_server.types import ColorRGBA_uint8
|
||||
|
||||
|
||||
def hardware_falloff_enum():
|
||||
return [
|
||||
{"label": "Linear", "value": "0"},
|
||||
{"label": "Exponential", "value": "1"},
|
||||
{"label": "Exponential Squared", "value": "2"}
|
||||
]
|
||||
|
||||
|
||||
def renderer_enum():
|
||||
return [
|
||||
{"label": "Viewport 2.0", "value": "vp2Renderer"}
|
||||
]
|
||||
|
||||
|
||||
def displayLights_enum():
|
||||
return [
|
||||
{"label": "Default Lighting", "value": "default"},
|
||||
{"label": "All Lights", "value": "all"},
|
||||
{"label": "Selected Lights", "value": "selected"},
|
||||
{"label": "Flat Lighting", "value": "flat"},
|
||||
{"label": "No Lights", "value": "nolights"}
|
||||
]
|
||||
|
||||
|
||||
def plugin_objects_default():
|
||||
return [
|
||||
{
|
||||
"name": "gpuCacheDisplayFilter",
|
||||
"value": False
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
class CodecSetting(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
compression: str = Field("png", title="Encoding")
|
||||
format: str = Field("image", title="Format")
|
||||
quality: int = Field(95, title="Quality", ge=0, le=100)
|
||||
|
||||
|
||||
class DisplayOptionsSetting(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
override_display: bool = Field(True, title="Override display options")
|
||||
background: ColorRGBA_uint8 = Field(
|
||||
(125, 125, 125, 1.0), title="Background Color"
|
||||
)
|
||||
displayGradient: bool = Field(True, title="Display background gradient")
|
||||
backgroundTop: ColorRGBA_uint8 = Field(
|
||||
(125, 125, 125, 1.0), title="Background Top"
|
||||
)
|
||||
backgroundBottom: ColorRGBA_uint8 = Field(
|
||||
(125, 125, 125, 1.0), title="Background Bottom"
|
||||
)
|
||||
|
||||
|
||||
class GenericSetting(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
isolate_view: bool = Field(True, title="Isolate View")
|
||||
off_screen: bool = Field(True, title="Off Screen")
|
||||
pan_zoom: bool = Field(False, title="2D Pan/Zoom")
|
||||
|
||||
|
||||
class RendererSetting(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
rendererName: str = Field(
|
||||
"vp2Renderer",
|
||||
enum_resolver=renderer_enum,
|
||||
title="Renderer name"
|
||||
)
|
||||
|
||||
|
||||
class ResolutionSetting(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
width: int = Field(0, title="Width")
|
||||
height: int = Field(0, title="Height")
|
||||
|
||||
|
||||
class PluginObjectsModel(BaseSettingsModel):
|
||||
name: str = Field("", title="Name")
|
||||
value: bool = Field(True, title="Enabled")
|
||||
|
||||
|
||||
class ViewportOptionsSetting(BaseSettingsModel):
|
||||
override_viewport_options: bool = Field(
|
||||
True, title="Override viewport options"
|
||||
)
|
||||
displayLights: str = Field(
|
||||
"default", enum_resolver=displayLights_enum, title="Display Lights"
|
||||
)
|
||||
displayTextures: bool = Field(True, title="Display Textures")
|
||||
textureMaxResolution: int = Field(1024, title="Texture Clamp Resolution")
|
||||
renderDepthOfField: bool = Field(
|
||||
True, title="Depth of Field", section="Depth of Field"
|
||||
)
|
||||
shadows: bool = Field(True, title="Display Shadows")
|
||||
twoSidedLighting: bool = Field(True, title="Two Sided Lighting")
|
||||
lineAAEnable: bool = Field(
|
||||
True, title="Enable Anti-Aliasing", section="Anti-Aliasing"
|
||||
)
|
||||
multiSample: int = Field(8, title="Anti Aliasing Samples")
|
||||
useDefaultMaterial: bool = Field(False, title="Use Default Material")
|
||||
wireframeOnShaded: bool = Field(False, title="Wireframe On Shaded")
|
||||
xray: bool = Field(False, title="X-Ray")
|
||||
jointXray: bool = Field(False, title="X-Ray Joints")
|
||||
backfaceCulling: bool = Field(False, title="Backface Culling")
|
||||
ssaoEnable: bool = Field(
|
||||
False, title="Screen Space Ambient Occlusion", section="SSAO"
|
||||
)
|
||||
ssaoAmount: int = Field(1, title="SSAO Amount")
|
||||
ssaoRadius: int = Field(16, title="SSAO Radius")
|
||||
ssaoFilterRadius: int = Field(16, title="SSAO Filter Radius")
|
||||
ssaoSamples: int = Field(16, title="SSAO Samples")
|
||||
fogging: bool = Field(False, title="Enable Hardware Fog", section="Fog")
|
||||
hwFogFalloff: str = Field(
|
||||
"0", enum_resolver=hardware_falloff_enum, title="Hardware Falloff"
|
||||
)
|
||||
hwFogDensity: float = Field(0.0, title="Fog Density")
|
||||
hwFogStart: int = Field(0, title="Fog Start")
|
||||
hwFogEnd: int = Field(100, title="Fog End")
|
||||
hwFogAlpha: int = Field(0, title="Fog Alpha")
|
||||
hwFogColorR: float = Field(1.0, title="Fog Color R")
|
||||
hwFogColorG: float = Field(1.0, title="Fog Color G")
|
||||
hwFogColorB: float = Field(1.0, title="Fog Color B")
|
||||
motionBlurEnable: bool = Field(
|
||||
False, title="Enable Motion Blur", section="Motion Blur"
|
||||
)
|
||||
motionBlurSampleCount: int = Field(8, title="Motion Blur Sample Count")
|
||||
motionBlurShutterOpenFraction: float = Field(
|
||||
0.2, title="Shutter Open Fraction"
|
||||
)
|
||||
cameras: bool = Field(False, title="Cameras", section="Show")
|
||||
clipGhosts: bool = Field(False, title="Clip Ghosts")
|
||||
deformers: bool = Field(False, title="Deformers")
|
||||
dimensions: bool = Field(False, title="Dimensions")
|
||||
dynamicConstraints: bool = Field(False, title="Dynamic Constraints")
|
||||
dynamics: bool = Field(False, title="Dynamics")
|
||||
fluids: bool = Field(False, title="Fluids")
|
||||
follicles: bool = Field(False, title="Follicles")
|
||||
greasePencils: bool = Field(False, title="Grease Pencils")
|
||||
grid: bool = Field(False, title="Grid")
|
||||
hairSystems: bool = Field(True, title="Hair Systems")
|
||||
handles: bool = Field(False, title="Handles")
|
||||
headsUpDisplay: bool = Field(False, title="HUD")
|
||||
ikHandles: bool = Field(False, title="IK Handles")
|
||||
imagePlane: bool = Field(True, title="Image Plane")
|
||||
joints: bool = Field(False, title="Joints")
|
||||
lights: bool = Field(False, title="Lights")
|
||||
locators: bool = Field(False, title="Locators")
|
||||
manipulators: bool = Field(False, title="Manipulators")
|
||||
motionTrails: bool = Field(False, title="Motion Trails")
|
||||
nCloths: bool = Field(False, title="nCloths")
|
||||
nParticles: bool = Field(False, title="nParticles")
|
||||
nRigids: bool = Field(False, title="nRigids")
|
||||
controlVertices: bool = Field(False, title="NURBS CVs")
|
||||
nurbsCurves: bool = Field(False, title="NURBS Curves")
|
||||
hulls: bool = Field(False, title="NURBS Hulls")
|
||||
nurbsSurfaces: bool = Field(False, title="NURBS Surfaces")
|
||||
particleInstancers: bool = Field(False, title="Particle Instancers")
|
||||
pivots: bool = Field(False, title="Pivots")
|
||||
planes: bool = Field(False, title="Planes")
|
||||
pluginShapes: bool = Field(False, title="Plugin Shapes")
|
||||
polymeshes: bool = Field(True, title="Polygons")
|
||||
strokes: bool = Field(False, title="Strokes")
|
||||
subdivSurfaces: bool = Field(False, title="Subdiv Surfaces")
|
||||
textures: bool = Field(False, title="Texture Placements")
|
||||
pluginObjects: list[PluginObjectsModel] = Field(
|
||||
default_factory=plugin_objects_default,
|
||||
title="Plugin Objects"
|
||||
)
|
||||
|
||||
@validator("pluginObjects")
|
||||
def validate_unique_plugin_objects(cls, value):
|
||||
ensure_unique_names(value)
|
||||
return value
|
||||
|
||||
|
||||
class CameraOptionsSetting(BaseSettingsModel):
|
||||
displayGateMask: bool = Field(False, title="Display Gate Mask")
|
||||
displayResolution: bool = Field(False, title="Display Resolution")
|
||||
displayFilmGate: bool = Field(False, title="Display Film Gate")
|
||||
displayFieldChart: bool = Field(False, title="Display Field Chart")
|
||||
displaySafeAction: bool = Field(False, title="Display Safe Action")
|
||||
displaySafeTitle: bool = Field(False, title="Display Safe Title")
|
||||
displayFilmPivot: bool = Field(False, title="Display Film Pivot")
|
||||
displayFilmOrigin: bool = Field(False, title="Display Film Origin")
|
||||
overscan: int = Field(1.0, title="Overscan")
|
||||
|
||||
|
||||
class CapturePresetSetting(BaseSettingsModel):
|
||||
Codec: CodecSetting = Field(
|
||||
default_factory=CodecSetting,
|
||||
title="Codec",
|
||||
section="Codec")
|
||||
DisplayOptions: DisplayOptionsSetting = Field(
|
||||
default_factory=DisplayOptionsSetting,
|
||||
title="Display Options",
|
||||
section="Display Options")
|
||||
Generic: GenericSetting = Field(
|
||||
default_factory=GenericSetting,
|
||||
title="Generic",
|
||||
section="Generic")
|
||||
Renderer: RendererSetting = Field(
|
||||
default_factory=RendererSetting,
|
||||
title="Renderer",
|
||||
section="Renderer")
|
||||
Resolution: ResolutionSetting = Field(
|
||||
default_factory=ResolutionSetting,
|
||||
title="Resolution",
|
||||
section="Resolution")
|
||||
ViewportOptions: ViewportOptionsSetting = Field(
|
||||
default_factory=ViewportOptionsSetting,
|
||||
title="Viewport Options")
|
||||
CameraOptions: CameraOptionsSetting = Field(
|
||||
default_factory=CameraOptionsSetting,
|
||||
title="Camera Options")
|
||||
|
||||
|
||||
class ProfilesModel(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
task_types: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Task types",
|
||||
enum_resolver=task_types_enum
|
||||
)
|
||||
task_names: list[str] = Field(default_factory=list, title="Task names")
|
||||
product_names: list[str] = Field(default_factory=list, title="Products names")
|
||||
capture_preset: CapturePresetSetting = Field(
|
||||
default_factory=CapturePresetSetting,
|
||||
title="Capture Preset"
|
||||
)
|
||||
|
||||
|
||||
class ExtractPlayblastSetting(BaseSettingsModel):
|
||||
capture_preset: CapturePresetSetting = Field(
|
||||
default_factory=CapturePresetSetting,
|
||||
title="DEPRECATED! Please use \"Profiles\" below. Capture Preset"
|
||||
)
|
||||
profiles: list[ProfilesModel] = Field(
|
||||
default_factory=list,
|
||||
title="Profiles"
|
||||
)
|
||||
|
||||
|
||||
DEFAULT_PLAYBLAST_SETTING = {
|
||||
"capture_preset": {
|
||||
"Codec": {
|
||||
"compression": "png",
|
||||
"format": "image",
|
||||
"quality": 95
|
||||
},
|
||||
"DisplayOptions": {
|
||||
"override_display": True,
|
||||
"background": [
|
||||
125,
|
||||
125,
|
||||
125,
|
||||
1.0
|
||||
],
|
||||
"backgroundBottom": [
|
||||
125,
|
||||
125,
|
||||
125,
|
||||
1.0
|
||||
],
|
||||
"backgroundTop": [
|
||||
125,
|
||||
125,
|
||||
125,
|
||||
1.0
|
||||
],
|
||||
"displayGradient": True
|
||||
},
|
||||
"Generic": {
|
||||
"isolate_view": True,
|
||||
"off_screen": True,
|
||||
"pan_zoom": False
|
||||
},
|
||||
"Renderer": {
|
||||
"rendererName": "vp2Renderer"
|
||||
},
|
||||
"Resolution": {
|
||||
"width": 1920,
|
||||
"height": 1080
|
||||
},
|
||||
"ViewportOptions": {
|
||||
"override_viewport_options": True,
|
||||
"displayLights": "default",
|
||||
"displayTextures": True,
|
||||
"textureMaxResolution": 1024,
|
||||
"renderDepthOfField": True,
|
||||
"shadows": True,
|
||||
"twoSidedLighting": True,
|
||||
"lineAAEnable": True,
|
||||
"multiSample": 8,
|
||||
"useDefaultMaterial": False,
|
||||
"wireframeOnShaded": False,
|
||||
"xray": False,
|
||||
"jointXray": False,
|
||||
"backfaceCulling": False,
|
||||
"ssaoEnable": False,
|
||||
"ssaoAmount": 1,
|
||||
"ssaoRadius": 16,
|
||||
"ssaoFilterRadius": 16,
|
||||
"ssaoSamples": 16,
|
||||
"fogging": False,
|
||||
"hwFogFalloff": "0",
|
||||
"hwFogDensity": 0.0,
|
||||
"hwFogStart": 0,
|
||||
"hwFogEnd": 100,
|
||||
"hwFogAlpha": 0,
|
||||
"hwFogColorR": 1.0,
|
||||
"hwFogColorG": 1.0,
|
||||
"hwFogColorB": 1.0,
|
||||
"motionBlurEnable": False,
|
||||
"motionBlurSampleCount": 8,
|
||||
"motionBlurShutterOpenFraction": 0.2,
|
||||
"cameras": False,
|
||||
"clipGhosts": False,
|
||||
"deformers": False,
|
||||
"dimensions": False,
|
||||
"dynamicConstraints": False,
|
||||
"dynamics": False,
|
||||
"fluids": False,
|
||||
"follicles": False,
|
||||
"greasePencils": False,
|
||||
"grid": False,
|
||||
"hairSystems": True,
|
||||
"handles": False,
|
||||
"headsUpDisplay": False,
|
||||
"ikHandles": False,
|
||||
"imagePlane": True,
|
||||
"joints": False,
|
||||
"lights": False,
|
||||
"locators": False,
|
||||
"manipulators": False,
|
||||
"motionTrails": False,
|
||||
"nCloths": False,
|
||||
"nParticles": False,
|
||||
"nRigids": False,
|
||||
"controlVertices": False,
|
||||
"nurbsCurves": False,
|
||||
"hulls": False,
|
||||
"nurbsSurfaces": False,
|
||||
"particleInstancers": False,
|
||||
"pivots": False,
|
||||
"planes": False,
|
||||
"pluginShapes": False,
|
||||
"polymeshes": True,
|
||||
"strokes": False,
|
||||
"subdivSurfaces": False,
|
||||
"textures": False,
|
||||
"pluginObjects": [
|
||||
{
|
||||
"name": "gpuCacheDisplayFilter",
|
||||
"value": False
|
||||
}
|
||||
]
|
||||
},
|
||||
"CameraOptions": {
|
||||
"displayGateMask": False,
|
||||
"displayResolution": False,
|
||||
"displayFilmGate": False,
|
||||
"displayFieldChart": False,
|
||||
"displaySafeAction": False,
|
||||
"displaySafeTitle": False,
|
||||
"displayFilmPivot": False,
|
||||
"displayFilmOrigin": False,
|
||||
"overscan": 1.0
|
||||
}
|
||||
},
|
||||
"profiles": []
|
||||
}
|
||||
1262
server_addon/maya/server/settings/publishers.py
Normal file
1262
server_addon/maya/server/settings/publishers.py
Normal file
File diff suppressed because it is too large
Load diff
500
server_addon/maya/server/settings/render_settings.py
Normal file
500
server_addon/maya/server/settings/render_settings.py
Normal file
|
|
@ -0,0 +1,500 @@
|
|||
"""Providing models and values for Maya Render Settings."""
|
||||
from pydantic import Field
|
||||
|
||||
from ayon_server.settings import BaseSettingsModel
|
||||
|
||||
|
||||
def aov_separators_enum():
|
||||
return [
|
||||
{"value": "dash", "label": "- (dash)"},
|
||||
{"value": "underscore", "label": "_ (underscore)"},
|
||||
{"value": "dot", "label": ". (dot)"}
|
||||
]
|
||||
|
||||
|
||||
def arnold_image_format_enum():
|
||||
"""Return enumerator for Arnold output formats."""
|
||||
return [
|
||||
{"label": "jpeg", "value": "jpeg"},
|
||||
{"label": "png", "value": "png"},
|
||||
{"label": "deepexr", "value": "deep exr"},
|
||||
{"label": "tif", "value": "tif"},
|
||||
{"label": "exr", "value": "exr"},
|
||||
{"label": "maya", "value": "maya"},
|
||||
{"label": "mtoa_shaders", "value": "mtoa_shaders"}
|
||||
]
|
||||
|
||||
|
||||
def arnold_aov_list_enum():
|
||||
"""Return enumerator for Arnold AOVs.
|
||||
|
||||
Note: Key is value, Value in this case is Label. This
|
||||
was taken from v3 settings.
|
||||
"""
|
||||
return [
|
||||
{"value": "empty", "label": "< empty >"},
|
||||
{"value": "ID", "label": "ID"},
|
||||
{"value": "N", "label": "N"},
|
||||
{"value": "P", "label": "P"},
|
||||
{"value": "Pref", "label": "Pref"},
|
||||
{"value": "RGBA", "label": "RGBA"},
|
||||
{"value": "Z", "label": "Z"},
|
||||
{"value": "albedo", "label": "albedo"},
|
||||
{"value": "background", "label": "background"},
|
||||
{"value": "coat", "label": "coat"},
|
||||
{"value": "coat_albedo", "label": "coat_albedo"},
|
||||
{"value": "coat_direct", "label": "coat_direct"},
|
||||
{"value": "coat_indirect", "label": "coat_indirect"},
|
||||
{"value": "cputime", "label": "cputime"},
|
||||
{"value": "crypto_asset", "label": "crypto_asset"},
|
||||
{"value": "crypto_material", "label": "cypto_material"},
|
||||
{"value": "crypto_object", "label": "crypto_object"},
|
||||
{"value": "diffuse", "label": "diffuse"},
|
||||
{"value": "diffuse_albedo", "label": "diffuse_albedo"},
|
||||
{"value": "diffuse_direct", "label": "diffuse_direct"},
|
||||
{"value": "diffuse_indirect", "label": "diffuse_indirect"},
|
||||
{"value": "direct", "label": "direct"},
|
||||
{"value": "emission", "label": "emission"},
|
||||
{"value": "highlight", "label": "highlight"},
|
||||
{"value": "indirect", "label": "indirect"},
|
||||
{"value": "motionvector", "label": "motionvector"},
|
||||
{"value": "opacity", "label": "opacity"},
|
||||
{"value": "raycount", "label": "raycount"},
|
||||
{"value": "rim_light", "label": "rim_light"},
|
||||
{"value": "shadow", "label": "shadow"},
|
||||
{"value": "shadow_diff", "label": "shadow_diff"},
|
||||
{"value": "shadow_mask", "label": "shadow_mask"},
|
||||
{"value": "shadow_matte", "label": "shadow_matte"},
|
||||
{"value": "sheen", "label": "sheen"},
|
||||
{"value": "sheen_albedo", "label": "sheen_albedo"},
|
||||
{"value": "sheen_direct", "label": "sheen_direct"},
|
||||
{"value": "sheen_indirect", "label": "sheen_indirect"},
|
||||
{"value": "specular", "label": "specular"},
|
||||
{"value": "specular_albedo", "label": "specular_albedo"},
|
||||
{"value": "specular_direct", "label": "specular_direct"},
|
||||
{"value": "specular_indirect", "label": "specular_indirect"},
|
||||
{"value": "sss", "label": "sss"},
|
||||
{"value": "sss_albedo", "label": "sss_albedo"},
|
||||
{"value": "sss_direct", "label": "sss_direct"},
|
||||
{"value": "sss_indirect", "label": "sss_indirect"},
|
||||
{"value": "transmission", "label": "transmission"},
|
||||
{"value": "transmission_albedo", "label": "transmission_albedo"},
|
||||
{"value": "transmission_direct", "label": "transmission_direct"},
|
||||
{"value": "transmission_indirect", "label": "transmission_indirect"},
|
||||
{"value": "volume", "label": "volume"},
|
||||
{"value": "volume_Z", "label": "volume_Z"},
|
||||
{"value": "volume_albedo", "label": "volume_albedo"},
|
||||
{"value": "volume_direct", "label": "volume_direct"},
|
||||
{"value": "volume_indirect", "label": "volume_indirect"},
|
||||
{"value": "volume_opacity", "label": "volume_opacity"},
|
||||
]
|
||||
|
||||
|
||||
def vray_image_output_enum():
|
||||
"""Return output format for Vray enumerator."""
|
||||
return [
|
||||
{"label": "png", "value": "png"},
|
||||
{"label": "jpg", "value": "jpg"},
|
||||
{"label": "vrimg", "value": "vrimg"},
|
||||
{"label": "hdr", "value": "hdr"},
|
||||
{"label": "exr", "value": "exr"},
|
||||
{"label": "exr (multichannel)", "value": "exr (multichannel)"},
|
||||
{"label": "exr (deep)", "value": "exr (deep)"},
|
||||
{"label": "tga", "value": "tga"},
|
||||
{"label": "bmp", "value": "bmp"},
|
||||
{"label": "sgi", "value": "sgi"}
|
||||
]
|
||||
|
||||
|
||||
def vray_aov_list_enum():
|
||||
"""Return enumerator for Vray AOVs.
|
||||
|
||||
Note: Key is value, Value in this case is Label. This
|
||||
was taken from v3 settings.
|
||||
"""
|
||||
|
||||
return [
|
||||
{"value": "empty", "label": "< empty >"},
|
||||
{"value": "atmosphereChannel", "label": "atmosphere"},
|
||||
{"value": "backgroundChannel", "label": "background"},
|
||||
{"value": "bumpNormalsChannel", "label": "bumpnormals"},
|
||||
{"value": "causticsChannel", "label": "caustics"},
|
||||
{"value": "coatFilterChannel", "label": "coat_filter"},
|
||||
{"value": "coatGlossinessChannel", "label": "coatGloss"},
|
||||
{"value": "coatReflectionChannel", "label": "coat_reflection"},
|
||||
{"value": "vrayCoatChannel", "label": "coat_specular"},
|
||||
{"value": "CoverageChannel", "label": "coverage"},
|
||||
{"value": "cryptomatteChannel", "label": "cryptomatte"},
|
||||
{"value": "customColor", "label": "custom_color"},
|
||||
{"value": "drBucketChannel", "label": "DR"},
|
||||
{"value": "denoiserChannel", "label": "denoiser"},
|
||||
{"value": "diffuseChannel", "label": "diffuse"},
|
||||
{"value": "ExtraTexElement", "label": "extraTex"},
|
||||
{"value": "giChannel", "label": "GI"},
|
||||
{"value": "LightMixElement", "label": "None"},
|
||||
{"value": "lightingChannel", "label": "lighting"},
|
||||
{"value": "LightingAnalysisChannel", "label": "LightingAnalysis"},
|
||||
{"value": "materialIDChannel", "label": "materialID"},
|
||||
{"value": "MaterialSelectElement", "label": "materialSelect"},
|
||||
{"value": "matteShadowChannel", "label": "matteShadow"},
|
||||
{"value": "MultiMatteElement", "label": "multimatte"},
|
||||
{"value": "multimatteIDChannel", "label": "multimatteID"},
|
||||
{"value": "normalsChannel", "label": "normals"},
|
||||
{"value": "nodeIDChannel", "label": "objectId"},
|
||||
{"value": "objectSelectChannel", "label": "objectSelect"},
|
||||
{"value": "rawCoatFilterChannel", "label": "raw_coat_filter"},
|
||||
{"value": "rawCoatReflectionChannel", "label": "raw_coat_reflection"},
|
||||
{"value": "rawDiffuseFilterChannel", "label": "rawDiffuseFilter"},
|
||||
{"value": "rawGiChannel", "label": "rawGI"},
|
||||
{"value": "rawLightChannel", "label": "rawLight"},
|
||||
{"value": "rawReflectionChannel", "label": "rawReflection"},
|
||||
{
|
||||
"value": "rawReflectionFilterChannel",
|
||||
"label": "rawReflectionFilter"
|
||||
},
|
||||
{"value": "rawRefractionChannel", "label": "rawRefraction"},
|
||||
{
|
||||
"value": "rawRefractionFilterChannel",
|
||||
"label": "rawRefractionFilter"
|
||||
},
|
||||
{"value": "rawShadowChannel", "label": "rawShadow"},
|
||||
{"value": "rawSheenFilterChannel", "label": "raw_sheen_filter"},
|
||||
{
|
||||
"value": "rawSheenReflectionChannel",
|
||||
"label": "raw_sheen_reflection"
|
||||
},
|
||||
{"value": "rawTotalLightChannel", "label": "rawTotalLight"},
|
||||
{"value": "reflectIORChannel", "label": "reflIOR"},
|
||||
{"value": "reflectChannel", "label": "reflect"},
|
||||
{"value": "reflectionFilterChannel", "label": "reflectionFilter"},
|
||||
{"value": "reflectGlossinessChannel", "label": "reflGloss"},
|
||||
{"value": "refractChannel", "label": "refract"},
|
||||
{"value": "refractionFilterChannel", "label": "refractionFilter"},
|
||||
{"value": "refractGlossinessChannel", "label": "refrGloss"},
|
||||
{"value": "renderIDChannel", "label": "renderId"},
|
||||
{"value": "FastSSS2Channel", "label": "SSS"},
|
||||
{"value": "sampleRateChannel", "label": "sampleRate"},
|
||||
{"value": "samplerInfo", "label": "samplerInfo"},
|
||||
{"value": "selfIllumChannel", "label": "selfIllum"},
|
||||
{"value": "shadowChannel", "label": "shadow"},
|
||||
{"value": "sheenFilterChannel", "label": "sheen_filter"},
|
||||
{"value": "sheenGlossinessChannel", "label": "sheenGloss"},
|
||||
{"value": "sheenReflectionChannel", "label": "sheen_reflection"},
|
||||
{"value": "vraySheenChannel", "label": "sheen_specular"},
|
||||
{"value": "specularChannel", "label": "specular"},
|
||||
{"value": "Toon", "label": "Toon"},
|
||||
{"value": "toonLightingChannel", "label": "toonLighting"},
|
||||
{"value": "toonSpecularChannel", "label": "toonSpecular"},
|
||||
{"value": "totalLightChannel", "label": "totalLight"},
|
||||
{"value": "unclampedColorChannel", "label": "unclampedColor"},
|
||||
{"value": "VRScansPaintMaskChannel", "label": "VRScansPaintMask"},
|
||||
{"value": "VRScansZoneMaskChannel", "label": "VRScansZoneMask"},
|
||||
{"value": "velocityChannel", "label": "velocity"},
|
||||
{"value": "zdepthChannel", "label": "zDepth"},
|
||||
{"value": "LightSelectElement", "label": "lightselect"},
|
||||
]
|
||||
|
||||
|
||||
def redshift_engine_enum():
|
||||
"""Get Redshift engine type enumerator."""
|
||||
return [
|
||||
{"value": "0", "label": "None"},
|
||||
{"value": "1", "label": "Photon Map"},
|
||||
{"value": "2", "label": "Irradiance Cache"},
|
||||
{"value": "3", "label": "Brute Force"}
|
||||
]
|
||||
|
||||
|
||||
def redshift_image_output_enum():
|
||||
"""Return output format for Redshift enumerator."""
|
||||
return [
|
||||
{"value": "iff", "label": "Maya IFF"},
|
||||
{"value": "exr", "label": "OpenEXR"},
|
||||
{"value": "tif", "label": "TIFF"},
|
||||
{"value": "png", "label": "PNG"},
|
||||
{"value": "tga", "label": "Targa"},
|
||||
{"value": "jpg", "label": "JPEG"}
|
||||
]
|
||||
|
||||
|
||||
def redshift_aov_list_enum():
|
||||
"""Return enumerator for Vray AOVs.
|
||||
|
||||
Note: Key is value, Value in this case is Label. This
|
||||
was taken from v3 settings.
|
||||
"""
|
||||
return [
|
||||
{"value": "empty", "label": "< none >"},
|
||||
{"value": "AO", "label": "Ambient Occlusion"},
|
||||
{"value": "Background", "label": "Background"},
|
||||
{"value": "Beauty", "label": "Beauty"},
|
||||
{"value": "BumpNormals", "label": "Bump Normals"},
|
||||
{"value": "Caustics", "label": "Caustics"},
|
||||
{"value": "CausticsRaw", "label": "Caustics Raw"},
|
||||
{"value": "Cryptomatte", "label": "Cryptomatte"},
|
||||
{"value": "Custom", "label": "Custom"},
|
||||
{"value": "Z", "label": "Depth"},
|
||||
{"value": "DiffuseFilter", "label": "Diffuse Filter"},
|
||||
{"value": "DiffuseLighting", "label": "Diffuse Lighting"},
|
||||
{"value": "DiffuseLightingRaw", "label": "Diffuse Lighting Raw"},
|
||||
{"value": "Emission", "label": "Emission"},
|
||||
{"value": "GI", "label": "Global Illumination"},
|
||||
{"value": "GIRaw", "label": "Global Illumination Raw"},
|
||||
{"value": "Matte", "label": "Matte"},
|
||||
{"value": "MotionVectors", "label": "Ambient Occlusion"},
|
||||
{"value": "N", "label": "Normals"},
|
||||
{"value": "ID", "label": "ObjectID"},
|
||||
{"value": "ObjectBumpNormal", "label": "Object-Space Bump Normals"},
|
||||
{"value": "ObjectPosition", "label": "Object-Space Positions"},
|
||||
{"value": "PuzzleMatte", "label": "Puzzle Matte"},
|
||||
{"value": "Reflections", "label": "Reflections"},
|
||||
{"value": "ReflectionsFilter", "label": "Reflections Filter"},
|
||||
{"value": "ReflectionsRaw", "label": "Reflections Raw"},
|
||||
{"value": "Refractions", "label": "Refractions"},
|
||||
{"value": "RefractionsFilter", "label": "Refractions Filter"},
|
||||
{"value": "RefractionsRaw", "label": "Refractions Filter"},
|
||||
{"value": "Shadows", "label": "Shadows"},
|
||||
{"value": "SpecularLighting", "label": "Specular Lighting"},
|
||||
{"value": "SSS", "label": "Sub Surface Scatter"},
|
||||
{"value": "SSSRaw", "label": "Sub Surface Scatter Raw"},
|
||||
{
|
||||
"value": "TotalDiffuseLightingRaw",
|
||||
"label": "Total Diffuse Lighting Raw"
|
||||
},
|
||||
{
|
||||
"value": "TotalTransLightingRaw",
|
||||
"label": "Total Translucency Filter"
|
||||
},
|
||||
{"value": "TransTint", "label": "Translucency Filter"},
|
||||
{"value": "TransGIRaw", "label": "Translucency Lighting Raw"},
|
||||
{"value": "VolumeFogEmission", "label": "Volume Fog Emission"},
|
||||
{"value": "VolumeFogTint", "label": "Volume Fog Tint"},
|
||||
{"value": "VolumeLighting", "label": "Volume Lighting"},
|
||||
{"value": "P", "label": "World Position"},
|
||||
]
|
||||
|
||||
|
||||
class AdditionalOptionsModel(BaseSettingsModel):
|
||||
"""Additional Option"""
|
||||
_layout = "compact"
|
||||
|
||||
attribute: str = Field("", title="Attribute name")
|
||||
value: str = Field("", title="Value")
|
||||
|
||||
|
||||
class ArnoldSettingsModel(BaseSettingsModel):
|
||||
image_prefix: str = Field(title="Image prefix template")
|
||||
image_format: str = Field(
|
||||
enum_resolver=arnold_image_format_enum, title="Output Image Format")
|
||||
multilayer_exr: bool = Field(title="Multilayer (exr)")
|
||||
tiled: bool = Field(title="Tiled (tif, exr)")
|
||||
aov_list: list[str] = Field(
|
||||
default_factory=list,
|
||||
enum_resolver=arnold_aov_list_enum,
|
||||
title="AOVs to create"
|
||||
)
|
||||
additional_options: list[AdditionalOptionsModel] = Field(
|
||||
default_factory=list,
|
||||
title="Additional Arnold Options",
|
||||
description=(
|
||||
"Add additional options - put attribute and value, like AASamples"
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class VraySettingsModel(BaseSettingsModel):
|
||||
image_prefix: str = Field(title="Image prefix template")
|
||||
# engine was str because of JSON limitation (key must be string)
|
||||
engine: str = Field(
|
||||
enum_resolver=lambda: [
|
||||
{"label": "V-Ray", "value": "1"},
|
||||
{"label": "V-Ray GPU", "value": "2"}
|
||||
],
|
||||
title="Production Engine"
|
||||
)
|
||||
image_format: str = Field(
|
||||
enum_resolver=vray_image_output_enum,
|
||||
title="Output Image Format"
|
||||
)
|
||||
aov_list: list[str] = Field(
|
||||
default_factory=list,
|
||||
enum_resolver=vray_aov_list_enum,
|
||||
title="AOVs to create"
|
||||
)
|
||||
additional_options: list[AdditionalOptionsModel] = Field(
|
||||
default_factory=list,
|
||||
title="Additional Vray Options",
|
||||
description=(
|
||||
"Add additional options - put attribute and value,"
|
||||
" like aaFilterSize"
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class RedshiftSettingsModel(BaseSettingsModel):
|
||||
image_prefix: str = Field(title="Image prefix template")
|
||||
# both engines are using the same enumerator,
|
||||
# both were originally str because of JSON limitation.
|
||||
primary_gi_engine: str = Field(
|
||||
enum_resolver=redshift_engine_enum,
|
||||
title="Primary GI Engine"
|
||||
)
|
||||
secondary_gi_engine: str = Field(
|
||||
enum_resolver=redshift_engine_enum,
|
||||
title="Secondary GI Engine"
|
||||
)
|
||||
image_format: str = Field(
|
||||
enum_resolver=redshift_image_output_enum,
|
||||
title="Output Image Format"
|
||||
)
|
||||
multilayer_exr: bool = Field(title="Multilayer (exr)")
|
||||
force_combine: bool = Field(title="Force combine beauty and AOVs")
|
||||
aov_list: list[str] = Field(
|
||||
default_factory=list,
|
||||
enum_resolver=redshift_aov_list_enum,
|
||||
title="AOVs to create"
|
||||
)
|
||||
additional_options: list[AdditionalOptionsModel] = Field(
|
||||
default_factory=list,
|
||||
title="Additional Vray Options",
|
||||
description=(
|
||||
"Add additional options - put attribute and value,"
|
||||
" like reflectionMaxTraceDepth"
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def renderman_display_filters():
|
||||
return [
|
||||
"PxrBackgroundDisplayFilter",
|
||||
"PxrCopyAOVDisplayFilter",
|
||||
"PxrEdgeDetect",
|
||||
"PxrFilmicTonemapperDisplayFilter",
|
||||
"PxrGradeDisplayFilter",
|
||||
"PxrHalfBufferErrorFilter",
|
||||
"PxrImageDisplayFilter",
|
||||
"PxrLightSaturation",
|
||||
"PxrShadowDisplayFilter",
|
||||
"PxrStylizedHatching",
|
||||
"PxrStylizedLines",
|
||||
"PxrStylizedToon",
|
||||
"PxrWhitePointDisplayFilter"
|
||||
]
|
||||
|
||||
|
||||
def renderman_sample_filters_enum():
|
||||
return [
|
||||
"PxrBackgroundSampleFilter",
|
||||
"PxrCopyAOVSampleFilter",
|
||||
"PxrCryptomatte",
|
||||
"PxrFilmicTonemapperSampleFilter",
|
||||
"PxrGradeSampleFilter",
|
||||
"PxrShadowFilter",
|
||||
"PxrWatermarkFilter",
|
||||
"PxrWhitePointSampleFilter"
|
||||
]
|
||||
|
||||
|
||||
class RendermanSettingsModel(BaseSettingsModel):
|
||||
image_prefix: str = Field(
|
||||
"", title="Image prefix template")
|
||||
image_dir: str = Field(
|
||||
"", title="Image Output Directory")
|
||||
display_filters: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Display Filters",
|
||||
enum_resolver=renderman_display_filters
|
||||
)
|
||||
imageDisplay_dir: str = Field(
|
||||
"", title="Image Display Filter Directory")
|
||||
sample_filters: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Sample Filters",
|
||||
enum_resolver=renderman_sample_filters_enum
|
||||
)
|
||||
cryptomatte_dir: str = Field(
|
||||
"", title="Cryptomatte Output Directory")
|
||||
watermark_dir: str = Field(
|
||||
"", title="Watermark Filter Directory")
|
||||
additional_options: list[AdditionalOptionsModel] = Field(
|
||||
default_factory=list,
|
||||
title="Additional Renderer Options"
|
||||
)
|
||||
|
||||
|
||||
class RenderSettingsModel(BaseSettingsModel):
|
||||
apply_render_settings: bool = Field(
|
||||
title="Apply Render Settings on creation"
|
||||
)
|
||||
default_render_image_folder: str = Field(
|
||||
title="Default render image folder"
|
||||
)
|
||||
enable_all_lights: bool = Field(
|
||||
title="Include all lights in Render Setup Layers by default"
|
||||
)
|
||||
aov_separator: str = Field(
|
||||
"underscore",
|
||||
title="AOV Separator character",
|
||||
enum_resolver=aov_separators_enum
|
||||
)
|
||||
reset_current_frame: bool = Field(
|
||||
title="Reset Current Frame")
|
||||
remove_aovs: bool = Field(
|
||||
title="Remove existing AOVs")
|
||||
arnold_renderer: ArnoldSettingsModel = Field(
|
||||
default_factory=ArnoldSettingsModel,
|
||||
title="Arnold Renderer")
|
||||
vray_renderer: VraySettingsModel = Field(
|
||||
default_factory=VraySettingsModel,
|
||||
title="Vray Renderer")
|
||||
redshift_renderer: RedshiftSettingsModel = Field(
|
||||
default_factory=RedshiftSettingsModel,
|
||||
title="Redshift Renderer")
|
||||
renderman_renderer: RendermanSettingsModel = Field(
|
||||
default_factory=RendermanSettingsModel,
|
||||
title="Renderman Renderer")
|
||||
|
||||
|
||||
DEFAULT_RENDER_SETTINGS = {
|
||||
"apply_render_settings": True,
|
||||
"default_render_image_folder": "renders/maya",
|
||||
"enable_all_lights": True,
|
||||
"aov_separator": "underscore",
|
||||
"reset_current_frame": False,
|
||||
"remove_aovs": False,
|
||||
"arnold_renderer": {
|
||||
"image_prefix": "<Scene>/<RenderLayer>/<RenderLayer>_<RenderPass>",
|
||||
"image_format": "exr",
|
||||
"multilayer_exr": True,
|
||||
"tiled": True,
|
||||
"aov_list": [],
|
||||
"additional_options": []
|
||||
},
|
||||
"vray_renderer": {
|
||||
"image_prefix": "<scene>/<Layer>/<Layer>",
|
||||
"engine": "1",
|
||||
"image_format": "exr",
|
||||
"aov_list": [],
|
||||
"additional_options": []
|
||||
},
|
||||
"redshift_renderer": {
|
||||
"image_prefix": "<Scene>/<RenderLayer>/<RenderLayer>",
|
||||
"primary_gi_engine": "0",
|
||||
"secondary_gi_engine": "0",
|
||||
"image_format": "exr",
|
||||
"multilayer_exr": True,
|
||||
"force_combine": True,
|
||||
"aov_list": [],
|
||||
"additional_options": []
|
||||
},
|
||||
"renderman_renderer": {
|
||||
"image_prefix": "<layer>{aov_separator}<aov>.<f4>.<ext>",
|
||||
"image_dir": "<scene>/<layer>",
|
||||
"display_filters": [],
|
||||
"imageDisplay_dir": "<imagedir>/<layer>{aov_separator}imageDisplayFilter.<f4>.<ext>",
|
||||
"sample_filters": [],
|
||||
"cryptomatte_dir": "<imagedir>/<layer>{aov_separator}cryptomatte.<f4>.<ext>",
|
||||
"watermark_dir": "<imagedir>/<layer>{aov_separator}watermarkFilter.<f4>.<ext>",
|
||||
"additional_options": []
|
||||
}
|
||||
}
|
||||
43
server_addon/maya/server/settings/scriptsmenu.py
Normal file
43
server_addon/maya/server/settings/scriptsmenu.py
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
from pydantic import Field
|
||||
|
||||
from ayon_server.settings import BaseSettingsModel
|
||||
|
||||
|
||||
class ScriptsmenuSubmodel(BaseSettingsModel):
|
||||
"""Item Definition"""
|
||||
_isGroup = True
|
||||
type: str = Field(title="Type")
|
||||
command: str = Field(title="Command")
|
||||
sourcetype: str = Field(title="Source Type")
|
||||
title: str = Field(title="Title")
|
||||
tooltip: str = Field(title="Tooltip")
|
||||
tags: list[str] = Field(default_factory=list, title="A list of tags")
|
||||
|
||||
|
||||
class ScriptsmenuModel(BaseSettingsModel):
|
||||
_isGroup = True
|
||||
|
||||
name: str = Field(title="Menu Name")
|
||||
definition: list[ScriptsmenuSubmodel] = Field(
|
||||
default_factory=list,
|
||||
title="Menu Definition",
|
||||
description="Scriptmenu Items Definition"
|
||||
)
|
||||
|
||||
|
||||
DEFAULT_SCRIPTSMENU_SETTINGS = {
|
||||
"name": "OpenPype Tools",
|
||||
"definition": [
|
||||
{
|
||||
"type": "action",
|
||||
"command": "import openpype.hosts.maya.api.commands as op_cmds; op_cmds.edit_shader_definitions()",
|
||||
"sourcetype": "python",
|
||||
"title": "Edit shader name definitions",
|
||||
"tooltip": "Edit shader name definitions used in validation and renaming.",
|
||||
"tags": [
|
||||
"pipeline",
|
||||
"shader"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
from pydantic import Field
|
||||
from ayon_server.settings import BaseSettingsModel, task_types_enum
|
||||
|
||||
|
||||
class WorkfileBuildProfilesModel(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
task_types: list[str] = Field(
|
||||
default_factory=list,
|
||||
title="Task types",
|
||||
enum_resolver=task_types_enum
|
||||
)
|
||||
task_names: list[str] = Field(default_factory=list, title="Task names")
|
||||
path: str = Field("", title="Path to template")
|
||||
|
||||
|
||||
class TemplatedProfilesModel(BaseSettingsModel):
|
||||
profiles: list[WorkfileBuildProfilesModel] = Field(
|
||||
default_factory=list,
|
||||
title="Profiles"
|
||||
)
|
||||
|
||||
|
||||
DEFAULT_TEMPLATED_WORKFILE_SETTINGS = {
|
||||
"profiles": []
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue