Esempio n. 1
0
def initialize():
    """
    Initializes the node.
    """
    # guide attributes
    fn_num = oMa.MFnNumericAttribute()
    SeamlessFkIk.thigh_len_mobj = fn_num.create("thighLen", "tl",
                                                oMa.MFnNumericData.kFloat)
    SeamlessFkIk.shin_len_mobj = fn_num.create("shinLen", "sl",
                                               oMa.MFnNumericData.kFloat)

    # message attributes
    fn_message = oMa.MFnMessageAttribute()
    SeamlessFkIk.fk_01_mobj = fn_message.create("fk01", "fk01")
    SeamlessFkIk.fk_02_mobj = fn_message.create("fk02", "fk02")
    SeamlessFkIk.fk_03_mobj = fn_message.create("fk03", "fk03")
    SeamlessFkIk.ik_main_mobj = fn_message.create("ikMain", "ikm")
    SeamlessFkIk.ik_pole_mobj = fn_message.create("ikPole", "ikp")

    # add attributes
    SeamlessFkIk.addAttribute(SeamlessFkIk.thigh_len_mobj)
    SeamlessFkIk.addAttribute(SeamlessFkIk.shin_len_mobj)

    SeamlessFkIk.addAttribute(SeamlessFkIk.fk_01_mobj)
    SeamlessFkIk.addAttribute(SeamlessFkIk.fk_02_mobj)
    SeamlessFkIk.addAttribute(SeamlessFkIk.fk_03_mobj)
    SeamlessFkIk.addAttribute(SeamlessFkIk.ik_main_mobj)
    SeamlessFkIk.addAttribute(SeamlessFkIk.ik_pole_mobj)
Esempio n. 2
0
def createSrcMsgAttr(longName, shortName):
    """Create a source (a.k.a. output, or readable) message attribute."""
    msgAttrFn = OpenMaya.MFnMessageAttribute()
    attr = msgAttrFn.create(longName, shortName)
    msgAttrFn.writable = False
    msgAttrFn.storable = False
    return attr
Esempio n. 3
0
def _addOutputControls(obj, side):
    '''
    Adds attributes to card for tracking the created controls.  Used in conjunction
    with OutputControls.
    
    :param PyNode obj: The card to add attributes to
    :param str side: Either "Left", "Right" or "Center"
    '''
    if obj.hasAttr('output' + side):
        return

    mobj = core.capi.asMObject(obj)
    cattr = OpenMaya.MFnCompoundAttribute()
    mattr = OpenMaya.MFnMessageAttribute()
    nattr = OpenMaya.MFnNumericAttribute()

    extraNodes = cattr.create('output' + side, 'out' + side[0])
    cattr.array = True

    link = mattr.create('outputLink' + side, 'ol' + side[0])
    type = nattr.create('out' + side + 'Type', 'o' + side[0] + 't',
                        OpenMaya.MFnNumericData.kInt, 0)

    cattr.addChild(link)
    cattr.addChild(type)

    mobj.addAttribute(extraNodes)
Esempio n. 4
0
def _addSeqAttr(obj):
    '''
    Add `.sequence` attribute to a Script node to enable the custom Sequence api.
    Safe to run repeatedly since it only adds required attrs.
    '''
    if not obj:
        return

    if not obj.hasAttr('sequence'):
        mobj = core.capi.asMObject(obj)
        cattr = OpenMaya.MFnCompoundAttribute()
        nattr = OpenMaya.MFnNumericAttribute()
        tattr = OpenMaya.MFnTypedAttribute()
        mattr = OpenMaya.MFnMessageAttribute()

        sequence = cattr.create("sequence", 'seq')
        cattr.array = True

        for long, short, type in _dataSequenceAttr:
            if type is OpenMaya.MFnStringData.kString:
                newAttr = tattr.create(long, short, type)
            elif type is OpenMaya.MFnNumericData.kInt:
                newAttr = nattr.create(long, short, type, 0)
            elif type == 'message':
                newAttr = mattr.create(long, short)

            cattr.addChild(newAttr)

        mobj.addAttribute(sequence)

    if not obj.hasAttr('animNotes'):
        obj.addAttr('animNotes', dt='string')
        obj.animNotes.set('')
Esempio n. 5
0
def createDstMsgAttr(longName, shortName):
    """Create a destination (a.k.a. input, or writable) message attribute."""
    msgAttrFn = OpenMaya.MFnMessageAttribute()
    attr = msgAttrFn.create(longName, shortName)
    msgAttrFn.writable = True
    # Since message attributes carry no data, does storable mean anything?
    msgAttrFn.storable = True
    return attr
Esempio n. 6
0
    def parseMessageAttribute(self, name, shortName, attrInfo):
        """
		Given a JSON subsection describing a message attribute create the
		attribute and set all of the provided flags/members for it.
			name = Attribute long name
			shortName = Attribute short name
			attrInfo = JSON object containing the main attribute information
		"""
        jsonDebug('parseMessageAttribute(%s)' % name)
        mAttr = omAPI.MFnMessageAttribute()

        jsonDebug('Creating message attribute')
        attr = mAttr.create(name, shortName)

        return attr
Esempio n. 7
0
def addJointArrayAttr(obj):
    '''
    .. todo:: Eventually this should be abstracted.
    '''

    mobj = core.capi.asMObject(obj)

    cAttr = OpenMaya.MFnCompoundAttribute()
    mList = cAttr.create('joints', 'jnts')
    cAttr.array = True

    mAttr = OpenMaya.MFnMessageAttribute()
    jMsg = mAttr.create('jmsg', 'jmsg')

    cAttr.addChild(jMsg)

    mobj.addAttribute(mList)
Esempio n. 8
0
    def initialize():
        unitFn = om.MFnUnitAttribute()
        numericFn = om.MFnNumericAttribute()
        enumFn = om.MFnEnumAttribute()
        messageFn = om.MFnMessageAttribute()

        ######VECTOR
        drawVector.sourcePt = numericFn.createPoint('sourcePoint', 'sp')
        drawVector.aimPt = numericFn.createPoint('aimPoint', 'ap')
        drawVector.drawMessage = messageFn.create('drawMessage', 'drawMessage')
        drawVector.lineColor = numericFn.createColor('color', 'color')
        drawVector.lineWidth = numericFn.create('width', 'width',
                                                om.MFnNumericData.kFloat, 2.0)

        ######VECTOR
        om.MPxNode.addAttribute(drawVector.sourcePt)
        om.MPxNode.addAttribute(drawVector.aimPt)
        om.MPxNode.addAttribute(drawVector.drawMessage)
        om.MPxNode.addAttribute(drawVector.lineColor)
        om.MPxNode.addAttribute(drawVector.lineWidth)
