Example #1
0
def name_to_node(name):
    """Open Maya utility to convert a given node name to MObject"""
    selectionList = MSelectionList()
    selectionList.add(name)
    node = MObject()
    selectionList.getDependNode(0, node)
    return node
Example #2
0
File: it.py Project: kthulhu/mrv
def graphIterator( nodeOrPlug, *args, **kwargs ):
	"""
	:return: MItDependencyGraph configured according to args - see docs at
		`iterGraph`.
	:note: use this method if you want to use more advanced features of the iterator
	:raise RuntimeError: if the filter types does not allow any nodes to be returned.
		This is a bug in that sense as it should just return nothing. It also shows that
		maya pre-parses the result and then just iterates over a list with the iterator in
		question"""
	startObj = startPlug = None

	if isinstance( nodeOrPlug, api.MPlug ):
		startPlug = nodeOrPlug
		startObj = MObject()
	elif isinstance( nodeOrPlug, Node ):
		startObj = nodeOrPlug.object()
		startPlug = nullplugarray[0]
	else:
		startObj = nodeOrPlug
		startPlug = nullplugarray[0]
	# END traversal root

	inputPlugs = kwargs.get('input', False)
	breadth = kwargs.get('breadth', False)
	plug = kwargs.get('plug', False)
	prune = kwargs.get('prune', False)
	typeFilter = _argsToFilter( args )

	if startPlug is not None :
		typeFilter.setObjectType( api.MIteratorType.kMPlugObject )
	else :
		typeFilter.setObjectType( api.MIteratorType.kMObject )
	# END handle object type

	direction = api.MItDependencyGraph.kDownstream
	if inputPlugs :
		direction = api.MItDependencyGraph.kUpstream

	traversal =	 api.MItDependencyGraph.kDepthFirst
	if breadth :
		traversal = api.MItDependencyGraph.kBreadthFirst

	level = api.MItDependencyGraph.kNodeLevel
	if plug :
		level = api.MItDependencyGraph.kPlugLevel

	iterObj = api.MItDependencyGraph( startObj, startPlug, typeFilter, direction, traversal, level )

	iterObj.disablePruningOnFilter()
	if prune :
		iterObj.enablePruningOnFilter()

	return iterObj
Example #3
0
 def addCBs(self, event=None):
     try:
         print "adding callbacks"
         self.renderLayer.currentIndexChanged.connect(self.layerChanged)
         self.NodeNameMsgId = MNodeMessage.addNameChangedCallback(
             MObject(), self.nameChangedCB)
         self.newNodeCBMsgId = MDGMessage.addNodeAddedCallback(
             self.newNodeCB)
         self.delNodeCBMsgId = MDGMessage.addNodeRemovedCallback(
             self.delNodeCB)
         print "adding scriptjob"
         self.layerChangedJob = cmds.scriptJob(
             e=["renderLayerManagerChange", self.setCurrentLayer])
     except:
         pass
