Thursday, June 11, 2015

Maya - Node Types - Filter Types

How to list all the lambert shaders in maya?
Well, if we use the MEL or pyhton command ls -type "lambert" we get more than just lambert shaders (if there are others in the scene). The reason is that the lambert shader has a type name which is the type for eg. blinn and phong are inherited from. The class hierarchy or inheritance diagram looks like this.


We can get this from the maya API documentation but we can query via MEL or python commands.

The following line gives us the inheritance diagram of  "blinn1" shader as a list:

 cmds.nodeType("blinn1", inherited = 1)  
 # Result: [u'shadingDependNode', u'lambert', u'reflect', u'blinn'] #   

As we can see the items are similar but not the same. That is why because MEL and python scripts not work with C++ API names. If we look up blinn  node from the nodes list of the technical documentation area we can see the parents field:


If we click on reflect we get the node to get the description of that node we can see the relfect node's partent is the lambert.

So we can really search node types or "supertypes". We can imagine these nodes as part of a set. Maya  ls command and other commands with type flag can use these types. So for eg. we can list all the shape nodes in the scene by entering the following line:

 cmds.ls(type = "shape")  

Or we can filter all the geometry type shapes, like curves, nurbs surfaces, meshes:

 cmds.ls(type = "geometryShape")  

So answering the first question: we can filter lambert shaders if we list lambert type with ls than check the exact type with nodeType command.

 lambertTypeMaterialList = cmds.ls(type = "lambert")  
 lambertMaterialList = []  
 for item in lambertTypeMaterialList:  
     if cmds.nodeType(item) == "lambert":  
         lambertMaterialList.append(item)  
 # Result: [u'lambert1', u'lambert2'] #   


With python set we can achieve useful functions easily. I wrote a function to check two or more objects' common type. I hope it works well.


 def GetCommonClass(SelectedNodeList):  
     '''  
     == DESCRIPTION ==  
     Get the common type of the passed object list which is the first item in the inheritance diagram.  
     For eg. if we test a directionalLight and a nurbsCurve type nodes together the inheritance diagram are like this:  
     [u'containerBase', u'entity', u'dagNode', u'shape', u'geometryShape', u'deformableShape', u'controlPoint', u'curveShape', u'nurbsCurve']  
     [u'containerBase', u'entity', u'dagNode', u'shape', u'light', u'renderLight', u'nonAmbientLightShapeNode', u'nonExtendedLightShapeNode', u'directionalLight']  
     And we can see the first common type is the 'shape'.  
     == INPUT ARGUMENTS ==  
     + list - SelectedNodeList - Maya node list  
     +  
     == RETURN ==  
     string - the first common type   
     == DEPENDENCIES ==  
     - maya.cmds  
     -  
     '''  
     if SelectedNodeList:  
         nodeTypeList = []  
         nodeTypeSet = set()  
         for item in SelectedNodeList:  
             nodeTypeList = cmds.nodeType(item, inherited = 1)  
             print nodeTypeList  
             if len(nodeTypeSet) != 0:  
                 nodeTypeSet.intersection_update(set(nodeTypeList))  
                 if len(nodeTypeSet) == 0:  
                     print "There is no common type within selection."  
                     return None  
             else:  
                 nodeTypeSet.update(set(nodeTypeList))  
         commonTypeIndexList = []  
         for commonType in nodeTypeSet:  
             commonTypeIndexList.append(nodeTypeList.index(commonType))  
         firstCommonType = nodeTypeList[sorted(commonTypeIndexList)[-1]]  
         return firstCommonType  
     else:  
         return None