def compute(self, plug, dataBlock):
        """
        Node computation method:
            * plug is a connection point related to one of our node attributes (either an input or an output).
            * dataBlock contains the data on which we will base our computations.
        """
        # pylint: disable=no-self-use
        mInput = dataBlock.inputValue(
            DecomposeRowMatrix.inMatrix).asFloatMatrix()
        normalize = dataBlock.inputValue(
            DecomposeRowMatrix.inNormalizeOutput).asBool()

        if plug == DecomposeRowMatrix.outRow1:
            vRow1 = om2.MFloatVector(mInput[0], mInput[1], mInput[2])
            if normalize:
                vRow1.normalize()
            outRow1Handle = dataBlock.outputValue(DecomposeRowMatrix.outRow1)
            outRow1Handle.setMFloatVector(vRow1)
            outRow1Handle.setClean()
        elif plug == DecomposeRowMatrix.outRow2:
            vRow2 = om2.MFloatVector(mInput[4], mInput[5], mInput[6])
            if normalize:
                vRow2.normalize()
            outRow2Handle = dataBlock.outputValue(DecomposeRowMatrix.outRow2)
            outRow2Handle.setMFloatVector(vRow2)
            outRow2Handle.setClean()
        elif plug == DecomposeRowMatrix.outRow3:
            vRow3 = om2.MFloatVector(mInput[8], mInput[9], mInput[10])
            if normalize:
                vRow3.normalize()
            outRow3Handle = dataBlock.outputValue(DecomposeRowMatrix.outRow3)
            outRow3Handle.setMFloatVector(vRow3)
            outRow3Handle.setClean()
        elif plug == DecomposeRowMatrix.outRow4:
            vRow4 = om2.MFloatVector(mInput[12], mInput[13], mInput[14])
            if normalize:
                vRow4.normalize()
            outRow4Handle = dataBlock.outputValue(DecomposeRowMatrix.outRow4)
            outRow4Handle.setMFloatVector(vRow4)
            outRow4Handle.setClean()
        else:
            return om2.kUnknownParameter
Esempio n. 2
0
    def boundingBox(self, objPath, cameraPath):
        """ Return the boundingBox """
        # pylint: disable=unused-argument
        node = objPath.node()
        operation = om2.MPlug(node, DebugVector.inOperation).asShort()
        vVector1 = om2.MPlug(
            node, DebugVector.inVec1).asMDataHandle().asFloatVector()
        vVector2 = om2.MPlug(
            node, DebugVector.inVec2).asMDataHandle().asFloatVector()
        normalize = om2.MPlug(node, DebugVector.inNormalize).asBool()

        if operation == 0:
            vEnd = vVector1
        elif operation == 1:
            vFinal = vVector1 + vVector2
            vEnd = vFinal
        elif operation == 2:
            vFinal = vVector1 - vVector2
            vEnd = vFinal
        elif operation == 3:
            vFinal = vVector1 ^ vVector2
            vEnd = vFinal
        elif operation == 4:
            if vVector2.length() < 0.001:
                vFinal = om2.MFloatVector(0.0, 0.0, 0.0)
            else:
                vFinal = ((vVector1 * vVector2) /
                          math.pow(vVector2.length(), 2.0)) * vVector2
            vEnd = vFinal

        vStart = om2.MFloatVector()
        if normalize:
            vEnd.normalize()

        corner1 = om2.MPoint(vStart.x, vStart.y, vStart.z)
        corner2 = om2.MPoint(vEnd.x, vEnd.y, vEnd.z)

        return om2.MBoundingBox(corner1, corner2)