Example #4
0
    def doIt(self, mArgs):
        ret, argData = self.grabArgDb(mArgs)
        if ret:
            return

        sel = OpenMaya.MSelectionList()
        argData.getObjects(sel)

        objs = []
        for n in range(sel.length()):
            obj = MObject()
            sel.getDependNode(n, obj)
            objs.append(obj)

        #
        if argData.isQuery():
            rotNode = objs[0]

            if argData.isFlagSet(self.kFlagAxis):
                self.setResult(cmd.getAttr('%s.mirrorAxis' % rotNode))

            elif argData.isFlagSet(self.kFlagMode):
                self.setResult(cmd.getAttr('%s.mirrorTranslation' % rotNode))

            return

        #if we're in edit mode, find the node
        elif argData.isEdit():
            rotNode = objs[0]

        #otherwise we're in creation mode - so build the node and connect things up
        else:
            obj, tgt = objs

            #is dummy mode set?
            isDummyMode = argData.isFlagSet(
                self.kFlagDummy) or argData.isFlagSet(self.kFlagDummy)

            #see if there is already a node connected
            existing = cmd.listConnections('%s.t' % tgt,
                                           '%s.r' % tgt,
                                           type=MirrorNode.NODE_TYPE_NAME)
            if existing:
                self.displayWarning(
                    "There is a %s node already connected - use edit mode!" %
                    MirrorNode.NODE_TYPE_NAME)
                self.setResult(existing[0])

                return
            else:
                rotNode = cmd.createNode('rotationMirror')
                cmd.connectAttr('%s.worldMatrix' % obj,
                                '%s.inWorldMatrix' % rotNode)
                cmd.connectAttr('%s.parentInverseMatrix' % obj,
                                '%s.inParentInverseMatrix' % rotNode)

                cmd.connectAttr('%s.parentInverseMatrix' % tgt,
                                '%s.targetParentInverseMatrix' % rotNode)

                joAttrpath = '%s.jo' % tgt
                if cmd.objExists(joAttrpath):
                    cmd.connectAttr(joAttrpath,
                                    '%s.targetJointOrient' % rotNode)

                cmd.connectAttr('%s.rotateOrder' % tgt,
                                '%s.targetRotationOrder' % rotNode)

                if not isDummyMode:
                    cmd.connectAttr('%s.outTranslate' % rotNode, '%s.t' % tgt)
                    cmd.connectAttr('%s.outRotate' % rotNode, '%s.r' % tgt)

                cmd.select(obj)

        #set the result to the node created...
        self.setResult(rotNode)

        #set any attributes passed in from the command-line
        if argData.isFlagSet(self.kFlagAxis):
            axisInt = Axis.FromName(
                argData.flagArgumentString(self.kFlagAxis, 0))
            cmd.setAttr('%s.mirrorAxis' % rotNode, axisInt)

        if argData.isFlagSet(self.kFlagMode):
            modeStr = argData.flagArgumentString(self.kFlagMode, 0)
            modeIdx = list(MirrorNode.MIRROR_MODE_NAMES).index(modeStr)
            cmd.setAttr('%s.mirrorTranslation' % rotNode, modeIdx)
Example #5
0
class ControlPairNode(MPxNode):
    '''
	is used by the poseSym tool for storing control pair relationships
	'''

    NODE_ID = OpenMaya.MTypeId(0x00115941)
    NODE_TYPE_NAME = "controlPair"

    controlA = MObject()
    controlB = MObject()

    axis = MObject()  #this is the axis which things get mirrored across
    flipAxes = MObject()

    neverDoT = MObject(
    )  #if this is true then translation won't get mirrored/swapped
    neverDoR = MObject(
    )  #if this is true then rotation won't get mirrored/swapped
    neverDoOther = MObject(
    )  #if this is true then other keyable attributes won't get mirrored/swapped

    worldSpace = MObject(
    )  #if this is true mirroring is done in world space - otherwise local spaces

    #these are the values for the flip axes
    FLIP_AXES = (), (vectors.AX_X,
                     vectors.AX_Y), (vectors.AX_X,
                                     vectors.AX_Z), (vectors.AX_Y,
                                                     vectors.AX_Z)

    @classmethod
    def Creator(cls):
        return OpenMayaMPx.asMPxPtr(cls())

    @classmethod
    def Init(cls):
        attrMsg = MFnMessageAttribute()

        cls.controlA = attrMsg.create("controlA", "ca")
        cls.controlB = attrMsg.create("controlB", "cb")
        cls.addAttribute(cls.controlA)
        cls.addAttribute(cls.controlB)

        attrEnum = MFnEnumAttribute()
        cls.axis = attrEnum.create("axis", "ax")
        attrEnum.addField('x', 0)
        attrEnum.addField('y', 1)
        attrEnum.addField('z', 2)
        attrEnum.setDefault('x')
        attrEnum.setKeyable(False)
        attrEnum.setChannelBox(True)

        cls.addAttribute(cls.axis)

        cls.axis = attrEnum.create("flipAxes", "flax")
        for n, thisAxes in enumerate(cls.FLIP_AXES):
            if thisAxes:
                enumStr = ''.join([ax.asName() for ax in thisAxes])
            else:
                enumStr = 'none'

            attrEnum.addField(enumStr, n)

        attrEnum.setKeyable(False)
        attrEnum.setChannelBox(True)

        cls.addAttribute(cls.axis)

        numAttr = MFnNumericAttribute()
        cls.neverDoT = numAttr.create("neverDoT", "nvt",
                                      MFnNumericData.kBoolean)
        cls.neverDoR = numAttr.create("neverDoR", "nvr",
                                      MFnNumericData.kBoolean)
        cls.neverDoOther = numAttr.create("neverDoOther", "nvo",
                                          MFnNumericData.kBoolean)

        cls.addAttribute(cls.neverDoT)
        cls.addAttribute(cls.neverDoR)
        cls.addAttribute(cls.neverDoOther)

        cls.worldSpace = numAttr.create("worldSpace", "ws",
                                        MFnNumericData.kBoolean, True)
        cls.addAttribute(cls.worldSpace)
