Exemplo n.º 1
0
def iter_input(component_mob):
    if is_component(component_mob):
        fn = om2.MFnDagNode(component_mob)
        child_count = fn.childCount()

        for i in range(child_count):
            child_mob = fn.child(i)
            child_name = om2.MFnDagNode(child_mob).name()
            if child_name.endswith('_input'):
                yield child_mob
Exemplo n.º 2
0
def iter_components(rig_mob):
    if is_control_rig(rig_mob):
        fn = om2.MFnDagNode(rig_mob)
        child_count = fn.childCount()

        for i in range(child_count):
            child_mob = fn.child(i)
            child_name = om2.MFnDagNode(child_mob).name()
            if child_name.endswith('_cmpnt'):
                yield child_mob
Exemplo n.º 3
0
def is_control_rig(mob):
    fn = om2.MFnDagNode(mob)
    is_named_correctly = fn.name() == "rig"

    is_two_from_world = False
    if (is_named_correctly):
        parent_mob = fn.parent(0)
        parent_fn = om2.MFnDagNode(parent_mob)

        if parent_fn.name() != 'world':
            granny_mob = parent_fn.parent(0)
            granny_fn = om2.MFnDagNode(granny_mob)

            is_two_from_world = granny_fn.name() == 'world'

    return is_named_correctly and is_two_from_world
Exemplo n.º 4
0
def is_component(mob):
    fn = om2.MFnDagNode(mob)

    is_under_rig = is_control_rig(fn.parent(0))
    if is_under_rig:
        return fn.name().endswith('_cmpnt')
    else:
        return False
Exemplo n.º 5
0
def iter_output(component_mob):
    if is_component(component_mob):
        fn = om2.MFnDagNode(component_mob)
        child_count = fn.childCount()

        for i in range(child_count):
            child_mob = fn.child(i)
            child_name = om2.MFnDagNode(child_mob).name()
            if child_name.endswith('_output'):
                yield child_mob

                itr_dag = om2.MItDag()
                itr_dag.reset(child_mob)
                itr_dag.next()

                while (not itr_dag.isDone()):
                    curr_node = itr_dag.currentItem()

                    yield curr_node
                    itr_dag.next()
Exemplo n.º 6
0
def container_from_component(component_mob):
    assert is_component(component_mob)

    comp_fn = om2.MFnDagNode(component_mob)
    comp_dag_name = comp_fn.name()

    container_name = "{}_container".format(comp_dag_name[:-6])

    sel = om2.MSelectionList()
    sel.add(container_name)

    container_mob = sel.getDependNode(0)

    return container_mob
Exemplo n.º 7
0
 def boundingBox(self):
     """Return the boundingBox"""
     if not MeshController.ctrlVertices:
         thisMob = self.thisMObject()
         thisPath = om2.MDagPath.getAPathTo(thisMob)
         transformPath = om2.MDagPath.getAPathTo(
             om2.MFnDagNode(thisPath).parent(0))
         mWorldInv = transformPath.inclusiveMatrixInverse()
         indexStr = om2.MPlug(thisMob,
                              MeshController.inIndexList).asString()
         offset = om2.MPlug(thisMob, MeshController.inOffset).asFloat()
         mesh = om2.MPlug(thisMob,
                          MeshController.inMesh).asMDataHandle().asMesh()
         MeshController.getGeometryPoints(mesh, indexStr, offset, mWorldInv)
     return MeshController.bBox
Exemplo n.º 8
0
 def connectionMade(self, plug, otherPlug, asSrc):
     """This method gets called when connections are made to attributes of this node.
         * plug (MPlug) is the attribute on this node.
         * otherPlug (MPlug) is the attribute on the other node.
         * asSrc (bool) is this plug a source of the connection.
     """
     if plug == DebugMatrix.inMatrix:
         thisMob = self.thisMObject()
         distancePlug = om2.MPlug(thisMob, DebugMatrix.inDistance)
         dagFn = om2.MFnDagNode(otherPlug.node())
         bBox = dagFn.boundingBox
         offset = bBox.width / 2.0
         distancePlug.setFloat(offset + 2.0)
     return omui2.MPxLocatorNode.connectionMade(self, plug, otherPlug,
                                                asSrc)
Exemplo n.º 9
0
def wMtxFromMob(node_mob):
    """
    finds the world matrix attribute and returns its value in matrix form
    :param node_mob: [MObject] the node to get the world matrix from 
    :return: [MMatrix] the matrix value of the world transform on the argument node
    """
    if not node_mob.hasFn(om2.MFn.kDagNode):
        return None

    mfn_dag = om2.MFnDagNode(node_mob)
    wMtxPlug = mfn_dag.findPlug(_MAYA_MATRIX_ATTRIBUTE_NAME, False)
    elPlug = wMtxPlug.elementByLogicalIndex(0)

    node_mob_attr = elPlug.asMObject()
    mfn_mtxData = om2.MFnMatrixData(node_mob_attr)
    return mfn_mtxData.matrix()
