Пример #1
0
    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
Пример #2
0
    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
Пример #3
0
 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()))
Пример #4
0
    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
Пример #5
0
    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
Пример #7
0
 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
Пример #8
0
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)