Smathermather's Weblog

Remote Sensing, GIS, Ecology, and Oddball Techniques

Optimizing Pov-Ray include files– smaller trees with the same effect

Posted by smathermather on January 8, 2010

One limitation I’ve run into in rendering large scenes of trees in PovRay, whether for fun for work is memory usage.  I’ve found that about a half million trees is about as many as I can place on a 32-bit system before running out of memory.  Sometime this year I’ll switch to 64-bits, but in the mean time, I hacked together a solution for reducing my tree include file sizes to save memory.

My include file is called tree.inc.  It has the following format (generated by PovTree):

#declare FOLIAGE = mesh {
triangle{<0.18162394, -0.24128051, 0.030293489>, <0.18287745, -0.23965627, 0.026677>, <0.18274091, -0.23925833, 0.033750653>}
triangle{<0.18287745, -0.23965627, 0.026677>, <0.18274091, -0.23925833, 0.033750653>, <0.18468907, -0.23614006, 0.0350326>}
...
...

#declare TREE = union {
object{FOLIAGE}
}

You’ll notice 8 decimal places for those coordinates.  We probably don’t need that level of precision.  The code that follows is messy, but it does the trick– using printf within awk to reduce the total number of decimal points (3 decimal places in this case).  If memory serves me, we strip all the extra brackets, carrots, and commas with sed, format with awk as a 3 decimal place number, put our brackets, carrots, and commas back where they belong, and the trim out any extra characters with sed before piping to a new include file, tree1.inc.  Oh, and I think I just manually added back on the FOLIAGE declaration, etc..

more tree.inc | grep "triangle" | \
sed -e 's/{/ /g' -e 's/</ /g' -e 's/>/ /g' -e 's/}/ /g' -e 's/,/ /g'| \
awk '{ printf "%0.3f %0.3f %0.3f %0.3f %0.3f %0.3f %0.3f %0.3f %0.3f \n", $2, $3, $4, $5, $6, $7, $8, $9, $10};' | \
awk '{ print "triangle {<", $1, ",", $2, ",", $3, ">, <", $4, ",", $5, ",", $6, ">, <", $7, ",", $8, ",", $9, ">}"    };' | \
sed -e 's/ //g' -e 's/0\./\./g'  > tree1.inc

resulting in:

#declare FOLIAGE = mesh {
triangle{<.182,-.241,.030>,<.183,-.240,.027>,<.183,-.239,.034>}
triangle{<.183,-.240,.027>,<.183,-.239,.034>,<.185,-.236,.035>}
...
...

#declare TREE = union {
object{FOLIAGE}
}

Tree image before:

Tree image after:

What’s the difference in size for the include file?

-rw-r--r--  1 user  group    13M Nov  6 21:52 tree.inc
-rw-r--r--  1 user  group   5.6M Nov  8 00:40 tree1.inc

How far can we go with this?  Well, here’s two decimal places for our coordinates:

It’s starting to get a little chunky here, but it might work for a lot of purposes.  However, we’re reaching the limit of our optimization:

-rw-r--r--  1 user  group   5.2M Nov  8 00:48 tree4.inc

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: