Merge pull request #4556 from ynput/feature/OP-5006_Nuke-publish-colorspaceData-from-rendered-images

This commit is contained in:
Jakub Ježek 2023-03-06 11:52:37 +01:00 committed by GitHub
commit f5ef4597b2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 61 additions and 44 deletions

View file

@ -3,12 +3,14 @@ from pprint import pformat
import nuke
import pyblish.api
from openpype.hosts.nuke import api as napi
from openpype.pipeline import publish
class CollectNukeWrites(pyblish.api.InstancePlugin):
class CollectNukeWrites(pyblish.api.InstancePlugin,
publish.ColormanagedPyblishPluginMixin):
"""Collect all write nodes."""
order = pyblish.api.CollectorOrder - 0.48
order = pyblish.api.CollectorOrder + 0.0021
label = "Collect Writes"
hosts = ["nuke", "nukeassist"]
families = ["render", "prerender", "image"]
@ -66,6 +68,9 @@ class CollectNukeWrites(pyblish.api.InstancePlugin):
write_file_path = nuke.filename(write_node)
output_dir = os.path.dirname(write_file_path)
# get colorspace and add to version data
colorspace = napi.get_colorspace_from_node(write_node)
self.log.debug('output dir: {}'.format(output_dir))
if render_target == "frames":
@ -128,6 +133,12 @@ class CollectNukeWrites(pyblish.api.InstancePlugin):
else:
representation['files'] = collected_frames
# inject colorspace data
self.set_representation_colorspace(
representation, instance.context,
colorspace=colorspace
)
instance.data["representations"].append(representation)
self.log.info("Publishing rendered frames ...")
@ -145,8 +156,7 @@ class CollectNukeWrites(pyblish.api.InstancePlugin):
instance.data["farm"] = True
self.log.info("Farm rendering ON ...")
# get colorspace and add to version data
colorspace = napi.get_colorspace_from_node(write_node)
# TODO: remove this when we have proper colorspace support
version_data = {
"colorspace": colorspace
}

View file

