読者です 読者をやめる 読者になる 読者になる

ON-BLOG

CGのこと、あれこれ書いてます。

FormLayoutについて

maya.cmds

FormLayout結構使ってるんですが、たまに意図しない配置になったりするので
昔書いた絵をサルベージしました。

って書いてますが正直Help見ればいいですが…
とりあえずその昔(MAYAを本格的に触り始めた10ヶ月前ぐらい)書いた絵を
f:id:tommy_on:20161007003253j:plain


要はアタッチ系がよくわかっていませんでした。
アタッチなので、枠にひっついている。という単純な事だったんですけどね‥

上記の上部ボタンに関しては、
ボタンSIZE = (windowSize[0] -20)/2,height
とすれば、キレイに当分してくれますね。
※windowSizeは(横、縦)のウィンドウサイズの配列で「20」は左右のオフセット5px+ボタンの間(隙間)10Pxの合計値

FormLayoutは私的にすごく重要なのです。
例えば、超簡単セレクタ

import maya.cmds as cmds
def Sel(*args):
    print "selection"
 
window = cmds.window()
form = cmds.formLayout()
JPG = cmds.image(image = 'c:/test.jpg')
b1 = cmds.button(l="R_Hund" , bgc = [1.0,0.5,0.3] , c=Sel)
b2 = cmds.button(l="L_Hund" , bgc = [0.0,0.5,1.0] ,c=Sel)
b3 = cmds.button(l="Head" , bgc = [0.0,1.0,0.2] ,c=Sel)
cmds.formLayout( form, edit=True, 
							attachForm=[(JPG, 'top', 1),(JPG, 'left', 1),(JPG, 'right', 1),(JPG, 'bottom', 1),(b1,'top',140),(b1,'right',10),(b2,'top',140),(b2,'left',5),(b3,'top',20)],
							attachPosition=[(b3,'left',0,45),(b2,'right',30,50),(b1,'left',30,50)] )
cmds.showWindow( window )

こんなやつが出てきます。
f:id:tommy_on:20161007011237p:plain

以前にも書いた気がしますが・・

ようはFormLayoutで配置をするわけなんですが
これをすべてFormでやるとなると、正直結構死ねます。

ってことで、次【時間あれば】、Qtデザイナー使って
セレクター作ってみたいと思います。

以上。

Pythonのメモ

maya.cmds

こんな事できるなんて…と思ったのをメモに

【リストを変数に個々に格納】

Sel1,Sel2,Sel3,Sel4 = ["polyShpere1","pTorus1","pCylinder1","pCube1"]
print Sel2

結果↓

pTorus1

こんな事できたとは…
あと、内包表記。
今まで少しだけ使ってたんですが、いろんなチュートリアル
スクリプトを見てると、上手いこと内包表記を使われてる方が多い。
なので、復習がてらにメモ。

以下のコードは、MAYAのパスにPSDファイルを保存するための
(実際は絶対こんな事はしてはいけないのですが。。。)
コードです。
単純に文字列をくっつけてるだけの例になります。

# -*- coding: utf-8 -*-
import maya.cmds as cmds

ScenePath = cmds.internalVar(uad = True)
File_List = ["File1.psd","File2.psd","File3.psd"]
CreatePath = []
for File in File_List:
	CreatePath.append(ScenePath + File)
print CreatePath


結果がこれ↓

[u'C:/Users/UserName/Documents/maya/File1.psd', u'C:/Users/UserName/Documents/maya/File2.psd', u'C:/Users/UserName/Documents/maya/File3.psd']

今まで結構使ってた手法です。
これでも問題ないのですが、あまりすっきりした書き方がではないです。
なのでここに内包表記をつかってみるとこうなります。

# -*- coding: utf-8 -*-
import maya.cmds as cmds

ScenePath = cmds.internalVar(uad = True)
File_List = ["File1.psd","File2.psd","File3.psd"]
CreatePath = []
CreatePath = [ScenePath + File for File in File_List]
print CreatePath

結果は同じで、結構スッキリしました。
これは今後優先して使っていこう。


【更新】
次にBoolのトグルについて
今までは、IF文を使っていたが以下の書き方にすることで
IF分がいらないようになる。

# -*- coding: utf-8 -*-
import maya.cmds as cmds

Sel = cmds.ls(sl=True,tr=True)
for i in Sel:
	Vis = cmds.getAttr(i+".visibility")
	cmds.setAttr(i+".visibility",(1-int(cmds.getAttr(i+".visibility"))))

要は「1-今の値」をしてるだけという、めちゃシンプルな内容。
昔からあるやり方みたいなんですが、最近知りました。
こうやって簡単に考えないと行けないっすよね‥

●USERパスを取得
単純に便利だなって思ったのでメモ

# -*- coding: utf-8 -*-
import os

FileExtension = 'Anim'

print os.path.join(os.path.expanduser('~'),'Sample.%s'%FileExtension)

結果こうなる。

##C:/Users/tommy_on/Documents\Sample.Anim

うん。
地味に便利。
今後はこっちを使おう。

ちなみに、

print os.path.expanduser('~')

でカレントユーザのホームディレクトリを取得してます。
もっと短く(拡張子の汎用性を無視するなら)

print os.path.expanduser('~/Sample.Anim')

でもいける。
ファイルの有無を簡単に調べるかも。

●Panelのドッキング方法
これ初めて知ったのでメモを‥
全く使ってコなかったなぁと。

パスにシンプルなウィンドウを記載してスクリプトを配置して実行

import maya.cmds as cmds
#パスにtestScript.pyを配置している。中身はクラス化した、簡単なウィンドウ
import testScript
Samplescript = testScript.ClassName()
Samplescript.main()
cmds.toggleWindowVisibility(Samplescript.window)
layout = cmds.paneLayout(configuration='single')
dock = cmds.dockControl(label=Samplescript.title,
						width=Samplescript.size[0],
						allowedArea='all',
						area='left',
						floating=False,
						content=layout)

