Quite often, especially when you are writing and testing a new MEL script, you’ll inadvertently create a for or while loop that never exits. Usually due to a testing condition that never becomes true, 99% of times it’s probably due to a dumb oversight that is (hopefully) picked up during initial testing/debugging, but infinite loops can still sometimes occur in production scripts. Even if you haven’t got stuck in an infinite loop you may suddenly realise that you’ve started a script with the wrong type of, or too many, components selected and the script will be churning away for a good 2-3 hours if not interrupted!
Once a bit of MEL enters such a loop there is no way of breaking out of it other than killing Maya’s process from the Windows Task Manager. Obviously this is a bit of a tedious job at the best of times, especially if it’s a script that needs thorough testing, but what if your loop-locked script was running on a scene you’d not saved for a couple of hours?
Here’s an excellent and, so far, bulletproof (touch wood) method of protecting yourself and your scripts. Because Maya has locked up at this point we can’t issue any kind of command or process from Maya. We can however issue a command from outside Maya, say from DOS…
If you create a batch file somewhere on your PC with the following content:
@echo off
echo This file breaks infinite loops in MEL scripts > c:\breakMel
pause Maya halted - Press any key to continue
del c:\breakMel
call it HALTMAYA.bat or STOPLOOP.bat or whatever name works best for you so you don’t forget what it’s for. If you have no idea what a batch file is, simply copy and paste the above code into a text file and save it as one of the names suggested above (make sure you don’t have file extensions hidden in windows!).
Now, when you run this batch file it should open a DOS shell window and prompt you to press a key to continue. Pressing a key dismisses the DOS box…
So? what exactly did this do and how does it help us stop an infinite loop??
Well if we take a look at the batch code it should be relatively self explanatory, even if you don’t know any DOS batch commands. The first line simply hides the echoing of commands (kinda like Maya script Editor “Echo All Commands” set to “off”). The second line echos the specified sentence, but the important bit is the > at the end. This > symbol tells the echo commad to redirect the echoed words into a file instead of onto the screen. That’s why you never see these words printed in the DOS window, they are sitting in a file called “breakMel” on the root of your C: drive. Of course you can change these words and the name of the file, as they are entirely irrelevant and no-one will ever see either of them. All that’s important here is that a detectable file has been created. The third line simply pauses DOS and prompts you to press a key. This is vitally important because we’ve no idea how long the rogue MEL script will take to get once through the loop it’s stuck in, and we need to ensure that it detects the breakMel file we’ve just created. The pause allows us to sit and wait for the loop to detect the file before we proceed to the fourth and final line which deletes it. If we don’t delete the break file your MEL script will find it again next time it is run and halt immediately!
So, the final piece of the puzzle.. how does your MEL script detect the creation of this file? It’s quite straightforward; you just put a single line inside the loop in your MEL script:
if (`filetest -f "c:/breakMel"`) break;
Every iteration through your loop will look for the existence of a file called “c:\breakMel” and if it exists it will break out of the loop. If you have more than one nested loop though, you will either need to put the same line in each nested level of the loop or change the break command into an error, which is a lot simpler:
if (`filetest -f "c:/breakMel"`) error "User broke out of infinite loop!";
Believe it or not, adding this command doesn’t appear to have any noticeable effect on the performance speed of a script. I initially thought checking for a file would take MEL ages but surprisingly it doesn’t, at least not in this context. I’ve run timing tests with and without this line and there’s no significant difference, so you don’t need to worry about adding this feature to all your scripts. Of course, once you’re convinced your script is fully robust enough that it can’t get stuck in an infinite loop you can always remove this line, but it won’t hurt if you do decide to leave it in.
The other good thing about this trick is that it has no dependencies, so you can safely distribute the script to anyone without worrying that the line will cause any kind of problems at their end, as it’s unlikely anyone will ever have a file called “breakMel” on their C:\ drive!
You can do a similar thing in Python:
import os
if os.path.exists("c:/break"): break
re: infinite loop
God bless you and all yer future offspring
Comment by Roger Klado — May 8, 2009 @ 5:38 pm
[…] http://www.naughtynathan.co.uk/?p=59 […]
Pingback by teacup’s techy Art stuff » Breaking infinite loops in MEL — May 15, 2009 @ 4:17 pm
I have a doubt …..
is it possible to save a new scene using MEL commands …
I am trying for that can u help me…
Comment by mujeesh — September 17, 2009 @ 2:41 pm
mujeesh, yeah, pretty much everything you do in Maya can be replicated in MEL (or Python)
most file operations are handled by the “file” command, check out the MEL docs for details.
Basically you have to NAME the current file first then you have to save it, so:
file -rename "c:/work/myScene.ma";
file -save -type "mayaAscii";
would save the current scene as: c:\work\myScene.ma. Good luck.
Comment by Naughty — September 17, 2009 @ 9:52 pm
Good golly, what a clever-clogs you are !
Nathan, it’s highly unfair that you’re actually a tremendous artist as well as remarkably insightful programmer. I’ve decided I don’t like you any more 🙂
Comment by Rico — July 28, 2010 @ 9:33 am
Thanks Rico, that means a lot coming from an artist as accomplished as yourself, cheers. I just wish I could put a little more effort into it 😀
Comment by Naughty — July 31, 2010 @ 5:26 pm
Thank you, Nathan. It was very helpful. Now I don’t have to launch the Windows task manager.
Comment by Cimple — November 15, 2010 @ 2:28 pm
Hi
Just looking through blog…
I knew about this method but never implemented it myself.
I don’t know windows batch commands(etc) so i wrote python file.
Save this as .py file and make your py files association with python.exe and then you can double click
import os
input = raw_input(‘Break Loop:y/n\n’)
if input == ‘y’:
file=open(“c:/breakLoop”,”w”)
filePath=file.name
file.close()
input = raw_input(‘Press Enter To Continue’)
os.remove(filePath)
Comment by ginoauri — May 5, 2011 @ 1:47 am
good idea Ginoauri, although I should point out that this only works if you have python independently installed on your system, which not all Maya users may have!
Comment by Naughty — May 5, 2011 @ 9:26 pm
I think you do not have to install python.
There is in mayas bin folder python executable (mayapy.exe) , so you can make your association with this , and it will be crossplatform solution not windows specific 😛 .
Comment by ginoauri — May 5, 2011 @ 10:51 pm
have you actually tried associating .py files with mayapy.exe to execute them..? 😉
Comment by Naughty — May 5, 2011 @ 11:04 pm
Yes , and it works.(Just tested above script)
Comment by ginoauri — May 6, 2011 @ 12:52 am