Merge pull request #70 from ynput/enhancement/OP-8204_Nuke-use-AYON-settings

Nuke: Use AYON settings
This commit is contained in:
Jakub Trllo 2024-02-22 15:01:49 +01:00 committed by GitHub
commit abd44277cb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 197 additions and 374 deletions

View file

@ -720,17 +720,17 @@ def get_created_node_imageio_setting_legacy(nodeclass, creator, subset):
"`{}`: Missing mandatory kwargs `host`, `cls`".format(__file__))
imageio_nodes = get_nuke_imageio_settings()["nodes"]
required_nodes = imageio_nodes["requiredNodes"]
required_nodes = imageio_nodes["required_nodes"]
# HACK: for backward compatibility this needs to be optional
override_nodes = imageio_nodes.get("overrideNodes", [])
override_nodes = imageio_nodes.get("override_nodes", [])
imageio_node = None
for node in required_nodes:
log.info(node)
if (
nodeclass in node["nukeNodeClass"]
and creator in node["plugins"]
nodeclass in node["nuke_node_class"]
and creator in node["plugins"]
):
imageio_node = node
break
@ -741,10 +741,10 @@ def get_created_node_imageio_setting_legacy(nodeclass, creator, subset):
override_imageio_node = None
for onode in override_nodes:
log.info(onode)
if nodeclass not in node["nukeNodeClass"]:
if nodeclass not in onode["nuke_node_class"]:
continue
if creator not in node["plugins"]:
if creator not in onode["plugins"]:
continue
if (
@ -766,26 +766,33 @@ def get_created_node_imageio_setting_legacy(nodeclass, creator, subset):
knob_names = [k["name"] for k in imageio_node["knobs"]]
for oknob in override_imageio_node["knobs"]:
oknob_name = oknob["name"]
oknob_type = oknob["type"]
oknob_value = oknob[oknob_type]
for knob in imageio_node["knobs"]:
# override matching knob name
if oknob["name"] == knob["name"]:
log.debug(
"_ overriding knob: `{}` > `{}`".format(
knob, oknob
))
if not oknob["value"]:
# remove original knob if no value found in oknob
imageio_node["knobs"].remove(knob)
else:
# override knob value with oknob's
knob["value"] = oknob["value"]
knob_name = knob["name"]
# add missing knobs into imageio_node
if oknob["name"] not in knob_names:
if oknob_name not in knob_names:
log.debug(
"_ adding knob: `{}`".format(oknob))
imageio_node["knobs"].append(oknob)
knob_names.append(oknob["name"])
knob_names.append(oknob_name)
continue
# override matching knob name
if oknob_name != knob_name:
continue
knob_type = knob["type"]
log.debug(
"_ overriding knob: `{}` > `{}`".format(knob, oknob)
)
if not oknob_value:
# remove original knob if no value found in oknob
imageio_node["knobs"].remove(knob)
else:
# override knob value with oknob's
knob[knob_type] = oknob_value
log.info("ImageIO node: {}".format(imageio_node))
return imageio_node
@ -795,14 +802,14 @@ def get_imageio_node_setting(node_class, plugin_name, subset):
''' Get preset data for dataflow (fileType, compression, bitDepth)
'''
imageio_nodes = get_nuke_imageio_settings()["nodes"]
required_nodes = imageio_nodes["requiredNodes"]
required_nodes = imageio_nodes["required_nodes"]
imageio_node = None
for node in required_nodes:
log.info(node)
if (
node_class in node["nukeNodeClass"]
and plugin_name in node["plugins"]
node_class in node["nuke_node_class"]
and plugin_name in node["plugins"]
):
imageio_node = node
break
@ -830,14 +837,14 @@ def get_imageio_node_override_setting(
''' Get imageio node overrides from settings
'''
imageio_nodes = get_nuke_imageio_settings()["nodes"]
override_nodes = imageio_nodes["overrideNodes"]
override_nodes = imageio_nodes["override_nodes"]
# find matching override node
override_imageio_node = None
for onode in override_nodes:
log.debug("__ onode: {}".format(onode))
log.debug("__ subset: {}".format(subset))
if node_class not in onode["nukeNodeClass"]:
if node_class not in onode["nuke_node_class"]:
continue
if plugin_name not in onode["plugins"]:
@ -862,26 +869,31 @@ def get_imageio_node_override_setting(
knob_names = [k["name"] for k in knobs_settings]
for oknob in override_imageio_node["knobs"]:
oknob_name = oknob["name"]
oknob_type = oknob["type"]
oknob_value = oknob[oknob_type]
for knob in knobs_settings:
# override matching knob name
if oknob["name"] == 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)
else:
# override knob value with oknob's
knob["value"] = oknob["value"]
# add missing knobs into imageio_node
if oknob["name"] not in knob_names:
log.debug(
"_ adding knob: `{}`".format(oknob))
if oknob_name not in knob_names:
log.debug("_ adding knob: `{}`".format(oknob))
knobs_settings.append(oknob)
knob_names.append(oknob["name"])
knob_names.append(oknob_name)
continue
if oknob_name != knob["name"]:
continue
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)
else:
# override knob value with oknob's
knob[knob_type] = oknob_value
return knobs_settings
@ -890,7 +902,7 @@ def get_imageio_input_colorspace(filename):
''' Get input file colorspace based on regex in settings.
'''
imageio_regex_inputs = (
get_nuke_imageio_settings()["regexInputs"]["inputs"])
get_nuke_imageio_settings()["regex_inputs"]["inputs"])
preset_clrsp = None
for regexInput in imageio_regex_inputs:
@ -1177,8 +1189,9 @@ def create_prenodes(
):
last_node = None
for_dependency = {}
for name, node in nodes_setting.items():
for node in nodes_setting:
# get attributes
name = node["name"]
nodeclass = node["nodeclass"]
knobs = node["knobs"]
@ -1240,8 +1253,8 @@ def create_write_node(
name (str): name of node
data (dict): creator write instance data
input (node)[optional]: selected node to connect to
prenodes (dict)[optional]:
nodes to be created before write with dependency
prenodes (Optional[list[dict]]): nodes to be created before write
with dependency
review (bool)[optional]: adding review knob
farm (bool)[optional]: rendering workflow target
kwargs (dict)[optional]: additional key arguments for formatting
@ -1270,7 +1283,7 @@ def create_write_node(
Return:
node (obj): group node with avalon data as Knobs
'''
prenodes = prenodes or {}
prenodes = prenodes or []
# filtering variables
plugin_name = data["creator"]
@ -1285,7 +1298,8 @@ def create_write_node(
for knob in imageio_writes["knobs"]:
if knob["name"] == "file_type":
ext = knob["value"]
knot_type = knob["type"]
ext = knob[knot_type]
data.update({
"imageio_writes": imageio_writes,
@ -1400,12 +1414,17 @@ def create_write_node(
# set tile color
tile_color = next(
iter(
k["value"] for k in imageio_writes["knobs"]
k[k["type"]] for k in imageio_writes["knobs"]
if "tile_color" in k["name"]
), [255, 0, 0, 255]
)
new_tile_color = []
for c in tile_color:
if isinstance(c, float):
c = int(c * 255)
new_tile_color.append(c)
GN["tile_color"].setValue(
color_gui_to_int(tile_color))
color_gui_to_int(new_tile_color))
return GN
@ -1701,42 +1720,32 @@ def set_node_knobs_from_settings(node, knob_settings, **kwargs):
"""
for knob in knob_settings:
log.debug("__ knob: {}".format(pformat(knob)))
knob_type = knob["type"]
knob_name = knob["name"]
if knob_name not in node.knobs():
continue
knob_type = knob["type"]
knob_value = knob[knob_type]
if knob_type == "expression":
knob_expression = knob["expression"]
node[knob_name].setExpression(
knob_expression
)
node[knob_name].setExpression(knob_value)
continue
# first deal with formattable knob settings
if knob_type == "formatable":
template = knob["template"]
to_type = knob["to_type"]
template = knob_value["template"]
to_type = knob_value["to_type"]
try:
_knob_value = template.format(
**kwargs
)
knob_value = template.format(**kwargs)
except KeyError as msg:
raise KeyError(
"Not able to format expression: {}".format(msg))
# convert value to correct type
if to_type == "2d_vector":
knob_value = _knob_value.split(";").split(",")
else:
knob_value = _knob_value
knob_value = knob_value.split(";").split(",")
knob_type = to_type
else:
knob_value = knob["value"]
if not knob_value:
continue
@ -1747,29 +1756,46 @@ def set_node_knobs_from_settings(node, knob_settings, **kwargs):
def convert_knob_value_to_correct_type(knob_type, knob_value):
# first convert string types to string
# just to ditch unicode
if isinstance(knob_value, six.text_type):
knob_value = str(knob_value)
# Convert 'text' to string to avoid unicode
if knob_type == "text":
return str(knob_value)
# set correctly knob types
if knob_type == "bool":
knob_value = bool(knob_value)
elif knob_type == "decimal_number":
knob_value = float(knob_value)
elif knob_type == "number":
knob_value = int(knob_value)
elif knob_type == "text":
knob_value = knob_value
elif knob_type == "color_gui":
knob_value = color_gui_to_int(knob_value)
elif knob_type in ["2d_vector", "3d_vector", "color", "box"]:
knob_value = [float(val_) for val_ in knob_value]
if knob_type == "boolean":
return bool(knob_value)
if knob_type == "decimal_number":
return float(knob_value)
if knob_type == "number":
return int(knob_value)
if knob_type == "color_gui":
new_color = []
for value in knob_value:
if isinstance(value, float):
value = int(value * 255)
new_color.append(value)
return color_gui_to_int(new_color)
if knob_type == "box":
return [
knob_value["x"], knob_value["y"],
knob_value["r"], knob_value["t"]
]
if knob_type == "vector_2d":
return [knob_value["x"], knob_value["y"]]
if knob_type == "vector_3d":
return [knob_value["x"], knob_value["y"], knob_value["z"]]
return knob_value
def color_gui_to_int(color_gui):
# Append alpha channel if not present
if len(color_gui) == 3:
color_gui = list(color_gui) + [255]
hex_value = (
"0x{0:0>2x}{1:0>2x}{2:0>2x}{3:0>2x}").format(*color_gui)
return int(hex_value, 16)
@ -2016,41 +2042,21 @@ class WorkfileSettings(object):
host_name="nuke"
)
workfile_settings = imageio_host["workfile"]
viewer_process_settings = imageio_host["viewer"]["viewerProcess"]
workfile_settings = imageio_host["workfile"]
color_management = workfile_settings["color_management"]
native_ocio_config = workfile_settings["native_ocio_config"]
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()]
# no ocio config found and no custom path used
if self._root_node["colorManagement"].value() \
not in color_management:
self._root_node["colorManagement"].setValue(color_management)
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:
# 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 native_ocio_config:
self._root_node["OCIO_config"].setValue(native_ocio_config)
else:
# OCIO config path is defined from prelaunch hook
@ -2063,22 +2069,17 @@ class WorkfileSettings(object):
residual_path
))
# we dont need the key anymore
workfile_settings.pop("customOCIOConfigPath", None)
workfile_settings.pop("colorManagement", None)
workfile_settings.pop("OCIO_config", None)
# get monitor lut from settings respecting Nuke version differences
monitor_lut = workfile_settings.pop("monitorLut", None)
monitor_lut = workfile_settings["thumbnail_space"]
monitor_lut_data = self._get_monitor_settings(
viewer_process_settings, monitor_lut)
# set monitor related knobs luts (MonitorOut, Thumbnails)
for knob, value_ in monitor_lut_data.items():
workfile_settings[knob] = value_
viewer_process_settings, monitor_lut
)
monitor_lut_data["workingSpaceLUT"] = (
workfile_settings["working_space"]
)
# then set the rest
for knob, value_ in workfile_settings.items():
for knob, value_ in monitor_lut_data.items():
# skip unfilled ocio config path
# it will be dict in value
if isinstance(value_, dict):
@ -2360,25 +2361,8 @@ Reopening Nuke should synchronize these paths and resolve any discrepancies.
if not write_node:
return
try:
# write all knobs to node
for knob in nuke_imageio_writes["knobs"]:
value = knob["value"]
if isinstance(value, six.text_type):
value = str(value)
if str(value).startswith("0x"):
value = int(value, 16)
log.debug("knob: {}| value: {}".format(
knob["name"], value
))
write_node[knob["name"]].setValue(value)
except TypeError:
log.warning(
"Legacy workflow didn't work, switching to current")
set_node_knobs_from_settings(
write_node, nuke_imageio_writes["knobs"])
set_node_knobs_from_settings(
write_node, nuke_imageio_writes["knobs"])
def set_reads_colorspace(self, read_clrs_inputs):
""" Setting colorspace to Read nodes
@ -2456,7 +2440,7 @@ Reopening Nuke should synchronize these paths and resolve any discrepancies.
log.error(_error)
log.info("Setting colorspace to read nodes...")
read_clrs_inputs = nuke_colorspace["regexInputs"].get("inputs", [])
read_clrs_inputs = nuke_colorspace["regex_inputs"].get("inputs", [])
if read_clrs_inputs:
self.set_reads_colorspace(read_clrs_inputs)

View file

@ -396,17 +396,25 @@ class NukeWriteCreator(NukeCreator):
# plugin settings
plugin_settings = self.get_creator_settings(project_settings)
temp_rendering_path_template = (
plugin_settings.get("temp_rendering_path_template")
or self.temp_rendering_path_template
)
# TODO remove template key replacements
temp_rendering_path_template = (
temp_rendering_path_template
.replace("{product[name]}", "{subset}")
.replace("{product[type]}", "{family}")
.replace("{task[name]}", "{task}")
.replace("{folder[name]}", "{asset}")
)
# individual attributes
self.instance_attributes = plugin_settings.get(
"instance_attributes") or self.instance_attributes
self.prenodes = plugin_settings["prenodes"]
self.default_variants = plugin_settings.get(
"default_variants") or self.default_variants
self.temp_rendering_path_template = (
plugin_settings.get("temp_rendering_path_template")
or self.temp_rendering_path_template
)
self.temp_rendering_path_template = temp_rendering_path_template
class OpenPypeCreator(LegacyCreator):
@ -1061,7 +1069,7 @@ class AbstractWriteRender(OpenPypeCreator):
icon = "sign-out"
defaults = ["Main", "Mask"]
knobs = []
prenodes = {}
prenodes = []
def __init__(self, *args, **kwargs):
super(AbstractWriteRender, self).__init__(*args, **kwargs)
@ -1167,7 +1175,7 @@ class AbstractWriteRender(OpenPypeCreator):
bool: True if legacy
"""
imageio_nodes = get_nuke_imageio_settings()["nodes"]
node = imageio_nodes["requiredNodes"][0]
node = imageio_nodes["required_nodes"][0]
if "type" not in node["knobs"][0]:
# if type is not yet in project anatomy
return True

View file

@ -53,7 +53,7 @@ class LoadClip(plugin.NukeLoader):
color = "white"
# Loaded from settings
_representations = []
representations_include = []
script_start = int(nuke.root()["first_frame"].value())
@ -82,7 +82,7 @@ class LoadClip(plugin.NukeLoader):
@classmethod
def get_representations(cls):
return cls._representations or cls.representations
return cls.representations_include or cls.representations
def load(self, context, name, namespace, options):
"""Load asset via database
@ -457,7 +457,7 @@ class LoadClip(plugin.NukeLoader):
colorspace = repre_data.get("colorspace")
colorspace = colorspace or version_data.get("colorspace")
# colorspace from `project_settings/nuke/imageio/regexInputs`
# colorspace from `project_settings/nuke/imageio/regex_inputs`
iio_colorspace = get_imageio_input_colorspace(path)
# Set colorspace defined in version data

View file

@ -47,7 +47,7 @@ class LoadImage(load.LoaderPlugin):
color = "white"
# Loaded from settings
_representations = []
representations_include = []
node_name_template = "{class_name}_{ext}"
@ -64,7 +64,7 @@ class LoadImage(load.LoaderPlugin):
@classmethod
def get_representations(cls):
return cls._representations or cls.representations
return cls.representations_include or cls.representations
def load(self, context, name, namespace, options):
self.log.info("__ options: `{}`".format(options))

View file

@ -12,7 +12,7 @@ class CollectInstanceData(pyblish.api.InstancePlugin):
hosts = ["nuke", "nukeassist"]
# presets
sync_workfile_version_on_families = []
sync_workfile_version_on_product_types = []
def process(self, instance):
family = instance.data["family"]
@ -25,7 +25,7 @@ class CollectInstanceData(pyblish.api.InstancePlugin):
pixel_aspect = format_.pixelAspect()
# sync workfile version
if family in self.sync_workfile_version_on_families:
if family in self.sync_workfile_version_on_product_types:
self.log.debug(
"Syncing version with workfile for '{}'".format(
family

View file

@ -50,6 +50,7 @@ class ExtractReviewIntermediates(publish.Extractor):
cls.outputs = current_setting["outputs"]
def process(self, instance):
# TODO 'families' should not be included for filtering of outputs
families = set(instance.data["families"])
# add main family to make sure all families are compared
@ -75,29 +76,33 @@ class ExtractReviewIntermediates(publish.Extractor):
# generate data
with maintained_selection():
generated_repres = []
for o_name, o_data in self.outputs.items():
for o_data in self.outputs:
o_name = o_data["name"]
self.log.debug(
"o_name: {}, o_data: {}".format(o_name, pformat(o_data)))
f_families = o_data["filter"]["families"]
f_product_types = o_data["filter"]["product_types"]
f_task_types = o_data["filter"]["task_types"]
f_subsets = o_data["filter"]["subsets"]
product_names = o_data["filter"]["product_names"]
self.log.debug(
"f_families `{}` > families: {}".format(
f_families, families))
"f_product_types `{}` > families: {}".format(
f_product_types, families))
self.log.debug(
"f_task_types `{}` > task_type: {}".format(
f_task_types, task_type))
self.log.debug(
"f_subsets `{}` > subset: {}".format(
f_subsets, subset))
"product_names `{}` > subset: {}".format(
product_names, subset))
# test if family found in context
# using intersection to make sure all defined
# families are present in combination
if f_families and not families.intersection(f_families):
if (
f_product_types
and not families.intersection(f_product_types)
):
continue
# test task types from filter
@ -105,8 +110,9 @@ class ExtractReviewIntermediates(publish.Extractor):
continue
# test subsets from filter
if f_subsets and not any(
re.search(s, subset) for s in f_subsets):
if product_names and not any(
re.search(p, subset) for p in product_names
):
continue
self.log.debug(
@ -117,7 +123,7 @@ class ExtractReviewIntermediates(publish.Extractor):
# check if settings have more then one preset
# so we dont need to add outputName to representation
# in case there is only one preset
multiple_presets = len(self.outputs.keys()) > 1
multiple_presets = len(self.outputs) > 1
# adding bake presets to instance data for other plugins
if not instance.data.get("bakePresets"):

View file

@ -29,9 +29,15 @@ class ExtractSlateFrame(publish.Extractor):
# Settings values
key_value_mapping = {
"f_submission_note": [True, "{comment}"],
"f_submitting_for": [True, "{intent[value]}"],
"f_vfx_scope_of_work": [False, ""]
"f_submission_note": {
"enabled": True, "template": "{comment}"
},
"f_submitting_for": {
"enabled": True, "template": "{intent[value]}"
},
"f_vfx_scope_of_work": {
"enabled": False, "template": ""
}
}
def process(self, instance):
@ -316,11 +322,11 @@ class ExtractSlateFrame(publish.Extractor):
})
for key, _values in self.key_value_mapping.items():
enabled, template = _values
if not enabled:
if not _values["enabled"]:
self.log.debug("Key \"{}\" is disabled".format(key))
continue
template = _values["template"]
try:
value = template.format(**fill_data)

View file

@ -25,7 +25,7 @@
### How to repair?
Contact your supervisor or fix it in project settings at
'project_settings/nuke/imageio/nodes/requiredNodes' at knobs.
'project_settings/nuke/imageio/nodes/required_nodes' at knobs.
Each '__legacy__' type has to be defined accordingly to its type.
</description>
</error>

View file

@ -30,6 +30,8 @@ class ValidateKnobs(pyblish.api.ContextPlugin):
actions = [RepairContextAction]
optional = True
knobs = "{}"
def process(self, context):
invalid = self.get_invalid(context, compute=True)
if invalid:
@ -61,6 +63,8 @@ class ValidateKnobs(pyblish.api.ContextPlugin):
invalid_knobs = []
for instance in context:
# Load fresh knobs data for each instance
settings_knobs = json.loads(cls.knobs)
# Filter families.
families = [instance.data["family"]]
@ -74,12 +78,12 @@ class ValidateKnobs(pyblish.api.ContextPlugin):
family = family.split(".")[0]
# avoid families not in settings
if family not in cls.knobs:
if family not in settings_knobs:
continue
# get presets of knobs
for preset in cls.knobs[family]:
knobs[preset] = cls.knobs[family][preset]
for preset in settings_knobs[family]:
knobs[preset] = settings_knobs[family][preset]
# Get invalid knobs.
nodes = []

View file

@ -86,7 +86,10 @@ class ValidateNukeWriteNode(
# Collect key values of same type in a list.
values_by_name = defaultdict(list)
for knob_data in correct_data["knobs"]:
values_by_name[knob_data["name"]].append(knob_data["value"])
knob_type = knob_data["type"]
knob_value = knob_data[knob_type]
values_by_name[knob_data["name"]].append(knob_value)
for knob_data in correct_data["knobs"]:
knob_type = knob_data["type"]
@ -97,7 +100,7 @@ class ValidateNukeWriteNode(
raise PublishXmlValidationError(
self, (
"Please update data in settings 'project_settings"
"/nuke/imageio/nodes/requiredNodes'"
"/nuke/imageio/nodes/required_nodes'"
),
key="legacy"
)

View file

@ -127,8 +127,8 @@ class WriteNodeKnobSettingPanel(nukescripts.PythonPanel):
knobs_nodes = []
settings = [
node_settings for node_settings
in get_nuke_imageio_settings()["nodes"]["overrideNodes"]
if node_settings["nukeNodeClass"] == "Write"
in get_nuke_imageio_settings()["nodes"]["override_nodes"]
if node_settings["nuke_node_class"] == "Write"
and node_settings["subsets"]
]
if not settings:

View file

@ -133,192 +133,6 @@ def convert_system_settings(ayon_settings, default_settings, addon_versions):
# --------- Project settings ---------
def _convert_nuke_knobs(knobs):
new_knobs = []
for knob in knobs:
knob_type = knob["type"]
if knob_type == "boolean":
knob_type = "bool"
if knob_type != "bool":
value = knob[knob_type]
elif knob_type in knob:
value = knob[knob_type]
else:
value = knob["boolean"]
new_knob = {
"type": knob_type,
"name": knob["name"],
}
new_knobs.append(new_knob)
if knob_type == "formatable":
new_knob["template"] = value["template"]
new_knob["to_type"] = value["to_type"]
continue
value_key = "value"
if knob_type == "expression":
value_key = "expression"
elif knob_type == "color_gui":
value = _convert_color(value)
elif knob_type == "vector_2d":
value = [value["x"], value["y"]]
elif knob_type == "vector_3d":
value = [value["x"], value["y"], value["z"]]
elif knob_type == "box":
value = [value["x"], value["y"], value["r"], value["t"]]
new_knob[value_key] = value
return new_knobs
def _convert_nuke_project_settings(ayon_settings, output):
if "nuke" not in ayon_settings:
return
ayon_nuke = ayon_settings["nuke"]
# --- Load ---
ayon_load = ayon_nuke["load"]
ayon_load["LoadClip"]["_representations"] = (
ayon_load["LoadClip"].pop("representations_include")
)
ayon_load["LoadImage"]["_representations"] = (
ayon_load["LoadImage"].pop("representations_include")
)
# --- Create ---
ayon_create = ayon_nuke["create"]
for creator_name in (
"CreateWritePrerender",
"CreateWriteImage",
"CreateWriteRender",
):
create_plugin_settings = ayon_create[creator_name]
create_plugin_settings["temp_rendering_path_template"] = (
create_plugin_settings["temp_rendering_path_template"]
.replace("{product[name]}", "{subset}")
.replace("{product[type]}", "{family}")
.replace("{task[name]}", "{task}")
.replace("{folder[name]}", "{asset}")
)
new_prenodes = {}
for prenode in create_plugin_settings["prenodes"]:
name = prenode.pop("name")
prenode["knobs"] = _convert_nuke_knobs(prenode["knobs"])
new_prenodes[name] = prenode
create_plugin_settings["prenodes"] = new_prenodes
# --- Publish ---
ayon_publish = ayon_nuke["publish"]
slate_mapping = ayon_publish["ExtractSlateFrame"]["key_value_mapping"]
for key in tuple(slate_mapping.keys()):
value = slate_mapping[key]
slate_mapping[key] = [value["enabled"], value["template"]]
ayon_publish["ValidateKnobs"]["knobs"] = json.loads(
ayon_publish["ValidateKnobs"]["knobs"]
)
new_review_data_outputs = {}
outputs_settings = []
# Check deprecated ExtractReviewDataMov
# settings for backwards compatibility
deprecrated_review_settings = ayon_publish["ExtractReviewDataMov"]
current_review_settings = (
ayon_publish.get("ExtractReviewIntermediates")
)
if deprecrated_review_settings["enabled"]:
outputs_settings = deprecrated_review_settings["outputs"]
elif current_review_settings is None:
pass
elif current_review_settings["enabled"]:
outputs_settings = current_review_settings["outputs"]
for item in outputs_settings:
item_filter = item["filter"]
if "product_names" in item_filter:
item_filter["subsets"] = item_filter.pop("product_names")
item_filter["families"] = item_filter.pop("product_types")
reformat_nodes_config = item.get("reformat_nodes_config") or {}
reposition_nodes = reformat_nodes_config.get(
"reposition_nodes") or []
for reposition_node in reposition_nodes:
if "knobs" not in reposition_node:
continue
reposition_node["knobs"] = _convert_nuke_knobs(
reposition_node["knobs"]
)
name = item.pop("name")
new_review_data_outputs[name] = item
if deprecrated_review_settings["enabled"]:
deprecrated_review_settings["outputs"] = new_review_data_outputs
elif current_review_settings["enabled"]:
current_review_settings["outputs"] = new_review_data_outputs
collect_instance_data = ayon_publish["CollectInstanceData"]
if "sync_workfile_version_on_product_types" in collect_instance_data:
collect_instance_data["sync_workfile_version_on_families"] = (
collect_instance_data.pop(
"sync_workfile_version_on_product_types"))
# --- ImageIO ---
# NOTE 'monitorOutLut' is maybe not yet in v3 (ut should be)
ayon_imageio = ayon_nuke["imageio"]
# workfile
imageio_workfile = ayon_imageio["workfile"]
workfile_keys_mapping = (
("color_management", "colorManagement"),
("native_ocio_config", "OCIO_config"),
("working_space", "workingSpaceLUT"),
("thumbnail_space", "monitorLut"),
)
for src, dst in workfile_keys_mapping:
if (
src in imageio_workfile
and dst not in imageio_workfile
):
imageio_workfile[dst] = imageio_workfile.pop(src)
# regex inputs
if "regex_inputs" in ayon_imageio:
ayon_imageio["regexInputs"] = ayon_imageio.pop("regex_inputs")
# nodes
ayon_imageio_nodes = ayon_imageio["nodes"]
if "required_nodes" in ayon_imageio_nodes:
ayon_imageio_nodes["requiredNodes"] = (
ayon_imageio_nodes.pop("required_nodes"))
if "override_nodes" in ayon_imageio_nodes:
ayon_imageio_nodes["overrideNodes"] = (
ayon_imageio_nodes.pop("override_nodes"))
for item in ayon_imageio_nodes["requiredNodes"]:
if "nuke_node_class" in item:
item["nukeNodeClass"] = item.pop("nuke_node_class")
item["knobs"] = _convert_nuke_knobs(item["knobs"])
for item in ayon_imageio_nodes["overrideNodes"]:
if "nuke_node_class" in item:
item["nukeNodeClass"] = item.pop("nuke_node_class")
item["knobs"] = _convert_nuke_knobs(item["knobs"])
output["nuke"] = ayon_nuke
def _convert_royalrender_project_settings(ayon_settings, output):
if "royalrender" not in ayon_settings:
return
@ -335,8 +149,6 @@ def convert_project_settings(ayon_settings, default_settings):
default_settings = copy.deepcopy(default_settings)
output = {}
_convert_nuke_project_settings(ayon_settings, output)
_convert_royalrender_project_settings(ayon_settings, output)
for key, value in ayon_settings.items():