cmds.control(Samplescript.window,e=True,p=layout)

うん。すごくいい。
ただ、あんま使わないかな‥
とりあえずメモ。

●joinでの'|'の追加
私普通にテキストの接続でやってましたがこっちの方が
キレイですね。
こんな感じ。

base = 'one|two|three'
add = 'five|six'
mix = '|'.join([base,'fore',add])

print mix

結果

one|two|three|fore|five|six

ウン。。
わかりやすいのがいい感じです。



こんな感じで、気になった事を
今後もこのページにメモしていきたいと思います。


以上。

キーワード引数のメモ

maya.cmds

キーワード引数にリストを入れるとタプルになって
無理やり文字列操作でリストにしてたんですが
実は引数の前にアスタリスクを入れるだけでよかったという事が
わかったのでメモ。
かなり初歩的な事っぽい。。

def testFunc(*args):
	print(args[0:])


nodelist = ["test1","test2","test3","test4"]

testFunc(nodelist)

これだと

(['test1', 'test2', 'test3', 'test4'],)

とタプルになる。
別に引数が一つならこれで全然問題ないのですが
引数が複数ある関数だと、リストじゃないと
いけないときがちらほらあったりします。

いままでは一回文字列に変換して、まさかの文字列操作で
操ってました。

が、これ実は

def testFunc(*args):
	print(args[0:])


nodelist = ["test1","test2","test3","test4"]

testFunc(*nodelist)

と引数のリスト前に「*」を入れるだけでよかったみたいです。。

('test1', 'test2', 'test3', 'test4')

はい。
こんな事でできるとは…

とい言うことでメモに残しておきます。

以上。

続・オーダー変えるやつ

maya.cmds

更新に時間がかかりました‥
実際は8割り程度結構前にできてたんですが
まぁ色々ありまして‥


と前置きはともかくいきなり完成コードを

# -*- coding: utf-8 -*-
import maya.cmds as cmds
from functools import partial
import re
import ast

