拿 Vim 來替代 Maya Script Editor

Feb 13 2009

animation

Vim As a Maya Script Editor Vim As a Maya Script Editor

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 執行。 
comments powered by Disqus