Skip to content
This repository has been archived by the owner on Sep 20, 2024. It is now read-only.

Maya: Support for configurable AOV separator characters #2197

Merged
merged 4 commits into from
Nov 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion openpype/hosts/maya/api/lib_renderproducts.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ def __init__(self, layer, render_instance):
self.layer = layer
self.render_instance = render_instance
self.multipart = False
self.aov_separator = render_instance.data.get("aovSeparator", "_")

# Initialize
self.layer_data = self._get_layer_data()
Expand Down Expand Up @@ -676,7 +677,7 @@ def get_renderer_prefix(self):

"""
prefix = super(RenderProductsVray, self).get_renderer_prefix()
prefix = "{}.<aov>".format(prefix)
prefix = "{}{}<aov>".format(prefix, self.aov_separator)
return prefix

def _get_layer_data(self):
Expand Down
89 changes: 56 additions & 33 deletions openpype/hosts/maya/plugins/create/create_render.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from openpype.modules import ModulesManager

from avalon.api import Session
from avalon.api import CreatorError


class CreateRender(plugin.Creator):
Expand Down Expand Up @@ -81,26 +82,46 @@ class CreateRender(plugin.Creator):
}

_image_prefixes = {
'mentalray': 'maya/<Scene>/<RenderLayer>/<RenderLayer>_<RenderPass>',
'mentalray': 'maya/<Scene>/<RenderLayer>/<RenderLayer>{aov_separator}<RenderPass>', # noqa
'vray': 'maya/<scene>/<Layer>/<Layer>',
'arnold': 'maya/<Scene>/<RenderLayer>/<RenderLayer>_<RenderPass>',
'renderman': 'maya/<Scene>/<layer>/<layer>_<aov>',
'redshift': 'maya/<Scene>/<RenderLayer>/<RenderLayer>_<RenderPass>'
'arnold': 'maya/<Scene>/<RenderLayer>/<RenderLayer>{aov_separator}<RenderPass>', # noqa
'renderman': 'maya/<Scene>/<layer>/<layer>{aov_separator}<aov>',
'redshift': 'maya/<Scene>/<RenderLayer>/<RenderLayer>{aov_separator}<RenderPass>' # noqa
}

_aov_chars = {
"dot": ".",
"dash": "-",
"underscore": "_"
}

_project_settings = None

def __init__(self, *args, **kwargs):
"""Constructor."""
super(CreateRender, self).__init__(*args, **kwargs)
deadline_settings = get_system_settings()["modules"]["deadline"]
if not deadline_settings["enabled"]:
self.deadline_servers = {}
return
project_settings = get_project_settings(Session["AVALON_PROJECT"])
self._project_settings = get_project_settings(
Session["AVALON_PROJECT"])

# project_settings/maya/create/CreateRender/aov_separator
try:
self.aov_separator = self._aov_chars[(
self._project_settings["maya"]
["create"]
["CreateRender"]
["aov_separator"]
)]
except KeyError:
self.aov_separator = "_"

try:
default_servers = deadline_settings["deadline_urls"]
project_servers = (
project_settings["deadline"]
["deadline_servers"]
self._project_settings["deadline"]["deadline_servers"]
)
self.deadline_servers = {
k: default_servers[k]
Expand Down Expand Up @@ -409,8 +430,10 @@ def _set_default_renderer_settings(self, renderer):
renderer (str): Renderer name.

"""
prefix = self._image_prefixes[renderer]
prefix = prefix.replace("{aov_separator}", self.aov_separator)
cmds.setAttr(self._image_prefix_nodes[renderer],
self._image_prefixes[renderer],
prefix,
type="string")

asset = get_asset()
Expand Down Expand Up @@ -446,37 +469,37 @@ def _set_default_renderer_settings(self, renderer):

self._set_global_output_settings()

@staticmethod
def _set_renderer_option(renderer_node, arg=None, value=None):
# type: (str, str, str) -> str
"""Set option on renderer node.

If renderer settings node doesn't exists, it is created first.

Args:
renderer_node (str): Renderer name.
arg (str, optional): Argument name.
value (str, optional): Argument value.

Returns:
str: Renderer settings node.

"""
settings = cmds.ls(type=renderer_node)
result = settings[0] if settings else cmds.createNode(renderer_node)
cmds.setAttr(arg.format(result), value)
return result

def _set_vray_settings(self, asset):
# type: (dict) -> None
"""Sets important settings for Vray."""
node = self._set_renderer_option(
"VRaySettingsNode", "{}.fileNameRenderElementSeparator", "_"
)
settings = cmds.ls(type="VRaySettingsNode")
node = settings[0] if settings else cmds.createNode("VRaySettingsNode")

# set separator
# set it in vray menu
if cmds.optionMenuGrp("vrayRenderElementSeparator", exists=True,
q=True):
items = cmds.optionMenuGrp(
"vrayRenderElementSeparator", ill=True, query=True)

