新・続・スクリプト書いてみようかと
前回までで、書き出しと読み込みのコードが【とりあえず】できたので
それらをテストも含めて、関数化してみます。
まずは書き出し。
関数にする前に、一番はじめに書いた仕様を確認。
3.外部に保存するコマンドとそうではない、イテレーションが早いコマンドも必要。パスはドキュメントで
4.外部保存の形式はなんでもいいが、中身はPythonで実装。
5.できれば、複数フレームの一斉書き出しがほしい。
これらを見ていると、3のイテレーションが早いコマンドは現状で問題ないのですが
ファイルの名前、ディレクトリ指定が現状だと、できていないですね。
あと5の複数フレームにも対応してません。
また複数フレームについて、読み込み時どうするのかもまだ決まってませんね。
※現状だと複数読み込みは対応しないかなー。意味ないし。
では、ファイル名とディレクトリ変更を含めて関数化してみます。
まずは、現状のコード↓
# -*- coding: utf-8 -*- import maya.cmds as cmds import codecs import os.path oSel = cmds.ls(sl=True,l=True,type='transform') Select_Value = [] print oSel ImportText = "import maya.cmds as cmds" Select_Value.append(ImportText) 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: gettype = cmds.getAttr(i + "." + att,type=True) if gettype == "bool": getValue = cmds.getAttr(i + "." + att) else: getValue = cmds.getAttr(i + "." + att) AttrStr = str(i) + "." + str(att) Value = "(¥'" + str(AttrStr) + "¥'," + str(getValue) + " , clamp = True)" Select_Value.append("cmds.setAttr" + Value) ScenePath = cmds.internalVar(uad = True) + 'SavePose' if not os.path.exists(ScenePath): os.makedirs(ScenePath) TextOpen = codecs.open(ScenePath+"\SavePose.py","w","utf-8") for val in Select_Value: TextOpen.write(val) TextOpen.write("\r\n") TextOpen.close()
まずはファイル名の変更について変更してみます。
ファイル名はUIからのフラグによって共通か個別か決めるので
スクリプト内の
「TextOpen = codecs.open(ScenePath+"\SavePose.py","w","utf-8")」の
"SavePose.py"
を変数に変数指定に変更して、さらに条件分岐すればよさそうですね。
加えて、ディレクトリの同様に【ScenePath】を、条件分岐によって
変更できるように(上書き)すれば問題なさそうです。
あとは複数フレームですが、こればカレントフレームを動かすという
行動が必要な為、加筆が必須だと思います。
まずは指定のフレームに移動するコードですが
シンプルにこれでいけますね。
import maya.cmds as cmds cmds.currentTime(10)
10F目に移動してますね。
あとは、そのフレームをUIから、入力値を取得して、Forで回して
セーブポーズすればいいはずです。
※カレントの場合は常に1にしておけばOk。
では関数にしようかな?
って思ったんですが、まずはUIを用意した方が
良さそうなので、UIからやってみます。
で、まずUIで必要な情報はなにか?を列挙してみます。
1.Save実行ボタン
2.ロード実行ボタン
3.ファイル指定のラジオボタン
4.複数か単フレームかのラジオボタンないし、タブ区分け
5.保存パス※個人的にほしいので
6.あとHelpボタンないし、説明するタブ?
こんなもんかと。
では早速上記を含めてコード書いてみました。
# -*- coding: utf-8 -*- import maya.cmds as cmds def MenuMake(self): Pose_window = "SavePose" WindowWidth_Size = 300 WindowHight_Size = 180 if cmds.window(Pose_window,exists=True): cmds.deleteUI(Pose_window,window=True) MakeWindow = cmds.window(Pose_window,title=Pose_window,sizeable=False,mxb=False,w=WindowWidth_Size) #Helpの為にメインメニューバーを追加します cmds.menuBarLayout() cmds.menu(label=u"Menu",tearOff=False) cmds.menuItem(label=Pose_window+u"の解説") cmds.setParent("..") #複数フレーム対応の為、タブを生成 cmds.columnLayout(w=WindowWidth_Size+3) tab = cmds.tabLayout(w=WindowWidth_Size) #続けてボタンなど配置 tab1_B = cmds.columnLayout(w=WindowWidth_Size) cmds.rowLayout(numberOfColumns=2) Radio = cmds.radioCollection() RadioB1 = cmds.radioButton(label="システム") RadioB2 = cmds.radioButton(label="ユーザー") cmds.setParent( '..' ) cmds.separator(w = WindowWidth_Size) cmds.rowColumnLayout(numberOfColumns=4 , columnWidth=[(1,15), (2, 120), (3, 15),(4, 120)]) cmds.text(l = '') cmds.button(l = u'セーブ') cmds.text(l = '') cmds.button(l = u'ロード') cmds.setParent( tab ) tab2_B = cmds.columnLayout(w=WindowWidth_Size) cmds.rowColumnLayout(numberOfColumns=4 , columnWidth=[(1,5),(2,150),(3,8),(4,100)]) cmds.text(l = '') cmds.text(l = u'フレーム【カンマで区切って入力】') cmds.text(l = '') cmds.textField(text="0,100") cmds.setParent( '..' ) cmds.separator(w = WindowWidth_Size) cmds.rowColumnLayout(numberOfColumns=2 ,columnWidth=([1,65],[2,150])) cmds.text(l = '') cmds.button(l = u'セーブ') #各所設定 cmds.radioCollection(Radio,e=True,select=RadioB1) cmds.tabLayout( tab , edit=True, tabLabel=((tab1_B, u'フレーム'), (tab2_B,u"連番")) ) cmds.showWindow(MakeWindow) MenuMake(" ")
こんな感じに。
連番が
こうなりました。
細かい説明はいらないかな。。
すべてHELPに載ってることを実装しているだけなので・・・
ちなみにSaveする際に、ディレクトリを指定するには
以下のコードを、出力関数に足す必要がある。
# -*- coding: utf-8 -*- import maya.cmds as cmds basicFilter = "*.pose" Export_File = cmds.fileDialog2(okCaption=u"書き出し!",ds=2,fm=0,caption=u"ポーズを保存",fileFilter=basicFilter, dialogStyle=2) if Export_File != None: savePose_file = open(Export_File[0], 'w') savePose_file.write("test") savePose_file.close()
※現状デフォルトのパスは指定しておらず、書き出す中身も適当。
これはセーブだが、ロードの際は、Openを"r"としてreadすればOK。
とまぁ、UI書いてたら、結構長くなっちゃたので
ここで一旦切ります。
次回で組み込みやって、テストやって終わりたいと思います。
では…