Beispiel #1
0
    def __init__(self, position=None, color=None, size=2):
        super(PointPrim, self).__init__()

        position = om2.MVector() if position is None else om2.MVector(position)
        self.transform.setTranslation(position, om2.MSpace.kWorld)
        # `color` as a tuple of floats representing RGB values (normalized).
        self.color = color or COLOR_BLACK
        self.size = size
Beispiel #2
0
def linearInterpolate(t, p0, p1):
    """
    Performs a linear interpolation between p0 and p1.
    """
    if _isIterable(p0):
        p0 = om2.MVector(p0)
        p1 = om2.MVector(p1)
    return p0 + ((p1 - p0) * t)
Beispiel #3
0
    def update(self):
        super(VectorPrim, self).update()
        # update the line along the length of the vector
        self.body.color = self.color
        self.body.transform = self.transform
        self.body.transform.setScale((self.size, self.size, self.size),
                                     om2.MSpace.kWorld)
        self.body.update()

        # update the header of the vector (arrow)
        self.head.color = self.color
        self.head.transform = self.body.transform
        m_vector = om2.MVector(self.body._drawPoints[1])
        m_vector -= self.transform.translation(om2.MSpace.kWorld)
        m_vectorX = om2.MVector(1, 0, 0)
        m_rot = m_vectorX.rotateTo(m_vector)
        self.head.transform.setRotation(m_rot)
Beispiel #4
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()
        size = om2.MPlug(thisMob, TestLocator.inSize).asDouble()

        view.beginGL()

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

        glFT.glPushAttrib(omr1.MGL_CURRENT_BIT)
        glFT.glDisable(omr1.MGL_CULL_FACE)

        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(1.0, 1.0, 0.0)

        vPoint1 = om2.MVector(1.0, 0.0, -1.0) * size
        vPoint2 = om2.MVector(-1.0, 0.0, -1.0) * size
        vPoint3 = om2.MVector(-1.0, 0.0, 1.0) * size
        vPoint4 = om2.MVector(1.0, 0.0, 1.0) * size

        glFT.glBegin(omr1.MGL_QUADS)
        glFT.glVertex3f(vPoint1.x, vPoint1.y, vPoint1.z)
        glFT.glVertex3f(vPoint2.x, vPoint2.y, vPoint2.z)
        glFT.glVertex3f(vPoint3.x, vPoint3.y, vPoint3.z)
        glFT.glVertex3f(vPoint4.x, vPoint4.y, vPoint4.z)
        glFT.glEnd()

        glFT.glPopAttrib()

        view.endGL()
Beispiel #5
0
def pointsAlongVector( start='', end='', divisions=2, bias=0 ):
    '''
    returns a list of points that lie on a line between start and end
    'divisions' specifies the number of points to return.
    divisions = 2 (default) will return the start and end points with one intermediate point: [ p1(start), p2, p3(end) ]

    start and end can be supplied as lists, tuples or nodes. If they are not supplied, and 2 scene nodes are selected
    will attempt to use their world space positions as start and end

    creates a vector by subtracting end from start
    stores length of vector
    normalizes vector
    multiplies normalized vector by length / divisions

    bias specifies weight of point distribution towards start or end. Positive values favour end, negative favour start
    '''
    startPos, endPos = getStartAndEnd(start, end)

    if not startPos or not endPos:
        return 'pointsAlongVector: Cannot determine start and end points'

    startVec = om2.MVector(startPos[0], startPos[1], startPos[2])
    endVec = om2.MVector(endPos[0], endPos[1], endPos[2])
    newVec = endVec - startVec
    segLength = (newVec.length() / divisions) / newVec.length()
    #newVec.normalize()
    points = []
    points.append(tuple(startPos))

    segLengths = [segLength * each for each in range(divisions)]
    if bias:
        for i in range(divisions):
            #paramVals[i] - pow(paramVals[i], 1 + bias)
            segLengths[i] += segLengths[i] - pow(segLengths[i], 1 + bias)

    for p in range( 1, divisions ):
        point = (newVec * segLengths[p]) + startVec
        points.append((point.x, point.y, point.z))

    points.append(tuple(endPos))

    return points
    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()