Esempio n. 9
0
    def initialize(cls):
        nAttr = OpenMaya.MFnNumericAttribute()
        tAttr = OpenMaya.MFnTypedAttribute()
        enumAttr = OpenMaya.MFnEnumAttribute()
        compAttr = OpenMaya.MFnCompoundAttribute()
        matrixAttr = OpenMaya.MFnMatrixAttribute()
        messageAttr = OpenMaya.MFnMessageAttribute()

        cls.boundingBoxCorner1 = nAttr.create("boundingBoxCorner1", "bb1", OpenMaya.MFnNumericData.k3Double, 0)
        nAttr.keyable = False
        cls.addAttribute(cls.boundingBoxCorner1)
        cls.boundingBoxCorner2 = nAttr.create("boundingBoxCorner2", "bb2", OpenMaya.MFnNumericData.k3Double, 0)
        nAttr.keyable = False
        cls.addAttribute(cls.boundingBoxCorner2)

        cls.forgeID = tAttr.create("forgeID", "fid", OpenMaya.MFnData.kString, OpenMaya.MObject.kNullObj)
        cls.addAttribute(cls.forgeID)

        cls.handleMatrix = matrixAttr.create("handleMatrix", "hm", OpenMaya.MFnMatrixAttribute.kDouble)
        cls.addAttribute(cls.handleMatrix)

        cls.guideInverseScale = nAttr.create("guideInverseScale", "gis", OpenMaya.MFnNumericData.k3Double, 1.0)
        cls.addAttribute(cls.guideInverseScale)

        cls.guide = messageAttr.create("guide", "g")
        cls.addAttribute(cls.guide)

        cls.parentHandle = messageAttr.create("parentHandle", "ph")
        cls.addAttribute(cls.parentHandle)

        cls.parentHandleMatrix = matrixAttr.create("parentHandleMatrix", "phm", OpenMaya.MFnMatrixAttribute.kDouble)
        cls.addAttribute(cls.parentHandleMatrix)

        cls.childHandle = messageAttr.create("childHandle", "ch")
        messageAttr.array = True
        cls.addAttribute(cls.childHandle)

        cls.childHandleMatrix = matrixAttr.create("childHandleMatrix", "chm", OpenMaya.MFnMatrixAttribute.kDouble)
        matrixAttr.array = True
        cls.addAttribute(cls.childHandleMatrix)

        cls.orientTarget = messageAttr.create("orientTarget", "ot")
        cls.addAttribute(cls.orientTarget)

        cls.orientTargetMatrix = matrixAttr.create("orientTargetMatrix", "otm", OpenMaya.MFnMatrixAttribute.kDouble)
        cls.addAttribute(cls.orientTargetMatrix)

        cls.childPosition = nAttr.create("childPosition", "cpos", OpenMaya.MFnNumericData.k3Double, 0)
        nAttr.array = True
        nAttr.usesArrayDataBuilder = True
        cls.addAttribute(cls.childPosition)

        cls.jointRotateOrder = enumAttr.create("jointRotateOrder", "jro", 0)
        enumAttr.addField("xyz", 0)
        enumAttr.addField("yzx", 1)
        enumAttr.addField("zxy", 2)
        enumAttr.addField("xzy", 3)
        enumAttr.addField("yxz", 4)
        enumAttr.addField("zyx", 5)
        enumAttr.keyable = False
        cls.addAttribute(cls.jointRotateOrder)

        cls.jointSide = enumAttr.create("jointSide", "js", 0)
        enumAttr.addField("center", 0)
        enumAttr.addField("left", 1)
        enumAttr.addField("right", 2)
        enumAttr.addField("none", 3)
        enumAttr.keyable = True
        cls.addAttribute(cls.jointSide)

        cls.jointExcludeFromBind = nAttr.create("jointExcludeFromBind", "jeb", OpenMaya.MFnNumericData.kBoolean, 0)
        cls.addAttribute(cls.jointExcludeFromBind)

        cls.aimAxis = enumAttr.create("aimAxis", "aa", 0)
        enumAttr.addField("X", 0)
        enumAttr.addField("Y", 1)
        enumAttr.addField("Z", 2)
        enumAttr.addField("-X", 3)
        enumAttr.addField("-Y", 4)
        enumAttr.addField("-Z", 5)
        enumAttr.keyable = False
        cls.addAttribute(cls.aimAxis)

        cls.upAxis = enumAttr.create("upAxis", "ua", 2)
        enumAttr.addField("X", 0)
        enumAttr.addField("Y", 1)
        enumAttr.addField("Z", 2)
        enumAttr.addField("-X", 3)
        enumAttr.addField("-Y", 4)
        enumAttr.addField("-Z", 5)
        enumAttr.keyable = False
        cls.addAttribute(cls.upAxis)

        cls.aimVector = nAttr.create("aimVector", "av", OpenMaya.MFnNumericData.k3Double)
        cls.addAttribute(cls.aimVector)

        cls.upVector = nAttr.create("upVector", "uv", OpenMaya.MFnNumericData.k3Double)
        cls.addAttribute(cls.upVector)

        cls.useGuideAim = nAttr.create("useGuideAim", "uga", OpenMaya.MFnNumericData.kBoolean)
        cls.addAttribute(cls.useGuideAim)

        cls.jointMatrix = matrixAttr.create("jointMatrix", "jm", OpenMaya.MFnMatrixAttribute.kDouble)
        cls.addAttribute(cls.jointMatrix)

        cls.handleColor = nAttr.createColor("handleColor", "hc")
        cls.addAttribute(cls.handleColor)

        cls.handleStyle = enumAttr.create("handleStyle", "hs", 0)
        enumAttr.addField("basic", 0)
        enumAttr.addField("spine", 1)
        enumAttr.addField("limb", 2)
        enumAttr.addField("limb base", 3)
        enumAttr.addField("limb hinge", 4)
        enumAttr.addField("limb end", 5)
        enumAttr.addField("free", 6)
        enumAttr.addField("world", 7)
        cls.addAttribute(cls.handleStyle)

        cls.attributeAffects(cls.handleMatrix, cls.boundingBoxCorner1)
        cls.attributeAffects(cls.handleMatrix, cls.boundingBoxCorner2)
        cls.attributeAffects(cls.handleMatrix, cls.childPosition)
        cls.attributeAffects(cls.childHandleMatrix, cls.boundingBoxCorner1)
        cls.attributeAffects(cls.childHandleMatrix, cls.boundingBoxCorner2)
        cls.attributeAffects(cls.childHandleMatrix, cls.childPosition)
        cls.attributeAffects(cls.handleStyle, cls.boundingBoxCorner1)
        cls.attributeAffects(cls.handleStyle, cls.boundingBoxCorner2)

        cls.attributeAffects(cls.handleMatrix, cls.jointMatrix)
        cls.attributeAffects(cls.orientTargetMatrix, cls.jointMatrix)
        cls.attributeAffects(cls.parentHandleMatrix, cls.jointMatrix)
        cls.attributeAffects(cls.aimAxis, cls.jointMatrix)
        cls.attributeAffects(cls.upAxis, cls.jointMatrix)
        cls.attributeAffects(cls.aimVector, cls.jointMatrix)
        cls.attributeAffects(cls.upVector, cls.jointMatrix)
        cls.attributeAffects(cls.useGuideAim, cls.jointMatrix)
Esempio n. 10
0
    def initialize(cls):
        nAttr = OpenMaya.MFnNumericAttribute()
        tAttr = OpenMaya.MFnTypedAttribute()
        uAttr = OpenMaya.MFnUnitAttribute()
        enumAttr = OpenMaya.MFnEnumAttribute()
        compAttr = OpenMaya.MFnCompoundAttribute()
        matrixAttr = OpenMaya.MFnMatrixAttribute()
        messageAttr = OpenMaya.MFnMessageAttribute()

        cls.forgeID = tAttr.create("forgeID", "fid", OpenMaya.MFnData.kString,
                                   OpenMaya.MObject.kNullObj)
        cls.addAttribute(cls.forgeID)

        cls.guideMatrix = matrixAttr.create(
            "guideMatrix", "gm", OpenMaya.MFnMatrixAttribute.kDouble)
        cls.addAttribute(cls.guideMatrix)

        cls.handleInverseScale = nAttr.create("handleInverseScale", "his",
                                              OpenMaya.MFnNumericData.k3Double,
                                              1.0)
        cls.addAttribute(cls.handleInverseScale)

        cls.boundingBoxCorner1 = nAttr.create("boundingBoxCorner1", "bb1",
                                              OpenMaya.MFnNumericData.k3Double,
                                              0)
        nAttr.keyable = False
        cls.addAttribute(cls.boundingBoxCorner1)
        cls.boundingBoxCorner2 = nAttr.create("boundingBoxCorner2", "bb2",
                                              OpenMaya.MFnNumericData.k3Double,
                                              0)
        nAttr.keyable = False
        cls.addAttribute(cls.boundingBoxCorner2)

        cls.aimAxis = enumAttr.create("aimAxis", "aa", 0)
        enumAttr.addField("X", 0)
        enumAttr.addField("Y", 1)
        enumAttr.addField("Z", 2)
        enumAttr.addField("-X", 3)
        enumAttr.addField("-Y", 4)
        enumAttr.addField("-Z", 5)
        enumAttr.keyable = False
        cls.addAttribute(cls.aimAxis)

        cls.upAxis = enumAttr.create("upAxis", "ua", 2)
        enumAttr.addField("X", 0)
        enumAttr.addField("Y", 1)
        enumAttr.addField("Z", 2)
        enumAttr.addField("-X", 3)
        enumAttr.addField("-Y", 4)
        enumAttr.addField("-Z", 5)
        enumAttr.keyable = False
        cls.addAttribute(cls.upAxis)

        cls.aimVector = nAttr.create("aimVector", "av",
                                     OpenMaya.MFnNumericData.k3Double)
        cls.addAttribute(cls.aimVector)

        cls.upVector = nAttr.create("upVector", "uv",
                                    OpenMaya.MFnNumericData.k3Double)
        cls.addAttribute(cls.upVector)

        cls.provideAimVector = nAttr.create("provideAimVector", "pav",
                                            OpenMaya.MFnNumericData.kBoolean,
                                            0)
        cls.addAttribute(cls.provideAimVector)

        cls.handle = messageAttr.create("handle", "hndl")
        messageAttr.array = True
        cls.addAttribute(cls.handle)

        cls.handleColor = nAttr.createColor("handleColor", "hc")
        cls.addAttribute(cls.handleColor)

        cls.parentGuide = messageAttr.create("parentGuide", "pg")
        cls.addAttribute(cls.parentGuide)

        cls.parentGuideHandleIndex = nAttr.create(
            "parentGuideHandleIndex", "pghi", OpenMaya.MFnNumericData.kShort,
            -1)
        cls.addAttribute(cls.parentGuideHandleIndex)

        cls.childGuide = messageAttr.create("childGuide", "cg")
        cls.addAttribute(cls.childGuide)

        cls.attributeAffects(cls.guideMatrix, cls.boundingBoxCorner1)
        cls.attributeAffects(cls.guideMatrix, cls.boundingBoxCorner2)
        cls.attributeAffects(cls.guideMatrix, cls.handleInverseScale)
        cls.attributeAffects(cls.guideMatrix, cls.aimVector)
        cls.attributeAffects(cls.guideMatrix, cls.upVector)
