211 ELEMTYPE globalMin[NUMDIMS];
212 ELEMTYPE globalMax[NUMDIMS];
214 for(
int d = 0; d < NUMDIMS; ++d )
216 globalMin[d] = std::numeric_limits<ELEMTYPE>::max();
217 globalMax[d] = std::numeric_limits<ELEMTYPE>::lowest();
222 for(
int d = 0; d < NUMDIMS; ++d )
224 ELEMTYPE
center = item.min[d] / 2 + item.max[d] / 2;
226 if(
center < globalMin[d] )
229 if(
center > globalMax[d] )
235 std::vector<uint64_t> hilbertValues( n );
237 for(
size_t i = 0; i < n; ++i )
239 uint32_t coords[NUMDIMS];
241 for(
int d = 0; d < NUMDIMS; ++d )
244 double range =
static_cast<double>( globalMax[d] ) - globalMin[d];
248 double normalized = (
static_cast<double>(
center ) - globalMin[d] )
250 coords[d] =
static_cast<uint32_t
>(
251 normalized *
static_cast<double>( UINT32_MAX ) );
263 std::vector<size_t> indices( n );
265 for(
size_t i = 0; i < n; ++i )
268 std::sort( indices.begin(), indices.end(),
269 [&hilbertValues](
size_t a,
size_t b )
271 return hilbertValues[a] < hilbertValues[b];
277 for(
size_t i = 0; i < n; ++i )
281 size_t numLeafNodes = ( n + FANOUT - 1 ) / FANOUT;
284 std::vector<size_t> nodesPerLevel;
285 nodesPerLevel.push_back( numLeafNodes );
287 size_t levelNodes = numLeafNodes;
289 while( levelNodes > 1 )
291 levelNodes = ( levelNodes + FANOUT - 1 ) / FANOUT;
292 nodesPerLevel.push_back( levelNodes );
296 size_t totalNodes = 0;
298 for(
size_t cnt : nodesPerLevel )
302 for(
int axis = 0; axis < NUMDIMS * 2; ++axis )
303 tree.
m_bounds[axis].resize( totalNodes * FANOUT,
304 std::numeric_limits<ELEMTYPE>::max() );
306 tree.
m_counts.resize( totalNodes, 0 );
312 for(
size_t lev = 0; lev < nodesPerLevel.size(); ++lev )
315 offset += nodesPerLevel[lev];
319 for(
size_t i = 0; i < n; ++i )
321 size_t nodeIdx = i / FANOUT;
322 int slot =
static_cast<int>( i % FANOUT );
327 for(
int d = 0; d < NUMDIMS; ++d )
329 tree.
m_bounds[d * 2][globalNodeIdx * FANOUT + slot] = item.
min[d];
330 tree.
m_bounds[d * 2 + 1][globalNodeIdx * FANOUT + slot] = item.
max[d];
333 tree.
m_counts[globalNodeIdx] = slot + 1;
337 for(
size_t lev = 1; lev < nodesPerLevel.size(); ++lev )
340 size_t childLevelCount = nodesPerLevel[lev - 1];
343 for(
size_t ci = 0; ci < childLevelCount; ++ci )
345 size_t parentIdx = ci / FANOUT;
346 int slot =
static_cast<int>( ci % FANOUT );
347 size_t globalParentIdx = parentLevelOffset + parentIdx;
348 size_t globalChildIdx = childLevelOffset + ci;
351 ELEMTYPE childMin[NUMDIMS];
352 ELEMTYPE childMax[NUMDIMS];
354 for(
int d = 0; d < NUMDIMS; ++d )
356 childMin[d] = std::numeric_limits<ELEMTYPE>::max();
357 childMax[d] = std::numeric_limits<ELEMTYPE>::lowest();
360 int childCount = tree.
m_counts[globalChildIdx];
362 for(
int s = 0; s < childCount; ++s )
364 for(
int d = 0; d < NUMDIMS; ++d )
366 ELEMTYPE mn = tree.
m_bounds[d * 2][globalChildIdx * FANOUT + s];
367 ELEMTYPE mx = tree.
m_bounds[d * 2 + 1][globalChildIdx * FANOUT + s];
369 if( mn < childMin[d] )
372 if( mx > childMax[d] )
378 for(
int d = 0; d < NUMDIMS; ++d )
380 tree.
m_bounds[d * 2][globalParentIdx * FANOUT + slot] = childMin[d];
381 tree.
m_bounds[d * 2 + 1][globalParentIdx * FANOUT + slot] = childMax[d];
384 tree.
m_counts[globalParentIdx] = slot + 1;