I have a tool that allows the user to run an arbitrary mel script on a number of selected files. tricky thing is, when mayapy has opened the file and I call the
mel.eval(my_arg_here) , it doesn’t seem to run if the arg is coming in from being stored by sys.argv[someIndex] . If I hard code the command it runs it on all the files, but if I have the command entered into a textField in Maya and then passed in as an arg it no worky. The argument prints correctly after being passed in so I know the mayapy part is getting the correct arg, it just doesn’t seem to be evaluating it. Thoughts anyone?
Wait, so this works:
def myfunc(s):
....mel.eval(s)
myfunc('<whatever>')
but this does not?
def myfunc(s):
....mel.eval(s)
arg = sys.argv[3]
myfunc(arg)
I don’t believe that. Can you post some sample code? Or a more clear example?
actually your example is pretty much what I have. I also tried storing the command in a text file and then just have the .py file that mayapy is launching open that file and run it from there.
ms.initialize(name='python')
f=open(arg_path, 'r')
run_cmd = f.readlines()
f.close
cmds.file(file_name,
o=True,
force=True)
mel.eval(run_cmd)
cmds.file(rename='large_tracks_of_land.ma')
cmds.file(save=True,
f=True,
type='mayaAscii')
take that same code and instead of run_cmd being opened from a file try maybe something like
run_cmd = 'setAttr 'pCube1.translateX 5;'
and then that will work.
Now, the only way I have of knowing if the code evaluated properly is that the file that was created (based on the rename and save) has a change in it. So I made a simple file with a cube and some other primitives in it, then save a few different variations of it. If I run the code above it writes a new file yet nothing changes inside, yet if I hard code the command it does.
Yeaaaaah… Either the example is wrong or it’s no wonder it doesn’t work.
Also, your example that ‘works’ doesn’t- please check your quotes.
As to the problem- f.readlines() is going to return a list of strings, with newline characters at the end. This probably is not going to eval properly (I’m almost not surprised it doesn’t error). If there is only one line in the file, try doing:
with open(file_name) as f:
run_cmd = f.read().strip()
That will read the entire file in as a single string and make sure whitespace (such as a trailing newline) is trimmed off.
EDIT: It’s possible I’m entirely wrong about mel.eval, I can’t test right now, but I suspect not.
well that actually makes sense, Thanks! one other question then, does it matter that I am storing the command in an external file? would it matter if the argument passed it was a really long string if the user have a ton of code to evaluate? I just want to be efficient but take the route that leaves the least room for error (as you can tell right now there is too much in my case :D).
If it’s via the commandline, argument length is limited. Passing stuff in an external file would be technically fine, but design-wise, stinks.
What would be better would be to write your code so it’s easily callable, and then pass in a short statement via the commandline (‘import foo.bar; foo.bar.frob(“C:/path/to/file.mb”)’). Exec’ing or eval’ing large statements is suicide.