Esempio n. 11
0
class Plug(object):
    ''' 
    Helper class to allow seamless value assignment from one plug to another, 
    while correctly handling and abstracting away plug type.

    "self.type" returns the type of the plug.
        This is necessary to determine how to read and write the plug.
    "self.value" returns the value of the plug.
    "self.value = otherValue" will set the value of the plug to otherValue.
        This mutator assumes otherValue to be the same type as self.type

    "self.overrideType" returns the type of the override that should be created to override this plug.
    '''

    # Plug types
    kInvalid = 0
    kFloat = 1
    kDouble = 2
    kInt = 3
    kByte = 4
    kBool = 5
    kColor = 6
    kEnum = 7
    kString = 8
    kObject = 9
    kMessage = 10
    kTime = 11
    kAngle = 12
    kDistance = 13
    kArray = 14
    kLast = 15

    _simpleOvrSupportedTypes = set([
        kFloat, kDouble, kInt, kByte, kBool, kColor, kEnum, kString, kTime,
        kAngle, kDistance
    ])
    _simpleNumericTypes = set(
        [kFloat, kDouble, kInt, kByte, kAngle, kDistance])

    @staticmethod
    def _isVector(type):
        # type is a vector type if it's a list and it has 2 or 3 homogeneous "simple numeric" elements
        # kTime is deliberately excluded, see create method in doc for explanation
        # http://help.autodesk.com/view/MAYAUL/2016/ENU/?guid=__cpp_ref_class_m_fn_numeric_attribute_html
        return isinstance(type, list) and len(type) <= 3 and (len(
            set(type)) == 1) and type[0] in Plug._simpleNumericTypes

    @staticmethod
    def _isOvrSupported(type):
        return Plug._isVector(type) if isinstance(
            type, list) else type in Plug._simpleOvrSupportedTypes

    _accessors = {
        kInvalid: lambda plug: None,
        kFloat: lambda plug: plug._getPlugValue(OpenMaya.MPlug.asFloat),
        kDouble: lambda plug: plug._getPlugValue(OpenMaya.MPlug.asDouble),
        kInt: lambda plug: plug._getPlugValue(OpenMaya.MPlug.asInt),
        kBool: lambda plug: plug._getPlugValue(OpenMaya.MPlug.asBool),
        kByte: lambda plug: plug._getPlugValue(OpenMaya.MPlug.asChar),
        kColor: lambda plug: plug._getCompound(),
        kEnum: lambda plug: plug._getPlugValue(OpenMaya.MPlug.asShort),
        kString: lambda plug: plug._getPlugValue(OpenMaya.MPlug.asString),
        kObject: lambda plug: plug._getObject(),
        kMessage: lambda plug: None,
        kTime: lambda plug: plug._getTime(),
        kAngle: lambda plug: plug._getPlugValue(
            OpenMaya.MPlug.asDouble),  # get the value in internal units
        kDistance: lambda plug: plug._getPlugValue(
            OpenMaya.MPlug.asDouble),  # get the value in internal units
        kArray: lambda plug: plug._getArray()
    }

    @staticmethod
    def _accessor(type):
        return (lambda plug: plug._getCompound()) if isinstance(
            type, list) else Plug._accessors[type]

    _mutators = {
        kInvalid:
        lambda plug, value: None,
        kFloat:
        lambda plug, value: plug._setPlugValue(
            OpenMaya.MDGModifier.newPlugValueFloat, value),
        kDouble:
        lambda plug, value: plug._setPlugValue(
            OpenMaya.MDGModifier.newPlugValueDouble, value),
        kInt:
        lambda plug, value: plug._setPlugValue(
            OpenMaya.MDGModifier.newPlugValueInt, int(round(value))),
        kBool:
        lambda plug, value: plug._setPlugValue(
            OpenMaya.MDGModifier.newPlugValueBool, bool(round(value))),
        kByte:
        lambda plug, value: plug._setPlugValue(
            OpenMaya.MDGModifier.newPlugValueChar, int(round(value))),
        kColor:
        lambda plug, value: plug._setCompound(value),
        kEnum:
        lambda plug, value: plug._setPlugValue(
            OpenMaya.MDGModifier.newPlugValueInt, int(round(value))),
        kString:
        lambda plug, value: plug._setPlugValue(
            OpenMaya.MDGModifier.newPlugValueString, value),
        kObject:
        lambda plug, value: plug._setObject(value),
        kMessage:
        lambda plug, value: None,
        kTime:
        lambda plug, value: plug._setTime(value),
        kAngle:
        lambda plug, value: plug._setPlugValue(
            OpenMaya.MDGModifier.newPlugValueDouble, value
        ),  # set the value in internal units
        kDistance:
        lambda plug, value: plug._setPlugValue(
            OpenMaya.MDGModifier.newPlugValueDouble, value
        ),  # set the value in internal units
        kArray:
        lambda plug, value: plug._setArray(value)
    }

    @staticmethod
    def _mutator(type):
        return (lambda plug, value: plug._setCompound(value)) if isinstance(
            type, list) else Plug._mutators[type]

    _creators = {
        kFloat:
        (OpenMaya.MFnNumericAttribute,
         lambda longName, shortName: OpenMaya.MFnNumericAttribute().create(
             longName, shortName, OpenMaya.MFnNumericData.kFloat)),
        kDouble:
        (OpenMaya.MFnNumericAttribute,
         lambda longName, shortName: OpenMaya.MFnNumericAttribute().create(
             longName, shortName, OpenMaya.MFnNumericData.kDouble)),
        kInt: (OpenMaya.MFnNumericAttribute,
               lambda longName, shortName: OpenMaya.MFnNumericAttribute(
               ).create(longName, shortName, OpenMaya.MFnNumericData.kInt)),
        kBool: (OpenMaya.MFnNumericAttribute,
                lambda longName, shortName: OpenMaya.MFnNumericAttribute().
                create(longName, shortName, OpenMaya.MFnNumericData.kBoolean)),
        kByte: (OpenMaya.MFnNumericAttribute,
                lambda longName, shortName: OpenMaya.MFnNumericAttribute(
                ).create(longName, shortName, OpenMaya.MFnNumericData.kChar)),
        kColor:
        (OpenMaya.MFnNumericAttribute, lambda longName, shortName: OpenMaya.
         MFnNumericAttribute().createColor(longName, shortName)),
        kEnum: (OpenMaya.MFnEnumAttribute, lambda longName, shortName: OpenMaya
                .MFnEnumAttribute().create(longName, shortName)),
        kString: (OpenMaya.MFnTypedAttribute,
                  lambda longName, shortName: OpenMaya.MFnTypedAttribute(
                  ).create(longName, shortName, OpenMaya.MFnData.kString)),
        kMessage: (OpenMaya.MFnMessageAttribute, lambda longName, shortName:
                   OpenMaya.MFnMessageAttribute().create(longName, shortName)),
        kTime: (OpenMaya.MFnUnitAttribute,
                lambda longName, shortName: OpenMaya.MFnUnitAttribute().create(
                    longName, shortName, OpenMaya.MFnUnitAttribute.kTime)),
        kAngle:
        (OpenMaya.MFnUnitAttribute,
         lambda longName, shortName: OpenMaya.MFnUnitAttribute().create(
             longName, shortName, OpenMaya.MFnUnitAttribute.kAngle)),
        kDistance:
        (OpenMaya.MFnUnitAttribute,
         lambda longName, shortName: OpenMaya.MFnUnitAttribute().create(
             longName, shortName, OpenMaya.MFnUnitAttribute.kDistance)),
        kObject: (None, None),
        kArray: (None, None)
    }

    @staticmethod
    def _creator(type):
        if isinstance(type, list):
            # compound type -> create a recursive creator
            childrenCreators = [Plug._creator(t) for t in type]

            def creator(longName, shortName):
                children = [
                    creator(longName + str(i), shortName + str(i))
                    for (i, (fnclass, creator)) in enumerate(childrenCreators)
                ]
                if Plug._isVector(type):
                    # special case for compound of homogeneous numeric or unit types
                    # using MFnCompoundAttribute is not enough as maya won't create
                    # unitConversion nodes on plug parent on connection in this case
                    # We need to create a MFnNumericAttribute to solve that
                    args = [longName, shortName] + children
                    obj = OpenMaya.MFnNumericAttribute().create(*args)
                else:
                    obj = OpenMaya.MFnCompoundAttribute().create(
                        longName, shortName)
                    attr = OpenMaya.MFnCompoundAttribute(obj)
                    for child in children:
                        attr.addChild(child)
                return obj

            return (OpenMaya.MFnCompoundAttribute, creator)
        return Plug._creators[type]

    _numericToPlugTypes = {
        OpenMaya.MFnNumericData.kFloat: kFloat,
        OpenMaya.MFnNumericData.kDouble: kDouble,
        OpenMaya.MFnNumericData.kInt: kInt,
        OpenMaya.MFnNumericData.kShort: kInt,
        OpenMaya.MFnNumericData.kLong: kInt,
        OpenMaya.MFnNumericData.kBoolean: kBool,
        OpenMaya.MFnNumericData.kByte: kByte,
        OpenMaya.MFnNumericData.kChar: kByte,
    }

    _unitToPlugTypes = {
        OpenMaya.MFnUnitAttribute.kTime: kTime,
        OpenMaya.MFnUnitAttribute.kAngle: kAngle,
        OpenMaya.MFnUnitAttribute.kDistance: kDistance
    }

    # MAYA-66685: remove this table and its associated static function (below)
    # it won't be needed anymore when we remove relative override's children classes
    # and adapt the overrideType(self, overrideType) method accordingly
    _typesToOverrideTypes = {
        kFloat: [typeIDs.absOverride, typeIDs.relOverride],
        kDouble: [typeIDs.absOverride, typeIDs.relOverride],
        kInt: [typeIDs.absOverride, typeIDs.relOverride],
        kBool: [typeIDs.absOverride, typeIDs.absOverride],
        kByte: [typeIDs.absOverride, typeIDs.relOverride],
        kColor: [typeIDs.absOverride, typeIDs.relOverride],
        kEnum: [typeIDs.absOverride, typeIDs.absOverride],
        kString: [typeIDs.absOverride, typeIDs.absOverride],
        kTime: [typeIDs.absOverride, typeIDs.relOverride],
        kAngle: [typeIDs.absOverride, typeIDs.relOverride],
        kDistance: [typeIDs.absOverride, typeIDs.relOverride]
    }

    @staticmethod
    def _typeToOverrideType(type):
        vecDict = {
            2: [typeIDs.absOverride, typeIDs.relOverride],
            3: [typeIDs.absOverride, typeIDs.relOverride]
        }
        return vecDict[len(type)] if Plug._isVector(
            type) else Plug._typesToOverrideTypes[type]

    _typesToApplyOverrideTypes = {
        kFloat: [typeIDs.applyAbsFloatOverride, typeIDs.applyRelFloatOverride],
        kDouble:
        [typeIDs.applyAbsFloatOverride, typeIDs.applyRelFloatOverride],
        kInt: [typeIDs.applyAbsIntOverride, typeIDs.applyRelIntOverride],
        kBool: [typeIDs.applyAbsBoolOverride, typeIDs.applyAbsBoolOverride],
        kByte: [typeIDs.applyAbsIntOverride, typeIDs.applyRelIntOverride],
        kColor:
        [typeIDs.applyAbs3FloatsOverride, typeIDs.applyRel3FloatsOverride],
        kEnum: [typeIDs.applyAbsEnumOverride, typeIDs.applyAbsEnumOverride],
        kString:
        [typeIDs.applyAbsStringOverride, typeIDs.applyAbsStringOverride],
        kTime: [typeIDs.applyAbsFloatOverride, typeIDs.applyRelFloatOverride],
        kAngle: [typeIDs.applyAbsFloatOverride, typeIDs.applyRelFloatOverride],
        kDistance:
        [typeIDs.applyAbsFloatOverride, typeIDs.applyRelFloatOverride]
    }

    @staticmethod
    def _typeToApplyOverrideType(type):
        vecDict = {
            2:
            [typeIDs.applyAbs2FloatsOverride, typeIDs.applyRel2FloatsOverride],
            3:
            [typeIDs.applyAbs3FloatsOverride, typeIDs.applyRel3FloatsOverride]
        }
        return vecDict[len(type)] if Plug._isVector(
            type) else Plug._typesToApplyOverrideTypes[type]

    _typesToStrings = {
        kInvalid: "Invalid",
        kFloat: "Float",
        kDouble: "Double",
        kInt: "Int",
        kByte: "Byte",
        kBool: "Bool",
        kColor: "Color",
        kEnum: "Enum",
        kString: "String",
        kObject: "Object",
        kMessage: "Message",
        kTime: "Time",
        kAngle: "Angle",
        kDistance: "Distance",
        kArray: "Array"
    }

    @staticmethod
    def _typeToString(type):
        return [Plug._typeToString(t) for t in type] if isinstance(
            type, list) else Plug._typesToStrings[type]

    _stringsToTypes = {v: k for k, v in _typesToStrings.items()}

    @staticmethod
    def _stringToType(string):
        return [Plug._stringToType(s) for s in string] if isinstance(
            string, list) else Plug._stringsToTypes[string]

    _typesToLocalizedStrings = {
        kInvalid: maya.stringTable['y_plug.kInvalid'],
        kFloat: maya.stringTable['y_plug.kFloat'],
        kDouble: maya.stringTable['y_plug.kDouble'],
        kInt: maya.stringTable['y_plug.kInt'],
        kByte: maya.stringTable['y_plug.kByte'],
        kBool: maya.stringTable['y_plug.kBool'],
        kColor: maya.stringTable['y_plug.kColor'],
        kEnum: maya.stringTable['y_plug.kEnum'],
        kString: maya.stringTable['y_plug.kString'],
        kObject: maya.stringTable['y_plug.kObject'],
        kMessage: maya.stringTable['y_plug.kMessage'],
        kTime: maya.stringTable['y_plug.kTime'],
        kAngle: maya.stringTable['y_plug.kAngle'],
        kDistance: maya.stringTable['y_plug.kDistance'],
        kArray: maya.stringTable['y_plug.kArray']
    }

    @staticmethod
    def _typeToLocalizedString(type):
        if isinstance(type, list):
            return kCompoundTypeStr if not Plug._isVector(type) else \
                   kVectorTypeStr % (len(type), Plug._typesToLocalizedStrings[type[0]])
        return Plug._typesToLocalizedStrings[type]

    # Types with a function set supporting min/max limits
    _limitTypes = set([kFloat, kDouble, kInt, kByte, kTime, kAngle, kDistance])

    @staticmethod
    def _hasLimits(type):
        return not isinstance(type, list) and type in Plug._limitTypes

    def __init__(self, plugOrNode, attrName=None):
        """ Constructors:
             Plug(MPlug)
             Plug(string (full plug name))
             Plug(MObject, MObject)
             Plug(MObject, string (attribute name))
             Plug(string (node name), string (attribute name))
        """
        if isinstance(plugOrNode, OpenMaya.MPlug):
            # Plug(MPlug)
            self._plug = plugOrNode
        elif attrName is None:
            self._plug = commonUtils.nameToPlug(plugOrNode)
        else:
            self._plug = commonUtils.findPlug(plugOrNode, attrName)

        if self._plug is not None:
            # There is no consistency around the node name (i.e. child node names)
            # and the attribute name (i.e. long vs. short names and compound names)
            # between the various API methods. To avoid different names, Plug is now always using
            # the same API methods.
            self._nodeName = commonUtils.nodeToLongName(self._plug.node())
            self._attributeName = self._plug.partialName(
                includeInstancedIndices=True, useLongNames=True)
            self._name = self._nodeName + '.' + self._attributeName

        self._type = None if self._plug else Plug.kInvalid

    def copyValue(self, other):
        """ Sets the value of plug 'self' to the value contained in plug 'other' 
            The 'other' plug can be either a Plug or a MPlug.
        """
        # MAYA-66652: more tests with generic attributes vs non generic attributes copies
        if isinstance(other, OpenMaya.MPlug):
            other = Plug(other)
        if other.plug.isCompound and not self.plug.isCompound:
            # We cannot do recursive get/set since 'self' has no children
            # Try to read 'other' as MObject and set it to dst
            # This is valid for example if 'self' is generic and accepts 'other' data type
            self._type = Plug.kObject
            self.value = other._getObject()
        else:
            self.uiUnitValue = other.uiUnitValue

    @staticmethod
    def getNames(plugName):
        pos = plugName.find('.')
        return (plugName[:pos], plugName[pos + 1:])

    @property
    def name(self):
        return self._name

    @property
    def attributeName(self):
        return self._attributeName

    @property
    def nodeName(self):
        return self._nodeName

    @property
    def plug(self):
        return self._plug

    def node(self):
        return self._plug.node()

    def isOvrSupported(self):
        return Plug._isOvrSupported(self.type)

    def overrideType(self, overType):
        if not self.isOvrSupported():
            raise RuntimeError(
                kNotOverridablePlug %
                (self.plug.name(), str(Plug._typeToString(self.type))))
        return Plug._typeToOverrideType(
            self.type)[0 if overType == typeIDs.absOverride else 1]

    def applyOverrideType(self, overType):
        if not self.isOvrSupported():
            raise RuntimeError(
                kNotOverridablePlug %
                (self.plug.name(), str(Plug._typeToString(self.type))))
        return Plug._typeToApplyOverrideType(
            self.type)[0 if overType == typeIDs.absOverride else 1]

    @property
    def uiUnitValue(self):
        return toUiUnits(self.type, self.value)

    @uiUnitValue.setter
    def uiUnitValue(self, value):
        self.value = toInternalUnits(self.type, value)

    @property
    def value(self):
        return Plug._accessor(self.type)(self)

    @value.setter
    def value(self, value):
        # Check that plug parent and children are settable.
        # Otherwise the DGModifier fails to write value
        plug = self.plug
        if plug.isChild and plug.parent().isDestination:
            raise RuntimeError(kPlugHasConnectedParent % self.name)
        if plug.isCompound and plug.numConnectedChildren() != 0:
            for i in range(0, self.plug.numChildren()):
                if not isSettable(self.plug.child(i)):
                    raise RuntimeError(kPlugHasNotSettableChild % self.name)
        Plug._mutator(self.type)(self, value)

    def parent(self):
        return Plug(self.plug.parent()) if self.plug.isChild else None

    def children(self):
        if not self.plug.isCompound:
            return
        for i in xrange(0, self.plug.numChildren()):
            yield Plug(self.plug.child(i))

    @property
    def type(self):
        # Lazy evaluate
        if self._type is None:
            plug = self.plug
            attr = plug.attribute()

            if attr.hasFn(OpenMaya.MFn.kMessageAttribute):
                self._type = Plug.kMessage

            elif plug.isArray:
                self._type = Plug.kArray

            elif attr.hasFn(OpenMaya.MFn.kCompoundAttribute):
                self._type = Plug.kColor if OpenMaya.MFnAttribute(attr).usedAsColor else \
                             [ child.type for child in self._children() ]

            elif attr.hasFn(OpenMaya.MFn.kNumericAttribute):
                self._type = Plug._numericToPlugTypes.get(
                    OpenMaya.MFnNumericAttribute(attr).numericType(),
                    Plug.kInvalid)

            elif attr.hasFn(OpenMaya.MFn.kTypedAttribute):
                dataType = OpenMaya.MFnTypedAttribute(attr).attrType()
                if dataType == OpenMaya.MFnData.kString:
                    self._type = Plug.kString
                else:
                    self._type = Plug.kInvalid

            elif attr.hasFn(OpenMaya.MFn.kEnumAttribute):
                self._type = Plug.kEnum

            elif attr.hasFn(OpenMaya.MFn.kUnitAttribute):
                self._type = Plug._unitToPlugTypes.get(
                    OpenMaya.MFnUnitAttribute(attr).unitType(), Plug.kInvalid)

            elif attr.hasFn(OpenMaya.MFn.kGenericAttribute):
                handle = plug.asMDataHandle()
                isGeneric, isGenericNumeric, isGenericNull = handle.isGeneric()
                if isGeneric and isGenericNumeric:
                    # It's a generic simple attribute.
                    # According to docs there is no method to check the type
                    # of a generic simple attribute:
                    # http://help.autodesk.com/view/MAYAUL/2016/ENU/?guid=__cpp_ref_class_m_data_handle_html
                    # So always return as double here
                    self._type = Plug.kDouble
                elif not isGenericNull:
                    obj = handle.data()
                    if obj.hasFn(OpenMaya.MFn.kStringData):
                        self._type = Plug.kString
                    else:
                        # if handle.data() didn't raise an exception,
                        # plug can be read as MObject
                        self._type = Plug.kObject
                else:
                    raise RuntimeError(kUnknownType % self.name)

            else:
                raise RuntimeError(kUnsupportedAttribute % self.name)

        return self._type

    @property
    def isValid(self):
        return self.type != Plug.kInvalid

    def localizedTypeString(self):
        return Plug._typeToLocalizedString(self.type)

    @property
    def isLocked(self):
        """Returns true is plug or plug's children (compound) are locked."""
        plug = self.plug
        if plug.isLocked:
            return True
        elif plug.isCompound:
            for i in range(0, plug.numChildren()):
                if Plug(plug.child(i)).isLocked:
                    return True
        return False

    @property
    def isConnectable(self):
        """Returns true if plug's input can be connected."""
        if not self.attribute().connectable:
            return False

        plug = self.plug
        if plug.isCompound:
            for i in range(0, plug.numChildren()):
                if not Plug(plug.child(i)).isConnectable:
                    return False
        return True

    @property
    def isKeyable(self):
        """Returns true if the plug has the keyable property.

        Note that a plug that does not have this property can still have
        key frames set on it.  As per Maya documentation, a keyable
        attribute means that 'if any of the animation commands (setKeyframe,
        cutKey, copyKey,..) are issued without explicitly specifying any
        attributes with the -at/attribute flag, then the command will
        operate on all keyable attributes of the specified objects'.

        The autoKeyframe functionality also uses the keyable property to
        determine if key frames should be set."""

        return self.attribute().keyable

    def attribute(self):
        """Returns the attribute (MFnAttribute) of the plug """
        return OpenMaya.MFnAttribute(self.plug.attribute())

    def accepts(self, other):
        """Returns true if plug would accept a connection with other plug
           i.e. plug and other plug are type compatible for connection."""
        if isinstance(other, OpenMaya.MPlug):
            other = Plug(other)
        return self.attribute().acceptsAttribute(other.attribute())

    @property
    def isVector(self):
        """ Returns true if the type is a vector type. """
        return Plug._isVector(self.type)

    @property
    def isUnit(self):
        return self._plug.attribute().hasFn(OpenMaya.MFn.kUnitAttribute)

    @property
    def isNumeric(self):
        return self._plug.attribute().hasFn(OpenMaya.MFn.kNumericAttribute)

    @property
    def hasLimits(self):
        """ Returns true if the type supports min/max limits. """
        return Plug._hasLimits(self.type)

    # specialized GETS and SETS
    def _setPlugValue(self, method, value):
        """ Sets the value of the plug to value, using DGModifier specified method """
        dgMod = OpenMaya.MDGModifier()
        method(dgMod, self.plug, value)
        dgMod.doIt()

    def _getPlugValue(self, method):
        """ Gets the value of the plug using MPlug specified method """
        return method(self.plug) if not self.plug.isNull else None

    def _children(self):
        children = [
            Plug(self.plug.child(i)) for i in range(0, self.plug.numChildren())
        ]
        if isinstance(self._type, list):
            # avoid recompute types for children if we already know it from the parent
            for child, t in itertools.izip(children, self.type):
                child._type = t
        return children

    def _getCompound(self):
        return [child.value for child in self._children()]

    def _setCompound(self, value):
        children = self._children()
        if len(children) != len(value):
            raise RuntimeError(kArityMismatch %
                               (self.name, len(children), len(value)))
        for child, val in itertools.izip(children, value):
            child.value = val

    def _getObject(self):
        return self._getPlugValue(OpenMaya.MPlug.asMObject)

    def _setObject(self, value):
        self._setPlugValue(OpenMaya.MDGModifier.newPlugValue, value)

    def _getTime(self):
        return self._getPlugValue(OpenMaya.MPlug.asMTime).asUnits(
            OpenMaya.MTime.k6000FPS)  # internal time units

    def _setTime(self, value):
        """ Sets plug's value to the given time 
            If value is a MTime, set's it directly
            Otherwise, assumes value is given in the same units as the plug's unit type."""
        time = value if isinstance(value, OpenMaya.MTime) \
                else OpenMaya.MTime(value, OpenMaya.MTime.k6000FPS) # internal time units
        self._setPlugValue(OpenMaya.MDGModifier.newPlugValueMTime, time)

    def _getArray(self):
        elements = []
        plug = self.plug
        for i in range(0, plug.numElements()):
            elements.append(Plug(plug.elementByLogicalIndex(i)).value)
        return elements

    def _setArray(self, value):
        plug = self.plug
        n = len(value)

        # clear remaining elements if any
        dgMod = OpenMaya.MDGModifier()
        for i in range(n, plug.numElements()):
            dgMod.removeMultiInstance(plug.elementByLogicalIndex(i), False)
        dgMod.doIt()

        # fill array with new values
        plug.setNumElements(n)
        for i in range(0, n):
            Plug(plug.elementByLogicalIndex(i)).value = value[i]

    def __str__(self):
        return self.name + " (" + Plug._typeToLocalizedString(
            self.type) + ") = " + str(self.value)

    @staticmethod
    def createAttribute(nodeObj,
                        longName,
                        shortName,
                        dict,
                        undoable=kUndoable):
        """ Create a new attribute on a node using the given names and properties dictionary. 
        Returns an MObject to the new attribute. By default, it uses the command 
        addDynamicAttribute (if it's not undoable, use MFnDependencyNode.addAttribute()) 
        to add the returned object as a new dynamic attribute on a node.
        """

        if 'type' not in dict:
            return None

        plugType = Plug._stringToType(dict['type'])
        fnclass, create = Plug._creator(plugType)
        if not (fnclass and create):
            return None

        # Create the attribute and add it to the node with a command if undoable
        # Use the DGModifier if not
        attrObj = create(longName, shortName)
        if undoable == kUndoable:
            AddDynamicAttribute.execute(nodeObj, attrObj)
        else:
            nodeFn = OpenMaya.MFnDependencyNode(nodeObj)
            nodeFn.addAttribute(attrObj)

        # Set all properties from the dictionary
        plg = Plug(nodeObj, attrObj)
        plg._decodeProperties(dict)
        return plg

    def _createAttribute(self,
                         nodeObj,
                         longName,
                         shortName,
                         dict,
                         undoable=kUndoable):
        """See createAttribute documentation for details.

        This method calls createAttribute.  If the created attribute is a
        compound, it additionally copies over the keyable property from the
        original's children to the copy's children."""

        copy = Plug.createAttribute(nodeObj, longName, shortName, dict,
                                    undoable)

        if copy.plug.isCompound:
            for i in xrange(0, copy.plug.numChildren()):
                copy.plug.child(i).isKeyable = self.plug.child(i).isKeyable

        return copy

    def cloneAttribute(self, nodeObj, longName, shortName, undoable=kUndoable):
        """ Creates a new attribute on a node by cloning this plug's attribute.
        Undoable by default """
        dict = {}
        self._encodeProperties(dict)
        return self._createAttribute(nodeObj, longName, shortName, dict,
                                     undoable)

    def createAttributeFrom(self, nodeObj, longName, shortName, limits=None):
        """ Creates a new attribute on a node by cloning this plug's attribute. 
        
            Note: None for a limit value means that there is no limit. For example,
                  if min is None, it means that there is no minimum limit.
        """
        dict = {}
        self._encodeProperties(dict)

        # Adjust the limits
        if limits is not None:
            for (key, value) in limits.items():
                if value is not None:
                    dict[key] = value
                elif key in dict:
                    del dict[key]

        return self._createAttribute(nodeObj, longName, shortName, dict)

    def getAttributeLimits(self):
        """ Get the limits of the plug """
        if self.hasLimits:

            def _get(f, unit):
                return f().value if unit else f()

            unit = self.isUnit
            cls = OpenMaya.MFnUnitAttribute if unit else OpenMaya.MFnNumericAttribute
            fn2 = cls(self._plug.attribute())

            limits = dict()

            limits['min'] = _get(fn2.getMin, unit) if fn2.hasMin() else None
            limits['softMin'] = _get(fn2.getSoftMin,
                                     unit) if fn2.hasSoftMin() else None
            limits['softMax'] = _get(fn2.getSoftMax,
                                     unit) if fn2.hasSoftMax() else None
            limits['max'] = _get(fn2.getMax, unit) if fn2.hasMax() else None

            return limits
        else:
            raise RuntimeError(kPlugWithoutLimits % self.plug.name())

    def _encodeProperties(self, dict):
        """ Encode the properties of this plug's attribute into a dictionary. """

        fn = OpenMaya.MFnAttribute(self._plug.attribute())

        dict['type'] = Plug._typeToString(self.type)
        dict['connectable'] = fn.connectable
        if fn.keyable:
            dict['keyable'] = True
        val = self.value
        if val is not None:
            dict['value'] = val

        if self.hasLimits:
            limits = self.getAttributeLimits()
            # There is no need to save None values
            for (key, value) in limits.items():
                if value is not None:
                    dict[key] = value

        if self.type == Plug.kEnum:
            fn2 = OpenMaya.MFnEnumAttribute(self._plug.attribute())
            enum = {}
            for val in range(fn2.getMin(), fn2.getMax() + 1):
                try:
                    # Need to catch exception here because all values in
                    # range min -> max are not always used, but there is no
                    # way to query the attribute if a value is used or not.
                    # An exception is raised if a value is not used.
                    enum[val] = fn2.fieldName(val)
                except:
                    pass
            dict['enum'] = enum

    def setAttributeLimits(self, limits):
        if self.hasLimits:
            fnclass, create = Plug._creator(self.type)
            fn = fnclass(self._plug.attribute())
            setters = {
                'min': fn.setMin,
                'softMin': fn.setSoftMin,
                'softMax': fn.setSoftMax,
                'max': fn.setMax
            }
            for (key, value) in limits.items():
                if value is not None:
                    setters[key](value)
        else:
            raise RuntimeError(kPlugWithoutLimits % self.plug.name())

    def _decodeProperties(self, dict):
        """ Decode and set the properties from the given dictionary. """

        plugType = Plug._stringToType(dict['type'])
        fnclass, create = Plug._creator(plugType)
        if not (fnclass and create):
            return None

        fn = fnclass(self._plug.attribute())
        fn.connectable = dict['connectable']
        if 'keyable' in dict:
            fn.keyable = dict['keyable']

        if self.hasLimits:
            # To ease the manipulation, the limit keywords for the limits and the properties
            #  are the same. But keep in mind that they are indepdendent.
            self.setAttributeLimits({
                'min':
                float(dict['min']) if 'min' in dict else None,
                'softMin':
                float(dict['softMin']) if 'softMin' in dict else None,
                'softMax':
                float(dict['softMax']) if 'softMax' in dict else None,
                'max':
                float(dict['max']) if 'max' in dict else None
            })

        if plugType == Plug.kEnum and 'enum' in dict:
            enum = dict['enum']
            for val, name in enum.iteritems():
                fn.addField(name, int(val))

        # Set the value if a value is available. For attributes that don't have
        # values, e.g. message attributes, we don't encode any value.
        if 'value' in dict:
            self.value = dict['value']