Example #6
0
class MirrorNode(MPxNode):

    NODE_ID = OpenMaya.MTypeId(0x00115940)
    NODE_TYPE_NAME = "rotationMirror"

    inWorldMatrix = MObject(
    )  #this is the input world matrix; the one we want mirrored
    inParentMatrixInv = MObject(
    )  #this is the input parent inverse matrix. ie the parent inverse matrix of the transform we want mirrored

    mirrorAxis = MObject()  #which axis are we mirroring on?
    mirrorTranslation = MObject(
    )  #boolean to determine whether translation mirroring happens in world space or local space

    targetJointOrient = MObject(
    )  #this is the joint orient attribute for the target joint - so it can be compensated for
    targetJointOrientX = MObject()
    targetJointOrientY = MObject()
    targetJointOrientZ = MObject()

    targetParentMatrixInv = MObject(
    )  #this is the parent inverse matrix for the target transform
    targetRotationOrder = MObject()  #the rotation order on the target

    outTranslate = MObject()  #the output translation
    outTranslateX = MObject()
    outTranslateY = MObject()
    outTranslateZ = MObject()

    outRotate = MObject()  #the output rotation
    outRotateX = MObject()
    outRotateY = MObject()
    outRotateZ = MObject()

    MIRROR_MODES = M_COPY, M_INVERT, M_MIRROR = range(3)
    MIRROR_MODE_NAMES = 'copy', 'invert', 'mirror'
    MIRROR_DEFAULT = M_MIRROR

    @classmethod
    def Creator(cls):
        return OpenMayaMPx.asMPxPtr(cls())

    @classmethod
    def Init(cls):
        attrInWorldMatrix = MFnMatrixAttribute()
        attrInParentMatrixInv = MFnMatrixAttribute()

        attrMirrorAxis = MFnEnumAttribute()
        attrMirrorTranslation = MFnEnumAttribute()

        attrTargetParentMatrixInv = MFnMatrixAttribute()
        targetRotationOrder = MFnNumericAttribute()

        attrOutTranslate = MFnNumericAttribute()
        attrOutTranslateX = MFnUnitAttribute()
        attrOutTranslateY = MFnUnitAttribute()
        attrOutTranslateZ = MFnUnitAttribute()

        attrOutRotate = MFnNumericAttribute()
        attrOutRotateX = MFnUnitAttribute()
        attrOutRotateY = MFnUnitAttribute()
        attrOutRotateZ = MFnUnitAttribute()

        attrTargetJointOrient = MFnNumericAttribute()
        attrTargetJointOrientX = MFnUnitAttribute()
        attrTargetJointOrientY = MFnUnitAttribute()
        attrTargetJointOrientZ = MFnUnitAttribute()

        #create the world matrix
        cls.inWorldMatrix = attrInWorldMatrix.create("inWorldMatrix", "iwm")

        cls.addAttribute(cls.inWorldMatrix)

        #create the local matrix
        cls.inParentMatrixInv = attrInWorldMatrix.create(
            "inParentInverseMatrix", "ipmi")

        cls.addAttribute(cls.inParentMatrixInv)

        #create the mirror axis
        cls.mirrorAxis = attrMirrorAxis.create("mirrorAxis", "m")
        attrMirrorAxis.addField('x', 0)
        attrMirrorAxis.addField('y', 1)
        attrMirrorAxis.addField('z', 2)
        attrMirrorAxis.setDefault('x')
        attrMirrorAxis.setKeyable(False)
        attrMirrorAxis.setChannelBox(True)

        cls.addAttribute(cls.mirrorAxis)

        #create the mirror axis
        cls.mirrorTranslation = attrMirrorTranslation.create(
            "mirrorTranslation", "mt")
        for modeName, modeIdx in zip(cls.MIRROR_MODE_NAMES, cls.MIRROR_MODES):
            attrMirrorTranslation.addField(modeName, modeIdx)

        attrMirrorTranslation.setDefault(cls.MIRROR_DEFAULT)
        attrMirrorTranslation.setKeyable(False)
        attrMirrorTranslation.setChannelBox(True)

        cls.addAttribute(cls.mirrorTranslation)

        #create the out world matrix inverse
        cls.targetParentMatrixInv = attrTargetParentMatrixInv.create(
            "targetParentInverseMatrix", "owm")
        cls.addAttribute(cls.targetParentMatrixInv)

        #create the target rotation order attribute
        cls.targetRotationOrder = targetRotationOrder.create(
            "targetRotationOrder", "troo", MFnNumericData.kInt)
        cls.addAttribute(cls.targetRotationOrder)

        #create the joint orient compensation attributes
        cls.targetJointOrientX = attrTargetJointOrientX.create(
            "targetJointOrientX", "tjox", MFnUnitAttribute.kAngle)
        cls.targetJointOrientY = attrTargetJointOrientY.create(
            "targetJointOrientY", "tjoy", MFnUnitAttribute.kAngle)
        cls.targetJointOrientZ = attrTargetJointOrientZ.create(
            "targetJointOrientZ", "tjoz", MFnUnitAttribute.kAngle)
        cls.targetJointOrient = attrTargetJointOrient.create(
            "targetJointOrient", "tjo", cls.targetJointOrientX,
            cls.targetJointOrientY, cls.targetJointOrientZ)
        cls.addAttribute(cls.targetJointOrient)

        #create the out translate attributes
        cls.outTranslateX = attrOutTranslateX.create(
            "outTranslateX", "otx", MFnUnitAttribute.kDistance)
        cls.outTranslateY = attrOutTranslateY.create(
            "outTranslateY", "oty", MFnUnitAttribute.kDistance)
        cls.outTranslateZ = attrOutTranslateZ.create(
            "outTranslateZ", "otz", MFnUnitAttribute.kDistance)
        cls.outTranslate = attrOutTranslate.create("outTranslate", "ot",
                                                   cls.outTranslateX,
                                                   cls.outTranslateY,
                                                   cls.outTranslateZ)
        cls.addAttribute(cls.outTranslate)

        #create the out rotation attributes
        cls.outRotateX = attrOutRotateX.create("outRotateX", "orx",
                                               MFnUnitAttribute.kAngle)
        cls.outRotateY = attrOutRotateY.create("outRotateY", "ory",
                                               MFnUnitAttribute.kAngle)
        cls.outRotateZ = attrOutRotateZ.create("outRotateZ", "orz",
                                               MFnUnitAttribute.kAngle)
        cls.outRotate = attrOutRotate.create("outRotate", "or", cls.outRotateX,
                                             cls.outRotateY, cls.outRotateZ)
        cls.addAttribute(cls.outRotate)

        #setup attribute dependency relationships
        cls.attributeAffects(cls.inWorldMatrix, cls.outTranslate)
        cls.attributeAffects(cls.inWorldMatrix, cls.outRotate)

        cls.attributeAffects(cls.inParentMatrixInv, cls.outTranslate)
        cls.attributeAffects(cls.inParentMatrixInv, cls.outRotate)

        cls.attributeAffects(cls.mirrorAxis, cls.outTranslate)
        cls.attributeAffects(cls.mirrorAxis, cls.outRotate)

        cls.attributeAffects(cls.mirrorTranslation, cls.outTranslate)
        cls.attributeAffects(cls.mirrorTranslation, cls.outRotate)

        cls.attributeAffects(cls.targetParentMatrixInv, cls.outTranslate)
        cls.attributeAffects(cls.targetParentMatrixInv, cls.outRotate)

        cls.attributeAffects(cls.targetRotationOrder, cls.outTranslate)
        cls.attributeAffects(cls.targetRotationOrder, cls.outRotate)

        cls.attributeAffects(cls.targetJointOrient, cls.outRotate)

    def compute(self, plug, dataBlock):
        dh_mirrorTranslation = dataBlock.inputValue(self.mirrorTranslation)
        mirrorTranslation = Axis(dh_mirrorTranslation.asShort())

        inWorldMatrix = dataBlock.inputValue(self.inWorldMatrix).asMatrix()
        inParentInvMatrix = dataBlock.inputValue(
            self.inParentMatrixInv).asMatrix()

        dh_mirrorAxis = dataBlock.inputValue(self.mirrorAxis)
        axis = Axis(dh_mirrorAxis.asShort())

        ### DEAL WITH ROTATION AND POSITION SEPARATELY ###
        R, S = inWorldMatrix.asPy(
            3).decompose()  #this gets just the 3x3 rotation and scale matrices
        x, y, z = R  #extract basis vectors

        #mirror the rotation axes and construct the mirrored rotation matrix
        idxA, idxB = axis.otherAxes()
        x[idxA] = -x[idxA]
        x[idxB] = -x[idxB]

        y[idxA] = -y[idxA]
        y[idxB] = -y[idxB]

        z[idxA] = -z[idxA]
        z[idxB] = -z[idxB]

        #factor scale back into the matrix
        mirroredMatrix = Matrix(x + y + z, 3) * S
        mirroredMatrix = mirroredMatrix.expand(4)

        #now put the rotation matrix in the space of the target object
        dh_targetParentMatrixInv = dataBlock.inputValue(
            self.targetParentMatrixInv)
        tgtParentMatrixInv = dh_targetParentMatrixInv.asMatrix()
        matInv = tgtParentMatrixInv.asPy()

        #put the rotation in the space of the target's parent
        mirroredMatrix = mirroredMatrix * matInv

        #if there is a joint orient, make sure to compensate for it
        tgtJoX = dataBlock.inputValue(self.targetJointOrientX).asDouble()
        tgtJoY = dataBlock.inputValue(self.targetJointOrientY).asDouble()
        tgtJoZ = dataBlock.inputValue(self.targetJointOrientZ).asDouble()

        jo = Matrix.FromEulerXYZ(tgtJoX, tgtJoY, tgtJoZ)
        joInv = jo.inverse()
        joInv = joInv.expand(4)
        mirroredMatrix = mirroredMatrix * joInv

        #grab the rotation order of the target
        rotOrderIdx = dataBlock.inputValue(self.targetRotationOrder).asInt()

        #grab euler values
        R, S = mirroredMatrix.decompose(
        )  #we need to decompose again to extract euler angles...
        eulerXYZ = outX, outY, outZ = mayaRotationOrders[rotOrderIdx](
            R)  #R.ToEulerYZX()

        dh_outRX = dataBlock.outputValue(self.outRotateX)
        dh_outRY = dataBlock.outputValue(self.outRotateY)
        dh_outRZ = dataBlock.outputValue(self.outRotateZ)

        #set the rotation
        dh_outRX.setDouble(outX)
        dh_outRY.setDouble(outY)
        dh_outRZ.setDouble(outZ)

        dataBlock.setClean(plug)

        ### NOW DEAL WITH POSITION ###

        #set the position
        if mirrorTranslation == self.M_COPY:
            inLocalMatrix = inWorldMatrix * inParentInvMatrix
            pos = MPoint(inLocalMatrix(3, 0), inLocalMatrix(3, 1),
                         inLocalMatrix(3, 2))
        elif mirrorTranslation == self.M_INVERT:
            inLocalMatrix = inWorldMatrix * inParentInvMatrix
            pos = MPoint(-inLocalMatrix(3, 0), -inLocalMatrix(3, 1),
                         -inLocalMatrix(3, 2))
        elif mirrorTranslation == self.M_MIRROR:
            pos = MPoint(inWorldMatrix(3, 0), inWorldMatrix(3, 1),
                         inWorldMatrix(3, 2))
            pos = [pos.x, pos.y, pos.z]
            pos[axis] = -pos[axis]
            pos = MPoint(*pos)
            pos = pos * tgtParentMatrixInv

        else:
            return

        dh_outTX = dataBlock.outputValue(self.outTranslateX)
        dh_outTY = dataBlock.outputValue(self.outTranslateY)
        dh_outTZ = dataBlock.outputValue(self.outTranslateZ)

        dh_outTX.setDouble(pos[0])
        dh_outTY.setDouble(pos[1])
        dh_outTZ.setDouble(pos[2])
