mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-25 05:14:40 +01:00
Merge pull request #70 from ynput/enhancement/OP-8204_Nuke-use-AYON-settings
Nuke: Use AYON settings
This commit is contained in:
commit
abd44277cb
12 changed files with 197 additions and 374 deletions
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"):
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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 = []
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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():
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue