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>
113 for (
unsigned char i = 0; i < index; i++) {
114 if ( ( 1 << i ) &
valid ) {
156 return reinterpret_cast<T*
>(
176 for (
unsigned char i = 0; i < index; i++) {
194 return ( ( 1 << index ) &
node.
leaf );
200 extern char amap[8][8];
201 extern char imap[8][8];
214 template <
typename T>
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]);
253 T sizeNew =
size / 2.0;
255 for (
unsigned char i = 0; i < 8; i++) {
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++) {
306 T sizeNew =
size / 2.0;
308 for (
unsigned char i = 0; i < 8; i++) {
355 ip::offset_ptr<bitoct>
root;
410 inline const T*
getMins()
const {
return &(*mins); }
411 inline const T*
getMaxs()
const {
return &(*maxs); }
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);
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);
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++) {
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 ) {
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++)
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 ) {
739 unsigned int length =
first.length;
740 for (
unsigned int k = 0; k < length; k++) {
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 ) {
769 unsigned int length =
first.length;
777 f.read(
reinterpret_cast<char*
>(points),
sizeof(
pointrep) * length *
POINTDIM);
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));
818 for (
unsigned char i = 0; i < 8; i++) {
819 if ( ( 1 << i ) & node.
valid ) {
821 if ( ( 1 << i ) & node.
leaf ) {
823 for (
unsigned int iterator = 0; iterator < 3; iterator++) {
824 cp[iterator] = ccenter[iterator];
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);
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));
910 for (
short i = 0; i < 8; i++) {
911 if ( ( 1 << i ) & node.
valid ) {
912 if ( ( 1 << i ) & node.
leaf ) {
928 for (
short i = 0; i < 8; i++) {
929 if ( ( 1 << i ) & node.
valid ) {
930 if ( ( 1 << i ) & node.
leaf ) {
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 ) {
995 points[0].length = n;
997 for (
int j = 0; j < n; j++) {
998 for (
unsigned int iterator = 0; iterator <
POINTDIM; iterator++) {
1009 sizeNew = _size / 2.0;
1011 for (
unsigned char i = 0; i < 8; i++) {
1028 for (
typename vector<P *>::iterator itr =
splitPoints.begin();
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++) {
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()) {
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) {
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;
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);
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;
1165 unsigned int length = node->
getLength();
1166 for(
unsigned int iterator = 0; iterator < length; iterator++ ) {
1167 double myd2 = Dist2(
params[threadNum].
p, points);
1168 if (myd2 <
params[threadNum].closest_d2) {
1171 if (myd2 <= 0.0001) {
1190 double *
FindClosest(
double *point,
double maxdist2,
int threadNum)
const
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);
1215 unsigned char depth = 0;
1216 unsigned int child_bit;
1217 unsigned int child_index_min;
1218 unsigned int child_index_max;
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) {
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);
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 ) {
1284 if (
params[threadNum].closest_v == 0 || max(max(
abs( cx -
params[threadNum].x ),
1287 >
params[threadNum].closest_v ) {
1291 if ( ( 1 << child_index ) & node.
leaf ) {
1313 x = (point[0] +
add[0]) *
mult;
1314 y = (point[1] +
add[1]) *
mult;
1315 z = (point[2] +
add[2]) *
mult;
1317 unsigned int length;
1320 unsigned char child_index;
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) {
1341 if (node->
isValid(child_index) ) {
1342 node = node->
getChild(child_index);
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)
1454 for(i = 0; i < 3; ++i)
1502 for(
unsigned int i = 0; i < 8; ++i) {
1503 if((1<<i) & other.
valid) {
1504 if((1<<i) & other.
leaf) {
1506 unsigned int length = other_children->
getLength();
1509 for(
unsigned int j = 0; j <
POINTDIM * length + 1; ++j)
1510 my_pointreps[j] = other_pointreps[j];
1527 return sizeof(*this)
1546 for(
unsigned int i = 0; i < 8; ++i) {
1547 if((1<<i) & node.
valid) {
1548 if((1<<i) & node.
leaf) {