Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Load VDB to Redshift: Create and assign a RedshiftStandardVolume material on load #220

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Changes from 3 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
68 changes: 59 additions & 9 deletions client/ayon_maya/plugins/load/load_vdb_to_redshift.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import os
from typing import List

from ayon_core.pipeline import get_representation_path
from ayon_core.settings import get_project_settings
from ayon_maya.api import plugin
from ayon_core.lib import BoolDef

from ayon_maya.api import plugin, lib
from ayon_maya.api.plugin import get_load_color_for_product_type
from ayon_maya.api.pipeline import containerise

from maya import cmds, mel


class LoadVDBtoRedShift(plugin.Loader):
Expand All @@ -23,11 +29,17 @@ class LoadVDBtoRedShift(plugin.Loader):
icon = "cloud"
color = "orange"

def load(self, context, name=None, namespace=None, data=None):
options = [
BoolDef("create_shader",
label="Create Redshift Volume Shader",
tooltip="When enabled create a Redshift Volume Shader and "
"assign it to the volume shape. Without a volume "
"shader assigned Redshift may not render the volume "
"at all.",
default=True)
]

from ayon_maya.api.lib import unique_namespace
from ayon_maya.api.pipeline import containerise
from maya import cmds
def load(self, context, name=None, namespace=None, options=None):

product_type = context["product"]["productType"]

Expand All @@ -51,7 +63,7 @@ def load(self, context, name=None, namespace=None, data=None):
% compatible)

folder_name = context["folder"]["name"]
namespace = namespace or unique_namespace(
namespace = namespace or lib.unique_namespace(
folder_name + "_",
prefix="_" if folder_name[0].isdigit() else "",
suffix="_",
Expand All @@ -78,6 +90,9 @@ def load(self, context, name=None, namespace=None, data=None):
path=self.filepath_from_context(context),
representation=context["representation"])

if options.get("create_shader", True):
self._create_default_redshift_volume_shader(volume_node)

nodes = [root, volume_node]
self[:] = nodes

Expand All @@ -89,7 +104,6 @@ def load(self, context, name=None, namespace=None, data=None):
loader=self.__class__.__name__)

def update(self, container, context):
from maya import cmds

repre_entity = context["representation"]
path = get_representation_path(repre_entity)
Expand All @@ -108,7 +122,6 @@ def update(self, container, context):
type="string")

def remove(self, container):
from maya import cmds

# Get all members of the AYON container, ensure they are unlocked
# and delete everything
Expand All @@ -131,7 +144,6 @@ def _set_path(grid_node,
path,
representation):
"""Apply the settings for the VDB path to the RedshiftVolumeShape"""
from maya import cmds

if not os.path.exists(path):
raise RuntimeError("Path does not exist: %s" % path)
Expand All @@ -141,3 +153,41 @@ def _set_path(grid_node,

# Set file path
cmds.setAttr(grid_node + ".fileName", path, type="string")

# Force refresh with the use frame extension
# This makes sure we can directly retrieve the `.gridNames` attribute
# and avoids potential 'Failed to find volume file' warnings that
# appear once on load whe Maya has not yet initialized use frame
# extension behavior correctly on load yet.
mel.eval(f'checkUseFrameExtension("{grid_node}")')

def _create_default_redshift_volume_shader(
self, volume_shape: str) -> List[str]:
"""Create RedshiftStandardVolume shader and assign it to the volume"""
# TODO: Should this material become "managed" and get removed on
# removing the Redshift Volume itself? Currently it is not and it
# will linger in the scene as dangling unused material.

# Create shading engine with RedshiftStandardVolume
material = cmds.shadingNode("RedshiftStandardVolume", asShader=True)
sg = cmds.shadingNode(
"shadingEngine", asShader=True, name=f"{material}SG")
cmds.connectAttr(f"{material}.outColor",
f"{sg}.volumeShader",
force=True)

# Set default density name
channel = "density"
grid_names: List[str] = cmds.getAttr(f"{volume_shape}.gridNames")
if grid_names and channel not in grid_names:
channel = grid_names[0]
cmds.setAttr("{}.density_name".format(material),
channel, type="string")

# Assign shader to the volume shape
cmds.sets(volume_shape, forceElement=sg)

self.log.info(
f"Created RedshiftStandardVolume: '{material}'"
f" using channel '{channel}'")
return [material, sg]
Loading