25 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
52 void split(
CellHandle _ch,
const bool bGarbageCollectionOnTheFly=
false );
120 inline int size()
const;
156 return binary_cell_size;
180 inline void reserve(
unsigned int _size );
181 inline void resize (
unsigned int _size );
189 fprintf( stderr,
"Error: octree::initialize(): invalid root level\n" );
190 exit( EXIT_FAILURE );
205 for (
size_t i=0; i<7; ++i)
m_OctreeCell.push_back( dummy );
223 inline int cell(
int _i )
const
265 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
268 m_OctreeCell.reserve( _size );
273 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
276 m_OctreeCell.resize( _size );
281 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
289 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
292 return location( _ch ).parent();
297 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
305 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
308 return (m_OctreeCell[ _ch.
idx() ].next<0);
313 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
316 return ((m_OctreeCell[ _ch.
idx() ].next<0) || (level(_ch)==m_ExtractionLevel));
321 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
324 return _ch.
idx() == 7;
329 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
332 const Location & locinfo = location( _ch );
336 _size = (
Scalar ) binary_cell_size;
344 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
347 const Location & locinfo = location( _ch );
359 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
362 const Location & locinfo = location( _ch );
365 _s = (
Scalar ) binary_cell_size;
374 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
377 const Location & locinfo = location( _ch );
381 _size = (
Scalar ) binary_cell_size;
389 case 1 : _x += _size;
break;
390 case 2 : _y += _size;
break;
391 case 3 : _x += _size; _y += _size;
break;
392 case 4 : _z += _size;
break;
393 case 5 : _x += _size; _z += _size;
break;
394 case 6 : _y += _size; _z += _size;
break;
395 case 7 : _x += _size; _y += _size; _z += _size;
break;
401 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
404 const Location & locinfo = location( _ch );
416 case 1 : _x += size;
break;
417 case 2 : _y += size;
break;
418 case 3 : _x += size; _y += size;
break;
419 case 4 : _z += size;
break;
420 case 5 : _x += size; _z += size;
break;
421 case 6 : _y += size; _z += size;
break;
422 case 7 : _x += size; _y += size; _z += size;
break;
428 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
435 LocCode next_level = location( _ch ).level() - 1;
437 while ( ! is_leaf( _ch ) )
439 LocCode child_branch_bit = 1 << next_level;
440 unsigned int child_index =
441 ( ( _loc_x & child_branch_bit ) >> ( next_level ) ) +
442 2 * ( ( _loc_y & child_branch_bit ) >> ( next_level ) ) +
443 4 * ( ( _loc_z & child_branch_bit ) >> ( next_level ) );
445 _ch = child( _ch, child_index );
453 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
461 LocCode next_level = level( _ch ) - 1;
463 LocCode n = next_level - _level + 1;
467 LocCode child_branch_bit = 1 << next_level;
468 unsigned int child_index =
469 1 * ( ( _loc_x & child_branch_bit ) >> ( next_level ) ) +
470 2 * ( ( _loc_y & child_branch_bit ) >> ( next_level ) ) +
471 4 * ( ( _loc_z & child_branch_bit ) >> ( next_level ) );
473 _ch = child( _ch, child_index );
475 if ( is_leaf( _ch ) )
break;
483 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
486 const Location & locinfo = location( _ch );
491 const LocCode binary_cell_size = ((int)1) << locinfo.
level();
501 if ( loc_x + binary_cell_size >= ( 1 << m_rootLevel ) )
return CellHandle();
502 new_loc_x = loc_x + binary_cell_size;
503 diff = loc_x ^ new_loc_x;
507 if ( loc_y + binary_cell_size >= ( 1 << m_rootLevel ) )
return CellHandle();
508 new_loc_y = loc_y + binary_cell_size;
509 diff = loc_y ^ new_loc_y;
513 if ( loc_z + binary_cell_size >= ( 1 << m_rootLevel ) )
return CellHandle();
514 new_loc_z = loc_z + binary_cell_size;
515 diff = loc_z ^ new_loc_z;
520 new_loc_z = loc_z - 1;
521 diff = loc_z ^ new_loc_z;
526 new_loc_y = loc_y - 1;
527 diff = loc_y ^ new_loc_y;
532 new_loc_x = loc_x - 1;
533 diff = loc_x ^ new_loc_x;
537 CellHandle parent = get_common_ancestor( _ch, diff );
539 return traverse_to_level( parent, new_loc_x, new_loc_y, new_loc_z, locinfo.
level() );
544 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
547 LocCode cell_level = level( _ch );
549 while ( _binary_diff & ( 1 << cell_level ) )
560 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
566 LocCode cell_level = level( _ch );
568 while ( _binary_diff0 & _binary_diff1 & ( 1 << cell_level ) )
574 if ( _binary_diff0 & ( 1 << cell_level ) )
575 while ( _binary_diff0 & ( 1 << cell_level ) )
581 while ( _binary_diff1 & ( 1 << cell_level ) )
592 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
604 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
607 const Location & locinfo = location( _ch );
619 int extent = ( 1 << m_rootLevel );
627 new_loc_y = loc_y - 1;
628 new_loc_z = loc_z - 1;
635 new_loc_x = loc_x - 1;
636 new_loc_z = loc_z - 1;
643 new_loc_x = loc_x - 1;
644 new_loc_y = loc_y - 1;
649 if ( loc_x + binary_cell_size >= extent )
return CellHandle();
651 new_loc_x = loc_x + binary_cell_size;
652 new_loc_z = loc_z - 1;
658 if ( loc_y + binary_cell_size >= extent )
return CellHandle();
659 new_loc_x = loc_x - 1;
660 new_loc_y = loc_y + binary_cell_size;
666 if ( loc_z + binary_cell_size >= extent )
return CellHandle();
667 new_loc_y = loc_y - 1;
668 new_loc_z = loc_z + binary_cell_size;
673 if ( loc_y + binary_cell_size >= extent )
return CellHandle();
675 new_loc_y = loc_y + binary_cell_size;
676 new_loc_z = loc_z - 1;
681 if ( loc_x + binary_cell_size >= extent )
return CellHandle();
683 new_loc_x = loc_x + binary_cell_size;
684 new_loc_y = loc_y - 1;
690 if ( loc_z + binary_cell_size >= extent )
return CellHandle();
691 new_loc_x = loc_x - 1;
692 new_loc_z = loc_z + binary_cell_size;
697 if ( loc_x + binary_cell_size >= extent )
return CellHandle();
698 if ( loc_y + binary_cell_size >= extent )
return CellHandle();
699 new_loc_x = loc_x + binary_cell_size;
700 new_loc_y = loc_y + binary_cell_size;
705 if ( loc_x + binary_cell_size >= extent )
return CellHandle();
706 if ( loc_z + binary_cell_size >= extent )
return CellHandle();
707 new_loc_x = loc_x + binary_cell_size;
708 new_loc_z = loc_z + binary_cell_size;
713 if ( loc_y + binary_cell_size >= extent )
return CellHandle();
714 if ( loc_z + binary_cell_size >= extent )
return CellHandle();
715 new_loc_y = loc_y + binary_cell_size;
716 new_loc_z = loc_z + binary_cell_size;
724 return traverse_to_level( parent, new_loc_x, new_loc_y, new_loc_z, locinfo.
level() );
729 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
732 std::vector<CellHandle> cellHandles;
733 std::vector<uint> markers;
734 std::vector<Location*> locations;
742 int extent = ( 1 << m_rootLevel );
750 for(
unsigned char i = 0; i < 8; i++)
756 int new_loc_x = loc_X;
757 int new_loc_y = loc_Y;
758 int new_loc_z = loc_Z;
761 if ( new_loc_x >= extent || new_loc_x < 0 )
768 if ( new_loc_y >= extent || new_loc_y < 0 )
775 if ( new_loc_z >= extent || new_loc_z < 0 )
781 locations.push_back(
new Location(new_loc_x, new_loc_y, new_loc_z, locinfo.
level() + 1, locinfo.
parent()));
782 markers.push_back(marker);
785 for(
Location * location : locations)
787 cellHandles.push_back(traverse(root(), location->loc_x(), location->loc_y(), location->loc_z()));
791 std::vector<Location*>().swap(locations);
793 return make_pair(cellHandles, markers);
798 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
801 const Location & locinfo = location( _ch );
813 int extent = ( 1 << m_rootLevel );
822 new_loc_x = loc_x - 1;
823 new_loc_y = loc_y - 1;
824 new_loc_z = loc_z - 1;
829 if ( loc_x + binary_cell_size >= extent )
return CellHandle();
832 new_loc_x = loc_x + binary_cell_size;
833 new_loc_y = loc_y - 1;
834 new_loc_z = loc_z - 1;
840 if ( loc_y + binary_cell_size >= extent )
return CellHandle();
842 new_loc_x = loc_x - 1;
843 new_loc_y = loc_y + binary_cell_size;
844 new_loc_z = loc_z - 1;
849 if ( loc_x + binary_cell_size >= extent )
return CellHandle();
850 if ( loc_y + binary_cell_size >= extent )
return CellHandle();
852 new_loc_x = loc_x + binary_cell_size;
853 new_loc_y = loc_y + binary_cell_size;
854 new_loc_z = loc_z - 1;
861 if ( loc_z + binary_cell_size >= extent )
return CellHandle();
862 new_loc_x = loc_x - 1;
863 new_loc_y = loc_y - 1;
864 new_loc_z = loc_z + binary_cell_size;
869 if ( loc_x + binary_cell_size >= extent )
return CellHandle();
871 if ( loc_z + binary_cell_size >= extent )
return CellHandle();
872 new_loc_x = loc_x + binary_cell_size;
873 new_loc_y = loc_y - 1;
874 new_loc_z = loc_z + binary_cell_size;
880 if ( loc_y + binary_cell_size >= extent )
return CellHandle();
881 if ( loc_z + binary_cell_size >= extent )
return CellHandle();
882 new_loc_x = loc_x - 1;
883 new_loc_y = loc_y + binary_cell_size;
884 new_loc_z = loc_z + binary_cell_size;
889 if ( loc_x + binary_cell_size >= extent )
return CellHandle();
890 if ( loc_y + binary_cell_size >= extent )
return CellHandle();
891 if ( loc_z + binary_cell_size >= extent )
return CellHandle();
892 new_loc_x = loc_x + binary_cell_size;
893 new_loc_y = loc_y + binary_cell_size;
894 new_loc_z = loc_z + binary_cell_size;
901 return traverse_to_level( parent, new_loc_x, new_loc_y, new_loc_z, locinfo.
level() );
906 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
909 return location( _ch ).level();
914 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
917 return m_rootLevel - level( _ch );
922 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
925 return m_OctreeCell.size();
930 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
934 return m_OctreeCell.size()-7;
939 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
942 const Location & locinfo = location( _ch );
950 LocCode tree_size = 1 << m_rootLevel;
952 return ( loc_x == 0 ||
955 loc_x + binary_cell_size == tree_size ||
956 loc_y + binary_cell_size == tree_size ||
957 loc_z + binary_cell_size == tree_size );
962 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
969 Scalar extent( 1 << m_rootLevel );
977 while ( ! is_leaf( ch ) )
980 cell_center( ch, cx, cy, cz );
982 unsigned int cidx = ( _x < cx ? 0 : 1 )
983 + ( _y < cy ? 0 : 2 )
984 + ( _z < cz ? 0 : 4 );
985 ch = child( ch, cidx );
993 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
996 MovePickedCell(0, _mvm);
1001 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
1004 MovePickedCell(1, _mvm);
1009 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
1012 MovePickedCell(2, _mvm);
1017 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
1020 MovePickedCell(3, _mvm);
1033 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
1036 bool left = (_direction == 0);
1037 bool right = (_direction == 1);
1038 bool up = (_direction == 2);
1039 bool down = (_direction == 3);
1041 BaseVecT xAxis(_mvm[0], _mvm[4], _mvm[8]);
1042 BaseVecT yAxis(_mvm[1], _mvm[5], _mvm[9]);
1047 if (fabs(xAxis[0])>fabs(xAxis[1]))
1049 if (fabs(xAxis[0])>fabs(xAxis[2]))
1052 else if (fabs(xAxis[1])>fabs(xAxis[2]))
1056 if (fabs(yAxis[0])>fabs(yAxis[1]))
1058 if (fabs(yAxis[0])>fabs(yAxis[2]))
1061 else if (fabs(yAxis[1])>fabs(yAxis[2]))
1069 if (xAxis[xIndex]<0)
1072 neighCell = face_neighbor(m_PickedCell, 0);
1074 neighCell = face_neighbor(m_PickedCell, 5);
1079 neighCell = face_neighbor(m_PickedCell, 5);
1081 neighCell = face_neighbor(m_PickedCell, 0);
1086 if (xAxis[xIndex]<0)
1089 neighCell = face_neighbor(m_PickedCell, 1);
1091 neighCell = face_neighbor(m_PickedCell, 4);
1096 neighCell = face_neighbor(m_PickedCell, 4);
1098 neighCell = face_neighbor(m_PickedCell, 1);
1103 if (xAxis[xIndex]<0)
1106 neighCell = face_neighbor(m_PickedCell, 2);
1108 neighCell = face_neighbor(m_PickedCell, 3);
1113 neighCell = face_neighbor(m_PickedCell, 3);
1115 neighCell = face_neighbor(m_PickedCell, 2);
1123 if (yAxis[yIndex]<0)
1126 neighCell = face_neighbor(m_PickedCell, 0);
1128 neighCell = face_neighbor(m_PickedCell, 5);
1133 neighCell = face_neighbor(m_PickedCell, 5);
1135 neighCell = face_neighbor(m_PickedCell, 0);
1140 if (yAxis[yIndex]<0)
1143 neighCell = face_neighbor(m_PickedCell, 1);
1145 neighCell = face_neighbor(m_PickedCell, 4);
1150 neighCell = face_neighbor(m_PickedCell, 4);
1152 neighCell = face_neighbor(m_PickedCell, 1);
1157 if (yAxis[yIndex]<0)
1160 neighCell = face_neighbor(m_PickedCell, 2);
1162 neighCell = face_neighbor(m_PickedCell, 3);
1167 neighCell = face_neighbor(m_PickedCell, 3);
1169 neighCell = face_neighbor(m_PickedCell, 2);
1175 if ((neighCell.
is_valid()) && (level(neighCell)==level(m_PickedCell)))
1177 m_PickedCell = neighCell;
1197 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
1200 return (((*point)[0]) > center[0] ) | ((((*point)[1]) > center[1] ) << 1) | ((((*point)[2]) > center[2] ) << 2);
1203 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
1206 return ((point[0]) > center[0] ) | (((point[1]) > center[1] ) << 1) | (((point[2]) > center[2] ) << 2);
1221 template <
typename BaseVecT,
typename BoxT,
typename T_CellData>
1236 m_NumberOfGeneratedCells += 8;
1239 LocCode cell_level = level( _parent ) - 1;
1240 LocCode cell_bit_mask = ( 1 << cell_level );
1241 LocCode par_loc_x = location( _parent ).loc_x();
1242 LocCode par_loc_y = location( _parent ).loc_y();
1243 LocCode par_loc_z = location( _parent ).loc_z();
1245 if (!bGarbageCollectionOnTheFly || (m_nextFreeBlock==m_OctreeCell.size()))
1247 m_OctreeCell[ _parent.
idx() ].next = m_OctreeCell.size();
1251 dummy.location =
Location( par_loc_x, par_loc_y, par_loc_z, cell_level, _parent );
1252 m_OctreeCell.push_back( dummy );
1254 dummy.location =
Location( par_loc_x | cell_bit_mask, par_loc_y, par_loc_z, cell_level, _parent );
1255 m_OctreeCell.push_back( dummy );
1257 dummy.location =
Location( par_loc_x, par_loc_y | cell_bit_mask, par_loc_z, cell_level, _parent );
1258 m_OctreeCell.push_back( dummy );
1260 dummy.location =
Location( par_loc_x | cell_bit_mask, par_loc_y | cell_bit_mask, par_loc_z, cell_level, _parent );
1261 m_OctreeCell.push_back( dummy );
1263 dummy.location =
Location( par_loc_x, par_loc_y, par_loc_z | cell_bit_mask, cell_level, _parent );
1264 m_OctreeCell.push_back( dummy );
1266 dummy.location =
Location( par_loc_x | cell_bit_mask, par_loc_y, par_loc_z | cell_bit_mask, cell_level, _parent );
1267 m_OctreeCell.push_back( dummy );
1269 dummy.location =
Location( par_loc_x, par_loc_y | cell_bit_mask, par_loc_z | cell_bit_mask, cell_level, _parent );
1270 m_OctreeCell.push_back( dummy );
1272 dummy.location =
Location( par_loc_x | cell_bit_mask, par_loc_y | cell_bit_mask, par_loc_z | cell_bit_mask, cell_level, _parent );
1273 m_OctreeCell.push_back( dummy );
1278 m_OctreeCell[ _parent.
idx() ].next = m_nextFreeBlock;
1280 m_OctreeCell[m_nextFreeBlock].location =
1281 Location( par_loc_x, par_loc_y, par_loc_z, cell_level, _parent );
1282 m_OctreeCell[m_nextFreeBlock+1].location =
1283 Location( par_loc_x | cell_bit_mask, par_loc_y, par_loc_z, cell_level, _parent );
1284 m_OctreeCell[m_nextFreeBlock+2].location =
1285 Location( par_loc_x, par_loc_y | cell_bit_mask, par_loc_z, cell_level, _parent );
1286 m_OctreeCell[m_nextFreeBlock+3].location =
1287 Location( par_loc_x | cell_bit_mask, par_loc_y | cell_bit_mask, par_loc_z, cell_level, _parent );
1288 m_OctreeCell[m_nextFreeBlock+4].location =
1289 Location( par_loc_x, par_loc_y, par_loc_z | cell_bit_mask, cell_level, _parent );
1290 m_OctreeCell[m_nextFreeBlock+5].location =
1291 Location( par_loc_x | cell_bit_mask, par_loc_y, par_loc_z | cell_bit_mask, cell_level, _parent );
1292 m_OctreeCell[m_nextFreeBlock+6].location =
1293 Location( par_loc_x, par_loc_y | cell_bit_mask, par_loc_z | cell_bit_mask, cell_level, _parent );
1294 m_OctreeCell[m_nextFreeBlock+7].location =
1295 Location( par_loc_x | cell_bit_mask, par_loc_y | cell_bit_mask, par_loc_z | cell_bit_mask, cell_level, _parent );
1299 while ((m_nextFreeBlock<m_OctreeCell.size()) && m_OctreeCell[m_nextFreeBlock].location.parent().is_valid()) m_nextFreeBlock+=8;