Find material of selected mesh in RenderLayers in python


#1

I’m trying to get the material name of a selected mesh in each renderLayers it is added, without switching render layers. However, I get this error: TypeError: object of type ‘RenderLayer’ has no len()

Code to get material from object:

import pymel.core as pm
import maya.cmds as cmds
# Create a dictionary for {"object1": ["material1", "material2"]}
objectToMaterials = {}
for obj in pm.ls(sl=1):
    for layer in obj.listConnections(type="renderLayer"):
        print 'object: %s  layer: %s' % (obj, layer )                       # result:     object: pSphere1  layer: layer3
        allChildren = cmds.listRelatives(ad=1)
        for eachChild in allChildren:
            if cmds.objectType(eachChild)=="mesh":
                eachChild = cmds.listRelatives(eachChild, parent=1)
                print eachChild # result:     [u'pSphere1']
                print layer  # result:      layer3
                cmds.editRenderLayerGlobals(crl=layer)              # result:   TypeError: object of type 'RenderLayer' has no len() # 
                # Get the shader groups attached to this particular object
                shaderGroups = cmds.listConnections(cmds.listHistory(eachChild))
                if shaderGroups is not None:
                    # Get the material attached to the shader group
                    materials = [x for x in cmds.ls(cmds.listConnections(shaderGroups), materials=1)]       
                objectToMaterials.setdefault(eachChild[0], []).append(eachRenderLayer)
                objectToMaterials.setdefault(eachChild[0], []).append(materials[0])
print(objectToMaterials)

Thanks for any help because i’ve done many tests without any success …


#2

Hey Manue
I noticed you were using cmds and pm together, but these both store variables differently. I found that once you use all pymel it works fine.

import pymel.core as pm

objectToMaterials = {}
for obj in pm.ls(sl=1):
for layer in obj.listConnections(type=“renderLayer”):
print ‘object: %s layer: %s’ % (obj, layer )
allChildren = pm.listRelatives(ad=1)
for eachChild in allChildren:
if pm.objectType(eachChild)==“mesh”:
eachChild = pm.listRelatives(eachChild, parent=1)
print eachChild
print layer
pm.editRenderLayerGlobals(crl=layer)
shaderGroups = pm.listConnections(pm.listHistory(eachChild))
if shaderGroups is not None:
materials = [x for x in pm.ls(pm.listConnections(shaderGroups), materials=1)]
objectToMaterials.setdefault(eachChild[0], []).append(eachRenderLayer) #i dont know where this comes from
objectToMaterials.setdefault(eachChild[0], []).append(materials[0])
print(objectToMaterials)

Although I don’t know where this variable comes from.

objectToMaterials.setdefault(eachChild[0], []).append(eachRenderLayer)