Problems with MItSelectionList Filters

One of the most common tools in the Maya API for custom commands is the MItSelectionList class. Part of the reason why it is so valuable is because it allows for an optional filter in its constructor using the MFn::Type enum. Applying a filter allows us to effectively ignore certain types of objects in which we are not interested, and conceivably to code with some amount of impunity since we know what the objects inside the iterator will be. Conceivably…

While working on some custom commands for the book over the weekend, I discovered some cases in which the filters do not work correctly (at least in Python). Based on what I have seen so far, I would not be surprised if similar errors appeared for other filters, so be on the lookout!

Specifically, using the MFn.kDagNode or the MFn.kTransform filter should limit the iterator to objects of type kDagSelection. In the former case, this could still include shape nodes, while the latter case properly excludes them. The problem, however, is that the iterator will still include objects of type kPlugSelection! As such, while a transform or any other DAG object could be captured using MItSelectionList.getDagPath(), you can get a difficult-to-find error if a plug has snuck into your selection somehow.

You should therefore include an additional test within your iterator using MItSelectionList.itemType(). I have made a simple Python script so you can see the problem as well as a possible solution:

import maya.OpenMaya as OM
import maya.cmds as cmds

locator1 = cmds.spaceLocator()
mathNode = cmds.createNode("multMatrix")
locator2 = cmds.spaceLocator()

sList = OM.MSelectionList()
sList.add(locator1[0])
sList.add(locator1[0]+".rotateX")
sList.add(mathNode)
sList.add(locator2[0])
sList.add("locatorShape"+locator2[0].lstrip("locator"))

sListAsStrings = []
sList.getSelectionStrings(sListAsStrings)

print "List: %s" % sListAsStrings

iter = OM.MItSelectionList(sList, OM.MFn.kDagNode)

while not iter.isDone():
    objectName = []
    iter.getStrings(objectName)
    if iter.itemType() is not OM.MItSelectionList.kDagSelectionItem:
          print "%s is not a valid dagpath. It is item type %s" % (objectName[0], iter.itemType())
    else:
          print "%s is a valid dagpath" % objectName[0]
    iter.next()

You should end up with something like:

List: [u’locator1’, u’locator1.rotateX’, u’multMatrix1’, u’locator2’, u’locatorShape2’]
locator1 is a valid dagpath
locator1.rotateX is not a valid dagpath. It is item type 3
locator2 is a valid dagpath
locatorShape2 is a valid dagpath

Tags: , , ,

Leave a Reply