Esempio n. 12
0
def nodeInitializer():
    '''
    Defines the input and output attributes as static variables in our plug-in class.
    '''

    # The following function set will allow us to create our attributes.
    numericAttributeFn = OpenMaya.MFnNumericAttribute()
    typedAttributeFn = OpenMaya.MFnTypedAttribute()
    messageAttributeFn = OpenMaya.MFnMessageAttribute()
    compoundAttributeFn = OpenMaya.MFnCompoundAttribute()

    #==================================#
    #      INPUT NODE ATTRIBUTE(S)     #
    #==================================#

    #-----------------------------------------#
    #            Focus Iris Zoom              #
    #-----------------------------------------#
    mFIZ_remap.focus_in_attr = numericAttributeFn.create(
        'focus', 'focus', OpenMaya.MFnNumericData.kFloat)
    numericAttributeFn.writable = True
    numericAttributeFn.storable = True
    numericAttributeFn.hidden = False
    numericAttributeFn.setMin(0)
    numericAttributeFn.setMax(1)
    mFIZ_remap.addAttribute(mFIZ_remap.focus_in_attr)

    mFIZ_remap.iris_in_attr = numericAttributeFn.create(
        'iris', 'iris', OpenMaya.MFnNumericData.kFloat)
    numericAttributeFn.writable = True
    numericAttributeFn.storable = True
    numericAttributeFn.hidden = False
    numericAttributeFn.setMin(0)
    numericAttributeFn.setMax(1)
    mFIZ_remap.addAttribute(mFIZ_remap.iris_in_attr)

    mFIZ_remap.zoom_in_attr = numericAttributeFn.create(
        'zoom', 'zoom', OpenMaya.MFnNumericData.kFloat)
    numericAttributeFn.writable = True
    numericAttributeFn.storable = True
    numericAttributeFn.hidden = False
    numericAttributeFn.setMin(0)
    numericAttributeFn.setMax(1)
    mFIZ_remap.addAttribute(mFIZ_remap.zoom_in_attr)

    #==================================#
    #     OUTPUT NODE ATTRIBUTE(S)     #
    #==================================#
    mFIZ_remap.focus_out_attr = numericAttributeFn.create(
        'focusMapped', 'focusMapped', OpenMaya.MFnNumericData.kInt, 0)
    numericAttributeFn.writable = False
    numericAttributeFn.storable = False
    numericAttributeFn.readable = True
    numericAttributeFn.hidden = False
    mFIZ_remap.addAttribute(mFIZ_remap.focus_out_attr)

    mFIZ_remap.iris_out_attr = numericAttributeFn.create(
        'irisMapped', 'irisMapped', OpenMaya.MFnNumericData.kInt, 0)
    numericAttributeFn.writable = False
    numericAttributeFn.storable = False
    numericAttributeFn.readable = True
    numericAttributeFn.hidden = False
    mFIZ_remap.addAttribute(mFIZ_remap.iris_out_attr)

    mFIZ_remap.zoom_out_attr = numericAttributeFn.create(
        'zoomMapped', 'zoomMapped', OpenMaya.MFnNumericData.kInt, 0)
    numericAttributeFn.writable = False
    numericAttributeFn.storable = False
    numericAttributeFn.readable = True
    numericAttributeFn.hidden = False
    mFIZ_remap.addAttribute(mFIZ_remap.zoom_out_attr)

    #===================================#
    #    NODE ATTRIBUTE DEPENDENCIES    #
    #===================================#

    input_attrs = [
        mFIZ_remap.focus_in_attr, mFIZ_remap.iris_in_attr,
        mFIZ_remap.zoom_in_attr
    ]

    output_attrs = [
        mFIZ_remap.focus_out_attr, mFIZ_remap.iris_out_attr,
        mFIZ_remap.zoom_out_attr
    ]

    for input_attr in input_attrs:
        for output_attr in output_attrs:
            mFIZ_remap.attributeAffects(input_attr, output_attr)
