traypublish: adding colorspace look product type publishing workflow

This commit is contained in:
Jakub Jezek 2023-08-30 14:53:58 +02:00
parent fb4567560e
commit 3cc8c51ea2
No known key found for this signature in database
GPG key ID: 730D7C02726179A7
5 changed files with 345 additions and 0 deletions

View file

@ -0,0 +1,185 @@
# -*- coding: utf-8 -*-
"""Creator of colorspace look files.
This creator is used to publish colorspace look files thanks to
production type `ociolook`. All files are published as representation.
"""
from pathlib import Path
from openpype.client import get_asset_by_name
from openpype.lib.attribute_definitions import (
FileDef, EnumDef, TextDef, UISeparatorDef
)
from openpype.pipeline import (
CreatedInstance,
CreatorError
)
from openpype.pipeline.create import (
get_subset_name,
TaskNotSetError,
)
from openpype.pipeline import colorspace
from openpype.hosts.traypublisher.api.plugin import TrayPublishCreator
class CreateColorspaceLook(TrayPublishCreator):
"""Creates colorspace look files."""
identifier = "io.openpype.creators.traypublisher.colorspace_look"
label = "Colorspace Look"
family = "ociolook"
description = "Publishes color space look file."
extensions = [".cc", ".cube", ".3dl", ".spi1d", ".spi3d", ".csp", ".lut"]
enabled = False
colorspace_items = [
(None, "Not set")
]
colorspace_attr_show = False
def get_detail_description(self):
return """# Colorspace Look
This creator publishes color space look file (LUT).
"""
def get_icon(self):
return "mdi.format-color-fill"
def create(self, subset_name, instance_data, pre_create_data):
repr_file = pre_create_data.get("luts_file")
if not repr_file:
raise CreatorError("No files specified")
files = repr_file.get("filenames")
if not files:
# this should never happen
raise CreatorError("Missing files from representation")
asset_doc = get_asset_by_name(
self.project_name, instance_data["asset"])
subset_name = self._get_subset(
asset_doc, instance_data["variant"], self.project_name,
instance_data["task"]
)
instance_data["creator_attributes"] = {
"abs_lut_path": (
Path(repr_file["directory"]) / files[0]).as_posix()
}
# Create new instance
new_instance = CreatedInstance(self.family, subset_name,
instance_data, self)
self._store_new_instance(new_instance)
def get_instance_attr_defs(self):
return [
EnumDef(
"working_colorspace",
self.colorspace_items,
default="Not set",
label="Working Colorspace",
),
UISeparatorDef(
label="Advanced1"
),
TextDef(
"abs_lut_path",
label="LUT Path",
),
EnumDef(
"input_colorspace",
self.colorspace_items,
default="Not set",
label="Input Colorspace",
),
EnumDef(
"direction",
[
(None, "Not set"),
("forward", "Forward"),
("inverse", "Inverse")
],
default="Not set",
label="Direction"
),
EnumDef(
"interpolation",
[
(None, "Not set"),
("linear", "Linear"),
("tetrahedral", "Tetrahedral"),
("best", "Best"),
("nearest", "Nearest")
],
default="Not set",
label="Interpolation"
),
EnumDef(
"output_colorspace",
self.colorspace_items,
default="Not set",
label="Output Colorspace",
),
]
def get_pre_create_attr_defs(self):
return [
FileDef(
"luts_file",
folders=False,
extensions=self.extensions,
allow_sequences=False,
single_item=True,
label="Look Files",
)
]
def apply_settings(self, project_settings, system_settings):
host = self.create_context.host
host_name = host.name
project_name = host.get_current_project_name()
config_data = colorspace.get_imageio_config(
project_name, host_name,
project_settings=project_settings
)
if config_data:
filepath = config_data["path"]
config_items = colorspace.get_ocio_config_colorspaces(filepath)
self.colorspace_items.extend((
(name, f"{name} [{data_['type']}]")
for name, data_ in config_items.items()
if data_.get("type") == "colorspace"
))
self.enabled = True
def _get_subset(self, asset_doc, variant, project_name, task_name=None):
"""Create subset name according to standard template process"""
try:
subset_name = get_subset_name(
self.family,
variant,
task_name,
asset_doc,
project_name
)
except TaskNotSetError:
# Create instance with fake task
# - instance will be marked as invalid so it can't be published
# but user have ability to change it
# NOTE: This expect that there is not task 'Undefined' on asset
task_name = "Undefined"
subset_name = get_subset_name(
self.family,
variant,
task_name,
asset_doc,
project_name
)
return subset_name

View file

