Exemple #1
0
    def type(self):
        # Lazy evaluate
        if self._type is None:
            plug = self.plug
            attr = plug.attribute()

            if attr.hasFn(OpenMaya.MFn.kMessageAttribute):
                self._type = Plug.kMessage

            elif plug.isArray:
                self._type = Plug.kArray

            elif attr.hasFn(OpenMaya.MFn.kCompoundAttribute):
                self._type = Plug.kColor if OpenMaya.MFnAttribute(attr).usedAsColor else \
                             [ child.type for child in self._children() ]

            elif attr.hasFn(OpenMaya.MFn.kNumericAttribute):
                self._type = Plug._numericToPlugTypes.get(
                    OpenMaya.MFnNumericAttribute(attr).numericType(),
                    Plug.kInvalid)

            elif attr.hasFn(OpenMaya.MFn.kTypedAttribute):
                dataType = OpenMaya.MFnTypedAttribute(attr).attrType()
                if dataType == OpenMaya.MFnData.kString:
                    self._type = Plug.kString
                else:
                    self._type = Plug.kInvalid

            elif attr.hasFn(OpenMaya.MFn.kEnumAttribute):
                self._type = Plug.kEnum

            elif attr.hasFn(OpenMaya.MFn.kUnitAttribute):
                self._type = Plug._unitToPlugTypes.get(
                    OpenMaya.MFnUnitAttribute(attr).unitType(), Plug.kInvalid)

            elif attr.hasFn(OpenMaya.MFn.kGenericAttribute):
                handle = plug.asMDataHandle()
                isGeneric, isGenericNumeric, isGenericNull = handle.isGeneric()
                if isGeneric and isGenericNumeric:
                    # It's a generic simple attribute.
                    # According to docs there is no method to check the type
                    # of a generic simple attribute:
                    # http://help.autodesk.com/view/MAYAUL/2016/ENU/?guid=__cpp_ref_class_m_data_handle_html
                    # So always return as double here
                    self._type = Plug.kDouble
                elif not isGenericNull:
                    obj = handle.data()
                    if obj.hasFn(OpenMaya.MFn.kStringData):
                        self._type = Plug.kString
                    else:
                        # if handle.data() didn't raise an exception,
                        # plug can be read as MObject
                        self._type = Plug.kObject
                else:
                    raise RuntimeError(kUnknownType % self.name)

            else:
                raise RuntimeError(kUnsupportedAttribute % self.name)

        return self._type
Exemple #2
0
def api_listAttr(path, shortNames=False):
    sel = om.MSelectionList()
    try:
        sel.add(path)
    except RuntimeError:
        return []
    if not sel.length():
        return []
    try:
        plug = sel.getPlug(0)
    except TypeError:
        try:
            node = om.MFnDependencyNode(sel.getDependNode(0))
        except RuntimeWarning:
            return []
        attrs = [
            om.MFnAttribute(node.attribute(i))
            for i in xrange(node.attributeCount())
        ]
        if shortNames:
            return [x.shortName for x in attrs]
        else:
            return [x.name for x in attrs]
    else:
        return [
            plug.child(i).partialName(useLongNames=not shortNames)
            for i in xrange(plug.numChildren())
        ]
Exemple #3
0
    def _encodeProperties(self, dict):
        """ Encode the properties of this plug's attribute into a dictionary. """

        fn = OpenMaya.MFnAttribute(self._plug.attribute())

        dict['type'] = Plug._typeToString(self.type)
        dict['connectable'] = fn.connectable
        if fn.keyable:
            dict['keyable'] = True
        val = self.value
        if val is not None:
            dict['value'] = val

        if self.hasLimits:
            limits = self.getAttributeLimits()
            # There is no need to save None values
            for (key, value) in limits.items():
                if value is not None:
                    dict[key] = value

        if self.type == Plug.kEnum:
            fn2 = OpenMaya.MFnEnumAttribute(self._plug.attribute())
            enum = {}
            for val in range(fn2.getMin(), fn2.getMax() + 1):
                try:
                    # Need to catch exception here because all values in
                    # range min -> max are not always used, but there is no
                    # way to query the attribute if a value is used or not.
                    # An exception is raised if a value is not used.
                    enum[val] = fn2.fieldName(val)
                except:
                    pass
            dict['enum'] = enum