Esempio n. 13
0
def nodeInitializer():
    '''
    Defines the input and output attributes as static variables in our plug-in class.
    '''

    # The following function set will allow us to create our attributes.
    numericAttributeFn = OpenMaya.MFnNumericAttribute()
    typedAttributeFn = OpenMaya.MFnTypedAttribute()
    messageAttributeFn = OpenMaya.MFnMessageAttribute()
    compoundAttributeFn = OpenMaya.MFnCompoundAttribute()

    #==================================#
    #      INPUT NODE ATTRIBUTE(S)     #
    #==================================#

    #-----------------------------------------#
    #            Focus Iris Zoom              #
    #-----------------------------------------#
    mFIZ.focus_attr = numericAttributeFn.create('focus', 'focus',
                                                OpenMaya.MFnNumericData.kFloat)
    numericAttributeFn.writable = True
    numericAttributeFn.storable = True
    numericAttributeFn.hidden = False
    numericAttributeFn.setMin(0)
    numericAttributeFn.setMax(1)
    mFIZ.addAttribute(mFIZ.focus_attr)

    mFIZ.iris_attr = numericAttributeFn.create('iris', 'iris',
                                               OpenMaya.MFnNumericData.kFloat)
    numericAttributeFn.writable = True
    numericAttributeFn.storable = True
    numericAttributeFn.hidden = False
    numericAttributeFn.setMin(0)
    numericAttributeFn.setMax(1)
    mFIZ.addAttribute(mFIZ.iris_attr)

    mFIZ.zoom_attr = numericAttributeFn.create('zoom', 'zoom',
                                               OpenMaya.MFnNumericData.kFloat)
    numericAttributeFn.writable = True
    numericAttributeFn.storable = True
    numericAttributeFn.hidden = False
    numericAttributeFn.setMin(0)
    numericAttributeFn.setMax(1)
    mFIZ.addAttribute(mFIZ.zoom_attr)

    #-----------------------------------------#
    #                Connection               #
    #-----------------------------------------#
    mFIZ.live_attr = numericAttributeFn.create(
        'live', 'live', OpenMaya.MFnNumericData.kBoolean, 0)
    numericAttributeFn.writable = True
    numericAttributeFn.connectable = False
    numericAttributeFn.storable = False
    numericAttributeFn.hidden = False
    mFIZ.addAttribute(mFIZ.live_attr)

    #-----------------------------------------#
    #                 Port Name               #
    #-----------------------------------------#
    mFIZ.port_name_attr = typedAttributeFn.create('portName', 'portName',
                                                  OpenMaya.MFnData.kString)
    typedAttributeFn.writable = True
    typedAttributeFn.connectable = False
    typedAttributeFn.storable = False
    typedAttributeFn.hidden = False
    mFIZ.addAttribute(mFIZ.port_name_attr)

    #-----------------------------------------#
    #                 API Type                #
    #-----------------------------------------#
    mFIZ.api_attr = typedAttributeFn.create('api', 'api',
                                            OpenMaya.MFnData.kString)
    typedAttributeFn.writable = True
    typedAttributeFn.storable = False
    typedAttributeFn.connectable = False
    typedAttributeFn.hidden = False
    mFIZ.addAttribute(mFIZ.api_attr)
    ''' 
    mFIZ.api_attr= numericAttributeFn.create('api', 'api', OpenMaya.MFnNumericData.kInt, 0)
    numericAttributeFn.writable = True
    numericAttributeFn.storable = False
    numericAttributeFn.connectable = False
    numericAttributeFn.hidden = False
    mFIZ.addAttribute(mFIZ.api_attr)     
    '''

    #-----------------------------------------#
    #       Stop Playback on Disconnect       #
    #-----------------------------------------#
    mFIZ.stop_playback_on_disconnect_attr = numericAttributeFn.create(
        'stopPlaybackOnDisconnect', 'stopPlaybackOnDisconnect',
        OpenMaya.MFnNumericData.kBoolean, 0)
    numericAttributeFn.writable = True
    numericAttributeFn.connectable = False
    numericAttributeFn.storable = True
    numericAttributeFn.hidden = False
    mFIZ.addAttribute(mFIZ.stop_playback_on_disconnect_attr)

    #==================================#
    #     OUTPUT NODE ATTRIBUTE(S)     #
    #==================================#
    mFIZ.data_sent_attr = numericAttributeFn.create(
        'dataSent', 'dataSent', OpenMaya.MFnNumericData.kBoolean, 0)
    numericAttributeFn.writable = False
    numericAttributeFn.storable = False
    numericAttributeFn.readable = True
    numericAttributeFn.hidden = False
    mFIZ.addAttribute(mFIZ.data_sent_attr)

    mFIZ.controller_attr = messageAttributeFn.create('controller',
                                                     'controller')
    messageAttributeFn.writable = True
    messageAttributeFn.storable = True
    messageAttributeFn.hidden = False
    mFIZ.addAttribute(mFIZ.controller_attr)

    #===================================#
    #    NODE ATTRIBUTE DEPENDENCIES    #
    #===================================#

    input_attrs = [
        mFIZ.focus_attr, mFIZ.iris_attr, mFIZ.zoom_attr, mFIZ.live_attr,
        mFIZ.api_attr, mFIZ.stop_playback_on_disconnect_attr
    ]

    output_attrs = [mFIZ.data_sent_attr]

    for input_attr in input_attrs:
        for output_attr in output_attrs:
            mFIZ.attributeAffects(input_attr, output_attr)
