Maya 原生的 Script Editor 不太好用,因為:
- copy & past 不好用:這是指在 Linux 下,使用 Motif API 的 Maya 而言,其它平台的 Maya 沒有這個問題。
- 沒有 syntax highlighting:雖然說使用 script editor 時大都是試驗性或很簡短的程式碼,但天曉得,syntax highlighting 肯定能讓你的心情好一些,誰說「讓程式師計師的心情好不重要」的!!
- 不支援 regexp:just my humble opinion
- 不方便調整字型大小;just my humble opinion
- 沒有 smart indent;just my humble opinion but very important to Python
但是它也有幾點好處:
- 與 Maya output 在同一個視窗:方便 debug,在任何有疑問的地方 print 一下就行即時的 debug。
- 可以 run by selection:對於寫一些實驗性的 coding snippets 非常好用,至於在寫比較有規模的程式或模組時,直接透過 source (MEL) 與 import…reload (Python) 來做即可。
- 可以及時地查 mel 或 python 的 help:只有非常有經驗,寫過無數程式碼的工程師,才不需要查閱 API document,甚至可以誇張一點地說,程式設計師的工作不過就是查閱技術文件,然後把腦子裏的思緒(不管清不清楚,有沒有組織)以剛剛查到的語法寫出來,然後逐步(可能是逐行、逐函式、逐模組…)測試,最後交差,以接下來的維設與新增減功能。也因此,可否方便查閱文件,成了寫程式能不能很順暢的重要指標。不過 python 這一塊可以透過 mayaipy (maya + ipython2.4 + pymel) 來做到就是了。
- Maya 原生的:不容易當掉,當掉的話,大概都是 Maya 其它的部分爛了。
Vim as Maya’s Script Editor 的目的是:
使用 vim(末來可以擴充至其它 editor)來編寫 maya script (目前先以 python 為主),以補足 maya script editor 的不足,同時希望可以盡可能地做到一些它原有的好處。重點是,要很容易做到,不需要用 c/c++ 改寫 vim 什麼之類的就做到,這樣比較方便 deployment 與 maintain。
想法
- 透過 commandPort,先由 maya 開啟一個 tcp/ip commandPort (port 6000),用來與 vim 端溝通。
- 在 Maya 端,定義好一個叫 pythonCall 的 python function,這個 function 是用來被 vim 呼叫用的,目的是處理來自 vim 的 python script(因為 Maya 預設的 commandPort 只適合處理 MEL)。
- vim 這一邊,透過如下的設定檔來把程式碼先暫存到 /tmp/pythonToMaya.py,然後透過 socket (commandPort)呼叫 Maya 的 python(“pythonCall()"); 來執行。
1. 開啟 commandPort
commandPort -n ":6000" -echoOutput;
2. 在 maya 裏頭定義 pythonCall,這部分已經先行加到 userSetup.py 裏頭了,不需要再手動執行。
import __main__
import os
def pythonCall():
"""
exec the temp file on disk, in Maya
"""
tempFile = "/tmp/pythonToMaya.py"
if os.access(tempFile , os.F_OK):
# open and print the file in Maya:
f = open(tempFile , "r")
lines = f.readlines()
for line in lines:
print "##", line.rstrip()
f.close()
print "\n",
# execute the file contents in Maya:
f = open(tempFile , "r")
exec(f, __main__.__dict__, __main__.__dict__)
f.close()
else:
print "No temp file exists: " + tempFile
3. 準備一個 vim 設定檔 ~/.vim/ftplugin/python/python_maya.vim
" Only do this when not done yet for this buffer
if exists("b:loaded_py_maya")
finish
endif
let b:loaded_py_maya = 1
python << EOF
import vim
_tempFile = "/tmp/pythonToMaya.py"
_init = False
_maya = None
def PyMayaInit():
global _maya
global _init
import socket
_maya = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
_maya.connect(("127.0.0.1", 6000))
except socket.error, e:
return
_init = True
def PyMayaHandleLines(lines):
return lines
def PyMayaWriteOut(txt):
f = open(_tempFile, "w")
f.write(txt)
f.close()
def PyMayaSubmitIt(txt):
if not _init:
return
PyMayaWriteOut(txt)
_maya.send('python("pythonCall()")')
def PyMayaLine():
line = vim.current.line + "\n"
PyMayaSubmitIt(line)
def PyMayaRange():
range = vim.current.range
lines = ""
for line in range:
lines += line + "\n"
PyMayaSubmitIt(lines)
EOF
vmap :python PyMayaRange()
nmap :python PyMayaLine()
python PyMayaInit()
4. 在 vim 編輯一 python 檔時,在 normal mode 下,ctrl-m 就會把游標下的那一行傳到 maya 執行;在 visual mode 下,會把選取的整段傳到 maya 執行。