Esempio n. 3
0
    def compute(self, plug, dataBlock):
        """
        Node computation method:
            * plug is a connection point related to one of our node attributes (either an input or an output).
            * dataBlock contains the data on which we will base our computations.
        """
        # pylint: disable=no-self-use
        euler = dataBlock.inputValue(EulerToVector.inEuler).asDouble3()
        toDegrees = dataBlock.inputValue(EulerToVector.inToDegrees).asBool()

        if toDegrees:
            euler = [angle * (180.0 / math.pi) for angle in euler]
        vVector = om2.MFloatVector(euler)

        outVectorHandle = dataBlock.outputValue(EulerToVector.outVector)
        outVectorHandle.setMFloatVector(vVector)
        outVectorHandle.setClean()
 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 == PoleVectorConstraint.inTargetWMtx:
         thisMob = self.thisMObject()
         restPosPlug = om2.MPlug(thisMob,
                                 PoleVectorConstraint.inRestPosition)
         targetMob = otherPlug.asMObject()
         mtxDataFn = om2.MFnMatrixData(targetMob)
         mTarget = mtxDataFn.matrix()
         vTarget = om2.MFloatVector(mTarget[12], mTarget[13], mTarget[14])
         restPosHdle = restPosPlug.asMDataHandle()
         restPosHdle.setMFloatVector(vTarget)
         restPosPlug.setMDataHandle(restPosHdle)
     return om2.MPxNode.connectionMade(self, plug, otherPlug, asSrc)
    def compute(self, plug, dataBlock):
        """
        Node computation method:
            * plug is a connection point related to one of our node attributes (either an input or an output).
            * dataBlock contains the data on which we will base our computations.
        """
        # pylint: disable=no-self-use
        if plug != PoleVectorConstraint.outConstraint:
            return om2.kUnknownParameter

        mRoot = dataBlock.inputValue(
            PoleVectorConstraint.inRootWMtx).asMatrix()
        mTarget = dataBlock.inputValue(
            PoleVectorConstraint.inTargetWMtx).asMatrix()
        mConstParInv = dataBlock.inputValue(
            PoleVectorConstraint.inConstParInvMtx).asMatrix()
        targetWeight = dataBlock.inputValue(
            PoleVectorConstraint.inTargetWeight).asDouble()
        vRest = om2.MVector(
            dataBlock.inputValue(
                PoleVectorConstraint.inRestPosition).asFloat3())
        normalize = dataBlock.inputValue(
            PoleVectorConstraint.inNormalizeOutput).asBool()

        vRoot = om2.MVector(mRoot[12], mRoot[13], mRoot[14])
        vTarget = om2.MVector(mTarget[12], mTarget[13], mTarget[14])

        vPoleDirection = (vTarget - vRoot) * mConstParInv
        vRestDirection = (vRest - vRoot) * mConstParInv
        vPole = (1.0 -
                 targetWeight) * vRestDirection + targetWeight * vPoleDirection

        vResult = om2.MFloatVector(vPole)
        if normalize:
            vResult.normalize()
        outConstHdle = dataBlock.outputValue(
            PoleVectorConstraint.outConstraint)
        outConstHdle.setMFloatVector(vResult)
        outConstHdle.setClean()
Esempio n. 6
0
    def compute(self, plug, dataBlock):
        """
        Node computation method:
            * plug is a connection point related to one of our node attributes (either an input or an output).
            * dataBlock contains the data on which we will base our computations.
        """
        if plug == DebugVector.outVector:
            operation = dataBlock.inputValue(DebugVector.inOperation).asShort()
            vVector1 = dataBlock.inputValue(DebugVector.inVec1).asFloatVector()
            vVector2 = dataBlock.inputValue(DebugVector.inVec2).asFloatVector()
            normalize = dataBlock.inputValue(DebugVector.inNormalize).asBool()

            if operation == 0:
                vEnd = vVector1
            elif operation == 1:
                vFinal = vVector1 + vVector2
                vEnd = vFinal
            elif operation == 2:
                vFinal = vVector1 - vVector2
                vEnd = vFinal
            elif operation == 3:
                vFinal = vVector1 ^ vVector2
                vEnd = vFinal
            elif operation == 4:
                if vVector2.length() < 0.001:
                    vFinal = om2.MFloatVector(0.0, 0.0, 0.0)
                else:
                    vFinal = ((vVector1 * vVector2) /
                              math.pow(vVector2.length(), 2.0)) * vVector2
                vEnd = vFinal

            if normalize:
                vEnd.normalize()

            outVectorHandle = dataBlock.outputValue(DebugVector.outVector)
            outVectorHandle.setMFloatVector(vEnd)
            outVectorHandle.setClean()
