mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 12:54:40 +01:00
Merge branch 'develop' into enhancement/OP-7630_DCC-connection-timeout
This commit is contained in:
commit
0c24c12075
206 changed files with 1980 additions and 3202 deletions
102
.github/pr-glob-labeler.yml
vendored
Normal file
102
.github/pr-glob-labeler.yml
vendored
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
# Add type: unittest label if any changes in tests folders
|
||||
'type: unittest':
|
||||
- '*/*tests*/**/*'
|
||||
|
||||
# any changes in documentation structure
|
||||
'type: documentation':
|
||||
- '*/**/*website*/**/*'
|
||||
- '*/**/*docs*/**/*'
|
||||
|
||||
# hosts triage
|
||||
'host: Nuke':
|
||||
- '*/**/*nuke*'
|
||||
- '*/**/*nuke*/**/*'
|
||||
|
||||
'host: Photoshop':
|
||||
- '*/**/*photoshop*'
|
||||
- '*/**/*photoshop*/**/*'
|
||||
|
||||
'host: Harmony':
|
||||
- '*/**/*harmony*'
|
||||
- '*/**/*harmony*/**/*'
|
||||
|
||||
'host: UE':
|
||||
- '*/**/*unreal*'
|
||||
- '*/**/*unreal*/**/*'
|
||||
|
||||
'host: Houdini':
|
||||
- '*/**/*houdini*'
|
||||
- '*/**/*houdini*/**/*'
|
||||
|
||||
'host: Maya':
|
||||
- '*/**/*maya*'
|
||||
- '*/**/*maya*/**/*'
|
||||
|
||||
'host: Resolve':
|
||||
- '*/**/*resolve*'
|
||||
- '*/**/*resolve*/**/*'
|
||||
|
||||
'host: Blender':
|
||||
- '*/**/*blender*'
|
||||
- '*/**/*blender*/**/*'
|
||||
|
||||
'host: Hiero':
|
||||
- '*/**/*hiero*'
|
||||
- '*/**/*hiero*/**/*'
|
||||
|
||||
'host: Fusion':
|
||||
- '*/**/*fusion*'
|
||||
- '*/**/*fusion*/**/*'
|
||||
|
||||
'host: Flame':
|
||||
- '*/**/*flame*'
|
||||
- '*/**/*flame*/**/*'
|
||||
|
||||
'host: TrayPublisher':
|
||||
- '*/**/*traypublisher*'
|
||||
- '*/**/*traypublisher*/**/*'
|
||||
|
||||
'host: 3dsmax':
|
||||
- '*/**/*max*'
|
||||
- '*/**/*max*/**/*'
|
||||
|
||||
'host: TV Paint':
|
||||
- '*/**/*tvpaint*'
|
||||
- '*/**/*tvpaint*/**/*'
|
||||
|
||||
'host: CelAction':
|
||||
- '*/**/*celaction*'
|
||||
- '*/**/*celaction*/**/*'
|
||||
|
||||
'host: After Effects':
|
||||
- '*/**/*aftereffects*'
|
||||
- '*/**/*aftereffects*/**/*'
|
||||
|
||||
'host: Substance Painter':
|
||||
- '*/**/*substancepainter*'
|
||||
- '*/**/*substancepainter*/**/*'
|
||||
|
||||
# modules triage
|
||||
'module: Deadline':
|
||||
- '*/**/*deadline*'
|
||||
- '*/**/*deadline*/**/*'
|
||||
|
||||
'module: RoyalRender':
|
||||
- '*/**/*royalrender*'
|
||||
- '*/**/*royalrender*/**/*'
|
||||
|
||||
'module: Sitesync':
|
||||
- '*/**/*sync_server*'
|
||||
- '*/**/*sync_server*/**/*'
|
||||
|
||||
'module: Ftrack':
|
||||
- '*/**/*ftrack*'
|
||||
- '*/**/*ftrack*/**/*'
|
||||
|
||||
'module: Shotgrid':
|
||||
- '*/**/*shotgrid*'
|
||||
- '*/**/*shotgrid*/**/*'
|
||||
|
||||
'module: Kitsu':
|
||||
- '*/**/*kitsu*'
|
||||
- '*/**/*kitsu*/**/*'
|
||||
|
|
@ -788,6 +788,7 @@ class AddonsManager:
|
|||
|
||||
addon_classes.append(modules_item)
|
||||
|
||||
aliased_names = []
|
||||
for addon_cls in addon_classes:
|
||||
name = addon_cls.__name__
|
||||
if issubclass(addon_cls, OpenPypeModule):
|
||||
|
|
@ -807,6 +808,13 @@ class AddonsManager:
|
|||
self._addons.append(addon)
|
||||
self._addons_by_id[addon.id] = addon
|
||||
self._addons_by_name[addon.name] = addon
|
||||
# NOTE This will be removed with release 1.0.0 of ayon-core
|
||||
# please use carefully.
|
||||
# Gives option to use alias name for addon for cases when
|
||||
# name in OpenPype was not the same as in AYON.
|
||||
name_alias = getattr(addon, "openpype_alias", None)
|
||||
if name_alias:
|
||||
aliased_names.append((name_alias, addon))
|
||||
enabled_str = "X"
|
||||
if not addon.enabled:
|
||||
enabled_str = " "
|
||||
|
|
@ -822,6 +830,17 @@ class AddonsManager:
|
|||
exc_info=True
|
||||
)
|
||||
|
||||
for item in aliased_names:
|
||||
name_alias, addon = item
|
||||
if name_alias not in self._addons_by_name:
|
||||
self._addons_by_name[name_alias] = addon
|
||||
continue
|
||||
self.log.warning(
|
||||
"Alias name '{}' of addon '{}' is already assigned.".format(
|
||||
name_alias, addon.name
|
||||
)
|
||||
)
|
||||
|
||||
if self._report is not None:
|
||||
report[self._report_total_key] = time.time() - time_start
|
||||
self._report["Initialization"] = report
|
||||
|
|
|
|||
|
|
@ -73,6 +73,20 @@ class Commands:
|
|||
import pyblish.api
|
||||
import pyblish.util
|
||||
|
||||
# Fix older jobs
|
||||
for src_key, dst_key in (
|
||||
("AVALON_PROJECT", "AYON_PROJECT_NAME"),
|
||||
("AVALON_ASSET", "AYON_FOLDER_PATH"),
|
||||
("AVALON_TASK", "AYON_TASK_NAME"),
|
||||
("AVALON_WORKDIR", "AYON_WORKDIR"),
|
||||
("AVALON_APP_NAME", "AYON_APP_NAME"),
|
||||
("AVALON_APP", "AYON_HOST_NAME"),
|
||||
):
|
||||
if src_key in os.environ and dst_key not in os.environ:
|
||||
os.environ[dst_key] = os.environ[src_key]
|
||||
# Remove old keys, so we're sure they're not used
|
||||
os.environ.pop(src_key, None)
|
||||
|
||||
log = Logger.get_logger("CLI-publish")
|
||||
|
||||
install_ayon_plugins()
|
||||
|
|
@ -87,7 +101,7 @@ class Commands:
|
|||
if not any(paths):
|
||||
raise RuntimeError("No publish paths specified")
|
||||
|
||||
app_full_name = os.getenv("AVALON_APP_NAME")
|
||||
app_full_name = os.getenv("AYON_APP_NAME")
|
||||
if app_full_name:
|
||||
context = get_global_context()
|
||||
env = get_app_environments_for_context(
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ class CreateWorkdirExtraFolders(PreLaunchHook):
|
|||
return
|
||||
|
||||
env = self.data.get("env") or {}
|
||||
workdir = env.get("AVALON_WORKDIR")
|
||||
workdir = env.get("AYON_WORKDIR")
|
||||
if not workdir or not os.path.exists(workdir):
|
||||
return
|
||||
|
||||
|
|
|
|||
|
|
@ -92,8 +92,8 @@ class HostDirmap(object):
|
|||
|
||||
self.on_enable_dirmap()
|
||||
|
||||
for k, sp in enumerate(mapping["source-path"]):
|
||||
dst = mapping["destination-path"][k]
|
||||
for k, sp in enumerate(mapping["source_path"]):
|
||||
dst = mapping["destination_path"][k]
|
||||
try:
|
||||
# add trailing slash if missing
|
||||
sp = os.path.join(sp, '')
|
||||
|
|
@ -116,7 +116,7 @@ class HostDirmap(object):
|
|||
continue
|
||||
|
||||
def get_mappings(self):
|
||||
"""Get translation from source-path to destination-path.
|
||||
"""Get translation from source_path to destination_path.
|
||||
|
||||
It checks if Site Sync is enabled and user chose to use local
|
||||
site, in that case configuration in Local Settings takes precedence
|
||||
|
|
@ -138,8 +138,8 @@ class HostDirmap(object):
|
|||
|
||||
if (
|
||||
not mapping
|
||||
or not mapping.get("destination-path")
|
||||
or not mapping.get("source-path")
|
||||
or not mapping.get("destination_path")
|
||||
or not mapping.get("source_path")
|
||||
):
|
||||
return {}
|
||||
self.log.info("Processing directory mapping ...")
|
||||
|
|
@ -154,7 +154,7 @@ class HostDirmap(object):
|
|||
in Local Settings.
|
||||
|
||||
Returns:
|
||||
dict : { "source-path": [XXX], "destination-path": [YYYY]}
|
||||
dict : { "source_path": [XXX], "destination_path": [YYYY]}
|
||||
"""
|
||||
project_name = self.project_name
|
||||
|
||||
|
|
@ -210,13 +210,13 @@ class HostDirmap(object):
|
|||
continue
|
||||
|
||||
if os.path.isdir(active_site_dir):
|
||||
if "destination-path" not in mapping:
|
||||
mapping["destination-path"] = []
|
||||
mapping["destination-path"].append(active_site_dir)
|
||||
if "destination_path" not in mapping:
|
||||
mapping["destination_path"] = []
|
||||
mapping["destination_path"].append(active_site_dir)
|
||||
|
||||
if "source-path" not in mapping:
|
||||
mapping["source-path"] = []
|
||||
mapping["source-path"].append(remote_site_dir)
|
||||
if "source_path" not in mapping:
|
||||
mapping["source_path"] = []
|
||||
mapping["source_path"].append(remote_site_dir)
|
||||
|
||||
self.log.debug("local sync mapping:: {}".format(mapping))
|
||||
return mapping
|
||||
|
|
|
|||
|
|
@ -49,7 +49,6 @@ class HostBase(object):
|
|||
Todo:
|
||||
- move content of 'install_host' as method of this class
|
||||
- register host object
|
||||
- install legacy_io
|
||||
- install global plugin paths
|
||||
- store registered plugin paths to this object
|
||||
- handle current context (project, asset, task)
|
||||
|
|
@ -107,7 +106,7 @@ class HostBase(object):
|
|||
Union[str, None]: Current project name.
|
||||
"""
|
||||
|
||||
return os.environ.get("AVALON_PROJECT")
|
||||
return os.environ.get("AYON_PROJECT_NAME")
|
||||
|
||||
def get_current_asset_name(self):
|
||||
"""
|
||||
|
|
@ -115,7 +114,7 @@ class HostBase(object):
|
|||
Union[str, None]: Current asset name.
|
||||
"""
|
||||
|
||||
return os.environ.get("AVALON_ASSET")
|
||||
return os.environ.get("AYON_FOLDER_PATH")
|
||||
|
||||
def get_current_task_name(self):
|
||||
"""
|
||||
|
|
@ -123,7 +122,7 @@ class HostBase(object):
|
|||
Union[str, None]: Current task name.
|
||||
"""
|
||||
|
||||
return os.environ.get("AVALON_TASK")
|
||||
return os.environ.get("AYON_TASK_NAME")
|
||||
|
||||
def get_current_context(self):
|
||||
"""Get current context information.
|
||||
|
|
@ -133,8 +132,6 @@ class HostBase(object):
|
|||
can be opened multiple workfiles at one moment and change of context
|
||||
can't be caught properly.
|
||||
|
||||
Default implementation returns values from 'legacy_io.Session'.
|
||||
|
||||
Returns:
|
||||
Dict[str, Union[str, None]]: Context with 3 keys 'project_name',
|
||||
'asset_name' and 'task_name'. All of them can be 'None'.
|
||||
|
|
|
|||
|
|
@ -234,7 +234,7 @@ class IWorkfileHost:
|
|||
str: Path to new workdir.
|
||||
"""
|
||||
|
||||
return session["AVALON_WORKDIR"]
|
||||
return session["AYON_WORKDIR"]
|
||||
|
||||
# --- Deprecated method names ---
|
||||
def file_extensions(self):
|
||||
|
|
|
|||
|
|
@ -15,9 +15,8 @@ from wsrpc_aiohttp import (
|
|||
|
||||
from qtpy import QtCore
|
||||
|
||||
from ayon_core.lib import Logger
|
||||
from ayon_core.tests.lib import is_in_tests
|
||||
from ayon_core.pipeline import install_host, legacy_io
|
||||
from ayon_core.lib import Logger, is_in_tests
|
||||
from ayon_core.pipeline import install_host
|
||||
from ayon_core.addon import AddonsManager
|
||||
from ayon_core.tools.utils import host_tools, get_ayon_qt_app
|
||||
from ayon_core.tools.adobe_webserver.app import WebServerTool
|
||||
|
|
@ -298,14 +297,11 @@ class AfterEffectsRoute(WebSocketRoute):
|
|||
log.info("Setting context change")
|
||||
log.info("project {} asset {} ".format(project, asset))
|
||||
if project:
|
||||
legacy_io.Session["AVALON_PROJECT"] = project
|
||||
os.environ["AVALON_PROJECT"] = project
|
||||
os.environ["AYON_PROJECT_NAME"] = project
|
||||
if asset:
|
||||
legacy_io.Session["AVALON_ASSET"] = asset
|
||||
os.environ["AVALON_ASSET"] = asset
|
||||
os.environ["AYON_FOLDER_PATH"] = asset
|
||||
if task:
|
||||
legacy_io.Session["AVALON_TASK"] = task
|
||||
os.environ["AVALON_TASK"] = task
|
||||
os.environ["AYON_TASK_NAME"] = task
|
||||
|
||||
async def read(self):
|
||||
log.debug("aftereffects.read client calls server server calls "
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ from ayon_core.host import (
|
|||
from ayon_core.client import get_asset_by_name
|
||||
from ayon_core.pipeline import (
|
||||
schema,
|
||||
legacy_io,
|
||||
get_current_project_name,
|
||||
get_current_asset_name,
|
||||
register_loader_plugin_path,
|
||||
|
|
@ -273,7 +272,7 @@ def set_resolution(data):
|
|||
|
||||
|
||||
def on_new():
|
||||
project = os.environ.get("AVALON_PROJECT")
|
||||
project = os.environ.get("AYON_PROJECT_NAME")
|
||||
settings = get_project_settings(project).get("blender")
|
||||
|
||||
set_resolution_startup = settings.get("set_resolution_startup")
|
||||
|
|
@ -294,7 +293,7 @@ def on_new():
|
|||
|
||||
|
||||
def on_open():
|
||||
project = os.environ.get("AVALON_PROJECT")
|
||||
project = os.environ.get("AYON_PROJECT_NAME")
|
||||
settings = get_project_settings(project).get("blender")
|
||||
|
||||
set_resolution_startup = settings.get("set_resolution_startup")
|
||||
|
|
@ -380,7 +379,7 @@ def _on_task_changed():
|
|||
# `directory` attribute, so it opens in that directory (does it?).
|
||||
# https://docs.blender.org/api/blender2.8/bpy.types.Operator.html#calling-a-file-selector
|
||||
# https://docs.blender.org/api/blender2.8/bpy.types.WindowManager.html#bpy.types.WindowManager.fileselect_add
|
||||
workdir = legacy_io.Session["AVALON_WORKDIR"]
|
||||
workdir = os.getenv("AYON_WORKDIR")
|
||||
log.debug("New working directory: %s", workdir)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ def file_extensions() -> List[str]:
|
|||
def work_root(session: dict) -> str:
|
||||
"""Return the default root to browse for work files."""
|
||||
|
||||
work_dir = session["AVALON_WORKDIR"]
|
||||
work_dir = session["AYON_WORKDIR"]
|
||||
scene_dir = session.get("AVALON_SCENEDIR")
|
||||
if scene_dir:
|
||||
return str(Path(work_dir, scene_dir))
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
import os
|
||||
import json
|
||||
|
||||
import clique
|
||||
import pyblish.api
|
||||
|
||||
import bpy
|
||||
|
||||
import pyblish.api
|
||||
from ayon_core.pipeline import publish
|
||||
from ayon_core.hosts.blender.api import capture
|
||||
from ayon_core.hosts.blender.api.lib import maintained_time
|
||||
|
|
@ -23,6 +25,8 @@ class ExtractPlayblast(publish.Extractor, publish.OptionalPyblishPluginMixin):
|
|||
optional = True
|
||||
order = pyblish.api.ExtractorOrder + 0.01
|
||||
|
||||
presets = "{}"
|
||||
|
||||
def process(self, instance):
|
||||
if not self.is_active(instance.data):
|
||||
return
|
||||
|
|
@ -59,8 +63,7 @@ class ExtractPlayblast(publish.Extractor, publish.OptionalPyblishPluginMixin):
|
|||
|
||||
self.log.debug(f"Outputting images to {path}")
|
||||
|
||||
project_settings = instance.context.data["project_settings"]["blender"]
|
||||
presets = project_settings["publish"]["ExtractPlayblast"]["presets"]
|
||||
presets = json.loads(self.presets)
|
||||
preset = presets.get("default")
|
||||
preset.update({
|
||||
"camera": camera,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import os
|
||||
import glob
|
||||
import json
|
||||
|
||||
import pyblish.api
|
||||
from ayon_core.pipeline import publish
|
||||
|
|
@ -21,7 +22,7 @@ class ExtractThumbnail(publish.Extractor):
|
|||
hosts = ["blender"]
|
||||
families = ["review"]
|
||||
order = pyblish.api.ExtractorOrder + 0.01
|
||||
presets = {}
|
||||
presets = "{}"
|
||||
|
||||
def process(self, instance):
|
||||
self.log.debug("Extracting capture..")
|
||||
|
|
@ -44,7 +45,8 @@ class ExtractThumbnail(publish.Extractor):
|
|||
family = instance.data.get("family")
|
||||
isolate = instance.data("isolate", None)
|
||||
|
||||
preset = self.presets.get(family, {})
|
||||
presets = json.loads(self.presets)
|
||||
preset = presets.get(family, {})
|
||||
|
||||
preset.update({
|
||||
"camera": camera,
|
||||
|
|
|
|||
|
|
@ -34,4 +34,4 @@ def current_file():
|
|||
|
||||
|
||||
def work_root(session):
|
||||
return os.path.normpath(session["AVALON_WORKDIR"]).replace("\\", "/")
|
||||
return os.path.normpath(session["AYON_WORKDIR"]).replace("\\", "/")
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ class LoadClip(opfapi.ClipLoader):
|
|||
self.log.info("Loading with colorspace: `{}`".format(colorspace))
|
||||
|
||||
# create workfile path
|
||||
workfile_dir = os.environ["AVALON_WORKDIR"]
|
||||
workfile_dir = os.environ["AYON_WORKDIR"]
|
||||
openclip_dir = os.path.join(
|
||||
workfile_dir, clip_name
|
||||
)
|
||||
|
|
|
|||
|
|
@ -50,17 +50,28 @@ class LoadClipBatch(opfapi.ClipLoader):
|
|||
version_name = version.get("name", None)
|
||||
colorspace = self.get_colorspace(context)
|
||||
|
||||
# TODO remove '{folder[name]}' and '{product[name]}' replacement
|
||||
clip_name_template = (
|
||||
self.clip_name_template
|
||||
.replace("{folder[name]}", "{asset}")
|
||||
.replace("{product[name]}", "{subset}")
|
||||
)
|
||||
layer_rename_template = (
|
||||
self.layer_rename_template
|
||||
.replace("{folder[name]}", "{asset}")
|
||||
.replace("{product[name]}", "{subset}")
|
||||
)
|
||||
# in case output is not in context replace key to representation
|
||||
if not context["representation"]["context"].get("output"):
|
||||
self.clip_name_template = self.clip_name_template.replace(
|
||||
clip_name_template = clip_name_template.replace(
|
||||
"output", "representation")
|
||||
self.layer_rename_template = self.layer_rename_template.replace(
|
||||
layer_rename_template = layer_rename_template.replace(
|
||||
"output", "representation")
|
||||
|
||||
formatting_data = deepcopy(context["representation"]["context"])
|
||||
formatting_data["batch"] = self.batch.name.get_value()
|
||||
|
||||
clip_name = StringTemplate(self.clip_name_template).format(
|
||||
clip_name = StringTemplate(clip_name_template).format(
|
||||
formatting_data)
|
||||
|
||||
# convert colorspace with ocio to flame mapping
|
||||
|
|
@ -69,7 +80,7 @@ class LoadClipBatch(opfapi.ClipLoader):
|
|||
self.log.info("Loading with colorspace: `{}`".format(colorspace))
|
||||
|
||||
# create workfile path
|
||||
workfile_dir = options.get("workdir") or os.environ["AVALON_WORKDIR"]
|
||||
workfile_dir = options.get("workdir") or os.environ["AYON_WORKDIR"]
|
||||
openclip_dir = os.path.join(
|
||||
workfile_dir, clip_name
|
||||
)
|
||||
|
|
@ -86,7 +97,7 @@ class LoadClipBatch(opfapi.ClipLoader):
|
|||
"path": path.replace("\\", "/"),
|
||||
"colorspace": colorspace,
|
||||
"version": "v{:0>3}".format(version_name),
|
||||
"layer_rename_template": self.layer_rename_template,
|
||||
"layer_rename_template": layer_rename_template,
|
||||
"layer_rename_patterns": self.layer_rename_patterns,
|
||||
"context_data": formatting_data
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import os
|
||||
import re
|
||||
import tempfile
|
||||
from copy import deepcopy
|
||||
|
||||
import pyblish.api
|
||||
|
|
@ -15,12 +14,12 @@ from ayon_core.pipeline.editorial import (
|
|||
import flame
|
||||
|
||||
|
||||
class ExtractSubsetResources(publish.Extractor):
|
||||
class ExtractProductResources(publish.Extractor):
|
||||
"""
|
||||
Extractor for transcoding files from Flame clip
|
||||
"""
|
||||
|
||||
label = "Extract subset resources"
|
||||
label = "Extract product resources"
|
||||
order = pyblish.api.ExtractorOrder
|
||||
families = ["clip"]
|
||||
hosts = ["flame"]
|
||||
|
|
@ -47,7 +46,7 @@ class ExtractSubsetResources(publish.Extractor):
|
|||
hide_ui_on_process = True
|
||||
|
||||
# settings
|
||||
export_presets_mapping = {}
|
||||
export_presets_mapping = []
|
||||
|
||||
def process(self, instance):
|
||||
if not self.keep_original_representation:
|
||||
|
|
@ -146,15 +145,21 @@ class ExtractSubsetResources(publish.Extractor):
|
|||
# append staging dir for later cleanup
|
||||
instance.context.data["cleanupFullPaths"].append(staging_dir)
|
||||
|
||||
export_presets_mapping = {}
|
||||
for preset_mapping in deepcopy(self.export_presets_mapping):
|
||||
name = preset_mapping.pop("name")
|
||||
export_presets_mapping[name] = preset_mapping
|
||||
|
||||
# add default preset type for thumbnail and reviewable video
|
||||
# update them with settings and override in case the same
|
||||
# are found in there
|
||||
_preset_keys = [k.split('_')[0] for k in self.export_presets_mapping]
|
||||
_preset_keys = [k.split('_')[0] for k in export_presets_mapping]
|
||||
export_presets = {
|
||||
k: v for k, v in deepcopy(self.default_presets).items()
|
||||
k: v
|
||||
for k, v in deepcopy(self.default_presets).items()
|
||||
if k not in _preset_keys
|
||||
}
|
||||
export_presets.update(self.export_presets_mapping)
|
||||
export_presets.update(export_presets_mapping)
|
||||
|
||||
if not instance.data.get("versionData"):
|
||||
instance.data["versionData"] = {}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ def get_fusion_version(app_name):
|
|||
The function is triggered by the prelaunch hooks to get the fusion version.
|
||||
|
||||
`app_name` is obtained by prelaunch hooks from the
|
||||
`launch_context.env.get("AVALON_APP_NAME")`.
|
||||
`launch_context.env.get("AYON_APP_NAME")`.
|
||||
|
||||
To get a correct Fusion version, a version number should be present
|
||||
in the `applications/fusion/variants` key
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ class FusionHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost):
|
|||
return current_filepath
|
||||
|
||||
def work_root(self, session):
|
||||
work_dir = session["AVALON_WORKDIR"]
|
||||
work_dir = session["AYON_WORKDIR"]
|
||||
scene_dir = session.get("AVALON_SCENEDIR")
|
||||
if scene_dir:
|
||||
return os.path.join(work_dir, scene_dir)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ from ayon_core.lib import (
|
|||
EnumDef,
|
||||
)
|
||||
from ayon_core.pipeline import (
|
||||
legacy_io,
|
||||
Creator,
|
||||
CreatedInstance
|
||||
)
|
||||
|
|
@ -136,7 +135,7 @@ class GenericCreateSaver(Creator):
|
|||
ext = data["creator_attributes"]["image_format"]
|
||||
|
||||
# Subset change detected
|
||||
workdir = os.path.normpath(legacy_io.Session["AVALON_WORKDIR"])
|
||||
workdir = os.path.normpath(os.getenv("AYON_WORKDIR"))
|
||||
formatting_data.update({
|
||||
"workdir": workdir,
|
||||
"frame": "0" * frame_padding,
|
||||
|
|
@ -148,7 +147,16 @@ class GenericCreateSaver(Creator):
|
|||
})
|
||||
|
||||
# build file path to render
|
||||
filepath = self.temp_rendering_path_template.format(**formatting_data)
|
||||
# TODO make sure the keys are available in 'formatting_data'
|
||||
temp_rendering_path_template = (
|
||||
self.temp_rendering_path_template
|
||||
.replace("{product[name]}", "{subset}")
|
||||
.replace("{product[type]}", "{family}")
|
||||
.replace("{folder[name]}", "{asset}")
|
||||
.replace("{task[name]}", "{task}")
|
||||
)
|
||||
|
||||
filepath = temp_rendering_path_template.format(**formatting_data)
|
||||
|
||||
comp = get_current_comp()
|
||||
tool["Clip"] = comp.ReverseMapPath(os.path.normpath(filepath))
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook):
|
|||
) = self.get_copy_fusion_prefs_settings()
|
||||
|
||||
# Get launched application context and return correct app version
|
||||
app_name = self.launch_context.env.get("AVALON_APP_NAME")
|
||||
app_name = self.launch_context.env.get("AYON_APP_NAME")
|
||||
app_version = get_fusion_version(app_name)
|
||||
if app_version is None:
|
||||
version_names = ", ".join(str(x) for x in FUSION_VERSIONS_DICT)
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class FusionPrelaunch(PreLaunchHook):
|
|||
def execute(self):
|
||||
# making sure python 3 is installed at provided path
|
||||
# Py 3.3-3.10 for Fusion 18+ or Py 3.6 for Fu 16-17
|
||||
app_data = self.launch_context.env.get("AVALON_APP_NAME")
|
||||
app_data = self.launch_context.env.get("AYON_APP_NAME")
|
||||
app_version = get_fusion_version(app_data)
|
||||
if not app_version:
|
||||
raise ApplicationLaunchFailed(
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ Because Harmony projects are directories, this integration uses `.zip` as work f
|
|||
|
||||
### Show Workfiles on launch
|
||||
|
||||
You can show the Workfiles app when Harmony launches by setting environment variable `AVALON_HARMONY_WORKFILES_ON_LAUNCH=1`.
|
||||
You can show the Workfiles app when Harmony launches by setting environment variable `AYON_HARMONY_WORKFILES_ON_LAUNCH=1`.
|
||||
|
||||
## Developing
|
||||
|
||||
|
|
|
|||
|
|
@ -349,7 +349,7 @@ function start() {
|
|||
/** hostname or ip of server - should be localhost */
|
||||
var host = '127.0.0.1';
|
||||
/** port of the server */
|
||||
var port = parseInt(System.getenv('AVALON_HARMONY_PORT'));
|
||||
var port = parseInt(System.getenv('AYON_HARMONY_PORT'));
|
||||
|
||||
// Attach the client to the QApplication to preserve.
|
||||
var app = QCoreApplication.instance();
|
||||
|
|
|
|||
|
|
@ -189,14 +189,14 @@ def launch(application_path, *args):
|
|||
install_host(harmony)
|
||||
|
||||
ProcessContext.port = random.randrange(49152, 65535)
|
||||
os.environ["AVALON_HARMONY_PORT"] = str(ProcessContext.port)
|
||||
os.environ["AYON_HARMONY_PORT"] = str(ProcessContext.port)
|
||||
ProcessContext.application_path = application_path
|
||||
|
||||
# Launch Harmony.
|
||||
setup_startup_scripts()
|
||||
check_libs()
|
||||
|
||||
if not os.environ.get("AVALON_HARMONY_WORKFILES_ON_LAUNCH", False):
|
||||
if not os.environ.get("AYON_HARMONY_WORKFILES_ON_LAUNCH", False):
|
||||
open_empty_workfile()
|
||||
return
|
||||
|
||||
|
|
|
|||
|
|
@ -74,4 +74,4 @@ def current_file():
|
|||
|
||||
|
||||
def work_root(session):
|
||||
return os.path.normpath(session["AVALON_WORKDIR"]).replace("\\", "/")
|
||||
return os.path.normpath(session["AYON_WORKDIR"]).replace("\\", "/")
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ class ValidateSceneSettings(pyblish.api.InstancePlugin):
|
|||
expected_settings.pop("resolutionWidth")
|
||||
expected_settings.pop("resolutionHeight")
|
||||
|
||||
if (any(re.search(pattern, os.getenv('AVALON_TASK'))
|
||||
if (any(re.search(pattern, os.getenv('AYON_TASK_NAME'))
|
||||
for pattern in self.skip_timelines_check)):
|
||||
self.log.info("Skipping frames check because of "
|
||||
"task name and pattern {}".format(
|
||||
|
|
|
|||
|
|
@ -70,4 +70,4 @@ def current_file():
|
|||
|
||||
|
||||
def work_root(session):
|
||||
return os.path.normpath(session["AVALON_WORKDIR"]).replace("\\", "/")
|
||||
return os.path.normpath(session["AYON_WORKDIR"]).replace("\\", "/")
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ from qtpy import QtWidgets, QtCore, QtGui
|
|||
|
||||
from ayon_core import style
|
||||
from ayon_core.client import get_asset_by_name
|
||||
from ayon_core.pipeline import legacy_io, get_current_project_name
|
||||
from ayon_core.pipeline import get_current_project_name
|
||||
from ayon_core.tools.utils.assets_widget import SingleSelectAssetsWidget
|
||||
|
||||
from pxr import Sdf
|
||||
|
|
@ -27,7 +27,8 @@ class SelectAssetDialog(QtWidgets.QWidget):
|
|||
self.setWindowTitle("Pick Asset")
|
||||
self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.Popup)
|
||||
|
||||
assets_widget = SingleSelectAssetsWidget(legacy_io, parent=self)
|
||||
assets_widget = SingleSelectAssetsWidget(self)
|
||||
assets_widget.set_project_name(get_current_project_name(), False)
|
||||
|
||||
layout = QtWidgets.QHBoxLayout(self)
|
||||
layout.addWidget(assets_widget)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ class SetPath(PreLaunchHook):
|
|||
launch_types = {LaunchTypes.local}
|
||||
|
||||
def execute(self):
|
||||
workdir = self.launch_context.env.get("AVALON_WORKDIR", "")
|
||||
workdir = self.launch_context.env.get("AYON_WORKDIR", "")
|
||||
if not workdir:
|
||||
self.log.warning("BUG: Workdir is not filled.")
|
||||
return
|
||||
|
|
|
|||
|
|
@ -63,9 +63,8 @@ class MaxHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost):
|
|||
rt.callbacks.addScript(rt.Name('postWorkspaceChange'),
|
||||
self._deferred_menu_creation)
|
||||
|
||||
def has_unsaved_changes(self):
|
||||
# TODO: how to get it from 3dsmax?
|
||||
return True
|
||||
def workfile_has_unsaved_changes(self):
|
||||
return rt.getSaveRequired()
|
||||
|
||||
def get_workfile_extensions(self):
|
||||
return [".max"]
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ class SetPath(PreLaunchHook):
|
|||
launch_types = {LaunchTypes.local}
|
||||
|
||||
def execute(self):
|
||||
workdir = self.launch_context.env.get("AVALON_WORKDIR", "")
|
||||
workdir = self.launch_context.env.get("AYON_WORKDIR", "")
|
||||
if not workdir:
|
||||
self.log.warning("BUG: Workdir is not filled.")
|
||||
return
|
||||
|
|
|
|||
|
|
@ -155,7 +155,9 @@ class ExtractPointCloud(publish.Extractor):
|
|||
|
||||
custom_attr_list = []
|
||||
attr_settings = self.settings["attribute"]
|
||||
for key, value in attr_settings.items():
|
||||
for attr in attr_settings:
|
||||
key = attr["name"]
|
||||
value = attr["value"]
|
||||
custom_attr = "{0}.PRTChannels_{1}=True".format(operator,
|
||||
value)
|
||||
self.log.debug(
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
import pyblish.api
|
||||
import os
|
||||
from ayon_core.pipeline import registered_host
|
||||
|
||||
|
||||
class SaveCurrentScene(pyblish.api.ContextPlugin):
|
||||
"""Save current scene
|
||||
|
||||
"""
|
||||
"""Save current scene"""
|
||||
|
||||
label = "Save current file"
|
||||
order = pyblish.api.ExtractorOrder - 0.49
|
||||
|
|
@ -13,9 +11,13 @@ class SaveCurrentScene(pyblish.api.ContextPlugin):
|
|||
families = ["maxrender", "workfile"]
|
||||
|
||||
def process(self, context):
|
||||
from pymxs import runtime as rt
|
||||
folder = rt.maxFilePath
|
||||
file = rt.maxFileName
|
||||
current = os.path.join(folder, file)
|
||||
assert context.data["currentFile"] == current
|
||||
rt.saveMaxFile(current)
|
||||
host = registered_host()
|
||||
current_file = host.get_current_workfile()
|
||||
|
||||
assert context.data["currentFile"] == current_file
|
||||
|
||||
if host.workfile_has_unsaved_changes():
|
||||
self.log.info(f"Saving current file: {current_file}")
|
||||
host.save_workfile(current_file)
|
||||
else:
|
||||
self.log.debug("No unsaved changes, skipping file save..")
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Validator for Attributes."""
|
||||
import json
|
||||
|
||||
from pyblish.api import ContextPlugin, ValidatorOrder
|
||||
from pymxs import runtime as rt
|
||||
|
||||
|
|
@ -61,9 +63,13 @@ class ValidateAttributes(OptionalPyblishPluginMixin,
|
|||
|
||||
@classmethod
|
||||
def get_invalid(cls, context):
|
||||
attributes = (
|
||||
context.data["project_settings"]["max"]["publish"]
|
||||
["ValidateAttributes"]["attributes"]
|
||||
attributes = json.loads(
|
||||
context.data
|
||||
["project_settings"]
|
||||
["max"]
|
||||
["publish"]
|
||||
["ValidateAttributes"]
|
||||
["attributes"]
|
||||
)
|
||||
if not attributes:
|
||||
return
|
||||
|
|
@ -112,9 +118,13 @@ class ValidateAttributes(OptionalPyblishPluginMixin,
|
|||
|
||||
@classmethod
|
||||
def repair(cls, context):
|
||||
attributes = (
|
||||
context.data["project_settings"]["max"]["publish"]
|
||||
["ValidateAttributes"]["attributes"]
|
||||
attributes = json.loads(
|
||||
context.data
|
||||
["project_settings"]
|
||||
["max"]
|
||||
["publish"]
|
||||
["ValidateAttributes"]
|
||||
["attributes"]
|
||||
)
|
||||
invalid_attributes = cls.get_invalid(context)
|
||||
for attrs in invalid_attributes:
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin,
|
|||
optional = True
|
||||
actions = [RepairAction]
|
||||
|
||||
family_plugins_mapping = {}
|
||||
family_plugins_mapping = []
|
||||
|
||||
@classmethod
|
||||
def get_invalid(cls, instance):
|
||||
|
|
@ -34,6 +34,12 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin,
|
|||
if not family_plugins_mapping:
|
||||
return
|
||||
|
||||
# Backward compatibility - settings did have 'product_types'
|
||||
if "product_types" in family_plugins_mapping:
|
||||
family_plugins_mapping["families"] = family_plugins_mapping.pop(
|
||||
"product_types"
|
||||
)
|
||||
|
||||
invalid = []
|
||||
# Find all plug-in requirements for current instance
|
||||
instance_families = {instance.data["family"]}
|
||||
|
|
@ -47,7 +53,9 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin,
|
|||
if not mapping:
|
||||
return
|
||||
|
||||
match_families = {fam.strip() for fam in mapping["families"]}
|
||||
match_families = {
|
||||
fam.strip() for fam in mapping["families"]
|
||||
}
|
||||
has_match = "*" in match_families or match_families.intersection(
|
||||
instance_families)
|
||||
|
||||
|
|
|
|||
|
|
@ -59,7 +59,9 @@ class ValidatePointCloud(pyblish.api.InstancePlugin):
|
|||
event_name = sub_anim.name
|
||||
opt = "${0}.{1}.export_particles".format(sel.name,
|
||||
event_name)
|
||||
for key, value in attr_settings.items():
|
||||
for attr in attr_settings:
|
||||
key = attr["name"]
|
||||
value = attr["value"]
|
||||
custom_attr = "{0}.PRTChannels_{1}".format(opt,
|
||||
value)
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -8,5 +8,8 @@
|
|||
local pythonpath = systemTools.getEnvVariable "MAX_PYTHONPATH"
|
||||
systemTools.setEnvVariable "PYTHONPATH" pythonpath
|
||||
|
||||
/*opens the create menu on startup to ensure users are presented with a useful default view.*/
|
||||
max create mode
|
||||
|
||||
python.ExecuteFile startup
|
||||
)
|
||||
|
|
@ -329,7 +329,7 @@ def generate_capture_preset(instance, camera, path,
|
|||
|
||||
# Update preset with current panel setting
|
||||
# if override_viewport_options is turned off
|
||||
if not capture_preset["Viewport Options"]["override_viewport_options"]:
|
||||
if not capture_preset["ViewportOptions"]["override_viewport_options"]:
|
||||
panel_preset = capture.parse_view(preset["panel"])
|
||||
panel_preset.pop("camera")
|
||||
preset.update(panel_preset)
|
||||
|
|
@ -2937,14 +2937,15 @@ def load_capture_preset(data):
|
|||
options.update(data["Generic"])
|
||||
options.update(data["Resolution"])
|
||||
|
||||
camera_options.update(data['Camera Options'])
|
||||
camera_options.update(data["CameraOptions"])
|
||||
viewport_options.update(data["Renderer"])
|
||||
|
||||
# DISPLAY OPTIONS
|
||||
disp_options = {}
|
||||
for key, value in data['Display Options'].items():
|
||||
if key.startswith('background'):
|
||||
for key, value in data["DisplayOptions"].items():
|
||||
if key.startswith("background"):
|
||||
# Convert background, backgroundTop, backgroundBottom colors
|
||||
|
||||
if len(value) == 4:
|
||||
# Ignore alpha + convert RGB to float
|
||||
value = [
|
||||
|
|
@ -2956,7 +2957,7 @@ def load_capture_preset(data):
|
|||
elif key == "displayGradient":
|
||||
disp_options[key] = value
|
||||
|
||||
options['display_options'] = disp_options
|
||||
options["display_options"] = disp_options
|
||||
|
||||
# Viewport Options has a mixture of Viewport2 Options and Viewport Options
|
||||
# to pass along to capture. So we'll need to differentiate between the two
|
||||
|
|
@ -2981,7 +2982,7 @@ def load_capture_preset(data):
|
|||
"motionBlurShutterOpenFraction",
|
||||
"lineAAEnable"
|
||||
}
|
||||
for key, value in data['Viewport Options'].items():
|
||||
for key, value in data["ViewportOptions"].items():
|
||||
|
||||
# There are some keys we want to ignore
|
||||
if key in {"override_viewport_options", "high_quality"}:
|
||||
|
|
@ -3140,119 +3141,6 @@ def fix_incompatible_containers():
|
|||
"ReferenceLoader", type="string")
|
||||
|
||||
|
||||
def _null(*args):
|
||||
pass
|
||||
|
||||
|
||||
class shelf():
|
||||
'''A simple class to build shelves in maya. Since the build method is empty,
|
||||
it should be extended by the derived class to build the necessary shelf
|
||||
elements. By default it creates an empty shelf called "customShelf".'''
|
||||
|
||||
###########################################################################
|
||||
'''This is an example shelf.'''
|
||||
# class customShelf(_shelf):
|
||||
# def build(self):
|
||||
# self.addButon(label="button1")
|
||||
# self.addButon("button2")
|
||||
# self.addButon("popup")
|
||||
# p = cmds.popupMenu(b=1)
|
||||
# self.addMenuItem(p, "popupMenuItem1")
|
||||
# self.addMenuItem(p, "popupMenuItem2")
|
||||
# sub = self.addSubMenu(p, "subMenuLevel1")
|
||||
# self.addMenuItem(sub, "subMenuLevel1Item1")
|
||||
# sub2 = self.addSubMenu(sub, "subMenuLevel2")
|
||||
# self.addMenuItem(sub2, "subMenuLevel2Item1")
|
||||
# self.addMenuItem(sub2, "subMenuLevel2Item2")
|
||||
# self.addMenuItem(sub, "subMenuLevel1Item2")
|
||||
# self.addMenuItem(p, "popupMenuItem3")
|
||||
# self.addButon("button3")
|
||||
# customShelf()
|
||||
###########################################################################
|
||||
|
||||
def __init__(self, name="customShelf", iconPath="", preset={}):
|
||||
self.name = name
|
||||
|
||||
self.iconPath = iconPath
|
||||
|
||||
self.labelBackground = (0, 0, 0, 0)
|
||||
self.labelColour = (.9, .9, .9)
|
||||
|
||||
self.preset = preset
|
||||
|
||||
self._cleanOldShelf()
|
||||
cmds.setParent(self.name)
|
||||
self.build()
|
||||
|
||||
def build(self):
|
||||
'''This method should be overwritten in derived classes to actually
|
||||
build the shelf elements. Otherwise, nothing is added to the shelf.'''
|
||||
for item in self.preset['items']:
|
||||
if not item.get('command'):
|
||||
item['command'] = self._null
|
||||
if item['type'] == 'button':
|
||||
self.addButon(item['name'],
|
||||
command=item['command'],
|
||||
icon=item['icon'])
|
||||
if item['type'] == 'menuItem':
|
||||
self.addMenuItem(item['parent'],
|
||||
item['name'],
|
||||
command=item['command'],
|
||||
icon=item['icon'])
|
||||
if item['type'] == 'subMenu':
|
||||
self.addMenuItem(item['parent'],
|
||||
item['name'],
|
||||
command=item['command'],
|
||||
icon=item['icon'])
|
||||
|
||||
def addButon(self, label, icon="commandButton.png",
|
||||
command=_null, doubleCommand=_null):
|
||||
'''
|
||||
Adds a shelf button with the specified label, command,
|
||||
double click command and image.
|
||||
'''
|
||||
cmds.setParent(self.name)
|
||||
if icon:
|
||||
icon = os.path.join(self.iconPath, icon)
|
||||
print(icon)
|
||||
cmds.shelfButton(width=37, height=37, image=icon, label=label,
|
||||
command=command, dcc=doubleCommand,
|
||||
imageOverlayLabel=label, olb=self.labelBackground,
|
||||
olc=self.labelColour)
|
||||
|
||||
def addMenuItem(self, parent, label, command=_null, icon=""):
|
||||
'''
|
||||
Adds a shelf button with the specified label, command,
|
||||
double click command and image.
|
||||
'''
|
||||
if icon:
|
||||
icon = os.path.join(self.iconPath, icon)
|
||||
print(icon)
|
||||
return cmds.menuItem(p=parent, label=label, c=command, i="")
|
||||
|
||||
def addSubMenu(self, parent, label, icon=None):
|
||||
'''
|
||||
Adds a sub menu item with the specified label and icon to
|
||||
the specified parent popup menu.
|
||||
'''
|
||||
if icon:
|
||||
icon = os.path.join(self.iconPath, icon)
|
||||
print(icon)
|
||||
return cmds.menuItem(p=parent, label=label, i=icon, subMenu=1)
|
||||
|
||||
def _cleanOldShelf(self):
|
||||
'''
|
||||
Checks if the shelf exists and empties it if it does
|
||||
or creates it if it does not.
|
||||
'''
|
||||
if cmds.shelfLayout(self.name, ex=1):
|
||||
if cmds.shelfLayout(self.name, q=1, ca=1):
|
||||
for each in cmds.shelfLayout(self.name, q=1, ca=1):
|
||||
cmds.deleteUI(each)
|
||||
else:
|
||||
cmds.shelfLayout(self.name, p="ShelfLayout")
|
||||
|
||||
|
||||
def update_content_on_context_change():
|
||||
"""
|
||||
This will update scene content to match new asset on context change
|
||||
|
|
@ -4059,10 +3947,10 @@ def get_capture_preset(task_name, task_type, subset, project_settings, log):
|
|||
|
||||
Args:
|
||||
task_name (str): Task name.
|
||||
take_type (str): Task type.
|
||||
task_type (str): Task type.
|
||||
subset (str): Subset name.
|
||||
project_settings (dict): Project settings.
|
||||
log (object): Logging object.
|
||||
log (logging.Logger): Logging object.
|
||||
"""
|
||||
capture_preset = None
|
||||
filtering_criteria = {
|
||||
|
|
@ -4091,8 +3979,18 @@ def get_capture_preset(task_name, task_type, subset, project_settings, log):
|
|||
"Falling back to deprecated Extract Playblast capture preset "
|
||||
"because no new style playblast profiles are defined."
|
||||
)
|
||||
capture_preset = plugin_settings["capture_preset"]
|
||||
capture_preset = plugin_settings.get("capture_preset")
|
||||
|
||||
if capture_preset:
|
||||
# Create deepcopy of preset as we'll change the values
|
||||
capture_preset = copy.deepcopy(capture_preset)
|
||||
|
||||
viewport_options = capture_preset["ViewportOptions"]
|
||||
# Change 'list' to 'dict' for 'capture.py'
|
||||
viewport_options["pluginObjects"] = {
|
||||
item["name"]: item["value"]
|
||||
for item in viewport_options["pluginObjects"]
|
||||
}
|
||||
return capture_preset or {}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ class RenderSettings(object):
|
|||
project_settings = get_project_settings(
|
||||
get_current_project_name()
|
||||
)
|
||||
render_settings = project_settings["maya"]["RenderSettings"]
|
||||
render_settings = project_settings["maya"]["render_settings"]
|
||||
image_prefixes = {
|
||||
"vray": render_settings["vray_renderer"]["image_prefix"],
|
||||
"arnold": render_settings["arnold_renderer"]["image_prefix"],
|
||||
|
|
@ -82,12 +82,12 @@ class RenderSettings(object):
|
|||
try:
|
||||
aov_separator = self._aov_chars[(
|
||||
self._project_settings["maya"]
|
||||
["RenderSettings"]
|
||||
["render_settings"]
|
||||
["aov_separator"]
|
||||
)]
|
||||
except KeyError:
|
||||
aov_separator = "_"
|
||||
reset_frame = self._project_settings["maya"]["RenderSettings"]["reset_current_frame"] # noqa
|
||||
reset_frame = self._project_settings["maya"]["render_settings"]["reset_current_frame"] # noqa
|
||||
|
||||
if reset_frame:
|
||||
start_frame = cmds.getAttr("defaultRenderGlobals.startFrame")
|
||||
|
|
@ -131,7 +131,7 @@ class RenderSettings(object):
|
|||
import maya.mel as mel # noqa: F401
|
||||
|
||||
createOptions()
|
||||
render_settings = self._project_settings["maya"]["RenderSettings"]
|
||||
render_settings = self._project_settings["maya"]["render_settings"]
|
||||
arnold_render_presets = render_settings["arnold_renderer"] # noqa
|
||||
# Force resetting settings and AOV list to avoid having to deal with
|
||||
# AOV checking logic, for now.
|
||||
|
|
@ -180,7 +180,7 @@ class RenderSettings(object):
|
|||
from maya import cmds # noqa: F401
|
||||
import maya.mel as mel # noqa: F401
|
||||
|
||||
render_settings = self._project_settings["maya"]["RenderSettings"]
|
||||
render_settings = self._project_settings["maya"]["render_settings"]
|
||||
redshift_render_presets = render_settings["redshift_renderer"]
|
||||
|
||||
remove_aovs = render_settings["remove_aovs"]
|
||||
|
|
@ -239,7 +239,7 @@ class RenderSettings(object):
|
|||
rman_render_presets = (
|
||||
self._project_settings
|
||||
["maya"]
|
||||
["RenderSettings"]
|
||||
["render_settings"]
|
||||
["renderman_renderer"]
|
||||
)
|
||||
display_filters = rman_render_presets["display_filters"]
|
||||
|
|
@ -304,7 +304,7 @@ class RenderSettings(object):
|
|||
|
||||
settings = cmds.ls(type="VRaySettingsNode")
|
||||
node = settings[0] if settings else cmds.createNode("VRaySettingsNode")
|
||||
render_settings = self._project_settings["maya"]["RenderSettings"]
|
||||
render_settings = self._project_settings["maya"]["render_settings"]
|
||||
vray_render_presets = render_settings["vray_renderer"]
|
||||
# vrayRenderElement
|
||||
remove_aovs = render_settings["remove_aovs"]
|
||||
|
|
@ -390,7 +390,8 @@ class RenderSettings(object):
|
|||
import maya.mel as mel # noqa: F401
|
||||
|
||||
for item in additional_attribs:
|
||||
attribute, value = item
|
||||
attribute = item["attribute"]
|
||||
value = item["value"]
|
||||
attribute = str(attribute) # ensure str conversion from settings
|
||||
attribute_type = cmds.getAttr(attribute, type=True)
|
||||
if attribute_type in {"long", "bool"}:
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ import maya.cmds as cmds
|
|||
|
||||
from ayon_core.pipeline import (
|
||||
get_current_asset_name,
|
||||
get_current_task_name
|
||||
get_current_task_name,
|
||||
registered_host
|
||||
)
|
||||
from ayon_core.pipeline.workfile import BuildWorkfile
|
||||
from ayon_core.tools.utils import host_tools
|
||||
|
|
@ -21,8 +22,10 @@ from .workfile_template_builder import (
|
|||
create_placeholder,
|
||||
update_placeholder,
|
||||
build_workfile_template,
|
||||
update_workfile_template,
|
||||
update_workfile_template
|
||||
)
|
||||
from ayon_core.tools.workfile_template_build import open_template_ui
|
||||
from .workfile_template_builder import MayaTemplateBuilder
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
|
@ -167,16 +170,6 @@ def install(project_settings):
|
|||
tearOff=True,
|
||||
parent=MENU_NAME
|
||||
)
|
||||
cmds.menuItem(
|
||||
"Create Placeholder",
|
||||
parent=builder_menu,
|
||||
command=create_placeholder
|
||||
)
|
||||
cmds.menuItem(
|
||||
"Update Placeholder",
|
||||
parent=builder_menu,
|
||||
command=update_placeholder
|
||||
)
|
||||
cmds.menuItem(
|
||||
"Build Workfile from template",
|
||||
parent=builder_menu,
|
||||
|
|
@ -187,6 +180,27 @@ def install(project_settings):
|
|||
parent=builder_menu,
|
||||
command=update_workfile_template
|
||||
)
|
||||
cmds.menuItem(
|
||||
divider=True,
|
||||
parent=builder_menu
|
||||
)
|
||||
cmds.menuItem(
|
||||
"Open Template",
|
||||
parent=builder_menu,
|
||||
command=lambda *args: open_template_ui(
|
||||
MayaTemplateBuilder(registered_host()), get_main_window()
|
||||
),
|
||||
)
|
||||
cmds.menuItem(
|
||||
"Create Placeholder",
|
||||
parent=builder_menu,
|
||||
command=create_placeholder
|
||||
)
|
||||
cmds.menuItem(
|
||||
"Update Placeholder",
|
||||
parent=builder_menu,
|
||||
command=update_placeholder
|
||||
)
|
||||
|
||||
cmds.setParent(MENU_NAME, menu=True)
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ from ayon_core.lib import (
|
|||
emit_event
|
||||
)
|
||||
from ayon_core.pipeline import (
|
||||
legacy_io,
|
||||
get_current_project_name,
|
||||
register_loader_plugin_path,
|
||||
register_inventory_action_path,
|
||||
|
|
@ -247,7 +246,7 @@ def _set_project():
|
|||
None
|
||||
|
||||
"""
|
||||
workdir = legacy_io.Session["AVALON_WORKDIR"]
|
||||
workdir = os.getenv("AYON_WORKDIR")
|
||||
|
||||
try:
|
||||
os.makedirs(workdir)
|
||||
|
|
@ -629,7 +628,7 @@ def on_task_changed():
|
|||
# Run
|
||||
menu.update_menu_task_label()
|
||||
|
||||
workdir = legacy_io.Session["AVALON_WORKDIR"]
|
||||
workdir = os.getenv("AYON_WORKDIR")
|
||||
if os.path.exists(workdir):
|
||||
log.info("Updating Maya workspace for task change to %s", workdir)
|
||||
_set_project()
|
||||
|
|
@ -678,7 +677,7 @@ def workfile_save_before_xgen(event):
|
|||
|
||||
import xgenm
|
||||
|
||||
current_work_dir = legacy_io.Session["AVALON_WORKDIR"].replace("\\", "/")
|
||||
current_work_dir = os.getenv("AYON_WORKDIR").replace("\\", "/")
|
||||
expected_work_dir = event.data["workdir_path"].replace("\\", "/")
|
||||
if current_work_dir == expected_work_dir:
|
||||
return
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ from ayon_core.pipeline import (
|
|||
LegacyCreator,
|
||||
LoaderPlugin,
|
||||
get_representation_path,
|
||||
get_current_project_name,
|
||||
)
|
||||
from ayon_core.pipeline.load import LoadError
|
||||
from ayon_core.client import get_asset_by_name
|
||||
|
|
@ -585,6 +586,39 @@ class RenderlayerCreator(NewCreator, MayaCreatorBase):
|
|||
project_name)
|
||||
|
||||
|
||||
def get_load_color_for_family(family, settings=None):
|
||||
"""Get color for family from settings.
|
||||
|
||||
Args:
|
||||
family (str): Family name.
|
||||
settings (Optional[dict]): Settings dictionary.
|
||||
|
||||
Returns:
|
||||
Union[tuple[float, float, float], None]: RGB color.
|
||||
|
||||
"""
|
||||
if settings is None:
|
||||
settings = get_project_settings(get_current_project_name())
|
||||
|
||||
colors = settings["maya"]["load"]["colors"]
|
||||
color = colors.get(family)
|
||||
if not color:
|
||||
return None
|
||||
|
||||
if len(color) == 3:
|
||||
red, green, blue = color
|
||||
elif len(color) == 4:
|
||||
red, green, blue, _ = color
|
||||
else:
|
||||
raise ValueError("Invalid color definition {}".format(str(color)))
|
||||
|
||||
if isinstance(red, int):
|
||||
red = red / 255.0
|
||||
green = green / 255.0
|
||||
blue = blue / 255.0
|
||||
return red, green, blue
|
||||
|
||||
|
||||
class Loader(LoaderPlugin):
|
||||
hosts = ["maya"]
|
||||
|
||||
|
|
@ -611,33 +645,38 @@ class Loader(LoaderPlugin):
|
|||
options["attach_to_root"] = True
|
||||
custom_naming = self.load_settings[loader_key]
|
||||
|
||||
if not custom_naming['namespace']:
|
||||
if not custom_naming["namespace"]:
|
||||
raise LoadError("No namespace specified in "
|
||||
"Maya ReferenceLoader settings")
|
||||
elif not custom_naming['group_name']:
|
||||
elif not custom_naming["group_name"]:
|
||||
self.log.debug("No custom group_name, no group will be created.")
|
||||
options["attach_to_root"] = False
|
||||
|
||||
asset = context['asset']
|
||||
subset = context['subset']
|
||||
asset = context["asset"]
|
||||
subset = context["subset"]
|
||||
family = (
|
||||
subset["data"].get("family")
|
||||
or subset["data"]["families"][0]
|
||||
)
|
||||
formatting_data = {
|
||||
"asset_name": asset['name'],
|
||||
"asset_type": asset['type'],
|
||||
"asset_name": asset["name"],
|
||||
"asset_type": asset["type"],
|
||||
"folder": {
|
||||
"name": asset["name"],
|
||||
},
|
||||
"subset": subset['name'],
|
||||
"family": (
|
||||
subset['data'].get('family') or
|
||||
subset['data']['families'][0]
|
||||
)
|
||||
"subset": subset["name"],
|
||||
"product": {
|
||||
"name": subset["name"],
|
||||
"type": family,
|
||||
},
|
||||
"family": family
|
||||
}
|
||||
|
||||
custom_namespace = custom_naming['namespace'].format(
|
||||
custom_namespace = custom_naming["namespace"].format(
|
||||
**formatting_data
|
||||
)
|
||||
|
||||
custom_group_name = custom_naming['group_name'].format(
|
||||
custom_group_name = custom_naming["group_name"].format(
|
||||
**formatting_data
|
||||
)
|
||||
|
||||
|
|
@ -937,7 +976,7 @@ class ReferenceLoader(Loader):
|
|||
"""
|
||||
settings = get_project_settings(project_name)
|
||||
use_env_var_as_root = (settings["maya"]
|
||||
["maya-dirmap"]
|
||||
["maya_dirmap"]
|
||||
["use_env_var_as_root"])
|
||||
if use_env_var_as_root:
|
||||
anatomy = Anatomy(project_name)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import gridfs
|
|||
|
||||
|
||||
DEFINITION_FILENAME = "{}/maya/shader_definition.txt".format(
|
||||
os.getenv("AVALON_PROJECT"))
|
||||
os.getenv("AYON_PROJECT_NAME"))
|
||||
|
||||
|
||||
class ShaderDefinitionsEditor(QtWidgets.QWidget):
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ def current_file():
|
|||
|
||||
|
||||
def work_root(session):
|
||||
work_dir = session["AVALON_WORKDIR"]
|
||||
work_dir = session["AYON_WORKDIR"]
|
||||
scene_dir = None
|
||||
|
||||
# Query scene file rule from workspace.mel if it exists in WORKDIR
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ class PreCopyMel(PreLaunchHook):
|
|||
|
||||
def execute(self):
|
||||
project_doc = self.data["project_doc"]
|
||||
workdir = self.launch_context.env.get("AVALON_WORKDIR")
|
||||
workdir = self.launch_context.env.get("AYON_WORKDIR")
|
||||
if not workdir:
|
||||
self.log.warning("BUG: Workdir is not filled.")
|
||||
return
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ class CreateRenderlayer(plugin.RenderlayerCreator):
|
|||
|
||||
@classmethod
|
||||
def apply_settings(cls, project_settings):
|
||||
cls.render_settings = project_settings["maya"]["RenderSettings"]
|
||||
cls.render_settings = project_settings["maya"]["render_settings"]
|
||||
|
||||
def create(self, subset_name, instance_data, pre_create_data):
|
||||
# Only allow a single render instance to exist
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ class CreateReview(plugin.MayaCreator):
|
|||
"review_width": preset["Resolution"]["width"],
|
||||
"review_height": preset["Resolution"]["height"],
|
||||
"isolate": preset["Generic"]["isolate_view"],
|
||||
"imagePlane": preset["Viewport Options"]["imagePlane"],
|
||||
"imagePlane": preset["ViewportOptions"]["imagePlane"],
|
||||
"panZoom": preset["Generic"]["pan_zoom"]
|
||||
}
|
||||
for key, value in mapping.items():
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ class CreateVRayScene(plugin.RenderlayerCreator):
|
|||
|
||||
@classmethod
|
||||
def apply_settings(cls, project_settings):
|
||||
cls.render_settings = project_settings["maya"]["RenderSettings"]
|
||||
cls.render_settings = project_settings["maya"]["render_settings"]
|
||||
|
||||
def create(self, subset_name, instance_data, pre_create_data):
|
||||
# Only allow a single render instance to exist
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import maya.cmds as cmds
|
|||
from ayon_core.settings import get_project_settings
|
||||
from ayon_core.pipeline import (
|
||||
load,
|
||||
legacy_io,
|
||||
get_representation_path
|
||||
)
|
||||
from ayon_core.hosts.maya.api.lib import (
|
||||
|
|
@ -16,6 +15,7 @@ from ayon_core.hosts.maya.api.lib import (
|
|||
convert_to_maya_fps
|
||||
)
|
||||
from ayon_core.hosts.maya.api.pipeline import containerise
|
||||
from ayon_core.hosts.maya.api.plugin import get_load_color_for_family
|
||||
|
||||
|
||||
def is_sequence(files):
|
||||
|
|
@ -26,11 +26,6 @@ def is_sequence(files):
|
|||
return sequence
|
||||
|
||||
|
||||
def get_current_session_fps():
|
||||
session_fps = float(legacy_io.Session.get('AVALON_FPS', 25))
|
||||
return convert_to_maya_fps(session_fps)
|
||||
|
||||
|
||||
class ArnoldStandinLoader(load.LoaderPlugin):
|
||||
"""Load as Arnold standin"""
|
||||
|
||||
|
|
@ -72,11 +67,12 @@ class ArnoldStandinLoader(load.LoaderPlugin):
|
|||
|
||||
# Set color.
|
||||
settings = get_project_settings(context["project"]["name"])
|
||||
color = settings['maya']['load']['colors'].get('ass')
|
||||
color = get_load_color_for_family("ass", settings)
|
||||
if color is not None:
|
||||
red, green, blue = color
|
||||
cmds.setAttr(root + ".useOutlinerColor", True)
|
||||
cmds.setAttr(
|
||||
root + ".outlinerColor", color[0], color[1], color[2]
|
||||
root + ".outlinerColor", red, green, blue
|
||||
)
|
||||
|
||||
with maintained_selection():
|
||||
|
|
@ -99,7 +95,7 @@ class ArnoldStandinLoader(load.LoaderPlugin):
|
|||
sequence = is_sequence(os.listdir(os.path.dirname(repre_path)))
|
||||
cmds.setAttr(standin_shape + ".useFrameExtension", sequence)
|
||||
|
||||
fps = float(version["data"].get("fps"))or get_current_session_fps()
|
||||
fps = float(version["data"].get("fps")) or 25
|
||||
cmds.setAttr(standin_shape + ".abcFPS", fps)
|
||||
|
||||
nodes = [root, standin, standin_shape]
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ from ayon_core.pipeline import (
|
|||
get_representation_path
|
||||
)
|
||||
from ayon_core.settings import get_project_settings
|
||||
from ayon_core.hosts.maya.api.plugin import get_load_color_for_family
|
||||
|
||||
|
||||
class GpuCacheLoader(load.LoaderPlugin):
|
||||
|
|
@ -39,13 +40,12 @@ class GpuCacheLoader(load.LoaderPlugin):
|
|||
|
||||
project_name = context["project"]["name"]
|
||||
settings = get_project_settings(project_name)
|
||||
colors = settings['maya']['load']['colors']
|
||||
c = colors.get('model')
|
||||
if c is not None:
|
||||
color = get_load_color_for_family("model", settings)
|
||||
if color is not None:
|
||||
red, green, blue = color
|
||||
cmds.setAttr(root + ".useOutlinerColor", 1)
|
||||
cmds.setAttr(
|
||||
root + ".outlinerColor",
|
||||
(float(c[0]) / 255), (float(c[1]) / 255), (float(c[2]) / 255)
|
||||
root + ".outlinerColor", red, green, blue
|
||||
)
|
||||
|
||||
# Create transform with shape
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ from ayon_core.hosts.maya.api.lib import (
|
|||
unique_namespace
|
||||
)
|
||||
from ayon_core.hosts.maya.api.pipeline import containerise
|
||||
from ayon_core.hosts.maya.api.plugin import get_load_color_for_family
|
||||
|
||||
|
||||
class RedshiftProxyLoader(load.LoaderPlugin):
|
||||
|
|
@ -59,12 +60,13 @@ class RedshiftProxyLoader(load.LoaderPlugin):
|
|||
# colour the group node
|
||||
project_name = context["project"]["name"]
|
||||
settings = get_project_settings(project_name)
|
||||
colors = settings['maya']['load']['colors']
|
||||
c = colors.get(family)
|
||||
if c is not None:
|
||||
color = get_load_color_for_family(family, settings)
|
||||
if color is not None:
|
||||
red, green, blue = color
|
||||
cmds.setAttr("{0}.useOutlinerColor".format(group_node), 1)
|
||||
cmds.setAttr("{0}.outlinerColor".format(group_node),
|
||||
c[0], c[1], c[2])
|
||||
cmds.setAttr(
|
||||
"{0}.outlinerColor".format(group_node), red, green, blue
|
||||
)
|
||||
|
||||
return containerise(
|
||||
name=name,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import os
|
||||
import difflib
|
||||
import contextlib
|
||||
|
||||
|
|
@ -6,7 +5,7 @@ from maya import cmds
|
|||
import qargparse
|
||||
|
||||
from ayon_core.settings import get_project_settings
|
||||
import ayon_core.hosts.maya.api.plugin
|
||||
from ayon_core.hosts.maya.api import plugin
|
||||
from ayon_core.hosts.maya.api.lib import (
|
||||
maintained_selection,
|
||||
get_container_members,
|
||||
|
|
@ -87,7 +86,7 @@ def preserve_modelpanel_cameras(container, log=None):
|
|||
cmds.modelPanel(panel, edit=True, camera=new_camera)
|
||||
|
||||
|
||||
class ReferenceLoader(ayon_core.hosts.maya.api.plugin.ReferenceLoader):
|
||||
class ReferenceLoader(plugin.ReferenceLoader):
|
||||
"""Reference file"""
|
||||
|
||||
families = ["model",
|
||||
|
|
@ -185,14 +184,16 @@ class ReferenceLoader(ayon_core.hosts.maya.api.plugin.ReferenceLoader):
|
|||
"{}.displayHandle".format(group_name), display_handle
|
||||
)
|
||||
|
||||
colors = settings['maya']['load']['colors']
|
||||
c = colors.get(family)
|
||||
if c is not None:
|
||||
color = plugin.get_load_color_for_family(family, settings)
|
||||
if color is not None:
|
||||
red, green, blue = color
|
||||
cmds.setAttr("{}.useOutlinerColor".format(group_name), 1)
|
||||
cmds.setAttr("{}.outlinerColor".format(group_name),
|
||||
(float(c[0]) / 255),
|
||||
(float(c[1]) / 255),
|
||||
(float(c[2]) / 255))
|
||||
cmds.setAttr(
|
||||
"{}.outlinerColor".format(group_name),
|
||||
red,
|
||||
green,
|
||||
blue
|
||||
)
|
||||
|
||||
cmds.setAttr(
|
||||
"{}.displayHandle".format(group_name), display_handle
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ from ayon_core.pipeline import (
|
|||
load,
|
||||
get_representation_path
|
||||
)
|
||||
from ayon_core.hosts.maya.api.plugin import get_load_color_for_family
|
||||
# TODO aiVolume doesn't automatically set velocity fps correctly, set manual?
|
||||
|
||||
|
||||
|
|
@ -50,16 +51,11 @@ class LoadVDBtoArnold(load.LoaderPlugin):
|
|||
|
||||
project_name = context["project"]["name"]
|
||||
settings = get_project_settings(project_name)
|
||||
colors = settings['maya']['load']['colors']
|
||||
|
||||
c = colors.get(family)
|
||||
if c is not None:
|
||||
color = get_load_color_for_family(family, settings)
|
||||
if color is not None:
|
||||
red, green, blue = color
|
||||
cmds.setAttr(root + ".useOutlinerColor", 1)
|
||||
cmds.setAttr(root + ".outlinerColor",
|
||||
(float(c[0]) / 255),
|
||||
(float(c[1]) / 255),
|
||||
(float(c[2]) / 255)
|
||||
)
|
||||
cmds.setAttr(root + ".outlinerColor", red, green, blue)
|
||||
|
||||
# Create VRayVolumeGrid
|
||||
grid_node = cmds.createNode("aiVolume",
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ from ayon_core.pipeline import (
|
|||
load,
|
||||
get_representation_path
|
||||
)
|
||||
from ayon_core.hosts.maya.api.plugin import get_load_color_for_family
|
||||
|
||||
|
||||
class LoadVDBtoRedShift(load.LoaderPlugin):
|
||||
|
|
@ -69,16 +70,11 @@ class LoadVDBtoRedShift(load.LoaderPlugin):
|
|||
|
||||
project_name = context["project"]["name"]
|
||||
settings = get_project_settings(project_name)
|
||||
colors = settings['maya']['load']['colors']
|
||||
|
||||
c = colors.get(family)
|
||||
if c is not None:
|
||||
color = get_load_color_for_family(family, settings)
|
||||
if color is not None:
|
||||
red, green, blue = color
|
||||
cmds.setAttr(root + ".useOutlinerColor", 1)
|
||||
cmds.setAttr(root + ".outlinerColor",
|
||||
(float(c[0])/255),
|
||||
(float(c[1])/255),
|
||||
(float(c[2])/255)
|
||||
)
|
||||
cmds.setAttr(root + ".outlinerColor", red, green, blue)
|
||||
|
||||
# Create VR
|
||||
volume_node = cmds.createNode("RedshiftVolumeShape",
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ from ayon_core.pipeline import (
|
|||
load,
|
||||
get_representation_path
|
||||
)
|
||||
from ayon_core.hosts.maya.api.plugin import get_load_color_for_family
|
||||
|
||||
from maya import cmds
|
||||
|
||||
|
|
@ -129,15 +130,11 @@ class LoadVDBtoVRay(load.LoaderPlugin):
|
|||
|
||||
project_name = context["project"]["name"]
|
||||
settings = get_project_settings(project_name)
|
||||
colors = settings['maya']['load']['colors']
|
||||
|
||||
c = colors.get(family)
|
||||
if c is not None:
|
||||
color = get_load_color_for_family(family, settings)
|
||||
if color is not None:
|
||||
red, green, blue = color
|
||||
cmds.setAttr(root + ".useOutlinerColor", 1)
|
||||
cmds.setAttr(root + ".outlinerColor",
|
||||
float(c[0]) / 255,
|
||||
float(c[1]) / 255,
|
||||
float(c[2]) / 255)
|
||||
cmds.setAttr(root + ".outlinerColor", red, green, blue)
|
||||
|
||||
# Create VRayVolumeGrid
|
||||
grid_node = cmds.createNode("VRayVolumeGrid",
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ from ayon_core.hosts.maya.api.lib import (
|
|||
unique_namespace
|
||||
)
|
||||
from ayon_core.hosts.maya.api.pipeline import containerise
|
||||
from ayon_core.hosts.maya.api.plugin import get_load_color_for_family
|
||||
|
||||
|
||||
class VRayProxyLoader(load.LoaderPlugin):
|
||||
|
|
@ -80,15 +81,12 @@ class VRayProxyLoader(load.LoaderPlugin):
|
|||
# colour the group node
|
||||
project_name = context["project"]["name"]
|
||||
settings = get_project_settings(project_name)
|
||||
colors = settings['maya']['load']['colors']
|
||||
c = colors.get(family)
|
||||
if c is not None:
|
||||
color = get_load_color_for_family(family, settings)
|
||||
if color is not None:
|
||||
red, green, blue = color
|
||||
cmds.setAttr("{0}.useOutlinerColor".format(group_node), 1)
|
||||
cmds.setAttr(
|
||||
"{0}.outlinerColor".format(group_node),
|
||||
(float(c[0]) / 255),
|
||||
(float(c[1]) / 255),
|
||||
(float(c[2]) / 255)
|
||||
"{0}.outlinerColor".format(group_node), red, green, blue
|
||||
)
|
||||
|
||||
return containerise(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import os
|
||||
import maya.cmds as cmds # noqa
|
||||
from ayon_core.settings import get_project_settings
|
||||
from ayon_core.pipeline import (
|
||||
|
|
@ -12,6 +11,7 @@ from ayon_core.hosts.maya.api.lib import (
|
|||
unique_namespace
|
||||
)
|
||||
from ayon_core.hosts.maya.api.pipeline import containerise
|
||||
from ayon_core.hosts.maya.api.plugin import get_load_color_for_family
|
||||
|
||||
|
||||
class VRaySceneLoader(load.LoaderPlugin):
|
||||
|
|
@ -58,14 +58,12 @@ class VRaySceneLoader(load.LoaderPlugin):
|
|||
# colour the group node
|
||||
project_name = context["project"]["name"]
|
||||
settings = get_project_settings(project_name)
|
||||
colors = settings['maya']['load']['colors']
|
||||
c = colors.get(family)
|
||||
if c is not None:
|
||||
color = get_load_color_for_family(family, settings)
|
||||
if color is not None:
|
||||
red, green, blue = color
|
||||
cmds.setAttr("{0}.useOutlinerColor".format(root_node), 1)
|
||||
cmds.setAttr("{0}.outlinerColor".format(root_node),
|
||||
(float(c[0])/255),
|
||||
(float(c[1])/255),
|
||||
(float(c[2])/255)
|
||||
cmds.setAttr(
|
||||
"{0}.outlinerColor".format(root_node), red, green, blue
|
||||
)
|
||||
|
||||
return containerise(
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ from ayon_core.pipeline import (
|
|||
)
|
||||
from ayon_core.hosts.maya.api import lib
|
||||
from ayon_core.hosts.maya.api.pipeline import containerise
|
||||
from ayon_core.hosts.maya.api.plugin import get_load_color_for_family
|
||||
|
||||
|
||||
# Do not reset these values on update but only apply on first load
|
||||
|
|
@ -81,16 +82,11 @@ class YetiCacheLoader(load.LoaderPlugin):
|
|||
project_name = context["project"]["name"]
|
||||
|
||||
settings = get_project_settings(project_name)
|
||||
colors = settings['maya']['load']['colors']
|
||||
|
||||
c = colors.get(family)
|
||||
if c is not None:
|
||||
color = get_load_color_for_family(family, settings)
|
||||
if color is not None:
|
||||
red, green, blue = color
|
||||
cmds.setAttr(group_node + ".useOutlinerColor", 1)
|
||||
cmds.setAttr(group_node + ".outlinerColor",
|
||||
(float(c[0])/255),
|
||||
(float(c[1])/255),
|
||||
(float(c[2])/255)
|
||||
)
|
||||
cmds.setAttr(group_node + ".outlinerColor", red, green, blue)
|
||||
|
||||
nodes.append(group_node)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
import maya.cmds as cmds
|
||||
|
||||
from ayon_core.settings import get_current_project_settings
|
||||
import ayon_core.hosts.maya.api.plugin
|
||||
from ayon_core.hosts.maya.api import plugin
|
||||
from ayon_core.hosts.maya.api import lib
|
||||
|
||||
|
||||
class YetiRigLoader(ayon_core.hosts.maya.api.plugin.ReferenceLoader):
|
||||
class YetiRigLoader(plugin.ReferenceLoader):
|
||||
"""This loader will load Yeti rig."""
|
||||
|
||||
families = ["yetiRig"]
|
||||
|
|
@ -41,14 +40,12 @@ class YetiRigLoader(ayon_core.hosts.maya.api.plugin.ReferenceLoader):
|
|||
groupName=group_name
|
||||
)
|
||||
|
||||
settings = get_current_project_settings()
|
||||
colors = settings["maya"]["load"]["colors"]
|
||||
c = colors.get("yetiRig")
|
||||
if c is not None:
|
||||
color = plugin.get_load_color_for_family("yetiRig")
|
||||
if color is not None:
|
||||
red, green, blue = color
|
||||
cmds.setAttr(group_name + ".useOutlinerColor", 1)
|
||||
cmds.setAttr(
|
||||
group_name + ".outlinerColor",
|
||||
(float(c[0]) / 255), (float(c[1]) / 255), (float(c[2]) / 255)
|
||||
group_name + ".outlinerColor", red, green, blue
|
||||
)
|
||||
self[:] = nodes
|
||||
|
||||
|
|
|
|||
|
|
@ -8,13 +8,12 @@ publishing on farm.
|
|||
Requires:
|
||||
instance -> families
|
||||
instance -> setMembers
|
||||
instance -> asset
|
||||
|
||||
context -> currentFile
|
||||
context -> workspaceDir
|
||||
context -> user
|
||||
|
||||
session -> AVALON_ASSET
|
||||
|
||||
Optional:
|
||||
|
||||
Provides:
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ class CollectReview(pyblish.api.InstancePlugin):
|
|||
if display_lights == "project_settings":
|
||||
settings = instance.context.data["project_settings"]
|
||||
settings = settings["maya"]["publish"]["ExtractPlayblast"]
|
||||
settings = settings["capture_preset"]["Viewport Options"]
|
||||
settings = settings["capture_preset"]["ViewportOptions"]
|
||||
display_lights = settings["displayLights"]
|
||||
|
||||
# Collect camera focal length.
|
||||
|
|
|
|||
|
|
@ -1,13 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Collect Vray Scene and prepare it for extraction and publishing."""
|
||||
import re
|
||||
|
||||
import maya.app.renderSetup.model.renderSetup as renderSetup
|
||||
from maya import cmds
|
||||
|
||||
import pyblish.api
|
||||
|
||||
from ayon_core.pipeline import legacy_io
|
||||
from ayon_core.lib import get_formatted_current_time
|
||||
from ayon_core.hosts.maya.api import lib
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import os
|
||||
import json
|
||||
|
||||
from maya import cmds
|
||||
|
||||
|
|
@ -21,7 +22,7 @@ class ExtractCameraAlembic(publish.Extractor,
|
|||
label = "Extract Camera (Alembic)"
|
||||
hosts = ["maya"]
|
||||
families = ["camera", "matchmove"]
|
||||
bake_attributes = []
|
||||
bake_attributes = "[]"
|
||||
|
||||
def process(self, instance):
|
||||
|
||||
|
|
@ -95,11 +96,12 @@ class ExtractCameraAlembic(publish.Extractor,
|
|||
|
||||
job_str += ' -file "{0}"'.format(path)
|
||||
|
||||
bake_attributes = json.loads(self.bake_attributes)
|
||||
# bake specified attributes in preset
|
||||
assert isinstance(self.bake_attributes, (list, tuple)), (
|
||||
assert isinstance(bake_attributes, list), (
|
||||
"Attributes to bake must be specified as a list"
|
||||
)
|
||||
for attr in self.bake_attributes:
|
||||
for attr in bake_attributes:
|
||||
self.log.debug("Adding {} attribute".format(attr))
|
||||
job_str += " -attr {0}".format(attr)
|
||||
|
||||
|
|
|
|||
|
|
@ -112,9 +112,11 @@ class ExtractCameraMayaScene(publish.Extractor,
|
|||
def process(self, instance):
|
||||
"""Plugin entry point."""
|
||||
# get settings
|
||||
ext_mapping = (
|
||||
instance.context.data["project_settings"]["maya"]["ext_mapping"]
|
||||
)
|
||||
maya_settings = instance.context.data["project_settings"]["maya"]
|
||||
ext_mapping = {
|
||||
item["name"]: item["value"]
|
||||
for item in maya_settings["ext_mapping"]
|
||||
}
|
||||
if ext_mapping:
|
||||
self.log.debug("Looking in settings for scene type ...")
|
||||
# use extension mapping for first family found
|
||||
|
|
|
|||
|
|
@ -37,9 +37,11 @@ class ExtractImportReference(publish.Extractor,
|
|||
if not self.is_active(instance.data):
|
||||
return
|
||||
|
||||
ext_mapping = (
|
||||
instance.context.data["project_settings"]["maya"]["ext_mapping"]
|
||||
)
|
||||
maya_settings = instance.context.data["project_settings"]["maya"]
|
||||
ext_mapping = {
|
||||
item["name"]: item["value"]
|
||||
for item in maya_settings["ext_mapping"]
|
||||
}
|
||||
if ext_mapping:
|
||||
self.log.debug("Looking in settings for scene type ...")
|
||||
# use extension mapping for first family found
|
||||
|
|
|
|||
|
|
@ -431,9 +431,11 @@ class ExtractLook(publish.Extractor):
|
|||
project settings.
|
||||
|
||||
"""
|
||||
ext_mapping = (
|
||||
instance.context.data["project_settings"]["maya"]["ext_mapping"]
|
||||
)
|
||||
maya_settings = instance.context.data["project_settings"]["maya"]
|
||||
ext_mapping = {
|
||||
item["name"]: item["value"]
|
||||
for item in maya_settings["ext_mapping"]
|
||||
}
|
||||
if ext_mapping:
|
||||
self.log.debug("Looking in settings for scene type ...")
|
||||
# use extension mapping for first family found
|
||||
|
|
|
|||
|
|
@ -43,9 +43,11 @@ class ExtractMayaSceneRaw(publish.Extractor, AYONPyblishPluginMixin):
|
|||
|
||||
def process(self, instance):
|
||||
"""Plugin entry point."""
|
||||
ext_mapping = (
|
||||
instance.context.data["project_settings"]["maya"]["ext_mapping"]
|
||||
)
|
||||
maya_settings = instance.context.data["project_settings"]["maya"]
|
||||
ext_mapping = {
|
||||
item["name"]: item["value"]
|
||||
for item in maya_settings["ext_mapping"]
|
||||
}
|
||||
if ext_mapping:
|
||||
self.log.debug("Looking in settings for scene type ...")
|
||||
# use extension mapping for first family found
|
||||
|
|
|
|||
|
|
@ -35,9 +35,11 @@ class ExtractModel(publish.Extractor,
|
|||
if not self.is_active(instance.data):
|
||||
return
|
||||
|
||||
ext_mapping = (
|
||||
instance.context.data["project_settings"]["maya"]["ext_mapping"]
|
||||
)
|
||||
maya_settings = instance.context.data["project_settings"]["maya"]
|
||||
ext_mapping = {
|
||||
item["name"]: item["value"]
|
||||
for item in maya_settings["ext_mapping"]
|
||||
}
|
||||
if ext_mapping:
|
||||
self.log.debug("Looking in settings for scene type ...")
|
||||
# use extension mapping for first family found
|
||||
|
|
|
|||
|
|
@ -18,9 +18,11 @@ class ExtractRig(publish.Extractor):
|
|||
|
||||
def process(self, instance):
|
||||
"""Plugin entry point."""
|
||||
ext_mapping = (
|
||||
instance.context.data["project_settings"]["maya"]["ext_mapping"]
|
||||
)
|
||||
maya_settings = instance.context.data["project_settings"]["maya"]
|
||||
ext_mapping = {
|
||||
item["name"]: item["value"]
|
||||
for item in maya_settings["ext_mapping"]
|
||||
}
|
||||
if ext_mapping:
|
||||
self.log.debug("Looking in settings for scene type ...")
|
||||
# use extension mapping for first family found
|
||||
|
|
|
|||
|
|
@ -100,9 +100,11 @@ class ExtractYetiRig(publish.Extractor):
|
|||
|
||||
def process(self, instance):
|
||||
"""Plugin entry point."""
|
||||
ext_mapping = (
|
||||
instance.context.data["project_settings"]["maya"]["ext_mapping"]
|
||||
)
|
||||
maya_settings = instance.context.data["project_settings"]["maya"]
|
||||
ext_mapping = {
|
||||
item["name"]: item["value"]
|
||||
for item in maya_settings["ext_mapping"]
|
||||
}
|
||||
if ext_mapping:
|
||||
self.log.debug("Looking in settings for scene type ...")
|
||||
# use extension mapping for first family found
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import json
|
||||
from collections import defaultdict
|
||||
|
||||
import pyblish.api
|
||||
|
|
@ -23,19 +24,19 @@ class ValidateAttributes(pyblish.api.InstancePlugin,
|
|||
"""
|
||||
|
||||
order = ValidateContentsOrder
|
||||
label = "Attributes"
|
||||
label = "Validate Attributes"
|
||||
hosts = ["maya"]
|
||||
actions = [RepairAction]
|
||||
optional = True
|
||||
|
||||
attributes = None
|
||||
attributes = "{}"
|
||||
|
||||
def process(self, instance):
|
||||
if not self.is_active(instance.data):
|
||||
return
|
||||
|
||||
# Check for preset existence.
|
||||
if not self.attributes:
|
||||
if not self.get_attributes_data():
|
||||
return
|
||||
|
||||
invalid = self.get_invalid(instance, compute=True)
|
||||
|
|
@ -44,6 +45,10 @@ class ValidateAttributes(pyblish.api.InstancePlugin,
|
|||
"Found attributes with invalid values: {}".format(invalid)
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_attributes_data(cls):
|
||||
return json.loads(cls.attributes)
|
||||
|
||||
@classmethod
|
||||
def get_invalid(cls, instance, compute=False):
|
||||
if compute:
|
||||
|
|
@ -55,21 +60,22 @@ class ValidateAttributes(pyblish.api.InstancePlugin,
|
|||
def get_invalid_attributes(cls, instance):
|
||||
invalid_attributes = []
|
||||
|
||||
attributes_data = cls.get_attributes_data()
|
||||
# Filter families.
|
||||
families = [instance.data["family"]]
|
||||
families += instance.data.get("families", [])
|
||||
families = set(families) & set(cls.attributes.keys())
|
||||
families = set(families) & set(attributes_data.keys())
|
||||
if not families:
|
||||
return []
|
||||
|
||||
# Get all attributes to validate.
|
||||
attributes = defaultdict(dict)
|
||||
for family in families:
|
||||
if family not in cls.attributes:
|
||||
if family not in attributes_data:
|
||||
# No attributes to validate for family
|
||||
continue
|
||||
|
||||
for preset_attr, preset_value in cls.attributes[family].items():
|
||||
for preset_attr, preset_value in attributes_data[family].items():
|
||||
node_name, attribute_name = preset_attr.split(".", 1)
|
||||
attributes[node_name][attribute_name] = preset_value
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ class ValidateFrameRange(pyblish.api.InstancePlugin,
|
|||
"yeticache"]
|
||||
optional = True
|
||||
actions = [RepairAction]
|
||||
exclude_families = []
|
||||
exclude_product_types = []
|
||||
|
||||
def process(self, instance):
|
||||
if not self.is_active(instance.data):
|
||||
|
|
@ -73,7 +73,9 @@ class ValidateFrameRange(pyblish.api.InstancePlugin,
|
|||
|
||||
# compare with data on instance
|
||||
errors = []
|
||||
if [ef for ef in self.exclude_families
|
||||
# QUESTION shouldn't this be just:
|
||||
# 'if instance.data["family"] in self.exclude_product_types:'
|
||||
if [ef for ef in self.exclude_product_types
|
||||
if instance.data["family"] in ef]:
|
||||
return
|
||||
if (inst_start != frame_start_handle):
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import ayon_core.hosts.maya.api.action
|
|||
from ayon_core.client.mongo import OpenPypeMongoConnection
|
||||
from ayon_core.hosts.maya.api.shader_definition_editor import (
|
||||
DEFINITION_FILENAME)
|
||||
from ayon_core.pipeline import legacy_io
|
||||
from ayon_core.pipeline.publish import (
|
||||
OptionalPyblishPluginMixin, PublishValidationError, ValidateContentsOrder)
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import pyblish.api
|
|||
import ayon_core.hosts.maya.api.action
|
||||
from ayon_core.client import get_assets
|
||||
from ayon_core.hosts.maya.api import lib
|
||||
from ayon_core.pipeline import legacy_io
|
||||
from ayon_core.pipeline.publish import (
|
||||
PublishValidationError, ValidatePipelineOrder)
|
||||
|
||||
|
|
|
|||
|
|
@ -30,14 +30,18 @@ class ValidatePluginPathAttributes(pyblish.api.InstancePlugin):
|
|||
def get_invalid(cls, instance):
|
||||
invalid = list()
|
||||
|
||||
file_attrs = cls.attribute
|
||||
file_attrs = {
|
||||
item["name"]: item["value"]
|
||||
for item in cls.attribute
|
||||
}
|
||||
if not file_attrs:
|
||||
return invalid
|
||||
|
||||
# Consider only valid node types to avoid "Unknown object type" warning
|
||||
all_node_types = set(cmds.allNodeTypes())
|
||||
node_types = [
|
||||
key for key in file_attrs.keys()
|
||||
key
|
||||
for key in file_attrs.keys()
|
||||
if key in all_node_types
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -55,12 +55,15 @@ class ValidateRenderImageRule(pyblish.api.InstancePlugin):
|
|||
if staging_dir:
|
||||
cls.log.debug(
|
||||
"Staging dir found: \"{}\". Ignoring setting from "
|
||||
"`project_settings/maya/RenderSettings/"
|
||||
"`project_settings/maya/render_settings/"
|
||||
"default_render_image_folder`.".format(staging_dir)
|
||||
)
|
||||
return staging_dir
|
||||
|
||||
return instance.context.data.get('project_settings')\
|
||||
.get('maya') \
|
||||
.get('RenderSettings') \
|
||||
.get('default_render_image_folder')
|
||||
return (
|
||||
instance.context.data
|
||||
["project_settings"]
|
||||
["maya"]
|
||||
["render_settings"]
|
||||
["default_render_image_folder"]
|
||||
)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ import pyblish.api
|
|||
|
||||
import ayon_core.hosts.maya.api.action
|
||||
from ayon_core.client import get_subset_by_name
|
||||
from ayon_core.pipeline import legacy_io
|
||||
from ayon_core.pipeline.publish import PublishValidationError
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -265,7 +265,7 @@ class ValidateRenderSettings(pyblish.api.InstancePlugin):
|
|||
# load validation definitions from settings
|
||||
settings_lights_flag = instance.context.data["project_settings"].get(
|
||||
"maya", {}).get(
|
||||
"RenderSettings", {}).get(
|
||||
"render_settings", {}).get(
|
||||
"enable_all_lights", False)
|
||||
|
||||
instance_lights_flag = instance.data.get("renderSetupIncludeLights")
|
||||
|
|
@ -281,6 +281,8 @@ class ValidateRenderSettings(pyblish.api.InstancePlugin):
|
|||
# if so, compare its value from the one required.
|
||||
for data in cls.get_nodes(instance, renderer):
|
||||
for node in data["nodes"]:
|
||||
# Why is captured 'PublishValidationError'? How it can be
|
||||
# raised by 'cmds.getAttr(...)'?
|
||||
try:
|
||||
render_value = cmds.getAttr(
|
||||
"{}.{}".format(node, data["attribute"])
|
||||
|
|
@ -310,11 +312,16 @@ class ValidateRenderSettings(pyblish.api.InstancePlugin):
|
|||
@classmethod
|
||||
def get_nodes(cls, instance, renderer):
|
||||
maya_settings = instance.context.data["project_settings"]["maya"]
|
||||
renderer_key = "{}_render_attributes".format(renderer)
|
||||
validation_settings = (
|
||||
maya_settings["publish"]["ValidateRenderSettings"].get(
|
||||
"{}_render_attributes".format(renderer)
|
||||
) or []
|
||||
)
|
||||
renderer_key
|
||||
)
|
||||
) or []
|
||||
validation_settings = [
|
||||
(item["type"], item["value"])
|
||||
for item in validation_settings
|
||||
]
|
||||
result = []
|
||||
for attr, values in OrderedDict(validation_settings).items():
|
||||
values = [convert_to_int_or_float(v) for v in values if v]
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ from ayon_core.hosts.maya.api import lib
|
|||
from ayon_core.pipeline.publish import (
|
||||
RepairAction,
|
||||
ValidateContentsOrder,
|
||||
PublishValidationError
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -38,7 +39,8 @@ class ValidateRigJointsHidden(pyblish.api.InstancePlugin):
|
|||
invalid = self.get_invalid(instance)
|
||||
|
||||
if invalid:
|
||||
raise ValueError("Visible joints found: {0}".format(invalid))
|
||||
raise PublishValidationError(
|
||||
"Visible joints found: {0}".format(invalid))
|
||||
|
||||
@classmethod
|
||||
def repair(cls, instance):
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Plugin for validating naming conventions."""
|
||||
import json
|
||||
from maya import cmds
|
||||
|
||||
import pyblish.api
|
||||
|
|
@ -35,29 +36,37 @@ class ValidateTransformNamingSuffix(pyblish.api.InstancePlugin,
|
|||
"""
|
||||
|
||||
order = ValidateContentsOrder
|
||||
hosts = ['maya']
|
||||
families = ['model']
|
||||
hosts = ["maya"]
|
||||
families = ["model"]
|
||||
optional = True
|
||||
label = 'Suffix Naming Conventions'
|
||||
label = "Suffix Naming Conventions"
|
||||
actions = [ayon_core.hosts.maya.api.action.SelectInvalidAction]
|
||||
SUFFIX_NAMING_TABLE = {"mesh": ["_GEO", "_GES", "_GEP", "_OSD"],
|
||||
"nurbsCurve": ["_CRV"],
|
||||
"nurbsSurface": ["_NRB"],
|
||||
"locator": ["_LOC"],
|
||||
"group": ["_GRP"]}
|
||||
SUFFIX_NAMING_TABLE = json.dumps({
|
||||
"mesh": ["_GEO", "_GES", "_GEP", "_OSD"],
|
||||
"nurbsCurve": ["_CRV"],
|
||||
"nurbsSurface": ["_NRB"],
|
||||
"locator": ["_LOC"],
|
||||
"group": ["_GRP"]
|
||||
})
|
||||
|
||||
ALLOW_IF_NOT_IN_SUFFIX_TABLE = True
|
||||
|
||||
@classmethod
|
||||
def get_table_for_invalid(cls):
|
||||
ss = []
|
||||
for k, v in cls.SUFFIX_NAMING_TABLE.items():
|
||||
ss.append(" - <b>{}</b>: {}".format(k, ", ".join(v)))
|
||||
suffix_naming_table = json.loads(cls.SUFFIX_NAMING_TABLE)
|
||||
ss = [
|
||||
" - <b>{}</b>: {}".format(k, ", ".join(v))
|
||||
for k, v in suffix_naming_table.items()
|
||||
]
|
||||
return "<br>".join(ss)
|
||||
|
||||
@staticmethod
|
||||
def is_valid_name(node_name, shape_type,
|
||||
SUFFIX_NAMING_TABLE, ALLOW_IF_NOT_IN_SUFFIX_TABLE):
|
||||
def is_valid_name(
|
||||
node_name,
|
||||
shape_type,
|
||||
suffix_naming_table,
|
||||
allow_if_not_in_suffix_table
|
||||
):
|
||||
"""Return whether node's name is correct.
|
||||
|
||||
The correctness for a transform's suffix is dependent on what
|
||||
|
|
@ -70,18 +79,18 @@ class ValidateTransformNamingSuffix(pyblish.api.InstancePlugin,
|
|||
Args:
|
||||
node_name (str): Node name.
|
||||
shape_type (str): Type of node.
|
||||
SUFFIX_NAMING_TABLE (dict): Mapping dict for suffixes.
|
||||
ALLOW_IF_NOT_IN_SUFFIX_TABLE (dict): Filter dict.
|
||||
suffix_naming_table (dict): Mapping dict for suffixes.
|
||||
allow_if_not_in_suffix_table (bool): Default output.
|
||||
|
||||
"""
|
||||
if shape_type not in SUFFIX_NAMING_TABLE:
|
||||
return ALLOW_IF_NOT_IN_SUFFIX_TABLE
|
||||
else:
|
||||
suffices = SUFFIX_NAMING_TABLE[shape_type]
|
||||
for suffix in suffices:
|
||||
if node_name.endswith(suffix):
|
||||
return True
|
||||
return False
|
||||
if shape_type not in suffix_naming_table:
|
||||
return allow_if_not_in_suffix_table
|
||||
|
||||
suffices = suffix_naming_table[shape_type]
|
||||
for suffix in suffices:
|
||||
if node_name.endswith(suffix):
|
||||
return True
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def get_invalid(cls, instance):
|
||||
|
|
@ -91,9 +100,10 @@ class ValidateTransformNamingSuffix(pyblish.api.InstancePlugin,
|
|||
instance (:class:`pyblish.api.Instance`): published instance.
|
||||
|
||||
"""
|
||||
transforms = cmds.ls(instance, type='transform', long=True)
|
||||
transforms = cmds.ls(instance, type="transform", long=True)
|
||||
|
||||
invalid = []
|
||||
suffix_naming_table = json.loads(cls.SUFFIX_NAMING_TABLE)
|
||||
for transform in transforms:
|
||||
shapes = cmds.listRelatives(transform,
|
||||
shapes=True,
|
||||
|
|
@ -101,9 +111,12 @@ class ValidateTransformNamingSuffix(pyblish.api.InstancePlugin,
|
|||
noIntermediate=True)
|
||||
|
||||
shape_type = cmds.nodeType(shapes[0]) if shapes else "group"
|
||||
if not cls.is_valid_name(transform, shape_type,
|
||||
cls.SUFFIX_NAMING_TABLE,
|
||||
cls.ALLOW_IF_NOT_IN_SUFFIX_TABLE):
|
||||
if not cls.is_valid_name(
|
||||
transform,
|
||||
shape_type,
|
||||
suffix_naming_table,
|
||||
cls.ALLOW_IF_NOT_IN_SUFFIX_TABLE
|
||||
):
|
||||
invalid.append(transform)
|
||||
|
||||
return invalid
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@ import re
|
|||
import pyblish.api
|
||||
|
||||
import ayon_core.hosts.maya.api.action
|
||||
from ayon_core.pipeline import legacy_io
|
||||
from ayon_core.settings import get_project_settings
|
||||
from ayon_core.pipeline.publish import (
|
||||
ValidateContentsOrder,
|
||||
OptionalPyblishPluginMixin,
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ if explicit_plugins_loading["enabled"]:
|
|||
key = "AYON_OPEN_WORKFILE_POST_INITIALIZATION"
|
||||
if bool(int(os.environ.get(key, "0"))):
|
||||
def _log_and_open():
|
||||
path = os.environ["AVALON_LAST_WORKFILE"]
|
||||
path = os.environ["AYON_LAST_WORKFILE"]
|
||||
print("Opening \"{}\"".format(path))
|
||||
cmds.file(path, open=True, force=True)
|
||||
cmds.evalDeferred(
|
||||
|
|
@ -46,24 +46,5 @@ if bool(int(os.environ.get(key, "0"))):
|
|||
lowestPriority=True
|
||||
)
|
||||
|
||||
# Build a shelf.
|
||||
shelf_preset = settings['maya'].get('project_shelf')
|
||||
if shelf_preset:
|
||||
icon_path = os.path.join(
|
||||
os.environ['OPENPYPE_PROJECT_SCRIPTS'],
|
||||
project_name,
|
||||
"icons")
|
||||
icon_path = os.path.abspath(icon_path)
|
||||
|
||||
for i in shelf_preset['imports']:
|
||||
import_string = "from {} import {}".format(project_name, i)
|
||||
print(import_string)
|
||||
exec(import_string)
|
||||
|
||||
cmds.evalDeferred(
|
||||
"mlib.shelf(name=shelf_preset['name'], iconPath=icon_path,"
|
||||
" preset=shelf_preset)"
|
||||
)
|
||||
|
||||
|
||||
print("Finished OpenPype usersetup.")
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ def deprecated(new_destination):
|
|||
class Context:
|
||||
main_window = None
|
||||
context_action_item = None
|
||||
project_name = os.getenv("AVALON_PROJECT")
|
||||
project_name = os.getenv("AYON_PROJECT_NAME")
|
||||
# Workfile related code
|
||||
workfiles_launched = False
|
||||
workfiles_tool_timer = None
|
||||
|
|
@ -2605,7 +2605,7 @@ Reopening Nuke should synchronize these paths and resolve any discrepancies.
|
|||
def set_favorites(self):
|
||||
from .utils import set_context_favorites
|
||||
|
||||
work_dir = os.getenv("AVALON_WORKDIR")
|
||||
work_dir = os.getenv("AYON_WORKDIR")
|
||||
asset = get_current_asset_name()
|
||||
favorite_items = OrderedDict()
|
||||
|
||||
|
|
@ -2953,7 +2953,7 @@ def process_workfile_builder():
|
|||
create_fv_on = workfile_builder.get("create_first_version") or None
|
||||
builder_on = workfile_builder.get("builder_on_start") or None
|
||||
|
||||
last_workfile_path = os.environ.get("AVALON_LAST_WORKFILE")
|
||||
last_workfile_path = os.environ.get("AYON_LAST_WORKFILE")
|
||||
|
||||
# generate first version in file not existing and feature is enabled
|
||||
if create_fv_on and not os.path.exists(last_workfile_path):
|
||||
|
|
@ -3203,7 +3203,7 @@ class DirmapCache:
|
|||
@classmethod
|
||||
def project_name(cls):
|
||||
if cls._project_name is None:
|
||||
cls._project_name = os.getenv("AVALON_PROJECT")
|
||||
cls._project_name = os.getenv("AYON_PROJECT_NAME")
|
||||
return cls._project_name
|
||||
|
||||
@classmethod
|
||||
|
|
|
|||
|
|
@ -21,10 +21,12 @@ from ayon_core.pipeline import (
|
|||
AVALON_CONTAINER_ID,
|
||||
get_current_asset_name,
|
||||
get_current_task_name,
|
||||
registered_host,
|
||||
)
|
||||
from ayon_core.pipeline.workfile import BuildWorkfile
|
||||
from ayon_core.tools.utils import host_tools
|
||||
from ayon_core.hosts.nuke import NUKE_ROOT_DIR
|
||||
from ayon_core.tools.workfile_template_build import open_template_ui
|
||||
|
||||
from .command import viewer_update_and_undo_stop
|
||||
from .lib import (
|
||||
|
|
@ -55,6 +57,7 @@ from .workfile_template_builder import (
|
|||
build_workfile_template,
|
||||
create_placeholder,
|
||||
update_placeholder,
|
||||
NukeTemplateBuilder,
|
||||
)
|
||||
from .workio import (
|
||||
open_file,
|
||||
|
|
@ -176,7 +179,7 @@ def add_nuke_callbacks():
|
|||
nuke.addOnScriptLoad(WorkfileSettings().set_context_settings)
|
||||
|
||||
|
||||
if nuke_settings["nuke-dirmap"]["enabled"]:
|
||||
if nuke_settings["dirmap"]["enabled"]:
|
||||
log.info("Added Nuke's dir-mapping callback ...")
|
||||
# Add dirmap for file paths.
|
||||
nuke.addFilenameFilter(dirmap_file_name_filter)
|
||||
|
|
@ -313,7 +316,7 @@ def _install_menu():
|
|||
lambda: BuildWorkfile().process()
|
||||
)
|
||||
|
||||
menu_template = menu.addMenu("Template Builder") # creating template menu
|
||||
menu_template = menu.addMenu("Template Builder")
|
||||
menu_template.addCommand(
|
||||
"Build Workfile from template",
|
||||
lambda: build_workfile_template()
|
||||
|
|
@ -321,6 +324,12 @@ def _install_menu():
|
|||
|
||||
if not ASSIST:
|
||||
menu_template.addSeparator()
|
||||
menu_template.addCommand(
|
||||
"Open template",
|
||||
lambda: open_template_ui(
|
||||
NukeTemplateBuilder(registered_host()), get_main_window()
|
||||
)
|
||||
)
|
||||
menu_template.addCommand(
|
||||
"Create Place Holder",
|
||||
lambda: create_placeholder()
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ from ayon_core.pipeline.workfile.workfile_template_builder import (
|
|||
LoadPlaceholderItem,
|
||||
CreatePlaceholderItem,
|
||||
PlaceholderLoadMixin,
|
||||
PlaceholderCreateMixin
|
||||
PlaceholderCreateMixin,
|
||||
)
|
||||
from ayon_core.tools.workfile_template_build import (
|
||||
WorkfileBuildPlaceholderDialog,
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ def current_file():
|
|||
|
||||
def work_root(session):
|
||||
|
||||
work_dir = session["AVALON_WORKDIR"]
|
||||
work_dir = session["AYON_WORKDIR"]
|
||||
scene_dir = session.get("AVALON_SCENEDIR")
|
||||
if scene_dir:
|
||||
path = os.path.join(work_dir, scene_dir)
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ class WriteNodeKnobSettingPanel(nukescripts.PythonPanel):
|
|||
for write_node in write_selected_nodes:
|
||||
# data for mapping the path
|
||||
data = {
|
||||
"work": os.getenv("AVALON_WORKDIR"),
|
||||
"work": os.getenv("AYON_WORKDIR"),
|
||||
"subset": write_node["name"].value(),
|
||||
"frame": "#" * frame_padding,
|
||||
"ext": ext
|
||||
|
|
|
|||
|
|
@ -3,12 +3,11 @@ import sys
|
|||
import contextlib
|
||||
import traceback
|
||||
|
||||
from ayon_core.lib import env_value_to_bool, Logger
|
||||
from ayon_core.lib import env_value_to_bool, Logger, is_in_tests
|
||||
from ayon_core.addon import AddonsManager
|
||||
from ayon_core.pipeline import install_host
|
||||
from ayon_core.tools.utils import host_tools
|
||||
from ayon_core.tools.utils import get_ayon_qt_app
|
||||
from ayon_core.tests.lib import is_in_tests
|
||||
|
||||
from .launch_logic import ProcessLauncher, stub
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ class PhotoshopHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost):
|
|||
return None
|
||||
|
||||
def work_root(self, session):
|
||||
return os.path.normpath(session["AVALON_WORKDIR"]).replace("\\", "/")
|
||||
return os.path.normpath(session["AYON_WORKDIR"]).replace("\\", "/")
|
||||
|
||||
def open_workfile(self, filepath):
|
||||
lib.stub().open(filepath)
|
||||
|
|
|
|||
|
|
@ -17,12 +17,11 @@ import os
|
|||
|
||||
import pyblish.api
|
||||
|
||||
from ayon_core.pipeline import legacy_io
|
||||
from openpype_modules.webpublisher.lib import (
|
||||
get_batch_asset_task_info,
|
||||
parse_json
|
||||
)
|
||||
from ayon_core.tests.lib import is_in_tests
|
||||
from ayon_core.lib import is_in_tests
|
||||
|
||||
|
||||
class CollectBatchData(pyblish.api.ContextPlugin):
|
||||
|
|
@ -53,10 +52,10 @@ class CollectBatchData(pyblish.api.ContextPlugin):
|
|||
assert os.path.exists(batch_dir), \
|
||||
"Folder {} doesn't exist".format(batch_dir)
|
||||
|
||||
project_name = os.environ.get("AVALON_PROJECT")
|
||||
project_name = os.environ.get("AYON_PROJECT_NAME")
|
||||
if project_name is None:
|
||||
raise AssertionError(
|
||||
"Environment `AVALON_PROJECT` was not found."
|
||||
"Environment `AYON_PROJECT_NAME` was not found."
|
||||
"Could not set project `root` which may cause issues."
|
||||
)
|
||||
|
||||
|
|
@ -69,10 +68,8 @@ class CollectBatchData(pyblish.api.ContextPlugin):
|
|||
batch_data["context"]
|
||||
)
|
||||
|
||||
os.environ["AVALON_ASSET"] = asset_name
|
||||
os.environ["AVALON_TASK"] = task_name
|
||||
legacy_io.Session["AVALON_ASSET"] = asset_name
|
||||
legacy_io.Session["AVALON_TASK"] = task_name
|
||||
os.environ["AYON_FOLDER_PATH"] = asset_name
|
||||
os.environ["AYON_TASK_NAME"] = task_name
|
||||
|
||||
context.data["asset"] = asset_name
|
||||
context.data["task"] = task_name
|
||||
|
|
|
|||
|
|
@ -3,10 +3,9 @@ import re
|
|||
|
||||
import pyblish.api
|
||||
|
||||
from ayon_core.lib import prepare_template_data
|
||||
from ayon_core.lib import prepare_template_data, is_in_tests
|
||||
from ayon_core.hosts.photoshop import api as photoshop
|
||||
from ayon_core.settings import get_project_settings
|
||||
from ayon_core.tests.lib import is_in_tests
|
||||
|
||||
|
||||
class CollectColorCodedInstances(pyblish.api.ContextPlugin):
|
||||
|
|
@ -29,9 +28,8 @@ class CollectColorCodedInstances(pyblish.api.ContextPlugin):
|
|||
Identifier:
|
||||
id (str): "pyblish.avalon.instance"
|
||||
"""
|
||||
order = pyblish.api.CollectorOrder + 0.100
|
||||
|
||||
label = "Instances"
|
||||
label = "Collect Color-coded Instances"
|
||||
order = pyblish.api.CollectorOrder
|
||||
hosts = ["photoshop"]
|
||||
targets = ["automated"]
|
||||
|
|
@ -42,7 +40,7 @@ class CollectColorCodedInstances(pyblish.api.ContextPlugin):
|
|||
# flattened template cannot
|
||||
subset_template_name = ""
|
||||
create_flatten_image = "no"
|
||||
flatten_subset_template = ""
|
||||
flatten_product_name_template = ""
|
||||
|
||||
def process(self, context):
|
||||
self.log.info("CollectColorCodedInstances")
|
||||
|
|
@ -124,12 +122,12 @@ class CollectColorCodedInstances(pyblish.api.ContextPlugin):
|
|||
|
||||
if self.create_flatten_image != "no" and publishable_layers:
|
||||
self.log.debug("create_flatten_image")
|
||||
if not self.flatten_subset_template:
|
||||
if not self.flatten_product_name_template:
|
||||
self.log.warning("No template for flatten image")
|
||||
return
|
||||
|
||||
fill_pairs.pop("layer")
|
||||
subset = self.flatten_subset_template.format(
|
||||
subset = self.flatten_product_name_template.format(
|
||||
**prepare_template_data(fill_pairs))
|
||||
|
||||
first_layer = publishable_layers[0] # dummy layer
|
||||
|
|
|
|||
|
|
@ -6,24 +6,17 @@ Provides:
|
|||
instance -> family ("review")
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
import pyblish.api
|
||||
|
||||
from ayon_core.pipeline.create import get_subset_name
|
||||
|
||||
|
||||
class CollectReview(pyblish.api.ContextPlugin):
|
||||
"""Adds review to families for instances marked to be reviewable.
|
||||
"""
|
||||
|
||||
label = "Collect Review"
|
||||
label = "Review"
|
||||
hosts = ["photoshop"]
|
||||
order = pyblish.api.CollectorOrder + 0.1
|
||||
|
||||
publish = True
|
||||
|
||||
def process(self, context):
|
||||
for instance in context:
|
||||
creator_attributes = instance.data["creator_attributes"]
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ def open_file(filepath):
|
|||
def current_file():
|
||||
pm = get_project_manager()
|
||||
file_ext = file_extensions()[0]
|
||||
workdir_path = os.getenv("AVALON_WORKDIR")
|
||||
workdir_path = os.getenv("AYON_WORKDIR")
|
||||
project = pm.GetCurrentProject()
|
||||
project_name = project.GetName()
|
||||
file_name = project_name + file_ext
|
||||
|
|
@ -93,4 +93,4 @@ def current_file():
|
|||
|
||||
|
||||
def work_root(session):
|
||||
return os.path.normpath(session["AVALON_WORKDIR"]).replace("\\", "/")
|
||||
return os.path.normpath(session["AYON_WORKDIR"]).replace("\\", "/")
|
||||
|
|
|
|||
|
|
@ -240,33 +240,34 @@ class SubstanceHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost):
|
|||
|
||||
def _install_shelves(self, project_settings):
|
||||
|
||||
shelves = project_settings["substancepainter"].get("shelves", {})
|
||||
shelves = project_settings["substancepainter"].get("shelves", [])
|
||||
if not shelves:
|
||||
return
|
||||
|
||||
# Prepare formatting data if we detect any path which might have
|
||||
# template tokens like {asset} in there.
|
||||
formatting_data = {}
|
||||
has_formatting_entries = any("{" in path for path in shelves.values())
|
||||
has_formatting_entries = any("{" in item["value"] for item in shelves)
|
||||
if has_formatting_entries:
|
||||
project_name = self.get_current_project_name()
|
||||
asset_name = self.get_current_asset_name()
|
||||
task_name = self.get_current_asset_name()
|
||||
system_settings = get_system_settings()
|
||||
formatting_data = get_template_data_with_names(project_name,
|
||||
asset_name,
|
||||
task_name,
|
||||
system_settings)
|
||||
formatting_data = get_template_data_with_names(
|
||||
project_name, asset_name, task_name, system_settings
|
||||
)
|
||||
anatomy = Anatomy(project_name)
|
||||
formatting_data["root"] = anatomy.roots
|
||||
|
||||
for name, path in shelves.items():
|
||||
shelf_name = None
|
||||
for shelve_item in shelves:
|
||||
|
||||
# Allow formatting with anatomy for the paths
|
||||
path = shelve_item["value"]
|
||||
if "{" in path:
|
||||
path = StringTemplate.format_template(path, formatting_data)
|
||||
|
||||
name = shelve_item["name"]
|
||||
shelf_name = None
|
||||
try:
|
||||
shelf_name = lib.load_shelf(path, name=name)
|
||||
except ValueError as exc:
|
||||
|
|
|
|||
|
|
@ -16,25 +16,31 @@ class ShotMetadataSolver:
|
|||
|
||||
NO_DECOR_PATERN = re.compile(r"\{([a-z]*?)\}")
|
||||
|
||||
# presets
|
||||
clip_name_tokenizer = None
|
||||
shot_rename = True
|
||||
shot_hierarchy = None
|
||||
shot_add_tasks = None
|
||||
def __init__(self, logger):
|
||||
self.clip_name_tokenizer = []
|
||||
self.shot_rename = {
|
||||
"enabled": False,
|
||||
"shot_rename_template": "",
|
||||
}
|
||||
self.shot_hierarchy = {
|
||||
"enabled": False,
|
||||
"parents": [],
|
||||
"parents_path": "",
|
||||
}
|
||||
self.shot_add_tasks = []
|
||||
self.log = logger
|
||||
|
||||
def __init__(
|
||||
def update_data(
|
||||
self,
|
||||
clip_name_tokenizer,
|
||||
shot_rename,
|
||||
shot_hierarchy,
|
||||
shot_add_tasks,
|
||||
logger
|
||||
shot_add_tasks
|
||||
):
|
||||
self.clip_name_tokenizer = clip_name_tokenizer
|
||||
self.shot_rename = shot_rename
|
||||
self.shot_hierarchy = shot_hierarchy
|
||||
self.shot_add_tasks = shot_add_tasks
|
||||
self.log = logger
|
||||
|
||||
def _rename_template(self, data):
|
||||
"""Shot renaming function
|
||||
|
|
@ -86,7 +92,9 @@ class ShotMetadataSolver:
|
|||
|
||||
search_text = parent_name + clip_name
|
||||
|
||||
for token_key, pattern in self.clip_name_tokenizer.items():
|
||||
for clip_name_item in self.clip_name_tokenizer:
|
||||
token_key = clip_name_item["name"]
|
||||
pattern = clip_name_item["regex"]
|
||||
p = re.compile(pattern)
|
||||
match = p.findall(search_text)
|
||||
if not match:
|
||||
|
|
@ -137,11 +145,11 @@ class ShotMetadataSolver:
|
|||
))
|
||||
|
||||
_parent_tokens_type = {
|
||||
parent_token["name"]: parent_token["type"]
|
||||
parent_token["name"]: parent_token["parent_type"]
|
||||
for parent_token in hierarchy_parents
|
||||
}
|
||||
for _index, _parent in enumerate(
|
||||
shot_hierarchy["parents_path"].split("/")
|
||||
shot_hierarchy["parents_path"].split("/")
|
||||
):
|
||||
# format parent token with value which is formatted
|
||||
try:
|
||||
|
|
@ -262,22 +270,22 @@ class ShotMetadataSolver:
|
|||
"""
|
||||
tasks_to_add = {}
|
||||
|
||||
project_tasks = project_doc["config"]["tasks"]
|
||||
for task_name, task_data in self.shot_add_tasks.items():
|
||||
_task_data = deepcopy(task_data)
|
||||
project_task_types = project_doc["config"]["tasks"]
|
||||
for task_item in self.shot_add_tasks:
|
||||
task_name = task_item["name"]
|
||||
task_type = task_item["task_type"]
|
||||
|
||||
# check if task type in project task types
|
||||
if _task_data["type"] in project_tasks.keys():
|
||||
tasks_to_add[task_name] = _task_data
|
||||
else:
|
||||
if task_type not in project_task_types.keys():
|
||||
raise KeyError(
|
||||
"Missing task type `{}` for `{}` is not"
|
||||
" existing in `{}``".format(
|
||||
_task_data["type"],
|
||||
task_type,
|
||||
task_name,
|
||||
list(project_tasks.keys())
|
||||
list(project_task_types.keys())
|
||||
)
|
||||
)
|
||||
tasks_to_add[task_name] = {"type": task_type}
|
||||
|
||||
return tasks_to_add
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import pyblish.api
|
|||
|
||||
from ayon_core.pipeline import (
|
||||
register_creator_plugin_path,
|
||||
legacy_io,
|
||||
)
|
||||
from ayon_core.host import HostBase, IPublishHost
|
||||
|
||||
|
|
@ -23,8 +22,7 @@ class TrayPublisherHost(HostBase, IPublishHost):
|
|||
name = "traypublisher"
|
||||
|
||||
def install(self):
|
||||
os.environ["AVALON_APP"] = self.name
|
||||
legacy_io.Session["AVALON_APP"] = self.name
|
||||
os.environ["AYON_HOST_NAME"] = self.name
|
||||
|
||||
pyblish.api.register_host("traypublisher")
|
||||
pyblish.api.register_plugin_path(PUBLISH_PATH)
|
||||
|
|
@ -42,9 +40,7 @@ class TrayPublisherHost(HostBase, IPublishHost):
|
|||
def set_project_name(self, project_name):
|
||||
# TODO Deregister project specific plugins and register new project
|
||||
# plugins
|
||||
os.environ["AVALON_PROJECT"] = project_name
|
||||
legacy_io.Session["AVALON_PROJECT"] = project_name
|
||||
legacy_io.install()
|
||||
os.environ["AYON_PROJECT_NAME"] = project_name
|
||||
HostContext.set_project_name(project_name)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -311,7 +311,7 @@ class SettingsCreator(TrayPublishCreator):
|
|||
@classmethod
|
||||
def from_settings(cls, item_data):
|
||||
identifier = item_data["identifier"]
|
||||
family = item_data["family"]
|
||||
family = item_data["product_type"]
|
||||
if not identifier:
|
||||
identifier = "settings_{}".format(family)
|
||||
return type(
|
||||
|
|
|
|||
|
|
@ -174,46 +174,42 @@ Supporting publishing new shots to project
|
|||
or updating already created. Publishing will create OTIO file.
|
||||
"""
|
||||
icon = "fa.file"
|
||||
product_type_presets = []
|
||||
|
||||
def __init__(
|
||||
self, project_settings, *args, **kwargs
|
||||
):
|
||||
super(EditorialSimpleCreator, self).__init__(
|
||||
project_settings, *args, **kwargs
|
||||
)
|
||||
def __init__(self, *args, **kwargs):
|
||||
self._shot_metadata_solver = ShotMetadataSolver(self.log)
|
||||
super(EditorialSimpleCreator, self).__init__(*args, **kwargs)
|
||||
|
||||
def apply_settings(self, project_settings):
|
||||
editorial_creators = deepcopy(
|
||||
project_settings["traypublisher"]["editorial_creators"]
|
||||
)
|
||||
# get this creator settings by identifier
|
||||
self._creator_settings = editorial_creators.get(self.identifier)
|
||||
creator_settings = editorial_creators.get(self.identifier)
|
||||
|
||||
clip_name_tokenizer = self._creator_settings["clip_name_tokenizer"]
|
||||
shot_rename = self._creator_settings["shot_rename"]
|
||||
shot_hierarchy = self._creator_settings["shot_hierarchy"]
|
||||
shot_add_tasks = self._creator_settings["shot_add_tasks"]
|
||||
|
||||
self._shot_metadata_solver = ShotMetadataSolver(
|
||||
clip_name_tokenizer,
|
||||
shot_rename,
|
||||
shot_hierarchy,
|
||||
shot_add_tasks,
|
||||
self.log
|
||||
self._shot_metadata_solver.update_data(
|
||||
creator_settings["clip_name_tokenizer"],
|
||||
creator_settings["shot_rename"],
|
||||
creator_settings["shot_hierarchy"],
|
||||
creator_settings["shot_add_tasks"]
|
||||
)
|
||||
|
||||
# try to set main attributes from settings
|
||||
if self._creator_settings.get("default_variants"):
|
||||
self.default_variants = self._creator_settings["default_variants"]
|
||||
self.product_type_presets = creator_settings["product_type_presets"]
|
||||
default_variants = creator_settings.get("default_variants")
|
||||
if default_variants:
|
||||
self.default_variants = default_variants
|
||||
|
||||
def create(self, subset_name, instance_data, pre_create_data):
|
||||
allowed_family_presets = self._get_allowed_family_presets(
|
||||
allowed_product_type_presets = self._get_allowed_product_type_presets(
|
||||
pre_create_data)
|
||||
|
||||
product_types = {
|
||||
item["product_type"]
|
||||
for item in self.product_type_presets
|
||||
}
|
||||
clip_instance_properties = {
|
||||
k: v for k, v in pre_create_data.items()
|
||||
k: v
|
||||
for k, v in pre_create_data.items()
|
||||
if k != "sequence_filepath_data"
|
||||
if k not in [
|
||||
i["family"] for i in self._creator_settings["family_presets"]
|
||||
]
|
||||
if k not in product_types
|
||||
}
|
||||
|
||||
asset_name = instance_data["folderPath"]
|
||||
|
|
@ -255,7 +251,7 @@ or updating already created. Publishing will create OTIO file.
|
|||
otio_timeline,
|
||||
media_path,
|
||||
clip_instance_properties,
|
||||
allowed_family_presets,
|
||||
allowed_product_type_presets,
|
||||
os.path.basename(seq_path),
|
||||
first_otio_timeline
|
||||
)
|
||||
|
|
@ -355,7 +351,7 @@ or updating already created. Publishing will create OTIO file.
|
|||
otio_timeline,
|
||||
media_path,
|
||||
instance_data,
|
||||
family_presets,
|
||||
product_type_presets,
|
||||
sequence_file_name,
|
||||
first_otio_timeline=None
|
||||
):
|
||||
|
|
@ -365,7 +361,7 @@ or updating already created. Publishing will create OTIO file.
|
|||
otio_timeline (otio.Timeline): otio timeline object
|
||||
media_path (str): media file path string
|
||||
instance_data (dict): clip instance data
|
||||
family_presets (list): list of dict settings subset presets
|
||||
product_type_presets (list): list of dict settings subset presets
|
||||
"""
|
||||
|
||||
tracks = [
|
||||
|
|
@ -411,17 +407,17 @@ or updating already created. Publishing will create OTIO file.
|
|||
"instance_id": None
|
||||
}
|
||||
|
||||
for _fpreset in family_presets:
|
||||
for product_type_preset in product_type_presets:
|
||||
# exclude audio family if no audio stream
|
||||
if (
|
||||
_fpreset["family"] == "audio"
|
||||
product_type_preset["product_type"] == "audio"
|
||||
and not media_data.get("audio")
|
||||
):
|
||||
continue
|
||||
|
||||
instance = self._make_subset_instance(
|
||||
otio_clip,
|
||||
_fpreset,
|
||||
product_type_preset,
|
||||
deepcopy(base_instance_data),
|
||||
parenting_data
|
||||
)
|
||||
|
|
@ -533,7 +529,7 @@ or updating already created. Publishing will create OTIO file.
|
|||
def _make_subset_instance(
|
||||
self,
|
||||
otio_clip,
|
||||
preset,
|
||||
product_type_preset,
|
||||
instance_data,
|
||||
parenting_data
|
||||
):
|
||||
|
|
@ -541,16 +537,16 @@ or updating already created. Publishing will create OTIO file.
|
|||
|
||||
Args:
|
||||
otio_clip (otio.Clip): otio clip object
|
||||
preset (dict): single family preset
|
||||
product_type_preset (dict): single family preset
|
||||
instance_data (dict): instance data
|
||||
parenting_data (dict): shot instance parent data
|
||||
|
||||
Returns:
|
||||
CreatedInstance: creator instance object
|
||||
"""
|
||||
family = preset["family"]
|
||||
family = product_type_preset["product_type"]
|
||||
label = self._make_subset_naming(
|
||||
preset,
|
||||
product_type_preset,
|
||||
instance_data
|
||||
)
|
||||
instance_data["label"] = label
|
||||
|
|
@ -569,11 +565,11 @@ or updating already created. Publishing will create OTIO file.
|
|||
else:
|
||||
# add review family if defined
|
||||
instance_data.update({
|
||||
"outputFileType": preset["output_file_type"],
|
||||
"outputFileType": product_type_preset["output_file_type"],
|
||||
"parent_instance_id": parenting_data["instance_id"],
|
||||
"creator_attributes": {
|
||||
"parent_instance": parenting_data["instance_label"],
|
||||
"add_review_family": preset.get("review")
|
||||
"add_review_family": product_type_preset.get("review")
|
||||
}
|
||||
})
|
||||
|
||||
|
|
@ -585,15 +581,11 @@ or updating already created. Publishing will create OTIO file.
|
|||
|
||||
return c_instance
|
||||
|
||||
def _make_subset_naming(
|
||||
self,
|
||||
preset,
|
||||
instance_data
|
||||
):
|
||||
def _make_subset_naming(self, product_type_preset, instance_data):
|
||||
""" Subset name maker
|
||||
|
||||
Args:
|
||||
preset (dict): single preset item
|
||||
product_type_preset (dict): single preset item
|
||||
instance_data (dict): instance data
|
||||
|
||||
Returns:
|
||||
|
|
@ -602,10 +594,10 @@ or updating already created. Publishing will create OTIO file.
|
|||
asset_name = instance_data["creator_attributes"]["folderPath"]
|
||||
|
||||
variant_name = instance_data["variant"]
|
||||
family = preset["family"]
|
||||
family = product_type_preset["product_type"]
|
||||
|
||||
# get variant name from preset or from inheritance
|
||||
_variant_name = preset.get("variant") or variant_name
|
||||
_variant_name = product_type_preset.get("variant") or variant_name
|
||||
|
||||
# subset name
|
||||
subset_name = "{}{}".format(
|
||||
|
|
@ -763,7 +755,7 @@ or updating already created. Publishing will create OTIO file.
|
|||
"sourceOut": int(source_out)
|
||||
}
|
||||
|
||||
def _get_allowed_family_presets(self, pre_create_data):
|
||||
def _get_allowed_product_type_presets(self, pre_create_data):
|
||||
""" Filter out allowed family presets.
|
||||
|
||||
Args:
|
||||
|
|
@ -773,10 +765,11 @@ or updating already created. Publishing will create OTIO file.
|
|||
list: lit of dict with preset items
|
||||
"""
|
||||
return [
|
||||
{"family": "shot"},
|
||||
{"product_type": "shot"},
|
||||
*[
|
||||
preset for preset in self._creator_settings["family_presets"]
|
||||
if pre_create_data[preset["family"]]
|
||||
preset
|
||||
for preset in self.product_type_presets
|
||||
if pre_create_data[preset["product_type"]]
|
||||
]
|
||||
]
|
||||
|
||||
|
|
@ -853,8 +846,8 @@ or updating already created. Publishing will create OTIO file.
|
|||
]
|
||||
# add variants swithers
|
||||
attr_defs.extend(
|
||||
BoolDef(_var["family"], label=_var["family"])
|
||||
for _var in self._creator_settings["family_presets"]
|
||||
BoolDef(item["product_type"], label=item["product_type"])
|
||||
for item in self.product_type_presets
|
||||
)
|
||||
attr_defs.append(UISeparatorDef())
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ log = Logger.get_logger(__name__)
|
|||
def initialize():
|
||||
from ayon_core.hosts.traypublisher.api.plugin import SettingsCreator
|
||||
|
||||
project_name = os.environ["AVALON_PROJECT"]
|
||||
project_name = os.environ["AYON_PROJECT_NAME"]
|
||||
project_settings = get_project_settings(project_name)
|
||||
|
||||
simple_creators = project_settings["traypublisher"]["simple_creators"]
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ from ayon_core.hosts.tvpaint import TVPAINT_ROOT_DIR
|
|||
from ayon_core.settings import get_current_project_settings
|
||||
from ayon_core.lib import register_event_callback
|
||||
from ayon_core.pipeline import (
|
||||
legacy_io,
|
||||
register_loader_plugin_path,
|
||||
register_creator_plugin_path,
|
||||
AVALON_CONTAINER_ID,
|
||||
|
|
@ -66,11 +65,10 @@ class TVPaintHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost):
|
|||
def install(self):
|
||||
"""Install TVPaint-specific functionality."""
|
||||
|
||||
log.info("OpenPype - Installing TVPaint integration")
|
||||
legacy_io.install()
|
||||
log.info("AYON - Installing TVPaint integration")
|
||||
|
||||
# Create workdir folder if does not exist yet
|
||||
workdir = legacy_io.Session["AVALON_WORKDIR"]
|
||||
workdir = os.getenv("AYON_WORKDIR")
|
||||
if not os.path.exists(workdir):
|
||||
os.makedirs(workdir)
|
||||
|
||||
|
|
@ -157,7 +155,7 @@ class TVPaintHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost):
|
|||
return execute_george(george_script)
|
||||
|
||||
def work_root(self, session):
|
||||
return session["AVALON_WORKDIR"]
|
||||
return session["AYON_WORKDIR"]
|
||||
|
||||
def get_current_workfile(self):
|
||||
return execute_george("tv_GetProjectName")
|
||||
|
|
@ -176,7 +174,7 @@ class TVPaintHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost):
|
|||
# Setup project settings if its the template that's launched.
|
||||
# TODO also check for template creation when it's possible to define
|
||||
# templates
|
||||
last_workfile = os.environ.get("AVALON_LAST_WORKFILE")
|
||||
last_workfile = os.environ.get("AYON_LAST_WORKFILE")
|
||||
if not last_workfile or os.path.exists(last_workfile):
|
||||
return
|
||||
|
||||
|
|
|
|||
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