I've got a short Maya script that just rotates the camera continuously in a circle. Problem is, when I try to run the script, once it's running I can't close the application until I kill the script. I'm using cmds.refresh() but that only refreshes the UI and still delays other operations (like closing the program). I understand I can just kill the script by hand but I would like to be able to do it programmatically through callbacks or some other such thing.
Here's what my code looks like right now:
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)
Basically is there something I can put in the while() instead of "True" that will kill the script automatically when you go to close the program? Or something I could be doing differently altogether?
You really don't want to while True:
here. Maya is pretty old fashioned about threading -- touching the visible scene or the UI from a separate thread is a no-no -- so you can't easily create the kind of behavior you want without completely taking over the Maya session. Unfortunately that gives you the behavior you're experiencing.
You can try two basic strategies:
The simple thing is to use a maya scriptjob that fire on the 'idle' event. That will only try to run when Maya is not doing anything else and -- since Maya fires it for you in the main thread -- will not cause any problems. However this will only fire when Maya is not doing anything else -- so if the user is doing something in the UI or the scene your script won't fire. Something like:
def orbit_cam():
cmds.orbit('persp', ha = .01)
cmds.scriptJob(e=('idle', orbit_cam))
The big drawback to this is that you don't have any control over the frequency with which the script fires: that's up to Maya.
The second option is to create a separate thread to fire the script on your own terms. However you'll have to be careful here because functions fired from the second thread will cause crashes unless you wrap them in a call to maya.util.executeDeferred.
More background: How to use python (maya) multithreading and How to execute a Maya MEL procedure at regular intervals