def CreateLoc(oObj,ver):
	if ver == 0:
		Order = cmds.optionMenu( 'Order_List', q= True, sl= True) -1
		BakeAll = cmds.checkBox("FrameLock",q=True,value=True)
	else:
		Order = cmds.optionMenu( 'Check_Order_List', q= True, sl= True) -1
		BakeAll = cmds.checkBox("Check_FrameLock",q=True,value=True)
	timeIn = cmds.playbackOptions(q=True,min=True)
	timeout = cmds.playbackOptions(q=True,max=True)
	inframe = []
	outframe = []
	Flag = 0
	plotObj = []
	plotDummy = []
	obj_tmp = []
	delConst = []
	for i in oObj:	
		obj_tmp.append(i)
		#キー、オーダー、アトリビュート取得
		Original_Orders = cmds.listAttr( i,r=True, string="Original_Order*" )
		oObj_Order = cmds.getAttr(i+".rotateOrder")
		oKey_Rot = []
		if cmds.findKeyframe( i , c=True, at='rotateX' ) != None:
			oKey_Rot.append(cmds.findKeyframe( i , c=True, at='rotateX' ))
		if cmds.findKeyframe( i , c=True, at='rotateY' ) != None:
			oKey_Rot.append(cmds.findKeyframe( i , c=True, at='rotateY' ))
		if cmds.findKeyframe( i , c=True, at='rotateZ' ) != None:
			oKey_Rot.append(cmds.findKeyframe( i , c=True, at='rotateZ' ))
		if len(oKey_Rot) > 1:
			keys = cmds.keyframe(oKey_Rot[0],query=True)
			if len(keys) > 1:
			#ここからが実行文
				#アトリビュートの設定とオリジナルのキーを保存しておく
				if not cmds.objExists(i+".Original_Order"):
					cmds.addAttr(i,sn="Ori", ln="Original_Order", dt="string" )
					cmds.setAttr(i+".Original_Order",oObj_Order,type="string")
				if not cmds.objExists(i+".Original_Order_RotX"):
					cmds.addAttr(i,sn="RotX", ln="Original_Order_RotX", at= "double")
					cmds.setAttr(i+".Original_Order_RotX", e= True, k= True , cb=False)
					cmds.copyKey(i,at="rotateX",o="curve")
					cmds.pasteKey(i+'.Original_Order_RotX')
				if not cmds.objExists(i+".Original_Order_RotY"):
					cmds.addAttr(i,sn="RotY", ln="Original_Order_RotY", at= "double")
					cmds.setAttr(i+".Original_Order_RotY", e= True, k= True , cb=False)
					cmds.copyKey(i,at="rotateY",o="curve")
					cmds.pasteKey(i+'.Original_Order_RotY')
				if not cmds.objExists(i+".Original_Order_RotZ"):
					cmds.addAttr(i,sn="RotZ", ln="Original_Order_RotZ", at= "double")
					cmds.setAttr(i+".Original_Order_RotZ", e= True, k= True , cb=False)
					cmds.copyKey(i,at="rotateZ",o="curve")
					cmds.pasteKey(i+'.Original_Order_RotZ')

				#ロケータを作ってオーダーを変えてプロット
				oLoc = cmds.spaceLocator(n=i+"_TempObj")
				inframe.append(keys[0])
				outframe.append(keys[-1])
				PointCons = cmds.pointConstraint(i,oLoc,n="Dummy_point")
				OrientCons = cmds.orientConstraint(i,oLoc,n="Dummy_orient")
				cmds.setAttr(i+".rotateOrder",Order)
				Connections = cmds.listRelatives(oLoc,c=True,typ="constraint",fullPath=True)
				delConst.append(Connections)
				if BakeAll == True:
					plotObj.append(i+".rotateX")
					plotObj.append(i+".rotateY")
					plotObj.append(i+".rotateZ")
					dummy = oLoc[0]
					plotDummy.append(dummy+".rotateX")
					plotDummy.append(dummy+".rotateY")
					plotDummy.append(dummy+".rotateZ")
				else:
					cmds.bakeResults([oLoc[0]+".rotateX",oLoc[0]+".rotateY",oLoc[0]+".rotateZ"],sm=False,t=(keys[0],keys[-1]),pok=True)
					for d in Connections:
						cmds.select(d)
						cmds.delete()
					To_OrientCons = cmds.orientConstraint(oLoc,i,n="Dummy_orient")

					cmds.delete(i+"_rotateX")
					cmds.delete(i+"_rotateY")
					cmds.delete(i+"_rotateZ")
					cmds.bakeResults([i+".rotateX",i+".rotateY",i+".rotateZ"],sm=False,t=(keys[0],keys[-1]),pok=True)
					Connections = cmds.listRelatives(i,c=True,typ="constraint",fullPath=True)
					for c in Connections:
						cmds.select(c)
						cmds.delete()
					cmds.delete(oLoc)
					if len(plotDummy) > 0 :
						#配列済なので、sortedでソート実行
						S_in = sorted(inframe)
						S_out = sorted(outframe)
						Sort_in = set(S_in)
						Sort_out = set(S_out)
						Min_Frame = list(Sort_in)[0]
						Max_Frame = list(Sort_out)[-1]
						#Plot
						cmds.bakeResults(plotDummy,sm=False,t=(Min_Frame,Max_Frame),pok=True)
						for d in delConst:
							cmds.select(d)
							cmds.delete()
						if len(obj_tmp) != []:
							delConst = []
							for tmp in obj_tmp:
								OrientCons = cmds.orientConstraint(tmp+"_TempObj",tmp,n="Dummy_orient")
								Connections = cmds.listRelatives(tmp,c=True,typ="constraint",fullPath=True)
								delConst.append(Connections)
							cmds.bakeResults(plotObj,sm=False,t=(Min_Frame,Max_Frame),pok=True)
							for d in delConst:
								cmds.select(d)
								cmds.delete()
							for tmp in obj_tmp:
								cmds.delete(tmp+"_TempObj")
			else:
				cmds.warning(u'キーが2つ以上打たれていません。')
				DirectChange = cmds.confirmDialog( title='ChangeOrder',  m= u'キーが2つ以上打たれていません。そのままオーダーが変えますがよろしいでしょうか?', button=['Yes','No'], defaultButton='Yes', cancelButton='No', dismissString='No' )
				if DirectChange == "Yes":
					cmds.setAttr(i+".rotateOrder",Order)
				else:
					cmds.warning(u'終了しました。')
		else:
			cmds.warning(u'回転XYZの2つ以上キー設定がされてません')
			cmds.confirmDialog( title= 'ChangeOrder', m= u'回転XYZの2つ以上キー設定がされてません', icon= 'warning')
	if BakeAll == True:
		delConect = []
		Min_Frame = sorted(inframe)[0]
		Max_Frame = sorted(outframe)[-1]

		cmds.bakeResults(plotDummy,sm=False,t=(Min_Frame,Max_Frame),pok=True)
		for d in Connections:
			cmds.select(d)
			cmds.delete()
		for i in oObj:
			To_OrientCons = cmds.orientConstraint(i+"_TempObj",i,n="Dummy_orient")
			cmds.delete(i+"_rotateX")
			cmds.delete(i+"_rotateY")
			cmds.delete(i+"_rotateZ")
			delConect.append(cmds.listRelatives(i,c=True,typ="constraint",fullPath=True))
		cmds.bakeResults(plotObj,sm=False,t=(Min_Frame,Max_Frame),pok=True)
		for dc in delConect:
			cmds.select(dc)
			cmds.delete()
		delConect = []
		for tmp in oObj:
			OrientCons = cmds.orientConstraint(tmp+"_TempObj",tmp,n="Dummy_orient")
			Connections = cmds.listRelatives(tmp,c=True,typ="constraint",fullPath=True)
			delConect.append(Connections)
		cmds.bakeResults(plotObj,sm=False,t=(Min_Frame,Max_Frame),pok=True)
		for d in delConect:
			cmds.select(d)
			cmds.delete()
		for tmp in oObj:
			cmds.delete(tmp+"_TempObj")


def ChangeOrder_exe(ver):
	#選択を取得
	oObj = cmds.ls(sl=True,type="transform")
	#メニューからもらえるオーダーの値
	if not oObj == []:
		FirstObj = oObj[0].split("_")[-1]
		if FirstObj != "TempObj":
			CreateLoc(oObj,ver)
		else:
			oObj_Sel = cmds.getAttr(oObj[0]+".Original_Selection")
			date = ast.literal_eval(oObj_Sel)
			cmds.select(clear=True)
			for sel in range(0,len(date)):
				cmds.select(date[sel],add=True)
			cmds.delete(oObj)
			oObj = cmds.ls(sl=True)
			CreateLoc(oObj,ver)
		cmds.select(oObj)
		cmds.headsUpMessage( u'完了しました。', verticalOffset=20 )
	else:
		cmds.warning(u'選択して実行してください。')
		cmds.confirmDialog( title= 'ChangeOrder', m= u'選択して実行してください。', icon= 'warning')


