The Surcoat Macros

Scripted by Tim Nikias Wenclawiak - Homepage: www.NoLights.de

Last update: 27.06.2008

Contents
Introduction
Usage
The Speed-Up Possibility
Further Processing


The Surcoat Macros take care of a single issue: sampling the surface of an object, or, in other words, "coating" the object. This is done in several steps via several macros. Further macros (not supplied with the initial include) may enhance the visualization of the taken samples to create different effects like snow, moss, dust, ice, etc.

Note: Take a look at the example files in this ZIP, as they will demonstrate the usage of the macros. This help will only explain the techniques involved and provide a very basic understanding, think of it as of a walkthrough.
In regard to copyrights: this set of macros was written by me in my spare time. All I require is that you give credit where you feel credit is due, and drop me a note to let me have a look at what you've achieved with my macros. :-)
If, however, you make money with them, that's a no-no without my consent!


Up ahead is a verbal explanation of the steps needed to coat an object with samples. Note that the ZIP comes with a heavily commented example to see the macros at work.

The setup is actually pretty simple. Declare the object that is to be coated along with a few settings which control the amount of samples dropped, the direction to shoot, etc, and call the main macro, namely Surcoat_CreateSamples(Your_Object), where Your_Object is the object's declaration-name.
The macro will sample the object and save the results in a file. You can then either save the collected samples using Surcoat_SaveSurface(Filename), and/or prepare for the sorting steps by calling Surcoat_PrepareSorting().
Then, using various macros, you can dismiss samples based on certain criteria. For example, you might want to remove samples that are on a steep surface, or inside another object. If working with meshes, it can happen that some surfaces are inside the actual volume, and thus, samples might be placed within the mesh. The Surcoat-Set has several macros to help you along and fulfill the basic needs (take a look at "example_2.pov" for some examples).
Once that is done, Surcoat_SaveSorted(Filename) will save the remaining samples to the given file.
Also note that you don't have to recoat the object if you just want to create a second set of sorted samples. Using Surcoat_PrepareSorting(Filename) again you can reload the samples of the latest coating pass for another sorting pass, or you can use Surcoat_LoadSurface(Filename) to load a set of formerly saved (even pre-sorted, if need be) samples for further processing, but this would require another call of Surcoat_PrepareSorting() for the sorting process.
Surcoat_Spheres(Filename,Radius) will finally visualize the given file with spheres of given radius, or, as an alternative, you can use
Surcoat_BlobSpheres(Filename,Threshold,Radius,Strength) to visualize them as one blob.


Dropping samples onto an object is often done using a brute force method: drop hundreds of thousands of samples onto the boundary box of the object and hope that enough samples hit. This, as is obvious, is fairly inefficient, especially when working with objects which have a huge boundary box, but only take very little volume inside that box. A tree is the best example, it will spread out fairly wide, but there's lots of space between the branches.
So, to speed things up and make it more efficient, the Surcoat-Macros can make use of a presorting technique. What it requires for this is an orthographic view of the object, where the object is colored white and the background is black. To align the orthographic image with the sampling later on, the Surcoat-Set comes with a macro, namely Surcoat_Orthoview(Your_Object). To ensure that the macro works correctly, the scene should only include the declaration of the untextured object (the macro will texture it with a white color automatically, but this doesn't always work when the object is already textured) and the call to the macro, which will place the camera, object and set the lighting.
For the Surcoat-Macros to make use of this, all you need to do is declare Surcoat_Topview as a pigment with the image-map of the orthographic view. To ensure that later coating processes don't make use of the same pigment, the pigment is undeclared once the macro has coated the object.
Later on, the Surcoat-Macros will divide the boundary box into cells and, using the supplied image as reference, can quickly check if the object is actually touching or inside a given cell. Of course, like all discretization algorithms, using a too low resolution for the orthographic view, or having several small, non-connected objects can results in cells not being tested where there actually is a portion of the object inside. Just enhance the resolution of the cells then.
The orthographic view isn't a requirement though, the Surcoat-Macros can also run using the simple brute force method, but, depending on the object you're coating and the amount of particles being dropped onto the object, you might lose quite some precious parsing time that way.


The files generated by the Surcoat-Macros are of a simple kind: a comma-seperated list of positions and normal-vectors. The comma-seperation is a style which POV-Ray's File I/O is capable of reading and writing. You can simply open the file and read the vectors to do further stuff with them. The first vector is always the position of a sample, the second vector is the surface- normal of the object at the sample's position. The normal isn't use for the visualization macros, but seems like a useful addition to save (as it is most likely that further processing them will require the surface-normal in various situations). Also note that the visualization macros supplied with the Surcoat-Set just require a file which has that same style: position_1, normal_1, position_2, normal_2, etc. For POV-Ray's File I/O to work properly, the last vector should not be followed by another comma, as the macros rely solely on the ending of the data-list. A comma would imply that more data will follow. To work around this problem, I simply all but the first sample with a comma in front of the data. The first sample has no leading comma.
To make things easier, I've scripted a small set of macros which you may call to ease the I/O, just take a look at "process.pov" for an example.