Esempio n. 14
0
def addAttribute(node, longName, shortName, attrType=attrtypes.kMFnNumericDouble, isArray=False, apply=True):
    """This function uses the api to create attributes on the given node, currently WIP but currently works for
    string,int, float, bool, message, matrix. if the attribute exists a ValueError will be raised.

    :param node: MObject
    :param longName: str, the long name for the attribute
    :param shortName: str, the shortName for the attribute
    :param attrType: attribute Type, attrtypes constants
    :param apply: if False the attribute will be immediately created on the node else just return the attribute instance
    :rtype: om.MObject
    """
    if hasAttribute(node, longName):
        raise ValueError("Node -> '%s' already has attribute -> '%s'" % (nameFromMObject(node), longName))
    aobj = None
    attr = None
    if attrType == attrtypes.kMFnNumericDouble:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.kDouble)
    elif attrType == attrtypes.kMFnNumericFloat:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.kFloat)
    elif attrType == attrtypes.kMFnNumericBoolean:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.kBoolean)
    elif attrType == attrtypes.kMFnNumericInt:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.kInt)
    elif attrType == attrtypes.kMFnNumericShort:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.kShort)
    elif attrType == attrtypes.kMFnNumericLong:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.kLong)
    elif attrType == attrtypes.kMFnNumericByte:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.kByte)
    elif attrType == attrtypes.kMFnNumericChar:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.kChar)
    elif attrType == attrtypes.kMFnNumericAddr:
        attr = om2.MFnNumericAttribute()
        aobj = attr.createAddr(longName, shortName)
    elif attrType == attrtypes.kMFnkEnumAttribute:
        attr = om2.MFnEnumAttribute()
        aobj = attr.create(longName, shortName)
    elif attrType == attrtypes.kMFnCompoundAttribute:
        attr = om2.MFnCompoundAttribute()
        aobj = attr.create(longName, shortName)
    elif attrType == attrtypes.kMFnMessageAttribute:
        attr = om2.MFnMessageAttribute()
        aobj = attr.create(longName, shortName)
    elif attrType == attrtypes.kMFnDataString:
        attr = om2.MFnTypedAttribute()
        stringData = om2.MFnStringData().create("")
        aobj = attr.create(longName, shortName, om2.MFnData.kString, stringData)
    elif attrType == attrtypes.kMFnUnitAttributeDistance:
        attr = om2.MFnUnitAttribute()
        aobj = attr.create(longName, shortName, om2.MDistance())
    elif attrType == attrtypes.kMFnUnitAttributeAngle:
        attr = om2.MFnUnitAttribute()
        aobj = attr.create(longName, shortName, om2.MAngle())
    elif attrType == attrtypes.kMFnUnitAttributeTime:
        attr = om2.MFnUnitAttribute()
        aobj = attr.create(longName, shortName, om2.MTime())
    elif attrType == attrtypes.kMFnDataMatrix:
        attr = om2.MFnMatrixAttribute()
        aobj = attr.create(longName, shortName)
    elif attrType == attrtypes.kMFnDataFloatArray:
        attr = om2.MFnFloatArray()
        aobj = attr.create(longName, shortName)
    elif attrType == attrtypes.kMFnDataDoubleArray:
        data = om2.MFnDoubleArrayData().create(om2.MDoubleArray())
        attr = om2.MFnTypedAttribute()
        aobj = attr.create(longName, shortName, om2.MFnData.kDoubleArray, data)
    elif attrType == attrtypes.kMFnDataIntArray:
        data = om2.MFnIntArrayData().create(om2.MIntArray())
        attr = om2.MFnTypedAttribute()
        aobj = attr.create(longName, shortName, om2.MFnData.kIntArray, data)
    elif attrType == attrtypes.kMFnDataPointArray:
        data = om2.MFnPointArrayData().create(om2.MPointArray())
        attr = om2.MFnTypedAttribute()
        aobj = attr.create(longName, shortName, om2.MFnData.kPointArray, data)
    elif attrType == attrtypes.kMFnDataVectorArray:
        data = om2.MFnVectorArrayData().create(om2.MVectorArray())
        attr = om2.MFnTypedAttribute()
        aobj = attr.create(longName, shortName, om2.MFnData.kVectorArray, data)
    elif attrType == attrtypes.kMFnDataStringArray:
        data = om2.MFnStringArrayData().create(om2.MStringArray())
        attr = om2.MFnTypedAttribute()
        aobj = attr.create(longName, shortName, om2.MFnData.kStringArray, data)
    elif attrType == attrtypes.kMFnDataMatrixArray:
        data = om2.MFnMatrixArrayData().create(om2.MMatrixArray())
        attr = om2.MFnTypedAttribute()
        aobj = attr.create(longName, shortName, om2.MFnData.kMatrixArray, data)
    elif attrType == attrtypes.kMFnNumericInt64:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.kInt64)
    elif attrType == attrtypes.kMFnNumericLast:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.kLast)
    elif attrType == attrtypes.kMFnNumeric2Double:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.k2Double)
    elif attrType == attrtypes.kMFnNumeric2Float:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.k2Float)
    elif attrType == attrtypes.kMFnNumeric2Int:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.k2Int)
    elif attrType == attrtypes.kMFnNumeric2Long:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.k2Long)
    elif attrType == attrtypes.kMFnNumeric2Short:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.k2Short)
    elif attrType == attrtypes.kMFnNumeric3Double:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.k3Double)
    elif attrType == attrtypes.kMFnNumeric3Float:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.k3Float)
    elif attrType == attrtypes.kMFnNumeric3Int:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.k3Int)
    elif attrType == attrtypes.kMFnNumeric3Long:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.k3Long)
    elif attrType == attrtypes.kMFnNumeric3Short:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.k3Short)
    elif attrType == attrtypes.kMFnNumeric4Double:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.k4Double)

    if aobj is not None and apply:
        attr.array = isArray
        mod = om2.MDGModifier()
        mod.addAttribute(node, aobj)
        mod.doIt()
    return attr