def Bake_BeforeOrder(self):
	oObj = cmds.ls(sl=True,type="transform")
	for i in oObj:
		oObj_Order = cmds.getAttr(i+".Original_Order")
		cmds.setAttr(i+".rotateOrder",int(oObj_Order))
		cmds.delete(i+"_rotateX")
		cmds.delete(i+"_rotateY")
		cmds.delete(i+"_rotateZ")
		cmds.copyKey(i,at="Original_Order_RotX",o="curve")
		cmds.pasteKey(i+'.rotateX')
		cmds.copyKey(i,at="Original_Order_RotY",o="curve")
		cmds.pasteKey(i+'.rotateY')
		cmds.copyKey(i,at="Original_Order_RotZ",o="curve")
		cmds.pasteKey(i+'.rotateZ')
		cmds.deleteAttr(i+".Original_Order")
		cmds.deleteAttr(i+".Original_Order_RotX")
		cmds.deleteAttr(i+".Original_Order_RotY")
		cmds.deleteAttr(i+".Original_Order_RotZ")
	cmds.select(oObj)
	cmds.headsUpMessage( u'完了しました。', verticalOffset=20 )

def ChangeSelect(self):
	sel = []
	oObj = cmds.ls()
	for i in oObj:
		Artr_Check = cmds.attributeQuery('Original_Order', node=i, exists=1)
		if Artr_Check == True :
			sel.append(i)
	if sel == []:
		cmds.confirmDialog( title= 'ChangeOrder', m= u'存在しませんでした。', icon= 'warning')
	else:
		cmds.select(sel)
		print u"選択しました。"


def ParamChange(self):
	try:
		oObj = cmds.ls(sl=True,type="transform")
		FirstObj = oObj[0].split("_")[-1]
	except:
		cmds.warning(u'選択して実行してください。')
		cmds.confirmDialog( title= 'ChangeOrder', m= u'選択して実行してください。', icon= 'warning')
		return
	if FirstObj != "TempObj":
		oLoc = cmds.spaceLocator(n=oObj[0]+"_TempObj")[0]
		cmds.addAttr(oLoc,sn="OriSel", ln="Original_Selection", dt="string" )
		cmds.setAttr(oLoc+".Original_Selection",oObj,type="string")
		PointCons = cmds.pointConstraint(oObj[0],oLoc,n="Dummy_point")
		OrientCons = cmds.orientConstraint(oObj[0],oLoc,n="Dummy_orient")
	else:
		oLoc = cmds.ls(sl=True)[0]
	cmds.setToolTo( 'RotateSuperContext' )
	Rotate_Mode = cmds.manipRotateContext( 'Rotate', q= True, mode= True)
	cmds.manipRotateContext( 'Rotate', e= True, mode= 2)
	oOrder = cmds.optionMenu( 'Check_Order_List', q= True, sl= True)
	if oOrder == 1:
		cmds.setAttr(oLoc+".rotateOrder",0)
	elif oOrder == 2:
		cmds.setAttr(oLoc+".rotateOrder",1)
	elif oOrder == 3:
		cmds.setAttr(oLoc+".rotateOrder",2)
	elif oOrder == 4:
		cmds.setAttr(oLoc+".rotateOrder",3)
	elif oOrder == 5:
		cmds.setAttr(oLoc+".rotateOrder",4)
	elif oOrder == 6:
		cmds.setAttr(oLoc+".rotateOrder",5)

#HelpWindow
def HelpWindow_Page(self):
	Helpwindow = "ChangeOrder_Help"
	Help_WindowWidth_Size = 350
	Help_WindowHight_Size = 270
	if cmds.window(Helpwindow,exists=True):
		cmds.deleteUI(Helpwindow,window=True)
	Help_MakeWindow = cmds.window(Helpwindow,title=Helpwindow,sizeable=False,mxb=False,wh=[Help_WindowWidth_Size,Help_WindowHight_Size])
	cmds.columnLayout()
	cmds.separator(w = Help_WindowWidth_Size,h=20)
	cmds.text(label=u"                          ChangeOrderのHelpページ!!")
	cmds.separator(w = Help_WindowWidth_Size,h=30)
	cmds.text(label=u"●選択したオブジェクトのローテーションオーダーを")
	cmds.text(label=u" アニメーションを崩さず変更するスクリプトです。")
	cmds.separator(w = Help_WindowWidth_Size,h=10)
	cmds.text(label=u"●【オーダー確認】ボタンで一時的にオーダー変更後の")
	cmds.text(label=u"状態を確認することができます。")
	cmds.separator(w = Help_WindowWidth_Size,h=10)
	cmds.text(label=u"●【フレームを保持しない】は、選択した物の総尺を取得し")
	cmds.text(label=u" そのイン、アウトに合わせてベイクします。")
	cmds.separator(w = Help_WindowWidth_Size,h=10)
	cmds.text(label=u"●元に戻す際は、【プロット】タブを")
	cmds.text(label=u" 選択していただき、【オーダーを元に戻す】")
	cmds.text(label=u" ボタンをクリックしてください。")
	cmds.showWindow(Help_MakeWindow)
	cmds.separator(w = Help_WindowWidth_Size,h=30)

