--- a/src/kdtree.cc Tue Apr 22 13:33:12 2008 +0200
+++ b/src/kdtree.cc Wed Apr 23 10:38:33 2008 +0200
@@ -26,9 +26,11 @@
#include <algorithm>
#include <stack>
+#include <string>
+#include <sstream>
-#include "common.h"
#include "kdtree.h"
+#include "serialize.h"
class ShapeBound
{
@@ -265,7 +267,7 @@
}
else
{ /* (stack[entry].pb[axis] > splitVal) */
- if (splitVal < stack[exit].pb[axis])
+ if (stack[exit].pb[axis] > splitVal)
{
/* case P1, P2, P3, and N5 */
node = node->getRightChild();
@@ -305,7 +307,7 @@
ShapeList::iterator shape;
for (shape = node->getShapes()->begin(); shape != node->getShapes()->end(); shape++)
if (*shape != origin_shape && (*shape)->intersect(ray, dist)
- && dist >= stack[entry].t)
+ && dist >= stack[entry].t - Eps)
{
nearest_shape = *shape;
nearest_distance = dist;
@@ -326,27 +328,118 @@
return NULL;
}
-// this should save whole kd-tree with triangles distributed into leaves
-void KdTree::save(ostream &str, KdNode *node)
+ostream & operator<<(ostream &st, KdNode &node)
+{
+ if (node.isLeaf())
+ {
+ st << "(l," << node.getShapes()->size();
+ ShapeList::iterator shape;
+ for (shape = node.getShapes()->begin(); shape != node.getShapes()->end(); shape++)
+ st << "," << shape_index[*shape];
+ st << ")";
+ }
+ else
+ {
+ st << "(s," << (char)('x'+node.getAxis()) << "," << node.getSplit() << ",";
+ st << *node.getLeftChild() << ",";
+ st << *node.getRightChild() << ")";
+ }
+ return st;
+}
+
+ostream & KdTree::dump(ostream &st)
{
if (!built)
- return;
- if (node == NULL)
- node = root;
- if (node->isLeaf())
- str << "(leaf: " << node->getShapes()->size() << " shapes)";
- else
+ return Container::dump(st);
+
+ st << "(kdtree," << shapes.size();
+ ShapeList::iterator shape;
+ for (shape = shapes.begin(); shape != shapes.end(); shape++)
+ {
+ int idx;
+ if (!shape_index.get(*shape, idx))
+ st << "," << endl << **shape;
+ }
+ return st << "," << endl << *getRootNode() << ")";
+}
+
+void KdTree::recursive_load(istream &st, KdNode *node)
+{
+ string s;
+ istringstream is;
+
+ getline(st, s, ',');
+ trim(s);
+
+ if (s.compare("(s") == 0)
{
- str << "(split " << (char)('x'+node->getAxis()) << " at " << node->getSplit() << "; L=";
- save(str, node->getLeftChild());
- str << "; R=";
- save(str, node->getRightChild());
- str << ";)";
+ // split
+ int axis;
+ Float split;
+
+ delete node->getShapes();
+ node->setChildren(new KdNode[2]);
+
+ getline(st, s, ',');
+ axis = s.c_str()[0]-'x';
+ node->setAxis(axis);
+
+ st >> split;
+ getline(st, s, ',');
+ node->setSplit(split);
+
+ recursive_load(st, node->getLeftChild());
+ getline(st, s, ',');
+ recursive_load(st, node->getRightChild());
+ getline(st, s, ')');
+ }
+
+ if (s.compare("(l") == 0)
+ {
+ // leaf
+ int count, idx;
+
+ node->setLeaf();
+
+ st >> count;
+ for (int i = 0; i < count; i++)
+ {
+ getline(st, s, ',');
+ st >> idx;
+ node->addShape(shapes[idx]);
+ }
+ getline(st, s, ')');
}
}
-// load kd-tree from file/stream
-void KdTree::load(istream &str, KdNode *node)
+istream & KdTree::load(istream &st)
{
+ string s;
+ istringstream is;
+ getline(st, s, ',');
+ if (s.compare("(kdtree") != 0)
+ return st;
+
+ shapes.clear();
+ if (root) delete root;
+ root = new KdNode();
+
+ getline(st, s, ',');
+ int shape_count;
+ is.str(s);
+ is >> shape_count;
+
+ Shape *shape;
+ for (int i = 0; i < shape_count; i++)
+ {
+ shape = loadShape(st);
+ Container::addShape(shape);
+ getline(st, s, ',');
+ }
+
+ recursive_load(st, root);
+
+ built = true;
+ return st;
}