#mox-motion presents #keyReductor (Maya_Pyhton) #キーフレームをリダクションする。頂点とその中間のみ残し削除。 #12/11/19 範囲選択に対応 #使い方:Fカーブを選択して実行 #================================================================= harftimeOption = True #頂点の中間にキーを打ちたいのならTrue、いらないのならFalse #================================================================ import maya.cmds as cmds #======================キーリダクションのメイン関数=============== def keyReductor(): #カーブをバッファ。 cmds.animCurveEditor("graphEditor1GraphEd",e=True,sb="on") cmds.bufferCurve (an="keys", ov=True) oSels = cmds.ls( sl=True )#選択したノードのリストを取得、つまりセレクションズ for oSel in oSels:#選択したノードを個別に処理、つまりoSelはセレクト oFcvs = cmds.keyframe(oSel,q=True, n=True, sl=True) #選択したオブジェクトの選択したFカーブを取得 if not oFcvs:#Fカーブリストに何も入らなかった場合 cmds.error(u"FCurveが選択されていません。") for oFcv in oFcvs:#取得したFカーブリストから、一本だけFカーブを取り出し個別に処理 #===============値のリストと時間のリストとキーの数を取得========== listKeyVal = cmds.keyframe(oFcv,q=True,vc=True)#vc= キーの値をリスト化。全部 listKeyTim = cmds.keyframe(oFcv,q=True,tc=True)#tc= キーの時間をリスト化。もちろん全部 iNumKey = cmds.keyframe(oFcv,q=True, kc=True)#kc= キーフレームの数 #===============キーの最初と最後のフレームを取得========== oStartFrame = listKeyTim[0] oEndFrame = listKeyTim[len(listKeyTim)-1] #===============選択した範囲の最初と最後のフレームを取得========== oSelMinKey = cmds.keyframe(q=True,tc=True,sl=True)[0] #選択範囲の最初のキー oSelMaxKey = cmds.keyframe(q=True,tc=True,lsl=True)[-1] #選択範囲の最後のキー #===============頂点のリストを制作========== cmd = [] #空のリストを用意 result = []#空のリストを用意 result.append(listKeyTim[0])#リストの最初は頂点ではなくFカーブの最初の時間を入れる。 for i in range(iNumKey-2):#キーフレームの数から2を引いた数だけ繰り返す。 if listKeyVal[i] > listKeyVal[i - 1] and listKeyVal[i] > listKeyVal[i + 1]:#山のてっぺん result.append(listKeyTim[i]) elif listKeyVal[i] < listKeyVal[i - 1] and listKeyVal[i] < listKeyVal[i + 1]:#谷のそこ result.append(listKeyTim[i]) result.append(listKeyTim[len(listKeyTim)-1])#リストの最後尾は頂点ではなく、最後のキーとなる #===============中間地点のリストを制作========== halftime = []#空のリストを用意 for i in range(len(result) - 1): #近接キーとの差分の中間をリストに追加していく halftime.append(result[i] + (round((result[i + 1] - result[i]) / 2))) #===============選択範囲外前半のリストを制作========== frontlist = [] for i in cmds.keyframe(oFcv,q=True,tc=True,t=(oStartFrame,oSelMinKey)): frontlist.append(i) #===============選択範囲外後半のリストを制作========== backlist = [] for i in cmds.keyframe(oFcv,q=True,tc=True,t=(oSelMaxKey,oEndFrame)): backlist.append(i) #=======頂点リストと中間リスト以外のキーのリストを作って削除======== setA = set(listKeyTim) setB = set(result) setC = set(halftime) setD = set(frontlist) setE = set(backlist) if harftimeOption: removeList = list(setA-setB-setC-setD-setE) else:removeList = list(setA-setB-setD-setE) for i in range(len(removeList)):#不要なキーリストの数だけ繰り返す cmd.append(eval("(" + str(removeList[i]) + ",)")) #リストに追加していく。結果的に下記のtime値フラグ専用のリスト[(4,),(12,),(16,)]みたいなのが出来る。 cmds.cutKey(oFcv, cl=True,t=cmd)#キーを削除 #========頂点タンジェントを水平にする========= for i in range(len(result)):#頂点リストの数だけ繰り返す。 cmd.append(eval("(" + str(result[i]) + ",)"))#下記time値フラグ用リストに頂点を追加していく。 cmds.keyTangent (oFcv,itt="flat", ott="flat", t=cmd)#頂点のタンジェントをフラットにする。 del halftime,result,listKeyVal,listKeyTim #使い終わった変数を削除 print("Complete! ----KeyReduction----") keyReductor()