def getAddAttrCmd(sNodeAttr, longName=True):

    sNode, sAttr = sNodeAttr.split(".")

    node = api.getNode(sNode)
    fnNode = om.MFnDependencyNode(node)
    mAttr = om.MFnAttribute(fnNode.attribute(sAttr))
    return mAttr.getAddAttrCmd(longName)
    def doIt(self, args):
        # gather the values from args
        argParser = om.MArgParser(self.syntax(), args)

        plugString = argParser.commandArgumentString(0)
        sel = om.MSelectionList()
        sel.add(plugString)
        self.plug = sel.getPlug(0)

        attributeMObj = self.plug.attribute()
        fnAttr = om.MFnAttribute(attributeMObj)
        if fnAttr.affectsWorldSpace:
            self.modifier = om.MDGModifier()
            # self.modifier = om.MDagModifier()
        else:
            self.modifier = om.MDGModifier()

        if not self.plug.source().isNull:
            self.displayError('{} is connected and cannot be set.'.format(
                self.plug.name()))
            return

        if argParser.isFlagSet('double') or argParser.isFlagSet('d'):
            self.plugType = 'double'
            self.value = argParser.flagArgumentDouble('d', 0)
            self.redoIt()

        elif argParser.isFlagSet('boolean') or argParser.isFlagSet('b'):
            self.plugType = 'boolean'
            self.value = argParser.flagArgumentBool('b', 0)
            self.redoIt()

        elif argParser.isFlagSet('string') or argParser.isFlagSet('s'):
            self.plugType = 'string'
            self.value = argParser.flagArgumentString('s', 0)
            self.redoIt()

        elif argParser.isFlagSet('float') or argParser.isFlagSet('f'):
            self.plugType = 'float'
            self.value = argParser.flagArgumentFloat('f', 0)
            self.redoIt()

        elif argParser.isFlagSet('int') or argParser.isFlagSet('i'):
            self.plugType = 'int'
            self.value = argParser.flagArgumentInt('i', 0)
            self.redoIt()

        elif argParser.isFlagSet('angle') or argParser.isFlagSet('a'):
            self.plugType = 'angle'
            self.value = argParser.flagArgumentMAngle('a', 0)
            self.redoIt()
Exemple #6
0
    def doIt(self, args):
        # gather the values from args
        argParser = om.MArgParser(self.syntax(), args)

        sourcePlugStr = argParser.commandArgumentString(0)
        destPlugStr = argParser.commandArgumentString(1)

        sel = om.MSelectionList()
        sel.add(sourcePlugStr)
        sel.add(destPlugStr)
        self.sourcePlug = sel.getPlug(0)
        self.destPlug = sel.getPlug(1)

        if argParser.isFlagSet('f') or argParser.isFlagSet('forceConnection'):
            self.forceConnection = argParser.flagArgumentBool('f', 0)
        else:
            self.forceConnection = False

        sourceFnAttr = om.MFnAttribute(self.sourcePlug.attribute())
        destFnAttr = om.MFnAttribute(self.destPlug.attribute())

        if not sourceFnAttr.connectable:
            self.displayError('{} is not connectable'.format(
                self.sourcePlug.name()))
            return
        elif not destFnAttr.connectable:
            self.displayError('{} is not connectable'.format(
                self.destPlug.name()))
            return
        elif not destFnAttr.writable:
            self.displayError('{} is not writable'.format(
                self.destPlug.name()))
            return

        # Create a new MDGModifier for this action
        self.modifier = om.MDGModifier()

        self.redoIt()
