def compute(self, plug, data): if plug == SoftIKConstraint.output: softVal = data.inputValue(SoftIKConstraint.soft).asFloat() inverseWorldMatrix = data.inputValue( SoftIKConstraint.matInv).asMatrix() transformAWorldMatrix = data.inputValue( SoftIKConstraint.matA).asMatrix() transformBWorldMatrix = data.inputValue( SoftIKConstraint.matB).asMatrix() vecAwm = OpenMaya.MPoint() * transformAWorldMatrix vecBwm = OpenMaya.MPoint() * transformBWorldMatrix vecAB = vecAwm - vecBwm currentLength = getMagnitude(vecAB) if self.magRetrieved == 0: transformCWorldMatrix = data.inputValue( SoftIKConstraint.matC).asMatrix() vecCwm = OpenMaya.MPoint() * transformCWorldMatrix vecAC = vecAwm - vecCwm vecCB = vecCwm - vecBwm self.chainLength = getMagnitude(vecAC) + getMagnitude(vecCB) self.magRetrieved = 1 if softVal == 0: ratioOfLength = 1 else: affectedLength = self.chainLength * softVal unnafectedLength = self.chainLength - affectedLength # create a falloff based on where the unnafected length ends. The function creates a curve all the way from 0 to max length but the result is forced to become linear where the unnafected length applies. if currentLength <= unnafectedLength: fractionOfLength = currentLength else: fractionOfLength = affectedLength * (1 - math.exp( (unnafectedLength - currentLength) / affectedLength)) + unnafectedLength ratioOfLength = fractionOfLength / currentLength worldPosition = OpenMaya.MVector((vecAwm * (1.0 - ratioOfLength)) + OpenMaya.MVector(vecBwm * ratioOfLength)) localPosition = worldPosition * inverseWorldMatrix outHandle = data.outputValue(SoftIKConstraint.output) outHandleX = outHandle.child(SoftIKConstraint.pointX) outHandleY = outHandle.child(SoftIKConstraint.pointY) outHandleZ = outHandle.child(SoftIKConstraint.pointZ) outHandleX.setMDistance(OpenMaya.MDistance(localPosition.x)) outHandleY.setMDistance(OpenMaya.MDistance(localPosition.y)) outHandleZ.setMDistance(OpenMaya.MDistance(localPosition.z)) data.setClean(plug) else: return OpenMaya.kUnknownParameter
def applyTranslationLocks(self, newTrans, savedTrans): """Use locking to make sure object does not actually move, but the mouse delta movements are stored in deltaTrans.""" #print "setting translation locks for %s" % self.name() delta = newTrans - savedTrans # print "old values for deltaTrans:" # self.debugPrintDeltaTrans() # print dist = OpenMaya.MDistance() dist.setUnit(OpenMaya.MDistance.internalUnit()) for axis in "XYZ": child = self.getDeltaTransPlug(axis) #print child.name() #print "is a unit attribute?: %s" % child.attribute().hasFn(OpenMaya.MFn.kUnitAttribute) dist.setValue(getattr(delta, axis.lower()) + child.asDouble()) child.setMDistance(dist) # child.setDouble(delta[i]) # print "new values for deltaTrans:" # self.debugPrintDeltaTrans() # print return savedTrans
def set_unit_attribute_value(plug, value): fn = OpenMaya.MFnUnitAttribute(plug.attribute()) if fn.unitType() == OpenMaya.MFnUnitAttribute.kAngle: MayaUndoHelper.dg_modifier.newPlugValueMAngle( plug, OpenMaya.MAngle(math.radians(value))) elif fn.unitType() == OpenMaya.MFnUnitAttribute.kDistance: MayaUndoHelper.dg_modifier.newPlugValueMDistance( plug, OpenMaya.MDistance(value)) elif fn.unitType() == OpenMaya.MFnUnitAttribute.kTime: MayaUndoHelper.dg_modifier.newPlugValueMTime( plug, OpenMaya.MTime(value, OpenMaya.MTime.uiUnit()))
def compute(self, plug, dataBlock): outputAttrs = (self.constraintTranslate, self.constraintTranslateX, self.constraintTranslateY, self.constraintTranslateZ) if plug in outputAttrs: # First, check that we have sufficient information / connections useDefaults = False matrices = { 'start': self.startJointWorldMatrix, 'target': self.targetWorldMatrix, 'inverse': self.constraintParentInverseMatrix } for matrixType, attr in matrices.iteritems(): data = dataBlock.inputValue(attr).data() if data.isNull(): useDefaults = True break matrices[matrixType] = om.MFnMatrixData(data) if useDefaults: localPos = om.MPoint() else: # Compute start/target world positions startWorldPos = om.MPoint() * matrices['start'].matrix() targetWorldPos = om.MPoint() * matrices['target'].matrix() targetDist = startWorldPos.distanceTo(targetWorldPos) chainLength = dataBlock.inputValue( self.chainLength).asDistance().value() softRatio = dataBlock.inputValue(self.softRatio).asDouble() if softRatio == 0: finalRatio = 1.0 else: softDist = softRatio * chainLength hardDist = chainLength - softDist finalDistance = self._getFinalDist(targetDist, softDist, hardDist) finalRatio = finalDistance / targetDist # Yay API - we can only add an MVector to an MPoint finalWorldPos = ((startWorldPos * (1.0 - finalRatio)) + om.MVector(targetWorldPos * finalRatio)) localPos = finalWorldPos * matrices['inverse'].matrix() for dir in 'XYZ': attr = getattr(self, 'constraintTranslate' + dir) outHandle = dataBlock.outputValue(attr) outHandle.setMDistance( om.MDistance(getattr(localPos, dir.lower()))) dataBlock.setClean(attr) dataBlock.setClean(self.constraintTranslate) else: return om.kUnknownParameter
def sanitize_matrix(matrix): # apparently the matrix translation values are always in centimeters. # so we use this little hack to have the right translation values if OpenMaya.MDistance.uiUnit() == OpenMaya.MDistance.kCentimeters: final_index = 4 else: final_index = 3 matrix_list = [] for i in range(final_index): for j in range(4): matrix_list.append(matrix(i, j)) if final_index == 3: for i in range(3): matrix_list.append( OpenMaya.MDistance(matrix(3, i)).asUnits( OpenMaya.MDistance.uiUnit())) matrix_list.append(1.0) return matrix_list
def nodeInitializer(): nAttr = OpenMaya.MFnNumericAttribute() unitAttr = OpenMaya.MFnUnitAttribute() cAttr = OpenMaya.MFnCompoundAttribute() enumAttr = OpenMaya.MFnEnumAttribute() matAttr = OpenMaya.MFnMatrixAttribute() milkShake.blendHierarchy = nAttr.create("blendHierarchy", "bHr", OpenMaya.MFnNumericData.kBoolean, False) nAttr.setStorable(1) nAttr.setKeyable(1) nAttr.setHidden(0) milkShake.addAttribute(milkShake.blendHierarchy) defaultAngle = OpenMaya.MAngle(0.0, OpenMaya.MAngle.kDegrees) defaultDist = OpenMaya.MDistance(0.0, OpenMaya.MDistance.kCentimeters) #--> just to keep things simple lets say this node is to be used for the animation rig: and scaling is done with the translate channel #--> the node do a basic index matching: if input index is not valid write default value #--> behaves like a pairblendNode from input1 to input2 mode_Attr = OpenMaya.MFnEnumAttribute() milkShake.rotInterpolation = mode_Attr.create("rotInterpolation", "ri", 0) mode_Attr.addField("euler", 0) mode_Attr.addField("quaternion", 1) mode_Attr.setStorable(1) mode_Attr.setKeyable(1) mode_Attr.setHidden(0) milkShake.addAttribute(milkShake.rotInterpolation) milkShake.weight = nAttr.create("weight", "w", OpenMaya.MFnNumericData.kFloat, 0) nAttr.setStorable(1) nAttr.setKeyable(1) nAttr.setHidden(0) nAttr.setMin(0.0) nAttr.setMax(1.0) milkShake.addAttribute(milkShake.weight) #----------------------------------------------------------------------------------------------- Input Translate Attributes milkShake.input1_TranslateOffset = nAttr.create( "input1_TranslateOffset", "in1OTR", OpenMaya.MFnNumericData.k3Float, 0) milkShake.input2_TranslateOffset = nAttr.create( "input2_TranslateOffset", "in2OTR", OpenMaya.MFnNumericData.k3Float, 0) milkShake.input1_RotateOffsetX = unitAttr.create("input1_RotateOffsetX", "i1Orx", defaultAngle) milkShake.input1_RotateOffsetY = unitAttr.create("input1_RotateOffsetY", "i1Ory", defaultAngle) milkShake.input1_RotateOffsetZ = unitAttr.create("input1_RotateOffsetZ", "i1Orz", defaultAngle) milkShake.inputScaleOffset1 = nAttr.create("inputScaleOffset1", "inO1S", OpenMaya.MFnNumericData.k3Float, 1.0) milkShake.inputScaleOffset2 = nAttr.create("inputScaleOffset2", "inO2S", OpenMaya.MFnNumericData.k3Float, 1.0) milkShake.input1_RotateOffset = nAttr.create( "input1_RotateOffset", "in1RotO", milkShake.input1_RotateOffsetX, milkShake.input1_RotateOffsetY, milkShake.input1_RotateOffsetZ) milkShake.input2_RotateOffsetX = unitAttr.create("input2_RotateOffsetX", "i2Orx", defaultAngle) milkShake.input2_RotateOffsetY = unitAttr.create("input2_RotateOffsetY", "i2Ory", defaultAngle) milkShake.input2_RotateOffsetZ = unitAttr.create("input2_RotateOffsetZ", "i2Orz", defaultAngle) milkShake.input2_RotateOffset = nAttr.create( "input2_RotateOffset", "in2ORot", milkShake.input2_RotateOffsetX, milkShake.input2_RotateOffsetY, milkShake.input2_RotateOffsetZ) milkShake.inRotationOrder1 = enumAttr.create("inRotationOrder1", "iro1", 0) enumAttr.setStorable(1) enumAttr.setKeyable(1) enumAttr.addField('xyz', 0) enumAttr.addField('yzx', 1) enumAttr.addField('zxy', 2) enumAttr.addField('xzy', 3) enumAttr.addField('yxz', 4) enumAttr.addField('zyx', 5) milkShake.addAttribute(milkShake.inRotationOrder1) milkShake.inRotationOrder2 = enumAttr.create("inRotationOrder2", "iro2", 0) enumAttr.setStorable(1) enumAttr.setKeyable(1) enumAttr.addField('xyz', 0) enumAttr.addField('yzx', 1) enumAttr.addField('zxy', 2) enumAttr.addField('xzy', 3) enumAttr.addField('yxz', 4) enumAttr.addField('zyx', 5) milkShake.addAttribute(milkShake.inRotationOrder2) milkShake.input1_Translate = nAttr.create("input1_Translate", "in1TR", OpenMaya.MFnNumericData.k3Float, 0) milkShake.input2_Translate = nAttr.create("input2_Translate", "in2TR", OpenMaya.MFnNumericData.k3Float, 0) #-------------------------------------------- Input rotate Attributes milkShake.input1_RotateX = unitAttr.create("input1_RotateX", "i1rx", defaultAngle) milkShake.input1_RotateY = unitAttr.create("input1_RotateY", "i1ry", defaultAngle) milkShake.input1_RotateZ = unitAttr.create("input1_RotateZ", "i1rz", defaultAngle) milkShake.input1_Rotate = nAttr.create("input1_Rotate", "in1Rot", milkShake.input1_RotateX, milkShake.input1_RotateY, milkShake.input1_RotateZ) milkShake.input2_RotateX = unitAttr.create("input2_RotateX", "i2rx", defaultAngle) milkShake.input2_RotateY = unitAttr.create("input2_RotateY", "i2ry", defaultAngle) milkShake.input2_RotateZ = unitAttr.create("input2_RotateZ", "i2rz", defaultAngle) milkShake.input2_Rotate = nAttr.create("input2_Rotate", "in2Rot", milkShake.input2_RotateX, milkShake.input2_RotateY, milkShake.input2_RotateZ) milkShake.inputScale1 = nAttr.create("inputScale1", "in1S", OpenMaya.MFnNumericData.k3Float, 1.0) milkShake.inputScale2 = nAttr.create("inputScale2", "in2S", OpenMaya.MFnNumericData.k3Float, 1.0) milkShake.input = cAttr.create("input", "in") cAttr.addChild(milkShake.input1_TranslateOffset) cAttr.addChild(milkShake.input2_TranslateOffset) cAttr.addChild(milkShake.input1_RotateOffset) cAttr.addChild(milkShake.input2_RotateOffset) cAttr.addChild(milkShake.inputScaleOffset1) cAttr.addChild(milkShake.inputScaleOffset2) cAttr.addChild(milkShake.input1_Translate) cAttr.addChild(milkShake.input1_Rotate) cAttr.addChild(milkShake.inputScale1) cAttr.addChild(milkShake.inRotationOrder1) cAttr.addChild(milkShake.input2_Translate) cAttr.addChild(milkShake.input2_Rotate) cAttr.addChild(milkShake.inputScale2) cAttr.addChild(milkShake.inRotationOrder2) cAttr.setArray(1) cAttr.setStorable(1) cAttr.setKeyable(0) cAttr.setHidden(0) cAttr.setDisconnectBehavior(OpenMaya.MFnAttribute.kNothing) milkShake.addAttribute(milkShake.input) #----------------------------------------------------------------------------------------------- Output Attributes milkShake.outRotateX = unitAttr.create("outRotateX", "orx", defaultAngle) milkShake.outRotateY = unitAttr.create("outRotateY", "ory", defaultAngle) milkShake.outRotateZ = unitAttr.create("outRotateZ", "orz", defaultAngle) milkShake.outRotate = nAttr.create("outRotate", "oRot", milkShake.outRotateX, milkShake.outRotateY, milkShake.outRotateZ) milkShake.outTranslate = nAttr.create("outTranslate", "oTrn", OpenMaya.MFnNumericData.k3Float, 0.0) milkShake.outScale = nAttr.create("outScale", "outS", OpenMaya.MFnNumericData.k3Float, 1.0) milkShake.outMatrix = matAttr.create("outMatrix", "oMat", OpenMaya.MFnMatrixAttribute.kDouble) milkShake.output = cAttr.create("output", "out") cAttr.addChild(milkShake.outRotate) cAttr.addChild(milkShake.outTranslate) cAttr.addChild(milkShake.outScale) cAttr.addChild(milkShake.outMatrix) cAttr.setArray(1) cAttr.setStorable(0) cAttr.setKeyable(0) cAttr.setHidden(True) cAttr.setUsesArrayDataBuilder(1) milkShake.addAttribute(milkShake.output) milkShake.attributeAffects(milkShake.input, milkShake.output) milkShake.attributeAffects(milkShake.rotInterpolation, milkShake.output) milkShake.attributeAffects(milkShake.weight, milkShake.output) milkShake.attributeAffects(milkShake.blendHierarchy, milkShake.output) return
def sanitize_translation_vector(vector): if OpenMaya.MDistance.uiUnit() != OpenMaya.MDistance.kCentimeters: for i in range(3): vector[i] = OpenMaya.MDistance(vector[i]).asUnits( OpenMaya.MDistance.uiUnit()) return vector
def nodeInitializer(): nAttr = OpenMaya.MFnNumericAttribute() matAttr = OpenMaya.MFnMatrixAttribute() unitAttr = OpenMaya.MFnUnitAttribute() cAttr = OpenMaya.MFnCompoundAttribute() heimer.worldToLocal = matAttr.create("worldToLocal", "wtlMat", OpenMaya.MFnMatrixAttribute.kDouble) matAttr.setHidden(True) heimer.addAttribute(heimer.worldToLocal) heimer.targetMatrix = matAttr.create("targetMatrix", "trgMat", OpenMaya.MFnMatrixAttribute.kDouble) matAttr.setHidden(True) heimer.addAttribute(heimer.targetMatrix) heimer.targetPosition = nAttr.create("targetPosition", "trgPos", OpenMaya.MFnNumericData.k3Double) nAttr.setStorable(0) nAttr.setKeyable(1) nAttr.setHidden(0) heimer.addAttribute(heimer.targetPosition) defaultAngle = OpenMaya.MAngle(0.0, OpenMaya.MAngle.kDegrees) defaultDist = OpenMaya.MDistance(0.0, OpenMaya.MDistance.kCentimeters) heimer.outRotateX = unitAttr.create("outRotateX", "orx", defaultAngle) heimer.outRotateY = unitAttr.create("outRotateY", "ory", defaultAngle) heimer.outRotateZ = unitAttr.create("outRotateZ", "orz", defaultAngle) heimer.outRotate = nAttr.create("outRotate", "or", heimer.outRotateX, heimer.outRotateY, heimer.outRotateZ) heimer.local = cAttr.create("local", "lcl") cAttr.addChild(heimer.outRotate) cAttr.setStorable(0) cAttr.setKeyable(0) cAttr.setHidden(True) heimer.addAttribute(heimer.local) heimer.translateX = unitAttr.create("translateX", "tx", defaultDist) heimer.translateY = unitAttr.create("translateY", "ty", defaultDist) heimer.translateZ = unitAttr.create("translateZ", "tz", defaultDist) heimer.translate = nAttr.create("translate", "t", heimer.translateX, heimer.translateY, heimer.translateZ) heimer.rotateX = unitAttr.create("rotateX", "rx", defaultAngle) heimer.rotateY = unitAttr.create("rotateY", "ry", defaultAngle) heimer.rotateZ = unitAttr.create("rotateZ", "rz", defaultAngle) heimer.rotate = nAttr.create("rotate", "r", heimer.rotateX, heimer.rotateY, heimer.rotateZ) heimer.outMatrix = matAttr.create("outMatrix", "oMat", OpenMaya.MFnMatrixAttribute.kDouble) heimer.outScale = nAttr.create("outScale", "outS", OpenMaya.MFnNumericData.k3Double, 1.0) heimer.convertWorldToLocal = nAttr.create("convertWorldToLocal", "cnv", OpenMaya.MFnNumericData.kBoolean, False) heimer.addAttribute(heimer.convertWorldToLocal) heimer.world = cAttr.create("world", "wrl") cAttr.addChild(heimer.rotate) cAttr.addChild(heimer.translate) cAttr.addChild(heimer.outScale) cAttr.addChild(heimer.outMatrix) cAttr.setStorable(0) cAttr.setKeyable(0) cAttr.setHidden(True) heimer.addAttribute(heimer.world) heimer.attributeAffects(heimer.convertWorldToLocal, heimer.local) heimer.attributeAffects(heimer.targetPosition, heimer.local) heimer.attributeAffects(heimer.worldToLocal, heimer.local) heimer.attributeAffects(heimer.targetMatrix, heimer.local) heimer.attributeAffects(heimer.worldToLocal, heimer.world) heimer.attributeAffects(heimer.targetMatrix, heimer.world) heimer.attributeAffects(heimer.convertWorldToLocal, heimer.world) return
def nodeInitializer(): typed_Attr = OpenMaya.MFnTypedAttribute() nAttr = OpenMaya.MFnNumericAttribute() unitAttr = OpenMaya.MFnUnitAttribute() matAttr = OpenMaya.MFnMatrixAttribute() cAttr = OpenMaya.MFnCompoundAttribute() #input worldMesh curve yakisoba.inputCurve = typed_Attr.create( "inputCurve", "inCv", OpenMaya.MFnNurbsCurveData.kNurbsCurve ) typed_Attr.setStorable(0) typed_Attr.setKeyable(0) typed_Attr.setHidden(True) yakisoba.addAttribute( yakisoba.inputCurve ) yakisoba.inputRibbon = typed_Attr.create( "inputRibbon", "inrb", OpenMaya.MFnNurbsCurveData.kNurbsSurface ) typed_Attr.setStorable(0) typed_Attr.setKeyable(0) typed_Attr.setHidden(True) yakisoba.addAttribute( yakisoba.inputRibbon ) yakisoba.uValue = nAttr.create( "uValue", "uVl", OpenMaya.MFnNumericData.kDouble,0 ) nAttr.setArray(1) nAttr.setStorable(1) nAttr.setKeyable(0) nAttr.setHidden(0) nAttr.setMin(0.0) yakisoba.addAttribute( yakisoba.uValue ) yakisoba.disableRotation = nAttr.create( "disableRotation", "dRot", OpenMaya.MFnNumericData.kBoolean,0 ) nAttr.setStorable(1) nAttr.setKeyable(1) nAttr.setHidden(0) yakisoba.addAttribute( yakisoba.disableRotation ) yakisoba.twist = nAttr.create( "twist", "tw", OpenMaya.MFnNumericData.kDouble,0 ) nAttr.setKeyable(1) yakisoba.addAttribute( yakisoba.twist) #---------------------------------------------------------------------------- Output Attributes defaultAngle = OpenMaya.MAngle ( 0.0, OpenMaya.MAngle.kDegrees ) defaultDist = OpenMaya.MDistance ( 0.0, OpenMaya.MDistance.kCentimeters ) yakisoba.outRotateX = unitAttr.create( "outRotateX", "orx", defaultAngle) yakisoba.outRotateY = unitAttr.create( "outRotateY", "ory", defaultAngle) yakisoba.outRotateZ = unitAttr.create( "outRotateZ", "orz", defaultAngle) yakisoba.outRotate = nAttr.create( "outRotate", "oRot",yakisoba.outRotateX,yakisoba.outRotateY,yakisoba.outRotateZ) yakisoba.outTranslateX = unitAttr.create( "outTranslateX", "otx", defaultDist) yakisoba.outTranslateY = unitAttr.create( "outTranslateY", "oty", defaultDist) yakisoba.outTranslateZ = unitAttr.create( "outTranslateZ", "otz", defaultDist) yakisoba.outTranslate = nAttr.create( "outTranslate", "oTrn",yakisoba.outTranslateX,yakisoba.outTranslateY,yakisoba.outTranslateZ) yakisoba.outMatrix = matAttr.create("outMatrix", "oMat",OpenMaya.MFnMatrixAttribute.kDouble) yakisoba.outScale = nAttr.create( "outScale", "outS", OpenMaya.MFnNumericData.k3Double,1.0 ) yakisoba.output = cAttr.create( "output", "out" ) cAttr.addChild(yakisoba.outRotate) cAttr.addChild(yakisoba.outTranslate) cAttr.addChild(yakisoba.outMatrix) cAttr.addChild( yakisoba.outScale) cAttr.setArray(1) cAttr.setStorable(1) cAttr.setKeyable(0) cAttr.setHidden(True) cAttr.setUsesArrayDataBuilder(1) yakisoba.addAttribute(yakisoba.output) yakisoba.attributeAffects( yakisoba.inputCurve , yakisoba.output ) yakisoba.attributeAffects( yakisoba.inputRibbon , yakisoba.output) yakisoba.attributeAffects( yakisoba.uValue , yakisoba.output) yakisoba.attributeAffects( yakisoba.twist , yakisoba.output) yakisoba.attributeAffects( yakisoba.disableRotation , yakisoba.output) yakisoba.uParameters = typed_Attr.create( "uParameters", "uuPrm", OpenMaya.MFnData.kDoubleArray) typed_Attr.setStorable(1) typed_Attr.setKeyable(0) typed_Attr.setHidden(1) yakisoba.addAttribute(yakisoba.uParameters) yakisoba.splineMatrix = typed_Attr.create( "splineMatrix", "sMat", OpenMaya.MFnData.kVectorArray) typed_Attr.setStorable(1) typed_Attr.setKeyable(0) typed_Attr.setHidden(1) yakisoba.addAttribute(yakisoba.splineMatrix) yakisoba.attributeAffects( yakisoba.inputCurve , yakisoba.splineMatrix ) yakisoba.attributeAffects( yakisoba.inputRibbon , yakisoba.splineMatrix ) yakisoba.attributeAffects( yakisoba.uParameters , yakisoba.splineMatrix ) yakisoba.attributeAffects( yakisoba.twist , yakisoba.splineMatrix )
def nodeInitializer(): typed_Attr = OpenMaya.MFnTypedAttribute() nAttr = OpenMaya.MFnNumericAttribute() unitAttr = OpenMaya.MFnUnitAttribute() matAttr = OpenMaya.MFnMatrixAttribute() cAttr = OpenMaya.MFnCompoundAttribute() tortilla.uParameters = typed_Attr.create("uParameters", "uuPrm", OpenMaya.MFnData.kDoubleArray) typed_Attr.setStorable(1) typed_Attr.setHidden(1) tortilla.addAttribute(tortilla.uParameters) tortilla.startTwist = nAttr.create("startTwist", "sTw", OpenMaya.MFnNumericData.kDouble, 0.0) nAttr.setStorable(1) nAttr.setKeyable(1) nAttr.setHidden(0) tortilla.addAttribute(tortilla.startTwist) tortilla.endTwist = nAttr.create("endTwist", "eTw", OpenMaya.MFnNumericData.kDouble, 0.0) nAttr.setStorable(1) nAttr.setKeyable(1) nAttr.setHidden(0) tortilla.addAttribute(tortilla.endTwist) tortilla.startScale = nAttr.create("startScale", "sSc", OpenMaya.MFnNumericData.k3Double, 1.0) nAttr.setStorable(1) nAttr.setKeyable(1) nAttr.setHidden(0) tortilla.addAttribute(tortilla.startScale) tortilla.endScale = nAttr.create("endScale", "eSc", OpenMaya.MFnNumericData.k3Double, 1.0) nAttr.setStorable(1) nAttr.setKeyable(1) nAttr.setHidden(0) tortilla.addAttribute(tortilla.endScale) tortilla.twistTweak = nAttr.create("twistTweak", "sWk", OpenMaya.MFnNumericData.kDouble, 0.0) nAttr.setStorable(1) nAttr.setKeyable(1) nAttr.setHidden(0) tortilla.addAttribute(tortilla.twistTweak) tortilla.scaleTweak = nAttr.create("scaleTweak", "scWk", OpenMaya.MFnNumericData.kDouble, 1.0) nAttr.setStorable(1) nAttr.setKeyable(1) nAttr.setHidden(0) tortilla.addAttribute(tortilla.scaleTweak) rmp_Attr = OpenMaya.MRampAttribute() tortilla.twist_rampWeight = rmp_Attr.createCurveRamp( "twist_rampWeight", "tw_rWg") tortilla.addAttribute(tortilla.twist_rampWeight) tortilla.endScale_rampWeight = rmp_Attr.createCurveRamp( "endScale_rampWeight", "enS_rWg") tortilla.addAttribute(tortilla.endScale_rampWeight) tortilla.twistTweak_rampWeight = rmp_Attr.createCurveRamp( "twistTweak_rampWeight", "ttw_rWg") tortilla.addAttribute(tortilla.twistTweak_rampWeight) tortilla.scaleTweak_rampWeight = rmp_Attr.createCurveRamp( "scaleTweak_rampWeight", "stw_rWg") tortilla.addAttribute(tortilla.scaleTweak_rampWeight) #---------------------------------------------------------------------------- Output Attributes defaultAngle = OpenMaya.MAngle(0.0, OpenMaya.MAngle.kDegrees) defaultDist = OpenMaya.MDistance(0.0, OpenMaya.MDistance.kCentimeters) tortilla.outRotateX = unitAttr.create("outRotateX", "orx", defaultAngle) tortilla.outRotateY = unitAttr.create("outRotateY", "ory", defaultAngle) tortilla.outRotateZ = unitAttr.create("outRotateZ", "orz", defaultAngle) tortilla.outRotate = nAttr.create("outRotate", "oRot", tortilla.outRotateX, tortilla.outRotateY, tortilla.outRotateZ) tortilla.outTranslateX = unitAttr.create("outTranslateX", "otx", defaultDist) tortilla.outTranslateY = unitAttr.create("outTranslateY", "oty", defaultDist) tortilla.outTranslateZ = unitAttr.create("outTranslateZ", "otz", defaultDist) tortilla.outTranslate = nAttr.create("outTranslate", "oTrn", tortilla.outTranslateX, tortilla.outTranslateY, tortilla.outTranslateZ) tortilla.outScale = nAttr.create("outScale", "outS", OpenMaya.MFnNumericData.k3Double, 1.0) tortilla.output = cAttr.create("output", "out") cAttr.addChild(tortilla.outRotate) cAttr.addChild(tortilla.outScale) cAttr.setArray(1) cAttr.setStorable(1) cAttr.setKeyable(0) cAttr.setHidden(True) cAttr.setUsesArrayDataBuilder(1) tortilla.addAttribute(tortilla.output) tortilla.attributeAffects(tortilla.startTwist, tortilla.output) tortilla.attributeAffects(tortilla.endTwist, tortilla.output) tortilla.attributeAffects(tortilla.uParameters, tortilla.output) tortilla.attributeAffects(tortilla.startScale, tortilla.output) tortilla.attributeAffects(tortilla.endScale, tortilla.output) tortilla.attributeAffects(tortilla.twist_rampWeight, tortilla.output) tortilla.attributeAffects(tortilla.scaleTweak, tortilla.output) tortilla.attributeAffects(tortilla.twistTweak, tortilla.output) tortilla.attributeAffects(tortilla.twistTweak_rampWeight, tortilla.output) tortilla.attributeAffects(tortilla.scaleTweak_rampWeight, tortilla.output) tortilla.attributeAffects(tortilla.endScale_rampWeight, tortilla.output) # TWIST array for spline deformer tortilla.twistArray = typed_Attr.create("twistArray", "twL", OpenMaya.MFnData.kDoubleArray) typed_Attr.setStorable(1) typed_Attr.setHidden(1) tortilla.addAttribute(tortilla.twistArray) tortilla.attributeAffects(tortilla.startTwist, tortilla.twistArray) tortilla.attributeAffects(tortilla.endTwist, tortilla.twistArray) tortilla.attributeAffects(tortilla.uParameters, tortilla.twistArray) tortilla.attributeAffects(tortilla.twist_rampWeight, tortilla.twistArray) tortilla.attributeAffects(tortilla.twistTweak, tortilla.twistArray) tortilla.attributeAffects(tortilla.twistTweak_rampWeight, tortilla.twistArray)