スクリプト書いてみようかと
超久しぶりにブログ書きます。
というのも色々本当にありまして…
…
さておき
では今回は割とガッツリスクリプトを書いてみようかと思います。
はじめに仕様面を決めてみようかと思います。
お題:ポーズセーブスクリプト
制作理由:MAYAデフォルトでポーズだけ保存したり、外部に残しておける方法がないため。
実装方法:今回は選択した物と、その子ども以下の階層のSRTとアトリビュートの値を保存する。
シェイプや、追加アトリビュートについては現状は無しで、完成後追加で実装できればする。
できればカレントのシェリフにも追加したい。
ポーズ保存と実行なので、以下の注意点がある。
1.選択したオブジェクトはフルパスし、重複するオブジェクトはエラーで出力
2.実行する際は、階層の持ち方に注意する。
3.外部に保存するコマンドとそうではない、イテレーションが早いコマンドも必要。パスはドキュメントで
4.外部保存の形式はなんでもいいが、中身はPythonで実装。
5.できれば、複数フレームの一斉書き出しがほしい。
プロトタイプとして、まずは値の取得から行う。
# -*- coding: utf-8 -*- import maya.cmds as cmds oSel = cmds.ls(sl=True,l=True, type='transform') for i in oSel: #name print i #Rotate ro = cmds.xform(i,q=True,ro=True) #Trans tr = cmds.xform(i,q=True,t=True) #Vis vis = cmds.getAttr(i+".visibility") #Scale sc = cmds.xform(i,q=True,s=True) print sc
これで値自体は取れた。
ただ、ロックしている値まで取ってきているので、処理的に問題にもなりそう。
ということで、ロック情報を取得するか、除外する方法を考える。
SDK等みていると、「listAttr」というコマンドが使えそう。
このコマンドのフラグにて、
unlocked(u) boolean create
ロックが解除されているアトリビュートのみがリストされます。
このフラグがそのまま使えそうですね。
しかもありがたい事に、keyableや、channelBoxなどもありますね。
ではこれを用いて、再度値の取得を書いてみました。
# -*- coding: utf-8 -*- import maya.cmds as cmds oSel = cmds.ls(sl=True,l=True,type='transform') print oSel for i in oSel: #name print i list = cmds.listAttr(i, unlocked = True , visible = True , keyable = True, connectable = True, scalar = True, write = True, hd = True) print list
で結果。
[u'visibility', u'translateX', u'translateY', u'translateZ', u'rotateX', u'rotateY', u'rotateZ', u'scaleX', u'scaleY', u'scaleZ']
あれ…値が。。。
そうなんです。このままだと値が取れないので、ここからさらにGetAttrをかまして値を取ってみます。
# -*- coding: utf-8 -*- import maya.cmds as cmds oSel = cmds.ls(sl=True,l=True,type='transform') print oSel for i in oSel: #name print i list = cmds.listAttr(i, unlocked = True , visible = True , keyable = True, connectable = True, scalar = True, write = True, hd = True) print list for att in list: Tmpsel = cmds.ls(sl=True)[0] getValue = cmds.getAttr(Tmpsel + "." + att) print getValue
結果こんな感じ。
[-1.4327737,100.82367,-26.672975]
うん。取れました。
あとこれは余談ですが、個人的にアトリビュートのタイプは分けて処理したほうがいいので、以下の感じで
一回アトリビュートのタイプで篩をかけています。
※大きく意味はないのですが、一応。
# -*- coding: utf-8 -*- import maya.cmds as cmds oSel = cmds.ls(sl=True,l=True,type='transform') print oSel for i in oSel: #name print i list = cmds.listAttr(i, unlocked = True , visible = True , keyable = True, connectable = True, scalar = True, write = True, hd = True) print list for att in list: Tmpsel = cmds.ls(sl=True,type='transform')[0] gettype = cmds.getAttr(Tmpsel + "." + att,type=True) if gettype == "bool": BoolValue = cmds.getAttr(Tmpsel + "." + att) print BoolValue else: getValue = cmds.getAttr(Tmpsel + "." + att) print getValue
では、以上で値が取れたきた事を確認しました。
続いては、この情報を選択名とくっつけて、テキスト保存し拡張子を変更しましょう。
まずは、値を実行できるように、「SetAttr」としてまとめていきます。
現状取得できているのは、
「i」で選択物の名前
「att」でアトリビュート名
「getValue」でその値
が取得できています。
ここまで取得できてると、setattr用に簡易にまとめれますね。
こんな感じでまとめました。
# -*- coding: utf-8 -*- import maya.cmds as cmds oSel = cmds.ls(sl=True,l=True,type='transform') print oSel for i in oSel: #name print i list = cmds.listAttr(i, unlocked = True , visible = True , keyable = True, connectable = True, scalar = True, write = True, hd = True) print list for att in list: Tmpsel = cmds.ls(sl=True,type='transform')[0] gettype = cmds.getAttr(Tmpsel + "." + att,type=True) if gettype == "bool": getValue = cmds.getAttr(Tmpsel + "." + att) print getValue else: getValue = cmds.getAttr(Tmpsel + "." + att) print getValue AttrStr = str(i) + "." + str(att) Value = "(¥'" + str(AttrStr) + "¥'," + str(getValue) + " , clamp = True)" SetValue = "cmds.setAttr" + Value #exec(SetValue)
こんな感じで値をまとめれました。
実行したらこんな感じに↓
cmds.setAttr('|Monster_Rig|ALL|COG|Stomach|Chest|Neck|Head.rotateX',-11.0883595763 , clamp = True) cmds.setAttr('|Monster_Rig|ALL|COG|Stomach|Chest|Neck|Head.rotateY',0.0 , clamp = True) cmds.setAttr('|Monster_Rig|ALL|COG|Stomach|Chest|Neck|Head.rotateZ',0.0 , clamp = True)
あとはこれをテキストに保存します。
保存の仕方はGoogle先生なんかでよくでてくる感じでまとました。↓
またその際に、保存するディレクトリーを作成し、配置させてます。
※ディレクトリーがない場合は、作成する方向で
# -*- coding: utf-8 -*- import maya.cmds as cmds import codecs import os.path oSel = cmds.ls(sl=True,l=True,type='transform') for i in oSel: #name list = cmds.listAttr(i, unlocked = True , visible = True , keyable = True, connectable = True, scalar = True, write = True, hd = True) for att in list: Tmpsel = cmds.ls(sl=True,type='transform')[0] gettype = cmds.getAttr(Tmpsel + "." + att,type=True) if gettype == "bool": getValue = cmds.getAttr(Tmpsel + "." + att) else: getValue = cmds.getAttr(Tmpsel + "." + att) AttrStr = str(i) + "." + str(att) Value = "(¥'" + str(AttrStr) + "¥'," + str(getValue) + " , clamp = True)" SetValue = "cmds.setAttr" + Value #exec(SetValue) ScenePath = cmds.internalVar(uad = True) + 'SavePose' ImportText = "import maya.cmds as cmds" if not os.path.exists(ScenePath): os.makedirs(ScenePath) TextOpen = codecs.open(ScenePath+"\SavePose.py","w","utf-8") TextOpen.write(ImportText) TextOpen.write("\r\n") TextOpen.write(SetValue) TextOpen.write("\r\n") TextOpen.close() """ 使わないけど、拡張子変更する方法も記載。 file_path = ScenePath+"\SavePose.txt" basefile, ext = os.path.splitext(file_path) basefile, ext = os.path.splitext( os.path.basename(file_path) ) print ScenePath + "\\" + basefile + ".py" os.rename(file_path, ScenePath + "\\" + basefile + ".py") """
すげぇ汚いっすね。
今後スクラッチかけますわ‥
とりあえず、リグの頭を選んで実行すると、以下の画像みたくなります。
※拡張子がテキストになってますが、間違いです。。。
正式には、「.py」になってます。
はい。
これでテキスト出力までできました。
次はこれらを複数できるようにカスタムし、実行文とUIをやっていきます。
が、長くなったので一旦ここで切ります。
大体ここまでで2時間ぐらいでしょうか‥
それでは‥