def test_get_as_plug(self):
        name = 'myNode1'
        node = maya.cmds.createNode('transform', name=name)
        plug = node_utils.get_as_plug(node + '.translateY')
        self.assertEqual(plug.name(), 'myNode1.translateY')
        self.assertEqual(plug.asDouble(), 0.0)

        plug.setDouble(3.147)
        self.assertEqual(plug.asDouble(), 3.147)
 def member_in_set(self, name):
     # NOTE: For attributes, you must use a MPlug, as testing with
     # an MObject only tests the dependency node
     if '.' in name:
         plug = node_utils.get_as_plug(name)
         ret = self._mfn.isMember(plug)
     else:
         obj = node_utils.get_as_object(name)
         ret = self._mfn.isMember(obj)
     return ret
Exemple #3
0
    def __init__(self, name=None, node=None, attr=None):
        """
        Initialise an Attribute object.

        Attribute can use a 'name', or 'node' and 'attr'.

        A 'name' is a string of both node and attribute path; `node.attr`.

        :param name: Node and attribute path as a single string: 'node.attr'
        :type name: str

        :param node: DG Maya node path.
        :type node: str

        :param attr: Long or short attribute name.
        :type attr: str
        """
        if isinstance(name, (str, unicode)):
            assert api_utils.get_object_type(
                name) == const.OBJECT_TYPE_ATTRIBUTE
            part = name.partition('.')
            node = part[0]
            attr = part[-1]

        self._plug = None
        self._dependFn = None
        if isinstance(node,
                      (str, unicode)) and isinstance(attr, (str, unicode)):
            assert maya.cmds.objExists(node)
            # Long and short names must be checked.
            attr_list_long = maya.cmds.listAttr(node, shortNames=False) or []
            attr_list_short = maya.cmds.listAttr(node, shortNames=True) or []
            if attr not in (attr_list_long + attr_list_short):
                msg = 'Attribute not found on node. node=%r attr=%r'
                LOG.error(msg, node, attr)
                raise RuntimeError(msg)

            node_attr = node + '.' + attr
            plug = node_utils.get_as_plug(node_attr)
            self._plug = plug

            node_obj = self._plug.node()
            self._dependFn = OpenMaya.MFnDependencyNode(node_obj)

        # The minimum and maximum values allowed for the attribute.
        self._min_value = None
        self._max_value = None
        return
def disconnect_animcurves(kwargs):
    """
    HACK: Disconnect animCurves from animated attributes,
    then re-connect afterward. This is to solve a Maya bug,
    which will not solve values on a single frame.

    :param kwargs: Solver keyword arguments.
    :type kwargs: dict

    :returns: Pairs of source and destination plugs that have been
              disconnected by this function.
    :rtype: [(str, str), ..]
    """
    f = kwargs.get('frame')[0]
    maya.cmds.currentTime(f, edit=True, update=False)

    save_node_attrs = []
    attrs = kwargs.get('attr') or []
    for attr_name, min_val, max_val, offset_val, scale_val in attrs:
        attr_obj = attribute.Attribute(name=attr_name)
        if attr_obj.is_animated() is False:
            continue

        in_plug_name = None
        out_plug_name = attr_name
        plug = node_utils.get_as_plug(attr_name)
        isDest = plug.isDestination()
        if isDest:
            connPlugs = OpenMaya.MPlugArray()
            asDest = True  # get the source plugs on the other end of 'plug'.
            asSrc = False
            plug.connectedTo(connPlugs, asDest, asSrc)
            for i, conn in enumerate(connPlugs):
                connPlug = connPlugs[i]
                connObj = connPlug.node()
                if connObj.hasFn(OpenMaya.MFn.kAnimCurve):
                    in_plug_name = connPlug.name()
                    break
        if in_plug_name is not None:
            save_node_attrs.append((in_plug_name, out_plug_name))
            if maya.cmds.isConnected(in_plug_name, out_plug_name) is True:
                maya.cmds.disconnectAttr(in_plug_name, out_plug_name)
            else:
                LOG.error('Nodes are not connected. This is WRONG.')
    return save_node_attrs
def create_anim_curve_node_apione(
        times,
        values,
        node_attr=None,
        tangent_in_type=OpenMayaAnim1.MFnAnimCurve.kTangentGlobal,
        tangent_out_type=OpenMayaAnim1.MFnAnimCurve.kTangentGlobal,
        anim_type=OpenMayaAnim1.MFnAnimCurve.kAnimCurveTL,
        undo_cache=None):
    """
    Create an animCurve using Maya API (one).

    :param times: Time values for the animCurve
    :type times: list

    :param values: Values for the animCurve.
    :type values: list

    :param node_attr: The 'plug' to connect the animCurve to.
    :type node_attr: str

    :param tangent_in_type: The "in" tangent type for keyframes.
    :type tangent_in_type: maya.OpenMayaAnim.MFnAnimCurve.kTangent*

    :param tangent_out_type: The "out" tangent type for keyframes.
    :type tangent_out_type: maya.OpenMayaAnim.MFnAnimCurve.kTangent*

    :param anim_type: The type of animation curve node.
    :type anim_type: maya.OpenMayaAnim.MFnAnimCurve.kAnimCurve*

    :param undo_cache: The Maya AnimCurve Undo Cache data structure or
                       None if no undo is required.
    :type undo_cache: maya.OpenMayaAnim.MAnimCurveChange

    :return: MFnAnimCurve object attached to a newly created animation curve.
    :rtype: maya.OpenMaya.MFnAnimCurve
    """
    if not isinstance(times, list):
        raise ValueError('times must be a list or sequence type.')
    if not isinstance(values, list):
        raise ValueError('times must be a list or sequence type.')
    if len(times) == 0:
        raise ValueError('times must have 1 or more values.')
    if len(values) == 0:
        raise ValueError('values must have 1 or more values.')
    if len(times) != len(values):
        raise ValueError('Number of times and values does not match.')

    # create anim curve
    animfn = OpenMayaAnim1.MFnAnimCurve()
    if node_attr is None:
        animCurve = animfn.create(anim_type)
    else:
        # Get the plug to be animated.
        dst_plug = node_utils.get_as_plug(node_attr)

        objs = OpenMaya1.MObjectArray()
        find = OpenMayaAnim1.MAnimUtil.findAnimation(dst_plug, objs)
        if find is True and objs.length() > 0:
            animfn = OpenMayaAnim1.MFnAnimCurve(objs[0])
        else:
            animfn = OpenMayaAnim1.MFnAnimCurve()
            animfn.create(dst_plug)

    # Copy the times into an MTimeArray and the values into an MDoubleArray.
    time_array = OpenMaya1.MTimeArray()
    value_array = OpenMaya1.MDoubleArray()
    for time, value in zip(times, values):
        time_array.append(OpenMaya1.MTime(time, OpenMaya1.MTime.uiUnit()))
        value_array.append(value)

    # force a default undo cache
    if not undo_cache:
        undo_cache = OpenMayaAnim1.MAnimCurveChange()

    # Add the keys to the animCurve.
    animfn.addKeys(
        time_array,
        value_array,
        tangent_in_type,
        tangent_out_type,
        False,  # overwrite any keys that get in our way
        undo_cache)
    return animfn