From 83de346d990ac9e86c10cf85548483d5db17e176 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 16 May 2022 14:59:37 +0200 Subject: [PATCH 1/2] Implement update, remove, switch + fix vdb sequence support --- .../maya/plugins/load/load_vdb_to_redshift.py | 87 +++++++++++++++++-- 1 file changed, 81 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/maya/plugins/load/load_vdb_to_redshift.py b/openpype/hosts/maya/plugins/load/load_vdb_to_redshift.py index 70bd9d22e2..7867f49bd1 100644 --- a/openpype/hosts/maya/plugins/load/load_vdb_to_redshift.py +++ b/openpype/hosts/maya/plugins/load/load_vdb_to_redshift.py @@ -1,11 +1,21 @@ import os from openpype.api import get_project_settings -from openpype.pipeline import load +from openpype.pipeline import ( + load, + get_representation_path +) class LoadVDBtoRedShift(load.LoaderPlugin): - """Load OpenVDB in a Redshift Volume Shape""" + """Load OpenVDB in a Redshift Volume Shape + + Note that the RedshiftVolumeShape is created without a RedshiftVolume + shader assigned. To get the Redshift volume to render correctly assign + a RedshiftVolume shader (in the Hypershade) and set the density, scatter + and emission channels to the channel names of the volumes in the VDB file. + + """ families = ["vdbcache"] representations = ["vdb"] @@ -55,7 +65,7 @@ class LoadVDBtoRedShift(load.LoaderPlugin): # Root group label = "{}:{}".format(namespace, name) - root = cmds.group(name=label, empty=True) + root = cmds.createNode("transform", name=label) settings = get_project_settings(os.environ['AVALON_PROJECT']) colors = settings['maya']['load']['colors'] @@ -74,9 +84,7 @@ class LoadVDBtoRedShift(load.LoaderPlugin): name="{}RVSShape".format(label), parent=root) - cmds.setAttr("{}.fileName".format(volume_node), - self.fname, - type="string") + self._apply_settings(volume_node, path=self.fname) nodes = [root, volume_node] self[:] = nodes @@ -87,3 +95,70 @@ class LoadVDBtoRedShift(load.LoaderPlugin): nodes=nodes, context=context, loader=self.__class__.__name__) + + def _apply_settings(self, + grid_node, + path): + """Apply the settings for the VDB path to the VRayVolumeGrid""" + from maya import cmds + + # The path points to a single file. However the vdb files could be + # either just that single file or a sequence in a folder so we check + # whether it's a sequence + folder = os.path.dirname(path) + files = os.listdir(folder) + is_single_file = len(files) == 1 + if is_single_file: + filename = path + else: + # The path points to the publish .vdb sequence filepath so we + # find the first file in there that ends with .vdb + files = sorted(files) + first = next((x for x in files if x.endswith(".vdb")), None) + if first is None: + raise RuntimeError("Couldn't find first .vdb file of " + "sequence in: %s" % path) + filename = os.path.join(path, first) + + # Tell Redshift whether it should load as sequence or single file + cmds.setAttr(grid_node + ".useFrameExtension", not is_single_file) + + # Set file path + cmds.setAttr(grid_node + ".fileName", filename, type="string") + + def update(self, container, representation): + from maya import cmds + + path = get_representation_path(representation) + + # Find VRayVolumeGrid + members = cmds.sets(container['objectName'], query=True) + grid_nodes = cmds.ls(members, type="RedshiftVolumeShape", long=True) + assert len(grid_nodes) == 1, "This is a bug" + + # Update the VRayVolumeGrid + self._apply_settings(grid_nodes[0], path=path) + + # Update container representation + cmds.setAttr(container["objectName"] + ".representation", + str(representation["_id"]), + type="string") + + def remove(self, container): + from maya import cmds + + # Get all members of the avalon container, ensure they are unlocked + # and delete everything + members = cmds.sets(container['objectName'], query=True) + cmds.lockNode(members, lock=False) + cmds.delete([container['objectName']] + members) + + # Clean up the namespace + try: + cmds.namespace(removeNamespace=container['namespace'], + deleteNamespaceContent=True) + except RuntimeError: + pass + + def switch(self, container, representation): + self.update(container, representation) From 9d556a9ae8f3f42770c4296cd799a427674db062 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 30 Jun 2022 23:47:27 +0200 Subject: [PATCH 2/2] Match set path logic more to Arnold VDB loader from #3433 --- .../maya/plugins/load/load_vdb_to_redshift.py | 52 +++++++------------ 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/openpype/hosts/maya/plugins/load/load_vdb_to_redshift.py b/openpype/hosts/maya/plugins/load/load_vdb_to_redshift.py index 7867f49bd1..c6a69dfe35 100644 --- a/openpype/hosts/maya/plugins/load/load_vdb_to_redshift.py +++ b/openpype/hosts/maya/plugins/load/load_vdb_to_redshift.py @@ -84,7 +84,9 @@ class LoadVDBtoRedShift(load.LoaderPlugin): name="{}RVSShape".format(label), parent=root) - self._apply_settings(volume_node, path=self.fname) + self._set_path(volume_node, + path=self.fname, + representation=context["representation"]) nodes = [root, volume_node] self[:] = nodes @@ -96,36 +98,6 @@ class LoadVDBtoRedShift(load.LoaderPlugin): context=context, loader=self.__class__.__name__) - def _apply_settings(self, - grid_node, - path): - """Apply the settings for the VDB path to the VRayVolumeGrid""" - from maya import cmds - - # The path points to a single file. However the vdb files could be - # either just that single file or a sequence in a folder so we check - # whether it's a sequence - folder = os.path.dirname(path) - files = os.listdir(folder) - is_single_file = len(files) == 1 - if is_single_file: - filename = path - else: - # The path points to the publish .vdb sequence filepath so we - # find the first file in there that ends with .vdb - files = sorted(files) - first = next((x for x in files if x.endswith(".vdb")), None) - if first is None: - raise RuntimeError("Couldn't find first .vdb file of " - "sequence in: %s" % path) - filename = os.path.join(path, first) - - # Tell Redshift whether it should load as sequence or single file - cmds.setAttr(grid_node + ".useFrameExtension", not is_single_file) - - # Set file path - cmds.setAttr(grid_node + ".fileName", filename, type="string") - def update(self, container, representation): from maya import cmds @@ -137,7 +109,7 @@ class LoadVDBtoRedShift(load.LoaderPlugin): assert len(grid_nodes) == 1, "This is a bug" # Update the VRayVolumeGrid - self._apply_settings(grid_nodes[0], path=path) + self._set_path(grid_nodes[0], path=path, representation=representation) # Update container representation cmds.setAttr(container["objectName"] + ".representation", @@ -162,3 +134,19 @@ class LoadVDBtoRedShift(load.LoaderPlugin): def switch(self, container, representation): self.update(container, representation) + + @staticmethod + 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) + + is_sequence = bool(representation["context"].get("frame")) + cmds.setAttr(grid_node + ".useFrameExtension", is_sequence) + + # Set file path + cmds.setAttr(grid_node + ".fileName", path, type="string")