Esempio n. 7
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
        data = oldData
        if not isinstance(data, DebugVectorData):
            data = DebugVectorData()

        node = objPath.node()
        lineW = om2.MPlug(node, DebugVector.inLineWidth).asFloat()
        color = om2.MPlug(node,
                          DebugVector.inColor).asMDataHandle().asFloatVector()
        tipSize = om2.MPlug(node, DebugVector.inTipSize).asFloat()
        subd = om2.MPlug(node, DebugVector.inSubdivisions).asInt()
        radius = om2.MPlug(node, DebugVector.inRadius).asFloat()
        xray = om2.MPlug(node, DebugVector.inXRay).asBool()
        dashed = om2.MPlug(node, DebugVector.inDashed).asBool()
        operation = om2.MPlug(node, DebugVector.inOperation).asShort()
        vVector1 = om2.MPlug(
            node, DebugVector.inVec1).asMDataHandle().asFloatVector()
        vVector2 = om2.MPlug(
            node, DebugVector.inVec2).asMDataHandle().asFloatVector()
        normalize = om2.MPlug(node, DebugVector.inNormalize).asBool()

        data.fDormantColor = om2.MColor([color.x, color.y, color.z])
        data.fActiveColor = om2.MColor([0.3, 1.0, 1.0])
        data.fLeadColor = om2.MColor([1.0, 1.0, 1.0])
        data.fLineWidth = lineW
        data.fTipSize = tipSize
        data.fSubd = subd
        data.fRadius = radius
        data.fXRay = xray
        data.fDashed = dashed
        data.fOperation = operation

        if operation == 0:
            vEnd = vVector1
        elif operation == 1:
            vFinal = vVector1 + vVector2
            vEnd = vFinal
        elif operation == 2:
            vFinal = vVector1 - vVector2
            vEnd = vFinal
        elif operation == 3:
            vFinal = vVector1 ^ vVector2
            vEnd = vFinal
        elif operation == 4:
            if vVector2.length() < 0.001:
                vFinal = om2.MFloatVector(0.0, 0.0, 0.0)
            else:
                vFinal = ((vVector1 * vVector2) /
                          math.pow(vVector2.length(), 2.0)) * vVector2
            vEnd = vFinal

        vStart = om2.MFloatVector()
        if normalize:
            vEnd.normalize()

        data.fLineList.clear()
        DebugVector.drawArrow(vStart,
                              vEnd,
                              tipSize,
                              radius,
                              subd,
                              lineW,
                              vp2=True,
                              lineList=data.fLineList)

        return data
