18 #include "globals.icc" 35 #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) 36 #define POPCOUNT(mask) __builtin_popcount(mask) 38 #define POPCOUNT(mask) _my_popcount_3(mask) 41 #include <boost/interprocess/offset_ptr.hpp> 42 namespace {
namespace ip = boost::interprocess; }
61 #define pointrep union dunion<T> 86 __int64 child_pointer : 48;
113 for (
unsigned char i = 0; i < index; i++) {
114 if ( ( 1 << i ) & valid ) {
156 return reinterpret_cast<T*
>(
166 return (reinterpret_cast<pointrep*>((
char*)
this + node.
child_pointer))[0].length;
176 for (
unsigned char i = 0; i < index; i++) {
177 if ( ( 1 << i ) & node.
valid ) {
185 return ( ( 1 << index ) & node.
valid );
194 return ( ( 1 << index ) & node.
leaf );
200 extern char amap[8][8];
201 extern char imap[8][8];
214 template <
typename T>
221 BOctTree(P *
const* pts,
int n, T voxelSize,
PointType _pointtype =
PointType(),
bool _earlystop =
false ) : pointtype(_pointtype), earlystop(_earlystop)
225 this->voxelSize = voxelSize;
227 this->POINTDIM = pointtype.getPointDim();
229 mins = alloc->allocate<T>(POINTDIM);
230 maxs = alloc->allocate<T>(POINTDIM);
233 for (
unsigned int i = 0; i < POINTDIM; i++) {
238 for (
unsigned int i = 0; i < POINTDIM; i++) {
239 for (
int j = 1; j < n; j++) {
240 mins[i] = min(
mins[i], (T)pts[j][i]);
241 maxs[i] = max(maxs[i], (T)pts[j][i]);
245 center[0] = 0.5 * (
mins[0] + maxs[0]);
246 center[1] = 0.5 * (
mins[1] + maxs[1]);
247 center[2] = 0.5 * (
mins[2] + maxs[2]);
248 size = max(max(0.5 * (maxs[0] -
mins[0]), 0.5 * (maxs[1] -
mins[1])), 0.5 * (maxs[2] -
mins[2]));
253 T sizeNew = size / 2.0;
255 for (
unsigned char i = 0; i < 8; i++) {
256 childcenter(center, newcenter[i], size, i);
262 countPointsAndQueueFast(pts, n, newcenter, sizeNew, *root, center);
268 deserialize(filename);
277 this->voxelSize = voxelSize;
279 this->POINTDIM = pointtype.getPointDim();
281 mins = alloc->allocate<T>(POINTDIM);
282 maxs = alloc->allocate<T>(POINTDIM);
285 for (
unsigned int i = 0; i < POINTDIM; i++) {
290 for (
unsigned int i = 0; i < POINTDIM; i++) {
291 for (
unsigned int j = 1; j < pts.size(); j++) {
293 maxs[i] = max(maxs[i], pts[j][i]);
297 center[0] = 0.5 * (
mins[0] + maxs[0]);
298 center[1] = 0.5 * (
mins[1] + maxs[1]);
299 center[2] = 0.5 * (
mins[2] + maxs[2]);
300 size = max(max(0.5 * (maxs[0] -
mins[0]), 0.5 * (maxs[1] -
mins[1])), 0.5 * (maxs[2] -
mins[2]));
306 T sizeNew = size / 2.0;
308 for (
unsigned char i = 0; i < 8; i++) {
309 childcenter(center, newcenter[i], size, i);
315 countPointsAndQueue(pts, newcenter, sizeNew, *root, center);
327 real_voxelSize = size;
329 while (real_voxelSize > voxelSize) {
330 real_voxelSize = real_voxelSize/2.0;
334 child_bit_depth = alloc->allocate<
unsigned int>(max_depth);
335 child_bit_depth_inv = alloc->allocate<
unsigned int>(max_depth);
337 for(
int d=0; d < max_depth; d++) {
338 child_bit_depth[d] = 1 << (max_depth - d - 1);
339 child_bit_depth_inv[d] = ~child_bit_depth[d];
342 mult = 1.0/real_voxelSize;
343 add[0] = -center[0] + size;
344 add[1] = -center[1] + size;
345 add[2] = -center[2] + size;
347 largest_index = child_bit_depth[0] * 2 -1;
355 ip::offset_ptr<bitoct> root;
410 inline const T*
getMins()
const {
return &(*mins); }
411 inline const T*
getMaxs()
const {
return &(*maxs); }
419 _center[0] = center[0];
420 _center[1] = center[1];
421 _center[2] = center[2];
434 char buffer[
sizeof(T) * 20];
435 T *
p =
reinterpret_cast<T*
>(buffer);
438 file.open (filename.c_str(), std::ios::in | std::ios::binary);
441 file.read(buffer, 2);
442 if ( buffer[0] !=
'X' || buffer[1] !=
'T') {
443 std::cerr <<
"Not an octree file!!" << endl;
451 file.read(buffer, 5 *
sizeof(T));
458 file.read(buffer,
sizeof(
int));
459 int *ip =
reinterpret_cast<int*
>(buffer);
462 mins = alloc->
allocate<T>(POINTDIM);
463 maxs = alloc->
allocate<T>(POINTDIM);
465 file.read(reinterpret_cast<char*>(&(*mins)), POINTDIM *
sizeof(T));
466 file.read(reinterpret_cast<char*>(&(*maxs)), POINTDIM *
sizeof(T));
472 deserialize(file, *root);
477 char buffer[
sizeof(T) * 20];
480 file.open (filename.c_str(), std::ios::in | std::ios::binary);
483 file.read(buffer, 2);
484 if ( buffer[0] !=
'X' || buffer[1] !=
'T') {
485 std::cerr <<
"Not an octree file!!" << endl;
493 file.read(buffer, 5 *
sizeof(T));
494 file.read(buffer,
sizeof(
int));
496 int *ip =
reinterpret_cast<int*
>(buffer);
497 unsigned int POINTDIM = *ip;
499 file.read(buffer, POINTDIM *
sizeof(T));
500 file.read(buffer, POINTDIM *
sizeof(T));
503 deserialize(file, points, pointtype);
508 char buffer[
sizeof(T) * 20];
509 T *
p =
reinterpret_cast<T*
>(buffer);
512 file.open (filename.c_str(), std::ios::out | std::ios::binary);
517 file.write(buffer, 2);
528 int *ip =
reinterpret_cast<int*
>(&(buffer[5 *
sizeof(T)]));
531 file.write(buffer, 5 *
sizeof(T) +
sizeof(
int));
534 for (
unsigned int i = 0; i < POINTDIM; i++) {
537 for (
unsigned int i = 0; i < POINTDIM; i++) {
538 p[i+POINTDIM] = maxs[i];
541 file.write(buffer, 2*POINTDIM *
sizeof(T));
544 serialize(file, *root);
550 char buffer[
sizeof(T) * 20];
553 file.open (filename.c_str(), std::ios::in | std::ios::binary);
556 file.read(buffer, 2);
557 if ( buffer[0] !=
'X' || buffer[1] !=
'T') {
558 std::cerr <<
"Not an octree file!!" << endl;
580 for (
short i = 0; i < 8; i++) {
581 if ( ( 1 << i ) & node.
valid ) {
582 if ( ( 1 << i ) & node.
leaf ) {
588 return pickPoint(children->
node);
596 static void childcenter(
const T *pcenter, T *ccenter, T size,
unsigned char i) {
599 ccenter[0] = pcenter[0] - size / 2.0;
600 ccenter[1] = pcenter[1] - size / 2.0;
601 ccenter[2] = pcenter[2] - size / 2.0;
604 ccenter[0] = pcenter[0] + size / 2.0;
605 ccenter[1] = pcenter[1] - size / 2.0;
606 ccenter[2] = pcenter[2] - size / 2.0;
609 ccenter[0] = pcenter[0] - size / 2.0;
610 ccenter[1] = pcenter[1] + size / 2.0;
611 ccenter[2] = pcenter[2] - size / 2.0;
614 ccenter[0] = pcenter[0] + size / 2.0;
615 ccenter[1] = pcenter[1] + size / 2.0;
616 ccenter[2] = pcenter[2] - size / 2.0;
619 ccenter[0] = pcenter[0] - size / 2.0;
620 ccenter[1] = pcenter[1] - size / 2.0;
621 ccenter[2] = pcenter[2] + size / 2.0;
624 ccenter[0] = pcenter[0] + size / 2.0;
625 ccenter[1] = pcenter[1] - size / 2.0;
626 ccenter[2] = pcenter[2] + size / 2.0;
629 ccenter[0] = pcenter[0] - size / 2.0;
630 ccenter[1] = pcenter[1] + size / 2.0;
631 ccenter[2] = pcenter[2] + size / 2.0;
634 ccenter[0] = pcenter[0] + size / 2.0;
635 ccenter[1] = pcenter[1] + size / 2.0;
636 ccenter[2] = pcenter[2] + size / 2.0;
643 static void childcenter(
int x,
int y,
int z,
int &cx,
int &cy,
int &cz,
char i,
int size) {
696 for (
short i = 0; i < 8; i++) {
697 if ( ( 1 << i ) & node.
valid ) {
698 if ( ( 1 << i ) & node.
leaf ) {
703 unsigned int length = points[0].length;
704 T *point = &(points[1].v);
705 for(
unsigned int iterator = 0; iterator <
length; iterator++ ) {
710 for (
unsigned int k = 0; k < BOctTree<T>::POINTDIM; k++)
719 AllPoints( children->
node, vp);
731 node.
valid = buffer[0];
732 node.
leaf = buffer[1];
734 for (
short i = 0; i < 8; i++) {
735 if ( ( 1 << i ) & node.
valid ) {
736 if ( ( 1 << i ) & node.
leaf ) {
738 f.read(reinterpret_cast<char*>(&first),
sizeof(
pointrep));
739 unsigned int length = first.length;
740 for (
unsigned int k = 0; k <
length; k++) {
742 vpoints.push_back( pointtype.
createPoint( &(point->v ) ) );
745 deserialize(f, vpoints, pointtype);
755 node.
valid = buffer[0];
756 node.
leaf = buffer[1];
764 for (
short i = 0; i < 8; i++) {
765 if ( ( 1 << i ) & node.
valid ) {
766 if ( ( 1 << i ) & node.
leaf ) {
768 f.read(reinterpret_cast<char*>(&first),
sizeof(
pointrep));
769 unsigned int length = first.length;
777 f.read(reinterpret_cast<char*>(points),
sizeof(
pointrep) * length * POINTDIM);
779 deserialize(f, children->
node);
788 buffer[0] = node.
valid;
789 buffer[1] = node.
leaf;
796 for (
short i = 0; i < 8; i++) {
797 if ( ( 1 << i ) & node.
valid ) {
798 if ( ( 1 << i ) & node.
leaf ) {
803 unsigned int length = points[0].length;
804 of.write(reinterpret_cast<char*>(points),
sizeof(
pointrep) * (length * POINTDIM +1));
806 serialize(of, children->
node);
818 for (
unsigned char i = 0; i < 8; i++) {
819 if ( ( 1 << i ) & node.
valid ) {
820 childcenter(center, ccenter, size, i);
821 if ( ( 1 << i ) & node.
leaf ) {
823 for (
unsigned int iterator = 0; iterator < 3; iterator++) {
824 cp[iterator] = ccenter[iterator];
828 GetOctTreeCenter(c, children->
node, ccenter, size/2.0);
839 for (
short i = 0; i < 8; i++) {
840 if ( ( 1 << i ) & node.
valid ) {
841 if ( ( 1 << i ) & node.
leaf ) {
857 int tmp = rand(points[0].
length);
858 T *point = &(points[POINTDIM*tmp+1].v);
863 GetOctTreeRandom(c, children->
node);
874 for (
short i = 0; i < 8; i++) {
875 if ( ( 1 << i ) & node.
valid ) {
876 if ( ( 1 << i ) & node.
leaf ) {
881 unsigned int length = points[0].length;
882 if (ptspervoxel >= length) {
883 for (
unsigned int j = 0; j <
length; j++)
884 c.push_back(&(points[POINTDIM*j+1].v));
890 while(indices.size() < ptspervoxel) {
891 int tmp = rand(length-1);
894 for(set<int>::iterator it = indices.begin(); it != indices.end(); it++)
895 c.push_back(&(points[POINTDIM*(*it)+1].v));
898 GetOctTreeRandom(c, ptspervoxel, children->
node);
910 for (
short i = 0; i < 8; i++) {
911 if ( ( 1 << i ) & node.
valid ) {
912 if ( ( 1 << i ) & node.
leaf ) {
915 result += countNodes(children->
node) + 1;
928 for (
short i = 0; i < 8; i++) {
929 if ( ( 1 << i ) & node.
valid ) {
930 if ( ( 1 << i ) & node.
leaf ) {
932 result += POINTDIM*nrpts;
934 result += countLeaves(children->
node);
947 for (
short i = 0; i < 8; i++) {
948 if ( ( 1 << i ) & node.
valid ) {
949 if ( ( 1 << i ) & node.
leaf ) {
952 result += countTrueLeaves(children->
node);
964 bool haschildren =
false;
966 for (
short i = 0; i < 8; i++) {
967 if ( ( 1 << i ) & node.
valid ) {
968 if ( ( 1 << i ) & node.
leaf ) {
974 deletetNodes(children->
node);
990 if ((_size <= voxelSize) || (earlystop && n <= 10) ) {
995 points[0].length = n;
997 for (
int j = 0; j < n; j++) {
998 for (
unsigned int iterator = 0; iterator < POINTDIM; iterator++) {
999 points[i++].v = splitPoints[j][iterator];
1009 sizeNew = _size / 2.0;
1011 for (
unsigned char i = 0; i < 8; i++) {
1012 childcenter(_center, newcenter[i], _size, i);
1015 countPointsAndQueueFast(splitPoints, n, newcenter, sizeNew, node, _center);
1023 if ((_size <= voxelSize) || (earlystop && splitPoints.size() <= 10) ) {
1026 points[0].length = splitPoints.size();
1028 for (
typename vector<P *>::iterator itr = splitPoints.begin();
1029 itr != splitPoints.end(); itr++) {
1030 for (
unsigned int iterator = 0; iterator < POINTDIM; iterator++) {
1031 points[i++].v = (*itr)[iterator];
1041 sizeNew = _size / 2.0;
1043 for (
unsigned char i = 0; i < 8; i++) {
1044 childcenter(_center, newcenter[i], _size, i);
1047 countPointsAndQueue(splitPoints, newcenter, sizeNew, node, _center);
1053 vector<P*> points[8];
1055 for (
typename vector<P *>::iterator itr = i_points.begin(); itr != i_points.end(); itr++) {
1056 points[childIndex<P>(pcenter, *itr)].push_back( *itr );
1060 vector<P*>().
swap(i_points);
1061 for (
int j = 0; j < 8; j++) {
1062 if (!points[j].empty()) {
1072 for (
int j = 0; j < 8; j++) {
1073 if (!points[j].empty()) {
1074 pointrep *c = (
pointrep*)branch(children[count].node, points[j], center[j], size);
1080 parent.
leaf = ( 1 << j ) | parent.
leaf;
1083 vector<P*>().
swap(points[j]);
1091 P *
const *blocks[9];
1093 blocks[8] = points + n;
1094 fullsort(points, n, pcenter, blocks+1);
1098 for (
int j = 0; j < 8; j++) {
1100 if (blocks[j+1] - blocks[j] > 0) {
1110 for (
int j = 0; j < 8; j++) {
1111 if (blocks[j+1] - blocks[j] > 0) {
1112 pointrep *c = (
pointrep*)branch(children[count].node, blocks[j], blocks[j+1] - blocks[j], center[j], size);
1118 parent.
leaf = ( 1 << j ) | parent.
leaf;
1128 x = (point[0] + add[0]) * mult;
1129 y = (point[1] + add[1]) * mult;
1130 z = (point[2] + add[2]) * mult;
1133 unsigned char child_index;
1134 unsigned int child_bit;
1135 unsigned int depth = 0;
1138 child_bit = child_bit_depth[depth];
1139 child_index = ((x & child_bit )!=0) | (((y & child_bit )!=0 )<< 1) | (((z & child_bit )!=0) << 2);
1141 node = node->
getChild(child_index);
1146 node = node->
getChild(child_index);
1153 inline unsigned char childIndex(
const T *center,
const P *point) {
1154 return (point[0] > center[0] ) | ((point[1] > center[1] ) << 1) | ((point[2] > center[2] ) << 2) ;
1162 if (params[threadNum].count >= params[threadNum].max_count)
return;
1163 params[threadNum].
count++;
1166 for(
unsigned int iterator = 0; iterator <
length; iterator++ ) {
1167 double myd2 = Dist2(params[threadNum].
p, points);
1168 if (myd2 < params[threadNum].closest_d2) {
1170 params[threadNum].
closest = points;
1171 if (myd2 <= 0.0001) {
1174 params[threadNum].
closest_v = sqrt(myd2) * mult + 1;
1190 double *
FindClosest(
double *point,
double maxdist2,
int threadNum)
const 1192 params[threadNum].
closest = 0;
1194 params[threadNum].
p = point;
1195 params[threadNum].
x = (point[0] + add[0]) * mult;
1196 params[threadNum].
y = (point[1] + add[1]) * mult;
1197 params[threadNum].
z = (point[2] + add[2]) * mult;
1198 params[threadNum].
closest_v = sqrt(maxdist2) * mult + 1;
1199 params[threadNum].
count = 0;
1204 int xmin, ymin, zmin, xmax, ymax, zmax;
1205 xmin = max(params[threadNum].x-params[threadNum].closest_v, 0);
1206 ymin = max(params[threadNum].y-params[threadNum].closest_v, 0);
1207 zmin = max(params[threadNum].z-params[threadNum].closest_v, 0);
1211 xmax = min(params[threadNum].x+params[threadNum].closest_v, largest_index);
1212 ymax = min(params[threadNum].y+params[threadNum].closest_v, largest_index);
1213 zmax = min(params[threadNum].z+params[threadNum].closest_v, largest_index);
1215 unsigned char depth = 0;
1216 unsigned int child_bit;
1217 unsigned int child_index_min;
1218 unsigned int child_index_max;
1224 child_bit = child_bit_depth[depth];
1225 cx = child_bit_depth[depth];
1226 cy = child_bit_depth[depth];
1227 cz = child_bit_depth[depth];
1230 child_index_min = ((xmin & child_bit )!=0) | (((ymin & child_bit )!=0 )<< 1) | (((zmin & child_bit )!=0) << 2);
1231 child_index_max = ((xmax & child_bit )!=0) | (((ymax & child_bit )!=0 )<< 1) | (((zmax & child_bit )!=0) << 2);
1235 if (child_index_min == child_index_max) {
1237 findClosestInLeaf(node->
getChild(child_index_min), threadNum);
1238 return static_cast<double*
>(params[threadNum].
closest);
1240 if (node->
isValid(child_index_min) ) {
1241 childcenter(cx,cy,cz, cx,cy,cz, child_index_min, child_bit/2 );
1242 node = node->
getChild(child_index_min);
1255 _FindClosest(threadNum, node->
node, child_bit/2, cx, cy, cz);
1256 return static_cast<double*
>(params[threadNum].
closest);
1269 unsigned char child_index = ((params[threadNum].
x - x) >= 0) |
1270 (((params[threadNum].
y - y) >= 0) << 1) |
1271 (((params[threadNum].z - z) >= 0) << 2);
1274 char *mmap =
amap[child_index];
1280 for (
unsigned char i = 0; i < 8; i++) {
1281 child_index = mmap[i];
1282 if ( ( 1 << child_index ) & node.
valid ) {
1283 childcenter(x,y,z, cx,cy,cz, child_index, size);
1284 if ( params[threadNum].closest_v == 0 || max(max(
abs( cx - params[threadNum].x ),
1285 abs( cy - params[threadNum].y )),
1286 abs( cz - params[threadNum].z )) - size
1287 > params[threadNum].closest_v ) {
1291 if ( ( 1 << child_index ) & node.
leaf ) {
1292 findClosestInLeaf( &children[seq2ci[i]], threadNum);
1294 _FindClosest(threadNum, children[seq2ci[i]].node, size/2, cx, cy, cz);
1309 params[threadNum].
closest = 0;
1311 params[threadNum].
p = point;
1313 x = (point[0] + add[0]) * mult;
1314 y = (point[1] + add[1]) * mult;
1315 z = (point[2] + add[2]) * mult;
1320 unsigned char child_index;
1322 unsigned int child_bit = child_bit_depth[0];
1325 child_index = ((x & child_bit )!=0) | (((y & child_bit )!=0 )<< 1) | (((z & child_bit )!=0) << 2);
1327 node = node->
getChild(child_index);
1331 for(
unsigned int iterator = 0; iterator <
length; iterator++ ) {
1332 double myd2 = Dist2(params[threadNum].
p, points);
1333 if (myd2 < params[threadNum].closest_d2) {
1335 params[threadNum].
closest = points;
1339 return static_cast<double*
>(params[threadNum].
closest);
1341 if (node->
isValid(child_index) ) {
1342 node = node->
getChild(child_index);
1349 return static_cast<double*
>(params[threadNum].
closest);
1354 void fullsort(P *
const * points,
int n, T splitval[3], P *
const * blocks[9]) {
1358 unsigned int n0L, n0R, n1L, n1R ;
1361 L0 = sort(points, n, splitval[2], 2);
1365 L1 = sort(points, n0L, splitval[1], 1);
1369 L2 = sort(points, n1L, splitval[0], 0);
1375 L2 = sort(L1, n1R, splitval[0], 0);
1382 L1 = sort(L0, n0R, splitval[1], 1);
1386 L2 = sort(L0, n1L, splitval[0], 0);
1393 L2 = sort(L1, n1R, splitval[0], 0);
1401 P*
const *
sort(P*
const * points,
unsigned int n, T splitval,
unsigned char index) {
1402 if (n==0)
return points;
1405 if (points[0][index] < splitval)
1411 P **left =
const_cast<P**
>(points);
1412 P **right =
const_cast<P**
>(points + n - 1);
1416 while ((*left)[index] < splitval)
1422 while ((*right)[index] >= splitval)
1449 for(i = 0; i < 3; ++i)
1450 center[i] = other.
center[i];
1454 for(i = 0; i < 3; ++i)
1455 add[i] = other.
add[i];
1458 mins = alloc->
allocate<T>(POINTDIM);
1459 maxs = alloc->
allocate<T>(POINTDIM);
1460 for(i = 0; i < POINTDIM; ++i) {
1461 mins[i] = other.
mins[i];
1462 maxs[i] = other.
maxs[i];
1466 child_bit_depth = alloc->
allocate<
unsigned int>(max_depth);
1467 child_bit_depth_inv = alloc->
allocate<
unsigned int>(max_depth);
1468 for(i = 0; i < max_depth; ++i) {
1476 root = &uroot->
node;
1477 copy_children(*other.
root, *root);
1483 delete alloc; alloc = 0;
1502 for(
unsigned int i = 0; i < 8; ++i) {
1503 if((1<<i) & other.
valid) {
1504 if((1<<i) & other.
leaf) {
1509 for(
unsigned int j = 0; j < POINTDIM * length + 1; ++j)
1510 my_pointreps[j] = other_pointreps[j];
1515 copy_children(other_children->
node, my_children->
node);
1527 return sizeof(*this)
1528 + 2*POINTDIM*
sizeof(T)
1529 + 2*max_depth*
sizeof(
unsigned int)
1531 + sizeChildren(*root);
1546 for(
unsigned int i = 0; i < 8; ++i) {
1547 if((1<<i) & node.
valid) {
1548 if((1<<i) & node.
leaf) {
1553 s += sizeChildren(children->
node);
ip::offset_ptr< unsigned int > child_bit_depth
T * getPoints() const
Leaf node: points in the array.
bitunion< T > * getChild(unsigned char index) const
int splitPoints(Vector3f *points, int n, int axis, double splitValue)
Sorts a Point array so that all Points smaller than splitValue are on the left.
static void getChildren(const bitoct &parent, bitunion< T > *&children)
double * FindClosest(double *point, double maxdist2, int threadNum) const
void GetOctTreeRandom(vector< T *> &c)
void getCenter(double _center[3]) const
void deletetNodes(bitoct &node)
bool isValid(unsigned char index)
long countNodes(bitoct &node)
static PointType deserialize(std::ifstream &f)
void deserialize(std::ifstream &f, bitoct &node)
T add[3]
Offset and real voxelsize inverse factor for manipulation points.
T * createPoint(const Point &P, unsigned int index=0)
const T * getMins() const
unsigned int sizeChildren(const bitoct &node)
Recursive size of a node's children.
SingleObject< BOctTree< float > > DataOcttree
static void deserialize(std::string filename, vector< Point > &points)
Representation of a general search trees.
static void childcenter(const T *pcenter, T *ccenter, T size, unsigned char i)
static PointType readType(std::string filename)
BOctTree(vector< P *> &pts, T voxelSize, PointType _pointtype=PointType(), bool _earlystop=false)
T center[3]
storing the center
ip::offset_ptr< unsigned int > child_bit_depth_inv
unsigned int getPointDim()
bitunion< T > * getChild(unsigned char index)
unsigned int getLength() const
Leaf node: length in the array.
bool childIsLeaf(unsigned char index)
void getByIndex(T *point, T *&points, unsigned int &length)
ip::offset_ptr< bitoct > root
the root of the octree
static void link(bitoct &parent, bitunion< T > *child)
BOctTree(const BOctTree &other, unsigned char *mem_ptr, unsigned int mem_max)
void AllPoints(vector< T *> &vp)
__kf_hdevice__ void swap(T &a, T &b)
Representation of a 3D point type.
PointType pointtype
Details of point attributes.
void findClosestInLeaf(bitunion< T > *node, int threadNum) const
void countPointsAndQueue(vector< P *> &i_points, T center[8][3], T size, bitoct &parent, T *pcenter)
BOctTree(P *const *pts, int n, T voxelSize, PointType _pointtype=PointType(), bool _earlystop=false)
void * branch(bitoct &node, P *const *splitPoints, int n, T _center[3], T _size)
void countPointsAndQueueFast(P *const *points, int n, T center[8][3], T size, bitoct &parent, T pcenter[3])
unsigned int getMaxDepth() const
long countLeaves(bitoct &node)
long countOctLeaves(bitoct &node)
T size
storing the dimension
static void link(bitunion< T > *leaf, pointrep *points)
Leaf node: links a pointrep array [length+values] to this union, saved as an offset pointer...
void serialize(std::ofstream &of, bitoct &node)
unsigned int POINTDIM
Dimension of each point: 3 (xyz) + N (attributes)
unsigned int getMemorySize()
Size of the whole tree structure, including the main class, its serialize critical allocated variable...
void * branch(bitoct &node, vector< P *> &splitPoints, T _center[3], T _size)
void copy_children(const bitoct &other, bitoct &my)
static void childcenter(int x, int y, int z, int &cx, int &cy, int &cz, char i, int size)
void GetOctTreeRandom(vector< T *> &c, unsigned int ptspervoxel)
void deserialize(std::string filename)
double * FindClosestInBucket(double *point, double maxdist2, int threadNum)
BOctTree(std::string filename)
ip::offset_ptr< bitunion< T > > uroot
void fullsort(P *const *points, int n, T splitval[3], P *const *blocks[9])
void GetOctTreeCenter(vector< T *> &c, bitoct &node, T *center, T size)
Allocator * alloc
Allocator used for creating nodes in the constructor.
T voxelSize
storing the voxel size
void serialize(std::ofstream &f)
unsigned int getPointdim() const
T * allocate(unsigned int nr=1)
void AllPoints(bitoct &node, vector< T *> &vp)
pointrep * getPointreps() const
Leaf node: all points.
ip::offset_ptr< T > mins
storing minimal and maximal values for all dimensions
T real_voxelSize
The real voxelsize of the leaves.
allocator object that gets chunks of memory and then hands parts of them to a user ...
char sequence2ci[8][256][8]
T * pickPoint(bitoct &node)
void GetOctTreeCenter(vector< T *> &c)
void _FindClosest(int threadNum, bitoct &node, int size, int x, int y, int z) const
void GetOctTreeRandom(vector< T *> &c, bitoct &node)
P *const * sort(P *const *points, unsigned int n, T splitval, unsigned char index)
unsigned char childIndex(const T *center, const P *point)
const bitoct & getRoot() const
void GetOctTreeRandom(vector< T *> &c, unsigned int ptspervoxel, bitoct &node)
void serialize(std::string filename)
The search tree structure.
signed long child_pointer
static void deserialize(std::ifstream &f, vector< Point > &vpoints, PointType &pointtype)
const T * getCenter() const
Basic DataPointer class and its derivates SingleArray and TripleArray.
const T * getMaxs() const