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

Commit

Permalink
Merge pull request #2197 from pypeclub/hotfix/OP-1148_vray-aov-separator
Browse files Browse the repository at this point in the history
Maya: Support for configurable AOV separator characters
  • Loading branch information
antirotor authored Nov 18, 2021
2 parents 1888ece + 5916389 commit 278ee5f
Show file tree
Hide file tree
Showing 8 changed files with 149 additions and 59 deletions.
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 @@ -62,6 +62,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 @@ -167,6 +173,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 @@ -267,6 +285,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 @@ -308,7 +337,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 @@ -42,7 +42,8 @@
"enabled": true,
"defaults": [
"Main"
]
],
"aov_separator": "underscore"
},
"CreateAnimation": {
"enabled": true,
Expand Down
Loading

0 comments on commit 278ee5f

Please sign in to comment.