Sunday, August 15, 2010

Current Version

It is often necessary to know the exact Python version for debugging or installing modules.
import sys
print sys.version_info
It is also sometimes important to know what Maya version is currently running, especially for backwards compatibility.
import maya.cmds as cmds
print cmds.about(version=1)


If you are using an IDE and want to make sure your code will execute as expected without having to worry about version control set its default Python interpreter to C:\Program Files\Autodesk\Maya2009\bin\mayapy.exe.

External Editor

Maya 2011 new features
Although Maya 2011 added a slew of new features to the script editor, it is still best practice to program in a standalone IDE.  Some of the benefits include:
  • Custom syntax highlighting.
  • Collapsible Code.
  • Regex Assistance.
  • File management, versioning, sharing is easier. 
  • Runs on an independent process.
Fortunately,  Maya automatically saves your scripts on exit.  However, you WILL lose data if you solely rely on this feature.  This can occur if you are coding on multiple instances of Maya simultaneously, or more likely, Maya crashes.  Also, keep in mind, your scripts can easily, unintentionally trigger a crash themselves.  Programming on an independent process will allow you to force quit from Maya with no data lose.

Again Python has the benefit over MEL in that it is an independent, open-source language.  Therefore IDE's are readily available.  Eclipse + PyDev [open-source], Komodo [commercial], PyCrust [commercial], etc.  In addition every Python interpreter comes with a bare bones editor called IDLE.  Install either version 2.5 or 2.6 (post Maya 2010).  http://www.python.org/download/  To launch the IDE go to Start > Python > IDLE.  You can also launch it through a shell using:
python C:/Python27/Lib/idlelib/idle.py
Yes, you are using a Python application to write your own Python scripts.  Once the Tk Python shell opens go to File > New Window.  Here you can type your code as if you were using Maya's Script Editor.  You will want to save your file to ~\Users\Paul\Documents\maya\scripts [Windows] or ~/Library/Preferences/Autodesk/maya/scripts [Mac] with a .py extension.


Then in order to execute this file from Maya type:
import filename
Once the file is imported successfully and you want to make changes you will need to run:
reload(filename)
There may be times while debugging when it may be more convenient to execute portions of your external script from Maya.  To interact with imported objects you must type the filename . variableName.
import HelloWorld
print HelloWorld.mySting  #call a variable defined in HelloWorld.py
HelloWorld.myFunction()   #call a function defined in HelloWorld.py
*Maya can read Python documents created after Maya has launched, but cannot read new MEL files until it has been restarted. 

Alternative Importing

Using Maya's scripts folder is great if your working on a personal project, but isn't as handy for a company wide script.  In these cases you can assign Maya to look in a shared folder.
import sys
sys.path.append("M:\mayascripts")
import HelloWorld

Whereas the MEL source command allows for absolute paths:
source "C:/users/paul/desktop/something.mel"
Or set the environment variables MAYA_SCRIPT_PATH for MEL and the PYTHONPATH for Python to the scripts directory.  Also note Maya will automatically source all your MEL files, but Python scripts must always be manually imported.

If you are going to be editing the env variables you will need to restart Maya for changes to take affect.

History Menu

Script Editor > History
Batch Render Messages
  • MEL - Only effects messages detailing batch rendering progress.
Echo All Commands
  • MEL - Displays overly verbose detail for every action Maya takes.  You might think this is beneficial to have on but rarely is this information valuable. This is equivalent to:
cmds.commandEcho(state=1)    #or 0
Line Numbers In Errors
  • MEL & Python (2011) -  Displays the line the error occured. Pre 2011, or when Show Stack Trace is enabled, Python's interpreter outputs this information regardless.
Show Stack Trace
  • MEL & Python (2011) - Creates a separate stack output window for runtime errors.  Pre 2011 Python's interpreter outputs this information regardless.  This is equivalent to:
    stackTrace -state 1    #or 0
    print (12/0)           #try making a runtime error
    • *Manually setting the commandEcho, stackTrace state triggers toggling errors in the UI. 
    Suppress Command Results
    • MEL - Toggles command results.  Will still display //Result in the command line.
    polySphere;
    >>// Result: pSphere3 polySphere3 // 
    Suppress Info Messages
    • Toggles display of info messages, only generated by Maya internals.
    Suppress Warning Messages
    • MEL & Python - Toggles display of purple (yellow 2011) warning messages(commands).  Will still display //Warning in the command line.  [Added to Python library in 2011] 
    warning "You did something wrong.";
    >>// Warning: You did something wrong. // 
      Suppress Error Messages
      • MEL & Python - Toggles display of red error messages(commands).  Will still display //Error in the command line.  [Added to Python library in 2011]
      Suppress Stack Window
      • Toggling this from the menu takes no affect.  However, if Show Stack Trace is on and you manually set suppressStackWindow the stack window is suppressed AND the Suppress Stack Window menu reflects the change.  Querying this field defaults to off, otherwise it is the previously set state regardless of the UI display on startup.
      scriptEditorInfo -suppressStackWindow 1; 
        *Manually setting the stackTrace state triggers toggling errors for selecting Show Stack Trace from the UI.

        Basic Python in Maya

        Lets cover some Python fundamentals to get us started.

        Since, out of the box, Python was not developed for Maya it does not understand how to interact with any of your scene's nodes.  Therefore, although you can always write pure Python code with no problem, whenever Python needs to interact with your scene you will need to import a module Maya provides to append all its MEL functions. 
        import maya.cmds
        maya.cmds.polySphere()
        
        This will first execute the module maya.cmds from the current Python session.  This will import all of Maya's Python wrappers for its MEL commands.  To execute the Maya command you must write the module name followed by the command name.  To reduce the need to type maya.cmds for every command it is most common to assign the module to a namespace.
        import maya.cmds as cmds    #mc is also a frequently assigned namespace
        cmds.polySphere()
        
        Another method is to bring all the maya.cmds objects into the current main module:
        from maya.cmds import *
        polySphere()
        
        This requires no namespaces.  However, standard Python functions may be overridden. Alternatively, since everything in Python are objects you can copy the function call to an object in the current module.
        import maya.cmds as cmds
        polySphere=cmds.polySphere()
        polySphere()
        

         -----

        Most commands return feedback after a successful call.
        • All commands in create mode return the name of the node created. 
        • Query commands return the attribute(s) designated.  
        • Edit commands will return either 0 or 1.  
        Again, always have the docs open while programming to check available flags.
        mySphere=cmds.polySphere() #stored the created nodes in mySphere
        print mySphere
        >>[u'pSphere1', u'polySphere1']
        
        These are some of the most simple, essential commands that even non programmers should know. You will return to these time and time again.
        • ls
        • select
        • delete
        • listAttr
        • setAttr
        • listConnections
        • listRelatives
        • nodeType
        • undo

        Example:
        import maya.cmds as cmds
        stepTransforms=[]     #a python array
        for i in xrange(50):     #loop this code block 50 times
            currentStep=cmds.polyCube(width=6, height=.2, depth=1, name="step%s" %i)
            cmds.xform(currentStep, translation=[0,float(i)/5,0], rotation=[0,i*10,0])
        
            stepTransform, stepMesh=currentStep     #unpack the polyCube result into transforms and meshes
            stepTransforms.append(stepTransform)
        cmds.group(stepTransforms, name="stairs")
        
        Writing Python procedures for Maya doesn't get much more complicated than that.  Play around with different commands, and remember the docs have examples on nearly everything.