Example #7
0
def getNodeFromName(in_name):
    selector = MSelectionList()
    MGlobal.getSelectionListByName(in_name, selector)
    node = MObject()
    selector.getDependNode(0, node)
    return node
Example #8
0
def iterSelectionList( sellist, filterType = api.MFn.kInvalid, predicate = lambda x: True,
                        asNode = True, handlePlugs = True, handleComponents = False ):
    """Iterate the given selection list
    
    :param sellist: MSelectionList to iterate
    :param filterType: MFnType id acting as simple type filter to ignore all objects which do not
        have the given object type
    :param asNode: if True, returned MObjects or DagPaths will be wrapped as Node, compoents will be
        wrapped as Component. 
        Otherwise they will be returned as MObjects and MDagPaths respectively.
    :param handlePlugs: if True, plugs can be part of the selection list and will be returned. This
        implicitly means that the selection list will be iterated without an iterator, and MFnType filters
        will be slower as it is implemented in python. If components are enabled, the tuple returned will be
        ( Plug, MObject() )
    :param predicate: method returninng True if passed in iteration element can be yielded
        default: lambda x: True
    :param handleComponents: if True, possibly selected components of dagNodes will be returned
        as well. This forces the return value into tuple(Node, Component)
    :return: Node or Plug on each iteration step
        If handleComponents is True, for each Object, a tuple will be returned as tuple( Node, Component ) where
        component is NullObject ( MObject ) if the whole object is on the list.
        If the original object was a plug, it will be in the tuples first slot, whereas the component 
        will be a NullObject"""
    kNullObj = MObject()
    if handlePlugs:
        # version compatibility - maya 8.5 still defines a plug ptr class that maya 2005 lacks
        plug_types = api.MPlug
        if cmds.about( v=1 ).startswith( "8.5" ):
            plug_types = ( api.MPlug, api.MPlugPtr )

        # SELECTION LIST MODE
        kInvalid = api.MFn.kInvalid
        getDagPath = sellist.getDagPath
        getPlug = sellist.getPlug
        getDependNode = sellist.getDependNode
        for i in xrange( sellist.length() ):
            # DAG PATH
            rval = None
            component = kNullObj
            try:
                rval = MDagPath( )
                if handleComponents:
                    component = MObject()
                    getDagPath( i, rval, component )
                    if asNode and not component.isNull():
                        component = Component( component )
                    # END handle asNode
                else:
                    getDagPath( i, rval )
                # END handle components in DagPaths
            except RuntimeError:
                # TRY PLUG - first as the object could be returned as well if called
                # for DependNode
                try:
                    rval = nullplugarray[0]
                    getPlug( i, rval )
                    # try to access the attribute - if it is not really a plug, it will
                    # fail and throw - for some reason maya can put just the depend node into
                    # a plug
                    rval.attribute()
                except RuntimeError:
                # TRY DG NODE
                    rval = MObject( )
                    getDependNode( i, rval )
                # END its not an MObject
            # END handle dagnodes/plugs/dg nodes

            # should have rval now
            if isinstance( rval, plug_types ):
                # apply filter
                if filterType != kInvalid and rval.node().apiType() != filterType:
                    continue
                    # END apply filter type
            else:
                if filterType != kInvalid:
                    # must be MDagPath or MObject
                    if rval.apiType() != filterType:
                        continue
                # END filter handling
                
                if asNode:
                    rval = NodeFromObj( rval )
            # END plug handling
            
            if handleComponents:
                rval = ( rval, component )
            
            if predicate( rval ):
                yield rval
        # END for each element
    else:
        # ITERATOR MODE
        # the code above can handle it all, this one might be faster though 
        iterator = selectionListIterator( sellist, filterType = filterType )
        kDagSelectionItem = api.MItSelectionList.kDagSelectionItem
        kDNselectionItem = api.MItSelectionList.kDNselectionItem
        rval = None
        
        isDone = iterator.isDone
        itemType = iterator.itemType
        getDagPath = iterator.getDagPath
        getDependNode = iterator.getDependNode
        next = iterator.next
        while not isDone():
            # try dag object
            component = kNullObj
            itemtype = itemType( )
            if itemtype == kDagSelectionItem:
                rval = MDagPath( )
                if handleComponents:
                    component = MObject( )
                    getDagPath( rval, component )
                    if asNode and not component.isNull():
                        component = Component( component )
                    # END handle component conversion
                else:
                    getDagPath( rval )
                # END handle components
            else:
                rval = MObject()
                getDependNode( rval )
            # END handle item type
            
            if asNode:
                rval = NodeFromObj( rval )
            # END handle as node
            
            if handleComponents:
                rval = ( rval, component )
            # END handle component
                
            if predicate( rval ):
                yield rval
            
            next()