Esempio n. 15
0
def makePickwalkNode(ikControls=None, fkControls=None):
    '''
    node.ikLinker[*].ikController
                    .ikLeftIndexIk
                    .ikLeftIndexFk
                    .ikRightIndexIk
                    .ikRightIndexFk
    '''

    ikControls = ikControls if ikControls else []
    fkControls = fkControls if fkControls else []

    obj = createNode('network')

    obj.addAttr('up', at='message')
    obj.addAttr('down', at='message')

    obj.addAttr('switcher', at='double', dv=0)

    mobj = pdil.capi.asMObject(obj)

    for xk in ['ik', 'fk']:

        cattr = OpenMaya.MFnCompoundAttribute()
        mattr = OpenMaya.MFnMessageAttribute()
        nattr = OpenMaya.MFnNumericAttribute()

        controlLinker = cattr.create(xk + 'Linker', xk)
        cattr.array = True

        controller = mattr.create(xk + 'Controller', xk + 'ctrl')
        left = mattr.create(xk + 'Left', xk + 'l')
        right = mattr.create(xk + 'Right', xk + 'r')

        leftIndexIk = nattr.create(xk + 'LeftIndexIk', xk + 'lii',
                                   OpenMaya.MFnNumericData.kInt, -1)
        leftIndexFk = nattr.create(xk + 'LeftIndexFk', xk + 'lif',
                                   OpenMaya.MFnNumericData.kInt, -1)
        rightIndexIk = nattr.create(xk + 'RightIndexIk', xk + 'rii',
                                    OpenMaya.MFnNumericData.kInt, -1)
        rightIndexFk = nattr.create(xk + 'RightIndexFk', xk + 'rif',
                                    OpenMaya.MFnNumericData.kInt, -1)

        cattr.addChild(controller)
        cattr.addChild(left)
        cattr.addChild(right)
        cattr.addChild(leftIndexIk)
        cattr.addChild(leftIndexFk)
        cattr.addChild(rightIndexIk)
        cattr.addChild(rightIndexFk)

        mobj.addAttribute(controlLinker)

    for i, ctrl in enumerate(fkControls):
        print(ctrl, type(ctrl))
        ctrl.message >> obj.fkLinker[i].fkController

    for i, ctrl in enumerate(ikControls):
        ctrl.message >> obj.ikLinker[i].ikController

    return obj