Esempio n. 8
0
    def draw(self, view, path, style, status):
        """
        Draw custom geometry in the viewport using OpenGL calls.
            * view [M3dView] is a 3D view that is being drawn into.
            * path [MDagPath] to the parent (transform node) of this locator in the DAG.  To obtain the locator shape node,
                use MDagPath::extendToShape() if there is only one shape node under the transform or
                MDagPath::extendToShapeDirectlyBelow(unsigned int index) with the shape index if there are multiple
                shapes under the transform.
            * style [M3dView.DisplayStyle] is the style to draw object in.
            * status [M3dView.DisplayStatus] is the selection status of the object.
        """
        # pylint: disable=unused-argument

        thisMob = self.thisMObject()
        lineW = om2.MPlug(thisMob, DebugVector.inLineWidth).asFloat()
        color = om2.MPlug(thisMob,
                          DebugVector.inColor).asMDataHandle().asFloatVector()
        tipSize = om2.MPlug(thisMob, DebugVector.inTipSize).asFloat()
        subd = om2.MPlug(thisMob, DebugVector.inSubdivisions).asInt()
        radius = om2.MPlug(thisMob, DebugVector.inRadius).asFloat()
        xray = om2.MPlug(thisMob, DebugVector.inXRay).asBool()
        dashed = om2.MPlug(thisMob, DebugVector.inDashed).asBool()

        operation = om2.MPlug(thisMob, DebugVector.inOperation).asShort()
        vVector1 = om2.MPlug(
            thisMob, DebugVector.inVec1).asMDataHandle().asFloatVector()
        vVector2 = om2.MPlug(
            thisMob, DebugVector.inVec2).asMDataHandle().asFloatVector()
        normalize = om2.MPlug(thisMob, DebugVector.inNormalize).asBool()

        if operation == 0:
            vEnd = vVector1
        elif operation == 1:
            vFinal = vVector1 + vVector2
            vEnd = vFinal
        elif operation == 2:
            vFinal = vVector1 - vVector2
            vEnd = vFinal
        elif operation == 3:
            vFinal = vVector1 ^ vVector2
            vEnd = vFinal
        elif operation == 4:
            if vVector2.length() < 0.001:
                vFinal = om2.MFloatVector(0.0, 0.0, 0.0)
            else:
                vFinal = ((vVector1 * vVector2) /
                          math.pow(vVector2.length(), 2.0)) * vVector2
            vEnd = vFinal

        vStart = om2.MFloatVector()
        if normalize:
            vEnd.normalize()

        view.beginGL()

        glRenderer = omr1.MHardwareRenderer.theRenderer()
        glFT = glRenderer.glFunctionTable()

        glFT.glPushAttrib(omr1.MGL_CURRENT_BIT)
        glFT.glDisable(omr1.MGL_CULL_FACE)
        if dashed:
            glFT.glEnable(omr1.MGL_LINE_STIPPLE)
        if xray:
            glFT.glEnable(omr1.MGL_DEPTH_TEST)
            glFT.glClear(omr1.MGL_DEPTH_BUFFER_BIT)

        if status == omui2.M3dView.kActive:
            glFT.glColor3f(0.3, 1.0, 1.0)
        elif status == omui2.M3dView.kLead:
            glFT.glColor3f(1.0, 1.0, 1.0)
        elif status == omui2.M3dView.kDormant:
            glFT.glColor3f(color.x, color.y, color.z)

        if dashed:
            glFT.glLineStipple(1, 0x00FF)
        DebugVector.drawArrow(vStart,
                              vEnd,
                              tipSize,
                              radius,
                              subd,
                              lineW,
                              glFT=glFT)

        if dashed:
            glFT.glDisable(omr1.MGL_LINE_STIPPLE)
        if xray:
            glFT.glDisable(omr1.MGL_DEPTH_TEST)
        glFT.glPopAttrib()
        glFT.glLineWidth(1.0)

        view.endGL()
Esempio n. 9
0
    def drawArrow(startPnt,
                  endPnt,
                  size,
                  radius,
                  subd,
                  lineW,
                  vp2=False,
                  glFT=None,
                  lineList=None):
        """Draw an aim arrow

        Args:
            startPnt (MFloatVector): The base of the vector.
            endPnt (MFloatVector): The end of the vector.
            size (float): The size of the arrow.
            radius (float): The radius of the arrow.
            subd (int): The number of subdivisions of the arrow.
            lineW (float): The width of the lines.
            vp2 (bool: False [Optional]): Draw inside of drawing override for viewport 2.0.
            glFT (instance: None [Optional]): The GL Function Table to draw in viewport 1.0.
            lineList (MPointArray: None [Optional]): The line list to append for drawing override.
        """
        tipSize = 1.0 - size
        step = 2.0 * math.pi / subd
        vAim = endPnt - startPnt
        vBaseOrigin = vAim * tipSize
        nAim = vAim.normal()
        nWorld = om2.MFloatVector(0.0, 1.0, 0.0)
        nBinormal = nWorld ^ nAim
        nBinormal.normalize()
        nNormal = nAim ^ nBinormal
        nNormal.normalize()
        aim = [
            nAim.x, nAim.y, nAim.z, 0.0, nNormal.x, nNormal.y, nNormal.z, 0.0,
            nBinormal.x, nBinormal.y, nBinormal.z, 0.0, startPnt.x, startPnt.y,
            startPnt.z, 1.0
        ]
        mBase = om2.MMatrix(aim)
        mOrigin = om2.MMatrix()
        mOrigin[12] = vBaseOrigin.length()
        mBaseOrigin = mOrigin * mBase
        if vp2:
            lineList.append(om2.MPoint(startPnt))
            lineList.append(om2.MPoint(endPnt))
        else:
            glFT.glLineWidth(lineW)
            glFT.glBegin(omr1.MGL_LINES)
            glFT.glVertex3f(startPnt.x, startPnt.y, startPnt.z)
            glFT.glVertex3f(endPnt.x, endPnt.y, endPnt.z)
            glFT.glEnd()
        for i in range(subd):
            theta = step * i
            mPoint = om2.MMatrix()
            mPoint[13] = math.cos(theta) * radius
            mPoint[14] = math.sin(theta) * radius
            mArrow = mPoint * mBaseOrigin
            if vp2:
                lineList.append(
                    om2.MPoint(mBaseOrigin[12], mBaseOrigin[13],
                               mBaseOrigin[14]))
                lineList.append(om2.MPoint(mArrow[12], mArrow[13], mArrow[14]))
                lineList.append(om2.MPoint(mArrow[12], mArrow[13], mArrow[14]))
                lineList.append(om2.MPoint(endPnt))
            else:
                glFT.glBegin(omr1.MGL_LINES)
                glFT.glVertex3f(mBaseOrigin[12], mBaseOrigin[13],
                                mBaseOrigin[14])
                glFT.glVertex3f(mArrow[12], mArrow[13], mArrow[14])
                glFT.glVertex3f(mArrow[12], mArrow[13], mArrow[14])
                glFT.glVertex3f(endPnt.x, endPnt.y, endPnt.z)
                glFT.glEnd()
        return None
