#include #include namespace CosmoTool { namespace simple_bsp { template BSP::BSP() throw() { root = 0; } template BSP::~BSP() { while (!allocated.empty()) { node_t *r = allocated.front(); allocated.pop(); delete r; } } template void BSP::insert(Facet& f) { std::list subtrees; std::list leaf_insert; if (root != 0) subtrees.push_back(&root); else leaf_insert.push_back(&root); // Find the point of insertion. Do not bother to split triangle for this // implementation. while (!subtrees.empty()) { std::list new_subtrees; typename std::list::iterator iter = subtrees.begin(); while (iter != subtrees.end()) { typename space_t::point_t dp; bool cond_plus = false, cond_minus = false; node_t *current = *(*iter); for (int j = 0; j < N; j++) { dp = dot_product(f.p[j],current->plane.n) + current->plane.d; cond_plus = cond_plus || (dp > 0); cond_minus = cond_minus || (dp <= 0); } bool joint = cond_plus && cond_minus; bool not_joint = (!cond_plus) && (!cond_minus); if (joint || not_joint) { // Crawl and add another subtree *iter = &(current->minus); if (current->plus != 0) new_subtrees.push_back(¤t->plus); else leaf_insert.push_back(¤t->plus); } else { if (cond_plus) *iter = ¤t->plus; else *iter = ¤t->minus; } if (*(*iter) == 0) { leaf_insert.push_back(*iter); iter = subtrees.erase(iter); } else ++iter; } if (!new_subtrees.empty()) subtrees.splice(subtrees.end(), new_subtrees); } node_t * current = new node_t; f.normal(current->plane.n); current->plane.d = -dot_product((f.p[0]),current->plane.n); for (typename std::list::iterator i = leaf_insert.begin(); i != leaf_insert.end(); ++i) *(*i) = current; allocated.push(current); } }; };