Reputation: 1533
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?
Upvotes: 0
Views: 424
Reputation: 12218
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
Upvotes: 1
Reputation: 1501
You could do this with a scriptJob
attached to the idle
event.
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)
This will continually rotate the camera while allowing the user to quit the application at any time or interact with the UI. Note that you'll probably want a callback which deletes the script job when the animation should end.
Upvotes: 0