mirror of
https://github.com/ynput/ayon-core.git
synced 2026-01-01 16:34:53 +01:00
Merge branch 'develop' into feature/OP-5871_Max-Review-feature
This commit is contained in:
commit
a0947de6cf
92 changed files with 2219 additions and 819 deletions
|
|
@ -855,12 +855,13 @@ def get_output_link_versions(project_name, version_id, fields=None):
|
|||
return conn.find(query_filter, _prepare_fields(fields))
|
||||
|
||||
|
||||
def get_last_versions(project_name, subset_ids, fields=None):
|
||||
def get_last_versions(project_name, subset_ids, active=None, fields=None):
|
||||
"""Latest versions for entered subset_ids.
|
||||
|
||||
Args:
|
||||
project_name (str): Name of project where to look for queried entities.
|
||||
subset_ids (Iterable[Union[str, ObjectId]]): List of subset ids.
|
||||
active (Optional[bool]): If True only active versions are returned.
|
||||
fields (Optional[Iterable[str]]): Fields that should be returned. All
|
||||
fields are returned if 'None' is passed.
|
||||
|
||||
|
|
@ -899,12 +900,21 @@ def get_last_versions(project_name, subset_ids, fields=None):
|
|||
if name_needed:
|
||||
group_item["name"] = {"$last": "$name"}
|
||||
|
||||
aggregate_filter = {
|
||||
"type": "version",
|
||||
"parent": {"$in": subset_ids}
|
||||
}
|
||||
if active is False:
|
||||
aggregate_filter["data.active"] = active
|
||||
elif active is True:
|
||||
aggregate_filter["$or"] = [
|
||||
{"data.active": {"$exists": 0}},
|
||||
{"data.active": active},
|
||||
]
|
||||
|
||||
aggregation_pipeline = [
|
||||
# Find all versions of those subsets
|
||||
{"$match": {
|
||||
"type": "version",
|
||||
"parent": {"$in": subset_ids}
|
||||
}},
|
||||
{"$match": aggregate_filter},
|
||||
# Sorting versions all together
|
||||
{"$sort": {"name": 1}},
|
||||
# Group them by "parent", but only take the last
|
||||
|
|
|
|||
|
|
@ -1,37 +0,0 @@
|
|||
from openpype.lib import PreLaunchHook
|
||||
|
||||
from openpype.pipeline.colorspace import get_imageio_config
|
||||
from openpype.pipeline.template_data import get_template_data
|
||||
|
||||
|
||||
class PreLaunchHostSetOCIO(PreLaunchHook):
|
||||
"""Set OCIO environment for the host"""
|
||||
|
||||
order = 0
|
||||
app_groups = ["substancepainter"]
|
||||
|
||||
def execute(self):
|
||||
"""Hook entry method."""
|
||||
|
||||
anatomy_data = get_template_data(
|
||||
project_doc=self.data["project_doc"],
|
||||
asset_doc=self.data["asset_doc"],
|
||||
task_name=self.data["task_name"],
|
||||
host_name=self.host_name,
|
||||
system_settings=self.data["system_settings"]
|
||||
)
|
||||
|
||||
ocio_config = get_imageio_config(
|
||||
project_name=self.data["project_doc"]["name"],
|
||||
host_name=self.host_name,
|
||||
project_settings=self.data["project_settings"],
|
||||
anatomy_data=anatomy_data,
|
||||
anatomy=self.data["anatomy"]
|
||||
)
|
||||
|
||||
if ocio_config:
|
||||
ocio_path = ocio_config["path"]
|
||||
self.log.info(f"Setting OCIO config path: {ocio_path}")
|
||||
self.launch_context.env["OCIO"] = ocio_path
|
||||
else:
|
||||
self.log.debug("OCIO not set or enabled")
|
||||
|
|
@ -1,12 +1,27 @@
|
|||
from openpype.lib import PreLaunchHook
|
||||
|
||||
from openpype.pipeline.colorspace import get_imageio_config
|
||||
from openpype.pipeline.colorspace import (
|
||||
get_imageio_config
|
||||
)
|
||||
from openpype.pipeline.template_data import get_template_data_with_names
|
||||
|
||||
|
||||
class FusionPreLaunchOCIO(PreLaunchHook):
|
||||
"""Set OCIO environment variable for Fusion"""
|
||||
app_groups = ["fusion"]
|
||||
class OCIOEnvHook(PreLaunchHook):
|
||||
"""Set OCIO environment variable for hosts that use OpenColorIO."""
|
||||
|
||||
order = 0
|
||||
hosts = [
|
||||
"substancepainter",
|
||||
"fusion",
|
||||
"blender",
|
||||
"aftereffects",
|
||||
"max",
|
||||
"houdini",
|
||||
"maya",
|
||||
"nuke",
|
||||
"hiero",
|
||||
"resolve"
|
||||
]
|
||||
|
||||
def execute(self):
|
||||
"""Hook entry method."""
|
||||
|
|
@ -26,7 +41,13 @@ class FusionPreLaunchOCIO(PreLaunchHook):
|
|||
anatomy_data=template_data,
|
||||
anatomy=self.data["anatomy"]
|
||||
)
|
||||
ocio_path = config_data["path"]
|
||||
|
||||
self.log.info(f"Setting OCIO config path: {ocio_path}")
|
||||
self.launch_context.env["OCIO"] = ocio_path
|
||||
if config_data:
|
||||
ocio_path = config_data["path"]
|
||||
|
||||
self.log.info(
|
||||
f"Setting OCIO environment to config path: {ocio_path}")
|
||||
|
||||
self.launch_context.env["OCIO"] = ocio_path
|
||||
else:
|
||||
self.log.debug("OCIO not set or enabled")
|
||||
|
|
@ -10,6 +10,7 @@ from qtpy import QtCore, QtWidgets
|
|||
from openpype import style
|
||||
from openpype.lib import Logger, StringTemplate
|
||||
from openpype.pipeline import LegacyCreator, LoaderPlugin
|
||||
from openpype.pipeline.colorspace import get_remapped_colorspace_to_native
|
||||
from openpype.settings import get_current_project_settings
|
||||
|
||||
from . import constants
|
||||
|
|
@ -701,6 +702,7 @@ class ClipLoader(LoaderPlugin):
|
|||
]
|
||||
|
||||
_mapping = None
|
||||
_host_settings = None
|
||||
|
||||
def apply_settings(cls, project_settings, system_settings):
|
||||
|
||||
|
|
@ -769,15 +771,26 @@ class ClipLoader(LoaderPlugin):
|
|||
Returns:
|
||||
str: native colorspace name defined in mapping or None
|
||||
"""
|
||||
# TODO: rewrite to support only pipeline's remapping
|
||||
if not cls._host_settings:
|
||||
cls._host_settings = get_current_project_settings()["flame"]
|
||||
|
||||
# [Deprecated] way of remapping
|
||||
if not cls._mapping:
|
||||
settings = get_current_project_settings()["flame"]
|
||||
mapping = settings["imageio"]["profilesMapping"]["inputs"]
|
||||
mapping = (
|
||||
cls._host_settings["imageio"]["profilesMapping"]["inputs"])
|
||||
cls._mapping = {
|
||||
input["ocioName"]: input["flameName"]
|
||||
for input in mapping
|
||||
}
|
||||
|
||||
return cls._mapping.get(input_colorspace)
|
||||
native_name = cls._mapping.get(input_colorspace)
|
||||
|
||||
if not native_name:
|
||||
native_name = get_remapped_colorspace_to_native(
|
||||
input_colorspace, "flame", cls._host_settings["imageio"])
|
||||
|
||||
return native_name
|
||||
|
||||
|
||||
class OpenClipSolver(flib.MediaInfoFile):
|
||||
|
|
|
|||
|
|
@ -47,6 +47,17 @@ class FlamePrelaunch(PreLaunchHook):
|
|||
|
||||
imageio_flame = project_settings["flame"]["imageio"]
|
||||
|
||||
# Check whether 'enabled' key from host imageio settings exists
|
||||
# so we can tell if host is using the new colormanagement framework.
|
||||
# If the 'enabled' isn't found we want 'colormanaged' set to True
|
||||
# because prior to the key existing we always did colormanagement for
|
||||
# Flame
|
||||
colormanaged = imageio_flame.get("enabled")
|
||||
# if key was not found, set to True
|
||||
# ensuring backward compatibility
|
||||
if colormanaged is None:
|
||||
colormanaged = True
|
||||
|
||||
# get user name and host name
|
||||
user_name = get_openpype_username()
|
||||
user_name = user_name.replace(".", "_")
|
||||
|
|
@ -68,9 +79,7 @@ class FlamePrelaunch(PreLaunchHook):
|
|||
"FrameWidth": int(width),
|
||||
"FrameHeight": int(height),
|
||||
"AspectRatio": float((width / height) * _db_p_data["pixelAspect"]),
|
||||
"FrameRate": self._get_flame_fps(fps),
|
||||
"FrameDepth": str(imageio_flame["project"]["frameDepth"]),
|
||||
"FieldDominance": str(imageio_flame["project"]["fieldDominance"])
|
||||
"FrameRate": self._get_flame_fps(fps)
|
||||
}
|
||||
|
||||
data_to_script = {
|
||||
|
|
@ -78,7 +87,6 @@ class FlamePrelaunch(PreLaunchHook):
|
|||
"host_name": _env.get("FLAME_WIRETAP_HOSTNAME") or hostname,
|
||||
"volume_name": volume_name,
|
||||
"group_name": _env.get("FLAME_WIRETAP_GROUP"),
|
||||
"color_policy": str(imageio_flame["project"]["colourPolicy"]),
|
||||
|
||||
# from project
|
||||
"project_name": project_name,
|
||||
|
|
@ -86,6 +94,16 @@ class FlamePrelaunch(PreLaunchHook):
|
|||
"project_data": project_data
|
||||
}
|
||||
|
||||
# add color management data
|
||||
if colormanaged:
|
||||
project_data.update({
|
||||
"FrameDepth": str(imageio_flame["project"]["frameDepth"]),
|
||||
"FieldDominance": str(
|
||||
imageio_flame["project"]["fieldDominance"])
|
||||
})
|
||||
data_to_script["color_policy"] = str(
|
||||
imageio_flame["project"]["colourPolicy"])
|
||||
|
||||
self.log.info(pformat(dict(_env)))
|
||||
self.log.info(pformat(data_to_script))
|
||||
|
||||
|
|
|
|||
|
|
@ -23,11 +23,17 @@ except ImportError:
|
|||
|
||||
from openpype.client import get_project
|
||||
from openpype.settings import get_project_settings
|
||||
from openpype.pipeline import legacy_io, Anatomy
|
||||
from openpype.pipeline import (
|
||||
get_current_project_name, legacy_io, Anatomy
|
||||
)
|
||||
from openpype.pipeline.load import filter_containers
|
||||
from openpype.lib import Logger
|
||||
from . import tags
|
||||
|
||||
from openpype.pipeline.colorspace import (
|
||||
get_imageio_config
|
||||
)
|
||||
|
||||
|
||||
class DeprecatedWarning(DeprecationWarning):
|
||||
pass
|
||||
|
|
@ -1047,6 +1053,18 @@ def apply_colorspace_project():
|
|||
imageio = get_project_settings(project_name)["hiero"]["imageio"]
|
||||
presets = imageio.get("workfile")
|
||||
|
||||
# backward compatibility layer
|
||||
# TODO: remove this after some time
|
||||
config_data = get_imageio_config(
|
||||
project_name=get_current_project_name(),
|
||||
host_name="hiero"
|
||||
)
|
||||
|
||||
if config_data:
|
||||
presets.update({
|
||||
"ocioConfigName": "custom"
|
||||
})
|
||||
|
||||
# save the workfile as subversion "comment:_colorspaceChange"
|
||||
split_current_file = os.path.splitext(current_file)
|
||||
copy_current_file = current_file
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ from operator import attrgetter
|
|||
|
||||
import json
|
||||
|
||||
from openpype.host import HostBase, IWorkfileHost, ILoadHost, INewPublisher
|
||||
from openpype.host import HostBase, IWorkfileHost, ILoadHost, IPublishHost
|
||||
import pyblish.api
|
||||
from openpype.pipeline import (
|
||||
register_creator_plugin_path,
|
||||
|
|
@ -28,7 +28,7 @@ CREATE_PATH = os.path.join(PLUGINS_DIR, "create")
|
|||
INVENTORY_PATH = os.path.join(PLUGINS_DIR, "inventory")
|
||||
|
||||
|
||||
class MaxHost(HostBase, IWorkfileHost, ILoadHost, INewPublisher):
|
||||
class MaxHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost):
|
||||
|
||||
name = "max"
|
||||
menu = None
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
"""Standalone helper functions"""
|
||||
|
||||
import os
|
||||
from pprint import pformat
|
||||
import sys
|
||||
import platform
|
||||
import uuid
|
||||
|
|
@ -3239,75 +3240,6 @@ def iter_shader_edits(relationships, shader_nodes, nodes_by_id, label=None):
|
|||
def set_colorspace():
|
||||
"""Set Colorspace from project configuration
|
||||
"""
|
||||
project_name = os.getenv("AVALON_PROJECT")
|
||||
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
|
||||
# separate settings for both so we fall back when necessary.
|
||||
use_ocio_v2 = imageio["colorManagementPreference_v2"]["enabled"]
|
||||
required_maya_version = 2022
|
||||
maya_version = int(cmds.about(version=True))
|
||||
maya_supports_ocio_v2 = maya_version >= required_maya_version
|
||||
if use_ocio_v2 and not maya_supports_ocio_v2:
|
||||
# Fallback to legacy behavior with a warning
|
||||
log.warning("Color Management Preference v2 is enabled but not "
|
||||
"supported by current Maya version: {} (< {}). Falling "
|
||||
"back to legacy settings.".format(
|
||||
maya_version, required_maya_version)
|
||||
)
|
||||
use_ocio_v2 = False
|
||||
|
||||
if use_ocio_v2:
|
||||
root_dict = imageio["colorManagementPreference_v2"]
|
||||
else:
|
||||
root_dict = imageio["colorManagementPreference"]
|
||||
|
||||
if not isinstance(root_dict, dict):
|
||||
msg = "set_colorspace(): argument should be dictionary"
|
||||
log.error(msg)
|
||||
|
||||
log.debug(">> root_dict: {}".format(root_dict))
|
||||
|
||||
# enable color management
|
||||
cmds.colorManagementPrefs(e=True, cmEnabled=True)
|
||||
cmds.colorManagementPrefs(e=True, ocioRulesEnabled=True)
|
||||
|
||||
# set config path
|
||||
custom_ocio_config = False
|
||||
if root_dict.get("configFilePath"):
|
||||
unresolved_path = root_dict["configFilePath"]
|
||||
ocio_paths = unresolved_path[platform.system().lower()]
|
||||
|
||||
resolved_path = None
|
||||
for ocio_p in ocio_paths:
|
||||
resolved_path = str(ocio_p).format(**os.environ)
|
||||
if not os.path.exists(resolved_path):
|
||||
continue
|
||||
|
||||
if resolved_path:
|
||||
filepath = str(resolved_path).replace("\\", "/")
|
||||
cmds.colorManagementPrefs(e=True, configFilePath=filepath)
|
||||
cmds.colorManagementPrefs(e=True, cmConfigFileEnabled=True)
|
||||
log.debug("maya '{}' changed to: {}".format(
|
||||
"configFilePath", resolved_path))
|
||||
custom_ocio_config = True
|
||||
else:
|
||||
cmds.colorManagementPrefs(e=True, cmConfigFileEnabled=False)
|
||||
cmds.colorManagementPrefs(e=True, configFilePath="")
|
||||
|
||||
# If no custom OCIO config file was set we make sure that Maya 2022+
|
||||
# either chooses between Maya's newer default v2 or legacy config based
|
||||
# on OpenPype setting to use ocio v2 or not.
|
||||
if maya_supports_ocio_v2 and not custom_ocio_config:
|
||||
if use_ocio_v2:
|
||||
# Use Maya 2022+ default OCIO v2 config
|
||||
log.info("Setting default Maya OCIO v2 config")
|
||||
cmds.colorManagementPrefs(edit=True, configFilePath="")
|
||||
else:
|
||||
# Set the Maya default config file path
|
||||
log.info("Setting default Maya OCIO v1 legacy config")
|
||||
cmds.colorManagementPrefs(edit=True, configFilePath="legacy")
|
||||
|
||||
# set color spaces for rendering space and view transforms
|
||||
def _colormanage(**kwargs):
|
||||
|
|
@ -3324,17 +3256,74 @@ def set_colorspace():
|
|||
except RuntimeError as exc:
|
||||
log.error(exc)
|
||||
|
||||
if use_ocio_v2:
|
||||
_colormanage(renderingSpaceName=root_dict["renderSpace"])
|
||||
_colormanage(displayName=root_dict["displayName"])
|
||||
_colormanage(viewName=root_dict["viewName"])
|
||||
else:
|
||||
_colormanage(renderingSpaceName=root_dict["renderSpace"])
|
||||
if maya_supports_ocio_v2:
|
||||
_colormanage(viewName=root_dict["viewTransform"])
|
||||
_colormanage(displayName="legacy")
|
||||
project_name = os.getenv("AVALON_PROJECT")
|
||||
imageio = get_project_settings(project_name)["maya"]["imageio"]
|
||||
|
||||
# ocio compatibility variables
|
||||
ocio_v2_maya_version = 2022
|
||||
maya_version = int(cmds.about(version=True))
|
||||
ocio_v2_support = use_ocio_v2 = maya_version >= ocio_v2_maya_version
|
||||
|
||||
root_dict = {}
|
||||
use_workfile_settings = imageio.get("workfile", {}).get("enabled")
|
||||
|
||||
if use_workfile_settings:
|
||||
# TODO: deprecated code from 3.15.5 - remove
|
||||
# Maya 2022+ introduces new OCIO v2 color management settings that
|
||||
# can override the old color management preferences. OpenPype has
|
||||
# separate settings for both so we fall back when necessary.
|
||||
use_ocio_v2 = imageio["colorManagementPreference_v2"]["enabled"]
|
||||
if use_ocio_v2 and not ocio_v2_support:
|
||||
# Fallback to legacy behavior with a warning
|
||||
log.warning(
|
||||
"Color Management Preference v2 is enabled but not "
|
||||
"supported by current Maya version: {} (< {}). Falling "
|
||||
"back to legacy settings.".format(
|
||||
maya_version, ocio_v2_maya_version)
|
||||
)
|
||||
|
||||
if use_ocio_v2:
|
||||
root_dict = imageio["colorManagementPreference_v2"]
|
||||
else:
|
||||
_colormanage(viewTransformName=root_dict["viewTransform"])
|
||||
root_dict = imageio["colorManagementPreference"]
|
||||
|
||||
if not isinstance(root_dict, dict):
|
||||
msg = "set_colorspace(): argument should be dictionary"
|
||||
log.error(msg)
|
||||
|
||||
else:
|
||||
root_dict = imageio["workfile"]
|
||||
|
||||
log.debug(">> root_dict: {}".format(pformat(root_dict)))
|
||||
|
||||
if root_dict:
|
||||
# enable color management
|
||||
cmds.colorManagementPrefs(e=True, cmEnabled=True)
|
||||
cmds.colorManagementPrefs(e=True, ocioRulesEnabled=True)
|
||||
|
||||
# backward compatibility
|
||||
# TODO: deprecated code from 3.15.5 - refactor to use new settings
|
||||
view_name = root_dict.get("viewTransform")
|
||||
if view_name is None:
|
||||
view_name = root_dict.get("viewName")
|
||||
|
||||
if use_ocio_v2:
|
||||
# Use Maya 2022+ default OCIO v2 config
|
||||
log.info("Setting default Maya OCIO v2 config")
|
||||
cmds.colorManagementPrefs(edit=True, configFilePath="")
|
||||
|
||||
# set rendering space and view transform
|
||||
_colormanage(renderingSpaceName=root_dict["renderSpace"])
|
||||
_colormanage(viewName=view_name)
|
||||
_colormanage(displayName=root_dict["displayName"])
|
||||
else:
|
||||
# Set the Maya default config file path
|
||||
log.info("Setting default Maya OCIO v1 legacy config")
|
||||
cmds.colorManagementPrefs(edit=True, configFilePath="legacy")
|
||||
|
||||
# set rendering space and view transform
|
||||
_colormanage(renderingSpaceName=root_dict["renderSpace"])
|
||||
_colormanage(viewTransformName=view_name)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
|
|
|
|||
|
|
@ -273,6 +273,11 @@ class FileNodeLoader(load.LoaderPlugin):
|
|||
project_name, host_name,
|
||||
project_settings=project_settings
|
||||
)
|
||||
|
||||
# ignore if host imageio is not enabled
|
||||
if not config_data:
|
||||
return
|
||||
|
||||
file_rules = get_imageio_file_rules(
|
||||
project_name, host_name,
|
||||
project_settings=project_settings
|
||||
|
|
|
|||
|
|
@ -274,16 +274,18 @@ class ValidateRenderSettings(pyblish.api.InstancePlugin):
|
|||
|
||||
# go through definitions and test if such node.attribute exists.
|
||||
# if so, compare its value from the one required.
|
||||
for attribute, data in cls.get_nodes(instance, renderer).items():
|
||||
for data in cls.get_nodes(instance, renderer):
|
||||
for node in data["nodes"]:
|
||||
try:
|
||||
render_value = cmds.getAttr(
|
||||
"{}.{}".format(node, attribute)
|
||||
"{}.{}".format(node, data["attribute"])
|
||||
)
|
||||
except RuntimeError:
|
||||
invalid = True
|
||||
cls.log.error(
|
||||
"Cannot get value of {}.{}".format(node, attribute)
|
||||
"Cannot get value of {}.{}".format(
|
||||
node, data["attribute"]
|
||||
)
|
||||
)
|
||||
else:
|
||||
if render_value not in data["values"]:
|
||||
|
|
@ -291,7 +293,10 @@ class ValidateRenderSettings(pyblish.api.InstancePlugin):
|
|||
cls.log.error(
|
||||
"Invalid value {} set on {}.{}. Expecting "
|
||||
"{}".format(
|
||||
render_value, node, attribute, data["values"]
|
||||
render_value,
|
||||
node,
|
||||
data["attribute"],
|
||||
data["values"]
|
||||
)
|
||||
)
|
||||
|
||||
|
|
@ -305,7 +310,7 @@ class ValidateRenderSettings(pyblish.api.InstancePlugin):
|
|||
"{}_render_attributes".format(renderer)
|
||||
) or []
|
||||
)
|
||||
result = {}
|
||||
result = []
|
||||
for attr, values in OrderedDict(validation_settings).items():
|
||||
values = [convert_to_int_or_float(v) for v in values if v]
|
||||
|
||||
|
|
@ -335,7 +340,13 @@ class ValidateRenderSettings(pyblish.api.InstancePlugin):
|
|||
)
|
||||
continue
|
||||
|
||||
result[attribute_name] = {"nodes": nodes, "values": values}
|
||||
result.append(
|
||||
{
|
||||
"attribute": attribute_name,
|
||||
"nodes": nodes,
|
||||
"values": values
|
||||
}
|
||||
)
|
||||
|
||||
return result
|
||||
|
||||
|
|
@ -350,11 +361,11 @@ class ValidateRenderSettings(pyblish.api.InstancePlugin):
|
|||
"{aov_separator}", instance.data.get("aovSeparator", "_")
|
||||
)
|
||||
|
||||
for attribute, data in cls.get_nodes(instance, renderer).items():
|
||||
for data in cls.get_nodes(instance, renderer):
|
||||
if not data["values"]:
|
||||
continue
|
||||
for node in data["nodes"]:
|
||||
lib.set_attribute(attribute, data["values"][0], node)
|
||||
lib.set_attribute(data["attribute"], data["values"][0], node)
|
||||
|
||||
with lib.renderlayer(layer_node):
|
||||
default = lib.RENDER_ATTRS['default']
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ from openpype.settings import (
|
|||
from openpype.modules import ModulesManager
|
||||
from openpype.pipeline.template_data import get_template_data_with_names
|
||||
from openpype.pipeline import (
|
||||
get_current_project_name,
|
||||
discover_legacy_creator_plugins,
|
||||
legacy_io,
|
||||
Anatomy,
|
||||
|
|
@ -2001,63 +2002,72 @@ class WorkfileSettings(object):
|
|||
"Attention! Viewer nodes {} were erased."
|
||||
"It had wrong color profile".format(erased_viewers))
|
||||
|
||||
def set_root_colorspace(self, nuke_colorspace):
|
||||
def set_root_colorspace(self, imageio_host):
|
||||
''' Adds correct colorspace to root
|
||||
|
||||
Arguments:
|
||||
nuke_colorspace (dict): adjustmensts from presets
|
||||
imageio_host (dict): host colorspace configurations
|
||||
|
||||
'''
|
||||
workfile_settings = nuke_colorspace["workfile"]
|
||||
config_data = get_imageio_config(
|
||||
project_name=get_current_project_name(),
|
||||
host_name="nuke"
|
||||
)
|
||||
|
||||
# resolve config data if they are enabled in host
|
||||
config_data = None
|
||||
if nuke_colorspace.get("ocio_config", {}).get("enabled"):
|
||||
# switch ocio config to custom config
|
||||
workfile_settings["OCIO_config"] = "custom"
|
||||
workfile_settings["colorManagement"] = "OCIO"
|
||||
workfile_settings = imageio_host["workfile"]
|
||||
|
||||
# get resolved ocio config path
|
||||
config_data = get_imageio_config(
|
||||
legacy_io.active_project(), "nuke"
|
||||
)
|
||||
if not config_data:
|
||||
# TODO: backward compatibility for old projects - remove later
|
||||
# perhaps old project overrides is having it set to older version
|
||||
# with use of `customOCIOConfigPath`
|
||||
resolved_path = None
|
||||
if workfile_settings.get("customOCIOConfigPath"):
|
||||
unresolved_path = workfile_settings["customOCIOConfigPath"]
|
||||
ocio_paths = unresolved_path[platform.system().lower()]
|
||||
|
||||
# first set OCIO
|
||||
if self._root_node["colorManagement"].value() \
|
||||
not in str(workfile_settings["colorManagement"]):
|
||||
self._root_node["colorManagement"].setValue(
|
||||
str(workfile_settings["colorManagement"]))
|
||||
for ocio_p in ocio_paths:
|
||||
resolved_path = str(ocio_p).format(**os.environ)
|
||||
if not os.path.exists(resolved_path):
|
||||
continue
|
||||
|
||||
# we dont need the key anymore
|
||||
workfile_settings.pop("colorManagement")
|
||||
if resolved_path:
|
||||
# set values to root
|
||||
self._root_node["colorManagement"].setValue("OCIO")
|
||||
self._root_node["OCIO_config"].setValue("custom")
|
||||
self._root_node["customOCIOConfigPath"].setValue(
|
||||
resolved_path)
|
||||
else:
|
||||
# no ocio config found and no custom path used
|
||||
if self._root_node["colorManagement"].value() \
|
||||
not in str(workfile_settings["colorManagement"]):
|
||||
self._root_node["colorManagement"].setValue(
|
||||
str(workfile_settings["colorManagement"]))
|
||||
|
||||
# second set ocio version
|
||||
if self._root_node["OCIO_config"].value() \
|
||||
not in str(workfile_settings["OCIO_config"]):
|
||||
self._root_node["OCIO_config"].setValue(
|
||||
str(workfile_settings["OCIO_config"]))
|
||||
# second set ocio version
|
||||
if self._root_node["OCIO_config"].value() \
|
||||
not in str(workfile_settings["OCIO_config"]):
|
||||
self._root_node["OCIO_config"].setValue(
|
||||
str(workfile_settings["OCIO_config"]))
|
||||
|
||||
# we dont need the key anymore
|
||||
workfile_settings.pop("OCIO_config")
|
||||
else:
|
||||
# set values to root
|
||||
self._root_node["colorManagement"].setValue("OCIO")
|
||||
|
||||
# third set ocio custom path
|
||||
if config_data:
|
||||
self._root_node["customOCIOConfigPath"].setValue(
|
||||
str(config_data["path"]).replace("\\", "/")
|
||||
)
|
||||
# backward compatibility, remove in case it exists
|
||||
workfile_settings.pop("customOCIOConfigPath")
|
||||
# we dont need the key anymore
|
||||
workfile_settings.pop("customOCIOConfigPath", None)
|
||||
workfile_settings.pop("colorManagement", None)
|
||||
workfile_settings.pop("OCIO_config", None)
|
||||
|
||||
# then set the rest
|
||||
for knob, value in workfile_settings.items():
|
||||
for knob, value_ in workfile_settings.items():
|
||||
# skip unfilled ocio config path
|
||||
# it will be dict in value
|
||||
if isinstance(value, dict):
|
||||
if isinstance(value_, dict):
|
||||
continue
|
||||
if self._root_node[knob].value() not in value:
|
||||
self._root_node[knob].setValue(str(value))
|
||||
if self._root_node[knob].value() not in value_:
|
||||
self._root_node[knob].setValue(str(value_))
|
||||
log.debug("nuke.root()['{}'] changed to: {}".format(
|
||||
knob, value))
|
||||
knob, value_))
|
||||
|
||||
def set_writes_colorspace(self):
|
||||
''' Adds correct colorspace to write node dict
|
||||
|
|
|
|||
|
|
@ -237,15 +237,25 @@ def _install_menu():
|
|||
|
||||
menu.addSeparator()
|
||||
if not ASSIST:
|
||||
# only add parent if nuke version is 14 or higher
|
||||
# known issue with no solution yet
|
||||
menu.addCommand(
|
||||
"Create...",
|
||||
lambda: host_tools.show_publisher(
|
||||
parent=(
|
||||
main_window if nuke.NUKE_VERSION_RELEASE >= 14 else None
|
||||
),
|
||||
tab="create"
|
||||
)
|
||||
)
|
||||
# only add parent if nuke version is 14 or higher
|
||||
# known issue with no solution yet
|
||||
menu.addCommand(
|
||||
"Publish...",
|
||||
lambda: host_tools.show_publisher(
|
||||
parent=(
|
||||
main_window if nuke.NUKE_VERSION_RELEASE >= 14 else None
|
||||
),
|
||||
tab="publish"
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ class NukeRenderLocal(publish.Extractor,
|
|||
order = pyblish.api.ExtractorOrder
|
||||
label = "Render Local"
|
||||
hosts = ["nuke"]
|
||||
families = ["render.local", "prerender.local", "still.local"]
|
||||
families = ["render.local", "prerender.local", "image.local"]
|
||||
|
||||
def process(self, instance):
|
||||
child_nodes = (
|
||||
|
|
@ -136,9 +136,9 @@ class NukeRenderLocal(publish.Extractor,
|
|||
families.remove('prerender.local')
|
||||
families.insert(0, "prerender")
|
||||
instance.data["anatomyData"]["family"] = "prerender"
|
||||
elif "still.local" in families:
|
||||
elif "image.local" in families:
|
||||
instance.data['family'] = 'image'
|
||||
families.remove('still.local')
|
||||
families.remove('image.local')
|
||||
instance.data["anatomyData"]["family"] = "image"
|
||||
instance.data["families"] = families
|
||||
|
||||
|
|
|
|||
|
|
@ -222,7 +222,6 @@ class CollectContextDataSAPublish(pyblish.api.ContextPlugin):
|
|||
"label": subset,
|
||||
"name": subset,
|
||||
"family": in_data["family"],
|
||||
# "version": in_data.get("version", 1),
|
||||
"frameStart": in_data.get("representations", [None])[0].get(
|
||||
"frameStart", None
|
||||
),
|
||||
|
|
@ -232,6 +231,14 @@ class CollectContextDataSAPublish(pyblish.api.ContextPlugin):
|
|||
"families": instance_families
|
||||
}
|
||||
)
|
||||
# Fill version only if 'use_next_available_version' is disabled
|
||||
# and version is filled in instance data
|
||||
version = in_data.get("version")
|
||||
use_next_available_version = in_data.get(
|
||||
"use_next_available_version", True)
|
||||
if not use_next_available_version and version is not None:
|
||||
instance.data["version"] = version
|
||||
|
||||
self.log.info("collected instance: {}".format(pformat(instance.data)))
|
||||
self.log.info("parsing data: {}".format(pformat(in_data)))
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,14 @@
|
|||
from openpype.lib.attribute_definitions import FileDef
|
||||
from openpype.client import (
|
||||
get_assets,
|
||||
get_subsets,
|
||||
get_last_versions,
|
||||
)
|
||||
from openpype.lib.attribute_definitions import (
|
||||
FileDef,
|
||||
BoolDef,
|
||||
NumberDef,
|
||||
UISeparatorDef,
|
||||
)
|
||||
from openpype.lib.transcoding import IMAGE_EXTENSIONS, VIDEO_EXTENSIONS
|
||||
from openpype.pipeline.create import (
|
||||
Creator,
|
||||
|
|
@ -94,6 +104,7 @@ class TrayPublishCreator(Creator):
|
|||
class SettingsCreator(TrayPublishCreator):
|
||||
create_allow_context_change = True
|
||||
create_allow_thumbnail = True
|
||||
allow_version_control = False
|
||||
|
||||
extensions = []
|
||||
|
||||
|
|
@ -101,8 +112,18 @@ class SettingsCreator(TrayPublishCreator):
|
|||
# Pass precreate data to creator attributes
|
||||
thumbnail_path = pre_create_data.pop(PRE_CREATE_THUMBNAIL_KEY, None)
|
||||
|
||||
# Fill 'version_to_use' if version control is enabled
|
||||
if self.allow_version_control:
|
||||
asset_name = data["asset"]
|
||||
subset_docs_by_asset_id = self._prepare_next_versions(
|
||||
[asset_name], [subset_name])
|
||||
version = subset_docs_by_asset_id[asset_name].get(subset_name)
|
||||
pre_create_data["version_to_use"] = version
|
||||
data["_previous_last_version"] = version
|
||||
|
||||
data["creator_attributes"] = pre_create_data
|
||||
data["settings_creator"] = True
|
||||
|
||||
# Create new instance
|
||||
new_instance = CreatedInstance(self.family, subset_name, data, self)
|
||||
|
||||
|
|
@ -111,7 +132,158 @@ class SettingsCreator(TrayPublishCreator):
|
|||
if thumbnail_path:
|
||||
self.set_instance_thumbnail_path(new_instance.id, thumbnail_path)
|
||||
|
||||
def _prepare_next_versions(self, asset_names, subset_names):
|
||||
"""Prepare next versions for given asset and subset names.
|
||||
|
||||
Todos:
|
||||
Expect combination of subset names by asset name to avoid
|
||||
unnecessary server calls for unused subsets.
|
||||
|
||||
Args:
|
||||
asset_names (Iterable[str]): Asset names.
|
||||
subset_names (Iterable[str]): Subset names.
|
||||
|
||||
Returns:
|
||||
dict[str, dict[str, int]]: Last versions by asset
|
||||
and subset names.
|
||||
"""
|
||||
|
||||
# Prepare all versions for all combinations to '1'
|
||||
subset_docs_by_asset_id = {
|
||||
asset_name: {
|
||||
subset_name: 1
|
||||
for subset_name in subset_names
|
||||
}
|
||||
for asset_name in asset_names
|
||||
}
|
||||
if not asset_names or not subset_names:
|
||||
return subset_docs_by_asset_id
|
||||
|
||||
asset_docs = get_assets(
|
||||
self.project_name,
|
||||
asset_names=asset_names,
|
||||
fields=["_id", "name"]
|
||||
)
|
||||
asset_names_by_id = {
|
||||
asset_doc["_id"]: asset_doc["name"]
|
||||
for asset_doc in asset_docs
|
||||
}
|
||||
subset_docs = list(get_subsets(
|
||||
self.project_name,
|
||||
asset_ids=asset_names_by_id.keys(),
|
||||
subset_names=subset_names,
|
||||
fields=["_id", "name", "parent"]
|
||||
))
|
||||
|
||||
subset_ids = {subset_doc["_id"] for subset_doc in subset_docs}
|
||||
last_versions = get_last_versions(
|
||||
self.project_name,
|
||||
subset_ids,
|
||||
fields=["name", "parent"])
|
||||
|
||||
for subset_doc in subset_docs:
|
||||
asset_id = subset_doc["parent"]
|
||||
asset_name = asset_names_by_id[asset_id]
|
||||
subset_name = subset_doc["name"]
|
||||
subset_id = subset_doc["_id"]
|
||||
last_version = last_versions.get(subset_id)
|
||||
version = 0
|
||||
if last_version is not None:
|
||||
version = last_version["name"]
|
||||
subset_docs_by_asset_id[asset_name][subset_name] += version
|
||||
return subset_docs_by_asset_id
|
||||
|
||||
def _fill_next_versions(self, instances_data):
|
||||
"""Fill next version for instances.
|
||||
|
||||
Instances have also stored previous next version to be able to
|
||||
recognize if user did enter different version. If version was
|
||||
not changed by user, or user set it to '0' the next version will be
|
||||
updated by current database state.
|
||||
"""
|
||||
|
||||
filtered_instance_data = []
|
||||
for instance in instances_data:
|
||||
previous_last_version = instance.get("_previous_last_version")
|
||||
creator_attributes = instance["creator_attributes"]
|
||||
use_next_version = creator_attributes.get(
|
||||
"use_next_version", True)
|
||||
version = creator_attributes.get("version_to_use", 0)
|
||||
if (
|
||||
use_next_version
|
||||
or version == 0
|
||||
or version == previous_last_version
|
||||
):
|
||||
filtered_instance_data.append(instance)
|
||||
|
||||
asset_names = {
|
||||
instance["asset"]
|
||||
for instance in filtered_instance_data}
|
||||
subset_names = {
|
||||
instance["subset"]
|
||||
for instance in filtered_instance_data}
|
||||
subset_docs_by_asset_id = self._prepare_next_versions(
|
||||
asset_names, subset_names
|
||||
)
|
||||
for instance in filtered_instance_data:
|
||||
asset_name = instance["asset"]
|
||||
subset_name = instance["subset"]
|
||||
version = subset_docs_by_asset_id[asset_name][subset_name]
|
||||
instance["creator_attributes"]["version_to_use"] = version
|
||||
instance["_previous_last_version"] = version
|
||||
|
||||
def collect_instances(self):
|
||||
"""Collect instances from host.
|
||||
|
||||
Overriden to be able to manage version control attributes. If version
|
||||
control is disabled, the attributes will be removed from instances,
|
||||
and next versions are filled if is version control enabled.
|
||||
"""
|
||||
|
||||
instances_by_identifier = cache_and_get_instances(
|
||||
self, SHARED_DATA_KEY, list_instances
|
||||
)
|
||||
instances = instances_by_identifier[self.identifier]
|
||||
if not instances:
|
||||
return
|
||||
|
||||
if self.allow_version_control:
|
||||
self._fill_next_versions(instances)
|
||||
|
||||
for instance_data in instances:
|
||||
# Make sure that there are not data related to version control
|
||||
# if plugin does not support it
|
||||
if not self.allow_version_control:
|
||||
instance_data.pop("_previous_last_version", None)
|
||||
creator_attributes = instance_data["creator_attributes"]
|
||||
creator_attributes.pop("version_to_use", None)
|
||||
creator_attributes.pop("use_next_version", None)
|
||||
|
||||
instance = CreatedInstance.from_existing(instance_data, self)
|
||||
self._add_instance_to_context(instance)
|
||||
|
||||
def get_instance_attr_defs(self):
|
||||
defs = self.get_pre_create_attr_defs()
|
||||
if self.allow_version_control:
|
||||
defs += [
|
||||
UISeparatorDef(),
|
||||
BoolDef(
|
||||
"use_next_version",
|
||||
default=True,
|
||||
label="Use next version",
|
||||
),
|
||||
NumberDef(
|
||||
"version_to_use",
|
||||
default=1,
|
||||
minimum=0,
|
||||
maximum=999,
|
||||
label="Version to use",
|
||||
)
|
||||
]
|
||||
return defs
|
||||
|
||||
def get_pre_create_attr_defs(self):
|
||||
# Use same attributes as for instance attributes
|
||||
return [
|
||||
FileDef(
|
||||
"representation_files",
|
||||
|
|
@ -132,10 +304,6 @@ class SettingsCreator(TrayPublishCreator):
|
|||
)
|
||||
]
|
||||
|
||||
def get_pre_create_attr_defs(self):
|
||||
# Use same attributes as for instance attrobites
|
||||
return self.get_instance_attr_defs()
|
||||
|
||||
@classmethod
|
||||
def from_settings(cls, item_data):
|
||||
identifier = item_data["identifier"]
|
||||
|
|
@ -155,6 +323,8 @@ class SettingsCreator(TrayPublishCreator):
|
|||
"extensions": item_data["extensions"],
|
||||
"allow_sequences": item_data["allow_sequences"],
|
||||
"allow_multiple_items": item_data["allow_multiple_items"],
|
||||
"default_variants": item_data["default_variants"]
|
||||
"allow_version_control": item_data.get(
|
||||
"allow_version_control", False),
|
||||
"default_variants": item_data["default_variants"],
|
||||
}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -487,7 +487,22 @@ or updating already created. Publishing will create OTIO file.
|
|||
)
|
||||
|
||||
# get video stream data
|
||||
video_stream = media_data["streams"][0]
|
||||
video_streams = []
|
||||
audio_streams = []
|
||||
for stream in media_data["streams"]:
|
||||
codec_type = stream.get("codec_type")
|
||||
if codec_type == "audio":
|
||||
audio_streams.append(stream)
|
||||
|
||||
elif codec_type == "video":
|
||||
video_streams.append(stream)
|
||||
|
||||
if not video_streams:
|
||||
raise ValueError(
|
||||
"Could not find video stream in source file."
|
||||
)
|
||||
|
||||
video_stream = video_streams[0]
|
||||
return_data = {
|
||||
"video": True,
|
||||
"start_frame": 0,
|
||||
|
|
@ -500,12 +515,7 @@ or updating already created. Publishing will create OTIO file.
|
|||
}
|
||||
|
||||
# get audio streams data
|
||||
audio_stream = [
|
||||
stream for stream in media_data["streams"]
|
||||
if stream["codec_type"] == "audio"
|
||||
]
|
||||
|
||||
if audio_stream:
|
||||
if audio_streams:
|
||||
return_data["audio"] = True
|
||||
|
||||
except Exception as exc:
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ class CollectSettingsSimpleInstances(pyblish.api.InstancePlugin):
|
|||
"Created temp staging directory for instance {}. {}"
|
||||
).format(instance_label, tmp_folder))
|
||||
|
||||
self._fill_version(instance, instance_label)
|
||||
|
||||
# Store filepaths for validation of their existence
|
||||
source_filepaths = []
|
||||
# Make sure there are no representations with same name
|
||||
|
|
@ -93,6 +95,28 @@ class CollectSettingsSimpleInstances(pyblish.api.InstancePlugin):
|
|||
)
|
||||
)
|
||||
|
||||
def _fill_version(self, instance, instance_label):
|
||||
"""Fill instance version under which will be instance integrated.
|
||||
|
||||
Instance must have set 'use_next_version' to 'False'
|
||||
and 'version_to_use' to version to use.
|
||||
|
||||
Args:
|
||||
instance (pyblish.api.Instance): Instance to fill version for.
|
||||
instance_label (str): Label of instance to fill version for.
|
||||
"""
|
||||
|
||||
creator_attributes = instance.data["creator_attributes"]
|
||||
use_next_version = creator_attributes.get("use_next_version", True)
|
||||
# If 'version_to_use' is '0' it means that next version should be used
|
||||
version_to_use = creator_attributes.get("version_to_use", 0)
|
||||
if use_next_version or not version_to_use:
|
||||
return
|
||||
instance.data["version"] = version_to_use
|
||||
self.log.debug(
|
||||
"Version for instance \"{}\" was set to \"{}\"".format(
|
||||
instance_label, version_to_use))
|
||||
|
||||
def _create_main_representations(
|
||||
self,
|
||||
instance,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<root>
|
||||
<error id="main">
|
||||
<title>Version already exists</title>
|
||||
<description>
|
||||
## Version already exists
|
||||
|
||||
Version {version} you have set on instance '{subset_name}' under '{asset_name}' already exists. This validation is enabled by default to prevent accidental override of existing versions.
|
||||
|
||||
### How to repair?
|
||||
- Click on 'Repair' action -> this will change version to next available.
|
||||
- Disable validation on the instance if you are sure you want to override the version.
|
||||
- Reset publishing and manually change the version number.
|
||||
</description>
|
||||
</error>
|
||||
</root>
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
import pyblish.api
|
||||
|
||||
from openpype.pipeline.publish import (
|
||||
ValidateContentsOrder,
|
||||
PublishXmlValidationError,
|
||||
OptionalPyblishPluginMixin,
|
||||
RepairAction,
|
||||
)
|
||||
|
||||
|
||||
class ValidateExistingVersion(
|
||||
OptionalPyblishPluginMixin,
|
||||
pyblish.api.InstancePlugin
|
||||
):
|
||||
label = "Validate Existing Version"
|
||||
order = ValidateContentsOrder
|
||||
|
||||
hosts = ["traypublisher"]
|
||||
|
||||
actions = [RepairAction]
|
||||
|
||||
settings_category = "traypublisher"
|
||||
optional = True
|
||||
|
||||
def process(self, instance):
|
||||
if not self.is_active(instance.data):
|
||||
return
|
||||
|
||||
version = instance.data.get("version")
|
||||
if version is None:
|
||||
return
|
||||
|
||||
last_version = instance.data.get("latestVersion")
|
||||
if last_version is None or last_version < version:
|
||||
return
|
||||
|
||||
subset_name = instance.data["subset"]
|
||||
msg = "Version {} already exists for subset {}.".format(
|
||||
version, subset_name)
|
||||
|
||||
formatting_data = {
|
||||
"subset_name": subset_name,
|
||||
"asset_name": instance.data["asset"],
|
||||
"version": version
|
||||
}
|
||||
raise PublishXmlValidationError(
|
||||
self, msg, formatting_data=formatting_data)
|
||||
|
||||
@classmethod
|
||||
def repair(cls, instance):
|
||||
create_context = instance.context.data["create_context"]
|
||||
created_instance = create_context.get_instance_by_id(
|
||||
instance.data["instance_id"])
|
||||
creator_attributes = created_instance["creator_attributes"]
|
||||
# Disable version override
|
||||
creator_attributes["use_next_version"] = True
|
||||
create_context.save_changes()
|
||||
|
|
@ -113,6 +113,12 @@ def pack_project(
|
|||
project_name
|
||||
))
|
||||
|
||||
if only_documents and not destination_dir:
|
||||
raise ValueError((
|
||||
"Destination directory must be defined"
|
||||
" when only documents should be packed."
|
||||
))
|
||||
|
||||
root_path = None
|
||||
source_root = {}
|
||||
project_source_path = None
|
||||
|
|
@ -141,6 +147,11 @@ def pack_project(
|
|||
if not destination_dir:
|
||||
destination_dir = root_path
|
||||
|
||||
if not destination_dir:
|
||||
raise ValueError(
|
||||
"Project {} does not have any roots.".format(project_name)
|
||||
)
|
||||
|
||||
destination_dir = os.path.normpath(destination_dir)
|
||||
if not os.path.exists(destination_dir):
|
||||
os.makedirs(destination_dir)
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ IMAGE_EXTENSIONS = {
|
|||
".jng", ".jpeg", ".jpeg-ls", ".jpeg", ".2000", ".jpg", ".xr",
|
||||
".jpeg", ".xt", ".jpeg-hdr", ".kra", ".mng", ".miff", ".nrrd",
|
||||
".ora", ".pam", ".pbm", ".pgm", ".ppm", ".pnm", ".pcx", ".pgf",
|
||||
".pictor", ".png", ".psb", ".psp", ".qtvr", ".ras",
|
||||
".pictor", ".png", ".psd", ".psb", ".psp", ".qtvr", ".ras",
|
||||
".rgbe", ".logluv", ".tiff", ".sgi", ".tga", ".tiff", ".tiff/ep",
|
||||
".tiff/it", ".ufo", ".ufp", ".wbmp", ".webp", ".xbm", ".xcf",
|
||||
".xpm", ".xwd"
|
||||
|
|
|
|||
|
|
@ -59,7 +59,6 @@ class CelactionSubmitDeadline(pyblish.api.InstancePlugin):
|
|||
render_path).replace("\\", "/")
|
||||
|
||||
instance.data["publishJobState"] = "Suspended"
|
||||
instance.context.data['ftrackStatus'] = "Render"
|
||||
|
||||
# adding 2d render specific family for version identification in Loader
|
||||
instance.data["families"] = ["render2d"]
|
||||
|
|
|
|||
|
|
@ -109,8 +109,6 @@ class IntegrateFtrackApi(pyblish.api.InstancePlugin):
|
|||
for status in asset_version_statuses
|
||||
}
|
||||
|
||||
self._set_task_status(instance, project_entity, task_entity, session)
|
||||
|
||||
# Prepare AssetTypes
|
||||
asset_types_by_short = self._ensure_asset_types_exists(
|
||||
session, component_list
|
||||
|
|
@ -180,45 +178,6 @@ class IntegrateFtrackApi(pyblish.api.InstancePlugin):
|
|||
if asset_version not in instance.data[asset_versions_key]:
|
||||
instance.data[asset_versions_key].append(asset_version)
|
||||
|
||||
def _set_task_status(self, instance, project_entity, task_entity, session):
|
||||
if not project_entity:
|
||||
self.log.info("Task status won't be set, project is not known.")
|
||||
return
|
||||
|
||||
if not task_entity:
|
||||
self.log.info("Task status won't be set, task is not known.")
|
||||
return
|
||||
|
||||
status_name = instance.context.data.get("ftrackStatus")
|
||||
if not status_name:
|
||||
self.log.info("Ftrack status name is not set.")
|
||||
return
|
||||
|
||||
self.log.debug(
|
||||
"Ftrack status name will be (maybe) set to \"{}\"".format(
|
||||
status_name
|
||||
)
|
||||
)
|
||||
|
||||
project_schema = project_entity["project_schema"]
|
||||
task_statuses = project_schema.get_statuses(
|
||||
"Task", task_entity["type_id"]
|
||||
)
|
||||
task_statuses_by_low_name = {
|
||||
status["name"].lower(): status for status in task_statuses
|
||||
}
|
||||
status = task_statuses_by_low_name.get(status_name.lower())
|
||||
if not status:
|
||||
self.log.warning((
|
||||
"Task status \"{}\" won't be set,"
|
||||
" status is now allowed on task type \"{}\"."
|
||||
).format(status_name, task_entity["type"]["name"]))
|
||||
return
|
||||
|
||||
self.log.info("Setting task status to \"{}\"".format(status_name))
|
||||
task_entity["status"] = status
|
||||
session.commit()
|
||||
|
||||
def _fill_component_locations(self, session, component_list):
|
||||
components_by_location_name = collections.defaultdict(list)
|
||||
components_by_location_id = collections.defaultdict(list)
|
||||
|
|
|
|||
|
|
@ -1,150 +0,0 @@
|
|||
import pyblish.api
|
||||
from openpype.lib import filter_profiles
|
||||
|
||||
|
||||
class IntegrateFtrackFarmStatus(pyblish.api.ContextPlugin):
|
||||
"""Change task status when should be published on farm.
|
||||
|
||||
Instance which has set "farm" key in data to 'True' is considered as will
|
||||
be rendered on farm thus it's status should be changed.
|
||||
"""
|
||||
|
||||
order = pyblish.api.IntegratorOrder + 0.48
|
||||
label = "Integrate Ftrack Farm Status"
|
||||
|
||||
farm_status_profiles = []
|
||||
|
||||
def process(self, context):
|
||||
# Quick end
|
||||
if not self.farm_status_profiles:
|
||||
project_name = context.data["projectName"]
|
||||
self.log.info((
|
||||
"Status profiles are not filled for project \"{}\". Skipping"
|
||||
).format(project_name))
|
||||
return
|
||||
|
||||
filtered_instances = self.filter_instances(context)
|
||||
instances_with_status_names = self.get_instances_with_statuse_names(
|
||||
context, filtered_instances
|
||||
)
|
||||
if instances_with_status_names:
|
||||
self.fill_statuses(context, instances_with_status_names)
|
||||
|
||||
def filter_instances(self, context):
|
||||
filtered_instances = []
|
||||
for instance in context:
|
||||
# Skip disabled instances
|
||||
if instance.data.get("publish") is False:
|
||||
continue
|
||||
subset_name = instance.data["subset"]
|
||||
msg_start = "Skipping instance {}.".format(subset_name)
|
||||
if not instance.data.get("farm"):
|
||||
self.log.debug(
|
||||
"{} Won't be rendered on farm.".format(msg_start)
|
||||
)
|
||||
continue
|
||||
|
||||
task_entity = instance.data.get("ftrackTask")
|
||||
if not task_entity:
|
||||
self.log.debug(
|
||||
"{} Does not have filled task".format(msg_start)
|
||||
)
|
||||
continue
|
||||
|
||||
filtered_instances.append(instance)
|
||||
return filtered_instances
|
||||
|
||||
def get_instances_with_statuse_names(self, context, instances):
|
||||
instances_with_status_names = []
|
||||
for instance in instances:
|
||||
family = instance.data["family"]
|
||||
subset_name = instance.data["subset"]
|
||||
task_entity = instance.data["ftrackTask"]
|
||||
host_name = context.data["hostName"]
|
||||
task_name = task_entity["name"]
|
||||
task_type = task_entity["type"]["name"]
|
||||
status_profile = filter_profiles(
|
||||
self.farm_status_profiles,
|
||||
{
|
||||
"hosts": host_name,
|
||||
"task_types": task_type,
|
||||
"task_names": task_name,
|
||||
"families": family,
|
||||
"subsets": subset_name,
|
||||
},
|
||||
logger=self.log
|
||||
)
|
||||
if not status_profile:
|
||||
# There already is log in 'filter_profiles'
|
||||
continue
|
||||
|
||||
status_name = status_profile["status_name"]
|
||||
if status_name:
|
||||
instances_with_status_names.append((instance, status_name))
|
||||
return instances_with_status_names
|
||||
|
||||
def fill_statuses(self, context, instances_with_status_names):
|
||||
# Prepare available task statuses on the project
|
||||
project_name = context.data["projectName"]
|
||||
session = context.data["ftrackSession"]
|
||||
project_entity = session.query((
|
||||
"select project_schema from Project where full_name is \"{}\""
|
||||
).format(project_name)).one()
|
||||
project_schema = project_entity["project_schema"]
|
||||
|
||||
task_type_ids = set()
|
||||
for item in instances_with_status_names:
|
||||
instance, _ = item
|
||||
task_entity = instance.data["ftrackTask"]
|
||||
task_type_ids.add(task_entity["type"]["id"])
|
||||
|
||||
task_statuses_by_type_id = {
|
||||
task_type_id: project_schema.get_statuses("Task", task_type_id)
|
||||
for task_type_id in task_type_ids
|
||||
}
|
||||
|
||||
# Keep track if anything has changed
|
||||
skipped_status_names = set()
|
||||
status_changed = False
|
||||
for item in instances_with_status_names:
|
||||
instance, status_name = item
|
||||
task_entity = instance.data["ftrackTask"]
|
||||
task_statuses = task_statuses_by_type_id[task_entity["type"]["id"]]
|
||||
status_name_low = status_name.lower()
|
||||
|
||||
status_id = None
|
||||
status_name = None
|
||||
# Skip if status name was already tried to be found
|
||||
for status in task_statuses:
|
||||
if status["name"].lower() == status_name_low:
|
||||
status_id = status["id"]
|
||||
status_name = status["name"]
|
||||
break
|
||||
|
||||
if status_id is None:
|
||||
if status_name_low not in skipped_status_names:
|
||||
skipped_status_names.add(status_name_low)
|
||||
joined_status_names = ", ".join({
|
||||
'"{}"'.format(status["name"])
|
||||
for status in task_statuses
|
||||
})
|
||||
self.log.warning((
|
||||
"Status \"{}\" is not available on project \"{}\"."
|
||||
" Available statuses are {}"
|
||||
).format(status_name, project_name, joined_status_names))
|
||||
continue
|
||||
|
||||
# Change task status id
|
||||
if status_id != task_entity["status_id"]:
|
||||
task_entity["status_id"] = status_id
|
||||
status_changed = True
|
||||
path = "/".join([
|
||||
item["name"]
|
||||
for item in task_entity["link"]
|
||||
])
|
||||
self.log.debug("Set status \"{}\" to \"{}\"".format(
|
||||
status_name, path
|
||||
))
|
||||
|
||||
if status_changed:
|
||||
session.commit()
|
||||
|
|
@ -0,0 +1,433 @@
|
|||
import copy
|
||||
|
||||
import pyblish.api
|
||||
from openpype.lib import filter_profiles
|
||||
|
||||
|
||||
def create_chunks(iterable, chunk_size=None):
|
||||
"""Separate iterable into multiple chunks by size.
|
||||
|
||||
Args:
|
||||
iterable(list|tuple|set): Object that will be separated into chunks.
|
||||
chunk_size(int): Size of one chunk. Default value is 200.
|
||||
|
||||
Returns:
|
||||
list<list>: Chunked items.
|
||||
"""
|
||||
chunks = []
|
||||
|
||||
tupled_iterable = tuple(iterable)
|
||||
if not tupled_iterable:
|
||||
return chunks
|
||||
iterable_size = len(tupled_iterable)
|
||||
if chunk_size is None:
|
||||
chunk_size = 200
|
||||
|
||||
if chunk_size < 1:
|
||||
chunk_size = 1
|
||||
|
||||
for idx in range(0, iterable_size, chunk_size):
|
||||
chunks.append(tupled_iterable[idx:idx + chunk_size])
|
||||
return chunks
|
||||
|
||||
|
||||
class CollectFtrackTaskStatuses(pyblish.api.ContextPlugin):
|
||||
"""Collect available task statuses on the project.
|
||||
|
||||
This is preparation for integration of task statuses.
|
||||
|
||||
Requirements:
|
||||
ftrackSession (ftrack_api.Session): Prepared ftrack session.
|
||||
|
||||
Provides:
|
||||
ftrackTaskStatuses (dict[str, list[Any]]): Dictionary of available
|
||||
task statuses on project by task type id.
|
||||
ftrackStatusByTaskId (dict[str, str]): Empty dictionary of task
|
||||
statuses by task id. Status on task can be set only once.
|
||||
Value should be a name of status.
|
||||
"""
|
||||
|
||||
# After 'CollectFtrackApi'
|
||||
order = pyblish.api.CollectorOrder + 0.4992
|
||||
label = "Collect Ftrack Task Statuses"
|
||||
settings_category = "ftrack"
|
||||
|
||||
def process(self, context):
|
||||
ftrack_session = context.data("ftrackSession")
|
||||
if ftrack_session is None:
|
||||
self.log.info("Ftrack session is not created.")
|
||||
return
|
||||
|
||||
# Prepare available task statuses on the project
|
||||
project_name = context.data["projectName"]
|
||||
project_entity = ftrack_session.query((
|
||||
"select project_schema from Project where full_name is \"{}\""
|
||||
).format(project_name)).one()
|
||||
project_schema = project_entity["project_schema"]
|
||||
|
||||
task_type_ids = {
|
||||
task_type["id"]
|
||||
for task_type in ftrack_session.query("select id from Type").all()
|
||||
}
|
||||
task_statuses_by_type_id = {
|
||||
task_type_id: project_schema.get_statuses("Task", task_type_id)
|
||||
for task_type_id in task_type_ids
|
||||
}
|
||||
context.data["ftrackTaskStatuses"] = task_statuses_by_type_id
|
||||
context.data["ftrackStatusByTaskId"] = {}
|
||||
self.log.info("Collected ftrack task statuses.")
|
||||
|
||||
|
||||
class IntegrateFtrackStatusBase(pyblish.api.InstancePlugin):
|
||||
"""Base plugin for status collection.
|
||||
|
||||
Requirements:
|
||||
projectName (str): Name of the project.
|
||||
hostName (str): Name of the host.
|
||||
ftrackSession (ftrack_api.Session): Prepared ftrack session.
|
||||
ftrackTaskStatuses (dict[str, list[Any]]): Dictionary of available
|
||||
task statuses on project by task type id.
|
||||
ftrackStatusByTaskId (dict[str, str]): Empty dictionary of task
|
||||
statuses by task id. Status on task can be set only once.
|
||||
Value should be a name of status.
|
||||
"""
|
||||
|
||||
active = False
|
||||
settings_key = None
|
||||
status_profiles = []
|
||||
|
||||
@classmethod
|
||||
def apply_settings(cls, project_settings):
|
||||
settings_key = cls.settings_key
|
||||
if settings_key is None:
|
||||
settings_key = cls.__name__
|
||||
|
||||
try:
|
||||
settings = project_settings["ftrack"]["publish"][settings_key]
|
||||
except KeyError:
|
||||
return
|
||||
|
||||
for key, value in settings.items():
|
||||
setattr(cls, key, value)
|
||||
|
||||
def process(self, instance):
|
||||
context = instance.context
|
||||
# No profiles -> skip
|
||||
profiles = self.get_status_profiles()
|
||||
if not profiles:
|
||||
project_name = context.data["projectName"]
|
||||
self.log.info((
|
||||
"Status profiles are not filled for project \"{}\". Skipping"
|
||||
).format(project_name))
|
||||
return
|
||||
|
||||
# Task statuses were not collected -> skip
|
||||
task_statuses_by_type_id = context.data.get("ftrackTaskStatuses")
|
||||
if not task_statuses_by_type_id:
|
||||
self.log.info(
|
||||
"Ftrack task statuses are not collected. Skipping.")
|
||||
return
|
||||
|
||||
self.prepare_status_names(context, instance, profiles)
|
||||
|
||||
def get_status_profiles(self):
|
||||
"""List of profiles to determine status name.
|
||||
|
||||
Example profile item:
|
||||
{
|
||||
"host_names": ["nuke"],
|
||||
"task_types": ["Compositing"],
|
||||
"task_names": ["Comp"],
|
||||
"families": ["render"],
|
||||
"subset_names": ["renderComp"],
|
||||
"status_name": "Rendering",
|
||||
}
|
||||
|
||||
Returns:
|
||||
list[dict[str, Any]]: List of profiles.
|
||||
"""
|
||||
|
||||
return self.status_profiles
|
||||
|
||||
def prepare_status_names(self, context, instance, profiles):
|
||||
if not self.is_valid_instance(context, instance):
|
||||
return
|
||||
|
||||
filter_data = self.get_profile_filter_data(context, instance)
|
||||
status_profile = filter_profiles(
|
||||
profiles,
|
||||
filter_data,
|
||||
logger=self.log
|
||||
)
|
||||
if not status_profile:
|
||||
return
|
||||
|
||||
status_name = status_profile["status_name"]
|
||||
if status_name:
|
||||
self.fill_status(context, instance, status_name)
|
||||
|
||||
def get_profile_filter_data(self, context, instance):
|
||||
task_entity = instance.data["ftrackTask"]
|
||||
return {
|
||||
"host_names": context.data["hostName"],
|
||||
"task_types": task_entity["type"]["name"],
|
||||
"task_names": task_entity["name"],
|
||||
"families": instance.data["family"],
|
||||
"subset_names": instance.data["subset"],
|
||||
}
|
||||
|
||||
def is_valid_instance(self, context, instance):
|
||||
"""Filter instances that should be processed.
|
||||
|
||||
Ignore instances that are not enabled for publishing or don't have
|
||||
filled task. Also skip instances with tasks that already have defined
|
||||
status.
|
||||
|
||||
Plugin should do more filtering which is custom for plugin logic.
|
||||
|
||||
Args:
|
||||
context (pyblish.api.Context): Pyblish context.
|
||||
instance (pyblish.api.Instance): Instance to process.
|
||||
|
||||
Returns:
|
||||
list[pyblish.api.Instance]: List of instances that should be
|
||||
processed.
|
||||
"""
|
||||
|
||||
ftrack_status_by_task_id = context.data["ftrackStatusByTaskId"]
|
||||
# Skip disabled instances
|
||||
if instance.data.get("publish") is False:
|
||||
return False
|
||||
|
||||
task_entity = instance.data.get("ftrackTask")
|
||||
if not task_entity:
|
||||
self.log.debug(
|
||||
"Skipping instance Does not have filled task".format(
|
||||
instance.data["subset"]))
|
||||
return False
|
||||
|
||||
task_id = task_entity["id"]
|
||||
if task_id in ftrack_status_by_task_id:
|
||||
self.log.debug("Status for task {} was already defined".format(
|
||||
task_entity["name"]
|
||||
))
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def fill_status(self, context, instance, status_name):
|
||||
"""Fill status for instance task.
|
||||
|
||||
If task already had set status, it will be skipped.
|
||||
|
||||
Args:
|
||||
context (pyblish.api.Context): Pyblish context.
|
||||
instance (pyblish.api.Instance): Pyblish instance.
|
||||
status_name (str): Name of status to set.
|
||||
"""
|
||||
|
||||
task_entity = instance.data["ftrackTask"]
|
||||
task_id = task_entity["id"]
|
||||
ftrack_status_by_task_id = context.data["ftrackStatusByTaskId"]
|
||||
if task_id in ftrack_status_by_task_id:
|
||||
self.log.debug("Status for task {} was already defined".format(
|
||||
task_entity["name"]
|
||||
))
|
||||
return
|
||||
|
||||
ftrack_status_by_task_id[task_id] = status_name
|
||||
self.log.info((
|
||||
"Task {} will be set to \"{}\" status."
|
||||
).format(task_entity["name"], status_name))
|
||||
|
||||
|
||||
class IntegrateFtrackFarmStatus(IntegrateFtrackStatusBase):
|
||||
"""Collect task status names for instances that are sent to farm.
|
||||
|
||||
Instance which has set "farm" key in data to 'True' is considered as will
|
||||
be rendered on farm thus it's status should be changed.
|
||||
|
||||
Requirements:
|
||||
projectName (str): Name of the project.
|
||||
hostName (str): Name of the host.
|
||||
ftrackSession (ftrack_api.Session): Prepared ftrack session.
|
||||
ftrackTaskStatuses (dict[str, list[Any]]): Dictionary of available
|
||||
task statuses on project by task type id.
|
||||
ftrackStatusByTaskId (dict[str, str]): Empty dictionary of task
|
||||
statuses by task id. Status on task can be set only once.
|
||||
Value should be a name of status.
|
||||
"""
|
||||
|
||||
order = pyblish.api.IntegratorOrder + 0.48
|
||||
label = "Ftrack Task Status To Farm Status"
|
||||
active = True
|
||||
|
||||
farm_status_profiles = []
|
||||
status_profiles = None
|
||||
|
||||
def is_valid_instance(self, context, instance):
|
||||
if not instance.data.get("farm"):
|
||||
self.log.debug("{} Won't be rendered on farm.".format(
|
||||
instance.data["subset"]
|
||||
))
|
||||
return False
|
||||
return super(IntegrateFtrackFarmStatus, self).is_valid_instance(
|
||||
context, instance)
|
||||
|
||||
def get_status_profiles(self):
|
||||
if self.status_profiles is None:
|
||||
profiles = copy.deepcopy(self.farm_status_profiles)
|
||||
for profile in profiles:
|
||||
profile["host_names"] = profile.pop("hosts")
|
||||
profile["subset_names"] = profile.pop("subsets")
|
||||
self.status_profiles = profiles
|
||||
return self.status_profiles
|
||||
|
||||
|
||||
class IntegrateFtrackLocalStatus(IntegrateFtrackStatusBase):
|
||||
"""Collect task status names for instances that are published locally.
|
||||
|
||||
Instance which has set "farm" key in data to 'True' is considered as will
|
||||
be rendered on farm thus it's status should be changed.
|
||||
|
||||
Requirements:
|
||||
projectName (str): Name of the project.
|
||||
hostName (str): Name of the host.
|
||||
ftrackSession (ftrack_api.Session): Prepared ftrack session.
|
||||
ftrackTaskStatuses (dict[str, list[Any]]): Dictionary of available
|
||||
task statuses on project by task type id.
|
||||
ftrackStatusByTaskId (dict[str, str]): Empty dictionary of task
|
||||
statuses by task id. Status on task can be set only once.
|
||||
Value should be a name of status.
|
||||
"""
|
||||
|
||||
order = IntegrateFtrackFarmStatus.order + 0.001
|
||||
label = "Ftrack Task Status Local Publish"
|
||||
active = True
|
||||
targets = ["local"]
|
||||
settings_key = "ftrack_task_status_local_publish"
|
||||
|
||||
def is_valid_instance(self, context, instance):
|
||||
if instance.data.get("farm"):
|
||||
self.log.debug("{} Will be rendered on farm.".format(
|
||||
instance.data["subset"]
|
||||
))
|
||||
return False
|
||||
return super(IntegrateFtrackLocalStatus, self).is_valid_instance(
|
||||
context, instance)
|
||||
|
||||
|
||||
class IntegrateFtrackOnFarmStatus(IntegrateFtrackStatusBase):
|
||||
"""Collect task status names for instances that are published on farm.
|
||||
|
||||
Requirements:
|
||||
projectName (str): Name of the project.
|
||||
hostName (str): Name of the host.
|
||||
ftrackSession (ftrack_api.Session): Prepared ftrack session.
|
||||
ftrackTaskStatuses (dict[str, list[Any]]): Dictionary of available
|
||||
task statuses on project by task type id.
|
||||
ftrackStatusByTaskId (dict[str, str]): Empty dictionary of task
|
||||
statuses by task id. Status on task can be set only once.
|
||||
Value should be a name of status.
|
||||
"""
|
||||
|
||||
order = IntegrateFtrackLocalStatus.order + 0.001
|
||||
label = "Ftrack Task Status On Farm Status"
|
||||
active = True
|
||||
targets = ["farm"]
|
||||
settings_key = "ftrack_task_status_on_farm_publish"
|
||||
|
||||
|
||||
class IntegrateFtrackTaskStatus(pyblish.api.ContextPlugin):
|
||||
# Use order of Integrate Ftrack Api plugin and offset it before or after
|
||||
base_order = pyblish.api.IntegratorOrder + 0.499
|
||||
# By default is after Integrate Ftrack Api
|
||||
order = base_order + 0.0001
|
||||
label = "Integrate Ftrack Task Status"
|
||||
|
||||
@classmethod
|
||||
def apply_settings(cls, project_settings):
|
||||
"""Apply project settings to plugin.
|
||||
|
||||
Args:
|
||||
project_settings (dict[str, Any]): Project settings.
|
||||
"""
|
||||
|
||||
settings = (
|
||||
project_settings["ftrack"]["publish"]["IntegrateFtrackTaskStatus"]
|
||||
)
|
||||
diff = 0.001
|
||||
if not settings["after_version_statuses"]:
|
||||
diff = -diff
|
||||
cls.order = cls.base_order + diff
|
||||
|
||||
def process(self, context):
|
||||
task_statuses_by_type_id = context.data.get("ftrackTaskStatuses")
|
||||
if not task_statuses_by_type_id:
|
||||
self.log.info("Ftrack task statuses are not collected. Skipping.")
|
||||
return
|
||||
|
||||
status_by_task_id = self._get_status_by_task_id(context)
|
||||
if not status_by_task_id:
|
||||
self.log.info("No statuses to set. Skipping.")
|
||||
return
|
||||
|
||||
ftrack_session = context.data["ftrackSession"]
|
||||
|
||||
task_entities = self._get_task_entities(
|
||||
ftrack_session, status_by_task_id)
|
||||
|
||||
for task_entity in task_entities:
|
||||
task_path = "/".join([
|
||||
item["name"] for item in task_entity["link"]
|
||||
])
|
||||
task_id = task_entity["id"]
|
||||
type_id = task_entity["type_id"]
|
||||
new_status = None
|
||||
status_name = status_by_task_id[task_id]
|
||||
self.log.debug(
|
||||
"Status to set {} on task {}.".format(status_name, task_path))
|
||||
status_name_low = status_name.lower()
|
||||
available_statuses = task_statuses_by_type_id[type_id]
|
||||
for status in available_statuses:
|
||||
if status["name"].lower() == status_name_low:
|
||||
new_status = status
|
||||
break
|
||||
|
||||
if new_status is None:
|
||||
joined_statuses = ", ".join([
|
||||
"'{}'".format(status["name"])
|
||||
for status in available_statuses
|
||||
])
|
||||
self.log.debug((
|
||||
"Status '{}' was not found in available statuses: {}."
|
||||
).format(status_name, joined_statuses))
|
||||
continue
|
||||
|
||||
if task_entity["status_id"] != new_status["id"]:
|
||||
task_entity["status_id"] = new_status["id"]
|
||||
|
||||
self.log.debug("Changing status of task '{}' to '{}'".format(
|
||||
task_path, status_name
|
||||
))
|
||||
ftrack_session.commit()
|
||||
|
||||
def _get_status_by_task_id(self, context):
|
||||
status_by_task_id = context.data["ftrackStatusByTaskId"]
|
||||
return {
|
||||
task_id: status_name
|
||||
for task_id, status_name in status_by_task_id.items()
|
||||
if status_name
|
||||
}
|
||||
|
||||
def _get_task_entities(self, ftrack_session, status_by_task_id):
|
||||
task_entities = []
|
||||
for chunk_ids in create_chunks(status_by_task_id.keys()):
|
||||
joined_ids = ",".join(
|
||||
['"{}"'.format(task_id) for task_id in chunk_ids]
|
||||
)
|
||||
task_entities.extend(ftrack_session.query((
|
||||
"select id, type_id, status_id, link from Task"
|
||||
" where id in ({})"
|
||||
).format(joined_ids)).all())
|
||||
return task_entities
|
||||
|
|
@ -63,7 +63,7 @@ class IntegrateHierarchyToFtrack(pyblish.api.ContextPlugin):
|
|||
"""
|
||||
|
||||
order = pyblish.api.IntegratorOrder - 0.04
|
||||
label = 'Integrate Hierarchy To Ftrack'
|
||||
label = "Integrate Hierarchy To Ftrack"
|
||||
families = ["shot"]
|
||||
hosts = [
|
||||
"hiero",
|
||||
|
|
@ -94,14 +94,13 @@ class IntegrateHierarchyToFtrack(pyblish.api.ContextPlugin):
|
|||
"Project \"{}\" was not found on ftrack.".format(project_name)
|
||||
)
|
||||
|
||||
self.context = context
|
||||
self.session = session
|
||||
self.ft_project = project
|
||||
self.task_types = self.get_all_task_types(project)
|
||||
self.task_statuses = self.get_task_statuses(project)
|
||||
|
||||
# import ftrack hierarchy
|
||||
self.import_to_ftrack(project_name, hierarchy_context)
|
||||
self.import_to_ftrack(context, project_name, hierarchy_context)
|
||||
|
||||
def query_ftrack_entitites(self, session, ft_project):
|
||||
project_id = ft_project["id"]
|
||||
|
|
@ -227,7 +226,7 @@ class IntegrateHierarchyToFtrack(pyblish.api.ContextPlugin):
|
|||
|
||||
return output
|
||||
|
||||
def import_to_ftrack(self, project_name, hierarchy_context):
|
||||
def import_to_ftrack(self, context, project_name, hierarchy_context):
|
||||
# Prequery hiearchical custom attributes
|
||||
hier_attrs = get_pype_attr(self.session)[1]
|
||||
hier_attr_by_key = {
|
||||
|
|
@ -258,7 +257,7 @@ class IntegrateHierarchyToFtrack(pyblish.api.ContextPlugin):
|
|||
self.session, matching_entities, hier_attrs)
|
||||
|
||||
# Get ftrack api module (as they are different per python version)
|
||||
ftrack_api = self.context.data["ftrackPythonModule"]
|
||||
ftrack_api = context.data["ftrackPythonModule"]
|
||||
|
||||
# Use queue of hierarchy items to process
|
||||
import_queue = collections.deque()
|
||||
|
|
@ -292,7 +291,7 @@ class IntegrateHierarchyToFtrack(pyblish.api.ContextPlugin):
|
|||
# CUSTOM ATTRIBUTES
|
||||
custom_attributes = entity_data.get('custom_attributes', {})
|
||||
instances = []
|
||||
for instance in self.context:
|
||||
for instance in context:
|
||||
instance_asset_name = instance.data.get("asset")
|
||||
if (
|
||||
instance_asset_name
|
||||
|
|
@ -369,6 +368,7 @@ class IntegrateHierarchyToFtrack(pyblish.api.ContextPlugin):
|
|||
if task_name:
|
||||
instances_by_task_name[task_name.lower()].append(instance)
|
||||
|
||||
ftrack_status_by_task_id = context.data["ftrackStatusByTaskId"]
|
||||
tasks = entity_data.get('tasks', [])
|
||||
existing_tasks = []
|
||||
tasks_to_create = []
|
||||
|
|
@ -389,11 +389,11 @@ class IntegrateHierarchyToFtrack(pyblish.api.ContextPlugin):
|
|||
|
||||
for task_name, task_type in tasks_to_create:
|
||||
task_entity = self.create_task(
|
||||
name=task_name,
|
||||
task_type=task_type,
|
||||
parent=entity
|
||||
task_name,
|
||||
task_type,
|
||||
entity,
|
||||
ftrack_status_by_task_id
|
||||
)
|
||||
|
||||
for instance in instances_by_task_name[task_name.lower()]:
|
||||
instance.data["ftrackTask"] = task_entity
|
||||
|
||||
|
|
@ -481,7 +481,7 @@ class IntegrateHierarchyToFtrack(pyblish.api.ContextPlugin):
|
|||
for status in task_workflow_statuses
|
||||
}
|
||||
|
||||
def create_task(self, name, task_type, parent):
|
||||
def create_task(self, name, task_type, parent, ftrack_status_by_task_id):
|
||||
filter_data = {
|
||||
"task_names": name,
|
||||
"task_types": task_type
|
||||
|
|
@ -491,12 +491,14 @@ class IntegrateHierarchyToFtrack(pyblish.api.ContextPlugin):
|
|||
filter_data
|
||||
)
|
||||
status_id = None
|
||||
status_name = None
|
||||
if profile:
|
||||
status_name = profile["status_name"]
|
||||
status_name_low = status_name.lower()
|
||||
for _status_id, status in self.task_statuses.items():
|
||||
if status["name"].lower() == status_name_low:
|
||||
status_id = _status_id
|
||||
status_name = status["name"]
|
||||
break
|
||||
|
||||
if status_id is None:
|
||||
|
|
@ -523,6 +525,8 @@ class IntegrateHierarchyToFtrack(pyblish.api.ContextPlugin):
|
|||
self.session._configure_locations()
|
||||
six.reraise(tp, value, tb)
|
||||
|
||||
if status_id is not None:
|
||||
ftrack_status_by_task_id[task["id"]] = None
|
||||
return task
|
||||
|
||||
def _get_active_assets(self, context):
|
||||
|
|
|
|||
|
|
@ -18,6 +18,10 @@ from openpype.pipeline import Anatomy
|
|||
log = Logger.get_logger(__name__)
|
||||
|
||||
|
||||
class CashedData:
|
||||
remapping = None
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def _make_temp_json_file():
|
||||
"""Wrapping function for json temp file
|
||||
|
|
@ -92,6 +96,11 @@ def get_imageio_colorspace_from_filepath(
|
|||
)
|
||||
config_data = get_imageio_config(
|
||||
project_name, host_name, project_settings)
|
||||
|
||||
# in case host color management is not enabled
|
||||
if not config_data:
|
||||
return None
|
||||
|
||||
file_rules = get_imageio_file_rules(
|
||||
project_name, host_name, project_settings)
|
||||
|
||||
|
|
@ -303,7 +312,8 @@ def get_views_data_subprocess(config_path):
|
|||
|
||||
|
||||
def get_imageio_config(
|
||||
project_name, host_name,
|
||||
project_name,
|
||||
host_name,
|
||||
project_settings=None,
|
||||
anatomy_data=None,
|
||||
anatomy=None
|
||||
|
|
@ -316,15 +326,12 @@ def get_imageio_config(
|
|||
Args:
|
||||
project_name (str): project name
|
||||
host_name (str): host name
|
||||
project_settings (dict, optional): project settings.
|
||||
Defaults to None.
|
||||
anatomy_data (dict, optional): anatomy formatting data.
|
||||
Defaults to None.
|
||||
anatomy (lib.Anatomy, optional): Anatomy object.
|
||||
Defaults to None.
|
||||
project_settings (Optional[dict]): Project settings.
|
||||
anatomy_data (Optional[dict]): anatomy formatting data.
|
||||
anatomy (Optional[Anatomy]): Anatomy object.
|
||||
|
||||
Returns:
|
||||
dict or bool: config path data or None
|
||||
dict: config path data or empty dict
|
||||
"""
|
||||
project_settings = project_settings or get_project_settings(project_name)
|
||||
anatomy = anatomy or Anatomy(project_name)
|
||||
|
|
@ -335,25 +342,65 @@ def get_imageio_config(
|
|||
anatomy_data = get_template_data_from_session()
|
||||
|
||||
formatting_data = deepcopy(anatomy_data)
|
||||
# add project roots to anatomy data
|
||||
|
||||
# Add project roots to anatomy data
|
||||
formatting_data["root"] = anatomy.roots
|
||||
formatting_data["platform"] = platform.system().lower()
|
||||
|
||||
# get colorspace settings
|
||||
# Get colorspace settings
|
||||
imageio_global, imageio_host = _get_imageio_settings(
|
||||
project_settings, host_name)
|
||||
|
||||
config_host = imageio_host.get("ocio_config", {})
|
||||
# Host 'ocio_config' is optional
|
||||
host_ocio_config = imageio_host.get("ocio_config") or {}
|
||||
|
||||
if config_host.get("enabled"):
|
||||
# Global color management must be enabled to be able to use host settings
|
||||
activate_color_management = imageio_global.get(
|
||||
"activate_global_color_management")
|
||||
# TODO: remove this in future - backward compatibility
|
||||
# For already saved overrides from previous version look for 'enabled'
|
||||
# on host settings.
|
||||
if activate_color_management is None:
|
||||
activate_color_management = host_ocio_config.get("enabled", False)
|
||||
|
||||
if not activate_color_management:
|
||||
# if global settings are disabled return empty dict because
|
||||
# it is expected that no colorspace management is needed
|
||||
log.info("Colorspace management is disabled globally.")
|
||||
return {}
|
||||
|
||||
# Check if host settings group is having 'activate_host_color_management'
|
||||
# - if it does not have activation key then default it to True so it uses
|
||||
# global settings
|
||||
# This is for backward compatibility.
|
||||
# TODO: in future rewrite this to be more explicit
|
||||
activate_host_color_management = imageio_host.get(
|
||||
"activate_host_color_management", True)
|
||||
|
||||
if not activate_host_color_management:
|
||||
# if host settings are disabled return False because
|
||||
# it is expected that no colorspace management is needed
|
||||
log.info(
|
||||
"Colorspace management for host '{}' is disabled.".format(
|
||||
host_name)
|
||||
)
|
||||
return {}
|
||||
|
||||
# get config path from either global or host settings
|
||||
# depending on override flag
|
||||
# TODO: in future rewrite this to be more explicit
|
||||
override_global_config = host_ocio_config.get("override_global_config")
|
||||
if override_global_config is None:
|
||||
# for already saved overrides from previous version
|
||||
# TODO: remove this in future - backward compatibility
|
||||
override_global_config = host_ocio_config.get("enabled")
|
||||
|
||||
if override_global_config:
|
||||
config_data = _get_config_data(
|
||||
config_host["filepath"], formatting_data
|
||||
host_ocio_config["filepath"], formatting_data
|
||||
)
|
||||
else:
|
||||
config_data = None
|
||||
|
||||
if not config_data:
|
||||
# get config path from either global or host_name
|
||||
# get config path from global
|
||||
config_global = imageio_global["ocio_config"]
|
||||
config_data = _get_config_data(
|
||||
config_global["filepath"], formatting_data
|
||||
|
|
@ -437,17 +484,82 @@ def get_imageio_file_rules(project_name, host_name, project_settings=None):
|
|||
|
||||
# get file rules from global and host_name
|
||||
frules_global = imageio_global["file_rules"]
|
||||
activate_global_rules = (
|
||||
frules_global.get("activate_global_file_rules", False)
|
||||
# TODO: remove this in future - backward compatibility
|
||||
or frules_global.get("enabled")
|
||||
)
|
||||
global_rules = frules_global["rules"]
|
||||
|
||||
if not activate_global_rules:
|
||||
log.info(
|
||||
"Colorspace global file rules are disabled."
|
||||
)
|
||||
global_rules = {}
|
||||
|
||||
# host is optional, some might not have any settings
|
||||
frules_host = imageio_host.get("file_rules", {})
|
||||
|
||||
# compile file rules dictionary
|
||||
file_rules = {}
|
||||
if frules_global["enabled"]:
|
||||
file_rules.update(frules_global["rules"])
|
||||
if frules_host and frules_host["enabled"]:
|
||||
file_rules.update(frules_host["rules"])
|
||||
activate_host_rules = frules_host.get("activate_host_rules")
|
||||
if activate_host_rules is None:
|
||||
# TODO: remove this in future - backward compatibility
|
||||
activate_host_rules = frules_host.get("enabled", False)
|
||||
|
||||
return file_rules
|
||||
# return host rules if activated or global rules
|
||||
return frules_host["rules"] if activate_host_rules else global_rules
|
||||
|
||||
|
||||
def get_remapped_colorspace_to_native(
|
||||
ocio_colorspace_name, host_name, imageio_host_settings
|
||||
):
|
||||
"""Return native colorspace name.
|
||||
|
||||
Args:
|
||||
ocio_colorspace_name (str | None): ocio colorspace name
|
||||
host_name (str): Host name.
|
||||
imageio_host_settings (dict[str, Any]): ImageIO host settings.
|
||||
|
||||
Returns:
|
||||
Union[str, None]: native colorspace name defined in remapping or None
|
||||
"""
|
||||
|
||||
CashedData.remapping.setdefault(host_name, {})
|
||||
if CashedData.remapping[host_name].get("to_native") is None:
|
||||
remapping_rules = imageio_host_settings["remapping"]["rules"]
|
||||
CashedData.remapping[host_name]["to_native"] = {
|
||||
rule["ocio_name"]: rule["host_native_name"]
|
||||
for rule in remapping_rules
|
||||
}
|
||||
|
||||
return CashedData.remapping[host_name]["to_native"].get(
|
||||
ocio_colorspace_name)
|
||||
|
||||
|
||||
def get_remapped_colorspace_from_native(
|
||||
host_native_colorspace_name, host_name, imageio_host_settings
|
||||
):
|
||||
"""Return ocio colorspace name remapped from host native used name.
|
||||
|
||||
Args:
|
||||
host_native_colorspace_name (str): host native colorspace name
|
||||
host_name (str): Host name.
|
||||
imageio_host_settings (dict[str, Any]): ImageIO host settings.
|
||||
|
||||
Returns:
|
||||
Union[str, None]: Ocio colorspace name defined in remapping or None.
|
||||
"""
|
||||
|
||||
CashedData.remapping.setdefault(host_name, {})
|
||||
if CashedData.remapping[host_name].get("from_native") is None:
|
||||
remapping_rules = imageio_host_settings["remapping"]["rules"]
|
||||
CashedData.remapping[host_name]["from_native"] = {
|
||||
rule["host_native_name"]: rule["ocio_name"]
|
||||
for rule in remapping_rules
|
||||
}
|
||||
|
||||
return CashedData.remapping[host_name]["from_native"].get(
|
||||
host_native_colorspace_name)
|
||||
|
||||
|
||||
def _get_imageio_settings(project_settings, host_name):
|
||||
|
|
|
|||
|
|
@ -1441,6 +1441,19 @@ class CreateContext:
|
|||
"""Access to global publish attributes."""
|
||||
return self._publish_attributes
|
||||
|
||||
def get_instance_by_id(self, instance_id):
|
||||
"""Receive instance by id.
|
||||
|
||||
Args:
|
||||
instance_id (str): Instance id.
|
||||
|
||||
Returns:
|
||||
Union[CreatedInstance, None]: Instance or None if instance with
|
||||
given id is not available.
|
||||
"""
|
||||
|
||||
return self._instances_by_id.get(instance_id)
|
||||
|
||||
def get_sorted_creators(self, identifiers=None):
|
||||
"""Sorted creators by 'order' attribute.
|
||||
|
||||
|
|
|
|||
|
|
@ -331,6 +331,11 @@ class ColormanagedPyblishPluginMixin(object):
|
|||
project_settings=project_settings_,
|
||||
anatomy_data=anatomy_data
|
||||
)
|
||||
|
||||
# in case host color management is not enabled
|
||||
if not config_data:
|
||||
return None
|
||||
|
||||
file_rules = get_imageio_file_rules(
|
||||
project_name, host_name,
|
||||
project_settings=project_settings_
|
||||
|
|
@ -387,6 +392,11 @@ class ColormanagedPyblishPluginMixin(object):
|
|||
if colorspace_settings is None:
|
||||
colorspace_settings = self.get_colorspace_settings(context)
|
||||
|
||||
# in case host color management is not enabled
|
||||
if not colorspace_settings:
|
||||
self.log.warning("Host's colorspace management is disabled.")
|
||||
return
|
||||
|
||||
# unpack colorspace settings
|
||||
config_data, file_rules = colorspace_settings
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ class CollectFromCreateContext(pyblish.api.ContextPlugin):
|
|||
order = pyblish.api.CollectorOrder - 0.5
|
||||
|
||||
def process(self, context):
|
||||
create_context = context.data.pop("create_context", None)
|
||||
create_context = context.data.get("create_context")
|
||||
if not create_context:
|
||||
host = registered_host()
|
||||
if isinstance(host, IPublishHost):
|
||||
|
|
|
|||
|
|
@ -356,6 +356,13 @@ class PypeCommands:
|
|||
def pack_project(self, project_name, dirpath, database_only):
|
||||
from openpype.lib.project_backpack import pack_project
|
||||
|
||||
if database_only and not dirpath:
|
||||
raise ValueError((
|
||||
"Destination dir must be defined when using --dbonly."
|
||||
" Use '--dirpath {output dir path}' flag"
|
||||
" to specify directory."
|
||||
))
|
||||
|
||||
pack_project(project_name, dirpath, database_only)
|
||||
|
||||
def unpack_project(self, zip_filepath, new_root, database_only):
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
{
|
||||
"imageio": {
|
||||
"activate_host_color_management": true,
|
||||
"ocio_config": {
|
||||
"enabled": false,
|
||||
"override_global_config": false,
|
||||
"filepath": []
|
||||
},
|
||||
"file_rules": {
|
||||
"enabled": false,
|
||||
"activate_host_rules": false,
|
||||
"rules": {}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -5,12 +5,13 @@
|
|||
"base_file_unit_scale": 0.01
|
||||
},
|
||||
"imageio": {
|
||||
"activate_host_color_management": true,
|
||||
"ocio_config": {
|
||||
"enabled": false,
|
||||
"override_global_config": false,
|
||||
"filepath": []
|
||||
},
|
||||
"file_rules": {
|
||||
"enabled": false,
|
||||
"activate_host_rules": false,
|
||||
"rules": {}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
{
|
||||
"imageio": {
|
||||
"activate_host_color_management": true,
|
||||
"ocio_config": {
|
||||
"enabled": false,
|
||||
"override_global_config": false,
|
||||
"filepath": []
|
||||
},
|
||||
"file_rules": {
|
||||
"enabled": false,
|
||||
"activate_host_rules": false,
|
||||
"rules": {}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,11 +1,15 @@
|
|||
{
|
||||
"imageio": {
|
||||
"activate_host_color_management": true,
|
||||
"remapping": {
|
||||
"rules": []
|
||||
},
|
||||
"ocio_config": {
|
||||
"enabled": false,
|
||||
"override_global_config": false,
|
||||
"filepath": []
|
||||
},
|
||||
"file_rules": {
|
||||
"enabled": false,
|
||||
"activate_host_rules": false,
|
||||
"rules": {}
|
||||
},
|
||||
"project": {
|
||||
|
|
|
|||
|
|
@ -493,7 +493,29 @@
|
|||
"upload_reviewable_with_origin_name": false
|
||||
},
|
||||
"IntegrateFtrackFarmStatus": {
|
||||
"farm_status_profiles": []
|
||||
"farm_status_profiles": [
|
||||
{
|
||||
"hosts": [
|
||||
"celaction"
|
||||
],
|
||||
"task_types": [],
|
||||
"task_names": [],
|
||||
"families": [
|
||||
"render"
|
||||
],
|
||||
"subsets": [],
|
||||
"status_name": "Render"
|
||||
}
|
||||
]
|
||||
},
|
||||
"ftrack_task_status_local_publish": {
|
||||
"status_profiles": []
|
||||
},
|
||||
"ftrack_task_status_on_farm_publish": {
|
||||
"status_profiles": []
|
||||
},
|
||||
"IntegrateFtrackTaskStatus": {
|
||||
"after_version_statuses": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,13 @@
|
|||
{
|
||||
"imageio": {
|
||||
"activate_host_color_management": true,
|
||||
"ocio_config": {
|
||||
"enabled": false,
|
||||
"override_global_config": false,
|
||||
"filepath": []
|
||||
},
|
||||
"file_rules": {
|
||||
"enabled": false,
|
||||
"activate_host_rules": false,
|
||||
"rules": {}
|
||||
},
|
||||
"ocio": {
|
||||
"enabled": false,
|
||||
"configFilePath": {
|
||||
"windows": [],
|
||||
"darwin": [],
|
||||
"linux": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"copy_fusion_settings": {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"imageio": {
|
||||
"activate_global_color_management": false,
|
||||
"ocio_config": {
|
||||
"filepath": [
|
||||
"{OPENPYPE_ROOT}/vendor/bin/ocioconfig/OpenColorIOConfigs/aces_1.2/config.ocio",
|
||||
|
|
@ -7,7 +8,7 @@
|
|||
]
|
||||
},
|
||||
"file_rules": {
|
||||
"enabled": false,
|
||||
"activate_global_file_rules": false,
|
||||
"rules": {
|
||||
"example": {
|
||||
"pattern": ".*(beauty).*",
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
{
|
||||
"imageio": {
|
||||
"activate_host_color_management": true,
|
||||
"ocio_config": {
|
||||
"enabled": false,
|
||||
"override_global_config": false,
|
||||
"filepath": []
|
||||
},
|
||||
"file_rules": {
|
||||
"enabled": false,
|
||||
"activate_host_rules": false,
|
||||
"rules": {}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,20 +1,16 @@
|
|||
{
|
||||
"imageio": {
|
||||
"activate_host_color_management": true,
|
||||
"ocio_config": {
|
||||
"enabled": false,
|
||||
"override_global_config": false,
|
||||
"filepath": []
|
||||
},
|
||||
"file_rules": {
|
||||
"enabled": false,
|
||||
"activate_host_rules": false,
|
||||
"rules": {}
|
||||
},
|
||||
"workfile": {
|
||||
"ocioConfigName": "nuke-default",
|
||||
"ocioconfigpath": {
|
||||
"windows": [],
|
||||
"darwin": [],
|
||||
"linux": []
|
||||
},
|
||||
"workingSpace": "linear",
|
||||
"sixteenBitLut": "sRGB",
|
||||
"eightBitLut": "sRGB",
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
{
|
||||
"imageio": {
|
||||
"activate_host_color_management": true,
|
||||
"ocio_config": {
|
||||
"enabled": false,
|
||||
"override_global_config": false,
|
||||
"filepath": []
|
||||
},
|
||||
"file_rules": {
|
||||
"enabled": false,
|
||||
"activate_host_rules": false,
|
||||
"rules": {}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,12 +1,23 @@
|
|||
{
|
||||
"imageio": {
|
||||
"activate_host_color_management": true,
|
||||
"ocio_config": {
|
||||
"override_global_config": false,
|
||||
"filepath": []
|
||||
},
|
||||
"file_rules": {
|
||||
"activate_host_rules": false,
|
||||
"rules": {}
|
||||
}
|
||||
},
|
||||
"RenderSettings": {
|
||||
"default_render_image_folder": "renders/3dsmax",
|
||||
"aov_separator": "underscore",
|
||||
"image_format": "exr",
|
||||
"multipass": true
|
||||
},
|
||||
"PointCloud":{
|
||||
"attribute":{
|
||||
"PointCloud": {
|
||||
"attribute": {
|
||||
"Age": "age",
|
||||
"Radius": "radius",
|
||||
"Position": "position",
|
||||
|
|
|
|||
|
|
@ -410,31 +410,28 @@
|
|||
]
|
||||
},
|
||||
"imageio": {
|
||||
"activate_host_color_management": true,
|
||||
"ocio_config": {
|
||||
"enabled": false,
|
||||
"override_global_config": false,
|
||||
"filepath": []
|
||||
},
|
||||
"file_rules": {
|
||||
"enabled": false,
|
||||
"activate_host_rules": false,
|
||||
"rules": {}
|
||||
},
|
||||
"workfile": {
|
||||
"enabled": false,
|
||||
"renderSpace": "ACEScg",
|
||||
"displayName": "sRGB",
|
||||
"viewName": "ACES 1.0 SDR-video"
|
||||
},
|
||||
"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"
|
||||
}
|
||||
|
|
@ -456,6 +453,10 @@
|
|||
"destination-path": []
|
||||
}
|
||||
},
|
||||
"include_handles": {
|
||||
"include_handles_default": false,
|
||||
"per_task_type": []
|
||||
},
|
||||
"scriptsmenu": {
|
||||
"name": "OpenPype Tools",
|
||||
"definition": [
|
||||
|
|
@ -1556,10 +1557,6 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"include_handles": {
|
||||
"include_handles_default": false,
|
||||
"per_task_type": []
|
||||
},
|
||||
"templated_workfile_build": {
|
||||
"profiles": []
|
||||
},
|
||||
|
|
|
|||
|
|
@ -9,12 +9,13 @@
|
|||
}
|
||||
},
|
||||
"imageio": {
|
||||
"activate_host_color_management": true,
|
||||
"ocio_config": {
|
||||
"enabled": false,
|
||||
"override_global_config": false,
|
||||
"filepath": []
|
||||
},
|
||||
"file_rules": {
|
||||
"enabled": false,
|
||||
"activate_host_rules": false,
|
||||
"rules": {}
|
||||
},
|
||||
"viewer": {
|
||||
|
|
@ -26,11 +27,6 @@
|
|||
"workfile": {
|
||||
"colorManagement": "Nuke",
|
||||
"OCIO_config": "nuke-default",
|
||||
"customOCIOConfigPath": {
|
||||
"windows": [],
|
||||
"darwin": [],
|
||||
"linux": []
|
||||
},
|
||||
"workingSpaceLUT": "linear",
|
||||
"monitorLut": "sRGB",
|
||||
"int8Lut": "sRGB",
|
||||
|
|
@ -148,7 +144,7 @@
|
|||
},
|
||||
{
|
||||
"plugins": [
|
||||
"CreateWriteStill"
|
||||
"CreateWriteImage"
|
||||
],
|
||||
"nukeNodeClass": "Write",
|
||||
"knobs": [
|
||||
|
|
@ -563,15 +559,7 @@
|
|||
"load": {
|
||||
"LoadImage": {
|
||||
"enabled": true,
|
||||
"_representations": [
|
||||
"exr",
|
||||
"dpx",
|
||||
"jpg",
|
||||
"jpeg",
|
||||
"png",
|
||||
"psd",
|
||||
"tiff"
|
||||
],
|
||||
"_representations": [],
|
||||
"node_name_template": "{class_name}_{ext}"
|
||||
},
|
||||
"LoadClip": {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,15 @@
|
|||
{
|
||||
"imageio": {
|
||||
"activate_host_color_management": true,
|
||||
"remapping": {
|
||||
"rules": []
|
||||
},
|
||||
"ocio_config": {
|
||||
"enabled": false,
|
||||
"override_global_config": false,
|
||||
"filepath": []
|
||||
},
|
||||
"file_rules": {
|
||||
"enabled": false,
|
||||
"activate_host_rules": false,
|
||||
"rules": {}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,12 +1,16 @@
|
|||
{
|
||||
"launch_openpype_menu_on_start": false,
|
||||
"imageio": {
|
||||
"activate_host_color_management": true,
|
||||
"remapping": {
|
||||
"rules": []
|
||||
},
|
||||
"ocio_config": {
|
||||
"enabled": false,
|
||||
"override_global_config": false,
|
||||
"filepath": []
|
||||
},
|
||||
"file_rules": {
|
||||
"enabled": false,
|
||||
"activate_host_rules": false,
|
||||
"rules": {}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
{
|
||||
"imageio": {
|
||||
"activate_host_color_management": true,
|
||||
"ocio_config": {
|
||||
"enabled": true,
|
||||
"override_global_config": true,
|
||||
"filepath": []
|
||||
},
|
||||
"file_rules": {
|
||||
"enabled": true,
|
||||
"activate_host_rules": true,
|
||||
"rules": {}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
{
|
||||
"imageio": {
|
||||
"activate_host_color_management": true,
|
||||
"ocio_config": {
|
||||
"enabled": false,
|
||||
"override_global_config": false,
|
||||
"filepath": []
|
||||
},
|
||||
"file_rules": {
|
||||
"enabled": false,
|
||||
"activate_host_rules": false,
|
||||
"rules": {}
|
||||
}
|
||||
},
|
||||
|
|
@ -22,6 +23,7 @@
|
|||
"detailed_description": "Workfiles are full scenes from any application that are directly edited by artists. They represent a state of work on a task at a given point and are usually not directly referenced into other scenes.",
|
||||
"allow_sequences": false,
|
||||
"allow_multiple_items": false,
|
||||
"allow_version_control": false,
|
||||
"extensions": [
|
||||
".ma",
|
||||
".mb",
|
||||
|
|
@ -56,6 +58,7 @@
|
|||
"detailed_description": "Models should only contain geometry data, without any extras like cameras, locators or bones.\n\nKeep in mind that models published from tray publisher are not validated for correctness. ",
|
||||
"allow_sequences": false,
|
||||
"allow_multiple_items": true,
|
||||
"allow_version_control": false,
|
||||
"extensions": [
|
||||
".ma",
|
||||
".mb",
|
||||
|
|
@ -81,6 +84,7 @@
|
|||
"detailed_description": "Alembic or bgeo cache of animated data",
|
||||
"allow_sequences": true,
|
||||
"allow_multiple_items": true,
|
||||
"allow_version_control": false,
|
||||
"extensions": [
|
||||
".abc",
|
||||
".bgeo",
|
||||
|
|
@ -104,6 +108,7 @@
|
|||
"detailed_description": "Any type of image seqeuence coming from outside of the studio. Usually camera footage, but could also be animatics used for reference.",
|
||||
"allow_sequences": true,
|
||||
"allow_multiple_items": true,
|
||||
"allow_version_control": false,
|
||||
"extensions": [
|
||||
".exr",
|
||||
".png",
|
||||
|
|
@ -126,6 +131,7 @@
|
|||
"detailed_description": "Sequence or single file renders",
|
||||
"allow_sequences": true,
|
||||
"allow_multiple_items": true,
|
||||
"allow_version_control": false,
|
||||
"extensions": [
|
||||
".exr",
|
||||
".png",
|
||||
|
|
@ -149,6 +155,7 @@
|
|||
"detailed_description": "Ideally this should be only camera itself with baked animation, however, it can technically also include helper geometry.",
|
||||
"allow_sequences": false,
|
||||
"allow_multiple_items": true,
|
||||
"allow_version_control": false,
|
||||
"extensions": [
|
||||
".abc",
|
||||
".ma",
|
||||
|
|
@ -173,6 +180,7 @@
|
|||
"detailed_description": "Any image data can be published as image family. References, textures, concept art, matte paints. This is a fallback 2d family for everything that doesn't fit more specific family.",
|
||||
"allow_sequences": false,
|
||||
"allow_multiple_items": true,
|
||||
"allow_version_control": false,
|
||||
"extensions": [
|
||||
".exr",
|
||||
".jpg",
|
||||
|
|
@ -196,6 +204,7 @@
|
|||
"detailed_description": "Hierarchical data structure for the efficient storage and manipulation of sparse volumetric data discretized on three-dimensional grids",
|
||||
"allow_sequences": true,
|
||||
"allow_multiple_items": true,
|
||||
"allow_version_control": false,
|
||||
"extensions": [
|
||||
".vdb"
|
||||
]
|
||||
|
|
@ -214,6 +223,7 @@
|
|||
"detailed_description": "Script exported from matchmoving application to be later processed into a tracked camera with additional data",
|
||||
"allow_sequences": false,
|
||||
"allow_multiple_items": true,
|
||||
"allow_version_control": false,
|
||||
"extensions": []
|
||||
},
|
||||
{
|
||||
|
|
@ -226,6 +236,7 @@
|
|||
"detailed_description": "CG rigged character or prop. Rig should be clean of any extra data and directly loadable into it's respective application\t",
|
||||
"allow_sequences": false,
|
||||
"allow_multiple_items": false,
|
||||
"allow_version_control": false,
|
||||
"extensions": [
|
||||
".ma",
|
||||
".blend",
|
||||
|
|
@ -243,6 +254,7 @@
|
|||
"detailed_description": "Texture files with Unreal Engine naming conventions",
|
||||
"allow_sequences": false,
|
||||
"allow_multiple_items": true,
|
||||
"allow_version_control": false,
|
||||
"extensions": []
|
||||
}
|
||||
],
|
||||
|
|
@ -321,6 +333,11 @@
|
|||
"enabled": true,
|
||||
"optional": true,
|
||||
"active": true
|
||||
},
|
||||
"ValidateExistingVersion": {
|
||||
"enabled": true,
|
||||
"optional": true,
|
||||
"active": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
{
|
||||
"imageio": {
|
||||
"activate_host_color_management": true,
|
||||
"ocio_config": {
|
||||
"enabled": false,
|
||||
"override_global_config": false,
|
||||
"filepath": []
|
||||
},
|
||||
"file_rules": {
|
||||
"enabled": false,
|
||||
"activate_host_rules": false,
|
||||
"rules": {}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
{
|
||||
"imageio": {
|
||||
"activate_host_color_management": true,
|
||||
"ocio_config": {
|
||||
"enabled": false,
|
||||
"override_global_config": false,
|
||||
"filepath": []
|
||||
},
|
||||
"file_rules": {
|
||||
"enabled": false,
|
||||
"activate_host_rules": false,
|
||||
"rules": {}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
{
|
||||
"imageio": {
|
||||
"activate_host_color_management": true,
|
||||
"ocio_config": {
|
||||
"enabled": false,
|
||||
"override_global_config": false,
|
||||
"filepath": []
|
||||
},
|
||||
"file_rules": {
|
||||
"enabled": false,
|
||||
"activate_host_rules": false,
|
||||
"rules": {}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -8,18 +8,14 @@
|
|||
{
|
||||
"key": "imageio",
|
||||
"type": "dict",
|
||||
"label": "Color Management (ImageIO)",
|
||||
"label": "Color Management (OCIO managed)",
|
||||
"collapsible": true,
|
||||
"is_group": true,
|
||||
"children": [
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_config"
|
||||
},
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_file_rules"
|
||||
"type": "template",
|
||||
"name": "template_host_color_management_ocio"
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -34,18 +34,14 @@
|
|||
{
|
||||
"key": "imageio",
|
||||
"type": "dict",
|
||||
"label": "Color Management (ImageIO)",
|
||||
"label": "Color Management (OCIO managed)",
|
||||
"collapsible": true,
|
||||
"is_group": true,
|
||||
"children": [
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_config"
|
||||
},
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_file_rules"
|
||||
"type": "template",
|
||||
"name": "template_host_color_management_ocio"
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,18 +8,14 @@
|
|||
{
|
||||
"key": "imageio",
|
||||
"type": "dict",
|
||||
"label": "Color Management (ImageIO)",
|
||||
"label": "Color Management (derived to OCIO)",
|
||||
"collapsible": true,
|
||||
"is_group": true,
|
||||
"children": [
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_config"
|
||||
},
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_file_rules"
|
||||
"type": "template",
|
||||
"name": "template_host_color_management_derived"
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,16 +8,13 @@
|
|||
{
|
||||
"key": "imageio",
|
||||
"type": "dict",
|
||||
"label": "Color Management (ImageIO)",
|
||||
"label": "Color Management (remapped to OCIO)",
|
||||
"collapsible": true,
|
||||
"is_group": true,
|
||||
"children": [
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_config"
|
||||
},
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_file_rules"
|
||||
"type": "template",
|
||||
"name": "template_host_color_management_remapped"
|
||||
},
|
||||
{
|
||||
"key": "project",
|
||||
|
|
@ -47,10 +44,14 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"label": "Profile names mapping settings is deprecated use <a href=\"settings://project_settings/flame/imageio/remapping\"><b>./imagio/remapping</b></a> instead"
|
||||
},
|
||||
{
|
||||
"key": "profilesMapping",
|
||||
"type": "dict",
|
||||
"label": "Profile names mapping",
|
||||
"label": "Profile names mapping [deprecated]",
|
||||
"collapsible": true,
|
||||
"children": [
|
||||
{
|
||||
|
|
@ -362,7 +363,7 @@
|
|||
},
|
||||
{
|
||||
"key": "colorspace_out",
|
||||
"label": "Output color (imageio)",
|
||||
"label": "Output color",
|
||||
"type": "text",
|
||||
"default": "linear"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1058,7 +1058,7 @@
|
|||
{
|
||||
"type": "dict",
|
||||
"key": "IntegrateFtrackFarmStatus",
|
||||
"label": "Integrate Ftrack Farm Status",
|
||||
"label": "Ftrack Status To Farm",
|
||||
"children": [
|
||||
{
|
||||
"type": "label",
|
||||
|
|
@ -1068,7 +1068,7 @@
|
|||
"type": "list",
|
||||
"collapsible": true,
|
||||
"key": "farm_status_profiles",
|
||||
"label": "Farm status profiles",
|
||||
"label": "Profiles",
|
||||
"use_label_wrap": true,
|
||||
"object_type": {
|
||||
"type": "dict",
|
||||
|
|
@ -1114,6 +1114,142 @@
|
|||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "dict",
|
||||
"key": "ftrack_task_status_local_publish",
|
||||
"label": "Ftrack Status Local Integration",
|
||||
"children": [
|
||||
{
|
||||
"type": "label",
|
||||
"label": "Change status of task when is integrated locally"
|
||||
},
|
||||
{
|
||||
"type": "list",
|
||||
"collapsible": true,
|
||||
"key": "status_profiles",
|
||||
"label": "Profiles",
|
||||
"use_label_wrap": true,
|
||||
"object_type": {
|
||||
"type": "dict",
|
||||
"children": [
|
||||
{
|
||||
"key": "host_names",
|
||||
"label": "Host names",
|
||||
"type": "hosts-enum",
|
||||
"multiselection": true
|
||||
},
|
||||
{
|
||||
"key": "task_types",
|
||||
"label": "Task types",
|
||||
"type": "task-types-enum"
|
||||
},
|
||||
{
|
||||
"key": "task_names",
|
||||
"label": "Task names",
|
||||
"type": "list",
|
||||
"object_type": "text"
|
||||
},
|
||||
{
|
||||
"key": "families",
|
||||
"label": "Families",
|
||||
"type": "list",
|
||||
"object_type": "text"
|
||||
},
|
||||
{
|
||||
"key": "subset_names",
|
||||
"label": "Subset names",
|
||||
"type": "list",
|
||||
"object_type": "text"
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
},
|
||||
{
|
||||
"key": "status_name",
|
||||
"label": "Status name",
|
||||
"type": "text"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "dict",
|
||||
"key": "ftrack_task_status_on_farm_publish",
|
||||
"label": "Ftrack Status On Farm",
|
||||
"children": [
|
||||
{
|
||||
"type": "label",
|
||||
"label": "Change status of task when it's subset is integrated on farm"
|
||||
},
|
||||
{
|
||||
"type": "list",
|
||||
"collapsible": true,
|
||||
"key": "status_profiles",
|
||||
"label": "Profiles",
|
||||
"use_label_wrap": true,
|
||||
"object_type": {
|
||||
"type": "dict",
|
||||
"children": [
|
||||
{
|
||||
"key": "host_names",
|
||||
"label": "Host names",
|
||||
"type": "hosts-enum",
|
||||
"multiselection": true
|
||||
},
|
||||
{
|
||||
"key": "task_types",
|
||||
"label": "Task types",
|
||||
"type": "task-types-enum"
|
||||
},
|
||||
{
|
||||
"key": "task_names",
|
||||
"label": "Task names",
|
||||
"type": "list",
|
||||
"object_type": "text"
|
||||
},
|
||||
{
|
||||
"key": "families",
|
||||
"label": "Families",
|
||||
"type": "list",
|
||||
"object_type": "text"
|
||||
},
|
||||
{
|
||||
"key": "subset_names",
|
||||
"label": "Subset names",
|
||||
"type": "list",
|
||||
"object_type": "text"
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
},
|
||||
{
|
||||
"key": "status_name",
|
||||
"label": "Status name",
|
||||
"type": "text"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "dict",
|
||||
"key": "IntegrateFtrackTaskStatus",
|
||||
"label": "Integrate Ftrack Task Status",
|
||||
"children": [
|
||||
{
|
||||
"type": "label",
|
||||
"label": "Apply collected task statuses. This plugin can run before or after version integration. Some status automations may conflict with status changes on versions because of wrong order."
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"key": "after_version_statuses",
|
||||
"label": "After version integration"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,41 +8,13 @@
|
|||
{
|
||||
"key": "imageio",
|
||||
"type": "dict",
|
||||
"label": "Color Management (ImageIO)",
|
||||
"label": "Color Management (OCIO managed)",
|
||||
"collapsible": true,
|
||||
"is_group": true,
|
||||
"children": [
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_config"
|
||||
},
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_file_rules"
|
||||
},
|
||||
{
|
||||
"key": "ocio",
|
||||
"type": "dict",
|
||||
"label": "OpenColorIO (OCIO)",
|
||||
"collapsible": true,
|
||||
"checkbox_key": "enabled",
|
||||
"children": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"key": "enabled",
|
||||
"label": "Set OCIO variable for Fusion"
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"label": "<b style='color:red'>'configFilePath'</b> will be deprecated. <br>Please move values to : <i>project_settings/{app}/imageio/ocio_config/filepath</i>."
|
||||
},
|
||||
{
|
||||
"type": "path",
|
||||
"key": "configFilePath",
|
||||
"label": "OCIO Config File Path",
|
||||
"multiplatform": true,
|
||||
"multipath": true
|
||||
}
|
||||
]
|
||||
"type": "template",
|
||||
"name": "template_host_color_management_ocio"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
|||
|
|
@ -8,9 +8,18 @@
|
|||
{
|
||||
"key": "imageio",
|
||||
"type": "dict",
|
||||
"label": "Color Management (ImageIO)",
|
||||
"label": "Color Management",
|
||||
"is_group": true,
|
||||
"children": [
|
||||
{
|
||||
"type": "label",
|
||||
"label": "It's important to note that once color management is activated on a project, all hosts will be color managed by default. <br>The OpenColorIO (OCIO) config file is used either from the global settings or from the host's overrides. It's worth <br>noting that the order of the defined configuration paths matters, with higher priority given to paths listed earlier in <br>the configuration list.<br><br>To avoid potential issues, ensure that the OCIO configuration path is not an absolute path and includes at least <br>the root token (Anatomy). This helps ensure that the configuration path remains valid across different environments and <br>avoids any hard-coding of paths that may be specific to one particular system.<br><br><b><a href='https://ayon.ynput.io/docs/admin_colorspace' style=\"color:#00d6a1\";>Related documentation.</a></b>"
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"key": "activate_global_color_management",
|
||||
"label": "Enable Color Management"
|
||||
},
|
||||
{
|
||||
"key": "ocio_config",
|
||||
"type": "dict",
|
||||
|
|
@ -27,8 +36,44 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_file_rules"
|
||||
"key": "file_rules",
|
||||
"type": "dict",
|
||||
"label": "File Rules (OCIO v1 only)",
|
||||
"collapsible": true,
|
||||
"children": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"key": "activate_global_file_rules",
|
||||
"label": "Enable File Rules"
|
||||
},
|
||||
{
|
||||
"key": "rules",
|
||||
"label": "Rules",
|
||||
"type": "dict-modifiable",
|
||||
"highlight_content": true,
|
||||
"collapsible": false,
|
||||
"object_type": {
|
||||
"type": "dict",
|
||||
"children": [
|
||||
{
|
||||
"key": "pattern",
|
||||
"label": "Regex pattern",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"key": "colorspace",
|
||||
"label": "Colorspace name",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"key": "ext",
|
||||
"label": "File extension",
|
||||
"type": "text"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
]
|
||||
|
|
|
|||
|
|
@ -8,18 +8,14 @@
|
|||
{
|
||||
"key": "imageio",
|
||||
"type": "dict",
|
||||
"label": "Color Management (ImageIO)",
|
||||
"label": "Color Management (OCIO managed)",
|
||||
"collapsible": true,
|
||||
"is_group": true,
|
||||
"children": [
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_config"
|
||||
},
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_file_rules"
|
||||
"type": "template",
|
||||
"name": "template_host_color_management_ocio"
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,17 +8,13 @@
|
|||
{
|
||||
"key": "imageio",
|
||||
"type": "dict",
|
||||
"label": "Color Management (ImageIO)",
|
||||
"is_group": true,
|
||||
"label": "Color Management (OCIO managed)",
|
||||
"collapsible": true,
|
||||
"is_group": true,
|
||||
"children": [
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_config"
|
||||
},
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_file_rules"
|
||||
"type": "template",
|
||||
"name": "template_host_color_management_ocio"
|
||||
},
|
||||
{
|
||||
"key": "workfile",
|
||||
|
|
@ -26,10 +22,6 @@
|
|||
"label": "Workfile",
|
||||
"collapsible": false,
|
||||
"children": [
|
||||
{
|
||||
"type": "label",
|
||||
"label": "<b style='color:red'>'ocioconfigpath'</b> will be deprecated. <br>Please move values to : <i>project_settings/{app}/imageio/ocio_config/filepath</i>."
|
||||
},
|
||||
{
|
||||
"type": "form",
|
||||
"children": [
|
||||
|
|
@ -55,19 +47,9 @@
|
|||
},
|
||||
{
|
||||
"cg-config-v1.0.0_aces-v1.3_ocio-v2.1": "cg-config-v1.0.0_aces-v1.3_ocio-v2.1 (14)"
|
||||
},
|
||||
{
|
||||
"custom": "custom"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "path",
|
||||
"key": "ocioconfigpath",
|
||||
"label": "Custom OCIO path",
|
||||
"multiplatform": true,
|
||||
"multipath": true
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"key": "workingSpace",
|
||||
|
|
|
|||
|
|
@ -8,18 +8,14 @@
|
|||
{
|
||||
"key": "imageio",
|
||||
"type": "dict",
|
||||
"label": "Color Management (ImageIO)",
|
||||
"label": "Color Management (OCIO managed)",
|
||||
"collapsible": true,
|
||||
"is_group": true,
|
||||
"children": [
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_config"
|
||||
},
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_file_rules"
|
||||
"type": "template",
|
||||
"name": "template_host_color_management_ocio"
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -35,4 +31,4 @@
|
|||
"name": "schema_houdini_publish"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,19 @@
|
|||
"label": "Max",
|
||||
"is_file": true,
|
||||
"children": [
|
||||
{
|
||||
"key": "imageio",
|
||||
"type": "dict",
|
||||
"label": "Color Management (OCIO managed)",
|
||||
"collapsible": true,
|
||||
"is_group": true,
|
||||
"children": [
|
||||
{
|
||||
"type": "template",
|
||||
"name": "template_host_color_management_ocio"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "dict",
|
||||
"collapsible": true,
|
||||
|
|
|
|||
|
|
@ -48,40 +48,25 @@
|
|||
{
|
||||
"key": "imageio",
|
||||
"type": "dict",
|
||||
"label": "Color Management (ImageIO)",
|
||||
"label": "Color Management (OCIO managed)",
|
||||
"collapsible": true,
|
||||
"is_group": true,
|
||||
"children": [
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_config"
|
||||
"type": "template",
|
||||
"name": "template_host_color_management_ocio"
|
||||
},
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_file_rules"
|
||||
},
|
||||
{
|
||||
"key": "colorManagementPreference_v2",
|
||||
"key": "workfile",
|
||||
"type": "dict",
|
||||
"label": "Color Management Preference v2 (Maya 2022+)",
|
||||
"label": "Workfile",
|
||||
"collapsible": true,
|
||||
"checkbox_key": "enabled",
|
||||
"children": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"key": "enabled",
|
||||
"label": "Use Color Management Preference v2"
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"label": "<b style='color:red'>'configFilePath'</b> will be deprecated. <br>Please move values to : <i>project_settings/{app}/imageio/ocio_config/filepath</i>."
|
||||
},
|
||||
{
|
||||
"type": "path",
|
||||
"key": "configFilePath",
|
||||
"label": "OCIO Config File Path",
|
||||
"multiplatform": true,
|
||||
"multipath": true
|
||||
"label": "Enabled"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
|
|
@ -101,31 +86,57 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"key": "colorManagementPreference",
|
||||
"type": "dict",
|
||||
"label": "Color Management Preference (legacy)",
|
||||
"type": "collapsible-wrap",
|
||||
"label": "<b>[Deprecated] please migrate all to 'Workfile' and enable it.</b>",
|
||||
"collapsible": true,
|
||||
"collapsed": true,
|
||||
"children": [
|
||||
{
|
||||
"type": "label",
|
||||
"label": "<b style='color:red'>'configFilePath'</b> will be deprecated. <br>Please move values to : <i>project_settings/{app}/imageio/ocio_config/filepath</i>."
|
||||
"key": "colorManagementPreference_v2",
|
||||
"type": "dict",
|
||||
"label": "[DEPRECATED] Color Management Preference v2 (Maya 2022+)",
|
||||
"collapsible": true,
|
||||
"checkbox_key": "enabled",
|
||||
"children": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"key": "enabled",
|
||||
"label": "Use Color Management Preference v2"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"key": "renderSpace",
|
||||
"label": "Rendering Space"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"key": "displayName",
|
||||
"label": "Display"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"key": "viewName",
|
||||
"label": "View"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"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"
|
||||
"key": "colorManagementPreference",
|
||||
"type": "dict",
|
||||
"label": "[DEPRECATED] Color Management Preference (legacy)",
|
||||
"collapsible": true,
|
||||
"children": [
|
||||
{
|
||||
"type": "text",
|
||||
"key": "renderSpace",
|
||||
"label": "Rendering Space"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"key": "viewTransform",
|
||||
"label": "Viewer Transform (workfile/viewName)"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,18 +8,14 @@
|
|||
{
|
||||
"key": "imageio",
|
||||
"type": "dict",
|
||||
"label": "Color Management (ImageIO)",
|
||||
"label": "Color Management (remapped to OCIO)",
|
||||
"collapsible": true,
|
||||
"is_group": true,
|
||||
"children": [
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_config"
|
||||
},
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_file_rules"
|
||||
"type": "template",
|
||||
"name": "template_host_color_management_remapped"
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -13,18 +13,14 @@
|
|||
{
|
||||
"key": "imageio",
|
||||
"type": "dict",
|
||||
"label": "Color Management (ImageIO)",
|
||||
"label": "Color Management (remapped to OCIO)",
|
||||
"collapsible": true,
|
||||
"is_group": true,
|
||||
"children": [
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_config"
|
||||
},
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_file_rules"
|
||||
"type": "template",
|
||||
"name": "template_host_color_management_remapped"
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,18 +8,13 @@
|
|||
{
|
||||
"key": "imageio",
|
||||
"type": "dict",
|
||||
"label": "Color Management (ImageIO)",
|
||||
"label": "Color Management (OCIO managed)",
|
||||
"is_group": true,
|
||||
"children": [
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_config"
|
||||
},
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_file_rules"
|
||||
"type": "template",
|
||||
"name": "template_host_color_management_ocio"
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,18 +8,14 @@
|
|||
{
|
||||
"key": "imageio",
|
||||
"type": "dict",
|
||||
"label": "Color Management (ImageIO)",
|
||||
"label": "Color Management (derived to OCIO)",
|
||||
"collapsible": true,
|
||||
"is_group": true,
|
||||
"children": [
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_config"
|
||||
},
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_file_rules"
|
||||
"type": "template",
|
||||
"name": "template_host_color_management_derived"
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -89,6 +85,12 @@
|
|||
"label": "Allow multiple items",
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"key": "allow_version_control",
|
||||
"label": "Allow version control",
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"type": "list",
|
||||
"key": "extensions",
|
||||
|
|
@ -350,6 +352,10 @@
|
|||
{
|
||||
"key": "ValidateFrameRange",
|
||||
"label": "Validate frame range"
|
||||
},
|
||||
{
|
||||
"key": "ValidateExistingVersion",
|
||||
"label": "Validate Existing Version"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,18 +8,14 @@
|
|||
{
|
||||
"key": "imageio",
|
||||
"type": "dict",
|
||||
"label": "Color Management (ImageIO)",
|
||||
"label": "Color Management (derived to OCIO)",
|
||||
"collapsible": true,
|
||||
"is_group": true,
|
||||
"children": [
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_config"
|
||||
},
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_file_rules"
|
||||
"type": "template",
|
||||
"name": "template_host_color_management_derived"
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,18 +8,14 @@
|
|||
{
|
||||
"key": "imageio",
|
||||
"type": "dict",
|
||||
"label": "Color Management (ImageIO)",
|
||||
"label": "Color Management (OCIO managed)",
|
||||
"collapsible": true,
|
||||
"is_group": true,
|
||||
"children": [
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_config"
|
||||
},
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_file_rules"
|
||||
"type": "template",
|
||||
"name": "template_host_color_management_ocio"
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,18 +8,14 @@
|
|||
{
|
||||
"key": "imageio",
|
||||
"type": "dict",
|
||||
"label": "Color Management (ImageIO)",
|
||||
"label": "Color Management (derived to OCIO)",
|
||||
"collapsible": true,
|
||||
"is_group": true,
|
||||
"children": [
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_config"
|
||||
},
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_file_rules"
|
||||
"type": "template",
|
||||
"name": "template_host_color_management_derived"
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
{
|
||||
"key": "ocio_config",
|
||||
"type": "dict",
|
||||
"label": "OCIO config",
|
||||
"collapsible": true,
|
||||
"checkbox_key": "enabled",
|
||||
"children": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"key": "enabled",
|
||||
"label": "Enabled"
|
||||
},
|
||||
{
|
||||
"type": "path",
|
||||
"key": "filepath",
|
||||
"label": "Config path",
|
||||
"multiplatform": false,
|
||||
"multipath": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
{
|
||||
"key": "file_rules",
|
||||
"type": "dict",
|
||||
"label": "File Rules",
|
||||
"collapsible": true,
|
||||
"checkbox_key": "enabled",
|
||||
"children": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"key": "enabled",
|
||||
"label": "Enabled"
|
||||
},
|
||||
{
|
||||
"key": "rules",
|
||||
"label": "Rules",
|
||||
"type": "dict-modifiable",
|
||||
"highlight_content": true,
|
||||
"collapsible": false,
|
||||
"object_type": {
|
||||
"type": "dict",
|
||||
"children": [
|
||||
{
|
||||
"key": "pattern",
|
||||
"label": "Regex pattern",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"key": "colorspace",
|
||||
"label": "Colorspace name",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"key": "ext",
|
||||
"label": "File extension",
|
||||
"type": "text"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,21 +1,13 @@
|
|||
{
|
||||
"key": "imageio",
|
||||
"type": "dict",
|
||||
"label": "Color Management (ImageIO)",
|
||||
"label": "Color Management (OCIO managed)",
|
||||
"collapsible": true,
|
||||
"is_group": true,
|
||||
"children": [
|
||||
{
|
||||
"type": "label",
|
||||
"label": "<b style='color:red'>'Custom OCIO config path'</b> has deprecated. <br> If you need to set custom config, just enable and add path into 'OCIO config'. <br>Anatomy keys are supported.</i>."
|
||||
},
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_config"
|
||||
},
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_imageio_file_rules"
|
||||
"type": "template",
|
||||
"name": "template_host_color_management_ocio"
|
||||
},
|
||||
{
|
||||
"key": "viewer",
|
||||
|
|
@ -102,19 +94,9 @@
|
|||
},
|
||||
{
|
||||
"cg-config-v1.0.0_aces-v1.3_ocio-v2.1": "cg-config-v1.0.0_aces-v1.3_ocio-v2.1 (14)"
|
||||
},
|
||||
{
|
||||
"custom": "custom"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "path",
|
||||
"key": "customOCIOConfigPath",
|
||||
"label": "Custom OCIO config path",
|
||||
"multiplatform": true,
|
||||
"multipath": true
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"key": "workingSpaceLUT",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
[
|
||||
{
|
||||
"key": "remapping",
|
||||
"type": "dict",
|
||||
"label": "Remapping colorspace names",
|
||||
"collapsible": true,
|
||||
"children": [
|
||||
{
|
||||
"type": "list",
|
||||
"key": "rules",
|
||||
"object_type": {
|
||||
"type": "dict",
|
||||
"children": [
|
||||
{
|
||||
"type": "text",
|
||||
"key": "host_native_name",
|
||||
"label": "Application native colorspace name"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"key": "ocio_name",
|
||||
"label": "OCIO colorspace name"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
[
|
||||
{
|
||||
"type": "label",
|
||||
"label": "The application does not include any built-in color management capabilities, OpenPype offers a solution <br>to this limitation by deriving valid colorspace names for the OpenColorIO (OCIO) color management <br>system from file paths, using File Rules feature only during Publishing.<br><br><b><a href='https://ayon.ynput.io/docs/admin_colorspace#derived-colorspace' style=\"color:#00d6a1\";>Related documentation.</a></b>"
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"key": "activate_host_color_management",
|
||||
"label": "Enable Color Management"
|
||||
},
|
||||
{
|
||||
"type": "template",
|
||||
"name": "template_imageio_config"
|
||||
},
|
||||
{
|
||||
"type": "template",
|
||||
"name": "template_imageio_file_rules"
|
||||
}
|
||||
]
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
[
|
||||
{
|
||||
"type": "label",
|
||||
"label": "Colorspace management for the application can be controlled through OpenPype settings. <br>Specifically, the configured OpenColorIO (OCIO) config path is utilized in the application's workfile. <br>Additionally, the File Rules feature can be leveraged for both publishing and loading procedures.<br><br><b><a href='https://ayon.ynput.io/docs/admin_colorspace#remapped-internal-colorspace' style=\"color:#00d6a1\";>Related documentation.</a></b>"
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"key": "activate_host_color_management",
|
||||
"label": "Enable Color Management"
|
||||
},
|
||||
{
|
||||
"type": "template",
|
||||
"name": "template_imageio_config"
|
||||
},
|
||||
{
|
||||
"type": "template",
|
||||
"name": "template_imageio_file_rules"
|
||||
}
|
||||
]
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
[
|
||||
{
|
||||
"type": "label",
|
||||
"label": "The application includes internal color management functionality, but it does not offer external control <br>over this feature. To address this limitation, OpenPype uses mapping rules to remap the native <br>colorspace names used in the internal color management system to the OpenColorIO (OCIO) <br>color management system. Remapping feature is used in Publishing and Loading procedures.<br><br><b><a href='https://ayon.ynput.io/docs/admin_colorspace#remapped-internal-colorspace' style=\"color:#00d6a1\";>Related documentation.</a></b>."
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"key": "activate_host_color_management",
|
||||
"label": "Enable Color Management"
|
||||
},
|
||||
{
|
||||
"type": "template",
|
||||
"name": "template_colorspace_remapping"
|
||||
},
|
||||
{
|
||||
"type": "template",
|
||||
"name": "template_imageio_config"
|
||||
},
|
||||
{
|
||||
"type": "template",
|
||||
"name": "template_imageio_file_rules"
|
||||
}
|
||||
]
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
[
|
||||
{
|
||||
"key": "ocio_config",
|
||||
"type": "dict",
|
||||
"label": "OCIO config",
|
||||
"collapsible": true,
|
||||
"children": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"key": "override_global_config",
|
||||
"label": "Override global OCIO config"
|
||||
},
|
||||
{
|
||||
"type": "path",
|
||||
"key": "filepath",
|
||||
"label": "Config path",
|
||||
"multiplatform": false,
|
||||
"multipath": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
[
|
||||
{
|
||||
"key": "file_rules",
|
||||
"type": "dict",
|
||||
"label": "File Rules (OCIO v1 only)",
|
||||
"collapsible": true,
|
||||
"children": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"key": "activate_host_rules",
|
||||
"label": "Activate Host File Rules"
|
||||
},
|
||||
{
|
||||
"key": "rules",
|
||||
"label": "Rules",
|
||||
"type": "dict-modifiable",
|
||||
"highlight_content": true,
|
||||
"collapsible": false,
|
||||
"object_type": {
|
||||
"type": "dict",
|
||||
"children": [
|
||||
{
|
||||
"key": "pattern",
|
||||
"label": "Regex pattern",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"key": "colorspace",
|
||||
"label": "Colorspace name",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"key": "ext",
|
||||
"label": "File extension",
|
||||
"type": "text"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
@ -53,6 +53,9 @@ class CreatorsModel(QtGui.QStandardItemModel):
|
|||
index = self.index(row, 0)
|
||||
item_id = index.data(ITEM_ID_ROLE)
|
||||
creator_plugin = self._creators_by_id.get(item_id)
|
||||
if creator_plugin and creator_plugin.family == family:
|
||||
if creator_plugin and (
|
||||
creator_plugin.label.lower() == family.lower()
|
||||
or creator_plugin.family.lower() == family.lower()
|
||||
):
|
||||
indexes.append(index)
|
||||
return indexes
|
||||
|
|
|
|||
|
|
@ -446,6 +446,7 @@ class SubsetsModel(BaseRepresentationModel, TreeModel):
|
|||
last_versions_by_subset_id = get_last_versions(
|
||||
project_name,
|
||||
subset_ids,
|
||||
active=True,
|
||||
fields=["_id", "parent", "name", "type", "data", "schema"]
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -828,6 +828,7 @@ class CreateWidget(QtWidgets.QWidget):
|
|||
|
||||
if success:
|
||||
self._set_creator(self._selected_creator)
|
||||
self.variant_input.setText(variant)
|
||||
self._controller.emit_card_message("Creation finished...")
|
||||
self._last_thumbnail_path = None
|
||||
self._thumbnail_widget.set_current_thumbnails()
|
||||
|
|
|
|||
|
|
@ -453,7 +453,11 @@ class PublisherWindow(QtWidgets.QDialog):
|
|||
return
|
||||
|
||||
save_match = event.matches(QtGui.QKeySequence.Save)
|
||||
if save_match == QtGui.QKeySequence.ExactMatch:
|
||||
# PySide2 and PySide6 support
|
||||
if not isinstance(save_match, bool):
|
||||
save_match = save_match == QtGui.QKeySequence.ExactMatch
|
||||
|
||||
if save_match:
|
||||
if not self._controller.publish_has_started:
|
||||
self._save_changes(True)
|
||||
event.accept()
|
||||
|
|
|
|||
|
|
@ -128,7 +128,8 @@ class FamilyWidget(QtWidgets.QWidget):
|
|||
'family_preset_key': key,
|
||||
'family': family,
|
||||
'subset': self.input_result.text(),
|
||||
'version': self.version_spinbox.value()
|
||||
'version': self.version_spinbox.value(),
|
||||
'use_next_available_version': self.version_checkbox.isChecked(),
|
||||
}
|
||||
return data
|
||||
|
||||
|
|
|
|||
|
|
@ -123,10 +123,14 @@ class VersionDelegate(QtWidgets.QStyledItemDelegate):
|
|||
project_name = self.dbcon.active_project()
|
||||
# Add all available versions to the editor
|
||||
parent_id = item["version_document"]["parent"]
|
||||
version_docs = list(sorted(
|
||||
get_versions(project_name, subset_ids=[parent_id]),
|
||||
key=lambda item: item["name"]
|
||||
))
|
||||
version_docs = [
|
||||
version_doc
|
||||
for version_doc in sorted(
|
||||
get_versions(project_name, subset_ids=[parent_id]),
|
||||
key=lambda item: item["name"]
|
||||
)
|
||||
if version_doc["data"].get("active", True)
|
||||
]
|
||||
|
||||
hero_versions = list(
|
||||
get_hero_versions(
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Package declaring Pype version."""
|
||||
__version__ = "3.15.10-nightly.2"
|
||||
__version__ = "3.15.11-nightly.3"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue