2016-03-21 33 views
0

我需要符合我们从客户端接收的一些maya场景,以使它们与我们的管道兼容。显然,我希望批量执行此操作,并要求我从Maya内启动此过程。
我已经尝试了两种方法(非常相似),这两种方法都有效,但问题在于Maya GUI冻结,直到过程完成。我希望该过程对于用户来说是完全透明的,以便他们可以保留工作表,并且只有完成时才显示一条消息。
这里是我的尝试,发现到现在为止:
这里本教程:http://www.toadstorm.com/blog/?p=136促使我写这篇文章,并将其保存:Maya GUI在子流程调用期间冻结

filename = sys.argv[1] 

def createSphere(filename): 
    std.initialize(name='python') 
    try: 
     mc.file(filename, open=True, pmt=False, force=True) 
     sphere = mc.polySphere() [0] 
     mc.file(save=True, force=True) 
     sys.stdout.write(sphere) 
    except Exception, e: 
     sys.stderr.write(str(e)) 
     sys.exit(-1) 
    if float(mc.about(v=True)) >= 2016.0: 
     std.uninitialize() 

createSphere(filename) 

然后将其从Maya调用方式:

mayapyPath = 'C:/Program Files/Autodesk/Maya2016/bin/mayapy.exe' 
scriptPath = 'P:/WG_MAYA_Users/lbouet/scripts/createSphere.py' 
filenames = ['file1', 'file2', 'file3', 'file4'] 

def massCreateSphere(filenames): 
    for filename in filenames: 
     maya = subprocess.Popen(mayapyPath+' '+scriptPath+' '+filename,stdout=subprocess.PIPE,stderr=subprocess.PIPE) 
     out,err = maya.communicate() 
     exitcode = maya.returncode 
     if str(exitcode) != '0': 
      print(err) 
      print 'error opening file: %s' % (filename) 
     else: 
      print 'added sphere %s to %s' % (out,filename) 

massCreateSphere(filenames) 

它工作正常,但正如我所说,冻结Maya GUI直到过程结束。这仅仅是为了创造一个球体,所以不能接近我实际上必须在场景中执行的所有动作。
我也尝试通过调用mayabatch的.bat文件运行第一个脚本,并运行脚本,同样的问题。
我发现这个职位(Running list of cmd.exe commands from maya in Python)谁似乎正是我正在寻找,但我看不出如何适应我的情况?
从我所了解的问题可能来自一个循环(即多次)调用Popen,但我真的不知道该怎么做,否则......我想也许将第二个脚本保存在磁盘上的某个地方,从玛雅称这一个?

回答

0

在这种情况下,subprocess.communicate()将会阻塞,直到子进程完成,所以它不会自行解决您的问题。

如果您只是想启动流程,而不是等待它们完成 - “激发并忘记”风格 - 您可以使用线程,从每个流程的新线程开始。但是,您必须非常小心地向用户报告 - 如果尝试从外部线程触摸Maya场景或GUI,您会看到神秘的,无法解析的错误。 print()通常确定但maya.cmds()不是。如果你只是打印邮件,你可能会拿到maya.utils.executeDeferred(),这是讨论in this questionin the docs

+0

是的,这就是我意识到的。当我启动它来处理各种文件时,如果没有'subprocess.communicate()',它会根据需要打开尽可能多的控制台,完成这项工作后,将输出结果打印在控制台上,并在打开时快速关闭。通过说'maya.cmds'不好,你的意思是你不建议用这种方法在maya场景上做一些改变?感谢这些链接,我现在就去阅读它们。 –

+0

基本上,除非包含在'maya.utils.executeDeferred'中,否则不应该尝试从'maya.cmds'之外的任何其他线程发出任何内容。这有点过分简化,但这是一个很好的经验法则。你仍然可以按常用方式在你的_other_ maya实例中使用'cmds',但是在用户看到的那个中,不要触摸线程中的cmds – theodox

+0

感谢您的回复。我不得不承认,英语不是我的主要语言,加上自己学习python使一些概念仍然很难掌握,但我会继续挖掘。我认为现在我会继续在主线程中使用子进程,因为我确实需要一些输出。 –