15#include <Octree_Int.h>
17static constexpr int max_levels_ = 32;
35template <
typename _SIZE_>
55template <
typename _SIZE_>
74template <
typename _SIZE_>
98template <
typename _SIZE_>
101 assert(dimension >= 1 && dimension <= 3);
102 assert(elements_boxes.
dimension(1) == dimension
103 || elements_boxes.
dimension(1) == dimension * 2 );
109 const int nb_octrees = 1 << dimension;
113 || (min_array(elements_boxes) >= 0 && max_array(elements_boxes) <=
coord_max_));
115 AOFlagS_ tmp_elem_flags(max_levels_);
118 elements_list.
resize_array(nb_elems, RESIZE_OPTIONS::NOCOPY_NOINIT);
119 for (
int_t i = 0; i < nb_elems; i++)
120 elements_list[i] = i;
137template <
typename _SIZE_>
160template <
typename _SIZE_>
167 int xmax,
int ymax,
int zmax,
184template <
typename _SIZE_>
186 int xmax,
int ymax,
int zmax,
225template <
typename _SIZE_>
227 int_t octree_floor_id)
const
232 for (
int_t i = 0; i < n; i++)
239 for (
int_t i = 0; i < n; i++)
247static int sub_cube_flags_min[3] = { 1+4+16+64,
251static int sub_cube_flags_max[3] = { 2+8+32+128,
259template <
typename _SIZE_>
262 int cx,
int cy,
int cz,
263 int half_width)
const
266 if (cx > boxdata.
xmax_)
267 flags &= sub_cube_flags_min[0];
268 if (cx <= boxdata.
xmin_)
269 flags &= sub_cube_flags_max[0];
270 if (cy > boxdata.
ymax_)
271 flags &= sub_cube_flags_min[1];
272 if (cy <= boxdata.
ymin_)
273 flags &= sub_cube_flags_max[1];
274 if (cz > boxdata.
zmax_)
275 flags &= sub_cube_flags_min[2];
276 if (cz <= boxdata.
zmin_)
277 flags &= sub_cube_flags_max[2];
280 const int half_width_2 = half_width >> 1;
281 const int mhalf_width = - half_width_2;
283 for (
int i = 0; i < 8; i++, test_flag <<= 1)
285 if ((flags & test_flag) != 0)
294 cx2 = cx + ((i & 1) ? half_width_2 : mhalf_width);
295 cy2 = cy + ((i & 2) ? half_width_2 : mhalf_width);
296 cz2 = cz + ((i & 4) ? half_width_2 : mhalf_width);
308template <
typename _SIZE_>
320template <
typename _SIZE_>
325 floor_elements_.resize_array(index + nb_elems + 1, RESIZE_OPTIONS::COPY_NOINIT);
327 for (
int_t i = 0; i < nb_elems; i++)
339template <
typename _SIZE_>
341 const int octree_center_y,
342 const int octree_center_z,
343 const int octree_half_width,
351 constexpr int OCTREE_FLOOR_MAX_ELEMS = 8;
354 constexpr int OCTREE_DUPLICATE_ELEMENTS_LIMIT = 64;
355 const ArrOfInt_t& elements_list = vect_elements_list[level];
362 if (nb_elems < OCTREE_FLOOR_MAX_ELEMS || octree_half_width == 1 )
365 return the_octree_id;
368 AOFlag_& elem_flags = tmp_elem_flags[level];
369 elem_flags.
resize_array(nb_elems, RESIZE_OPTIONS::NOCOPY_NOINIT);
372 assert(nb_octrees == 2 || nb_octrees == 4 || nb_octrees == 8);
375 const int box_delta = (elem_box_dim > 3) ? (elem_box_dim >> 1) : 0;
378 int_t nb_duplicate_elements = 0;
380 for (
int_t i_elem = 0; i_elem < nb_elems; i_elem++)
382 const int_t elem = elements_list[i_elem];
387 int octree_flags = 255;
389 int_t nb_duplicates = 1;
391 for (
int direction = 0; direction < 3; direction++)
393 const int_t elem_min = elements_boxes(elem, direction);
394 const int_t elem_max = elements_boxes(elem, box_delta+direction);
395 assert(elem_max >= elem_min);
397 const int center = (direction==0) ? octree_center_x : ((direction==1) ? octree_center_y : octree_center_z);
399 if (elem_min >= center)
400 octree_flags &= sub_cube_flags_max[direction];
401 else if (elem_max < center)
402 octree_flags &= sub_cube_flags_min[direction];
405 dir_flag = dir_flag << 1;
406 if (dir_flag == nb_octrees)
409 elem_flags[i_elem] = octree_flags;
410 nb_duplicate_elements += nb_duplicates - 1;
417 if ((nb_duplicate_elements * 2 >= nb_elems && nb_elems < OCTREE_DUPLICATE_ELEMENTS_LIMIT)
418 || nb_duplicate_elements > nb_elems)
422 return the_octree_id;
428 ArrOfInt_t& new_liste_elems = vect_elements_list[level+1];
430 const int width = octree_half_width >> 1;
431 const int m_width = - width;
433 for (
int i_cube = 0; i_cube < nb_octrees; i_cube++)
435 const int octree_flag = 1 << i_cube;
436 new_liste_elems.
resize_array(nb_elems, RESIZE_OPTIONS::NOCOPY_NOINIT);
439 for (
int_t i_elem = 0; i_elem < nb_elems; i_elem++)
440 if ((elem_flags[i_elem] & octree_flag) != 0)
441 new_liste_elems[count++] = elements_list[i_elem];
450 const int cx = octree_center_x + ((i_cube&1) ? width : m_width);
451 const int cy = octree_center_y + ((i_cube&2) ? width : m_width);
452 const int cz = octree_center_z + ((i_cube&4) ? width : m_width);
468template <
typename _SIZE_>
483 const int ix = (x & flag) ? 1 : 0;
484 const int iy = (y & flag) ? 2 : 0;
485 const int iz = (z & flag) ? 4 : 0;
486 int i_sous_cube = ix + iy + iz;
490 return the_octree_id;
int testsetbit(int_t i) const
Renvoie la valeur du bit e, puis met le bit e a 1.
: Un octree permettant de retrouver des objets ponctuels ou parallelipipediques dans un espace 1D,...
int_t search_octree_floor(int x_pos, int y_pos, int z_pos) const
renvoie l'octree_id de l'octree_floor contenant le sommet (x,y,z) (peut renvoyer l'octree EMPTY)
static Octree_Type octree_type(int_t octree_id)
Renvoie le type d'un octree en fonction de son octree_id.
void search_elements_box_recursively(IntBoxData< _SIZE_ > &boxdata, int_t octree_id, int cx, int cy, int cz, int half_width) const
cherche recursivement les elements inclus dans la boite boxdata pour l'octree_id donne,...
int_t search_elements_box(int xmin, int ymin, int zmin, int xmax, int ymax, int zmax, ArrOfInt_t &elements) const
cherche les elements ayant potentiellement une intersection non vide avec la boite xmin....
ArrOfInt_T< _SIZE_ > ArrOfInt_t
IntTab_T< _SIZE_ > IntTab_t
ArrOfInt_t floor_elements_
int_t build_octree_recursively(const int octree_center_x, const int octree_center_y, const int octree_center_z, const int octree_half_width, const IntTab_t &elements_boxes, ArrsOfInt_t &vect_elements_list, const int level, AOFlagS_ &tmp_elem_flags)
octree_center_i est le premier int de la moitie superieure de l'octree dans la direction i.
static const int root_octree_half_width_
static int_t octree_id(int_t index, Octree_Type type)
construction d'un octree_id (voir octree_structure_)
TRUSTArray< int, _SIZE_ > AOFlag_
IntTab_t octree_structure_
ArrsOfInt_T< _SIZE_ > ArrsOfInt_t
int_t search_elements(int x, int y, int z, int_t &floor_elements_index) const
renvoie la liste des elements contenant potentiellement le point (x,y,z) On renvoie n=nombre d'elemen...
static int_t octree_index(int_t octree_id, Octree_Type type)
calcul de l'index de l'octree dans octree_structure ou floor_elements en fonction du type de l'octree...
void search_elements_box_floor(IntBoxData< _SIZE_ > &boxdata, int_t octree_floor_id) const
ajoute des elements de l'octree_floor a boxdata.
TRUST_Vector< AOFlag_ > AOFlagS_
static const int coord_max_
int_t build_octree_floor(const ArrOfInt_t &elements_list)
construit un octree_floor avec la liste d'elements donnee et renvoie l'octree_id de cet octree_floor
void build(const int dimension, const IntTab_t &elements_boxes)
construction de l'octree.
void append_array(_TYPE_ valeur)
_SIZE_ size_array() const
void resize_array(_SIZE_ new_size, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
int dimension_int(int d) const
_SIZE_ dimension(int d) const
ArrOfInt_T< _SIZE_ > ArrOfInt_t
ArrOfBit_32_64< _SIZE_ > AOBit_
IntBoxData(int xmin, int ymin, int zmin, int xmax, int ymax, int zmax, ArrOfInt_t &elements, AOBit_ *markers)