diff -r dbe8438d5dca -r 9569e9f35374 src/kdtree.cc --- 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 #include +#include +#include -#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; }