Exemplo n.º 1
0
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 eachDestinationPlug in plug.destinations():
        destinationNode = eachDestinationPlug.node()
        if not destinationNode.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
        mfnDestinationNode = om2.MFnDependencyNode(destinationNode)
        layoutNodeMsgPlug = mfnDestinationNode.findPlug("message", False)

        msgDestinations = layoutNodeMsgPlug.destinations()
        for eachLayoutDestination in msgDestinations:
            if eachLayoutDestination.node().hasFn(om2.MFn.kContainer):
                return eachLayoutDestination.node()
Exemplo n.º 2
0
def cb(msg, plug1, plug2, payload):
    if msg != 2056:  #check most common case first and return unless it's
        return  # an attribute edit type of callback

    if not plug1.partialName(includeNodeName=False,
                             useAlias=False) == fkik_attrName:
        # We ensure if the attribute being changed is uninteresting we do nothing
        return

    isFK = plug1.asBool() == False  # Switched To FK
    isIK = not isFK  # Switched to IK

    settingsAttrs = { # all interesting attribute names in keys, respective plugs in values
                     'fkRotation': None,
                     'ikRotation': None,
                     'fk_ctrl_rotx': None,
                     'ik_ctrl_translate': None,
                     'ikPedalOffset': None,
                     }

    mfn_dep = om2.MFnDependencyNode(plug1.node())
    # We populate the dictionary of interesting attributes with their plugs
    for eachPName in settingsAttrs.iterkeys():
        plug = mfn_dep.findPlug(eachPName, False)
        settingsAttrs[eachPName] = plug

    for p in settingsAttrs.itervalues():
        # We will exit early and do nothing if a plug couldn't be initialised, the object
        #  is malformed, or we installed the callback on an object that is only
        #  conformant by accident and can't operate as we expect it to.
        if p is None:
            return

    angle = None  # empty init
    if isFK:
        # Simplest case, if we switched to FK we copy the roation from IK
        #  to the FK control's X rotation value
        angle = -settingsAttrs.get("ikRotation").source().asDouble()
        fkSourcePlug = settingsAttrs.get("fk_ctrl_rotx").source()
        fkSourcePlug.setDouble(angle)
    elif isIK:
        # If instead we switched to IK we need to
        #  derive the translation of the IK control that produces the result
        #  of an equivalent rotation to the one coming from the FK control
        angle = settingsAttrs.get("fkRotation").source().asDouble()
        projectedLen = settingsAttrs.get("ikPedalOffset").source().asDouble()

        y = (math.cos(angle) * projectedLen) - projectedLen
        z = math.sin(angle) * projectedLen

        ikSourcePlug = settingsAttrs.get("ik_ctrl_translate").source()
        for i in xrange(ikSourcePlug.numChildren()):
            realName = ikSourcePlug.child(i).partialName(includeNodeName=False,
                                                         useAlias=False)
            if realName == 'ty':
                ikSourcePlug.child(i).setDouble(y)
            elif realName == 'tz':
                ikSourcePlug.child(i).setDouble(z)
Exemplo n.º 3
0
def msgConnectedPlugs(plug):
    """
    :param plug: [MPlug] plug on a node owning message plug
                         we wish to retrieve all destination plugs from
    :return: [tuple(MPlug)] all plugs on other nodes receiving a message connection
                            coming from the one owning the argument plug
    """
    mfn_dep = om2.MFnDependencyNode(plug.node())
    msgPlug = mfn_dep.findPlug('message', False)
    return tuple([om2.MPlug(otherP) for otherP in msgPlug.destinations()])
Exemplo n.º 4
0
def translationPlugsFromAnyPlug(plug):
    """
    :param plug: [MPlug] plug on a node to retrieve translation related plugs from
    :return: [tuple(MPlug)] tuple of compound translate plug,
                            and three axes translate plugs
    """
    node = plug.node()
    if not node.hasFn(om2.MFn.kTransform
                      ):  # this should exclude nodes without translate plugs
        return
    mfn_dep = om2.MFnDependencyNode(node)
    pNames = ('translate', 'tx', 'ty', 'tz')
    return tuple([mfn_dep.findPlug(eachName, False) for eachName in pNames])
Exemplo n.º 5
0
def getMRotFromNodeOutput(node_mob, rotOrder=om2.MEulerRotation.kXYZ):
    """
    finds the angular output of the argument node and returns it
     as a Euler rotation where that angle is the X element
    :param node_mob: [MObject] the node to get the output port from
    :param rotOrder: [int] the factory constant for the desired rotation order
                            the returned Euler rotation should be set to
    :return: [MEulerRotation] the Euler rotation composition where the
                                angular output on the argument node is the X value
    """
    mfn_dep = om2.MFnDependencyNode(node_mob)
    angle = om2.MAngle(0.0)
    if node_mob.hasFn(om2.MFn.kAnimBlend) and mfn_dep.hasAttribute(
            _MAYA_OUTPUT_ATTRIBUTE_NAME):
        plug = mfn_dep.findPlug(_MAYA_OUTPUT_ATTRIBUTE_NAME, False)
        angle = plug.asMAngle()

    rot = om2.MEulerRotation(angle.asRadians(), 0.0, 0.0, rotOrder)
    return rot