Beispiel #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, TestLocatorData):
            data = TestLocatorData()

        node = objPath.node()
        size = om2.MPlug(node, TestLocator.inSize).asDouble()

        data.fDormantColor = om2.MColor([1.0, 1.0, 0.0])
        data.fActiveColor = om2.MColor([0.3, 1.0, 1.0])
        data.fLeadColor = om2.MColor([1.0, 1.0, 1.0])

        data.fSize = size

        vPoint1 = om2.MVector(1.0, 0.0, -1.0) * size
        vPoint2 = om2.MVector(-1.0, 0.0, -1.0) * size
        vPoint3 = om2.MVector(-1.0, 0.0, 1.0) * size
        vPoint4 = om2.MVector(1.0, 0.0, 1.0) * size

        data.fQuadList.clear()
        data.fQuadList.append(om2.MPoint(vPoint1))
        data.fQuadList.append(om2.MPoint(vPoint2))
        data.fQuadList.append(om2.MPoint(vPoint3))
        data.fQuadList.append(om2.MPoint(vPoint4))
        data.fQuadList.append(om2.MPoint(vPoint1))

        return data
Beispiel #8
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
        vector = dataBlock.inputValue(VectorToEuler.inVector).asFloat3()
        vVector = om2.MVector([unit * (math.pi / 180.0) for unit in vector])

        eEuler = om2.MEulerRotation(vVector)

        outEulerHandle = dataBlock.outputValue(VectorToEuler.outEuler)
        outEulerHandle.set3Double(eEuler.x, eEuler.y, eEuler.z)
        outEulerHandle.setClean()
Beispiel #9
0
    def __init__(self, vector, size=1.0, color=None):
        super(VectorPrim, self).__init__()
        self._size = size
        self.color = color or COLOR_BLACK

        # body line
        _points = ((0, 0, 0), vector)
        self.body = CurvePrim(_points, color=self.color)
        self.body.scale(self.size, self.size, self.size)

        # head line
        m_vector = om2.MVector(*vector)
        length = m_vector.length()
        headSize = 0.1 * length
        points = ((length - headSize, headSize, 0.0), (length, 0.0, 0.0),
                  (length - headSize, -headSize, 0.0))
        self.head = CurvePrim(points, color=self.color)
        self.isDirty = True  # force to re-orient header
Beispiel #10
0
def bezierInterpolate(t, points):
    """
    Performs a bezier interpolation (recursive).
    """
    if not _isIterable(points):
        logger.error('Points is expected to be a secuence of points')
        return
    n = len(points) - 1
    n_factorial = math.factorial(n)
    for i, p in enumerate(points):
        if not isinstance(p, om2.MVector):
            p = om2.MVector(p)
        k = n_factorial / float(math.factorial(i) * math.factorial(n - i))
        b = (t**i) * (1 - t)**(n - i)
        v = p * b * k
        if i == 0:
            rval = v
        else:
            rval += v
    return rval
