Feb 04
I ran into this module and just thought it was cool so I thought I would mention it here. Python has a few modules for working with processing URL’s and using ftp. So you could create a tool that you share with the public and have it read a URL which would allow you to dynamically create start up messages or even tell the user that the tool has been updated. Ahhhh.. that could get scary.
import urllib2
# Open the URL for reading
urlFile = urllib2.urlopen('http://www.rtrowbridge.com/blog/about/')
# Get info abou the URL
urlFile.info()
# Read the URL source code
for line in urlFile:
try:
print line
except:
pass
Cheers,
-RyanT
Feb 03
I found this out the hard way while working on my 4x4MatrixToTRS plugin. So I thought it would be handy to pass along. There are a few bugs with the MTransformationMatrix class when using Python. You can get around them, you just need to know about them to do so. The main bug seems to be that any function of this class that asks for RotationOrder &order will not work with Python. It will always throws an error.
So if you are attempting to get the Euler rotation in a certain order like I was then you need to find a work around. What I found was I just need to use the MTransformationMatrix.rotation() function to get the quaternion then I could use the MQuaternion.asEulerRotation() function and from there I could use the MEulerRotation functions to get what I needed. Here are two examples one that does not work that should and one that does work. I have let Autodesk know about this issue.
If you want to get the rotation value of the MTransformationMatrix class this is the wrong way to do it:
Continue reading »
Feb 03
I have been meaning to post this for some time well here it is finally. Hopefully this plugin is commented well enough to understand. I have included the source so you can tinker with it. I have also included an html file that looks like a traditional Maya Node help file. Which lists all the attributes and what they do.
Since the script is rather long I wont post it here. Please take a look at it and if you have any questions feel free to post or e-mail me.
You can find the new python plugin at my new downloads page.
Have fun!
-RyanT
Jan 12
I saw this anydbm module and thought that it could be handy for storing certain user options. Maya already has a built in optionVar command that Python can use. There are a great many reasons to use optionVar’s. I just wanted to give an example of a built in Python library module that lets you create your own files like the optionVar file.
Note that this module creates binary files so I dont think they are as useful as creating your own asci file since asci is readable. As you can see in the example they are so easy to create and update I could see myself using them at some point.
import anydbm
# Create a new database file, use c - creating | r - reading | w - writing | n - newdatabase
db = anydbm.open('C://databasefile', 'w')
# Add new dictionary keys | values to the file
db['python'] = '1'
db['in'] = '2'
db['maya'] = '3'
# Print the data in the file
# As with all dictionarys in Python this will not print the values in order
# This is because Python is optimising how it stores the values so they can be accessed quickly
for k, v in db.iteritems():
print k, '\t', v
# This will auto overwrite the existing keys | values which makes it easy to update the file
db['python'] = 'is'
db['in'] = 'really'
db['maya'] = 'cool'
# The previous 1 2 3 values no longer exist and now maya will print the new values
for k, v in db.iteritems():
print k, '\t', v
db.close()
# Note: If no path is given files are stored as binary files in your Maya installation dirrectory
# C:\Program Files\Autodesk\Maya_version\bin\
Next on my list to show will be a Python Maya API utility node,
-RyanT
Dec 16
I thought it worth a post on how eval works in Python. Somone posted a question on cgtalk about how they tried to use eval inside of a Python class and they received errors. They tried to test the code by executing the string in the script editor which worked. The problem is that eval is not for executing code it is for executing expressions. Here is some Python code as an example. Just run this in your Maya Python tab.
import maya.mel as mel
import maya.cmds as cmds
# Mel eval test
def meleval():
mel.eval('float $foo = 10;')
meleval()
# switch to the mel tab and type:
print $foo;
# this prints 10
# Switch back to the Python tab
# Now try python eval, which is for expressions
print eval( '1+1' )
# prints 2
# Try to get more complicated with eval though and this happens:
eval( 'foo = 10' )
# Error: ('invalid syntax', ('', 1, 5, 'foo = 10'))
# Traceback (most recent call last):
# File "", line 1, in
# SyntaxError: ('invalid syntax', ('', 1, 5, 'foo = 10')) #
# so what do you use?
def pyexec():
exec( 'foo = 10' )
print foo
pyexec()
# prints 10
# now try to print foo like you did with MEL eval
print foo
# Error: name 'foo' is not defined
# Traceback (most recent call last):
# File "", line 1, in
# NameError: name 'foo' is not defined #
# Now why is this?
# The exec executes in the scope that it is executed in
# You can get around this though:
def pyexecglobal():
exec( 'foo = 5' ) in globals()
exec( 'foob = 5' ) in locals()
print foo
print foob
pyexecglobal()
# Now try:
print foo
# success
print foob
# Error: name 'foob' is not defined
# Traceback (most recent call last):
# File "", line 1, in
# NameError: name 'foob' is not defined #
So exec is what you want.
-RyanT
Dec 16
Just a brief example but say you are doing a task that locks up Maya and you want to get some feedback. Printing to the script editor is not helpful if you are batching files or you have a script that needs to do several tasks before finishing because Maya will not allow you to see the script editor until its finished.
Alternatively to print you can use the MEL trace command which prints to the output window of Maya. This is not a Python command technically and ends up being a bit messy when concatenating strings.
The last method shown I import the sys module and use __stdout__ which mimics C++ cout the most closely.
Another benefit is printing to the Output Window is much faster than printing to the script editor. Printing to the output window can help you debug certain types of scripts easier.
import sys
import maya.mel as mel
import maya.cmds as cmds
dagNodes = cmds.ls( dagObjects=True )
# print nodes in script editor, slow
print "List of nodes in the scene///////////////////////////////////////"
for dag in dagNodes:
print ('Dag Node: ' + dag)
# print nodes in output window, messy
mel.eval('trace "List of nodes in the scene///////////////////////////////////////";')
for dag in dagNodes:
mel.eval('trace (\"' + 'Dag Node: ' + dag + '\");')
# print nodes in output window, using Python sys module
sys.__stdout__.write( 'List of nodes in the scene///////////////////////////////////////\n' )
for dag in dagNodes:
sys.__stdout__.write( 'Dag Node: ' + dag + '\n')
Have fun,
-RyanT
Dec 09
I answered a question about working with meshes using the python API on cgtalk and thought I would go more in depth on it.
First if you have not written anything using the API you need to know where the documentation is. If I tell you about a class and a function in that class you will only know about what I tell you and that is not very helpful. I looked on Autodesks website and found the latest documentation. This is for Maya 2009. Now there are changes between versions but the main reason for pointing you to this version is they reorganized the pages and added some new help. Also since this is how they will look from now on you should get familiar with it. The location of the docs are here:
Python Command
http://download.autodesk.com/us/maya/2009help/CommandsPython/index.html
Python API
http://download.autodesk.com/us/maya/2009help/API/main.html
Maya has two main ways to interact with it, using either Maya Commands or Maya API. Almost any time a MEL command is created it is also available to Python. There are some exceptions though. Autodesk did not make any of the string MEL commands available to Python because those are specifically made for MEL and do not apply to Python which already has a stronger suite of string functions. This also applies to the MEL commands that interact with your system like creating and reading files and printing to them.
Open up the Python API document and click on the Classes tab. This will show you all the classes available to you with C++ and Python. By default this tab shows the Alphabetical List. With this form of the documentation you also get the “Class List” tab which shows short descriptions of each class.
Today I will show how to get some information from a mesh. This Python script is using the API but a nice feature about Python is you do not need to create a Plugin to do this. It is fine to do so, but you dont have to like you do with C++. So even if you are writing a C++ plugin you could use Python just to quickly build up an idea of what your going to write just doing it in the script editor. No compiling!
Copy and paste this into a Python tab in your script editor and make sure to have a mesh selected so that it has something to work with:
Continue reading »
Dec 05
We were talking at my work the other day how one could create a MEL command with many arguments without using tokens. So a previous example I gave of MEL in how it compares to Python needs to be updated. While creating this version I have to say it is much more error prone than creating a simple Python object like I show here:
Maya Python vs MEL data storage
It is simply much easier to manage and write more complex data in Python. Regardless here is a MEL test I made to show a more complex and robust version. This is for those who would rather use MEL or are simply curious to see what I am talking about.
Continue reading »
Dec 03
I was thinking today it would be handy to send an e-mail to myself when a tool was done. Guess what its fairly easy to do with Python in Maya and here is an example:
import smtplib
import email.Message
# Create a function to send an e-mail
def pyMail(user='', password='', serverURL=None, sender='', to='', subject='', text=''):
mailfailed = ''
try:
# The Message object helps with formating the e-mail for the server to read
message = email.Message.Message()
message['To'] = to
message['From'] = sender
message['Subject'] = subject
message.set_payload(text)
# Connect to the mailsever
# Also you can specify a specific port like this:
# mailServer = smtplib.SMTP(serverURL, 365)
print 'connecting...',
mailServer = smtplib.SMTP(serverURL)
mailServer.set_debuglevel(1)
# (Transport Layer Security) mode. All SMTP commands that follow will be encrypted.
print 'starting tls...',
try:
mailServer.starttls()
mailServer.ehlo(serverURL)
except: pass
# If you pass a user name and password it will be passed to the mail server
# Note if your server requires auth it will fail without
# If the server does not require auth it will fail if you pass it something
print 'logging in...',
if(user and password):
mailServer.login(user, password)
# It is a requirement to add '\n.\n' to the end of a message
print 'sending...',
mailfailed = mailServer.sendmail(sender, to, message.as_string())
print 'disconnecting...',
try:
mailServer.quit()
except: pass
print 'mail sent.'
except:
print 'Error in sending mail.',
if mailfailed:
print 'failed:', mailfailed # some recipients, but not all of them, failed
# Send an e-mail
pyMail( serverURL = 'mail.server.com',
sender = 'from@address.com',
to = 'to@address.com',
subject = 'hello',
text = 'world',
user = 'user',
password = 'password')
Not to hard ehh? And there is nothing wrong with you creating a python function like this and calling it with MEL if this is all you want from Python.
Happy coding,
-RyanT
Dec 01
Our first teaser trailer for our game has been released. Check it out!
And a bit of info has been released on Game Informer’s website as well.

Recent Comments