void KDPhotonsTree::InitTree(const Photons &photons, const size_t index, const Photons::iterator begin, const Photons::iterator end, const size_t depth) { const size_t dist_it = end - begin; if(dist_it < 0) { throw Error("initializing KD tree error"); } if(dist_it < 1) { if(index < m_numberOfPhotons && begin != photons.end())m_treeArray[index] = TreeElement(*begin, ST_NON_EXIST); return; } if(dist_it == 1) { if(index < m_numberOfPhotons)m_treeArray[index] = TreeElement(*begin, ST_LEAF); return; } Point min( GLOBAL_PROPERTIES::INFINITY, GLOBAL_PROPERTIES::INFINITY, GLOBAL_PROPERTIES::INFINITY); Point max(-GLOBAL_PROPERTIES::INFINITY, -GLOBAL_PROPERTIES::INFINITY, -GLOBAL_PROPERTIES::INFINITY); for(Photons::iterator it = begin; it != end; it++) { if(it->position.x() < min.x()) min.x(it->position.x()); if(it->position.y() < min.y()) min.y(it->position.y()); if(it->position.z() < min.z()) min.z(it->position.z()); if(it->position.x() > max.x()) max.x(it->position.x()); if(it->position.y() > max.y()) max.y(it->position.y()); if(it->position.z() > max.z()) max.z(it->position.z()); } Point distPoint = max - min; Split_type split = (distPoint.x() >= distPoint.y() && distPoint.x() >= distPoint.z()) ? ST_X_COORD : ( (distPoint.y() >= distPoint.z()) ? ST_Y_COORD : ST_Z_COORD ); std::sort(begin, end, split == ST_X_COORD ? x_comp_func : (split == ST_Y_COORD ? y_comp_func : z_comp_func) ); const Photons::iterator middle = begin + ((end - begin)/2); if(((index << 1) | 1) < m_numberOfPhotons) { m_treeArray[index] = TreeElement(*middle, split); if(depth < m_logOfNumberOfThreads) { // Need to split to two threads (create extra one) ///////////////////////////////////////////////////////////// // parallelization ///////////////////////////////////////////////////////////// DWORD tID; HANDLE handle; PhotonsTreeBuildThreadArguments *arguments = new PhotonsTreeBuildThreadArguments(*this, photons, (index << 1), begin, middle, depth+1); handle = CreateThread( NULL, 0, ThreadBuildFunc, (LPVOID)arguments, 0, &tID); ///////////////////////////////////////////////////////////// // Complete second part of tree itself InitTree(photons, (index << 1) | 1, middle+1, end , depth+1); // wait for sibling thread to finish his work WaitForSingleObject(handle, INFINITE); } else { InitTree(photons, (index << 1) , begin , middle, depth+1); InitTree(photons, (index << 1) | 1, middle+1, end , depth+1); } } else { m_treeArray[index] = TreeElement(*middle, ST_LEAF); } }
static TreeElement Root(const std::string& root_name) { return TreeElement(root_name); };