Exemplo n.º 6
0
    rot = om2.MEulerRotation(angle.asRadians(), 0.0, 0.0, rotOrder)
    return rot


# A dictionary of all attributes we're interested in by name, ready
#   to accept values for each.
attribs = {
    'blendedRotation': None,
    'fk_bfr_mtx': None,
    'ik_bfr_mtx': None,
    'ikPedalOffset': None,
}

mobTuple = tuple(iterSelection())
if mobTuple:
    mfn_dep = om2.MFnDependencyNode(mobTuple[0])
    plug = om2.MPlug()
    if mfn_dep.hasAttribute("FKIK_switch"):
        plug = mfn_dep.findPlug("FKIK_switch", False)

    if plug.isNull:
        print(
            "invalid selection, no FKIK_switch attribute found on first selected item"
        )
    else:
        for eachPName in attribs.iterkeys():
            plug = mfn_dep.findPlug(eachPName, False)
            attribs[eachPName] = plug

    isValid = True
    for p in attribs.itervalues():
Exemplo n.º 7
0
 def postConstructor(self):
     """ Post Constructor. """
     thisMob = self.thisMObject()
     om2.MFnDependencyNode(thisMob).setName("%sShape#" %
                                            DebugVector.kNodeName)
Exemplo n.º 8
0
    def doIt(self, args):
        """
        Maya Factory method
        :param args: in new-api mode this is probably going to be a tuple
        :return: `None`
        """

        if not RUN_LOCAL_INSTANCE_MODE:
            argDB = om2.MArgDatabase(self.syntax(), args)
            obList = argDB.getObjectList()
            sw = argDB.isFlagSet('-sw')
            rd = argDB.isFlagSet('-rd')
            rg = argDB.isFlagSet('-rg')
        else:  # debug only case, set manually as needed
            obList = om2.MGlobal.getActiveSelectionList()
            sw = True
            rd = False
            rg = False

        # We assume there can only be one object in the list we received
        #   based on the constraints we established for the arguments
        mob = obList.getDependNode(0)

        containerNode = containerFromNode(mob)
        self.__containerHandle = om2.MObjectHandle(containerNode)

        if containerNode is None or containerNode.isNull():
            return
        else:
            self.__componentDict = importantObjectsFromContainer(
                self.__containerHandle)
            self.__toolParsMobha = self.__componentDict[TOOLPARAMETERS_SUFFIX]

            requiresPanel = sw or rg

            if requiresPanel and (self.__toolParsMobha is None
                                  or not self.__toolParsMobha.isValid()):
                return

        if sw:
            # This section is responsible for, if invoked, swapping the plugs
            #     that set the state of the component to guided or unguided
            mfn_panelDag = om2.MFnDagNode(self.__toolParsMobha.object())
            plug_toSwap = mfn_panelDag.findPlug('toSwap', False)

            for eachNamedCouple in iterSwapPlugs(plug_toSwap):
                trPlug_origin = eachNamedCouple[
                    TRACKER_PLUG_NAMES[0]]  # origin on tracker panel
                trPlug_guided = eachNamedCouple[
                    TRACKER_PLUG_NAMES[1]]  # guided on tracker panel

                actPlug_origin = None  # source of tracked origin plug, might remain None
                actPlug_originSource = None  # source of active origin plug, might remain None
                actPlug_guided = None  # source of tracked guided plug, might remain None
                actPlug_guidedSource = None  # most upstream plug to swap, might remain None

                if trPlug_origin.isDestination:
                    actPlug_origin = trPlug_origin.source()
                    if actPlug_origin.isDestination:
                        actPlug_originSource = actPlug_origin.source()

                if trPlug_guided.isDestination:
                    actPlug_guided = trPlug_guided.source()
                    if actPlug_guided.isDestination:
                        actPlug_guidedSource = actPlug_guided.source()

                doNothing = (actPlug_origin is None) and (actPlug_guidedSource
                                                          is None)
                if doNothing:
                    continue
                else:  # else is redundant here, it's only for clarity and legibility
                    self.__needsUndoing = 1

                name_trOrigin = cmdFriendlyNameFromPlug(trPlug_origin)
                name_trGuided = cmdFriendlyNameFromPlug(trPlug_guided)

                name_actOrigin = cmdFriendlyNameFromPlug(actPlug_origin)
                name_actOriginSource = cmdFriendlyNameFromPlug(
                    actPlug_originSource)
                name_actGuided = cmdFriendlyNameFromPlug(actPlug_guided)
                name_actGuidedSource = cmdFriendlyNameFromPlug(
                    actPlug_guidedSource)

                connect = actPlug_origin is not None and actPlug_guidedSource is None
                disconnect = actPlug_origin is None and actPlug_guidedSource is not None
                swap = actPlug_origin is not None and actPlug_guidedSource is not None

                if connect:
                    m_cmds.connectAttr(name_actOrigin, name_actGuided)
                    m_cmds.disconnectAttr(name_actOrigin, name_trOrigin)

                elif disconnect:
                    m_cmds.disconnectAttr(name_actGuidedSource, name_actGuided)
                    m_cmds.connectAttr(name_actGuidedSource, name_trOrigin)

                elif swap:
                    m_cmds.connectAttr(name_actGuidedSource,
                                       name_trOrigin,
                                       force=True)
                    m_cmds.connectAttr(name_actOrigin,
                                       name_actGuided,
                                       force=True)

                else:
                    # if things get to this point it means that no combination of
                    #   flags ever took place and all cases are False.
                    # This error should literally be impossible since check coverage is complete.
                    # If this occurs something might have mutated the various branching flags
                    #   between checks, which would be extremely unlikely to happen
                    raise RuntimeError("WTF, mate?!")
        # end swap

        if rg:
            # This section, if invoked, is responsible to iterate the plugs
            #     flagging what objects require deletion and issuing
            #     the command to delete each
            mfn_panelDag = om2.MFnDagNode(self.__toolParsMobha.object())
            plug_toDelete = mfn_panelDag.findPlug('toDelete', False)

            elemCount = plug_toDelete.evaluateNumElements()

            foundAtLeastOne = 0
            for i in xrange(elemCount):
                elemPlug = plug_toDelete.elementByPhysicalIndex(i)
                if elemPlug.isDestination:
                    foundAtLeastOne = 2
                    sourceNode = elemPlug.source().node()

                    if sourceNode.hasFn(om2.MFn.kDagNode):
                        om2.MDagPath.getAPathTo(sourceNode)
                        pathToNode = om2.MDagPath.getAPathTo(
                            sourceNode).fullPathName()
                    else:
                        pathToNode = om2.MFnDependencyNode(sourceNode).name()

                    if pathToNode:
                        m_cmds.delete(pathToNode)

            self.__needsUndoing += foundAtLeastOne
        # end delete DG nodes

        if rd:
            # This section, if invoked, is responsible to delete the guide DAG object
            #     for the component, which should take with it the entire hierarchy
            guideMobha = self.__componentDict[GUIDE_KEY]
            if guideMobha is None or not guideMobha.isValid(
            ) or guideMobha.object().isNull():
                self.__needsUndoing = self.__needsUndoing or 0
                return

            guideMob = guideMobha.object()
            assert guideMob.hasFn(
                om2.MFn.kDagNode
            ), "guide object stored in dictionary doesn't seem to be a DAG node"

            pathToGuide = om2.MDagPath.getAPathTo(
                guideMobha.object()).fullPathName()
            m_cmds.delete(pathToGuide)
