<?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>CG Rebel</title>
	<atom:link href="http://cgrebel.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://cgrebel.com</link>
	<description>A Good Pipeline does Not Require a Huge Team</description>
	<lastBuildDate>Tue, 26 Apr 2011 08:32:45 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>The 48 fps Crime</title>
		<link>http://cgrebel.com/2011/04/the-48-fps-crime/</link>
		<comments>http://cgrebel.com/2011/04/the-48-fps-crime/#comments</comments>
		<pubDate>Fri, 15 Apr 2011 22:06:09 +0000</pubDate>
		<dc:creator>Martin</dc:creator>
				<category><![CDATA[Film Production]]></category>
		<category><![CDATA[Camera]]></category>
		<category><![CDATA[Filmmaking]]></category>

		<guid isPermaLink="false">http://cgrebel.com/?p=521</guid>
		<description><![CDATA[Peter Jackson has stirred some controversy when he announced that he will be shooting The Hobbit at 48 frames per second (fps). Film purists are crying out loud in face of that &#8220;crime&#8221;. Stu Maschwitz &#8211; who I highly respect &#8211; has been a proponent of 24 fps for years and a clear, laid back [...]]]></description>
			<content:encoded><![CDATA[<p>Peter Jackson has stirred some controversy when he announced that he will be <a title="The Hobbit in 48 fps" href="http://if.com.au/2011/04/04/article/Andrew-Lesnie-reveals-The-Hobbit-3D-cinematography-set-up/XEGCDWWZHJ.html" target="_blank">shooting The Hobbit at 48 frames per second</a> (fps). Film purists are crying out loud in face of that &#8220;crime&#8221;. Stu Maschwitz &#8211; who I highly respect &#8211; has been a proponent of 24 fps for years and a clear, laid back <a title="Stu Maschwitz on higher frame rates" href="http://prolost.com/blog/2011/4/4/movies-at-high-frame-rates.html" target="_blank">opinion on the topic</a>. With all due respect I have to argue &#8230;</p>
<p><span id="more-521"></span>One often heard argument is that 30, 50 or 60 fps are a bane of video and diminishes production value. Stu argues that audiences have rejected shows shot at such framerates. I think the argument falls short and there is much more to it than framerate. Shooting on video is the main culprit. Video has much less dynamic range than chemical film (only recent developments rectify that). Also, the 180° shutter in film cameras has a very specific optical quality (due to the mechanical workings and the 1/48 sec exposure). Video with their CCDs and CMOS chips often has been exposed at 360° thus exhibiting a very different quality in motion blur. Furthermore CCDs (the predominant form of sensors for a long time in the video world) are read line by line &#8211; resulting again in a very distinctive look due to the temporal shift from the top to the bottom of the frame. Video also more often than not is shot interlaced as that is the format which is broadcasted. All that contributes to the &#8220;video look&#8221;. Framerate is just one aspect &#8211; though still an very important one.</p>
<p>I think we agree that film is becoming a rare beast in production and the shift to digital is almost complete. So we already witness a change in optical shutter quality (a rotating disc versus digital sensor readouts). While a film camera would not be able to expose at more than 180° our new digital cameras can. Still, almost every DOP (director of photography) would pay attention to follow the 180° shutter rule to keep the film look and we all should be thankful for that. Opening the shutter for more than 180° would increase the motion blur. This would mash up the picture tremendously. So we end up in the digital world shooting &#8220;film&#8221; that very closely looks like what we have been used to for many decades.</p>
<p>By wanting to keep the film look the framerate is also kept at 24 fps. Quite understandably so. Though with that decision (or lack of decision to change it) come all the shortcomings of film. Fast pans can start to judder or strobe. The same is true for fast motion. Still, most DOPs and directors have not thought about using different frame rates. Quite understandably so as it would result in a very different look, would it not?</p>
<p>That&#8217;s the point where I think Peter Jackson really made a smart move.  He is shooting at 48 fps &#8211; double the framerate. This might sound insignificant and I&#8217;ve heard arguments why not 50 fps like with PAL or 60 fps like with NTSC. I argue that 48 fps have a dramatic consequence over those frame rates considering a second aspect: shutter angle.</p>
<p>Filming at 48 fps with a 360° shutter will give you a frame that is indistinguishable from a simultaneously shot frame at 24 fps with a 180° shutter. Both frames have an exposure of 1/48 second. Both sensors will have the same amount of light hitting them. Both frames will exhibit the same amount of motion blur. On a frame-by-frame basis they will be identical. The only difference &#8211; which still might be considerable &#8211; is this: shot at 24 fps you blank for 1/48 second every frame. You essentially miss half of what is happening. At 48 fps you fill in those 50% of missing time. You get the whole picture, so to speak.</p>
<p>Also, think about this: In cinemas film has been projected with shutter rates of 48 or even 72 Hz to reduce flicker for a long time. So what has been recorded at 24 fps has been projected at 48 fps for good measure. Film has been mangled through a 3:2 pulldown (NTSC) or sped up by 4% (PAL) for DVD and TV release and shown at 50 or 60 interlaced frames. Still, movies have retained the &#8220;film look&#8221; after all that torture. Yes, it still has been recorded at 24 fps at 1/48 exposure. I argue that recording at 48 fps at 1/48 exposure will retain the film look and getting rid of judder and strobing which should come at great relief -especially when projected in stereoscopic 3D.</p>
<p>Just one note: I don&#8217;t know what shutter angles Peter Jackson is using on The Hobbit. Somehow I have the gut feeling that a 360° shutter would be a logical choice to make regarding lighting requirements, motion blur quality, speed of lenses etc. &#8230; Just saying <img src='http://cgrebel.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Update April 26th, 2011: Peter Jackson <a href="http://www.facebook.com/notes/peter-jackson/your-comments-on-48-fps/10150235459531558" target="_blank">posted on Facebook</a> that they are shooting at 48 fps with a 270° shutter (translating to a 135° shutter at 24 fps). So it&#8217;s right between the traditional 180° and my speculation of 360°. Smaller shutter angles have been used before on film @24 fps as well (giving that very crisp, strobing look). I for once am curious how The Hobbit will look.</p>
]]></content:encoded>
			<wfw:commentRss>http://cgrebel.com/2011/04/the-48-fps-crime/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>P4D102 &#8211; Act on your Selected Objects</title>
		<link>http://cgrebel.com/2011/01/p4d102-selected-objects/</link>
		<comments>http://cgrebel.com/2011/01/p4d102-selected-objects/#comments</comments>
		<pubDate>Tue, 25 Jan 2011 22:29:10 +0000</pubDate>
		<dc:creator>Martin</dc:creator>
				<category><![CDATA[Cinema 4D Scripting]]></category>
		<category><![CDATA[Python Scripting]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Cinema 4D]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://cgrebel.com/?p=475</guid>
		<description><![CDATA[In this article you will learn how to go through your selected objects in Cinema 4D and perform commands on them using a Python script.]]></description>
			<content:encoded><![CDATA[<p>Now that we have had a short glimpse on the basics in the first article lets move on to do something meaningful. So far it has been a purely academic discourse.</p>
<p>Usually, we want a script to do something with the objects we have in a scene. So the first step is to look at how we can access the scene file and go through selected objects and perform Cinema 4D commands on them.<br />
<span id="more-475"></span></p>
<h2>Accessing the Cinema 4D Scene</h2>
<p>Let&#8217;s start with the basics. We import the c4d module and check if we are running as a script within Cinema 4D (remember: __name__ is defined as &#8220;__main__&#8221; in this case, so we check for that value):</p>
<div class="codesnip-container" >
<div class="python codesnip"><span class="kw1">import</span> c4d</p>
<p><span class="kw1">if</span> __name__ == <span class="st0">&quot;__main__&quot;</span>:<br />
&nbsp; &nbsp; <span class="kw1">pass</span></div>
</div>
<p>The <em>pass</em> statement does nothing. We use it as placeholder for code we will now place inside the <em>if</em> block. Without it, Python would complain as it expects a statement within <em>if</em>.</p>
<p>When looking through the Cinema 4D Python documentation we find the <em>c4d.documents</em> module that has all the functionality to access our scene. The function <em>GetActiveDocument()</em> function returns the currently active scene as a <em>BaseDocument</em> object.</p>
<p>Now that we know how to access the scene we are left with finding out how to get a list of the selected objects in the scene. Looking at <em>BaseDocument</em> we see that it has a <em>GetActiveObjects()</em> method that returns a list of <em>BaseObject</em> objects.</p>
<p>Now let us implement this:</p>
<div class="codesnip-container" >
<div class="python codesnip"><span class="kw1">import</span> c4d</p>
<p><span class="kw1">if</span> __name__ == <span class="st0">&quot;__main__&quot;</span>:<br />
&nbsp; &nbsp; doc = c4d.<span class="me1">documents</span>.<span class="me1">GetActiveDocument</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; selected = doc.<span class="me1">GetActiveObjects</span><span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span></div>
</div>
<p>So far so good. We fetched the scene using <em>GetActiveDocument()</em> and assigned it to the variable <em>doc</em> so we can reference it later when needed. Then we stored the list of selected objects in the variable <em>selected</em> (NB: other than in the documentation, GetActiveObjects() requires a parameter. 0 works fine for me so I use that). </p>
<p>Now here is something new. What is a list in Python?</p>
<h2>Python Lists</h2>
<p>Python lists are very versatile and are really powerful and actually easy to use (at least compared to other programming languages like C++). I won&#8217;t go into much detail on lists here for now. Read up on the <a href="http://docs.python.org/tutorial/introduction.html#lists" title="Python lists">Python documentation</a> if you want to learn more about them. For now it is sufficient to learn that lists contain several objects. We can access them through an index like <em>a = list[2]</em>. This would access the third object in the list as they start at index 0 (zero).</p>
<p>For our script we would need to know if there is an object in the list, ie. if there have been objects selected. Python has a build-in function to see how many items a list contains: <em>len()</em>. So len(list) returns the number of objects in the list. Very convenient! So we check if there are objects n the list and then we &#8220;go through&#8221; them and do &#8220;something&#8221;. </p>
<h2>Traversing Selected Objects</h2>
<p>The question is, how do we &#8220;go through&#8221; the list? This also is quite easy in Python. Say hello to the <em>for</em> statement: Python&#8217;s <em>for</em> statement iterates over the items of a sequence (like a list or string). in the order they appear.</p>
<div class="codesnip-container" >
<div class="python codesnip"><span class="kw1">for</span> ob <span class="kw1">in</span> selected:<br />
&nbsp; &nbsp; <span class="kw1">pass</span></div>
</div>
<p>This will &#8220;go through&#8221; all items in the <em>selected</em> list. Within the <em>for</em> statement we can access the individual item through the <em>ob</em> variable we used in the <em>for</em> statement.</p>
<p>So we make something simple and let our script output all the selected objects&#8217; names to the Python console as a test:</p>
<div class="codesnip-container" >
<div class="python codesnip"><span class="kw1">import</span> c4d</p>
<p><span class="kw1">if</span> __name__ == <span class="st0">&quot;__main__&quot;</span>:<br />
&nbsp; &nbsp; doc = c4d.<span class="me1">documents</span>.<span class="me1">GetActiveDocument</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; selected = doc.<span class="me1">GetActiveObjects</span><span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">if</span> <span class="kw2">len</span><span class="br0">&#40;</span>selected<span class="br0">&#41;</span> <span class="sy0">&gt;</span> <span class="nu0">0</span>: &nbsp;<span class="co1"># we have one or more selected objects in the scene</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> ob <span class="kw1">in</span> selected:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> ob.<span class="me1">GetName</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</div>
<p>Now we are getting somewhere!</p>
<h2>Collapse Extrude Nurbs Script</h2>
<p>Over at the CG Society forum there was a request for a script that collapses Extrude Nurbs to polygon objects. Let us use this as an example. </p>
<p>So what do we want the script to do?</p>
<ol>
<li>Go through all selected objects</li>
<li>Check if it is an Extrude Nurbs object</li>
<li>Make it a single polygon object</li>
</ol>
<p>Sound simple enough for a start without being too simple and without purpose.</p>
<p>We already nailed the first step: Go through all selected objects. Done <img src='http://cgrebel.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<h3>Checking for an Object Type</h3>
<p>So how do we check if it is an Extrude Nurbs object? We could check for the name. By default Cinema 4D calls them &#8220;Extrude NURBS&#8221;. Doing that would quickly fail though as users can change the name. Looking at the <em>BaseObject</em> class that represents all objects in a Cinema 4D scene we don&#8217;t find much useful though. </p>
<p>Now here is a &#8220;tricky&#8221; thing with classes: They inherit the properties of their ancestors. Looking at the c4d module documentation we see that BaseObject is a descendant of BaseList2D which is a descendant of GeListNode which again is a descendant of C4DAtom. Looking through all those classes we see that C4DAtom has a method <em>GetType()</em> which returns a number containing the type ID of the object. Looking further we discover that <em>BaseList2D</em> has a method of <em>GetTypeName()</em>. We can use either to check if the object is an Extrude Nurbs.</p>
<p>As we do not know the type ID or the type name of an Extrude Nurbs we can use our basic script to give us those values.</p>
<div class="codesnip-container" >
<div class="python codesnip"><span class="kw1">import</span> c4d<br />
<span class="kw1">if</span> __name__ == <span class="st0">&quot;__main__&quot;</span>:<br />
&nbsp; &nbsp; doc = c4d.<span class="me1">documents</span>.<span class="me1">GetActiveDocument</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; selected = doc.<span class="me1">GetActiveObjects</span><span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="kw2">len</span><span class="br0">&#40;</span>selected<span class="br0">&#41;</span> <span class="sy0">&gt;</span> <span class="nu0">0</span>: &nbsp;<span class="co1"># we have one or more selected objects in the scene</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> ob <span class="kw1">in</span> selected:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> ob.<span class="me1">GetName</span><span class="br0">&#40;</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;is an &lt;&quot;</span> + ob.<span class="me1">GetTypeName</span><span class="br0">&#40;</span><span class="br0">&#41;</span> + <span class="st0">&quot;&gt;&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;ID: &quot;</span> + <span class="kw2">str</span><span class="br0">&#40;</span>ob.<span class="me1">GetType</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</div>
<p>Printing the object&#8217;s name, type name and type ID to the Python console will show us the values we need for our script. Using a comma (,) after the last object with the <em>print</em> statement will prevent a new line so the output for each object is on one line.</p>
<p>The output should be something like this:</p>
<pre>
Sphere is an &lt;Sphere&gt; ID: 5160
Extrude NURBS is an &lt;Extrude NURBS&gt; ID: 5116
Cube is an &lt;Cube&gt; ID: 5159
</pre>
<p>So now that we know both the type name (within the angle <> brackets) and ID for an Extrude Nurbs. By creating an object, selecting it and running the script above we now can determine the values for type ID and type name of any object.</p>
<p>Using these values we can check if objects are of a certain kind:</p>
<div class="codesnip-container" >
<div class="python codesnip"><span class="kw1">import</span> c4d<br />
<span class="kw1">if</span> __name__ == <span class="st0">&quot;__main__&quot;</span>:<br />
&nbsp; &nbsp; doc = c4d.<span class="me1">documents</span>.<span class="me1">GetActiveDocument</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; selected = doc.<span class="me1">GetActiveObjects</span><span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="kw2">len</span><span class="br0">&#40;</span>selected<span class="br0">&#41;</span> <span class="sy0">&gt;</span> <span class="nu0">0</span>: &nbsp;<span class="co1"># we have one or more selected objects in the scene</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> ob <span class="kw1">in</span> selected:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> ob.<span class="me1">GetTypeName</span><span class="br0">&#40;</span><span class="br0">&#41;</span> == <span class="st0">&quot;Extrude NURBS&quot;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;Yeeehaaaw&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;Drat&quot;</span></div>
</div>
<p>Step 2 &#8211; check if it is an Extrude Nurbs &#8211; done!</p>
<h3>Performing Commands on Objects in a Python Script</h3>
<p>Now that we can traverse the selected objects in a scene and know when we encounter an object of a specific type (in our case a Extrude Nurbs) we need to perform some action on them. In this example we want to convert the Extrude Nurbs in a polygon object and have the front and back cap connected with the body (by default, the caps are disconnect from the extruded polygons).</p>
<p>At first, we see what steps would be involved when doing it manually:</p>
<ol>
<li>select the object</li>
<li>perform &#8220;Make Editable&#8221;</li>
<li>select all created children</li>
<li>connect the objects and delete the originals</li>
<li>use &#8220;optimize&#8221; to connect the caps to the body</li>
</ol>
<p>To perform these steps we could write the instructions one after the other within the <em>if</em>-statement. This would result in ugly &#8220;spaghetti-code&#8221; though and we could use the code we have so far for other purposes as well. Last time we saw how a function is defined in Python so we will make use of that and put the code that performs all the above steps into a function.</p>
<div class="codesnip-container" >
<div class="python codesnip"><span class="kw1">def</span> MakeExtrudeEditable<span class="br0">&#40;</span>doc,op<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="kw1">pass</span></div>
</div>
<p>This is the body of our function. We give it the name <em>MakeExtrudeEditable</em>. We define two parameters that we pass from the outside. A reference to the current scene (doc) and a reference to the object we want to convert to a polygon object (op). <em>pass</em> is a placeholder for now that does nothing but Python requires a statement within the function.</p>
<p>The whole script looks like this:</p>
<div class="codesnip-container" >
<div class="python codesnip"><span class="kw1">import</span> c4d</p>
<p><span class="kw1">def</span> MakeExtrudeEditable<span class="br0">&#40;</span>doc,op<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="kw1">pass</span></p>
<p><span class="kw1">if</span> __name__ == <span class="st0">&quot;__main__&quot;</span>:<br />
&nbsp; &nbsp; doc = c4d.<span class="me1">documents</span>.<span class="me1">GetActiveDocument</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; selected = doc.<span class="me1">GetActiveObjects</span><span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="kw2">len</span><span class="br0">&#40;</span>selected<span class="br0">&#41;</span> <span class="sy0">&gt;</span> <span class="nu0">0</span>: &nbsp;<span class="co1"># we have one or more selected objects in the scene</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> ob <span class="kw1">in</span> selected:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> ob.<span class="me1">GetTypeName</span><span class="br0">&#40;</span><span class="br0">&#41;</span> == <span class="st0">&quot;Extrude NURBS&quot;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MakeExtrudeEditable<span class="br0">&#40;</span>doc,ob<span class="br0">&#41;</span></div>
</div>
<p>We need to define our function before the main code so that it is known to Python once we call it from there. Instead of the <em>print</em>-statement from before we now call our own function within the inner most <em>if</em>-statement once we are sure the object is an Extrude Nurbs.</p>
<p>Now for the action. As the list of selected objects might contain several objects we need to make sure the object in question is the only one selected.  So we need to select the object. The BaseDocument class provides a method called <em>SetActiveObject</em> that has two parameters: the object and the mode. By default the mode is set to SELECTION_NEW which sets the selection to the object used as first parameter. An existing selection will be gone. That&#8217;s exactly what we want. So we call the method using the default parameter, ie. we omit the second parameter <em>mode</em>.</p>
<div class="codesnip-container" >
<div class="python codesnip"><span class="kw1">def</span> MakeExtrudeEditable<span class="br0">&#40;</span>op,doc<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; doc.<span class="me1">SetActiveObject</span><span class="br0">&#40;</span>op<span class="br0">&#41;</span></div>
</div>
<p>To perform a command that is called from a menu or icon in Cinema 4D the c4d module provides the <em>CallCommand()</em> function. It expects an ID that represents the command. To find out that ID we need to open the Command Manager in Cinema 4D. Using the name filter we can search for the &#8220;Make Editable&#8221; command. Once we select it from the list of available commands the Command Manager shows the ID at the bottom where we can assign custom shortcuts. This is the number we need to use with the <em>CallCommand()</em> function.</p>
<p>The commands we need to perform in sequence are: <em>Make Editable</em> which converts the Extrude Nurbs in a hierarchy of separate polygon objects with the topmost selected. To connect these objects we need to select them: using the <em>Select Children</em> command we add the two child objects to the already selected parent polygon object. A last we use <em>Connect+Delete</em> to create a single polygon object and get rid of the separate parts.</p>
<div class="codesnip-container" >
<div class="python codesnip"><span class="kw1">def</span> MakeExtrudeEditable<span class="br0">&#40;</span>op,doc<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; doc.<span class="me1">SetActiveObject</span><span class="br0">&#40;</span>op<span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; c4d.<span class="me1">CallCommand</span><span class="br0">&#40;</span><span class="nu0">12236</span><span class="br0">&#41;</span> &nbsp; &nbsp; <span class="co1"># Make Editable</span><br />
&nbsp; &nbsp; c4d.<span class="me1">CallCommand</span><span class="br0">&#40;</span><span class="nu0">100004768</span><span class="br0">&#41;</span> <span class="co1"># Select Children</span><br />
&nbsp; &nbsp; c4d.<span class="me1">CallCommand</span><span class="br0">&#40;</span><span class="nu0">16768</span><span class="br0">&#41;</span> &nbsp; &nbsp; <span class="co1"># Connect+Delete</span></div>
</div>
<p>After performing all those steps we end up with a single polygon object that is selected. The front and rear cap are still disconnected from the body though.</p>
<div class="info-box"><br />
One disadvantage of the <em>CallCommand()</em> in Cinema 4D is the way it records separate Undo steps for each call to the function. This makes it impossible to have a single Undo for the whole script as the separate steps are recorded to the Undo stack individually.<br />
</div>
<p>For the next step &#8211; Optimize &#8211; we switch from using CallCommand() to the c4d.utils module&#8217;s <em>SendModelingCommand()</em>. With CallCommand() we are limited to simple functions that do not require settings for the tool. Optimize has several options though that we cannot set using <em>CallCommand()</em>.</p>
<p>The <em>SendModelingCommand()</em> requires several parameters. Beside the command itself it expects a list of objects and an optional <em>BaseContainer</em> object with the settings.</p>
<p>Here is the script:</p>
<div class="codesnip-container" >
<div class="python codesnip"><span class="kw1">def</span> MakeExtrudeEditable<span class="br0">&#40;</span>doc,op<span class="br0">&#41;</span> :<br />
&nbsp; &nbsp; doc.<span class="me1">SetActiveObject</span><span class="br0">&#40;</span>op<span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; c4d.<span class="me1">CallCommand</span><span class="br0">&#40;</span><span class="nu0">12236</span><span class="br0">&#41;</span> &nbsp; &nbsp; <span class="co1"># Make Editable</span><br />
&nbsp; &nbsp; c4d.<span class="me1">CallCommand</span><span class="br0">&#40;</span><span class="nu0">100004768</span><span class="br0">&#41;</span> <span class="co1"># Select Children</span><br />
&nbsp; &nbsp; c4d.<span class="me1">CallCommand</span><span class="br0">&#40;</span><span class="nu0">16768</span><span class="br0">&#41;</span> &nbsp; &nbsp; <span class="co1"># Connect+Delete</span><br />
&nbsp;<br />
&nbsp; &nbsp; ob = doc.<span class="me1">GetActiveObject</span><span class="br0">&#40;</span><span class="br0">&#41;</span> &nbsp; &nbsp;<span class="co1"># store the active object for later use</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> ob == <span class="kw2">None</span>: <span class="kw1">return</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; bc = c4d.<span class="me1">BaseContainer</span><span class="br0">&#40;</span><span class="br0">&#41;</span> &nbsp; &nbsp;<span class="co1"># create a base container to hold the settings</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> bc == <span class="kw2">None</span>: <span class="kw1">return</span></p>
<p>&nbsp; &nbsp; bc.<span class="me1">SetData</span><span class="br0">&#40;</span>c4d.<span class="me1">MDATA_OPTIMIZE_POLYGONS</span>, <span class="kw2">True</span><span class="br0">&#41;</span> &nbsp; &nbsp; &nbsp; <span class="co1"># remove 1 or 2 point polygons &nbsp; &nbsp;</span><br />
&nbsp; &nbsp; bc.<span class="me1">SetData</span><span class="br0">&#40;</span>c4d.<span class="me1">MDATA_OPTIMIZE_UNUSEDPOINTS</span>, <span class="kw2">True</span><span class="br0">&#41;</span> &nbsp; <span class="co1"># remove unused points</span><br />
&nbsp; &nbsp; bc.<span class="me1">SetData</span><span class="br0">&#40;</span>c4d.<span class="me1">MDATA_OPTIMIZE_POINTS</span>, <span class="kw2">True</span><span class="br0">&#41;</span> &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># remove double points</span><br />
&nbsp; &nbsp; bc.<span class="me1">SetData</span><span class="br0">&#40;</span>c4d.<span class="me1">MDATA_OPTIMIZE_TOLERANCE</span>, <span class="nu0">0.5</span><span class="br0">&#41;</span> &nbsp; &nbsp; &nbsp; <span class="co1"># tolerance</span></p>
<p>&nbsp; &nbsp; doc.<span class="me1">AddUndo</span><span class="br0">&#40;</span> c4d.<span class="me1">UNDOTYPE_CHANGE_NOCHILDREN</span>, ob <span class="br0">&#41;</span><br />
&nbsp; &nbsp; c4d.<span class="me1">utils</span>.<span class="me1">SendModelingCommand</span><span class="br0">&#40;</span>c4d.<span class="me1">MCOMMAND_OPTIMIZE</span>, <span class="br0">&#91;</span>ob<span class="br0">&#93;</span>, c4d.<span class="me1">MODIFY_ALL</span>, bc, doc<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span></div>
</div>
<p>First, we store the selected object after the <em>Connect+Delete</em> command for later use. We make sure that we have an selected object. If that is not the case we exit for now using <em>return</em>.</p>
<p>For the <em>SendModelingCommand()</em> function we need some settings. So we create an object of the type <em>BaseContainer()</em>. If that fails (ie. bc == None) we stop and exit the function again. If everything worked we continue.</p>
<p>We need to set all the parameters for the Optimize command by filling the <em>BaseContainer</em> bc with the according values using <em>SetData()</em>. We want to remove 1 and 2 point polygons, unused points, double points and merge all points within a certain tolerance (eg. 0.5 units). You can find the parameter names from the Python documentation. For some parameters you need to check out the C++ SDK documentation though.</p>
<p>To add <em>Optimize</em> to the Undo Stack we call the document&#8217;s <em>AddUndo</em> method. To make this work we need to add a <em>StartUndo()</em> and <em>EndUndo()</em> call outside our <em>for</em>-Loop also.</p>
<p>So here is the complete script:</p>
<div class="codesnip-container" >
<div class="python codesnip"><span class="kw1">import</span> c4d</p>
<p><span class="co1"># =======================================================================</span><br />
<span class="kw1">def</span> MakeExtrudeEditable<span class="br0">&#40;</span>doc,op<span class="br0">&#41;</span> :<br />
&nbsp; &nbsp; doc.<span class="me1">SetActiveObject</span><span class="br0">&#40;</span>op<span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; c4d.<span class="me1">CallCommand</span><span class="br0">&#40;</span><span class="nu0">12236</span><span class="br0">&#41;</span> &nbsp; &nbsp; <span class="co1"># Make Editable</span><br />
&nbsp; &nbsp; c4d.<span class="me1">CallCommand</span><span class="br0">&#40;</span><span class="nu0">100004768</span><span class="br0">&#41;</span> <span class="co1"># Select Children</span><br />
&nbsp; &nbsp; c4d.<span class="me1">CallCommand</span><span class="br0">&#40;</span><span class="nu0">16768</span><span class="br0">&#41;</span> &nbsp; &nbsp; <span class="co1"># Connect+Delete</span><br />
&nbsp;<br />
&nbsp; &nbsp; ob = doc.<span class="me1">GetActiveObject</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> ob == <span class="kw2">None</span>: <span class="kw1">return</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; bc = c4d.<span class="me1">BaseContainer</span><span class="br0">&#40;</span><span class="br0">&#41;</span>&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="kw1">if</span> bc == <span class="kw2">None</span>: <span class="kw1">return</span></p>
<p>&nbsp; &nbsp; bc.<span class="me1">SetData</span><span class="br0">&#40;</span>c4d.<span class="me1">MDATA_OPTIMIZE_POLYGONS</span>, <span class="kw2">True</span><span class="br0">&#41;</span> &nbsp; &nbsp; &nbsp; <span class="co1"># remove 1 or 2 point polygons &nbsp; &nbsp;</span><br />
&nbsp; &nbsp; bc.<span class="me1">SetData</span><span class="br0">&#40;</span>c4d.<span class="me1">MDATA_OPTIMIZE_UNUSEDPOINTS</span>, <span class="kw2">True</span><span class="br0">&#41;</span> &nbsp; <span class="co1"># remove unused points</span><br />
&nbsp; &nbsp; bc.<span class="me1">SetData</span><span class="br0">&#40;</span>c4d.<span class="me1">MDATA_OPTIMIZE_POINTS</span>, <span class="kw2">True</span><span class="br0">&#41;</span> &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># remove double points</span><br />
&nbsp; &nbsp; bc.<span class="me1">SetData</span><span class="br0">&#40;</span>c4d.<span class="me1">MDATA_OPTIMIZE_TOLERANCE</span>, <span class="nu0">0.5</span><span class="br0">&#41;</span> &nbsp; &nbsp; &nbsp; <span class="co1"># tolerance</span></p>
<p>&nbsp; &nbsp; doc.<span class="me1">AddUndo</span><span class="br0">&#40;</span> c4d.<span class="me1">UNDOTYPE_CHANGE_NOCHILDREN</span>, ob <span class="br0">&#41;</span><br />
&nbsp; &nbsp; c4d.<span class="me1">utils</span>.<span class="me1">SendModelingCommand</span><span class="br0">&#40;</span>c4d.<span class="me1">MCOMMAND_OPTIMIZE</span>, <span class="br0">&#91;</span>ob<span class="br0">&#93;</span>, c4d.<span class="me1">MODIFY_ALL</span>, bc, doc<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span></p>
<p>
<span class="co1"># =======================================================================</span><br />
<span class="kw1">if</span> __name__ == <span class="st0">&quot;__main__&quot;</span>:<br />
&nbsp; &nbsp; doc = c4d.<span class="me1">documents</span>.<span class="me1">GetActiveDocument</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; selected = doc.<span class="me1">GetActiveObjects</span><span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">if</span> <span class="kw2">len</span><span class="br0">&#40;</span>selected<span class="br0">&#41;</span> <span class="sy0">&gt;</span> <span class="nu0">0</span> :<br />
&nbsp; &nbsp; &nbsp; &nbsp; c4d.<span class="me1">StopAllThreads</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; doc.<span class="me1">StartUndo</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> ob <span class="kw1">in</span> selected:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span> ob.<span class="me1">GetTypeName</span><span class="br0">&#40;</span><span class="br0">&#41;</span> == <span class="st0">&quot;Extrude NURBS&quot;</span> <span class="br0">&#41;</span> :<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MakeExtrudeEditable<span class="br0">&#40;</span>doc,ob<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; doc.<span class="me1">EndUndo</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; c4d.<span class="me1">DrawViews</span><span class="br0">&#40;</span>c4d.<span class="me1">DRAWFLAGS_NO_ANIMATION</span><span class="br0">&#41;</span></div>
</div>
<h3>Conclusion</h3>
<p>As you can see we need to understand a few principles of Python and the internal workings of Cinema 4D to write a script. On the other hand it is not really hard once we overcome that hurdle. In the future it should be straight forward to replace our <em>MakeExtrudeEditable()</em> function with a function that performs different steps. The main part of getting all selected objects and traversing them to perform the desired steps remains the same. Taking a couple of minutes to think about a script and writing it certainly beats doing the same tedious task over and over again throughout a work day or even over weeks and months. </p>
<p>Putting it all together writing this simple script required to learn few principles:</p>
<ul>
<li>how to interact with the scene (the document) through BaseDocument class</li>
<li>how to get the selected objects in a scene using GetActiveObjects</li>
<li>using the for statement to go through that list</li>
<li>writing our own function to capsulate the steps we want to perform on the objects</li>
<li>using CallCommand() to use menu commands in our script</li>
<li>using SendModelingCommand() to use more complex commands that require parameters</li>
<li>a brief glimpse on how to use Undo()</li>
</ul>
<div class="download-box">Download File: <a href="http://cgrebel.com/downloads/c4dscripts/MakeExtrudeNurbsEditable.py.zip">Make Extrude NURBS editable Python script</a></div>
<blockquote><p>
Do you have a question or want to learn something specific? Leave a reply below or use the contact form from the top of the page!
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://cgrebel.com/2011/01/p4d102-selected-objects/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>P4D101 &#8211; Getting started with Python in Cinema 4D</title>
		<link>http://cgrebel.com/2011/01/p4d101-starting/</link>
		<comments>http://cgrebel.com/2011/01/p4d101-starting/#comments</comments>
		<pubDate>Sun, 02 Jan 2011 13:11:15 +0000</pubDate>
		<dc:creator>Martin</dc:creator>
				<category><![CDATA[Cinema 4D Scripting]]></category>
		<category><![CDATA[Python Scripting]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Cinema 4D]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://cgrebel.com/?p=426</guid>
		<description><![CDATA[The Python integration into Cinema 4D is quite thorough. There are several places where you can use Python to script and Python is integrated as a first class citizen with the same level of access like Cinema 4D's internal scripting language COFFEE as well as the C++ API. Learn how to get started with Python scripting in Cinema 4D.]]></description>
			<content:encoded><![CDATA[<p>The Python integration into Cinema 4D is quite thorough. There are several places where you can use Python to script and Python is integrated as a first class citizen with the same level of access like Cinema 4D&#8217;s internal scripting language COFFEE as well as the C++ API.</p>
<p>There are different places in which you can use Python:</p>
<ul>
<li>as Python Script</li>
<li>as  Python Generator</li>
<li>as Python Tag</li>
<li>as Python Xpresso Node</li>
<li>as Python Plugin</li>
</ul>
<p>As you can see, there are plenty of options to use Python in Cinema 4D. For a start let us focus on using a Python script &#8211; ignoring the other possibilities for now.</p>
<p><span id="more-426"></span></p>
<h2>Python Script</h2>
<p>Python scripts are probably the most immediate way to perform automated tasks. To create a script open the <em>Script Manager (Python)</em> from the Python menu. Also open the <em>Console (Python)</em> from the same menu. The console will show you error messages and output from <em>print </em>statements in your Python script.</p>
<p>When you have not done something in Cinema 4D before the Script Manager should already contain this code:</p>
<div class="codesnip-container" >
<div class="python codesnip"><span class="kw1">import</span> c4d<br />
<span class="kw1">from</span> c4d <span class="kw1">import</span> gui<br />
<span class="co1">#Welcome to the world of Python</span></p>
<p><span class="kw1">def</span> main<span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; gui.<span class="me1">MessageDialog</span><span class="br0">&#40;</span><span class="st0">&#8216;Hello World!&#8217;</span><span class="br0">&#41;</span></p>
<p><span class="kw1">if</span> __name__==<span class="st0">&#8216;__main__&#8217;</span>:<br />
&nbsp; &nbsp; main<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</div>
<h3>The executed part</h3>
<p>Now let us examine this a bit closer. For a start let us ignore the first few statements and look at the parts that actually do something:</p>
<div class="codesnip-container" >
<div class="python codesnip"><span class="kw1">if</span> __name__==<span class="st0">&#8216;__main__&#8217;</span>:<br />
&nbsp; &nbsp; main<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</div>
<p>This is the part that get&#8217;s executed when Cinema 4D runs the Python script. When a Python program is loaded as script, Python sets the variable <em>__name__</em> to the value of &#8220;__main__&#8221;. This way a Python script knows it has been called as script rather than having been imported.</p>
<p>This brings us to the first statements &#8211; the import:</p>
<h3>Imports</h3>
<div class="codesnip-container" >
<div class="python codesnip"><span class="kw1">import</span> c4d<br />
<span class="kw1">from</span> c4d <span class="kw1">import</span> gui</div>
</div>
<p>The <em>import</em> statement loads existing Python code from another file &#8211; a <em>module</em>. The Python binding to Cinema 4D is defined by the c4d module. By importing the c4d module you gain access to Cinema 4D&#8217;s functions through the API (Application Programming Interface). Within the c4d module there are several specialized packages that handle different parts of the API. One of those packages is c4d.gui that deals with the graphical user interface functions and classes.</p>
<div class="codesnip-container" >
<div class="python codesnip"><span class="kw1">from</span> c4d <span class="kw1">import</span> gui</div>
</div>
<p>This statements imports the gui package from the c4d module. This is an optional step that makes the gui functions available without the need to prefix them with the c4d module name (the namespace). Without the above statement you would have to explicitly prefix the gui.MessageDialog() function with c4d.</p>
<div class="codesnip-container" >
<div class="python codesnip"><span class="kw1">import</span> c4d<br />
c4d.<span class="me1">gui</span>.<span class="me1">MessageDialog</span><span class="br0">&#40;</span><span class="st0">&quot;Hello World!&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</div>
<h3>Condition and Code Block</h3>
<p>Back to the actual code:</p>
<div class="codesnip-container" >
<div class="python codesnip"><span class="kw1">if</span> __name__== <span class="st0">&#8216;__main__&#8217;</span>:<br />
&nbsp; &nbsp; main<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</div>
<p>The conditional <em>if</em> statement checks the <em>__name__</em> variable for the value of &#8216;__main__&#8217;. If this is true &#8211; so the program was loaded as script &#8211; the code block in the if statement is executed. Here, the previously defined function <em>main()</em> is called.</p>
<div class="info-box"><br />
In Python a code block (=scope) like within a if statement or a function is defined by indenting the code rather than having curly brackets { } like eg. in COFFEE. You need to pay attention to have the identical number of whitespace characters when indenting. Different levels indicate different code blocks. Generally I would advise you to use spaces and no tab characters. Indenting by four spaces is a widely used format.<br />
</div>
<h3>Print</h3>
<p>Instead of defining a function first and then calling it when the script is executed you can also write your code here:</p>
<div class="codesnip-container" >
<div class="python codesnip"><span class="kw1">if</span> __name__ == &nbsp;<span class="st0">&quot;__main__&quot;</span> :<br />
&nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;Hello World!&quot;</span></div>
</div>
<p>This would output the text &#8220;Hello World!&#8221; into the Python console rather than popping up a dialog window like <em>MessageDialog()</em> does. The advantage of <em>print</em> is that it does not interrupt the execution of the script like the dialog window that requires the user to press the OK button. So print is a great way of outputting debugging data to the console that can show you what is happening in your script. This makes it easier to find errors when something goes wrong. The disadvantage of print is that is only shows in the console which a normal user generally does not have open when using scripts. So avoid print for displaying data that is important to the user.</p>
<h3>Functions</h3>
<p>In the example code there is definition of the function main() that is being called from the script rather than immediate code:</p>
<div class="codesnip-container" >
<div class="python codesnip"><span class="kw1">def</span> main<span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; gui.<span class="me1">MessageDialog</span><span class="br0">&#40;</span><span class="st0">&#8216;Hello World!&#8217;</span><span class="br0">&#41;</span></div>
</div>
<p>This <em>def</em> statement defines a function named <em>main()</em>. The code following the definition is indented to contain the code block for the function. In this case a popup window with the text &#8220;Hello World!&#8221; is shown. This function only contains this one statement and does not have parameters or return values. We will have a look on how to use those in a later article.</p>
<p>In the example the function <em>main()</em> is called below using the statement <em>main()</em>.</p>
<h3>Summary</h3>
<p>This was a very brief introduction into Python scripting in Cinema 4D by looking at the default script that is generated when opening the Script Manager.</p>
<p>What we have learned is:</p>
<ul>
<li>how Python scripts are executed in Cinema 4D (it defines __name__ as &#8220;__main__&#8221; conforming to general Python scripts)</li>
<li>how Python can access Cinema 4D&#8217;s API through the <em>c4d module</em> and how to use <em>import</em> to use the c4d module and its packages</li>
<li>how to use the <em>print</em> statement to output text to the Python console</li>
<li>how to define a basic function using the <em>def</em> statement and how to call it</li>
</ul>
<p>In future articles we actually will have a look at how to do something meaningful in a Python script like working with the current scene and how to use variables to store values and how to save your scripts so you can reuse them.</p>
<p>For further information have a look at the <a href="http://docs.python.org/release/2.6.4/">Python 2.6.4 documentation</a> and <a href="http://www.plugincafe.com">Maxon&#8217;s documentation</a> on their Python integration.</p>
<blockquote><p>
Do you have a question or want to learn something specific? Leave a reply below or use the contact form from the top of the page!
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://cgrebel.com/2011/01/p4d101-starting/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Python&#8217;s the Lingua Franca of CG</title>
		<link>http://cgrebel.com/2010/12/pythons-the-lingua-franca-of-cg/</link>
		<comments>http://cgrebel.com/2010/12/pythons-the-lingua-franca-of-cg/#comments</comments>
		<pubDate>Thu, 30 Dec 2010 22:38:59 +0000</pubDate>
		<dc:creator>Martin</dc:creator>
				<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://cgrebel.com/?p=409</guid>
		<description><![CDATA[I think it is pretty safe to say that Python has become the mostly widely adopted scripting language across many, many CG and VFX applications. A few years back almost every tool had its very own choice of scripting language. They pretty much still exist and from pure history they are still heavily used for [...]]]></description>
			<content:encoded><![CDATA[<p>I think it is pretty safe to say that Python has become the mostly widely adopted scripting language across many, many CG and VFX applications. A few years back almost every tool had its very own choice of scripting language. They pretty much still exist and from pure history they are still heavily used for existing tools or just for the fact that developers, TDs and artists rely on them because they know them well. Python increasingly replaces them across the board though.</p>
<h2><span id="more-409"></span>Widespread Industy Support&#8230;</h2>
<p>So let&#8217;s have a brief look what applications support Python these days &#8211; and this list is definitely neither complete nor well researched as it is what comes to my mind right now:</p>
<h3>3D Applications</h3>
<ul>
<li>Maya (natively using MEL, a TCL dialect)</li>
<li>Softimage (using the Windows scripting host, previously supported VBScript and JScript)</li>
<li>Cinema 4D (with R12 Python is now officially supported, until then only COFFEE, a JavaScript like language was available for scripting)</li>
<li>Modo (in addition to Perl and LUA)</li>
<li>Houdini (starting to replacing HScript)</li>
<li>Vue</li>
<li>Blender</li>
<li>Realflow</li>
<li>Massive</li>
<li>Renderfarm tools like RenderPal, Deadline, Cube!, DrQueue</li>
</ul>
<h3>VFX Applications</h3>
<ul>
<li>Nuke (in addition to TCL)</li>
<li>Fusion (in addition to eyeonscript which is based on LUA)</li>
<li>Toxik &#8211; now bundled as Composite with Maya etc.</li>
</ul>
<h2>&#8230; means what?</h2>
<p>That sound very promising. One might now think learning Python will allow you to script all those applications and use the same scripts with different applications. They all support Python, don&#8217;t they?</p>
<p>Unfortunately the language itself is just a minor part. Just like a C++ program does not automatically run on Windows, OSX and Linux a Python script does not work across applications. They integrate Python differently and more importantly, they have very different APIs (Application Programming Interfaces).</p>
<p>It not as grave though. Python clearly has the advantage that you do not need to learn the language each time, just broaden your vocabulary. Python is easy enough to be picked up by an artist but powerful enough to provide all the bells and whistles for an advanced programmer. So it scales well. Scripts grow in complexity over time and Python allows that without the need to resort to clumsy workarounds. It allows to build up libraries and resort to existing ones to build upon blocks of prior, tested code.</p>
<h2>What now?</h2>
<p>The first step in learning a programming language would be to get acquainted with its basic syntax. How to declare variables to store values and basic flow control. Luckily Python is pretty easy to pick up in this regard.</p>
<p>After knowing the basics you need to learn about you applications APIs that allow you to interact with your scene data. That&#8217;s more taxing. Some applications record your interaction into an log that shows what APIs were used. That is a good starting point to pick up the necessary functions to call. More often than not you would need to consult the documentation or get some scripts from the Web and examine them. Use them as starting points and modify them to do what you need.</p>
<p>Initial scripts should help you get things done faster. Often it&#8217;s enough to collect several steps you do manually into a script &#8211; making them work as macros that perform several steps at once. Next, you might want to give them some intelligence. Have some conditions in there that do things differently depending on what data they work or what parameters you provide for them. From there the sky is the limit.</p>
]]></content:encoded>
			<wfw:commentRss>http://cgrebel.com/2010/12/pythons-the-lingua-franca-of-cg/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Season Greetings</title>
		<link>http://cgrebel.com/2010/12/season-greetings/</link>
		<comments>http://cgrebel.com/2010/12/season-greetings/#comments</comments>
		<pubDate>Fri, 24 Dec 2010 10:07:54 +0000</pubDate>
		<dc:creator>Martin</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Showcase]]></category>
		<category><![CDATA[Animation]]></category>
		<category><![CDATA[Cinema 4D]]></category>

		<guid isPermaLink="false">http://cgrebel.com/?p=402</guid>
		<description><![CDATA[Have some nice holidays!
Here is a small animation our team at Effects Garden did as season greetings. Enjoy!
]]></description>
			<content:encoded><![CDATA[<p>Have some nice holidays!</p>
<p>Here is a small animation our team at Effects Garden did as season greetings. Enjoy!</p>
<p><a href="http://www.youtube.com/watch?v=xSiepmrMMn0"><img src="http://img.youtube.com/vi/xSiepmrMMn0/2.jpg"></a></p>
<p><a href="http://www.youtube.com/watch?v=xSiepmrMMn0">Click here</a> to view the video on YouTube.</p>

]]></content:encoded>
			<wfw:commentRss>http://cgrebel.com/2010/12/season-greetings/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Camaro Studio Environment Rendering</title>
		<link>http://cgrebel.com/2010/10/camaro-studio-environment-rendering/</link>
		<comments>http://cgrebel.com/2010/10/camaro-studio-environment-rendering/#comments</comments>
		<pubDate>Sun, 31 Oct 2010 14:41:07 +0000</pubDate>
		<dc:creator>Martin</dc:creator>
				<category><![CDATA[My Work]]></category>
		<category><![CDATA[Showcase]]></category>
		<category><![CDATA[CG]]></category>
		<category><![CDATA[Cinema 4D]]></category>
		<category><![CDATA[V-Ray]]></category>

		<guid isPermaLink="false">http://cgrebel.com/?p=387</guid>
		<description><![CDATA[I could not stop it and continued to tweak the car painting shaders of the Camaro. I put it in a studio environment with an analogue color to the paint job. The result is at least quite fitting for Halloween  
These images are straight out of the renderer (Cinema 4D with V-Ray) without post [...]]]></description>
			<content:encoded><![CDATA[<p>I could not stop it and continued to tweak the car painting shaders of the Camaro. I put it in a studio environment with an analogue color to the paint job. The result is at least quite fitting for Halloween <img src='http://cgrebel.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>These images are straight out of the renderer (Cinema 4D with V-Ray) without post work.</p>
<p><a rel="lightbox" href="http://cgrebel.com/wp-content/uploads/2010/10/fxg_camaro_studio_front_960.jpg"><img class="alignnone" src="http://cgrebel.com/wp-content/uploads/2010/10/fxg_camaro_studio_front_612.jpg" alt="" width="612" height="344" /></a></p>
<p><a rel="lightbox" href="http://cgrebel.com/wp-content/uploads/2010/10/fxg_camaro_studio_rear_960.jpg"><img class="alignnone" src="http://cgrebel.com/wp-content/uploads/2010/10/fxg_camaro_studio_rear_612.jpg" alt="" width="612" height="344" /></a></p>
<p><a rel="lightbox" href="http://cgrebel.com/wp-content/uploads/2010/10/fxg_camaro_studio_side_960.jpg"><img class="alignnone" src="http://cgrebel.com/wp-content/uploads/2010/10/fxg_camaro_studio_side_612.jpg" alt="" width="612" height="344" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://cgrebel.com/2010/10/camaro-studio-environment-rendering/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Camera Work</title>
		<link>http://cgrebel.com/2010/10/camera-work/</link>
		<comments>http://cgrebel.com/2010/10/camera-work/#comments</comments>
		<pubDate>Tue, 26 Oct 2010 09:00:53 +0000</pubDate>
		<dc:creator>Martin</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Resources]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Camera]]></category>
		<category><![CDATA[CG]]></category>
		<category><![CDATA[Filmmaking]]></category>

		<guid isPermaLink="false">http://cgrebel.com/?p=384</guid>
		<description><![CDATA[One thing that many CG artists don&#8217;t get right at first is camera movement. It&#8217;s all too easy to do things with the camera that is not possible in the real world. Moves that defy inertia and gravity &#8211; or even space as it moves through obstacles.
One great way to learn about camera work is [...]]]></description>
			<content:encoded><![CDATA[<p>One thing that many CG artists don&#8217;t get right at first is camera movement. It&#8217;s all too easy to do things with the camera that is not possible in the real world. Moves that defy inertia and gravity &#8211; or even space as it moves through obstacles.</p>
<p>One great way to learn about camera work is <a href="http://www.hollywoodcamerawork.us/mc_index.html" target="_blank">Hollywood Camera Work Master Class</a>. They now also released an add-on <a href="http://www.hollywoodcamerawork.us/hm_index.html" target="_self">Hot Moves</a> for those trailer-worthy shots. The master class is a great resource on learning how to block out shots &#8211; especially character driven ones. Hot moves is more about those &#8220;wow&#8221; moments.</p>
<p>Luckily, all those moves are relatively easy to do in CG at no cost. Once you start to move in the physical realm it really gets expensive and complicated. So enjoy what you can do in CG <img src='http://cgrebel.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  Oh, and pay close attention to your frame rates, exposure and shutter speeds while you are at it. It is equally important to the way you move your camera to get a great result.</p>
<p><span style="color: #999999;">Disclaimer: I am not affiliated with Hollywood Camera Work. I just happen to find their training videos a great resource that I like to recommend to you.</span></p>
]]></content:encoded>
			<wfw:commentRss>http://cgrebel.com/2010/10/camera-work/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ND Filters</title>
		<link>http://cgrebel.com/2010/08/nd-filters/</link>
		<comments>http://cgrebel.com/2010/08/nd-filters/#comments</comments>
		<pubDate>Wed, 25 Aug 2010 21:23:37 +0000</pubDate>
		<dc:creator>Martin</dc:creator>
				<category><![CDATA[Film Production]]></category>
		<category><![CDATA[Background]]></category>
		<category><![CDATA[Camera]]></category>
		<category><![CDATA[Filmmaking]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://cgrebel.com/?p=378</guid>
		<description><![CDATA[For a guy that has a background in software development and CG/post production the ever wonderful world of production craft and equipment can be full of small technical hurdles. Sometimes it takes a moment or two to make sense of what others have honed for decades.

When looking into matte boxes and filters one of that [...]]]></description>
			<content:encoded><![CDATA[<p>For a guy that has a background in software development and CG/post production the ever wonderful world of production craft and equipment can be full of small technical hurdles. Sometimes it takes a moment or two to make sense of what others have honed for decades.<br />
<span id="more-378"></span><br />
When looking into matte boxes and filters one of that &#8220;what?!&#8221; moments was when I looked at ND (neutral density) filters. Wading through filter stages and form factors like 4&#215;4 and 4&#215;5.65, graduated and what not it took me a while to make sense of their rating. Assuming that a 0.3 filter would let through 30% of the light was quickly ridiculed by filters with a factor of 1.2 or higher. So the guess of a multiplication factor was ruled out quickly.</p>
<p>The number is the optical density which is the logarithm of the ratio of the light passing through the filter to the light entering the filter. Sounds complicated but isn&#8217;t really. An optical density of 0.3 reduces brightness by 50%, thus halfing it (1 stop in photography terms). The math is simple:  0.3 = -log<sub>10</sub> ( 0.5/1.0 ). 0.5 is the amount of light (intensity) passing through the filter, 1.0 is the intensity before the filter. (You can just get rid of that part in the equation as the intensity in front of the filter always is 1.0)</p>
<p>Still does not make sense?</p>
<p>Reversing it might help: With an optical density of 0.3 the amount of light passing through the filter is:  I = 10<sup>-0.3</sup> which is 0.5</p>
<p>So suddenly a filter of 1.0 or 1.5 makes sense:</p>
<p>10<sup>-1.0</sup> = 0.1 or 10%<br />
10<sup>-1.5</sup> = 0.03 or 3%</p>
<p>Once I was past this hurdle it got a bit easier to grok and I was ready to learn why you should use an hot mirror when stepping down considerable and what the heck a hot mirror actually does &#8211; and how it relates to infrared and the properties of sensors (or film should you still work analog).</p>
]]></content:encoded>
			<wfw:commentRss>http://cgrebel.com/2010/08/nd-filters/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cinema 4D (2010#28)</title>
		<link>http://cgrebel.com/2010/07/cinema-4d-201028/</link>
		<comments>http://cgrebel.com/2010/07/cinema-4d-201028/#comments</comments>
		<pubDate>Mon, 19 Jul 2010 18:18:31 +0000</pubDate>
		<dc:creator>Martin</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Resources]]></category>
		<category><![CDATA[Cinema 4D]]></category>

		<guid isPermaLink="false">http://cgrebel.com/?p=370</guid>
		<description><![CDATA[Resouces

nice resources for animators from Graphite 9

]]></description>
			<content:encoded><![CDATA[<h3>Resouces</h3>
<ul>
<li><a href="http://www.graphite9.com/CinemaDownloads.html" target="_blank">nice resources</a> for animators from Graphite 9</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://cgrebel.com/2010/07/cinema-4d-201028/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Industry News (2010#28)</title>
		<link>http://cgrebel.com/2010/07/industry-news-201028/</link>
		<comments>http://cgrebel.com/2010/07/industry-news-201028/#comments</comments>
		<pubDate>Mon, 19 Jul 2010 18:17:45 +0000</pubDate>
		<dc:creator>Martin</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Performance Capture]]></category>
		<category><![CDATA[Virtual Camera]]></category>

		<guid isPermaLink="false">http://cgrebel.com/?p=372</guid>
		<description><![CDATA[OptiTrack Insight Virutal Camera System looks like an affordable solution for a virtual camera system as used on films like Ironman 2 (see Cinefex issue 122, pg.59 showing ILM&#8217;s real-time virtual camera system) or Avatar.
]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.vizworld.com/2010/07/optitracks-insight-virtual-camera-system/" target="_blank">OptiTrack Insight Virutal Camera System</a> looks like an affordable solution for a virtual camera system as used on films like Ironman 2 (see <a href="http://cinefex.com/" target="_blank">Cinefex</a> issue 122, pg.59 showing ILM&#8217;s real-time virtual camera system) or Avatar.</p>
]]></content:encoded>
			<wfw:commentRss>http://cgrebel.com/2010/07/industry-news-201028/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