def copyAttrs(srcNode, destNode, *sAttrList, **kwargs):
    logMsg(log='all')

    if "values" not in kwargs:
        kwargs["values"] = True

    bDelete = kwargs.pop("delete", False)
    bCreate = kwargs.pop("create", False)

    sSrcNode = argToStr(srcNode)
    sDestNode = argToStr(destNode)

    mObj = api.getNode(sSrcNode)
    fnNode = om.MFnDependencyNode(mObj)

    sCopyAttrList = []
    for sAttr in sAttrList:
        if not getObject(sDestNode + "." + sAttr):
            if bCreate:
                mAttr = om.MFnAttribute(fnNode.attribute(sAttr))
                sAddAttrCmd = mAttr.getAddAttrCmd(False).replace(";", " {};".format(sDestNode))

                logMsg("Copy attr. '{}' from '{}' to '{}'."
                       .format(sAttr, sSrcNode, sDestNode), log="info")
                pm.mel.eval(sAddAttrCmd)
            else:
                sAttr = ""
        else:
            if bCreate:
                logMsg("Attr. '{}' already exists on '{}'.".format(sAttr, sDestNode), log="info")

        if sAttr:
            sCopyAttrList.append(sAttr)

    mc.copyAttr(sSrcNode, sDestNode, attribute=sCopyAttrList, **kwargs)
    #copyAttrState(sSrcNode, sDestNode , *sCopyAttrList)

    if bDelete:
        for sAttr in sCopyAttrList:
            mc.deleteAttr(sSrcNode + "." + sAttr)

    return sCopyAttrList
Exemple #8
0
def findPlug(node, attr):
    """ Return the MPlug corresponding to attr on argument node or None if not found.
    The node argument can be an MObject or a node string name.
    The attr argument can be an MObject or a attr string name.
    Raises RuntimeError if plug is ambiguous."""
    if isinstance(node, basestring):
        attrName = attr if isinstance(
            attr, basestring) else OpenMaya.MFnAttribute(attr).name
        return nameToPlug(node + "." + attrName)

    if isinstance(attr, OpenMaya.MObject):
        plg = OpenMaya.MPlug(node, attr)
    else:
        if attr.find('[') != -1:
            # fn.findPlug doesn't work for elements of arrays
            # use a selection list to find the plug
            return nameToPlug(nodeToLongName(node) + "." + attr)
        if attr.find('.') != -1:
            # fn.findPlug doesn't work for compound paths
            # use last name in compound path as it is unique
            attr = attr.split('.')[-1]

        fn = OpenMaya.MFnDependencyNode(node)
        plg = fn.findPlug(attr, True) if fn.hasAttribute(attr) else None

    if not plg or plg.isNull or plg.isArray:
        # an array of plug is not a plug
        return None

    if plg.isChild and plg.parent(
    ).isElement and plg.parent().logicalIndex() < 0:
        # MAYA-66726: Plugs satisfying this should not be valid plugs
        # Example: "miDefaultOptions.name" satisfies this and is said to be a valid plug
        # its parent is miDefaultOptions.stringOptions[-1] which is an element with invalid logical index...
        return None

    return plg
    # 1. Current input convert to MObject
    # currentObject = 'pSphere1'
    objSelection = om.MSelectionList()
    objSelection.add(currentObject)
    objMObject = objSelection.getDependNode(0)

    # 2.Find the attributes of current object
    mfnDependencyNode = om.MFnDependencyNode(objMObject)
    attributeCount = mfnDependencyNode.attributeCount()

    nodeAnimInfomationList = {}

    for attriIndex in range(attributeCount):
        attriMObject = mfnDependencyNode.attribute(attriIndex)

        mfnAttribute = om.MFnAttribute(attriMObject)
        attriName = mfnAttribute.name.encode()

        # 3. Find the Attribute - Animation curve is connected
        currentPlug = mfnDependencyNode.findPlug(attriName, 1)
        if currentPlug.connectedTo(1, 0):
            connectedList = currentPlug.connectedTo(1, 0)

            # Find the connected node type
            conNodeMObject = connectedList[0].node()

            # Check its is a Animation curve
            if conNodeMObject.hasFn(om.MFn.kAnimCurve):

                # Read Anim Curve Attribute valus
                mfnAnimCurve = oma.MFnAnimCurve(conNodeMObject)
Exemple #10
0
 def __init__(self, mplug):
     if isinstance(mplug, om.MPlug):
         self.mobject = mplug.attribute()
     elif isinstance(mplug, om.MObject):
         self.mobject = mplug
     self.attr = om.MFnAttribute(self.mobject)