Example #9
0
File: it.py Project: kthulhu/mrv
def iterSelectionList( sellist, filterType = api.MFn.kInvalid, predicate = lambda x: True,
					  	asNode = True, handlePlugs = True, handleComponents = False ):
	"""Iterate the given selection list
	
	:param sellist: MSelectionList to iterate
	:param filterType: MFnType id acting as simple type filter to ignore all objects which do not
		have the given object type
	:param asNode: if True, returned MObjects or DagPaths will be wrapped as Node, compoents will be
		wrapped as Component. 
		Otherwise they will be returned as MObjects and MDagPaths respectively.
	:param handlePlugs: if True, plugs can be part of the selection list and will be returned. This
		implicitly means that the selection list will be iterated without an iterator, and MFnType filters
		will be slower as it is implemented in python. If components are enabled, the tuple returned will be
		( Plug, MObject() )
	:param predicate: method returninng True if passed in iteration element can be yielded
		default: lambda x: True
	:param handleComponents: if True, possibly selected components of dagNodes will be returned
		as well. This forces the return value into tuple(Node, Component)
	:return: Node or Plug on each iteration step
		If handleComponents is True, for each Object, a tuple will be returned as tuple( Node, Component ) where
		component is NullObject ( MObject ) if the whole object is on the list.
		If the original object was a plug, it will be in the tuples first slot, whereas the component 
		will be a NullObject"""
	kNullObj = MObject()
	if handlePlugs:
		# version compatibility - maya 8.5 still defines a plug ptr class that maya 2005 lacks
		plug_types = api.MPlug
		if cmds.about( v=1 ).startswith( "8.5" ):
			plug_types = ( api.MPlug, api.MPlugPtr )

		# SELECTION LIST MODE
		kInvalid = api.MFn.kInvalid
		getDagPath = sellist.getDagPath
		getPlug = sellist.getPlug
		getDependNode = sellist.getDependNode
		for i in xrange( sellist.length() ):
			# DAG PATH
			rval = None
			component = kNullObj
			try:
				rval = MDagPath( )
				if handleComponents:
					component = MObject()
					getDagPath( i, rval, component )
					if asNode and not component.isNull():
						component = Component( component )
					# END handle asNode
				else:
					getDagPath( i, rval )
				# END handle components in DagPaths
			except RuntimeError:
				# TRY PLUG - first as the object could be returned as well if called
				# for DependNode
				try:
					rval = nullplugarray[0]
					getPlug( i, rval )
					# try to access the attribute - if it is not really a plug, it will
					# fail and throw - for some reason maya can put just the depend node into
					# a plug
					rval.attribute()
				except RuntimeError:
				# TRY DG NODE
					rval = MObject( )
					getDependNode( i, rval )
				# END its not an MObject
			# END handle dagnodes/plugs/dg nodes

			# should have rval now
			if isinstance( rval, plug_types ):
				# apply filter
				if filterType != kInvalid and rval.node().apiType() != filterType:
					continue
					# END apply filter type
			else:
				if filterType != kInvalid:
					# must be MDagPath or MObject
					if rval.apiType() != filterType:
						continue
				# END filter handling
				
				if asNode:
					rval = NodeFromObj( rval )
			# END plug handling
			
			if handleComponents:
				rval = ( rval, component )
			
			if predicate( rval ):
				yield rval
		# END for each element
	else:
		# ITERATOR MODE
		# the code above can handle it all, this one might be faster though 
		iterator = selectionListIterator( sellist, filterType = filterType )
		kDagSelectionItem = api.MItSelectionList.kDagSelectionItem
		kDNselectionItem = api.MItSelectionList.kDNselectionItem
		rval = None
		
		isDone = iterator.isDone
		itemType = iterator.itemType
		getDagPath = iterator.getDagPath
		getDependNode = iterator.getDependNode
		next = iterator.next
		while not isDone():
			# try dag object
			component = kNullObj
			itemtype = itemType( )
			if itemtype == kDagSelectionItem:
				rval = MDagPath( )
				if handleComponents:
					component = MObject( )
					getDagPath( rval, component )
					if asNode and not component.isNull():
						component = Component( component )
					# END handle component conversion
				else:
					getDagPath( rval )
				# END handle components
			else:
				rval = MObject()
				getDependNode( rval )
			# END handle item type
			
			if asNode:
				rval = NodeFromObj( rval )
			# END handle as node
			
			if handleComponents:
				rval = ( rval, component )
			# END handle component
				
			if predicate( rval ):
				yield rval
			
			next()