pythonの引数をmaya.cmds風にしてみる。
これは Maya Advent Calendar 2018 12月21日の記事です。
def test(aaa=[], bbb='test'):
— Kentaro Ashino (@Kentaro5626) 2018年9月6日
return aaa, bbb
print test(aaa=['a','b'], bbb='ddd')
>> (['a', 'b'], 'ddd')
こういう風に書くこともできるのね。これならモジュールをcmds風に使わせることもできそう。ロングとショートはどうやって混在させてんのやろ?#maya #python
こんなツイートを見かけたので 自分なりに仕組みを考えてみました
maya.cmds風の引数にしてみたい
maya.cmdsのソースを見てみよう
まずはmaya.cmdsのソースを見てみようと思ったのですが...
maya.cmds.__file__ // Result: <module 'maya.cmds' from 'C:\Program Files\Autodesk\Maya2018\Python\lib\site-packages\maya\cmds\__init__.pyc'> //
ん?
なんにも書いてないじゃん!?!?
どうやって読み込んでるの!?
・
・
・
cmdsのソースが見れない
調べたところmayapyで外部からcmdsを使うときなんかは
import maya.standalone maya.standalone.initialize(name='python')
ってのを実行しないとcmdsコマンドが使えないそうです。 maya.standaloneもコンパイルされてたのでソースを見ること叶わず...
help(maya.standalone) Help on module maya.standalone in maya: NAME maya.standalone FILE (built-in) FUNCTIONS initialize(...)
スタンドアロン アプリケーション ( Maya Python - 07AA )
引数の優先度を調べてみる
仕方ないので自分で調査することに
Mayaコマンドのショートとロングの引数の優先度を調べてみました。
True/False
cmds.ls(sl=True,selection=True) # Result: [u'pSphere1', u'pCube1', u'pCylinder1'] # #選択しているものがリストアップされた cmds.ls(sl=False,selection=False) # Result: [u'time1',u'sequenceManager1',u'hardwareRenderingGlobals',u'renderPartition',u'renderGlobalsList1',u'defaultLightList1',u'defaultShaderList1',u'postProcessList1',u'defaultRenderUtilityList1',u'defaultRenderingList1',u'lightList1',u'defaultTextureList1',u'lambert1',u'particleCloud1',u'initialShadingGroup',u'initialParticleSE',u'initialMaterialInfo',u'shaderGlow1',u'dof1',u'defaultRenderGlobals',u'defaultRenderQuality',u'defaultResolution',u'defaultLightSet',u'defaultObjectSet',u'defaultViewColorManager',u'defaultColorMgtGlobals',u'hardwareRenderGlobals',u'characterPartition',u'defaultHardwareRenderGlobals',u'ikSystem',u'hyperGraphInfo',u'hyperGraphLayout',u'globalCacheControl',u'strokeGlobals',u'dynController1',u'lightLinker1',u'persp',u'perspShape',u'top',u'topShape',u'front',u'frontShape',u'side',u'sideShape',u'shapeEditorManager',u'poseInterpolatorManager',u'layerManager',u'defaultLayer',u'renderLayerManager',u'defaultRenderLayer',u'polySphere1',u'pSphere1',u'pSphereShape1',u'polyCube1',u'pCube1',u'pCubeShape1',u'polyCylinder1',u'pCylinder1',u'pCylinderShape1'] # #シーン内のすべてが返された cmds.ls(sl=True,selection=False) # Result: [u'pSphere1', u'pCube1', u'pCylinder1'] # #選択しているものがリストアップされた cmds.ls(sl=False,selection=True) # Result: [u'pSphere1', u'pCube1', u'pCylinder1'] # #選択しているものがリストアップされた
True
/False
はショートとロングのどちらかがTrue
になるとTrue
となるようです。- any関数で処理されているのだと思う。
any([True,True]) # Result: True # any([False,False]) # Result: False # any([True,False]) # Result: True #
List
for x in cmds.ls(typ="mesh",type=["transform","camera"]): print(x,cmds.nodeType(x)) // Result: (u'pSphereShape1', u'mesh') (u'front', u'transform') (u'nurbsCircle1', u'transform') (u'nurbsSphere1', u'transform') (u'pSphere1', u'transform') (u'persp', u'transform') (u'side', u'transform') (u'top', u'transform') (u'frontShape', u'camera') (u'perspShape', u'camera') (u'sideShape', u'camera') (u'topShape', u'camera') //
- typ type どちらも処理される。
- 文字列,リストの両方が使える。
- 文字列を一旦リストに格納してから処理を行っているのだと思う。
Num
polySmooth = cmds.polySmooth(divisions=2,dv=0) cmds.getAttr("%s.divisions" % polySmooth[0]) # Result: 0 #
- 数値で値を入力するものはショートフラグが優先される。
- ショートとロングをリストにショート引数が優先になるように格納してからリストの0番を取れば良さそう
実装
とりあえず上記3つの条件を元に関数を作ってみた。
sl/selection False -------------------------------------------------------------------------------- typ/type [u'mesh', u'transform', u'camera'] -------------------------------------------------------------------------------- idx/index [1, 5] -------------------------------------------------------------------------------- h/help True -------------------------------------------------------------------------------- ls [u'pCubeShape1', u'pCylinderShape1', u'pSphereShape1', u'lambert1', u'frontShape', u'perspShape', u'sideShape', u'topShape'] --------------------------------------------------------------------------------
- メインとなる関数側で引数と値を指定
- 予めショート/ロング引数とデフォルト値を決めておいてメイン関数で受け取った辞書を処理する
- いい感じに値が返ってくる
- いい感じに返ってきた値を好き勝手に料理する
こんな感じ
ヘルプやドキュメントが不可欠になると思いますが、cmdsコマンドと似たような事が出来るようになりました。
書いてみたもののあまり使う機会は多くなさそう...?
classで書くともう少し拡張性は高くなるのですかね...?あまり書かないのでよくわからないですが...
help()で返ってくる簡易ヘルプみたいなのが設定出来たら良いかもしれません。
おわり
最後投げやりになってしまいましたが、可変長引数を利用して面白いものが出来たのではと思います。
明日はPatriotさんの記事です。 「ワークフローについて書きます。」とのこと、楽しみです。