diff --git a/CHANGELOG.md b/CHANGELOG.md
index 455c7aa900..dca0e7ecef 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,29 +1,38 @@
# Changelog
-## [3.14.4-nightly.2](https://github.com/pypeclub/OpenPype/tree/HEAD)
+## [3.14.4-nightly.3](https://github.com/pypeclub/OpenPype/tree/HEAD)
[Full Changelog](https://github.com/pypeclub/OpenPype/compare/3.14.3...HEAD)
**🚀 Enhancements**
- General: Set root environments before DCC launch [\#3947](https://github.com/pypeclub/OpenPype/pull/3947)
+- Refactor: changed legacy way to update database for Hero version integrate [\#3941](https://github.com/pypeclub/OpenPype/pull/3941)
- Maya: Moved plugin from global to maya [\#3939](https://github.com/pypeclub/OpenPype/pull/3939)
+- Fusion: Implement Alembic and FBX mesh loader [\#3927](https://github.com/pypeclub/OpenPype/pull/3927)
- Publisher: Instances can be marked as stored [\#3846](https://github.com/pypeclub/OpenPype/pull/3846)
**🐛 Bug fixes**
+- Maya: Deadline OutputFilePath hack regression for Renderman [\#3950](https://github.com/pypeclub/OpenPype/pull/3950)
+- Houdini: Fix validate workfile paths for non-parm file references [\#3948](https://github.com/pypeclub/OpenPype/pull/3948)
- Photoshop: missed sync published version of workfile with workfile [\#3946](https://github.com/pypeclub/OpenPype/pull/3946)
- Maya: fix regression of Renderman Deadline hack [\#3943](https://github.com/pypeclub/OpenPype/pull/3943)
+- Tray: Change order of attribute changes [\#3938](https://github.com/pypeclub/OpenPype/pull/3938)
- AttributeDefs: Fix crashing multivalue of files widget [\#3937](https://github.com/pypeclub/OpenPype/pull/3937)
+- General: Fix links query on hero version [\#3900](https://github.com/pypeclub/OpenPype/pull/3900)
- Publisher: Files Drag n Drop cleanup [\#3888](https://github.com/pypeclub/OpenPype/pull/3888)
- Maya: Render settings validation attribute check tweak logging [\#3821](https://github.com/pypeclub/OpenPype/pull/3821)
**🔀 Refactored code**
+- General: Direct settings imports [\#3934](https://github.com/pypeclub/OpenPype/pull/3934)
- General: import 'Logger' from 'openpype.lib' [\#3926](https://github.com/pypeclub/OpenPype/pull/3926)
**Merged pull requests:**
+- Maya + Yeti: Load Yeti Cache fix frame number recognition [\#3942](https://github.com/pypeclub/OpenPype/pull/3942)
+- Fusion: Implement callbacks to Fusion's event system thread [\#3928](https://github.com/pypeclub/OpenPype/pull/3928)
- Photoshop: create single frame image in Ftrack as review [\#3908](https://github.com/pypeclub/OpenPype/pull/3908)
- Maya: Warn correctly about nodes in render instance with unexpected names [\#3816](https://github.com/pypeclub/OpenPype/pull/3816)
@@ -68,6 +77,7 @@
- Unreal: Use new Extractor location [\#3917](https://github.com/pypeclub/OpenPype/pull/3917)
- Flame: Use new Extractor location [\#3916](https://github.com/pypeclub/OpenPype/pull/3916)
- Houdini: Use new Extractor location [\#3894](https://github.com/pypeclub/OpenPype/pull/3894)
+- Harmony: Use new Extractor location [\#3893](https://github.com/pypeclub/OpenPype/pull/3893)
- Hiero: Use new Extractor location [\#3851](https://github.com/pypeclub/OpenPype/pull/3851)
- Maya: Remove old legacy \(ftrack\) plug-ins that are of no use anymore [\#3819](https://github.com/pypeclub/OpenPype/pull/3819)
- Nuke: Use new Extractor location [\#3799](https://github.com/pypeclub/OpenPype/pull/3799)
@@ -97,18 +107,6 @@
- Igniter: Fix status handling when version is already installed [\#3804](https://github.com/pypeclub/OpenPype/pull/3804)
- Resolve: Addon import is Python 2 compatible [\#3798](https://github.com/pypeclub/OpenPype/pull/3798)
- Hiero: retimed clip publishing is working [\#3792](https://github.com/pypeclub/OpenPype/pull/3792)
-- nuke: validate write node is not failing due wrong type [\#3780](https://github.com/pypeclub/OpenPype/pull/3780)
-- Fix - changed format of version string in pyproject.toml [\#3777](https://github.com/pypeclub/OpenPype/pull/3777)
-
-**🔀 Refactored code**
-
-- Photoshop: Use new Extractor location [\#3789](https://github.com/pypeclub/OpenPype/pull/3789)
-- Blender: Use new Extractor location [\#3787](https://github.com/pypeclub/OpenPype/pull/3787)
-- AfterEffects: Use new Extractor location [\#3784](https://github.com/pypeclub/OpenPype/pull/3784)
-
-**Merged pull requests:**
-
-- Standalone Publisher: Ignore empty labels, then still use name like other asset models [\#3779](https://github.com/pypeclub/OpenPype/pull/3779)
## [3.14.1](https://github.com/pypeclub/OpenPype/tree/3.14.1) (2022-08-30)
diff --git a/openpype/client/operations.py b/openpype/client/operations.py
index 48e8645726..fd639c34a7 100644
--- a/openpype/client/operations.py
+++ b/openpype/client/operations.py
@@ -23,6 +23,7 @@ CURRENT_PROJECT_CONFIG_SCHEMA = "openpype:config-2.0"
CURRENT_ASSET_DOC_SCHEMA = "openpype:asset-3.0"
CURRENT_SUBSET_SCHEMA = "openpype:subset-3.0"
CURRENT_VERSION_SCHEMA = "openpype:version-3.0"
+CURRENT_HERO_VERSION_SCHEMA = "openpype:hero_version-1.0"
CURRENT_REPRESENTATION_SCHEMA = "openpype:representation-2.0"
CURRENT_WORKFILE_INFO_SCHEMA = "openpype:workfile-1.0"
CURRENT_THUMBNAIL_SCHEMA = "openpype:thumbnail-1.0"
@@ -162,6 +163,34 @@ def new_version_doc(version, subset_id, data=None, entity_id=None):
}
+def new_hero_version_doc(version_id, subset_id, data=None, entity_id=None):
+ """Create skeleton data of hero version document.
+
+ Args:
+ version_id (ObjectId): Is considered as unique identifier of version
+ under subset.
+ subset_id (Union[str, ObjectId]): Id of parent subset.
+ data (Dict[str, Any]): Version document data.
+ entity_id (Union[str, ObjectId]): Predefined id of document. New id is
+ created if not passed.
+
+ Returns:
+ Dict[str, Any]: Skeleton of version document.
+ """
+
+ if data is None:
+ data = {}
+
+ return {
+ "_id": _create_or_convert_to_mongo_id(entity_id),
+ "schema": CURRENT_HERO_VERSION_SCHEMA,
+ "type": "hero_version",
+ "version_id": version_id,
+ "parent": subset_id,
+ "data": data
+ }
+
+
def new_representation_doc(
name, version_id, context, data=None, entity_id=None
):
@@ -293,6 +322,20 @@ def prepare_version_update_data(old_doc, new_doc, replace=True):
return _prepare_update_data(old_doc, new_doc, replace)
+def prepare_hero_version_update_data(old_doc, new_doc, replace=True):
+ """Compare two hero version documents and prepare update data.
+
+ Based on compared values will create update data for 'UpdateOperation'.
+
+ Empty output means that documents are identical.
+
+ Returns:
+ Dict[str, Any]: Changes between old and new document.
+ """
+
+ return _prepare_update_data(old_doc, new_doc, replace)
+
+
def prepare_representation_update_data(old_doc, new_doc, replace=True):
"""Compare two representation documents and prepare update data.
diff --git a/openpype/hosts/flame/api/plugin.py b/openpype/hosts/flame/api/plugin.py
index 4bbdc79621..092ce9d106 100644
--- a/openpype/hosts/flame/api/plugin.py
+++ b/openpype/hosts/flame/api/plugin.py
@@ -6,9 +6,9 @@ from xml.etree import ElementTree as ET
from Qt import QtCore, QtWidgets
-import openpype.api as openpype
import qargparse
from openpype import style
+from openpype.settings import get_current_project_settings
from openpype.lib import Logger
from openpype.pipeline import LegacyCreator, LoaderPlugin
@@ -306,7 +306,7 @@ class Creator(LegacyCreator):
def __init__(self, *args, **kwargs):
super(Creator, self).__init__(*args, **kwargs)
- self.presets = openpype.get_current_project_settings()[
+ self.presets = get_current_project_settings()[
"flame"]["create"].get(self.__class__.__name__, {})
# adding basic current context flame objects
diff --git a/openpype/hosts/flame/hooks/pre_flame_setup.py b/openpype/hosts/flame/hooks/pre_flame_setup.py
index 0173eb8e3b..f0fdaa86ba 100644
--- a/openpype/hosts/flame/hooks/pre_flame_setup.py
+++ b/openpype/hosts/flame/hooks/pre_flame_setup.py
@@ -42,17 +42,9 @@ class FlamePrelaunch(PreLaunchHook):
volume_name = _env.get("FLAME_WIRETAP_VOLUME")
# get image io
- project_anatomy = self.data["anatomy"]
+ project_settings = self.data["project_settings"]
- # make sure anatomy settings are having flame key
- if not project_anatomy["imageio"].get("flame"):
- raise ApplicationLaunchFailed((
- "Anatomy project settings are missing `flame` key. "
- "Please make sure you remove project overides on "
- "Anatomy Image io")
- )
-
- imageio_flame = project_anatomy["imageio"]["flame"]
+ imageio_flame = project_settings["flame"]["imageio"]
# get user name and host name
user_name = get_openpype_username()
diff --git a/openpype/hosts/fusion/hooks/pre_fusion_ocio_hook.py b/openpype/hosts/fusion/hooks/pre_fusion_ocio_hook.py
index 12fc640f5c..d1ae5f64fd 100644
--- a/openpype/hosts/fusion/hooks/pre_fusion_ocio_hook.py
+++ b/openpype/hosts/fusion/hooks/pre_fusion_ocio_hook.py
@@ -15,13 +15,7 @@ class FusionPreLaunchOCIO(PreLaunchHook):
project_settings = self.data["project_settings"]
# make sure anatomy settings are having flame key
- imageio_fusion = project_settings.get("fusion", {}).get("imageio")
- if not imageio_fusion:
- raise ApplicationLaunchFailed((
- "Anatomy project settings are missing `fusion` key. "
- "Please make sure you remove project overrides on "
- "Anatomy ImageIO")
- )
+ imageio_fusion = project_settings["fusion"]["imageio"]
ocio = imageio_fusion.get("ocio")
enabled = ocio.get("enabled", False)
diff --git a/openpype/hosts/hiero/api/lib.py b/openpype/hosts/hiero/api/lib.py
index 895e95e0c0..e5d35945af 100644
--- a/openpype/hosts/hiero/api/lib.py
+++ b/openpype/hosts/hiero/api/lib.py
@@ -14,7 +14,7 @@ import hiero
from Qt import QtWidgets
from openpype.client import get_project
-from openpype.settings import get_anatomy_settings
+from openpype.settings import get_project_settings
from openpype.pipeline import legacy_io, Anatomy
from openpype.pipeline.load import filter_containers
from openpype.lib import Logger
@@ -878,8 +878,7 @@ def apply_colorspace_project():
project.close()
# get presets for hiero
- imageio = get_anatomy_settings(
- project_name)["imageio"].get("hiero", None)
+ imageio = get_project_settings(project_name)["hiero"]["imageio"]
presets = imageio.get("workfile")
# save the workfile as subversion "comment:_colorspaceChange"
@@ -932,8 +931,7 @@ def apply_colorspace_clips():
clips = project.clips()
# get presets for hiero
- imageio = get_anatomy_settings(
- project_name)["imageio"].get("hiero", None)
+ imageio = get_project_settings(project_name)["hiero"]["imageio"]
from pprint import pprint
presets = imageio.get("regexInputs", {}).get("inputs", {})
diff --git a/openpype/hosts/hiero/api/plugin.py b/openpype/hosts/hiero/api/plugin.py
index 77fedbbbdc..ea8a9e836a 100644
--- a/openpype/hosts/hiero/api/plugin.py
+++ b/openpype/hosts/hiero/api/plugin.py
@@ -8,7 +8,7 @@ import hiero
from Qt import QtWidgets, QtCore
import qargparse
-import openpype.api as openpype
+from openpype.settings import get_current_project_settings
from openpype.lib import Logger
from openpype.pipeline import LoaderPlugin, LegacyCreator
from openpype.pipeline.context_tools import get_current_project_asset
@@ -606,7 +606,7 @@ class Creator(LegacyCreator):
def __init__(self, *args, **kwargs):
super(Creator, self).__init__(*args, **kwargs)
import openpype.hosts.hiero.api as phiero
- self.presets = openpype.get_current_project_settings()[
+ self.presets = get_current_project_settings()[
"hiero"]["create"].get(self.__class__.__name__, {})
# adding basic current context resolve objects
diff --git a/openpype/hosts/houdini/plugins/load/load_image.py b/openpype/hosts/houdini/plugins/load/load_image.py
index 928c2ee734..c78798e58a 100644
--- a/openpype/hosts/houdini/plugins/load/load_image.py
+++ b/openpype/hosts/houdini/plugins/load/load_image.py
@@ -73,7 +73,7 @@ class ImageLoader(load.LoaderPlugin):
# Imprint it manually
data = {
- "schema": "avalon-core:container-2.0",
+ "schema": "openpype:container-2.0",
"id": AVALON_CONTAINER_ID,
"name": node_name,
"namespace": namespace,
diff --git a/openpype/hosts/houdini/plugins/load/load_usd_layer.py b/openpype/hosts/houdini/plugins/load/load_usd_layer.py
index 48580fc3aa..2e5079925b 100644
--- a/openpype/hosts/houdini/plugins/load/load_usd_layer.py
+++ b/openpype/hosts/houdini/plugins/load/load_usd_layer.py
@@ -43,7 +43,7 @@ class USDSublayerLoader(load.LoaderPlugin):
# Imprint it manually
data = {
- "schema": "avalon-core:container-2.0",
+ "schema": "openpype:container-2.0",
"id": AVALON_CONTAINER_ID,
"name": node_name,
"namespace": namespace,
diff --git a/openpype/hosts/houdini/plugins/load/load_usd_reference.py b/openpype/hosts/houdini/plugins/load/load_usd_reference.py
index 6851c77e6d..c4371db39b 100644
--- a/openpype/hosts/houdini/plugins/load/load_usd_reference.py
+++ b/openpype/hosts/houdini/plugins/load/load_usd_reference.py
@@ -43,7 +43,7 @@ class USDReferenceLoader(load.LoaderPlugin):
# Imprint it manually
data = {
- "schema": "avalon-core:container-2.0",
+ "schema": "openpype:container-2.0",
"id": AVALON_CONTAINER_ID,
"name": node_name,
"namespace": namespace,
diff --git a/openpype/hosts/maya/addon.py b/openpype/hosts/maya/addon.py
index 7b1f7bf754..cdd2bc1667 100644
--- a/openpype/hosts/maya/addon.py
+++ b/openpype/hosts/maya/addon.py
@@ -28,13 +28,16 @@ class MayaAddon(OpenPypeModule, IHostAddon):
env["PYTHONPATH"] = os.pathsep.join(new_python_paths)
- # Set default values if are not already set via settings
- defaults = {
- "OPENPYPE_LOG_NO_COLORS": "Yes"
+ # Set default environments
+ envs = {
+ "OPENPYPE_LOG_NO_COLORS": "Yes",
+ # For python module 'qtpy'
+ "QT_API": "PySide2",
+ # For python module 'Qt'
+ "QT_PREFERRED_BINDING": "PySide2"
}
- for key, value in defaults.items():
- if not env.get(key):
- env[key] = value
+ for key, value in envs.items():
+ env[key] = value
def get_launch_hook_paths(self, app):
if app.host_name != self.host_name:
diff --git a/openpype/hosts/maya/api/customize.py b/openpype/hosts/maya/api/customize.py
index 683e6b24b0..f66858dfb6 100644
--- a/openpype/hosts/maya/api/customize.py
+++ b/openpype/hosts/maya/api/customize.py
@@ -8,7 +8,7 @@ from functools import partial
import maya.cmds as cmds
import maya.mel as mel
-from openpype.api import resources
+from openpype import resources
from openpype.tools.utils import host_tools
from .lib import get_main_window
diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py
index 6a8447d6ad..292b95da84 100644
--- a/openpype/hosts/maya/api/lib.py
+++ b/openpype/hosts/maya/api/lib.py
@@ -23,7 +23,7 @@ from openpype.client import (
get_last_versions,
get_representation_by_name
)
-from openpype.api import get_anatomy_settings
+from openpype.settings import get_project_settings
from openpype.pipeline import (
legacy_io,
discover_loader_plugins,
@@ -3159,7 +3159,7 @@ def set_colorspace():
"""Set Colorspace from project configuration
"""
project_name = os.getenv("AVALON_PROJECT")
- imageio = get_anatomy_settings(project_name)["imageio"]["maya"]
+ imageio = get_project_settings(project_name)["maya"]["imageio"]
# Maya 2022+ introduces new OCIO v2 color management settings that
# can override the old color managenement preferences. OpenPype has
diff --git a/openpype/hosts/maya/api/lib_rendersettings.py b/openpype/hosts/maya/api/lib_rendersettings.py
index 777a6ffbc9..b0a283da5a 100644
--- a/openpype/hosts/maya/api/lib_rendersettings.py
+++ b/openpype/hosts/maya/api/lib_rendersettings.py
@@ -6,7 +6,7 @@ import six
import sys
from openpype.lib import Logger
-from openpype.api import (
+from openpype.settings import (
get_project_settings,
get_current_project_settings
)
diff --git a/openpype/hosts/maya/plugins/create/create_render.py b/openpype/hosts/maya/plugins/create/create_render.py
index 5418ec1f2f..2b2c978d3c 100644
--- a/openpype/hosts/maya/plugins/create/create_render.py
+++ b/openpype/hosts/maya/plugins/create/create_render.py
@@ -9,7 +9,7 @@ import requests
from maya import cmds
from maya.app.renderSetup.model import renderSetup
-from openpype.api import (
+from openpype.settings import (
get_system_settings,
get_project_settings,
)
diff --git a/openpype/hosts/maya/plugins/create/create_unreal_staticmesh.py b/openpype/hosts/maya/plugins/create/create_unreal_staticmesh.py
index 4e4417ff34..44cbee0502 100644
--- a/openpype/hosts/maya/plugins/create/create_unreal_staticmesh.py
+++ b/openpype/hosts/maya/plugins/create/create_unreal_staticmesh.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
"""Creator for Unreal Static Meshes."""
from openpype.hosts.maya.api import plugin, lib
-from openpype.api import get_project_settings
+from openpype.settings import get_project_settings
from openpype.pipeline import legacy_io
from maya import cmds # noqa
diff --git a/openpype/hosts/maya/plugins/create/create_vrayscene.py b/openpype/hosts/maya/plugins/create/create_vrayscene.py
index 45c4b7e443..59d80e6d5b 100644
--- a/openpype/hosts/maya/plugins/create/create_vrayscene.py
+++ b/openpype/hosts/maya/plugins/create/create_vrayscene.py
@@ -12,7 +12,7 @@ from openpype.hosts.maya.api import (
lib,
plugin
)
-from openpype.api import (
+from openpype.settings import (
get_system_settings,
get_project_settings
)
diff --git a/openpype/hosts/maya/plugins/load/load_ass.py b/openpype/hosts/maya/plugins/load/load_ass.py
index d1b12ceaba..5db6fc3dfa 100644
--- a/openpype/hosts/maya/plugins/load/load_ass.py
+++ b/openpype/hosts/maya/plugins/load/load_ass.py
@@ -1,7 +1,7 @@
import os
import clique
-from openpype.api import get_project_settings
+from openpype.settings import get_project_settings
from openpype.pipeline import (
load,
get_representation_path
diff --git a/openpype/hosts/maya/plugins/load/load_gpucache.py b/openpype/hosts/maya/plugins/load/load_gpucache.py
index 179819f904..a09f924c7b 100644
--- a/openpype/hosts/maya/plugins/load/load_gpucache.py
+++ b/openpype/hosts/maya/plugins/load/load_gpucache.py
@@ -4,7 +4,7 @@ from openpype.pipeline import (
load,
get_representation_path
)
-from openpype.api import get_project_settings
+from openpype.settings import get_project_settings
class GpuCacheLoader(load.LoaderPlugin):
diff --git a/openpype/hosts/maya/plugins/load/load_redshift_proxy.py b/openpype/hosts/maya/plugins/load/load_redshift_proxy.py
index d93a9f02a2..c288e23ded 100644
--- a/openpype/hosts/maya/plugins/load/load_redshift_proxy.py
+++ b/openpype/hosts/maya/plugins/load/load_redshift_proxy.py
@@ -5,7 +5,7 @@ import clique
import maya.cmds as cmds
-from openpype.api import get_project_settings
+from openpype.settings import get_project_settings
from openpype.pipeline import (
load,
get_representation_path
diff --git a/openpype/hosts/maya/plugins/load/load_reference.py b/openpype/hosts/maya/plugins/load/load_reference.py
index 5a06661df9..c762a29326 100644
--- a/openpype/hosts/maya/plugins/load/load_reference.py
+++ b/openpype/hosts/maya/plugins/load/load_reference.py
@@ -1,7 +1,7 @@
import os
from maya import cmds
-from openpype.api import get_project_settings
+from openpype.settings import get_project_settings
from openpype.pipeline import legacy_io
from openpype.pipeline.create import (
legacy_create,
diff --git a/openpype/hosts/maya/plugins/load/load_vdb_to_arnold.py b/openpype/hosts/maya/plugins/load/load_vdb_to_arnold.py
index d458c5abda..8a386cecfd 100644
--- a/openpype/hosts/maya/plugins/load/load_vdb_to_arnold.py
+++ b/openpype/hosts/maya/plugins/load/load_vdb_to_arnold.py
@@ -1,6 +1,6 @@
import os
-from openpype.api import get_project_settings
+from openpype.settings import get_project_settings
from openpype.pipeline import (
load,
get_representation_path
diff --git a/openpype/hosts/maya/plugins/load/load_vdb_to_redshift.py b/openpype/hosts/maya/plugins/load/load_vdb_to_redshift.py
index c6a69dfe35..1f02321dc8 100644
--- a/openpype/hosts/maya/plugins/load/load_vdb_to_redshift.py
+++ b/openpype/hosts/maya/plugins/load/load_vdb_to_redshift.py
@@ -1,6 +1,6 @@
import os
-from openpype.api import get_project_settings
+from openpype.settings import get_project_settings
from openpype.pipeline import (
load,
get_representation_path
diff --git a/openpype/hosts/maya/plugins/load/load_vdb_to_vray.py b/openpype/hosts/maya/plugins/load/load_vdb_to_vray.py
index 3a16264ec0..9267c59c02 100644
--- a/openpype/hosts/maya/plugins/load/load_vdb_to_vray.py
+++ b/openpype/hosts/maya/plugins/load/load_vdb_to_vray.py
@@ -1,6 +1,6 @@
import os
-from openpype.api import get_project_settings
+from openpype.settings import get_project_settings
from openpype.pipeline import (
load,
get_representation_path
diff --git a/openpype/hosts/maya/plugins/load/load_vrayproxy.py b/openpype/hosts/maya/plugins/load/load_vrayproxy.py
index e3d6166d3a..720a132aa7 100644
--- a/openpype/hosts/maya/plugins/load/load_vrayproxy.py
+++ b/openpype/hosts/maya/plugins/load/load_vrayproxy.py
@@ -10,7 +10,7 @@ import os
import maya.cmds as cmds
from openpype.client import get_representation_by_name
-from openpype.api import get_project_settings
+from openpype.settings import get_project_settings
from openpype.pipeline import (
legacy_io,
load,
diff --git a/openpype/hosts/maya/plugins/load/load_vrayscene.py b/openpype/hosts/maya/plugins/load/load_vrayscene.py
index 61132088cc..d87992f9a7 100644
--- a/openpype/hosts/maya/plugins/load/load_vrayscene.py
+++ b/openpype/hosts/maya/plugins/load/load_vrayscene.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
import os
import maya.cmds as cmds # noqa
-from openpype.api import get_project_settings
+from openpype.settings import get_project_settings
from openpype.pipeline import (
load,
get_representation_path
diff --git a/openpype/hosts/maya/plugins/load/load_yeti_cache.py b/openpype/hosts/maya/plugins/load/load_yeti_cache.py
index 8d15ed23c4..090047e22d 100644
--- a/openpype/hosts/maya/plugins/load/load_yeti_cache.py
+++ b/openpype/hosts/maya/plugins/load/load_yeti_cache.py
@@ -6,7 +6,7 @@ from collections import defaultdict
import clique
from maya import cmds
-from openpype.api import get_project_settings
+from openpype.settings import get_project_settings
from openpype.pipeline import (
load,
get_representation_path
diff --git a/openpype/hosts/maya/plugins/load/load_yeti_rig.py b/openpype/hosts/maya/plugins/load/load_yeti_rig.py
index 4b730ad2c1..651607de8a 100644
--- a/openpype/hosts/maya/plugins/load/load_yeti_rig.py
+++ b/openpype/hosts/maya/plugins/load/load_yeti_rig.py
@@ -1,7 +1,7 @@
import os
from collections import defaultdict
-from openpype.api import get_project_settings
+from openpype.settings import get_project_settings
import openpype.hosts.maya.api.plugin
from openpype.hosts.maya.api import lib
diff --git a/openpype/hosts/maya/plugins/publish/submit_maya_muster.py b/openpype/hosts/maya/plugins/publish/submit_maya_muster.py
index c4250a20bd..df06220fd3 100644
--- a/openpype/hosts/maya/plugins/publish/submit_maya_muster.py
+++ b/openpype/hosts/maya/plugins/publish/submit_maya_muster.py
@@ -11,7 +11,7 @@ import pyblish.api
from openpype.lib import requests_post
from openpype.hosts.maya.api import lib
from openpype.pipeline import legacy_io
-from openpype.api import get_system_settings
+from openpype.settings import get_system_settings
# mapping between Maya renderer names and Muster template ids
diff --git a/openpype/hosts/maya/startup/userSetup.py b/openpype/hosts/maya/startup/userSetup.py
index 10e68c2ddb..40cd51f2d8 100644
--- a/openpype/hosts/maya/startup/userSetup.py
+++ b/openpype/hosts/maya/startup/userSetup.py
@@ -1,5 +1,5 @@
import os
-from openpype.api import get_project_settings
+from openpype.settings import get_project_settings
from openpype.pipeline import install_host
from openpype.hosts.maya.api import MayaHost
from maya import cmds
diff --git a/openpype/hosts/nuke/api/lib.py b/openpype/hosts/nuke/api/lib.py
index df0b303878..157a2eb321 100644
--- a/openpype/hosts/nuke/api/lib.py
+++ b/openpype/hosts/nuke/api/lib.py
@@ -688,7 +688,15 @@ def get_node_path(path, padding=4):
def get_nuke_imageio_settings():
- return get_anatomy_settings(Context.project_name)["imageio"]["nuke"]
+ project_imageio = get_project_settings(
+ Context.project_name)["nuke"]["imageio"]
+
+ # backward compatibility for project started before 3.10
+ # those are still having `__legacy__` knob types
+ if not project_imageio["enabled"]:
+ return get_anatomy_settings(Context.project_name)["imageio"]["nuke"]
+
+ return get_project_settings(Context.project_name)["nuke"]["imageio"]
@deprecated("openpype.hosts.nuke.api.lib.get_nuke_imageio_settings")
diff --git a/openpype/hosts/nuke/api/pipeline.py b/openpype/hosts/nuke/api/pipeline.py
index 013b5e3ed4..c93a4f090f 100644
--- a/openpype/hosts/nuke/api/pipeline.py
+++ b/openpype/hosts/nuke/api/pipeline.py
@@ -13,9 +13,7 @@ from openpype.host import (
ILoadHost,
INewPublisher
)
-from openpype.api import (
- get_current_project_settings
-)
+from openpype.settings import get_current_project_settings
from openpype.lib import register_event_callback, Logger
from openpype.pipeline import (
register_loader_plugin_path,
diff --git a/openpype/hosts/nuke/api/plugin.py b/openpype/hosts/nuke/api/plugin.py
index 8ef6c60296..c9460295fb 100644
--- a/openpype/hosts/nuke/api/plugin.py
+++ b/openpype/hosts/nuke/api/plugin.py
@@ -14,7 +14,7 @@ from openpype.client import (
get_subsets,
)
-from openpype.api import get_current_project_settings
+from openpype.settings import get_current_project_settings
from openpype.lib import (
BoolDef,
EnumDef
diff --git a/openpype/hosts/nuke/api/utils.py b/openpype/hosts/nuke/api/utils.py
index 5b0c607292..6bcb752dd1 100644
--- a/openpype/hosts/nuke/api/utils.py
+++ b/openpype/hosts/nuke/api/utils.py
@@ -1,7 +1,7 @@
import os
import nuke
-from openpype.api import resources
+from openpype import resources
from .lib import maintained_selection
diff --git a/openpype/hosts/nuke/plugins/load/load_clip.py b/openpype/hosts/nuke/plugins/load/load_clip.py
index 346773b5af..654ea367c8 100644
--- a/openpype/hosts/nuke/plugins/load/load_clip.py
+++ b/openpype/hosts/nuke/plugins/load/load_clip.py
@@ -425,7 +425,7 @@ class LoadClip(plugin.NukeLoader):
colorspace = repre_data.get("colorspace")
colorspace = colorspace or version_data.get("colorspace")
- # colorspace from `project_anatomy/imageio/nuke/regexInputs`
+ # colorspace from `project_settings/nuke/imageio/regexInputs`
iio_colorspace = get_imageio_input_colorspace(path)
# Set colorspace defined in version data
diff --git a/openpype/hosts/nuke/plugins/publish/validate_write_nodes.py b/openpype/hosts/nuke/plugins/publish/validate_write_nodes.py
index ab1671ad0e..cfd0fb3871 100644
--- a/openpype/hosts/nuke/plugins/publish/validate_write_nodes.py
+++ b/openpype/hosts/nuke/plugins/publish/validate_write_nodes.py
@@ -97,11 +97,14 @@ class ValidateNukeWriteNode(
# fix type differences
if type(node_value) in (int, float):
- if isinstance(value, list):
- value = color_gui_to_int(value)
- else:
- value = float(value)
- node_value = float(node_value)
+ try:
+ if isinstance(value, list):
+ value = color_gui_to_int(value)
+ else:
+ value = float(value)
+ node_value = float(node_value)
+ except ValueError:
+ value = str(value)
else:
value = str(value)
node_value = str(node_value)
diff --git a/openpype/hosts/resolve/api/plugin.py b/openpype/hosts/resolve/api/plugin.py
index b03125d502..3995077d21 100644
--- a/openpype/hosts/resolve/api/plugin.py
+++ b/openpype/hosts/resolve/api/plugin.py
@@ -504,7 +504,7 @@ class Creator(LegacyCreator):
def __init__(self, *args, **kwargs):
super(Creator, self).__init__(*args, **kwargs)
- from openpype.api import get_current_project_settings
+ from openpype.settings import get_current_project_settings
resolve_p_settings = get_current_project_settings().get("resolve")
self.presets = {}
if resolve_p_settings:
diff --git a/openpype/hosts/traypublisher/plugins/create/create_from_settings.py b/openpype/hosts/traypublisher/plugins/create/create_from_settings.py
index 5d80c20309..df6253b0c2 100644
--- a/openpype/hosts/traypublisher/plugins/create/create_from_settings.py
+++ b/openpype/hosts/traypublisher/plugins/create/create_from_settings.py
@@ -1,6 +1,6 @@
import os
from openpype.lib import Logger
-from openpype.api import get_project_settings
+from openpype.settings import get_project_settings
log = Logger.get_logger(__name__)
diff --git a/openpype/hosts/tvpaint/api/pipeline.py b/openpype/hosts/tvpaint/api/pipeline.py
index 427c927264..cbaa059809 100644
--- a/openpype/hosts/tvpaint/api/pipeline.py
+++ b/openpype/hosts/tvpaint/api/pipeline.py
@@ -10,7 +10,7 @@ import pyblish.api
from openpype.client import get_project, get_asset_by_name
from openpype.hosts import tvpaint
-from openpype.api import get_current_project_settings
+from openpype.settings import get_current_project_settings
from openpype.lib import register_event_callback
from openpype.pipeline import (
legacy_io,
diff --git a/openpype/hosts/unreal/plugins/load/load_layout.py b/openpype/hosts/unreal/plugins/load/load_layout.py
index 926c932a85..c1d66ddf2a 100644
--- a/openpype/hosts/unreal/plugins/load/load_layout.py
+++ b/openpype/hosts/unreal/plugins/load/load_layout.py
@@ -24,7 +24,7 @@ from openpype.pipeline import (
legacy_io,
)
from openpype.pipeline.context_tools import get_current_project_asset
-from openpype.api import get_current_project_settings
+from openpype.settings import get_current_project_settings
from openpype.hosts.unreal.api import plugin
from openpype.hosts.unreal.api import pipeline as unreal_pipeline
diff --git a/openpype/hosts/webpublisher/plugins/publish/collect_published_files.py b/openpype/hosts/webpublisher/plugins/publish/collect_published_files.py
index 278a102f9d..dd4646f356 100644
--- a/openpype/hosts/webpublisher/plugins/publish/collect_published_files.py
+++ b/openpype/hosts/webpublisher/plugins/publish/collect_published_files.py
@@ -37,6 +37,15 @@ class CollectPublishedFiles(pyblish.api.ContextPlugin):
This is not applicable for 'studio' processing where host application is
called to process uploaded workfile and render frames itself.
+
+ For each task configure what properties should resulting instance have
+ based on uploaded files:
+ - uploading sequence of 'png' >> create instance of 'render' family,
+ by adding 'review' to 'Families' and 'Create review' to Tags it will
+ produce review.
+
+ There might be difference between single(>>image) and sequence(>>render)
+ uploaded files.
"""
# must be really early, context values are only in json file
order = pyblish.api.CollectorOrder - 0.490
@@ -46,6 +55,7 @@ class CollectPublishedFiles(pyblish.api.ContextPlugin):
# from Settings
task_type_to_family = []
+ sync_next_version = False # find max version to be published, use for all
def process(self, context):
batch_dir = context.data["batchDir"]
@@ -64,6 +74,9 @@ class CollectPublishedFiles(pyblish.api.ContextPlugin):
task_type = context.data["taskType"]
project_name = context.data["project_name"]
variant = context.data["variant"]
+
+ next_versions = []
+ instances = []
for task_dir in task_subfolders:
task_data = parse_json(os.path.join(task_dir,
"manifest.json"))
@@ -90,11 +103,14 @@ class CollectPublishedFiles(pyblish.api.ContextPlugin):
version = self._get_next_version(
project_name, asset_doc, subset_name
)
+ next_versions.append(version)
instance = context.create_instance(subset_name)
instance.data["asset"] = asset_name
instance.data["subset"] = subset_name
+ # set configurable result family
instance.data["family"] = family
+ # set configurable additional families
instance.data["families"] = families
instance.data["version"] = version
instance.data["stagingDir"] = tempfile.mkdtemp()
@@ -137,8 +153,18 @@ class CollectPublishedFiles(pyblish.api.ContextPlugin):
instance.data["handleStart"] = asset_doc["data"]["handleStart"]
instance.data["handleEnd"] = asset_doc["data"]["handleEnd"]
+ instances.append(instance)
self.log.info("instance.data:: {}".format(instance.data))
+ if not self.sync_next_version:
+ return
+
+ # overwrite specific version with same version for all
+ max_next_version = max(next_versions)
+ for inst in instances:
+ inst.data["version"] = max_next_version
+ self.log.debug("overwritten version:: {}".format(max_next_version))
+
def _get_subset_name(self, family, subset_template, task_name, variant):
fill_pairs = {
"variant": variant,
@@ -176,7 +202,7 @@ class CollectPublishedFiles(pyblish.api.ContextPlugin):
"ext": ext[1:],
"files": files,
"stagingDir": task_dir,
- "tags": tags
+ "tags": tags # configurable tags from Settings
}
self.log.info("sequences repre_data.data:: {}".format(repre_data))
return [repre_data]
diff --git a/openpype/modules/deadline/plugins/publish/submit_maya_deadline.py b/openpype/modules/deadline/plugins/publish/submit_maya_deadline.py
index 7fbe134410..890d10595f 100644
--- a/openpype/modules/deadline/plugins/publish/submit_maya_deadline.py
+++ b/openpype/modules/deadline/plugins/publish/submit_maya_deadline.py
@@ -36,8 +36,19 @@ from openpype_modules.deadline import abstract_submit_deadline
from openpype_modules.deadline.abstract_submit_deadline import DeadlineJobInfo
+def _validate_deadline_bool_value(instance, attribute, value):
+ if not isinstance(value, (str, bool)):
+ raise TypeError(
+ "Attribute {} must be str or bool.".format(attribute))
+ if value not in {"1", "0", True, False}:
+ raise ValueError(
+ ("Value of {} must be one of "
+ "'0', '1', True, False").format(attribute)
+ )
+
+
@attr.s
-class MayaPluginInfo:
+class MayaPluginInfo():
SceneFile = attr.ib(default=None) # Input
OutputFilePath = attr.ib(default=None) # Output directory and filename
OutputFilePrefix = attr.ib(default=None)
@@ -46,11 +57,13 @@ class MayaPluginInfo:
RenderLayer = attr.ib(default=None) # Render only this layer
Renderer = attr.ib(default=None)
ProjectPath = attr.ib(default=None) # Resolve relative references
- RenderSetupIncludeLights = attr.ib(default=None) # Include all lights flag
+ # Include all lights flag
+ RenderSetupIncludeLights = attr.ib(
+ default="1", validator=_validate_deadline_bool_value)
@attr.s
-class PythonPluginInfo:
+class PythonPluginInfo():
ScriptFile = attr.ib()
Version = attr.ib(default="3.6")
Arguments = attr.ib(default=None)
@@ -58,7 +71,7 @@ class PythonPluginInfo:
@attr.s
-class VRayPluginInfo:
+class VRayPluginInfo():
InputFilename = attr.ib(default=None) # Input
SeparateFilesPerFrame = attr.ib(default=None)
VRayEngine = attr.ib(default="V-Ray")
@@ -69,7 +82,7 @@ class VRayPluginInfo:
@attr.s
-class ArnoldPluginInfo:
+class ArnoldPluginInfo():
ArnoldFile = attr.ib(default=None)
@@ -185,12 +198,26 @@ class MayaSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline):
instance = self._instance
context = instance.context
+ # Set it to default Maya behaviour if it cannot be determined
+ # from instance (but it should be, by the Collector).
+
+ default_rs_include_lights = (
+ instance.context.data['project_settings']
+ ['maya']
+ ['RenderSettings']
+ ['enable_all_lights']
+ )
+
+ rs_include_lights = instance.data.get(
+ "renderSetupIncludeLights", default_rs_include_lights)
+ if rs_include_lights not in {"1", "0", True, False}:
+ rs_include_lights = default_rs_include_lights
plugin_info = MayaPluginInfo(
SceneFile=self.scene_path,
Version=cmds.about(version=True),
RenderLayer=instance.data['setMembers'],
Renderer=instance.data["renderer"],
- RenderSetupIncludeLights=instance.data.get("renderSetupIncludeLights"), # noqa
+ RenderSetupIncludeLights=rs_include_lights, # noqa
ProjectPath=context.data["workspaceDir"],
UsingRenderLayers=True,
)
diff --git a/openpype/modules/ftrack/event_handlers_user/action_create_cust_attrs.py b/openpype/modules/ftrack/event_handlers_user/action_create_cust_attrs.py
index d04440a564..c19cfd1502 100644
--- a/openpype/modules/ftrack/event_handlers_user/action_create_cust_attrs.py
+++ b/openpype/modules/ftrack/event_handlers_user/action_create_cust_attrs.py
@@ -18,7 +18,7 @@ from openpype_modules.ftrack.lib import (
tool_definitions_from_app_manager
)
-from openpype.api import get_system_settings
+from openpype.settings import get_system_settings
from openpype.lib import ApplicationManager
"""
diff --git a/openpype/modules/ftrack/launch_hooks/post_ftrack_changes.py b/openpype/modules/ftrack/launch_hooks/post_ftrack_changes.py
index d5a95fad91..86ecffd5b8 100644
--- a/openpype/modules/ftrack/launch_hooks/post_ftrack_changes.py
+++ b/openpype/modules/ftrack/launch_hooks/post_ftrack_changes.py
@@ -1,7 +1,7 @@
import os
import ftrack_api
-from openpype.api import get_project_settings
+from openpype.settings import get_project_settings
from openpype.lib import PostLaunchHook
diff --git a/openpype/modules/job_queue/module.py b/openpype/modules/job_queue/module.py
index f1d7251e85..7075fcea14 100644
--- a/openpype/modules/job_queue/module.py
+++ b/openpype/modules/job_queue/module.py
@@ -43,7 +43,7 @@ import platform
import click
from openpype.modules import OpenPypeModule
-from openpype.api import get_system_settings
+from openpype.settings import get_system_settings
class JobQueueModule(OpenPypeModule):
diff --git a/openpype/modules/kitsu/utils/update_zou_with_op.py b/openpype/modules/kitsu/utils/update_zou_with_op.py
index da924aa5ee..39baf31b93 100644
--- a/openpype/modules/kitsu/utils/update_zou_with_op.py
+++ b/openpype/modules/kitsu/utils/update_zou_with_op.py
@@ -12,7 +12,7 @@ from openpype.client import (
get_assets,
)
from openpype.pipeline import AvalonMongoDB
-from openpype.api import get_project_settings
+from openpype.settings import get_project_settings
from openpype.modules.kitsu.utils.credentials import validate_credentials
diff --git a/openpype/modules/shotgrid/lib/settings.py b/openpype/modules/shotgrid/lib/settings.py
index 924099f04b..5b0b728f55 100644
--- a/openpype/modules/shotgrid/lib/settings.py
+++ b/openpype/modules/shotgrid/lib/settings.py
@@ -1,4 +1,4 @@
-from openpype.api import get_system_settings, get_project_settings
+from openpype.settings import get_system_settings, get_project_settings
from openpype.modules.shotgrid.lib.const import MODULE_NAME
diff --git a/openpype/pipeline/create/creator_plugins.py b/openpype/pipeline/create/creator_plugins.py
index 945a97a99c..05ba8902aa 100644
--- a/openpype/pipeline/create/creator_plugins.py
+++ b/openpype/pipeline/create/creator_plugins.py
@@ -246,7 +246,7 @@ class BaseCreator:
return self.icon
def get_dynamic_data(
- self, variant, task_name, asset_doc, project_name, host_name
+ self, variant, task_name, asset_doc, project_name, host_name, instance
):
"""Dynamic data for subset name filling.
@@ -257,7 +257,13 @@ class BaseCreator:
return {}
def get_subset_name(
- self, variant, task_name, asset_doc, project_name, host_name=None
+ self,
+ variant,
+ task_name,
+ asset_doc,
+ project_name,
+ host_name=None,
+ instance=None
):
"""Return subset name for passed context.
@@ -271,16 +277,21 @@ class BaseCreator:
Asset document is not used yet but is required if would like to use
task type in subset templates.
+ Method is also called on subset name update. In that case origin
+ instance is passed in.
+
Args:
variant(str): Subset name variant. In most of cases user input.
task_name(str): For which task subset is created.
asset_doc(dict): Asset document for which subset is created.
project_name(str): Project name.
host_name(str): Which host creates subset.
+ instance(str|None): Object of 'CreatedInstance' for which is
+ subset name updated. Passed only on subset name update.
"""
dynamic_data = self.get_dynamic_data(
- variant, task_name, asset_doc, project_name, host_name
+ variant, task_name, asset_doc, project_name, host_name, instance
)
return get_subset_name(
diff --git a/openpype/plugins/publish/collect_settings.py b/openpype/plugins/publish/collect_settings.py
index d56eabd1b5..a418a6400c 100644
--- a/openpype/plugins/publish/collect_settings.py
+++ b/openpype/plugins/publish/collect_settings.py
@@ -1,5 +1,8 @@
from pyblish import api
-from openpype.api import get_current_project_settings, get_system_settings
+from openpype.settings import (
+ get_current_project_settings,
+ get_system_settings,
+)
class CollectSettings(api.ContextPlugin):
diff --git a/openpype/plugins/publish/integrate_hero_version.py b/openpype/plugins/publish/integrate_hero_version.py
index c0760a5471..5f4d284740 100644
--- a/openpype/plugins/publish/integrate_hero_version.py
+++ b/openpype/plugins/publish/integrate_hero_version.py
@@ -4,8 +4,6 @@ import clique
import errno
import shutil
-from bson.objectid import ObjectId
-from pymongo import InsertOne, ReplaceOne
import pyblish.api
from openpype.client import (
@@ -14,10 +12,15 @@ from openpype.client import (
get_archived_representations,
get_representations,
)
+from openpype.client.operations import (
+ OperationsSession,
+ new_hero_version_doc,
+ prepare_hero_version_update_data,
+ prepare_representation_update_data,
+)
from openpype.lib import create_hard_link
from openpype.pipeline import (
- schema,
- legacy_io,
+ schema
)
from openpype.pipeline.publish import get_publish_template_name
@@ -187,35 +190,32 @@ class IntegrateHeroVersion(pyblish.api.InstancePlugin):
repre["name"].lower(): repre for repre in old_repres
}
+ op_session = OperationsSession()
+
+ entity_id = None
if old_version:
- new_version_id = old_version["_id"]
- else:
- new_version_id = ObjectId()
-
- new_hero_version = {
- "_id": new_version_id,
- "version_id": src_version_entity["_id"],
- "parent": src_version_entity["parent"],
- "type": "hero_version",
- "schema": "openpype:hero_version-1.0"
- }
- schema.validate(new_hero_version)
-
- # Don't make changes in database until everything is O.K.
- bulk_writes = []
+ entity_id = old_version["_id"]
+ new_hero_version = new_hero_version_doc(
+ src_version_entity["_id"],
+ src_version_entity["parent"],
+ entity_id=entity_id
+ )
if old_version:
self.log.debug("Replacing old hero version.")
- bulk_writes.append(
- ReplaceOne(
- {"_id": new_hero_version["_id"]},
- new_hero_version
- )
+ update_data = prepare_hero_version_update_data(
+ old_version, new_hero_version
+ )
+ op_session.update_entity(
+ project_name,
+ new_hero_version["type"],
+ old_version["_id"],
+ update_data
)
else:
self.log.debug("Creating first hero version.")
- bulk_writes.append(
- InsertOne(new_hero_version)
+ op_session.create_entity(
+ project_name, new_hero_version["type"], new_hero_version
)
# Separate old representations into `to replace` and `to delete`
@@ -235,7 +235,7 @@ class IntegrateHeroVersion(pyblish.api.InstancePlugin):
archived_repres = list(get_archived_representations(
project_name,
# Check what is type of archived representation
- version_ids=[new_version_id]
+ version_ids=[new_hero_version["_id"]]
))
archived_repres_by_name = {}
for repre in archived_repres:
@@ -382,12 +382,15 @@ class IntegrateHeroVersion(pyblish.api.InstancePlugin):
# Replace current representation
if repre_name_low in old_repres_to_replace:
old_repre = old_repres_to_replace.pop(repre_name_low)
+
repre["_id"] = old_repre["_id"]
- bulk_writes.append(
- ReplaceOne(
- {"_id": old_repre["_id"]},
- repre
- )
+ update_data = prepare_representation_update_data(
+ old_repre, repre)
+ op_session.update_entity(
+ project_name,
+ old_repre["type"],
+ old_repre["_id"],
+ update_data
)
# Unarchive representation
@@ -395,21 +398,21 @@ class IntegrateHeroVersion(pyblish.api.InstancePlugin):
archived_repre = archived_repres_by_name.pop(
repre_name_low
)
- old_id = archived_repre["old_id"]
- repre["_id"] = old_id
- bulk_writes.append(
- ReplaceOne(
- {"old_id": old_id},
- repre
- )
+ repre["_id"] = archived_repre["old_id"]
+ update_data = prepare_representation_update_data(
+ archived_repre, repre)
+ op_session.update_entity(
+ project_name,
+ old_repre["type"],
+ archived_repre["_id"],
+ update_data
)
# Create representation
else:
- repre["_id"] = ObjectId()
- bulk_writes.append(
- InsertOne(repre)
- )
+ repre.pop("_id", None)
+ op_session.create_entity(project_name, "representation",
+ repre)
self.path_checks = []
@@ -430,28 +433,22 @@ class IntegrateHeroVersion(pyblish.api.InstancePlugin):
archived_repre = archived_repres_by_name.pop(
repre_name_low
)
- repre["old_id"] = repre["_id"]
- repre["_id"] = archived_repre["_id"]
- repre["type"] = archived_repre["type"]
- bulk_writes.append(
- ReplaceOne(
- {"_id": archived_repre["_id"]},
- repre
- )
- )
+ changes = {"old_id": repre["_id"],
+ "_id": archived_repre["_id"],
+ "type": archived_repre["type"]}
+ op_session.update_entity(project_name,
+ archived_repre["type"],
+ archived_repre["_id"],
+ changes)
else:
- repre["old_id"] = repre["_id"]
- repre["_id"] = ObjectId()
+ repre["old_id"] = repre.pop("_id")
repre["type"] = "archived_representation"
- bulk_writes.append(
- InsertOne(repre)
- )
+ op_session.create_entity(project_name,
+ "archived_representation",
+ repre)
- if bulk_writes:
- legacy_io.database[project_name].bulk_write(
- bulk_writes
- )
+ op_session.commit()
# Remove backuped previous hero
if (
diff --git a/openpype/plugins/publish/integrate_thumbnail.py b/openpype/plugins/publish/integrate_thumbnail.py
index d86cec10ad..e7046ba2ea 100644
--- a/openpype/plugins/publish/integrate_thumbnail.py
+++ b/openpype/plugins/publish/integrate_thumbnail.py
@@ -1,3 +1,13 @@
+""" Integrate Thumbnails for Openpype use in Loaders.
+
+ This thumbnail is different from 'thumbnail' representation which could
+ be uploaded to Ftrack, or used as any other representation in Loaders to
+ pull into a scene.
+
+ This one is used only as image describing content of published item and
+ shows up only in Loader in right column section.
+"""
+
import os
import sys
import errno
@@ -12,7 +22,7 @@ from openpype.client.operations import OperationsSession, new_thumbnail_doc
class IntegrateThumbnails(pyblish.api.InstancePlugin):
- """Integrate Thumbnails."""
+ """Integrate Thumbnails for Openpype use in Loaders."""
label = "Integrate Thumbnails"
order = pyblish.api.IntegratorOrder + 0.01
diff --git a/openpype/plugins/publish/preintegrate_thumbnail_representation.py b/openpype/plugins/publish/preintegrate_thumbnail_representation.py
new file mode 100644
index 0000000000..f9e23223e6
--- /dev/null
+++ b/openpype/plugins/publish/preintegrate_thumbnail_representation.py
@@ -0,0 +1,72 @@
+""" Marks thumbnail representation for integrate to DB or not.
+
+ Some hosts produce thumbnail representation, most of them do not create
+ them explicitly, but they created during extract phase.
+
+ In some cases it might be useful to override implicit setting for host/task
+
+ This plugin needs to run after extract phase, but before integrate.py as
+ thumbnail is part of review family and integrated there.
+
+ It should be better to control integration of thumbnail in one place than
+ configure it in multiple places on host implementations.
+"""
+import pyblish.api
+
+from openpype.lib.profiles_filtering import filter_profiles
+
+
+class PreIntegrateThumbnails(pyblish.api.InstancePlugin):
+ """Marks thumbnail representation for integrate to DB or not."""
+
+ label = "Override Integrate Thumbnail Representations"
+ order = pyblish.api.IntegratorOrder - 0.1
+ families = ["review"]
+
+ integrate_profiles = {}
+
+ def process(self, instance):
+ repres = instance.data.get("representations")
+ if not repres:
+ return
+
+ thumbnail_repre = None
+ for repre in repres:
+ if repre["name"] == "thumbnail":
+ thumbnail_repre = repre
+ break
+
+ if not thumbnail_repre:
+ return
+
+ family = instance.data["family"]
+ subset_name = instance.data["subset"]
+ host_name = instance.context.data["hostName"]
+
+ anatomy_data = instance.data["anatomyData"]
+ task = anatomy_data.get("task", {})
+
+ found_profile = filter_profiles(
+ self.integrate_profiles,
+ {
+ "hosts": host_name,
+ "task_names": task.get("name"),
+ "task_types": task.get("type"),
+ "families": family,
+ "subsets": subset_name,
+ },
+ logger=self.log
+ )
+
+ if not found_profile:
+ return
+
+ if not found_profile["integrate_thumbnail"]:
+ if "delete" not in thumbnail_repre["tags"]:
+ thumbnail_repre["tags"].append("delete")
+ else:
+ if "delete" in thumbnail_repre["tags"]:
+ thumbnail_repre["tags"].remove("delete")
+
+ self.log.debug(
+ "Thumbnail repre tags {}".format(thumbnail_repre["tags"]))
diff --git a/openpype/plugins/publish/validate_version.py b/openpype/plugins/publish/validate_version.py
index b94152ef2d..b91633430f 100644
--- a/openpype/plugins/publish/validate_version.py
+++ b/openpype/plugins/publish/validate_version.py
@@ -10,7 +10,8 @@ class ValidateVersion(pyblish.api.InstancePlugin):
order = pyblish.api.ValidatorOrder
label = "Validate Version"
- hosts = ["nuke", "maya", "houdini", "blender", "standalonepublisher"]
+ hosts = ["nuke", "maya", "houdini", "blender", "standalonepublisher",
+ "photoshop", "aftereffects"]
optional = False
active = True
diff --git a/openpype/settings/defaults/project_settings/flame.json b/openpype/settings/defaults/project_settings/flame.json
index c90193fe13..0f3080ad64 100644
--- a/openpype/settings/defaults/project_settings/flame.json
+++ b/openpype/settings/defaults/project_settings/flame.json
@@ -1,4 +1,23 @@
{
+ "imageio": {
+ "project": {
+ "colourPolicy": "ACES 1.1",
+ "frameDepth": "16-bit fp",
+ "fieldDominance": "PROGRESSIVE"
+ },
+ "profilesMapping": {
+ "inputs": [
+ {
+ "flameName": "ACEScg",
+ "ocioName": "ACES - ACEScg"
+ },
+ {
+ "flameName": "Rec.709 video",
+ "ocioName": "Output - Rec.709"
+ }
+ ]
+ }
+ },
"create": {
"CreateShotClip": {
"hierarchy": "{folder}/{sequence}",
diff --git a/openpype/settings/defaults/project_settings/global.json b/openpype/settings/defaults/project_settings/global.json
index 115a719995..1b7dc7a41a 100644
--- a/openpype/settings/defaults/project_settings/global.json
+++ b/openpype/settings/defaults/project_settings/global.json
@@ -164,6 +164,10 @@
}
]
},
+ "PreIntegrateThumbnails": {
+ "enabled": true,
+ "integrate_profiles": []
+ },
"IntegrateSubsetGroup": {
"subset_grouping_profiles": [
{
diff --git a/openpype/settings/defaults/project_settings/hiero.json b/openpype/settings/defaults/project_settings/hiero.json
index e9e7199330..d2ba697305 100644
--- a/openpype/settings/defaults/project_settings/hiero.json
+++ b/openpype/settings/defaults/project_settings/hiero.json
@@ -1,4 +1,29 @@
{
+ "imageio": {
+ "workfile": {
+ "ocioConfigName": "nuke-default",
+ "ocioconfigpath": {
+ "windows": [],
+ "darwin": [],
+ "linux": []
+ },
+ "workingSpace": "linear",
+ "sixteenBitLut": "sRGB",
+ "eightBitLut": "sRGB",
+ "floatLut": "linear",
+ "logLut": "Cineon",
+ "viewerLut": "sRGB",
+ "thumbnailLut": "sRGB"
+ },
+ "regexInputs": {
+ "inputs": [
+ {
+ "regex": "[^-a-zA-Z0-9](plateRef).*(?=mp4)",
+ "colorspace": "sRGB"
+ }
+ ]
+ }
+ },
"create": {
"CreateShotClip": {
"hierarchy": "{folder}/{sequence}",
diff --git a/openpype/settings/defaults/project_settings/maya.json b/openpype/settings/defaults/project_settings/maya.json
index 76ef0a7338..00e47d37da 100644
--- a/openpype/settings/defaults/project_settings/maya.json
+++ b/openpype/settings/defaults/project_settings/maya.json
@@ -1,4 +1,26 @@
{
+ "imageio": {
+ "colorManagementPreference_v2": {
+ "enabled": true,
+ "configFilePath": {
+ "windows": [],
+ "darwin": [],
+ "linux": []
+ },
+ "renderSpace": "ACEScg",
+ "displayName": "sRGB",
+ "viewName": "ACES 1.0 SDR-video"
+ },
+ "colorManagementPreference": {
+ "configFilePath": {
+ "windows": [],
+ "darwin": [],
+ "linux": []
+ },
+ "renderSpace": "scene-linear Rec 709/sRGB",
+ "viewTransform": "sRGB gamma"
+ }
+ },
"mel_workspace": "workspace -fr \"shaders\" \"renderData/shaders\";\nworkspace -fr \"images\" \"renders\";\nworkspace -fr \"particles\" \"particles\";\nworkspace -fr \"mayaAscii\" \"\";\nworkspace -fr \"mayaBinary\" \"\";\nworkspace -fr \"scene\" \"\";\nworkspace -fr \"alembicCache\" \"cache/alembic\";\nworkspace -fr \"renderData\" \"renderData\";\nworkspace -fr \"sourceImages\" \"sourceimages\";\nworkspace -fr \"fileCache\" \"cache/nCache\";\n",
"ext_mapping": {
"model": "ma",
@@ -35,7 +57,7 @@
"RenderSettings": {
"apply_render_settings": true,
"default_render_image_folder": "renders",
- "enable_all_lights": false,
+ "enable_all_lights": true,
"aov_separator": "underscore",
"reset_current_frame": false,
"arnold_renderer": {
diff --git a/openpype/settings/defaults/project_settings/nuke.json b/openpype/settings/defaults/project_settings/nuke.json
index 8e4dd163ab..0b3f13ed99 100644
--- a/openpype/settings/defaults/project_settings/nuke.json
+++ b/openpype/settings/defaults/project_settings/nuke.json
@@ -7,6 +7,197 @@
"build_workfile": "ctrl+alt+b"
}
},
+ "imageio": {
+ "enabled": false,
+ "viewer": {
+ "viewerProcess": "sRGB"
+ },
+ "baking": {
+ "viewerProcess": "rec709"
+ },
+ "workfile": {
+ "colorManagement": "Nuke",
+ "OCIO_config": "nuke-default",
+ "customOCIOConfigPath": {
+ "windows": [],
+ "darwin": [],
+ "linux": []
+ },
+ "workingSpaceLUT": "linear",
+ "monitorLut": "sRGB",
+ "int8Lut": "sRGB",
+ "int16Lut": "sRGB",
+ "logLut": "Cineon",
+ "floatLut": "linear"
+ },
+ "nodes": {
+ "requiredNodes": [
+ {
+ "plugins": [
+ "CreateWriteRender"
+ ],
+ "nukeNodeClass": "Write",
+ "knobs": [
+ {
+ "type": "text",
+ "name": "file_type",
+ "value": "exr"
+ },
+ {
+ "type": "text",
+ "name": "datatype",
+ "value": "16 bit half"
+ },
+ {
+ "type": "text",
+ "name": "compression",
+ "value": "Zip (1 scanline)"
+ },
+ {
+ "type": "bool",
+ "name": "autocrop",
+ "value": true
+ },
+ {
+ "type": "color_gui",
+ "name": "tile_color",
+ "value": [
+ 186,
+ 35,
+ 35,
+ 255
+ ]
+ },
+ {
+ "type": "text",
+ "name": "channels",
+ "value": "rgb"
+ },
+ {
+ "type": "text",
+ "name": "colorspace",
+ "value": "linear"
+ },
+ {
+ "type": "bool",
+ "name": "create_directories",
+ "value": true
+ }
+ ]
+ },
+ {
+ "plugins": [
+ "CreateWritePrerender"
+ ],
+ "nukeNodeClass": "Write",
+ "knobs": [
+ {
+ "type": "text",
+ "name": "file_type",
+ "value": "exr"
+ },
+ {
+ "type": "text",
+ "name": "datatype",
+ "value": "16 bit half"
+ },
+ {
+ "type": "text",
+ "name": "compression",
+ "value": "Zip (1 scanline)"
+ },
+ {
+ "type": "bool",
+ "name": "autocrop",
+ "value": true
+ },
+ {
+ "type": "color_gui",
+ "name": "tile_color",
+ "value": [
+ 171,
+ 171,
+ 10,
+ 255
+ ]
+ },
+ {
+ "type": "text",
+ "name": "channels",
+ "value": "rgb"
+ },
+ {
+ "type": "text",
+ "name": "colorspace",
+ "value": "linear"
+ },
+ {
+ "type": "bool",
+ "name": "create_directories",
+ "value": true
+ }
+ ]
+ },
+ {
+ "plugins": [
+ "CreateWriteStill"
+ ],
+ "nukeNodeClass": "Write",
+ "knobs": [
+ {
+ "type": "text",
+ "name": "file_type",
+ "value": "tiff"
+ },
+ {
+ "type": "text",
+ "name": "datatype",
+ "value": "16 bit"
+ },
+ {
+ "type": "text",
+ "name": "compression",
+ "value": "Deflate"
+ },
+ {
+ "type": "color_gui",
+ "name": "tile_color",
+ "value": [
+ 56,
+ 162,
+ 7,
+ 255
+ ]
+ },
+ {
+ "type": "text",
+ "name": "channels",
+ "value": "rgb"
+ },
+ {
+ "type": "text",
+ "name": "colorspace",
+ "value": "sRGB"
+ },
+ {
+ "type": "bool",
+ "name": "create_directories",
+ "value": true
+ }
+ ]
+ }
+ ],
+ "overrideNodes": []
+ },
+ "regexInputs": {
+ "inputs": [
+ {
+ "regex": "(beauty).*(?=.exr)",
+ "colorspace": "linear"
+ }
+ ]
+ }
+ },
"nuke-dirmap": {
"enabled": false,
"paths": {
diff --git a/openpype/settings/defaults/project_settings/webpublisher.json b/openpype/settings/defaults/project_settings/webpublisher.json
index cba472514e..09c7d3ec94 100644
--- a/openpype/settings/defaults/project_settings/webpublisher.json
+++ b/openpype/settings/defaults/project_settings/webpublisher.json
@@ -10,6 +10,7 @@
],
"publish": {
"CollectPublishedFiles": {
+ "sync_next_version": false,
"task_type_to_family": {
"Animation": [
{
diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_flame.json b/openpype/settings/entities/schemas/projects_schema/schema_project_flame.json
index 5f05bef0e1..73664300aa 100644
--- a/openpype/settings/entities/schemas/projects_schema/schema_project_flame.json
+++ b/openpype/settings/entities/schemas/projects_schema/schema_project_flame.json
@@ -5,6 +5,69 @@
"label": "Flame",
"is_file": true,
"children": [
+ {
+ "key": "imageio",
+ "type": "dict",
+ "label": "Color Management (ImageIO)",
+ "is_group": true,
+ "children": [
+ {
+ "key": "project",
+ "type": "dict",
+ "label": "Project",
+ "collapsible": false,
+ "children": [
+ {
+ "type": "form",
+ "children": [
+ {
+ "type": "text",
+ "key": "colourPolicy",
+ "label": "Colour Policy (name or path)"
+ },
+ {
+ "type": "text",
+ "key": "frameDepth",
+ "label": "Image Depth"
+ },
+ {
+ "type": "text",
+ "key": "fieldDominance",
+ "label": "Field Dominance"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "key": "profilesMapping",
+ "type": "dict",
+ "label": "Profile names mapping",
+ "collapsible": true,
+ "children": [
+ {
+ "type": "list",
+ "key": "inputs",
+ "object_type": {
+ "type": "dict",
+ "children": [
+ {
+ "type": "text",
+ "key": "flameName",
+ "label": "Flame name"
+ },
+ {
+ "type": "text",
+ "key": "ocioName",
+ "label": "OCIO name"
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
{
"type": "dict",
"collapsible": true,
diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_hiero.json b/openpype/settings/entities/schemas/projects_schema/schema_project_hiero.json
index 3108d2197e..9e18522def 100644
--- a/openpype/settings/entities/schemas/projects_schema/schema_project_hiero.json
+++ b/openpype/settings/entities/schemas/projects_schema/schema_project_hiero.json
@@ -5,6 +5,116 @@
"label": "Hiero",
"is_file": true,
"children": [
+ {
+ "key": "imageio",
+ "type": "dict",
+ "label": "Color Management (ImageIO)",
+ "is_group": true,
+ "collapsible": true,
+ "children": [
+ {
+ "key": "workfile",
+ "type": "dict",
+ "label": "Workfile",
+ "collapsible": false,
+ "children": [
+ {
+ "type": "form",
+ "children": [
+ {
+ "type": "enum",
+ "key": "ocioConfigName",
+ "label": "OpenColorIO Config",
+ "enum_items": [
+ {
+ "nuke-default": "nuke-default"
+ },
+ {
+ "aces_1.0.3": "aces_1.0.3"
+ },
+ {
+ "aces_1.1": "aces_1.1"
+ },
+ {
+ "custom": "custom"
+ }
+ ]
+ },
+ {
+ "type": "path",
+ "key": "ocioconfigpath",
+ "label": "Custom OCIO path",
+ "multiplatform": true,
+ "multipath": true
+ },
+ {
+ "type": "text",
+ "key": "workingSpace",
+ "label": "Working Space"
+ },
+ {
+ "type": "text",
+ "key": "sixteenBitLut",
+ "label": "16 Bit Files"
+ },
+ {
+ "type": "text",
+ "key": "eightBitLut",
+ "label": "8 Bit Files"
+ },
+ {
+ "type": "text",
+ "key": "floatLut",
+ "label": "Floating Point Files"
+ },
+ {
+ "type": "text",
+ "key": "logLut",
+ "label": "Log Files"
+ },
+ {
+ "type": "text",
+ "key": "viewerLut",
+ "label": "Viewer"
+ },
+ {
+ "type": "text",
+ "key": "thumbnailLut",
+ "label": "Thumbnails"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "key": "regexInputs",
+ "type": "dict",
+ "label": "Colorspace on Inputs by regex detection",
+ "collapsible": true,
+ "children": [
+ {
+ "type": "list",
+ "key": "inputs",
+ "object_type": {
+ "type": "dict",
+ "children": [
+ {
+ "type": "text",
+ "key": "regex",
+ "label": "Regex"
+ },
+ {
+ "type": "text",
+ "key": "colorspace",
+ "label": "Colorspace"
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
{
"type": "dict",
"collapsible": true,
diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_maya.json b/openpype/settings/entities/schemas/projects_schema/schema_project_maya.json
index d7a2b086d9..b2d79797a3 100644
--- a/openpype/settings/entities/schemas/projects_schema/schema_project_maya.json
+++ b/openpype/settings/entities/schemas/projects_schema/schema_project_maya.json
@@ -5,6 +5,76 @@
"label": "Maya",
"is_file": true,
"children": [
+ {
+ "key": "imageio",
+ "type": "dict",
+ "label": "Color Management (ImageIO)",
+ "collapsible": true,
+ "is_group": true,
+ "children": [
+ {
+ "key": "colorManagementPreference_v2",
+ "type": "dict",
+ "label": "Color Management Preference v2 (Maya 2022+)",
+ "collapsible": true,
+ "checkbox_key": "enabled",
+ "children": [
+ {
+ "type": "boolean",
+ "key": "enabled",
+ "label": "Use Color Management Preference v2"
+ },
+ {
+ "type": "path",
+ "key": "configFilePath",
+ "label": "OCIO Config File Path",
+ "multiplatform": true,
+ "multipath": true
+ },
+ {
+ "type": "text",
+ "key": "renderSpace",
+ "label": "Rendering Space"
+ },
+ {
+ "type": "text",
+ "key": "displayName",
+ "label": "Display"
+ },
+ {
+ "type": "text",
+ "key": "viewName",
+ "label": "View"
+ }
+ ]
+ },
+ {
+ "key": "colorManagementPreference",
+ "type": "dict",
+ "label": "Color Management Preference (legacy)",
+ "collapsible": true,
+ "children": [
+ {
+ "type": "path",
+ "key": "configFilePath",
+ "label": "OCIO Config File Path",
+ "multiplatform": true,
+ "multipath": true
+ },
+ {
+ "type": "text",
+ "key": "renderSpace",
+ "label": "Rendering Space"
+ },
+ {
+ "type": "text",
+ "key": "viewTransform",
+ "label": "Viewer Transform"
+ }
+ ]
+ }
+ ]
+ },
{
"type": "text",
"multiline" : true,
diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_nuke.json b/openpype/settings/entities/schemas/projects_schema/schema_project_nuke.json
index 00ba3d5f03..b1a8cc1812 100644
--- a/openpype/settings/entities/schemas/projects_schema/schema_project_nuke.json
+++ b/openpype/settings/entities/schemas/projects_schema/schema_project_nuke.json
@@ -41,6 +41,10 @@
}
]
},
+ {
+ "type": "schema",
+ "name": "schema_nuke_imageio"
+ },
{
"type": "dict",
"collapsible": true,
diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_webpublisher.json b/openpype/settings/entities/schemas/projects_schema/schema_project_webpublisher.json
index 2ef7a05b21..a81a403bcb 100644
--- a/openpype/settings/entities/schemas/projects_schema/schema_project_webpublisher.json
+++ b/openpype/settings/entities/schemas/projects_schema/schema_project_webpublisher.json
@@ -49,6 +49,19 @@
"key": "CollectPublishedFiles",
"label": "Collect Published Files",
"children": [
+ {
+ "type": "label",
+ "label": "Select if all versions of published items should be kept same. (As max(published) + 1.)"
+ },
+ {
+ "type": "boolean",
+ "key": "sync_next_version",
+ "label": "Sync next publish version"
+ },
+ {
+ "type": "label",
+ "label": "Configure resulting family and tags on representation based on uploaded file and task.
Eg. '.png' is uploaded >> create instance of 'render' family
'Create review' in Tags >> mark representation to create review from."
+ },
{
"type": "dict-modifiable",
"collapsible": true,
@@ -74,6 +87,9 @@
"label": "Extensions",
"object_type": "text"
},
+ {
+ "type": "separator"
+ },
{
"type": "list",
"key": "families",
@@ -84,9 +100,6 @@
"type": "schema",
"name": "schema_representation_tags"
},
- {
- "type": "separator"
- },
{
"type": "text",
"key": "result_family",
diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_imageio.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_imageio.json
index ef8c907dda..93b6adae6b 100644
--- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_imageio.json
+++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_imageio.json
@@ -1,10 +1,14 @@
{
"type": "dict",
"key": "imageio",
- "label": "Color Management and Output Formats",
+ "label": "Color Management and Output Formats (Deprecated)",
"is_file": true,
"is_group": true,
"children": [
+ {
+ "type": "label",
+ "label": "These settings are deprecated and have moved to: project_settings/{app}/imageio.
You can right click to copy each host's values and paste them to apply to each host as needed.
Changing these values here will not do anything."
+ },
{
"key": "hiero",
"type": "dict",
diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json
index 297f96aa8c..773dea1229 100644
--- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json
+++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json
@@ -555,6 +555,73 @@
}
]
},
+ {
+ "type": "dict",
+ "collapsible": true,
+ "key": "PreIntegrateThumbnails",
+ "label": "Override Integrate Thumbnail Representations",
+ "is_group": true,
+ "checkbox_key": "enabled",
+ "children": [
+ {
+ "type": "boolean",
+ "key": "enabled",
+ "label": "Enabled"
+ },
+ {
+ "type": "label",
+ "label": "Explicitly set if Thumbnail representation should be integrated into DB.
If no matching profile set, existing state from Host implementation is kept."
+ },
+ {
+ "type": "list",
+ "key": "integrate_profiles",
+ "label": "Integrate profiles",
+ "use_label_wrap": true,
+ "object_type": {
+ "type": "dict",
+ "children": [
+ {
+ "key": "families",
+ "label": "Families",
+ "type": "list",
+ "object_type": "text"
+ },
+ {
+ "type": "hosts-enum",
+ "key": "hosts",
+ "label": "Hosts",
+ "multiselection": true
+ },
+ {
+ "key": "task_types",
+ "label": "Task types",
+ "type": "task-types-enum"
+ },
+ {
+ "key": "task_names",
+ "label": "Task names",
+ "type": "list",
+ "object_type": "text"
+ },
+ {
+ "key": "subsets",
+ "label": "Subset names",
+ "type": "list",
+ "object_type": "text"
+ },
+ {
+ "type": "separator"
+ },
+ {
+ "type": "boolean",
+ "key": "integrate_thumbnail",
+ "label": "Integrate thumbnail"
+ }
+ ]
+ }
+ }
+ ]
+ },
{
"type": "dict",
"collapsible": true,
diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_nuke_imageio.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_nuke_imageio.json
new file mode 100644
index 0000000000..52db853ef6
--- /dev/null
+++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_nuke_imageio.json
@@ -0,0 +1,254 @@
+{
+ "key": "imageio",
+ "type": "dict",
+ "label": "Color Management (ImageIO)",
+ "checkbox_key": "enabled",
+ "collapsible": true,
+ "is_group": true,
+ "children": [
+ {
+ "type": "boolean",
+ "key": "enabled",
+ "label": "Enabled"
+ },
+ {
+ "key": "viewer",
+ "type": "dict",
+ "label": "Viewer",
+ "collapsible": false,
+ "children": [
+ {
+ "type": "text",
+ "key": "viewerProcess",
+ "label": "Viewer Process"
+ }
+ ]
+ },
+ {
+ "key": "baking",
+ "type": "dict",
+ "label": "Extract-review baking profile",
+ "collapsible": false,
+ "children": [
+ {
+ "type": "text",
+ "key": "viewerProcess",
+ "label": "Viewer Process"
+ }
+ ]
+ },
+ {
+ "key": "workfile",
+ "type": "dict",
+ "label": "Workfile",
+ "collapsible": false,
+ "children": [
+ {
+ "type": "form",
+ "children": [
+ {
+ "type": "enum",
+ "key": "colorManagement",
+ "label": "color management",
+ "enum_items": [
+ {
+ "Nuke": "Nuke"
+ },
+ {
+ "OCIO": "OCIO"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "key": "OCIO_config",
+ "label": "OpenColorIO Config",
+ "enum_items": [
+ {
+ "nuke-default": "nuke-default"
+ },
+ {
+ "spi-vfx": "spi-vfx"
+ },
+ {
+ "spi-anim": "spi-anim"
+ },
+ {
+ "aces_0.1.1": "aces_0.1.1"
+ },
+ {
+ "aces_0.7.1": "aces_0.7.1"
+ },
+ {
+ "aces_1.0.1": "aces_1.0.1"
+ },
+ {
+ "aces_1.0.3": "aces_1.0.3"
+ },
+ {
+ "aces_1.1": "aces_1.1"
+ },
+ {
+ "aces_1.2": "aces_1.2"
+ },
+ {
+ "custom": "custom"
+ }
+ ]
+ },
+ {
+ "type": "path",
+ "key": "customOCIOConfigPath",
+ "label": "Custom OCIO config path",
+ "multiplatform": true,
+ "multipath": true
+ },
+ {
+ "type": "text",
+ "key": "workingSpaceLUT",
+ "label": "Working Space"
+ },
+ {
+ "type": "text",
+ "key": "monitorLut",
+ "label": "monitor"
+ },
+ {
+ "type": "text",
+ "key": "int8Lut",
+ "label": "8-bit files"
+ },
+ {
+ "type": "text",
+ "key": "int16Lut",
+ "label": "16-bit files"
+ },
+ {
+ "type": "text",
+ "key": "logLut",
+ "label": "log files"
+ },
+ {
+ "type": "text",
+ "key": "floatLut",
+ "label": "float files"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "key": "nodes",
+ "type": "dict",
+ "label": "Nodes",
+ "collapsible": true,
+ "children": [
+ {
+ "key": "requiredNodes",
+ "type": "list",
+ "label": "Plugin required",
+ "object_type": {
+ "type": "dict",
+ "children": [
+ {
+ "type": "list",
+ "key": "plugins",
+ "label": "Used in plugins",
+ "object_type": {
+ "type": "text",
+ "key": "pluginClass"
+ }
+ },
+ {
+ "type": "text",
+ "key": "nukeNodeClass",
+ "label": "Nuke Node Class"
+ },
+ {
+ "type": "schema_template",
+ "name": "template_nuke_knob_inputs",
+ "template_data": [
+ {
+ "label": "Knobs",
+ "key": "knobs"
+ }
+ ]
+ }
+
+ ]
+ }
+ },
+ {
+ "type": "splitter"
+ },
+ {
+ "type": "list",
+ "key": "overrideNodes",
+ "label": "Plugin's node overrides",
+ "object_type": {
+ "type": "dict",
+ "children": [
+ {
+ "type": "list",
+ "key": "plugins",
+ "label": "Used in plugins",
+ "object_type": {
+ "type": "text",
+ "key": "pluginClass"
+ }
+ },
+ {
+ "type": "text",
+ "key": "nukeNodeClass",
+ "label": "Nuke Node Class"
+ },
+ {
+ "key": "subsets",
+ "label": "Subsets",
+ "type": "list",
+ "object_type": "text"
+ },
+ {
+ "type": "schema_template",
+ "name": "template_nuke_knob_inputs",
+ "template_data": [
+ {
+ "label": "Knobs overrides",
+ "key": "knobs"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "key": "regexInputs",
+ "type": "dict",
+ "label": "Colorspace on Inputs by regex detection",
+ "collapsible": true,
+ "children": [
+ {
+ "type": "list",
+ "key": "inputs",
+ "object_type": {
+ "type": "dict",
+ "children": [
+ {
+ "type": "text",
+ "key": "regex",
+ "label": "Regex"
+ },
+ {
+ "type": "text",
+ "key": "colorspace",
+ "label": "Colorspace"
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/openpype/tools/creator/window.py b/openpype/tools/creator/window.py
index a3937d6a40..e2396ed29e 100644
--- a/openpype/tools/creator/window.py
+++ b/openpype/tools/creator/window.py
@@ -6,7 +6,7 @@ from Qt import QtWidgets, QtCore
from openpype.client import get_asset_by_name, get_subsets
from openpype import style
-from openpype.api import get_current_project_settings
+from openpype.settings import get_current_project_settings
from openpype.tools.utils.lib import qt_app_context
from openpype.pipeline import legacy_io
from openpype.pipeline.create import (
diff --git a/openpype/tools/launcher/actions.py b/openpype/tools/launcher/actions.py
index b954110da4..34d06f72cc 100644
--- a/openpype/tools/launcher/actions.py
+++ b/openpype/tools/launcher/actions.py
@@ -4,7 +4,7 @@ from Qt import QtWidgets, QtGui
from openpype import PLUGINS_DIR
from openpype import style
-from openpype.api import resources
+from openpype import resources
from openpype.lib import (
Logger,
ApplictionExecutableNotFound,
diff --git a/openpype/tools/launcher/lib.py b/openpype/tools/launcher/lib.py
index c1392b7b8f..68e57c6b92 100644
--- a/openpype/tools/launcher/lib.py
+++ b/openpype/tools/launcher/lib.py
@@ -1,7 +1,7 @@
import os
from Qt import QtGui
import qtawesome
-from openpype.api import resources
+from openpype import resources
ICON_CACHE = {}
NOT_FOUND = type("NotFound", (object, ), {})
diff --git a/openpype/tools/launcher/window.py b/openpype/tools/launcher/window.py
index dab6949613..a9eaa932bb 100644
--- a/openpype/tools/launcher/window.py
+++ b/openpype/tools/launcher/window.py
@@ -4,7 +4,7 @@ import logging
from Qt import QtWidgets, QtCore, QtGui
from openpype import style
-from openpype.api import resources
+from openpype import resources
from openpype.pipeline import AvalonMongoDB
import qtawesome
diff --git a/openpype/tools/publisher/widgets/widgets.py b/openpype/tools/publisher/widgets/widgets.py
index d1fa71343c..7fdceff68f 100644
--- a/openpype/tools/publisher/widgets/widgets.py
+++ b/openpype/tools/publisher/widgets/widgets.py
@@ -1080,7 +1080,11 @@ class GlobalAttrsWidget(QtWidgets.QWidget):
try:
new_subset_name = instance.creator.get_subset_name(
- new_variant_value, new_task_name, asset_doc, project_name
+ new_variant_value,
+ new_task_name,
+ asset_doc,
+ project_name,
+ instance=instance
)
except TaskNotSetError:
invalid_tasks = True
diff --git a/openpype/tools/pyblish_pype/control.py b/openpype/tools/pyblish_pype/control.py
index 05e53a989a..90bb002ba5 100644
--- a/openpype/tools/pyblish_pype/control.py
+++ b/openpype/tools/pyblish_pype/control.py
@@ -22,7 +22,7 @@ import pyblish.version
from . import util
from .constants import InstanceStates
-from openpype.api import get_project_settings
+from openpype.settings import get_current_project_settings
class IterationBreak(Exception):
@@ -204,7 +204,7 @@ class Controller(QtCore.QObject):
def presets_by_hosts(self):
# Get global filters as base
- presets = get_project_settings(os.environ['AVALON_PROJECT']) or {}
+ presets = get_current_project_settings()
if not presets:
return {}
diff --git a/openpype/tools/pyblish_pype/model.py b/openpype/tools/pyblish_pype/model.py
index 1479d91bb5..383d8304a5 100644
--- a/openpype/tools/pyblish_pype/model.py
+++ b/openpype/tools/pyblish_pype/model.py
@@ -34,7 +34,7 @@ import qtawesome
from six import text_type
from .constants import PluginStates, InstanceStates, GroupStates, Roles
-from openpype.api import get_system_settings
+from openpype.settings import get_system_settings
# ItemTypes
diff --git a/openpype/tools/settings/local_settings/window.py b/openpype/tools/settings/local_settings/window.py
index 761b978ab4..76c2d851e9 100644
--- a/openpype/tools/settings/local_settings/window.py
+++ b/openpype/tools/settings/local_settings/window.py
@@ -2,6 +2,10 @@ from Qt import QtWidgets, QtGui
from openpype import style
+from openpype.settings import (
+ SystemSettings,
+ ProjectSettings
+)
from openpype.settings.lib import (
get_local_settings,
save_local_settings
@@ -9,10 +13,6 @@ from openpype.settings.lib import (
from openpype.lib import Logger
from openpype.tools.settings import CHILD_OFFSET
from openpype.tools.utils import MessageOverlayObject
-from openpype.api import (
- SystemSettings,
- ProjectSettings
-)
from openpype.modules import ModulesManager
from .widgets import (
diff --git a/openpype/tools/standalonepublish/app.py b/openpype/tools/standalonepublish/app.py
index 081235c91c..c93c33b2a5 100644
--- a/openpype/tools/standalonepublish/app.py
+++ b/openpype/tools/standalonepublish/app.py
@@ -13,7 +13,7 @@ from .widgets import (
)
from .widgets.constants import HOST_NAME
from openpype import style
-from openpype.api import resources
+from openpype import resources
from openpype.pipeline import AvalonMongoDB
from openpype.modules import ModulesManager
diff --git a/openpype/tools/tray/pype_info_widget.py b/openpype/tools/tray/pype_info_widget.py
index 8414cefec8..232d2024ac 100644
--- a/openpype/tools/tray/pype_info_widget.py
+++ b/openpype/tools/tray/pype_info_widget.py
@@ -5,7 +5,7 @@ import collections
from Qt import QtCore, QtGui, QtWidgets
from openpype import style
-from openpype.api import resources
+from openpype import resources
from openpype.settings.lib import get_local_settings
from openpype.lib.pype_info import (
get_all_current_info,
diff --git a/openpype/tools/utils/lib.py b/openpype/tools/utils/lib.py
index 31ea26cef9..d8dd80046a 100644
--- a/openpype/tools/utils/lib.py
+++ b/openpype/tools/utils/lib.py
@@ -17,7 +17,7 @@ from openpype.style import (
)
from openpype.resources import get_image_path
from openpype.lib import filter_profiles, Logger
-from openpype.api import get_project_settings
+from openpype.settings import get_project_settings
from openpype.pipeline import registered_host
log = Logger.get_logger(__name__)
diff --git a/openpype/version.py b/openpype/version.py
index 1bd566aa9b..3a0c538daf 100644
--- a/openpype/version.py
+++ b/openpype/version.py
@@ -1,3 +1,3 @@
# -*- coding: utf-8 -*-
"""Package declaring Pype version."""
-__version__ = "3.14.4-nightly.2"
+__version__ = "3.14.4-nightly.3"
diff --git a/openpype/widgets/password_dialog.py b/openpype/widgets/password_dialog.py
index 9990642ca1..58add7832f 100644
--- a/openpype/widgets/password_dialog.py
+++ b/openpype/widgets/password_dialog.py
@@ -3,7 +3,7 @@ from Qt import QtWidgets, QtCore, QtGui
from openpype import style
from openpype.resources import get_resource
-from openpype.api import get_system_settings
+from openpype.settings import get_system_settings
from openpype.settings.lib import (
get_local_settings,
save_local_settings
diff --git a/website/docs/dev_publishing.md b/website/docs/dev_publishing.md
index f11a2c3047..7a6082a517 100644
--- a/website/docs/dev_publishing.md
+++ b/website/docs/dev_publishing.md
@@ -198,6 +198,37 @@ class RenderLayerCreator(Creator):
- **`get_dynamic_data`** (method) - Can be used to extend data for subset templates which may be required in some cases.
+Methods are used before instance creation and on instance subset name update. Update may require to have access to existing instance because dynamic data should be filled from there. Because of that is instance passed to `get_subset_name` and `get_dynamic_data` so the creator can handle that cases.
+
+This is one example where subset name template may contain `"{layer}"` which is filled during creation because the value is taken from selection. In that case `get_dynamic_data` returns value for `"layer"` -> `"{layer}"` so it can be filled in creation. But when subset name of already existing instance is updated it should return already existing value. Note: Creator must make sure the value is available on instance.
+
+```python
+from openpype.lib import prepare_template_data
+from my_host import get_selected_layer
+
+
+class SomeCreator(Creator):
+ def get_dynamic_data(
+ self, variant, task_name, asset_doc, project_name, host_name, instance
+ ):
+ # Before instance is created return unfilled key
+ # - the key will be filled during creation
+ if instance is None:
+ return {"layer": "{layer}"}
+ # Take value from existing instance
+ # - creator must know where to look for the value
+ return {"layer": instance.data["layer"]}
+
+ def create(self, subset_name, instance_data, pre_create_data):
+ # Fill the layer name in
+ layer = get_selected_layer()
+ layer_name = layer["name"]
+ layer_fill_data = prepare_template_data({"layer": layer_name})
+ subset_name = subset_name.format(**layer_fill_data)
+ instance_data["layer"] = layer_name
+ ...
+```
+
#### *HiddenCreator*
Creator which is not showed in UI so artist can't trigger it directly but is available for other creators. This creator is primarily meant for cases when creation should create different types of instances. For example during editorial publishing where input is single edl file but should create 2 or more kind of instances each with different family, attributes and abilities. Arguments for creation were limited to `instance_data` and `source_data`. Data of `instance_data` should follow what is sent to other creators and `source_data` can be used to send custom data defined by main creator. It is expected that `HiddenCreator` has specific main or "parent" creator.