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
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
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
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)
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)
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])
def getNodeFromName(in_name): selector = MSelectionList() MGlobal.getSelectionListByName(in_name, selector) node = MObject() selector.getDependNode(0, node) return node
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()