def connectWithDecompMtx(srcMobj, trgMobj): """ Connect and two DAG nodes using matrixDecompose :param srcMobj: MObject :param trgMobj: MObject :return: None """ assert srcMobj, "Please select a source" assert trgMobj, "Please select a target" dgMod = om2.MDGModifier() srcMFn = om2.MFnDependencyNode(srcMobj) trgMFn = om2.MFnDependencyNode(trgMobj) decompMobj = cUtils.createDGNode(tConst.DECOMPOSEMATRIX, nodeName="") srcPlug = srcMFn.findPlug("worldMatrix", False) srcWorldMtxPlug = srcPlug.elementByLogicalIndex(0) decompMfn = om2.MFnDependencyNode(decompMobj) decompMfnPlug = decompMfn.findPlug("inputMatrix", False) for srcAttr, trgAttr in [("outputRotate", "rotate"), ("outputTranslate", "translate"), ("outputScale", "scale")]: srcPlug = decompMfn.findPlug(srcAttr, False) trgPlug = trgMFn.findPlug(trgAttr, False) dgMod.connect(srcPlug, trgPlug) dgMod.connect(srcWorldMtxPlug, decompMfnPlug) dgMod.doIt()
def saveShadingEngine(shadingEngineObj, storagePlug): '''Save a connection to the shading engine node in the storage plug. This function unconditionally connects the shading engine to the storage plug. It also stores the name of the shading engine as a full name with the namespace path in the storage plug's node, if the shading engine is not in the main scene.''' # Store the shading engine message attribute fnEngine = OpenMaya.MFnDependencyNode(shadingEngineObj) enginePlug = fnEngine.findPlug('message', False) utils.connect(enginePlug, storagePlug) # Deal with fact that material might be in a referenced file. storageNode = storagePlug.node() storageStrPlug = plug.findPlug(storageNode, MaterialOverride.kShadingEngineNameLong) if fnEngine.isFromReferencedFile: if storageStrPlug is None: properties = {'type': 'String', 'connectable': False} storageStrPlug = plug.Plug.createAttribute( storageNode, MaterialOverride.kShadingEngineNameLong, MaterialOverride.kShadingEngineNameShort, properties, plug.kNotUndoable) storageStrPlug.value = fnEngine.name() elif storageStrPlug is not None: # Remove dynamic attribute. fn = OpenMaya.MFnDependencyNode(storageNode) fn.removeAttribute(storageStrPlug.plug.attribute())
def connectAttrToAttr(self, sourcePlug, destinationPlug, force): """ Handle connection requests from source attribute to destination attribute. """ if destinationPlug.isDestination and not force: # The destination is already connected and we're not allowed to break it # There is nothing we can do so early out here return sourceNode = sourcePlug.node() fnSourceNode = OpenMaya.MFnDependencyNode(sourceNode) fnDestinationNode = OpenMaya.MFnDependencyNode(destinationPlug.node()) # If an explicit source attribute is given we think the user # wants to connect to that specific node.attribute. # If the node types doesn't match don't try to guess the right connection, # instead give an error message. # One exception is for material override where we can try to find the # shading engine for the source node. # Handle connection overrides node if fnDestinationNode.typeId == ConnectionOverride.kTypeId: # The value attribute is the only user connectable attribute if destinationPlug.partialName( useLongNames=True) == ConnectionOverride.kAttrValueLong: DragAndDropBehavior.connect(sourcePlug, destinationPlug) # Handle shader overrides node elif fnDestinationNode.typeId == ShaderOverride.kTypeId: # The override attribute is the only user connectable attribute if destinationPlug.partialName( useLongNames=True) == ConnectionOverride.kAttrValueLong: # Source must be a surface shader if DragAndDropBehavior.isMatchingClass(sourceNode, "shader/surface"): DragAndDropBehavior.connect(sourcePlug, destinationPlug) else: DragAndDropBehavior.raiseWarning( DragAndDropBehavior.kErrorMsg_NoSurfaceShader + " (%s)" % fnSourceNode.name()) # Handle material overrides node elif fnDestinationNode.typeId == MaterialOverride.kTypeId: # The value attribute is the only user connectable attribute if destinationPlug.partialName( useLongNames=True) == ConnectionOverride.kAttrValueLong: # For material override we ignore which plug was given on the source node, # we just want the shading group for the source node. # Find the shading group for this node (searching downstream if needed) sgNode = DragAndDropBehavior.findNode( sourceNode, typeId=OpenMaya.MFn.kShadingEngine, acceptor=lambda obj: OpenMaya.MFnDependencyNode(obj).name( ) not in self.kNodeSearchIgnoreList) if sgNode: sourcePlug = plug.Plug(sgNode, 'message').plug DragAndDropBehavior.connect(sourcePlug, destinationPlug) else: DragAndDropBehavior.raiseWarning( DragAndDropBehavior.kErrorMsg_NoShadingGroupFound + " (%s)" % fnSourceNode.name())
def attachNodeToCurveAtParam(curve, node, param, name): """Attaches the given node to the curve using a motion path node. :param curve: nurbsCurve Shape to attach to :type curve: om2.MObject :param node: the node to attach to the curve :type node: om2.MObject :param param: the parameter float value along the curve :type param: float :param name: the motion path node name to use :type name: str :return: motion path node :rtype: om2.MObject """ nodeFn = om2.MFnDependencyNode(node) crvFn = om2.MFnDependencyNode(curve) mp = nodes.createDGNode(name, "motionPath") mpFn = om2.MFnDependencyNode(mp) plugs.connectVectorPlugs(mpFn.findPlug("rotate", False), nodeFn.findPlug("rotate", False), (True, True, True)) plugs.connectVectorPlugs(mpFn.findPlug("allCoordinates", False), nodeFn.findPlug("translate", False), (True, True, True)) crvWorld = crvFn.findPlug("worldSpace", False) plugs.connectPlugs(crvWorld.elementByLogicalIndex(0), mpFn.findPlug("geometryPath", False)) mpFn.findPlug("uValue", False).setFloat(param) mpFn.findPlug("frontAxis", False).setInt(0) mpFn.findPlug("upAxis", False).setInt(1) return mp
def getContainerHyperLayout(container, create=True): """ Gets the hyperlayout that is connected to the container. If the container has not got one, and create is set to True, a hyperlayout will be created and joined to the container. @param MObject container: The container object that you want to return its hyperlayout. @return: The hyperlayout connected to the container @rtype: MObject """ _dgContainer = om2.MFnDependencyNode(container) _hyperLPlug = _dgContainer.findPlug('hyperLayout', True) _hyperLayoutMo = None # check if container has a hyperlayout, is not creates one if not _hyperLPlug.isConnected and not _hyperLPlug.isDestination: if create: _dgMod = om2.MDGModifier() _hyperLayoutMo = _dgMod.createNode('hyperLayout') _dgMod.doIt() _hyperLayoutMfn = om2.MFnDependencyNode(_hyperLayoutMo) _hyperLayoutMfn.setName(_dgContainer.name() + "_hyperLayout") _dgMod.connect(_hyperLayoutMfn.findPlug("message", True), _hyperLPlug) _dgMod.doIt() else: _hyperLayoutMo = _hyperLPlug.source().node() return _hyperLayoutMo
def connectNodes(srcMobjHandle, trgMobjHandle): """ connect nodes :param srcMobjHandle: MObjectHandle :param trgMobjHandle: MObjectHandle :return: None """ assert srcMobjHandle.isValid() == True, "src MObject not valid" assert trgMobjHandle.isValid() == True, "trg MObject not valid" srcMobj = srcMobjHandle.object() trgMobj = trgMobjHandle.object() srcMFn = om2.MFnDependencyNode(srcMobj) trgMFn = om2.MFnDependencyNode(trgMobj) srcInputPlugs, srcOutputPlugs, trgInputPlugs, trgOutputPlugs = getInputOutput( srcMobj, trgMobj) srcPlug = srcMFn.findPlug(srcOutputPlugs, False) trgPlug = trgMFn.findPlug(trgInputPlugs, False) if srcPlug.isArray and not trgMFn.hasAttribute("matrixIn"): srcWorldMtxPlug = srcPlug.elementByLogicalIndex(0) dgMod.connect(srcWorldMtxPlug, trgPlug) print("connecting: {} to {}".format(srcWorldMtxPlug, trgPlug)) elif trgMFn.hasAttribute("matrixIn"): srcWorldMtxPlug = srcPlug.elementByLogicalIndex(0) trgMtxPlug = trgPlug.elementByLogicalIndex(0) dgMod.connect(srcWorldMtxPlug, trgMtxPlug) print("connecting: {} to {}".format(srcWorldMtxPlug, trgMtxPlug)) else: dgMod.connect(srcPlug, trgPlug)
def getLocalRotationHoldMatrix(wsTransform, wsInvTransform, name): """Creates a holdMatrix node, and sets the local rotateMatrix returns holdMatrix node """ holdmat = cmds.createNode('holdMatrix', n='_%s_HMAT'%name) MList = om.MSelectionList() MList.add(wsTransform) mplug = om.MFnDependencyNode(MList.getDependNode(0)).findPlug('worldMatrix', 0) mat = om.MFnMatrixData(mplug.elementByLogicalIndex( 0 ).asMObject()).matrix() if wsInvTransform: MList.add(wsInvTransform) mplug = om.MFnDependencyNode(MList.getDependNode(1)).findPlug('worldInverseMatrix', 0) invmat = om.MFnMatrixData(mplug.elementByLogicalIndex( 0 ).asMObject()).matrix() mtmat = om.MTransformationMatrix(mat * invmat) cmds.setAttr(holdmat + '.inMatrix', mtmat.asRotateMatrix(), type='matrix') else: mtmat = om.MTransformationMatrix(mat) cmds.setAttr(holdmat + '.inMatrix', mtmat.asRotateMatrix(), type='matrix') return holdmat
def set_weights(skin, data, prune=False): """Set an skin cluster with weight data. Args: skin: Skin cluster node or mobject data: Weight data specifically in the format `get_weights` returns prune: Remove unused influences from the skin cluster Returns: None """ influences = get_skin_influences(skin) influences_remapped = {v: k for k, v in influences.items()} mfn_skin = oma2.MFnSkinCluster(skin) for vert, weights in data: weight_list_index_attr = '{skincluster}.weightList[{vertId}]'.format( skincluster=mfn_skin.name(), vertId=vert) for influence, weight_value in weights: influence_logical_index = influences_remapped[influence] weights_attr = '.weights[{influenceId}]'.format( influenceId=influence_logical_index) cmds.setAttr(weight_list_index_attr + weights_attr, weight_value) if prune: skin_name = om2.MFnDependencyNode(skin).name() skin_geo = om2.MFnDependencyNode( oma2.MFnGeometryFilter(skin).getOutputGeometry()[0]).name() cmds.skinPercent(skin_name, skin_geo, nrm=False, prw=0)
def _getNewConnections(surfaceShader, shadingEngine): """ Get a list for connections that should be made when connecting a surface shader to a shading engine. This can be customizable by plug-ins using the callback hook 'provideNodeToNodeConnection'. """ connections = [] fnSurfaceShader = OpenMaya.MFnDependencyNode(surfaceShader) fnShadingEngine = OpenMaya.MFnDependencyNode(shadingEngine) # Check if a plug-in has provided custom attributes to use for the connection # Using EAFP style code and catch any exception raised if no custom attributes # are given, or they are given in incorrect format. try: result = cmds.callbacks(fnSurfaceShader.typeName, fnShadingEngine.typeName, executeCallbacks=True, hook='provideNodeToNodeConnection') attributes = result[0].split(':') # Make a connection for each pair of "src:dst" attributes count = len(attributes) for i in xrange(0, count, 2): shaderPlug = fnSurfaceShader.findPlug(attributes[i], False) enginePlug = fnShadingEngine.findPlug(attributes[i + 1], False) connections.append((shaderPlug, enginePlug)) except: # Fall back to default behavior making a default connection # between surface shader and shading engine shaderPlug = fnSurfaceShader.findPlug('outColor', False) enginePlug = fnShadingEngine.findPlug('surfaceShader', False) if shaderPlug and enginePlug: connections.append((shaderPlug, enginePlug)) return connections
def containerFromNode(mayaNode): """ Inspects a node connection set for standard containered topology and returns the owning container if one is found, None otherwise :param mayaNode: `MObject` any dependency node in Maya :return: `MObject | None` the container object the argument is linked to if there is one otherwise None """ fnDep = om2.MFnDependencyNode(mayaNode) plug = fnDep.findPlug("message", False) for eachDestPlug in plug.destinations(): destNode = eachDestPlug.node() if not destNode.hasFn(om2.MFn.kHyperLayout): continue # at this point we're dealing with an interesting node # and we should find if it's connected to a container fnDestNode = om2.MFnDependencyNode(destNode) layoutMsg = fnDestNode.findPlug("message", False) layoutDestinations = layoutMsg.destinations() for eachLayoutDestination in layoutDestinations: if eachLayoutDestination.node().hasFn(om2.MFn.kContainer): return eachLayoutDestination.node()
def addToContainer(mobj, containerObj): """ Add an object to a container. @param mobj: Object you wish to add to the container @param om2.MObject containerObj: container that have the object added to it """ _hyperLayoutDG = getContainerHyperLayout(containerObj) _hyperLayoutMfn = om2.MFnDependencyNode(_hyperLayoutDG) _hyperLayoutMessagePlug = _hyperLayoutMfn.findPlug('hyperPosition', True) _nextPlugIndex = _hyperLayoutMessagePlug.numElements() _dagMod = om2.MDGModifier() _mfnNode = om2.MFnDependencyNode() _hyperposPlug = _hyperLayoutMessagePlug.elementByLogicalIndex(_nextPlugIndex) _availableDependNodePlug = node.getNextAvailablePlugInPlug(_hyperposPlug, 'dependNode') print("NEXT AVAILABLE dependNode : {0}".format(_availableDependNodePlug)) _mfnNode.setObject(mobj) _msgPlug = _mfnNode.findPlug('message', True) _badConnection = node.isSourceConnectedTo(_msgPlug, nodeType='hyperLayout') # TODO: check if you are trying to add the object to the container it is already added to if _availableDependNodePlug and not _badConnection: _dagMod.connect(_msgPlug, _availableDependNodePlug) _dagMod.doIt() _nextPlugIndex += 1 else: print("ERROR: Object not added to container!")
def doAction(self, target, source): """ This method performs the override action for a given target and source. """ # NOTE: doAction should never add commands in the undo stack shaderPlug = utils.plugSrc(source) if shaderPlug: surfaceShader = shaderPlug.node() shadingEngine = target.node() # Break any connections to old surface shader fnShadingEngine = OpenMaya.MFnDependencyNode(shadingEngine) connections = fnShadingEngine.getConnections() for c in connections: if c.isDestination: fn = OpenMaya.MFnDependencyNode(c.source().node()) nodeClass = OpenMaya.MNodeClass(fn.typeName) if 'shader/surface' in nodeClass.classification: utils.disconnect(c.source(), c) # Make connections to new surface shader connections = ShaderOverride._getNewConnections( surfaceShader, shadingEngine) # Turn reference edits on if restoring the original. with handleRestoringOriginalCtx(): for c in connections: utils.connect(c[0], c[1])
def get_groupNode(self): MselectionList = OpenMaya.MGlobal.getActiveSelectionList() MObj = MselectionList.getDependNode(0) MObjDNFn = OpenMaya.MFnDependencyNode(MObj) if MObjDNFn.typeName == 'mnt_groupNode': return MObj elif MObjDNFn.typeName == 'transform': MDagPath = OpenMaya.MDagPath.getAPathTo(MObj) for i in range(MDagPath.childCount()): child = MDagPath.child(i) childDNFn = OpenMaya.MFnDependencyNode(child) if childDNFn.typeName == 'mnt_poseScope': inputFaceComponentsPlug = childDNFn.findPlug( 'inputFaceComponents', False) connections = inputFaceComponentsPlug.connectedTo( True, False) for i in range(0, len(connections)): node = connections[i].node() nodeDNFn = OpenMaya.MFnDependencyNode(node) if nodeDNFn.typeName == 'mnt_groupNode': return node break
def getWorldMatrix(self): try: inputMeshParent = OpenMaya.MFnDagNode(self.shape).parent(0) except: return fnInputMeshParent = OpenMaya.MFnDependencyNode(inputMeshParent) inputMeshWorldMatrixAttr = fnInputMeshParent.attribute('worldMatrix') inputMeshWorldMatrixPlug = OpenMaya.MPlug(inputMeshParent, inputMeshWorldMatrixAttr) inputMeshWorldMatrixPlug = inputMeshWorldMatrixPlug.elementByLogicalIndex( 0) inputMeshWorldMatrixObj = inputMeshWorldMatrixPlug.asMObject() inputMeshWorldMatrixData = OpenMaya.MFnMatrixData( inputMeshWorldMatrixObj) inputMeshWorldMatrix = inputMeshWorldMatrixData.matrix() MObjFn = OpenMaya.MFnDagNode(self.MObj) MObjParent = MObjFn.parent(0) fnMObjParent = OpenMaya.MFnDependencyNode(MObjParent) worldMatrixAttr = fnMObjParent.attribute('worldMatrix') matrixPlug = OpenMaya.MPlug(MObjParent, worldMatrixAttr) matrixPlug = matrixPlug.elementByLogicalIndex(0) worldMatrixObject = matrixPlug.asMObject() worldMatrixData = OpenMaya.MFnMatrixData(worldMatrixObject) worldMatrix = worldMatrixData.matrix().inverse() outputMatrix = inputMeshWorldMatrix.__mul__(worldMatrix) return outputMatrix
def distanceBetween(firstNode, secondNode, name): """Creates a distance between node and connects the 'firstNode' and 'secondNode' world space matrices. :param firstNode: The start transform node :type firstNode: MObject :param secondNode: The second transform node :type secondNode: MObject :return: the Three nodes created by the function in the form of a tuple, the first element \ is the distance between node, the second is the start node decompose matrix, the third element \ is the second node decompose matrix. :rtype: tuple(om2.MObject, om2.MObject, om2.MObject) """ firstFn = om2.MFnDependencyNode(firstNode) secondFn = om2.MFnDependencyNode(secondNode) distanceBetweenNode = nodes.createDGNode(name, "distanceBetween") distFn = om2.MFnDependencyNode(distanceBetweenNode) firstFnWorldMat = firstFn.findPlug("worldMatrix", False) firstFnWorldMat.evaluateNumElements() secondFnWorldMat = secondFn.findPlug("worldMatrix", False) secondFnWorldMat.evaluateNumElements() plugs.connectPlugs(firstFnWorldMat.elementByPhysicalIndex(0), distFn.findPlug("inMatrix1", False)) plugs.connectPlugs(secondFnWorldMat.elementByPhysicalIndex(0), distFn.findPlug("inMatrix2", False)) return distanceBetweenNode
def createControllerTag(node, name, parent=None, visibilityPlug=None): """Create a maya kControllerTag and connects it up to the 'node'. :param node: The Dag node MObject to tag :type node: om2.MObject :param name: The name for the kControllerTag :type name: str :param parent: The Parent kControllerTag mObject or None :type parent: om2.MObject or None :param visibilityPlug: The Upstream Plug to connect to the visibility mode Plug :type visibilityPlug: om2.MPlug or None :return: The newly created kController node as a MObject :rtype: om.MObject """ ctrl = nodes.createDGNode(name, "controller") fn = om2.MFnDependencyNode(ctrl) plugs.connectPlugs( om2.MFnDependencyNode(node).findPlug("message", False), fn.findPlug("controllerObject", False)) if visibilityPlug is not None: plugs.connectPlugs(visibilityPlug, fn.findPlug("visibilityMode", False)) if parent is not None: parentFn = om2.MFnDependencyNode(parent) plugs.connectPlugs( fn.findPlug("parent", False), plugs.nextAvailableDestElementPlug( parentFn.findPlug("children", False))) plugs.connectPlugs(parentFn.findPlug("prepopulate", False), fn.findPlug("prepopulate", False)) return ctrl
def _findShader(shadingEngine, attribute, classification=None): ''' Returns the shader connected to given attribute on given shading engine. Optionally search for nodes from input connections to the shading engines satisfying classification if plug to attribute is not a destination and a classification string is specified. ''' # If expected input attribute to a shading node DOES have a node as source, take it. We're done. # Otherwise, we're in a non-standard connection from shader to shading engine. # => search for alternate input connection by node classification. # Idea is: avoid heavy computation (searching) if we can. => Try expected scenario, and search on fail. node = OpenMaya.MFnDependencyNode(shadingEngine) # Try "standard scenario" first to avoid searching plg = node.findPlug(attribute, False) if plg.isDestination: return plg.source().node() elif classification: # We're not in the standard scenario (shader might be connected through plugin's added attributes) # (some mentalray's shaders work this way for example) # Then search for input connections satifying classification sources = (plg.source().node() for plg in node.getConnections() if plg.isDestination) for source in sources: for c in OpenMaya.MFnDependencyNode.classification(OpenMaya.MFnDependencyNode(source).typeName).split(':'): if c.startswith(classification): return source return None
def serializeConnection(plug): """Take's destination om2.MPlug and serializes the connection as a dict. :param plug: A om2.MPlug that is the destination of a connection :type plug: om2.MPlug :return: {sourcePlug: str, destinationPlug: str, source: str, # source node destination: str} # destination node :rtype: dict """ source = plug.source() sourceNPath = "" if source: sourceN = source.node() sourceNPath = om2.MFnDagNode(sourceN).fullPathName() if sourceN.hasFn( om2.MFn.kDagNode) else om2.MFnDependencyNode(sourceN).name() destN = plug.node() return { "sourcePlug": source.partialName(includeNonMandatoryIndices=True, useLongNames=True, includeInstancedIndices=True), "destinationPlug": plug.partialName(includeNonMandatoryIndices=True, useLongNames=True, includeInstancedIndices=True), "source": sourceNPath, "destination": om2.MFnDagNode(destN).fullPathName() if destN.hasFn(om2.MFn.kDagNode) else om2.MFnDependencyNode(destN).name() }
def createLocAtVertex(selList, componentIDs, mDagMod): """ Create an locator on vertex aligned with the vertex normal :param selList: MSelectionList :param componentID: int :param mDagMod: MDagModifier :return: None """ for componentID in componentIDs: # Get vertex normal/position meshDagPath = selList.getDagPath(0) mFnMesh = om2.MFnMesh(meshDagPath) vtxNormal = mFnMesh.getVertexNormal(componentID, False, om2.MSpace.kObject) vtxPoint = mFnMesh.getPoint(componentID, om2.MSpace.kObject) mObj = selList.getDependNode(0) mFn = om2.MFnDependencyNode(mObj) getMtxPlug = mFn.findPlug("worldMatrix", False) mtxPlug = getMtxPlug.elementByLogicalIndex(0) plugMObj = mtxPlug.asMObject() mFnMtxData = om2.MFnMatrixData(plugMObj) offsetMtx = mFnMtxData.matrix() # Construct a matrix mtxConstruct = (vtxNormal.x, vtxNormal.y, vtxNormal.z, 0, 0, 1, 0, 0, 0, 0, 1, 0, vtxPoint.x, vtxPoint.y, vtxPoint.z, vtxPoint.w) vtxMMatrix = om2.MMatrix( mtxConstruct) * offsetMtx # Convert to Maya MMatrix vtxMtransMtx = om2.MTransformationMatrix(vtxMMatrix) # Get rotation/translation rot = vtxMtransMtx.rotation() trans = vtxMtransMtx.translation(om2.MSpace.kWorld) loc = createLocator(componentID, "vtx", mDagMod) if loc.isValid(): locMObj = loc.object() mFn = om2.MFnDependencyNode(locMObj) transX = mFn.findPlug("translateX", False) transY = mFn.findPlug("translateY", False) transZ = mFn.findPlug("translateZ", False) transX.setFloat(trans.x) transY.setFloat(trans.y) transZ.setFloat(trans.z) rotX = mFn.findPlug("rotateX", False) rotY = mFn.findPlug("rotateY", False) rotZ = mFn.findPlug("rotateZ", False) rotX.setFloat(rot.x) rotY.setFloat(rot.y) rotZ.setFloat(rot.z)
def addConstraintMap(node, driven, utilities, kwargsMap=None): """Adds a mapping of drivers and utilities to the constraint compound array attribute :param node: The node to add or has the constraint map , typically this would be the driver node \ of the constraint. :type node: om2.MObject :param driven: a list of driven transform nodes. :type driven: tuple(om2.MObject) :param utilities: a list of utilities/support nodes that make up the constraint, this could be the \ constraint node itself or any math node etc. :type utilities: tuple(om2.MObject) """ kwargsmap = kwargsMap or "" mfn = om2.MFnDependencyNode(node) if not mfn.hasAttribute("constraints"): compoundPlug = addConstraintAttribute(node) else: compoundPlug = mfn.findPlug("constraints", False) availPlug = plugs.nextAvailableElementPlug(compoundPlug) drivenPlug = availPlug.child(0) # lets add the driven nodes to the xth of the element compound for drive in iter(driven): if drive is None: continue drivenFn = om2.MFnDependencyNode(drive) if drivenFn.hasAttribute("constraint"): p = drivenFn.findPlug("constraint", False) elementP = plugs.nextAvailableElementPlug(p) plugs.connectPlugs(drivenPlug, elementP) continue attr = nodes.addAttribute(drive, "constraint", "constraint", attrtypes.kMFnMessageAttribute, isArray=True) attrP = om2.MPlug(drive, attr.object()) plugs.connectPlugs(drivenPlug, attrP.elementByLogicalIndex(0)) utilPlug = availPlug.child(1) # add all the utilities for i in iter(utilities): if i is None: continue utilFn = om2.MFnDependencyNode(i) if utilFn.hasAttribute("constraint"): p = utilFn.findPlug("constraint", False) if p.isDestination: continue plugs.connectPlugs(utilPlug, p) continue attr = nodes.addAttribute(i, "constraint", "constraint", attrtypes.kMFnMessageAttribute) plugs.connectPlugs(utilPlug, om2.MPlug(i, attr.object())) # set the kwargs map plug, so we know how the constraint was created plugs.setPlugValue(availPlug.child(2), kwargsmap) return compoundPlug
def Write(self, usdTime): depNodeFn = OpenMaya.MFnDependencyNode(self.GetMayaObject()) plg = depNodeFn.findPlug('inMesh', True) dn = OpenMaya.MFnDependencyNode(plg.source().node()) plg = dn.findPlug('radius', False) radius = plg.asFloat() usdPrim = self.GetUsdPrim() radiusAttr = usdPrim.GetAttribute('radius') radiusAttr.Set(radius) primWriterTest.WriteCalled = True
def undoIt(self): if len(self.transformNodesList) == 0 and len( self.inputComponentsList) == 0: return for i in range(len(self.transformNodesList)): MSelectionList = OpenMaya.MSelectionList() MSelectionList.add(self.transformNodesList[i]) MSelectionList.add(self.inputMeshList[i]) MTransformNodeObj = MSelectionList.getDependNode(0) MInputMeshObj = MSelectionList.getDependNode(1) inputComponentsListStr = self.inputComponentsList[i] inputMeshDGFn = OpenMaya.MFnDependencyNode(MInputMeshObj) # Creates poseScope Node poseScopeDagNodeFn = OpenMaya.MFnDagNode() poseScopeDagNodeObj = poseScopeDagNodeFn.create('mnt_poseScope') poseScopeNodePath = OpenMaya.MFnDagNode( poseScopeDagNodeObj).getPath().extendToShape() poseScopeNode = OpenMaya.MFnDependencyNode( poseScopeNodePath.node()) poseScopeNode.findPlug('colorR', False).setDouble(1.0) poseScopeNode.findPlug('colorG', False).setDouble(0.75) poseScopeNode.findPlug('colorB', False).setDouble(0.0) poseScopeNode.findPlug('opacity', False).setFloat(0.1) # ______________________ # Parents poseScope shape to transformNode transformDagNode = OpenMaya.MFnDagNode(MTransformNodeObj) transformDagNode.addChild(poseScopeNodePath.node(), 0, False) OpenMaya.MGlobal.deleteNode(poseScopeDagNodeObj) # ________________________________________ # Recreates group Node DGModifier = OpenMaya.MDGModifier() groupNodeObj = DGModifier.createNode('mnt_groupNode') groupNodeDGNode = OpenMaya.MFnDependencyNode(groupNodeObj) groupNodeDGNode.findPlug('mode', False).setInt(1) groupNodeDGNode.findPlug('componentsList', False).setString( self.inputComponentsList[i]) # ____________________ # Creates node connections DGModifier.connect( groupNodeDGNode.findPlug('outputsComponent', False), poseScopeNode.findPlug('inputFaceComponents', False)) DGModifier.connect(inputMeshDGFn.findPlug('outMesh', False), poseScopeNode.findPlug('inputMesh', False)) DGModifier.doIt() # ________________________ return
def ls(self, patterns): names = set() for pattern in patterns: negate, prog = createProgram(pattern) update = set.difference_update if negate else set.update if '|' in pattern: update(names, itertools.ifilter(lambda n: prog.match(n), (p.fullPathName() for p in self.paths()))) else: dags = (key for key in self._paths.iterkeys() if prog.match(OpenMaya.MFnDependencyNode(key.object()).name())) update(names, (self._paths[key].getDagPath(0).fullPathName() for key in dags)) update(names, itertools.ifilter(lambda n: prog.match(n), (OpenMaya.MFnDependencyNode(o.object()).name() for o in self._nondags))) return names
def onAttributeChanged(self, msg, plg, otherPlug, clientData): if msg & OpenMaya.MNodeMessage.kAttributeSet: # Plug itself might be overridden, or its parent might be # overridden. plugs = [plg] if plg.isChild: plugs.append(plg.parent()) for p in plugs: # Get rid of uninteresting plugs as quickly as possible. # # 1) Overridden plug is connected, by definition. if not p.isConnected: continue # 2) If plug's node is a render setup node, not interesting. nodeFn = OpenMaya.MFnDependencyNode(p.node()) if typeIDs.isRenderSetupType(nodeFn.typeId): continue # Check if the plug is connected to an apply override node. src = utils.plugSrc(p) if src is None: continue node = OpenMaya.MFnDependencyNode(src.node()).userNode() if not isinstance(node, applyOverride.ApplyOverride): continue # Query the autoKeyer only if a plug is interesting. # Autokeyer should not be listening during undo / redo, # only when the attribute is initially set. if 'autoKeyedAttr' not in locals(): inUndoRedo = OpenMaya.MGlobal.isUndoing() or \ OpenMaya.MGlobal.isRedoing() autoKeyedAttr = set() if inUndoRedo else autoKey.autoKeyed( ) autoKeyed = p.name() in autoKeyedAttr # At this point we know the node can handle the override. # No need to call ApplyValueOverride.canHandleSetOverride # to validate, because that method has been called by # isPassiveOutput, which returned true to allow the # attribute to be changed and therefore end up in this # notification. node.handleSetOverride(p, autoKeyed) # all plugs between override and target plug should never be dirty plug.Plug(p).value break
def _isLightCamera(nodeObj): fn = OpenMaya.MFnDagNode(nodeObj) if fn.object().hasFn( OpenMaya.MFn.kCamera) and fn.parentCount() == 1: # Check if the parent transform has another child that is a light source fn = OpenMaya.MFnDagNode(fn.parent(0)) if fn.object().hasFn( OpenMaya.MFn.kTransform) and fn.childCount() == 2: fnChild0 = OpenMaya.MFnDependencyNode(fn.child(0)) fnChild1 = OpenMaya.MFnDependencyNode(fn.child(1)) return cmds.getClassification(fnChild0.typeName, satisfies='light') or \ cmds.getClassification(fnChild1.typeName, satisfies='light') return False
def getQuaternion(jointObj): jointFn=om.MFnDagNode(jointObj) jointName=jointFn.name() quaternion=om.MQuaternion() # The root joint, a.k.a belly joint if "Belly" in jointName: # Get joint position # To avoid issues like freezeTransform, recommend rotate pivot to attain the position p0=cmds.xform(jointName,absolute=True,query=True,worldSpace=True,rotatePivot=True) for i in range(jointFn.childCount()): childJointObj=jointFn.child(i) childFn=om.MFnDagNode(childJointObj) childJointName=childFn.name() if "Chest" in childJointName: p1=cmds.xform(childJointName,absolute=True,query=True,worldSpace=True,rotatePivot=True) newUp=om.MVector(p1[0]-p0[0],p1[1]-p0[1],p1[2]-p0[2]) quaternion=om.MVector.kYaxisVector.rotateTo(newUp) break elif 'Hip' in jointName: p1=cmds.xform(jointName,absolute=True,query=True,worldSpace=True,rotatePivot=True) fatherObj=jointFn.parent(0) fatherFn=om.MFnDependencyNode(fatherObj) fatherJointName=fatherFn.name() p0=cmds.xform(fatherJointName,absolute=True,query=True,worldSpace=True,rotatePivot=True) newUp=om.MVector(p1[0]-p0[0],p1[1]-p0[1],p1[2]-p0[2]) quaternion=om.MVector.kYnegAxisVector.rotateTo(newUp) elif 'Neck' in jointName: p0=cmds.xform(jointName,absolute=True,query=True,worldSpace=True,rotatePivot=True) for i in range(jointFn.childCount()): childObj=jointFn.child(0) childJointName=om.MFnDependencyNode(childObj).name() if 'Head' in childJointName: p1=cmds.xform(childJointName,absolute=True,query=True,worldSpace=True,rotatePivot=True) newUp=om.MVector(p1[0]-p0[0],p1[1]-p0[1],p1[2]-p0[2]) quaternion=om.MVector.kYaxisVector.rotateTo(newUp) break elif jointFn.parentCount==1 and jointFn.childCount==1: p0=cmds.xform(jointName,absolute=True,query=True,worldSpace=True,rotatePivot=True) childObj=jointFn.parent(0) childFn=om.MFnDependencyNode(childObj) childJointName=childFn.name() p1=cmds.xform(childJointName,absolute=True,query=True,worldSpace=True,rotatePivot=True) newUp=om.MVector(p1[0]-p0[0],p1[1]-p0[1],p1[2]-p0[2]) if newUp.y>0: quaternion=om.MVector.kYaxisVector.rotateTo(newUp) else: quaternion=om.MVector.kYnegAxisVector.rotateTo(newUp) return quaternion
def createLocator(name, selType, mDagMod): """ create a locator with vertexID in the name :param componentID: str/int :param selType: str :param mDagMod: MDagModifier :return: MObjectHandle """ locLocalScale = 0.2 mDagPath = om2.MDagPath() loc = mDagMod.createNode("locator") newName = "LOC_{}_{}".format(selType, name) mDagMod.renameNode(loc, newName) locMObjHandle = om2.MObjectHandle(loc) mDagMod.doIt() dagPath = mDagPath.getAPathTo(loc) shapeDagPath = dagPath.extendToShape() shapeMObj = shapeDagPath.node() shapeMFn = om2.MFnDependencyNode(shapeMObj) shapeLocalScaleX = shapeMFn.findPlug("localScaleX", False) shapeLocalScaleY = shapeMFn.findPlug("localScaleY", False) shapeLocalScaleZ = shapeMFn.findPlug("localScaleZ", False) shapeLocalScaleX.setFloat(locLocalScale) shapeLocalScaleY.setFloat(locLocalScale) shapeLocalScaleZ.setFloat(locLocalScale) return locMObjHandle
def insert(self, target, nextOvr=None): '''Insert self in the override chain for given target, or start the chain if none exists.''' destinations = (OpenMaya.MFnDependencyNode(d.node()).userNode() for d in target.destinations()) firstApplyNode = next( (d for d in destinations if d and isinstance(d, ApplyConnectionOverride)), None) if not firstApplyNode: # no apply override chain on that target => self becomes the only apply override node for that target self.connectTarget(target) self.override().doSaveOriginal(target, self.getOriginalPlug()) return utils.transferPlug(firstApplyNode.getOriginalPlug(), self.getOriginalPlug()) # search where to insert if not nextOvr: prevAO, nextAO = firstApplyNode, None else: nextAO = (ao for ao in ApplyConnectionOverride.reverseGenerator( firstApplyNode) if ao.override() == nextOvr).next() prevAO = nextAO.prev() # insert between prevAO and nextAO if prevAO: utils.connect(prevAO.getNextPlug(), self.getPrevPlug()) if nextAO: utils.connect(self.getNextPlug(), nextAO.getPrevPlug()) else: # no nextAO => self becomes highest priority => must hold target prevAO.moveTargetTo(self)
def prepareForDraw(self, objPath, cameraPath, frameContext, oldData): depNode = om.MFnDependencyNode(objPath.node()) obj = depNode.userNode() isSelected = isPathSelected(objPath) self.xray = obj.xray plug = om.MPlug(objPath.node(), zRigHandle.colorAttr) self.color = om.MColor(om.MFnNumericData(plug.asMObject()).getData()) alpha = om.MPlug(objPath.node(), zRigHandle.alphaAttr).asFloat() self.color.a = alpha if isSelected: self.borderColor = omr.MGeometryUtilities.wireframeColor(objPath) else: plug = om.MPlug(objPath.node(), zRigHandle.borderColorAttr) self.borderColor = om.MColor( om.MFnNumericData(plug.asMObject()).getData()) # If no color has been set and we're on the default of (-1,-1,-1), use the main color, # so in the common case where you want to use the same color you don't have to set both. if self.borderColor.r == -1 and self.borderColor.g == -1 and self.borderColor.b == -1: self.borderColor = om.MColor(self.color) self.borderColor.a = om.MPlug( objPath.node(), zRigHandle.borderAlphaAttr).asFloat() self.shape = obj.getShape()
def doSaveOriginal(self, target, storage): """ This method performs saving of original state for a given target and a storage plug for storing the state. """ # Find old surface shader fnShadingEngine = OpenMaya.MFnDependencyNode(target.node()) connections = fnShadingEngine.getConnections() for c in connections: if c.isDestination: fn = OpenMaya.MFnDependencyNode(c.source().node()) nodeClass = OpenMaya.MNodeClass(fn.typeName) if 'shader/surface' in nodeClass.classification: # Source surface shader found. # Use the message plug to save a reference to it. target = fn.findPlug('message', False) utils.connect(target, storage) break