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
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)
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()
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()
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
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()
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
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()
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()