Exemplo n.º 10
0
    def prepareForDraw(self, objPath, cameraPath, frameContext, oldData):
        """
        Called by Maya each time the object needs to be drawn.
        Any data needed from the Maya dependency graph must be retrieved and cached in this stage.
        Returns the data to be passed to the draw callback method.
            * objPath [MDagPath] is the path to the object being drawn.
            * cameraPath [MDagPath] is the path to the camera that is being used to draw.
            * frameContext [MFrameContext] is the frame level context information.
            * oldData [MUserData] is the data cached by the previous draw of the instance.
        """
        # pylint: disable=unused-argument
        startTime = time.time()
        data = oldData
        if not isinstance(data, MeshControllerData):
            data = MeshControllerData()

        node = objPath.node()
        transformPath = om2.MDagPath.getAPathTo(
            om2.MFnDagNode(objPath).parent(0))
        mWorldInv = transformPath.inclusiveMatrixInverse()
        indexStr = om2.MPlug(node, MeshController.inIndexList).asString()
        offset = om2.MPlug(node, MeshController.inOffset).asFloat()
        mesh = om2.MPlug(node, MeshController.inMesh).asMDataHandle().asMesh()
        color = om2.MPlug(
            node, MeshController.inColor).asMDataHandle().asFloatVector()

        # If plugs are dirty calculate the geometry points
        MeshController.getGeometryPoints(mesh, indexStr, offset, mWorldInv)

        data.fVtxPositions = MeshController.ctrlVertices

        status = omr2.MGeometryUtilities.displayStatus(objPath)
        if status == omr2.MGeometryUtilities.kDormant:
            # Not selected
            alpha = 0.25
        elif status == omr2.MGeometryUtilities.kActive:
            # Multiselection
            alpha = 0.65
        elif status == omr2.MGeometryUtilities.kLead:
            # Selected
            alpha = 0.5
        data.fColor = om2.MColor([color.x, color.y, color.z, alpha])

        runTime = round((time.time() - startTime) * 1000, 5)
        om2.MGlobal.displayInfo("prepareForDraw time: %s ms" % str(runTime))
        return data
Exemplo n.º 11
0
def importantObjectsFromContainer(containerHandle):
    """
    This takes a component name for some filtering and a container handle and isolates
      the key objects related to it that represent our component interesting items.
    :param containerHandle: `MObjectHandle`
    :return: `dict` k,v pairs for interesting objects and their handle, None if unavailable
    """

    mfn_cont = om2.MFnContainerNode(containerHandle.object())
    mobaMembers = mfn_cont.getMembers()

    fullname = mfn_cont.name()
    tokens = fullname.rsplit('_', 1)
    componentName = tokens[0]

    keyObsDict = {
        'componentName': componentName,
        CONTROL_KEY: None,
        GUIDE_KEY: None,
        DEFORM_KEY: None,
        TOOLPARAMETERS_SUFFIX: None,
    }

    toolParametersObjName = '{}_{}'.format(componentName,
                                           TOOLPARAMETERS_SUFFIX)
    for eachMob in mobaMembers:
        if not eachMob.hasFn(om2.MFn.kDagNode):
            continue

        mfn_dag = om2.MFnDagNode(eachMob)

        objectName = mfn_dag.name()

        if objectName == CONTROL_KEY:
            keyObsDict[CONTROL_KEY] = om2.MObjectHandle(eachMob)
        elif objectName == GUIDE_KEY:
            keyObsDict[GUIDE_KEY] = om2.MObjectHandle(eachMob)
        elif objectName == DEFORM_KEY:
            keyObsDict[DEFORM_KEY] = om2.MObjectHandle(eachMob)
        elif objectName == toolParametersObjName:
            keyObsDict[TOOLPARAMETERS_SUFFIX] = om2.MObjectHandle(eachMob)

    return keyObsDict
