<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>A Character TD's Random Thoughts...</title>
	<atom:link href="http://www.rtrowbridge.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.rtrowbridge.com/blog</link>
	<description>Learn about rigging, scripting, and problem solving from Ryan Trowbridge</description>
	<pubDate>Sat, 13 Mar 2010 09:09:03 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.2</generator>
	<language>en</language>
			<item>
		<title>GDC</title>
		<link>http://www.rtrowbridge.com/blog/2010/03/13/gdc/</link>
		<comments>http://www.rtrowbridge.com/blog/2010/03/13/gdc/#comments</comments>
		<pubDate>Sat, 13 Mar 2010 09:09:03 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.rtrowbridge.com/blog/?p=422</guid>
		<description><![CDATA[Its been a crazy few days at GDC. I wanted to let everyone know that me and my friend Adam Mechtley put together a video Masterclass on Python for Autodesk&#8217;s Virtual GDC. You will need to get an account with area.autodesk.com and they require you to register separately for the class as well. Its free, [...]]]></description>
			<content:encoded><![CDATA[<p>Its been a crazy few days at GDC. I wanted to let everyone know that me and my friend <a href="http://adammechtley.com/">Adam Mechtley</a> put together a video Masterclass on Python for Autodesk&#8217;s Virtual GDC. You will need to get an account with area.autodesk.com and they require you to register separately for the class as well. Its free, watch it! The class description and link to the video follows:</p>
<p>Class Description:<br />
&#8220;Since the formal introduction of Python into Maya, it has been rapidly gaining ground as the scripting language of choice among technical artists and tools developers. Its host of built-in features and its support for programming with the Maya API allow Python developers to interact with Maya in many exciting ways. In this MasterClass, Adam and Ryan discuss different scenarios that may appear during production and for which Python is ideally suited to provide a quick and flexible solution. Using two example projects, Adam and Ryan will demonstrate practical applications of threading as well as Maya plug-in development.&#8221;</p>
<p><a href="http://area.autodesk.com/gdc/class2">http://area.autodesk.com/gdc/class2</a></p>
<p>Last but not least Uncharted 2 received five awards at the 10th annual Game Developers Choice Awards including the Game of The Year award. More info here:</p>
<p><a href=" http://www.gamasutra.com/view/news/27649/GDC_Uncharted_2_Wins_Big_At_10th_Annual_Game_Developers_Choice_Awards.php"><br />
http://www.gamasutra.com/view/news/27649/GDC_Uncharted_2_Wins_Big_At_10th_Annual_Game_Developers_Choice_Awards.php</a></p>
<p>Cheers,<br />
Ryan</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rtrowbridge.com/blog/2010/03/13/gdc/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Evolve CG Featured Speaker</title>
		<link>http://www.rtrowbridge.com/blog/2010/02/18/evolve-cg-featured-speaker/</link>
		<comments>http://www.rtrowbridge.com/blog/2010/02/18/evolve-cg-featured-speaker/#comments</comments>
		<pubDate>Thu, 18 Feb 2010 19:56:56 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.rtrowbridge.com/blog/?p=414</guid>
		<description><![CDATA[I thought I would let people know that I will be giving a talk on our Character Pipeline at a conference called Evolve CG. Evolve CG&#8217;s main focus is to give students a chance to learn from people in the industry. The conference will be held at the Hilton Marina in Ft. Lauderdale, Florida on [...]]]></description>
			<content:encoded><![CDATA[<p>I thought I would let people know that I will be giving a talk on our Character Pipeline at a conference called Evolve CG. Evolve CG&#8217;s main focus is to give students a chance to learn from people in the industry. The conference will be held at the Hilton Marina in Ft. Lauderdale, Florida on May 15-16.</p>
<p><a href="http://evolve3d.net/feature-speaker-ryan-trowbridge/">http://evolve3d.net/feature-speaker-ryan-trowbridge/</a></p>
<p>Cheers,<br />
Ryan</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rtrowbridge.com/blog/2010/02/18/evolve-cg-featured-speaker/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The __main__ Module</title>
		<link>http://www.rtrowbridge.com/blog/2010/02/10/the-__main__-module/</link>
		<comments>http://www.rtrowbridge.com/blog/2010/02/10/the-__main__-module/#comments</comments>
		<pubDate>Wed, 10 Feb 2010 08:33:35 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Maya Python]]></category>

		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.rtrowbridge.com/blog/?p=409</guid>
		<description><![CDATA[Did you ever wonder what Python does with all those variables and functions you write in the Maya script editor? No? Well I am going to tell you anyway. I recently refered to the Maya Script Editors Python global scope or main namespace as the main module to a friend. He said that I must [...]]]></description>
			<content:encoded><![CDATA[<p>Did you ever wonder what Python does with all those variables and functions you write in the Maya script editor? No? Well I am going to tell you anyway. I recently refered to the Maya Script Editors Python global scope or main namespace as the main module to a friend. He said that I must have been tired and meant something else, but I didnt and here is why.</p>
<p>Type in and execute the following code into your script editor in a Maya Python tab:</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">
print __name__
</pre>
<p></p>
<p>Which will print:</p>
<p>__main__</p>
<p>When you print __name__ in a module it will give you the namespace of the module itself. So why did printing __name__ work inside of the Script Editor? Now write a quick function and execute it in the Script Editor:</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">
def test():
    """this function is a test"""
    print "test"
</pre>
<p></p>
<p>Next type and execute the following line:</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">
help(test)

#Result:
Help on function test in module __main__:

test()
    testing
</pre>
<p></p>
<p><span id="more-409"></span></p>
<p>Ok so your thinking its just calling it module __main__ its not really a real module is it? Try executing the following:</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">
import __main__
dir(__main__)
# Result: ['__builtins__', '__doc__', '__main__', '__name__', '__package__', 'test'] #
</pre>
<p></p>
<p>You can see that by calling dir on the __main__ module that test has been defined inside of the __main__ module. So Python is adding functions that we write and variables on the fly to this __main__ module. If you import a module it will also go into this list.</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">
import math
dir(__main__)
# Result: ['__builtins__', '__doc__', '__main__', '__name__', '__package__', 'math', 'test'] #
</pre>
<p></p>
<p>Every Python program starts with a __main__ module. If we were to make a Python program outside of Maya the first module loaded and executed would become the __main__ module. Some people write a line that states:</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">
if __name__ == "__main__":
    print "do special stuff if your the main module"
</pre>
<p></p>
<p>Python docs state:</p>
<p>http://docs.python.org/library/__main__.html</p>
<p>&#8220;This module represents the (otherwise anonymous) scope in which the interpreter’s main program executes — commands read either from standard input, from a script file, or from an interactive prompt. It is this environment in which the idiomatic “conditional script” stanza causes a script to run:&#8221;</p>
<p>In the end the __main__ module is not an actual file though, but you could call it the main module.</p>
<p>Have fun,<br />
Ryan</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rtrowbridge.com/blog/2010/02/10/the-__main__-module/feed/</wfw:commentRss>
		</item>
		<item>
		<title>U2 GOTY 2009</title>
		<link>http://www.rtrowbridge.com/blog/2010/02/06/u2-goty-2009/</link>
		<comments>http://www.rtrowbridge.com/blog/2010/02/06/u2-goty-2009/#comments</comments>
		<pubDate>Sun, 07 Feb 2010 00:45:20 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://www.rtrowbridge.com/blog/?p=406</guid>
		<description><![CDATA[


This post has nothing to do with Python or anything to do with character rigging. With that warning given I thought I would post something I had made to remember Uncharted 2: Among Thieves. My last project was by far the best project I have ever worked on. So far we have won more awards [...]]]></description>
			<content:encoded><![CDATA[<p><CENTER><br />
<a href="http://www.rtrowbridge.com/blog/wp-content/uploads/2010/02/u2_goty_frame.jpg"><img src="http://www.rtrowbridge.com/blog/wp-content/uploads/2010/02/u2_goty_frame-300x225.jpg" alt="Uncharted2: Game of the Year 2009" title="u2_goty_frame" width="300" height="225" class="size-medium wp-image-407" /></a><br />
</CENTER>
<p></p>
<p>This post has nothing to do with Python or anything to do with character rigging. With that warning given I thought I would post something I had made to remember Uncharted 2: Among Thieves. My last project was by far the best project I have ever worked on. So far we have won more awards than we can count. Last time I looked there were 98 major magazine or online publications that had given us the Game of the Year award for 2009. So to celebrate this I decided to make something to remember the game by.</p>
<p>I had a poster we had on hand signed by all my colleges at ND, then I had a plaque engraved with Uncharted 2:Among Thieves Game of the Year 2009. I had all of these framed in a shadow box style frame. The boarders use the black, red, and white Naughty Dog colors. The shadow box style frame let me put the game cd, box, and plaque to the side of the poster. The frame shop did a great job.</p>
<p>I look forward to shipping our next game,<br />
<B>Ryan</B></p>
]]></content:encoded>
			<wfw:commentRss>http://www.rtrowbridge.com/blog/2010/02/06/u2-goty-2009/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Maya Python UI Example</title>
		<link>http://www.rtrowbridge.com/blog/2010/02/04/maya-python-ui-example/</link>
		<comments>http://www.rtrowbridge.com/blog/2010/02/04/maya-python-ui-example/#comments</comments>
		<pubDate>Thu, 04 Feb 2010 09:16:48 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Maya Python]]></category>

		<category><![CDATA[class]]></category>

		<category><![CDATA[instance]]></category>

		<category><![CDATA[Python]]></category>

		<category><![CDATA[UI]]></category>

		<guid isPermaLink="false">http://www.rtrowbridge.com/blog/?p=401</guid>
		<description><![CDATA[Its been awhile since I posted. Ive been creating a lot of Python UI&#8217;s of late. I have seen others struggle with creating their first UI. There are a few gotchas and the best way to set up a Python UI is different than setting it up with MEL.
A good way to setup your UI [...]]]></description>
			<content:encoded><![CDATA[<p>Its been awhile since I posted. Ive been creating a lot of Python UI&#8217;s of late. I have seen others struggle with creating their first UI. There are a few gotchas and the best way to set up a Python UI is different than setting it up with MEL.</p>
<p>A good way to setup your UI is to encapsulate the UI in a class including the functions you will use with the UI. You dont need all of your functions inside of the class. If you need to work with a function that is external to the class, you can use a partial function. When you set a button command to use a function it is best not to give it a string like you would in MEL. You should pass the functions directly to the command. You should not pass the functions as if you called them however like function() but by just giving it the name. If you need to pass an argument you need to use a partial function so the function does not get called until the user presses the UI item. You should note the UI button command happens to always pass one argument even if you dont pass anything to the function. If you pass your function one argument it will receive two, or if you pass two it will receive three. This is easily remedied by adding an extra unused argument.</p>
<p>I have several personal projects taking up my time right now so I am going to be brief on the how to and what does what part. The following example should help you get started. You can execute it from the script editor and start playing around with it.</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">
import maya.cmds as cmds
from functools import partial

def myfunc(inst=None, thing=None, arg=None):
    print 'arg: ', arg
    print 'inst: ', inst
    print 'thing: ', thing
    data = cmds.button(inst.btnA, query=True, label=True)
    print data

class ui():
    def __init__(self, winName="winTheWindow"):
        self.winTitle = "The Window"
        self.winName = winName

    def create(self):
        if cmds.window(self.winName, exists=True):
            cmds.deleteUI(self.winName)

        cmds.window(self.winName, title=self.winTitle)
        self.mainCol = cmds.columnLayout( adjustableColumn=True )
        self.btnA = cmds.button( label='Press Me - External Func', c=partial(myfunc, self, 'say...') )
        self.btnB = cmds.button( label='Press Me - Internal Func', c=partial(self.a, 'something...') )
        self.btnC = cmds.button( label='Press Me - Internal Func No Args', c=self.b)
        cmds.showWindow( self.winName )
        cmds.window(self.winName, edit=True, widthHeight=[250,75])

    def a(self, myarg=None, arg=None):
        print 'myarg: ', myarg

    def b(self, arg=None):
        print 'buttons require an argument'
        print 'the argument passed in will always be the last argument'

# create the window
inst = ui()
inst.create()
</pre>
</p>
<p>Have fun,<br />
<strong>Ryan</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.rtrowbridge.com/blog/2010/02/04/maya-python-ui-example/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Uncharted 2 - E3 Awards</title>
		<link>http://www.rtrowbridge.com/blog/2009/07/17/uncharted-2-e3-awards/</link>
		<comments>http://www.rtrowbridge.com/blog/2009/07/17/uncharted-2-e3-awards/#comments</comments>
		<pubDate>Fri, 17 Jul 2009 17:09:46 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://www.rtrowbridge.com/blog/?p=399</guid>
		<description><![CDATA[Ive been very busy with Uncharted 2 and projects, but I thought I would post our new trailers and links to all the E3 awards we got.

Uncharted 2 Trailers -
E3 Trailer
Level Walkthrough
Dont Quite Cinematic

Awards -
Game Critics Awards
]]></description>
			<content:encoded><![CDATA[<p>Ive been very busy with Uncharted 2 and projects, but I thought I would post our new trailers and links to all the E3 awards we got.</p>
<p></p>
<p><b>Uncharted 2 Trailers -</b><br />
<A HREF="http://www.gametrailers.com/video/e3-09-uncharted-2/50366">E3 Trailer</A><br />
<A HREF="http://www.gametrailers.com/video/e3-09-uncharted-2/50504">Level Walkthrough</A><br />
<A HREF="http://www.gametrailers.com/video/exclusive-dont-uncharted-2/52546">Dont Quite Cinematic</A></p>
<p><span id="more-399"></span></p>
<p><b>Awards -</b></p>
<p><b>Game Critics Awards</b><br />
<A HREF="http://www.gamecriticsawards.com/winners.html>http://www.gamecriticsawards.com/winners.html</A></p>
<ul>
<li>Best of Show</li>
<li>Best Console Game</li>
<li>Best Action/Adventure Game</li>
</ul>
<p>&#8220;The incredible visuals on display in Uncharted 2 almost overshadow the gameâ€™s tight controls, intricate environments, witty dialogue and interesting characters.&#8221;</p>
<p></p>
<p><b>Go Gaming Giant</b><br />
<A HREF="http://www.gogaminggiant.com/2009/06/my-e3-game-of-the-show/">http://www.gogaminggiant.com/2009/06/my-e3-game-of-the-show/</A></p>
<ul>
<li>Game of the Show</li>
</ul>
<p>&#8220;The storyline of the game, the writing and the characters also all look top-notch, like something out of a Hollywood movie.&#8221;</p>
<p></p>
<p><b>PlatformNation</b><br />
<A HREF="http://www.platformnation.com/2009/06/06/uncharted-2-among-thieves-2009-game-of-e3/">http://www.platformnation.com/2009/06/06/uncharted-2-among-thieves-2009-game-of-e3/</A></p>
<ul>
<li>Best Game of E3</li>
</ul>
<p>&#8220;&#8230;it is the best looking video game this generation.&#8221;</p>
<p></p>
<p><b>G4</b><br />
<A HREF="http://g4tv.com/videos/39019/Best-of-E3-09-Best-of-Show/ ">http://g4tv.com/videos/39019/Best-of-E3-09-Best-of-Show/</A><br />
<A HREF="http://g4tv.com/videos/39016/Best-of-E3-09-PlayStation-3-Game/">http://g4tv.com/videos/39016/Best-of-E3-09-PlayStation-3-Game/</A></p>
<ul>
<li>Best of Show</li>
<li>Best PS3 Game</li>
</ul>
<p>&#8220;It is a summer blockbuster in a nutshell.&#8221;</p>
<p></p>
<p><b>Game Focus</b><br />
<A HREF="http://www.gamefocus.ca/?nav=article&#038;did=429">http://www.gamefocus.ca/?nav=article&#038;did=429</A></p>
<ul>
<li>Best of Show</li>
<li>Best Action/Adventure</li>
<li>Best PS3 Game</li>
</ul>
<p>&#8220;It was a tough call once again bug overall, Uncharted 2 had the most things to show at E3.&#8221;</p>
<p></p>
<p><b>1up</b><br />
<A HREF="http://www.1up.com/do/feature?cId=3174543">http://www.1up.com/do/feature?cId=3174543</A></p>
<ul>
<li>Best of Show</li>
<li>Best PS3 Game</li>
</ul>
<p>&#8220;Nathan Drake&#8217;s new adventure looks prettier, scarier, and more intense than ever.&#8221;</p>
<p></p>
<p><b>Gameblog</b><br />
<A HREF="http://www.gameblog.fr/news_9729_e3-09-les-gameblog-awards-de-l-e3-2009">http://www.gameblog.fr/news_9729_e3-09-les-gameblog-awards-de-l-e3-2009</A></p>
<ul>
<li>Best of Show</li>
<li>Best Action / Adventure game</li>
<li>Best Graphics</li>
<li>Best Sound</li>
</ul>
<p></p>
<p><b>Futureshop</b><br />
<A HREF="http://www.futureshopforums.ca/t5/Tech-Blog/E3-09-Uncharted-2-was-a-Show-Stealer">http://www.futureshopforums.ca/t5/Tech-Blog/E3-09-Uncharted-2-was-a-Show-Stealer/ba-p/155082#A234</A></p>
<ul>
<li>Game of the show</li>
</ul>
<p>&#8220;For those of you who have seen the recent E3 trailer (if you haven&#8217;t, see below) you&#8217;ll probably agree that this game looks absolutely stunning.&#8221;</p>
<p></p>
<p><b>The Totaly Rad Show</b><br />
<A HREF="http://revision3.com/trs/fundane?hp">http://revision3.com/trs/fundane?hp</A></p>
<ul>
<li>game of the show</li>
</ul>
<p>&#8220;Uncharted 2 game of show. It is so awesome, Thee best graphics, thee most exciting gameplay, fun, smart, funny, great story, it is going to be a phenominal game.&#8221;</p>
<p></p>
<p><b>IGN Australia</b><br />
<A HREF="http://xbox360.ign.com/articles/993/993782p2.html">http://xbox360.ign.com/articles/993/993782p2.html</A></p>
<ul>
<li>best game of E3 2009</li>
</ul>
<p>&#8220;Uncharted: Among Thieves is the best game of E3 2009, without question. It is a title of unsurpassed beauty, combining wonderful programming with technical beauty. Uncharted: Among Thieves is so refined on all fronts â€“ single player, multiplayer, cinematically, thematically â€“ that it shames every other game in the action-shooter category.&#8221;</p>
<p></p>
<p><b>Gamespy</b><br />
<A HREF="http://www.gamespy.com/articles/993/993100p1.html">http://www.gamespy.com/articles/993/993100p1.html</A></p>
<ul>
<li>PS3 Game of Show</li>
</ul>
<p>&#8220;Uncharted 2&#8217;s thieving protagonist Drake climbed monolithic structures as a camera panned to show miles and miles of dangerously lush skylines, all before collapsing and sending him into a chaotic series of duck-and-cover firefights. Yet somehow, through all the madness, he was able to keep his cool. It&#8217;s that balance of cockiness and confidence that exudes from every detail of Uncharted 2. The final product is shaping up to be not just a must-have for PS3 owners, but a defining icon of gaming for this generation.&#8221;</p>
<p></p>
<p><b>Crispygamer</b><br />
<A HREF="http://www.crispygamer.com/features/2009-06-11/the-crispy-awards-e3-2009-edition.aspx">http://www.crispygamer.com/features/2009-06-11/the-crispy-awards-e3-2009-edition.aspx</A></p>
<ul>
<li>PS3 Game of Show</li>
</ul>
<p>&#8220;It should have been Kratos&#8217; show. (We picture the old bald-headed bastard somewhere in a hotel room, pulling the wings off flies.) Instead, it&#8217;s Nathan Drake&#8217;s this-freaking-building-is-falling-down-around-meeeee demo that&#8217;s indelibly etched into our admittedly soft brains.&#8221;</p>
<p></p>
<p><b>IGN</b><br />
<A HREF="http://ps3.ign.com/articles/992/992656p1.html">http://ps3.ign.com/articles/992/992656p1.html</A></p>
<ul>
<li>PS3 Best Game of Show</li>
<li>PS3 Best Action Game</li>
<li>PS3 Best Graphics</li>
<li>PS3 Best Multiplayer</li>
<li>Ps3 Best Tech</li>
</ul>
<p>&#8220;The way the characters react to this with the newly-enhanced physics and animation systems makes the game look absolutely incredible, more like a summer blockbuster than your everyday videogame. We cannot wait until this fall to get our hands on it.&#8221;</p>
<p></p>
<p><b>Game Trailers</b><br />
<A HREF="http://www.gametrailers.com/video/best-graphics-best-of-e3/51488">http://www.gametrailers.com/video/best-graphics-best-of-e3/51488</A></p>
<ul>
<li>Best Graphics of E3</li>
<li>Best Third Person Shooter</li>
</ul>
<p><b>Game Spot</b><br />
<A HREF="http://www.gamespot.com/special_feature/e3-2009-editors-choice/">http://www.gamespot.com/special_feature/e3-2009-editors-choice/</A></p>
<ul>
<li>Best PS3 Game</li>
<li>Best Graphics</li>
</ul>
<p>&#8220;The folks at Naughty Dog brought it all to E3 2009. For starters, they showcased a live demo during the Sony press conference that combined an impressive array of gameplay variety, stunning visuals, and mind-bending destruction.&#8221;</p>
<p></p>
<p><b>Gamepro</b><br />
<A HREF="http://www.gamepro.com/article/features/210658/best-of-e3-the-27-best-games/">http://www.gamepro.com/article/features/210658/best-of-e3-the-27-best-games/</A></p>
<ul>
<li>E3 gold award</li>
</ul>
<p>&#8220;In the trailer, the graphics are so damn good you might not be able to tell the difference between real gameplay and the cut scenes.&#8221;</p>
<p></p>
<p>I think they liked it,<br />
Ryan</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rtrowbridge.com/blog/2009/07/17/uncharted-2-e3-awards/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Render Selected Meshes Region</title>
		<link>http://www.rtrowbridge.com/blog/2009/05/22/render-selected-meshes-region/</link>
		<comments>http://www.rtrowbridge.com/blog/2009/05/22/render-selected-meshes-region/#comments</comments>
		<pubDate>Fri, 22 May 2009 10:12:41 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Maya Python API]]></category>

		<category><![CDATA[Python]]></category>

		<category><![CDATA[region]]></category>

		<category><![CDATA[render]]></category>

		<guid isPermaLink="false">http://www.rtrowbridge.com/blog/?p=393</guid>
		<description><![CDATA[I saw a post on www.cgtalk.com where a user wanted to render the selected meshes bounding box as a render region using the current render settings. He gave this example:

I thought this was an interesting challege that the Python API could handle since it can access the M3dView class which lets you test points in [...]]]></description>
			<content:encoded><![CDATA[<p>I saw a post on www.cgtalk.com where a user wanted to render the selected meshes bounding box as a render region using the current render settings. He gave this example:</p>
<p><a href="http://www.rtrowbridge.com/blog/wp-content/uploads/2009/05/bb_example.jpg"><img src="http://www.rtrowbridge.com/blog/wp-content/uploads/2009/05/bb_example.jpg" alt="" title="bb_example" width="500" height="503" class="aligncenter size-full wp-image-395" /></a></p>
<p>I thought this was an interesting challege that the Python API could handle since it can access the M3dView class which lets you test points in the Maya 3d space and get what pixel they are at in the viewport. Here is the finished script, also posted in my downloads section:</p>
<p><A HREF="http://www.rtrowbridge.com/rtRenderSelectedMeshesRegion.zip">rtRenderSelectedMeshesRegion.zip</A></p>
<p>Cheers,<br />
Ryan</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rtrowbridge.com/blog/2009/05/22/render-selected-meshes-region/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Q and A: Unicode and passing buttons commands</title>
		<link>http://www.rtrowbridge.com/blog/2009/05/18/q-and-a-unicode-and-passing-buttons-commands/</link>
		<comments>http://www.rtrowbridge.com/blog/2009/05/18/q-and-a-unicode-and-passing-buttons-commands/#comments</comments>
		<pubDate>Tue, 19 May 2009 05:44:41 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Maya Python]]></category>

		<category><![CDATA[unicode]]></category>

		<guid isPermaLink="false">http://www.rtrowbridge.com/blog/?p=388</guid>
		<description><![CDATA[In response to an e-mail I received I wrote back this response. I figured I would post it.
So I was given this example and asked what the u charter was for in front of each string name returned in the list.


aList = cmds.ls(selection=True)
print aList

>>[u'pSphere1', u'pSphere2', u'pSphere3', u'pSphere4']

The long and the short of it is Unicode [...]]]></description>
			<content:encoded><![CDATA[<p>In response to an e-mail I received I wrote back this response. I figured I would post it.</p>
<p>So I was given this example and asked what the u charter was for in front of each string name returned in the list.</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">

aList = cmds.ls(selection=True)
print aList

>>[u'pSphere1', u'pSphere2', u'pSphere3', u'pSphere4']
</pre>
<p>The long and the short of it is Unicode allows more characters than ASCII. ASCII can hold 256 values and Unicode can hold 65,536 values. This allows computers to support complex languages with many characters. If you want a more complex explanation go here:</p>
<p><A HREF="http://www.amk.ca/python/howto/unicode">http://www.amk.ca/python/howto/unicode</A></p>
<p>Getting back to the example. So the aList returns a list of string names using Python Unicode. Thats what the u stands for. It shouldnt bother you though nor affect anything.</p>
<p>So if you have two spheres in your scene and you run this in the script editor it will return u&#8217;pSphere2&#8242; and u&#8217;pSphere1&#8242; like this:</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">

import maya.cmds as cmds

getlist = cmds.ls(sl=True)
print getlist
>>[u'pSphere2', u'pSphere1']
</pre>
<p><span id="more-388"></span></p>
<p>You should not need to worry about this because Maya automatically converts back to regular strings when you get the items out of the list:</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">

for node in getlist:
    print node
>>pSphere2
>>pSphere1
</pre>
<p>Notice maya converts the string to a normal string when you print each item in the list. Or if you print just one item like this:</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">

print getlist[0]
>>pSphere2
</pre>
<p>You could do this though, even though you shouldn&#8217;t need to do this, unless linux or apple computers work differently. I am not sure.</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">

import maya.cmds as cmds

getlist = cmds.ls(sl=True)
print len(getlist)

for i in range( 0, len(getlist) ):
    getlist[i] = getlist[i].encode("ascii","ignore")

print getlist
>>['pSphere1', 'pSphere2']
</pre>
<p>As for the second question:</p>
<p>&#8220;Is there a way to fit arguments into the command?&#8221;</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">

def fooB (var = 1.0):
cmds.button(command=fooB(var = 9.5) )       	# won't work
cmds.button(command=fooB)                 	# but this will work?
</pre>
<p>The reason the first method wont work is that the button command is getting confused as to what arguments are being passed to it. The second works but the command thinks it is a string not a function. You can make the first work by passing the command a string containing what you are passing it. To further that thought you can pass it other variables as well.</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">

#Example 1

# this works because it is inside of a string so the command
# clearly understands what is passed to it
def fooB (var = 1.0)
cmds.button(command='fooB(var = 9.5)' )

#Example 2

# this works as long as the functions doesnt expect an argument,
# since you are using keyword like var = 1.0 you dont have to pass
# anything to the function
def fooB (var = 1.0)
cmds.button(command='fooB()') 

#Example 3

# this also works but gets much harder to read whats going on
fooA = 9.5
def fooB (var = 1.0)
cmds.button(command=('fooB(var = ' + fooA + ')'), label='something' )
</pre>
<p>In example 3 I surround the multiple strings with brackets ( and ) so that it is clear to the command what is to be passed to it. Think of it like brackets in MEL you are defining a clump of data to be passed to the command. Last thing to note is only strings can be passed to a command so you need to type str(fooA) to cast the 9.5 into a string like this &#8220;9.5&#8243; so it can be added to the &#8216;fooB(var = &#8216; and &#8216;)&#8217; string. Now this is getting more complex to read.</p>
<p>If you get to the point you want to do this, you probably need to start reading data from your UI.<br />
For example you could create a floatField like this:</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">

import maya.cmds as cmds

window = cmds.window()
cmds.columnLayout()
cmds.floatField('myFloatFieldA', minValue=-10, maxValue=10, value=5 )
cmds.showWindow( window )
</pre>
<p>Since I defined the float field with a name &#8216;myFloatFieldA&#8217; you can ask the UI what the value is in your script editor or a function.</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">

cmds.floatField('myFloatFieldA', query=True, value=True )
</pre>
<p>Then instead of using:</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">

fooA = 9.5
def fooB (var = 1.0)
cmds.button(command=('fooB(var = ' + fooA + ')'), label='something' )
</pre>
<p>You can do this:</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">

import maya.cmds as cmds

def fooB ():
	myFloatValue = cmds.floatField('myFloatFieldA', query=True, value=True )
	print myFloatValue

window = cmds.window()
cmds.columnLayout()
cmds.floatField('myFloatFieldA', minValue=-10, maxValue=10, value=5 )
cmds.button(command='fooB()', label='something' )
cmds.showWindow( window )
</pre>
<p>If you press the button it will print the value in the float field.</p>
<p>Cheers,<br />
Ryan</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rtrowbridge.com/blog/2009/05/18/q-and-a-unicode-and-passing-buttons-commands/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Michael B. Comet poseReader converted to Python</title>
		<link>http://www.rtrowbridge.com/blog/2009/04/04/michael-b-comet-posereader-converted-to-python/</link>
		<comments>http://www.rtrowbridge.com/blog/2009/04/04/michael-b-comet-posereader-converted-to-python/#comments</comments>
		<pubDate>Sat, 04 Apr 2009 08:33:07 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Maya Python API]]></category>

		<category><![CDATA[poseReader]]></category>

		<category><![CDATA[Python]]></category>

		<category><![CDATA[Python API]]></category>

		<guid isPermaLink="false">http://www.rtrowbridge.com/blog/?p=379</guid>
		<description><![CDATA[I am finally posting the poseReader plug-in I converted. You can find it in the downloads section here:
http://www.rtrowbridge.com/blog/downloads/
It was originally written by Michael B. Comet so the concept was created by him and he deserves the credit. I converted his C++ code into a Maya Python API plug-in. Hopefully with no bugs, but there very [...]]]></description>
			<content:encoded><![CDATA[<p>I am finally posting the poseReader plug-in I converted. You can find it in the downloads section here:</p>
<p><A HREF="http://www.rtrowbridge.com/blog/downloads/">http://www.rtrowbridge.com/blog/downloads/</A></p>
<p>It was originally written by <a href="http://www.comet-cartoons.com">Michael B. Comet</a> so the concept was created by him and he deserves the credit. I converted his C++ code into a Maya Python API plug-in. Hopefully with no bugs, but there very well could be some still lurking. If you find any feel free to tell me and I will look into fixing them. I think this was a good exercise in converting a plug-in. It helped me with understanding better how to read C++ into Python. Not that I will be doing that often but it is still a good learning experience.</p>
<p>This changes the poseReader from being a plug-in that must be compiled for every version of Maya to a plug-in that will work on any platform and for any version of Maya using Python. That&#8217;s pretty cool I think.</p>
<p>Feel free to pick it apart and learn from it.</p>
<p>Cheers,<br />
RyanT</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rtrowbridge.com/blog/2009/04/04/michael-b-comet-posereader-converted-to-python/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Python API - Compound attribute</title>
		<link>http://www.rtrowbridge.com/blog/2009/03/17/python-api-compound-attribute/</link>
		<comments>http://www.rtrowbridge.com/blog/2009/03/17/python-api-compound-attribute/#comments</comments>
		<pubDate>Wed, 18 Mar 2009 05:35:51 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Maya Python API]]></category>

		<category><![CDATA[API]]></category>

		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.rtrowbridge.com/blog/?p=365</guid>
		<description><![CDATA[I saw a post on www.cgtalk.com requesting an example of how to create a compound attribute on a node. Here is a full working example with a detailed description of how it works following the example:

import maya.OpenMaya as OpenMaya
import maya.OpenMayaMPx as OpenMayaMPx

kcompUtilNodeTypeName = "compoundExampleNode"
kcompUtilNodeClassify = "utility/general"
kcompUtilNodeId = OpenMaya.MTypeId(0x87325)

# define a new matrixUtilNode class derived from [...]]]></description>
			<content:encoded><![CDATA[<p>I saw a post on www.cgtalk.com requesting an example of how to create a compound attribute on a node. Here is a full working example with a detailed description of how it works following the example:</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">
import maya.OpenMaya as OpenMaya
import maya.OpenMayaMPx as OpenMayaMPx

kcompUtilNodeTypeName = "compoundExampleNode"
kcompUtilNodeClassify = "utility/general"
kcompUtilNodeId = OpenMaya.MTypeId(0x87325)

# define a new matrixUtilNode class derived from the MPxNode class
class rtcompUtilNode(OpenMayaMPx.MPxNode):

	# class variables
	compIn = OpenMaya.MObject()
	compOut = OpenMaya.MObject()
	input = OpenMaya.MObject()
	output = OpenMaya.MObject()

	def __init__(self):
		OpenMayaMPx.MPxNode.__init__(self)

	# arguments ( self, MPlug, MDataBlock)
	def compute(self, plug, dataBlock):

		# if these attributes are requested, recompute their values
		if plug == rtcompUtilNode.compOut or plug.parent() == rtcompUtilNode.compOut:

			# get MDataHandle's to attributes
			#
			try:
				input_dataHandle = dataBlock.inputValue( rtcompUtilNode.input )
			except:
				sys.stderr.write( "Failed to get MDataHandle inputValue input" )
				raise
			try:
				output_dataHandle = dataBlock.outputValue( rtcompUtilNode.output )
			except:
				sys.stderr.write( "Failed to get MDataHandle outputValue output" )
				raise

			# get values from dataHandle
			#
			input_value = input_dataHandle.asFloat()

			# set the output
			output_dataHandle.setFloat(input_value)

			# set the plug clean so maya knows it can update
			dataBlock.setClean(plug)

		else:
			return OpenMaya.kUnknownParameter

		return OpenMaya.MStatus.kSuccess

def nodeCreator():

	return OpenMayaMPx.asMPxPtr( rtcompUtilNode() )

# create and initialize the attributes to the node
def nodeInitializer():

	nAttr = OpenMaya.MFnNumericAttribute()
	cAttr = OpenMaya.MFnCompoundAttribute()

	# create input attributes
	#
	rtcompUtilNode.input = nAttr.create("input", "i", OpenMaya.MFnNumericData.kFloat, 0.0)
	nAttr.setWritable(True)
	nAttr.setStorable(True)
	nAttr.setReadable(True)
	nAttr.setKeyable(True)

	rtcompUtilNode.output = nAttr.create("output", "o", OpenMaya.MFnNumericData.kFloat, 0.0)
	nAttr.setWritable(False)
	nAttr.setStorable(False)
	nAttr.setReadable(True)

	# create compound attribute
	#
	rtcompUtilNode.compIn = cAttr.create( "compIn", "ci" )
	cAttr.addChild( rtcompUtilNode.input )

	rtcompUtilNode.compOut = cAttr.create( "compOut", "co" )
	cAttr.addChild( rtcompUtilNode.output )

	# add attribues
	#
	rtcompUtilNode.addAttribute( rtcompUtilNode.compIn )
	rtcompUtilNode.addAttribute( rtcompUtilNode.compOut )

	# Setup which attributes affect each other
	rtcompUtilNode.attributeAffects ( rtcompUtilNode.compIn,  rtcompUtilNode.compOut )

# initialize the script plug-in
def initializePlugin(mobject):
	mplugin = OpenMayaMPx.MFnPlugin(mobject, "Autodesk", "1.0", "Any")
	try:
		mplugin.registerNode( kcompUtilNodeTypeName, kcompUtilNodeId, nodeCreator, nodeInitializer, OpenMayaMPx.MPxNode.kDependNode, kcompUtilNodeClassify)
	except:
		sys.stderr.write( "Failed to register node: %s" % kcompUtilNodeTypeName )
		raise

# uninitialize the script plug-in
def uninitializePlugin(mobject):
	mplugin = OpenMayaMPx.MFnPlugin(mobject)
	try:
		mplugin.deregisterNode( kcompUtilNodeId )
	except:
		sys.stderr.write( "Failed to deregister node: %s" % kcompUtilNodeTypeName )
		raise
</pre>
<p><span id="more-365"></span></p>
<p>First lets get it working before I talk about how the script works. Save this script as a file somewhere on your computer with a .py extension. In maya select the menu Window/Settings and Preferences/Plug-in Manager. Click the browse button in the plug-in manager and select the file that you saved the script as. This will a plug-in called compountAttrExample to the â€œOtherRegisteredPluginsâ€ section of the manager. If you click on the â€œiâ€ icon to the right of it, the plug-in shows the Dependency nodes of that plug-in. This lets you see what the plug-in has created. Now lets create the new node we added.</p>
<p>Open the script editor, and in a python tab run these lines of script:</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">
import maya.cmds as cmds

cmdAttrNode = cmds.createNode(â€™compoundExampleNodeâ€™)
sphere = cmds.polySphere()
cmds.connectAttr( (sphere[1] + â€˜.radiusâ€™), (cmdAttrNode + â€˜.inputâ€™), force=True)
cmds.getAttr( cmdAttrNode + â€˜.outputâ€™)
</pre>
<p>This creates a new compoundExampleNode and a poly sphere. The poly sphere has its radius attribute connected to the input attribute of the compoundExampleNode. Finally we get the attribute value of the output from the compoundExampleNode. If the sphereâ€™s radius changes it will automatically change the output.</p>
<p>Now lets break down the script.</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">
import maya.OpenMaya as OpenMaya
import maya.OpenMayaMPx as OpenMayaMPx

kcompUtilNodeTypeName = "compoundExampleNode"
kcompUtilNodeClassify = "utility/general"
kcompUtilNodeId = OpenMaya.MTypeId(0Ã—87325)
</pre>
<p>First we must import maya.OpenMaya nd maya.OpenMayaMPx. These give us access to the Maya api classes we need for creating the plug-in. Most maya.OpenMaya classes can be used in the script editor in in a general Python script, but maya.OpenMayaMPx classes are specifically used for creating nodes which you must create a plug-in to use.</p>
<p>Next the kcompUtilNodeTypeName defines the name of the plugin node. This is just a variable placed at the top of the script so it is easy to change. The kcompUtilNodeClassify variable allows you to classify your node. If a node is in the utility/general class it will show up in the hypershade under general utilities. You can get the class of any specific Maya node by using</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">
cmds.getClassification( â€˜nodeNameâ€™ )
</pre>
<p>The last variable defines the node id number. Maya needs this to understand which node is which. If your class id is the same as another node it will conflict and your node will not work.</p>
<p>Moving on to the next part we define the nodes class and figure out what we derive from:</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">
class rtcompUtilNode(OpenMayaMPx.MPxNode):
...
</pre>
<p>First we define the class rtcompUtilNode which derives from the class OpenMayaMPx.MPxNode Maya defines what is needed for a non dag node inside of the MPxNode class. If you want to create a node that has a transform you need to derive from another class like MPxLocatorNode for instance.</p>
<p>Next we define the variables of that class.</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">

# class variables
compIn = OpenMaya.MObject()
compOut = OpenMaya.MObject()
input = OpenMaya.MObject()
output = OpenMaya.MObject()
</pre>
<p>You can have general variables you need for doing whatever it is you want to do, but these variables are special. They define OpenMaya.MObject() attributes which is what you will use to create input / output attributes on your node.</p>
<p>Next we move onto compute:</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">
def compute(self, plug, dataBlock):

	# if these attributes are requested, recompute their values
	if plug == rtcompUtilNode.compOut or plug.parent() == rtcompUtilNode.compOut:
</pre>
<p>This function is run anytime an attribute on the node changes. The if plug statement changes to see if the compOut attribute has been requested. Then you know you have the attribute that you want to update.</p>
<p>The last part of the class looks like this:</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">
try:
	input_dataHandle = dataBlock.inputValue( rtcompUtilNode.input )
except:
	sys.stderr.write( "Failed to get MDataHandle inputValue input" )
	raise
try:
	output_dataHandle = dataBlock.outputValue( rtcompUtilNode.output )
except:
	sys.stderr.write( "Failed to get MDataHandle outputValue output" )
	raise

# get values from dataHandle
#
input_value = input_dataHandle.asFloat()

# set the output
output_dataHandle.setFloat(input_value)

# set the plug clean so maya knows it can update
dataBlock.setClean(plug)
</pre>
<p>Here we get the input and output attributes as MDataHandle objects. The MDataHandle class lets you get and set data on a attribute.</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">
input_dataHandle = dataBlock.inputValue( rtcompUtilNode.input )
output_dataHandle = dataBlock.outputValue( rtcompUtilNode.output )
</pre>
<p>Once we have the MDataHandle object we can query the value on the input attribute like this. The MDataHandle class has several ways of querying data. You must use the correct function to work with the type of data you have stored. asFloat() does not work for intâ€™s ect. You would use asInt() for an int. See the documentation on the class for more details.</p>
<p>input_value = input_dataHandle.asFloat()</p>
<p>And our last step is to set the output attribute. First we set the attribute again with a specific function for setting floats that the MDataHandle class has. Then we use setClean(plug) to tell Maya that we updated the attribute and the node is ready.</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">
output_dataHandle.setFloat(input_value)
dataBlock.setClean(plug)
</pre>
<p>Every node needs nodeCreator() function. This simply returns the node that you have setup.</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">
def nodeCreator()
</pre>
<p>The nodeInitializer function is what sets up the nodes attributes. First we start off by defining the types of attributes we want to create.</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">
nAttr = OpenMaya.MFnNumericAttribute()
cAttr = OpenMaya.MFnCompoundAttribute()
</pre>
<p>Next we create some numeric attributes.</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">
rtcompUtilNode.input = nAttr.create("input", "i", OpenMaya.MFnNumericData.kFloat, 0.0)
nAttr.setWritable(True)
nAttr.setStorable(True)
nAttr.setReadable(True)
nAttr.setKeyable(True)

rtcompUtilNode.output = nAttr.create("output", "o", OpenMaya.MFnNumericData.kFloat, 0.0)
nAttr.setWritable(False)
nAttr.setStorable(False)
nAttr.setReadable(True)
</pre>
<p>Then we create two compound attributes. Note we create the compound attribute and then add the attribute that we want to be a child of that compound attribute. Once we add a attribute to a compound attribute we do not add it again.</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">
rtcompUtilNode.compIn = cAttr.create( "compIn", "ci" )
cAttr.addChild( rtcompUtilNode.input )

rtcompUtilNode.compOut = cAttr.create( "compOut", "co" )
cAttr.addChild( rtcompUtilNode.output )
</pre>
<p>Now we add the compound attributes.</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">
rtcompUtilNode.addAttribute( rtcompUtilNode.compIn )
rtcompUtilNode.addAttribute( rtcompUtilNode.compOut )
</pre>
<p>Our last step is we tell Maya that we want the input compound attribute to affect the output. If the input changes it will tell the node to call the compute function. Any attribute inside of the compound attribute will cause compute to be called. Also note it is ok to have many attributes that affect many attributes. You can save yourself some trouble though by creating fewer compound attributes to group attributes that are similar.</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">
rtcompUtilNode.attributeAffects ( rtcompUtilNode.compIn, rtcompUtilNode.compOut )
</pre>
<p>Almost done!</p>
<p>Now we need to make it so Maya knows how to create the node and uncreate the node. This is what the node id and name and all the above that we created comes together as a package.</p>
<p>When you call the command createNode Maya calls teh initializePlugin function of this node. This attempts to register this node with the name, id, nodeCreator function, nodeInitializer function, type of maya node, and the class we defined it as. The node</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">
def initializePlugin(mobject):
	mplugin = OpenMayaMPx.MFnPlugin(mobject, "Autodesk", "1.0", "Any")
	try:
		mplugin.registerNode( kcompUtilNodeTypeName, kcompUtilNodeId, nodeCreator, nodeInitializer, OpenMayaMPx.MPxNode.kDependNode, kcompUtilNodeClassify)
	except:
		sys.stderr.write( "Failed to register node: %s" % kcompUtilNodeTypeName )
		raise
</pre>
<p>This just does the opposite and removes the node when you delete it from Maya using the node id that it has.</p>
<pre class="alt2" style="border: 2px inset; margin: 0px; padding: 6px; background: #f1e7c0 none repeat scroll 0% 0%; overflow: auto; font-family: ariel roman; width: 475px; height: auto;">
def uninitializePlugin(mobject):
	mplugin = OpenMayaMPx.MFnPlugin(mobject)
	try:
		mplugin.deregisterNode( kcompUtilNodeId )
	except:
		sys.stderr.write( "Failed to deregister node: %s" % kcompUtilNodeTypeName )
		raise
</pre>
<p>
Wow that takes a bit to describe but I hope it helps.<br />
-RyanT</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rtrowbridge.com/blog/2009/03/17/python-api-compound-attribute/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