Esempio n. 16
0
    def initialize(cls):
        nAttr = OpenMaya.MFnNumericAttribute()
        tAttr = OpenMaya.MFnTypedAttribute()
        uAttr = OpenMaya.MFnUnitAttribute()
        enumAttr = OpenMaya.MFnEnumAttribute()
        compAttr = OpenMaya.MFnCompoundAttribute()
        matrixAttr = OpenMaya.MFnMatrixAttribute()
        messageAttr = OpenMaya.MFnMessageAttribute()

        cls.forgeID = tAttr.create("forgeID",
                                   "fid",
                                   OpenMaya.MFnData.kString,
                                   OpenMaya.MObject.kNullObj)
        cls.addAttribute(cls.forgeID)

        cls.guideMatrix = matrixAttr.create("guideMatrix",
                                            "gm",
                                            OpenMaya.MFnMatrixAttribute.kDouble)
        cls.addAttribute(cls.guideMatrix)

        cls.handleInverseScale = nAttr.create("handleInverseScale",
                                              "his",
                                              OpenMaya.MFnNumericData.k3Double,
                                              1.0)
        cls.addAttribute(cls.handleInverseScale)

        cls.boundingBoxCorner1 = nAttr.create("boundingBoxCorner1",
                                              "bb1",
                                              OpenMaya.MFnNumericData.k3Double,
                                              0)
        nAttr.keyable = False
        cls.addAttribute(cls.boundingBoxCorner1)
        cls.boundingBoxCorner2 = nAttr.create("boundingBoxCorner2",
                                              "bb2",
                                              OpenMaya.MFnNumericData.k3Double,
                                              0)
        nAttr.keyable = False
        cls.addAttribute(cls.boundingBoxCorner2)

        cls.aimAxis = enumAttr.create("aimAxis", "aa", 0)
        enumAttr.addField("X", 0)
        enumAttr.addField("Y", 1)
        enumAttr.addField("Z", 2)
        enumAttr.addField("-X", 3)
        enumAttr.addField("-Y", 4)
        enumAttr.addField("-Z", 5)
        enumAttr.keyable = False
        cls.addAttribute(cls.aimAxis)

        cls.upAxis = enumAttr.create("upAxis", "ua", 2)
        enumAttr.addField("X", 0)
        enumAttr.addField("Y", 1)
        enumAttr.addField("Z", 2)
        enumAttr.addField("-X", 3)
        enumAttr.addField("-Y", 4)
        enumAttr.addField("-Z", 5)
        enumAttr.keyable = False
        cls.addAttribute(cls.upAxis)

        cls.aimVector = nAttr.create("aimVector", "av", OpenMaya.MFnNumericData.k3Double)
        cls.addAttribute(cls.aimVector)

        cls.upVector = nAttr.create("upVector", "uv", OpenMaya.MFnNumericData.k3Double)
        cls.addAttribute(cls.upVector)

        cls.provideAimVector = nAttr.create("provideAimVector", "pav", OpenMaya.MFnNumericData.kBoolean, 0)
        cls.addAttribute(cls.provideAimVector)

        cls.baseMatrix = matrixAttr.create("baseMatrix",
                                           "base",
                                           OpenMaya.MFnMatrixAttribute.kDouble)
        cls.addAttribute(cls.baseMatrix)

        cls.hingeMatrix = matrixAttr.create("hingeMatrix",
                                            "hng",
                                            OpenMaya.MFnMatrixAttribute.kDouble)
        cls.addAttribute(cls.hingeMatrix)

        cls.endMatrix = matrixAttr.create("endMatrix",
                                          "end",
                                          OpenMaya.MFnMatrixAttribute.kDouble)
        cls.addAttribute(cls.endMatrix)

        cls.useChildBaseAsEnd = nAttr.create("useChildBaseAsEnd", "ucb", OpenMaya.MFnNumericData.kBoolean, 0)
        cls.addAttribute(cls.useChildBaseAsEnd)

        cls.handle = messageAttr.create("handle", "hndl")
        messageAttr.array = True
        cls.addAttribute(cls.handle)

        cls.handleColor = nAttr.createColor("handleColor", "hc")
        cls.addAttribute(cls.handleColor)

        cls.orientGroup = messageAttr.create("orientGroup", "ogrp")
        cls.addAttribute(cls.orientGroup)

        cls.orientGroupTranslateX = uAttr.create("orientGroupTranslateX", "ogtx", OpenMaya.MFnUnitAttribute.kDistance, 0.0)
        cls.orientGroupTranslateY = uAttr.create("orientGroupTranslateY", "ogty", OpenMaya.MFnUnitAttribute.kDistance, 0.0)
        cls.orientGroupTranslateZ = uAttr.create("orientGroupTranslateZ", "ogtz", OpenMaya.MFnUnitAttribute.kDistance, 0.0)
        cls.orientGroupTranslate = nAttr.create("orientGroupTranslate",
                                             "ogt",
                                             cls.orientGroupTranslateX,
                                             cls.orientGroupTranslateY,
                                             cls.orientGroupTranslateZ)
        cls.addAttribute(cls.orientGroupTranslate)

        cls.orientGroupRotateX = uAttr.create("orientGroupRotateX", "ogrx", OpenMaya.MFnUnitAttribute.kAngle, 0.0)
        cls.orientGroupRotateY = uAttr.create("orientGroupRotateY", "ogry", OpenMaya.MFnUnitAttribute.kAngle, 0.0)
        cls.orientGroupRotateZ = uAttr.create("orientGroupRotateZ", "ogrz", OpenMaya.MFnUnitAttribute.kAngle, 0.0)
        cls.orientGroupRotate = nAttr.create("orientGroupRotate",
                                             "ogr",
                                             cls.orientGroupRotateX,
                                             cls.orientGroupRotateY,
                                             cls.orientGroupRotateZ)
        cls.addAttribute(cls.orientGroupRotate)

        cls.parentGuide = messageAttr.create("parentGuide", "pg")
        cls.addAttribute(cls.parentGuide)

        cls.parentGuideHandleIndex = nAttr.create("parentGuideHandleIndex", "pghi", OpenMaya.MFnNumericData.kShort, -1)
        cls.addAttribute(cls.parentGuideHandleIndex)

        cls.childGuide = messageAttr.create("childGuide", "cg")
        cls.addAttribute(cls.childGuide)

        cls.attributeAffects(cls.guideMatrix, cls.boundingBoxCorner1)
        cls.attributeAffects(cls.guideMatrix, cls.boundingBoxCorner2)
        # cls.attributeAffects(cls.baseMatrix, cls.boundingBoxCorner1)
        # cls.attributeAffects(cls.baseMatrix, cls.boundingBoxCorner2)
        cls.attributeAffects(cls.baseMatrix, cls.orientGroupTranslate)
        cls.attributeAffects(cls.baseMatrix, cls.orientGroupRotate)
        cls.attributeAffects(cls.baseMatrix, cls.aimVector)
        cls.attributeAffects(cls.baseMatrix, cls.upVector)
        # cls.attributeAffects(cls.hingeMatrix, cls.boundingBoxCorner1)
        # cls.attributeAffects(cls.hingeMatrix, cls.boundingBoxCorner2)
        cls.attributeAffects(cls.hingeMatrix, cls.orientGroupTranslate)
        cls.attributeAffects(cls.hingeMatrix, cls.orientGroupRotate)
        cls.attributeAffects(cls.hingeMatrix, cls.aimVector)
        cls.attributeAffects(cls.hingeMatrix, cls.upVector)
        # cls.attributeAffects(cls.endMatrix, cls.boundingBoxCorner1)
        # cls.attributeAffects(cls.endMatrix, cls.boundingBoxCorner2)
        cls.attributeAffects(cls.endMatrix, cls.orientGroupTranslate)
        cls.attributeAffects(cls.endMatrix, cls.orientGroupRotate)
        cls.attributeAffects(cls.endMatrix, cls.aimVector)
        cls.attributeAffects(cls.endMatrix, cls.upVector)
        cls.attributeAffects(cls.guideMatrix, cls.handleInverseScale)
        cls.attributeAffects(cls.provideAimVector, cls.aimVector)