<?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>Jose&#039;s sketchbook</title>
	<atom:link href="http://www.joesfer.com/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.joesfer.com</link>
	<description>A personal collection of ideas, programming and shiny stuff</description>
	<lastBuildDate>Sun, 17 Mar 2013 11:26:02 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Color Stippling</title>
		<link>http://www.joesfer.com/?p=149</link>
		<comments>http://www.joesfer.com/?p=149#comments</comments>
		<pubDate>Sat, 16 Mar 2013 10:03:39 +0000</pubDate>
		<dc:creator>Jose</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[blue-noise]]></category>
		<category><![CDATA[color]]></category>
		<category><![CDATA[dithering]]></category>
		<category><![CDATA[halftoning]]></category>
		<category><![CDATA[multi class]]></category>
		<category><![CDATA[NPR]]></category>
		<category><![CDATA[sampling]]></category>
		<category><![CDATA[stippling]]></category>

		<guid isPermaLink="false">http://www.joesfer.com/?p=149</guid>
		<description><![CDATA[At the end of writing my post on Stippling and Blue Noise, I left it wondering how would this apply if we wanted to use colors. Just to recapitulate, the idea of stippling is to generate a reproduction of an image by halftoning, making use of fixed-size points distributed on a plane. The points need [...]]]></description>
				<content:encoded><![CDATA[<div id="attachment_159" class="wp-caption aligncenter" style="width: 505px"><a href="http://www.joesfer.com/wp-content/uploads/2013/03/130076155940007923_stippling_4096.png" target="_blank"><img class=" wp-image-159    " alt="Stippling using a CMYK color basis. Original image from pennlive.com" src="http://www.joesfer.com/wp-content/uploads/2013/03/ragamalaparna_crop.png" width="495" height="495" /></a><p class="wp-caption-text">Stippling applying the Hard Disk Sampling method with a CMYK color basis. Original image from <a href="http://blog.pennlive.com/go/2012/02/ragamala_troupe_to_present_tra.html" target="_blank">pennlive.com</a>. Click for full resolution.</p></div>
<p>At the end of writing my post on <a title="Stippling and Blue Noise" href="http://www.joesfer.com/?p=108">Stippling and Blue Noise</a>, I left it wondering how would this apply if we wanted to use colors. Just to recapitulate, the idea of stippling is to generate a reproduction of an image by <a title="Halftoning" href="http://en.wikipedia.org/wiki/Halftone" target="_blank">halftoning</a>, making use of fixed-size points distributed on a plane. The points need to be distributed in a way which is both aesthetically pleasing (for which we place the points carefully in a way which shows <a title="Blue Noise" href="http://en.wikipedia.org/wiki/Colors_of_noise#Blue_noise" target="_blank">Blue Noise</a> properties) and be spaced according to the local density of the image. If we use black dots over a white background, this simply means we need to add more dots on the darker areas of the image.</p>
<p>This is all better summarized in this awesome video:<br />
<iframe src="http://player.vimeo.com/video/33091687" width="400" height="225" frameborder="0"></iframe></p>
<p>It also illustrates very well why we would want to use a computer program to carry out this task <img src='http://www.joesfer.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<h1>More than one sample class</h1>
<p>So the principle looks simple enough for black and white. Now, if we want to add color, the first immediate question is: Can we not just do the same for each individual <strong><span style="color: #ff0000;">R</span>, <span style="color: #339966;">G</span>, <span style="color: #3366ff;">B</span></strong> or <strong><span style="color: #00ffff;">C</span>, <span style="color: #ff00ff;">M</span>, <span style="color: #c1c100;">Y</span>, K</strong> channel? As it turns out, that would more or less work, but it will look <em>worse</em> than the black and white image. The reason for it is that combining individual Blue Noise distributions does <strong>not</strong> lead to a result with the same propertie. This is easy to reason about by looking at the first row on <strong>Figure 1</strong> below: if we place samples carefully by enforcing a minimum distance between each one of them, but do so on a per-class (color) basis, nothing is preventing points belonging to different classes from ending up close to each other. Similarly, as shown in the second row, merging all samples into a single uniform distribution, and then sepparating them again into individual classes will cause noticeable gaps in the individual classes&#8217; distribution.</p>
<p><div id="attachment_151" class="wp-caption aligncenter" style="width: 500px"><a href="http://www.joesfer.com/wp-content/uploads/2013/03/uniformClassesVsUniformResult.png"><img class=" wp-image-151  " alt="Top row: Uniform individual classes does not lead to uniform combined result. Bottom row: Uniform result does not lead to uniform individual classes." src="http://www.joesfer.com/wp-content/uploads/2013/03/uniformClassesVsUniformResult.png" width="490" height="323" /></a><p class="wp-caption-text"><strong>Figure 1.</strong> Top row: Uniform individual classes does not lead to uniform combined result.<br />Bottom row: Uniform result does not lead to uniform individual classes.<br />Image by [Wei 10], click for a better view.</p></div>A solution to this is to consider all color channels into a common distribution, but preserve class information while sampling. Li-Yi Wei wrote about this naming the method <strong><em>Multi-Class Blue Noise </em><a href="http://research.microsoft.com/apps/pubs/default.aspx?id=12182">[Wei 10]</a></strong>. In his paper, Li-Yi discusses two methods of achieving color stippling (or, in general, distribution of N classes of elements in the same space). On the simpler approach called <em>Hard-Disk Sampling</em>, which is derived from the original Poisson Sampling or <em>Dart-Throwing</em> method <strong><a href="http://www.google.co.uk/url?sa=t&amp;rct=j&amp;q=cook%2C%20r.%20l.%201986.%20stochastic%20sampling%20in%20computer%20graphics.%20acm%20transactions%20on%20graphics%205%2C%201%2C%2051%E2%80%9372.&amp;source=web&amp;cd=1&amp;ved=0CB8QFjAA&amp;url=http%3A%2F%2Fciteseerx.ist.psu.edu%2Fviewdoc%2Fdownload%3Fdoi%3D10.1.1.84.5916%26rep%3Drep1%26type%3Dpdf&amp;ei=b3_BTsOHNsiV8gP9hNzDBA&amp;usg=AFQjCNGattXhiwkd6R5HOwYe6dCxBGZF-A&amp;cad=rja" target="_blank">[Cook 86]</a></strong>, we work by extending the acceptance test to check neighbour points of <em>all</em> classes. This is done building a symmetrical distance matrix for each pair of classes where the elements on the diagonal correspond to the distance of each class to itself. Note that setting every other element in the conflict check matrix to zero degenerates into regular dart-throwing (first row of <strong>Figure 1</strong>). On the other extreme, treating samples as exclusive disks for all classes leads to the bottom row in <strong>Figure 1</strong>, where the  individual classes are not well distributed. The matrix generation method (refer to the paper for details) falls inbetween these two extremes, giving classes a priority according to their relevance on each region, and decreases the conflict radius with less-important classes (allowing for a higher density of these) so that the expected density of the combined result is proportional to the input reference.</p>
<p>Therefore the Hard-Disk Sampling method boils down to an easy extension of the original dart-throwing approach, where we check this carefully-built conflict matrix to decide whether or not to accept each randomly-generated color sample, producing results that sit inbetween the two extreme cases depicted in <strong>Figure 1</strong>. This sounds easy-enough to give it a shot with a quick prototype!</p>
<h1>Hard-Disk Sampling implementation</h1>
<div id="attachment_158" class="wp-caption alignnone" style="width: 505px"><a href="http://www.joesfer.com/wp-content/uploads/2013/03/result1.png" target="_blank"><img class=" wp-image-158  " alt="" src="http://www.joesfer.com/wp-content/uploads/2013/03/result1.png" width="495" height="202" /></a><p class="wp-caption-text"><strong>Figure 2. </strong>Stippling result using a CMYK color basis with subtractive blending. The source image is &#8220;Portrait of Jack Nicholson&#8221; by Martin Schoeller. Click for full resolution version.</p></div>
<p>&nbsp;</p>
<p>The first detail to bear in mind is that the minimum distance values for each class <em>vary</em> in space: in our stippling case, each individual pixel of the original image has potentially a different color distribution which translates into different importance for each component of the color basis we choose. The distance matrix for a 2D image will thus be 2N dimensional, where N is the number of point classes we consider.</p>
<p>How to choose the point classes depends on the look we&#8217;re after: we can use for instance Red, Green and Blue and combine them with additive blending over a black background to emulate a screen. Or we could use Cyan, Magenta, Yellow and Black over a white background to emulate print. Any combination will do, but obviously the more classes and the closer their respective colors are to the original image, the better match. I personally find the results of <em>restrictive</em> color basis like the two aforementioned to be more interesting, as they let you better appreciate how the result emerges from the combination of all the individual samples rather than from a perfect match of each individual sample.</p>
<p>The UI in the prototype provided will let you pick a color basis, which has a blending mode associated: (+) for additive, and (-) for subtractive. Then the density for each individual color class is extracted from each pixel on the source image by projecting the original RGB values to the elements of the chosen basis. I&#8217;ve tried different approaches to generate the per-channel densities, and what seems to be working fairly well is to take a projection of each source color into the color basis by doing the dot-product of their resulting vectors in RGB space.</p>
<p><img src="http://www.joesfer.com/wp-content/ql-cache/quicklatex.com-265153dd0ab328632fa038e9798af4c1_l3.png" class="ql-img-inline-formula " alt="&#92;&#109;&#97;&#116;&#104;&#98;&#102;&#123;&#83;&#125;&#32;&#61;&#32;&#91;&#83;&#94;&#82;&#44;&#32;&#83;&#94;&#71;&#44;&#32;&#83;&#94;&#66;&#93;" title="Rendered by QuickLaTeX.com" height="20" width="128" style="vertical-align: -5px;"/> = source pixel</p>
<p><img src="http://www.joesfer.com/wp-content/ql-cache/quicklatex.com-09f8f8a1100216398f87c1d59f0eb3f5_l3.png" class="ql-img-inline-formula " alt="&#92;&#109;&#97;&#116;&#104;&#98;&#102;&#123;&#67;&#125;&#32;&#61;&#32;&#123;&#32;&#91;&#67;&#95;&#48;&#94;&#82;&#44;&#32;&#67;&#95;&#48;&#94;&#71;&#44;&#32;&#67;&#95;&#48;&#94;&#66;&#93;&#44;&#32;&#91;&#67;&#95;&#49;&#94;&#82;&#44;&#32;&#67;&#95;&#49;&#94;&#71;&#44;&#32;&#67;&#95;&#49;&#94;&#66;&#93;&#44;&#32;&#46;&#46;&#46;&#44;&#32;&#91;&#67;&#95;&#123;&#78;&#45;&#49;&#125;&#94;&#82;&#44;&#32;&#67;&#95;&#123;&#78;&#45;&#49;&#125;&#94;&#71;&#44;&#32;&#67;&#95;&#123;&#78;&#45;&#49;&#125;&#94;&#66;&#93;&#32;&#125;" title="Rendered by QuickLaTeX.com" height="21" width="434" style="vertical-align: -6px;"/> = desired N-class color basis</p>
<p><img src="http://www.joesfer.com/wp-content/ql-cache/quicklatex.com-00f6da719d9bee6e68eea964498456e0_l3.png" class="ql-img-inline-formula " alt="&#92;&#109;&#97;&#116;&#104;&#98;&#102;&#123;&#68;&#95;&#83;&#125;&#32;&#61;&#32;&#91;&#32;&#68;&#95;&#48;&#44;&#32;&#68;&#95;&#49;&#44;&#32;&#46;&#46;&#46;&#44;&#32;&#68;&#95;&#123;&#110;&#45;&#49;&#125;&#32;&#93;" title="Rendered by QuickLaTeX.com" height="18" width="181" style="vertical-align: -5px;"/> = densites for <img src="http://www.joesfer.com/wp-content/ql-cache/quicklatex.com-e2e3ca05df769ab46780b3f23e81212e_l3.png" class="ql-img-inline-formula " alt="&#92;&#109;&#97;&#116;&#104;&#98;&#102;&#123;&#83;&#125;" title="Rendered by QuickLaTeX.com" height="12" width="10" style="vertical-align: 0px;"/>, where:</p>
<p><img src="http://www.joesfer.com/wp-content/ql-cache/quicklatex.com-8427a87ab67b08b32c145052ce837417_l3.png" class="ql-img-inline-formula " alt="&#80;&#32;&#61;&#32;&#92;&#109;&#97;&#116;&#104;&#98;&#102;&#123;&#83;&#125;&#32;&#92;&#99;&#100;&#111;&#116;&#32;&#92;&#109;&#97;&#116;&#104;&#98;&#102;&#123;&#67;&#95;&#105;&#125;" title="Rendered by QuickLaTeX.com" height="15" width="81" style="vertical-align: -3px;"/> is the projection of the input sample into the i-th color basis vector.<br />
<img src="http://www.joesfer.com/wp-content/ql-cache/quicklatex.com-1b0f0bf5bd5ceb8a4b1225937fb97f8b_l3.png" class="ql-img-inline-formula " alt="&#68;&#95;&#105;&#32;&#61;&#32;&#92;&#102;&#114;&#97;&#99;&#123;&#49;&#125;&#123;&#80;&#125;" title="Rendered by QuickLaTeX.com" height="22" width="57" style="vertical-align: -6px;"/> for additive basis, and<br />
<img src="http://www.joesfer.com/wp-content/ql-cache/quicklatex.com-4679e666d8c36452907e5c2c5e3a17c3_l3.png" class="ql-img-inline-formula " alt="&#68;&#95;&#105;&#32;&#61;&#32;&#92;&#102;&#114;&#97;&#99;&#123;&#49;&#125;&#123;&#49;&#45;&#80;&#125;" title="Rendered by QuickLaTeX.com" height="23" width="75" style="vertical-align: -7px;"/> for subtractive basis</p>
<p>Note this is a non-linear response to intensity, which I found to work a bit better than the linear one.<span style="color: #ff0000;"><br />
</span></p>
<pre><code><code><p class="ql-center-picture"><img src="http://www.joesfer.com/wp-content/ql-cache/quicklatex.com-c373393ccf41af0ca4cb0225fa880233_l3.png" height="256" width="348" class="ql-img-picture " alt="Rendered by QuickLaTeX.com" title="Rendered by QuickLaTeX.com"/></p></code>
</code></code></pre>
<p>Going back to the sampling issue shown in <strong>Figure 1</strong>, I was wondering: if for our particular case of stippling where we are interested in the combined result and not so much in the individual color channels, could we not get away with the simpler method of a uniform combined result, as shown in the second row, despite of the less uniform distribution of the individual color pigments?</p>
<p>To test that out it was easy to simplify the algorithm to calculate the distance matrix based solely on the brightness of the input pixels, disregarding class information. Then, when once a random sample had been accepted based exclusively on the spatial density, its class is chosen randomly from the available color basis according to a probability distribution matching the underlying pixel color.</p>
<div id="attachment_161" class="wp-caption aligncenter" style="width: 505px"><a href="http://www.joesfer.com/wp-content/uploads/2013/03/uniformComparison.png" target="_blank"><img class=" wp-image-161 " alt="Comparison between single class uniform distribution (left) taking only distances between samples into account, and hard disk sampling (right) producing a uniform distribution both per class and on the combined result. Note how the sharp edges around the eyes are defined similarly, but the results differ in the smooth areas." src="http://www.joesfer.com/wp-content/uploads/2013/03/uniformComparison.png" width="495" height="834" /></a><p class="wp-caption-text"><strong>Figure 3.</strong> Comparison between single class uniform distribution (left) taking only distances between samples into account, and hard disk sampling (right) producing a uniform distribution both per class and on the combined result. Note how the sharp edges around the eyes are defined similarly, but the results differ in the smooth areas. Click for a larger view.</p></div>
<p>With this test I was expecting to still get the good spatial distribution of a single-class dart throwing, and an on-average correct color: each individual sample would be off, but on average the sum of the samples should more or less match the tone of the underlying region. <strong>Figure 3</strong> shows the comparison between the two methods, which differ much more than I was expecting. Truth is that in high-frequency regions the adaptive sampling predominates over the more even distribution of the former method &#8211; the difference is more evident in the smoother gradients on the image such as the clothing, where you can see that my naive simplification tends to produce noisier results. Having a uniform distribution for the combined result helps achieving good gradients of density, and having good per-class distribution produces more uniform, smoother tones, with less color clumps.</p>
<h2>Retries</h2>
<p>An interesting aspect of the Hard Disk Sampling method as proposed in Wei&#8217;s paper is that at the core of it, we still rely on random sampling to place points in the image. This is very fast at the beginning but once the image starts to fill up, it becomes increasingly unlikely for a sample to be accepted. More so, since for a given position on the image, we&#8217;ve prioritized the classes (the densities of each class), it may be extremely hard to place samples of faint tones in the image by just random chance. Recall from the <a title="Stippling and Blue Noise" href="http://www.joesfer.com/?p=108">original stippling post</a> that this is the reason why Dart-throwing is so easy to implement, but also so slow for most practical uses.</p>
<div id="attachment_157" class="wp-caption aligncenter" style="width: 510px"><a href="http://www.joesfer.com/wp-content/uploads/2013/03/restart.png"><img class="size-full wp-image-157" alt="A blue sample couldn't find a suitable place in the image by random chance, so it is 'forced' by removing much more likely green samples which will be reintroduced eventually." src="http://www.joesfer.com/wp-content/uploads/2013/03/restart.png" width="500" height="432" /></a><p class="wp-caption-text"><strong>Figure 4:</strong> A blue sample couldn&#8217;t find a suitable place in the image by random chance, so it is &#8216;forced&#8217; by removing much more likely green samples which will be reintroduced eventually.</p></div>
<p>There are ways to be smarter about the way we place samples (other than rely on random chance), but the alternative method proposed in the paper is to <em>discard</em> existing samples after we&#8217;ve given up trying to place a new one. This is simple and ingenuous: we can think of this as having samples that settle down int he image, and from time to time we need to &#8220;shake&#8221; portions of the image to dust them off and allow room for improbable samples to settle. More rigurously though <img src='http://www.joesfer.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  what we do is rely on the fact that the &#8220;probable&#8221; samples we remove to make room have a better chance to settle on the final image again, and the result will converge faster than if we expect the unlikely samples to find a suitable spot by randomness alone. This also leads to a better color rendition with less noise as you can see in <strong>Figure 3</strong>.</p>
<h1>Downloads</h1>
<p>I wrote a small prototype application which does color stippling of an input image using the Hard Disk Sampling method described in this post. It will generate both images and XML data files which should be easy to parse and render with other applications.</p>
<p>The code is written in C# and is available as usual on GitHub at: <a href="https://github.com/joesfer/ColorStippling" target="_blank">https://github.com/joesfer/ColorStippling</a><br />
And you can also download the precompiled binaries directly from <a href="http://joesfer.com/wp-content/uploads/programming/C/ColorStipplingBinaries.zip" target="_blank">here</a>.</p>
<p style="text-align: center;"><a href="http://www.joesfer.com/wp-content/uploads/2013/03/screenshot.jpg"><img class="aligncenter  wp-image-160" alt="screenshot" src="http://www.joesfer.com/wp-content/uploads/2013/03/screenshot.jpg" width="731" height="471" /></a></p>
<h1>References</h1>
<p><a href="http://research.microsoft.com/apps/pubs/default.aspx?id=12182"><strong>[Wei 10]</strong></a> Li-Yi Wei. 2010. <em>Multi-Class Blue Noise Sampling</em>. Siggraph.</p>
<p><a href="http://www.google.co.uk/url?sa=t&amp;rct=j&amp;q=cook%2C%20r.%20l.%201986.%20stochastic%20sampling%20in%20computer%20graphics.%20acm%20transactions%20on%20graphics%205%2C%201%2C%2051%E2%80%9372.&amp;source=web&amp;cd=1&amp;ved=0CB8QFjAA&amp;url=http%3A%2F%2Fciteseerx.ist.psu.edu%2Fviewdoc%2Fdownload%3Fdoi%3D10.1.1.84.5916%26rep%3Drep1%26type%3Dpdf&amp;ei=b3_BTsOHNsiV8gP9hNzDBA&amp;usg=AFQjCNGattXhiwkd6R5HOwYe6dCxBGZF-A&amp;cad=rja" target="_blank"><strong>[Cook 86]</strong></a>  Cook, R. L. 1986. <em>Stochastic sampling in computer graphics.</em> ACM Transactions on Graphics 5, 1, 51–72.</p>
<p>&nbsp;</p>
<div class="tweetthis" style="text-align:left;"><p> <a target="_blank" rel="nofollow" class="tt" href="http://twitter.com/home/?status=Color+Stippling+http%3A%2F%2Fjoesfer.com%2F%3Fp%3D149"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/twitter/tt-twitter.png" alt="Post to Twitter" /></a> <a target="_blank" rel="nofollow" class="tt" href="http://delicious.com/post?url=http://www.joesfer.com/?p=149&amp;title=Color+Stippling"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/delicious/tt-delicious.png" alt="Post to Delicious" /></a> <a target="_blank" rel="nofollow" class="tt" href="http://www.facebook.com/share.php?u=http://www.joesfer.com/?p=149&amp;t=Color+Stippling"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/facebook/tt-facebook.png" alt="Post to Facebook" /></a> <a target="_blank" rel="nofollow" class="tt" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http://www.joesfer.com/?p=149&amp;title=Color+Stippling&amp;summary=%0D%0A%0D%0AAt+the+end+of+writing+my+post+on+Stippling+and+Blue+Noise%2C+I+left+it+wondering+how+would+this+apply+if+we+wanted+to+use+colors.+Just+to+recapit...&amp;source=Jose&#039;s sketchbook"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/linkedin/tt-linkedin.png" alt="Post to LinkedIn" /></a></p></div>]]></content:encoded>
			<wfw:commentRss>http://www.joesfer.com/?feed=rss2&#038;p=149</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Transmittance Function Maps</title>
		<link>http://www.joesfer.com/?p=154</link>
		<comments>http://www.joesfer.com/?p=154#comments</comments>
		<pubDate>Sat, 01 Sep 2012 21:07:09 +0000</pubDate>
		<dc:creator>Jose</dc:creator>
				<category><![CDATA[misc]]></category>
		<category><![CDATA[paper]]></category>
		<category><![CDATA[participating media]]></category>
		<category><![CDATA[publication]]></category>
		<category><![CDATA[real-time rendering]]></category>

		<guid isPermaLink="false">http://www.joesfer.com/?p=154</guid>
		<description><![CDATA[It is not very often that I get a chance to talk about what I do in my day job. I am privileged to work with very smart people in great projects, but it is a fact that these projects are normally protected with teeth and claws, and that includes their technology. In fact I [...]]]></description>
				<content:encoded><![CDATA[<div id="attachment_155" class="wp-caption aligncenter" style="width: 501px"><a href="http://www.joesfer.com/wp-content/uploads/2013/03/image.jpg"><img class="size-full wp-image-155" alt="Wrath of The Titans" src="http://www.joesfer.com/wp-content/uploads/2013/03/image.jpg" width="491" height="292" /></a><p class="wp-caption-text">Scenes from Wrath of the Titans involve extremely dense volumetric objects. We adapt the Transmittance Function Mapping algorithm for high quality interactive previsualization and tuning of those media. (c) 2012 Warner Bros. Entertainment</p></div>
<p>It is not very often that I get a chance to talk about what I do in my day job. I am privileged to work with very smart people in great projects, but it is a fact that these projects are normally protected with teeth and claws, and that includes their technology. In fact I would normally keep the topics on this sketchbook deliberately <em>away</em> from possible overlaps to avoid breaking any confidentiality arrangement and also because there&#8217;s simply lots of other interesting topics I want to still look into and share!</p>
<p>I was fortunate to collaborate on a project with some colleagues at <a title="MPC" href="http://www.moving-picture.com" target="_blank">MPC</a>, which ended up being published at <a title="DigiPro2012" href="http://www.olm.co.jp/digipro2012/" target="_blank">DigiPro 2012</a>, and therefore is public domain now. The text is on a bit more technical tone than I would normally like to have in these posts, but it has some pretty pictures which I think are worth skimming through.</p>
<p>The topic is about rendering of volumetric effects in real-time, including lighting and shadowing. We wanted to give our artists a tool to work with their fluid simulations without always requiring slow offline renders, thus reducing their iteration times.</p>
<p>The technical paper can be found here: <a title="TransmittanceMaps" href="http://www.joesfer.com/publications/bringingTransmittanceFunctionMapsToTheScreen.pdf" target="_blank">Bringing Transmittance Function Maps to the Screen: Wrath of the Titans and Prometheus</a></p>
<div class="tweetthis" style="text-align:left;"><p> <a target="_blank" rel="nofollow" class="tt" href="http://twitter.com/home/?status=Transmittance+Function+Maps+http%3A%2F%2Fjoesfer.com%2F%3Fp%3D154"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/twitter/tt-twitter.png" alt="Post to Twitter" /></a> <a target="_blank" rel="nofollow" class="tt" href="http://delicious.com/post?url=http://www.joesfer.com/?p=154&amp;title=Transmittance+Function+Maps"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/delicious/tt-delicious.png" alt="Post to Delicious" /></a> <a target="_blank" rel="nofollow" class="tt" href="http://www.facebook.com/share.php?u=http://www.joesfer.com/?p=154&amp;t=Transmittance+Function+Maps"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/facebook/tt-facebook.png" alt="Post to Facebook" /></a> <a target="_blank" rel="nofollow" class="tt" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http://www.joesfer.com/?p=154&amp;title=Transmittance+Function+Maps&amp;summary=%0D%0A%0D%0AIt+is+not+very+often+that+I+get+a+chance+to+talk+about+what+I+do+in+my+day+job.+I+am+privileged+to+work+with+very+smart+people+in+great+project...&amp;source=Jose&#039;s sketchbook"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/linkedin/tt-linkedin.png" alt="Post to LinkedIn" /></a></p></div>]]></content:encoded>
			<wfw:commentRss>http://www.joesfer.com/?feed=rss2&#038;p=154</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Source code migration to GitHub</title>
		<link>http://www.joesfer.com/?p=139</link>
		<comments>http://www.joesfer.com/?p=139#comments</comments>
		<pubDate>Sun, 01 Jan 2012 20:37:57 +0000</pubDate>
		<dc:creator>Jose</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[cmake]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[repository]]></category>
		<category><![CDATA[source code]]></category>
		<category><![CDATA[svn]]></category>

		<guid isPermaLink="false">http://www.joesfer.com/?p=139</guid>
		<description><![CDATA[Happy New Year! Just a quick post to write about the ongoing migration to GitHub and source code revamping I&#8217;m currently carrying out. Since the beginning of this sketchbook it&#8217;s been my intention to provide with the source code of the projects with the hope that anyone finds it valuable as a complement for the [...]]]></description>
				<content:encoded><![CDATA[<p>Happy New Year!</p>
<p>Just a quick post to write about the ongoing migration to GitHub and source code revamping I&#8217;m currently carrying out.</p>
<p>Since the beginning of this sketchbook it&#8217;s been my intention to provide with the source code of the projects with the hope that anyone finds it valuable as a complement for the articles. So far this had been done in a less-than-ideal way by attaching zip/rar files with the contents of a Visual Studio solution. Some other times this hasn&#8217;t been even possible since the code depended on my internal libraries and therefore it was hard to isolate. My intention is therefore to slowly migrate the existing code from <a href="http://en.wikipedia.org/wiki/Apache_Subversion" target="_blank">SVN</a> to <a href="http://en.wikipedia.org/wiki/Git_%28software%29" target="_blank">git</a>, reorganize the library dependencies as git submodules so this no longer becomes a limitation to distribute code, and upload the suitable projects to <a href="https://github.com/joesfer" target="_blank">GitHub</a>.</p>
<p>Another change will be moving to cross-platform development. So far I&#8217;ve been developing primary under Windows/VS, but this has become a limitation the times I&#8217;ve been asked about, for example, a Mac versions of a given plugin. Instead of having to compile the code for each version of Windows/Mac/Linux available out there, I&#8217;m removing the dependency on the IDE so that the interested people are able to build the code themselves (this will hopefully help finding bugs as well). For this I&#8217;m using <a href="http://www.cmake.org/" target="_blank">CMake</a>, which is a cross-platform build system which from a description file will be able to generate Visual Studio solutions under windows, GCC makefiles under Linux, and so on so forth. One exception to this will be the C# projects, for which I&#8217;m sticking to Windows for now.</p>
<p>So the GitHub repository can be found at <a href="https://github.com/joesfer" target="_blank">https://github.com/joesfer</a> &#8211; I&#8217;ll be fleshing it out in the next weeks, please let me know of any issue you may find.</p>
<p>Please bear with me as these are quite big changes and I&#8217;m also learning as I go <img src='http://www.joesfer.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  hopefully it&#8217;ll be much better in the long run.</p>
<p>&nbsp;</p>
<div class="tweetthis" style="text-align:left;"><p> <a target="_blank" rel="nofollow" class="tt" href="http://twitter.com/home/?status=Source+code+migration+to+GitHub+http%3A%2F%2Fjoesfer.com%2F%3Fp%3D139"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/twitter/tt-twitter.png" alt="Post to Twitter" /></a> <a target="_blank" rel="nofollow" class="tt" href="http://delicious.com/post?url=http://www.joesfer.com/?p=139&amp;title=Source+code+migration+to+GitHub"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/delicious/tt-delicious.png" alt="Post to Delicious" /></a> <a target="_blank" rel="nofollow" class="tt" href="http://www.facebook.com/share.php?u=http://www.joesfer.com/?p=139&amp;t=Source+code+migration+to+GitHub"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/facebook/tt-facebook.png" alt="Post to Facebook" /></a> <a target="_blank" rel="nofollow" class="tt" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http://www.joesfer.com/?p=139&amp;title=Source+code+migration+to+GitHub&amp;summary=Happy+New+Year%21%0D%0A%0D%0AJust+a+quick+post+to+write+about+the+ongoing+migration+to+GitHub+and+source+code+revamping+I%27m+currently+carrying+out.%0D%0A%0D%0ASince+...&amp;source=Jose&#039;s sketchbook"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/linkedin/tt-linkedin.png" alt="Post to LinkedIn" /></a></p></div>]]></content:encoded>
			<wfw:commentRss>http://www.joesfer.com/?feed=rss2&#038;p=139</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Stippling and Blue Noise</title>
		<link>http://www.joesfer.com/?p=108</link>
		<comments>http://www.joesfer.com/?p=108#comments</comments>
		<pubDate>Thu, 17 Nov 2011 07:00:18 +0000</pubDate>
		<dc:creator>Jose</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[blue-noise]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[NPR]]></category>
		<category><![CDATA[poisson disk]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[stippling]]></category>
		<category><![CDATA[synthesis]]></category>
		<category><![CDATA[voronoi]]></category>
		<category><![CDATA[wang tiles]]></category>

		<guid isPermaLink="false">http://www.joesfer.com/?p=108</guid>
		<description><![CDATA[It’s been a while since the last post, and truth is I’ve spent most of my spare time lately devoted to my photography. Back however to more technical matters, one of the topics I find fascinating is NPR techniques, and particularly Stippling as an interesting example of them. I&#8217;ve been reading about it for some [...]]]></description>
				<content:encoded><![CDATA[<p><strong><a href="http://www.joesfer.com/wp-content/uploads/2011/11/headerImg2.jpg"><img class="aligncenter size-full wp-image-133" title="headerImg" src="http://www.joesfer.com/wp-content/uploads/2011/11/headerImg2.jpg" alt="" width="500" height="166" /></a><br />
</strong></p>
<p>It’s been a while since the last post, and truth is I’ve spent most of my spare time lately devoted to my <a href="http://www.flickr.com/photos/joesfer/" target="_blank">photography</a>. Back however to more technical matters, one of the topics I find fascinating is <a href="http://en.wikipedia.org/wiki/Non-photorealistic_rendering" target="_blank">NPR</a> techniques, and particularly <a title="Stippling" href="http://en.wikipedia.org/wiki/Stippling" target="_blank">Stippling</a> as an interesting example of them. I&#8217;ve been reading about it for some time now, and learnt a couple of interesting things along the way, so I thought I would share them in a post.</p>
<p>When stippling an image, we’re basically interested in generating a distribution of points with a density distribution matching the tones of the original image, the size of the points is generally constant, and we add more or less of them to create darker or lighter tones. In these areas it is important to generate a distribution free of sampling artifacts, which reveal as patterns in the image –the eye is really good picking up these patterns-.</p>
<p>So essentially all we need is a big number of points distributed randomly, and a way of quantizing their required density when we place them over the image. To generate the points, the first approach would be using purely random points. It turns out, however that pure randomness does not lead to aesthetically pleasing results, as points tend to clutter in areas and leave empty spaces. On the other extreme, using a perfectly homogeneous scheme –say a grid- would lead to artifacts in the form of aliasing. We thus need something still random but still somewhat a bit more even.</p>
<div id="attachment_116" class="wp-caption aligncenter" style="width: 510px"><a href="http://www.joesfer.com/wp-content/uploads/2011/11/randomvsblue.jpg"><img class="size-full wp-image-116 " title="randomvsblue" src="http://www.joesfer.com/wp-content/uploads/2011/11/randomvsblue.jpg" alt="" width="500" height="173" /></a><p class="wp-caption-text">Random pattern on the left, Blue noise on the right. Image from |Kopf 06|</p></div>
<p><strong></strong>In the in-between land there’s a flavor of noise called <a href="http://en.wikipedia.org/wiki/Colors_of_noise#Blue_noise" target="_blank">Blue Noise</a>, which is the name given to a particular distribution of frequencies with “minimal low frequency components and no concentrated spikes in energy”. This means that we have no structural aliasing given by the low frequencies, and even spacing with minimal cluttering. It is generally accepted that blue noise properties make for some of the best sampling patterns for a wide range of applications (see <strong><strong><a href="http://jgt.akpeters.com/papers/Ascencio-Lopez10/" target="_blank">[Lopez 10]</a></strong></strong>) .</p>
<div id="attachment_113" class="wp-caption alignleft" style="width: 260px"><a href="http://www.joesfer.com/wp-content/uploads/2011/11/noisepatterns.png"><img class="size-full wp-image-113 " title="noisepatterns" src="http://www.joesfer.com/wp-content/uploads/2011/11/noisepatterns.png" alt="" width="250" height="750" /></a><p class="wp-caption-text">Noise patterns: the top image shows structural repetition. The middle one displays radial patterns and clustering. The third one displays blue noise characteristics. Images from |Kopf 06|</p></div>
<p>One way of generating point distributions with blue noise properties is by means of a <strong>Poisson-Disk Distribution</strong> <strong><a href="http://www.google.co.uk/url?sa=t&amp;rct=j&amp;q=cook%2C%20r.%20l.%201986.%20stochastic%20sampling%20in%20computer%20graphics.%20acm%20transactions%20on%20graphics%205%2C%201%2C%2051%E2%80%9372.&amp;source=web&amp;cd=1&amp;ved=0CB8QFjAA&amp;url=http%3A%2F%2Fciteseerx.ist.psu.edu%2Fviewdoc%2Fdownload%3Fdoi%3D10.1.1.84.5916%26rep%3Drep1%26type%3Dpdf&amp;ei=b3_BTsOHNsiV8gP9hNzDBA&amp;usg=AFQjCNGattXhiwkd6R5HOwYe6dCxBGZF-A&amp;cad=rja" target="_blank"><strong>[Cook 86]</strong></a></strong>. One of the most straightforward ways of generating such distribution is by using a so called <em>Dart-Throwing Algorithm</em> <strong><a href="http://www.google.co.uk/url?sa=t&amp;rct=j&amp;q=cook%2C%20r.%20l.%201986.%20stochastic%20sampling%20in%20computer%20graphics.%20acm%20transactions%20on%20graphics%205%2C%201%2C%2051%E2%80%9372.&amp;source=web&amp;cd=1&amp;ved=0CB8QFjAA&amp;url=http%3A%2F%2Fciteseerx.ist.psu.edu%2Fviewdoc%2Fdownload%3Fdoi%3D10.1.1.84.5916%26rep%3Drep1%26type%3Dpdf&amp;ei=b3_BTsOHNsiV8gP9hNzDBA&amp;usg=AFQjCNGattXhiwkd6R5HOwYe6dCxBGZF-A&amp;cad=rja" target="_blank"><strong>[Cook 86]</strong></a></strong>, which generates candidate points in a random fashion over the plane, but will only accept each candidate if it lies at a minimum distance from every previous accepted sample. McCool and Fiume <a href="www.dgp.toronto.edu/%7Eelf/.misc/poissondisk.pdf" target="_blank"><strong>[McCool 82] </strong></a> describe a more practical variant<br />
of dart throwing, where the dart radius is gradually decreased as more samples are placed. The Dart-Throwing algorithm is therefore inherently sequential and slow due to its quadratic complexity, but the quality of the results is nevertheless high.</p>
<p>An important property of any distributions generated with the aforementioned variation proposed by McCool and Fiume is its <strong>progressiveness</strong>: Similarly to some <a href="http://en.wikipedia.org/wiki/Low-discrepancy_sequence" target="_blank">low-discrepancy sequences</a>, if we put all the generated points into a list of N elements, and draw only a portion of that list [1, N &lt; M], the resulting point distribution also covers the entire plane (as opposed to sweeping it), but simply does it with a lower density. This is important because it means that if we can stipple a spatial region with a given density by plotting all the points of a tile T, we will also be able to generate any lighter density by using the same T by plotting a smaller set of its points.</p>
<p>The amount of points we typically need to stipple an image, which is in the range of thousands in the best of cases, makes the straightforward implementation of the dart-throwing algorithm impracticable. A big part of the problem we’re facing with stippling is how to <strong><em>efficiently</em></strong> generate <em>lots</em> of points in a blue noise distribution. There is a significant amount of research on the matter, and the rest of the post will deal with a couple of approaches I liked and implemented myself, along with notes on related work.</p>
<h1>Efficient generation of Poisson-Disk Point Distributions</h1>
<p>To generate PD point distributions with blue noise properties there are several <em>families</em> of approaches, among which we have:</p>
<ul>
<li><strong>Incremental methods</strong>, which place samples sequentially. The Dart-Throwing algorithm described above is a basic example of them, but one could easily come up with more sophisticated implementations which made use of auxiliary structures such as hashing grids or trees to reduce the cost of the nearest-neighbor lookups. A proposal I found particularly interesting is described in the paper <strong></strong><strong></strong><strong><a href="http://jgt.akpeters.com/papers/Ascencio-Lopez10/" target="_blank">[Lopez 10]</a></strong>, further details on the implementation of this method are provided below.</li>
<li><strong>High-throughput methods</strong>: which usually rely a heavy precomputation stage but a very fast execution time. A prime example of this kind of algorithms is <strong><strong><a href="http://johanneskopf.de/publications/blue_noise/" target="_blank"><strong>[Kopf 06]</strong></a></strong></strong>, also implemented and described in this post. Also impressive results are obtained by <strong></strong><a href="http://research.microsoft.com/apps/pubs/default.aspx?id=70563" target="_blank"><strong>[Wei 08]</strong></a> with a GPU-based Poisson-Disk distribution generation algorithm, orders of magnitude faster than the sequential approach.</li>
<li><strong>Approaches based on Constrained Voronoi Diagrams (CVD)</strong>, where each sample corresponds to a cell. These approaches, despite being extremely expensive in time, generate probably the most pleasing distributions. <strong></strong><strong><a href="http://research.microsoft.com/apps/pubs/default.aspx?id=115797" target="_blank"><strong>[Hongwei 09]</strong></a></strong> report gains of 10x in execution time in their paper.</li>
</ul>
<div id="attachment_117" class="wp-caption alignright" style="width: 260px"><a href="http://www.joesfer.com/wp-content/uploads/2011/11/cvd1.png"><img class="size-full wp-image-117 " title="cvd" src="http://www.joesfer.com/wp-content/uploads/2011/11/cvd1.png" alt="" width="250" height="254" /></a><p class="wp-caption-text">Constrained Voronoi Tessellation to generate samples. Image from the paper |Hongwei 09|</p></div>
<p>The differences between types of approaches are both quality (depicted as even, perceptually pleasing distributions) and execution time. The best results seem to be obtained with CVDs or sequential algorithms, but their execution times are <em>orders of magnitude</em> slower than high-throughput approaches such as the one based in Wang Tiles, which run on real-time. These later generate a more noisy result however, which as we’ll see, may not be so much aesthetically pleasing for the particular case of stippling – Nevertheless blue noise sampling may be used for a variety of applications such as object or texture placement as the authors show in the <strong><strong><a href="research.microsoft.com/en-us/um/people/cohen/WangFinal.pdf" target="_blank">[Cohen 03]</a></strong></strong>, where the density of the distribution will likely be much less dense and speed is crucial.</p>
<p><strong><br />
</strong></p>
<h1>Adaptive Incremental Sampling</h1>
<p>The first one of the approaches I tried is the one described in the paper <strong></strong><strong><a href="http://jgt.akpeters.com/papers/Ascencio-Lopez10/" target="_blank">[Lopez 10]</a></strong>, which is a more efficient extension of a sequential algorithm with good quality results and decent execution time.</p>
<p>The key idea behind the approach is simple: having a sample point on the plane, and a minimum acceptance distance limiting how close any other sample can get to it, we build a disk and generate all subsequent samples on its boundary*, instead of randomly on the plane. For each accepted new sample, we calculate the intersection between its disk and the currently active one, and subtract a portion of the active boundary area –so no new samples will overlap-. When there’s no remaining boundary on the active disk, we de-queue it and proceed with the next one.</p>
<p><strong><a href="http://www.joesfer.com/wp-content/uploads/2011/11/AIS.png"><img class="aligncenter size-full wp-image-131" title="AIS" src="http://www.joesfer.com/wp-content/uploads/2011/11/AIS.png" alt="" width="500" height="500" /></a><br />
</strong></p>
<p>This defines a pattern in how the samples are generated, as new samples are only generated on the currently active disk, and their corresponding disks queued for later processing. The samples then <em>grow</em> across the image from an initial seed (which it’s quite <a href="http://vimeo.com/32238761" target="_blank">pretty to watch</a>!). To speed-up disk overlapping checks, a secondary image buffer is carried, where disks are rasterized. In order to accept a sample we have to first check whether the corresponding rasterized disk would overlap a non-empty pixel in the disk buffer.</p>
<p>The acceptance distance for any sample is given by the density distribution, i.e. the amount of black, in the region covered by the sample on the source image</p>
<p>* More precisely, an <em>angle</em> is sampled on the remaining boundary of the active disk. The new disk will be placed on the line that parts from the center along the direction defined by this angle, at a distance given by the image densities of both the active and the new disk.</p>
<div id="attachment_119" class="wp-caption alignnone" style="width: 624px"><a href="http://www.joesfer.com/wp-content/uploads/2011/11/stippledAIS2.png"><img class="size-full wp-image-119  " title="stippledAIS" src="http://www.joesfer.com/wp-content/uploads/2011/11/stippledAIS1.png" alt="" width="614" height="461" /></a><p class="wp-caption-text">Stippled image generated with the AIS algorithm. Click for full resolution image.</p></div>
<p><strong><br />
</strong></p>
<h2>Implementation notes</h2>
<p>As part of the test application provided at the end of this post, I worked on an implementation of the AIS algorithm using C#. Despite the running times I’m getting are not nearly as fast as the ones reported in the paper, they’re not too bad for the quality. Although this is conveniently omitted in the paper, care has to be taken when implementing the disk adjustment heuristic to deal with sub-pixel disks, especially as they tend to make the process diverge, and  may even get the algorithm stuck due to the inability of the disk image buffer to handle disks smaller than 1 pixel. I found using a correct disk area calculation (as opposed to a squared window approximation) to produce less artifacts albeit being slightly slower. Dark images such as the zebra displayed in the screenshot below are remarkably difficult to handle robustly due to the high contrast and sample densities required</p>
<p>This being said, the results look pretty nice in most cases. There’s a free parameter which controls the overall density of the stippled image &#8211; not every image is suited for a fixed value of this parameter, and tinkering with it helps achieving optimal results.</p>
<h1>Recursive Wang-Tiles</h1>
<p>The second approach I tried belongs to the high-throughput family described above. This algorithm relies on a heavy precomputation stage to generate an auxiliary structure called Wang Tiles used in combination of PD distributions to achieve fast running times.</p>
<p>Wang Tiles <strong><a href="research.microsoft.com/en-us/um/people/cohen/WangFinal.pdf" target="_blank">[Cohen 03]</a></strong> are a construction which enables arranging a finite set of elements (the tiles) in a <em>non-periodic</em> (pseudorandom) sequence to cover the plane. The tiles are squares which have a color assigned to each one of its four edges. The algorithm states that a tile can only be placed if the color of its edges matches those of the surrounding tiles that have been previously placed. For any set of tiles which elements fulfill the required restrictions, an element is chosen randomly.</p>
<div id="attachment_121" class="wp-caption aligncenter" style="width: 510px"><a href="http://www.joesfer.com/wp-content/uploads/2011/11/wt1.png"><img class="size-full wp-image-121" title="wt" src="http://www.joesfer.com/wp-content/uploads/2011/11/wt1.png" alt="" width="500" height="368" /></a><p class="wp-caption-text">Set of Wang Tiles arranged in a valid configuration. Image from |Cohen 03|</p></div>
<p><strong></strong>We start with a tile and sequentially insert random tiles from left to right, simply ensuring that the left edge color on each newly placed tile matches the right edge color of the last one. Once we’ve reached the right bound of the area to cover, we continue building a new row, now matching the left <em>and</em> top edge with the tiles from the previous row. This is righteously called <strong>scanline algorithm</strong>.</p>
<p>We start with a fixed set of tiles, and place them satisfying 1 or 2 restrictions depending on how many neighbor edges we need to match at any given time. For C possible edge colors, we’ll need at least N*C<sup>2</sup>, N&gt;=1 tiles available to satisfy every restriction on the top and left edges. N determines the number of available choices for any placement, from where we chose using a uniformly distributed random number.</p>
<p>What it’s interesting from the sequence generated by the aforementioned algorithm is its <strong>aperiodicity</strong>, its lack of structure or repetitive patterns.</p>
<div id="attachment_122" class="wp-caption aligncenter" style="width: 510px"><a href="http://www.joesfer.com/wp-content/uploads/2011/11/wtsequence.jpg"><img class="size-full wp-image-122" title="wtsequence" src="http://www.joesfer.com/wp-content/uploads/2011/11/wtsequence.jpg" alt="" width="500" height="501" /></a><p class="wp-caption-text">Aperiodic sequence generated from a finite set of tiles. Image from |Cohen 03|</p></div>
<p><strong></strong>Now what do we put in the tiles? Wang Tiles have been used to synthesize textures from samples; we’ll use them to <strong>cover the plane with a noise pattern</strong>, <strong>generated from a <em>finite</em>, relatively small, set of PD distributions</strong>. This process is described in the paper <a href="http://johanneskopf.de/publications/blue_noise/" target="_blank"><strong>[Kopf 06]</strong></a>. Having this, all we need to do at runtime is execute the scanline algorithm to cover the desired image area with tiles from the precomputed set.</p>
<div id="attachment_124" class="wp-caption aligncenter" style="width: 510px"><a href="http://www.joesfer.com/wp-content/uploads/2011/11/texturesynth.jpg"><img class="size-full wp-image-124" title="texturesynth" src="http://www.joesfer.com/wp-content/uploads/2011/11/texturesynth.jpg" alt="" width="500" height="267" /></a><p class="wp-caption-text">Texture synthesis from samples. Image from |Cohen 03|</p></div>
<div id="attachment_123" class="wp-caption aligncenter" style="width: 510px"><a href="http://www.joesfer.com/wp-content/uploads/2011/11/noisesynth1.png"><img class="size-full wp-image-123" title="noisesynth" src="http://www.joesfer.com/wp-content/uploads/2011/11/noisesynth1.png" alt="" width="500" height="366" /></a><p class="wp-caption-text">Noise synthesis from samples. Image from |Cohen 03|</p></div>
<p>Before that, there are a couple more details to worry about: Edge seams and recursiveness.</p>
<h2>Edge Seams</h2>
<p>By simply choosing random squared samples of textures or noise patterns and then putting those together next to each, we won’t guarantee that the seams match. We need to build the tiles in such a way that, whenever the edge colors on the opposite edges match, so do the image on the tile.</p>
<p>To do this, the authors propose choosing square samples for the <em>colors</em> themselves, and then combining those sample colors to build each tile (4 source images for each tile) as depicted in the figure below:</p>
<div id="attachment_125" class="wp-caption aligncenter" style="width: 510px"><a href="http://www.joesfer.com/wp-content/uploads/2011/11/tilemerge.jpg"><img class="size-full wp-image-125" title="tilemerge" src="http://www.joesfer.com/wp-content/uploads/2011/11/tilemerge.jpg" alt="" width="500" height="504" /></a><p class="wp-caption-text">Tile merging: a source distribution is generated for each tile, and then merged with 4 additional distribution corresponding to each edge color. This will ensure the contents of adjacent tiles match on the boundaries. Image from |Kopf 06|</p></div>
<p>This way, since each matching edge comes from the same image, they will align properly.</p>
<p>For the case of <em>blue noise samples</em> however, things get a bit more involved: we not only need the noise patterns to match on the edges, but we also need the resulting merged tiles to preserve their PD properties: we don’t want merged samples to form clusters. The authors of <strong><a href="http://johanneskopf.de/publications/blue_noise/" target="_blank"><strong>[Kopf 06]</strong></a> </strong>propose making use of a Voronoi diagram containing all the samples to be merged, and then build a seam from the path that minimizes a cost function which penalizes nearby samples. Put in plain words, this means merging the source PD distributions by cutting along an irregular seam passing by those areas where points are more far away on average.</p>
<div id="attachment_126" class="wp-caption aligncenter" style="width: 510px"><a href="http://www.joesfer.com/wp-content/uploads/2011/11/voronoiSeam.png"><img class="size-full wp-image-126" title="voronoiSeam" src="http://www.joesfer.com/wp-content/uploads/2011/11/voronoiSeam.png" alt="" width="500" height="438" /></a><p class="wp-caption-text">Minimum cost seam generated from traversing the Voronoi boundaries. Edge cost is shown in red.</p></div>
<p>After this stage we’ll have a set of tiles that we can blindly arrange according to the scanline algorithm to generate a sequence which will also preserve PD distribution properties. Note that generating the Wang Tiles is the bulk of the work in this algorithm, but it’s a one off process. After that, we’ll be able to cover as much area as we want with blue noise without having to run a sequential dart throwing algorithm at runtime.</p>
<h2>Recursiveness</h2>
<p>The second issue we have to worry about is: we know our source tiles are <em>progressive</em>, and therefore plotting a subset of them produces a less dense, but equally filling noise distribution. We use this property to generate light shades on our stippled image &#8211; but if we happen to require more density than the maximum our tiles’ distribution can provide, we won’t have enough points!</p>
<p>We thus need to make the tiles <em>recursive</em>: allowing any tile to be subdivided into a set of NxN smaller tiles (built following the same edge-matching rules) which adds up to N<sup>2 </sup>more points than the source tile.</p>
<div id="attachment_127" class="wp-caption aligncenter" style="width: 510px"><a href="http://www.joesfer.com/wp-content/uploads/2011/11/tilesubdiv.jpg"><img class="size-full wp-image-127" title="tilesubdiv" src="http://www.joesfer.com/wp-content/uploads/2011/11/tilesubdiv.jpg" alt="" width="500" height="250" /></a><p class="wp-caption-text">Tile subdivision. Image from |Kopf 06|</p></div>
<p><strong></strong>Recursiveness along with Progressiveness are the properties that will allow us achieving arbitrarily dark or light shades in the stippled image.</p>
<h2>Putting it all together</h2>
<p>The stippling algorithm based on Recursive Wang Tiles is based in the following steps:</p>
<p style="padding-left: 30px;"><strong>Preprocessing</strong>:</p>
<blockquote>
<ol>
<li>Let C be the number of edge colors, generate a complete set of N*C<sup>2</sup> source PD point distributions.</li>
<li>Generate C more PD distributions, one for each edge</li>
<li>Build the complete set of unique N*C<sup>2</sup> Wang Tiles by merging each source distribution with the 4 edge distributions. Note that the original source distribution won’t match on the seams, but these merged ones will.</li>
</ol>
</blockquote>
<p style="padding-left: 30px;"><strong>At runtime</strong>: Cover the source image with a non-periodic sequence of the pre-generated tiles; for each tile, decide whether to insert each point based on the required image density. If we’ve inserted all the points on a tile distribution and we still require more density, subdivide the tile.</p>
<p>&nbsp;</p>
<div id="attachment_130" class="wp-caption aligncenter" style="width: 624px"><a href="http://www.joesfer.com/wp-content/uploads/2011/11/stippledWT1.png"><img class="size-full wp-image-130  " title="stippledWT" src="http://www.joesfer.com/wp-content/uploads/2011/11/stippledWT.png" alt="" width="614" height="461" /></a><p class="wp-caption-text">Stippled image generated using the Recursive Wang Tiles method. Click for full size.</p></div>
<p>Note that the image generated with this method is somewhat <em>noisier</em> than the result achieved with AIS, however if you run the provided software you’ll notice how much faster this method is (excluding the preprocessing, that is).</p>
<h1>Color?</h1>
<p>To finish the post, I wanted to provide a hint of what I consider a failed test either as a note to self, or in case anybody reading this is willing to come up with an idea to make it work in the future <img src='http://www.joesfer.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<div id="attachment_129" class="wp-caption aligncenter" style="width: 330px"><a href="http://www.joesfer.com/wp-content/uploads/2011/11/pointillism.jpg"><img class="size-full wp-image-129 " title="pointillism" src="http://www.joesfer.com/wp-content/uploads/2011/11/pointillism.jpg" alt="" width="320" height="297" /></a><p class="wp-caption-text">AIS extended to color. Pointillism?</p></div>
<p>Despite personally finding the monochrome stippled images to be beautiful, one trivial extension I thought of was extending the AIS algorithm to plot colored disks by averaging the underlying image pixels. I was aiming for a somewhat pointillist effect, which kind of reminds of. However the image doesn’t completely make it for me because the approach is basing the stipples (the strokes in this color version) exclusively on the <em>darkness</em> of the image, completely ignoring the homogeneity on the tone – this will prevent <em>dark</em> broad strokes from appearing on the result no matter what. Obviously that’s what the stippling algorithm is designed to do: generate dark shades from dense clustering of points, but I do think something like this could be achieved:</p>
<p><a href="http://www.joesfer.com/wp-content/uploads/2011/11/rgb-cymk_07.png"><img class="aligncenter size-full wp-image-128" title="rgb-cymk_07" src="http://www.joesfer.com/wp-content/uploads/2011/11/rgb-cymk_07.png" alt="" width="500" height="451" /></a></p>
<h1>Downloads</h1>
<p>An application implementing the Adaptive Incremental Sampling and Recursive Wang Tiles algorithms described in this post is provided. The source code is written in C# under Visual Studio 2010. If you just want to run it, there’s binaries already built, along with a pre-generated  set of Wang Tiles to use included in the compressed file.</p>
<p><strong>Precompiled binaries: <a href="http://www.joesfer.com/wp-content/uploads/programming/C/stippling.zip"><strong>stippling.zip</strong></a></strong></p>
<p><strong>Source code </strong><strong>repository on GitHub</strong>: <a href="https://github.com/joesfer/Stippling" target="_blank">https://github.com/joesfer/Stippling</a></p>
<p style="text-align: center;"><iframe src="http://player.vimeo.com/video/32238761" width="400" height="225" frameborder="0"></iframe></p>
<div id="attachment_136" class="wp-caption aligncenter" style="width: 667px"><a href="http://www.joesfer.com/wp-content/uploads/2011/11/sshot01.jpg"><img class="size-full wp-image-136 " title="sshot01" src="http://www.joesfer.com/wp-content/uploads/2011/11/sshot01.jpg" alt="" width="657" height="525" /></a><p class="wp-caption-text">Stippling application: AIS and Wang Tiles approaches available</p></div>
<div id="attachment_137" class="wp-caption aligncenter" style="width: 667px"><a href="http://www.joesfer.com/wp-content/uploads/2011/11/sshot02.jpg"><img class="size-full wp-image-137 " title="sshot02" src="http://www.joesfer.com/wp-content/uploads/2011/11/sshot02.jpg" alt="" width="657" height="525" /></a><p class="wp-caption-text">Stippling application: Wang Tiles generator, with (optionally) detailed step breakdown.</p></div>
<h1>References</h1>
<p><a href="http://www.google.co.uk/url?sa=t&amp;rct=j&amp;q=cook%2C%20r.%20l.%201986.%20stochastic%20sampling%20in%20computer%20graphics.%20acm%20transactions%20on%20graphics%205%2C%201%2C%2051%E2%80%9372.&amp;source=web&amp;cd=1&amp;ved=0CB8QFjAA&amp;url=http%3A%2F%2Fciteseerx.ist.psu.edu%2Fviewdoc%2Fdownload%3Fdoi%3D10.1.1.84.5916%26rep%3Drep1%26type%3Dpdf&amp;ei=b3_BTsOHNsiV8gP9hNzDBA&amp;usg=AFQjCNGattXhiwkd6R5HOwYe6dCxBGZF-A&amp;cad=rja" target="_blank"><strong>[Cook 86]</strong></a>  Cook, R. L. 1986. <em>Stochastic sampling in computer graphics.</em> ACM Transactions on Graphics 5, 1, 51–72.</p>
<p><a href="www.dgp.toronto.edu/%7Eelf/.misc/poissondisk.pdf" target="_blank"><strong>[McCool 82]</strong></a> McCool, M., and Fiume, E. 1992. <em>Hierarchical poisson disk sampling distributions.</em> In Proc. Graphics interface ’92, 94–105.</p>
<p><a href="http://johanneskopf.de/publications/blue_noise/" target="_blank"><strong>[Kopf 06]</strong></a> Johannes Kopf and Daniel Cohen-Or and Oliver Deussen and Dani Lischinski. <em>Recursive Wang Tiles for Real-Time Blue Noise.</em> ACM Transactions on Graphics (Proceedings of SIGGRAPH 2006).</p>
<p><a href="http://research.microsoft.com/apps/pubs/default.aspx?id=115797" target="_blank"><strong>[Hongwei 09]</strong></a> Hongwei Li, Diego Nehab, Li-Yi Wei, Pedro Sander, and Chi-Wing Fu. <em>Fast Capacity Constrained Voronoi Tessellation.</em></p>
<p><strong><a href="research.microsoft.com/en-us/um/people/cohen/WangFinal.pdf" target="_blank">[Cohen 03]</a></strong> Michael F Cohen, Jonathan Shade, Stefan Hiller, Oliver Deussen.<em> Wang Tiles for Image and Texture Generation</em><em>. </em>ACM Transactions on Graphics 22 (3) p. 287.</p>
<p><strong><a href="http://jgt.akpeters.com/papers/Ascencio-Lopez10/" target="_blank">[Lopez 10]</a></strong> Ignacio Ascencio-Lopez and Oscar Meruvia-Pastor and Hugo Hidalgo-Silva. <em>Adaptive Incremental Stippling using the Poisson-Disk Distribution</em>.<em> </em>Journal of graphics, gpu, and game tools.</p>
<p><a href="http://research.microsoft.com/apps/pubs/default.aspx?id=70563" target="_blank"><strong>[Wei 08]</strong></a> Li-Yi Wei. <em>Parallel Poisson Disk Sampling</em>, in SIGGRAPH 2008, Association for Computing Machinery, Inc., March 2008</p>
<div class="tweetthis" style="text-align:left;"><p> <a target="_blank" rel="nofollow" class="tt" href="http://twitter.com/home/?status=Stippling+and+Blue+Noise+http%3A%2F%2Fjoesfer.com%2F%3Fp%3D108"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/twitter/tt-twitter.png" alt="Post to Twitter" /></a> <a target="_blank" rel="nofollow" class="tt" href="http://delicious.com/post?url=http://www.joesfer.com/?p=108&amp;title=Stippling+and+Blue+Noise"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/delicious/tt-delicious.png" alt="Post to Delicious" /></a> <a target="_blank" rel="nofollow" class="tt" href="http://www.facebook.com/share.php?u=http://www.joesfer.com/?p=108&amp;t=Stippling+and+Blue+Noise"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/facebook/tt-facebook.png" alt="Post to Facebook" /></a> <a target="_blank" rel="nofollow" class="tt" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http://www.joesfer.com/?p=108&amp;title=Stippling+and+Blue+Noise&amp;summary=%0D%0A%0D%0A%0D%0AIt%E2%80%99s+been+a+while+since+the+last+post%2C+and+truth+is+I%E2%80%99ve+spent+most+of+my+spare+time+lately+devoted+to+my+photography.+Back+however+to+more+t...&amp;source=Jose&#039;s sketchbook"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/linkedin/tt-linkedin.png" alt="Post to LinkedIn" /></a></p></div>]]></content:encoded>
			<wfw:commentRss>http://www.joesfer.com/?feed=rss2&#038;p=108</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>On Mesh Sampling</title>
		<link>http://www.joesfer.com/?p=84</link>
		<comments>http://www.joesfer.com/?p=84#comments</comments>
		<pubDate>Fri, 08 Apr 2011 07:30:30 +0000</pubDate>
		<dc:creator>Jose</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[GPU]]></category>
		<category><![CDATA[Maya]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Raymarching]]></category>
		<category><![CDATA[sampling]]></category>
		<category><![CDATA[voxels]]></category>

		<guid isPermaLink="false">http://www.joesfer.com/?p=84</guid>
		<description><![CDATA[It&#8217;s not unusual that a given algorithm requires values or positions to be sampled from a geometric mesh &#8211; some of the projects described in past entries of this blog are examples of it: the Weathering Simulation and Space Colonization Algorithm required points to be placed on the surface of a mesh, wereas the Voronoi [...]]]></description>
				<content:encoded><![CDATA[<div id="attachment_88" class="wp-caption alignnone" style="width: 510px"><a href="http://www.joesfer.com/wp-content/uploads/2011/04/satyr-wireframe.png"><img class="size-full wp-image-88" title="satyr-wireframe" src="http://www.joesfer.com/wp-content/uploads/2011/04/satyr-wireframe.png" alt="" width="500" height="469" /></a><p class="wp-caption-text">Fig 1. Sampling the surface</p></div>
<p>It&#8217;s not unusual that a given algorithm requires values or positions to be sampled from a geometric mesh &#8211; some of the projects described in past entries of this blog are examples of it: the <a title="Surface Weathering" href="http://www.joesfer.com/?p=22">Weathering Simulation</a> and <a title="Growing organic structures" href="http://www.joesfer.com/?p=46">Space Colonization Algorithm</a> required points to be placed on the <strong>surface </strong>of a mesh, wereas the <a title="Voronoi Shattering (Part I)" href="http://www.joesfer.com/?p=60">Voronoi Shattering</a> seeds the fragments with positions obtained along the <strong>volume </strong>of a source object.</p>
<p>In this post I&#8217;ll be providing more detail on the implementation of those two kinds of samplers, and at the end of the post you can find the link to some source code which should hopefully help complementing the description.</p>
<h2>Sampling the surface of a mesh</h2>
<p>Placing random samples along the triangles of a polygonal mesh is the easiest case. The process consists in simply chosing a random triangle, and then generate a point within its bounds until we&#8217;ve reached a desired number of samples.</p>
<p>Sampling a triangle can be done using <a href="http://en.wikipedia.org/wiki/Barycentric_coordinate_system_%28mathematics%29" target="_blank">barycentric coordinates</a> as depicted in <strong>Figure 1</strong>. We start with two variables <em>u</em> and <em>v</em> with random values between 0 and 1 such that u + v ≤ 1 (for this we can keep generating values until the condition is met, or even quicker, just pick the complementary value u = 1 &#8211; u, v = 1 &#8211; v when u + v &gt; 1). The resulting point is given by the weighed sum of the triangle vertices such as:</p>
<pre><strong>s</strong> = u*<strong>A</strong> + v*<strong>B</strong> + w*<strong>C</strong> = u*<strong>A</strong> + v*<strong>B</strong> + (1 - (u+v)) * <strong>C</strong></pre>
<p>In order to guarantee a more uniform coverage of the samples, it&#8217;s better to weight the probability for a triangle to be sampled according to its area, so that larger triangles will be sampled more often and hold more samples along their surface. We can use the <a href="http://en.wikipedia.org/wiki/Cumulative_probability" target="_blank">cumulative distribution</a> to pick elements from the triangle array with the following simple steps:</p>
<p>1. Calculate the area of every triangle and store it into an array.</p>
<p style="padding-left: 30px;">E.g. [ 0.1, 0.4, 0.5, 0.2 ]</p>
<p>2. Find the smaller value on the array and divide every element by it, rounding to the next integer. The array is now holding how <em>proportionally </em>larger each triangle is compared to the smallest one.</p>
<p style="padding-left: 30px;">ceil( [ 0.1, 0.4, 0.5, 0.2 ] / 0.1) = [ 1, 4, 5, 2 ]</p>
<p>3. Add up the elements of the array and initialize a second array of that length, so that the index i of a triangle is repeated as many times as it&#8217;s corresponding values on the first array:</p>
<p style="padding-left: 30px;">A1: [ 1, 4, 5, 2 ]</p>
<p style="padding-left: 30px;">A2: [ 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3 ]</p>
<p>4. All that&#8217;s left is picking a random element within A2, t = A2[ random(0,1) * length(A2) ] as our triangle index.</p>
<h2>Sampling the volume of a mesh</h2>
<p>Things get a bit more involved when we want to place samples not just on the surface but also in the volume enclosed by the object. I&#8217;ve personally been using a couple of alternatives with different pros and cons that I found useful, an implementation as maya nodes can be found in the provided source code <img src='http://www.joesfer.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h3>Using ray intersections</h3>
<p>A very straightforward way of sampling a volume is the one illustrated in <strong>Figure 2</strong>: we begin by obtaining the bounds of the mesh and then iterativelly shoot rays joining two random points on opposite faces.</p>
<div id="attachment_85" class="wp-caption alignleft" style="width: 289px"><a href="http://www.joesfer.com/wp-content/uploads/2011/04/satyr-raymarched.png"><img class="size-full wp-image-85 " title="satyr-raymarched" src="http://www.joesfer.com/wp-content/uploads/2011/04/satyr-raymarched.png" alt="" width="279" height="500" /></a><p class="wp-caption-text">Fig 2. Sampler by Raymarching</p></div>
<p>Assuming the mesh is closed, each ray will intersect the geometry in a number of segments (red dashed lines) each defined by an entry and an exit point. We&#8217;ll generate samples for each segment, putting care in trying to preserve an overall sampling density #samples on segment = length segment * density, which in the implementation is defined as a &#8220;linear density factor&#8221; obtained from the bounding box volume and the number of samples requested. Rinse and repeat until we have enough samples.</p>
<p>&nbsp;</p>
<p>The pros of this approach is that it fits the shape perfectly since we can precisely obtain the entry and exit points for each ray. Maya provides built-in facilities for retrieving all the intersections on the MFnMesh class by using an internal grid acceleration structure (which is fair enough for moderate meshes). The downsides of this technique are that it may be a bit slow, depending on our requirements, and that the distribution is far from ideal for few samples &#8211; although it tends to converge decently when the number of requested samples increases. I found it useful to limit the number of samples a given segment can contribute with to enforce the algorithm shooting more rays and therefore increasing the density of segments instead of the number of samples along each segment.<br />
<span id="more-84"></span></p>
<h3>Sampling voxels</h3>
<p>A different approach to sample volumes is to first voxelize the source geometry and then obtain the samples as random points within the voxels. If our voxels are the same size, we just need to pick a random voxel and a random point within that voxel and repeat. If the voxels have different sizes though, we can use the same cumulative distribution concept described above and sample according their volume for a more uniform coverage.</p>
<div id="attachment_86" class="wp-caption alignnone" style="width: 510px"><a href="http://www.joesfer.com/wp-content/uploads/2011/04/satyr-voxelized.png"><img class="size-full wp-image-86" title="satyr-voxelized" src="http://www.joesfer.com/wp-content/uploads/2011/04/satyr-voxelized.png" alt="" width="500" height="500" /></a><p class="wp-caption-text">Fig 3. Sampling a voxelized version of the geometry</p></div>
<p>There are several ways of generating voxels from a mesh (<strong>Fig. 3</strong>), but it can be done particularly efficiently by using the <strong>GPU</strong>: the idea is to rasterize the object in a fairly low-res image, and use the pixels of those image as a grid to tell which cells are occupied. This can be done in a multi-pass algorithm by playing with the camera clip planes to &#8220;peel&#8221; the object into slices rendered to texture. Alternatively, we can do it in a <em>single pass</em> as described in [<a href="http://hal.inria.fr/docs/00/34/52/91/PDF/solidvoxelizationAuthorVersion.pdf">Eisemann 08</a>] by encoding the depth information in the bits of the color components of each pixel.</p>
<p>The idea is simple but powerful: let&#8217;s assume we&#8217;re using a render target using 32 bits 8+8+8+8 RGBA channels. For each pixel on the texture, we can set treat the color bits as cells in <em>depth</em>, and then set each one of the 32 different bits to 1 if there is a filled voxel occupying the corresponding cell. We do this by first disabling the depth mask, so no fragments are culled, and rendering the object <strong>once </strong>from an orthographic projection fitted around the bounding box. For each fragment rendered, we find it&#8217;s corresponding bit corresponding to it&#8217;s normalized depth in the bounding box, and output a bitmask which is combined in the resulting texture using OpenGL&#8217;s bit operator blend mode.</p>
<div id="attachment_87" class="wp-caption alignnone" style="width: 510px"><a href="http://www.joesfer.com/wp-content/uploads/2011/04/slicemap.png"><img class="size-full wp-image-87 " title="slicemap" src="http://www.joesfer.com/wp-content/uploads/2011/04/slicemap.png" alt="" width="500" height="226" /></a><p class="wp-caption-text">Fig 4. Packing voxel information into color channels</p></div>
<p>&nbsp;</p>
<p>To generate the voxels from the image, we check the value for every pixel, and instead of treating it as color, we treat it as a bit array and output a voxel for each active bit. Even better, by just changing the bitmasks used on each fragment, you can trivially change the behavior of the algorithm from volume to surface sampling <img src='http://www.joesfer.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>The main benefit of this technique by far is <em>speed</em>: you can voxelize complex objects in real time, and generate the samples from those voxels is cheap as well. On the other hand the number of voxels is limited by the bit depth used in the target texture. With 32 bits per component you can go up to 128 voxels in depth (this is how the provided implementation works), and to go beyond those numbers we&#8217;d have to make use of a multipass algorithm as described above. Another drawback is lack of precission: since the voxels won&#8217;t match the surface of the object perfectly, the samples we obtain from them may potentially be slithgly outside the original mesh. The problem is of course minimized as we increase the resolution of the voxelization.</p>
<div id="attachment_89" class="wp-caption alignnone" style="width: 510px"><a href="http://www.joesfer.com/wp-content/uploads/2011/04/torus.png"><img class="size-full wp-image-89" title="torus" src="http://www.joesfer.com/wp-content/uploads/2011/04/torus.png" alt="" width="500" height="598" /></a><p class="wp-caption-text">Fig 5. Voxel Sampler</p></div>
<h2><strong>Quality of random numbers</strong></h2>
<p>Just to make a quick note about this &#8211; we&#8217;ve been using random uniform variables in these methods to pick elements, or sample points within a triangle or a voxel. A straightforward way of doing this is to use the default <em>rand </em>method in C. For the sake of clarity that&#8217;s the method provided in the implementation, but one must be aware that the <em>quality </em>of these pseudo-random number sequences is generally very poor. Even with a <a href="http://en.wikipedia.org/wiki/Mersenne_twister" target="_blank">better random number generator</a> you may find that chosing points randomly along a surface tends to form clusters and gaps. If that&#8217;s the case, <a href="http://en.wikipedia.org/wiki/Low-discrepancy_sequence" target="_blank">better sampling methods</a> can be used instead to generate sequences of values and improve the distribution. I find the illustrations on <a href="http://www.cse.cuhk.edu.hk/~ttwong/papers/udpoint/udpoints.html" target="_blank">this paper</a> particularly clear to understand the differences visually.</p>
<h2>Downloads</h2>
<p>Precompiled plugins for Maya 2011 32 and 64 bit under Windows: <a title="sampler.zip" href="http://www.joesfer.com/wp-content/uploads/programming/Maya/sampler/sampler.zip">sampler.zip<br />
</a>Source code available on GitHub: <a href="https://github.com/joesfer/Sampler" target="_blank">https://github.com/joesfer/Sampler</a></p>
<p>The plugin also includes auxiliary preview nodes to help visualizing the samples and the voxels. Since I thought the voxelizer may be useful for purposes other than sampling (or just because producing Lego versions of meshes is fun!) it is encapsulated it in it&#8217;s own node for easy reuse.</p>
<h2>References</h2>
<p><a href="http://stackoverflow.com/questions/2772882/c-picking-a-random-item-based-on-probabilities" target="_blank">Stack Overflow</a>. Picking a random number based on probabilities.</p>
<p>[<a href="http://hal.inria.fr/docs/00/34/52/91/PDF/solidvoxelizationAuthorVersion.pdf">Eisemann 08</a>] Elmar Eisemann, Xavier D´ecoret. &#8220;Single-Pass GPU Solid Voxelization for Real-Time Applications&#8221;. GI &#8217;08: Proceedings of Graphics Interface 2008 322 (2008) 73-80.</p>
<div class="tweetthis" style="text-align:left;"><p> <a target="_blank" rel="nofollow" class="tt" href="http://twitter.com/home/?status=On+Mesh+Sampling+http%3A%2F%2Fjoesfer.com%2F%3Fp%3D84"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/twitter/tt-twitter.png" alt="Post to Twitter" /></a> <a target="_blank" rel="nofollow" class="tt" href="http://delicious.com/post?url=http://www.joesfer.com/?p=84&amp;title=On+Mesh+Sampling"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/delicious/tt-delicious.png" alt="Post to Delicious" /></a> <a target="_blank" rel="nofollow" class="tt" href="http://www.facebook.com/share.php?u=http://www.joesfer.com/?p=84&amp;t=On+Mesh+Sampling"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/facebook/tt-facebook.png" alt="Post to Facebook" /></a> <a target="_blank" rel="nofollow" class="tt" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http://www.joesfer.com/?p=84&amp;title=On+Mesh+Sampling&amp;summary=%0D%0A%0D%0AIt%27s+not+unusual+that+a+given+algorithm+requires+values+or+positions+to+be+sampled+from+a+geometric+mesh+-+some+of+the+projects+described+in+pa...&amp;source=Jose&#039;s sketchbook"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/linkedin/tt-linkedin.png" alt="Post to LinkedIn" /></a></p></div>]]></content:encoded>
			<wfw:commentRss>http://www.joesfer.com/?feed=rss2&#038;p=84</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Voronoi Shattering (Part II)</title>
		<link>http://www.joesfer.com/?p=69</link>
		<comments>http://www.joesfer.com/?p=69#comments</comments>
		<pubDate>Sat, 19 Mar 2011 11:29:22 +0000</pubDate>
		<dc:creator>Jose</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[delaunay]]></category>
		<category><![CDATA[Maya]]></category>
		<category><![CDATA[procedural]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[shattering]]></category>
		<category><![CDATA[voronoi]]></category>

		<guid isPermaLink="false">http://www.joesfer.com/?p=69</guid>
		<description><![CDATA[This post is a continuation of the first part about my Voronoi Shattering project, please make sure to read it first. Fragment carving On the previous post we left it at the point where we had a Voronoi Diagram generated from a set of points sampled from the source geometry&#8217;s volume. We&#8217;ll now take it [...]]]></description>
				<content:encoded><![CDATA[<p>This post is a continuation of the <a title="Voronoi Shattering part I" href="http://www.joesfer.com/?p=60" target="_blank">first part</a> about my Voronoi Shattering project, please make sure to read it first.</p>
<h2>Fragment carving</h2>
<p>On the previous post we left it at the point where we had a Voronoi Diagram generated from a set of points sampled from the source geometry&#8217;s volume. We&#8217;ll now take it from there and, in this post, I&#8217;ll be talking about the mesh slicing.</p>
<div id="attachment_71" class="wp-caption alignnone" style="width: 510px"><img class="size-full wp-image-71 " title="intersection" src="http://www.joesfer.com/wp-content/uploads/2011/03/intersection.jpg" alt="" width="500" height="341" /><p class="wp-caption-text">Fig. 1. Voronoi cell intersecting source geometry to form fragment</p></div>
<p>Given the voronoi diagram and the input geometry, the way to obtain the fragments for our shatter algorithm is by computing the intersection of the mesh with each one of the voronoi cells (<strong>Fig 1</strong>). Since the VD define a <a title="convex hull" href="http://en.wikipedia.org/wiki/Convex_hull" target="_blank">convex hull</a>, it means that we can calculate the intersection with the simple following method:</p>
<pre style="padding-left: 30px;"><code> For each voronoi cell C do For each face F in C do Obtain the plane P containing F Split the geometry in two using P, and discard all the polygons on the front side of P Identify the set of vertices lying exactly on P, and generate  a new set of faces filling the hole. end end </code></pre>
<div id="attachment_72" class="wp-caption alignnone" style="width: 510px"><img class="size-large wp-image-72  " title="torus_split" src="http://www.joesfer.com/wp-content/uploads/2011/03/torus_split-1024x974.jpg" alt="" width="500" height="476" /><p class="wp-caption-text">Fig 2. Slicing the geometry with the faces of a VD cell</p></div>
<p>&nbsp;</p>
<p>The process is depicted in <strong>Fig. 2</strong>. Note that by filling the holes left from each cut before we move on to the next one -marked as red faces in the picture-, we solve the problem of keeping the shape <strong>closed </strong>defining a volume.</p>
<h2>Hole filling</h2>
<div class="wp-caption alignleft" style="width: 310px"><img title="torus tessellation" src="http://www.joesfer.com/wp-content/uploads/2011/03/torus-tessellation.png" alt="" width="300" height="300" /><p class="wp-caption-text">Fig. 3. First attempt - Naive tessellation</p></div>
<p>Filling the holes left by each cut while we&#8217;re carving the shape is a matter of triangulating a flat set of vertices lying exactly over the cut plane. The vertices will be a combination of new vertices generated by splitting existing faces, and a few more previously existing ones, which happened to be coplanar already. Linking the vertices we&#8217;ll have edges describing <em>outlines </em>and <em>holes </em>(e.g. when we slice a torus in two as in <strong>Figure 3</strong>), and since everything happens on a plane we can just project the coordinates from 3D to 2D, triangulate, and then reproject the result back to 3D.</p>
<p>I initially made the mistake of going for a overly simplistic approach that led to more problems than actual benefits &#8211; I&#8217;m describing it here anyway possibly as an example of something that <em>didn&#8217;t</em> go well!</p>
<p><strong>Version 1</strong> of my hole filling algorithm was trying to identify sequences of linked segments describing loops. Then the relative position of those loops was tested to determine which of them were outlines and which were holes. Next, for every set of outline and its contained holes, every pair of vertices was linked with a new edge unless that edge would intersect with an existing one. The result is depicted in <strong>Figure 3</strong>.</p>
<p>Unfortunatelly there were several problems with this approach:</p>
<div id="attachment_77" class="wp-caption alignright" style="width: 220px"><a href="http://www.joesfer.com/wp-content/uploads/2011/03/loopCheck.png"><img class="size-medium wp-image-77 " title="loopCheck" src="http://www.joesfer.com/wp-content/uploads/2011/03/loopCheck-300x300.png" alt="" width="210" height="210" /></a><p class="wp-caption-text">Fig. 4. Finding loops</p></div>
<ul>
<li>First of all, identifying the closed loops from a pool of edges turned out to be harder than expected: ideally it would be a matter of finding a sequence of edges v1-v2, v2-v3, v3-v4&#8230; eventually finding edge vn-v1 closing the loop. However, tiny imperfections on the mesh slicing such as parallel faces perpendicular to the plane or just tiny or degenerated faces being discarded would cause missing edges -open loops-, inner loops or dangling segments, and an overall actual input being far from the ideal expected, see <strong>Figure 4</strong>.</li>
<li>Missing edges were particularly harmful because they would cause loop sequences not to be found, this then resulting in entire holes not being filled. When the shape (now left open) was sliced again, even more edges would be missing, just making things worse and worse.</li>
<li>Even when things didn&#8217;t go wrong, the quality of the triangulation was not very good, being very prone to stretched triangles that would just cause further trouble when being sliced.</li>
</ul>
<p>The overall method, despite being simple in principle, turned out to be not so simple in practice when having to deal with real-world details, and above all, it happened to be just <strong>too fragile</strong> for it to work for the general case.</p>
<p><span id="more-69"></span></p>
<div class="wp-caption alignleft" style="width: 310px"><img title="good-tessellation" src="http://www.joesfer.com/wp-content/uploads/2011/03/good-tessellation.jpg" alt="" width="300" height="300" /><p class="wp-caption-text">Fig. 5. Higher quality tessellation</p></div>
<p>Since the quality of the tessellation proved to be crucial for the success of the algorithm, I decided to throw away the first attempt and try a different approach which luckily ended up working much better: in <strong>Version 2</strong>, given the set of coplanar vertices, we would then perform a <strong>Constrained Delaunay Triangulation</strong> over it, generating an initial set of triangles filling both the inside of the outline <em>and the holes. </em>A Constrained Delaunay triangulation (CDT) is a generalization of the <a href="http://en.wikipedia.org/wiki/Delaunay_triangulation" target="_blank">Delaunay triangulation</a> that forces certain required segments into the triangulation. In our case, we need to ensure the triangulation conforms the shape by including every segment coplanar to the cut plane, with <em>no need</em> for a prior classification to tell whether it belongs to an outline or a hole. Fewer steps involved, and a <em>lot </em>more robust.</p>
<p>Calculating a CDT involves generating a regular DT first, and then progressively insert the required edges by removing all the intersecting triangles and re-tessellating the affected area (<strong>Figure 6</strong>). I based my implementation on <a href="http://www.cescg.org/CESCG-2004/web/Domiter-Vid/" target="_blank"><strong>[Domiter 04]</strong></a>, which is quite nicely explained. There&#8217;s a detail that is not covered in that text, which is <em><strong>how to get rid of the triangles that fill the hole loops</strong></em> (inner circle in <strong>Fig. 5</strong>)<em>.</em> The author proposes using a seed point provided by the user to start a triangle-killing greedy traversal on neighbor triangles. What I did instead in order to provide a (rather ineficient) automatic alternative was to start on each triangle centroid and trace a semi infinite line to count the number of intersections with each one of the source outline/hole edges (this excludes the new edges generated from the triangles) and this way determining whether the triangle is inside or outside the shape -being discarded in the later case-. You can find some explanatory diagrams in <a href="http://www.cs.cmu.edu/~quake/tripaper/triangle3.html" target="_blank"><strong>[Rupert].</strong></a><em> </em></p>
<p>This method vastly improved the quality of the tessellation, and the number of degenerate triangles that came out of further slicing it. Had it not been enough, though, I would probably had required to go one step further and implement a <a href="http://www.cgal.org/Manual/latest/doc_html/cgal_manual/Mesh_2/Chapter_main.html" target="_blank">Conforming Delaunay Triangulation</a> which would further reduce the distortion of the resulting triangles by splitting long edges.</p>
<div id="attachment_76" class="wp-caption alignnone" style="width: 510px"><a href="http://www.joesfer.com/wp-content/uploads/2011/03/CDTedge.gif"><img class="size-full wp-image-76" title="CDTedge" src="http://www.joesfer.com/wp-content/uploads/2011/03/CDTedge.gif" alt="" width="500" height="247" /></a><p class="wp-caption-text">Fig. 6. Triangles affected by an edge a-b inserted in a DT</p></div>
<h2><!--more--></h2>
<h2>Numerical Robustness</h2>
<p>A final note about implementation details: the main issue with the method described above is that it performs many geometrc operations on a relatively small region of the mesh &#8211; A given set of faces can be sliced and reconstructed many times before the final shape of a fragment is achieved, and sooner than later this leads to problems in the form of really small, and/or almost degenerate triangles. Think of how <em>wrong </em>things can go when a split plane just slightly touches the geometry, or it cuts it in an odd angle leading very tiny holes which have to be filled just to be cut again on further steps.</p>
<p>Just like any other numeric algorithm, a good deal of care has to be put on the implementation of these operations. A big number of nasty situations can be alleviated by avoiding <em>exact </em>tests and using <strong>tolerances</strong> or epsilons instead. To give a simple example, when cutting out the mesh with a plane it turned out better to be slightly permissive when testing which side of the plane a vertex was on, just to avoid slicing a triangle over and over again infinitesimally away from an existing vertex. Therefore, instead of doing something like:</p>
<pre><span style="text-decoration: underline;">If</span> (distance( Vertex, Plane ) &lt; 0) <span style="text-decoration: underline;">then</span> discard it</pre>
<p>You would do something like:</p>
<pre><span style="text-decoration: underline;">If</span> (distance( Vertex, Plane ) &lt; -epsilon) <span style="text-decoration: underline;">then</span> discard it</pre>
<p>Where epsilon is a small number, so that we avoid incurring in a false positive case where a coplanar vertex decides to return a distance of -0.000001 from the plane. So far so good, but things start smelling fishy again when we find ourselves with a growing number of epsilons, <em>magic numbers</em>, with <em>arbitrary </em>small values. How should we choose them? should they all have the same value?</p>
<p>While it&#8217;s true that different magnitudes of &#8220;small&#8221; may suit each algorithm, and some testing will help finding sensible ranges, <strong>instead of using absolute epsilon values, it is better to make the tolerance dependent on the magnitude of the numbers you&#8217;re testing</strong>.</p>
<div id="attachment_73" class="wp-caption aligncenter" style="width: 510px"><a href="http://www.joesfer.com/wp-content/uploads/2011/03/precision.jpg"><img class="size-full wp-image-73 " title="precision" src="http://www.joesfer.com/wp-content/uploads/2011/03/precision.jpg" alt="" width="500" height="75" /></a><p class="wp-caption-text">Fig. 7. Representable numbers using floating point</p></div>
<p>The reason for this is that real numbers are <em>approximated </em>in a computer <a href="http://en.wikipedia.org/wiki/Floating_point" target="_blank">internally</a> by using a fixed number of bits providing a <em>finite </em>precision. That precision, however, is <strong>not </strong>homogeneous along the line of numbers &#8211; it converges at it&#8217;s best around 0 but then it starts degrading with larger magnitudes (<strong>Fig. 7</strong>). Taking single-precision floats, the gap between two consecutive representable numbers close to 0 is as little as 0.000001, but only 0.0625 when our numbers are in the range of millions. That&#8217;s <em>sixty two thousand </em>times less precise! hence it makes sense to adjust our epsilon to grow it larger with the magnitude of the inputs. If you&#8217;re interested in further details, this is all explained in better detail in <a href="http://realtimecollisiondetection.net/pubs/GDC07_Ericson_Physics_Tutorial_Numerical_Robustness.ppt" target="_blank">Christer Ericson&#8217;s presentation for GDC &#8217;07</a>, and his blog and related book <a href="http://realtimecollisiondetection.net/" target="_blank">Real-Time Collision Detection</a> is an invaluable reference for this and many other related topics.</p>
<p>The takeaway of all this is that, when comparing numbers, instead of doing:</p>
<pre><code>Equal( A, B ) { return abs( A - B ) == 0; }</code></pre>
<p>We would then be adding a tolerance value as discussed above:</p>
<pre><code>Equal</code><code>( A, B, epsilon ) { return abs( A - B ) &lt; epsilon; }</code></pre>
<p>But even better, we&#8217;d make the epsilon value depend on the magnitude of our input values to make up for the non-homogeneous precision:</p>
<pre><code>Equal</code><code>( A, B, epsilon ) { magnitude = max( abs( A ), abs( B ) ); // you may want to clamp magnitude to 1, to avoid further<em> </em>// <em>decreasing </em>epsilon return abs( A - B ) &lt; magnitude * epsilon; }</code></pre>
<h2>References</h2>
<p><a href="http://www.cescg.org/CESCG-2004/web/Domiter-Vid/" target="_blank"><strong>[Domiter 04]</strong></a> Vid Domiter. <em>Constrained Delaunay Triangulation using Plane Subdivision.</em></p>
<p><a href="http://www.cs.cmu.edu/~quake/tripaper/triangle3.html" target="_blank"><strong>[Rupert]</strong></a><em> Ruppert&#8217;s Delaunay Refinement Algorithm</em>.</p>
<p><a href="http://realtimecollisiondetection.net/pubs/GDC07_Ericson_Physics_Tutorial_Numerical_Robustness.ppt" target="_blank"><strong>[Ericson 07]</strong></a> Christer Ericson. <em>Numerical Robustness for Geometric Calculations.</em> GDC 2007.</p>
<div id="_mcePaste" class="mcePaste" style="position: absolute; left: -10000px; top: 1419px; width: 1px; height: 1px; overflow: hidden;">
<p>Unfortunatelly there were several problems with this approach:</p>
<p>First of all, identifying the closed loops from a pool of edges turned out to be harder than expected: ideally it would be a matter of finding a sequence of edges v1-v2, v2-3, v3-v4&#8230; eventually finding edge v4-v1 closing the loop. However, tiny imperfections on the mesh slicing such as parallel faces perpendicular to the plane, T-junctions, or just micro-faces which were discarded for being degenerated would cause</p>
</div>
<div class="tweetthis" style="text-align:left;"><p> <a target="_blank" rel="nofollow" class="tt" href="http://twitter.com/home/?status=Voronoi+Shattering+%28Part+II%29+http%3A%2F%2Fjoesfer.com%2F%3Fp%3D69"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/twitter/tt-twitter.png" alt="Post to Twitter" /></a> <a target="_blank" rel="nofollow" class="tt" href="http://delicious.com/post?url=http://www.joesfer.com/?p=69&amp;title=Voronoi+Shattering+%28Part+II%29"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/delicious/tt-delicious.png" alt="Post to Delicious" /></a> <a target="_blank" rel="nofollow" class="tt" href="http://www.facebook.com/share.php?u=http://www.joesfer.com/?p=69&amp;t=Voronoi+Shattering+%28Part+II%29"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/facebook/tt-facebook.png" alt="Post to Facebook" /></a> <a target="_blank" rel="nofollow" class="tt" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http://www.joesfer.com/?p=69&amp;title=Voronoi+Shattering+%28Part+II%29&amp;summary=This+post+is+a+continuation+of+the+first+part+about+my+Voronoi+Shattering+project%2C+please+make+sure+to+read+it+first.%0D%0AFragment+carving%0D%0AOn+the+pre...&amp;source=Jose&#039;s sketchbook"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/linkedin/tt-linkedin.png" alt="Post to LinkedIn" /></a></p></div>]]></content:encoded>
			<wfw:commentRss>http://www.joesfer.com/?feed=rss2&#038;p=69</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Voronoi Shattering (Part I)</title>
		<link>http://www.joesfer.com/?p=60</link>
		<comments>http://www.joesfer.com/?p=60#comments</comments>
		<pubDate>Sat, 19 Mar 2011 11:02:49 +0000</pubDate>
		<dc:creator>Jose</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[delaunay]]></category>
		<category><![CDATA[Maya]]></category>
		<category><![CDATA[procedural]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[shattering]]></category>
		<category><![CDATA[voronoi]]></category>

		<guid isPermaLink="false">http://www.joesfer.com/?p=60</guid>
		<description><![CDATA[The project I&#8217;ve been working on for some time now is an implementation of a shattering algorithm used to break objects into pieces which could then be plugged to a physics simulation. The technique I went for is so-called Voronoi Shattering because it applies Voronoi Diagrams to generate the fragments, being fairly easy for the [...]]]></description>
				<content:encoded><![CDATA[<p><iframe src="http://player.vimeo.com/video/21180571" width="400" height="225" frameborder="0"></iframe></p>
<p>The project I&#8217;ve been working on for some time now is an implementation of a shattering algorithm used to break objects into pieces which could then be plugged to a physics simulation. The technique I went for is so-called <em>Voronoi Shattering</em> because it applies Voronoi Diagrams to generate the fragments, being fairly easy for the artist to define the distribution of those cracks and the overall look.</p>
<p>Shattering a mesh into pieces is an interesting problem that involved a lot more work than I initially thought! &#8211; as it is often the case with this kind of geometric algorithms, getting the basic prototype running for easy cases is not too bad, but turning that into a more robust algorithm became 80% of the work. I think it will still be interesting to describe the things that worked along those that didn&#8217;t, so I&#8217;m splitting this into a couple of posts to keep them manageable.</p>
<h2>The problem</h2>
<p>Generally speaking, we want to split an object into many<em> solid </em>fragments given by closed surfaces. Provided that we know how to partition the source object, the most immediate problem that arises is that we only have information about the <em>shell </em>of the object, and therefore we must reconstruct the interior <em>volume </em>to figure out how the cracks propagate through that object.</p>
<p>About the breakage process, it&#8217;s worth noting that the simulation is itself a very broad subject, and it largely depends on the <em>physical properties</em> of the material we&#8217;re simulating: for instance, wereas hard minerals and crystals will generally shatter in <em>clean </em>fractures, other materials such as wood will show some flexibility before breaking, and then splinter off  producing a very different kind of fragments. The problem we&#8217;re tackling here lies within the first kind of clean-fracturing materials.</p>
<div id="attachment_64" class="wp-caption alignnone" style="width: 510px"><a href="http://www.joesfer.com/wp-content/uploads/2011/02/materials.jpg" target="_blank"><img class="size-full wp-image-64  " title="materials" src="http://www.joesfer.com/wp-content/uploads/2011/02/materials.jpg" alt="" width="500" height="188" /></a><p class="wp-caption-text">Fig 1. Materials influence the appearance of the fractures</p></div>
<h2>The approach: Voronoi Shattering</h2>
<p>Purely procedural simulations have little value if they can&#8217;t be controlled. I therefore wanted to work on a solution which, while being automatic, would also give the artist some degree of <strong>control </strong>about the way the fragments are generated without having to describe each one of them individually.</p>
<p>Before getting into details, let&#8217;s have a look at the overall picture of the process to better understand each stage (see <strong>Fig. 2</strong>): we start with a source polygonal mesh which is sampled to produce a set of seed points directing the slicing. Each seed is turned into a set of planes describing it&#8217;s corresponding <em>Voronoi Cell</em> (more on this next) which is used to iteratively slice the mesh. After each split, a hole filling stage adds new faces to the mesh to cover the resulting gap. The process is repeated for all the planes of a seed, for each seed, resulting in a set of convex forms corresponding to the <em>fragment</em>s.</p>
<p>&nbsp;</p>
<div id="attachment_63" class="wp-caption alignnone" style="width: 510px"><strong><strong><img class="size-full wp-image-63 " title="overview" src="http://www.joesfer.com/wp-content/uploads/2011/02/overview1.png" alt="" width="500" height="468" /></strong></strong><p class="wp-caption-text">Fig 2. Process Overview</p></div>
<p>I&#8217;ll skip the details about the Volume Sampling for now to avoid sidetracking too much, and leave that (interesting) subject for a further post. For now all that matters is that we start with a set of points related somehow to the mesh we&#8217;re breaking &#8211; they could be obtained by sampling as it is the case here, but also by using other simpler means such as particle systems. Given those seed points telling us <em>where </em>to break our object, the complex task of splitting the mesh is decomposed into an iterative process of bulding each fragment by splitting the source geometry by a different set of planes each time. Let&#8217;s move on to see how we obtain the splitting planes from a seed point by using Voronoi Diagrams.<strong><br />
</strong></p>
<h3>Voronoi Diagrams</h3>
<div id="attachment_66" class="wp-caption alignleft" style="width: 260px"><img class="size-full wp-image-66      " style="border: 0pt none; margin-left: 0px; margin-right: 0px;" title="voronoi" src="http://www.joesfer.com/wp-content/uploads/2011/02/voronoi1.png" alt="" width="250" height="243" /><p class="wp-caption-text">Fig 3. Vornoi Diagram in 2D</p></div>
<p>A <a title="Voronoi Diagram" href="http://en.wikipedia.org/wiki/Voronoi_diagram" target="_blank">Voronoi Diagram</a> (VD) is a way of decompositing the space which takes a set of points and produces an equal number of <strong>disjoint convex </strong>areas (called <em>cells</em>), one for each point. A cell encloses the space which is closer to its associated point S<em>i</em> than to any other point of S.</p>
<p>Voronoi Diagrams have many applications, and for our purposes we&#8217;re particularly interested in the fact that visually they <em>look </em>a lot like <strong>cracks</strong> &#8211; by tweaking the distribution of the initial set of seed points, we can somewhat control the look of how we&#8217;re going to break our object. Furthermore, since we&#8217;ll be using the cells to slice the mesh, it is very convenient that there will be no intersections among them, and that each cell is guaranteed to be <strong>convex</strong>; this simplifies the mesh cutting by allowing us to use infinite split planes.</p>
<h3><span id="more-60"></span>Delaunay Tetrahedralization</h3>
<p>There are algorithms that can generate a Voronoi Diagram directly from a set of points, but a more common way of doing so is by using an intermediate <a title="Delaunay Triangulation" href="http://en.wikipedia.org/wiki/Delaunay_triangulation" target="_blank">Delaunay Triangulation</a> (DT) of the source points. The graph representing the information of a VD is said to be <em>dual </em>of the corresponding graph of a DT, and vice versa. This means that having one, we have all the information we need to reconstruct the other (for example, the vertices of a DT are the centers of each cell in a VD). Therefore,<strong> in order to obtain the VD we can first generate a Delaunay Triangulation</strong> from the seed points and obtain the dual graph from it. See <strong>Figure 4</strong> for a 2D representation.</p>
<div id="attachment_68" class="wp-caption alignright" style="width: 260px"><img class="size-full wp-image-68 " title="VD-DT" src="http://www.joesfer.com/wp-content/uploads/2011/02/VD-DT1.png" alt="" width="250" height="243" /><p class="wp-caption-text">Fig 4. DT (black) / VD (red) equivalence for the set of yellow points</p></div>
<p>Things get a bit trickier because we&#8217;re working on a 3D domain (our points describe a <em>volume</em>), and therefore instead of a 2D triangulation, we require extending the DT to 3 dimensions; this is called a <strong>tetrahedralization</strong>,<strong> </strong>since the primitives are no longer triangles but <em>tetrahedra </em>(pyramids with a triangular base). As you probably guessed, an extra dimension to the problem causes an nice evil explosion of new cases to be taken care of!</p>
<p>There is a lot of literature about DT for the 2-dimensional case,  being a very well studied problem. However the tetrahedralization doesn&#8217;t seem to be so popular, and some of the algorithms available for 2D DT don&#8217;t extend to higher dimensions. A good solution would be making use of 3rd party libraries such as <a title="CGAL" href="http://www.cgal.org/" target="_blank">CGAL</a>, which it&#8217;s really complete and free (in fact it&#8217;d be arguably the <em>sensible </em>choice to make) &#8211; however, for me the purpose of these pet projects to learn new things, so I took the hard way and went for an implementation of my own <img src='http://www.joesfer.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . A good reference I mostly based upon is <strong>[<a title="Ledoux" href="http://www.rgi-otb.nl/3dtopo/documents/RGI-011-56.pdf" target="_blank">Ledoux</a>]</strong>, which focuses both on the implementation details as well as handling of the (many) degenerate cases of a DT, using an incremental flip-based algorithm.</p>
<p>The idea for this mesh tetrahedralization is to start with a single large tetrahedron covering the entire domain, and progressively insert all the points, one at a time. On each insertion, we determine which tetrahedron on the existing partition contains the new point, and split that into smaller tetrahedra (the actual number depends on whether the point lies in the inside of the shape or on one of its faces). The algorithm is called <em>flip-based</em> because after each split follows a neighbour-fixing stage where the adjacent tetrahedra are recursively tested for the empty circumsphere criterion and fixed by flipping them in a series of configurations (<strong>Figure 5</strong>) until they&#8217;re Delaunay. The process is guaranteed to converge eventually, assuming we deal robustly with numerical precision issues. Once we&#8217;re done with the Delaunay tetrahedralization, we can easily obtain its dual Voronoi Diagram without further computations.</p>
<div id="attachment_81" class="wp-caption alignnone" style="width: 510px"><a href="http://www.joesfer.com/wp-content/uploads/2011/03/flips.png"><img class="size-full wp-image-81" title="flips" src="http://www.joesfer.com/wp-content/uploads/2011/03/flips.png" alt="" width="500" height="408" /></a><p class="wp-caption-text">Fig.5. Flips used to construct the tetrahedralization</p></div>
<p>The cells resulting from the 3D Voronoi Diagram are not actually flat polygons like the ones in <strong>Figure 3</strong>, but instead convex volumes made up of N-sided faces. An important lesson learnt here is how <em>crucial </em>is getting the DT step right and ensure each tetrahedron produced satisfies the Delaunay Condition (i.e. empty circumspheres) &#8211; even slight errors errors in this stage are magnified in the dual VD, resulting in more apparent problems such as cell overlapment or incoherent sizes which will produce horribly-looking cracks. <strong> </strong></p>
<h3>To be continued&#8230;</h3>
<p>This is the end of the first part, I hope it was an interesting read! At this point we got all the elements we need to proceed splitting the mesh. In <a href="http://www.joesfer.com/?p=69">the next post</a> I&#8217;ll elaborate about how the fragments are actually generated from the VD cells, and what didn&#8217;t turn up <em>that </em>well in the process&#8230;</p>
<h2>Downloads</h2>
<p>I&#8217;ve implemented the algorithm as a Maya plugin, there&#8217;s a version compiled for Maya 2011 32-bit (Windows) which you can download from <a href="http://www.joesfer.com/wp-content/uploads/programming/Maya/shatter/shatter.rar" target="_blank">here</a>. In the file you&#8217;ll find the .mll along with a sample MEL script to set up a sample scene. Please read the license and note this is a prototype to illustrate the described method, rather than a production-ready solution &#8211; no technical support is provided. Use it at your own risk (and enjoy it!).</p>
<p>The source code can be found in <a href="https://github.com/joesfer/Voronoi-Shattering" target="_blank">github</a></p>
<h2>References</h2>
<p><strong>[<a title="Ledoux" href="http://www.rgi-otb.nl/3dtopo/documents/RGI-011-56.pdf" target="_blank">Ledoux</a>]</strong> Hugo Ledoux. <em>Computing the 3D Voronoi Diagram Robustly: An Easy Explanation.</em></p>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 123px; width: 1px; height: 1px; overflow: hidden;">I wanted to work on a solution which while being procedural, would give the artist some <strong>control </strong>about the way the fragments are generated without having to describe them individually. Put in short, the idea I&#8217;ll describe is based on generating a set of <em>seed points </em>obtained by sampling the volume of the source mesh, and converting them to a 3D Voronoi Diagram which cells we&#8217;ll use to slice the geometry.</div>
<div class="tweetthis" style="text-align:left;"><p> <a target="_blank" rel="nofollow" class="tt" href="http://twitter.com/home/?status=Voronoi+Shattering+%28Part+I%29+http%3A%2F%2Fjoesfer.com%2F%3Fp%3D60"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/twitter/tt-twitter.png" alt="Post to Twitter" /></a> <a target="_blank" rel="nofollow" class="tt" href="http://delicious.com/post?url=http://www.joesfer.com/?p=60&amp;title=Voronoi+Shattering+%28Part+I%29"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/delicious/tt-delicious.png" alt="Post to Delicious" /></a> <a target="_blank" rel="nofollow" class="tt" href="http://www.facebook.com/share.php?u=http://www.joesfer.com/?p=60&amp;t=Voronoi+Shattering+%28Part+I%29"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/facebook/tt-facebook.png" alt="Post to Facebook" /></a> <a target="_blank" rel="nofollow" class="tt" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http://www.joesfer.com/?p=60&amp;title=Voronoi+Shattering+%28Part+I%29&amp;summary=%5Bvimeo+21180571%5D%0D%0A%0D%0AThe+project+I%27ve+been+working+on+for+some+time+now+is+an+implementation+of+a+shattering+algorithm+used+to+break+objects+into+pi...&amp;source=Jose&#039;s sketchbook"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/linkedin/tt-linkedin.png" alt="Post to LinkedIn" /></a></p></div>]]></content:encoded>
			<wfw:commentRss>http://www.joesfer.com/?feed=rss2&#038;p=60</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Nature patterns</title>
		<link>http://www.joesfer.com/?p=54</link>
		<comments>http://www.joesfer.com/?p=54#comments</comments>
		<pubDate>Mon, 25 Oct 2010 00:29:53 +0000</pubDate>
		<dc:creator>Jose</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[diffusion]]></category>
		<category><![CDATA[nature]]></category>
		<category><![CDATA[pattern]]></category>
		<category><![CDATA[procedural]]></category>
		<category><![CDATA[Processing]]></category>
		<category><![CDATA[Reaction]]></category>
		<category><![CDATA[texture]]></category>

		<guid isPermaLink="false">http://www.joesfer.com/?p=54</guid>
		<description><![CDATA[Using Reaction Diffusion system to generate natural-looking seamless patterns found in some mammals and fish.]]></description>
				<content:encoded><![CDATA[<p>In the field of Texture Synthesis, I recently discovered the wonders of the <a href="http://en.wikipedia.org/wiki/Reaction%E2%80%93diffusion_system" target="_blank">Reaction Diffusion System</a> for nature-like patterns synthesis. The RD method consists on a set of equations which iteratively simulate the distribution of a chemical agent (<em>activator</em>) modulated by the presence of another agent called <em>inhibitor</em>. It is believed that such interactions take place in nature to form patterns which can be found in mammals and fish, and the first model, generating spots, was proposed by Turing himself <strong>[Turing 52]</strong>, dating back from 1952!.</p>
<h2>Reaction Diffusion</h2>
<p><img class="alignright" title="animals" src="http://www.joesfer.com/wp-content/uploads/programming/processing/RD/media/animals.jpg" alt="" width="334" height="442" />By playing with the parameters of an RD system, it is possible to simulate a variety of patterns ranging from spots to stripes. Unfortunately I haven&#8217;t found huge amounts of information on the subject (let alone up-to-date resources): one of the most complete texts is Greg Turk&#8217;s thesis <strong>[Turk 91]</strong>, which covers both Turing-like spots and stripes. For the later, the most extended set of equations is the one proposed by <strong>[Meinhardt 82]</strong> which generates the kind of images I wanted to achieve.</p>
<p>The main problem <em>in practice</em>, however, is that Meinhardt&#8217;s description consists on 5 equations with several <strong>magic constants</strong> (which might make sense in chemical terms, but the authors seem to obviate) that lead to a large search space. Even more fun, the system is <em>really</em> sensitive to small variations on the value of each constant, and I spent quite a lot of time searching for a set of values which was <em>stable </em>and <em>converged </em>to something meaningful. Luckily, <strong>[Asai 99]</strong> and <strong>[Kondo 09]</strong> provide an alternative formulation of Meinhardt&#8217;s RD system, and an <em><strong>illustrated</strong></em> set of values to play with, which is how I ended up implementing it.</p>
<div id="attachment_48" class="wp-caption aligncenter" style="width: 390px"></p>
<p><img src="http://www.joesfer.com/wp-content/ql-cache/quicklatex.com-e2dc3db42d7bb8b8652a37cf049e76c5_l3.png" class="ql-img-inline-formula " alt=" &#92;&#102;&#114;&#97;&#99;&#123;&#92;&#112;&#97;&#114;&#116;&#105;&#97;&#108;&#32;&#117;&#125;&#123;&#92;&#112;&#97;&#114;&#116;&#105;&#97;&#108;&#32;&#116;&#125;&#32;&#61;&#32;&#120;&#40;&#117;&#44;&#118;&#41;&#32;&#45;&#32;&#100;&#123;&#92;&#99;&#100;&#111;&#116;&#125;&#117;&#32;&#43;&#32;&#68;&#95;&#123;&#117;&#125;&#92;&#98;&#105;&#103;&#116;&#114;&#105;&#97;&#110;&#103;&#108;&#101;&#100;&#111;&#119;&#110;&#94;&#50;&#117;&#92;&#110;&#101;&#119;&#108;&#105;&#110;&#101; &#92;&#102;&#114;&#97;&#99;&#123;&#92;&#112;&#97;&#114;&#116;&#105;&#97;&#108;&#32;&#118;&#125;&#123;&#92;&#112;&#97;&#114;&#116;&#105;&#97;&#108;&#32;&#116;&#125;&#32;&#61;&#32;&#121;&#40;&#117;&#44;&#118;&#41;&#32;&#45;&#32;&#103;&#123;&#92;&#99;&#100;&#111;&#116;&#125;&#118;&#32;&#43;&#32;&#68;&#95;&#123;&#118;&#125;&#92;&#98;&#105;&#103;&#116;&#114;&#105;&#97;&#110;&#103;&#108;&#101;&#100;&#111;&#119;&#110;&#94;&#50;&#118;&#92;&#110;&#101;&#119;&#108;&#105;&#110;&#101; &#120;&#40;&#117;&#44;&#118;&#41;&#32;&#61;&#32;&#32;&#97;&#123;&#92;&#99;&#100;&#111;&#116;&#125;&#117;&#32;&#45;&#32;&#98;&#123;&#92;&#99;&#100;&#111;&#116;&#125;&#118;&#32;&#43;&#32;&#99;&#92;&#110;&#101;&#119;&#108;&#105;&#110;&#101; &#121;&#40;&#117;&#44;&#118;&#41;&#32;&#61;&#32;&#32;&#101;&#123;&#92;&#99;&#100;&#111;&#116;&#125;&#117;&#32;&#45;&#32;&#102;&#92;&#110;&#101;&#119;&#108;&#105;&#110;&#101; " title="Rendered by QuickLaTeX.com" height="89" width="227" style="vertical-align: 18px;"/></p>
<p><p class="wp-caption-text">RD Strip system as appears in |Asai 99|. The reference value for the constants is a = 0.08, b = 0.08, c = 0.28, d = 0.03, e = 0.1, f = 0.15, g = 0.05</p></div>
<p>Below is an applet created with Processing which illustrates the process, it starts with a randomized concentration of the activator an inhibitor agents, and a small set of frozen points in the grid which help creating &#8220;vortices&#8221;. If you let it run long enough, it should converge to a nice seamless pattern with spirals (not that I&#8217;ve seen a fish with that pattern, but it would be cool!).<br />
<code></p>
<div id="processing"><!--[if !IE]> --><br />
<object classid="java:DiffusionReaction.class" type="application/x-java-applet" archive="wp-content/uploads/programming/processing/RD/DiffusionReaction.jar" standby="Loading Processing software..." height="500" width="500"><param name="archive" value="wp-content/uploads/programming/processing/RD/DiffusionReaction.jar"><param name="mayscript" value="true"><param name="scriptable" value="true"><param name="image" value="wp-content/uploads/programming/processing/loading.gif"><param name="boxmessage" value="Loading Processing software..."><param name="boxbgcolor" value="#FFFFFF"><param name="test_string" value="outer"><![endif]--><br />
<object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" codebase="http://java.sun.com/update/1.4.2/jinstall-1_4_2_12-windows-i586.cab" standby="Loading Processing software..." height="512" width="512"><param name="code" value="DiffusionReaction"><param name="archive" value="wp-content/uploads/programming/processing/RD/DiffusionReaction.jar"><param name="mayscript" value="true"><param name="scriptable" value="true"><param name="image" value="wp-content/uploads/programming/processing/loading.gif"><param name="boxmessage" value="Loading Processing software..."><param name="boxbgcolor" value="#FFFFFF"><param name="test_string" value="inner"><p>This browser does not have a Java Plug-in.<br /><a href="http://java.sun.com/products/plugin/downloads/index.html" title="Download Java Plug-in">Get the latest Java Plug-in here.</a></p>
<p></object><br />
<!--[if !IE]> --><br />
</object><br />
<!--<![endif]-->
</div>
<p>'Space' key to reset simulation. 'Enter' key to stop. Built with <a title="Processing.org" href="http://processing.org">Processing</a><br />
</code></p>
<p>And it produces some great displacement maps!</p>
<p><img alt="" src="http://www.joesfer.com/wp-content/uploads/programming/processing/RD/media/displacement.jpeg" title="Displacement" class="aligncenter" width="512" height="512" /></p>
<h2>References</h2>
<p>[Turing 52] Turing, Alan, “The Chemical Basis of Morphogenesis,” Philosophical Transactions of the Royal Society B, Vol. 237, pp. 37–72 (August 14, 1952).</p>
<p>[Meinhardt 82] Meinhardt, Hans, Models of Biological Pattern Formation, Academic Press, London, 1982.</p>
<p>[<a href="http://www.cc.gatech.edu/~turk/reaction_diffusion/reaction_diffusion.html" target="_blank">Turk 91</a>] Turk, Greg, &#8220;Texturing Surfaces Using Reaction-Diffusion&#8221; Ph.D. Thesis, 1981</p>
<p>[<a href="http://www.google.es/url?sa=t&amp;source=web&amp;cd=3&amp;ved=0CCIQFjAC&amp;url=http%3A%2F%2Fconlonlab.org%2Fcourses%2Fmaterials%2F523mats%2FTuring%2FAsai.pdf&amp;rct=j&amp;q=.%20Zebrafish%20leopard%20gene%20as%20a%20component%20of%20the%20putative%20reaction%E2%80%93diffusion%20system&amp;ei=VRPCTKOvHYKV4gb7yM3QCw&amp;usg=AFQjCNGxLk5GqKxP3B50bcJ2C5o_gvGSxA&amp;cad=rja" target="_blank">Asai 99</a>] Rihito Asaia, Emiko Taguchia, Yukari Kumea, Mayumi Saitoa, Shigeru Kondoa, &#8220;Zebrafish Leopard gene as a component of the putative reaction-diffusion system&#8221;.</p>
<p>[<a href="http://www.fbs.osaka-u.ac.jp/labs/skondo/paper/shirota%20%20seminors%20in%20dev%20biol.pdf" target="_blank">Kondo 09</a>] Shigeru Kondo, Hideaki Shirota, &#8220;Theoretical analysis of mechanisms that generate the pigmentation pattern of animals&#8221;, Division of Biological Science, Graduate School of Science, Nagoya University, Furo-cho, Chikusa-ku, Nagoya 464-8602, Japan</p>
<div class="tweetthis" style="text-align:left;"><p> <a target="_blank" rel="nofollow" class="tt" href="http://twitter.com/home/?status=Nature+patterns+http%3A%2F%2Fjoesfer.com%2F%3Fp%3D54"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/twitter/tt-twitter.png" alt="Post to Twitter" /></a> <a target="_blank" rel="nofollow" class="tt" href="http://delicious.com/post?url=http://www.joesfer.com/?p=54&amp;title=Nature+patterns"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/delicious/tt-delicious.png" alt="Post to Delicious" /></a> <a target="_blank" rel="nofollow" class="tt" href="http://www.facebook.com/share.php?u=http://www.joesfer.com/?p=54&amp;t=Nature+patterns"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/facebook/tt-facebook.png" alt="Post to Facebook" /></a> <a target="_blank" rel="nofollow" class="tt" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http://www.joesfer.com/?p=54&amp;title=Nature+patterns&amp;summary=Using+Reaction+Diffusion+system+to+generate+natural-looking+seamless+patterns+found+in+some+mammals+and+fish.&amp;source=Jose&#039;s sketchbook"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/linkedin/tt-linkedin.png" alt="Post to LinkedIn" /></a></p></div>]]></content:encoded>
			<wfw:commentRss>http://www.joesfer.com/?feed=rss2&#038;p=54</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Growing organic structures</title>
		<link>http://www.joesfer.com/?p=46</link>
		<comments>http://www.joesfer.com/?p=46#comments</comments>
		<pubDate>Sun, 26 Sep 2010 09:15:30 +0000</pubDate>
		<dc:creator>Jose</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[Maya]]></category>
		<category><![CDATA[procedural]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[synthesis]]></category>
		<category><![CDATA[veins]]></category>

		<guid isPermaLink="false">http://www.joesfer.com/?p=46</guid>
		<description><![CDATA[About procedural organic-looking grown structures, which  must be controllable and confined to user-defined space.]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.joesfer.com/wp-content/uploads/2010/09/bunny.jpg"><img class="aligncenter size-full wp-image-49" title="Image converted using ifftoany" src="http://www.joesfer.com/wp-content/uploads/2010/09/bunny.jpg" alt="" width="500" height="500" /></a></p>
<p>This project arose from a conversation with my friend <a title="Gino Dammers" href="http://uk.linkedin.com/in/ginodammers" target="_blank">Gino</a>, who is currently working on Medical Visualization, about the difficulty for an artist to create growing structures such as veins -let alone animate them- and how to make them look organic, and therefore irregular and adapted to the surrounding they grow upon.</p>
<h2>The Problem</h2>
<p>I decided to tackle the problem, and the first approach that came to my mind were <a title="L-Systems" href="http://en.wikipedia.org/wiki/L-system" target="_blank">L-Systems</a>, which have proven useful for modelling vegetation. There are two restrictions, however, which discouraged me from taking this approach:</p>
<ol>
<li>We should be able to bind the growing of the structures to a surface, and therefore the growth needs to be <strong><em>context</em> <em>aware</em></strong>.</li>
<li>We need to be able to <strong>direct the growth</strong> by specifying the areas the structure is allowed to occupy.</li>
</ol>
<p>Doing some research I ended up taking the approach described in the paper <a title="paper" href="http://algorithmicbotany.org/papers/colonization.egwnp2007.html" target="_blank">Modeling trees with a space colonization algorithm</a>, listed in <a title="algorithmic botany" href="http://algorithmicbotany.org/papers/" target="_blank">Algorithmic Botany</a>, which perfectly suits the aforementioned requirements.</p>
<h2>Space Colonization Algorithm</h2>
<div id="attachment_48" class="wp-caption alignleft" style="width: 310px"><a href="../wp-content/uploads/2010/09/SCA.png"><img class="size-medium wp-image-48 " title="SCA" src="../wp-content/uploads/2010/09/SCA-300x189.png" alt="" width="300" height="189" /></a><p class="wp-caption-text">Space Colonization Algorithm</p></div>
<p>The idea for the <strong>Space Colonization Algorithm</strong> is brilliantly simple: instead of generating the nodes that build our structure by using a set of rules (e.g. a grammar), we begin by producing a set of <strong>attractor points</strong> by sampling a domain -the surface of an object in our case-. Then we provide one or several<strong> start locations</strong>, and we iteratively start adding nodes by looking for the set of<strong> nearest <em>active </em>attractors</strong>, and growing towards them. When a new node is added, it <strong>kills all the attractor points</strong> which fall within a specified range, preventing other branches to fill in the same space, and directing the growth forward.</p>
<h2>Implementation in Maya</h2>
<p>Given the stages of the SCA algorithm, the natural solution felt to devise them as a set of separate DAG nodes which will be linked together. This allows Maya to cache the result of each individual stage and <strong>update the graph efficiently</strong> when a given parameter is tweaked without requiring the whole solution to be re-evaluated.</p>
<p><a href="http://www.joesfer.com/wp-content/uploads/2010/09/nodes.png"><img class="aligncenter size-full wp-image-47" title="nodes" src="http://www.joesfer.com/wp-content/uploads/2010/09/nodes.png" alt="" width="500" height="142" /></a></p>
<ul>
<li><strong>The Sampler node</strong>: takes a mesh as the input and produces a number of attractor points by sampling it. The more points we generate, the better the growing structure will fit upon the surface, but that will also tend to generate denser heavier structures.</li>
<li><strong>The Grower node</strong>: implements the SCA algorithm. It is fed with the set of attractor points, which are stored in a <a title="kd-tree" href="http://en.wikipedia.org/wiki/Kd-tree" target="_blank">kd-tree</a> for efficient <a title="nearest neighbor" href="http://en.wikipedia.org/wiki/Nearest_neighbor_search" target="_blank">nearest neighbor</a> queries. An <strong>input locator </strong>provides the start position for the growth, and the exposed parameters of the algorithm control how the attractors are consumed to produce the resulting structure:
<ul>
<li><strong><em>Search Radius</em></strong>: specifies what&#8217;s the maximum distance an attractor point can influence over a node. It is given in % of the mesh bounding box extents. A high value will link distant areas, allowing the structure to &#8220;jump&#8221; between them.</li>
<li><strong><em>Kill Radius</em></strong>: The range within an attractor point will be killed if it is near a grower node. Large kill radius result in smoother branches, whereas lower values will generate curlier shapes.</li>
<li><strong><em>Grow Distance</em></strong>: the distance between nodes, the lower the value, the denser the resulting geometry.</li>
<li><strong><em>Max Neighbors</em></strong>: for the nearest neighbor searches &#8211; controls how many attractor points affect a given node at a time. Large values will smooth out the branches, and a low number of neighbors on the other hand will produce <em>noisier </em>more organic lines (up to a limit).</li>
</ul>
</li>
<li><strong>The Trimmer node</strong>: provides a Percent Length parameter which can be used to animate the growth of the structure generated.</li>
<li><strong>The GrowerShape node</strong>: takes the (trimmed) result of the SCA and generates a polygonal mesh. It exposes a <em>Tube Sections</em>, and <em>Thickness </em>parameters, which control the smoothness and size of the branches.</li>
</ul>
<p>The node hierarchy can be easily built with the provided command <strong>&#8220;grow</strong>&#8221; -  Just select a mesh and an optional a locator node, and type <em>grow</em> on the MEL console.</p>
<p><iframe src="http://player.vimeo.com/video/15292473" width="400" height="225" frameborder="0"></iframe></p>
<h3>Directing the growth</h3>
<p>The sampler node allows restricting which faces are used to generate the attractor points. To do so, it uses a <strong>vertex color set</strong> associated with the input mesh: the lightness of the vertex colors is used to determine the probability for each face to be sampled, hence, black faces will be excluded from sampling. See the example video below.</p>
<p><iframe src="http://player.vimeo.com/video/15274926" width="400" height="225" frameborder="0"></iframe></p>
<h2>Download</h2>
<p>If you feel like trying it out, I have compiled a version of the plugin for Maya 2011 32 and 64-bit. You can find it <a title="Plugin" href="http://www.joesfer.com/wp-content/uploads/programming/Maya/grower/grower.zip" target="_blank">here</a>.</p>
<p>Also, the source code is hosted under <a title="github" href="https://github.com/joesfer/Grower">github</a></p>
<div class="tweetthis" style="text-align:left;"><p> <a target="_blank" rel="nofollow" class="tt" href="http://twitter.com/home/?status=Growing+organic+structures+http%3A%2F%2Fjoesfer.com%2F%3Fp%3D46"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/twitter/tt-twitter.png" alt="Post to Twitter" /></a> <a target="_blank" rel="nofollow" class="tt" href="http://delicious.com/post?url=http://www.joesfer.com/?p=46&amp;title=Growing+organic+structures"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/delicious/tt-delicious.png" alt="Post to Delicious" /></a> <a target="_blank" rel="nofollow" class="tt" href="http://www.facebook.com/share.php?u=http://www.joesfer.com/?p=46&amp;t=Growing+organic+structures"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/facebook/tt-facebook.png" alt="Post to Facebook" /></a> <a target="_blank" rel="nofollow" class="tt" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http://www.joesfer.com/?p=46&amp;title=Growing+organic+structures&amp;summary=About+procedural+organic-looking+grown+structures%2C+which++must+be+controllable+and+confined+to+user-defined+space.&amp;source=Jose&#039;s sketchbook"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/linkedin/tt-linkedin.png" alt="Post to LinkedIn" /></a></p></div>]]></content:encoded>
			<wfw:commentRss>http://www.joesfer.com/?feed=rss2&#038;p=46</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Blobs in Maya</title>
		<link>http://www.joesfer.com/?p=40</link>
		<comments>http://www.joesfer.com/?p=40#comments</comments>
		<pubDate>Sun, 12 Sep 2010 00:19:59 +0000</pubDate>
		<dc:creator>Jose</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[Maya]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[synthesis]]></category>

		<guid isPermaLink="false">http://www.joesfer.com/?p=40</guid>
		<description><![CDATA[For this post, I have been working on implementing isosurfaces as a modeling tool in Maya to create blobby things such as the one depicted in the image below. Isosurfaces An isosurface is a shape which is described by taking a scalar field and building a surface from all the points on the field of [...]]]></description>
				<content:encoded><![CDATA[<p>For this post, I have been working on implementing isosurfaces as a modeling tool in Maya to create <em>blobby </em>things such as the one depicted in the image below.</p>
<p><a href="http://www.joesfer.com/wp-content/uploads/2010/09/marching-cubes.png"><img class="size-medium wp-image-42 alignleft" title="marching cubes" src="http://www.joesfer.com/wp-content/uploads/2010/09/marching-cubes.png" alt="" width="500" height="363" /></a></p>
<h2>Isosurfaces</h2>
<p>An <a title="iso surface" href="http://en.wikipedia.org/wiki/Isosurface" target="_blank">isosurface</a> is a shape which is described by taking a <em><em>scalar </em>field</em> and building a surface from all the points on the field of which value matches a given threshold level we provide. To generate a polygonal surface we can use in computer graphics, our scalar field will be given by a 3D matrix -or grid- of numbers, which we will iterate in order to fetch the points that describe our shape. Unlike the mathematical scalar field, which  is defined in <em>every</em> point, our grid describes a <em><strong>discreet </strong></em>sampling of the field, for we only know the values of the field in the vertices of the grid cells.</p>
<div class="wp-caption alignright" style="width: 360px"><img class=" " title="Some of the Marching Cubes configurations" src="http://upload.wikimedia.org/wikipedia/commons/thumb/a/a7/MarchingCubes.svg/350px-MarchingCubes.svg.png" alt="Marching cubes" width="350" height="165" /><p class="wp-caption-text">Fig 1. Some of the Marching Cubes configurations</p></div>
<p>To build the surface from this discretized field, we generate triangles from each one of the cells conforming the grid by using the <a title="Marching Cubes" href="http://en.wikipedia.org/wiki/Marching_cubes" target="_blank">Marching Cubes</a> algorithm. Given a grid cell, we mark each one of the 8 vertices as <em>above </em>or <em>below </em>the threshold level we provided. From those values, the algorithm provides a set of triangles which describe the surface inside that cell (Fig 1).</p>
<h2>Maya Implementation</h2>
<p>This particular implementation I provide here is integrated with Maya as a Surface Plug-in. It uses <strong>Maya&#8217;s particle systems</strong> to generate the scalar field &#8211; for each particle, we define a radius that describes the <em>sphere of influence</em> of that particle. The influence rapidly decays to zero as soon as we move away from the particle. Next, a grid within the particle&#8217;s bounding box is created, and sampled at a frequency given by the<em> Grid Res</em> attribute in the shape node. The surface node can also be plugged the<strong> particle colors</strong> and interpolate them in the resulting triangles, producing nice color blends. The<strong> higher the sampling frequency</strong>, the smaller the triangles and the <strong>more detailed surface</strong> we obtain. Bear in mind however that the number of cells grows proportionally to the <strong>cube </strong>of the grid resolution, so the surface generation quickly<strong> </strong>becomes a <strong>processor-intensive task</strong>.</p>
<h3>Optimization</h3>
<div id="attachment_43" class="wp-caption alignright" style="width: 310px"><a href="http://www.joesfer.com/wp-content/uploads/2010/09/grid-optimization.png"><img class="size-medium wp-image-43" title="grid optimization" src="http://www.joesfer.com/wp-content/uploads/2010/09/grid-optimization-300x280.png" alt="" width="300" height="280" /></a><p class="wp-caption-text">Fig 2. Fraction of the cells actually used</p></div>
<p>I started prototyping the plug-in  using Maya Python, but it soon became too slow to be practical, and I had to switch to C++. While working on it, I realized that for &#8220;splashy&#8221;<em> </em>particle systems such as the one depicted in the picture above, applying the triangulation to the <em>entire </em>grid is very wasteful, as only a small portion of the total cells (around 20% in that particular example) tend to be touched by the particles and thus will actually produce triangles. Therefore I optimized the triangle generation by performing a first pass over the grid and tagging those cells that will potentially be affected by the particles, skipping all the rest. On a second pass, the marching cubes is only applied to those tagged cells (colored in white in Fig 2.). Finally, Maya seems to like copying data around when handling nodes, and the internal cell occupancy cache can generate a lot of memory fragmentation if created/deleted every frame. To avoid this, a lazy-copy wrapper around te memory chunk is provided, so that the number of memory operations is minimized.</p>
<h2>Downloads</h2>
<p>Finally, if you would like to try it, I have posted a version of the<a title="Plugin" href="http://joesfer.com/wp-content/uploads/programming/Maya/mc" target="_blank"> plug-in</a> compiled for Maya 2011 x64 here, as well as a sample scene. For the programmers among us, the source code can be found <a title="source" href="http://joesfer.com/wp-content/uploads/programming/Maya/mc/marchingCubes_src_VS9.rar" target="_blank">here</a>.</p>
<div class="tweetthis" style="text-align:left;"><p> <a target="_blank" rel="nofollow" class="tt" href="http://twitter.com/home/?status=Blobs+in+Maya+http%3A%2F%2Fjoesfer.com%2F%3Fp%3D40"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/twitter/tt-twitter.png" alt="Post to Twitter" /></a> <a target="_blank" rel="nofollow" class="tt" href="http://delicious.com/post?url=http://www.joesfer.com/?p=40&amp;title=Blobs+in+Maya"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/delicious/tt-delicious.png" alt="Post to Delicious" /></a> <a target="_blank" rel="nofollow" class="tt" href="http://www.facebook.com/share.php?u=http://www.joesfer.com/?p=40&amp;t=Blobs+in+Maya"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/facebook/tt-facebook.png" alt="Post to Facebook" /></a> <a target="_blank" rel="nofollow" class="tt" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http://www.joesfer.com/?p=40&amp;title=Blobs+in+Maya&amp;summary=For+this+post%2C+I+have+been+working+on+implementing+isosurfaces+as+a+modeling+tool+in+Maya+to+create+blobby+things+such+as+the+one+depicted+in+the+i...&amp;source=Jose&#039;s sketchbook"><img class="nothumb" src="http://www.joesfer.com/wp-content/plugins/tweet-this/icons/en/linkedin/tt-linkedin.png" alt="Post to LinkedIn" /></a></p></div>]]></content:encoded>
			<wfw:commentRss>http://www.joesfer.com/?feed=rss2&#038;p=40</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>
