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 #824 from pypeclub/feature/vray-referenced-aovs
Browse files Browse the repository at this point in the history
Maya: handle referenced AOVs for Vray
  • Loading branch information
mkolar authored Dec 18, 2020
2 parents c9e7f24 + b099211 commit 827eb60
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 31 deletions.
72 changes: 43 additions & 29 deletions pype/hosts/maya/expected_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
ImagePrefixes (dict): Mapping between renderers and their respective
image prefix atrribute names.
Todo:
Determine `multipart` from render instance.
"""

import types
Expand Down Expand Up @@ -94,6 +97,10 @@ class ExpectedFiles:

multipart = False

def __init__(self, render_instance):
"""Constructor."""
self._render_instance = render_instance

def get(self, renderer, layer):
"""Get expected files for given renderer and render layer.
Expand All @@ -114,15 +121,20 @@ def get(self, renderer, layer):
renderSetup.instance().switchToLayerUsingLegacyName(layer)

if renderer.lower() == "arnold":
return self._get_files(ExpectedFilesArnold(layer))
return self._get_files(ExpectedFilesArnold(layer,
self._render_instance))
elif renderer.lower() == "vray":
return self._get_files(ExpectedFilesVray(layer))
return self._get_files(ExpectedFilesVray(
layer, self._render_instance))
elif renderer.lower() == "redshift":
return self._get_files(ExpectedFilesRedshift(layer))
return self._get_files(ExpectedFilesRedshift(
layer, self._render_instance))
elif renderer.lower() == "mentalray":
return self._get_files(ExpectedFilesMentalray(layer))
return self._get_files(ExpectedFilesMentalray(
layer, self._render_instance))
elif renderer.lower() == "renderman":
return self._get_files(ExpectedFilesRenderman(layer))
return self._get_files(ExpectedFilesRenderman(
layer, self._render_instance))
else:
raise UnsupportedRendererException(
"unsupported {}".format(renderer)
Expand All @@ -149,9 +161,10 @@ class AExpectedFiles:
layer = None
multipart = False

def __init__(self, layer):
def __init__(self, layer, render_instance):
"""Constructor."""
self.layer = layer
self.render_instance = render_instance

@abstractmethod
def get_aovs(self):
Expand Down Expand Up @@ -460,9 +473,9 @@ class ExpectedFilesArnold(AExpectedFiles):
"maya": "",
}

def __init__(self, layer):
def __init__(self, layer, render_instance):
"""Constructor."""
super(ExpectedFilesArnold, self).__init__(layer)
super(ExpectedFilesArnold, self).__init__(layer, render_instance)
self.renderer = "arnold"

def get_aovs(self):
Expand Down Expand Up @@ -531,9 +544,9 @@ def get_aovs(self):
class ExpectedFilesVray(AExpectedFiles):
"""Expected files for V-Ray renderer."""

def __init__(self, layer):
def __init__(self, layer, render_instance):
"""Constructor."""
super(ExpectedFilesVray, self).__init__(layer)
super(ExpectedFilesVray, self).__init__(layer, render_instance)
self.renderer = "vray"

def get_renderer_prefix(self):
Expand Down Expand Up @@ -614,24 +627,25 @@ def get_aovs(self):
if default_ext == "exr (multichannel)" or default_ext == "exr (deep)":
default_ext = "exr"

# add beauty as default
enabled_aovs.append(
(u"beauty", default_ext)
)

if not self.maya_is_true(
cmds.getAttr("vraySettings.relements_enableall")
):
return enabled_aovs

# filter all namespace prefixed AOVs - they are pulled in from
# references and are not rendered.
vr_aovs = [
n
for n in cmds.ls(
type=["VRayRenderElement", "VRayRenderElementSet"]
)
if len(n.split(":")) == 1
]
# handle aovs from references
use_ref_aovs = self.render_instance.data.get(
"vrayUseReferencedAovs", False) or False

# this will have list of all aovs no matter if they are coming from
# reference or not.
vr_aovs = cmds.ls(
type=["VRayRenderElement", "VRayRenderElementSet"]) or []
if not use_ref_aovs:
ref_aovs = cmds.ls(
type=["VRayRenderElement", "VRayRenderElementSet"],
referencedNodes=True) or []
# get difference
vr_aovs = list(set(vr_aovs) - set(ref_aovs))

for aov in vr_aovs:
enabled = self.maya_is_true(cmds.getAttr("{}.enabled".format(aov)))
Expand Down Expand Up @@ -703,9 +717,9 @@ class ExpectedFilesRedshift(AExpectedFiles):

ext_mapping = ["iff", "exr", "tif", "png", "tga", "jpg"]

def __init__(self, layer):
def __init__(self, layer, render_instance):
"""Construtor."""
super(ExpectedFilesRedshift, self).__init__(layer)
super(ExpectedFilesRedshift, self).__init__(layer, render_instance)
self.renderer = "redshift"

