Thursday, September 30, 2010

Maya Python 試驗之旅(三) 東玩西玩

書翻著翻著,不知不覺就來到了書的第九章,不是說中間沒什麼好內容,每一章其實都有不錯的東西,但有些 Mel 語法上的介紹或者是 expression  的使用,跟我們所關心的部份有點遠,所以就先略過了,在介紹 Porcedures 這一章有看到一些個人覺得還蠻有趣的東西,在這裡分享一下心得,


在 Maya 中使用 Python 來定義 function 其實是一件很容易的事,只要會 Python,應該就沒什麼難度

# 定義一個 "controls" 的函式
def controls():
    # 建一個 window
    win = pm.window(title='controls')
    pm.columnLayout()
    # 為場景上的每一個 (transform) 物件都建一個 attrFieldSliderGrp 並用來控制物件的 translateY
    for obj in pm.ls( type='transform'):
        pm.attrFieldSliderGrp(label='%s translateY'%obj, min=10, max=100, attribute='%s.ty' % obj)
    
    pm.showWindow(win)

controls()

定義好 function 後,每次都只需呼叫 controls 就行了,是不是很方便呢


試做了一個簡單 UI,可以讓使用者快速的設定 frame range,個人是覺得還蠻方便的,但在實作的時候,發現 PyMel 居然沒有 intFieldSliderGrp,所以只好先用 intFieldGrp來代替

# called when frame range is changed
def frameRangeChanged(frameRangeField):
    pm.playbackOptions(min=frameRangeField.getValue1(), max=frameRangeField.getValue2())

# create frame range utility
def frameRangeUI():
    win = pm.window(title='frameRangeUtil')
    pm.columnLayout()

    # create an intFieldGrp and set current frame start and end 
    frameRangeField = pm.uitypes.IntFieldGrp(label='framerange',numberOfFields=2,     value1=pm.playbackOptions(query=True,min=True), value2=pm.playbackOptions(query=True,max=True) )

    # set callback whenever value is changed
    frameRangeField.changeCommand(pm.Callback(frameRangeChanged, frameRangeField))
    pm.showWindow(win)

frameRangeUI()

結果如下,我們之前一個人物的各個動作會放在同一個 Maya 檔中,這個小工具就可以很方便的找到特定動作的 frames (當然,這只是一開始,要做的話還是有非常大的改進空間,例如,animation tag, list all animations or jump to specific animation etc.. )


在書中的附錄中有一個我覺得也蠻有意思的範例,是將建一個專屬的  shelf,script 中用到了一些 function 像執行系統命令或是 tokenize 剛好可以測試一下 Python 的強項,


import subprocess

import pymel.core as pm
import pymel.util as pmUtil

def tornOffShelfWindow( shelfWindowName ):  
    # get HOME dir on Windows it should look like "C:/Documents and Settings/%USERNAME%/My Documents"
    homeDir = pmUtil.getEnv('HOME')
    
    # build command line to get all *.mels under shelves folder
    commandLine = "dir /W /ON /B " + "\"" +homeDir + "/maya/2011/prefs/shelves\""
    # get ouput 
    list = os.popen(commandLine).read()
    shelves = list.split("\n")
    
    # create main window
    win = pm.window(title=shelfWindowName, width=260,height=200)

    #create main shelf tab layout
    mainShelfTab = pm.uitypes.ShelfTabLayout( image='smallTrash.xpm', imageVisible=True )
    
    for item in shelves:
        if item.endswith(".mel"):
            scriptBaseName = item.replace('.mel', '')
            shelfName = scriptBaseName.replace('shelf_', '')
            pm.uitypes.ShelfLayout(shelfName, parent=mainShelfTab)
        
            # run the mel script, load icon, set command etc...
            pm.mel.eval( scriptBaseName+"()")

    pm.showWindow(win)

    
def tornOffShelf():
    if not pm.window("ShelfWindow", exists=True) :
        tornOffShelfWindow("ShelfWindow")
    else :
        print "ShelfWindow is already existed"


script 中一些如 string 處理或是系統命令的呼叫用 Python 來做,程式碼簡潔許多,也許是背景色的關係,連 shelves 看起來也變的更有質感了 :D

No comments: