Mar 12

I saw this screenshot which shows how the muscles flex on Fight Nighty Round 4 and I had to post something. The character TD’s working on Fight Night Round 4 deserve a pat on the back for their great work. Check out this screenshot from their game which was recently posted on www.ign.com

By the way I will be posting new Python examples soon. We have been really busy at work and I have not had the time to do any updates.

For those that have used Michael Comet’s Pose Reader I converted it to Python and will be posting that soon. His Pose Reader is a great way for driving muscles in the way these guys are showing above. The Pose Reader he wrote allows you to basicly take a snapshot of where a transform currently is. Then you can adjust a cone to check how close the specified transform is to the snapshot. The closer it is the closer the value changes from 0 to 1. You can use this value to drive whatever you need. Its really cool and very useful.

I have not used his Pose Deformer node for anything but I am working on converting that to Python as well. I will pose a zip with his C++ code and the Python code so people can learn from it.

Later,
RyanT

Feb 24

I saw users on www.cgtalk.com talking about this and I thought I would post it to show how Python is bridging the gap not only between MEL and the C++ API in Maya. But Python is bridging the gap between software as well.

Here are the steps to make Python work in 3ds Max.

# Step 1: Download Python Version x.x any version at http://www.python.org/download/
# Step 2: Download and install pywin32 which has the win32com python module in it here: http://sourceforge.net/projects/pywin32/
# Step 3: Make sure to download the win32com for the python version you have downloaded
# Step 4: Open up the Python IDLE Shell and select File\New Window
# Step 5: Copy and paste this code, written by David Mackenzie and posted on cgtalk.com:

Continue reading »

Feb 15

Someone sent me an e-mail trying to understand more about how to read the Maya API docs. Since they are written for C++ users it can be hard to understand them unless you understand a little more about C++. So below is my rather long winded answer. The only way you would completely understand this would be to read a C++ book but I think this gives most people a basic enough understanding that they can at least know what functions they can use, what to pass to those functions, and what to expect after doing that.

First off you find the Maya API documentation here:

http://download.autodesk.com/us/maya/2009help/API/classes.html

So lets say you are using this function:

MStatus MItMeshPolygon::getConnectedEdges ( MIntArray &edges )

Which you can find in the class:

MItMeshPolygon.

Continue reading »

Feb 13

I was curious if it was possible to overload the [] operators twice in a row to imitate a matrix while still using a single array. Someone gave me an example to go off of and here is a working example of how to make a flatMatrix class in python.

Try this in the Python script tab in Maya:

class SubItem:

	def __init__(self, parent, idx):
		self.parent = parent
		self.idx = idx

	def __repr__(self):
		return repr(self.parent.data[self.idx])

	def __setitem__(self, subIdx, item):
		index = (self.idx * self.parent.col) + subIdx
		self.parent.data[index] = item

	def __getitem__(self, subIdx):
		index = (self.idx * self.parent.col) + subIdx
		return self.parent.data[index]

class flatMatrix:
	def __init__(self, data):
		self.data = data
		self.col = 4

	def __setitem__(self, key, item):
		return SubItem(self, key, item) 

	def __getitem__(self, idx):
		return SubItem(self, idx)

A = flatMatrix([0,1,2,3,
		4,5,6,7,
		8,9,10,11,
		12,13,14,15])

print A[0][0]

A[0][0] = 50

print A[0][0]

I think its kind of cool. Not so sure I dig how complex it is to read though.
-RyanT

Feb 10

I have been converting a C++ plugin to Python and I came across some C++ code that I was unsure how to convert to Python. I needed to overload several operators like +, -, <<, and [] so how does one go about this? First thing which is always best is to find the python.org help docs.

http://www.python.org/doc/2.5.2/ref/numeric-types.html

Unfortunately they dont have any good examples so I went searching for more. And here is an example I compiled after my search concluded. The lambda function might seem a bit confusing at first but it simply defines two variables ( in this case ) then it runs an expression and at the end of it, it defines what those variables are. The map() function is even more simple. map() can run a function on a list. For example:

#map() example
def add_one(a):
	return (a+1)

foo = [1,2,3,4]
foobar = map(add_one, foo)
print foobar
>>[2, 3, 4, 5]

lambda is special in that it is a function and operates on lists so its allowed to be inside of map()

#lambda example
foo = [1,2,3,4]
bar = [1,2,3,4]
foobar = lambda x, y: x + y, foo, bar
print foobar
( at 0x0000000017A9BEB8>, [1, 2, 3, 4], [1, 2, 3, 4])

And last here is the overload operators example:

Continue reading »

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 4×4MatrixToTRS 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