Beispiel #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
        ctrlPntsHandle = dataBlock.inputArrayValue(
            QuadraticCurve.inControlPoints)
        ctrlPnts = om2.MPointArray()

        if len(ctrlPntsHandle) < 3:
            return

        for i in range(3):
            ctrlPntsHandle.jumpToLogicalElement(i)
            mCtrlPnt = ctrlPntsHandle.inputValue().asMatrix()
            ctrlPnt = om2.MPoint(mCtrlPnt[12], mCtrlPnt[13], mCtrlPnt[14])
            ctrlPnts.append(ctrlPnt)

        crvKnots = om2.MDoubleArray([0, 0, 1, 1])
        crvDegree = 2
        crvForm = om2.MFnNurbsCurve.kOpen
        crvIs2d = False
        crvRational = False
        crvData = om2.MFnNurbsCurveData().create()
        crvFn = om2.MFnNurbsCurve(crvData)

        crvFn.create(ctrlPnts, crvKnots, crvDegree, crvForm, crvIs2d,
                     crvRational, crvData)
        crvFn.updateCurve()

        if plug == QuadraticCurve.outCurve:
            outCurveHandle = dataBlock.outputValue(QuadraticCurve.outCurve)
            outCurveHandle.setMObject(crvData)
            outCurveHandle.setClean()

        elif plug == QuadraticCurve.outTransforms:
            outTransHandle = dataBlock.outputArrayValue(
                QuadraticCurve.outTransforms)
            lockLength = dataBlock.inputValue(
                QuadraticCurve.inLockLength).asFloat()
            restLength = dataBlock.inputValue(
                QuadraticCurve.inRestLength).asFloat()
            slide = dataBlock.inputValue(QuadraticCurve.inSlide).asFloat()
            numOutputs = len(outTransHandle)
            crvLength = crvFn.length()
            parRejected = crvFn.findParamFromLength(crvLength - restLength)
            stepFull = 1.0 / (numOutputs - 1) if numOutputs > 1 else 0.0
            stepLock = crvFn.findParamFromLength(restLength) / (
                numOutputs - 1) if numOutputs > 1 else 0.0
            step = (1.0 - lockLength) * stepFull + lockLength * stepLock
            parSlide = parRejected * slide * lockLength
            for i in range(numOutputs):
                parameter = (step * i)  # + parSlide
                pos = crvFn.getPointAtParam(parameter, om2.MSpace.kObject)
                vPos = om2.MVector(pos.x, pos.y, pos.z)
                mtx = [
                    1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
                    vPos.x, vPos.y, vPos.z, 1.0
                ]
                mOut = om2.MMatrix(mtx)
                outTransHandle.jumpToLogicalElement(i)
                resultHandle = outTransHandle.outputValue()
                resultHandle.setMMatrix(mOut)
            outTransHandle.setAllClean()

        else:
            return om2.kUnknownParameter