Exemplo n.º 9
0
selection = om.MGlobal.getActiveSelectionList()

print(selection)
# Iterate over each selected object and use the appropriate function set
# to query type specific data

for i in range(selection.length()):
    if i > 0:
        print('-------------')

    obj = selection.getDependNode(i)  # returns an MObject
    print('API Type: {0}'.format(obj.apiTypeStr))

    if obj.hasFn(om.MFn.kDependencyNode
                 ):  # Check if the function set is compatible with the MObject
        depend_fn = om.MFnDependencyNode(
            obj)  # Attach supported function set to the MObject
        print('Dependency Node: {0}'.format(
            depend_fn.name()))  # Use function set to query data

        if obj.hasFn(om.MFn.kTransform):
            transform_fn = om.MFnTransform(obj)
            print('Translation: {0}'.format(
                transform_fn.translation(om.MSpace.kTransform)))
        elif obj.hasFn(om.MFn.kMesh):
            mesh_fn = om.MFnMesh(obj)
            print('Mesh Vertices: {0}'.format(mesh_fn.getVertices()))
        elif obj.hasFn(om.MFn.kCamera):
            camera_fn = om.MFnCamera(obj)
            print('Clipping Planes: {0} {1}'.format(
                camera_fn.nearClippingPlane, camera_fn.farClippingPlane))
Exemplo n.º 10
0
 def postConstructor(self):
     """ Post Constructor. """
     thisMob = self.thisMObject()
     nodeFn = om2.MFnDependencyNode(thisMob)
     nodeFn.setName("%sShape#" % DebugMatrix.kNodeName)