def get_renderer_prefix(self):
Expand Down Expand Up @@ -822,9 +836,9 @@ class ExpectedFilesRenderman(AExpectedFiles):
This is very rudimentary and needs more love and testing.
"""

def __init__(self, layer):
def __init__(self, layer, render_instance):
"""Constructor."""
super(ExpectedFilesRenderman, self).__init__(layer)
super(ExpectedFilesRenderman, self).__init__(layer, render_instance)
self.renderer = "renderman"

def get_aovs(self):
Expand Down Expand Up @@ -887,7 +901,7 @@ def get_files(self):
class ExpectedFilesMentalray(AExpectedFiles):
"""Skeleton unimplemented class for Mentalray renderer."""

def __init__(self, layer):
def __init__(self, layer, render_instance):
"""Constructor.
Raises:
Expand Down
1 change: 1 addition & 0 deletions pype/plugins/maya/create/create_render.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ def _create_render_settings(self):
self.data["tilesX"] = 2
self.data["tilesY"] = 2
self.data["convertToScanline"] = False
self.data["vrayUseReferencedAovs"] = False
# Disable for now as this feature is not working yet
# self.data["assScene"] = False

Expand Down
5 changes: 3 additions & 2 deletions pype/plugins/maya/publish/collect_render.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ def process(self, context):

# return all expected files for all cameras and aovs in given
# frame range
ef = ExpectedFiles()
ef = ExpectedFiles(render_instance)
exp_files = ef.get(renderer, layer_name)
self.log.info("multipart: {}".format(ef.multipart))
assert exp_files, "no file names were generated, this is bug"
Expand Down Expand Up @@ -248,7 +248,8 @@ def process(self, context):
"tilesX": render_instance.data.get("tilesX") or 2,
"tilesY": render_instance.data.get("tilesY") or 2,
"priority": render_instance.data.get("priority"),
"convertToScanline": render_instance.data.get("convertToScanline") or False # noqa: E501
"convertToScanline": render_instance.data.get("convertToScanline") or False, # noqa: E501
"vrayUseReferencedAovs": render_instance.data.get("vrayUseReferencedAovs") or False # noqa: E501
}

if self.sync_workfile_version:
Expand Down
90 changes: 90 additions & 0 deletions pype/plugins/maya/publish/validate_vray_referenced_aovs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# -*- coding: utf-8 -*-
"""Validate if there are AOVs pulled from references."""
import pyblish.api
import types
from maya import cmds

import pype.hosts.maya.action


class ValidateVrayReferencedAOVs(pyblish.api.InstancePlugin):
"""Validate whether the V-Ray Render Elements (AOVs) include references.
This will check if there are AOVs pulled from references. If
`Vray Use Referenced Aovs` is checked on render instance, u must add those
manually to Render Elements as Pype will expect them to be rendered.
"""

order = pyblish.api.ValidatorOrder
label = 'VRay Referenced AOVs'
hosts = ['maya']
families = ['renderlayer']
actions = [pype.api.RepairContextAction]

def process(self, instance):
"""Plugin main entry point."""
if instance.data.get("renderer") != "vray":
# If not V-Ray ignore..
return

ref_aovs = cmds.ls(
type=["VRayRenderElement", "VRayRenderElementSet"],
referencedNodes=True)
ref_aovs_enabled = ValidateVrayReferencedAOVs.maya_is_true(
cmds.getAttr("vraySettings.relements_usereferenced"))

if not instance.data.get("vrayUseReferencedAovs"):
if ref_aovs_enabled and ref_aovs:
self.log.warning((
"Referenced AOVs are enabled in Vray "
"Render Settings and are detected in scene, but "
"Pype render instance option for referenced AOVs is "
"disabled. Those AOVs will be rendered but not published "
"by Pype."
))
self.log.warning(", ".join(ref_aovs))
else:
if not ref_aovs:
self.log.warning((
"Use of referenced AOVs enabled but there are none "
"in the scene."
))
if not ref_aovs_enabled:
self.log.error((
"'Use referenced' not enabled in Vray Render Settings."
))
raise AssertionError("Invalid render settings")

@classmethod
def repair(cls, context):
"""Repair action."""
vray_settings = cmds.ls(type="VRaySettingsNode")
if not vray_settings:
node = cmds.createNode("VRaySettingsNode")
else:
node = vray_settings[0]

cmds.setAttr("{}.relements_usereferenced".format(node), True)

@staticmethod
def maya_is_true(attr_val):
"""Whether a Maya attr evaluates to True.
When querying an attribute value from an ambiguous object the
Maya API will return a list of values, which need to be properly
handled to evaluate properly.
Args:
attr_val (mixed): Maya attribute to be evaluated as bool.
Returns:
bool: cast Maya attribute to Pythons boolean value.
"""
if isinstance(attr_val, types.BooleanType):
return attr_val
elif isinstance(attr_val, (types.ListType, types.GeneratorType)):
return any(attr_val)
else:
return bool(attr_val)

0 comments on commit 827eb60

Please sign in to comment.