Esempio n. 10
0
    def compute(self, plug, dataBlock):
        """
        Node computation method:
            * plug is a connection point related to one of our node attributes (either an input or an output).
            * dataBlock contains the data on which we will base our computations.
        """
        # pylint: disable=R0201
        blender = dataBlock.inputValue(BlendTransform.inBlender).asFloat()
        if plug == BlendTransform.outTrans:
            trans1Handle = dataBlock.inputArrayValue(BlendTransform.inTrans1)
            trans2Handle = dataBlock.inputArrayValue(BlendTransform.inTrans2)
            outTransHandle = dataBlock.outputArrayValue(
                BlendTransform.outTrans)
            outList = []
            for i in range(min(len(trans1Handle), len(trans2Handle))):
                trans1Handle.jumpToLogicalElement(i)
                trans2Handle.jumpToLogicalElement(i)
                vTrans1 = trans1Handle.inputValue().asFloatVector()
                vTrans2 = trans2Handle.inputValue().asFloatVector()
                vOut = (1.0 - blender) * vTrans1 + blender * vTrans2
                outList.append(vOut)
            for i in range(len(outTransHandle)):
                outTransHandle.jumpToLogicalElement(i)
                resultHandle = outTransHandle.outputValue()
                if i < len(outTransHandle) and i < len(outList):
                    resultHandle.setMFloatVector(outList[i])
                else:
                    resultHandle.setMFloatVector(om2.MFloatVector())
            outTransHandle.setAllClean()

        elif plug == BlendTransform.outRot:
            rotInterp = dataBlock.inputValue(
                BlendTransform.inRotInterp).asShort()
            rot1Handle = dataBlock.inputArrayValue(BlendTransform.inRot1)
            rot2Handle = dataBlock.inputArrayValue(BlendTransform.inRot2)
            outRotHandle = dataBlock.outputArrayValue(BlendTransform.outRot)
            rotOrder1Handle = dataBlock.inputArrayValue(
                BlendTransform.inRot1Order)
            rotOrder2Handle = dataBlock.inputArrayValue(
                BlendTransform.inRot2Order)
            outRotOrderHandle = dataBlock.inputArrayValue(
                BlendTransform.inOutRotOrder)
            outList = []
            for i in range(min(len(rot1Handle), len(rot2Handle))):
                rot1Handle.jumpToLogicalElement(i)
                rot2Handle.jumpToLogicalElement(i)
                rotOrder1 = BlendTransform.checkRotateOrderArrayHandle(
                    rotOrder1Handle, i)
                rotOrder2 = BlendTransform.checkRotateOrderArrayHandle(
                    rotOrder2Handle, i)
                outRotOrder = BlendTransform.checkRotateOrderArrayHandle(
                    outRotOrderHandle, i)
                rot1 = rot1Handle.inputValue().asVector()
                rot2 = rot2Handle.inputValue().asVector()
                eRot1 = om2.MEulerRotation(rot1, rotOrder1)
                eRot2 = om2.MEulerRotation(rot2, rotOrder2)
                eRot1.reorderIt(outRotOrder)
                eRot2.reorderIt(outRotOrder)
                if rotInterp == 0:
                    vRot1 = eRot1.asVector()
                    vRot2 = eRot2.asVector()
                    vOut = (1.0 - blender) * vRot1 + blender * vRot2
                else:
                    qRot1 = eRot1.asQuaternion()
                    qRot2 = eRot2.asQuaternion()
                    eSlerp = om2.MQuaternion.slerp(qRot1, qRot2,
                                                   blender).asEulerRotation()
                    eSlerp.reorderIt(outRotOrder)
                    vOut = eSlerp.asVector()
                outList.append(vOut)
            for i in range(len(outRotHandle)):
                outRotHandle.jumpToLogicalElement(i)
                resultHandle = outRotHandle.outputValue()
                if i < len(outRotHandle) and i < len(outList):
                    resultHandle.setMVector(outList[i])
                else:
                    resultHandle.setMVector(om2.MVector())
            outRotHandle.setAllClean()

        elif plug == BlendTransform.outSca:
            sca1Handle = dataBlock.inputArrayValue(BlendTransform.inSca1)
            sca2Handle = dataBlock.inputArrayValue(BlendTransform.inSca2)
            outScaHandle = dataBlock.outputArrayValue(BlendTransform.outSca)
            outList = []
            for i in range(min(len(sca1Handle), len(sca2Handle))):
                sca1Handle.jumpToLogicalElement(i)
                sca2Handle.jumpToLogicalElement(i)
                vSca1 = sca1Handle.inputValue().asFloatVector()
                vSca2 = sca2Handle.inputValue().asFloatVector()
                vOut = (1.0 - blender) * vSca1 + blender * vSca2
                outList.append(vOut)
            for i in range(len(outScaHandle)):
                outScaHandle.jumpToLogicalElement(i)
                resultHandle = outScaHandle.outputValue()
                if i < len(outScaHandle) and i < len(outList):
                    resultHandle.setMFloatVector(outList[i])
                else:
                    resultHandle.setMFloatVector(om2.MFloatVector())
            outScaHandle.setAllClean()

        elif plug in (BlendTransform.outVis, BlendTransform.outRevVis):
            outVisHandle = dataBlock.outputValue(BlendTransform.outVis)
            outRevVisHandle = dataBlock.outputValue(BlendTransform.outRevVis)
            vis, revVis = BlendTransform.visibilityCalculation(blender)
            outVisHandle.setBool(vis)
            outRevVisHandle.setBool(revVis)
            outVisHandle.setClean()
            outRevVisHandle.setClean()
