def get_skin_cluster(self, mesh_fn): ''' get a list of all the skin clusters in the file, iterate and see if the shapes connected match our selection ''' <<<<<<< HEAD self.inPlug = fnMesh.findPlug('inMesh', False) connections = self.inPlug.connectedTo(True, False) ======= self.in_plug = mesh_fn.findPlug('inMesh', False) connections = self.in_plug.connectedTo(True, False) >>>>>>> e58b6e68c85df042e9c07d31d823cd1914263493 for c in connections: obj = c.node() try: skin_cluster_fn = oma.MFnSkinCluster(obj) return skin_cluster_fn except: sys.stderr.write("No skin cluster found! ") return None def initializePlugin(plugin): plugin_fn = om.MFnPlugin(plugin) try: plugin_fn.registerCommand(ZooSurgeonCommand.cmd_name, ZooSurgeonCommand.creator) except: sys.stderr.write("Failed to register command: " + ZooSurgeonCommand.cmd_name) def uninitializePlugin(mobject): plugin_fn = om.MFnPlugin(mobject)
def prepare(mode): """ Prepares the dictionary of animation curves along with values before/after required to interpolate. """ global anim_cache global curve_key_values # get curves if utils.is_graph_editor(): curves = utils.get_selected_anim_curves() plugs = None else: nodes = utils.get_selected_objects() curves, plugs = utils.get_anim_curves_from_objects(nodes) # get prev and next values so we can use them to blend while dragging slider is_default = bool(mode == options.BlendingMode.default) is_curve_tangent = bool(mode == options.BlendingMode.curve) curve_key_values = {} time_range = utils.get_time_slider_range() unit = om.MTime.uiUnit() mtime_range = (om.MTime(time_range[0], unit), om.MTime(time_range[1], unit)) for plug_idx, curve_node in enumerate(curves): curve_fn = oma.MFnAnimCurve(curve_node.object()) default_val = None if is_default: if plugs: default_val = utils.get_attribute_default_value( plugs[plug_idx]) else: default_val = utils.get_anim_curve_default_value(curve_fn) key_group = KeyGroup(key_index=[], value=[], default_value=default_val, prev_value=[], next_value=[], tangent_points=[], has_two_segments=[]) selected_keys = cmds.keyframe(str(curve_fn.absoluteName()), q=True, selected=True, indexValue=True) if time_range[0] - time_range[1] != 0: # time range selected on time slider indices = cmds.keyframe(str(curve_fn.name()), q=True, time=time_range, iv=True) if indices is None: continue if indices[0] == 0: prev_index = 0 else: prev_index = indices[0] - 1 num_keys = curve_fn.numKeys next_index = indices[-1] + 1 if next_index >= num_keys: next_index = num_keys - 1 for idx in indices: add_to_key_group(curve_fn, idx, prev_index, next_index, key_group) if is_curve_tangent: for idx in indices: add_tangent_points_to_key_group(key_group, curve_fn, prev_index, next_index, idx) curve_key_values[curve_fn] = key_group elif selected_keys is not None: # keys selected in graph editor or dope sheet index_group = [] groups = [] # find groups of consecutive key indices index_group.append(selected_keys[0]) for i in range(1, len(selected_keys)): if selected_keys[i] - selected_keys[i - 1] < 2: index_group.append(selected_keys[i]) else: groups.append(index_group) index_group = [selected_keys[i]] # append last iteration groups.append(index_group) for grp in groups: prev_index = max(0, grp[0] - 1) next_index = min(grp[-1] + 1, curve_fn.numKeys - 1) for idx in grp: add_to_key_group(curve_fn, idx, prev_index, next_index, key_group) if is_curve_tangent: for idx in grp: add_tangent_points_to_key_group(key_group, curve_fn, prev_index, next_index, index=idx) curve_key_values[curve_fn] = key_group else: # no time range or keys selected current_index = curve_fn.find(mtime_range[0]) closest_index = curve_fn.findClosest(mtime_range[0]) closest_time = curve_fn.input(closest_index) if current_index is not None: prev_index = max(0, closest_index - 1) next_index = min(curve_fn.numKeys - 1, closest_index + 1) # key exists, so two curve tangent segments if is_curve_tangent: add_tangent_points_to_key_group(key_group, curve_fn, prev_index, next_index, current_index) else: if (closest_time.value - mtime_range[0].value) <= 0: prev_index = closest_index next_index = closest_index + 1 else: prev_index = closest_index - 1 next_index = closest_index if prev_index < 0: prev_index = 0 # add new key value = curve_fn.evaluate(mtime_range[0]) current_index = curve_fn.addKey(mtime_range[0], value, change=anim_cache) next_index = min(curve_fn.numKeys - 1, next_index + 1) # there isn't any key yet, so we only have one tangent segment and thus index=None if is_curve_tangent: add_tangent_points_to_key_group(key_group, curve_fn, prev_index, next_index, index=current_index) add_to_key_group(curve_fn, current_index, prev_index, next_index, key_group) curve_key_values[curve_fn] = key_group
#获得一个组件列表 cmp_list = [universal.intoComponents(i) for i in universal.translateToName(geo)] #检查组件列表的数量 if len(cmp_list)<1: raise EOFError('geo没有任何对象') #建立一个组件选择列表 sel_list = om.MSelectionList() [sel_list.add(i) for i in cmp_list] if int(sel_list.length())>1: raise EOFError('%s 不在一个mesh或者其他对象上'%geo) return 1 path,comp = sel_list.getComponent(0) sel_list.add(skinNode) skinNode = sel_list.getDependNode(1) fn_skin = oma.MFnSkinCluster(skinNode) m_inf = om.MIntArray(inf) m_weigth = om.MDoubleArray(weigth) unWeights = fn_skin.getWeights(path,comp,m_inf) doIt = functools.partial(fn_skin.setWeights,path,comp,m_inf,m_weigth) undoIt = functools.partial(fn_skin.setWeights,path,comp,m_inf,unWeights) cmcore.addCommand(doIt, undoIt) fl_array = fn_skin.getBlendWeights(path,comp) fn_skin.setBlendWeights(path,comp,fl_array) class SetWeights: '''
def write(path, target, skin=None, outdir=None, start=None, end=None): """ Write out data for the machine learning algorithm to train from. :param path: The path to the mesh we're writing data for. :param target: The target mesh to compare the vertices to. :param skin: The skin cluster to read weights from. :param outdir: The directory to write to. If no directory is provided, uses training directory. :param start: The start frame to write from. :param end: The end frame to write to :return: The path to the written data. """ # Make sure we can write out the data if not outdir: logger.warning('No output directory specified. Using default: %s', DEFAULT_LOCATION) outdir = DEFAULT_LOCATION if not os.path.exists(outdir): os.mkdir(outdir) # Figure out the start and end range if start is None: start = mc.playbackOptions(minTime=True, query=True) if end is None: end = mc.playbackOptions(maxTime=True, query=True) start = int(math.floor(start)) end = int(math.ceil(end)) currentTime = mc.currentTime(query=True) # Get the meshes sel = om.MSelectionList() sel.add(skinning.get_mesh(path)) sel.add(skinning.get_mesh(target)) mesh = om.MFnMesh(sel.getDagPath(0)) target_mesh = om.MFnMesh(sel.getDagPath(1)) # Get the skin cluster if not skin: skin = skinning.get_skincluster(mesh.fullPathName()) sel.add(skin) skin_node = sel.getDependNode(2) skin_cluster = oma.MFnSkinCluster(skin_node) # Get the weights vertices = range(mesh.numVertices) influence_objects = skin_cluster.influenceObjects() joints = [i.fullPathName() for i in influence_objects] joint_transforms = [om.MFnTransform(j) for j in influence_objects] influence_indexes, vertex_cmpt, weights = skinning.get_weights( mesh, skin_cluster, vertices) stride = len(influence_indexes) # Store the weight associations for vertices weight_map = [] joint_map = [] for i in range(stride): joint_map.append(list()) for vtx in vertices: vtx_weights = weights[vtx * stride:(vtx * stride) + stride] for i, weight in enumerate(vtx_weights): if weight > 0: weight_map.append(i) joint_map[i].append(vtx) break # Prepare data for joints frame_data = {} for joint in joints: frame_data[joint] = [] # Go through every frame and write out the data for all the joints and the vertexes for frame in range(start, end + 1): logger.debug('Processing frame %s', frame) mc.currentTime(frame) points = mesh.getPoints() target_points = target_mesh.getPoints() for jidx, vertices in enumerate(joint_map): xform = joint_transforms[jidx] rotation = xform.rotation(om.MSpace.kWorld, asQuaternion=True) translate = xform.translation(om.MSpace.kWorld) data = [] data += rotation data += translate for vtx in vertices: mpoint = points[vtx] tpoint = target_points[vtx] displacement = tpoint - mpoint data += displacement frame_data[joints[jidx]].append(data) # Write the data out to csv files csv_files = [] for joint in joints: data = frame_data[joint] filename = '%s.csv' % joint.replace('|', '_') if filename.startswith('_'): filename = filename[1:] filename = os.path.join(outdir, filename) logger.info('Wrote data for %s to %s', joint, filename) heading = ['rx', 'ry', 'rz', 'rw', 'tx', 'ty', 'tz'] verts = joint_map[joints.index(joint)] for v in verts: heading.extend(['vtx%sx' % v, 'vtx%sy' % v, 'vtx%sz' % v]) with open(filename, 'w') as f: writer = csv.writer(f) writer.writerow(heading) writer.writerows(data) csv_files.append(filename) mc.currentTime(currentTime) map_data = { 'joint_names': joints, 'joint_indexes': [i for i in influence_indexes], 'weights': weight_map, 'csv_files': csv_files, 'joint_map': joint_map, 'input_fields': ['rx', 'ry', 'rz', 'rw', 'tx', 'ty', 'tz'] } # Finally write out the data map_file = os.path.join(outdir, 'input_data.json') with open(map_file, 'w') as f: json.dump(map_data, f) logger.info('Wrote Weight Map to %s', map_file) return outdir
outTangentTypeList = objectAttriData['outTangentTypeList'] outTangentAngleList = objectAttriData['outTangentAngleList'] outTangentWeightList = objectAttriData['outTangentWeightList'] # Convert current object and attribute to a new MPlug object mSelectionList = om.MSelectionList() mSelectionList.add('%s.%s' % (currentObject, currentAttribute)) currentMPlug = mSelectionList.getPlug(0) connectedList = currentMPlug.connectedTo(1, 0) newAnimCurve = 1 if connectedList: connectedNode = connectedList[0].node() if connectedNode.hasFn(om.MFn.kAnimCurve): mfnAnimCurve = oma.MFnAnimCurve(connectedNode) newAnimCurve = 0 if newAnimCurve == 1: mfnAnimCurve = oma.MFnAnimCurve() mfnAnimCurve.create(currentMPlug, animCurveType) mfnAnimCurve.setPreInfinityType(preInfinity) mfnAnimCurve.setPostInfinityType(postInfinity) mfnAnimCurve.setIsWeighted(weightedTangents) mTimeList = om.MTimeArray() mDoubleValueList = om.MDoubleArray() for keyIndex in range(len(timeList)): mTimeList.append(om.MTime(timeList[keyIndex], om.MTime.uiUnit()))
def exportAnimCurve(selectionList, animPath, animName, animGIFPath, iconPath): animDataDict = {} for currentObject in selectionList: objMSL = om.MSelectionList() objMSL.add(currentObject) objMObject = objMSL.getDependNode(0) # find the attribute of current object objMFnDPNode = om.MFnDependencyNode(objMObject) attributeCount = objMFnDPNode.attributeCount() nodeAnimInformationDict = {} for attributeIndex in range(attributeCount): attributeMObject = objMFnDPNode.attribute(attributeIndex) MFnAttribute = om.MFnAttribute(attributeMObject) attributeName = MFnAttribute.name # find the attribute that anim curve connected currentPlug = objMFnDPNode.findPlug(attributeName, 1) if currentPlug.connectedTo(1, 0): currentConnectedList = currentPlug.connectedTo(1, 0) # find the connected node type currentConnectNodeMObject = currentConnectedList[0].node() # check it is an anim curve if currentConnectNodeMObject.hasFn(om.MFn.kAnimCurve): # get anim curve MFnAnimCurve = oma.MFnAnimCurve(currentConnectNodeMObject) # get attribute animCurveType = MFnAnimCurve.animCurveType preInfinity = MFnAnimCurve.preInfinityType postInfinity = MFnAnimCurve.postInfinityType weightedTangents = int(MFnAnimCurve.isWeighted) # get value of each key numKeys = MFnAnimCurve.numKeys timeList = [] valueList = [] inTangentTypeList = [] inTangentAngleList = [] inTangentAngleWeightList = [] outTangentTypeList = [] outTangentAngleList = [] outTangentAngleWeightList = [] for index in range(numKeys): # time input = MFnAnimCurve.input(index) mTime = om.MTime(input) currentTime = mTime.value timeList.append(currentTime) # value value = MFnAnimCurve.value(index) valueList.append(value) # inTangent inTangentType = MFnAnimCurve.inTangentType(index) inTangentTypeList.append(inTangentType) inTangentAngleWeight = MFnAnimCurve.getTangentAngleWeight(index, 1) inTangentAngleMAngle = om.MAngle(inTangentAngleWeight[0]) inTangentValue = inTangentAngleMAngle.value inTangentAngleList.append(inTangentValue) inTangentAngleWeightList.append(inTangentAngleWeight[1]) # outTangent outTangentType = MFnAnimCurve.outTangentType(index) outTangentTypeList.append(outTangentType) outTangentAngleWeight = MFnAnimCurve.getTangentAngleWeight(index, 0) outTangentAngleMAngle = om.MAngle(outTangentAngleWeight[0]) outTangetValue = outTangentAngleMAngle.value outTangentAngleList.append(outTangetValue) outTangentAngleWeightList.append(outTangentAngleWeight[1]) attributeDataDict = {'animCurveType': animCurveType, 'preInfinity': preInfinity, 'postInfinity': postInfinity, 'weightedTangents': weightedTangents, 'numKeys': numKeys, 'timeList': timeList, 'valueList': valueList, 'inTangentTypeList': inTangentTypeList, 'inTangentAngleList': inTangentAngleList, 'inTangentAngleWeightList': inTangentAngleWeightList, 'outTangentAngleList': outTangentAngleList, 'outTangentTypeList': outTangentTypeList, 'outTangentAngleWeightList': outTangentAngleWeightList} nodeAnimInformationDict.setdefault(attributeName, attributeDataDict) animDataDict.setdefault(currentObject.encode(), nodeAnimInformationDict) # Data History owner = os.getenv('USERNAME') time = datetime.datetime.now().strftime("%A, %B, %d, %Y %H:%M %p") mayaVersion = cmds.about(q=1, v=1) version = '0.1' dataList = {'animCurve': animDataDict, 'history': [owner, time, mayaVersion, version]} dataPath = '%s/%s.anim' % (animPath, animName) if os.path.isfile(dataPath): try: os.chmod(dataPath, 0777) os.remove(dataPath) except Exception, result: print result
# joint1 joint2 # weightList = [[0.2, 0.3, ...], [0.3, 0.2, ...]] weightList.append(jointWeights) # translate back to original position mFnTransform.setTranslation(world, om.MSpace.kWorld) # bind skin geoSkinCluster = cmds.skinCluster(jointList, geometry)[0] geoSkinMSelectionList = om.MSelectionList() geoSkinMSelectionList.add(geoSkinCluster) geoSkinMObject = geoSkinMSelectionList.getDependNode(0) mFnGeoSkinCluster = oma.MFnSkinCluster(geoSkinMObject) vertexIndexList = range(len(geoPosition)) mFnIndexComponent = om.MFnSingleIndexedComponent() vertexComponent = mFnIndexComponent.create(om.MFn.kMeshVertComponent) mFnIndexComponent.addElements(vertexIndexList) influenceObjects = mFnGeoSkinCluster.influenceObjects() influenceIntList = om.MIntArray() for each in influenceObjects: currentIndex = mFnGeoSkinCluster.indexForInfluenceObject(each) influenceIntList.append(currentIndex) mWeightList = om.MDoubleArray() for wIndex in range(len(weightList[0])): for jntIndex in range(len(weightList)):
jointWeights.append(weight) weightList.append(jointWeights) mFnTransform.setTranslation(world, om.MSpace.kWorld) if jntParent: cmds.parent(jointList[index], jntParent[0]) if jntChild: cmds.parent(jntChild[0], jointList[index]) # Set join weight to geometry geoSkinCluster = cmds.skinCluster(jointList, geometry)[0] skinMSelection = om.MSelectionList() skinMSelection.add(geoSkinCluster) skinMObject = skinMSelection.getDependNode(0) mfnSkinCluster = oma.MFnSkinCluster(skinMObject) # Vertex components vertexIndexList = range(len(geoPosition)) mfnIndexComp = om.MFnSingleIndexedComponent() vertexComp = mfnIndexComp.create(om.MFn.kMeshVertComponent) mfnIndexComp.addElements(vertexIndexList) # influences influenceObjects = mfnSkinCluster.influenceObjects() influenceList = om.MIntArray() for eachInfluenceObject in influenceObjects: currentIndex = mfnSkinCluster.indexForInfluenceObject(eachInfluenceObject) influenceList.append(currentIndex) # weights
def truncateWeights(skinCls, geo): """ Shorten the weight values of the skin cluster to 5 decimal places. [Args]: skinCls (string) - The name of the skin cluster to truncate geo (string) - The geometry the skin cluster is connected to """ # ## remove inused influences # allInfs = cmds.skinCluster(skinCls, q=1, inf=1) # nonZInfs = cmds.skinCluster(skinCls, q=1, wi=1) # for each in allInfs: # if each not in nonZInfs: # cmds.skinCluster(skinCls, e=1, ri=each) normVal = cmds.getAttr('{}.normalizeWeights'.format(skinCls)) cmds.setAttr('{}.normalizeWeights'.format(skinCls), 0) cmds.skinPercent(skinCls, geo, prw=0.001, nrm=1) skinMObj = apiFn.getMObj(skinCls) skin = oma.MFnSkinCluster(skinMObj) inflObj = skin.influenceObjects() inflIdList = {} for x in range(len(inflObj)): inflId = int(skin.indexForInfluenceObject(inflObj[x])) inflIdList[inflId] = x weightListPlug = skin.findPlug('weightList', False) weightsPlug = skin.findPlug('weights', False) weightListAttr = weightListPlug.attribute() weightsAttr = weightsPlug.attribute() for i, vertId in enumerate(range(weightListPlug.numElements())): vertWeights = {} weightsPlug.selectAncestorLogicalIndex(vertId, weightListAttr) weightInfluenceIds = weightsPlug.getExistingArrayAttributeIndices() remainder = 1 largestIndex = None largestVal = 0 inflPlug = om.MPlug(weightsPlug) for inflId in weightInfluenceIds: inflPlug.selectAncestorLogicalIndex(inflId, weightsAttr) try: vertWeights[inflIdList[inflId]] = val = round( inflPlug.asDouble(), 5) if val > largestVal: largestVal = val largestIndex = inflIdList[inflId] remainder -= val except KeyError: pass if largestVal <= 0: continue vertWeights[largestIndex] = round( vertWeights[largestIndex] + remainder, 5) for inflId in weightInfluenceIds: inflPlug.selectAncestorLogicalIndex(inflId, weightsAttr) cmds.setAttr( '{}.weightList[{}].weights[{}]'.format(skinCls, vertId, inflId), vertWeights[inflIdList[inflId]]) cmds.setAttr('{}.normalizeWeights'.format(skinCls), normVal)
def redoIt(self): # get the skin cluster MObject by going up the history skinClusterMObjects = self.findUpstreamNodesOfType( self.dagPath.node(), om.MFn.kSkinClusterFilter) if not skinClusterMObjects: om.MGlobal.displayError( 'Given mesh {} has no skin cluster.'.format( self.dagPath.partialPathName())) return skinClusterMObject = skinClusterMObjects[0] fnSkinCluster = omAnim.MFnSkinCluster(skinClusterMObject) numInfluences = len(fnSkinCluster.influenceObjects()) influenceIndices = om.MIntArray() for influence in xrange(numInfluences): influenceIndices.append(influence) # for the starting weights, we need to get weights on every vertex so we have neighbors # originalWeights = fnSkinCluster.getWeights(self.dagPath, emptyComponent, influenceIndices) # make the original weights just the selected components and its neighbor weights originalWeights = fnSkinCluster.getWeights( self.dagPath, self.selectedComponentsWithNeighbors, influenceIndices) oldWeights = om.MDoubleArray(originalWeights) vertIdToWeightListIndexMap = {} # Quickly create a mapping between the weights and their vertex id itVerts = om.MItMeshVertex(self.dagPath, self.selectedComponentsWithNeighbors) weightListId = 0 while not itVerts.isDone(): vertIdToWeightListIndexMap[int(itVerts.index())] = weightListId weightListId += 1 itVerts.next() # newWeights just starts as a copy of oldWeights newWeights = list(om.MDoubleArray(oldWeights)) # iterate over the selected verts itVerts = om.MItMeshVertex(self.dagPath, self.selectedComponents) weightListId = 0 while not itVerts.isDone(): isBoundaryVertex = itVerts.onBoundary() # option to skip evaluation on boundary vertices if self.pinBorderVerts and isBoundaryVertex: itVerts.next() else: neighborVerts = itVerts.getConnectedVertices() neighborWeightSums = [0.0] * numInfluences numNeighbors = len(neighborVerts) # When trying to smooth weights on just a subset of vertices, we need a way to # match a vertex's neighbor vert id to that neighbor vertex's weight list index. for i in xrange(numNeighbors): neighborVertexIndex = neighborVerts[i] neighborWeightIndex = vertIdToWeightListIndexMap[ neighborVertexIndex] # get these vertex's weights and add them to our weight sums for j in xrange(numInfluences): neighborWeightSums[j] += oldWeights[ (neighborWeightIndex * numInfluences) + j] smoothedWeights = [ w / float(numNeighbors) for w in neighborWeightSums ] strengthWeightedWeights = [] for weightIndex in xrange(len(smoothedWeights)): smoothedWeight = smoothedWeights[weightIndex] oldWeight = oldWeights[weightIndex] strengthWeightedWeights.append(oldWeight + ( self.strength * (smoothedWeight - oldWeight))) weightSum = float(sum(strengthWeightedWeights)) normalizedWeights = [ w / float(weightSum) for w in strengthWeightedWeights ] newWeights[(weightListId * numInfluences):(weightListId * numInfluences) + numInfluences] = normalizedWeights weightListId += 1 itVerts.next() newWeightsDoubleArray = om.MDoubleArray() for weightIndex in xrange(len(newWeights)): # make the final value weighted newWeightsDoubleArray.append(newWeights[weightIndex]) fnSkinCluster.setWeights(self.dagPath, self.selectedComponents, influenceIndices, newWeightsDoubleArray) self.undoQueue.append( (skinClusterMObject, originalWeights, self.dagPath, influenceIndices, self.selectedComponentsWithNeighbors))
def doIt(self, args): self.anim_cache = oma.MAnimCurveChange() animdata.anim_cache = self.anim_cache self.clearResult() self.setResult(keyhammer.do())
mfnAttribute = om.MFnAttribute(attriMObject) attriName = mfnAttribute.name.encode() # 3. Find the Attribute - Animation curve is connected currentPlug = mfnDependencyNode.findPlug(attriName, 1) if currentPlug.connectedTo(1, 0): connectedList = currentPlug.connectedTo(1, 0) # Find the connected node type conNodeMObject = connectedList[0].node() # Check its is a Animation curve if conNodeMObject.hasFn(om.MFn.kAnimCurve): # Read Anim Curve Attribute valus mfnAnimCurve = oma.MFnAnimCurve(conNodeMObject) attributeDataList = { 'animCurveType': 0, 'preInfinity': 0, 'postInfinity': 0, 'weightedTangents': 0, 'time': [], 'value': [], 'inTangentType': [], 'inTangentAngle': [], 'inTangentWeight': [], 'outTangentType': [], 'outTangentAngle': [], 'outTangentWeight': [] }
def importAnimCurve( selectionList, animPath, ): animData = open(animPath, 'r') data = json.load(animData) animData.close() if data and selectionList: for eachObject in selectionList: for eachAnimCurveAttribute in data['animCurve'][eachObject]: # get value animCurveType = data['animCurve'][eachObject][ eachAnimCurveAttribute]['animCurveType'] preInfinity = data['animCurve'][eachObject][ eachAnimCurveAttribute]['preInfinity'] postInfinity = data['animCurve'][eachObject][ eachAnimCurveAttribute]['postInfinity'] weightedTangents = data['animCurve'][eachObject][ eachAnimCurveAttribute]['weightedTangents'] numKeys = data['animCurve'][eachObject][ eachAnimCurveAttribute]['numKeys'] timeList = data['animCurve'][eachObject][ eachAnimCurveAttribute]['timeList'] valueList = data['animCurve'][eachObject][ eachAnimCurveAttribute]['valueList'] inTangentTypeList = data['animCurve'][eachObject][ eachAnimCurveAttribute]['inTangentTypeList'] inTangentAngleList = data['animCurve'][eachObject][ eachAnimCurveAttribute]['inTangentAngleList'] inTangentAngleWeightList = data['animCurve'][eachObject][ eachAnimCurveAttribute]['inTangentAngleWeightList'] outTangentTypeList = data['animCurve'][eachObject][ eachAnimCurveAttribute]['outTangentTypeList'] outTangentAngleList = data['animCurve'][eachObject][ eachAnimCurveAttribute]['outTangentAngleList'] outTangentAngleWeightList = data['animCurve'][eachObject][ eachAnimCurveAttribute]['outTangentAngleWeightList'] # convert current object and attribute to a new MPlug object mSelectionList = om.MSelectionList() mSelectionList.add('%s.%s' % (eachObject, eachAnimCurveAttribute)) attributeMPlug = mSelectionList.getPlug(0) connectedList = attributeMPlug.connectedTo(1, 0) # whether to create a new curve or use the existed curve newAnimCurve = 1 if connectedList: connectedNode = connectedList[0].node() if connectedNode.hasFn(om.MFn.kAnimCurve): MFnAnimCurve = oma.MFnAnimCurve(connectedNode) newAnimCurve = 0 if newAnimCurve: MFnAnimCurve = oma.MFnAnimCurve() MFnAnimCurve.create(attributeMPlug, animCurveType) # set value MFnAnimCurve.setPreInfinityType(preInfinity) MFnAnimCurve.setPostInfinityType(postInfinity) MFnAnimCurve.setIsWeighted(weightedTangents) MTimeArray = om.MTimeArray() MDoubleValueList = om.MDoubleArray() for index in range(len(timeList)): MTimeArray.append( om.MTime(timeList[index], om.MTime.uiUnit())) MDoubleValueList.append(valueList[index]) MFnAnimCurve.addKeys(MTimeArray, MDoubleValueList, 0, 0, 1) for index in range(len(timeList)): MFnAnimCurve.setInTangentType(index, inTangentTypeList[index]) MFnAnimCurve.setOutTangentType(index, outTangentTypeList[index]) inTangentAngle = om.MAngle(inTangentAngleList[index]) outTangentAngle = om.MAngle(outTangentAngleList[index]) MFnAnimCurve.setAngle(index, inTangentAngle, 1) MFnAnimCurve.setAngle(index, outTangentAngle, 0) MFnAnimCurve.setWeight(index, inTangentAngleWeightList[index], 1) MFnAnimCurve.setWeight(index, outTangentAngleWeightList[index], 0) # read history historyData = data['history'] historyList = [ 'Owner: %s' % historyData[0], 'Created: %s' % historyData[1], 'Maya version: %s' % historyData[2], 'Module version: %s' % historyData[3] ] return historyList
def getSkinInfluences(node): skin = OpenMayaAnim.MFnSkinCluster(node) return [inf.node() for inf in skin.influenceObjects()]
def createAnimCurve(self,dagNodeFn,dag,attribute): attr = dagNodeFn.attribute(attribute) attrCurve = oma.MFnAnimCurve() attrCurve.create(dag.transform(),attr, None ) return attrCurve
def get_mfn_skin(skin_ob): if isinstance(skin_ob, pm.PyNode): skin_ob = get_mobject(skin_ob.longName()) return oma2.MFnSkinCluster(skin_ob)
def create_ac(self, dag_fn, dag, attribute, curve_type): attr = dag_fn.attribute(attribute) anim_curve = oma.MFnAnimCurve() anim_curve.create(dag.transform(), attr, curve_type) return anim_curve
def do(): """ Creates a key on all attributes at any time-value, where a key exists in the curves list :return True on complete, False if cancelled :rtype bool """ # get selection if utils.is_graph_editor(): curves = utils.get_selected_anim_curves() else: nodes = utils.get_selected_objects() curves, plugs = utils.get_anim_curves_from_objects(nodes) # get curve functions curve_fns = [] for curve_node in curves: curve_fns.append(oma.MFnAnimCurve(curve_node.object())) if len(curve_fns) == 0: sys.stdout.write('# No anim curves to set keys on\n') return True # get time range time_range = utils.get_time_slider_range() is_range = time_range[0] - time_range[1] != 0 # get time for keyframes times = set() selected_keys = cmds.keyframe( q=True, selected=True, timeChange=True) if is_range is False else None if is_range: unit = om.MTime.uiUnit() min_time = om.MTime(time_range[0], unit) max_time = om.MTime(time_range[1], unit) for curve_fn in curve_fns: start_index = max(0, curve_fn.findClosest( min_time)) # -1 just to be safe, is checked later end_index = min( curve_fn.numKeys, curve_fn.findClosest(max_time)) # +1 just to be safe for i in range(start_index, end_index): times.add(curve_fn.input(i).value) elif selected_keys is not None: times = set(selected_keys) else: for curve_fn in curve_fns: for i in range(curve_fn.numKeys): times.add(curve_fn.input(i).value) # get main progress bar start progress gMainProgressBar = mel.eval('$tmp = $gMainProgressBar') cmds.progressBar(gMainProgressBar, e=True, beginProgress=True, isInterruptable=True, status='Adding keyframes...', maxValue=len(curve_fns)) # convert to MTime() m_times = [] unit = om.MTime.uiUnit() if is_range: for t in times: if time_range[0] <= t <= time_range[1]: m_times.append(om.MTime(t, unit)) else: for t in times: m_times.append(om.MTime(t, unit)) # add keys key_count = 0 cancelled = False for curve_fn in curve_fns: ts = [] vs = [] for mt in m_times: if curve_fn.find(mt) is None: ts.append(mt) vs.append(curve_fn.evaluate(mt)) for t, v in zip(ts, vs): curve_fn.addKey(t, v, change=animdata.anim_cache) key_count += 1 cmds.progressBar(gMainProgressBar, e=True, step=1) if cmds.progressBar(gMainProgressBar, q=True, isCancelled=True): cancelled = True break cmds.progressBar(gMainProgressBar, e=True, endProgress=True) if cancelled: sys.stdout.write('# Keyhammer cancelled...\n') return False else: sys.stdout.write('# Added %d key%s\n' % (key_count, '' if key_count == 1 else 's')) return True