mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-25 05:14:40 +01:00
Merge branch 'develop' into enhancement/set-version-works-for-all-selection
This commit is contained in:
commit
6461d1ba4f
18 changed files with 638 additions and 390 deletions
|
|
@ -1,7 +1,8 @@
|
|||
from .window import ContextDialog, main
|
||||
from .window import ContextDialog, main, ask_for_context
|
||||
|
||||
|
||||
__all__ = (
|
||||
"ContextDialog",
|
||||
"main",
|
||||
"ask_for_context"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -791,3 +791,12 @@ def main(
|
|||
window.show()
|
||||
app.exec_()
|
||||
controller.store_output()
|
||||
|
||||
|
||||
def ask_for_context(strict=True):
|
||||
controller = ContextDialogController()
|
||||
controller.set_strict(strict)
|
||||
window = ContextDialog(controller=controller)
|
||||
window.exec_()
|
||||
|
||||
return controller.get_selected_context()
|
||||
|
|
|
|||
|
|
@ -182,7 +182,27 @@ class TrayManager:
|
|||
}:
|
||||
envs.pop(key, None)
|
||||
|
||||
# Remove any existing addon path from 'PYTHONPATH'
|
||||
addons_dir = os.environ.get("AYON_ADDONS_DIR", "")
|
||||
if addons_dir:
|
||||
addons_dir = os.path.normpath(addons_dir)
|
||||
addons_dir = addons_dir.lower()
|
||||
|
||||
pythonpath = envs.get("PYTHONPATH") or ""
|
||||
new_python_paths = []
|
||||
for path in pythonpath.split(os.pathsep):
|
||||
if not path:
|
||||
continue
|
||||
path = os.path.normpath(path)
|
||||
if path.lower().startswith(addons_dir):
|
||||
continue
|
||||
new_python_paths.append(path)
|
||||
|
||||
envs["PYTHONPATH"] = os.pathsep.join(new_python_paths)
|
||||
|
||||
# Start new process
|
||||
run_detached_process(args, env=envs)
|
||||
# Exit current tray process
|
||||
self.exit()
|
||||
|
||||
def exit(self):
|
||||
|
|
|
|||
|
|
@ -2,7 +2,10 @@
|
|||
"""Creator plugin for creating publishable Houdini Digital Assets."""
|
||||
import ayon_api
|
||||
|
||||
from ayon_core.pipeline import CreatorError
|
||||
from ayon_core.pipeline import (
|
||||
CreatorError,
|
||||
get_current_project_name
|
||||
)
|
||||
from ayon_houdini.api import plugin
|
||||
import hou
|
||||
|
||||
|
|
@ -56,8 +59,18 @@ class CreateHDA(plugin.HoudiniCreator):
|
|||
raise CreatorError(
|
||||
"cannot create hda from node {}".format(to_hda))
|
||||
|
||||
# Pick a unique type name for HDA product per folder path per project.
|
||||
type_name = (
|
||||
"{project_name}{folder_path}_{node_name}".format(
|
||||
project_name=get_current_project_name(),
|
||||
folder_path=folder_path.replace("/","_"),
|
||||
node_name=node_name
|
||||
)
|
||||
)
|
||||
|
||||
hda_node = to_hda.createDigitalAsset(
|
||||
name=node_name,
|
||||
name=type_name,
|
||||
description=node_name,
|
||||
hda_file_name="$HIP/{}.hda".format(node_name)
|
||||
)
|
||||
hda_node.layoutChildren()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import os
|
||||
from ayon_core.pipeline import get_representation_path
|
||||
from ayon_core.pipeline.load import LoadError
|
||||
from ayon_houdini.api import (
|
||||
pipeline,
|
||||
plugin
|
||||
|
|
@ -28,14 +29,18 @@ class HdaLoader(plugin.HoudiniLoader):
|
|||
# Get the root node
|
||||
obj = hou.node("/obj")
|
||||
|
||||
# Create a unique name
|
||||
counter = 1
|
||||
namespace = namespace or context["folder"]["name"]
|
||||
formatted = "{}_{}".format(namespace, name) if namespace else name
|
||||
node_name = "{0}_{1:03d}".format(formatted, counter)
|
||||
node_name = "{}_{}".format(namespace, name) if namespace else name
|
||||
|
||||
hou.hda.installFile(file_path)
|
||||
hda_node = obj.createNode(name, node_name)
|
||||
|
||||
# Get the type name from the HDA definition.
|
||||
hda_defs = hou.hda.definitionsInFile(file_path)
|
||||
if not hda_defs:
|
||||
raise LoadError(f"No HDA definitions found in file: {file_path}")
|
||||
|
||||
type_name = hda_defs[0].nodeTypeName()
|
||||
hda_node = obj.createNode(type_name, node_name)
|
||||
|
||||
self[:] = [hda_node]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import os
|
||||
from pprint import pformat
|
||||
import re
|
||||
import json
|
||||
import six
|
||||
|
|
@ -37,6 +36,7 @@ from ayon_core.pipeline import (
|
|||
get_current_host_name,
|
||||
get_current_project_name,
|
||||
get_current_folder_path,
|
||||
get_current_task_name,
|
||||
AYON_INSTANCE_ID,
|
||||
AVALON_INSTANCE_ID,
|
||||
)
|
||||
|
|
@ -154,15 +154,9 @@ def set_node_data(node, knobname, data):
|
|||
"""
|
||||
# if exists then update data
|
||||
if knobname in node.knobs():
|
||||
log.debug("Updating knobname `{}` on node `{}`".format(
|
||||
knobname, node.name()
|
||||
))
|
||||
update_node_data(node, knobname, data)
|
||||
return
|
||||
|
||||
log.debug("Creating knobname `{}` on node `{}`".format(
|
||||
knobname, node.name()
|
||||
))
|
||||
# else create new
|
||||
knob_value = JSON_PREFIX + json.dumps(data)
|
||||
knob = nuke.String_Knob(knobname)
|
||||
|
|
@ -513,11 +507,9 @@ def get_avalon_knob_data(node, prefix="avalon:", create=True):
|
|||
# check if the node is avalon tracked
|
||||
try:
|
||||
# check if data available on the node
|
||||
test = node[DATA_GROUP_KEY].value()
|
||||
log.debug("Only testing if data available: `{}`".format(test))
|
||||
except NameError as e:
|
||||
_ = node[DATA_GROUP_KEY].value()
|
||||
except NameError:
|
||||
# if it doesn't then create it
|
||||
log.debug("Creating avalon knob: `{}`".format(e))
|
||||
if create:
|
||||
node = set_avalon_knob_data(node)
|
||||
return get_avalon_knob_data(node)
|
||||
|
|
@ -678,8 +670,6 @@ def get_imageio_node_setting(node_class, plugin_name, product_name):
|
|||
imageio_node = node
|
||||
break
|
||||
|
||||
log.debug("__ imageio_node: {}".format(imageio_node))
|
||||
|
||||
if not imageio_node:
|
||||
return
|
||||
|
||||
|
|
@ -690,8 +680,6 @@ def get_imageio_node_setting(node_class, plugin_name, product_name):
|
|||
product_name,
|
||||
imageio_node["knobs"]
|
||||
)
|
||||
|
||||
log.info("ImageIO node: {}".format(imageio_node))
|
||||
return imageio_node
|
||||
|
||||
|
||||
|
|
@ -706,8 +694,6 @@ def get_imageio_node_override_setting(
|
|||
# find matching override node
|
||||
override_imageio_node = None
|
||||
for onode in override_nodes:
|
||||
log.debug("__ onode: {}".format(onode))
|
||||
log.debug("__ productName: {}".format(product_name))
|
||||
if node_class not in onode["nuke_node_class"]:
|
||||
continue
|
||||
|
||||
|
|
@ -727,7 +713,6 @@ def get_imageio_node_override_setting(
|
|||
override_imageio_node = onode
|
||||
break
|
||||
|
||||
log.debug("__ override_imageio_node: {}".format(override_imageio_node))
|
||||
# add overrides to imageio_node
|
||||
if override_imageio_node:
|
||||
# get all knob names in imageio_node
|
||||
|
|
@ -740,7 +725,6 @@ def get_imageio_node_override_setting(
|
|||
for knob in knobs_settings:
|
||||
# add missing knobs into imageio_node
|
||||
if oknob_name not in knob_names:
|
||||
log.debug("_ adding knob: `{}`".format(oknob))
|
||||
knobs_settings.append(oknob)
|
||||
knob_names.append(oknob_name)
|
||||
continue
|
||||
|
|
@ -750,9 +734,6 @@ def get_imageio_node_override_setting(
|
|||
|
||||
knob_type = knob["type"]
|
||||
# override matching knob name
|
||||
log.debug(
|
||||
"_ overriding knob: `{}` > `{}`".format(knob, oknob)
|
||||
)
|
||||
if not oknob_value:
|
||||
# remove original knob if no value found in oknob
|
||||
knobs_settings.remove(knob)
|
||||
|
|
@ -923,7 +904,6 @@ def writes_version_sync():
|
|||
new_version = "v" + str("{" + ":0>{}".format(padding) + "}").format(
|
||||
int(rootVersion)
|
||||
)
|
||||
log.debug("new_version: {}".format(new_version))
|
||||
except Exception:
|
||||
return
|
||||
|
||||
|
|
@ -936,13 +916,11 @@ def writes_version_sync():
|
|||
|
||||
try:
|
||||
if avalon_knob_data["families"] not in ["render"]:
|
||||
log.debug(avalon_knob_data["families"])
|
||||
continue
|
||||
|
||||
node_file = each["file"].value()
|
||||
|
||||
node_version = "v" + get_version_from_path(node_file)
|
||||
log.debug("node_version: {}".format(node_version))
|
||||
|
||||
node_new_file = node_file.replace(node_version, new_version)
|
||||
each["file"].setValue(node_new_file)
|
||||
|
|
@ -1332,7 +1310,6 @@ def set_node_knobs_from_settings(node, knob_settings, **kwargs):
|
|||
kwargs (dict)[optional]: keys for formattable knob settings
|
||||
"""
|
||||
for knob in knob_settings:
|
||||
log.debug("__ knob: {}".format(pformat(knob)))
|
||||
knob_name = knob["name"]
|
||||
if knob_name not in node.knobs():
|
||||
continue
|
||||
|
|
@ -1486,13 +1463,17 @@ class WorkfileSettings(object):
|
|||
Context._project_entity = project_entity
|
||||
self._project_name = project_name
|
||||
self._folder_path = get_current_folder_path()
|
||||
self._task_name = get_current_task_name()
|
||||
self._folder_entity = ayon_api.get_folder_by_path(
|
||||
project_name, self._folder_path
|
||||
)
|
||||
self._root_node = root_node or nuke.root()
|
||||
self._nodes = self.get_nodes(nodes=nodes)
|
||||
|
||||
self.data = kwargs
|
||||
context_data = get_template_data_with_names(
|
||||
project_name, self._folder_path, self._task_name, "nuke"
|
||||
)
|
||||
self.formatting_data = context_data
|
||||
|
||||
def get_nodes(self, nodes=None, nodes_filter=None):
|
||||
|
||||
|
|
@ -1509,36 +1490,23 @@ class WorkfileSettings(object):
|
|||
for filter in nodes_filter:
|
||||
return [n for n in self._nodes if filter in n.Class()]
|
||||
|
||||
def set_viewers_colorspace(self, viewer_dict):
|
||||
def set_viewers_colorspace(self, imageio_nuke):
|
||||
''' Adds correct colorspace to viewer
|
||||
|
||||
Arguments:
|
||||
viewer_dict (dict): adjustments from presets
|
||||
imageio_nuke (dict): nuke colorspace configurations
|
||||
|
||||
'''
|
||||
if not isinstance(viewer_dict, dict):
|
||||
msg = "set_viewers_colorspace(): argument should be dictionary"
|
||||
log.error(msg)
|
||||
nuke.message(msg)
|
||||
return
|
||||
|
||||
filter_knobs = [
|
||||
"viewerProcess",
|
||||
"wipe_position",
|
||||
"monitorOutOutputTransform"
|
||||
]
|
||||
|
||||
display, viewer = get_viewer_config_from_string(
|
||||
viewer_dict["viewerProcess"]
|
||||
viewer_process = self._display_and_view_formatted(
|
||||
imageio_nuke["viewer"]
|
||||
)
|
||||
viewer_process = create_viewer_profile_string(
|
||||
viewer, display, path_like=False
|
||||
)
|
||||
display, viewer = get_viewer_config_from_string(
|
||||
viewer_dict["output_transform"]
|
||||
)
|
||||
output_transform = create_viewer_profile_string(
|
||||
viewer, display, path_like=False
|
||||
output_transform = self._display_and_view_formatted(
|
||||
imageio_nuke["monitor"]
|
||||
)
|
||||
erased_viewers = []
|
||||
for v in nuke.allNodes(filter="Viewer"):
|
||||
|
|
@ -1547,8 +1515,10 @@ class WorkfileSettings(object):
|
|||
|
||||
if viewer_process not in v["viewerProcess"].value():
|
||||
copy_inputs = v.dependencies()
|
||||
copy_knobs = {k: v[k].value() for k in v.knobs()
|
||||
if k not in filter_knobs}
|
||||
copy_knobs = {
|
||||
k: v[k].value() for k in v.knobs()
|
||||
if k not in filter_knobs
|
||||
}
|
||||
|
||||
# delete viewer with wrong settings
|
||||
erased_viewers.append(v["name"].value())
|
||||
|
|
@ -1574,6 +1544,21 @@ class WorkfileSettings(object):
|
|||
"Attention! Viewer nodes {} were erased."
|
||||
"It had wrong color profile".format(erased_viewers))
|
||||
|
||||
def _display_and_view_formatted(self, view_profile):
|
||||
""" Format display and view profile string
|
||||
|
||||
Args:
|
||||
view_profile (dict): view and display profile
|
||||
|
||||
Returns:
|
||||
str: formatted display and view profile string
|
||||
"""
|
||||
display_view = create_viewer_profile_string(
|
||||
view_profile["view"], view_profile["display"], path_like=False
|
||||
)
|
||||
# format any template tokens used in the string
|
||||
return StringTemplate(display_view).format_strict(self.formatting_data)
|
||||
|
||||
def set_root_colorspace(self, imageio_host):
|
||||
''' Adds correct colorspace to root
|
||||
|
||||
|
|
@ -1590,12 +1575,12 @@ class WorkfileSettings(object):
|
|||
if not config_data:
|
||||
# no ocio config found and no custom path used
|
||||
if self._root_node["colorManagement"].value() \
|
||||
not in color_management:
|
||||
not in color_management:
|
||||
self._root_node["colorManagement"].setValue(color_management)
|
||||
|
||||
# second set ocio version
|
||||
if self._root_node["OCIO_config"].value() \
|
||||
not in native_ocio_config:
|
||||
not in native_ocio_config:
|
||||
self._root_node["OCIO_config"].setValue(native_ocio_config)
|
||||
|
||||
else:
|
||||
|
|
@ -1623,21 +1608,25 @@ class WorkfileSettings(object):
|
|||
if correct_settings:
|
||||
self._set_ocio_config_path_to_workfile(config_data)
|
||||
|
||||
workfile_settings_output = {}
|
||||
# get monitor lut from settings respecting Nuke version differences
|
||||
monitor_lut_data = self._get_monitor_settings(
|
||||
workfile_settings["monitor_out_lut"],
|
||||
workfile_settings["monitor_lut"]
|
||||
)
|
||||
monitor_lut_data.update({
|
||||
"workingSpaceLUT": workfile_settings["working_space"],
|
||||
"int8Lut": workfile_settings["int_8_lut"],
|
||||
"int16Lut": workfile_settings["int_16_lut"],
|
||||
"logLut": workfile_settings["log_lut"],
|
||||
"floatLut": workfile_settings["float_lut"]
|
||||
})
|
||||
workfile_settings_output.update(monitor_lut_data)
|
||||
workfile_settings_output.update(
|
||||
{
|
||||
"workingSpaceLUT": workfile_settings["working_space"],
|
||||
"int8Lut": workfile_settings["int_8_lut"],
|
||||
"int16Lut": workfile_settings["int_16_lut"],
|
||||
"logLut": workfile_settings["log_lut"],
|
||||
"floatLut": workfile_settings["float_lut"],
|
||||
}
|
||||
)
|
||||
|
||||
# then set the rest
|
||||
for knob, value_ in monitor_lut_data.items():
|
||||
for knob, value_ in workfile_settings_output.items():
|
||||
# skip unfilled ocio config path
|
||||
# it will be dict in value
|
||||
if isinstance(value_, dict):
|
||||
|
|
@ -1646,7 +1635,6 @@ class WorkfileSettings(object):
|
|||
if not value_:
|
||||
continue
|
||||
self._root_node[knob].setValue(str(value_))
|
||||
log.debug("nuke.root()['{}'] changed to: {}".format(knob, value_))
|
||||
|
||||
def _get_monitor_settings(self, viewer_lut, monitor_lut):
|
||||
""" Get monitor settings from viewer and monitor lut
|
||||
|
|
@ -1889,8 +1877,6 @@ Reopening Nuke should synchronize these paths and resolve any discrepancies.
|
|||
elif node_data:
|
||||
nuke_imageio_writes = get_write_node_template_attr(node)
|
||||
|
||||
log.debug("nuke_imageio_writes: `{}`".format(nuke_imageio_writes))
|
||||
|
||||
if not nuke_imageio_writes:
|
||||
return
|
||||
|
||||
|
|
@ -1938,7 +1924,6 @@ Reopening Nuke should synchronize these paths and resolve any discrepancies.
|
|||
"to": future
|
||||
}
|
||||
|
||||
log.debug(changes)
|
||||
if changes:
|
||||
msg = "Read nodes are not set to correct colorspace:\n\n"
|
||||
for nname, knobs in changes.items():
|
||||
|
|
@ -1972,7 +1957,7 @@ Reopening Nuke should synchronize these paths and resolve any discrepancies.
|
|||
|
||||
log.info("Setting colorspace to viewers...")
|
||||
try:
|
||||
self.set_viewers_colorspace(nuke_colorspace["viewer"])
|
||||
self.set_viewers_colorspace(nuke_colorspace)
|
||||
except AttributeError as _error:
|
||||
msg = "Set Colorspace to viewer error: {}".format(_error)
|
||||
nuke.message(msg)
|
||||
|
|
@ -2653,8 +2638,6 @@ class NukeDirmap(HostDirmap):
|
|||
def dirmap_routine(self, source_path, destination_path):
|
||||
source_path = source_path.lower().replace(os.sep, '/')
|
||||
destination_path = destination_path.lower().replace(os.sep, '/')
|
||||
log.debug("Map: {} with: {}->{}".format(self.file_name,
|
||||
source_path, destination_path))
|
||||
if platform.system().lower() == "windows":
|
||||
self.file_name = self.file_name.lower().replace(
|
||||
source_path, destination_path)
|
||||
|
|
|
|||
|
|
@ -37,8 +37,6 @@ from .lib import (
|
|||
INSTANCE_DATA_KNOB,
|
||||
get_main_window,
|
||||
WorkfileSettings,
|
||||
# TODO: remove this once workfile builder will be removed
|
||||
process_workfile_builder,
|
||||
start_workfile_template_builder,
|
||||
launch_workfiles_app,
|
||||
check_inventory_versions,
|
||||
|
|
@ -67,6 +65,7 @@ from .workio import (
|
|||
current_file
|
||||
)
|
||||
from .constants import ASSIST
|
||||
from . import push_to_project
|
||||
|
||||
log = Logger.get_logger(__name__)
|
||||
|
||||
|
|
@ -159,9 +158,6 @@ def add_nuke_callbacks():
|
|||
# template builder callbacks
|
||||
nuke.addOnCreate(start_workfile_template_builder, nodeClass="Root")
|
||||
|
||||
# TODO: remove this callback once workfile builder will be removed
|
||||
nuke.addOnCreate(process_workfile_builder, nodeClass="Root")
|
||||
|
||||
# fix ffmpeg settings on script
|
||||
nuke.addOnScriptLoad(on_script_load)
|
||||
|
||||
|
|
@ -332,6 +328,11 @@ def _install_menu():
|
|||
lambda: update_placeholder()
|
||||
)
|
||||
|
||||
menu.addCommand(
|
||||
"Push to Project",
|
||||
lambda: push_to_project.main()
|
||||
)
|
||||
|
||||
menu.addSeparator()
|
||||
menu.addCommand(
|
||||
"Experimental tools...",
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ from ayon_core.lib import (
|
|||
BoolDef,
|
||||
EnumDef
|
||||
)
|
||||
from ayon_core.lib import StringTemplate
|
||||
from ayon_core.pipeline import (
|
||||
LoaderPlugin,
|
||||
CreatorError,
|
||||
|
|
@ -38,7 +39,6 @@ from .lib import (
|
|||
set_node_data,
|
||||
get_node_data,
|
||||
get_view_process_node,
|
||||
get_viewer_config_from_string,
|
||||
get_filenames_without_hash,
|
||||
link_knobs
|
||||
)
|
||||
|
|
@ -638,12 +638,15 @@ class ExporterReview(object):
|
|||
from . import lib as opnlib
|
||||
nuke_imageio = opnlib.get_nuke_imageio_settings()
|
||||
|
||||
# TODO: this is only securing backward compatibility lets remove
|
||||
# this once all projects's anatomy are updated to newer config
|
||||
if "baking" in nuke_imageio.keys():
|
||||
return nuke_imageio["baking"]["viewerProcess"]
|
||||
if nuke_imageio["baking_target"]["enabled"]:
|
||||
return nuke_imageio["baking_target"]
|
||||
else:
|
||||
return nuke_imageio["viewer"]["viewerProcess"]
|
||||
# viewer is having display and view keys only and it is
|
||||
# display_view type
|
||||
return {
|
||||
"type": "display_view",
|
||||
"display_view": nuke_imageio["viewer"],
|
||||
}
|
||||
|
||||
|
||||
class ExporterReviewLut(ExporterReview):
|
||||
|
|
@ -790,6 +793,7 @@ class ExporterReviewMov(ExporterReview):
|
|||
self.viewer_lut_raw = klass.viewer_lut_raw
|
||||
self.write_colorspace = instance.data["colorspace"]
|
||||
self.color_channels = instance.data["color_channels"]
|
||||
self.formatting_data = instance.data["anatomyData"]
|
||||
|
||||
self.name = name or "baked"
|
||||
self.ext = ext or "mov"
|
||||
|
|
@ -837,7 +841,7 @@ class ExporterReviewMov(ExporterReview):
|
|||
with maintained_selection():
|
||||
self.log.info("Saving nodes as file... ")
|
||||
# create nk path
|
||||
path = os.path.splitext(self.path)[0] + ".nk"
|
||||
path = f"{os.path.splitext(self.path)[0]}.nk"
|
||||
# save file to the path
|
||||
if not os.path.exists(os.path.dirname(path)):
|
||||
os.makedirs(os.path.dirname(path))
|
||||
|
|
@ -861,21 +865,20 @@ class ExporterReviewMov(ExporterReview):
|
|||
bake_viewer_process = kwargs["bake_viewer_process"]
|
||||
bake_viewer_input_process_node = kwargs[
|
||||
"bake_viewer_input_process"]
|
||||
viewer_process_override = kwargs[
|
||||
"viewer_process_override"]
|
||||
|
||||
baking_view_profile = (
|
||||
viewer_process_override or self.get_imageio_baking_profile())
|
||||
baking_colorspace = self.get_imageio_baking_profile()
|
||||
|
||||
colorspace_override = kwargs["colorspace_override"]
|
||||
if colorspace_override["enabled"]:
|
||||
baking_colorspace = colorspace_override
|
||||
|
||||
fps = self.instance.context.data["fps"]
|
||||
|
||||
self.log.debug(">> baking_view_profile `{}`".format(
|
||||
baking_view_profile))
|
||||
self.log.debug(f">> baking_view_profile `{baking_colorspace}`")
|
||||
|
||||
add_custom_tags = kwargs.get("add_custom_tags", [])
|
||||
|
||||
self.log.info(
|
||||
"__ add_custom_tags: `{0}`".format(add_custom_tags))
|
||||
self.log.info(f"__ add_custom_tags: `{add_custom_tags}`")
|
||||
|
||||
product_name = self.instance.data["productName"]
|
||||
self._temp_nodes[product_name] = []
|
||||
|
|
@ -932,32 +935,64 @@ class ExporterReviewMov(ExporterReview):
|
|||
|
||||
if not self.viewer_lut_raw:
|
||||
# OCIODisplay
|
||||
dag_node = nuke.createNode("OCIODisplay")
|
||||
if baking_colorspace["type"] == "display_view":
|
||||
display_view = baking_colorspace["display_view"]
|
||||
|
||||
# assign display
|
||||
display, viewer = get_viewer_config_from_string(
|
||||
str(baking_view_profile)
|
||||
)
|
||||
if display:
|
||||
dag_node["display"].setValue(display)
|
||||
message = "OCIODisplay... '{}'"
|
||||
node = nuke.createNode("OCIODisplay")
|
||||
|
||||
# assign viewer
|
||||
dag_node["view"].setValue(viewer)
|
||||
# assign display and view
|
||||
display = display_view["display"]
|
||||
view = display_view["view"]
|
||||
|
||||
if config_data:
|
||||
# convert display and view to colorspace
|
||||
colorspace = get_display_view_colorspace_name(
|
||||
config_path=config_data["path"],
|
||||
display=display,
|
||||
view=viewer
|
||||
# display could not be set in nuke_default config
|
||||
if display:
|
||||
# format display string with anatomy data
|
||||
display = StringTemplate(display).format_strict(
|
||||
self.formatting_data
|
||||
)
|
||||
node["display"].setValue(display)
|
||||
|
||||
# format view string with anatomy data
|
||||
view = StringTemplate(view).format_strict(
|
||||
self.formatting_data)
|
||||
# assign viewer
|
||||
node["view"].setValue(view)
|
||||
|
||||
if config_data:
|
||||
# convert display and view to colorspace
|
||||
colorspace = get_display_view_colorspace_name(
|
||||
config_path=config_data["path"],
|
||||
display=display, view=view
|
||||
)
|
||||
|
||||
# OCIOColorSpace
|
||||
elif baking_colorspace["type"] == "colorspace":
|
||||
baking_colorspace = baking_colorspace["colorspace"]
|
||||
# format colorspace string with anatomy data
|
||||
baking_colorspace = StringTemplate(
|
||||
baking_colorspace).format_strict(self.formatting_data)
|
||||
node = nuke.createNode("OCIOColorSpace")
|
||||
message = "OCIOColorSpace... '{}'"
|
||||
# no need to set input colorspace since it is driven by
|
||||
# working colorspace
|
||||
node["out_colorspace"].setValue(baking_colorspace)
|
||||
colorspace = baking_colorspace
|
||||
|
||||
else:
|
||||
raise ValueError(
|
||||
"Invalid baking color space type: "
|
||||
f"{baking_colorspace['type']}"
|
||||
)
|
||||
|
||||
self._connect_to_above_nodes(
|
||||
dag_node, product_name, "OCIODisplay... `{}`"
|
||||
node, product_name, message
|
||||
)
|
||||
|
||||
# Write node
|
||||
write_node = nuke.createNode("Write")
|
||||
self.log.debug("Path: {}".format(self.path))
|
||||
self.log.debug(f"Path: {self.path}")
|
||||
|
||||
write_node["file"].setValue(str(self.path))
|
||||
write_node["file_type"].setValue(str(self.ext))
|
||||
write_node["channels"].setValue(str(self.color_channels))
|
||||
|
|
@ -981,12 +1016,11 @@ class ExporterReviewMov(ExporterReview):
|
|||
self.log.info("`mov64_write_timecode` knob was not found")
|
||||
|
||||
write_node["raw"].setValue(1)
|
||||
|
||||
# connect
|
||||
write_node.setInput(0, self.previous_node)
|
||||
self._temp_nodes[product_name].append(write_node)
|
||||
self.log.debug("Write... `{}`".format(
|
||||
self._temp_nodes[product_name])
|
||||
)
|
||||
self.log.debug(f"Write... `{self._temp_nodes[product_name]}`")
|
||||
# ---------- end nodes creation
|
||||
|
||||
# ---------- render or save to nk
|
||||
|
|
@ -1014,7 +1048,7 @@ class ExporterReviewMov(ExporterReview):
|
|||
colorspace=colorspace,
|
||||
)
|
||||
|
||||
self.log.debug("Representation... `{}`".format(self.data))
|
||||
self.log.debug(f"Representation... `{self.data}`")
|
||||
|
||||
self.clean_nodes(product_name)
|
||||
nuke.scriptSave()
|
||||
|
|
|
|||
118
server_addon/nuke/client/ayon_nuke/api/push_to_project.py
Normal file
118
server_addon/nuke/client/ayon_nuke/api/push_to_project.py
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
from collections import defaultdict
|
||||
import shutil
|
||||
import os
|
||||
|
||||
from ayon_api import get_project, get_folder_by_id, get_task_by_id
|
||||
from ayon_core.settings import get_project_settings
|
||||
from ayon_core.pipeline import Anatomy, registered_host
|
||||
from ayon_core.pipeline.template_data import get_template_data
|
||||
from ayon_core.pipeline.workfile import get_workdir_with_workdir_data
|
||||
from ayon_core.tools import context_dialog
|
||||
|
||||
from .utils import bake_gizmos_recursively
|
||||
from .lib import MENU_LABEL
|
||||
|
||||
import nuke
|
||||
|
||||
|
||||
def bake_container(container):
|
||||
"""Bake containers to read nodes."""
|
||||
|
||||
node = container["node"]
|
||||
|
||||
# Fetch knobs to remove in order.
|
||||
knobs_to_remove = []
|
||||
remove = False
|
||||
for count in range(0, node.numKnobs()):
|
||||
knob = node.knob(count)
|
||||
|
||||
# All knobs from "AYON" tab knob onwards.
|
||||
if knob.name() == MENU_LABEL:
|
||||
remove = True
|
||||
|
||||
if remove:
|
||||
knobs_to_remove.append(knob)
|
||||
|
||||
# Dont remove knobs from "containerId" onwards.
|
||||
if knob.name() == "containerId":
|
||||
remove = False
|
||||
|
||||
# Knobs needs to be remove in reverse order, because child knobs needs to
|
||||
# be remove first.
|
||||
for knob in reversed(knobs_to_remove):
|
||||
node.removeKnob(knob)
|
||||
|
||||
node["tile_color"].setValue(0)
|
||||
|
||||
|
||||
def main():
|
||||
context = context_dialog.ask_for_context()
|
||||
|
||||
if context is None:
|
||||
return
|
||||
|
||||
# Get workfile path to save to.
|
||||
project_name = context["project_name"]
|
||||
project = get_project(project_name)
|
||||
folder = get_folder_by_id(project_name, context["folder_id"])
|
||||
task = get_task_by_id(project_name, context["task_id"])
|
||||
host = registered_host()
|
||||
project_settings = get_project_settings(project_name)
|
||||
anatomy = Anatomy(project_name)
|
||||
|
||||
workdir_data = get_template_data(
|
||||
project, folder, task, host.name, project_settings
|
||||
)
|
||||
|
||||
workdir = get_workdir_with_workdir_data(
|
||||
workdir_data,
|
||||
project_name,
|
||||
anatomy,
|
||||
project_settings=project_settings
|
||||
)
|
||||
# Save current workfile.
|
||||
current_file = host.current_file()
|
||||
host.save_file(current_file)
|
||||
|
||||
for container in host.ls():
|
||||
bake_container(container)
|
||||
|
||||
# Bake gizmos.
|
||||
bake_gizmos_recursively()
|
||||
|
||||
# Copy all read node files to "resources" folder next to workfile and
|
||||
# change file path.
|
||||
first_frame = int(nuke.root()["first_frame"].value())
|
||||
last_frame = int(nuke.root()["last_frame"].value())
|
||||
files_by_node_name = defaultdict(set)
|
||||
nodes_by_name = {}
|
||||
for count in range(first_frame, last_frame + 1):
|
||||
nuke.frame(count)
|
||||
for node in nuke.allNodes(filter="Read"):
|
||||
files_by_node_name[node.name()].add(
|
||||
nuke.filename(node, nuke.REPLACE)
|
||||
)
|
||||
nodes_by_name[node.name()] = node
|
||||
|
||||
resources_dir = os.path.join(workdir, "resources")
|
||||
for name, files in files_by_node_name.items():
|
||||
dir = os.path.join(resources_dir, name)
|
||||
if not os.path.exists(dir):
|
||||
os.makedirs(dir)
|
||||
|
||||
for f in files:
|
||||
shutil.copy(f, os.path.join(dir, os.path.basename(f)))
|
||||
|
||||
node = nodes_by_name[name]
|
||||
path = node["file"].value().replace(os.path.dirname(f), dir)
|
||||
node["file"].setValue(path.replace("\\", "/"))
|
||||
|
||||
# Save current workfile to new context.
|
||||
pushed_workfile = os.path.join(
|
||||
workdir, os.path.basename(current_file))
|
||||
host.save_file(pushed_workfile)
|
||||
|
||||
# Open current context workfile.
|
||||
host.open_file(current_file)
|
||||
|
||||
nuke.message(f"Pushed to project: \n{pushed_workfile}")
|
||||
|
|
@ -28,29 +28,6 @@ class ExtractReviewIntermediates(publish.Extractor):
|
|||
viewer_lut_raw = None
|
||||
outputs = {}
|
||||
|
||||
@classmethod
|
||||
def apply_settings(cls, project_settings):
|
||||
"""Apply the settings from the deprecated
|
||||
ExtractReviewDataMov plugin for backwards compatibility
|
||||
"""
|
||||
nuke_publish = project_settings["nuke"]["publish"]
|
||||
deprecated_setting = nuke_publish["ExtractReviewDataMov"]
|
||||
current_setting = nuke_publish.get("ExtractReviewIntermediates")
|
||||
if not deprecated_setting["enabled"] and (
|
||||
not current_setting["enabled"]
|
||||
):
|
||||
cls.enabled = False
|
||||
|
||||
if deprecated_setting["enabled"]:
|
||||
# Use deprecated settings if they are still enabled
|
||||
cls.viewer_lut_raw = deprecated_setting["viewer_lut_raw"]
|
||||
cls.outputs = deprecated_setting["outputs"]
|
||||
elif current_setting is None:
|
||||
pass
|
||||
elif current_setting["enabled"]:
|
||||
cls.viewer_lut_raw = current_setting["viewer_lut_raw"]
|
||||
cls.outputs = current_setting["outputs"]
|
||||
|
||||
def process(self, instance):
|
||||
# TODO 'families' should not be included for filtering of outputs
|
||||
families = set(instance.data["families"])
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Package declaring AYON addon 'nuke' version."""
|
||||
__version__ = "0.2.2"
|
||||
__version__ = "0.2.3"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
name = "nuke"
|
||||
title = "Nuke"
|
||||
version = "0.2.2"
|
||||
version = "0.2.3"
|
||||
|
||||
client_dir = "ayon_nuke"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,12 @@
|
|||
from typing import Type
|
||||
from typing import Type, Any
|
||||
|
||||
from ayon_server.addons import BaseServerAddon
|
||||
|
||||
from .settings import NukeSettings, DEFAULT_VALUES
|
||||
from .settings import (
|
||||
NukeSettings,
|
||||
DEFAULT_VALUES,
|
||||
convert_settings_overrides
|
||||
)
|
||||
|
||||
|
||||
class NukeAddon(BaseServerAddon):
|
||||
|
|
@ -11,3 +15,13 @@ class NukeAddon(BaseServerAddon):
|
|||
async def get_default_settings(self):
|
||||
settings_model_cls = self.get_settings_model()
|
||||
return settings_model_cls(**DEFAULT_VALUES)
|
||||
|
||||
async def convert_settings_overrides(
|
||||
self,
|
||||
source_version: str,
|
||||
overrides: dict[str, Any],
|
||||
) -> dict[str, Any]:
|
||||
convert_settings_overrides(source_version, overrides)
|
||||
# Use super conversion
|
||||
return await super().convert_settings_overrides(
|
||||
source_version, overrides)
|
||||
|
|
|
|||
|
|
@ -2,9 +2,12 @@ from .main import (
|
|||
NukeSettings,
|
||||
DEFAULT_VALUES,
|
||||
)
|
||||
from .conversion import convert_settings_overrides
|
||||
|
||||
|
||||
__all__ = (
|
||||
"NukeSettings",
|
||||
"DEFAULT_VALUES",
|
||||
|
||||
"convert_settings_overrides",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -133,3 +133,63 @@ class KnobModel(BaseSettingsModel):
|
|||
"",
|
||||
title="Expression"
|
||||
)
|
||||
|
||||
|
||||
colorspace_types_enum = [
|
||||
{"value": "colorspace", "label": "Use Colorspace"},
|
||||
{"value": "display_view", "label": "Use Display & View"},
|
||||
]
|
||||
|
||||
|
||||
class DisplayAndViewProfileModel(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
|
||||
display: str = SettingsField(
|
||||
"",
|
||||
title="Display",
|
||||
description="What display to use",
|
||||
)
|
||||
|
||||
view: str = SettingsField(
|
||||
"",
|
||||
title="View",
|
||||
description=(
|
||||
"What view to use. Anatomy context tokens can "
|
||||
"be used to dynamically set the value."
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class ColorspaceConfigurationModel(BaseSettingsModel):
|
||||
_isGroup: bool = True
|
||||
|
||||
enabled: bool = SettingsField(
|
||||
False,
|
||||
title="Enabled",
|
||||
description=(
|
||||
"Enable baking target (colorspace or display/view)."
|
||||
),
|
||||
)
|
||||
|
||||
type: str = SettingsField(
|
||||
"colorspace",
|
||||
title="Target baking type",
|
||||
description="Switch between different knob types",
|
||||
enum_resolver=lambda: colorspace_types_enum,
|
||||
conditionalEnum=True,
|
||||
)
|
||||
|
||||
colorspace: str = SettingsField(
|
||||
"",
|
||||
title="Colorspace",
|
||||
description=(
|
||||
"What colorspace name to use. Anatomy context tokens can "
|
||||
"be used to dynamically set the value."
|
||||
),
|
||||
)
|
||||
|
||||
display_view: DisplayAndViewProfileModel = SettingsField(
|
||||
title="Display & View",
|
||||
description="What display & view to use",
|
||||
default_factory=DisplayAndViewProfileModel,
|
||||
)
|
||||
|
|
|
|||
143
server_addon/nuke/server/settings/conversion.py
Normal file
143
server_addon/nuke/server/settings/conversion.py
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
import re
|
||||
from typing import Any
|
||||
|
||||
|
||||
def _get_viewer_config_from_string(input_string):
|
||||
"""Convert string to display and viewer string
|
||||
|
||||
Args:
|
||||
input_string (str): string with viewer
|
||||
|
||||
Raises:
|
||||
IndexError: if more then one slash in input string
|
||||
IndexError: if missing closing bracket
|
||||
|
||||
Returns:
|
||||
tuple[str]: display, viewer
|
||||
"""
|
||||
display = None
|
||||
viewer = input_string
|
||||
# check if () or / or \ in name
|
||||
if "/" in viewer:
|
||||
split = viewer.split("/")
|
||||
|
||||
# rise if more then one column
|
||||
if len(split) > 2:
|
||||
raise IndexError(
|
||||
"Viewer Input string is not correct. "
|
||||
f"More then two `/` slashes! {input_string}"
|
||||
)
|
||||
|
||||
viewer = split[1]
|
||||
display = split[0]
|
||||
elif "(" in viewer:
|
||||
pattern = r"([\w\d\s\.\-]+).*[(](.*)[)]"
|
||||
result_ = re.findall(pattern, viewer)
|
||||
try:
|
||||
result_ = result_.pop()
|
||||
display = str(result_[1]).rstrip()
|
||||
viewer = str(result_[0]).rstrip()
|
||||
except IndexError as e:
|
||||
raise IndexError(
|
||||
"Viewer Input string is not correct. "
|
||||
f"Missing bracket! {input_string}"
|
||||
) from e
|
||||
|
||||
return (display, viewer)
|
||||
|
||||
|
||||
def _convert_imageio_baking_0_2_3(overrides):
|
||||
if "baking" not in overrides:
|
||||
return
|
||||
|
||||
baking_view_process = overrides["baking"].get("viewerProcess")
|
||||
|
||||
if baking_view_process is None:
|
||||
return
|
||||
|
||||
display, view = _get_viewer_config_from_string(baking_view_process)
|
||||
|
||||
overrides["baking_target"] = {
|
||||
"enabled": True,
|
||||
"type": "display_view",
|
||||
"display_view": {
|
||||
"display": display,
|
||||
"view": view,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def _convert_viewers_0_2_3(overrides):
|
||||
if "viewer" not in overrides:
|
||||
return
|
||||
|
||||
viewer = overrides["viewer"]
|
||||
|
||||
if "viewerProcess" in viewer:
|
||||
viewer_process = viewer["viewerProcess"]
|
||||
display, view = _get_viewer_config_from_string(viewer_process)
|
||||
viewer.update({
|
||||
"display": display,
|
||||
"view": view,
|
||||
})
|
||||
if "output_transform" in viewer:
|
||||
output_transform = viewer["output_transform"]
|
||||
display, view = _get_viewer_config_from_string(output_transform)
|
||||
overrides["monitor"] = {
|
||||
"display": display,
|
||||
"view": view,
|
||||
}
|
||||
|
||||
|
||||
def _convert_imageio_configs_0_2_3(overrides):
|
||||
"""Image IO settings had changed.
|
||||
|
||||
0.2.2. is the latest version using the old way.
|
||||
"""
|
||||
if "imageio" not in overrides:
|
||||
return
|
||||
|
||||
imageio_overrides = overrides["imageio"]
|
||||
|
||||
_convert_imageio_baking_0_2_3(imageio_overrides)
|
||||
_convert_viewers_0_2_3(imageio_overrides)
|
||||
|
||||
|
||||
def _convert_extract_intermediate_files_0_2_3(publish_overrides):
|
||||
"""Extract intermediate files settings had changed.
|
||||
|
||||
0.2.2. is the latest version using the old way.
|
||||
"""
|
||||
# override can be either `display/view` or `view (display)`
|
||||
if "ExtractReviewIntermediates" in publish_overrides:
|
||||
extract_review_intermediates = publish_overrides[
|
||||
"ExtractReviewIntermediates"]
|
||||
|
||||
for output in extract_review_intermediates.get("outputs", []):
|
||||
if viewer_process_override := output.get("viewer_process_override"):
|
||||
display, view = _get_viewer_config_from_string(
|
||||
viewer_process_override)
|
||||
|
||||
output["colorspace_override"] = {
|
||||
"enabled": True,
|
||||
"type": "display_view",
|
||||
"display_view": {
|
||||
"display": display,
|
||||
"view": view,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def _convert_publish_plugins(overrides):
|
||||
if "publish" not in overrides:
|
||||
return
|
||||
_convert_extract_intermediate_files_0_2_3(overrides["publish"])
|
||||
|
||||
|
||||
def convert_settings_overrides(
|
||||
source_version: str,
|
||||
overrides: dict[str, Any],
|
||||
) -> dict[str, Any]:
|
||||
_convert_imageio_configs_0_2_3(overrides)
|
||||
_convert_publish_plugins(overrides)
|
||||
return overrides
|
||||
|
|
@ -6,7 +6,10 @@ from ayon_server.settings import (
|
|||
ensure_unique_names,
|
||||
)
|
||||
|
||||
from .common import KnobModel
|
||||
from .common import (
|
||||
KnobModel,
|
||||
ColorspaceConfigurationModel,
|
||||
)
|
||||
|
||||
|
||||
class NodesModel(BaseSettingsModel):
|
||||
|
|
@ -52,6 +55,8 @@ class OverrideNodesModel(NodesModel):
|
|||
|
||||
|
||||
class NodesSetting(BaseSettingsModel):
|
||||
_isGroup: bool = True
|
||||
|
||||
required_nodes: list[RequiredNodesModel] = SettingsField(
|
||||
title="Plugin required",
|
||||
default_factory=list
|
||||
|
|
@ -83,6 +88,8 @@ def ocio_configs_switcher_enum():
|
|||
class WorkfileColorspaceSettings(BaseSettingsModel):
|
||||
"""Nuke workfile colorspace preset. """
|
||||
|
||||
_isGroup: bool = True
|
||||
|
||||
color_management: Literal["Nuke", "OCIO"] = SettingsField(
|
||||
title="Color Management Workflow"
|
||||
)
|
||||
|
|
@ -125,6 +132,8 @@ class ReadColorspaceRulesItems(BaseSettingsModel):
|
|||
|
||||
|
||||
class RegexInputsModel(BaseSettingsModel):
|
||||
_isGroup: bool = True
|
||||
|
||||
inputs: list[ReadColorspaceRulesItems] = SettingsField(
|
||||
default_factory=list,
|
||||
title="Inputs"
|
||||
|
|
@ -132,15 +141,44 @@ class RegexInputsModel(BaseSettingsModel):
|
|||
|
||||
|
||||
class ViewProcessModel(BaseSettingsModel):
|
||||
viewerProcess: str = SettingsField(
|
||||
title="Viewer Process Name"
|
||||
_isGroup: bool = True
|
||||
|
||||
display: str = SettingsField(
|
||||
"",
|
||||
title="Display",
|
||||
description="What display to use",
|
||||
)
|
||||
output_transform: str = SettingsField(
|
||||
title="Output Transform"
|
||||
view: str = SettingsField(
|
||||
"",
|
||||
title="View",
|
||||
description=(
|
||||
"What view to use. Anatomy context tokens can "
|
||||
"be used to dynamically set the value."
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class MonitorProcessModel(BaseSettingsModel):
|
||||
_isGroup: bool = True
|
||||
|
||||
display: str = SettingsField(
|
||||
"",
|
||||
title="Display",
|
||||
description="What display to use",
|
||||
)
|
||||
view: str = SettingsField(
|
||||
"",
|
||||
title="View",
|
||||
description=(
|
||||
"What view to use. Anatomy context tokens can "
|
||||
"be used to dynamically set the value."
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class ImageIOConfigModel(BaseSettingsModel):
|
||||
_isGroup: bool = True
|
||||
|
||||
override_global_config: bool = SettingsField(
|
||||
False,
|
||||
title="Override global OCIO config"
|
||||
|
|
@ -159,6 +197,8 @@ class ImageIOFileRuleModel(BaseSettingsModel):
|
|||
|
||||
|
||||
class ImageIOFileRulesModel(BaseSettingsModel):
|
||||
_isGroup: bool = True
|
||||
|
||||
activate_host_rules: bool = SettingsField(False)
|
||||
rules: list[ImageIOFileRuleModel] = SettingsField(
|
||||
default_factory=list,
|
||||
|
|
@ -173,14 +213,7 @@ class ImageIOFileRulesModel(BaseSettingsModel):
|
|||
|
||||
class ImageIOSettings(BaseSettingsModel):
|
||||
"""Nuke color management project settings. """
|
||||
_isGroup: bool = True
|
||||
|
||||
"""# TODO: enhance settings with host api:
|
||||
to restructure settings for simplification.
|
||||
|
||||
now: nuke/imageio/viewer/viewerProcess
|
||||
future: nuke/imageio/viewer
|
||||
"""
|
||||
activate_host_color_management: bool = SettingsField(
|
||||
True, title="Enable Color Management")
|
||||
ocio_config: ImageIOConfigModel = SettingsField(
|
||||
|
|
@ -197,18 +230,13 @@ class ImageIOSettings(BaseSettingsModel):
|
|||
description="""Viewer profile is used during
|
||||
Creation of new viewer node at knob viewerProcess"""
|
||||
)
|
||||
|
||||
"""# TODO: enhance settings with host api:
|
||||
to restructure settings for simplification.
|
||||
|
||||
now: nuke/imageio/baking/viewerProcess
|
||||
future: nuke/imageio/baking
|
||||
"""
|
||||
baking: ViewProcessModel = SettingsField(
|
||||
default_factory=ViewProcessModel,
|
||||
title="Baking",
|
||||
description="""Baking profile is used during
|
||||
publishing baked colorspace data at knob viewerProcess"""
|
||||
monitor: MonitorProcessModel = SettingsField(
|
||||
default_factory=MonitorProcessModel,
|
||||
title="Monitor OUT"
|
||||
)
|
||||
baking_target: ColorspaceConfigurationModel = SettingsField(
|
||||
default_factory=ColorspaceConfigurationModel,
|
||||
title="Baking Target Colorspace"
|
||||
)
|
||||
|
||||
workfile: WorkfileColorspaceSettings = SettingsField(
|
||||
|
|
@ -231,13 +259,12 @@ class ImageIOSettings(BaseSettingsModel):
|
|||
|
||||
|
||||
DEFAULT_IMAGEIO_SETTINGS = {
|
||||
"viewer": {
|
||||
"viewerProcess": "ACES/sRGB",
|
||||
"output_transform": "ACES/sRGB"
|
||||
},
|
||||
"baking": {
|
||||
"viewerProcess": "ACES/Rec.709",
|
||||
"output_transform": "ACES/Rec.709"
|
||||
"viewer": {"display": "ACES", "view": "sRGB"},
|
||||
"monitor": {"display": "ACES", "view": "Rec.709"},
|
||||
"baking_target": {
|
||||
"enabled": True,
|
||||
"type": "colorspace",
|
||||
"colorspace": "Output - Rec.709",
|
||||
},
|
||||
"workfile": {
|
||||
"color_management": "OCIO",
|
||||
|
|
@ -248,170 +275,67 @@ DEFAULT_IMAGEIO_SETTINGS = {
|
|||
"int_8_lut": "role_matte_paint",
|
||||
"int_16_lut": "role_texture_paint",
|
||||
"log_lut": "role_compositing_log",
|
||||
"float_lut": "role_scene_linear"
|
||||
"float_lut": "role_scene_linear",
|
||||
},
|
||||
"nodes": {
|
||||
"required_nodes": [
|
||||
{
|
||||
"plugins": [
|
||||
"CreateWriteRender"
|
||||
],
|
||||
"plugins": ["CreateWriteRender"],
|
||||
"nuke_node_class": "Write",
|
||||
"knobs": [
|
||||
{
|
||||
"type": "text",
|
||||
"name": "file_type",
|
||||
"text": "exr"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "datatype",
|
||||
"text": "16 bit half"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "compression",
|
||||
"text": "Zip (1 scanline)"
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"name": "autocrop",
|
||||
"boolean": True
|
||||
},
|
||||
{"type": "text", "name": "file_type", "text": "exr"},
|
||||
{"type": "text", "name": "datatype", "text": "16 bit half"},
|
||||
{"type": "text", "name": "compression", "text": "Zip (1 scanline)"},
|
||||
{"type": "boolean", "name": "autocrop", "boolean": True},
|
||||
{
|
||||
"type": "color_gui",
|
||||
"name": "tile_color",
|
||||
"color_gui": [
|
||||
186,
|
||||
35,
|
||||
35
|
||||
]
|
||||
"color_gui": [186, 35, 35],
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "channels",
|
||||
"text": "rgb"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "colorspace",
|
||||
"text": "scene_linear"
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"name": "create_directories",
|
||||
"boolean": True
|
||||
}
|
||||
]
|
||||
{"type": "text", "name": "channels", "text": "rgb"},
|
||||
{"type": "text", "name": "colorspace", "text": "scene_linear"},
|
||||
{"type": "boolean", "name": "create_directories", "boolean": True},
|
||||
],
|
||||
},
|
||||
{
|
||||
"plugins": [
|
||||
"CreateWritePrerender"
|
||||
],
|
||||
"plugins": ["CreateWritePrerender"],
|
||||
"nuke_node_class": "Write",
|
||||
"knobs": [
|
||||
{
|
||||
"type": "text",
|
||||
"name": "file_type",
|
||||
"text": "exr"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "datatype",
|
||||
"text": "16 bit half"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "compression",
|
||||
"text": "Zip (1 scanline)"
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"name": "autocrop",
|
||||
"boolean": True
|
||||
},
|
||||
{"type": "text", "name": "file_type", "text": "exr"},
|
||||
{"type": "text", "name": "datatype", "text": "16 bit half"},
|
||||
{"type": "text", "name": "compression", "text": "Zip (1 scanline)"},
|
||||
{"type": "boolean", "name": "autocrop", "boolean": True},
|
||||
{
|
||||
"type": "color_gui",
|
||||
"name": "tile_color",
|
||||
"color_gui": [
|
||||
171,
|
||||
171,
|
||||
10
|
||||
]
|
||||
"color_gui": [171, 171, 10],
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "channels",
|
||||
"text": "rgb"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "colorspace",
|
||||
"text": "scene_linear"
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"name": "create_directories",
|
||||
"boolean": True
|
||||
}
|
||||
]
|
||||
{"type": "text", "name": "channels", "text": "rgb"},
|
||||
{"type": "text", "name": "colorspace", "text": "scene_linear"},
|
||||
{"type": "boolean", "name": "create_directories", "boolean": True},
|
||||
],
|
||||
},
|
||||
{
|
||||
"plugins": [
|
||||
"CreateWriteImage"
|
||||
],
|
||||
"plugins": ["CreateWriteImage"],
|
||||
"nuke_node_class": "Write",
|
||||
"knobs": [
|
||||
{
|
||||
"type": "text",
|
||||
"name": "file_type",
|
||||
"text": "tiff"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "datatype",
|
||||
"text": "16 bit"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "compression",
|
||||
"text": "Deflate"
|
||||
},
|
||||
{"type": "text", "name": "file_type", "text": "tiff"},
|
||||
{"type": "text", "name": "datatype", "text": "16 bit"},
|
||||
{"type": "text", "name": "compression", "text": "Deflate"},
|
||||
{
|
||||
"type": "color_gui",
|
||||
"name": "tile_color",
|
||||
"color_gui": [
|
||||
56,
|
||||
162,
|
||||
7
|
||||
]
|
||||
"color_gui": [56, 162, 7],
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "channels",
|
||||
"text": "rgb"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "colorspace",
|
||||
"text": "texture_paint"
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"name": "create_directories",
|
||||
"boolean": True
|
||||
}
|
||||
]
|
||||
}
|
||||
{"type": "text", "name": "channels", "text": "rgb"},
|
||||
{"type": "text", "name": "colorspace", "text": "texture_paint"},
|
||||
{"type": "boolean", "name": "create_directories", "boolean": True},
|
||||
],
|
||||
},
|
||||
],
|
||||
"override_nodes": []
|
||||
"override_nodes": [],
|
||||
},
|
||||
"regex_inputs": {
|
||||
"inputs": [
|
||||
{
|
||||
"regex": "(beauty).*(?=.exr)",
|
||||
"colorspace": "linear"
|
||||
}
|
||||
]
|
||||
}
|
||||
"inputs": [{"regex": "(beauty).*(?=.exr)", "colorspace": "linear"}]
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,11 @@ from ayon_server.settings import (
|
|||
ensure_unique_names,
|
||||
task_types_enum
|
||||
)
|
||||
from .common import KnobModel, validate_json_dict
|
||||
from .common import (
|
||||
KnobModel,
|
||||
ColorspaceConfigurationModel,
|
||||
validate_json_dict,
|
||||
)
|
||||
|
||||
|
||||
def nuke_render_publish_types_enum():
|
||||
|
|
@ -130,19 +134,22 @@ class IntermediateOutputModel(BaseSettingsModel):
|
|||
title="Filter", default_factory=BakingStreamFilterModel)
|
||||
read_raw: bool = SettingsField(
|
||||
False,
|
||||
title="Read raw switch"
|
||||
)
|
||||
viewer_process_override: str = SettingsField(
|
||||
"",
|
||||
title="Viewer process override"
|
||||
title="Input read node RAW switch"
|
||||
)
|
||||
bake_viewer_process: bool = SettingsField(
|
||||
True,
|
||||
title="Bake viewer process"
|
||||
title="Bake viewer process",
|
||||
section="Baking target",
|
||||
)
|
||||
colorspace_override: ColorspaceConfigurationModel = SettingsField(
|
||||
title="Target baking colorspace override",
|
||||
description="Override Baking target with colorspace or display/view",
|
||||
default_factory=ColorspaceConfigurationModel
|
||||
)
|
||||
bake_viewer_input_process: bool = SettingsField(
|
||||
True,
|
||||
title="Bake viewer input process node (LUT)"
|
||||
title="Bake viewer input process node (LUT)",
|
||||
section="Baking additional",
|
||||
)
|
||||
reformat_nodes_config: ReformatNodesConfigModel = SettingsField(
|
||||
default_factory=ReformatNodesConfigModel,
|
||||
|
|
@ -155,18 +162,6 @@ class IntermediateOutputModel(BaseSettingsModel):
|
|||
title="Custom tags", default_factory=list)
|
||||
|
||||
|
||||
class ExtractReviewDataMovModel(BaseSettingsModel):
|
||||
"""[deprecated] use Extract Review Data Baking
|
||||
Streams instead.
|
||||
"""
|
||||
enabled: bool = SettingsField(title="Enabled")
|
||||
viewer_lut_raw: bool = SettingsField(title="Viewer lut raw")
|
||||
outputs: list[IntermediateOutputModel] = SettingsField(
|
||||
default_factory=list,
|
||||
title="Baking streams"
|
||||
)
|
||||
|
||||
|
||||
class ExtractReviewIntermediatesModel(BaseSettingsModel):
|
||||
enabled: bool = SettingsField(title="Enabled")
|
||||
viewer_lut_raw: bool = SettingsField(title="Viewer lut raw")
|
||||
|
|
@ -259,10 +254,6 @@ class PublishPluginsModel(BaseSettingsModel):
|
|||
title="Extract Review Data Lut",
|
||||
default_factory=ExtractReviewDataLutModel
|
||||
)
|
||||
ExtractReviewDataMov: ExtractReviewDataMovModel = SettingsField(
|
||||
title="Extract Review Data Mov",
|
||||
default_factory=ExtractReviewDataMovModel
|
||||
)
|
||||
ExtractReviewIntermediates: ExtractReviewIntermediatesModel = (
|
||||
SettingsField(
|
||||
title="Extract Review Intermediates",
|
||||
|
|
@ -332,62 +323,6 @@ DEFAULT_PUBLISH_PLUGIN_SETTINGS = {
|
|||
"ExtractReviewDataLut": {
|
||||
"enabled": False
|
||||
},
|
||||
"ExtractReviewDataMov": {
|
||||
"enabled": False,
|
||||
"viewer_lut_raw": False,
|
||||
"outputs": [
|
||||
{
|
||||
"name": "baking",
|
||||
"publish": False,
|
||||
"filter": {
|
||||
"task_types": [],
|
||||
"product_types": [],
|
||||
"product_names": []
|
||||
},
|
||||
"read_raw": False,
|
||||
"viewer_process_override": "",
|
||||
"bake_viewer_process": True,
|
||||
"bake_viewer_input_process": True,
|
||||
"reformat_nodes_config": {
|
||||
"enabled": False,
|
||||
"reposition_nodes": [
|
||||
{
|
||||
"node_class": "Reformat",
|
||||
"knobs": [
|
||||
{
|
||||
"type": "text",
|
||||
"name": "type",
|
||||
"text": "to format"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "format",
|
||||
"text": "HD_1080"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "filter",
|
||||
"text": "Lanczos6"
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"name": "black_outside",
|
||||
"boolean": True
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"name": "pbb",
|
||||
"boolean": False
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"extension": "mov",
|
||||
"add_custom_tags": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"ExtractReviewIntermediates": {
|
||||
"enabled": True,
|
||||
"viewer_lut_raw": False,
|
||||
|
|
@ -401,7 +336,15 @@ DEFAULT_PUBLISH_PLUGIN_SETTINGS = {
|
|||
"product_names": []
|
||||
},
|
||||
"read_raw": False,
|
||||
"viewer_process_override": "",
|
||||
"colorspace_override": {
|
||||
"enabled": False,
|
||||
"type": "colorspace",
|
||||
"colorspace": "",
|
||||
"display_view": {
|
||||
"display": "",
|
||||
"view": ""
|
||||
}
|
||||
},
|
||||
"bake_viewer_process": True,
|
||||
"bake_viewer_input_process": True,
|
||||
"reformat_nodes_config": {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue