Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting the name of the mesh that shader was assigned to

How do I get the name of the mesh that the shader was assigned to, using python?

Example, lambert02 --> AreaA_01_geo, lambert03 --> AreaA_03_geo, lambert04 --> AreaA_04_geo

I tried using

Shader = cmds.ls(type = 'surfaceShader')
for i in Shader:
    con = mc.listConnections('%s.outColor' % i)
    name = cmds.listConnections(Shader, type="mesh")

But I was unable to get anything out of name variable

like image 334
yan Avatar asked Dec 12 '25 19:12

yan


2 Answers

The shader is connected to one or more shading sets which house the assignments. So this is not a 1:1 assignment but rather one to many, and then one to many again (granted you don't see it that often). Please note that you use 2 namespaces when you only should need one.

import maya.cmds as mc

Shader = mc.ls(type = 'surfaceShader')
for i in Shader:
    con = mc.listConnections('%s.outColor' % i)
    names = mc.listConnections(con, type="mesh")
    print i, "->", ", ".join(names)
like image 84
joojaa Avatar answered Dec 14 '25 07:12

joojaa


I ran into this same problem in my attempt to generate a list of existing shaders in my scene, and the objects (meshes, shapes, transforms) that each shader is assigned to.

from pymel.core import *

def getShaders():
    for shEngine in ls(type='shadingEngine'):
        print 'shading engine:', shEngine

        for connection in shEngine.listConnections():
            connectionNodeTypeList = nodeType(connection, i=True)

            if [x for x in connectionNodeTypeList if 'ependNode' in x]:
                # tests for shader nodes. they inherit the 'shadingDependNode' type
                # I am using Arnold renderer. Arnold shading nodes inherit the 'THdependNode' type
                print '\t<shader> ->', connection, '(%s)'% nodeType(connection)

            if 'dagNode' in connectionNodeTypeList:
                # tests for transform, geometry and shape node
                # any transform, mesh, shape, curves, vertices, edges, faces
                # will inherit from the 'dagNode' type
                print '\t<dagNode> ->',connection, '(%s)'% nodeType(connection)
        print ''
getShaders()

This will generate a sample print out as follows (when run on a test scene):

shading engine: aiHeiyuVarALashesShaderSG
    <dagNode> -> C_heiYuA_Mesh_lod200_v007:L_lower_eyelash_geo (transform)
    <dagNode> -> C_heiYuA_Mesh_lod200_v007:L_upper_eyelash_geo (transform)
    <dagNode> -> C_heiYuA_Mesh_lod200_v007:R_lower_eyelash_geo (transform)
    <dagNode> -> C_heiYuA_Mesh_lod200_v007:R_upper_eyelash_geo (transform)
    <shader> -> aiHeiyuVarALashesShader (aiStandard)

shading engine: aiHeiyuVarAPantsShaderSG
    <dagNode> -> C_heiYuA_Mesh_lod200_v007:pants_geo (transform)
    <shader> -> aiHeiyuVarAPantsShader (aiStandard)

shading engine: aiHeiyuVarASkinShaderMapSG
    <dagNode> -> C_heiYuA_Mesh_lod200_v007:body_geo (transform)
    <shader> -> aiHeiyuVarASkinShaderMap (aiStandard)

shading engine: aiTopShaderSG
    <dagNode> -> C_heiYuA_Mesh_lod200_v007:top_geo (transform)
    <shader> -> aiHeiyuVarATopShader (aiStandard)

shading engine: initialParticleSE
    <shader> -> lambert1 (lambert)
    <shader> -> particleCloud1 (particleCloud)

shading engine: initialShadingGroup
    <shader> -> lambert1 (lambert)
    <dagNode> -> C_heiYuA_Mesh_lod200_v007:R_nail_geo (transform)
    <dagNode> -> C_heiYuA_Mesh_lod200_v007:L_nail_geo (transform)
    <dagNode> -> C_heiYuA_Mesh_lod200_v007:gums_geo (transform)
    <dagNode> -> C_heiYuA_Mesh_lod200_v007:lowerTeeths_geo (transform)
    <dagNode> -> C_heiYuA_Mesh_lod200_v007:upperTeeths_geo (transform)

shading engine: phong1SG

shading engine: useBackground1SG

From here it is easy to arrive at the associated mesh objects if you are looking specifically for meshes.

Edit:

After reading up some more, I figured out that we can use the following command to get a list of the mesh objects that has been assigned the shader.

sets(shadingEngine, q=True)

Thus the final form of the

from pymel.core import *

def getShaders():
    for shEngine in ls(type='shadingEngine'):
        print 'shading engine:', shEngine

        for connection in [x for x in shEngine.listConnections()]:
            myType = nodeType(connection,i=True)
            if ('shadingDependNode' in myType or 'THdependNode' in myType):
                # found a shader, printing it out
                print '\t<shader> ->', connection, '(%s)'% nodeType(connection)

        for connection in sets(shEngine, q=True):
            # prints out the list of members that the shader is assigned to
            print '\t<dagNode> ->',connection, '(%s)'% nodeType(connection)
        print ''
getShaders()

This latest method enables us to get at the mesh nodes as well as the shader nodes.

Here's a sample output:

shading engine: aiHeiyuVarAPantsShaderSG
    <shader> -> aiHeiyuVarAPantsShader (aiStandard)
    <dagNode> -> C_heiYuA_Mesh_lod200_v007:pants_geoShape (mesh)

shading engine: aiHeiyuVarASkinShaderMapSG
    <shader> -> aiHeiyuVarASkinShaderMap (aiStandard)
    <dagNode> -> C_heiYuA_Mesh_lod200_v007:body_geoShape (mesh)

shading engine: aiTopShaderSG
    <shader> -> aiHeiyuVarATopShader (aiStandard)
    <dagNode> -> C_heiYuA_Mesh_lod200_v007:top_geoShape (mesh)

shading engine: initialParticleSE
    <shader> -> lambert1 (lambert)
    <shader> -> particleCloud1 (particleCloud)

shading engine: initialShadingGroup
    <shader> -> lambert1 (lambert)
    <dagNode> -> C_heiYuA_Mesh_lod200_v007:upperTeeths_geoShape (mesh)
    <dagNode> -> C_heiYuA_Mesh_lod200_v007:lowerTeeths_geoShape (mesh)
    <dagNode> -> C_heiYuA_Mesh_lod200_v007:gums_geoShape (mesh)
    <dagNode> -> C_heiYuA_Mesh_lod200_v007:L_nail_geoShape (mesh)
    <dagNode> -> C_heiYuA_Mesh_lod200_v007:R_nail_geoShape (mesh)
like image 29
Patrick Woo Avatar answered Dec 14 '25 08:12

Patrick Woo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!