获取分配着色器的网格的名称

时间:2014-06-19 08:26:12

标签: python geometry maya

如何使用python?

获取着色器所分配的网格的名称

示例,lambert02 - > AreaA_01_geo,lambert03 - > AreaA_03_geo,lambert04 - > AreaA_04_geo

我尝试使用

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

但我无法从name变量

中获取任何内容

3 个答案:

答案 0 :(得分:3)

着色器连接到一个或多个容纳分配的着色集。所以这不是1:1的任务,而是一对多,然后再一对多(授予你不经常看到它)。请注意,当您只需要一个名称空间时,可以使用2个名称空间。

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)

答案 1 :(得分:1)

我试图在我的场景中生成现有着色器列表以及每个着色器所分配的对象(网格,形状,变换)时遇到了同样的问题。

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()

这将生成如下打印样本(在测试场景上运行时):

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

如果你正在寻找专门用于网格物体的话,从这里可以很容易地得到相关的网格物体。

修改

在阅读了更多内容后,我发现我们可以使用以下命令获取已分配着色器的网格对象列表。

sets(shadingEngine, q=True)

因此

的最终形式
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()

这种最新方法使我们能够获得网格节点以及着色器节点。

这是一个示例输出:

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)

答案 2 :(得分:0)

在发布我之前的回答后,我偶然发现了Maya的意外行为。

我发现当我尝试从Hypershade窗口中选择shadingEngine节点(着色组节点)时,您会在属性编辑器中获得Shading Engine属性,如下所示: Shading Group Node selected in Hypershade Window

现在,如果您点击“属性编辑器”底部的“选择”按钮实际尝试选择该shadingEngine节点,则会得到以下结果: Selecting the Shading Group Node with code and inside Attribute Editor selects the assigned meshes!

Maya实际上已经为我们选择了指定的网格对象。

所以我尝试用这个单行代码做同样的事情:

select('aiHeiyuVarABelts2Shader', replace=True)

实际上,Maya选择了与着色器分配的完全相同的网格节点。

这是我之前回答中的确切测试场景。在我之前的代码中,listConnections()返回连接到shadingEngine节点的变换节点列表,使用上面这2个新方法选择shadingEngine节点,Maya实际为我们选择了网格对象。

因此,利用这种看似不一致的行为,我可以修改我的代码,专门获取您要求的网格列表。

for shEngine in ls(type='shadingEngine'):
    select(shEngine, replace=True)
    print 'shading engine:', shEngine

    for connection in ls(sl=True):
        print '->', connection, '(%s)' % nodeType(connection)

    print ''

在我之前的回复中的同一个示例场景中运行它,我得到了这个:

shading engine: aiHeiyuVarALashesShaderSG
    -> C_heiYuA_Mesh_lod200_v007:L_lower_eyelash_geoShape (mesh)
    -> C_heiYuA_Mesh_lod200_v007:L_upper_eyelash_geoShape (mesh)
    -> C_heiYuA_Mesh_lod200_v007:R_lower_eyelash_geoShape (mesh)
    -> C_heiYuA_Mesh_lod200_v007:R_upper_eyelash_geoShape (mesh)

shading engine: aiHeiyuVarAPantsShaderSG
    -> C_heiYuA_Mesh_lod200_v007:pants_geoShape (mesh)

shading engine: aiHeiyuVarASkinShaderMapSG
    -> C_heiYuA_Mesh_lod200_v007:body_geoShape (mesh)

shading engine: aiTopShaderSG
    -> C_heiYuA_Mesh_lod200_v007:top_geoShape (mesh)

shading engine: initialParticleSE

shading engine: initialShadingGroup
    -> C_heiYuA_Mesh_lod200_v007:upperTeeths_geoShape (mesh)
    -> C_heiYuA_Mesh_lod200_v007:lowerTeeths_geoShape (mesh)
    -> C_heiYuA_Mesh_lod200_v007:gums_geoShape (mesh)
    -> C_heiYuA_Mesh_lod200_v007:L_nail_geoShape (mesh)
    -> C_heiYuA_Mesh_lod200_v007:R_nail_geoShape (mesh)

shading engine: phong1SG

shading engine: useBackground1SG

现在代码更短,所有选定的对象都是网格对象。

要获取连接到shadingEngine节点的着色器节点/表面材质,我们可以使用:

listConnections(shadingEngineNode, type=['shadingDependNode', 'THdependNode'])

就我个人而言,我倾向于远离这种方法,因为不知怎的,我觉得它不优雅,不得不依靠select(),然后依靠ls(sl=True)函数来检索所选对象。

我是偏执狂吗?使用这种方法我也会感到不安全,总是担心Maya会在未来的版本中继续支持这种行为。

我刚刚在Maya 2014和Maya 2016中对此进行了测试。代码在两个版本中的工作原理完全相同。

底线是,它的工作原理。如果您愿意,请随意利用它:)

修改 在做了更多的挖掘和搜索之后,我意识到shadingEngine是objectSet的子类。当我们处理集合(选择集,渲染集,光链接集,变形成员集等)时,这种“意外行为”实际上是标准的Maya行为。

因此我们可以直接使用sets(setName, q=True)来查询集合成员。与上面提到的依赖select()命令的方法相比,这更加明智,优雅和快捷,然后查询选择以获取集合的成员。

这是最后一段代码:

from pymel.core import *

for shEngine in ls(type='shadingEngine'):
    print 'shading engine:', shEngine
    for connection in sets(shEngine,q=True):
        print '\t->', connection, '(%s)' % nodeType(connection)
    print ''