separators = [cmds.menuItem(i, label=True, query=True) for i in items] # noqa: E501
try:
sep_idx = separators.index(self.aov_separator)
except ValueError:
raise CreatorError(
"AOV character {} not in {}".format(
self.aov_separator, separators))

cmds.optionMenuGrp(
"vrayRenderElementSeparator", sl=sep_idx + 1, edit=True)
cmds.setAttr(
"{}.fileNameRenderElementSeparator".format(node),
self.aov_separator,
type="string"
)
# set format to exr
cmds.setAttr(
"{}.imageFormatStr".format(node), 5)
"{}.imageFormatStr".format(node), "exr", type="string")

# animType
cmds.setAttr(
Expand Down
32 changes: 31 additions & 1 deletion openpype/hosts/maya/plugins/publish/collect_render.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ class CollectMayaRender(pyblish.api.ContextPlugin):
label = "Collect Render Layers"
sync_workfile_version = False

_aov_chars = {
"dot": ".",
"dash": "-",
"underscore": "_"
}

def process(self, context):
"""Entry point to collector."""
render_instance = None
Expand Down Expand Up @@ -166,6 +172,18 @@ def process(self, context):
if renderer.startswith("renderman"):
renderer = "renderman"

try:
aov_separator = self._aov_chars[(
context.data["project_settings"]
["create"]
["CreateRender"]
["aov_separator"]
)]
except KeyError:
aov_separator = "_"

render_instance.data["aovSeparator"] = aov_separator

# return all expected files for all cameras and aovs in given
# frame range
layer_render_products = get_layer_render_products(
Expand Down Expand Up @@ -261,6 +279,17 @@ def process(self, context):
self.log.info(full_exp_files)
self.log.info("collecting layer: {}".format(layer_name))
# Get layer specific settings, might be overrides

try:
aov_separator = self._aov_chars[(
context.data["project_settings"]
["create"]
["CreateRender"]
["aov_separator"]
)]
except KeyError:
aov_separator = "_"

data = {
"subset": expected_layer_name,
"attachTo": attach_to,
Expand Down Expand Up @@ -302,7 +331,8 @@ def process(self, context):
"convertToScanline") or False,
"useReferencedAovs": render_instance.data.get(
"useReferencedAovs") or render_instance.data.get(
"vrayUseReferencedAovs") or False
"vrayUseReferencedAovs") or False,
"aovSeparator": aov_separator
}

if deadline_url:
Expand Down
65 changes: 44 additions & 21 deletions openpype/hosts/maya/plugins/publish/validate_rendersettings.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,19 @@ class ValidateRenderSettings(pyblish.api.InstancePlugin):

ImagePrefixTokens = {

'arnold': 'maya/<Scene>/<RenderLayer>/<RenderLayer>_<RenderPass>',
'arnold': 'maya/<Scene>/<RenderLayer>/<RenderLayer>{aov_separator}<RenderPass>', # noqa
'redshift': 'maya/<Scene>/<RenderLayer>/<RenderLayer>',
'vray': 'maya/<Scene>/<Layer>/<Layer>',
'renderman': '<layer>_<aov>.<f4>.<ext>'
'renderman': '<layer>{aov_separator}<aov>.<f4>.<ext>' # noqa
}

redshift_AOV_prefix = "<BeautyPath>/<BeautyFile>_<RenderPass>"
_aov_chars = {
"dot": ".",
"dash": "-",
"underscore": "_"
}

redshift_AOV_prefix = "<BeautyPath>/<BeautyFile>{aov_separator}<RenderPass>" # noqa: E501

# WARNING: There is bug? in renderman, translating <scene> token
# to something left behind mayas default image prefix. So instead
Expand Down Expand Up @@ -107,6 +113,9 @@ def get_invalid(cls, instance):

anim_override = lib.get_attr_in_layer("defaultRenderGlobals.animation",
layer=layer)

