<?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"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Stumbling Toward &#039;Awesomeness&#039;</title>
	<atom:link href="http://www.chrisevans3d.com/pub_blog/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.chrisevans3d.com/pub_blog</link>
	<description>A Technical Art Blog</description>
	<lastBuildDate>Sun, 09 Jun 2013 23:59:05 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>WordPress Malware Massacre</title>
		<link>http://www.chrisevans3d.com/pub_blog/?p=907</link>
		<comments>http://www.chrisevans3d.com/pub_blog/?p=907#comments</comments>
		<pubDate>Sun, 09 Jun 2013 23:56:06 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[chmod]]></category>
		<category><![CDATA[code injection]]></category>
		<category><![CDATA[hacked]]></category>
		<category><![CDATA[malware]]></category>
		<category><![CDATA[permissions]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[spam]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.chrisevans3d.com/pub_blog/?p=907</guid>
		<description><![CDATA[Some of my friends alerted me to my site being listed in the google malware database a week ago, but I was focusing on E3 and hadn&#8217;t had time to look into it. As it turns out, a vulnerability in a wordpress theme that I didn&#8217;t even have active allowed a virus to completely hose [...]]]></description>
				<content:encoded><![CDATA[<p style="text-align: center;"><a href="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2013/06/army_of_darkness_02.jpg"><img class="aligncenter  wp-image-909" alt="army_of_darkness_02" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2013/06/army_of_darkness_02.jpg" width="600" height="400" /></a></p>
<p>Some of my friends alerted me to my site being listed in the google malware database a week ago, but I was focusing on E3 and hadn&#8217;t had time to look into it. As it turns out, a vulnerability in a wordpress theme that I didn&#8217;t even have active allowed a virus to completely hose all sites on my co-located server with spam and random shit.</p>
<p>I wrote a quick python script [<a href="http://chrisevans3d.com/files/dirTools.rar">dirTools.py</a>] that looks over all files and directories on linux and reports the following:</p>
<ul>
<li>Html infested with twitter iFrame code injection</li>
<li>Malicious PHP, and code injected into existing PHP that eval&#8217;s strings obfuscated in
<ul>
<li>base_64</li>
<li>gzip</li>
<li>rot13</li>
</ul>
</li>
<li>.htaccess files that change mod_rewrite.c to re-direct your users to bogus sites and internal php files</li>
<li>Files with permissions set greater than 664 and folders greater than 755</li>
<li>Hidden directories</li>
</ul>
<p>I wrote this this afternoon and it&#8217;s focused on only this specific wordpress malware, it&#8217;s just basically some example code that warns of the above, and has two methods to remove PHP and HTML code injections.  Feel free to ask me questions, use at your own risk, by default the fixer methods are commented out, so this only reports issues. With them uncommented; they do make file edits to fix the code injections.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrisevans3d.com/pub_blog/?feed=rss2&#038;p=907</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Object Oriented Python in Maya Pt. 1</title>
		<link>http://www.chrisevans3d.com/pub_blog/?p=862</link>
		<comments>http://www.chrisevans3d.com/pub_blog/?p=862#comments</comments>
		<pubDate>Mon, 11 Feb 2013 00:03:36 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[maya]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[rigging]]></category>
		<category><![CDATA[tutorials]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[classes]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[properties]]></category>

		<guid isPermaLink="false">http://www.chrisevans3d.com/pub_blog/?p=862</guid>
		<description><![CDATA[I have written many tools at different companies, I taught myself, and don&#8217;t have a CS degree. I enjoy shot-sculpting, skinning, and have been known to tweak parameters of on-screen visuals for hours; I don&#8217;t consider myself a &#8216;coder&#8217;; still can&#8217;t allocate my own memory.  I feel I haven&#8217;t really used OOP from an architecture [...]]]></description>
				<content:encoded><![CDATA[<p>I have written many tools at different companies, I taught myself, and don&#8217;t have a CS degree. I enjoy shot-sculpting, skinning, and have been known to tweak parameters of on-screen visuals for hours; I don&#8217;t consider myself a &#8216;coder&#8217;;  still can&#8217;t allocate my own memory.  I feel I haven&#8217;t really used OOP from an architecture standpoint. So I bought an <a href="http://www.amazon.com/Python-3-Object-Oriented-Programming/dp/1849511268">OOP book</a>, and set out on a journey of self improvement.</p>
<h2><span style="font-size: 14px;">&#8216;OOP&#8217; In Maya</span></h2>
<p>In Maya, you often use <a href="http://www.google.com/url?sa=t&amp;rct=j&amp;q=&amp;esrc=s&amp;source=web&amp;cd=1&amp;cad=rja&amp;ved=0CC8QFjAA&amp;url=http%3A%2F%2Fdownload.autodesk.com%2Fus%2Fmaya%2F2011help%2Ffiles%2FDependency_graph_plugins_Dependency_Graph_DG_nodes.htm&amp;ei=9M0WUYKwJM3Ksgars4HIAg&amp;usg=AFQjCNE4a-dVv2XNrRH4_vqubYtMPdmNLA&amp;bvm=bv.42080656,d.Yms">DG nodes</a> as &#8216;objects&#8217;. At Crytek we have our own modular nodes that create meta-frameworks encapsulating the character pipeline at multiple levels (characters, characterParts, and rigParts). Without knowing it, we were using <a href="http://en.wikipedia.org/wiki/Object-oriented_analysis_and_design">Object Oriented Analysis</a> when designing our frameworks, and even had some charts that look quite a bit like <a href="http://en.wikipedia.org/wiki/Unified_Modeling_Language">UML</a>. DG node networks are connected often with message nodes, this is akin to a pointer to the object in memory, whereas with a python &#8216;object&#8217; I felt it could always easily lose it&#8217;s mapping to the scene.</p>
<p>It is possible now with the OpenMaya C++ API to store a pointer to the DG node in memory and just request the full dag path any time you want it, also <a href="http://code.google.com/p/pymel/">PyMel</a> objects are Python classes and link to the DG node even when the string name changes.</p>
<h2><span style="font-size: 14px;">&#8220;John is 47 Years Old and 6 Feet Tall&#8221;</span></h2>
<p>Classes always seemed great for times when I had a bunch of data objects, the classic uses are books in a library, or customers: John is 47 years old and likes the color purple. Awesome. However, in Maya, all our data is in nodes already, and those nodes have attributes, those attributes serialize into a Maya file when I save: so I never really felt the need to use classes.</p>
<p>Although, all this &#8216;getting&#8217;, &#8216;setting&#8217; and &#8216;listing&#8217; really grows tiresome, even when you have custom methods to do it fairly easily.</p>
<p>It was difficult to find any really useful examples of OOP with classes in Maya. Most of our code is for &#8216;constructing&#8217;: building a rig, building a window, etc. Code that runs in a linear fashion and does &#8216;stuff&#8217;. There&#8217;s no huge architecture, the architecture is Maya itself.</p>
<h2><span style="font-size: 14px;">Class Warfare</span></h2>
<p>I wanted to package my information in classes and pass that back and forth in a more elegant way <strong>&#8211;at all times, not just while constructing things</strong>. So for classes to be useful to me, I needed them to synchronously exist with DG nodes.</p>
<p>I also <strong>didn&#8217;t want to have to get and set the information</strong> when syncing the classes with DG nodes, that kind of defeats the purpose of Python classes IMO.</p>
<p>Any time I opened a tool I would &#8216;wrap&#8217; DG nodes in classes that harnessed the power of Python and OOP. To do this meant diving into more of the deep end, but since that was what was useful to me, that&#8217;s what I want to talk about here.</p>
<p>To demonstrate, let&#8217;s construct this example:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#the setup</span>
loc <span style="color: #66cc66;">=</span> cmds.<span style="color: black;">spaceLocator</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
cons <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span>cmds.<span style="color: black;">circle</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span> cmds.<span style="color: black;">circle</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#93;</span>
meshes <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span>cmds.<span style="color: black;">sphere</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span> cmds.<span style="color: black;">sphere</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span> cmds.<span style="color: black;">sphere</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#93;</span>
cmds.<span style="color: black;">addAttr</span><span style="color: black;">&#40;</span>loc<span style="color: #66cc66;">,</span> sn<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'controllers'</span><span style="color: #66cc66;">,</span> at<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'message'</span><span style="color: black;">&#41;</span>
cmds.<span style="color: black;">addAttr</span><span style="color: black;">&#40;</span>cons<span style="color: #66cc66;">,</span> sn<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'rigging'</span><span style="color: #66cc66;">,</span> at<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'message'</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">for</span> con <span style="color: #ff7700;font-weight:bold;">in</span> cons: cmds.<span style="color: black;">connectAttr</span><span style="color: black;">&#40;</span>loc<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span> + <span style="color: #483d8b;">'.controllers'</span><span style="color: #66cc66;">,</span> con + <span style="color: #483d8b;">'.rigging'</span><span style="color: black;">&#41;</span>
cmds.<span style="color: black;">addAttr</span><span style="color: black;">&#40;</span>loc<span style="color: #66cc66;">,</span> sn<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'rendermeshes'</span><span style="color: #66cc66;">,</span> at<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'message'</span><span style="color: black;">&#41;</span>
cmds.<span style="color: black;">addAttr</span><span style="color: black;">&#40;</span>meshes<span style="color: #66cc66;">,</span> sn<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'rendermesh'</span><span style="color: #66cc66;">,</span> at<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'message'</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">for</span> mesh <span style="color: #ff7700;font-weight:bold;">in</span> meshes: cmds.<span style="color: black;">connectAttr</span><span style="color: black;">&#40;</span>loc<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span> + <span style="color: #483d8b;">'.rendermeshes'</span><span style="color: #66cc66;">,</span> mesh + <span style="color: #483d8b;">'.rendermesh'</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>So now we have this little node network:</p>
<p><img class="aligncenter size-full wp-image-871" alt="node_network" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2013/02/node_network.png" width="500" height="433" /></p>
<p>Now if I wanted to wrap this network in a class. We are going to use <a href="http://docs.python.org/2/library/functions.html#property">@property</a> to give us the functionality of an attribute, but really a method that runs to return us a value (from the DG node) when the &#8216;attribute&#8217; is queried. I believe using properties is key to harnessing the power of classes in Maya.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> GameThing<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
	<span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> node<span style="color: black;">&#41;</span>:
		<span style="color: #008000;">self</span>.<span style="color: black;">node</span> <span style="color: #66cc66;">=</span> node
&nbsp;
	<span style="color: #808080; font-style: italic;">#controllers</span>
	<span style="color: #66cc66;">@</span><span style="color: #008000;">property</span>
	<span style="color: #ff7700;font-weight:bold;">def</span> controllers<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
		<span style="color: #ff7700;font-weight:bold;">return</span> cmds.<span style="color: black;">listConnections</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">node</span> + <span style="color: #483d8b;">&quot;.controllers&quot;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>So now we can query the &#8216;controllers&#8217; attribute/property, and it returns our controllers:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #dc143c;">test</span> <span style="color: #66cc66;">=</span> GameThing<span style="color: black;">&#40;</span>loc<span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #dc143c;">test</span>.<span style="color: black;">controllers</span>
<span style="color: #808080; font-style: italic;">##&gt;&gt;[u'nurbsCircle2', u'nurbsCircle1']</span></pre></td></tr></table></div>

<p>Next up, we add a setter, which runs code when you set a property &#8216;attribute&#8217;:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> GameThing<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
	<span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> node<span style="color: black;">&#41;</span>:
		<span style="color: #008000;">self</span>.<span style="color: black;">node</span> <span style="color: #66cc66;">=</span> node
&nbsp;
	<span style="color: #808080; font-style: italic;">#controllers</span>
	<span style="color: #66cc66;">@</span><span style="color: #008000;">property</span>
	<span style="color: #ff7700;font-weight:bold;">def</span> controllers<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
		<span style="color: #ff7700;font-weight:bold;">return</span> cmds.<span style="color: black;">listConnections</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">node</span> + <span style="color: #483d8b;">&quot;.controllers&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
	<span style="color: #66cc66;">@</span>controllers.<span style="color: black;">setter</span>
	<span style="color: #ff7700;font-weight:bold;">def</span> controllers<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> cons<span style="color: black;">&#41;</span>:
		<span style="color: #808080; font-style: italic;">#disconnect existing controller connections</span>
		<span style="color: #ff7700;font-weight:bold;">for</span> con <span style="color: #ff7700;font-weight:bold;">in</span> cmds.<span style="color: black;">listConnections</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">node</span> + <span style="color: #483d8b;">'.controllers'</span><span style="color: black;">&#41;</span>:
			cmds.<span style="color: black;">disconnectAttr</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">node</span> + <span style="color: #483d8b;">'.controllers'</span><span style="color: #66cc66;">,</span> con + <span style="color: #483d8b;">'.rigging'</span><span style="color: black;">&#41;</span>
&nbsp;
		<span style="color: #ff7700;font-weight:bold;">for</span> con <span style="color: #ff7700;font-weight:bold;">in</span> cons:
			<span style="color: #ff7700;font-weight:bold;">if</span> cmds.<span style="color: black;">objExists</span><span style="color: black;">&#40;</span>con<span style="color: black;">&#41;</span>:
				<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> cmds.<span style="color: black;">attributeQuery</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'rigging'</span><span style="color: #66cc66;">,</span> n<span style="color: #66cc66;">=</span>con<span style="color: #66cc66;">,</span> ex<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>:
					cmds.<span style="color: black;">addAttr</span><span style="color: black;">&#40;</span>con<span style="color: #66cc66;">,</span> longName<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'rigging'</span><span style="color: #66cc66;">,</span> attributeType<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'message'</span><span style="color: #66cc66;">,</span> s<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
				cmds.<span style="color: black;">connectAttr</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">node</span> + <span style="color: #483d8b;">'.controllers'</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: black;">&#40;</span>con + <span style="color: #483d8b;">'.rigging'</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> f<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
			<span style="color: #ff7700;font-weight:bold;">else</span>:
				cmds.<span style="color: black;">error</span><span style="color: black;">&#40;</span>con + <span style="color: #483d8b;">' does not exist!'</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>So now when we set the &#8216;controllers&#8217; attribute/property, it runs a method that blows away all current message connections and adds new ones connecting your cons:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #dc143c;">test</span> <span style="color: #66cc66;">=</span> GameThing<span style="color: black;">&#40;</span>loc<span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #dc143c;">test</span>.<span style="color: black;">controllers</span>
<span style="color: #808080; font-style: italic;">##&gt;&gt;[u'nurbsCircle2', u'nurbsCircle1']</span>
<span style="color: #dc143c;">test</span>.<span style="color: black;">controllers</span> <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span>cmds.<span style="color: black;">nurbsSquare</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#93;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #dc143c;">test</span>.<span style="color: black;">controllers</span>
<span style="color: #808080; font-style: italic;">##&gt;&gt;[u'nurbsSquare1']</span></pre></td></tr></table></div>

<p>To me, something like properties makes classes infinitely more useful in Maya. For a short time we tried to engineer a DG node at Crytek that when an attr changed, could eval a string with a similar name on the node. This is essentially what a property can do, and it&#8217;s pretty powerful. Take a moment to look through code of some of the real &#8216;heavy lifters&#8217; in the field, like <a href="http://code.google.com/p/zootoolbox/source/browse/skeletonPart_arm.py">zooToolBox</a>, and you&#8217;ll see @property all over the place.</p>
<p>I hope you found this as useful as I would have.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrisevans3d.com/pub_blog/?feed=rss2&#038;p=862</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Raucous Ball of Noise</title>
		<link>http://www.chrisevans3d.com/pub_blog/?p=841</link>
		<comments>http://www.chrisevans3d.com/pub_blog/?p=841#comments</comments>
		<pubDate>Wed, 09 Jan 2013 01:42:22 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[work]]></category>
		<category><![CDATA[communication]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[time management]]></category>

		<guid isPermaLink="false">http://www.chrisevans3d.com/pub_blog/?p=841</guid>
		<description><![CDATA[I can&#8217;t remember the last time I had a new year&#8217;s resolution. But this year I decided to go for it. A friend and I were joking that we increasingly feel like Producers: how we spend a large chunk of our time just making sure that things are moving. That a meeting has action items, [...]]]></description>
				<content:encoded><![CDATA[<p style="text-align: center;"><img class="aligncenter size-full wp-image-844" alt="email_overload" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2013/01/email_overload.png" width="300" height="255" /></p>
<p>I can&#8217;t remember the last time I had a new year&#8217;s resolution. But this year I decided to go for it.</p>
<p>A friend and I were joking that we increasingly feel like Producers: how we spend a large chunk of our time just making sure that things are moving. That a meeting has action items, or minutes. That tasks are scoped, their dependencies tracked, have resources assigned, or have dates on a calendar. That a process has proper gates to allow for course correction, etc. I now spend a majority of my time writing emails, attending meetings, or talking at desks.</p>
<h2><span style="font-size: 14px;">Death by Mail</span></h2>
<p>But what is crippling is the emails. I feel I have made a career out of always trying to be helpful, but I was surprised how easily I reply to anything someone sends me. And how willing people are to just &#8216;go hunting with a shotgun&#8217; and mail 15 others instead of trying to have a discussion with the right person. Many of the mails I saw myself spending time on were threads involving many people and important topics, <em>I felt the need to be involved</em>, but we rarely seemed to come to solid decisions -just running commentary. These mails often had more than 10 people added in CC &#8216;for awareness&#8217;, but then those people feel the need to contribute their opinion in some way.</p>
<p>It turned the simplest discussion a raucous ball of noise, which often then required the creation of a meeting to make a decision on how to progress.</p>
<p>The meetings were more successful, I think in part to the fact that only the people who needed to be involved in the decision were invited. Unfortunately, I had often spent time on the mail thread to avoid the need for a meeting, only to find myself reiterating my sentiments in a meeting the next day.</p>
<p>I looked for a day where I wrote the least number of mails, the number was ~35, and it was a recent sick day when I had stayed home.</p>
<h2><span style="font-size: 14px;">Small Adjustment, Big Victory</span></h2>
<p>So I decided to pull myself out of this, after all it is somewhat self-induced. Of all the options, the best seemed to limit myself to 10 work emails a day. All other communication would be in person, in meetings, or on the phone.</p>
<p>I didn&#8217;t think this would have the impact it did.</p>
<p>From this, other things started to fall in place. I really disliked how I would increasingly feel like standard operating procedure was constantly looking for dropped balls. I need to let dependencies and other departments drop their balls, and hope that they will learn from it, or hope that someone else is watching. In essence, trust people more, and as a by product: spend more time being a Director and less a Producer.</p>
<p>10 emails a day forced me to really choose what email discussions I want to be involved with carefully. I was not respecting my own time, and this arbitrary rule forced me to do that. As a result, it allows me to spend more time on Art Technology initiatives, looking at the project, talking with my team, and giving proper direction.</p>
<p>I can&#8217;t reject meeting invites, or ignore mails, but this little adjustment has really helped me more than I thought it would.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrisevans3d.com/pub_blog/?feed=rss2&#038;p=841</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Abusing &#8216;Blind Data&#8217; in Maya</title>
		<link>http://www.chrisevans3d.com/pub_blog/?p=807</link>
		<comments>http://www.chrisevans3d.com/pub_blog/?p=807#comments</comments>
		<pubDate>Mon, 07 Jan 2013 02:04:44 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[maya]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[rigging]]></category>
		<category><![CDATA[blind data]]></category>
		<category><![CDATA[skinning]]></category>
		<category><![CDATA[slow]]></category>

		<guid isPermaLink="false">http://www.chrisevans3d.com/pub_blog/?p=807</guid>
		<description><![CDATA[&#8216;Blind data&#8217; is custom data that you can store on any object or its components (vertex, edge, polygon, etc). The documentation says &#8216;Blind data is information stored with polygons which is not used by Maya in any way..&#8217; I believe it is used when importing meshes from other apps that have properties that do not [...]]]></description>
				<content:encoded><![CDATA[<p style="text-align: center;"><img class="aligncenter size-full" title="blindDataHeader" alt="" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2013/01/blindDataHeader.jpg" width="500" height="195" /></p>
<p>&#8216;Blind data&#8217; is custom data that you can store on any object or its components (vertex, edge, polygon, etc). The documentation says &#8216;Blind data is information stored with polygons which is<em> not used </em>by Maya in any way..&#8217; I believe it is used when importing meshes from other apps that have properties that do not map to Maya, so that when you take them back to those apps, those properties remain.</p>
<p>Anyway, the important point here is that blind data is metadata (int, float, double, boolean, string, binary) that you can attach to <em>any component</em>. It matters not what happens to said component, you can extract a polygon from a mesh, <span style="color: #993300;">it&#8217;s index will have changed, it&#8217;s object will have changed, but its blind data will remain with it</span><span style="color: #993300;">.</span> The only drawback can be that it can be painfully slow to write this data, but we will get to that later.</p>
<h2><span style="font-size: 18px;">Simple Example</span></h2>
<p>First let&#8217;s create a blind data template, this is required to store the data later. We use the command &#8216;blindDataType&#8217; to create a template for a string type called &#8216;skinningInfo&#8217; or &#8216;skin&#8217; for short, giving it an ID 12344. Then we query the ID and it returns the blind data attribs we have created.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">cmds.<span style="color: black;">blindDataType</span><span style="color: black;">&#40;</span><span style="color: #008000;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff4500;">12344</span><span style="color: #66cc66;">,</span> dt<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'string'</span><span style="color: #66cc66;">,</span> ldn<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'skinningInfo'</span><span style="color: #66cc66;">,</span> sdn<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'skin'</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> cmds.<span style="color: black;">blindDataType</span><span style="color: black;">&#40;</span><span style="color: #008000;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff4500;">12344</span><span style="color: #66cc66;">,</span> tn<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> q<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'skinningInfo'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'skin'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'string'</span><span style="color: black;">&#93;</span></pre></td></tr></table></div>

<p>So now we have our template, let&#8217;s try using it, this is more focused on getting the idea across than speed:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#query vertex # of mesh</span>
v <span style="color: #66cc66;">=</span> cmds.<span style="color: black;">polyEvaluate</span><span style="color: black;">&#40;</span>node<span style="color: #66cc66;">,</span> v<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
<span style="color: #808080; font-style: italic;">#loop through vertices</span>
<span style="color: #ff7700;font-weight:bold;">for</span> vtx <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span> v<span style="color: black;">&#41;</span>:
    <span style="color: #808080; font-style: italic;">#get influences</span>
    infs <span style="color: #66cc66;">=</span> cmds.<span style="color: black;">skinCluster</span><span style="color: black;">&#40;</span>sc<span style="color: #66cc66;">,</span> inf<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> q<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
    <span style="color: #808080; font-style: italic;">#get weights</span>
    objVtx <span style="color: #66cc66;">=</span> node + <span style="color: #483d8b;">&quot;.vtx[&quot;</span> + <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>vtx<span style="color: black;">&#41;</span> + <span style="color: #483d8b;">&quot;]&quot;</span>
    vals <span style="color: #66cc66;">=</span> cmds.<span style="color: black;">skinPercent</span><span style="color: black;">&#40;</span>sc<span style="color: #66cc66;">,</span> objVtx<span style="color: #66cc66;">,</span> q<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> v<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
    <span style="color: #808080; font-style: italic;">#build dict of influence:weight</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>infs<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>:
        weightDict<span style="color: black;">&#91;</span>infs<span style="color: black;">&#91;</span>i<span style="color: black;">&#93;</span><span style="color: black;">&#93;</span> <span style="color: #66cc66;">=</span> vals<span style="color: black;">&#91;</span>i<span style="color: black;">&#93;</span>
    <span style="color: #808080; font-style: italic;">#write value to blind data</span>
 cmds.<span style="color: black;">polyBlindData</span><span style="color: black;">&#40;</span>objVtx<span style="color: #66cc66;">,</span> <span style="color: #008000;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff4500;">12344</span><span style="color: #66cc66;">,</span> at<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'vertex'</span><span style="color: #66cc66;">,</span> ldn<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'skinningInfo'</span><span style="color: #66cc66;">,</span> sd<span style="color: #66cc66;">=</span><span style="color: #008000;">str</span><span style="color: black;">&#40;</span>weightDict<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>So here you have saved a dictionary per vertex that has key/value pairs of influence/weight. You can query like so:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#I have a vertex selected in component mode</span>
<span style="color: #ff7700;font-weight:bold;">print</span> cmds.<span style="color: black;">polyQueryBlindData</span><span style="color: black;">&#40;</span>cmds.<span style="color: black;">ls</span><span style="color: black;">&#40;</span>sl<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff4500;">12344</span><span style="color: #66cc66;">,</span> showComp<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#91;</span><span style="color: #483d8b;">'polySurface2.vtx[64].skin'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">&quot;{u'joint2': 0.49755714634259796, 'joint3': 0.49755714634259784, 'joint1': 0.0048857073148042395}&quot;</span><span style="color: black;">&#93;</span></pre></td></tr></table></div>

<h2><span style="font-size: 18px;">Now On To Something More Useful</span></h2>
<p>So let&#8217;s create a function to store skinning data per-vertex, as you may have seen with the above, that was painfully slow. If you have written any skinning tools, you know that the solution to this (other than learning C++) is to apply your change to all vertices at once. Below we build two lists, one of vertices and one of weights, then we</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> storeBlindSkinning<span style="color: black;">&#40;</span>mesh<span style="color: #66cc66;">,</span> sc<span style="color: black;">&#41;</span>:
	<span style="color: #483d8b;">'''
	mesh is a skinned mesh, and sc is the skincluster affecting the mesh
	'''</span>
	vtxList <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
	v <span style="color: #66cc66;">=</span> cmds.<span style="color: black;">polyEvaluate</span><span style="color: black;">&#40;</span>mesh<span style="color: #66cc66;">,</span> v<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
	infs <span style="color: #66cc66;">=</span> cmds.<span style="color: black;">skinCluster</span><span style="color: black;">&#40;</span>sc<span style="color: #66cc66;">,</span> inf<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> q<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
	vtxWeights <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
	<span style="color: #ff7700;font-weight:bold;">for</span> vtx <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span> v<span style="color: black;">&#41;</span>:
	    objVtx <span style="color: #66cc66;">=</span> mesh + <span style="color: #483d8b;">&quot;.vtx[&quot;</span> + <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>vtx<span style="color: black;">&#41;</span> + <span style="color: #483d8b;">&quot;]&quot;</span>
	    vtxList.<span style="color: black;">append</span><span style="color: black;">&#40;</span>objVtx<span style="color: black;">&#41;</span>
	    vals <span style="color: #66cc66;">=</span> cmds.<span style="color: black;">skinPercent</span><span style="color: black;">&#40;</span>sc<span style="color: #66cc66;">,</span> objVtx<span style="color: #66cc66;">,</span> q<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> v<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
	    <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>infs<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>:
        	weightDict<span style="color: black;">&#91;</span>infs<span style="color: black;">&#91;</span>i<span style="color: black;">&#93;</span><span style="color: black;">&#93;</span> <span style="color: #66cc66;">=</span> vals<span style="color: black;">&#91;</span>i<span style="color: black;">&#93;</span>
            vtxWeights.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: #008000;">str</span><span style="color: black;">&#40;</span>weightDict<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        cmds.<span style="color: black;">polyBlindData</span><span style="color: black;">&#40;</span>vtxList<span style="color: #66cc66;">,</span> <span style="color: #008000;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff4500;">12344</span><span style="color: #66cc66;">,</span> at<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'vertex'</span><span style="color: #66cc66;">,</span> ldn<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'skinningInfo'</span><span style="color: #66cc66;">,</span> sd<span style="color: #66cc66;">=</span>vtxWeights<span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Setting all the data at once is 1/3 faster, however, setting this data takes quite some time, and you may want to take a hit for a progress bar. (break it up into groups) On ~60,000 vertices this took 10min (15min doing it inside the loop). I don&#8217;t mind that hit if it means that I can now detach/alter/slice my mesh without losing skinning data. You can even extract faces and the new vertices created will get the same blind data as their original. (one becomes two)</p>
<p>As always, the C++ API is much faster, my colleague, Bogdan speed tested the above function and <span style="color: #993300;">50,000 vertices took only a few milliseconds, compared to 10 minutes in pythonland.</span></p>
<p>Remember, there are other ways to store skinning data, using UVs, position, vertex color channels, etc. I just wanted to introduce people to blind data in Maya and show a potential use.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrisevans3d.com/pub_blog/?feed=rss2&#038;p=807</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>My 2012 in Review</title>
		<link>http://www.chrisevans3d.com/pub_blog/?p=802</link>
		<comments>http://www.chrisevans3d.com/pub_blog/?p=802#comments</comments>
		<pubDate>Sun, 06 Jan 2013 00:27:50 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[crytek]]></category>
		<category><![CDATA[diving]]></category>
		<category><![CDATA[maya]]></category>
		<category><![CDATA[photography]]></category>

		<guid isPermaLink="false">http://www.chrisevans3d.com/pub_blog/?p=802</guid>
		<description><![CDATA[2012 blew by incredibly fast. If I had to sum the year up into three categories it would be: RYSE / CINEBOX: At Crytek, for the first time ever I broke away from the Crysis franchise and have been working on Ryse with my old friend Hanno Hagedorn, who returned to Crytek this year. In [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2013/01/sin_chrise.jpg"><img class="aligncenter size-full wp-image-803" title="sin_chrise" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2013/01/sin_chrise.jpg" alt="" width="600" height="401" /></a></p>
<p>2012 blew by incredibly fast. If I had to sum the year up into three categories it would be:</p>
<ul>
<li><strong>RYSE / CINEBOX: </strong>At Crytek, for the first time ever I broke away from the Crysis franchise and have been working on Ryse with my old friend <a href="http://www.hannohagedorn.com/" target="_blank">Hanno Hagedorn</a>, who returned to Crytek this year. In my &#8217;20% time&#8217; I am still on CINEBOX, which saw some of it&#8217;s first production use this year on some high profile film and game projects, but I can&#8217;t say much more than that.</li>
</ul>
<ul>
<li><strong>MAYA: </strong>New project, new team, and new software/pipeline! I mentioned this in my SIGGRAPH class, which cleared PR, so no issue mentioning it here: Ryse is the first Maya project at Crytek. In the past year, with the help of Crytek UK, we have been building up a Maya pipeline from scratch. The 3dsMax pipeline was ~10 years old and had a lot of legacy stuff.  Any Maya studio I have worked at always had a legacy pipeline, and I had a mental checklist of things we all would have done differently &#8216;if we could rewrite everything&#8217;. It has been really fun working with the Ryse TechArt team to build this pipeline, we have some really great guys (and gal!), but I won&#8217;t out them here. (to the dismay of recruiters everywhere)</li>
</ul>
<ul>
<li><strong>DIVING:</strong> This year I spent a lot more time in the water! Not only diving, but I stepped up my photography; nothing raises your pulse like a changing lenses out over a 200m dropoff! Colleen and I were lucky enough to get to Indonesia, Malaysia, and Egypt. (<a href="http://www.youtube.com/watch?v=7uMcYOVP8dI" target="_blank">video</a>, <a href="http://www.flickr.com/photos/chris_e/collections/72157601671223942/" target="_blank">photos</a>) We stayed on an old oil rig off Sipadan where we met a group of great photographers, one of which was Sin Hwa, who took that photo of me above.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.chrisevans3d.com/pub_blog/?feed=rss2&#038;p=802</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CINEBOX SIGGRAPH Talk and Studio Workshops</title>
		<link>http://www.chrisevans3d.com/pub_blog/?p=791</link>
		<comments>http://www.chrisevans3d.com/pub_blog/?p=791#comments</comments>
		<pubDate>Mon, 16 Jul 2012 18:06:28 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[cinebox]]></category>
		<category><![CDATA[cryengine]]></category>
		<category><![CDATA[crytek]]></category>
		<category><![CDATA[maya]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[tutorials]]></category>
		<category><![CDATA[siggraph]]></category>

		<guid isPermaLink="false">http://www.chrisevans3d.com/pub_blog/?p=791</guid>
		<description><![CDATA[CRYENGINE CINEBOX I am giving a talk at SIGGRAPH 2012 entitled &#8216;Film/Game Convergence: What&#8217;s Taking So Long?&#8216; where I discuss the inherent differences between games and film and go over a few case studies of projects that attempted to use a game engine for film previs. I also talk a bit about the development of [...]]]></description>
				<content:encoded><![CDATA[<p style="text-align: center;"><img class="aligncenter size-full wp-image-792" title="sigg2012" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2012/07/sigg2012.gif" alt="" width="434" height="132" /></p>
<h2 style="text-align: left;">CRYENGINE CINEBOX</h2>
<p style="text-align: left;">I am giving a talk at SIGGRAPH 2012 entitled &#8216;<a title="Film/Game Convergence: What's Taking So Long?" href="http://s2012.siggraph.org/attendees/sessions/100-149" target="_blank">Film/Game Convergence: What&#8217;s Taking So Long?</a>&#8216; where I discuss the inherent differences between games and film and go over a few case studies of projects that attempted to use a game engine for film previs. I also talk a bit about the development of our <a title="http://mycryengine.com/index.php?conid=59" href="http://mycryengine.com/index.php?conid=59" target="_blank">CINEBOX</a> application, the decisions we had to make, and how we dealt with many of the issues previous attempts have run into.</p>
<h2 style="text-align: left;">STUDIO WORKSHOPS</h2>
<p style="text-align: left;">I will be giving two more Studio Workshops this year, the first is a followup to last year&#8217;s Introduction to Python, entitled &#8216;<a href="http://s2012.siggraph.org/attendees/studio/studio-workshops" target="_blank">Python Scripting in Maya</a>&#8216;. The other workshop is &#8216;<a href="http://s2012.siggraph.org/attendees/studio/studio-workshops" target="_blank">Building a Game Level</a>&#8216;, which is the same basic workshop I gave last year where I show people how to make a playable game level in CryEngine in an hour. Studio Workshops are hands-on sessions where each attendee has a computer and follows along with the instructor. It&#8217;s a great chance for people of all ages to learn new things.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrisevans3d.com/pub_blog/?feed=rss2&#038;p=791</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Not Dead Yet</title>
		<link>http://www.chrisevans3d.com/pub_blog/?p=783</link>
		<comments>http://www.chrisevans3d.com/pub_blog/?p=783#comments</comments>
		<pubDate>Wed, 11 Jul 2012 23:36:15 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[mesh.acsii]]></category>
		<category><![CDATA[xnaLara]]></category>

		<guid isPermaLink="false">http://www.chrisevans3d.com/pub_blog/?p=783</guid>
		<description><![CDATA[I have been really busy on Ryse, this past weekend I found some time to wrap the XNA import methods I had written in a UI.  I will post it soon in an un-padded form for the people asking for it. For those who don&#8217;t know what I am referring to, a while back I [...]]]></description>
				<content:encoded><![CDATA[<div id="attachment_782" class="wp-caption aligncenter" style="width: 610px"><a href="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2012/07/mesh.ascii_.updates.png"><img class="size-large wp-image-782" title="mesh.ascii.updates" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2012/07/mesh.ascii_.updates-1024x467.png" alt="" width="600" /></a><p class="wp-caption-text">Click to Enlarge</p></div>
<p style="text-align: left;">I have been really busy on Ryse, this past weekend I found some time to wrap the XNA import methods I had written in a UI.  I will post it soon in an un-padded form for the people asking for it.</p>
<p style="text-align: left;">For those who don&#8217;t know what I am referring to, a while back I wrote some python to import XNA character files (from retail discs) into Maya as textured characters with original joint names, skinning, etc. I hit some snags on the UV, texturing, and then viewport 2.0 stuff. It&#8217;s really great to see topology, bind pose, weighting, joint layout, etc.. of your favorite characters. Great reference!</p>
<p style="text-align: left;">I would also like to make a post about viewport 2.0 in the next week or so, that whole system is such a complete piece of frustrating garbage, hopefully you can benefit from my aimless bumping into walls in the darkness.  Anyway, gotta start ramping up for SIGGRAPH, so that might have to wait.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrisevans3d.com/pub_blog/?feed=rss2&#038;p=783</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>RigPorn: Halo4 Skeleton and Loco Debug</title>
		<link>http://www.chrisevans3d.com/pub_blog/?p=779</link>
		<comments>http://www.chrisevans3d.com/pub_blog/?p=779#comments</comments>
		<pubDate>Tue, 24 Apr 2012 22:47:04 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[rigporn]]></category>
		<category><![CDATA[343]]></category>
		<category><![CDATA[halo4]]></category>
		<category><![CDATA[locomotion]]></category>
		<category><![CDATA[skeleton]]></category>

		<guid isPermaLink="false">http://www.chrisevans3d.com/pub_blog/?p=779</guid>
		<description><![CDATA[]]></description>
				<content:encoded><![CDATA[<p style="text-align: center;">
<div id="attachment_778" class="wp-caption aligncenter" style="width: 610px"><a href="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2012/04/halo_loco.jpg"><img class="size-large wp-image-778" title="halo_loco" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2012/04/halo_loco-1024x441.jpg" alt="" width="600" /></a><p class="wp-caption-text">Found a screen of 343&#39;s in-game locmotion debug for anyone interested (click to enlarge)</p></div>
]]></content:encoded>
			<wfw:commentRss>http://www.chrisevans3d.com/pub_blog/?feed=rss2&#038;p=779</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Crytek Cinema Sandbox, FMX Talk</title>
		<link>http://www.chrisevans3d.com/pub_blog/?p=771</link>
		<comments>http://www.chrisevans3d.com/pub_blog/?p=771#comments</comments>
		<pubDate>Sat, 21 Apr 2012 10:35:36 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[cinebox]]></category>
		<category><![CDATA[crytek]]></category>
		<category><![CDATA[vfx]]></category>
		<category><![CDATA[work]]></category>
		<category><![CDATA[previs]]></category>
		<category><![CDATA[virtual production]]></category>

		<guid isPermaLink="false">http://www.chrisevans3d.com/pub_blog/?p=771</guid>
		<description><![CDATA[I can finally talk about something I have been working on in the past two years.  One of the reasons I returned to Crytek was to push the use of game engines in linear content creation like film and television. On Avatar I saw how much time and effort went into layout, blocking, virtual sets, [...]]]></description>
				<content:encoded><![CDATA[<p style="text-align: center;"><a href="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2012/04/cinebox.gif"><img class="aligncenter size-full wp-image-772" title="cinebox" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2012/04/cinebox.gif" alt="" width="500" height="212" /></a></p>
<p>I can finally talk about something I have been working on in the past two years.  One of the reasons I returned to Crytek was to push the use of game engines in linear content creation like film and television. On Avatar I saw how much time and effort went into layout, blocking, virtual sets, etc. The tools were archaic, the feedback loop was abysmal at times. In games we have to layout massive levels that people can roam through for 8-15 hours or more and CryEngine&#8217;s tools are some of the best for that.</p>
<p>I have been working as Product Manager with a small team of great guys, where I basically define the goals and backlog. It&#8217;s thrilling to finally get to see things like Catmull-Clark subd in runtime, or multi-channel EXR output, or Alembic support. It&#8217;s been really fun to define what the product is and prioritize features largely without external dependencies or politics, I thank Crytek for trusting me to helm such a project.</p>
<p>We had a live demo kiosk at GDC; check out the <a href="http://mycryengine.com/index.php?conid=59" target="_blank">Cinema Sandbox Website</a> for more info.</p>
<p>I will be speaking at FMX about CineBox and the whole idea of using game engines for previs and virtual production: <a href="http://www.fmx.de/program/event-details/event/495/754/38/754/detail/Event.html" target="_blank">The Long Road to Film / Game Convergence</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrisevans3d.com/pub_blog/?feed=rss2&#038;p=771</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Maya: Walking the Line</title>
		<link>http://www.chrisevans3d.com/pub_blog/?p=762</link>
		<comments>http://www.chrisevans3d.com/pub_blog/?p=762#comments</comments>
		<pubDate>Sat, 21 Apr 2012 09:44:53 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[maya]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[rigging]]></category>
		<category><![CDATA[baking]]></category>
		<category><![CDATA[simulation]]></category>
		<category><![CDATA[timeline]]></category>

		<guid isPermaLink="false">http://www.chrisevans3d.com/pub_blog/?p=762</guid>
		<description><![CDATA[I am still finding my feet in Maya, on my project, some files have grown to 800mb in size. Things get corrupt, hand editing MAs is common; I am really learning some of the internals. In the past week I have had to do a lot of timeline walking to switch coord spaces and get [...]]]></description>
				<content:encoded><![CDATA[<p>I am still finding my feet in Maya, on my project, some files have grown to 800mb in size. Things get corrupt, hand editing MAs is common; I am really learning some of the internals.</p>
<p>In the past week I have had to do a lot of timeline walking to switch coord spaces and get baked animations into and out of hierarchies. In 3dsMax you can do a loop and evaluate a node &#8216;at time i&#8217;, and there is no redraw or anything. I didn&#8217;t know how to do this in Maya.</p>
<p>I previously did this with looping <span style="color: #33cccc;">cmds.currentTime(i)</span> and &#8216;walking the timeline&#8217;, however, you can set the time node directly like so:<span style="color: #3366ff;"> <span style="color: #33cccc;">cmds.setAttr(&#8220;time1.outTime&#8221;, int(i))</span></span></p>
<p><span style="color: #888888;"><strong>Unparenting a child with keyed compensation (1200 frames)</strong></span><br />
10.0299999714 sec &#8211; currentTime<br />
<span style="color: #ff0000;">2.02 sec &#8211; setAttr</span></p>
<p>There are some caveats, whereas in a currentTime loop you can just <span style="color: #33cccc;">cmds.setKeyframe(node)</span>, I now have to <span style="color: #33cccc;">cmds.setKeyframe(node, time=i)</span>.  But when grabbing a matrix, I don&#8217;t need to pass time and it works, I don&#8217;t think you can anyway.. I guess it gets time from the time node.</p>
<h4><strong>Here&#8217;s a sample loop that makes a locator and copies a nodes animation to world space:</strong></h4>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#function feeds in start, end, node</span>
	<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> start: start <span style="color: #66cc66;">=</span> cmds.<span style="color: black;">playbackOptions</span><span style="color: black;">&#40;</span>minTime<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> q<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
	<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> end: end <span style="color: #66cc66;">=</span> cmds.<span style="color: black;">playbackOptions</span><span style="color: black;">&#40;</span>maxTime<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> q<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
	loc <span style="color: #66cc66;">=</span> cmds.<span style="color: black;">spaceLocator</span><span style="color: black;">&#40;</span>name<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'parentAlignHelper'</span><span style="color: black;">&#41;</span>
	<span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span>start<span style="color: #66cc66;">,</span> <span style="color: black;">&#40;</span>end+<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>:
		cmds.<span style="color: black;">setAttr</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;time1.outTime&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>i<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
		matrix <span style="color: #66cc66;">=</span> cmds.<span style="color: black;">xform</span><span style="color: black;">&#40;</span>node<span style="color: #66cc66;">,</span> q<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> ws<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> m<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
		cmds.<span style="color: black;">xform</span><span style="color: black;">&#40;</span>loc<span style="color: #66cc66;">,</span> ws<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> m<span style="color: #66cc66;">=</span>matrix<span style="color: black;">&#41;</span>
		cmds.<span style="color: black;">setKeyframe</span><span style="color: black;">&#40;</span>loc<span style="color: #66cc66;">,</span> <span style="color: #dc143c;">time</span><span style="color: #66cc66;">=</span>i<span style="color: black;">&#41;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://www.chrisevans3d.com/pub_blog/?feed=rss2&#038;p=762</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Quick Note About Range(), Modulus, and Step</title>
		<link>http://www.chrisevans3d.com/pub_blog/?p=754</link>
		<comments>http://www.chrisevans3d.com/pub_blog/?p=754#comments</comments>
		<pubDate>Mon, 24 Oct 2011 23:42:31 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[tutorials]]></category>
		<category><![CDATA[modulus]]></category>
		<category><![CDATA[range]]></category>
		<category><![CDATA[step]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.chrisevans3d.com/pub_blog/?p=754</guid>
		<description><![CDATA[Maybe it&#8217;s me, but I often find myself parsing weird ascii text files from others. Sometimes the authors knew what the data was and there&#8217;s no real markup. Take this joint list for example: 143 # bones root ground -1 0 0 0 root hips 0 0 0.9512207 6E-08 spine 1 1 4E-08 0.9522207 1.4E-07 [...]]]></description>
				<content:encoded><![CDATA[<p>Maybe it&#8217;s me, but I often find myself parsing weird ascii text files from others.  Sometimes the authors knew what the data was and there&#8217;s no real markup. Take this joint list for example:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="text" style="font-family:monospace;">143 # bones
root ground
-1
0 0 0
root hips
0
0 0.9512207 6E-08
spine 1
1
4E-08 0.9522207 1.4E-07
spine 2
2
3E-07 1.0324 8.3E-07
spine 3
3
5.6E-07 1.11357 1.53E-06
spine 4
4
8.2E-07 1.194749 2.22E-06
head neck lower</pre></td></tr></table></div>

<p>So the first line is the number of joints then it begins in three line intervals stating from the root outwards: joint name, parent integer, position. I used to make a pretty obtuse loop using a <a href="http://docs.python.org/reference/expressions.html#binary-arithmetic-operations">modulus operator</a>. Basically, modulus is the remainder left over after division. So X%Y gives you the remainder of X divided by Y; here&#8217;s an example:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">20</span>+<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>:
	<span style="color: #ff7700;font-weight:bold;">if</span> i%<span style="color: #ff4500;">2</span> <span style="color: #66cc66;">==</span> <span style="color: #ff4500;">0</span>: <span style="color: #ff7700;font-weight:bold;">print</span> i
<span style="color: #808080; font-style: italic;">#&gt;&gt; 0</span>
<span style="color: #808080; font-style: italic;">#&gt;&gt; 2</span>
<span style="color: #808080; font-style: italic;">#&gt;&gt; 4</span>
<span style="color: #808080; font-style: italic;">#&gt;&gt; 6</span>
<span style="color: #808080; font-style: italic;">#&gt;&gt; 8</span>
<span style="color: #808080; font-style: italic;">#&gt;&gt; 10</span></pre></td></tr></table></div>

<p>The smart guys out there see where this is goin.. so I never knew <a href="http://docs.python.org/library/functions.html#range">range</a> had a &#8216;step&#8217; argument. (Or I believe I did, I think I actually had this epiphany maybe two years ago, but my memory is that bad.)  So parsing the above is as simple as this:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">jnts <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
<span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span>numJnts*<span style="color: #ff4500;">3</span>+<span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span>:
	jnt <span style="color: #66cc66;">=</span> lines<span style="color: black;">&#91;</span>i<span style="color: black;">&#93;</span>.<span style="color: black;">strip</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
	parent <span style="color: #66cc66;">=</span> <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>lines<span style="color: black;">&#91;</span>i+<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>.<span style="color: black;">strip</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
	posSplit <span style="color: #66cc66;">=</span> lines<span style="color: black;">&#91;</span>i+<span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span>.<span style="color: black;">strip</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">' '</span><span style="color: black;">&#41;</span>
	pos <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span><span style="color: #008000;">float</span><span style="color: black;">&#40;</span>posSplit<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>*jointScale<span style="color: #66cc66;">,</span> \
	<span style="color: #008000;">float</span><span style="color: black;">&#40;</span>posSplit<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>*jointScale<span style="color: #66cc66;">,</span> <span style="color: #008000;">float</span><span style="color: black;">&#40;</span>posSplit<span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>*jointScale<span style="color: black;">&#41;</span>
	jnts.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span>jnt<span style="color: #66cc66;">,</span> parent<span style="color: #66cc66;">,</span> pos<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Thanks to phuuchai on #python (efnet) for nudging me to RTFM!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrisevans3d.com/pub_blog/?feed=rss2&#038;p=754</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>SIGGRAPH 2011: Intro To Python Course</title>
		<link>http://www.chrisevans3d.com/pub_blog/?p=724</link>
		<comments>http://www.chrisevans3d.com/pub_blog/?p=724#comments</comments>
		<pubDate>Wed, 12 Oct 2011 03:12:42 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[tutorials]]></category>
		<category><![CDATA[cookbook]]></category>
		<category><![CDATA[course]]></category>
		<category><![CDATA[example]]></category>
		<category><![CDATA[introduction]]></category>
		<category><![CDATA[siggraph]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.chrisevans3d.com/pub_blog/?p=724</guid>
		<description><![CDATA[I gave a workshop/talk at SIGGRAPH geared toward introducing people to Python. There were ~25 people on PCs following along, and awkwardly enough, many more than that standing and watching. I prefaced my talk with the fact that I am self-taught and by no means an expert. That said, I have created many python tools [...]]]></description>
				<content:encoded><![CDATA[<p>I gave a workshop/talk at SIGGRAPH geared toward introducing people to Python. There were ~25 people on PCs following along, and awkwardly enough, many more than that standing and watching. I prefaced my talk with the fact that I am self-taught and by no means an expert. That said, I have created many python tools people use every day at industry-leading companies.</p>
<p>Starting from zero, in the next hour I aimed to not only introduce them to Python, but get them doing cool, usable things like:</p>
<ul>
<li>Iterating through batches/lists</li>
<li>Reading / writing data to excel files</li>
<li>Wrangling data from one format to another in order to create a &#8216;tag cloud&#8217;</li>
</ul>
<p>Many people have asked for the notes, and I only had rough notes. I love Python, and I work with this stuff every day, so I have had to really go back and flesh out some of what I talked about. This tutorial has a lot less of the general chit-chat and information. I apologize for that.</p>
<h1>Installation / Environment Check</h1>
<hr />Let&#8217;s check to see that you have the tools properly installed. If you open the command prompt and type &#8216;python&#8217; you should see this:</p>
<p><img class="aligncenter size-full wp-image-728" title="env" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2011/10/env1.png" alt="" width="580" height="198" /></p>
<p>So Python is correctly installed, for the following you can either follow along in the cmd window (more difficult) or in IDLE, the IDE that python ships with (easier). This can be found by typing IDLE into the start menu:</p>
<p><img class="aligncenter size-full wp-image-726" title="idle" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2011/10/idle.gif" alt="" width="590" height="225" /></p>
<h1>Variables</h1>
<hr />Variables are pieces of information you store in memory, I will talk a bit about different types of variables.</p>
<h3>Strings</h3>
<p>Strings are pieces of text. I assume you know that, so let&#8217;s just go over some quick things:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #dc143c;">string</span> <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'this is a string'</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #dc143c;">string</span>
<span style="color: #808080; font-style: italic;">#&gt;&gt;this is a string</span>
num <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'3.1415'</span>
<span style="color: #ff7700;font-weight:bold;">print</span> num
<span style="color: #808080; font-style: italic;">#&gt;&gt;3.1415</span></pre></td></tr></table></div>

<p>One thing to keep in mind, the above <em>is a string</em>, not a number. You can see this by:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">print</span> num + <span style="color: #ff4500;">2</span>
<span style="color: #808080; font-style: italic;">#&gt;&gt;Traceback (most recent call last):</span>
<span style="color: #808080; font-style: italic;">#&gt;&gt;  File &quot;basics_variables.py&quot;, line 5, in</span>
<span style="color: #808080; font-style: italic;">#&gt;&gt;    print num + 2</span>
<span style="color: #808080; font-style: italic;">#&gt;&gt;TypeError: cannot concatenate 'str' and 'int' objects</span></pre></td></tr></table></div>

<p>Python is telling you that you cannot add a number to a string of text. It does not know that &#8217;3.1415&#8242; is a number. So let&#8217;s convert it to a number, this is called &#8216;casting&#8217;, we will &#8216;cast&#8217; the string into a float and back:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">float</span><span style="color: black;">&#40;</span>num<span style="color: black;">&#41;</span> + <span style="color: #ff4500;">2</span>
<span style="color: #808080; font-style: italic;">#&gt;&gt;5.1415</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">str</span><span style="color: black;">&#40;</span><span style="color: #008000;">float</span><span style="color: black;">&#40;</span>num<span style="color: black;">&#41;</span> + <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span> + <span style="color: #483d8b;">' addme'</span>
<span style="color: #808080; font-style: italic;">#&gt;&gt;5.1415 addme</span></pre></td></tr></table></div>

<h3>Lists</h3>
<p>Lists are the simplest ways to store pieces of data. Let&#8217;s make one by breaking up a string:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">txt <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'jan tony senta michael brendon phillip jonathon mark'</span>
names <span style="color: #66cc66;">=</span> txt.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">' '</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> names
<span style="color: #808080; font-style: italic;">#&gt;&gt;['jan', 'tony', 'senta', 'michael', 'brendon', 'phillip', 'jonathon', 'mark']</span>
<span style="color: #ff7700;font-weight:bold;">for</span> item <span style="color: #ff7700;font-weight:bold;">in</span> names: <span style="color: #ff7700;font-weight:bold;">print</span> item
<span style="color: #808080; font-style: italic;">#&gt;&gt;jan</span>
<span style="color: #808080; font-style: italic;">#&gt;&gt;tony</span>
<span style="color: #808080; font-style: italic;">#&gt;&gt;senta</span>
<span style="color: #808080; font-style: italic;">#&gt;&gt;michael</span>
...</pre></td></tr></table></div>

<p>Split breaks up a string into pieces. You tell it what to break on, above, I told it to break on spaces txt.split(&#8216; &#8216;). So all the people are stored in a List, which is like an Array or Collection in some other languages.<br />
You can call up the item by it&#8217;s number starting with zero:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">print</span> names<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span> names<span style="color: black;">&#91;</span><span style="color: #ff4500;">5</span><span style="color: black;">&#93;</span>
<span style="color: #808080; font-style: italic;">#&gt;&gt;jan phillip</span></pre></td></tr></table></div>

<p><strong><span style="color: #ff0000;">TIP:</span></strong> [-1] index will return the last item in an array, here&#8217;s a quick way to get a file from a path:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">path <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'D:<span style="color: #000099; font-weight: bold;">\\</span>data<span style="color: #000099; font-weight: bold;">\\</span>dx11_PC_(110)_05_09<span style="color: #000099; font-weight: bold;">\\</span>Tools<span style="color: #000099; font-weight: bold;">\\</span>CryMaxInstaller.exe'</span>
<span style="color: #ff7700;font-weight:bold;">print</span> path.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\\</span>'</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span>-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>
<span style="color: #808080; font-style: italic;">#&gt;&gt;CryMaxInstaller.exe</span></pre></td></tr></table></div>

<h3>Dictionaries</h3>
<p>These store keys, and the keys reference different values. Let&#8217;s make one:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #008000;">dict</span> <span style="color: #66cc66;">=</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">'sascha'</span>:<span style="color: #483d8b;">'tech artist'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'harry'</span>: <span style="color: #ff4500;">142.1</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'sean'</span>:<span style="color: #008000;">False</span><span style="color: black;">&#125;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">dict</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'sean'</span><span style="color: black;">&#93;</span>
<span style="color: #808080; font-style: italic;">#&gt;&gt;False</span></pre></td></tr></table></div>

<p>So this is good, but these are just the keys, we need to know the values. Here&#8217;s another way to do this, using .keys()</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #008000;">dict</span> <span style="color: #66cc66;">=</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">'sascha'</span>:<span style="color: #483d8b;">'tech artist'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'harry'</span>: <span style="color: #ff4500;">142.1</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'sean'</span>:<span style="color: #008000;">False</span><span style="color: black;">&#125;</span>
<span style="color: #ff7700;font-weight:bold;">for</span> key <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">dict</span>.<span style="color: black;">keys</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>: <span style="color: #ff7700;font-weight:bold;">print</span> key<span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'is'</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">dict</span><span style="color: black;">&#91;</span>key<span style="color: black;">&#93;</span>
<span style="color: #808080; font-style: italic;">#&gt;&gt;sean is False</span>
<span style="color: #808080; font-style: italic;">#&gt;&gt;sascha is tech artist</span>
<span style="color: #808080; font-style: italic;">#&gt;&gt;harry is 142.1</span></pre></td></tr></table></div>

<p>So, dictionaries are a good way to store simple relationships of key and value pairs. In case you hadn&#8217;t notices, I used some &#8216;floats&#8217; and &#8216;ints&#8217; above. A float is a number with a decimal, like 3.1415, and an &#8216;int&#8217; is a whole number like 10.</p>
<h1>Creating Methods (Functions)</h1>
<hr />A method or function is like a little tool that you make. These building blocks work together to make your program.</p>
<p>Let&#8217;s say that you have to do something many times, you want to re-use this code and not copy/paste it all over. Let&#8217;s use the example above of names, let&#8217;s make a function that takes a big string of names and returns an ordered list:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> myFunc<span style="color: black;">&#40;</span><span style="color: #008000;">input</span><span style="color: black;">&#41;</span>:
	people <span style="color: #66cc66;">=</span> <span style="color: #008000;">input</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">' '</span><span style="color: black;">&#41;</span>
	people <span style="color: #66cc66;">=</span> <span style="color: #008000;">sorted</span><span style="color: black;">&#40;</span>people<span style="color: black;">&#41;</span>
	<span style="color: #ff7700;font-weight:bold;">return</span> people
txt <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'jan tony senta michael brendon phillip jonathon mark'</span>
orderedList <span style="color: #66cc66;">=</span> myFunc<span style="color: black;">&#40;</span>txt<span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> orderedList
<span style="color: #808080; font-style: italic;">#&gt;&gt;['brendon', 'jan', 'jonathon', 'mark', 'michael', 'phillip', 'senta', 'tony']</span></pre></td></tr></table></div>

<h1>Basic Example: Create A Tag Cloud From an Excel Document</h1>
<hr />So we have an excel sheet, and we want to turn it into a hip ‘tag cloud’ to get people’s attention.<br />
If we go to <a href="http://www.wordle.net/">http://www.wordle.net/</a> you will see that in order to create a tag cloud, we need to feed it the sentences multiple times, and we need to put a tilde in between the words of the sentence. We can automate this with Python!</p>
<p>First, download the excel sheet from me here: [<a href="http://chrisevans3d.com/tutorials/info.csv">info.csv</a>] The CSV filetype is a great way to read/write docs easily that you can give to others, they load in excel easily.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #008000;">file</span> <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'C:<span style="color: #000099; font-weight: bold;">\\</span>Users<span style="color: #000099; font-weight: bold;">\\</span>chris<span style="color: #000099; font-weight: bold;">\\</span>Desktop<span style="color: #000099; font-weight: bold;">\\</span>intro_to_python<span style="color: #000099; font-weight: bold;">\\</span>info.csv'</span>
f <span style="color: #66cc66;">=</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #008000;">file</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'r'</span><span style="color: black;">&#41;</span>
lines <span style="color: #66cc66;">=</span> f.<span style="color: black;">readlines</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
f.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> lines
<span style="color: #808080; font-style: italic;">#&gt;&gt; ['always late to work,13\n', 'does not respect others,1\n', 'does not check work properly,5\n', 'does not plan properly,4\n', 'ignores standards/conventions,3\n']</span></pre></td></tr></table></div>

<p>‘\n’ is a line break character, it means ‘new line’, we want to get rid of that, we also want to just store the items, and how many times they were listed.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #008000;">file</span> <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'C:<span style="color: #000099; font-weight: bold;">\\</span>Users<span style="color: #000099; font-weight: bold;">\\</span>chris<span style="color: #000099; font-weight: bold;">\\</span>Desktop<span style="color: #000099; font-weight: bold;">\\</span>intro_to_python<span style="color: #000099; font-weight: bold;">\\</span>info.csv'</span>
f <span style="color: #66cc66;">=</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #008000;">file</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'r'</span><span style="color: black;">&#41;</span>
lines <span style="color: #66cc66;">=</span> f.<span style="color: black;">readlines</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
f.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">dict</span> <span style="color: #66cc66;">=</span> <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
<span style="color: #ff7700;font-weight:bold;">for</span> line <span style="color: #ff7700;font-weight:bold;">in</span> lines:
	split <span style="color: #66cc66;">=</span> line.<span style="color: black;">strip</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">replace</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">' '</span><span style="color: #66cc66;">,</span><span style="color: #483d8b;">'~'</span><span style="color: black;">&#41;</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">','</span><span style="color: black;">&#41;</span>
	<span style="color: #008000;">dict</span><span style="color: black;">&#91;</span>split<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#93;</span> <span style="color: #66cc66;">=</span> <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>split<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">dict</span>
<span style="color: #808080; font-style: italic;">#&gt;&gt;{'ignores~standards/conventions': 3, 'does~not~respect~others': 1, 'does~not~plan~properly': 4, 'does~not~check~work~properly': 5, 'always~late~to~work': 13}</span></pre></td></tr></table></div>

<p>Now we have the data in memory in an easily readable way, let’s write it out to disk.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">output <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">''</span>
<span style="color: #ff7700;font-weight:bold;">for</span> key <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">dict</span>.<span style="color: black;">keys</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
	<span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span><span style="color: #008000;">dict</span><span style="color: black;">&#91;</span>key<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>: output +<span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span>key + <span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: black;">&#41;</span>
f <span style="color: #66cc66;">=</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'C:<span style="color: #000099; font-weight: bold;">\\</span>Users<span style="color: #000099; font-weight: bold;">\\</span>chris<span style="color: #000099; font-weight: bold;">\\</span>Desktop<span style="color: #000099; font-weight: bold;">\\</span>intro_to_python<span style="color: #000099; font-weight: bold;">\\</span>test.txt'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'w'</span><span style="color: black;">&#41;</span>
f.<span style="color: black;">write</span><span style="color: black;">&#40;</span>output<span style="color: black;">&#41;</span>
f.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p><img class="aligncenter size-full wp-image-746" title="output" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2011/10/output.png" alt="" width="329" height="404" /><br />
<img class="aligncenter size-full wp-image-751" title="cloud" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2011/10/cloud2.png" alt="" width="600" height="124" /></p>
<p>There we go. In one hour you have learned to:</p>
<ul>
<li>Read and write excel files</li>
<li>Iterate over data</li>
<li>Convert data sets into new formats</li>
<li>Write, read and alter ascii files</li>
</ul>
<p>If you have any questions, or I left out any parts of the presentation you liked, reply here and I will get back to you.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrisevans3d.com/pub_blog/?feed=rss2&#038;p=724</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Question: Rigging with MetaData?</title>
		<link>http://www.chrisevans3d.com/pub_blog/?p=707</link>
		<comments>http://www.chrisevans3d.com/pub_blog/?p=707#comments</comments>
		<pubDate>Tue, 04 Oct 2011 02:00:53 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[animation]]></category>
		<category><![CDATA[maya]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[rigging]]></category>

		<guid isPermaLink="false">http://www.chrisevans3d.com/pub_blog/?p=707</guid>
		<description><![CDATA[As many of you know, I feel the whole &#8216;autorigging&#8217; schtick is a bit overrated. Though Bungie gave a great talk at GDC09 (Modular Procedural Rigging), Dice was to give one this year at SIGGRAPH (Modular Rigging in Battlefield 3), but never showed up for the talk. At Crytek we are switching our animation dept [...]]]></description>
				<content:encoded><![CDATA[<p>As many of you know, I feel the whole &#8216;autorigging&#8217; schtick is a bit overrated. Though Bungie gave a great talk at GDC09 (<a href="http://downloads.bungie.net/presentations/ModularProceduralRigging.zip" target="_blank">Modular Procedural Rigging</a>), Dice was to give one this year at SIGGRAPH (<a href="http://www.siggraph.org/s2011/for_attendees/talks/sessions/123" target="_blank">Modular Rigging in Battlefield 3</a>), but never showed up for the talk.</p>
<p>At Crytek we are switching our animation dept from 3dsMax to Maya. This forces us to build a pipeline there from scratch; in 3dsMax we had 7 years of script development focused on animation and rigging tools. So I am looking at quite a bit o Maya work. The past two weeks focusing on a &#8216;rigging system&#8217; that I guess could be thought of as &#8216;procedural&#8217; but is not really an &#8216;autorigger&#8217;. My past experience was always regenerating rigs with mel cmds.</p>
<p>Things I would like to solve:</p>
<ul>
<li>Use one set of animator tools for many rigs &#8211; common interfaces, rig block encapsulation (oh god i said &#8216;block&#8217;)</li>
<li>Abstract things away, thinking of rigging &#8216;units&#8217; and character &#8216;parts&#8217; instead of individual rig elements, break reliance on naming, version out different parts</li>
<li>Be fluid enough to regenerate the &#8216;rigging&#8217; at any time</li>
</ul>
<h3>First Weekend: Skeleton &#8216;Tagging&#8217;</h3>
<p>I created a wrapper around the common rigging tools that I used, this way, when I rigged, it would automagically markup the skeleton/elements as I went. This looked like so:</p>
<p><img class="aligncenter size-full wp-image-714" title="rigTools_blog" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2011/10/rigTools_blog.png" alt="" width="600" height="361" /></p>
<p>The foundation of this was marking up the skeleton or cons with message nodes that pointed to things or held metadata.  This was cool, and I still like how simple it was, however, it didn&#8217;t really create the layer of abstraction I was after. There wasn&#8217;t the idea of a limb that I could tell to switch from FK to IK.</p>
<h3>Second Weekend: Custom Nodes</h3>
<p>That Bungie talk got a lot of us all excited, Roman went and created a really cool custom node plugin that does way more than we spec&#8217;d it out to do. I rewrote the rigging tools to create &#8216;rigPart&#8217; nodes, which could be like an IK chain, set of twist joints, expression, or constraint. These together could form a &#8216;charPart&#8217; like an arm or leg. All these nodes sat under a main &#8216;character&#8217; node. I realize that many companies abstract their characters into &#8216;blocks&#8217; or &#8216;parts&#8217;, but I had never seen a system that had another layer underneath that. Roman also whipped up a way that when an attr on a customNode changes, you could evaluate a script. So whether it&#8217;s a human arm or alien tentacle arm, the &#8216;charPart&#8217; node can have one FK/IK enum. I am still not sure if this is a better idea, because of the sheer legwork involved..</p>
<p><img class="aligncenter size-full wp-image-713" title="grunt_leg_blog" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2011/10/grunt_leg_blog.png" alt="" width="550" height="651" /></p>
<h3>Third Weekend: A Mix of Both?</h3>
<p>So a class like &#8216;charParts.gruntLeg()&#8217; not only knew how to build the leg rigParts, but also only the leg &#8216;rigging&#8217; if needed. This works pretty well, but the above was pretty hard to read. I took some of my favorite things about the tree-view-based system and I created a &#8216;character&#8217; outliner of sorts. This made it much easier to visualize the rigParts that made up individual &#8216;systems&#8217; of the character, like leg, spine, arm, etc. I did it as a test, but in a way that I easily swap it out with the treeWidget in the rigging tools dialog.</p>
<p><img class="aligncenter size-full wp-image-716" title="charExplorer" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2011/10/charExplorer.png" alt="" width="422" height="500" /></p>
<p>So how do you guys solve some of these issues?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrisevans3d.com/pub_blog/?feed=rss2&#038;p=707</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Creatures and Anatomy: Reticulated Python</title>
		<link>http://www.chrisevans3d.com/pub_blog/?p=685</link>
		<comments>http://www.chrisevans3d.com/pub_blog/?p=685#comments</comments>
		<pubDate>Sun, 02 Oct 2011 13:45:11 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[anatomy]]></category>
		<category><![CDATA[animals]]></category>

		<guid isPermaLink="false">http://www.chrisevans3d.com/pub_blog/?p=685</guid>
		<description><![CDATA[Pythons have probably my favorite skull of any animal. The reticulated python has a jaw that is in four movable parts, and the lower two can swing open over 120 degrees. Here are the main parts of a reticulated python skull: Four, independently moving jaw bones, in case you thought Predator or the Covenant were [...]]]></description>
				<content:encoded><![CDATA[<p><center><img class="aligncenter size-full wp-image-688" title="skull" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2011/10/skull.jpg" alt="" width="550" height="370" /></center></p>
<p>Pythons have probably my favorite skull of any animal. The reticulated python has a jaw that is in <em>four movable parts</em>, and the lower two can swing open over 120 degrees. Here are the main parts of a reticulated python skull:</p>
<p><center><div id="attachment_690" class="wp-caption aligncenter" style="width: 410px"><img class="size-full wp-image-690" title="parts" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2011/10/parts.jpg" alt="" width="400" height="400" /><p class="wp-caption-text">Via SkullsUnlimited.com</p></div></center></p>
<p>Four, independently moving jaw bones, in case you thought <a href="http://en.wikipedia.org/wiki/Predator_%28alien%29" target="_blank">Predator </a>or the <a href="http://www.youtube.com/watch?v=MvjvrUEHrTQ&amp;feature=channel_video_title" target="_blank">Covenant </a>were original: Mother Nature has had them beat for a while!  &#8211;And look at the angle of those teeth: <em>nothing that goes into that mouth is ever coming out!</em> <a href="http://www.break.com/index/huge-python-sinks-teeth-into-aussie1.html" target="_blank">Here&#8217;s a video</a> of a guy getting bitten and his friends have to push the skull forward very hard, then open the mouth, and then pull it away. With these four independent jaw parts, they have the ability to really get their mouths around prey that is much larger than their bodies, like this African antelope:</p>
<p><center><div id="attachment_692" class="wp-caption aligncenter" style="width: 525px"><img class="size-full wp-image-692" title="antelope" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2011/10/antelope.jpg" alt="" width="515" height="215" /><p class="wp-caption-text">I marked the mouth in red above</p></div></center></p>
<p>As if four independently moving jaw parts wasn&#8217;t cool enough: they have a second row of teeth! These are situated on the roof of their mouth, yes, you read that right, reticulated pythons have <a href="http://en.wikipedia.org/wiki/Palatine_bone" target="_blank">palatine</a> teeth, circled below:</p>
<p><center><img class="aligncenter size-full wp-image-686" title="drawing" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2011/10/drawing.jpg" alt="" width="550" height="459" /></center></p>
<p>This is a central row of teeth <em>behind </em>the maxillary teeth on the upper jaw! Here are some better pics to make it harder for you to get to sleep at night:</p>
<p><center><img class="aligncenter size-full wp-image-696" title="palatine_teeth1" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2011/10/palatine_teeth1.jpg" alt="" width="600" height="400" /></center></p>
<p><center><img class="aligncenter size-full wp-image-697" title="palatine_teeth2" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2011/10/palatine_teeth2.jpg" alt="" width="600" height="400" /></center></p>
<p>Here&#8217;s a link to a 3d Burmese Python skull 360 render (roll) from the <a href="http://digimorph.org/specimens/Python_molurus/" target="_blank">DigiMorph </a>website.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrisevans3d.com/pub_blog/?feed=rss2&#038;p=685</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Replacing Stripped Retaining Screws on a Nikon HK-27</title>
		<link>http://www.chrisevans3d.com/pub_blog/?p=679</link>
		<comments>http://www.chrisevans3d.com/pub_blog/?p=679#comments</comments>
		<pubDate>Sun, 25 Sep 2011 20:08:09 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[hardware]]></category>
		<category><![CDATA[photography]]></category>
		<category><![CDATA[400mm 2.8]]></category>
		<category><![CDATA[hk-27]]></category>
		<category><![CDATA[nikon]]></category>

		<guid isPermaLink="false">http://www.chrisevans3d.com/pub_blog/?p=679</guid>
		<description><![CDATA[The Nikon 400mm 2.8 has a lens hood that costs $400. For this price, you would think they use pretty solid parts, but there is a block that a thumbscrew goes into that&#8217;s actually hard plastic. If your lens is in a backpack with the hood attached, this retaining screw will strip. I have read [...]]]></description>
				<content:encoded><![CDATA[<p><center><img class="aligncenter size-full wp-image-680" title="400mm" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2011/09/400mm.gif" alt="" width="450" height="287" /></center></p>
<p>The Nikon 400mm 2.8 has a lens hood that <a href="http://www.adorama.com/NKHK27.html" target="_blank">costs $400</a>. For this price, you would think they use pretty solid parts, but there is a block that a thumbscrew goes into that&#8217;s actually hard plastic. If your lens is in a backpack with the hood attached, this retaining screw will strip.</p>
<p>I have read many forum posts where people begrudgingly REPLACED THE ENTIRE HOOD because of this. People said they contacted Nikon directly and were told there are no replacement parts.</p>
<p>After contacting Nikon, I would like anyone googling for a solution to know that you <em>can </em>order the parts from Nikon, the parts and numbers are pictured above. Contact the Nikon Parts Service at: 310-414-5121</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrisevans3d.com/pub_blog/?feed=rss2&#038;p=679</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>SIGGRAPH 2011</title>
		<link>http://www.chrisevans3d.com/pub_blog/?p=673</link>
		<comments>http://www.chrisevans3d.com/pub_blog/?p=673#comments</comments>
		<pubDate>Tue, 19 Jul 2011 07:32:42 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[3dsmax]]></category>
		<category><![CDATA[cryengine]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[rigging]]></category>

		<guid isPermaLink="false">http://www.chrisevans3d.com/pub_blog/?p=673</guid>
		<description><![CDATA[I am volunteering again in the Studio; giving three small talks at SIGGRAPH, drop me a line if you will be in Vancouver. Rigging Characters for CryENGINE How to rig, skin, and export a character for CryENGINE 3. Topics include physics setup, building characters from many skinned meshes, and creating Character Definitions and Character Parameter [...]]]></description>
				<content:encoded><![CDATA[<p>I am volunteering again in the Studio; giving three small talks at SIGGRAPH, drop me a line if you will be in Vancouver.</p>
<h2><a href="http://www.siggraph.org/s2011/content/Rigging-Characters-CryENGINE-0" target="_blank">Rigging Characters for CryENGINE</a></h2>
<p>How to rig, skin, and export a character for CryENGINE 3. Topics include  physics setup, building characters from many skinned meshes, and  creating Character Definitions and Character Parameter files. These  rigging basics are applicable to most run-time game engines.</p>
<h2><a href="http://www.siggraph.org/s2011/content/introduction-python-scripting-0" target="_blank">Introduction to Python Scripting</a></h2>
<p>In this introduction to Python, a powerful scripting language used by  many 3D applications, attendees learn the basics and explore small  example scenarios gleaned from actual game and film productions. The  sessions are taught in a way that should empower attendees to  immediately begin creating time-saving python scripts and applications.</p>
<h2><a href="http://www.siggraph.org/s2011/content/World-Creation-CryENGINE-0" target="_blank">World Creation in CryENGINE</a></h2>
<p>Have you ever wanted to make a videogame? This session shows how to  build a small level in the freely available CryENGINE 3 SDK. Topics  include: world building and tools (FlowGraph, CryENGINE&#8217;s visual  scripting language, and Trackview, the camera sequencing and directing  tools). In less than an hour, attendees create their own playable video  games.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrisevans3d.com/pub_blog/?feed=rss2&#038;p=673</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>REVIEW: GoPro &#8217;3D Hero System&#8217;</title>
		<link>http://www.chrisevans3d.com/pub_blog/?p=604</link>
		<comments>http://www.chrisevans3d.com/pub_blog/?p=604#comments</comments>
		<pubDate>Sun, 26 Jun 2011 16:21:24 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[diving]]></category>
		<category><![CDATA[hardware]]></category>
		<category><![CDATA[photography]]></category>
		<category><![CDATA[review]]></category>
		<category><![CDATA[stereo3d]]></category>
		<category><![CDATA[cameras]]></category>
		<category><![CDATA[gopro]]></category>
		<category><![CDATA[stereo photography]]></category>
		<category><![CDATA[underwater]]></category>

		<guid isPermaLink="false">http://www.chrisevans3d.com/pub_blog/?p=604</guid>
		<description><![CDATA[GoPro Cameras GoPro makes small $250 no-frills video cameras that record 1080p and come in waterproof polycarbonate housings rated to 60m depth. They have a 170º angle of view, glass lens, fixed focus (2.5ft &#8211; ∞), f/2.8 aperture, and 2.5 hour battery life. These cameras are &#8216;bare bones&#8217;; there is no way to even know [...]]]></description>
				<content:encoded><![CDATA[<p><center><img class="aligncenter size-full wp-image-630" title="gopro_singles" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2011/06/gopro_singles.jpg" alt="" width="434" height="200" /></center></p>
<h3>GoPro Cameras</h3>
<p><a href="http://gopro.com/">GoPro</a> makes small $250 no-frills video cameras that record 1080p and come in waterproof polycarbonate housings rated to 60m depth.  They have a 170º angle of view, glass lens, fixed focus (2.5ft &#8211; ∞), f/2.8 aperture, and 2.5 hour battery life. These cameras are &#8216;bare bones&#8217;; there is no way to even know if it&#8217;s recording but to look directly into the lens, no backfacing LCD or even blinking LED!</p>
<p><span style="color: #ff0000;"><strong>Not Usable Under Water!</strong></span> &#8211; I did some test dives as soon as I received the housing and was in for a rude awakening. <em>The glass domed ports blur the image underwater</em>. This is because domed ports <a href="http://scubageek.com/articles/wwwprim.html" target="_blank">create a secondary focal point or &#8216;virtual image&#8217; underwater that must be focused on</a>. It seems that GoPro did not take this into account; after contacting them directly I was told: &#8220;It is not possible at this time for the GoPro Hero to focus in an underwater environment.&#8221; One funny thing to point out, the cool underwater videos on <em>GoPro&#8217;s own site</em> are not shot with their own lens/housing!</p>
<p><span style="color: #99cc00;">SOLUTION: 3rd Party Lenses or Housing</span> &#8211; That&#8217;s right, to use your GoPro Hero underwater you have to buy a replacement housing from a 3rd party with flat ports (crisp images underwater). At the time of my writing this, there were none available for the 3d Hero System, so I purchased replacement lenses from <a href="http://freedivingspearfishinggear.com/61-flat-underwater-lens-for-gopro-camera.html" target="_blank">Pursuit Diving</a>. These lenses are very soft polycarbonate, and you might want to carry some <a href="http://www.amazon.com/NOVUS-POLISH-Fine-Scratch-Polish/dp/B000B4SCPA" target="_blank">Novus 2</a> polish with you as they scratch easily [<a href="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2011/06/scratches.jpg" target="_blank">image</a>]. Mine also had some small areas of blurriness: this is not an ideal solution. <a href="http://www.eyeofmine.com/gopro/" target="_blank">Eye of Mine</a> has a complete 3d housing replacement in the works, and GoPro themselves say they are &#8216;working&#8217; on a solution. Either way, be warned: <em>These cameras are unable to produce decent images underwater!</em></p>
<p><strong>Poor Dynamic Range / Image Quality </strong>- As you see below, bright highlights easily get blown out. They claim the 1/2.5&#8243; CMOS sensor is great for low light (&gt;1.4    V/lux-sec), this may be, but it is woefully bad at images that vary in bright and dark.</p>
<p><center><div id="attachment_640" class="wp-caption aligncenter" style="width: 560px"><img class="size-full wp-image-640" title="image_quality" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2011/06/image_quality.jpg" alt="" width="550" height="289" /><p class="wp-caption-text">Highlights are easily blown out, and create bad image artifacts</p></div></center></p>
<p><center><div id="attachment_641" class="wp-caption aligncenter" style="width: 560px"><img class="size-full wp-image-641" title="compression" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2011/06/compression.png"/><p class="wp-caption-text">The H264 (12mbit) really butchers the image at times (PNG)</p></div></center></p>
<p><strong>Rolling Shutter Artifacts (Wobble or Jelly)</strong> &#8211; Like most CMOS video cameras, the GoPro has some <a href="http://en.wikipedia.org/wiki/Rolling_shutter" target=blank>rolling shutter</a> issues; I would say more than other CMOS cameras I have used. Unfortunately, for a camera that is meant to be strapped to moving objects &#8211;this is pretty bad! You have no control over the shutter speed, so unfortunately the less light, the more rolling shutter artifacts. Here&#8217;s an example looking out my window, but you can also see this in the Thistlegorm wreck footage below.</p>
<p><center><img class="aligncenter size-full wp-image-628" title="gopro" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2011/06/shutter.gif"/></center></p>
<p>There is a great free solution for <a href="http://www.virtualdub.org/" target=blank>VirtualDub </a>called <a href="http://www.guthspot.se/video/deshaker.htm" target=blank>DeShaker</a>. For the HD Hero you should enter a rolling shutter amount of 82%.</p>
<p><strong>Poor Battery Retention</strong> &#8211; On more than one occasion I left full batteries in the camera and did not turn it on for one to two days. I was often surprised to find the batteries low or half-drained. I have many other smaller canon, fuji, etc cameras and they have much better retention.</p>
<p>
<center><img class="aligncenter size-full wp-image-628" title="gopro" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2011/06/gopro.jpg" alt="" width="300" height="224" /></center></p>
<h3>3D Hero System</h3>
<p>Before, if you wanted to make a GoPro s3d rig, you had to put both cameras on a plate, then clank it to later sync the videos by audio waveform. Not only that, but the cameras dropped frames, so you had to time warp the footage to take into account drift: It was less than ideal.</p>
<p>In March (2011) GoPro released the &#8217;3d Hero System&#8217; which is a new housing and a sync cable for two existing cameras. They also purchased CineForm Studio and <a href="http://gopro.com/3d-cineform-studio-how-it-works/">skinned the software</a> to make for a slightly less painful s3d workflow; unless you know what you&#8217;re doing, then their CineForm app can be pretty obnoxious/unintuitive.</p>
<p><strong>Somewhat Buggy / Unreliable</strong><br />
I was surprised by the bugs I encountered. It&#8217;s very frustrating to think you are recording something and later realize that the camera rig left you with unusable data. For instance, I thought the cameras were recording for an entire dive, but it turned out that they somehow entered a state where they made 400+ individual one second MP4 files. Other times one camera would turn off, or unsync and begin recording in a separate format (like one eye 1080p, the other 5mp stills). Many times one battery would run out well before the other, in which case you at least have 2d video, but still annoying.</p>
<p><strong>Sync Cable does not &#8216;Sync&#8217; Cameras</strong><br />
The &#8216;Sync Cable&#8217; does not really &#8216;sync&#8217; the cameras; treating it as a sync cable will only lead to complete frustration. This can really cause some issues, you need to think of the cable as a &#8216;controller cable&#8217;, where one camera is the master and the other a slave, or you will end up with only one camera recording. <em>Again, the functions of the cameras are not sync&#8217;d!</em> The Camera with the sync cable marked &#8216;R&#8217; must start/stop the recording for both cameras to record. It is easy to place the cameras in the housing so that the &#8216;slave&#8217; camera shutter button is pressed, this does not work, so be careful!</p>
<p><center><img class="aligncenter size-full wp-image-635" title="sync_cable" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2011/06/sync_cable.jpg" alt="" width="608" height="200" /></center></p>
<p>Here is a <a href="http://mikenz.geek.nz/gopro/cable.png" target="_blank">schematic </a>of the &#8216;sync cable&#8217; for DIY people.</p>
<p><strong>Sync&#8217;d Recording Not Perfect (Don&#8217;t think &#8216;Genlock&#8217;)</strong><br />
While better than clanging a metal bar and timewarping to the audio, the sync cable doesn&#8217;t really sync the sensors. The videos seem a full frame off, so maybe the CineForm software compensates for this.</p>
<p><center><div id="attachment_607" class="wp-caption aligncenter" style="width: 610px"><img class="size-full wp-image-607" title="genlock test" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2011/06/genlock.jpg" alt="" width="600" height="300" /><p class="wp-caption-text">As you can see, the right (master) camera is a frame or so ahead of the left</p></div></center></p>
<p><strong>Camera Settings Like White Balance and Exposure NOT Sync&#8217;d</strong><br />
Many times I find myself with stereo video where each eye is widely  different. Whether it&#8217;s exposure, white balance, etc.. it&#8217;s frustrating, and the included CineForm software doesn&#8217;t offer much of a solution.</p>
<p><center><img class="aligncenter size-full wp-image-644" title="w_balance" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2011/06/w_balance.jpg" alt="" width="600" height="180" /></center></p>
<p><strong>CineForm Software is Slow, Can be Frustrating</strong><br />
An example of some frustration advanced users may have is: &#8220;EXPORT TO MP4&#8243;: just a big button, nothing about datarate or other export options.. just a button. Unfortunately the UI has been dumbed down to the point of ambiguity and frustration. They should have continued and just made a &#8220;UPLOAD TO YOUTUBE 3D&#8221; because the software is dumbed down to the point of not being useful to advanced users, but not being easy enough for novices.</p>
<p><strong>Fixed Interocular</strong><br />
The interocular of the housing is ~3.5cm which is a bit too close for my liking. Reducing the interocular to something smaller than the distance between your eyes causes the 3d effect to be weakened and things to appear larger than they really are. The interocular was decent for underwater, and I guess if you are filming yourself on a surfboard, but not great for driving through the Serengeti. The sync cable is of fixed length, so you cannot use it with other GoPro housings.</p>
<p><strong>Unable to Use Other Attachments</strong><br />
Because the sync cable uses the expansion port, and the housing doesn&#8217;t accomodate, you cannot use the LCD backpac or the larger battery with the 3D Hero System.</p>
<h3>Final Thoughts and Some Footage!</h3>
<p>Sure I pointed out a lot of issues that I had, but for the price, the GoPro system is pretty great. The housing, though cheap, never flooded (many 30m dives). This is the first footage I have posted, and I have not post-processed it much. I will maybe make another post once I figure out the best ways to automatically post-process the footage to remove artifacts and distortion.<br />
<center><br />
<iframe width="560" height="349" src="http://www.youtube.com/embed/CwxKFjSZrJo" frameborder="0" allowfullscreen></iframe><br />
<br />
<iframe width="560" height="349" src="http://www.youtube.com/embed/aXELUJv5i3E" frameborder="0" allowfullscreen></iframe><br />
<br />
<iframe width="560" height="349" src="http://www.youtube.com/embed/ugkqyqILhNQ" frameborder="0" allowfullscreen></iframe><br />
<br />
<iframe width="560" height="349" src="http://www.youtube.com/embed/IDrti91t_ms" frameborder="0" allowfullscreen></iframe><br />
</center></p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrisevans3d.com/pub_blog/?feed=rss2&#038;p=604</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Writing Custom Perforce Plugins in Python</title>
		<link>http://www.chrisevans3d.com/pub_blog/?p=584</link>
		<comments>http://www.chrisevans3d.com/pub_blog/?p=584#comments</comments>
		<pubDate>Sun, 03 Oct 2010 23:09:49 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[perforce]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[tutorials]]></category>
		<category><![CDATA[custom tool]]></category>
		<category><![CDATA[pyqt]]></category>
		<category><![CDATA[qtgui]]></category>

		<guid isPermaLink="false">http://www.chrisevans3d.com/pub_blog/?p=584</guid>
		<description><![CDATA[I recently wrote a custom tool to diff CryEngine layer files in P4, and was surprised how simple it was. What follows is a quick tutorial on adding custom python tools to Perforce. Start by heading over to Tools&#62;Manage Custom Tools&#8230; Then click &#8216;New&#8217;: You can pass a lot of information to an external tool, [...]]]></description>
				<content:encoded><![CDATA[<p>I recently wrote a custom tool to diff CryEngine layer files in P4, and was surprised how simple it was. What follows is a quick tutorial on adding custom python tools to Perforce.</p>
<p>Start by heading over to Tools&gt;Manage Custom Tools&#8230; Then click &#8216;New&#8217;:</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-587" title="p4tools" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2010/10/p4tools1.png" alt="" width="416" height="516" /></p>
<p>You can pass a lot of information to an external tool, <a href="http://www.perforce.com/prod_dl/r06.2/doc/help/p4v-html-pure/custom_tools.html" target="_blank">here is a detailed rundown</a>. As you see above, we pass the client spec (local) file name (%f) to a python script, let&#8217;s create a new script called &#8216;custom_tool.py&#8217;:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
<span style="color: #ff7700;font-weight:bold;">from</span> PyQt4 <span style="color: #ff7700;font-weight:bold;">import</span> QtGui    
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> custom_tool<span style="color: black;">&#40;</span>QtGui.<span style="color: black;">QMessageBox</span><span style="color: black;">&#41;</span>:
	<span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> parent<span style="color: #66cc66;">=</span><span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
		QtGui.<span style="color: black;">QMessageBox</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>
		<span style="color: #008000;">self</span>.<span style="color: black;">setDetailedText</span><span style="color: black;">&#40;</span><span style="color: #008000;">str</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
		<span style="color: #008000;">self</span>.<span style="color: black;">show</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ <span style="color: #66cc66;">==</span> <span style="color: #483d8b;">&quot;__main__&quot;</span>:
	app <span style="color: #66cc66;">=</span> QtGui.<span style="color: black;">QApplication</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#41;</span>
	theTool <span style="color: #66cc66;">=</span> custom_tool<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
	theTool.<span style="color: black;">show</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
	<span style="color: #dc143c;">sys</span>.<span style="color: black;">exit</span><span style="color: black;">&#40;</span>app.<span style="color: black;">exec_</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>What this does is simply spits out the sys.argv in a way you can see it. So now you can feed any file you right click in Perforce into a python script:</p>
<p><img class="aligncenter size-full wp-image-598" title="p4tools2" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2010/10/p4tools22.png" alt="" width="580" height="234" /></p>
<p>If you would like to actually do something with a file or revision on the server and are passing the %F flag to get the depot file path, you then need to use p4 print to redirect the file contents (non-binary) to a local file:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">p4.<span style="color: black;">run_print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'-q'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'-o'</span><span style="color: #66cc66;">,</span> depotFile<span style="color: #66cc66;">,</span> localFile<span style="color: black;">&#41;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://www.chrisevans3d.com/pub_blog/?feed=rss2&#038;p=584</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Perforce Triggers in Python (Pt 2)</title>
		<link>http://www.chrisevans3d.com/pub_blog/?p=571</link>
		<comments>http://www.chrisevans3d.com/pub_blog/?p=571#comments</comments>
		<pubDate>Sat, 25 Sep 2010 17:39:19 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.chrisevans3d.com/pub_blog/?p=571</guid>
		<description><![CDATA[So last time I more introduced you to the idea of triggers, here&#8217;s a more complex example. This worked on my db, but if you have branching you would need to check each returned file against the branch you are submitting to. Check if The File is Already in the Depot This is a trigger [...]]]></description>
				<content:encoded><![CDATA[<p>So last time I more introduced you to the idea of triggers, here&#8217;s a more complex example. This worked on my db, but if you have branching you would need to check each returned file against the branch you are submitting to.</p>
<h2>Check if The File is Already in the Depot</h2>
<p>This is a trigger that checks the hash digest of the incoming file against that of the server. This way you can see if the user is checking in a file that already exists.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
<span style="color: #ff7700;font-weight:bold;">from</span> P4 <span style="color: #ff7700;font-weight:bold;">import</span> P4<span style="color: #66cc66;">,</span> P4Exception
&nbsp;
p4 <span style="color: #66cc66;">=</span> P4<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
describe <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
<span style="color: #ff7700;font-weight:bold;">try</span>:
	p4.<span style="color: #dc143c;">user</span> <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;admin&quot;</span>
	p4.<span style="color: black;">password</span> <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;admin&quot;</span>
	p4.<span style="color: black;">port</span> <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;1666&quot;</span>
	p4.<span style="color: black;">connect</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
	lst <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span>
	<span style="color: #dc143c;">stat</span> <span style="color: #66cc66;">=</span>  p4.<span style="color: black;">run</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'fstat'</span><span style="color: #66cc66;">,</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">'-Ol'</span><span style="color: #66cc66;">,</span><span style="color: #483d8b;">'//depot/...@'</span>+ <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>lst<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
	<span style="color: #008000;">hash</span> <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">stat</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'digest'</span><span style="color: black;">&#93;</span>
	fname <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">stat</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'depotFile'</span><span style="color: black;">&#93;</span>
	m <span style="color: #66cc66;">=</span>  p4.<span style="color: black;">run</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'fstat'</span><span style="color: #66cc66;">,</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">'-Ol'</span><span style="color: #66cc66;">,</span><span style="color: #483d8b;">'-F'</span><span style="color: #66cc66;">,</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">'digest = '</span> + <span style="color: #008000;">str</span><span style="color: black;">&#40;</span><span style="color: #008000;">hash</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #483d8b;">'//depot/...'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
	existing <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
	<span style="color: #ff7700;font-weight:bold;">for</span> <span style="color: #008000;">file</span> <span style="color: #ff7700;font-weight:bold;">in</span> m:
		<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">file</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'depotFile'</span><span style="color: black;">&#93;</span> <span style="color: #66cc66;">!=</span> fname: existing.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: #008000;">file</span><span style="color: black;">&#41;</span>
&nbsp;
	<span style="color: #ff7700;font-weight:bold;">if</span> existing <span style="color: #66cc66;">!=</span> <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>:
		<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>FILE EXISTS IN DEPOT!!'</span>
		<span style="color: #ff7700;font-weight:bold;">print</span>  <span style="color: #483d8b;">'YOUR FILE:  '</span> + <span style="color: black;">&#40;</span>fname.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'/'</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span>-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
		<span style="color: #ff7700;font-weight:bold;">for</span>  <span style="color: #008000;">file</span> <span style="color: #ff7700;font-weight:bold;">in</span> existing: <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'EXACTLY MATCHES:  '</span> + <span style="color: #008000;">file</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'depotFile'</span><span style="color: black;">&#93;</span>
		<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'P4 DIGEST:  '</span> + <span style="color: #008000;">hash</span>
		<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'SOLUTION: Contact your lead if you believe this message was generated in error.'</span>
		<span style="color: #dc143c;">sys</span>.<span style="color: black;">exit</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">Exception</span><span style="color: #66cc66;">,</span> e:
	<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Error: %s&quot;</span> % <span style="color: black;">&#40;</span>e<span style="color: black;">&#41;</span>
	<span style="color: #dc143c;">sys</span>.<span style="color: black;">exit</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
&nbsp;
p4.<span style="color: black;">disconnect</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #dc143c;">sys</span>.<span style="color: black;">exit</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Then your trigger line looks like this:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="text" style="font-family:monospace;">Triggers:
	dupeCheck change-submit //depot/... &quot;python X:/projects/2010/p4/dupe_trigger.py %user% %changelist%&quot;</pre></td></tr></table></div>

<p>This is what the user will see when they try to check in:</p>
<p><img class="aligncenter size-full wp-image-573" title="p4_trigger_exists" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2010/09/p4_trigger_exists.png" alt="" width="516" height="257" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrisevans3d.com/pub_blog/?feed=rss2&#038;p=571</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Perforce Triggers in Python (Pt 1)</title>
		<link>http://www.chrisevans3d.com/pub_blog/?p=551</link>
		<comments>http://www.chrisevans3d.com/pub_blog/?p=551#comments</comments>
		<pubDate>Wed, 25 Aug 2010 22:33:54 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[industry]]></category>
		<category><![CDATA[perforce]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[tutorials]]></category>
		<category><![CDATA[work]]></category>
		<category><![CDATA[p4]]></category>
		<category><![CDATA[p4python]]></category>
		<category><![CDATA[trigger]]></category>

		<guid isPermaLink="false">http://www.chrisevans3d.com/pub_blog/?p=551</guid>
		<description><![CDATA[Perforce is a wily beast. A lot of companies use it, but I feel few outside of the IT department really have to deal with it much. As I work myself deeper and deeper into the damp hole that is asset validation, I have really been writing a lot of python to deal with certain [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.perforce.com/" target="_blank">Perforce</a> is a wily beast. A lot of companies use it, but I feel few outside of the IT department really have to deal with it much. As I work myself deeper and deeper into the damp hole that is asset validation, I have really been writing a lot of python to deal with certain issues; but always scripts that work from the outside.</p>
<p>Perforce has a system that allows you to write scripts that are run, server side, when <a href="http://www.perforce.com/perforce/doc.current/manuals/p4sag/06_scripting.html" target="_blank">any number of events</a> are triggered. You can use many scripting languages, but I will only touch on Python.</p>
<h2>Test Environment</h2>
<p>To follow along here, you should set up a test environment. Perforce is <a href="http://www.perforce.com/perforce/downloads/index.html" target="_blank">freely downloadable</a>, and free to use with 2 users. Of course you are going to need python, and <a href="http://www.perforce.com/perforce/loadsupp.html" target="_blank">p4python</a>. So get your server running and add two users, a user and an administrator.</p>
<h2>Your First Trigger</h2>
<p>Let&#8217;s create the simplest python script. It will be a submit trigger that says &#8216;Hello World&#8217; then passes or fails. If it passes, the item will be checked in to perforce, if it fails, it will not. exiting while returning a &#8217;1&#8242; is considered a fail, &#8217;0&#8242; a pass.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Hello World!'</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'No checkin for you!'</span>
<span style="color: #dc143c;">sys</span>.<span style="color: black;">exit</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Ok, so save this file as hello_trigger.py. Now go to a command line and enter &#8216;p4 triggers&#8217; this will open a text document, edit that document to point to your trigger, like so (but point to the location of your script on disk):</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="text" style="font-family:monospace;">Triggers:
	hello_trigger change-submit //depot/... &quot;python X:/projects/2010/p4/hello_trigger.py&quot;</pre></td></tr></table></div>

<p>Close/save the trigger TMP file, you should see &#8216;Triggers saved.&#8217; echo&#8217;d at the prompt. Now, when we try to submit a file to the depot, we will get this:</p>
<p><img src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2010/08/triggers01.png" alt="" /></p>
<p>So: awesome, <strong><span style="color: #ff0000;">you just DENIED your first check-in!</span></strong></p>
<h2>Connecting to Perforce from Inside a Trigger</h2>
<p>So we are now denying check-ins, but let&#8217;s try to do some other things, let&#8217;s connect to perforce from inside a trigger.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> P4 <span style="color: #ff7700;font-weight:bold;">import</span> P4<span style="color: #66cc66;">,</span> P4Exception
&nbsp;
p4 <span style="color: #66cc66;">=</span> P4<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">try</span>:
	<span style="color: #808080; font-style: italic;">#use whatever your admin l/p was</span>
	<span style="color: #808080; font-style: italic;">#this isn't the safest, but it works at this beginner level</span>
	p4.<span style="color: #dc143c;">user</span> <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;admin&quot;</span>
	p4.<span style="color: black;">password</span> <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;admin&quot;</span>
	p4.<span style="color: black;">port</span> <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;1666&quot;</span>
	p4.<span style="color: black;">connect</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
	info <span style="color: #66cc66;">=</span> p4.<span style="color: black;">run</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;info&quot;</span><span style="color: black;">&#41;</span>
	<span style="color: #ff7700;font-weight:bold;">print</span> info
	<span style="color: #dc143c;">sys</span>.<span style="color: black;">exit</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#this will return any errors</span>
<span style="color: #ff7700;font-weight:bold;">except</span> P4Exception:
	<span style="color: #ff7700;font-weight:bold;">for</span> e <span style="color: #ff7700;font-weight:bold;">in</span> p4.<span style="color: black;">errors</span>: <span style="color: #ff7700;font-weight:bold;">print</span> e
	<span style="color: #dc143c;">sys</span>.<span style="color: black;">exit</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>So now when you try to submit a file to depot you will get this:</p>
<p><img src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2010/08/triggers02.png" alt="" /></p>
<h2>Passing Info to the Trigger</h2>
<p>Now we are running triggers, accepting or denying checkins, but we really don&#8217;t know much about them. Let&#8217;s try to get enough info to where we could make a decision about whether or not we want the file to pass validation. Let&#8217;s make another python trigger, trigger_test.py, and let&#8217;s query something from the perforce server in the submit trigger. To do this we need to edit our trigger file like so:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="text" style="font-family:monospace;">Triggers:
	test change-submit //depot/... &quot;python X:/projects/2010/p4/test_trigger.py %user% %changelist%&quot;</pre></td></tr></table></div>

<p>This will pass the user and changelist number into the python script as an arg, the same way dragging/dropping passed args to python in my previous example. So let&#8217;s set that up, save the script from before as &#8216;test_trigger.py&#8217; as shown above, and add the following:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
<span style="color: #ff7700;font-weight:bold;">from</span> P4 <span style="color: #ff7700;font-weight:bold;">import</span> P4<span style="color: #66cc66;">,</span> P4Exception
&nbsp;
p4 <span style="color: #66cc66;">=</span> P4<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
describe <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">try</span>:
	p4.<span style="color: #dc143c;">user</span> <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;admin&quot;</span>
	p4.<span style="color: black;">password</span> <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;admin&quot;</span>
	p4.<span style="color: black;">port</span> <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;1666&quot;</span>
	p4.<span style="color: black;">connect</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">except</span> P4Exception:
	<span style="color: #ff7700;font-weight:bold;">for</span> e <span style="color: #ff7700;font-weight:bold;">in</span> p4.<span style="color: black;">errors</span>: <span style="color: #ff7700;font-weight:bold;">print</span> e
	<span style="color: #dc143c;">sys</span>.<span style="color: black;">exit</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">str</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#41;</span>
describe <span style="color: #66cc66;">=</span> p4.<span style="color: black;">run</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'describe'</span><span style="color: #66cc66;">,</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>describe<span style="color: black;">&#41;</span>
&nbsp;
p4.<span style="color: black;">disconnect</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #dc143c;">sys</span>.<span style="color: black;">exit</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>So, as you can see, it has returned the user and changelist number:</p>
<p><img src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2010/08/triggers03.png" alt="" /></p>
<p>However, for this changelist to be useful, we query p4, asking the server to describe the changelist. This returns a lot of information about the changelist.</p>
<h2>Where to Go From here</h2>
<p>The few simple things shown here really give you the tools to do many more things. Here are some examples of triggers that can be  created with the know-how above:</p>
<ul>
<li>Deny check-ins of a certain filetype (like deny compiled source files/assets)</li>
<li>Deny check-ins whose hash digest matches an existing file on the server</li>
<li>Deny/allow a certain type of file check-in from a user in a certain group</li>
<li>Email a lead any time a file in a certain folder is updated</li>
</ul>
<p>Did you find this helpful? What creative triggers have you written?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrisevans3d.com/pub_blog/?feed=rss2&#038;p=551</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Sigma 8mm vs 4.5mm Comparison on Nikon APS-C</title>
		<link>http://www.chrisevans3d.com/pub_blog/?p=537</link>
		<comments>http://www.chrisevans3d.com/pub_blog/?p=537#comments</comments>
		<pubDate>Sun, 08 Aug 2010 12:56:33 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[hardware]]></category>
		<category><![CDATA[industry]]></category>
		<category><![CDATA[photography]]></category>
		<category><![CDATA[vfx]]></category>
		<category><![CDATA[aps-c]]></category>
		<category><![CDATA[fisheye]]></category>
		<category><![CDATA[hdr]]></category>
		<category><![CDATA[lenses]]></category>
		<category><![CDATA[nikon]]></category>
		<category><![CDATA[panorama]]></category>
		<category><![CDATA[photo]]></category>

		<guid isPermaLink="false">http://www.chrisevans3d.com/pub_blog/?p=537</guid>
		<description><![CDATA[I have been researching the best options available for the D300 when it comes to quickly generating some lightprobes/panoramas. This of course means fisheye lenses. Currently, Sigma is the only company that makes a 180 degree circular fisheye. They come in two flavors, 8mm, and 4.5mm. The 8mm projects a full circle onto a full [...]]]></description>
				<content:encoded><![CDATA[<div id="attachment_540" class="wp-caption aligncenter" style="width: 610px"><a href="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2010/08/8mm_apsc_compare.jpg"><img class="size-medium wp-image-540" title="8mm_apsc_compare" src="http://chrisevans3d.com/images/blog/8mm_apsc_compare_600px.jpg" alt="" width="600" height="292" /></a><p class="wp-caption-text">click to enlarge</p></div>
<p>I have been researching the best options available for the D300 when it comes to quickly generating some lightprobes/panoramas. This of course means fisheye lenses. Currently, Sigma is the only company that makes a 180 degree circular fisheye. They come in two flavors, 8mm, and 4.5mm. The 8mm projects a full circle onto a full 35mm sensor (full frame), but on an APS-C sensor it is cropped. The 4.5mm however, throws a perfect circular image onto an APS-C sized sensor; I believe it is the only lens that does this.</p>
<h2>The Pixels</h2>
<p>You would think that the 4.5mm would be the way to go, I did until I took a look at both. It really comes down to the pixels. The width in pixels of the image thrown by the 4.5mm lens is roughly 2285px in diameter. So while you can shoot less, an entire panorama taking about 3 shots, it will come out as a &lt;4k equirectangular. However, using the 8mm, you need 4 shots, plus one zenith (5 shots total) and it generates an 8k image.  While the 4.5mm does generate a 180 degree image across, as you can see it is very wasteful.</p>
<p><span style="color: #bf4035;">So why doesn&#8217;t the lens have full coverage in at least the short dimension? I think it&#8217;s because it&#8217;s a lens designed to fit Canon and Sigma cameras, not just Nikon. Canon sensors have a 1.6 crop factor and Sigma&#8217;s Foveon X3 has a 1.7 crop factor (13.8mm)! The coverage is so small because Nikon DX format has a 1.5 crop factor, the APS-C sensor is much larger than Canon or Sigma. The actual circle measures 12.3mm, even small for the Sigma, which makes me believe they future-proofed it for Four Thirds.<br />
</span></p>
<p>For an APS-C sensor like the D300, I would recommend the 8mm, unless you really need a full uncropped image. The 4.5mm, while being more expensive, also has an aperture of 2.8, compared to the 8mm (f/3.5)</p>
<p>I am not super constrained on time, if you are on set and shooting bracketed probes between takes or something, the 4.5mm will save you two shots (18 pictures) and this might be preferable. That said, it will only generate a 4k image in the end (which might be enough)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrisevans3d.com/pub_blog/?feed=rss2&#038;p=537</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python: Simple Decorator Example</title>
		<link>http://www.chrisevans3d.com/pub_blog/?p=530</link>
		<comments>http://www.chrisevans3d.com/pub_blog/?p=530#comments</comments>
		<pubDate>Mon, 28 Jun 2010 07:06:19 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[tutorials]]></category>
		<category><![CDATA[decorators]]></category>

		<guid isPermaLink="false">http://www.chrisevans3d.com/pub_blog/?p=530</guid>
		<description><![CDATA[In Python, a Decorator is a type of macro that allows you to inject or modify code in functions or classes. I was turned onto this by my friend Matt Chapman at ILM, but never fully grasped the importance. class myDecorator&#40;object&#41;: def __init__&#40;self, f&#41;: self.f = f def __call__&#40;self&#41;: print &#34;Entering&#34;, self.f.__name__ self.f&#40;&#41; print &#34;Exited&#34;, [...]]]></description>
				<content:encoded><![CDATA[<p>In Python, a <a href="http://en.wikipedia.org/wiki/Python_syntax_and_semantics#Decorators" target="_blank">Decorator</a> is a type of macro that allows you to inject or modify code in functions or classes. I was turned onto this by my friend Matt Chapman at ILM, but never fully grasped the importance.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> myDecorator<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
	<span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> f<span style="color: black;">&#41;</span>:
		<span style="color: #008000;">self</span>.<span style="color: black;">f</span> <span style="color: #66cc66;">=</span> f
	<span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__call__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
		<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Entering&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">self</span>.<span style="color: black;">f</span>.__name__
		<span style="color: #008000;">self</span>.<span style="color: black;">f</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
		<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Exited&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">self</span>.<span style="color: black;">f</span>.__name__
&nbsp;
<span style="color: #66cc66;">@</span>myDecorator
<span style="color: #ff7700;font-weight:bold;">def</span> aFunction<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
	<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;aFunction running&quot;</span>
&nbsp;
aFunction<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>When you run the code above you will see the following:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="code" style="font-family:monospace;">&gt;&gt;Entering aFunction
&gt;&gt;aFunction running
&gt;&gt;Exited aFunction</pre></td></tr></table></div>

<p>So when we call a decorated function, we get a completely different behavior. You can wrap any existing functions, here is an example of wrapping functions for error reporting:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> catchAll:
	<span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> function<span style="color: black;">&#41;</span>:
		<span style="color: #008000;">self</span>.<span style="color: black;">function</span> <span style="color: #66cc66;">=</span> function
&nbsp;
	<span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__call__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> *args<span style="color: black;">&#41;</span>:
		<span style="color: #ff7700;font-weight:bold;">try</span>:
			<span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">function</span><span style="color: black;">&#40;</span>*args<span style="color: black;">&#41;</span>
		<span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">Exception</span><span style="color: #66cc66;">,</span> e:
			<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Error: %s&quot;</span> % <span style="color: black;">&#40;</span>e<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">@</span>catchAll
<span style="color: #ff7700;font-weight:bold;">def</span> unsafe<span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span>:
  <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #ff4500;">1</span> / x
&nbsp;
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;unsafe(1): &quot;</span><span style="color: #66cc66;">,</span> unsafe<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;unsafe(0): &quot;</span><span style="color: #66cc66;">,</span> unsafe<span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>So when we run this and divide by zero we get:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="code" style="font-family:monospace;">unsafe(1):  1
unsafe(0):  Error: integer division or modulo by zero</pre></td></tr></table></div>

<p>Using decorators you can make sweeping changes to existing code with minimal effort, like the error reporting function above, you could go back and just sprinkle these in older code.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrisevans3d.com/pub_blog/?feed=rss2&#038;p=530</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python: Special Class Methods</title>
		<link>http://www.chrisevans3d.com/pub_blog/?p=524</link>
		<comments>http://www.chrisevans3d.com/pub_blog/?p=524#comments</comments>
		<pubDate>Sat, 26 Jun 2010 20:16:06 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[tutorials]]></category>

		<guid isPermaLink="false">http://www.chrisevans3d.com/pub_blog/?p=524</guid>
		<description><![CDATA[I have really been trying to learn some Python fundamentals lately, reading some books and taking an online class. So: wow. I can&#8217;t believe that I have written so many tools, some used by really competent people at large companies, without really understanding polymorphism and other basic Python concepts. Here&#8217;s an example of my sequence [...]]]></description>
				<content:encoded><![CDATA[<p>I have really been trying to learn some Python fundamentals lately, reading some books and taking an online class. So: wow. I can&#8217;t believe that I have written so many tools, some used by really competent people at large companies, without really understanding polymorphism and other basic Python concepts.</p>
<p>Here&#8217;s an example of my sequence method from before, but making it a class using special <a href="http://docs.python.org/reference/datamodel.html#specialnames" target="_blank">class methods</a>:</p>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow: hidden;">http://docs.python.org/reference/datamodel.html#specialnames</div>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> imSequence:
	<span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">file</span><span style="color: black;">&#41;</span>:
		<span style="color: #008000;">dir</span> <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">dirname</span><span style="color: black;">&#40;</span><span style="color: #008000;">file</span><span style="color: black;">&#41;</span>
		<span style="color: #008000;">file</span> <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">basename</span><span style="color: black;">&#40;</span><span style="color: #008000;">file</span><span style="color: black;">&#41;</span>
		segNum <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">findall</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\d</span>+'</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">file</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span>-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>
		<span style="color: #008000;">self</span>.<span style="color: black;">numPad</span> <span style="color: #66cc66;">=</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>segNum<span style="color: black;">&#41;</span>
		<span style="color: #008000;">self</span>.<span style="color: black;">baseName</span> <span style="color: #66cc66;">=</span> <span style="color: #008000;">file</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span>segNum<span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>
		<span style="color: #008000;">self</span>.<span style="color: black;">fileType</span> <span style="color: #66cc66;">=</span> <span style="color: #008000;">file</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'.'</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span>-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>
		globString <span style="color: #66cc66;">=</span> <span style="color: #008000;">self</span>.<span style="color: black;">baseName</span>
		<span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span><span style="color: #008000;">self</span>.<span style="color: black;">numPad</span><span style="color: black;">&#41;</span>: globString +<span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'?'</span>
		<span style="color: #008000;">self</span>.<span style="color: black;">images</span> <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">glob</span>.<span style="color: #dc143c;">glob</span><span style="color: black;">&#40;</span><span style="color: #008000;">dir</span>+<span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\\</span>'</span>+globString+<span style="color: #008000;">file</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span>segNum<span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
	<span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__len__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
		<span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">images</span><span style="color: black;">&#41;</span>
&nbsp;
	<span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__iter__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
		<span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">iter</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">images</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Here&#8217;s an example of use:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="code" style="font-family:monospace;">seq = imSequence('seq\\test_00087.tga')
print len(seq)
&gt;&gt;94
print 'BaseName: %s  FileType: %s  Padding: %s' % (seq.baseName, seq.fileType, seq.numPad)
&gt;&gt;BaseName: test_  FileType: tga  Padding: 5
for image in seq: print image
&gt;&gt;seq\test_00000.tga
&gt;&gt;seq\test_00001.tga
&gt;&gt;seq\test_000002.tga
...</pre></td></tr></table></div>

<p>[More info and examples: <a href='http://diveintopython.org/object_oriented_framework/special_class_methods2.html' target=blank>Dive Into Python: Special Class Methods</a>]</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrisevans3d.com/pub_blog/?feed=rss2&#038;p=524</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Nikon D300 Stereo Rig [$30 DIY]</title>
		<link>http://www.chrisevans3d.com/pub_blog/?p=507</link>
		<comments>http://www.chrisevans3d.com/pub_blog/?p=507#comments</comments>
		<pubDate>Sun, 02 May 2010 22:27:31 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[photography]]></category>
		<category><![CDATA[stereo3d]]></category>
		<category><![CDATA[tutorials]]></category>
		<category><![CDATA[d300]]></category>
		<category><![CDATA[DIY]]></category>
		<category><![CDATA[stereo 3d]]></category>

		<guid isPermaLink="false">http://www.chrisevans3d.com/pub_blog/?p=507</guid>
		<description><![CDATA[This is what the final product will look like. Two D300s, mounted as close as possible, sync&#8217;d metering, focus, flash, and shutter. Rig cost: Less than 30 dollars! Of course you are going to need two d300s and paired lenses, primes or zooms with a wide rubberband spanning them if you are really hardcore. Keep [...]]]></description>
				<content:encoded><![CDATA[<p style="text-align: center;"><img class="aligncenter size-full wp-image-510" title="final_rig" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2010/05/final1.jpg" alt="" width="600" height="290" /></p>
<p>This is what the final product will look like. Two D300s, mounted as close as possible, sync&#8217;d metering, focus, flash, and shutter. Rig cost: Less than 30 dollars! Of course you are going to need two d300s and paired lenses, primes or zooms with a wide rubberband spanning them if you are really hardcore. Keep in mind, the intraoccular is 13.5cm, this is a tad more than double the normal human width, but it&#8217;s the best we can do with the d300 [horizontal].</p>
<h2>Creating the Camera Bar</h2>
<p>This mainly involves you going to the local hardware store with your D300 and looking at the different L-brackets available. It&#8217;s really critical that you get the cameras as close as possible, so mounting one upside down is preferable. It may look weird, but heck, it already looks weird; might as well go full retard.</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-508" title="final_product" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2010/05/final.jpg" alt="" width="600" height="319" /></p>
<p>I usually get an extra part for the buttons, because they will need to be somewhere that you can easily reach</p>
<h2>Creating the Cabling</h2>
<p>Nikon cables with Nikon 10-pin connectors aren&#8217;t cheap! The <a href="http://www.nikonusa.com/Find-Your-Nikon/ProductDetail.page?pid=4652" target="_blank">MC-22</a>, <a href="http://www.nikonusa.com/Find-Your-Nikon/Photography-Accessories/Other-Cords/4653/MC-23-Connecting-Cord.html" target="_blank">MC-23</a>, <a href="http://www.nikonusa.com/Find-Your-Nikon/Photography-Accessories/Other-Cords/4655/MC-25-Adapter-Cord.html" target="_blank">MC-25</a>, or <a href="http://www.nikonusa.com/Find-Your-Nikon/ProductDetail.page?pid=4660" target="_blank">MC-30</a> are all over 60 dollars! I bought remote shutter cables at <a href="http://www.dealextreme.com/" target="_blank">DealExtreme.com</a>. I wanted to make my own switch, and also be able to use my GPS, and change the intraoccular, so the below describes that setup. If you just want to sync two identical cams, the fastest way is to buy a knock-off MC-23, which is the <a href="http://www.cnjjc.cc/products/seoth-ma23.htm" target="_blank">JJ MA-23</a> or <a href="http://www.fotografdunyasi.com.tr/JJC-MR23-Nikon-Makinalar-icin-Stereo-Cekim-Baglanti-Kablosu,PR-550.html" target="_blank">JJ MR-23</a>. I bought two <a href="http://www.dealextreme.com/details.dx/sku.15812" target="_blank">JueYing  RS-N1</a> remote shutters and cut them up. [$6 each]</p>
<p><img class="aligncenter size-full wp-image-515" title="pinout" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2010/05/pinout.jpg" alt="" width="561" height="224" /></p>
<p>I only labeled the pins most people would be interested in, for a more in depth pin-out that covers more than AE/AF and shutter (GPS, etc), have a look <a href="http://www.schneordesign.com/Avi/F100/diy_02.htm" target="_blank">here</a>. I decided to use molex connectors from RC cars, they make some good ones that are sealed/water-resistant and not too expensive.</p>
<p><img class="aligncenter size-full wp-image-513" title="DSC_4724" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2010/05/DSC_4724.jpg" alt="" width="600" height="243" /></p>
<p>So the cables have a pretty short lead. This so that I can connect them as single, double, have an intraoccular as wide or as short as any cable I make.. The next thing is to wire these to a set of AF/AE and shutter buttons.</p>
<p><img class="aligncenter size-full wp-image-514" title="soldering" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2010/05/soldering.jpg" alt="" width="600" height="442" /></p>
<p>Black focuses/meters and red is the shutter release. It&#8217;s not easy to find buttons that have two press states: half press and full press. If you see above, shutter is the combination of AF/AE, ground, and shutter. This is before the heat shrink is set in place.</p>
<h2>Altogether</h2>
<p>So that should be it. Here&#8217;s my first photo with sync&#8217;d metering, focus, flash, and shutter. They can even do bursts at high speed. Next post I will try to look into the software side, and take a look at lens distortion, vignetting, and other issues.</p>
<p><img class="aligncenter size-full wp-image-519" title="d300_01_anaglyph" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2010/05/d300_01_anaglyph.jpg" alt="" width="600" height="466" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrisevans3d.com/pub_blog/?feed=rss2&#038;p=507</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Dealing with File Sequences in Python</title>
		<link>http://www.chrisevans3d.com/pub_blog/?p=499</link>
		<comments>http://www.chrisevans3d.com/pub_blog/?p=499#comments</comments>
		<pubDate>Mon, 19 Apr 2010 16:49:34 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[tutorials]]></category>
		<category><![CDATA[file sequences]]></category>
		<category><![CDATA[image sequences]]></category>

		<guid isPermaLink="false">http://www.chrisevans3d.com/pub_blog/?p=499</guid>
		<description><![CDATA[I have been parsing through the files of other people a lot lately, and finally took the time to make a little function to give me general information about a sequence of files. It uses regex to yank the numeric parts out of a filename, figure out the padding, and glob to tell you how [...]]]></description>
				<content:encoded><![CDATA[<p>I have been parsing through the files of other people a lot lately, and finally took the time to make a little function to give me general information about a sequence of files. It uses regex to yank the numeric parts out of a filename, figure out the padding, and glob to tell you how many files in the sequence. Here&#8217;s the code and an example usage:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#returns [base name, padding, filetype, number of files, first file, last file]</span>
<span style="color: #ff7700;font-weight:bold;">def</span> getSeqInfo<span style="color: black;">&#40;</span><span style="color: #008000;">file</span><span style="color: black;">&#41;</span>:
	<span style="color: #008000;">dir</span> <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">dirname</span><span style="color: black;">&#40;</span><span style="color: #008000;">file</span><span style="color: black;">&#41;</span>
	<span style="color: #008000;">file</span> <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">basename</span><span style="color: black;">&#40;</span><span style="color: #008000;">file</span><span style="color: black;">&#41;</span>
	segNum <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">findall</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\d</span>+'</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">file</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span>-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>
	numPad <span style="color: #66cc66;">=</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>segNum<span style="color: black;">&#41;</span>
	baseName <span style="color: #66cc66;">=</span> <span style="color: #008000;">file</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span>segNum<span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>
	fileType <span style="color: #66cc66;">=</span> <span style="color: #008000;">file</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'.'</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span>-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>
	globString <span style="color: #66cc66;">=</span> baseName
	<span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span>numPad<span style="color: black;">&#41;</span>: globString +<span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'?'</span>
	theGlob <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">glob</span>.<span style="color: #dc143c;">glob</span><span style="color: black;">&#40;</span><span style="color: #008000;">dir</span>+<span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\\</span>'</span>+globString+<span style="color: #008000;">file</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span>segNum<span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
	numFrames <span style="color: #66cc66;">=</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>theGlob<span style="color: black;">&#41;</span>
	firstFrame <span style="color: #66cc66;">=</span> theGlob<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>
	lastFrame <span style="color: #66cc66;">=</span> theGlob<span style="color: black;">&#91;</span>-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>
	<span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#91;</span>baseName<span style="color: #66cc66;">,</span> numPad<span style="color: #66cc66;">,</span> fileType<span style="color: #66cc66;">,</span> numFrames<span style="color: #66cc66;">,</span> firstFrame<span style="color: #66cc66;">,</span> lastFrame<span style="color: black;">&#93;</span></pre></td></tr></table></div>

<p>Here is an example of usage:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="text" style="font-family:monospace;">print getSeqInfo('E:\\data\\data\\Games\\Project\\CaptureOutput\\Frame000547.jpg')
&gt;&gt;['Frame', 6, 'jpg', 994, 'E:\\data\\data\\Games\\Project\\CaptureOutput\\Frame000000.jpg', 'E:\\data\\data\\Games\\Project\\CaptureOutput\\Frame000993.jpg']</pre></td></tr></table></div>

<p>I know this is pretty simple, but I looked around a bit online and didn&#8217;t see anything readily available showing how to deal with different numbered file sets. I have needed something like this for a while that will work with anything from OBJs sent from external contractors, to images from After Effects&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrisevans3d.com/pub_blog/?feed=rss2&#038;p=499</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Drop Files on a Python Script</title>
		<link>http://www.chrisevans3d.com/pub_blog/?p=494</link>
		<comments>http://www.chrisevans3d.com/pub_blog/?p=494#comments</comments>
		<pubDate>Sun, 11 Apr 2010 22:33:41 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[tutorials]]></category>
		<category><![CDATA[registry]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://www.chrisevans3d.com/pub_blog/?p=494</guid>
		<description><![CDATA[So I have always been wondering how you can create almost like a &#8216;droplet&#8217; to steal the photoshop lingo, from a python script. A while ago I came across some sites showing how to edit shellex in regedit to allow for files to be dropped on any python script and fed to it as args [...]]]></description>
				<content:encoded><![CDATA[<p>So I have always been wondering how you can create almost like a &#8216;droplet&#8217; to steal the photoshop lingo, from a python script. A while ago I came across some sites showing how to edit shellex in regedit to allow for files to be dropped on any python script and fed to it as args (Windows).</p>
<p>It&#8217;s really simple, you grab this reg file [<a href="http://chrisevans3d.com/files/py_drag_n_drop.reg">py_drag_n_drop.reg</a>] and install it.</p>
<p>Now when you drop files onto a python script, their filenames will be passed as args, here&#8217;s a simple script to test.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
&nbsp;
f <span style="color: #66cc66;">=</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'c:<span style="color: #000099; font-weight: bold;">\\</span>tmp.txt'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'w'</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">for</span> arg <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span>:
    f.<span style="color: black;">write</span><span style="color: black;">&#40;</span>arg + <span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: black;">&#41;</span>
f.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>When you save this, and drop files onto its icon, it will create tmp.txt, which will look like this:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="text" style="font-family:monospace;">X:\projects\2010\python\drag_and_drop\drag_n_drop.py
X:\photos\2010.04 - easter weekend\fuji\DSCF9048.MPO
X:\photos\2010.04 - easter weekend\fuji\DSCF9049.MPO
X:\photos\2010.04 - easter weekend\fuji\DSCF9050.MPO
X:\photos\2010.04 - easter weekend\fuji\DSCF9051.MPO
X:\photos\2010.04 - easter weekend\fuji\DSCF9052.MPO</pre></td></tr></table></div>

<p>The script itself is the first arg, then all the files. This way you can easily create scripts that accept drops to do things like convert files, upload files, etc..</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrisevans3d.com/pub_blog/?feed=rss2&#038;p=494</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MPO to JPS and PNS</title>
		<link>http://www.chrisevans3d.com/pub_blog/?p=486</link>
		<comments>http://www.chrisevans3d.com/pub_blog/?p=486#comments</comments>
		<pubDate>Sun, 11 Apr 2010 20:31:31 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[photography]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[stereo3d]]></category>
		<category><![CDATA[fuji w1]]></category>
		<category><![CDATA[jps]]></category>
		<category><![CDATA[mpo]]></category>
		<category><![CDATA[pns]]></category>

		<guid isPermaLink="false">http://www.chrisevans3d.com/pub_blog/?p=486</guid>
		<description><![CDATA[I got some good feedback from the last post and updated the script to export JPEG Stereo (JPS) and PNG Stereo (PNS, really.) This way you can convert your images into a single lossless image that you can pop into photoshop and adjust hsv/levels, etc. import mpo mpo.makePNS&#40;'DSCF9463.MPO'&#41; #&#62;&#62;Saving image: DSCF9463.PNS #&#62;&#62;Save complete. This is [...]]]></description>
				<content:encoded><![CDATA[<p>I got some good feedback from the last post and updated the <a href="http://www.chrisevans3d.com/files/mpo.zip">script </a>to export JPEG Stereo (JPS) and PNG Stereo (PNS, really.) This way you can convert your images into a single lossless image that you can pop into photoshop and adjust hsv/levels, etc.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> mpo
mpo.<span style="color: black;">makePNS</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'DSCF9463.MPO'</span><span style="color: black;">&#41;</span>
<span style="color: #808080; font-style: italic;">#&gt;&gt;Saving image: DSCF9463.PNS</span>
<span style="color: #808080; font-style: italic;">#&gt;&gt;Save complete.</span></pre></td></tr></table></div>

<p>This is a super simple python script, no error padding. Also, keep in mind that coming from most modern camera rigs, you are saving like a 20-40 megapixel PNG compressed file here, wait until it says it is done saving, it may take a few seconds.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrisevans3d.com/pub_blog/?feed=rss2&#038;p=486</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Splitting MPO Files with ExifTool and Python</title>
		<link>http://www.chrisevans3d.com/pub_blog/?p=479</link>
		<comments>http://www.chrisevans3d.com/pub_blog/?p=479#comments</comments>
		<pubDate>Sun, 11 Apr 2010 00:58:40 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[photography]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[stereo3d]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[exif]]></category>
		<category><![CDATA[exiftool]]></category>
		<category><![CDATA[fuji w1]]></category>
		<category><![CDATA[splitting mpo file into two images]]></category>
		<category><![CDATA[stereo]]></category>

		<guid isPermaLink="false">http://www.chrisevans3d.com/pub_blog/?p=479</guid>
		<description><![CDATA[Many stereo cameras are using the new MPO format to store multiple images in a file. Unfortunately, nothing really works with these files (Other than Stereo Photo Maker). Here is a simple python wrapper around ExifTool that will extract the Right and Left image, and return EXIF data as a dict. I think this is [...]]]></description>
				<content:encoded><![CDATA[<p>Many stereo cameras are using the new MPO format to store multiple images in a file. Unfortunately, nothing really works with these files (Other than <a href="http://stereo.jpn.org/eng/stphmkr/" target="_blank">Stereo Photo Maker</a>). Here is a simple <a href="http://www.ChrisEvans3D.com/files/mpo.zip">python wrapper</a> around <a href="http://www.sno.phy.queensu.ca/~phil/exiftool/" target="_blank">ExifTool </a>that will extract the Right and Left image, and return EXIF data as a dict. I think this is probably easier than explaining how to use ExifTool, but you can see from looking at the simple wrapper code.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> mpo
&nbsp;
<span style="color: #808080; font-style: italic;">#Name of MPO file, name of output, whether or not you want all EXIF in a txt log</span>
mpo.<span style="color: black;">extractImagePair</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'DSCF9463.MPO'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'DSCF9463'</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">True</span><span style="color: black;">&#41;</span>
<span style="color: #808080; font-style: italic;">#&gt;&gt;Created DSCF9463_R.jpg</span>
<span style="color: #808080; font-style: italic;">#&gt;&gt;Created DSCF9463_L.jpg</span>
<span style="color: #808080; font-style: italic;">#&gt;&gt;Writing EXIF data</span></pre></td></tr></table></div>

<p>The above leaves you with two images and a text file that has all the EXIF data, even attributes that xnView and other apps do not read:</p>
<p style="text-align: center;"><img class="size-full wp-image-480 aligncenter" title="mpo_py" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2010/04/mpo_py.gif" alt="" width="488" height="240" /></p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">exif <span style="color: #66cc66;">=</span>  getExif<span style="color: black;">&#40;</span><span style="color: #483d8b;">'DSCF9463.MPO'</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> exif<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Convergence Angle&quot;</span><span style="color: black;">&#93;</span>
<span style="color: #808080; font-style: italic;">#&gt;&gt;0</span>
<span style="color: #ff7700;font-weight:bold;">print</span> exif<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Field Of View&quot;</span><span style="color: black;">&#93;</span>
<span style="color: #808080; font-style: italic;">#&gt;&gt;53.7 deg</span>
<span style="color: #ff7700;font-weight:bold;">print</span> exif<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Focal Length&quot;</span><span style="color: black;">&#93;</span>
<span style="color: #808080; font-style: italic;">#&gt;&gt;6.3 mm (35 mm equivalent: 35.6 mm)</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://www.chrisevans3d.com/pub_blog/?feed=rss2&#038;p=479</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>PyQt4 UIC Module Example</title>
		<link>http://www.chrisevans3d.com/pub_blog/?p=468</link>
		<comments>http://www.chrisevans3d.com/pub_blog/?p=468#comments</comments>
		<pubDate>Wed, 07 Apr 2010 21:54:38 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[tutorials]]></category>
		<category><![CDATA[pyqt]]></category>
		<category><![CDATA[ui file]]></category>
		<category><![CDATA[uic]]></category>

		<guid isPermaLink="false">http://www.chrisevans3d.com/pub_blog/?p=468</guid>
		<description><![CDATA[I have been really amazing myself at how much knowledge I have forgotten in the past five or six months&#8230; Most of the work I did in the past year utilized the UIC module to load UI files directly, but I can find very little information about this online. I was surprised to see that [...]]]></description>
				<content:encoded><![CDATA[<p>I have been really amazing myself at how much knowledge I have forgotten in the past five or six months&#8230; Most of the work I did in the past year utilized the UIC module to load UI files directly, but I can find very little information about this online. I was surprised to see that even the trusty old <a href="http://www.amazon.com/Programming-Python-Prentice-Software-Development/dp/product-description/0132354187" target="_blank">Rapid GUI Programming with Python and Qt</a> book doesn&#8217;t cover loading UI files with the UIC module.</p>
<p>So, here is a tiny script with UI file [<a href="http://www.ChrisEvans3d.com/files/pyqt_tutorial.ui" target="_blank">download</a>] that will generate a pyqt example window that does &#8216;stuff&#8217;:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
<span style="color: #ff7700;font-weight:bold;">from</span> PyQt4 <span style="color: #ff7700;font-weight:bold;">import</span> QtGui<span style="color: #66cc66;">,</span> QtCore<span style="color: #66cc66;">,</span> uic
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> TestApp<span style="color: black;">&#40;</span>QtGui.<span style="color: black;">QMainWindow</span><span style="color: black;">&#41;</span>:
	<span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
		QtGui.<span style="color: black;">QMainWindow</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>
&nbsp;
		<span style="color: #008000;">self</span>.<span style="color: black;">ui</span> <span style="color: #66cc66;">=</span> uic.<span style="color: black;">loadUi</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'X:/projects/2010/python/pyqt_tutorial/pyqt_tutorial.ui'</span><span style="color: black;">&#41;</span>
		<span style="color: #008000;">self</span>.<span style="color: black;">ui</span>.<span style="color: black;">show</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
		<span style="color: #008000;">self</span>.<span style="color: black;">connect</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">ui</span>.<span style="color: black;">doubleSpinBox</span><span style="color: #66cc66;">,</span> QtCore.<span style="color: black;">SIGNAL</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;valueChanged(double)&quot;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> spinFn<span style="color: black;">&#41;</span>
		<span style="color: #008000;">self</span>.<span style="color: black;">connect</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">ui</span>.<span style="color: black;">comboBox</span><span style="color: #66cc66;">,</span> QtCore.<span style="color: black;">SIGNAL</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;currentIndexChanged(QString)&quot;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> comboFn<span style="color: black;">&#41;</span>
		<span style="color: #008000;">self</span>.<span style="color: black;">connect</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">ui</span>.<span style="color: black;">pushButton</span><span style="color: #66cc66;">,</span> QtCore.<span style="color: black;">SIGNAL</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;clicked()&quot;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> buttonFn<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> spinFn<span style="color: black;">&#40;</span>value<span style="color: black;">&#41;</span>:
	win.<span style="color: black;">ui</span>.<span style="color: black;">doubleSpinBoxLabel</span>.<span style="color: black;">setText</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'doubleSpinBox is set to '</span> + <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>value<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">def</span> buttonFn<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
	win.<span style="color: black;">ui</span>.<span style="color: black;">setWindowTitle</span><span style="color: black;">&#40;</span>win.<span style="color: black;">ui</span>.<span style="color: black;">lineEdit</span>.<span style="color: black;">text</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">def</span> comboFn<span style="color: black;">&#40;</span>value<span style="color: black;">&#41;</span>:
	win.<span style="color: black;">ui</span>.<span style="color: black;">comboBoxLabel</span>.<span style="color: black;">setText</span><span style="color: black;">&#40;</span><span style="color: #008000;">str</span><span style="color: black;">&#40;</span>value<span style="color: black;">&#41;</span> + <span style="color: #483d8b;">' is selected'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ <span style="color: #66cc66;">==</span> <span style="color: #483d8b;">&quot;__main__&quot;</span>:
	app <span style="color: #66cc66;">=</span> QtGui.<span style="color: black;">QApplication</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#41;</span>
	win <span style="color: #66cc66;">=</span> TestApp<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
	<span style="color: #dc143c;">sys</span>.<span style="color: black;">exit</span><span style="color: black;">&#40;</span>app.<span style="color: black;">exec_</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Change the path to reflect where you have saved the UI file, and when you run the script you should get this:</p>
<p><img class="size-full wp-image-469 alignnone" title="window" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2010/04/window.gif" alt="" width="286" height="164" /></p>
<p><strong><span style="color: #ff0000;">EDIT: A few people have asked me to update this for other situations</span></strong></p>
<p><strong>PySide Inside Maya:</strong></p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
<span style="color: #ff7700;font-weight:bold;">from</span> PySide.<span style="color: black;">QtUiTools</span> <span style="color: #ff7700;font-weight:bold;">import</span> *
<span style="color: #ff7700;font-weight:bold;">from</span> PySide.<span style="color: black;">QtCore</span> <span style="color: #ff7700;font-weight:bold;">import</span> *
<span style="color: #ff7700;font-weight:bold;">from</span> PySide.<span style="color: black;">QtGui</span> <span style="color: #ff7700;font-weight:bold;">import</span> *
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> TestApp<span style="color: black;">&#40;</span>QMainWindow<span style="color: black;">&#41;</span>:
	<span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
		QMainWindow.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>
&nbsp;
		loader <span style="color: #66cc66;">=</span> QUiLoader<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
		<span style="color: #008000;">self</span>.<span style="color: black;">ui</span> <span style="color: #66cc66;">=</span> loader.<span style="color: black;">load</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'c:/pyqt_tutorial.ui'</span><span style="color: black;">&#41;</span>
		<span style="color: #008000;">self</span>.<span style="color: black;">ui</span>.<span style="color: black;">show</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
		<span style="color: #008000;">self</span>.<span style="color: black;">connect</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">ui</span>.<span style="color: black;">doubleSpinBox</span><span style="color: #66cc66;">,</span> SIGNAL<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;valueChanged(double)&quot;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> spinFn<span style="color: black;">&#41;</span>
		<span style="color: #008000;">self</span>.<span style="color: black;">connect</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">ui</span>.<span style="color: black;">comboBox</span><span style="color: #66cc66;">,</span> SIGNAL<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;currentIndexChanged(QString)&quot;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> comboFn<span style="color: black;">&#41;</span>
		<span style="color: #008000;">self</span>.<span style="color: black;">connect</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">ui</span>.<span style="color: black;">pushButton</span><span style="color: #66cc66;">,</span> SIGNAL<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;clicked()&quot;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> buttonFn<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> spinFn<span style="color: black;">&#40;</span>value<span style="color: black;">&#41;</span>:
	win.<span style="color: black;">ui</span>.<span style="color: black;">doubleSpinBoxLabel</span>.<span style="color: black;">setText</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'doubleSpinBox is set to '</span> + <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>value<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">def</span> buttonFn<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
	win.<span style="color: black;">ui</span>.<span style="color: black;">setWindowTitle</span><span style="color: black;">&#40;</span>win.<span style="color: black;">ui</span>.<span style="color: black;">lineEdit</span>.<span style="color: black;">text</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">def</span> comboFn<span style="color: black;">&#40;</span>value<span style="color: black;">&#41;</span>:
	win.<span style="color: black;">ui</span>.<span style="color: black;">comboBoxLabel</span>.<span style="color: black;">setText</span><span style="color: black;">&#40;</span><span style="color: #008000;">str</span><span style="color: black;">&#40;</span>value<span style="color: black;">&#41;</span> + <span style="color: #483d8b;">' is selected'</span><span style="color: black;">&#41;</span>
&nbsp;
win <span style="color: #66cc66;">=</span> TestApp<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p><strong>PyQT Inside Maya:</strong></p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
<span style="color: #ff7700;font-weight:bold;">from</span> PyQt4 <span style="color: #ff7700;font-weight:bold;">import</span> QtGui<span style="color: #66cc66;">,</span> QtCore<span style="color: #66cc66;">,</span> uic
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> TestApp<span style="color: black;">&#40;</span>QtGui.<span style="color: black;">QMainWindow</span><span style="color: black;">&#41;</span>:
	<span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
		QtGui.<span style="color: black;">QMainWindow</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>
&nbsp;
		<span style="color: #008000;">self</span>.<span style="color: black;">ui</span> <span style="color: #66cc66;">=</span> uic.<span style="color: black;">loadUi</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'c:/pyqt_tutorial.ui'</span><span style="color: black;">&#41;</span>
		<span style="color: #008000;">self</span>.<span style="color: black;">ui</span>.<span style="color: black;">show</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
		<span style="color: #008000;">self</span>.<span style="color: black;">connect</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">ui</span>.<span style="color: black;">doubleSpinBox</span><span style="color: #66cc66;">,</span> QtCore.<span style="color: black;">SIGNAL</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;valueChanged(double)&quot;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> spinFn<span style="color: black;">&#41;</span>
		<span style="color: #008000;">self</span>.<span style="color: black;">connect</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">ui</span>.<span style="color: black;">comboBox</span><span style="color: #66cc66;">,</span> QtCore.<span style="color: black;">SIGNAL</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;currentIndexChanged(QString)&quot;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> comboFn<span style="color: black;">&#41;</span>
		<span style="color: #008000;">self</span>.<span style="color: black;">connect</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">ui</span>.<span style="color: black;">pushButton</span><span style="color: #66cc66;">,</span> QtCore.<span style="color: black;">SIGNAL</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;clicked()&quot;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> buttonFn<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> spinFn<span style="color: black;">&#40;</span>value<span style="color: black;">&#41;</span>:
	win.<span style="color: black;">ui</span>.<span style="color: black;">doubleSpinBoxLabel</span>.<span style="color: black;">setText</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'doubleSpinBox is set to '</span> + <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>value<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">def</span> buttonFn<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
	win.<span style="color: black;">ui</span>.<span style="color: black;">setWindowTitle</span><span style="color: black;">&#40;</span>win.<span style="color: black;">ui</span>.<span style="color: black;">lineEdit</span>.<span style="color: black;">text</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">def</span> comboFn<span style="color: black;">&#40;</span>value<span style="color: black;">&#41;</span>:
	win.<span style="color: black;">ui</span>.<span style="color: black;">comboBoxLabel</span>.<span style="color: black;">setText</span><span style="color: black;">&#40;</span><span style="color: #008000;">str</span><span style="color: black;">&#40;</span>value<span style="color: black;">&#41;</span> + <span style="color: #483d8b;">' is selected'</span><span style="color: black;">&#41;</span>
&nbsp;
win <span style="color: #66cc66;">=</span> TestApp<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://www.chrisevans3d.com/pub_blog/?feed=rss2&#038;p=468</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>RigPorn: Uncharted 2</title>
		<link>http://www.chrisevans3d.com/pub_blog/?p=462</link>
		<comments>http://www.chrisevans3d.com/pub_blog/?p=462#comments</comments>
		<pubDate>Wed, 07 Apr 2010 18:32:57 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[industry]]></category>
		<category><![CDATA[maya]]></category>
		<category><![CDATA[rigging]]></category>
		<category><![CDATA[rigporn]]></category>
		<category><![CDATA[judd simantov]]></category>
		<category><![CDATA[naughty dog]]></category>
		<category><![CDATA[uncharted 2]]></category>
		<category><![CDATA[uncharted2]]></category>

		<guid isPermaLink="false">http://www.chrisevans3d.com/pub_blog/?p=462</guid>
		<description><![CDATA[My friends Judd and Rich gave a talk on some of the Character Tech behind Uncharted 2. Here are the slides.]]></description>
				<content:encoded><![CDATA[<p style="text-align: center;"><a href="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2010/04/uncharted2.jpg"><img class="aligncenter size-full wp-image-463" title="uncharted2" src="http://www.chrisevans3d.com/pub_blog/wp-content/uploads/2010/04/uncharted2.jpg" alt="" width="590" height="205" /></a></p>
<p style="text-align: center;">My friends Judd and Rich gave a talk on some of the Character Tech behind Uncharted 2. <a href="http://cmpmedia.vo.llnwd.net/o1/vault/gdc10/slides/simantov_judd_uncharted2_character_pipeline.pdf" target="_blank">Here are the slides</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrisevans3d.com/pub_blog/?feed=rss2&#038;p=462</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