Exemple #11
0
    def parseAttribute(self, jsonInfo):
        """
		Create an attribute using the JSON parameters to decode the structure
		and values for the attribute. If the attribute is a compound then this
		method will be recursively called so as to create the entire attribute
		tree below it.
			jsonInfo = JSON object containing the attribute's information
		Returns the newly created attribute.
		"""
        if JsonKeys.kKeyName not in jsonInfo:
            self.reportError('Missing attribute name')
        self.currentAttribute = jsonInfo[JsonKeys.kKeyName]
        jsonDebug('parseAttribute(%s)' % str(jsonInfo))
        attr = None

        # Short name must always be present so find or generate one now
        if JsonKeys.kKeyShortName in jsonInfo:
            shortName = jsonInfo[JsonKeys.kKeyShortName]
        else:
            shortName = self.currentAttribute
        jsonDebug('...got short name %s' % shortName)

        #----------------------------------------
        # Create the specific type of attribute requested and handle the
        # type-specific parameters.
        #
        if JsonKeys.kKeyAttrType not in jsonInfo:
            self.reportError('Required keyword "%s" missing' %
                             JsonKeys.kKeyAttrType)
        elif jsonInfo[JsonKeys.kKeyAttrType] in JsonKeys.kNumericTypes:
            attr = self.parseNumericAttribute(self.currentAttribute, shortName,
                                              jsonInfo[JsonKeys.kKeyAttrType],
                                              jsonInfo)
        elif jsonInfo[JsonKeys.kKeyAttrType] == JsonKeys.kTypeCompound:
            attr = self.parseCompoundAttribute(self.currentAttribute,
                                               shortName, jsonInfo)
        elif jsonInfo[JsonKeys.kKeyAttrType] == JsonKeys.kTypeEnum:
            attr = self.parseEnumAttribute(self.currentAttribute, shortName,
                                           jsonInfo)
        elif jsonInfo[JsonKeys.kKeyAttrType] == JsonKeys.kTypeString:
            attr = self.parseStringAttribute(self.currentAttribute, shortName,
                                             jsonInfo)
        elif jsonInfo[JsonKeys.kKeyAttrType] in JsonKeys.kTypeMatrix:
            attr = self.parseMatrixAttribute(self.currentAttribute, shortName,
                                             jsonInfo)
        elif jsonInfo[JsonKeys.kKeyAttrType] == JsonKeys.kTypeTyped:
            attr = self.parseTypedAttribute(self.currentAttribute, shortName,
                                            jsonInfo)
        elif jsonInfo[JsonKeys.kKeyAttrType] == JsonKeys.kTypeLightData:
            attr = self.parseLightDataAttribute(self.currentAttribute,
                                                shortName, jsonInfo)
        elif jsonInfo[JsonKeys.kKeyAttrType] == JsonKeys.kTypeMessage:
            attr = self.parseMessageAttribute(self.currentAttribute, shortName,
                                              jsonInfo)
        else:
            self.reportError('Unknown attribute type "%s"' %
                             jsonInfo[JsonKeys.kKeyAttrType])
            return None

        jsonDebug(
            'Done creating attribute "%s", now setting shared parameters' %
            str(attr))

        #----------------------------------------
        # Handle the parameters common to all attribute types
        #
        aBase = omAPI.MFnAttribute(attr)
        jsonDebug('...handling common attribute flags for "%s"' % str(aBase))

        # Handle the standard flags
        if JsonKeys.kKeyFlags in jsonInfo:
            self.parseStandardFlags(aBase, jsonInfo[JsonKeys.kKeyFlags])

        # Look for a nice name override
        if JsonKeys.kKeyNiceName in jsonInfo:
            jsonDebug('...Overriding nice name with "%s"' %
                      jsonInfo[JsonKeys.kKeyNiceName])
            aBase.setNiceNameOverride(jsonInfo[JsonKeys.kKeyNiceName])

        # See if the attribute has been added to any categories
        if JsonKeys.kKeyCategories in jsonInfo:
            for category in jsonInfo[JsonKeys.kKeyCategories]:
                jsonDebug('...Adding category "%s"' % category)
                aBase.addToCategory(category)
                jsonDebug('...Done on category "%s"' % category)
        jsonDebug('...Done the categories')

        # See if there is any special disconnection behaviour
        if JsonKeys.kKeyDisconnect in jsonInfo:
            behavior = jsonInfo[JsonKeys.kKeyDisconnect]
            jsonDebug('...Setting disconnect behaviour to "%s"' % behavior)
            if behavior in JsonKeys.kDisconnectBehaviors:
                aBase.disconnectBehavior = JsonKeys.kDisconnectBehaviors[
                    behavior]
            else:
                self.reportError('Unknown behavior type "%s"' % behavior)

        return attr