Esempio n. 11
0
    def compute(self, plug, dataBlock):
        """
        Node computation method:
            * plug is a connection point related to one of our node attributes (either an input or an output).
            * dataBlock contains the data on which we will base our computations.
        """
        # pylint: disable=no-self-use
        # if not dataBlock.isClean(SpaceConstraint.inSpace):
        #     om2.MGlobal.displayInfo("\tSpace attribute is dirty.")
        #     om2.MUserEventMessage.postUserEvent("preCompute", self)

        curSpace = dataBlock.inputValue(SpaceConstraint.inSpace).asShort()

        offsetMatchHdle = dataBlock.inputArrayValue(
            SpaceConstraint.inOffsetMatches)
        offsetHdle = dataBlock.inputArrayValue(SpaceConstraint.inOffset)
        targetHdle = dataBlock.inputArrayValue(SpaceConstraint.inTarget)
        offsetMatchList = []
        offsetList = []
        targetList = []

        for i in range(len(offsetMatchHdle)):
            offsetMatchHdle.jumpToLogicalElement(i)
            mOffMatch = offsetMatchHdle.inputValue().asMatrix()
            offsetMatchList.append(mOffMatch)

        for i in range(len(offsetHdle)):
            offsetHdle.jumpToLogicalElement(i)
            mOff = offsetHdle.inputValue().asMatrix()
            offsetList.append(mOff)

        for i in range(len(targetHdle)):
            targetHdle.jumpToLogicalElement(i)
            mTgt = targetHdle.inputValue().asMatrix()
            targetList.append(mTgt)

        if len(offsetList) == 0 or len(targetList) == 0:
            mResult = om2.MMatrix()
        else:
            minRequired = min(len(offsetList), len(targetList)) - 1
            if curSpace > minRequired:
                curSpace = minRequired
            mResult = offsetMatchList[curSpace] * offsetList[
                curSpace] * targetList[curSpace]

        mtxFn = om2.MTransformationMatrix(mResult)

        if plug == SpaceConstraint.outConstTrans:
            vTransD = om2.MVector(mResult[12], mResult[13], mResult[14])
            vTrans = om2.MFloatVector(vTransD)
            outTransHdle = dataBlock.outputValue(SpaceConstraint.outConstTrans)
            outTransHdle.setMFloatVector(vTrans)
            outTransHdle.setClean()

        if plug == SpaceConstraint.outConstRot:
            eRot = mtxFn.rotation(asQuaternion=False)
            outRotHdle = dataBlock.outputValue(SpaceConstraint.outConstRot)
            outRotHdle.setMVector(eRot.asVector())
            outRotHdle.setClean()

        if plug == SpaceConstraint.outConstSca:
            outSca = mtxFn.scale(om2.MSpace.kWorld)
            outScaHdle = dataBlock.outputValue(SpaceConstraint.outConstSca)
            outScaHdle.set3Float(outSca[0], outSca[1], outSca[2])
            outScaHdle.setClean()
    def compute(self, plug, dataBlock):
        """
        Node computation method:
            * plug is a connection point related to one of our node attributes (either an input or an output).
            * dataBlock contains the data on which we will base our computations.
        """
        # pylint: disable=R0201
        if plug != VectorAnglePSD.outWeights:
            return om2.kUnknownParameter

        mBase = dataBlock.inputValue(VectorAnglePSD.inBase).asFloatMatrix()
        mSource = dataBlock.inputValue(VectorAnglePSD.inSource).asFloatMatrix()

        targetHandle = dataBlock.inputArrayValue(VectorAnglePSD.inTarget)
        targetEnvelopeHandle = dataBlock.inputArrayValue(
            VectorAnglePSD.inTargetEnvelope)
        targetFalloffHandle = dataBlock.inputArrayValue(
            VectorAnglePSD.inTargetFalloff)
        outWeightsHandle = dataBlock.outputArrayValue(
            VectorAnglePSD.outWeights)

        vBase = om2.MFloatVector(mBase[12], mBase[13], mBase[14])
        vSource = om2.MFloatVector(mSource[12], mSource[13], mSource[14])

        vCurPose = vSource - vBase
        nCurPose = vCurPose.normal()

        targetList = []
        envelopeList = []
        falloffList = []

        for i in range(len(targetHandle)):
            targetHandle.jumpToLogicalElement(i)
            mtx = targetHandle.inputValue().asFloatMatrix()
            vec = om2.MFloatVector(mtx[12], mtx[13], mtx[14])
            vTargetPose = vec - vBase
            nTargetPose = vTargetPose.normal()
            targetList.append(nTargetPose)

        for i in range(len(targetEnvelopeHandle)):
            targetEnvelopeHandle.jumpToLogicalElement(i)
            env = targetEnvelopeHandle.inputValue().asFloat()
            envelopeList.append(env)

        for i in range(len(targetFalloffHandle)):
            targetFalloffHandle.jumpToLogicalElement(i)
            fall = targetFalloffHandle.inputValue().asFloat()
            falloffList.append(fall)

        for i in range(len(outWeightsHandle)):
            outWeightsHandle.jumpToLogicalElement(i)
            resultHandle = outWeightsHandle.outputValue()
            if (i < len(outWeightsHandle) and i < len(targetHandle)
                    and i < len(targetEnvelopeHandle)
                    and i < len(targetFalloffHandle)):
                theta = math.acos(targetList[i] * nCurPose)
                ratio = min(max(theta / math.radians(falloffList[i]), -1.0),
                            1.0)
                if ratio == 0.0:
                    weight = envelopeList[i] * 1.0
                elif ratio > 0.0:
                    weight = envelopeList[i] * (1.0 - ratio)
                elif ratio < 0.0:
                    weight = envelopeList[i] * (1.0 + ratio)

                thisMob = self.thisMObject()
                rampAttr = om2.MRampAttribute(thisMob,
                                              VectorAnglePSD.inRampWeights)
                resultWeight = rampAttr.getValueAtPosition(weight)
                resultHandle.setFloat(resultWeight)
            else:
                resultHandle.setFloat(0.0)
    def compute(self, plug, dataBlock):
        """
        Node computation method:
            * plug is a connection point related to one of our node attributes (either an input or an output).
            * dataBlock contains the data on which we will base our computations.
        """
        # pylint: disable=no-self-use
        eConstJntOri = om2.MEulerRotation(
            dataBlock.inputValue(
                ParentConstraint.inConstraintJntOri).asDouble3())
        mConstParInv = dataBlock.inputValue(
            ParentConstraint.inConstraintParInvMtx).asMatrix()
        constRotOrder = dataBlock.inputValue(
            ParentConstraint.inConstraintRotOrder).asShort()
        constParSca = dataBlock.inputValue(
            ParentConstraint.inConstraintParSca).asFloat3()
        targetListHandle = dataBlock.inputArrayValue(
            ParentConstraint.inTargetList)
        mTargetsAdded = om2.MMatrix()
        mtxFn = om2.MTransformationMatrix()
        mtxFn.scaleBy(constParSca, om2.MSpace.kTransform)
        mInvSca = mtxFn.asMatrix()

        for i in range(len(targetListHandle)):
            targetListHandle.jumpToLogicalElement(i)
            targetHandle = targetListHandle.inputValue()
            # targetJntOri = om2.MEulerRotation(targetHandle.child(ParentConstraint.inTargetJntOri).asDouble3())
            # targetRotOrder = targetHandle.child(ParentConstraint.inTargetRotOrder).asShort()
            mTargetW = targetHandle.child(
                ParentConstraint.inTargetWorldMatrix).asMatrix()
            mOffset = targetHandle.child(
                ParentConstraint.inTargetOffset).asMatrix()
            targetWeight = targetHandle.child(
                ParentConstraint.inTargetWeight).asFloat()

            mTarget = mOffset * (mTargetW * targetWeight)
            if mTargetsAdded == om2.MMatrix():
                mTargetsAdded = mTarget
            else:
                mTargetsAdded += mTarget

        mResult = mTargetsAdded * mConstParInv * mInvSca

        if plug == ParentConstraint.outConstTrans:
            outTransHandle = dataBlock.outputValue(
                ParentConstraint.outConstTrans)
            outTrans = om2.MFloatVector(mResult[12], mResult[13], mResult[14])
            outTransHandle.setMFloatVector(outTrans)
            outTransHandle.setClean()
        if plug == ParentConstraint.outConstRot:
            outRotHandle = dataBlock.outputValue(ParentConstraint.outConstRot)
            mtxFn = om2.MTransformationMatrix(mResult)
            eRotMtx = mtxFn.rotation(asQuaternion=False)
            qRotMtx = eRotMtx.asQuaternion()
            qConstJntOri = eConstJntOri.asQuaternion()
            qOutRot = qRotMtx * qConstJntOri.invertIt()
            outRot = qOutRot.asEulerRotation().reorderIt(constRotOrder)
            outRotHandle.setMVector(outRot.asVector())
            outRotHandle.setClean()
        if plug == ParentConstraint.outConstSca:
            outScaHandle = dataBlock.outputValue(ParentConstraint.outConstSca)
            mtxFn = om2.MTransformationMatrix(mResult)
            outSca = mtxFn.scale(om2.MSpace.kWorld)
            outScaHandle.set3Float(outSca[0], outSca[1], outSca[2])
            outScaHandle.setClean()