Beispiel #12
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.
        """
        rotation = dataBlock.inputValue(TwistExtractor.inRotation).asDouble3()
        rotOrder = dataBlock.inputValue(
            TwistExtractor.inRotationOrder).asShort()
        eRoll = om2.MEulerRotation(rotation, rotOrder)
        useUpObj = dataBlock.inputValue(TwistExtractor.inUseUpVec).asBool()
        revTwist = dataBlock.inputValue(TwistExtractor.inInvTwist).asBool()

        # Non flip ROO = XYZ
        # Not working = XZY
        twistOrder = om2.MEulerRotation.kXYZ
        eRoll.reorderIt(twistOrder)

        # Non-Roll orientation
        mtxFn = om2.MTransformationMatrix()
        mtxFn.rotateBy(eRoll, om2.MSpace.kWorld)
        mRoll = mtxFn.asMatrix()

        qNonRoll = om2.MQuaternion()

        nAim = om2.MVector(mRoll[0], mRoll[1], mRoll[2])
        nAim.normalize()
        nAimAxis = om2.MVector.kXaxisVector
        qAim = om2.MQuaternion(nAimAxis, nAim)
        qNonRoll *= qAim

        if useUpObj:
            vUp = om2.MVector(
                dataBlock.inputValue(TwistExtractor.inUpVec).asFloat3())
            nNormal = vUp - ((vUp * nAim) * nAim)
            nNormal.normalize()
            nUp = om2.MVector.kYaxisVector.rotateBy(qAim)
            angle = nUp.angle(nNormal)
            qNormal = om2.MQuaternion(angle, nAim)
            if not nNormal.isEquivalent(nUp.rotateBy(qNormal), 1.0e-5):
                angle = 2.0 * kPI - angle
                qNormal = om2.MQuaternion(angle, nAim)
            qNonRoll *= qNormal
        eNonRoll = qNonRoll.asEulerRotation()
        eNonRoll = om2.MEulerRotation(eNonRoll.x, eNonRoll.y, eNonRoll.z,
                                      twistOrder)

        # Extract Twist from orientations
        qRoll = eRoll.asQuaternion()
        qExtract180 = qNonRoll * qRoll.inverse()
        eExtract180 = qExtract180.asEulerRotation()
        twist = -eExtract180.x
        if revTwist:
            twist *= -1.0

        # Output Twist
        if plug == TwistExtractor.outTwist:
            outTwistHdle = dataBlock.outputValue(TwistExtractor.outTwist)
            outTwistHdle.setMAngle(om2.MAngle(twist))
            outTwistHdle.setClean()

        # Output Twist Distribution
        if plug == TwistExtractor.outTwistDist:
            invDist = dataBlock.inputValue(TwistExtractor.inRevDist).asBool()
            outTwistDistHdle = dataBlock.outputArrayValue(
                TwistExtractor.outTwistDist)
            outputs = len(outTwistDistHdle)
            step = twist / (outputs - 1) if outputs > 1 else twist
            outList = []
            outList.extend(range(outputs))
            if not invDist:
                outList.reverse()
            # pylint: disable=consider-using-enumerate
            for i in range(len(outList)):
                outTwistDistHdle.jumpToLogicalElement(i)
                resultHdle = outTwistDistHdle.outputValue()
                result = step * outList[i] if outputs > 1 else twist
                resultHdle.setMAngle(om2.MAngle(result))
            outTwistDistHdle.setAllClean()

        return
Beispiel #13
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 != IKVChainSolver.outChain:
            return om2.kUnknownParameter

        # Get Basis Quaternion
        mRoot = dataBlock.inputValue(IKVChainSolver.inRoot).asMatrix()
        mHandle = dataBlock.inputValue(IKVChainSolver.inHandle).asMatrix()
        mPoleVector = dataBlock.inputValue(
            IKVChainSolver.inPoleVector).asMatrix()
        pvMode = dataBlock.inputValue(IKVChainSolver.inPvMode).asShort()
        prefAngle = dataBlock.inputValue(
            IKVChainSolver.inPreferredAngle).asAngle().asRadians()
        twist = dataBlock.inputValue(
            IKVChainSolver.inTwist).asAngle().asRadians()
        snap = dataBlock.inputValue(IKVChainSolver.inSnapUpVector).asFloat()
        mSnap = dataBlock.inputValue(IKVChainSolver.inSnap).asMatrix()
        flip = dataBlock.inputValue(IKVChainSolver.inFlip).asBool()

        vRoot = om2.MVector(mRoot[12], mRoot[13], mRoot[14])
        vHandle = om2.MVector(mHandle[12], mHandle[13], mHandle[14])
        vPoleVector = om2.MVector(mPoleVector[12], mPoleVector[13],
                                  mPoleVector[14])
        vSnap = om2.MVector(mSnap[12], mSnap[13], mSnap[14])

        primAxis = om2.MVector.kXaxisVector
        secAxis = om2.MVector.kYaxisVector
        if flip:
            primAxis = -om2.MVector.kXaxisVector
            secAxis = -om2.MVector.kYaxisVector
        binAxis = primAxis ^ secAxis
        qBasis = om2.MQuaternion()

        vAim = vHandle - vRoot
        nAim = vAim.normal()
        qAim = om2.MQuaternion(primAxis, nAim)
        qBasis *= qAim

        vStartSnap = vSnap - vRoot
        vEndSnap = vSnap - vHandle

        if pvMode == 0:
            vUp = vPoleVector - vRoot
        else:
            qTwist = om2.MQuaternion(prefAngle + twist, nAim)
            vUp = secAxis.rotateBy(qTwist)
        nNormalPole = vUp - ((vUp * nAim) * nAim)
        nNormalPole.normalize()
        if snap > 0.0:
            nNormalSnap = vStartSnap - ((vStartSnap * nAim) * nAim)
            nNormalSnap.normalize()
            nNormal = (1.0 - snap) * nNormalPole + snap * nNormalSnap
        else:
            nNormal = nNormalPole

        nUp = secAxis.rotateBy(qAim)
        angle = nUp.angle(nNormal)
        qNormal = om2.MQuaternion(angle, nAim)
        if not nNormal.isEquivalent(nUp.rotateBy(qNormal), 1.0e-5):
            angle = 2.0 * math.pi - angle
            qNormal = om2.MQuaternion(angle, nAim)
        qBasis *= qNormal

        # Solver Triangle
        restStartLen = dataBlock.inputValue(
            IKVChainSolver.inRestLenStart).asFloat()
        restEndLen = dataBlock.inputValue(
            IKVChainSolver.inRestLenEnd).asFloat()
        compressionLimit = dataBlock.inputValue(
            IKVChainSolver.inCompressionLimit).asFloat()
        softVal = dataBlock.inputValue(IKVChainSolver.inSoftness).asFloat()

        startSnapLen = vStartSnap.length()
        endSnapLen = vEndSnap.length()

        startLen = (1.0 - snap) * restStartLen + snap * startSnapLen
        endLen = (1.0 - snap) * restEndLen + snap * endSnapLen
        chainLen = (1.0 - snap) * (restStartLen + restEndLen) + snap * (
            startSnapLen + endSnapLen)
        handleLen = vAim.length()

        rigidLen = max(min(handleLen, chainLen), chainLen * compressionLimit)
        dc = chainLen
        da = (1.0 - softVal) * dc
        if handleLen > da and softVal > 0.0:
            ds = dc - da
            softLen = ds * (1.0 - math.pow(math.e, (da - handleLen) / ds)) + da
            solverLen = (1.0 - snap) * softLen + snap * rigidLen
        else:
            solverLen = rigidLen

        # Pre Calculations
        startLenSquared = math.pow(startLen, 2.0)
        endLenSquared = math.pow(endLen, 2.0)
        solverLenSquared = math.pow(solverLen, 2.0)
        stretch = dataBlock.inputValue(IKVChainSolver.inStretch).asDouble()
        squashMultStart = dataBlock.inputValue(
            IKVChainSolver.inSquashMultStart).asFloat2()
        squashMultEnd = dataBlock.inputValue(
            IKVChainSolver.inSquashMultEnd).asFloat2()
        if stretch > 0.0:
            clampStretch = dataBlock.inputValue(
                IKVChainSolver.inClampStretch).asDouble()
            clampValue = dataBlock.inputValue(
                IKVChainSolver.inClampValue).asDouble()
            squash = dataBlock.inputValue(IKVChainSolver.inSquash).asDouble()
            if handleLen > da and softVal > 0.0:
                scaleFactor = handleLen / solverLen
            else:
                scaleFactor = handleLen / chainLen
            if handleLen >= da:
                clampFactor = (
                    1.0 - clampStretch) * scaleFactor + clampStretch * min(
                        scaleFactor, clampValue)
                stretchFactor = (1.0 - stretch) + stretch * clampFactor
            else:
                stretchFactor = 1.0
            squashFactor = (1.0 -
                            squash) + squash * (1.0 / math.sqrt(stretchFactor))
        else:
            stretchFactor = 1.0
            squashFactor = 1.0

        hierarchyMode = dataBlock.inputValue(
            IKVChainSolver.inHierarchyMode).asBool()
        useScale = dataBlock.inputValue(IKVChainSolver.inUseScale).asBool()
        outChainHandle = dataBlock.outputArrayValue(IKVChainSolver.outChain)
        offsetHandle = dataBlock.inputArrayValue(IKVChainSolver.inOffset)
        jntOriHandle = dataBlock.inputArrayValue(IKVChainSolver.inJntOri)
        mParInv = dataBlock.inputValue(IKVChainSolver.inParInvMtx).asMatrix()
        srtList = []
        offsetList = []
        jntOriList = []

        for i in range(len(offsetHandle)):
            offsetHandle.jumpToLogicalElement(i)
            eOff = om2.MEulerRotation(offsetHandle.inputValue().asDouble3())
            qOff = eOff.asQuaternion()
            offsetList.append(qOff)

        for i in range(len(jntOriHandle)):
            jntOriHandle.jumpToLogicalElement(i)
            eOri = om2.MEulerRotation(jntOriHandle.inputValue().asDouble3())
            qOri = eOri.asQuaternion()
            jntOriList.append(qOri)

        # First Output
        # Scale
        firstStretch = stretchFactor
        firstScaX = firstStretch
        if not useScale:
            firstStretch = 1.0
        firstSquash = [
            squashFactor * squashMultStart[0],
            squashFactor * squashMultStart[1]
        ]
        firstSca = [firstStretch, firstSquash[0], firstSquash[1]]
        # Rotation
        betaCosPure = (startLenSquared + solverLenSquared -
                       endLenSquared) / (2.0 * startLen * solverLen)
        betaCos = min(max(betaCosPure, -1.0), 1.0)
        beta = math.acos(betaCos)
        qBeta = om2.MQuaternion(beta, binAxis)
        qFirstRotW = qBeta * qBasis
        qFirstRot = om2.MQuaternion()
        if len(offsetList) >= 1:
            qFirstRot *= offsetList[0].invertIt()
        qFirstRot *= qFirstRotW
        if len(jntOriList) >= 1:
            qFirstRot *= jntOriList[0].invertIt()
        # Translation
        vFirstPos = vRoot
        # Matrix Output
        mtxFn = om2.MTransformationMatrix()
        mtxFn.setScale(firstSca, om2.MSpace.kTransform)
        mtxFn.setRotation(qFirstRot)
        mtxFn.setTranslation(vFirstPos, om2.MSpace.kTransform)
        mFirst = mtxFn.asMatrix()
        mFirst *= mParInv
        srtList.append(mFirst)

        # Second Output
        # Scale
        secondStretch = stretchFactor
        secondScaX = secondStretch
        if not useScale:
            secondStretch = 1.0
        secondSquash = [
            squashFactor * squashMultEnd[0], squashFactor * squashMultEnd[1]
        ]
        secondSca = [secondStretch, secondSquash[0], secondSquash[1]]
        # Rotation
        gammaCosPure = (startLenSquared + endLenSquared -
                        solverLenSquared) / (2.0 * startLen * endLen)
        gammaCos = min(max(gammaCosPure, -1.0), 1.0)
        gamma = math.acos(gammaCos)
        gammaCmp = gamma + beta - math.pi
        qGamma = om2.MQuaternion(gammaCmp, binAxis)
        qSecondRotW = qGamma * qBasis
        qSecondRot = om2.MQuaternion()
        if len(offsetList) >= 2:
            qSecondRot *= offsetList[1].invertIt()
        qSecondRot *= qSecondRotW
        if hierarchyMode:
            qSecondRot *= qFirstRotW.invertIt()
            if len(offsetList) >= 1:
                qSecondRot *= offsetList[0].invertIt()
        if len(jntOriList) >= 2:
            qSecondRot *= jntOriList[1].invertIt()
        # Translation
        if hierarchyMode:
            vSecondPos = primAxis * startLen
            if not useScale:
                vSecondPos *= firstScaX
        else:
            vSecondOri = nAim.rotateBy(om2.MQuaternion(
                beta, nAim ^ nNormal)) * startLen
            if not useScale:
                vSecondOri *= firstScaX
            vSecondPos = vRoot + vSecondOri
        # Matrix Output
        mtxFn = om2.MTransformationMatrix()
        mtxFn.setScale(secondSca, om2.MSpace.kTransform)
        mtxFn.setRotation(qSecondRot)
        mtxFn.setTranslation(vSecondPos, om2.MSpace.kTransform)
        mSecond = mtxFn.asMatrix()
        if not hierarchyMode:
            mSecond *= mParInv
        srtList.append(mSecond)

        # Third Output
        # Rotation
        qThirdRot = qBasis
        if hierarchyMode:
            qThirdRot *= qSecondRotW.invertIt()
            if len(offsetList) >= 2:
                qThirdRot *= offsetList[1].invertIt()
        # Translation
        if hierarchyMode:
            vThirdPos = primAxis * endLen
            if not useScale:
                vThirdPos *= secondScaX
        else:
            vThirdPos = vRoot + nAim * solverLen
            if not useScale:
                vThirdPos = vRoot + nAim * solverLen * stretchFactor
        # Matrix Output
        mtxFn = om2.MTransformationMatrix()
        mtxFn.setRotation(qThirdRot)
        mtxFn.setTranslation(vThirdPos, om2.MSpace.kTransform)
        mThird = mtxFn.asMatrix()
        if not hierarchyMode:
            mThird *= mParInv
        srtList.append(mThird)

        # Set outputs
        for i in range(len(outChainHandle)):
            outChainHandle.jumpToLogicalElement(i)
            resultHandle = outChainHandle.outputValue()
            if i < len(outChainHandle) and i < len(srtList):
                resultHandle.setMMatrix(srtList[i])
            else:
                resultHandle.setMMatrix(om2.MMatrix.kIdentity)

        outChainHandle.setAllClean()
Beispiel #14
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 plug != AimConstraint.outConstraint:
            return om2.kUnknownParameter

        upVecType = dataBlock.inputValue(AimConstraint.inUpVecType).asShort()
        eOffset = om2.MEulerRotation(
            dataBlock.inputValue(AimConstraint.inOffset).asDouble3())
        qOffset = eOffset.asQuaternion()
        mTargetW = dataBlock.inputValue(AimConstraint.inTargetWMtx).asMatrix()
        targetWeight = dataBlock.inputValue(
            AimConstraint.inTargetWeight).asDouble()
        mConstW = dataBlock.inputValue(AimConstraint.inConstWMtx).asMatrix()
        mConstParInv = dataBlock.inputValue(
            AimConstraint.inConstParInvMtx).asMatrix()
        eConstJntOri = om2.MEulerRotation(
            dataBlock.inputValue(AimConstraint.inConstJntOri).asDouble3())
        qConstJntOri = eConstJntOri.asQuaternion()
        constRotOrder = dataBlock.inputValue(
            AimConstraint.inConstRotOrder).asShort()

        vTarget = om2.MVector(mTargetW[12], mTargetW[13], mTargetW[14])
        vConst = om2.MVector(mConstW[12], mConstW[13], mConstW[14])
        mtxFn = om2.MTransformationMatrix(mConstParInv)
        qConstParInv = mtxFn.rotation(asQuaternion=True)

        primAxis = om2.MVector.kXaxisVector
        secAxis = om2.MVector.kYaxisVector
        qAimConst = om2.MQuaternion()

        nAim = vTarget - vConst
        nAim.normalize()
        qAim = om2.MQuaternion(primAxis, nAim)
        qAimConst *= qAim

        if upVecType != 0:
            if upVecType == 1:
                # World Up
                nWorldUp = om2.MVector(
                    dataBlock.inputValue(
                        AimConstraint.inWorldUpVector).asFloat3())
                nWorldUp.normalize()
                vUp = nWorldUp
            elif upVecType == 2:
                # Object Up
                mWorldUp = dataBlock.inputValue(
                    AimConstraint.inWorldUpMtx).asMatrix()
                vWorldUp = om2.MVector(mWorldUp[12], mWorldUp[13],
                                       mWorldUp[14])
                vUp = vWorldUp - vConst
            elif upVecType == 3:
                # Angle Up
                angleUp = dataBlock.inputValue(
                    AimConstraint.inAngleUp).asAngle().asRadians()
                qTwist = om2.MQuaternion(angleUp, nAim)
                vUp = secAxis.rotateBy(qTwist)
            nNormal = vUp - ((vUp * nAim) * nAim)
            nNormal.normalize()

            nUp = secAxis.rotateBy(qAim)
            angle = nUp.angle(nNormal)
            qNormal = om2.MQuaternion(angle, nAim)
            if not nNormal.isEquivalent(nUp.rotateBy(qNormal), 1.0e-5):
                angle = 2.0 * math.pi - angle
                qNormal = om2.MQuaternion(angle, nAim)
            qAimConst *= qNormal

        qResult = om2.MQuaternion()
        qResult *= qOffset.invertIt()
        qResult *= qAimConst
        qResult *= qConstParInv
        qResult *= qConstJntOri.invertIt()
        eResult = qResult.asEulerRotation()
        eResult.reorderIt(constRotOrder)
        eResult *= targetWeight
        vResult = eResult.asVector()
        outConstraintHandle = dataBlock.outputValue(
            AimConstraint.outConstraint)
        outConstraintHandle.setMVector(vResult)
        outConstraintHandle.setClean()
Beispiel #15
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 plug != HelperJoint.outTransform:
            return om2.kUnknownParameter

        mSource = dataBlock.inputValue(HelperJoint.inSource).asMatrix()
        mtxFn = om2.MTransformationMatrix(mSource)
        mtxFn.setScale([1.0, 1.0, 1.0], om2.MSpace.kTransform)
        mSource = mtxFn.asMatrix()
        mSourceParent = dataBlock.inputValue(HelperJoint.inSourceParent).asMatrix()

        mParInv = dataBlock.inputValue(HelperJoint.inParInvMtx).asMatrix()
        sourceParSca = dataBlock.inputValue(HelperJoint.inSourceParSca).asFloat3()
        mtxFn = om2.MTransformationMatrix()
        mtxFn.scaleBy(sourceParSca, om2.MSpace.kTransform)
        mInvSca = mtxFn.asMatrix()
        targetListHandle = dataBlock.inputArrayValue(HelperJoint.inTargetList)

        outputList = []

        for i in range(len(targetListHandle)):
            targetListHandle.jumpToLogicalElement(i)
            targetHandle = targetListHandle.inputValue()
            vPosOffset = om2.MVector(targetHandle.child(HelperJoint.inPositionOffset).asFloat3())
            eRotOffset = om2.MEulerRotation(targetHandle.child(HelperJoint.inRotationOffset).asDouble3())
            angle = targetHandle.child(HelperJoint.inRotAngle).asAngle().asRadians()
            restAngle = targetHandle.child(HelperJoint.inRestAngle).asAngle().asRadians()
            rotInterp = targetHandle.child(HelperJoint.inRotInterp).asFloat()
            posMult = targetHandle.child(HelperJoint.inPosMult).asFloat()
            negMult = targetHandle.child(HelperJoint.inNegMult).asFloat()

            mPositionOffset = om2.MMatrix()
            mPositionOffset[12] = vPosOffset.x
            mPositionOffset[13] = vPosOffset.y
            mPositionOffset[14] = vPosOffset.z
            multTranslation = abs(angle) * posMult
            if angle < restAngle:
                multTranslation = abs(angle) * negMult
            vPosOffset.normalize()
            mMultiplier = om2.MMatrix()
            mMultiplier[12] = vPosOffset.x * multTranslation
            mMultiplier[13] = vPosOffset.y * multTranslation
            mMultiplier[14] = vPosOffset.z * multTranslation
            mTargetPoint = mMultiplier * mPositionOffset * mSource
            mTargetOrient = mInvSca * (mSource * (1.0 - rotInterp)) + (mSourceParent * rotInterp)

            vResultPos = om2.MVector(mTargetPoint[12], mTargetPoint[13], mTargetPoint[14])
            mtxFn = om2.MTransformationMatrix(mTargetOrient)
            eResultOri = eRotOffset + mtxFn.rotation(asQuaternion=False)
            mtxFn = om2.MTransformationMatrix()
            mtxFn.setRotation(eResultOri)
            mtxFn.setTranslation(vResultPos, om2.MSpace.kTransform)
            mResult = mtxFn.asMatrix() * mParInv
            outputList.append(mResult)

        outTransHandle = dataBlock.outputArrayValue(HelperJoint.outTransform)
        for i in range(len(outTransHandle)):
            outTransHandle.jumpToLogicalElement(i)
            resultHandle = outTransHandle.outputValue()
            if i < len(outTransHandle) and i < len(outputList):
                resultHandle.setMMatrix(outputList[i])
            else:
                resultHandle.setMMatrix(om2.MMatrix.kIdentity)
Beispiel #16
0
 def scale(self, x=0.0, y=0.0, z=0.0):
     if x == y == z == 0.0:
         return
     offset = om2.MVector(x, y, z)
     self.transform.scaleBy(offset, om2.MSpace.kWorld)
     self.isDirty = True
Beispiel #17
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()
Beispiel #18
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()