一半君的总结纸

听话只听一半君

Maya Session Manager Experiment 1 (Linux)

Maya在linux下可以开很多,而且Linux虚拟桌面很好用,所以经常找不到自己想关的Maya,作为强迫症的lz,这怎么能忍,windows用户应该不会有此烦恼

预先研究点:

  • /proc/$pid/environ里面应该是有maya.bin启动时候的env vars, 在此应该可以得到show shot之类的信息,一般如果是在公司里,大部分是通过shell script来设置一些环境变量,从而启动正确版本的Maya以及load此项目需要的插件
  • module psutils应该可以用来得到maya的pid的启动时间
  • 如果有设计将maya运行时候的所有script editor输出全部同时转向到log文件的话,顺带还可以得到当前开着的文件是什么,因为你可以在log里parse “file -f -open” 或者 “file -f -save”这样的字样,说到这个lz又想起如果,所有k动画的命令都在log里的话,那你maya挂了没存也不怕,可以通过parse log来得到所有k过的地方,重新k过一编,这大概叫log replay?(借用irc的术语 orz ),当然实际中这不可能,除非特意设计了让所有k动画的辅助工具把做过些什么全部输出到log里,如果动画师只用s来key,那这方法确实可行,当然这是理想情况

具体实施:

  • 首先来模拟下production environment,看看 先查pid,再拿他的env var是否可行,lz的机器现在是CentOS 7,假设我们用showenv这个shell script来启动maya,他后面可以跟参数 这样… (我们就假设一下,具体不做什么)
    #!/usr/bin/env bash
    show="$1"
    shot="$2"
    export SHOW=$show
    export SHOT=$shot
    echo setting showenv to $show/$shot
    # you can call other script to set other env var such as 
    # additonal script or plugin path for show xyz
    

    用的时候就

    . ./showenv abc xyz010
    setting showenv to abc/xyz010
    
    # 于是SHOW 和 SHOT 这两个env var 就有了
    echo $SHOW
    abc
    echo $SHOT
    xyz010
    
    

    一般用linux的公司开软件之前都是要类似这样敲点命令的,为了设置项目abc的渲染分辨率,framerate或是需要的插件的路径,以及用什么版本的maya等等都可以在这里完成

  • 其此,你需要得到所有maya进程的pid,用命令可以做到
    pgrep -f maya.bin
    13760
    

    有几个maya就会返回几个pid,当然也可用psutils

    import psutil
    
    PROCNAME = "maya.bin"
    
    for proc in psutil.process_iter():
        if proc.name() == PROCNAME:
            print proc
    
    psutil.Process(pid=13760, name='maya.bin')
    [Finished in 0.1s]
    

    知道了pid,我们就可以去/proc/$pid/environ里取得env var,从而得到SHOW SHOT

    pid = 13760
    env = '/proc/%d/environ' % 13760
    with open(env,'r') as f:
    	for e in  f.read().split('\0'):
    		print e
    
    # 结果是
    psutil.Process(pid=13760, name='maya.bin')
    [Finished in 0.1s]
    
    

    把env vars存到dict里

    import re
    env_dict = {}
    with open(env, 'r') as f:
        for e in f.read().split('\0'):
            if e:
                k = re.search('^[^=]*(?=\=)', e).group()
                v = e[len(k)+1:]
                env_dict[k] = v
    
    print 'SHOW:', env_dict.get('SHOW', None)
    print 'SHOT:', env_dict.get('SHOT', None)
    
    # 结果是
    SHOW: abc
    SHOT: xyz010
    [Finished in 0.0s]
    

    所以这样是可以得到一个process的父process的env var的

  • 其次,考虑把script editor的输出同时写到文件里,这对解决某些crash问题的时候也许有用,虽然可以启动maya以后再运行
    cmdFileOutput -open /path/to/logfile

    但是maya启动之后到运行这条命令之前的输出就没有记录,如果想所有log都出到文件里,可以先设环境变量,再开maya

    export MAYA_CMD_FILE_OUTPUT='/tmp/logfile'

    比如我们可以这样开maya

    fn=$(mktemp -u -t 'maya-XXXXXX.log')
    export MAYA_CMD_FILE_OUTPUT=$fn
    maya &
    

    如果我们这样先有了这个环境变量,再开maya,那么上面的env_dict里就会有MAYA_CMD_FILE_OUTPUT,通过log文件(长这样的),我们可以间接的知道文件名,为什么呢,因为如过你开或者存了文件,必然会有这样的行

    ...
    file -f -options "v=0;"  -ignoreVersion  -typ "mayaAscii" -o "/home/oglop/maya/projects/default/scenes/hair.ma";
    ...
    file -f -save  -options "v=0;";
    // Result: /home/oglop/maya/projects/default/scenes/hair_v3.mb // 
    

    所以通过parse这个log文件,找到最后一个开的文件,和最后一个存的文件,就能知道当前的文件名了

    比如

    import re
    
    logfile = '/tmp/maya-GxOwzx.log'
    open_file = None
    save_file = None
    
    next_save = False
    with open(logfile, 'r') as f:
        for line in f:
    
            if next_save:
                save_file = re.search('(?<=Result:\s).*(?=\s//)', line).group()
                next_save = False
                continue
    
            if re.match('^file -f.*-o\s".*".*', line):
                open_file = re.search('(?<=\s-o\s\")[^\"]+(?=\")', line).group()
                continue
    
            if re.match('^file -f -save.*', line):
                next_save = True
    
    scene_file = open_file
    if save_file:
        scene_file = save_file
    
    print 'scene file:', scene_file
    
    # scene file: /home/oglop/maya/projects/default/scenes/hair_v3.mb
    

待续…

参考:
Handling positional parameters

Advertisements

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s