Exemplo n.º 12
0
 def autoFillOffset(self, thisMob, index):
     """Auto fill offsets attributes."""
     allClear = self.checkOutputConnections(thisMob)
     obj = self.constraintObject
     if not allClear:
         if obj.hasFn(om2.MFn.kDagNode):
             objPath = om2.MFnDagNode(obj).getPath()
             mOut = objPath.inclusiveMatrix()
             targetPlug = om2.MPlug(thisMob, SpaceConstraint.inTarget)
             curTargetPlug = targetPlug.elementByLogicalIndex(index)
             curTargetObj = curTargetPlug.asMObject()
             mtxDataFn = om2.MFnMatrixData(curTargetObj)
             mTarget = mtxDataFn.matrix()
             mOffset = mOut * mTarget.inverse()
             offsetPlug = om2.MPlug(thisMob, SpaceConstraint.inOffset)
             curOffsetPlug = offsetPlug.elementByLogicalIndex(index)
             curOffsetHdle = curOffsetPlug.asMDataHandle()
             mCurOffset = curOffsetHdle.asMatrix()
             if mCurOffset == om2.MMatrix():
                 curOffsetHdle.setMMatrix(mOffset)
                 curOffsetPlug.setMDataHandle(curOffsetHdle)
Exemplo n.º 13
0
 def parent(self):
     if self._parent is not None and \
             (self._parent.isNull() or
              not len(om2.MFnDagNode(self._parent).fullPathName())):
         self._parent = None
     return self._parent
Exemplo n.º 14
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.º 15
0
    def drawText(self,
                 mtx,
                 dist,
                 colorList,
                 status,
                 cameraPath,
                 lineH,
                 view=None,
                 drawManager=None):
        """Draw the matrix text.
        """
        mCamera = cameraPath.inclusiveMatrix()
        camFn = om2.MFnCamera(cameraPath)
        thisMob = self.thisMObject()
        worldMtxPlug = om2.MPlug(thisMob, DebugMatrix.inMatrix)
        destPlugList = worldMtxPlug.connectedTo(True, False)
        if len(destPlugList) >= 1:
            node = destPlugList[0].node()
            attr = destPlugList[0].attribute()
            dagFn = om2.MFnDagNode(node)
            name = dagFn.name()
            attrName = "%s   (%s)" % ("  " * len(name),
                                      om2.MFnAttribute(attr).name)
            bBox = dagFn.boundingBox
        else:
            attrName = ""
            name = "NO MATRIX INPUT"
            bBox = om2.MBoundingBox()

        offsetY = bBox.height / 2.0

        pntCamera = om2.MPoint(mCamera[12], mCamera[13], mCamera[14])
        pntPos = om2.MPoint(mtx[12] + dist, mtx[13] + offsetY, mtx[14])
        vCamera = pntCamera - pntPos
        distFromCamera = vCamera.length()
        pntLineOffset = om2.MPoint(0.0, (distFromCamera / camFn.focalLength) *
                                   lineH, 0.0)
        rowList = []

        pntRow1 = om2.MPoint(mtx[0], mtx[1], mtx[2], mtx[3])
        row1 = "%s | %s | %s | %s" % ("%.3f" % pntRow1.x, "%.3f" % pntRow1.y,
                                      "%.3f" % pntRow1.z, "%.3f" % pntRow1.w)
        rowList.append(row1)
        pntRow2 = om2.MPoint(mtx[4], mtx[5], mtx[6], mtx[7])
        row2 = "%s | %s | %s | %s" % ("%.3f" % pntRow2.x, "%.3f" % pntRow2.y,
                                      "%.3f" % pntRow2.z, "%.3f" % pntRow2.w)
        rowList.append(row2)
        pntRow3 = om2.MPoint(mtx[8], mtx[9], mtx[10], mtx[11])
        row3 = "%s | %s | %s | %s" % ("%.3f" % pntRow3.x, "%.3f" % pntRow3.y,
                                      "%.3f" % pntRow3.z, "%.3f" % pntRow3.w)
        rowList.append(row3)
        pntRow4 = om2.MPoint(mtx[12], mtx[13], mtx[14], mtx[15])
        row4 = "%s | %s | %s | %s" % ("%.3f" % pntRow4.x, "%.3f" % pntRow4.y,
                                      "%.3f" % pntRow4.z, "%.3f" % pntRow4.w)
        rowList.append(row4)

        if status == omui2.M3dView.kActive:
            view.setDrawColor(om2.MColor([0.3, 1.0, 1.0]))
        elif status == omui2.M3dView.kLead:
            view.setDrawColor(om2.MColor([1.0, 1.0, 1.0]))

        if status == omui2.M3dView.kDormant:
            view.setDrawColor(colorList[0])
        view.drawText(name, pntPos, omui2.M3dView.kLeft)

        if status == omui2.M3dView.kDormant:
            view.setDrawColor(colorList[1])
        view.drawText(attrName, pntPos, omui2.M3dView.kLeft)
        if worldMtxPlug.isConnected:
            for i in range(1, 5):
                pos = om2.MPoint(pntPos - (pntLineOffset * i))
                view.drawText(rowList[i - 1], pos, omui2.M3dView.kLeft)