def CheckOrder(self):
	BakeAll = cmds.checkBox("FrameLock",q=True,value=True)
	oObj=[]
	try:
		oObj = cmds.ls(sl=True,type="transform")[0]
	except:
		cmds.warning(u'選択して実行してください。')
		cmds.confirmDialog( title= 'ChangeOrder', m= u'選択して実行してください。', icon= 'warning')
		return
	Check_windowname = "ChangeOrder"
	Check_WindowWidth_Size = 230
	Check_WindowHight_Size = 300
	if cmds.window(Check_windowname,exists=True):
		cmds.deleteUI(Check_windowname,window=True)
	Check_window = cmds.window(Check_windowname,title=Check_windowname,sizeable=True,mxb=False,wh=[Check_WindowWidth_Size,Check_WindowHight_Size])

	cmds.frameLayout("CheckOrder",label="CheckOrder",bgc=[0.2,0.7,0.1])
	cmds.columnLayout(w=Check_WindowWidth_Size+3,bgc=[0.2,0.2,0.2])
	cmds.separator( height= 1)
	cmds.text(label=u"オーダーを確認できます。")
	cmds.text(label=u"プルダウンを変更して確認ください。")
	cmds.text(label=u"実行ボタンで、変更処理が走ります。")
	cmds.separator( height= 1)
	cmds.rowLayout("Check",numberOfColumns=3,columnWidth2=[100,40])

	cmds.optionMenu( 'Check_Order_List',changeCommand=ParamChange, w= 100,h=50)
	cmds.menuItem( l= '0.  xyz')
	cmds.menuItem( l= '1.     yzx')
	cmds.menuItem( l= '2.        zxy')
	cmds.menuItem( l= '3.  xzy')
	cmds.menuItem( l= '4.     yxz')
	cmds.menuItem( l= '5.        zyx')
	if len(oObj) > 1:
		oObj_Order = cmds.getAttr(oObj+".rotateOrder")
	else:
		oObj_Order = 0
	cmds.optionMenu( 'Check_Order_List', e= True, bgc= [0.1,0.5,0.7], ebg= False,sl=oObj_Order+1)
	cmds.button( 'exe', l= u'実行!', h= 40, w= 110,bgc=[1.0,0.0,0.0],c='ChangeOrder_exe(%d)' % (1))
	cmds.setParent("..")
	cmds.text(label=" ")
	cmds.checkBox("Check_FrameLock", label=u'フレームを保持しない' )
	cmds.text(label="")
	cmds.separator(w = Check_WindowWidth_Size , st = 'in')
	cmds.text(label=" ")
	cmds.button( 'back', l= u'戻る', h= 60, w= Check_WindowWidth_Size,bgc=[0.45,0.45,0.45],c=MainWindow)
	cmds.setParent("..")
	if BakeAll == True:
		cmds.checkBox("Check_FrameLock",e=True,value=True)
	cmds.showWindow(Check_window)


def MainWindow(V):
	print V
	try:
		Chcek_BakeAll = cmds.checkBox("Check_FrameLock",q=True,value=True)
	except:
		Chcek_BakeAll = []
	windowname = "ChangeOrder"
	WindowWidth_Size = 230
	WindowHight_Size = 300
	oObj = []

	if cmds.window(windowname,exists=True):
		cmds.deleteUI(windowname,window=True)
	Window = cmds.window(windowname,title=windowname,sizeable=True,mxb=False,wh=[WindowWidth_Size,WindowHight_Size])

	#Helpの為にメインメニューバーを追加します
	cmds.menuBarLayout()
	cmds.menu(label=u"Menu",tearOff=False)
	cmds.menuItem(label=Window+u"の解説",c=HelpWindow_Page)
	cmds.separator(w = WindowWidth_Size)
	cmds.setParent("..")

	cmds.columnLayout(w=WindowWidth_Size+3)
	tab = cmds.tabLayout(w=WindowWidth_Size)

	tab1_B = cmds.frameLayout("ChangeOrder",label="ChangeOrder",bgc=[1.0,0.3,0.2])
	cmds.columnLayout( columnAttach= ('left',2))
	cmds.rowLayout( 'Orders', numberOfColumns= 4, columnWidth2= [100,40])
	cmds.optionMenu( 'Order_List', w= 100,h=50)
	cmds.menuItem( l= '0.  xyz')
	cmds.menuItem( l= '1.     yzx')
	cmds.menuItem( l= '2.        zxy')
	cmds.menuItem( l= '3.  xzy')
	cmds.menuItem( l= '4.     yxz')
	cmds.menuItem( l= '5.        zyx')
	try:
		oObj = cmds.ls(sl=True,type="transform")[0]
		cmds.setToolTo("RotateSuperContext")
		cmds.manipRotateContext("Rotate",e=True,mode=2)
	except:
		pass
	if len(oObj) > 1:
		oObj_Order = cmds.getAttr(oObj+".rotateOrder")
	else:
		oObj_Order = 0

	cmds.optionMenu( 'Order_List', e= True, bgc= [0.5,0.2,0.2], ebg= False,sl=oObj_Order+1)
	cmds.button( 'exe', l= u'実行!', h= 40, w= 110,c='ChangeOrder_exe(%d)' % (0))
	cmds.separator( height= 1)
	cmds.setParent(tab1_B)
	Lock = cmds.checkBox("FrameLock", label=u'フレームを保持しない' )

	tab_2 = cmds.frameLayout("OrderCheck",label="OrderCheck",bgc=[0.2,0.4,0.6])
	cmds.columnLayout()
	cmds.text("")
	cmds.text(label=u"オーダー変更後の確認が行えます。")

	cmds.button( 'exe_test', l= u'オーダー確認', h= 35, w= 220,c=CheckOrder)
	cmds.separator( h= 15)

	cmds.setParent( tab )

	tab2_B = cmds.frameLayout("Plot",label=u"Plot処理",bgc=[0.9,0.1,0.1])
	cmds.columnLayout()
	cmds.separator( h= 15)
	cmds.button( 'remove', l= u'オーダーを元にもどす', h= 60, w= 220,c=Bake_BeforeOrder)
	cmds.separator( h= 15)
	cmds.button( 'order_sel', l= u'オーダー変えたやつを選択', h= 60, w= 220,c=ChangeSelect)

	cmds.tabLayout( tab , edit=True, tabLabel=((tab1_B, u'オーダー変更'), (tab2_B,u"プロット")) )
	if Chcek_BakeAll != []:
		if Chcek_BakeAll == True:
			cmds.checkBox("FrameLock",e=True,value=True)
	cmds.showWindow(Window)

