Maya 2019 | List Arnold Shaders

python
maya
#1

Hi there,

I’m trying to create a dictionary for all of my materials within maya. The shading engine as the key, and their material as the value. I’ve tried listing all the shading engines, and then listing the relatives to those, with the type “aiStandardSurface”. But maya is telling me that “aiStandardSurface” is a non. And if I try to find the type of an aiStandard called dogs or w/e, it tell me that it is of type “aiStandardSurface”.

I’ve also tried listing lambert as well but I get a “none” too.

Any insight would be greatly appreciated! :slight_smile: Thanks!

import maya.cmds as mc

mat_dict= {}

for SG in mc.ls(type='shadingEngine'):
    mat = mc.listRelatives(type='aiStandardSurface')
    
    print mat
    mat_dict[SG] = mat

for x in mat_dict:
    print(mat_dict[x])
#2

Hi polyShifter - welcome to the forum!,

Not sure about the shading engine (from my understanding they are basically sets) but to get the materials and the type you could use map and lambda:

import maya.cmds as cmds

# In one line

print dict(map(lambda n: (n, cmds.nodeType(n)), cmds.ls(mat=True)))

# Or ...

mats = {}
for mat in cmds.ls(mat=True)):
   mats[mat] = cmds.nodeType(mat)

print mats

if you want everything with just the type of aiStandardShader you could use filter:

# This will print a list of materials of type aiStandardSurface

print filter(lambda n: cmds.nodeType(n) == "aiStandardSurface", cmds.ls(mat=True))

# or maybe key/value pairs of types that starts with *ai* ?

ai_mats = filter(lambda n: cmds.nodeType(n).startswith("ai"),  cmds.ls(mat=True))
print dict(map(lambda n: (n, cmds.nodeType(n)), ai_mats))

-c

#3

Alternatively, if you wanted to start from the shading engine as you described,
you could list the connections form the surfaceShader plug, like so.

import maya.cmds as cmds
import pprint

mat_dict= {}

for SG in cmds.ls(type='shadingEngine'):
    mat = cmds.listConnections(SG + '.surfaceShader', destination=True)[0]   
    mat_dict[SG] = mat
    
pprint.pprint(mat_dict)

Of course this only works on materials that have a SG assigned, and only takes surface shader assignments into account.
So if you absolutely need all materials and don’t care about the SG, chalk’s approach is better.

1 Like
#4

Hey @PVDH - welcome to the forum! :slight_smile: Nice approach, wondering if we could combine both? Im going under the assumption the arnold shaders start with “ai”…:


mats = {}

for shading_group in cmds.ls(type="shadingEngine"): 

   connection = cmds.lsConnections(
       shading_group, ".surfaceShader", destination=True)[0]

   connection_type = cmds.nodeType(connection)

   if connection_type.startswith("ai"):
       mats[shading_group] = connection_type

-c

1 Like
#5

Omg, all of these solutions are awesome! haha thank you!

I was wondering how you knew to use “mat”, I mean it’s pretty obvious, but is there anything that I can use to identify what an “aiStandardSurface” is or anything else? I’m always at a loss to find out what exactly a node type is. I’ve tried using nodeType, but maybe I wasn’t using it correctly or something.

Again you guys totally rock :smiley: thanks!

Also, thanks for the tip with the pprint :wink: I looked up the module :smiley:

#6

Hey @chalk. Thank You! :slightly_smiling_face:

Combining them does indeed do precisely what @polyshifter asked for, good shout!

#7

“mat” is a flag in the ls command, but I’m not sure how Maya classifies those.
Because both nodeType and objectType will return the specific material type.
I imagine there is list somewhere of all the node types that are either materials or shading groups

And no worries about pprint. It is a lifesaver when working with dictionaries! :wink:

#8

no kidding! haha it’s so “pretty” :wink:
Yeah I’ve been looking for that dang list haha