Repository: ynput/OpenPype
Issue: Maya: Vray - handle vrmeshes in look assignment

 ## Problem

We don't support `vrmesh` type in vray proxy for look assignment as we cannot get object IDs from it. We support only alembics. Nevertheless if artist has `vrmesh` in scene and tries to apply look, it ends up with lot of crashes and confusion. We should at least issue visible warning that he can't assign look to `vrmesh`.

[cuID:1rgq6u8]

Changed files:
openpype/tools/mayalookassigner/vray_proxies.py, openpype/tools/mayalookassigner/commands.py, openpype/tools/mayalookassigner/app.py, openpype/tools/mayalookassigner/widgets.py

diff --git a/openpype/tools/mayalookassigner/app.py b/openpype/tools/mayalookassigner/app.py
index fb99333f87..31bb455f95 100644
--- a/openpype/tools/mayalookassigner/app.py
+++ b/openpype/tools/mayalookassigner/app.py
@@ -24,7 +24,6 @@ from .commands import (
 )
 from .vray_proxies import vrayproxy_assign_look
 
-
 module = sys.modules[__name__]
 module.window = None
 
@@ -210,7 +209,7 @@ class App(QtWidgets.QWidget):
             # Assign the first matching look relevant for this asset
             # (since assigning multiple to the same nodes makes no sense)
             assign_look = next((subset for subset in item["looks"]
-                               if subset["name"] in looks), None)
+                                if subset["name"] in looks), None)
             if not assign_look:
                 self.echo("{} No matching selected "
                           "look for {}".format(prefix, asset))
@@ -229,11 +228,14 @@ class App(QtWidgets.QWidget):
 
             if cmds.pluginInfo('vrayformaya', query=True, loaded=True):
                 self.echo("Getting vray proxy nodes ...")
-                vray_proxies = set(cmds.ls(type="VRayProxy"))
-                nodes = list(set(item["nodes"]).difference(vray_proxies))
+                vray_proxies = set(cmds.ls(type="VRayProxy", long=True))
+
                 if vray_proxies:
                     for vp in vray_proxies:
-                        vrayproxy_assign_look(vp, subset_name)
+                        if vp in nodes:
+                            vrayproxy_assign_look(vp, subset_name)
+
+                    nodes = list(set(item["nodes"]).difference(vray_proxies))
 
                 # Assign look
             if nodes:
diff --git a/openpype/tools/mayalookassigner/commands.py b/openpype/tools/mayalookassigner/commands.py
index f7d26f9adb..b9402d8ea1 100644
--- a/openpype/tools/mayalookassigner/commands.py
+++ b/openpype/tools/mayalookassigner/commands.py
@@ -8,7 +8,6 @@ from openpype.hosts.maya.api import lib
 
 from avalon import io, api
 
-
 from .vray_proxies import get_alembic_ids_cache
 
 log = logging.getLogger(__name__)
@@ -90,6 +89,7 @@ def get_all_asset_nodes():
         container_name = container["objectName"]
         nodes += cmds.sets(container_name, query=True, nodesOnly=True) or []
 
+    nodes = list(set(nodes))
     return nodes
 
 
@@ -106,9 +106,19 @@ def create_asset_id_hash(nodes):
         # iterate over content of reference node
         if cmds.nodeType(node) == "reference":
             ref_hashes = create_asset_id_hash(
-                cmds.referenceQuery(node, nodes=True))
+                list(set(cmds.referenceQuery(node, nodes=True, dp=True))))
             for asset_id, ref_nodes in ref_hashes.items():
                 node_id_hash[asset_id] += ref_nodes
+        elif cmds.pluginInfo('vrayformaya', query=True,
+                             loaded=True) and cmds.nodeType(
+                node) == "VRayProxy":
+            path = cmds.getAttr("{}.fileName".format(node))
+            ids = get_alembic_ids_cache(path)
+            for k, _ in ids.items():
+                pid = k.split(":")[0]
+                if node not in node_id_hash[pid]:
+                    node_id_hash[pid].append(node)
+
         else:
             value = lib.get_id(node)
             if value is None:
@@ -141,22 +151,8 @@ def create_items_from_nodes(nodes):
 
     id_hashes = create_asset_id_hash(nodes)
 
