def get_keyframable_channel_object(node_obj, channel_obj, force_create=True): connections = OpenMaya.MPlugArray() channel_obj.connectedTo(connections, True, False) if bool(connections.length()): try: mfna = OpenMayaAnim.MFnAnimCurve(channel_obj) # check if the node is referenced. Support for unitless input # animation curves is not available yet allow_ref = MayaPreferences.use_referenced_anim_curves if ((not allow_ref and mfna.isFromReferencedFile()) or mfna.isUnitlessInput()): return None return mfna except: return None elif force_create: try: curve_node = OpenMayaAnim.MFnAnimCurve().create( channel_obj, MayaUndoHelper.dg_modifier) except: warnings.warn( "Cannot create animation curve node for %s ." % channel_obj.partialName(True), FacadeWarning) return None return OpenMayaAnim.MFnAnimCurve(curve_node) return None
def create_animation_curve(self, mplug) : anim_curve = self.get_anim_curve(mplug) if anim_curve: mfn_anim_curve = OpenMayaAnim.MFnAnimCurve(anim_curve) else: mfn_anim_curve = OpenMayaAnim.MFnAnimCurve() anim_curve_type = mfn_anim_curve.timedAnimCurveTypeForPlug(mplug) mfn_anim_curve.create(mplug, anim_curve_type) return mfn_anim_curve
def get_deviation_anim_curve_fn(self): """ Get the MFnAnimCurve object for the deviation attribute animCurve. .. note:: Returned object is Maya API 1.0. :returns: Maya animCurve function set. :rtype: maya.OpenMayaAnim.MFnAnimCurve or None """ animFn = self._MFnAnimCurve_deviation if animFn is None: node = self.get_node() if node is None: msg = 'Could not get Marker node. self=%r' LOG.warning(msg, self) return animFn plug_name = '{0}.{1}'.format(node, const.MARKER_ATTR_LONG_NAME_DEVIATION) animCurves = maya.cmds.listConnections(plug_name, type='animCurveTU') or [] if len(animCurves) > 0: mobj = node_utils.get_as_object(animCurves[0]) animFn = OpenMayaAnim.MFnAnimCurve(mobj) return animFn
def get_mfn_anim_node(object_node): """ returns an OpenMaya.MFnAnimCurve object from the object specified. :param object_node: <str> object node. :return: <OpenMaya.MFnAnimCurve> maya object. """ return OpenMayaAnim.MFnAnimCurve(object_utils.get_m_obj(object_node))
def _GetAnimCurveFnForPlugName(self, depNodeFn, plugName): plug = depNodeFn.findPlug(plugName) animObjs = OpenMaya.MObjectArray() OpenMayaAnim.MAnimUtil.findAnimation(plug, animObjs) self.assertEqual(animObjs.length(), 1) animCurveFn = OpenMayaAnim.MFnAnimCurve(animObjs[0]) return animCurveFn
def __init__(self, animCurveNode): import math def getMObject(inputTarget): target = pymel.core.ls(inputTarget)[0] mObject = OpenMaya.MObject() selList = OpenMaya.MSelectionList() selList.add(target.name()) selList.getDependNode(0, mObject) return mObject self.animCurveNode = pymel.core.ls(animCurveNode)[0] self.fnAnimCurve = OpenMayaAnim.MFnAnimCurve( getMObject(self.animCurveNode.name())) self.times = [] self.values = [] self.tangent_ints = [] self.tangent_outs = [] for i in range(self.animCurveNode.numKeys()): self.times.append(self.animCurveNode.getTime(i).real) value = self.animCurveNode.getValue(i) value = math.degrees(value) if self.animCurveNode.output.type( ) == 'doubleAngle' else value self.values.append(value) self.tangent_ints.append(self.animCurveNode.getTangent(i, True)) self.tangent_outs.append(self.animCurveNode.getTangent(i, False)) print self.times
def key_callback(self, attributes, clientData): """Everything is put into a try statement for general safety reasons @param attributes: edited attributes @param clientData: additionalData, not used by the onionSkin, so always defaults to None @type clientData: None """ # try: for i in range(attributes.length()): attribute = attributes[i] keyframe_delta = OpenMayaAnim.MFnKeyframeDelta(attribute) animcurve = OpenMayaAnim.MFnAnimCurve(keyframe_delta.paramCurve()) object_name = cmds.listConnections(animcurve.name())[0] trans_name = object_name obj = None for c in cmds.listConnections(object_name): if '_BSP' in c: obj = c.split('_BSP')[0].split('CHAR_')[1] break if obj is None: return table = self.tabs[obj][1] trans_name = trans_name.split('SF_CHAR_')[1].split('_CTL')[0] item = table.findItems(trans_name, QtCore.Qt.MatchExactly) key_timeline = None for c in table.cellWidget(item[0].row(), self.column_timeline).children(): if type(c) is dwidget.DragSupportWidget: for tl in self.timelines: if tl.timeline is c: key_timeline = tl # end for tl in self.timelines # end for c in table.cellWidget(item[0].row(), self.column_timeline).children() if key_timeline is not None: key_timeline.refresh_buttons(animcurve)
def utilityGetOrCreateCurve(name, property, curveType): if not cmds.objExists("%s.%s" % (name, property)): return None selectList = OpenMaya.MSelectionList() selectList.add(name) try: nodePath = OpenMaya.MDagPath() selectList.getDagPath(0, nodePath) except RuntimeError: return None utilitySaveNodeData(nodePath, property in ["rx", "ry", "rz"]) propertyPlug = OpenMaya.MFnDependencyNode(nodePath.node()).findPlug( property, False) propertyPlug.setKeyable(True) propertyPlug.setLocked(False) inputSources = OpenMaya.MPlugArray() propertyPlug.connectedTo(inputSources, True, False) if inputSources.length() == 0: # There is no curve attached to this node, so we can # make a new one on top of the property newCurve = OpenMayaAnim.MFnAnimCurve() newCurve.create(propertyPlug, curveType) return newCurve elif inputSources[0].node().hasFn(OpenMaya.MFn.kAnimCurve): # There is an existing curve on this node, we need to # grab the curve, but then reset the rotation interpolation newCurve = OpenMayaAnim.MFnAnimCurve() newCurve.setObject(inputSources[0].node()) # If we have a rotation curve, it's interpolation must be reset before keying if property in [ "rx", "ry", "rz" ] and utilityGetCurveInterpolation(newCurve.name()) != "none": utilitySetCurveInterpolation(newCurve.name()) # Return the existing curve return newCurve return None
def remove_animation_from_frame_range(node_obj, channel_obj, start, end): node = MayaFacadeHelper.get_connected_animation_curve(channel_obj) if node is None: return mfna = OpenMayaAnim.MFnAnimCurve(channel_obj) c_key = mfna.numKeys() - 1 while c_key > 0 and mfna.time(c_key).value() >= start: if mfna.time(c_key).value() > end: c_key -= 1 continue mfna.remove(c_key, MayaUndoHelper.anim_curve_change) c_key -= 1
def shift_animation_in_frame_range(node_obj, channel_obj, start, end): node = MayaFacadeHelper.get_connected_animation_curve(channel_obj) if node is None: return mfna = OpenMayaAnim.MFnAnimCurve(channel_obj) delta = end - start c_key = mfna.numKeys() - 1 while c_key > 0 and mfna.time(c_key).value() >= start: ct = mfna.time(c_key).value() mfna.setTime(c_key, OpenMaya.MTime(ct + delta, OpenMaya.MTime.uiUnit()), MayaUndoHelper.anim_curve_change) c_key -= 1
def add_keys(self, plugName, times, values, changeCache=None): # Get the plug to be animated. sel = om.MSelectionList() sel.add(plugName) plug = om.MPlug() sel.getPlug(0, plug) # Create the animCurve. animfn = oma.MFnAnimCurve(plug) timeArray = om.MTimeArray() valueArray = om.MDoubleArray() for i in range(len(times)): timeArray.append(om.MTime(times[i], om.MTime.uiUnit())) valueArray.append(values[i]) # Add the keys to the animCurve. animfn.addKeys(timeArray, valueArray, oma.MFnAnimCurve.kTangentGlobal, oma.MFnAnimCurve.kTangentGlobal, False, changeCache)
def getKeyList(self, curveAnimNodeList): pm.select(cl=True) keyList = [] #iterate curveAnimNodeList and append all keys time to keyList for curveAnimNode in curveAnimNodeList: #get curveAnimMObject curveAnimObject = OpenMaya.MObject() #select current curveAnimNode pm.select(cl=True) pm.select(curveAnimNode) #getSelectionList API selectionList = OpenMaya.MSelectionList() #set selectionList to active selection OpenMaya.MGlobal.getActiveSelectionList(selectionList) #selectionList iterator itSelectionList = OpenMaya.MItSelectionList(selectionList) pm.select(cl=True) #traverse selectionList and assign curve anim mobject while not (itSelectionList.isDone()): itSelectionList.getDependNode(curveAnimObject) itSelectionList.next() #create curveAnim fnSet fnCurveAnimObject = OpenMayaAnim.MFnAnimCurve(curveAnimObject) #iterate for index in range(0, fnCurveAnimObject.numKeys()): #Get time object for index and append to list timeObject = fnCurveAnimObject.time(index) keyList.append(timeObject.value()) #remove duplicates and return return sorted(list(set(keyList)))
def get_anim_connections(object_name=""): """ get plug connections :param object_name: :return: <dict> found animation connection plugs. """ found_nodes = {} for cur_node in connections_gen(object_utils.get_m_obj(object_name)): if cur_node.hasFn(OpenMaya.MFn.kBlendWeighted): plugs = object_utils.get_plugs( cur_node, source=False, ignore_nodes=['kBlendWeighted', 'kUnitConversion', 'kNodeGraphEditorInfo']) if "targets" not in found_nodes: found_nodes["targets"] = [] # get plug nodes found_nodes["targets"].extend(plugs) # find what the curve nodes are attached to. if cur_node.hasFn(OpenMaya.MFn.kAnimCurve): if "source" not in found_nodes: found_nodes["source"] = [] plugs = object_utils.get_plugs(cur_node, source=True) for p_node in plugs: if p_node not in found_nodes["source"]: found_nodes["source"].append(p_node) # collect anim nodes. if "animNodes" not in found_nodes: found_nodes["animNodes"] = {} anim_fn = OpenMayaAnim.MFnAnimCurve(cur_node) if anim_fn.numKeys(): anim_node = OpenMaya.MFnDependencyNode(cur_node).name() found_nodes["animNodes"].update(get_animation_data_from_node(anim_node)) # change the lists into tuples if "source" in found_nodes: if found_nodes["source"]: found_nodes["source"] = tuple(found_nodes["source"]) if "targets" in found_nodes: if found_nodes["targets"]: found_nodes["targets"] = tuple(found_nodes["targets"]) return found_nodes
def doTest3(): oNode = om.MObject() selList = om.MSelectionList() selList.add( 'pSphere2' ) selList.getDependNode( 0, oNode ) fnNode = om.MFnDependencyNode( oNode ) txPlug = fnNode.findPlug( 'tx' ) fnAnimCurve = omAnim.MFnAnimCurve() oAnimCurve = fnAnimCurve.create( txPlug ) fnAnimCurve.setObject( oAnimCurve ) time1 = om.MTime( 0 ) time2 = om.MTime( 1 ) fnAnimCurve.addKeyframe( time1, 1 ) fnAnimCurve.addKeyframe( time2, 2 )
def bake_animation(plugs, frame_range=None, step=1): """Bake the animation to all nodes based on the passed list of plugs. Args: plugs (list): List of maya.om.MPlug Plugs to bake the animation to. Keyword Args: frame_range (float, float): Time range in which the keys are to be created. step (float): Time step for each sample. """ frame_range = frame_range or timeline.Timeline.frame_range() start_frame, end_frame = frame_range step_range = get_step_range(start_frame, end_frame, step=step) times = om.MTimeArray(step_range, om.MTime()) plugValues = [om.MDoubleArray(step_range, 0) for i in range(len(plugs))] plugsAndValues = zip(plugs, plugValues) for i in range(step_range): time = om.MTime(start_frame + i * step, om.MTime.kFilm) times.set(time, i) context = om.MDGContext(time) for plug, values in plugsAndValues: values.set(plug.asDouble(context), i) dg = om.MDGModifier() for plug in plugs: sources = om.MPlugArray() plug.connectedTo(sources, True, False) for i in range(sources.length()): dg.disconnect(sources[i], plug) dg.doIt() for plug, values in itertools.izip(plugs, plugValues): curve = oma.MFnAnimCurve() curve.create(plug, dg) curve.addKeys(times, values) dg.doIt()
def _ValidatePxrDiskLightTransformAnimation(self): nodePath = '|RfMLightsTest|Lights|DiskLight' depNodeFn = self._GetMayaDependencyNode(nodePath) animatedPlugs = OpenMaya.MPlugArray() OpenMayaAnim.MAnimUtil.findAnimatedPlugs(depNodeFn.object(), animatedPlugs) self.assertEqual(animatedPlugs.length(), 1) translateYPlug = animatedPlugs[0] self.assertEqual(translateYPlug.name(), 'DiskLight.translateY') animObjs = OpenMaya.MObjectArray() OpenMayaAnim.MAnimUtil.findAnimation(translateYPlug, animObjs) self.assertEqual(animObjs.length(), 1) animCurveFn = OpenMayaAnim.MFnAnimCurve(animObjs[0]) for frame in xrange(int(self.START_TIMECODE), int(self.END_TIMECODE + 1.0)): value = animCurveFn.evaluate(OpenMaya.MTime(frame)) self.assertTrue(Gf.IsClose(float(frame), value, 1e-6))
def test_get_animation(self): mmaya.Scene.new(force=True) p = nt.Node("persp") # translate is animated for tc in p.translate.mchildren(): apianim.MFnAnimCurve().create(tc) # END set animation # test animation iteration for converter in (lambda x: x, lambda x: nt.toSelectionList(x)): for as_node in range(2): nc = 0 target_type = nt.api.MObject if as_node: target_type = nt.Node # END define target type for anode in nt.AnimCurve.findAnimation( converter([p]), as_node): assert isinstance(anode, target_type) nc += 1 # END for each anim node assert nc == 3
def _AssertAnimation(self, dagNodePath, expectedKeyframeTimes, expectedKeyframeValues): self.assertEqual(len(expectedKeyframeTimes), len(expectedKeyframeValues)) dagNode = testUsdImportNestedAssemblyAnimation._GetMayaDagNode( dagNodePath) txPlug = dagNode.findPlug('translateX') animCurveFn = OMA.MFnAnimCurve(txPlug) expectedNumKeys = len(expectedKeyframeTimes) self.assertEqual(animCurveFn.numKeys(), expectedNumKeys) for keyNumber in range(expectedNumKeys): expectedTime = expectedKeyframeTimes[keyNumber] expectedValue = expectedKeyframeValues[keyNumber] keyTime = animCurveFn.time(keyNumber).value() self.assertAlmostEqual(expectedTime, keyTime) keyValue = animCurveFn.value(keyNumber) self.assertAlmostEqual(expectedValue, keyValue)
def create_animcurve(joint, attr): mFn_AnimCurve = OpenMayaAnim.MFnAnimCurve() # use the attribute on the joint to determine which type of anim curve to create in_plug = get_plug(joint, attr) plug_type = mFn_AnimCurve.timedAnimCurveTypeForPlug(in_plug) # create the curve and get its output attribute anim_curve = mFn_AnimCurve.create(plug_type) mFn_AnimCurve.setName('{}_{}'.format(OpenMaya.MFnDependencyNode(joint).name(), attr)) # check for and remove any existing connections if in_plug.isConnected(): mplugs = OpenMaya.MPlugArray() in_plug.connectedTo(mplugs, True, False) for i in range(0, mplugs.length()): m_DGMod = OpenMaya.MDGModifier() m_DGMod.deleteNode(mplugs[i].node()) # connect the new animation curve to the attribute on the joint connect_nodeplugs(anim_curve, 'output', joint, attr) return anim_curve, mFn_AnimCurve
def set_anim_data(anim_data={}, rounded=False): """ sets the existing animation data. This does not create new data. :param anim_data: <dict> animation data from get_anim_data function. :param rounded: <bool> flattens the animation data. :return: <bool> True for success. <bool> False for failure. """ if not anim_data or not isinstance(anim_data, dict): raise ValueError("[SetAnimData :: parameter anim_data is invalid.]") for node_name, a_data in anim_data.items(): if node_name not in a_data: continue num_keys = a_data[node_name]["num_keys"] anim_data = a_data[node_name]["anim_values"] mfn_anim = OpenMayaAnim.MFnAnimCurve(node_name) for i in xrange(num_keys): a_val, a_time = anim_data[i] if rounded: mfn_anim.setTime(i, __round(a_time)) else: mfn_anim.setTime(i, a_time) mfn_anim.setValue(i, a_val) return True
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
def get_kanimCurve(self, mobject): mfn_anim_curve = OpenMayaAnim.MFnAnimCurve(mobject) pre_infinity_type = mfn_anim_curve.preInfinityType() # preInfinityType post_infinity_type = mfn_anim_curve.postInfinityType() # postInfinityType static = mfn_anim_curve.isStatic() weighted = mfn_anim_curve.isWeighted() num_keys = mfn_anim_curve.numKeys() times = [] values = [] in_tangents = [] out_tangents = [] in_tangents_angle_weight = [] out_tangents_angle_weight = [] int_angents_type = [] out_tangents_type = [] breakdowns = [] weights_locked = [] tangents_locked = [] for index in range (num_keys): time = mfn_anim_curve.time(index).value() value = mfn_anim_curve.value(index) intangent_x, intangent_y = self.get_tanget(mfn_anim_curve, index, True) # In Tangent outtangent_x, outtangent_y = self.get_tanget(mfn_anim_curve, index, False) # Out Tangent intangent_angle, intangent_weight = self.get_tanget_angle_weight(mfn_anim_curve, index, True) # In Tangent angle and weight outtangent_angle, outtangent_weight = self.get_tanget_angle_weight(mfn_anim_curve, index, False) # out Tangent angle and weight in_tangent_type = mfn_anim_curve.inTangentType(index) # In Tangent Type out_tangent_type = mfn_anim_curve.outTangentType(index) # Out Tangent Type breakdown = mfn_anim_curve.isBreakdown(index) # isBreakdown weight_locked = mfn_anim_curve.weightsLocked(index) tangent_locked = mfn_anim_curve.tangentsLocked(index) times.append(time) values.append(value) in_tangents.append([intangent_x, intangent_y]) out_tangents.append([outtangent_x, outtangent_y]) in_tangents_angle_weight.append([intangent_angle, intangent_weight]) out_tangents_angle_weight.append([outtangent_angle, outtangent_weight]) int_angents_type.append(in_tangent_type) out_tangents_type.append(out_tangent_type) breakdowns.append(breakdown) weights_locked.append(weight_locked) tangents_locked.append(tangent_locked) anim_curve_data = { 'anim_curve': mfn_anim_curve.name(), 'pre_infinity_type': pre_infinity_type, 'post_infinity_type': post_infinity_type, 'static': static, 'weighted': weighted, 'time': times, 'value': values, 'num_keys': num_keys, 'in_tangent': in_tangents, 'out_tangent': out_tangents, 'in_tangent_angle_weight': in_tangents_angle_weight, 'out_tangent_angle_weight': out_tangents_angle_weight, 'in_tangent_type': int_angents_type, 'out_tangent_type': out_tangents_type, 'breakdown': breakdowns, 'weightlocked': weights_locked, 'tangentlocked': tangents_locked, } return anim_curve_data
def get_animation_data_from_node(object_node=""): """ get the animation data from the node specified. :param object_node: <str> the object to check the data frOpenMaya. :return: <dict> key data. """ if not object_node: return False o_anim = None if isinstance(object_node, (str, unicode)): m_object = object_utils.get_m_obj(object_node) o_anim = OpenMayaAnim.MFnAnimCurve(m_object) if isinstance(object_node, OpenMayaAnim.MFnAnimCurve): o_anim = object_node object_node = o_anim.name() if isinstance(object_node, OpenMaya.MObject): o_anim = OpenMayaAnim.MFnAnimCurve(object_node) object_node = o_anim.name() # get connections source_attr = object_utils.get_plugs( object_node, source=True) destination_attr = object_utils.get_plugs( object_node, source=False, ignore_nodes=['kUnitConversion', 'kBlendWeighted', 'kNodeGraphEditorInfo']) # get the time from the keys supplied number_of_keys = o_anim.numKeys() anim_data = {} if number_of_keys > 1: anim_data[object_node] = {'data': {}, 'tangents': {}, 'sourceAttr': source_attr, 'targetAttr': destination_attr } for i_key in xrange(number_of_keys): # this is a lie # i_x = _float_ptr.get_float_ptr() # i_y = _float_ptr.get_float_ptr() # # o_x = _float_ptr.get_float_ptr() # o_y = _float_ptr.get_float_ptr() # # o_anim.getTangent(i_key, i_x, i_y, True) # o_anim.getTangent(i_key, o_x, o_y, True) # this is a lie # v_float = o_anim.value(i_key) # this will get me the values that I want. # anim_data[object_node]['tangents'][i_key] = (ScriptUtil(i_x).asFloat(), ScriptUtil(i_y).asFloat(), # ScriptUtil(o_x).asFloat(), ScriptUtil(o_y).asFloat()) # anim_data[object_node]['tangents'][i_key] = (ScriptUtil(o_x).asFloat(), ScriptUtil(o_y).asFloat()) # get the information the standard way v_float = cmds.keyframe(object_node, q=1, valueChange=1)[i_key] try: t_float = cmds.keyframe(object_node, floatChange=1, q=1)[i_key] except TypeError: t_float = i_key o_x = cmds.getAttr('{}.keyTanOutX[{}]'.format(object_node, i_key)) o_y = cmds.getAttr('{}.keyTanOutY[{}]'.format(object_node, i_key)) i_x = cmds.getAttr('{}.keyTanInX[{}]'.format(object_node, i_key)) i_y = cmds.getAttr('{}.keyTanInY[{}]'.format(object_node, i_key)) # save the information anim_data[object_node]['tangents'][t_float] = {'out': (o_x, o_y), 'in': (i_x, i_y), 'keyNum': i_key} anim_data[object_node]['data'][t_float] = v_float return anim_data
def smooth_animcurve(animcurve, selected_keyframes, smooth_type, width, blend_smooth_type, blend_width): """ Smooth the given keyframes for an animCurve. :param animcurve: Animation curve node name. :type animcurve: str :param selected_keyframes: The frame numbers that are 'selected' to be smoothed. :type selected_keyframes: [int, ..] or [] :param smooth_type: What algorithm to use for smoothing. :type smooth_type: ? :param width: The width of the smoothing kernel; higher values produce more smoothing, and is slower to compute. :type width: float :param blend_smooth_type: What algorithm to use for smoothing the blend? :type blend_smooth_type: ? :param blend_width: The width of the smoothing kernel; higher values produce more smoothing, and is slower to compute. :type blend_width: float """ times = maya.cmds.keyframe(animcurve, query=True, timeChange=True) if len(times) < 1: return first_time = int(times[0]) last_time = int(times[-1]) first_time_padded = int(first_time - (width * 2)) last_time_padded = int(last_time + (width * 2)) all_times = xrange(first_time_padded, last_time_padded + 1) sel_first_time = int(selected_keyframes[0]) sel_last_time = int(selected_keyframes[-1]) sel_range_length = sel_last_time - sel_first_time original_range_length = last_time - first_time all_keys_selected = original_range_length == sel_range_length plug = animcurve + '.output' animCurve_obj = node_utils.get_as_object_apione(animcurve) animCurve_fn = OpenMayaAnim1.MFnAnimCurve(animCurve_obj) animCurve_type = animCurve_fn.animCurveType() ui_unit = OpenMaya1.MTime.uiUnit() initial_weight = 0.0 if all_keys_selected: initial_weight = 1.0 values = [] weight_array = [initial_weight] * len(all_times) value_array = [None] * len(all_times) for i, t in enumerate(all_times): frame = OpenMaya1.MTime(float(t), ui_unit) value = animCurve_fn.evaluate(frame) if animCurve_type == OpenMayaAnim1.MFnAnimCurve.kAnimCurveTA: value = math.degrees(value) value_array[i] = value if t < first_time: first_weight = initial_weight weight_array[i] = first_weight continue if t > last_time: last_weight = initial_weight weight_array[i] = last_weight continue if t in selected_keyframes: weight_array[i] = 1.0 new_weight_array = utils_smooth.smooth( blend_smooth_type, weight_array, width ) new_value_array = utils_smooth.smooth( smooth_type, value_array, blend_width ) assert len(value_array) == len(new_value_array) assert len(weight_array) == len(new_weight_array) if all_keys_selected is False: new_value_array = blend_curves_with_difference( selected_keyframes, all_times, value_array, new_value_array, ) # Blend betwen original and smoothed curves using the weight. for frame, old_value, new_value, weight in zip(all_times, value_array, new_value_array, new_weight_array): if frame not in times: continue inverse_weight = 1.0 - weight v = (new_value * weight) + (old_value * inverse_weight) time_range = (frame, frame) maya.cmds.keyframe( animcurve, valueChange=v, time=time_range) return
def getAnimData(self, mobject): mfn_anim_curve = OpenMayaAnim.MFnAnimCurve(mobject) pre_infinity = mfn_anim_curve.preInfinityType() post_infinity = mfn_anim_curve.postInfinityType() weighted_tangent = mfn_anim_curve.isWeighted() num_keys = mfn_anim_curve.numKeys() time_list = [] key_list = [] in_tangent_x_list = [] in_tangent_y_list = [] out_tangent_x_list = [] out_tangent_y_list = [] in_tangent_angle_list = [] in_tangent_weight_list = [] out_tangent_angle_list = [] out_tangent_weight_list = [] in_tangent_type_list = [] out_tangent_type_list = [] breakdown_list = [] for index in range(num_keys): time = mfn_anim_curve.time(index).value() key_value = mfn_anim_curve.value(index) in_tangent_x = OpenMaya.MScriptUtil().asFloatPtr() in_tangent_y = OpenMaya.MScriptUtil().asFloatPtr() out_tangent_x = OpenMaya.MScriptUtil().asFloatPtr() out_tangent_y = OpenMaya.MScriptUtil().asFloatPtr() in_tangent_angle = OpenMaya.MAngle() in_tangent_weight = OpenMaya.MScriptUtil().asDoublePtr() out_tangent_angle = OpenMaya.MAngle() out_tangent_weight = OpenMaya.MScriptUtil().asDoublePtr() #================================================================== # mfn_anim_curve.getTangent(index, in_tangent_x, in_tangent_y, True) # mfn_anim_curve.getTangent(index, out_tangent_x, out_tangent_y, False) # mfn_anim_curve.getTangent(index, in_tangent_angle, in_tangent_weight, True) # mfn_anim_curve.getTangent(index, out_tangent_angle, out_tangent_weight, False) #================================================================== in_tangent_type = mfn_anim_curve.inTangentType(index) out_tangent_type = mfn_anim_curve.outTangentType(index) breakdown = mfn_anim_curve.isBreakdown(index) time_list.append(time) key_list.append(key_value) in_tangent_x_list.append( OpenMaya.MScriptUtil.getFloat(in_tangent_x)) in_tangent_y_list.append( OpenMaya.MScriptUtil.getFloat(in_tangent_y)) out_tangent_x_list.append( OpenMaya.MScriptUtil.getFloat(out_tangent_x)) out_tangent_y_list.append( OpenMaya.MScriptUtil.getFloat(out_tangent_y)) in_tangent_angle_list.append(in_tangent_angle.value()) in_tangent_weight_list.append( OpenMaya.MScriptUtil.getDouble(in_tangent_weight)) out_tangent_angle_list.append(out_tangent_angle.value()) out_tangent_weight_list.append( OpenMaya.MScriptUtil.getDouble(out_tangent_weight)) in_tangent_type_list.append(in_tangent_type) out_tangent_type_list.append(out_tangent_type) breakdown_list.append(breakdown) anim_curve_data = {} anim_curve_data['time'] = time_list anim_curve_data['key'] = key_list anim_curve_data['in_tangent_x'] = in_tangent_x_list anim_curve_data['in_tangent_y'] = in_tangent_y_list anim_curve_data['out_tangent_x'] = out_tangent_x_list anim_curve_data['out_tangent_y'] = out_tangent_y_list anim_curve_data['in_tangent_angle'] = in_tangent_angle_list anim_curve_data['in_tangent_weight'] = in_tangent_weight_list anim_curve_data['out_tangent_angle'] = out_tangent_angle_list anim_curve_data['out_tangent_weight'] = out_tangent_weight_list anim_curve_data['in_tangent_type'] = in_tangent_type_list anim_curve_data['out_tangent_type'] = out_tangent_type_list anim_curve_data['breakdown'] = breakdown_list anim_curve_data['name'] = mfn_anim_curve.name().encode() return anim_curve_data
def importBakeData( cachePath ): transformBakePath = cachePath+'/transformBake.cPickle' f = open( transformBakePath, 'r' ) importedData = cPickle.load( f ) namespaces, filePaths, cacheBodyPaths, objectList, timeUnit = importedData cmds.currentUnit( time=timeUnit ) for k in range( len( namespaces ) ): cacheBodyPath = cacheBodyPaths[k] #print "cachebody path : ", cacheBodyPath if not os.path.exists( cacheBodyPath ): continue cmds.file( cacheBodyPath, i=True, type="mayaBinary", mergeNamespacesOnClash=False, ra=True, namespace = 'cachebody%d' % k, options= "v=0;", pr=1, loadReferenceDepth="all" ) for i in range( len( objectList ) ): namespaceIndex, parentIndex, tr, trMtx, trPiv, attrInfoList = objectList[i] if namespaceIndex != None: origName = tr.split( '|' )[-1].replace( namespaces[ namespaceIndex ][1:]+':', '' ) targetCacheBody = 'cachebody%d:%s' %( namespaceIndex , origName ) else: origName = tr.split( '|' )[-1] targetCacheBody = origName if not cmds.objExists( targetCacheBody ): targetCacheBody = cmds.createNode( 'transform', n=targetCacheBody ) if parentIndex != -1: try:targetCacheBody = cmds.parent( targetCacheBody, objectList[ parentIndex ][2] )[0] except:pass try: cmds.xform( targetCacheBody, os=1, matrix=trMtx ) cmds.xform( targetCacheBody, os=1, piv=trPiv ) objectList[i][2] = cmds.ls( targetCacheBody, l=1 )[0] except: continue for attrInfo in attrInfoList: attr, animCurveInfos = attrInfo if type( animCurveInfos ) == type( [] ): animCurve = cmds.createNode( 'animCurveTU', n=origName+'_'+attr ) fnAnimCurve = omAnim.MFnAnimCurve( sgModelDg.getMObject( animCurve ) ) time = om.MTime() for animCurveInfo in animCurveInfos: timeValue, value = animCurveInfo time.setValue( timeValue ) fnAnimCurve.addKey( time, value ) #print animCurve, targetCacheBody, attr try:cmds.connectAttr( animCurve+'.output', targetCacheBody+'.'+attr, f=1 ) except:pass else: try: animCurve = animCurveInfo.createAnimCurve() cmds.connectAttr( animCurve+'.output', targetCacheBody + '.' + attr, f=1 ) except:pass targetMesh = sgModelDag.getShape( targetCacheBody ) if not targetMesh: continue if namespaceIndex == None: continue xmlFileName = namespaces[ namespaceIndex ][1:] + '_' + origName.replace( ':', '_' )+'Shape.xml' xmlFilePath = cachePath + '/' + xmlFileName if os.path.exists( xmlFilePath ): print 'xml file path : ', xmlFilePath importCache( targetMesh, xmlFilePath )
def get_curve_statistics(attr): curve = create_curve_statistics() plug_name = attr.get_name() anim_curves = animcurve_utils.get_anim_curves_from_nodes([plug_name]) if len(anim_curves) == 0: return curve anim_curve_name = anim_curves[0] obj = node_utils.get_as_object_apione(anim_curve_name) animfn = OpenMayaAnim1.MFnAnimCurve(obj) animCurveType = animfn.animCurveType() ui_unit = OpenMaya1.MTime.uiUnit() num_keys = animfn.numKeys() start_time = animfn.time(0) end_time = animfn.time(num_keys - 1) start_frame = int(start_time.asUnits(ui_unit)) end_frame = int(end_time.asUnits(ui_unit)) frame_nums = end_frame - start_frame values = [] curve_min_value = 999999999.0 curve_max_value = -999999999.0 curve_mean_value = 0.0 for i, frame in enumerate(range(start_frame, end_frame + 1)): t = OpenMaya1.MTime(float(frame), ui_unit) value = animfn.evaluate(t) if animCurveType == OpenMayaAnim1.MFnAnimCurve.kAnimCurveTA: value = math.degrees(value) values.append(value) curve_min_value = min(curve_min_value, value) curve_max_value = max(curve_max_value, value) curve_mean_value += value curve_mean_value /= len(values) curve_variance = 0.0 for value in values: diff = value - curve_mean_value diff = diff * diff curve_variance += diff curve_variance /= len(values) curve_variance = math.sqrt(curve_variance) curve_max_variance = 0.0 curve_frame_variance = 0.0 for i, value in enumerate(values): idx_prev = max(0, i - 1) idx_next = min(i + 1, len(values) - 1) value_prev = values[idx_prev] value_next = values[idx_next] diff = abs(value - value_prev) curve_max_variance = max(curve_max_variance, diff) diff = diff * diff curve_frame_variance += diff diff = abs(value - value_next) curve_max_variance = max(curve_max_variance, diff) diff = diff * diff curve_frame_variance += diff curve_frame_variance /= len(values) * 2 curve_frame_variance = math.sqrt(curve_frame_variance) curve = create_curve_statistics( min_value=curve_min_value, max_value=curve_max_value, mean_value=curve_mean_value, variance=curve_variance, frame_variance=curve_frame_variance, max_variance=curve_max_variance, ) return curve