def main():
	ver = 1.0
	MainWindow(V=ver)

main()

これで一応できました。
とかく色々エラー処理がめんどくさかったです。
中身はすごい単純なのに‥
※re,partialは使ってないのですが、拡張を考えていて使う予定があるので‥
 【import ast】すげぇ便利でしたよ。


でUIは前回からあまり変わってないです。
テストように一回ウィンドウ作ったぐらいですね。
模索中だったところが、変更したオブジェクトを
選択するものにしました。
こんな感じ。
メインページ
f:id:tommy_on:20160923144702j:plain

プロットページ
f:id:tommy_on:20160923144913j:plain

テストページ
f:id:tommy_on:20160923144924j:plain

HELPページ
f:id:tommy_on:20160923150024j:plain

使い方はHELPにも書いてますが
選択して実行するだけです。
もちろん複数も可能です。


今回は色々とエラー処理やUIについて
学ぶことが多かったです。

ということで、次回はPysideか
法線にものを配置するツールを
作ってみたいと思います。

Pysideはともかく、法線はできるかな‥


以上です。

オーダー変えるやつ

maya.cmds

続けて次はアニメーションの結果を変えずに
オーダーを切り替えるスクリプトを書いていきたいと思います。
SI時代にも作成していて、さらに昨年MAYA版も作ったんですが
色々あり、闇に消えてしまったので一から作り直してみたいと思います。
※今回は色々時間がないので、さらにスローに作ります‥

では、このスクリプトの仕様を見ていきましょう。

お題:オーダー変更スクリプト
制作理由:オーダーを変えるのが、地味に面倒。
     外部に出して、変更しないとアニメーションの結果が変わる。
     一度プロットしないといけない。
     複数実行ができない。

実装方法:
●選択したものを取得して、ロケータを取得→コンストかけて
 オーダーを変えれるように
 またイテレーションをできるだけ、少なくしたいので
 オーダーを確認できるようにテストモードを実装。
 ボタンで一時的に確認できるようにする。

●テストモードは、実行と同じで、選択物に対して
ロケータを生成して、コンストをかける。
 そのロケーターでプルダウンを選ぶ度に、オーダーが変えれるようにして
 目視で実行後のイメージが見えるようにします。
     
●後は、この時のエラー処理をどうしようかと‥
 選択を固定する事はできないので、スクリプトジョブかなんかで
 監視する事が必要かも‥まだモヤモヤしてる箇所。
 あとアニメーションしていない、物は弾く。

●さらにキーが一個ならプロットせずに
 オーダーのそのまま変えるように設定。
 オーダー変えた際に、デフォルトのオーダーも
記憶しておかないと、いけないのでアトリビュートを追加

     
●オーダー変更自体は、一時的に作ったロケータをプロットして
 選択コントローラーを逆コンストする形で実装。
 ただ、複数あるとプロット祭りになるので
 一度配列にコントローラーを追加して、プロット自体は一気に行う。
 またコンスト自体も同様に一括で行う。

以上な感じで。

今回はぱっとUIを先作ってみました。
こんな感じ。
f:id:tommy_on:20160912165233p:plain

タブ切り替えると
f:id:tommy_on:20160912165245p:plain

現状のイメージでここにコマンド入れ込んでいきたいですね。
あと、マニュピレーターをボタンかなんかで変えれるようにした方がいいのか‥
また考えます。
一応コード
※すみません。汚いです。。。

# -*- coding: utf-8 -*-
import maya.cmds as cmds
windowname = "OrderCheck"
WindowWidth_Size = 230
WindowHight_Size = 300


if cmds.window(windowname,exists=True):
	cmds.deleteUI(windowname,window=True)
Window = cmds.window(windowname,title=windowname,sizeable=False,mxb=False,w=WindowWidth_Size)

#Helpの為にメインメニューバーを追加します
cmds.menuBarLayout()
cmds.menu(label=u"Menu",tearOff=False)
cmds.menuItem(label=Window+u"の解説")
cmds.separator(w = WindowWidth_Size)
cmds.setParent("..")

cmds.columnLayout(w=WindowWidth_Size+3)
tab = cmds.tabLayout(w=WindowWidth_Size)


tab1_B = cmds.frameLayout("ChangeOrder",label="ChangeOrder",bgc=[1.0,0.3,0.2])
cmds.columnLayout( columnAttach= ('left',2))
cmds.rowLayout( 'Orders', numberOfColumns= 4, columnWidth2= [100,40])
cmds.optionMenu( 'Order_List', l= '', w= 100,h=50)
cmds.menuItem( l= '0.  xyz')
cmds.menuItem( l= '1.     yzx')
cmds.menuItem( l= '2.        zxy')
cmds.menuItem( l= '3.  xzy')
cmds.menuItem( l= '4.     yxz')
cmds.menuItem( l= '5.        zyx')
cmds.optionMenu( 'Order_List', e= True, bgc= [0.5,0.2,0.2], ebg= False)

cmds.button( 'exe', l= u'実行!', h= 40, w= 110)
cmds.separator( height= 1)
cmds.setParent(tab1_B)


tab_2 = cmds.frameLayout("OrderCheck",label="OrderCheck",bgc=[0.2,0.4,0.6])
cmds.columnLayout()
cmds.text("")
cmds.text(label=u"オーダー変更後の確認が行えます。")
cmds.button( 'exe_test', l= u'オーダー確認', h= 35, w= 220)

cmds.separator( h= 15)

cmds.setParent( tab )

