Saturday, February 21, 2009

Hard Won Star

Star
This simple star represents about a month's worth of work. It was produced using Aqsis, an open source Renderman renderer. The actual program to make the star is actually quite simple. Almost all of the work was actually because I wrote a Python wrapper around the Aqsis library so that I could make Renderman calls from Python directly.

The tricky part in writing the wrapping code was that the Renderman C interface makes extensive use of C's variadic ... style of passing arguments for passing in extended parameter information. Luckily, the Renderman interfaces also specifies the Ri*V style of calls for passing parameters across, without which the wrapper would have been pretty much impossible to write.

All parameters passed in this way are represented using void pointers to low level C types, eg, floats, ints, etc. In particular, when passing in a list of elements, the underlying type actually passed across the interface is generally an array of floats, or ints, or whatever, which are all the same type and contiguously stored in memory. Of course, Python makes no such guarantees about how it stores its types, or that types in the same list are even the same type. The problem then, is converting whatever Python types are passed in into void *'s that can be safely passed across the Renderman C interface.

The way this problem was solved was to essentially maintain map of dynamic conversion objects, which we can clone and allow us to dynamically (and virtually) convert the Python type to the underlying C type, as well as doing any copying, conversion, and memory allocation necessary to store the converted values for the life of the Renderman function call. Another map is maintained which maps the names of Ri function names and parameters to the types that they expect, configured by an external XML file. The Python wrapper can then lookup the necessary types to convert to at call time, perform any conversions necessary, and safely make the underlying C call.

The end result is I can iterate a lot faster. The actual program to generate this star only took a few minutes to write. I'm hoping to get curved surfaces exposed soon and can thus start trying to make higher quality renderings of Jarvis' legs.

Sunday, January 11, 2009

First Images

These are the first images to come out of the program I've been working on. It's not much, but it's a start.

These are two examples of NURBS curves. The first represents a cross section of an octopus leg. The leg is in white; the red circle is a reference I used when manipulating the curve to the shape I wanted.

The second curve is a curve that the cross section will be "extruded" along. It's not apparent due to scaling, but the second curve is a planar curve which is about 8 units long and exactly one unit high (the red lines represent the lines y = 0 and y = 1, respectively). The cross section isn't going to be extruded in the true sense of the word. Instead, the height of the second curve will determine the scale of the cross section as it "moves" down the curve.

Cross Section for Octopus Leg

Scale Definition for Octopus Leg

The curves were created by manually specifying the control points using a custom written C++ NURBS module, which was then exposed as a Python module using Boost.Python. The image captures were then made using Boost.GIL.

The next step is to actually create a NURBS (or Bezier) control patch for the surface using the cross section and control curve. Hopefully, since I'm using NURBS, I'll eventually be able to produce high quality renderings (via Aqsis) as well produce a model of the octopus for realtime rendering purposes.