= Assignment 2 Discussion = == Support Files == For those it might be useful for, I've created a Makefile and a Visual Studio 2005 project for lz-kdtree you can find [http://www.stanford.edu/~lthendri/cs348b/lz-kdtree_build.zip here]. The Makefile will build lz-kdtree.so, and the VS 2005 solution will build Release/lz-kdtree.dll and Debug/lz-kdtree_d.dll. I find this kind of setup useful if you want to keep lz-kdtree.cpp in a "local" directory outside the pbrt source tree (e.g., in a cvs repository without the rest of the pbrt source). Note that you'll have to add your own copy of lz-kdtree to the Source Files in the VS solution file, and you'll have to change the path in the Makefile on line 10 to point to your own copy of pbrt. == Questions == === Q.1 Default Killeroo Scene (DougJohnston) === Using the scenes includes in the zip file, I get the following statistics: {{{ Geometry Total shapes created 532.2k Triangle Ray Intersections 673.8k:4826.8k (13.96%) Triangles created 532.2k Kd-Tree Accelerator Avg. number of primitives in leaf nodes 3.965M:1.376M (2.88x) Interior kd-tree nodes made 1.376M Leaf kd-tree nodes made 1.376M Maximum number of primitives in leaf node 284 }}} which is significantly different from those in the project description. === A.1 === The scene in the zip file has one more level of subdivisions for the killeroo models. That's why the numbers of tree nodes and triangle ray intersections are much higher than the numbers given in the example. === Q.2 Problems with const (LeeHendrickson) === I'm having some issues with dynamically creating new nodes in my lazy kd-tree. The crux of the issue is that both Intersect and IntersectP must be const methods (as they implement pure virtual methods from Primitive which are themselves const); however, in lazy evaluation these are also exactly the methods in which changes ''do'' need to be made to the kd-tree (at the very least either 1.) more nodes will need to be allocated, or 2.) nodes already allocated will need to have initLeaf or initInteriorNode called on them, neither of which is a const operation). Hopefully I'm missing something simple, any pointers/hints would be appreciated. (please don't tell me the answer is to make everything mutable...) === A.2 === * One possible way would be to const_cast the constant-ness away, then call whatever functions you need on the object. Ugly though...(YiLangMok)[[BR]] * If you define the tree as an array of nodes or some structure, you only need to make the tree {{{mutable}}}, which is not too bad? (MengYu) [[BR]] * But then you'd have to move non-const functions such as buildNode into the node itself, since you cannot make functions mutable. As it stands, Intersect cannot call buildNode because of const restrictions. Moving the functions might work, but it seems to be more work that it's worth. (YiLangMok)[[BR]] Well, what I ended up doing was just going the {{{mutable}}} route, moving as much as I could into a mutable member structure, and setting the building functions const so as to be able to be called from Intersect (even though some variables such as the number of free and alloc'ed nodes need to stay in the tree itself). The problem with const_cast'ing is having to do it on the {{{this}}} pointer that must also be const for all functions called from intersect, which just feels more kludgy. By using {{{mutable}}} members the functions themselves can stay in the top level tree '''and''' stay const. Quick and dirty, but given the framework of pbrt I don't see any good way around it. Any better suggestions are welcome. (LeeHendrickson)