tab2_B = cmds.frameLayout("Plot",label=u"Plot処理",bgc=[0.9,0.1,0.1])
cmds.columnLayout()
cmds.separator( h= 15)
cmds.button( 'remove', l= u'オーダーを元にもどす', h= 40, w= 220)
cmds.separator( h= 15)
cmds.button( 'test', l= u'模索中‥', h= 40, w= 220)

cmds.tabLayout( tab , edit=True, tabLabel=((tab1_B, u'オーダー変更'), (tab2_B,u"プロット")) )
cmds.showWindow(Window)



今回は短いですが、以上です。

完・続・スクリプト書いてみようかと

maya.cmds

前回までで、UIとコマンドができたので、組み込みと
テストをして、完成させたいと思います。

では早速、まずは関数化していきます。

ある程度前回の記事で仕様と、どうすればいいのか決まってるので
それらを踏まえ、加筆しました。

と書きましたが、まぁエラー出まくりで
めちゃ時間かかりました。。。
2日間、時間でいうと8時間くらい‥
情けない‥

とりあえずテストも終えたコードを↓

# -*- coding: utf-8 -*-
import maya.cmds as cmds
import codecs
import os.path
from functools import partial


class savepose:
	radioB = ""
	TextValue = ""
	radio = ""
	flag = ""

	#saveFunction
	def savepose_cmd(self,*args):
		currentF = cmds.currentTime( query=True )
		text_get = self.TextValue
		flag = args[0]
		oSel = cmds.ls(sl=True,l=True,type='transform')
		radioCollections = cmds.radioCollection(self.radioB,q=True,select=True)
		radioQuery = cmds.radioButton(self.radio, q = True, sl = True)
		ScenePath = cmds.internalVar(uad = True) + 'SavePose'
		if oSel != []:
			if not os.path.exists(str(ScenePath)):
				os.makedirs(str(ScenePath))
			if flag == 0:
				text_split = "0"
			else:
				InputTime = cmds.textField(text_get, q=True, tx=True )
				Brank_Check = InputTime.strip()
				text_split = Brank_Check.split(",")
			for F in range(len(text_split)):
				if flag == 1:
					try:
						cmds.currentTime( text_split[F] )
					except:
						cmds.confirmDialog( title= 'SavePose', m= u'半角数字を入力してください。', icon= 'warning')
						cmds.warning(u'半角数字を入力してください。')
						return
				Select_Value = []
				ImportText = "import maya.cmds as cmds"
				Select_Value.append(ImportText)
				for i in oSel:
					list = cmds.listAttr(i, unlocked = True , visible = True , keyable = True, connectable = True, scalar = True, write = True, hd = True)
					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)
				if flag == 0:
					if radioQuery == True:
						TextOpen = codecs.open(ScenePath+"\SavePose.py","w","utf-8")
					else:
						basicFilter = "*.py"
						Export_File = cmds.fileDialog2(dir=ScenePath,okCaption=u"書き出し!",ds=2,fm=0,caption=u"ポーズを保存",fileFilter=basicFilter, dialogStyle=2)
						if Export_File != None:
							TextOpen = open(Export_File[0], 'w')
					for val in Select_Value:
						TextOpen.write(val)
						TextOpen.write("\r\n")
					TextOpen.close()
				else:
					TextOpen = codecs.open(ScenePath+"\\"+ text_split[F] +".py","w","utf-8")
					for val in Select_Value:
						TextOpen.write(val)
						TextOpen.write("\r\n")
					TextOpen.close()
					
			if flag == 1:
				cmds.currentTime(currentF)
		else:
			cmds.warning(u'選択して実行してください。')
			cmds.confirmDialog( title= 'SavePose', m= u'選択して実行してください。', icon= 'warning')
			return

	#LoadFunction
	def LoadPose_cmd(self,*args):
		loadPath = cmds.internalVar(uad = True) + 'SavePose'
		radioCollections = cmds.radioCollection(self.radioB,q=True,select=True)
		radioQuery = cmds.radioButton(self.radio, q = True, sl = True)
		if radioQuery == True:
			ScenePath = cmds.internalVar(uad = True) + 'SavePose\SavePose.py'
		else:
			basicFilter = "*.py"
			Import_File = cmds.fileDialog2(dir=loadPath,okCaption=u"読み込み!",ds=2,fm=1,caption=u"ポーズを読み込み",fileFilter=basicFilter, dialogStyle=2)
			if Import_File != None:
				ScenePath = Import_File[0]

		script_code = []
		script_err = []
		for line in open(ScenePath, 'r').xreadlines():
			lines = line.rstrip()
			script_code.append(lines)
		for i in script_code:
			try:
				exec(i)
			except:
				print i+"は存在していない為、実行できませんでした。"
				script_err.append(i)

	#HelpWindow
	def HelpWindow_Page(self,*args):
		Helpwindow = "SavePose_Help"
		Help_WindowWidth_Size = 350
		Help_WindowHight_Size = 200
		if cmds.window(Helpwindow,exists=True):
			cmds.deleteUI(Helpwindow,window=True)
		Help_MakeWindow = cmds.window(Helpwindow,title=Helpwindow,sizeable=False,mxb=False,wh=[Help_WindowWidth_Size,Help_WindowHight_Size])
		cmds.columnLayout()
		cmds.separator(w = Help_WindowWidth_Size,h=20)
		cmds.text(label=u"                          SavePoseのHelpページ!!")
		cmds.separator(w = Help_WindowWidth_Size,h=30)
		cmds.text(label=u"●選択したノード保存するスクリプトです。")
		cmds.text(label=u" 複数可能で、ペーストは必ず、対になっているものに限ります。")
		cmds.separator(w = Help_WindowWidth_Size,h=10)
		cmds.text(label=u"●保存先はボタンを【ユーザー】に変える事で、変更可能です。")
		cmds.separator(w = Help_WindowWidth_Size,h=10)
		cmds.text(label=u"●タブを【連番に】変更すると、複数フレームを書き出せます。")
		cmds.text(label=u" 入力はカンマ「,」で区切っていただくと事で、出力がなされます。")
		cmds.text(label=u" 数字以外は入力しないで下さい。")
		cmds.showWindow(Help_MakeWindow)

	#folderOpen
	def folderOpen(self,*args):
		SystemPath = cmds.internalVar(uad = True) + 'SavePose/'
		if not os.path.exists(SystemPath):
			os.makedirs(SystemPath)
		SystemPath2 = SystemPath.replace("/", "\\\\")
		os.popen("explorer " + str(SystemPath2))
		#cmdがでるから、お休み
		#os.system('explorer ' + "\"" + SystemPath2 + "\"")
		
	def MenuMake(self,*args):
		Pose_window = "SavePose"
		WindowWidth_Size = 300
		WindowHight_Size = 140

		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,wh=[WindowWidth_Size,WindowHight_Size])

		#Helpの為にメインメニューバーを追加します
		cmds.menuBarLayout()
		cmds.menu(label=u"Menu",tearOff=False)
		cmds.menuItem(label=Pose_window+u"の解説",c=self.HelpWindow_Page)
		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)
		self.radioB = cmds.radioCollection()
		self.radio = 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'セーブ',c=partial(self.savepose_cmd, 0))
		cmds.text(l = '')
		cmds.button(l = u'ロード',c=self.LoadPose_cmd)
		cmds.setParent( '..' )

		cmds.separator(w = WindowWidth_Size)
		cmds.rowColumnLayout(numberOfColumns=2 , columnWidth=[(1,150), (2, 120)])
		cmds.text(l = '')
		cmds.button(l = u'システムフォルダを開く',c=self.folderOpen)

		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 = '')

		self.TextValue = cmds.textField()
		cmds.textField( self.TextValue, edit=True,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'セーブ',c=partial(self.savepose_cmd, 1))
		cmds.setParent( '..' )

		cmds.separator(w = WindowWidth_Size)
		cmds.rowColumnLayout(numberOfColumns=2 , columnWidth=[(1,65), (2, 150)])
		cmds.text(l = '')
		cmds.button(l = u'システムフォルダを開く',c=self.folderOpen)
		#各所設定
		cmds.radioCollection(self.radioB,e=True,select=self.radio)
		cmds.tabLayout( tab , edit=True, tabLabel=((tab1_B, u'フレーム'), (tab2_B,u"連番")) )


		cmds.showWindow(MakeWindow)