@ -0,0 +1,46 @@
import os
import pyblish.api
from openpype.pipeline import publish
class CollectColorspaceLook(pyblish.api.InstancePlugin,
publish.OpenPypePyblishPluginMixin):
"""Collect OCIO colorspace look from LUT file
"""
label = "Collect Colorspace Look"
order = pyblish.api.CollectorOrder
hosts = ["traypublisher"]
families = ["ociolook"]
def process(self, instance):
creator_attrs = instance.data["creator_attributes"]
lut_repre_name = "LUTfile"
file_url = creator_attrs["abs_lut_path"]
file_name = os.path.basename(file_url)
_, ext = os.path.splitext(file_name)
# create lut representation data
lut_repre = {
"name": lut_repre_name,
"ext": ext.lstrip("."),
"files": file_name,
"stagingDir": os.path.dirname(file_url),
"tags": []
}
instance.data.update({
"representations": [lut_repre],
"source": file_url,
"ocioLookItems": [
{
"name": lut_repre_name,
"ext": ext.lstrip("."),
"working_colorspace": creator_attrs["working_colorspace"],
"input_colorspace": creator_attrs["input_colorspace"],
"output_colorspace": creator_attrs["output_colorspace"],
"direction": creator_attrs["direction"],
"interpolation": creator_attrs["interpolation"]
}
]
})

View file

@ -0,0 +1,43 @@
import os
import json
import pyblish.api
from openpype.pipeline import publish
class ExtractColorspaceLook(publish.Extractor,
publish.OpenPypePyblishPluginMixin):
"""Extract OCIO colorspace look from LUT file
"""
label = "Extract Colorspace Look"
order = pyblish.api.ExtractorOrder
hosts = ["traypublisher"]
families = ["ociolook"]
def process(self, instance):
ociolook_items = instance.data["ocioLookItems"]
staging_dir = self.staging_dir(instance)
# create ociolook file attributes
ociolook_file_name = "ocioLookFile.json"
ociolook_file_content = {
"version": 1,
"data": {
"ocioLookItems": ociolook_items
}
}
# write ociolook content into json file saved in staging dir
file_url = os.path.join(staging_dir, ociolook_file_name)
with open(file_url, "w") as f_:
json.dump(ociolook_file_content, f_, indent=4)
# create lut representation data
ociolook_repre = {
"name": "ocioLookFile",
"ext": "json",
"files": ociolook_file_name,
"stagingDir": staging_dir,
"tags": []
}
instance.data["representations"].append(ociolook_repre)

View file

@ -0,0 +1,70 @@
import pyblish.api
from openpype.pipeline import (
publish,
PublishValidationError
)
class ValidateColorspaceLook(pyblish.api.InstancePlugin,
publish.OpenPypePyblishPluginMixin):
"""Validate colorspace look attributes"""
label = "Validate colorspace look attributes"
order = pyblish.api.ValidatorOrder
hosts = ["traypublisher"]
families = ["ociolook"]
def process(self, instance):
create_context = instance.context.data["create_context"]
created_instance = create_context.get_instance_by_id(
instance.data["instance_id"])
creator_defs = created_instance.creator_attribute_defs
ociolook_items = instance.data.get("ocioLookItems", [])
for ociolook_item in ociolook_items:
self.validate_colorspace_set_attrs(ociolook_item, creator_defs)
def validate_colorspace_set_attrs(self, ociolook_item, creator_defs):
"""Validate colorspace look attributes"""
self.log.debug(f"Validate colorspace look attributes: {ociolook_item}")
self.log.debug(f"Creator defs: {creator_defs}")
check_keys = [
"working_colorspace",
"input_colorspace",
"output_colorspace",
"direction",
"interpolation"
]
not_set_keys = []
for key in check_keys:
if ociolook_item[key]:
# key is set and it is correct
continue
def_label = next(
(d_.label for d_ in creator_defs if key == d_.key),
None
)
if not def_label:
def_attrs = [(d_.key, d_.label) for d_ in creator_defs]
# raise since key is not recognized by creator defs
raise KeyError(
f"Colorspace look attribute '{key}' is not "
f"recognized by creator attributes: {def_attrs}"
)
not_set_keys.append(def_label)
if not_set_keys:
message = (
f"Colorspace look attributes are not set: "
f"{', '.join(not_set_keys)}"
)
raise PublishValidationError(
title="Colorspace Look attributes",
message=message,
description=message
)

View file

@ -107,6 +107,7 @@ class IntegrateAsset(pyblish.api.InstancePlugin):
"rig",
"plate",
"look",
"ociolook",
"audio",
"yetiRig",
"yeticache",