0

我有一个简短的 Maya 脚本,它只是将相机连续旋转一圈。问题是,当我尝试运行脚本时,一旦它运行,我无法关闭应用程序,直到我终止脚本。我正在使用 cmds.refresh() 但这只会刷新 UI 并且仍然会延迟其他操作(例如关闭程序)。我知道我可以手动杀死脚本,但我希望能够通过回调或其他类似的东西以编程方式完成它。

这是我的代码现在的样子:

import sys
import time
import maya.cmds as cmds
import maya.api.OpenMayaUI as omui

view = omui.M3dView.active3dView()
currentCamera = view.getCamera()

while(True):
    cmds.orbit(currentCamera, ha = 1)
    view.setCamera(currentCamera)
    cmds.refresh()
    time.sleep(.01)

基本上有什么我可以在 while() 而不是“True”中放入的东西,当你关闭程序时会自动终止脚本?或者我可以做一些完全不同的事情?

4

2 回答 2

1

你真的不想在while True:这里。Maya 在线程方面非常老套——从单独的线程中接触可见场景或 UI 是不行的——因此,如果不完全接管 Maya 会话,就无法轻松创建所需的行为。不幸的是,这给了你你正在经历的行为。

您可以尝试两种基本策略:

简单的事情是使用在“空闲”事件上触发的 Maya 脚本作业。这只会在 Maya 没有做任何其他事情时尝试运行,并且 - 因为 Maya 在主线程中为您触发它 - 不会导致任何问题。然而,这只会在 Maya 不执行任何其他操作时触发 - 因此,如果用户在 UI 或场景中执行某些操作,您的脚本将不会触发。就像是:

def orbit_cam():
   cmds.orbit('persp', ha = .01)

cmds.scriptJob(e=('idle', orbit_cam))

这样做的最大缺点是您无法控制脚本触发的频率:这取决于 Maya。

第二种选择是创建一个单独的线程以按照您自己的方式触发脚本。但是,您必须在这里小心,因为从第二个线程触发的函数会导致崩溃,除非您将它们包装在对maya.util.executeDeferred的调用中。

更多背景知识:如何使用 python (maya) 多线程如何定期执行 Maya MEL 程序

于 2015-08-03T17:29:22.443 回答
0

您可以通过scriptJob附加到idle事件来执行此操作。

import time
import sys
import maya.cmds as cmds
import maya.api.OpenMayaUI as omui

view = omui.M3dView.active3dView()
currentCamera = view.getCamera()

def rotate_camera():
    cmds.orbit(currentCamera, ha = 1)
    view.setCamera(currentCamera)
    cmds.refresh()
    time.sleep(.01)

cmds.scriptJob(event=['idle', rotate_camera], killWithScene=True)

这将持续旋转相机,同时允许用户随时退出应用程序或与 UI 交互。请注意,您可能需要在动画结束时删除脚本作业的回调。

于 2015-08-03T17:27:14.227 回答