def main():
	classCommad = savepose()
	classCommad.MenuMake()



main()

メイン画面
f:id:tommy_on:20160910143905j:plain

連番画面
f:id:tommy_on:20160910143914j:plain

Helpウィンドウ
f:id:tommy_on:20160910143937j:plain
※入力の値について、エラー処理対応したので
この画像は間違いですね‥


出力されたファイル達
f:id:tommy_on:20160910144013j:plain

といった感じになりました。


とにかくメニューの値と関数の参照が欲しくて
クラス化にしたんですが
まぁ、エラーに悩まされました。
※何個かはMAYA自体のエラーとかもあったんですが。(再起動で治るパターン)

あと、今回パソコンの関係で外部エディタが使えなかったので
MAYAのスクリプトエディタで作業したんですが
マジで地獄でした。

個人的にハマったのが、ラジオボタンのセレクトの値をどうすればいいのかという事。
今回は2個だったんで(わからなかったので2個にしました。)一つの条件で仕分けができたんですが‥
今後の課題です。。

また、UI内に「システムフォルダ」を開くってボタンありますが
これちゃんと動いてません。
【cmds.internalVar(uad = True) + 'SavePose/'】
ディレクトリとってきてるんですが、そのまま使っても
ダメで、更に文字列操作して
エスケープ文字も対応したんですが、それでもダメでした。
なぜなんでしょうか‥
ちなみに、文字列操作した
値と同じ文字列を別途用意すると
そちらはちゃんとパスが通りました。
なんでやねん‥と。
とりあえずあまり支障がないので、ほっときますが、今後また調べてみます。

私の勘違いです。
文字列操作の
【SystemPath2 = SystemPath.replace("/", "\\\\")】
の部分に誤りがありました。。
正しくは
【replace('/', '\\')) 】
です。

SIの感覚でやってしまいしました…
この部分を変えてもらうと動きますね…
@horonigさん
@eco_haganeさん
ご助言感謝致します!
ありがとうございました。


あと、UIのデザインも。
できれば、タブで切り分ける事なく、UIのアニメーションとかで
表現できたらいいなぁーと思ってたんですが、Pysideを触らないとできないっぽいので
今回は流しました。


と愚痴を書いてますが、とりあえず完成しました。
本当はカスタムアトリビュートのコピーや、スキンの除外、シェリフへの書き出しなんかやりたかったんですが
それはまた機会みて実装します。

使い方なんかは前の記事を見ていただければと思います。
※簡単ですが。


では、次はオーダー変えるスクリプトを作り直したいと思います。
※昔作ったやつは闇に消えたので‥

以上です。

新・続・スクリプト書いてみようかと

maya.cmds

前回までで、書き出しと読み込みのコードが【とりあえず】できたので
それらをテストも含めて、関数化してみます。

まずは書き出し。
関数にする前に、一番はじめに書いた仕様を確認。
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(" ")

こんな感じに。
f:id:tommy_on:20160909005201p:plain
連番が
f:id:tommy_on:20160909005217p:plain
こうなりました。

細かい説明はいらないかな。。
すべて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書いてたら、結構長くなっちゃたので
ここで一旦切ります。

次回で組み込みやって、テストやって終わりたいと思います。

では…