Exemple #12
0
 def attribute(self):
     """Returns the attribute (MFnAttribute) of the plug """
     return OpenMaya.MFnAttribute(self.plug.attribute())
 def setDependentsDirty(self, plug, plugArray):
     if plug.attribute() == MntLocatorNode.iconType:
         iconMainAxisAttr = OpenMaya.MFnAttribute(MntLocatorNode.iconMainAxis)  
Exemple #14
0
def get_anim_curves_from_objects(nodes):
    """ Gets the animation curves connected to nodes.
    
    :param nodes: List with MFnDependencyNode
    :type nodes: list of om.MFnDependencyNode
    :return: Tuple of curves and plugs
    :rtype: (list of om.MFnDependencyNode, list of om.MPlug)
    """

    curves = []
    plugs = []
    channelbox_attr = get_channelbox_attributes()

    animlayers.cache.reset(
    )  # always reset cache before querying for animation layers!
    has_anim_layers = animlayers.has_anim_layers()

    if has_anim_layers and animlayers.all_layers_locked():
        cmds.warning('All animation layers are locked!')

    # get curves
    for node in nodes:
        # get all attributes
        attr_count = node.attributeCount()
        for index in range(attr_count):
            attr = node.attribute(index)
            plug = node.findPlug(attr, True)

            if plug.isLocked or not plug.isKeyable:
                continue

            connections = plug.connectedTo(True, False)

            # if the attribute has a connection
            if connections:
                conn_node = connections[0].node()

                api = conn_node.apiType()
                if api in ANIM_CURVE_TYPES:
                    # filter out attributes not selected in channelbox
                    if channelbox_attr:
                        attr_name = om.MFnAttribute(attr).shortName
                        if attr_name not in channelbox_attr:
                            continue

                    # add the node if it matches one of the types we want
                    curves.append(om.MFnDependencyNode(conn_node))
                    plugs.append(plug)

                # find curve in animation layer
                elif has_anim_layers and api in animlayers.BLEND_NODE_TYPES:
                    # filter out attributes not selected in channelbox
                    if channelbox_attr:
                        attr_name = om.MFnAttribute(attr).shortName
                        if attr_name not in channelbox_attr:
                            continue

                    # for testing purposes
                    # print('Attribute: %s' % plug)

                    # benchmark_start = time.clock()
                    best_layer = animlayers.get_best_layer(plug)
                    if not best_layer:
                        continue

                    # for testing purposes
                    # try:
                    #     print('-> Best layer is %s' % (om.MFnDependencyNode(best_layer).name()))
                    # except Exception as e:
                    #     pass

                    curve_node = animlayers.get_anim_curve(plug, best_layer)
                    # animlayers.cache.benchmark += time.clock() - benchmark_start
                    if curve_node:
                        curves.append(om.MFnDependencyNode(curve_node))
                        plugs.append(plug)

    # sys.stdout.write('# Retrieved %d curves in %.4f sec\n' % (len(curve_list), animlayers.cache.benchmark))
    return curves, plugs