-    # get ids from alembic
-    if cmds.pluginInfo('vrayformaya', query=True, loaded=True):
-        vray_proxy_nodes = cmds.ls(nodes, type="VRayProxy")
-        for vp in vray_proxy_nodes:
-            path = cmds.getAttr("{}.fileName".format(vp))
-            ids = get_alembic_ids_cache(path)
-            parent_id = {}
-            for k, _ in ids.items():
-                pid = k.split(":")[0]
-                if not parent_id.get(pid):
-                    parent_id.update({pid: [vp]})
-
-            print("Adding ids from alembic {}".format(path))
-            id_hashes.update(parent_id)
-
     if not id_hashes:
+        log.warning("No id hashes")
         return asset_view_items
 
     for _id, id_nodes in id_hashes.items():
diff --git a/openpype/tools/mayalookassigner/vray_proxies.py b/openpype/tools/mayalookassigner/vray_proxies.py
index d2f345e628..ecc9a2a873 100644
--- a/openpype/tools/mayalookassigner/vray_proxies.py
+++ b/openpype/tools/mayalookassigner/vray_proxies.py
@@ -41,7 +41,12 @@ def get_alembic_paths_by_property(filename, attr, verbose=False):
     filename = filename.replace("\\\\", "/")
     filename = str(filename)  # path must be string
 
-    archive = alembic.Abc.IArchive(filename)
+    try:
+        archive = alembic.Abc.IArchive(filename)
+    except RuntimeError:
+        # invalid alembic file - probably vrmesh
+        log.warning("{} is not an alembic file".format(filename))
+        return {}
     root = archive.getTop()
 
     iterator = list(root.children)
@@ -201,9 +206,7 @@ def load_look(version_id):
         with avalon.maya.maintained_selection():
             container_node = api.load(loader, look_representation)
 
-    # Get container members
-    shader_nodes = cmds.sets(container_node, query=True)
-    return shader_nodes
+    return cmds.sets(container_node, query=True)
 
 
 def get_latest_version(asset_id, subset):
diff --git a/openpype/tools/mayalookassigner/widgets.py b/openpype/tools/mayalookassigner/widgets.py
index 625e9ef8c6..fceaf27244 100644
--- a/openpype/tools/mayalookassigner/widgets.py
+++ b/openpype/tools/mayalookassigner/widgets.py
@@ -20,7 +20,6 @@ MODELINDEX = QtCore.QModelIndex()
 
 
 class AssetOutliner(QtWidgets.QWidget):
-
     refreshed = QtCore.Signal()
     selection_changed = QtCore.Signal()
 
@@ -84,14 +83,13 @@ class AssetOutliner(QtWidgets.QWidget):
         """
 
         selection_model = self.view.selectionModel()
-        items = [row.data(TreeModel.ItemRole) for row in
-                 selection_model.selectedRows(0)]
-
-        return items
+        return [row.data(TreeModel.ItemRole)
+                for row in selection_model.selectedRows(0)]
 
     def get_all_assets(self):
         """Add all items from the current scene"""
 
+        items = []
         with lib.preserve_expanded_rows(self.view):
             with lib.preserve_selection(self.view):
                 self.clear()
@@ -118,7 +116,7 @@ class AssetOutliner(QtWidgets.QWidget):
 
         # Collect all nodes by hash (optimization)
         if not selection:
-            nodes = cmds.ls(dag=True,  long=True)
+            nodes = cmds.ls(dag=True, long=True)
         else:
             nodes = commands.get_selected_nodes()
         id_nodes = commands.create_asset_id_hash(nodes)
@@ -187,7 +185,6 @@ class AssetOutliner(QtWidgets.QWidget):
 
 
 class LookOutliner(QtWidgets.QWidget):
-
     menu_apply_action = QtCore.Signal()
 
     def __init__(self, parent=None):
@@ -237,9 +234,7 @@ class LookOutliner(QtWidgets.QWidget):
         """
 
         datas = [i.data(TreeModel.ItemRole) for i in self.view.get_indices()]
-        items = [d for d in datas if d is not None]  # filter Nones
-
-        return items
+        return [d for d in datas if d is not None]
 
     def right_mouse_menu(self, pos):
         """Build RMB menu for look view"""