prefix = prefix.replace(
"{aov_separator}", instance.data.get("aovSeparator", "_"))
if not anim_override:
invalid = True
cls.log.error("Animation needs to be enabled. Use the same "
Expand Down Expand Up @@ -138,12 +147,16 @@ def get_invalid(cls, instance):
else:
node = vray_settings[0]

if cmds.getAttr(
"{}.fileNameRenderElementSeparator".format(node)) != "_":
invalid = False
scene_sep = cmds.getAttr(
"{}.fileNameRenderElementSeparator".format(node))
if scene_sep != instance.data.get("aovSeparator", "_"):
cls.log.error("AOV separator is not set correctly.")
invalid = True

if renderer == "redshift":
redshift_AOV_prefix = cls.redshift_AOV_prefix.replace(
"{aov_separator}", instance.data.get("aovSeparator", "_")
)
if re.search(cls.R_AOV_TOKEN, prefix):
invalid = True
cls.log.error(("Do not use AOV token [ {} ] - "
Expand All @@ -155,7 +168,7 @@ def get_invalid(cls, instance):
for aov in rs_aovs:
aov_prefix = cmds.getAttr("{}.filePrefix".format(aov))
# check their image prefix
if aov_prefix != cls.redshift_AOV_prefix:
if aov_prefix != redshift_AOV_prefix:
cls.log.error(("AOV ({}) image prefix is not set "
"correctly {} != {}").format(
cmds.getAttr("{}.name".format(aov)),
Expand All @@ -181,7 +194,7 @@ def get_invalid(cls, instance):
file_prefix = cmds.getAttr("rmanGlobals.imageFileFormat")
dir_prefix = cmds.getAttr("rmanGlobals.imageOutputDir")

if file_prefix.lower() != cls.ImagePrefixTokens[renderer].lower():
if file_prefix.lower() != prefix.lower():
invalid = True
cls.log.error("Wrong image prefix [ {} ]".format(file_prefix))

Expand All @@ -198,18 +211,20 @@ def get_invalid(cls, instance):
cls.log.error("Wrong image prefix [ {} ] - "
"You can't use '<renderpass>' token "
"with merge AOVs turned on".format(prefix))
else:
if not re.search(cls.R_AOV_TOKEN, prefix):
invalid = True
cls.log.error("Wrong image prefix [ {} ] - "
"doesn't have: '<renderpass>' or "
"token".format(prefix))
elif not re.search(cls.R_AOV_TOKEN, prefix):
invalid = True
cls.log.error("Wrong image prefix [ {} ] - "
"doesn't have: '<renderpass>' or "
"token".format(prefix))

# prefix check
if prefix.lower() != cls.ImagePrefixTokens[renderer].lower():
default_prefix = cls.ImagePrefixTokens[renderer]
default_prefix = default_prefix.replace(
"{aov_separator}", instance.data.get("aovSeparator", "_"))
if prefix.lower() != default_prefix.lower():
cls.log.warning("warning: prefix differs from "
"recommended {}".format(
cls.ImagePrefixTokens[renderer]))
default_prefix))

if padding != cls.DEFAULT_PADDING:
invalid = True
Expand Down Expand Up @@ -257,9 +272,14 @@ def get_invalid(cls, instance):

@classmethod
def repair(cls, instance):

renderer = instance.data['renderer']
layer_node = instance.data['setMembers']
redshift_AOV_prefix = cls.redshift_AOV_prefix.replace(
"{aov_separator}", instance.data.get("aovSeparator", "_")
)
default_prefix = cls.ImagePrefixTokens[renderer].replace(
"{aov_separator}", instance.data.get("aovSeparator", "_")
)

with lib.renderlayer(layer_node):
default = lib.RENDER_ATTRS['default']
Expand All @@ -270,7 +290,7 @@ def repair(cls, instance):
node = render_attrs["node"]
prefix_attr = render_attrs["prefix"]

fname_prefix = cls.ImagePrefixTokens[renderer]
fname_prefix = default_prefix
cmds.setAttr("{}.{}".format(node, prefix_attr),
fname_prefix, type="string")

Expand All @@ -281,7 +301,7 @@ def repair(cls, instance):
else:
# renderman handles stuff differently
cmds.setAttr("rmanGlobals.imageFileFormat",
cls.ImagePrefixTokens[renderer],
default_prefix,
type="string")
cmds.setAttr("rmanGlobals.imageOutputDir",
cls.RendermanDirPrefix,
Expand All @@ -294,10 +314,13 @@ def repair(cls, instance):
else:
node = vray_settings[0]

cmds.optionMenuGrp("vrayRenderElementSeparator",
v=instance.data.get("aovSeparator", "_"))
cmds.setAttr(
"{}.fileNameRenderElementSeparator".format(
node),
"_"
instance.data.get("aovSeparator", "_"),
type="string"
)

if renderer == "redshift":
Expand All @@ -306,7 +329,7 @@ def repair(cls, instance):
for aov in rs_aovs:
# fix AOV prefixes
cmds.setAttr(
"{}.filePrefix".format(aov), cls.redshift_AOV_prefix)
"{}.filePrefix".format(aov), redshift_AOV_prefix)
# fix AOV file format
default_ext = cmds.getAttr(
"redshiftOptions.imageFormat", asString=True)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin):
families = ["render.farm", "prerender.farm",
"renderlayer", "imagesequence", "vrayscene"]

aov_filter = {"maya": [r".*(?:\.|_)*([Bb]eauty)(?:\.|_)*.*"],
aov_filter = {"maya": [r".*(?:[\._-])*([Bb]eauty)(?:[\.|_])*.*"],
"aftereffects": [r".*"], # for everything from AE
"harmony": [r".*"], # for everything from AE
"celaction": [r".*"]}
Expand Down
3 changes: 2 additions & 1 deletion openpype/settings/defaults/project_settings/maya.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@
"enabled": true,
"defaults": [
"Main"
]
],
"aov_separator": "underscore"
},
"CreateAnimation": {
"enabled": true,
Expand Down
Loading