mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
Merge pull request #5322 from ynput/enhancement/OP-5600_Houdini-manage-colorspaces-in-review-ROP
This commit is contained in:
commit
ea94bacef6
9 changed files with 283 additions and 7 deletions
|
|
@ -1,7 +1,7 @@
|
|||
import attr
|
||||
import hou
|
||||
from openpype.hosts.houdini.api.lib import get_color_management_preferences
|
||||
|
||||
from openpype.pipeline.colorspace import get_display_view_colorspace_name
|
||||
|
||||
@attr.s
|
||||
class LayerMetadata(object):
|
||||
|
|
@ -54,3 +54,16 @@ class ARenderProduct(object):
|
|||
)
|
||||
]
|
||||
return colorspace_data
|
||||
|
||||
|
||||
def get_default_display_view_colorspace():
|
||||
"""Returns the colorspace attribute of the default (display, view) pair.
|
||||
|
||||
It's used for 'ociocolorspace' parm in OpenGL Node."""
|
||||
|
||||
prefs = get_color_management_preferences()
|
||||
return get_display_view_colorspace_name(
|
||||
config_path=prefs["config"],
|
||||
display=prefs["display"],
|
||||
view=prefs["view"]
|
||||
)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
from openpype.hosts.houdini.api import plugin
|
||||
from openpype.lib import EnumDef, BoolDef, NumberDef
|
||||
|
||||
import os
|
||||
import hou
|
||||
|
||||
|
||||
class CreateReview(plugin.HoudiniCreator):
|
||||
"""Review with OpenGL ROP"""
|
||||
|
|
@ -13,7 +16,6 @@ class CreateReview(plugin.HoudiniCreator):
|
|||
icon = "video-camera"
|
||||
|
||||
def create(self, subset_name, instance_data, pre_create_data):
|
||||
import hou
|
||||
|
||||
instance_data.pop("active", None)
|
||||
instance_data.update({"node_type": "opengl"})
|
||||
|
|
@ -82,6 +84,11 @@ class CreateReview(plugin.HoudiniCreator):
|
|||
|
||||
instance_node.setParms(parms)
|
||||
|
||||
# Set OCIO Colorspace to the default output colorspace
|
||||
# if there's OCIO
|
||||
if os.getenv("OCIO"):
|
||||
self.set_colorcorrect_to_default_view_space(instance_node)
|
||||
|
||||
to_lock = ["id", "family"]
|
||||
|
||||
self.lock_parameters(instance_node, to_lock)
|
||||
|
|
@ -123,3 +130,23 @@ class CreateReview(plugin.HoudiniCreator):
|
|||
minimum=0.0001,
|
||||
decimals=3)
|
||||
]
|
||||
|
||||
def set_colorcorrect_to_default_view_space(self,
|
||||
instance_node):
|
||||
"""Set ociocolorspace to the default output space."""
|
||||
from openpype.hosts.houdini.api.colorspace import get_default_display_view_colorspace # noqa
|
||||
|
||||
# set Color Correction parameter to OpenColorIO
|
||||
instance_node.setParms({"colorcorrect": 2})
|
||||
|
||||
# Get default view space for ociocolorspace parm.
|
||||
default_view_space = get_default_display_view_colorspace()
|
||||
instance_node.setParms(
|
||||
{"ociocolorspace": default_view_space}
|
||||
)
|
||||
|
||||
self.log.debug(
|
||||
"'OCIO Colorspace' parm on '{}' has been set to "
|
||||
"the default view color space '{}'"
|
||||
.format(instance_node, default_view_space)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,90 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import pyblish.api
|
||||
from openpype.pipeline import (
|
||||
PublishValidationError,
|
||||
OptionalPyblishPluginMixin
|
||||
)
|
||||
from openpype.pipeline.publish import RepairAction
|
||||
from openpype.hosts.houdini.api.action import SelectROPAction
|
||||
|
||||
import os
|
||||
import hou
|
||||
|
||||
|
||||
class SetDefaultViewSpaceAction(RepairAction):
|
||||
label = "Set default view colorspace"
|
||||
icon = "mdi.monitor"
|
||||
|
||||
|
||||
class ValidateReviewColorspace(pyblish.api.InstancePlugin,
|
||||
OptionalPyblishPluginMixin):
|
||||
"""Validate Review Colorspace parameters.
|
||||
|
||||
It checks if 'OCIO Colorspace' parameter was set to valid value.
|
||||
"""
|
||||
|
||||
order = pyblish.api.ValidatorOrder + 0.1
|
||||
families = ["review"]
|
||||
hosts = ["houdini"]
|
||||
label = "Validate Review Colorspace"
|
||||
actions = [SetDefaultViewSpaceAction, SelectROPAction]
|
||||
|
||||
optional = True
|
||||
|
||||
def process(self, instance):
|
||||
|
||||
if not self.is_active(instance.data):
|
||||
return
|
||||
|
||||
if os.getenv("OCIO") is None:
|
||||
self.log.debug(
|
||||
"Using Houdini's Default Color Management, "
|
||||
" skipping check.."
|
||||
)
|
||||
return
|
||||
|
||||
rop_node = hou.node(instance.data["instance_node"])
|
||||
if rop_node.evalParm("colorcorrect") != 2:
|
||||
# any colorspace settings other than default requires
|
||||
# 'Color Correct' parm to be set to 'OpenColorIO'
|
||||
raise PublishValidationError(
|
||||
"'Color Correction' parm on '{}' ROP must be set to"
|
||||
" 'OpenColorIO'".format(rop_node.path())
|
||||
)
|
||||
|
||||
if rop_node.evalParm("ociocolorspace") not in \
|
||||
hou.Color.ocio_spaces():
|
||||
|
||||
raise PublishValidationError(
|
||||
"Invalid value: Colorspace name doesn't exist.\n"
|
||||
"Check 'OCIO Colorspace' parameter on '{}' ROP"
|
||||
.format(rop_node.path())
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def repair(cls, instance):
|
||||
"""Set Default View Space Action.
|
||||
|
||||
It is a helper action more than a repair action,
|
||||
used to set colorspace on opengl node to the default view.
|
||||
"""
|
||||
from openpype.hosts.houdini.api.colorspace import get_default_display_view_colorspace # noqa
|
||||
|
||||
rop_node = hou.node(instance.data["instance_node"])
|
||||
|
||||
if rop_node.evalParm("colorcorrect") != 2:
|
||||
rop_node.setParms({"colorcorrect": 2})
|
||||
cls.log.debug(
|
||||
"'Color Correction' parm on '{}' has been set to"
|
||||
" 'OpenColorIO'".format(rop_node.path())
|
||||
)
|
||||
|
||||
# Get default view colorspace name
|
||||
default_view_space = get_default_display_view_colorspace()
|
||||
|
||||
rop_node.setParms({"ociocolorspace": default_view_space})
|
||||
cls.log.info(
|
||||
"'OCIO Colorspace' parm on '{}' has been set to "
|
||||
"the default view color space '{}'"
|
||||
.format(rop_node, default_view_space)
|
||||
)
|
||||
|
|
@ -721,3 +721,58 @@ def set_colorspace_data_to_representation(
|
|||
|
||||
# update data key
|
||||
representation["colorspaceData"] = colorspace_data
|
||||
|
||||
|
||||
def get_display_view_colorspace_name(config_path, display, view):
|
||||
"""Returns the colorspace attribute of the (display, view) pair.
|
||||
|
||||
Args:
|
||||
config_path (str): path string leading to config.ocio
|
||||
display (str): display name e.g. "ACES"
|
||||
view (str): view name e.g. "sRGB"
|
||||
|
||||
Returns:
|
||||
view color space name (str) e.g. "Output - sRGB"
|
||||
"""
|
||||
|
||||
if not compatibility_check():
|
||||
# python environment is not compatible with PyOpenColorIO
|
||||
# needs to be run in subprocess
|
||||
return get_display_view_colorspace_subprocess(config_path,
|
||||
display, view)
|
||||
|
||||
from openpype.scripts.ocio_wrapper import _get_display_view_colorspace_name # noqa
|
||||
|
||||
return _get_display_view_colorspace_name(config_path, display, view)
|
||||
|
||||
|
||||
def get_display_view_colorspace_subprocess(config_path, display, view):
|
||||
"""Returns the colorspace attribute of the (display, view) pair
|
||||
via subprocess.
|
||||
|
||||
Args:
|
||||
config_path (str): path string leading to config.ocio
|
||||
display (str): display name e.g. "ACES"
|
||||
view (str): view name e.g. "sRGB"
|
||||
|
||||
Returns:
|
||||
view color space name (str) e.g. "Output - sRGB"
|
||||
"""
|
||||
|
||||
with _make_temp_json_file() as tmp_json_path:
|
||||
# Prepare subprocess arguments
|
||||
args = [
|
||||
"run", get_ocio_config_script_path(),
|
||||
"config", "get_display_view_colorspace_name",
|
||||
"--in_path", config_path,
|
||||
"--out_path", tmp_json_path,
|
||||
"--display", display,
|
||||
"--view", view
|
||||
]
|
||||
log.debug("Executing: {}".format(" ".join(args)))
|
||||
|
||||
run_openpype_process(*args, logger=log)
|
||||
|
||||
# return default view colorspace name
|
||||
with open(tmp_json_path, "r") as f:
|
||||
return json.load(f)
|
||||
|
|
|
|||
|
|
@ -174,5 +174,79 @@ def _get_views_data(config_path):
|
|||
return data
|
||||
|
||||
|
||||
def _get_display_view_colorspace_name(config_path, display, view):
|
||||
"""Returns the colorspace attribute of the (display, view) pair.
|
||||
|
||||
Args:
|
||||
config_path (str): path string leading to config.ocio
|
||||
display (str): display name e.g. "ACES"
|
||||
view (str): view name e.g. "sRGB"
|
||||
|
||||
|
||||
Raises:
|
||||
IOError: Input config does not exist.
|
||||
|
||||
Returns:
|
||||
view color space name (str) e.g. "Output - sRGB"
|
||||
"""
|
||||
|
||||
config_path = Path(config_path)
|
||||
|
||||
if not config_path.is_file():
|
||||
raise IOError("Input path should be `config.ocio` file")
|
||||
|
||||
config = ocio.Config.CreateFromFile(str(config_path))
|
||||
colorspace = config.getDisplayViewColorSpaceName(display, view)
|
||||
|
||||
return colorspace
|
||||
|
||||
|
||||
@config.command(
|
||||
name="get_display_view_colorspace_name",
|
||||
help=(
|
||||
"return default view colorspace name "
|
||||
"for the given display and view "
|
||||
"--path input arg is required"
|
||||
)
|
||||
)
|
||||
@click.option("--in_path", required=True,
|
||||
help="path where to read ocio config file",
|
||||
type=click.Path(exists=True))
|
||||
@click.option("--out_path", required=True,
|
||||
help="path where to write output json file",
|
||||
type=click.Path())
|
||||
@click.option("--display", required=True,
|
||||
help="display name",
|
||||
type=click.STRING)
|
||||
@click.option("--view", required=True,
|
||||
help="view name",
|
||||
type=click.STRING)
|
||||
def get_display_view_colorspace_name(in_path, out_path,
|
||||
display, view):
|
||||
"""Aggregate view colorspace name to file.
|
||||
|
||||
Wrapper command for processes without access to OpenColorIO
|
||||
|
||||
Args:
|
||||
in_path (str): config file path string
|
||||
out_path (str): temp json file path string
|
||||
display (str): display name e.g. "ACES"
|
||||
view (str): view name e.g. "sRGB"
|
||||
|
||||
Example of use:
|
||||
> pyton.exe ./ocio_wrapper.py config \
|
||||
get_display_view_colorspace_name --in_path=<path> \
|
||||
--out_path=<path> --display=<display> --view=<view>
|
||||
"""
|
||||
|
||||
out_data = _get_display_view_colorspace_name(in_path,
|
||||
display,
|
||||
view)
|
||||
|
||||
with open(out_path, "w") as f:
|
||||
json.dump(out_data, f)
|
||||
|
||||
print(f"Display view colorspace saved to '{out_path}'")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -93,6 +93,11 @@
|
|||
"$JOB"
|
||||
]
|
||||
},
|
||||
"ValidateReviewColorspace": {
|
||||
"enabled": true,
|
||||
"optional": true,
|
||||
"active": true
|
||||
},
|
||||
"ValidateContainers": {
|
||||
"enabled": true,
|
||||
"optional": true,
|
||||
|
|
|
|||
|
|
@ -40,6 +40,10 @@
|
|||
"type": "schema_template",
|
||||
"name": "template_publish_plugin",
|
||||
"template_data": [
|
||||
{
|
||||
"key": "ValidateReviewColorspace",
|
||||
"label": "Validate Review Colorspace"
|
||||
},
|
||||
{
|
||||
"key": "ValidateContainers",
|
||||
"label": "ValidateContainers"
|
||||
|
|
@ -47,4 +51,4 @@
|
|||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ class ValidateWorkfilePathsModel(BaseSettingsModel):
|
|||
)
|
||||
|
||||
|
||||
class ValidateContainersModel(BaseSettingsModel):
|
||||
class BasicValidateModel(BaseSettingsModel):
|
||||
enabled: bool = Field(title="Enabled")
|
||||
optional: bool = Field(title="Optional")
|
||||
active: bool = Field(title="Active")
|
||||
|
|
@ -130,8 +130,11 @@ class PublishPluginsModel(BaseSettingsModel):
|
|||
ValidateWorkfilePaths: ValidateWorkfilePathsModel = Field(
|
||||
default_factory=ValidateWorkfilePathsModel,
|
||||
title="Validate workfile paths settings.")
|
||||
ValidateContainers: ValidateContainersModel = Field(
|
||||
default_factory=ValidateContainersModel,
|
||||
ValidateReviewColorspace: BasicValidateModel = Field(
|
||||
default_factory=BasicValidateModel,
|
||||
title="Validate Review Colorspace.")
|
||||
ValidateContainers: BasicValidateModel = Field(
|
||||
default_factory=BasicValidateModel,
|
||||
title="Validate Latest Containers.")
|
||||
|
||||
|
||||
|
|
@ -148,6 +151,11 @@ DEFAULT_HOUDINI_PUBLISH_SETTINGS = {
|
|||
"$JOB"
|
||||
]
|
||||
},
|
||||
"ValidateReviewColorspace": {
|
||||
"enabled": True,
|
||||
"optional": True,
|
||||
"active": True
|
||||
},
|
||||
"ValidateContainers": {
|
||||
"enabled": True,
|
||||
"optional": True,
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
__version__ = "0.1.1"
|
||||
__version__ = "0.1.2"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue