Background Python loops in Maya

I’m trying to get some functionality written down without the use of the C++ API. The thing is that I need my code to be continually evaluating say, every time a hard-coded node is re-evaluated after being flagged dirty.

I tried implementing something with expressions, but only when the frame is changed does it evaluate - in other words, not often enough.

Which brought me to my next idea - a while loop written in Python that constantly evaluates the data and spits out some new values! I was told by a professor that inside every program runs a while loop, waiting for user input (which then fires off a series of commands when certain parameters are met, and returns to the idle state). Seems to make sense, I could use that same methodology with a Python script. The problem is, whenever a while loop starts, it locks up all of Maya so that the user can’t feed new info into the loop.

Is there any way to get my loop to not cause Maya to freeze(AKA run in the background while still providing meaningful data to Maya). Right now I am experimenting with the multiprocessing module. Has anyone had success with a method like this, or am I going about this completely wrong and there is no way to provide such functionality outside of a compiled plugin. Any help would be greatly appreciated.

Thanks!

I’m not sure exactly what you are trying to do, but having a continuous loop in the background if never a good idea. It should get triggered when needed. The question is how to trigger it, which is hard to answer without knowing more details.

ScriptJob or OpenMaya.MSceneMessage.addCallback are examples of build in ways to trigger stuff.

am I going about this completely wrong and there is no way to provide such functionality outside of a compiled plugin.

Yes, this is the completely wrong way to go about this.

I was told by a professor that inside every program runs a while loop,

Well not every program, but most (all?) GUI programs, and obviously that was a greatly simplified description. In Maya’s case, this main loop is controlled by Maya (and Windows), not your python code!

Seems to make sense, I could use that same methodology with a Python script. The problem is, whenever a while loop starts, it locks up all of Maya so that the user can’t feed new info into the loop.

You’re running into two problems here. One is that what you’re doing is a bad idea- even in truly multithreaded environments like .NET, you do NOT want to have anything like this- what if everyone coded this way? You’d have a hundred threads idling because people used this model. I’ve blogged before about creating effective multithreaded programs.

The other problem is that python is NOT a truly multithreaded environment. It uses a Global Interpreter Lock, which means only one thread can execute at a time. So if you used the threading module to create a thread that just ran a while True loop, and then put the main thread into a while True loop, you wouldn’t have two loops running simultaneously- you’d have one running at a time and switching to the other one at some point (the rules for GILing and unlocking escape me right now for pure python code).

Right now I am experimenting with the multiprocessing module.

mutliprocessing makes a copy of the process memory, so you cannot adjust the original processes memory, which makes multiprocessing sort of not useful for what you want to do. Not only that but even threading wouldn’t work (which doesn’t copy process memory, it works in-process), because the Maya API should only be accessed from the main thread.

Having a continuously looping/waiting thread is never the best solution for anything, in python or otherwise, other than a program’s main loop. I’ve never seen or heard even a mildly convincing case otherwise. Find another way to do it.

Wolfson, thanks - I think scriptjob was exactly what I was looking for. I’m trying to deconstruct IK and FK, then rebuild it so I can understand it a little better - and add a few functional tweaks of my own. That’s also why I posted it in the rigging board.

and Rob, thanks for those resources - I’ll look into those - I’m a little new to programming in general and still learning how to do so effectively.

You can do a scriptJob on selectionChanged, which is good for most rigging/animation tools.

On a separate note, I just read a whitepaper yesterday that says that Maya has multithreading on the C++ API since 2009, but I think most of it is to take advantage of multiple cores, the examples were mostly for simulation stuff.

[QUOTE=lkruel;11341]You can do a scriptJob on selectionChanged, which is good for most rigging/animation tools.

On a separate note, I just read a whitepaper yesterday that says that Maya has multithreading on the C++ API since 2009, but I think most of it is to take advantage of multiple cores, the examples were mostly for simulation stuff.[/QUOTE]

Maya’s multithreading in the API is pretty specific though and actually does require you to think a bit about how you set your scene up. It definitely shouldn’t be thought of as a catch all multithreading perf improvement type thing, because that’s definitely not the case. Like everything in maya, it comes with a bullet list of caveats.

[QUOTE=lkruel;11341]You can do a scriptJob on selectionChanged, which is good for most rigging/animation tools.

On a separate note, I just read a whitepaper yesterday that says that Maya has multithreading on the C++ API since 2009, but I think most of it is to take advantage of multiple cores, the examples were mostly for simulation stuff.[/QUOTE]

Yeah, you can do a scriptjob on selectionChanged and a scriptjob on attributeChange, which is I think what I need. I know that I’m gonna have to be careful setting it up… I’m hoping to start and end the jobs with the click of a button in a GUI.

Also, I know that Maya’s supported multiple render threads as long as I’ve used it, but I didn’t know about the multiple core thing as far as simulations are concerned.

You can also parent a scriptJob to a UI element using the parent flag, which allows you to ensure that if your tool is gone, the jobs are dead.

[QUOTE=lkruel;11377]You can also parent a scriptJob to a UI element using the parent flag, which allows you to ensure that if your tool is gone, the jobs are dead.[/QUOTE]

interesting idea - one that works on an independent tool, but I’m looking to integrate this into a larger project.