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