def exportAnimCurve(selectionList,
                    animPath,
                    animName,
                    animGIFPath,
                    iconPath):

    animDataDict = {}
    for currentObject in selectionList:
        objMSL = om.MSelectionList()
        objMSL.add(currentObject)
        objMObject = objMSL.getDependNode(0)

        # find the attribute of current object
        objMFnDPNode = om.MFnDependencyNode(objMObject)
        attributeCount = objMFnDPNode.attributeCount()

        nodeAnimInformationDict = {}

        for attributeIndex in range(attributeCount):
            attributeMObject = objMFnDPNode.attribute(attributeIndex)

            MFnAttribute = om.MFnAttribute(attributeMObject)

            attributeName = MFnAttribute.name

            # find the attribute that anim curve connected

            currentPlug = objMFnDPNode.findPlug(attributeName, 1)

            if currentPlug.connectedTo(1, 0):
                currentConnectedList = currentPlug.connectedTo(1, 0)

                # find the connected node type
                currentConnectNodeMObject = currentConnectedList[0].node()

                # check it is an anim curve
                if currentConnectNodeMObject.hasFn(om.MFn.kAnimCurve):
                    # get anim curve
                    MFnAnimCurve = oma.MFnAnimCurve(currentConnectNodeMObject)

                    # get attribute
                    animCurveType = MFnAnimCurve.animCurveType
                    preInfinity = MFnAnimCurve.preInfinityType
                    postInfinity = MFnAnimCurve.postInfinityType

                    weightedTangents = int(MFnAnimCurve.isWeighted)

                    # get value of each key
                    numKeys = MFnAnimCurve.numKeys
                    timeList = []
                    valueList = []

                    inTangentTypeList = []
                    inTangentAngleList = []
                    inTangentAngleWeightList = []

                    outTangentTypeList = []
                    outTangentAngleList = []
                    outTangentAngleWeightList = []

                    for index in range(numKeys):
                        # time
                        input = MFnAnimCurve.input(index)
                        mTime = om.MTime(input)
                        currentTime = mTime.value
                        timeList.append(currentTime)

                        # value
                        value = MFnAnimCurve.value(index)
                        valueList.append(value)

                        # inTangent
                        inTangentType = MFnAnimCurve.inTangentType(index)
                        inTangentTypeList.append(inTangentType)

                        inTangentAngleWeight = MFnAnimCurve.getTangentAngleWeight(index, 1)

                        inTangentAngleMAngle = om.MAngle(inTangentAngleWeight[0])
                        inTangentValue = inTangentAngleMAngle.value
                        inTangentAngleList.append(inTangentValue)
                        inTangentAngleWeightList.append(inTangentAngleWeight[1])

                        # outTangent
                        outTangentType = MFnAnimCurve.outTangentType(index)
                        outTangentTypeList.append(outTangentType)

                        outTangentAngleWeight = MFnAnimCurve.getTangentAngleWeight(index, 0)
                        outTangentAngleMAngle = om.MAngle(outTangentAngleWeight[0])
                        outTangetValue = outTangentAngleMAngle.value
                        outTangentAngleList.append(outTangetValue)
                        outTangentAngleWeightList.append(outTangentAngleWeight[1])

                    attributeDataDict = {'animCurveType': animCurveType,
                                         'preInfinity': preInfinity,
                                         'postInfinity': postInfinity,
                                         'weightedTangents': weightedTangents,
                                         'numKeys': numKeys,
                                         'timeList': timeList,
                                         'valueList': valueList,
                                         'inTangentTypeList': inTangentTypeList,
                                         'inTangentAngleList': inTangentAngleList,
                                         'inTangentAngleWeightList': inTangentAngleWeightList,
                                         'outTangentAngleList': outTangentAngleList,
                                         'outTangentTypeList': outTangentTypeList,
                                         'outTangentAngleWeightList': outTangentAngleWeightList}

                    nodeAnimInformationDict.setdefault(attributeName, attributeDataDict)

        animDataDict.setdefault(currentObject.encode(), nodeAnimInformationDict)

    # Data History
    owner = os.getenv('USERNAME')
    time = datetime.datetime.now().strftime("%A, %B, %d, %Y %H:%M %p")
    mayaVersion = cmds.about(q=1, v=1)
    version = '0.1'
    dataList = {'animCurve': animDataDict, 'history': [owner, time, mayaVersion, version]}

    dataPath = '%s/%s.anim' % (animPath, animName)

    if os.path.isfile(dataPath):
        try:
            os.chmod(dataPath, 0777)
            os.remove(dataPath)
        except Exception, result:
            print result