@ -4,12 +4,13 @@ import shutil
import pyblish.api
import clique
import nuke
from openpype.hosts.nuke import api as napi
from openpype.pipeline import publish
from openpype.lib import collect_frames
class NukeRenderLocal(publish.ExtractorColormanaged):
class NukeRenderLocal(publish.Extractor,
publish.ColormanagedPyblishPluginMixin):
"""Render the current Nuke composition locally.
Extract the result of savers by starting a comp render
@ -85,7 +86,7 @@ class NukeRenderLocal(publish.ExtractorColormanaged):
)
ext = node["file_type"].value()
colorspace = node["colorspace"].value()
colorspace = napi.get_colorspace_from_node(node)
if "representations" not in instance.data:
instance.data["representations"] = []

View file

@ -335,9 +335,10 @@ def get_imageio_config(
get_template_data_from_session)
anatomy_data = get_template_data_from_session()
formatting_data = deepcopy(anatomy_data)
# add project roots to anatomy data
anatomy_data["root"] = anatomy.roots
anatomy_data["platform"] = platform.system().lower()
formatting_data["root"] = anatomy.roots
formatting_data["platform"] = platform.system().lower()
# get colorspace settings
imageio_global, imageio_host = _get_imageio_settings(
@ -347,7 +348,7 @@ def get_imageio_config(
if config_host.get("enabled"):
config_data = _get_config_data(
config_host["filepath"], anatomy_data
config_host["filepath"], formatting_data
)
else:
config_data = None
@ -356,7 +357,7 @@ def get_imageio_config(
# get config path from either global or host_name
config_global = imageio_global["ocio_config"]
config_data = _get_config_data(
config_global["filepath"], anatomy_data
config_global["filepath"], formatting_data
)
if not config_data:
@ -372,12 +373,12 @@ def _get_config_data(path_list, anatomy_data):
"""Return first existing path in path list.
If template is used in path inputs,
then it is formated by anatomy data
then it is formatted by anatomy data
and environment variables
Args:
path_list (list[str]): list of abs paths
anatomy_data (dict): formating data
anatomy_data (dict): formatting data
Returns:
dict: config data
@ -389,30 +390,30 @@ def _get_config_data(path_list, anatomy_data):
# first try host config paths
for path_ in path_list:
formated_path = _format_path(path_, formatting_data)
formatted_path = _format_path(path_, formatting_data)
if not os.path.exists(formated_path):
if not os.path.exists(formatted_path):
continue
return {
"path": os.path.normpath(formated_path),
"path": os.path.normpath(formatted_path),
"template": path_
}
def _format_path(tempate_path, formatting_data):
"""Single template path formating.
def _format_path(template_path, formatting_data):
"""Single template path formatting.
Args:
tempate_path (str): template string
template_path (str): template string
formatting_data (dict): data to be used for
template formating
template formatting
Returns:
str: absolute formated path
str: absolute formatted path
"""
# format path for anatomy keys
formatted_path = StringTemplate(tempate_path).format(
formatted_path = StringTemplate(template_path).format(
formatting_data)
return os.path.abspath(formatted_path)

View file

@ -19,7 +19,7 @@ from .publish_plugins import (
RepairContextAction,
Extractor,
ExtractorColormanaged,
ColormanagedPyblishPluginMixin
)
from .lib import (
@ -64,7 +64,7 @@ __all__ = (
"RepairContextAction",
"Extractor",
"ExtractorColormanaged",
"ColormanagedPyblishPluginMixin",
"get_publish_template_name",

View file

@ -3,7 +3,7 @@ from abc import ABCMeta
from pprint import pformat
import pyblish.api
from pyblish.plugin import MetaPlugin, ExplicitMetaPlugin
from openpype.lib.transcoding import VIDEO_EXTENSIONS, IMAGE_EXTENSIONS
from openpype.lib import BoolDef
from .lib import (
@ -288,28 +288,29 @@ class Extractor(pyblish.api.InstancePlugin):
return get_instance_staging_dir(instance)
class ExtractorColormanaged(Extractor):
"""Extractor base for color managed image data.
Each Extractor intended to export pixel data representation
should inherit from this class to allow color managed data.
Class implements "get_colorspace_settings" and
"set_representation_colorspace" functions used
for injecting colorspace data to representation data for farther
integration into db document.
class ColormanagedPyblishPluginMixin(object):
"""Mixin for colormanaged plugins.
This class is used to set colorspace data to a publishing
representation. It contains a static method,
get_colorspace_settings, which returns config and
file rules data for the host context.
It also contains a method, set_representation_colorspace,
which sets colorspace data to the representation.
The allowed file extensions are listed in the allowed_ext variable.
The method first checks if the file extension is in
the list of allowed extensions. If it is, it then gets the
colorspace settings from the host context and gets a
matching colorspace from rules. Finally, it infuses this
data into the representation.
"""
allowed_ext = [
"cin", "dpx", "avi", "dv", "gif", "flv", "mkv", "mov", "mpg", "mpeg",
"mp4", "m4v", "mxf", "iff", "z", "ifl", "jpeg", "jpg", "jfif", "lut",
"1dl", "exr", "pic", "png", "ppm", "pnm", "pgm", "pbm", "rla", "rpf",
"sgi", "rgba", "rgb", "bw", "tga", "tiff", "tif", "img"
]
allowed_ext = set(
ext.lstrip(".") for ext in IMAGE_EXTENSIONS.union(VIDEO_EXTENSIONS)
)
@staticmethod
def get_colorspace_settings(context):
"""Retuns solved settings for the host context.
"""Returns solved settings for the host context.
Args:
context (publish.Context): publishing context
@ -375,7 +376,10 @@ class ExtractorColormanaged(Extractor):
ext = representation["ext"]
# check extension
self.log.debug("__ ext: `{}`".format(ext))
if ext.lower() not in self.allowed_ext:
# check if ext in lower case is in self.allowed_ext
if ext.lstrip(".").lower() not in self.allowed_ext:
self.log.debug("Extension is not in allowed extensions.")
return
if colorspace_settings is None:

View file

@ -2,7 +2,8 @@ import pyblish.api
from openpype.pipeline import publish
class ExtractColorspaceData(publish.ExtractorColormanaged):
class ExtractColorspaceData(publish.Extractor,
publish.ColormanagedPyblishPluginMixin):
""" Inject Colorspace data to available representations.
Input data: