Monday, September 6, 2010

Kill Maya

There are plenty of times when Maya goes rogue and takes control of your system. Here are some methods of killing the frozen process.

Linux has superior methods of handling this situation so we'll start here.
  • First connect to an auxiliary terminal.  
    • Open a Virtual Console.
      • Press Ctrl+Alt+Fn.
    • Connect from a remote terminal using a secure shell.  *The SSH server must be started on the client machine.  service sshd start on fedora.
      • ssh username@ip
    • Connect from a remote OS using a VNC as an alternative user.  *The VNC server must be started on the client machine.
  • Once connected to the local terminal identify and kill the process.
    • Use standard unix commands.
      • ps -u paul | grep maya
      • kill -signal pid
        • 9 SIGKILL -Hardest
        • 15 SIGTERM -Softest 
    • If installed use top.
      • top
        • z: color
        • x: highlight column sort
        • <, > change sort column 
        • q: quit
        • u: username
        • R: reverse sort
        • k: kill process id

            Windows on the otherhand does not have virtual consoles so all these methods require a auxiliary computer on the network.
            • Run a basic taskkill.
              • taskkill /s ip /u username /p password /im maya.exe /f  [/pid process id]
            • Connect using telnet. *The telnet server must be started on the client machine. Check Telnet Client and Telnet Server from Control Panel->Programs and Features->Turn Windows features on or off.
              • telnet ip
              • taskkill /u username /p password /im maya.exe /f
            • Connect from a remote OS using a VNC as an alternative user.  *The VNC server, or default Microsoft Terminal Server, must be started on the client machine.
              • runas /user:username "taskkill /im maya.exe /f"

            Friday, September 3, 2010

            Hypergraph Colors

            I'm sure we can all agree working in the hypergraph can sometimes be quite imbroglio.  Knowing what to look for in this tangled web can really help.  It would be nice to have a hide connection lines on selected nodes feature like Nuke to help clean up the network.  But Maya only allows us to globally merge multiple connections, which doesn't really help when we are interested in node specifics.   

            It is therefor pretty valuable to remember how the hypergraph defines its line colors.  Here is my refined color chart from Maya's docs followed by an example of each.
            General > Basics > Basics Windows and Editors > Hypergraph > Hypergraph Overview

            Wednesday, August 25, 2010

            Monday, August 23, 2010

            Python Cheat Sheet

            This is for everyone who, for whatever reason, are putting off learning Python.  Ideally, if you are coming from another language such as MEL or Perl, you should be able to skim through these demos and have no problem transitioning to Pythonic syntax.  The following Python snippets are selections from the online documentation at http://docs.python.org/, which I modified whenever possible to fit into a Maya context.

            Data Structures
            • Strings
              myString="Hello"
              mySecondString="World"
              result=myString+mySecondString
              myMultilineString="""Hello World.
              What a beautiful world it is."""
              myRawString=r"C:/Users"
                
              firstLetter=myString[1]
              lastLetter=myString[-1]
              firstWord=myString[0:4] 
              • Unicode: Since Maya is used internationally, multiple language packs are supported which require a unicode character set. Think of unicode as the big brother of the standard ASCII model. You will not see anything unusual as the result of MEL commands, however Maya will return Python commands in unicode notation. As long as your in Maya the prefix u can be ignored, however, if you are writing output to a file they will have to be converted to ASCII.
              print cmds.ls(cameras=1)
              >>[u'frontShape', u'perspShape', u'sideShape', u'topShape']
              
              • Lists
              print cmds.ls(cameras=1)
              >>[u'frontShape', u'perspShape', u'sideShape', u'topShape']
              
              myToys=["yoyo", "cup", "ball", "crayon"] #the names of your objects
              cmds.select(myToys)
              
              firstToy=myToys[1]  #yoyo
              numToys=len(myToys)  #3
              
                • List Comprehensions: These are used to create lists from any iterable object.  The first time I used them was to retrieve the nth column in a matrix stored as vectors.
              myMatrix=[[1,2,3,4],[1,2,3,4],[1,2,3,4]]
              thirdRow=myMatrix[2] #[1,2,3]
              thirdColumn=[x[2] for x in myMatrix] #[3,3,3]
              
              • Tuples: Are similar to list except they cannot be modified, also known as immutable.
              myList=["Hello", 1]
              myList[1]=5 #can change the value
              
              myTuple=("Hello", 1) 
              myTuple[1]=5 #ERROR
              
              • Sets: Sets are GREAT.  They are just like lists but prevent duplicate elements.
              keyLight= cmds.lightlink(light="keyLight", query=1) #return all objects set to receive light from keyLight
              backLight= cmds.lightlink(light="backLight", query=1) #return all objects set to receive light from backLight
              
              lightsList=keyLight+backLight #12 items, lists duplicates
              lightsSet=set(keyLight+backLight) #8 items, returns only unique elements
              
              • Dictionaries: Sometimes referred to as hashes or associative arrays, are used to store data in name, value pairs.
              myCameras=cmds.ls(cameras=1)
              myTextures=cmds.ls(textures=1)
              myScene={'cameras':myCameras, 'textures':myTextures} #myScene stores all the cameras and textures in the scene
              
              print myScene.keys()
              print myScene.values()
              print myScene["cameras"]
              
              Control Flow
              • While Loops: Use extreme caution when using while loops. There is no way to close Maya if you get caught in an infinite loop.
              while x<10:
                  print x
                  x+=1 #make sure to terminate the loop!
              
              • If Statement
              if (myValue==10 or myValue==20) and myValue!=30
                  print myValue
              elif myValue==0:
                  print "Cannot be 0"
              else: #all occurances
                  pass #pass keeps Pythonic syntax, useful as placeholders 
              
              • For Statement
              for x in range(10):
                  print x, someList[x]
              
              for index, eachItem in enumerate(iterableItem):
                  print index, eachItem
              
              • Exceptions
              sphereAttrs=cmds.listAttr('pSphere1')
              for eachAttr in sphereAttrs:
                  print eachAttr+":",
                  try:
                      print cmds.getAttr("pSphere1."+eachAttr)
                  except:
                      print "Cannot Read"
              
              Functions
              def myFunction(arg=None): #defines function myFunction that accepts an argument arg that defaults to None
                  print arg
                  return 1
              myFunction("Hello World") #calls myFunction
              
              Classes
              class newClass():
                  myInt=5 #class variables
                  @classmethod  #class method decorator
                  def getInt(cls): #class method
                      return cls.myInt
                  def __init__(self, arg): #gets automatically called when an object is instantiated
                      self.myString=arg  #self are instance variables, they are unique per object
                  def myFunction(self, arg):
                      print arg, self.myString
              
              myClass =newClass("Hello") #creates a new object from class newClass, objects are instances of a class
              myClass.myFunction("World") #Hello World
              print myClass.myFunction.myString #Hello
              print newClass.myInt #5
              print newClass.getInt() #5
              I hope this will get you all started in the right direction. The vast majority of all your scripts will come from topics discussed here, everything else beyond this cheat sheet will merit a dedicated post. If you have further questions I find it's easiest to just to Google the topic. Even though I am a member of http://www.python-forum.org/pythonforum/ I rarely, if ever have to create a new thread. On the other hand I highly recommend the Maya Programming Forum on http://forums.cgsociety.org/ since Maya specifics sometimes get hazy. Hopefully you are all already members.

              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.

                    Sunday, August 8, 2010

                    Getting Started

                    Lets get started with an into to scripting in Maya. 
                    Start off by opening the script editor: Windows > General > Script Editor
                    You should also always have the API open at the same time:  In the Maya Docs go to Technical Documentation > CommandsPython.  Now, if your new to scripting by thankful your starting off in Maya.  The documentation and interpreter feedback are the best in the business.  90% of Maya's commands are echoed after execution and the API is extremely well documented.  All the commands have examples, and are both searchable and categorized. Luckily, Maya Scripting IS NOT a two bit chapter in a thousand page pdf manual, more on those programs later.

                    You could start off in MEL.  There are plenty of advantages in doing so:
                    • No need to import commands
                    • Automatic sourcing
                    • Maya's feedback is all in MEL 
                    • Unicode support
                    • Maya ASCII is all in MEL
                    • Expressions, Render Options, and many nodes except MEL directly
                    However, whenever possible I will be making my scripts in Python.
                    • Extremely expandable using modules.  NumPy, Django,...
                    • Extensive UI development.  wxPython, PyQT
                    • Compatible with many other CG applications.  Nuke, Houdini, Realflow, XSI, ...
                    • Syntax highlighting/decoration.
                    • Object Oriented.
                    • Easily readable.  NO ; $ ` required.
                     In either the MEL or Python tab type:
                    print "Hello World" 
                    >>Hello World
                    
                    To execute your code it is best to highlight the portion you want to run, then hit Control+Enter.  Maya's interpreter will return Hello World and you have completed your first script.