32 #include "poisson_exceptions.h"
50 template<
class NodeData,
class Real>
int OctNode<NodeData,Real>::UseAlloc=0;
53 template<
class NodeData,
class Real>
59 internalAllocator.set(blockSize);
64 template<
class NodeData,
class Real>
67 template <
class NodeData,
class Real>
70 d=off[0]=off[1]=off[2]=0;
73 template <
class NodeData,
class Real>
75 if(!UseAlloc){
delete[] children;}
79 template <
class NodeData,
class Real>
83 if( !children ) initChildren();
84 for(
int i=0 ; i<8 ; i++ ) children[i].setFullDepth( maxDepth-1 );
88 template <
class NodeData,
class Real>
92 if(UseAlloc){children=internalAllocator.newElements(8);}
102 depthAndOffset(d,off);
107 children[idx].parent=
this;
108 children[idx].children=NULL;
110 off2[0]=(off[0]<<1)+i;
111 off2[1]=(off[1]<<1)+j;
112 off2[2]=(off[2]<<1)+k;
113 Index(d+1,off2,children[idx].d,children[idx].off);
120 template <
class NodeData,
class Real>
123 off[0]=short((1<<depth)+offset[0]-1);
124 off[1]=short((1<<depth)+offset[1]-1);
125 off[2]=short((1<<depth)+offset[2]-1);
128 template<
class NodeData,
class Real>
131 offset[0]=(int(off[0])+1)&(~(1<<depth));
132 offset[1]=(int(off[1])+1)&(~(1<<depth));
133 offset[2]=(int(off[2])+1)&(~(1<<depth));
136 template<
class NodeData,
class Real>
138 template<
class NodeData,
class Real>
140 depth=int(index&DepthMask);
141 offset[0]=(int((index>>OffsetShift1)&OffsetMask)+1)&(~(1<<depth));
142 offset[1]=(int((index>>OffsetShift2)&OffsetMask)+1)&(~(1<<depth));
143 offset[2]=(int((index>>OffsetShift3)&OffsetMask)+1)&(~(1<<depth));
146 template<
class NodeData,
class Real>
148 template <
class NodeData,
class Real>
152 offset[0]=(int(off[0])+1)&(~(1<<depth));
153 offset[1]=(int(off[1])+1)&(~(1<<depth));
154 offset[2]=(int(off[2])+1)&(~(1<<depth));
155 width=
Real(1.0/(1<<depth));
156 for(
int dim=0;dim<DIMENSION;dim++){center.
coords[dim]=
Real(0.5+offset[dim])*width;}
159 template<
class NodeData ,
class Real >
164 centerAndWidth( c , w );
166 return (c[0]-w)<p[0] && p[0]<=(c[0]+w) && (c[1]-w)<p[1] && p[1]<=(c[1]+w) && (c[2]-w)<p[2] && p[2]<=(c[2]+w);
169 template <
class NodeData,
class Real>
172 depth=index&DepthMask;
173 offset[0]=(int((index>>OffsetShift1)&OffsetMask)+1)&(~(1<<depth));
174 offset[1]=(int((index>>OffsetShift2)&OffsetMask)+1)&(~(1<<depth));
175 offset[2]=(int((index>>OffsetShift3)&OffsetMask)+1)&(~(1<<depth));
177 for(
int dim=0;dim<DIMENSION;dim++){center.
coords[dim]=
Real(0.5+offset[dim])*width;}
180 template <
class NodeData,
class Real>
182 if(!children){
return 0;}
186 d=children[i].maxDepth();
193 template <
class NodeData,
class Real>
195 if(!children){
return 1;}
203 template <
class NodeData,
class Real>
205 if(!children){
return 1;}
213 template<
class NodeData,
class Real>
215 if(depth()>maxDepth){
return 0;}
216 if(!children){
return 1;}
224 template <
class NodeData,
class Real>
231 template <
class NodeData,
class Real>
234 if( !current->
parent || current==
this )
return NULL;
236 else return current+1;
239 template <
class NodeData,
class Real>
241 if(!current->
parent || current==
this){
return NULL;}
243 else{
return current+1;}
246 template<
class NodeData ,
class Real >
249 if( !current->
parent || current==
this )
return NULL;
251 else return current-1;
254 template<
class NodeData ,
class Real >
257 if( !current->
parent || current==
this )
return NULL;
259 else return current-1;
262 template <
class NodeData,
class Real>
270 const OctNode* temp=nextBranch(current);
271 if(!temp){
return NULL;}
275 template <
class NodeData,
class Real>
283 OctNode* temp=nextBranch(current);
284 if(!temp){
return NULL;}
288 template <
class NodeData,
class Real>
291 if( !current )
return this;
293 else return nextBranch(current);
296 template <
class NodeData,
class Real>
299 if( !current )
return this;
301 else return nextBranch( current );
304 template <
class NodeData,
class Real>
308 centerAndWidth(center,width);
309 for(
int dim=0;dim<DIMENSION;dim++){
310 printf(
"%[%f,%f]",center.
coords[dim]-width/2,center.
coords[dim]+width/2);
311 if(dim<DIMENSION-1){printf(
"x");}
316 template <
class NodeData,
class Real>
319 template <
class NodeData,
class Real>
320 template<
class NodeAdjacencyFunction>
322 if(processCurrent){F->Function(
this,node);}
323 if(children){__processNodeNodes(node,F);}
326 template <
class NodeData,
class Real>
327 template<
class NodeAdjacencyFunction>
329 if(processCurrent){F->Function(
this,node);}
333 __processNodeFaces(node,F,c1,c2,c3,c4);
337 template <
class NodeData,
class Real>
338 template<
class NodeAdjacencyFunction>
340 if(processCurrent){F->Function(
this,node);}
344 __processNodeEdges(node,F,c1,c2);
348 template <
class NodeData,
class Real>
349 template<
class NodeAdjacencyFunction>
351 if(processCurrent){F->Function(
this,node);}
355 F->Function(temp,node);
359 template <
class NodeData,
class Real>
360 template<
class NodeAdjacencyFunction>
362 F->Function(&children[0],node);
363 F->Function(&children[1],node);
364 F->Function(&children[2],node);
365 F->Function(&children[3],node);
366 F->Function(&children[4],node);
367 F->Function(&children[5],node);
368 F->Function(&children[6],node);
369 F->Function(&children[7],node);
370 if(children[0].children){children[0].__processNodeNodes(node,F);}
371 if(children[1].children){children[1].__processNodeNodes(node,F);}
372 if(children[2].children){children[2].__processNodeNodes(node,F);}
373 if(children[3].children){children[3].__processNodeNodes(node,F);}
374 if(children[4].children){children[4].__processNodeNodes(node,F);}
375 if(children[5].children){children[5].__processNodeNodes(node,F);}
376 if(children[6].children){children[6].__processNodeNodes(node,F);}
377 if(children[7].children){children[7].__processNodeNodes(node,F);}
380 template <
class NodeData,
class Real>
381 template<
class NodeAdjacencyFunction>
382 void OctNode<NodeData,Real>::__processNodeEdges(OctNode* node,NodeAdjacencyFunction* F,
int cIndex1,
int cIndex2){
383 F->Function(&children[cIndex1],node);
384 F->Function(&children[cIndex2],node);
385 if(children[cIndex1].children){children[cIndex1].__processNodeEdges(node,F,cIndex1,cIndex2);}
386 if(children[cIndex2].children){children[cIndex2].__processNodeEdges(node,F,cIndex1,cIndex2);}
389 template <
class NodeData,
class Real>
390 template<
class NodeAdjacencyFunction>
391 void OctNode<NodeData,Real>::__processNodeFaces(OctNode* node,NodeAdjacencyFunction* F,
int cIndex1,
int cIndex2,
int cIndex3,
int cIndex4){
392 F->Function(&children[cIndex1],node);
393 F->Function(&children[cIndex2],node);
394 F->Function(&children[cIndex3],node);
395 F->Function(&children[cIndex4],node);
396 if(children[cIndex1].children){children[cIndex1].__processNodeFaces(node,F,cIndex1,cIndex2,cIndex3,cIndex4);}
397 if(children[cIndex2].children){children[cIndex2].__processNodeFaces(node,F,cIndex1,cIndex2,cIndex3,cIndex4);}
398 if(children[cIndex3].children){children[cIndex3].__processNodeFaces(node,F,cIndex1,cIndex2,cIndex3,cIndex4);}
399 if(children[cIndex4].children){children[cIndex4].__processNodeFaces(node,F,cIndex1,cIndex2,cIndex3,cIndex4);}
402 template<
class NodeData,
class Real>
403 template<
class NodeAdjacencyFunction>
405 int c1[3],c2[3],w1,w2;
408 w1=node1->
width(maxDepth+1);
409 w2=node2->
width(maxDepth+1);
411 ProcessNodeAdjacentNodes(c1[0]-c2[0],c1[1]-c2[1],c1[2]-c2[2],node1,(width1*w1)>>1,node2,(width2*w2)>>1,w2,F,processCurrent);
414 template<
class NodeData,
class Real>
415 template<
class NodeAdjacencyFunction>
419 NodeAdjacencyFunction* F,
int processCurrent){
420 if(!Overlap(dx,dy,dz,radius1+radius2)){
return;}
421 if(processCurrent){F->Function(node2,node1);}
423 __ProcessNodeAdjacentNodes(-dx,-dy,-dz,node1,radius1,node2,radius2,width2/2,F);
426 template<
class NodeData,
class Real>
427 template<
class TerminatingNodeAdjacencyFunction>
429 int c1[3],c2[3],w1,w2;
432 w1=node1->
width(maxDepth+1);
433 w2=node2->
width(maxDepth+1);
435 ProcessTerminatingNodeAdjacentNodes(c1[0]-c2[0],c1[1]-c2[1],c1[2]-c2[2],node1,(width1*w1)>>1,node2,(width2*w2)>>1,w2,F,processCurrent);
438 template<
class NodeData,
class Real>
439 template<
class TerminatingNodeAdjacencyFunction>
443 TerminatingNodeAdjacencyFunction* F,
int processCurrent)
445 if(!Overlap(dx,dy,dz,radius1+radius2)){
return;}
446 if(processCurrent){F->Function(node2,node1);}
448 __ProcessTerminatingNodeAdjacentNodes(-dx,-dy,-dz,node1,radius1,node2,radius2,width2/2,F);
451 template<
class NodeData,
class Real>
452 template<
class Po
intAdjacencyFunction>
457 w2 = node2->
width( maxDepth+1 );
458 ProcessPointAdjacentNodes( c1[0]-c2[0] , c1[1]-c2[1] , c1[2]-c2[2] , node2 , (width2*w2)>>1 , w2 , F , processCurrent );
461 template<
class NodeData,
class Real>
462 template<
class Po
intAdjacencyFunction>
465 PointAdjacencyFunction* F,
int processCurrent)
467 if( !Overlap(dx,dy,dz,radius2) )
return;
468 if( processCurrent ) F->Function(node2);
470 __ProcessPointAdjacentNodes( -dx , -dy , -dz , node2 , radius2 , width2>>1 , F );
473 template<
class NodeData,
class Real>
474 template<
class NodeAdjacencyFunction>
478 int depth,NodeAdjacencyFunction* F,
int processCurrent)
480 int c1[3],c2[3],w1,w2;
483 w1=node1->
width(maxDepth+1);
484 w2=node2->
width(maxDepth+1);
486 ProcessFixedDepthNodeAdjacentNodes(c1[0]-c2[0],c1[1]-c2[1],c1[2]-c2[2],node1,(width1*w1)>>1,node2,(width2*w2)>>1,w2,depth,F,processCurrent);
489 template<
class NodeData,
class Real>
490 template<
class NodeAdjacencyFunction>
494 int depth,NodeAdjacencyFunction* F,
int processCurrent)
496 int d=node2->
depth();
498 if(!Overlap(dx,dy,dz,radius1+radius2)){
return;}
499 if(d==depth){
if(processCurrent){F->Function(node2,node1);}}
502 __ProcessFixedDepthNodeAdjacentNodes(-dx,-dy,-dz,node1,radius1,node2,radius2,width2/2,depth-1,F);
506 template<
class NodeData,
class Real>
507 template<
class NodeAdjacencyFunction>
511 int depth,NodeAdjacencyFunction* F,
int processCurrent)
513 int c1[3],c2[3],w1,w2;
516 w1=node1->
width(maxDepth+1);
517 w2=node2->
width(maxDepth+1);
518 ProcessMaxDepthNodeAdjacentNodes(c1[0]-c2[0],c1[1]-c2[1],c1[2]-c2[2],node1,(width1*w1)>>1,node2,(width2*w2)>>1,w2,depth,F,processCurrent);
521 template<
class NodeData,
class Real>
522 template<
class NodeAdjacencyFunction>
526 int depth,NodeAdjacencyFunction* F,
int processCurrent)
528 int d=node2->
depth();
530 if(!Overlap(dx,dy,dz,radius1+radius2)){
return;}
531 if(processCurrent){F->Function(node2,node1);}
532 if(d<depth && node2->children){__ProcessMaxDepthNodeAdjacentNodes(-dx,-dy,-dz,node1,radius1,node2,radius2,width2>>1,depth-1,F);}
535 template <
class NodeData,
class Real>
536 template<
class NodeAdjacencyFunction>
539 OctNode* node2,
int radius2,
int cWidth2,
540 NodeAdjacencyFunction* F)
542 int cWidth=cWidth2>>1;
543 int radius=radius2>>1;
544 int o=ChildOverlap(dx,dy,dz,radius1+radius,cWidth);
552 if(o& 1){F->Function(&node2->
children[0],node1);
if(node2->
children[0].
children){__ProcessNodeAdjacentNodes(dx1,dy1,dz1,node1,radius1,&node2->
children[0],radius,cWidth,F);}}
553 if(o& 2){F->Function(&node2->
children[1],node1);
if(node2->
children[1].
children){__ProcessNodeAdjacentNodes(dx2,dy1,dz1,node1,radius1,&node2->
children[1],radius,cWidth,F);}}
554 if(o& 4){F->Function(&node2->
children[2],node1);
if(node2->
children[2].
children){__ProcessNodeAdjacentNodes(dx1,dy2,dz1,node1,radius1,&node2->
children[2],radius,cWidth,F);}}
555 if(o& 8){F->Function(&node2->
children[3],node1);
if(node2->
children[3].
children){__ProcessNodeAdjacentNodes(dx2,dy2,dz1,node1,radius1,&node2->
children[3],radius,cWidth,F);}}
556 if(o& 16){F->Function(&node2->
children[4],node1);
if(node2->
children[4].
children){__ProcessNodeAdjacentNodes(dx1,dy1,dz2,node1,radius1,&node2->
children[4],radius,cWidth,F);}}
557 if(o& 32){F->Function(&node2->
children[5],node1);
if(node2->
children[5].
children){__ProcessNodeAdjacentNodes(dx2,dy1,dz2,node1,radius1,&node2->
children[5],radius,cWidth,F);}}
558 if(o& 64){F->Function(&node2->
children[6],node1);
if(node2->
children[6].
children){__ProcessNodeAdjacentNodes(dx1,dy2,dz2,node1,radius1,&node2->
children[6],radius,cWidth,F);}}
559 if(o&128){F->Function(&node2->
children[7],node1);
if(node2->
children[7].
children){__ProcessNodeAdjacentNodes(dx2,dy2,dz2,node1,radius1,&node2->
children[7],radius,cWidth,F);}}
563 template <
class NodeData,
class Real>
564 template<
class TerminatingNodeAdjacencyFunction>
565 void OctNode<NodeData,Real>::__ProcessTerminatingNodeAdjacentNodes(
int dx,
int dy,
int dz,
566 OctNode* node1,
int radius1,
567 OctNode* node2,
int radius2,
int cWidth2,
568 TerminatingNodeAdjacencyFunction* F)
570 int cWidth=cWidth2>>1;
571 int radius=radius2>>1;
572 int o=ChildOverlap(dx,dy,dz,radius1+radius,cWidth);
580 if(o& 1){
if(F->Function(&node2->children[0],node1) && node2->children[0].children){__ProcessTerminatingNodeAdjacentNodes(dx1,dy1,dz1,node1,radius1,&node2->children[0],radius,cWidth,F);}}
581 if(o& 2){
if(F->Function(&node2->children[1],node1) && node2->children[1].children){__ProcessTerminatingNodeAdjacentNodes(dx2,dy1,dz1,node1,radius1,&node2->children[1],radius,cWidth,F);}}
582 if(o& 4){
if(F->Function(&node2->children[2],node1) && node2->children[2].children){__ProcessTerminatingNodeAdjacentNodes(dx1,dy2,dz1,node1,radius1,&node2->children[2],radius,cWidth,F);}}
583 if(o& 8){
if(F->Function(&node2->children[3],node1) && node2->children[3].children){__ProcessTerminatingNodeAdjacentNodes(dx2,dy2,dz1,node1,radius1,&node2->children[3],radius,cWidth,F);}}
584 if(o& 16){
if(F->Function(&node2->children[4],node1) && node2->children[4].children){__ProcessTerminatingNodeAdjacentNodes(dx1,dy1,dz2,node1,radius1,&node2->children[4],radius,cWidth,F);}}
585 if(o& 32){
if(F->Function(&node2->children[5],node1) && node2->children[5].children){__ProcessTerminatingNodeAdjacentNodes(dx2,dy1,dz2,node1,radius1,&node2->children[5],radius,cWidth,F);}}
586 if(o& 64){
if(F->Function(&node2->children[6],node1) && node2->children[6].children){__ProcessTerminatingNodeAdjacentNodes(dx1,dy2,dz2,node1,radius1,&node2->children[6],radius,cWidth,F);}}
587 if(o&128){
if(F->Function(&node2->children[7],node1) && node2->children[7].children){__ProcessTerminatingNodeAdjacentNodes(dx2,dy2,dz2,node1,radius1,&node2->children[7],radius,cWidth,F);}}
591 template <
class NodeData,
class Real>
592 template<
class Po
intAdjacencyFunction>
593 void OctNode<NodeData,Real>::__ProcessPointAdjacentNodes(
int dx,
int dy,
int dz,
594 OctNode* node2,
int radius2,
int cWidth2,
595 PointAdjacencyFunction* F)
597 int cWidth=cWidth2>>1;
598 int radius=radius2>>1;
599 int o=ChildOverlap(dx,dy,dz,radius,cWidth);
608 if(o& 1){F->Function(&node2->children[0]);
if(node2->children[0].children){__ProcessPointAdjacentNodes(dx1,dy1,dz1,&node2->children[0],radius,cWidth,F);}}
609 if(o& 2){F->Function(&node2->children[1]);
if(node2->children[1].children){__ProcessPointAdjacentNodes(dx2,dy1,dz1,&node2->children[1],radius,cWidth,F);}}
610 if(o& 4){F->Function(&node2->children[2]);
if(node2->children[2].children){__ProcessPointAdjacentNodes(dx1,dy2,dz1,&node2->children[2],radius,cWidth,F);}}
611 if(o& 8){F->Function(&node2->children[3]);
if(node2->children[3].children){__ProcessPointAdjacentNodes(dx2,dy2,dz1,&node2->children[3],radius,cWidth,F);}}
612 if(o& 16){F->Function(&node2->children[4]);
if(node2->children[4].children){__ProcessPointAdjacentNodes(dx1,dy1,dz2,&node2->children[4],radius,cWidth,F);}}
613 if(o& 32){F->Function(&node2->children[5]);
if(node2->children[5].children){__ProcessPointAdjacentNodes(dx2,dy1,dz2,&node2->children[5],radius,cWidth,F);}}
614 if(o& 64){F->Function(&node2->children[6]);
if(node2->children[6].children){__ProcessPointAdjacentNodes(dx1,dy2,dz2,&node2->children[6],radius,cWidth,F);}}
615 if(o&128){F->Function(&node2->children[7]);
if(node2->children[7].children){__ProcessPointAdjacentNodes(dx2,dy2,dz2,&node2->children[7],radius,cWidth,F);}}
619 template <
class NodeData,
class Real>
620 template<
class NodeAdjacencyFunction>
621 void OctNode<NodeData,Real>::__ProcessFixedDepthNodeAdjacentNodes(
int dx,
int dy,
int dz,
622 OctNode* node1,
int radius1,
623 OctNode* node2,
int radius2,
int cWidth2,
624 int depth,NodeAdjacencyFunction* F)
626 int cWidth=cWidth2>>1;
627 int radius=radius2>>1;
628 int o=ChildOverlap(dx,dy,dz,radius1+radius,cWidth);
636 if(node2->depth()==depth){
637 if(o& 1){F->Function(&node2->children[0],node1);}
638 if(o& 2){F->Function(&node2->children[1],node1);}
639 if(o& 4){F->Function(&node2->children[2],node1);}
640 if(o& 8){F->Function(&node2->children[3],node1);}
641 if(o& 16){F->Function(&node2->children[4],node1);}
642 if(o& 32){F->Function(&node2->children[5],node1);}
643 if(o& 64){F->Function(&node2->children[6],node1);}
644 if(o&128){F->Function(&node2->children[7],node1);}
647 if(o& 1){
if(node2->children[0].children){__ProcessFixedDepthNodeAdjacentNodes(dx1,dy1,dz1,node1,radius1,&node2->children[0],radius,cWidth,depth,F);}}
648 if(o& 2){
if(node2->children[1].children){__ProcessFixedDepthNodeAdjacentNodes(dx2,dy1,dz1,node1,radius1,&node2->children[1],radius,cWidth,depth,F);}}
649 if(o& 4){
if(node2->children[2].children){__ProcessFixedDepthNodeAdjacentNodes(dx1,dy2,dz1,node1,radius1,&node2->children[2],radius,cWidth,depth,F);}}
650 if(o& 8){
if(node2->children[3].children){__ProcessFixedDepthNodeAdjacentNodes(dx2,dy2,dz1,node1,radius1,&node2->children[3],radius,cWidth,depth,F);}}
651 if(o& 16){
if(node2->children[4].children){__ProcessFixedDepthNodeAdjacentNodes(dx1,dy1,dz2,node1,radius1,&node2->children[4],radius,cWidth,depth,F);}}
652 if(o& 32){
if(node2->children[5].children){__ProcessFixedDepthNodeAdjacentNodes(dx2,dy1,dz2,node1,radius1,&node2->children[5],radius,cWidth,depth,F);}}
653 if(o& 64){
if(node2->children[6].children){__ProcessFixedDepthNodeAdjacentNodes(dx1,dy2,dz2,node1,radius1,&node2->children[6],radius,cWidth,depth,F);}}
654 if(o&128){
if(node2->children[7].children){__ProcessFixedDepthNodeAdjacentNodes(dx2,dy2,dz2,node1,radius1,&node2->children[7],radius,cWidth,depth,F);}}
659 template <
class NodeData,
class Real>
660 template<
class NodeAdjacencyFunction>
661 void OctNode<NodeData,Real>::__ProcessMaxDepthNodeAdjacentNodes(
int dx,
int dy,
int dz,
662 OctNode* node1,
int radius1,
663 OctNode* node2,
int radius2,
int cWidth2,
664 int depth,NodeAdjacencyFunction* F)
666 int cWidth=cWidth2>>1;
667 int radius=radius2>>1;
668 int o=ChildOverlap(dx,dy,dz,radius1+radius,cWidth);
676 if(node2->depth()<=depth){
677 if(o& 1){F->Function(&node2->children[0],node1);}
678 if(o& 2){F->Function(&node2->children[1],node1);}
679 if(o& 4){F->Function(&node2->children[2],node1);}
680 if(o& 8){F->Function(&node2->children[3],node1);}
681 if(o& 16){F->Function(&node2->children[4],node1);}
682 if(o& 32){F->Function(&node2->children[5],node1);}
683 if(o& 64){F->Function(&node2->children[6],node1);}
684 if(o&128){F->Function(&node2->children[7],node1);}
686 if(node2->depth()<depth){
687 if(o& 1){
if(node2->children[0].children){__ProcessMaxDepthNodeAdjacentNodes(dx1,dy1,dz1,node1,radius1,&node2->children[0],radius,cWidth,depth,F);}}
688 if(o& 2){
if(node2->children[1].children){__ProcessMaxDepthNodeAdjacentNodes(dx2,dy1,dz1,node1,radius1,&node2->children[1],radius,cWidth,depth,F);}}
689 if(o& 4){
if(node2->children[2].children){__ProcessMaxDepthNodeAdjacentNodes(dx1,dy2,dz1,node1,radius1,&node2->children[2],radius,cWidth,depth,F);}}
690 if(o& 8){
if(node2->children[3].children){__ProcessMaxDepthNodeAdjacentNodes(dx2,dy2,dz1,node1,radius1,&node2->children[3],radius,cWidth,depth,F);}}
691 if(o& 16){
if(node2->children[4].children){__ProcessMaxDepthNodeAdjacentNodes(dx1,dy1,dz2,node1,radius1,&node2->children[4],radius,cWidth,depth,F);}}
692 if(o& 32){
if(node2->children[5].children){__ProcessMaxDepthNodeAdjacentNodes(dx2,dy1,dz2,node1,radius1,&node2->children[5],radius,cWidth,depth,F);}}
693 if(o& 64){
if(node2->children[6].children){__ProcessMaxDepthNodeAdjacentNodes(dx1,dy2,dz2,node1,radius1,&node2->children[6],radius,cWidth,depth,F);}}
694 if(o&128){
if(node2->children[7].children){__ProcessMaxDepthNodeAdjacentNodes(dx2,dy2,dz2,node1,radius1,&node2->children[7],radius,cWidth,depth,F);}}
699 template <
class NodeData,
class Real>
700 inline int OctNode<NodeData,Real>::ChildOverlap(
int dx,
int dy,
int dz,
int d,
int cRadius2)
707 if(dx<w2 && dx>-w1){test =1;}
708 if(dx<w1 && dx>-w2){test|=2;}
711 if(dz<w2 && dz>-w1){test1 =test;}
712 if(dz<w1 && dz>-w2){test1|=test<<4;}
714 if(!test1){
return 0;}
715 if(dy<w2 && dy>-w1){overlap =test1;}
716 if(dy<w1 && dy>-w2){overlap|=test1<<2;}
720 template <
class NodeData,
class Real>
726 if(!children){
return this;}
727 centerAndWidth(center,width);
730 cIndex=CornerIndex(center,p);
733 if(cIndex&1){center.
coords[0]+=width/2;}
734 else {center.
coords[0]-=width/2;}
735 if(cIndex&2){center.
coords[1]+=width/2;}
736 else {center.
coords[1]-=width/2;}
737 if(cIndex&4){center.
coords[2]+=width/2;}
738 else {center.
coords[2]-=width/2;}
743 template <
class NodeData,
class Real>
747 if(!children){
return this;}
751 children[i].centerAndWidth(child_center, child_width);
753 if(!i || temp<dist2){
758 return children[nearest].getNearestLeaf(p);
761 template <
class NodeData,
class Real>
763 int o1,o2,i1,i2,j1,j2;
767 if(o1!=o2){
return 0;}
773 case 0: dir[0]=1; dir[1]=2;
break;
774 case 1: dir[0]=0; dir[1]=2;
break;
775 case 2: dir[0]=0; dir[1]=1;
break;
777 int d1,d2,off1[3],off2[3];
780 idx1[0]=off1[dir[0]]+(1<<d1)+i1;
781 idx1[1]=off1[dir[1]]+(1<<d1)+j1;
782 idx2[0]=off2[dir[0]]+(1<<d2)+i2;
783 idx2[1]=off2[dir[1]]+(1<<d2)+j2;
792 if(idx1[0]==idx2[0] && idx1[1]==idx2[1]){
return 1;}
796 template<
class NodeData,
class Real>
805 template <
class NodeData,
class Real>
806 template<
class NodeData2>
813 for(i=0;i<DIMENSION;i++){this->off[i] = node.
off[i];}
821 template <
class NodeData,
class Real>
826 template<
class NodeData ,
class Real >
831 if( n1->
d!=n2->
d )
return int(n1->
d)-int(n2->
d);
832 else if( n1->
off[0]!=n2->
off[0] )
return int(n1->
off[0]) - int(n2->
off[0]);
833 else if( n1->
off[1]!=n2->
off[1] )
return int(n1->
off[1]) - int(n2->
off[1]);
834 else if( n1->
off[2]!=n2->
off[2] )
return int(n1->
off[2]) - int(n2->
off[2]);
841 long long _p[3] = {p[0],p[1],p[2]};
842 for(
int i=0 ; i<31 ; i++ ) key |= ( ( _p[0] & (1ull<<i) )<<(2*i) ) | ( ( _p[1] & (1ull<<i) )<<(2*i+1) ) | ( ( _p[2] & (1ull<<i) )<<(2*i+2) );
846 template <
class NodeData,
class Real>
851 int d1 , off1[3] , d2 , off2[3];
853 if ( d1>d2 )
return 1;
854 else if( d1<d2 )
return -1;
856 if ( k1>k2 )
return 1;
857 else if( k1<k2 )
return -1;
861 template <
class NodeData,
class Real>
866 if(n1->
d!=n2->
d){
return int(n1->
d)-int(n2->
d);}
872 if(n1->
off[0]!=n2->
off[0]){
return int(n1->
off[0])-int(n2->
off[0]);}
873 if(n1->
off[1]!=n2->
off[1]){
return int(n1->
off[1])-int(n2->
off[1]);}
874 return int(n1->
off[2])-int(n2->
off[2]);
878 template <
class NodeData,
class Real>
883 template <
class NodeData,
class Real>
888 template <
class NodeData,
class Real>
891 Real w=multiplier2+multiplier1*(1<<d);
894 fabs(
Real(offSet2[0]-(offSet1[0]<<d))-w2)>=w ||
895 fabs(
Real(offSet2[1]-(offSet1[1]<<d))-w2)>=w ||
896 fabs(
Real(offSet2[2]-(offSet1[2]<<d))-w2)>=w
901 template <
class NodeData,
class Real>
903 if(c1>=dWidth || c1<=-dWidth || c2>=dWidth || c2<=-dWidth || c3>=dWidth || c3<=-dWidth){
return 0;}
907 template <
class NodeData,
class Real>
909 template <
class NodeData,
class Real>
911 template <
class NodeData,
class Real>
913 if(!parent){
return NULL;}
914 int pIndex=int(
this-(parent->children));
916 if((pIndex & (1<<dir))==(off<<dir)){
return &parent->children[pIndex];}
918 OctNode* temp=parent->__faceNeighbor(dir,off,forceChildren);
919 if(!temp){
return NULL;}
924 return &temp->children[pIndex];
928 template <
class NodeData,
class Real>
929 const OctNode<NodeData,Real>* OctNode<NodeData,Real>::__faceNeighbor(
int dir,
int off)
const {
930 if(!parent){
return NULL;}
931 int pIndex=int(
this-(parent->children));
933 if((pIndex & (1<<dir))==(off<<dir)){
return &parent->children[pIndex];}
935 const OctNode* temp=parent->__faceNeighbor(dir,off);
936 if(!temp || !temp->children){
return temp;}
937 else{
return &temp->children[pIndex];}
941 template <
class NodeData,
class Real>
946 case 0: idx[0]=1; idx[1]=2;
break;
947 case 1: idx[0]=0; idx[1]=2;
break;
948 case 2: idx[0]=0; idx[1]=1;
break;
950 return __edgeNeighbor(o,i,idx,forceChildren);
953 template <
class NodeData,
class Real>
958 case 0: idx[0]=1; idx[1]=2;
break;
959 case 1: idx[0]=0; idx[1]=2;
break;
960 case 2: idx[0]=0; idx[1]=1;
break;
962 return __edgeNeighbor(o,i,idx);
965 template <
class NodeData,
class Real>
967 if(!parent){
return NULL;}
968 int pIndex=int(
this-(parent->children));
969 int aIndex,x[DIMENSION];
972 aIndex=(~((i[0] ^ x[idx[0]]) | ((i[1] ^ x[idx[1]])<<1))) & 3;
973 pIndex^=(7 ^ (1<<o));
975 const OctNode* temp=parent->__faceNeighbor(idx[0],i[0]);
976 if(!temp || !temp->children){
return NULL;}
977 else{
return &temp->children[pIndex];}
980 const OctNode* temp=parent->__faceNeighbor(idx[1],i[1]);
981 if(!temp || !temp->children){
return NULL;}
982 else{
return &temp->children[pIndex];}
985 return &parent->children[pIndex];
988 const OctNode* temp=parent->__edgeNeighbor(o,i,idx);
989 if(!temp || !temp->children){
return temp;}
990 else{
return &temp->children[pIndex];}
995 template <
class NodeData,
class Real>
996 OctNode<NodeData,Real>* OctNode<NodeData,Real>::__edgeNeighbor(
int o,
const int i[2],
const int idx[2],
int forceChildren){
997 if(!parent){
return NULL;}
998 int pIndex=int(
this-(parent->children));
999 int aIndex,x[DIMENSION];
1002 aIndex=(~((i[0] ^ x[idx[0]]) | ((i[1] ^ x[idx[1]])<<1))) & 3;
1003 pIndex^=(7 ^ (1<<o));
1005 OctNode* temp=parent->__faceNeighbor(idx[0],i[0],0);
1006 if(!temp || !temp->children){
return NULL;}
1007 else{
return &temp->children[pIndex];}
1009 else if(aIndex==2) {
1010 OctNode* temp=parent->__faceNeighbor(idx[1],i[1],0);
1011 if(!temp || !temp->children){
return NULL;}
1012 else{
return &temp->children[pIndex];}
1014 else if(aIndex==0) {
1015 return &parent->children[pIndex];
1017 else if(aIndex==3) {
1018 OctNode* temp=parent->__edgeNeighbor(o,i,idx,forceChildren);
1019 if(!temp){
return NULL;}
1020 if(!temp->children){
1021 if(forceChildren){temp->initChildren();}
1024 return &temp->children[pIndex];
1029 template <
class NodeData,
class Real>
1031 int pIndex,aIndex=0;
1032 if(!parent){
return NULL;}
1034 pIndex=int(
this-(parent->children));
1035 aIndex=(cornerIndex ^ pIndex);
1038 return &parent->children[pIndex];
1042 if(!temp || !temp->
children){
return temp;}
1043 else{
return &temp->
children[pIndex];}
1046 const OctNode* temp=((
const OctNode*)parent)->__faceNeighbor(0,cornerIndex & 1);
1047 if(!temp || !temp->
children){
return NULL;}
1048 else{
return & temp->
children[pIndex];}
1051 const OctNode* temp=((
const OctNode*)parent)->__faceNeighbor(1,(cornerIndex & 2)>>1);
1052 if(!temp || !temp->
children){
return NULL;}
1053 else{
return & temp->
children[pIndex];}
1056 const OctNode* temp=((
const OctNode*)parent)->__faceNeighbor(2,(cornerIndex & 4)>>2);
1057 if(!temp || !temp->
children){
return NULL;}
1058 else{
return & temp->
children[pIndex];}
1062 if(!temp || !temp->
children){
return NULL;}
1063 else{
return & temp->
children[pIndex];}
1067 if(!temp || !temp->
children){
return NULL;}
1068 else{
return & temp->
children[pIndex];}
1072 if(!temp || !temp->
children){
return NULL;}
1073 else{
return & temp->
children[pIndex];}
1078 template <
class NodeData,
class Real>
1080 int pIndex,aIndex=0;
1081 if(!parent){
return NULL;}
1083 pIndex=int(
this-(parent->children));
1084 aIndex=(cornerIndex ^ pIndex);
1087 return &parent->children[pIndex];
1091 if(!temp){
return NULL;}
1099 OctNode* temp=((
OctNode*)parent)->__faceNeighbor(0,cornerIndex & 1,0);
1100 if(!temp || !temp->
children){
return NULL;}
1101 else{
return & temp->
children[pIndex];}
1104 OctNode* temp=((
OctNode*)parent)->__faceNeighbor(1,(cornerIndex & 2)>>1,0);
1105 if(!temp || !temp->
children){
return NULL;}
1106 else{
return & temp->
children[pIndex];}
1109 OctNode* temp=((
OctNode*)parent)->__faceNeighbor(2,(cornerIndex & 4)>>2,0);
1110 if(!temp || !temp->
children){
return NULL;}
1111 else{
return & temp->
children[pIndex];}
1115 if(!temp || !temp->
children){
return NULL;}
1116 else{
return & temp->
children[pIndex];}
1120 if(!temp || !temp->
children){
return NULL;}
1121 else{
return & temp->
children[pIndex];}
1125 if(!temp || !temp->
children){
return NULL;}
1126 else{
return & temp->
children[pIndex];}
1134 template<
class NodeData,
class Real>
1137 template<
class NodeData,
class Real>
1139 for(
int i=0;i<3;i++){
for(
int j=0;j<3;j++){
for(
int k=0;k<3;k++){neighbors[i][j][k]=NULL;}}}
1142 template<
class NodeData,
class Real>
1145 template<
class NodeData,
class Real>
1152 template<
class NodeData,
class Real>
1161 template<
class NodeData ,
class Real >
1164 if( !neighbors[
d].neighbors[1][1][1] || !neighbors[
d].neighbors[1][1][1]->
isInside( p ) )
1168 if( !
d ) neighbors[
d].neighbors[1][1][1] =
root;
1173 int i , j , k , x1 , y1 , z1 , x2 , y2 , z2;
1182 for( i=0 ; i<2 ; i++ )
for( j=0 ; j<2 ; j++ )
for( k=0 ; k<2 ; k++ )
1227 i=x1<<1 , j=y1<<1 , k=z1<<1;
1235 return neighbors[
d];
1238 template<
class NodeData ,
class Real >
1241 if( !neighbors[
d].neighbors[1][1][1] || !neighbors[
d].neighbors[1][1][1]->
isInside( p ) )
1245 if( !
d ) neighbors[
d].neighbors[1][1][1] =
root;
1248 Neighbors3& temp = getNeighbors(
root , p ,
d-1 );
1250 int i , j , k , x1 , y1 , z1 , x2 , y2 , z2;
1253 temp.neighbors[1][1][1]->centerAndWidth( c , w );
1258 if( !temp.neighbors[1][1][1] || !temp.neighbors[1][1][1]->children )
1262 for( i=0 ; i<2 ; i++ )
for( j=0 ; j<2 ; j++ )
for( k=0 ; k<2 ; k++ )
1263 neighbors[
d].neighbors[x2+i][y2+j][z2+k] = &temp.neighbors[1][1][1]->children[
Cube::CornerIndex(i,j,k)];
1268 if( temp.neighbors[i][1][1] )
1269 for( j=0 ; j<2 ; j++ )
for( k=0 ; k<2 ; k++ ) neighbors[
d].neighbors[i][y2+j][z2+k] = &temp.neighbors[i][1][1]->children[
Cube::CornerIndex(x2,j,k)];
1271 if( temp.neighbors[1][j][1] )
1272 for( i=0 ; i<2 ; i++ )
for( k=0 ; k<2 ; k++ ) neighbors[
d].neighbors[x2+i][j][z2+k] = &temp.neighbors[1][j][1]->children[
Cube::CornerIndex(i,y2,k)];
1274 if( temp.neighbors[1][1][k] )
1275 for( i=0 ; i<2 ; i++ )
for( j=0 ; j<2 ; j++ ) neighbors[
d].neighbors[x2+i][y2+j][k] = &temp.neighbors[1][1][k]->children[
Cube::CornerIndex(i,j,z2)];
1279 if( temp.neighbors[i][j][1] )
1280 for( k=0 ; k<2 ; k++ ) neighbors[
d].neighbors[i][j][z2+k] = &temp.neighbors[i][j][1]->children[
Cube::CornerIndex(x2,y2,k)];
1282 if( temp.neighbors[i][1][k] )
1283 for( j=0 ; j<2 ; j++ ) neighbors[
d].neighbors[i][y2+j][k] = &temp.neighbors[i][1][k]->children[
Cube::CornerIndex(x2,j,z2)];
1285 if( temp.neighbors[1][j][k] )
1286 for( i=0 ; i<2 ; i++ ) neighbors[
d].neighbors[x2+i][j][k] = &temp.neighbors[1][j][k]->children[
Cube::CornerIndex(i,y2,z2)];
1289 i=x1<<1 , j=y1<<1 , k=z1<<1;
1290 if( temp.neighbors[i][j][k] )
1291 neighbors[
d].neighbors[i][j][k] = &temp.neighbors[i][j][k]->children[
Cube::CornerIndex(x2,y2,z2)];
1294 return neighbors[
d];
1297 template<
class NodeData ,
class Real >
1300 int d = node->depth();
1301 if( node==neighbors[
d].neighbors[1][1][1] )
1304 for(
int i=0 ; i<3 ; i++ )
for(
int j=0 ; j<3 ; j++ )
for(
int k=0 ; k<3 ; k++ )
if( !neighbors[
d].neighbors[i][j][k] ) reset =
true;
1305 if( reset ) neighbors[
d].neighbors[1][1][1] = NULL;
1307 if( node!=neighbors[
d].neighbors[1][1][1] )
1309 neighbors[
d].clear();
1311 if( !node->parent ) neighbors[
d].neighbors[1][1][1] = node;
1314 int i,j,k,x1,y1,z1,x2,y2,z2;
1315 int idx=int(node-node->parent->children);
1321 neighbors[
d].neighbors[x2+i][y2+j][z2+k]=&node->parent->children[
Cube::CornerIndex(i,j,k)];
1325 Neighbors3& temp=setNeighbors(node->parent);
1329 if(temp.neighbors[i][1][1]){
1330 if(!temp.neighbors[i][1][1]->children){temp.neighbors[i][1][1]->initChildren();}
1331 for(j=0;j<2;j++){
for(k=0;k<2;k++){neighbors[
d].neighbors[i][y2+j][z2+k]=&temp.neighbors[i][1][1]->children[
Cube::CornerIndex(x2,j,k)];}}
1334 if(temp.neighbors[1][j][1]){
1335 if(!temp.neighbors[1][j][1]->children){temp.neighbors[1][j][1]->initChildren();}
1336 for(i=0;i<2;i++){
for(k=0;k<2;k++){neighbors[
d].neighbors[x2+i][j][z2+k]=&temp.neighbors[1][j][1]->children[
Cube::CornerIndex(i,y2,k)];}}
1339 if(temp.neighbors[1][1][k]){
1340 if(!temp.neighbors[1][1][k]->children){temp.neighbors[1][1][k]->initChildren();}
1341 for(i=0;i<2;i++){
for(j=0;j<2;j++){neighbors[
d].neighbors[x2+i][y2+j][k]=&temp.neighbors[1][1][k]->children[
Cube::CornerIndex(i,j,z2)];}}
1346 if(temp.neighbors[i][j][1]){
1347 if(!temp.neighbors[i][j][1]->children){temp.neighbors[i][j][1]->initChildren();}
1348 for(k=0;k<2;k++){neighbors[
d].neighbors[i][j][z2+k]=&temp.neighbors[i][j][1]->children[
Cube::CornerIndex(x2,y2,k)];}
1351 if(temp.neighbors[i][1][k]){
1352 if(!temp.neighbors[i][1][k]->children){temp.neighbors[i][1][k]->initChildren();}
1353 for(j=0;j<2;j++){neighbors[
d].neighbors[i][y2+j][k]=&temp.neighbors[i][1][k]->children[
Cube::CornerIndex(x2,j,z2)];}
1356 if(temp.neighbors[1][j][k]){
1357 if(!temp.neighbors[1][j][k]->children){temp.neighbors[1][j][k]->initChildren();}
1358 for(i=0;i<2;i++){neighbors[
d].neighbors[x2+i][j][k]=&temp.neighbors[1][j][k]->children[
Cube::CornerIndex(i,y2,z2)];}
1362 i=x1<<1; j=y1<<1; k=z1<<1;
1363 if(temp.neighbors[i][j][k]){
1364 if(!temp.neighbors[i][j][k]->children){temp.neighbors[i][j][k]->initChildren();}
1365 neighbors[
d].neighbors[i][j][k]=&temp.neighbors[i][j][k]->children[
Cube::CornerIndex(x2,y2,z2)];
1369 return neighbors[
d];
1374 template<
class NodeData ,
class Real >
1377 int d = node->depth();
1378 if( node==neighbors[
d].neighbors[1][1][1] )
1381 for(
int i=0 ; i<3 ; i++ )
for(
int j=0 ; j<3 ; j++ )
for(
int k=0 ; k<3 ; k++ )
if( flags[i][j][k] && !neighbors[
d].neighbors[i][j][k] ) reset =
true;
1382 if( reset ) neighbors[
d].neighbors[1][1][1] = NULL;
1384 if( node!=neighbors[
d].neighbors[1][1][1] )
1386 neighbors[
d].clear();
1388 if( !node->parent ) neighbors[
d].neighbors[1][1][1] = node;
1391 int x1,y1,z1,x2,y2,z2;
1392 int idx=int(node-node->parent->children);
1395 for(
int i=0 ; i<2 ; i++ )
1396 for(
int j=0 ; j<2 ; j++ )
1397 for(
int k=0 ; k<2 ; k++ )
1398 neighbors[
d].neighbors[x2+i][y2+j][z2+k]=&node->parent->children[
Cube::CornerIndex(i,j,k)];
1400 Neighbors3& temp=setNeighbors( node->parent , flags );
1405 if( temp.neighbors[i][1][1] )
1407 if( flags[i][1][1] && !temp.neighbors[i][1][1]->children ) temp.neighbors[i][1][1]->initChildren();
1408 if( temp.neighbors[i][1][1]->children )
for(
int j=0 ; j<2 ; j++ )
for(
int k=0 ; k<2 ; k++ ) neighbors[
d].neighbors[i][y2+j][z2+k] = &temp.neighbors[i][1][1]->children[
Cube::CornerIndex(x2,j,k)];
1413 if( temp.neighbors[1][j][1] )
1415 if( flags[1][j][1] && !temp.neighbors[1][j][1]->children ) temp.neighbors[1][j][1]->initChildren();
1416 if( temp.neighbors[1][j][1]->children )
for(
int i=0 ; i<2 ; i++ )
for(
int k=0 ; k<2 ; k++ ) neighbors[
d].neighbors[x2+i][j][z2+k] = &temp.neighbors[1][j][1]->children[
Cube::CornerIndex(i,y2,k)];
1421 if( temp.neighbors[1][1][k] )
1423 if( flags[1][1][k] && !temp.neighbors[1][1][k]->children ) temp.neighbors[1][1][k]->initChildren();
1424 if( temp.neighbors[1][1][k]->children )
for(
int i=0 ; i<2 ; i++ )
for(
int j=0 ; j<2 ; j++ ) neighbors[
d].neighbors[x2+i][y2+j][k] = &temp.neighbors[1][1][k]->children[
Cube::CornerIndex(i,j,z2)];
1430 int i=x1<<1 , j=y1<<1;
1431 if( temp.neighbors[i][j][1] )
1433 if( flags[i][j][1] && !temp.neighbors[i][j][1]->children ) temp.neighbors[i][j][1]->initChildren();
1434 if( temp.neighbors[i][j][1]->children )
for(
int k=0 ; k<2 ; k++ ) neighbors[
d].neighbors[i][j][z2+k] = &temp.neighbors[i][j][1]->children[
Cube::CornerIndex(x2,y2,k)];
1438 int i=x1<<1 , k=z1<<1;
1439 if( temp.neighbors[i][1][k] )
1441 if( flags[i][1][k] && !temp.neighbors[i][1][k]->children ) temp.neighbors[i][1][k]->initChildren();
1442 if( temp.neighbors[i][1][k]->children )
for(
int j=0 ; j<2 ; j++ ) neighbors[
d].neighbors[i][y2+j][k] = &temp.neighbors[i][1][k]->children[
Cube::CornerIndex(x2,j,z2)];
1446 int j=y1<<1 , k=z1<<1;
1447 if( temp.neighbors[1][j][k] )
1449 if( flags[1][j][k] && !temp.neighbors[1][j][k]->children ) temp.neighbors[1][j][k]->initChildren();
1450 if( temp.neighbors[1][j][k]->children )
for(
int i=0 ; i<2 ; i++ ) neighbors[
d].neighbors[x2+i][j][k] = &temp.neighbors[1][j][k]->children[
Cube::CornerIndex(i,y2,z2)];
1456 int i=x1<<1 , j=y1<<1 , k=z1<<1;
1457 if( temp.neighbors[i][j][k] )
1459 if( flags[i][j][k] && !temp.neighbors[i][j][k]->children ) temp.neighbors[i][j][k]->initChildren();
1460 if( temp.neighbors[i][j][k]->children ) neighbors[
d].neighbors[i][j][k] = &temp.neighbors[i][j][k]->children[
Cube::CornerIndex(x2,y2,z2)];
1465 return neighbors[
d];
1468 template<
class NodeData,
class Real>
1470 int d=node->depth();
1471 if(node!=neighbors[
d].neighbors[1][1][1]){
1472 neighbors[
d].clear();
1474 if(!node->parent){neighbors[
d].neighbors[1][1][1]=node;}
1476 int i,j,k,x1,y1,z1,x2,y2,z2;
1477 int idx=int(node-node->parent->children);
1483 neighbors[
d].neighbors[x2+i][y2+j][z2+k]=&node->parent->children[
Cube::CornerIndex(i,j,k)];
1487 Neighbors3& temp=getNeighbors(node->parent);
1491 if(temp.neighbors[i][1][1] && temp.neighbors[i][1][1]->children){
1492 for(j=0;j<2;j++){
for(k=0;k<2;k++){neighbors[
d].neighbors[i][y2+j][z2+k]=&temp.neighbors[i][1][1]->children[
Cube::CornerIndex(x2,j,k)];}}
1495 if(temp.neighbors[1][j][1] && temp.neighbors[1][j][1]->children){
1496 for(i=0;i<2;i++){
for(k=0;k<2;k++){neighbors[
d].neighbors[x2+i][j][z2+k]=&temp.neighbors[1][j][1]->children[
Cube::CornerIndex(i,y2,k)];}}
1499 if(temp.neighbors[1][1][k] && temp.neighbors[1][1][k]->children){
1500 for(i=0;i<2;i++){
for(j=0;j<2;j++){neighbors[
d].neighbors[x2+i][y2+j][k]=&temp.neighbors[1][1][k]->children[
Cube::CornerIndex(i,j,z2)];}}
1505 if(temp.neighbors[i][j][1] && temp.neighbors[i][j][1]->children){
1506 for(k=0;k<2;k++){neighbors[
d].neighbors[i][j][z2+k]=&temp.neighbors[i][j][1]->children[
Cube::CornerIndex(x2,y2,k)];}
1509 if(temp.neighbors[i][1][k] && temp.neighbors[i][1][k]->children){
1510 for(j=0;j<2;j++){neighbors[
d].neighbors[i][y2+j][k]=&temp.neighbors[i][1][k]->children[
Cube::CornerIndex(x2,j,z2)];}
1513 if(temp.neighbors[1][j][k] && temp.neighbors[1][j][k]->children){
1514 for(i=0;i<2;i++){neighbors[
d].neighbors[x2+i][j][k]=&temp.neighbors[1][j][k]->children[
Cube::CornerIndex(i,y2,z2)];}
1518 i=x1<<1; j=y1<<1; k=z1<<1;
1519 if(temp.neighbors[i][j][k] && temp.neighbors[i][j][k]->children){
1520 neighbors[
d].neighbors[i][j][k]=&temp.neighbors[i][j][k]->children[
Cube::CornerIndex(x2,y2,z2)];
1524 return neighbors[node->depth()];
1530 template<
class NodeData,
class Real>
1533 template<
class NodeData,
class Real>
1535 for(
int i=0;i<3;i++){
for(
int j=0;j<3;j++){
for(
int k=0;k<3;k++){neighbors[i][j][k]=NULL;}}}
1538 template<
class NodeData,
class Real>
1541 template<
class NodeData,
class Real>
1547 template<
class NodeData,
class Real>
1555 template<
class NodeData,
class Real>
1558 if(node!=neighbors[
d].neighbors[1][1][1]){
1559 neighbors[
d].clear();
1561 if(!node->
parent){neighbors[
d].neighbors[1][1][1]=node;}
1563 int i,j,k,x1,y1,z1,x2,y2,z2;
1574 ConstNeighbors3& temp=getNeighbors(node->
parent);
1578 if(temp.neighbors[i][1][1] && temp.neighbors[i][1][1]->children){
1579 for(j=0;j<2;j++){
for(k=0;k<2;k++){neighbors[
d].neighbors[i][y2+j][z2+k]=&temp.neighbors[i][1][1]->children[
Cube::CornerIndex(x2,j,k)];}}
1582 if(temp.neighbors[1][j][1] && temp.neighbors[1][j][1]->children){
1583 for(i=0;i<2;i++){
for(k=0;k<2;k++){neighbors[
d].neighbors[x2+i][j][z2+k]=&temp.neighbors[1][j][1]->children[
Cube::CornerIndex(i,y2,k)];}}
1586 if(temp.neighbors[1][1][k] && temp.neighbors[1][1][k]->children){
1587 for(i=0;i<2;i++){
for(j=0;j<2;j++){neighbors[
d].neighbors[x2+i][y2+j][k]=&temp.neighbors[1][1][k]->children[
Cube::CornerIndex(i,j,z2)];}}
1592 if(temp.neighbors[i][j][1] && temp.neighbors[i][j][1]->children){
1593 for(k=0;k<2;k++){neighbors[
d].neighbors[i][j][z2+k]=&temp.neighbors[i][j][1]->children[
Cube::CornerIndex(x2,y2,k)];}
1596 if(temp.neighbors[i][1][k] && temp.neighbors[i][1][k]->children){
1597 for(j=0;j<2;j++){neighbors[
d].neighbors[i][y2+j][k]=&temp.neighbors[i][1][k]->children[
Cube::CornerIndex(x2,j,z2)];}
1600 if(temp.neighbors[1][j][k] && temp.neighbors[1][j][k]->children){
1601 for(i=0;i<2;i++){neighbors[
d].neighbors[x2+i][j][k]=&temp.neighbors[1][j][k]->children[
Cube::CornerIndex(i,y2,z2)];}
1605 i=x1<<1; j=y1<<1; k=z1<<1;
1606 if(temp.neighbors[i][j][k] && temp.neighbors[i][j][k]->children){
1607 neighbors[
d].neighbors[i][j][k]=&temp.neighbors[i][j][k]->children[
Cube::CornerIndex(x2,y2,z2)];
1611 return neighbors[node->
depth()];
1614 template<
class NodeData,
class Real>
1617 int d=node->depth();
1622 if( node!=neighbors[
d].neighbors[1][1][1] )
1624 neighbors[
d].clear();
1626 if(
d==minDepth ) neighbors[
d].neighbors[1][1][1]=node;
1629 int i,j,k,x1,y1,z1,x2,y2,z2;
1630 int idx = int(node-node->parent->children);
1634 ConstNeighbors3& temp=getNeighbors( node->parent , minDepth );
1637 for( i=0 ; i<2 ; i++ )
for( j=0 ; j<2 ; j++ )
for( k=0 ; k<2 ; k++ )
1638 neighbors[
d].neighbors[x2+i][y2+j][z2+k] = &node->parent->children[
Cube::CornerIndex(i,j,k) ];
1642 if( temp.neighbors[i][1][1] && temp.neighbors[i][1][1]->children )
1643 for( j=0 ; j<2 ; j++ )
for( k=0 ; k<2 ; k++ ) neighbors[
d].neighbors[i][y2+j][z2+k] = &temp.neighbors[i][1][1]->children[
Cube::CornerIndex(x2,j,k)];
1646 if( temp.neighbors[1][j][1] && temp.neighbors[1][j][1]->children )
1647 for( i=0 ; i<2 ; i++ )
for( k=0 ; k<2 ; k++ ) neighbors[
d].neighbors[x2+i][j][z2+k] = &temp.neighbors[1][j][1]->children[
Cube::CornerIndex(i,y2,k)];
1650 if( temp.neighbors[1][1][k] && temp.neighbors[1][1][k]->children )
1651 for( i=0 ; i<2 ; i++ )
for( j=0 ; j<2 ; j++ ) neighbors[
d].neighbors[x2+i][y2+j][k] = &temp.neighbors[1][1][k]->children[
Cube::CornerIndex(i,j,z2)];
1655 if( temp.neighbors[i][j][1] && temp.neighbors[i][j][1]->children )
1656 for( k=0 ; k<2 ; k++ ) neighbors[
d].neighbors[i][j][z2+k] = &temp.neighbors[i][j][1]->children[
Cube::CornerIndex(x2,y2,k)];
1659 if( temp.neighbors[i][1][k] && temp.neighbors[i][1][k]->children )
1660 for( j=0 ; j<2 ; j++ ) neighbors[
d].neighbors[i][y2+j][k] = &temp.neighbors[i][1][k]->children[
Cube::CornerIndex(x2,j,z2)];
1663 if( temp.neighbors[1][j][k] && temp.neighbors[1][j][k]->children )
1664 for( i=0 ; i<2 ; i++ ) neighbors[
d].neighbors[x2+i][j][k] = &temp.neighbors[1][j][k]->children[
Cube::CornerIndex(i,y2,z2)];
1667 i=x1<<1 , j=y1<<1 , k=z1<<1;
1668 if( temp.neighbors[i][j][k] && temp.neighbors[i][j][k]->children )
1669 neighbors[
d].neighbors[i][j][k] = &temp.neighbors[i][j][k]->children[
Cube::CornerIndex(x2,y2,z2)];
1672 return neighbors[node->depth()];
1679 template<
class NodeData ,
class Real >
1682 for(
int i=0 ; i<5 ; i++ )
for(
int j=0 ; j<5 ; j++ )
for(
int k=0 ; k<5 ; k++ ) neighbors[i][j][k] = NULL;
1685 template<
class NodeData ,
class Real >
1688 for(
int i=0 ; i<5 ; i++ )
for(
int j=0 ; j<5 ; j++ )
for(
int k=0 ; k<5 ; k++ ) neighbors[i][j][k] = NULL;
1691 template<
class NodeData ,
class Real >
1698 template<
class NodeData ,
class Real >
1705 template<
class NodeData ,
class Real >
1712 template<
class NodeData ,
class Real >
1719 template<
class NodeData ,
class Real >
1729 template<
class NodeData ,
class Real >
1739 template<
class NodeData ,
class Real >
1743 if( node!=neighbors[
d].neighbors[2][2][2] )
1745 neighbors[
d].clear();
1747 if( !node->
parent ) neighbors[
d].neighbors[2][2][2]=node;
1750 getNeighbors( node->
parent );
1752 int x1 , y1 , z1 , x2 , y2 , z2;
1759 int fx0 = x2+1 , fy0 = y2+1 , fz0 = z2+1;
1760 int cx1 = x1*2+1 , cy1 = y1*2+1 , cz1 = z1*2+1;
1761 int cx2 = x2*2+1 , cy2 = y2*2+1 , cz2 = z2*2+1;
1762 int fx1 = x1*3 , fy1 = y1*3 , fz1 = z1*3;
1763 int fx2 = x2*4 , fy2 = y2*4 , fz2 = z2*4;
1766 for( i=0 ; i<2 ; i++ )
for( j=0 ; j<2 ; j++ )
for( k=0 ; k<2 ; k++ )
1771 for( i=0 ; i<2 ; i++ )
for( j=0 ; j<2 ; j++ )
for( k=0 ; k<2 ; k++ )
1774 for( i=0 ; i<2 ; i++ )
for( j=0 ; j<2 ; j++ )
for( k=0 ; k<2 ; k++ )
1777 for( i=0 ; i<2 ; i++ )
for( j=0 ; j<2 ; j++ )
for( k=0 ; k<2 ; k++ )
1780 for( j=0 ; j<2 ; j++ )
for( k=0 ; k<2 ; k++ )
1783 for( i=0 ; i<2 ; i++ )
for( k=0 ; k<2 ; k++ )
1786 for( i=0 ; i<2 ; i++ )
for( j=0 ; j<2 ; j++ )
1791 for( i=0 ; i<2 ; i++ )
for( j=0 ; j<2 ; j++ )
for( k=0 ; k<2 ; k++ )
1794 for( i=0 ; i<2 ; i++ )
for( j=0 ; j<2 ; j++ )
for( k=0 ; k<2 ; k++ )
1797 for( i=0 ; i<2 ; i++ )
for( j=0 ; j<2 ; j++ )
for( k=0 ; k<2 ; k++ )
1800 for( i=0 ; i<2 ; i++ )
for( k=0 ; k<2 ; k++ )
1803 for( i=0 ; i<2 ; i++ )
for( j=0 ; j<2 ; j++ )
1806 for( j=0 ; j<2 ; j++ )
for( k=0 ; k<2 ; k++ )
1809 for( i=0 ; i<2 ; i++ )
for( j=0 ; j<2 ; j++ )
1812 for( j=0 ; j<2 ; j++ )
for( k=0 ; k<2 ; k++ )
1815 for( i=0 ; i<2 ; i++ )
for( k=0 ; k<2 ; k++ )
1818 for( k=0 ; k<2 ; k++ )
1821 for( j=0 ; j<2 ; j++ )
1824 for( i=0 ; i<2 ; i++ )
1829 for( i=0 ; i<2 ; i++ )
for( j=0 ; j<2 ; j++ )
for( k=0 ; k<2 ; k++ )
1832 for( i=0 ; i<2 ; i++ )
for( j=0 ; j<2 ; j++ )
1835 for( i=0 ; i<2 ; i++ )
for( k=0 ; k<2 ; k++ )
1838 for( j=0 ; j<2 ; j++ )
for( k=0 ; k<2 ; k++ )
1841 for( i=0 ; i<2 ; i++ )
1844 for( j=0 ; j<2 ; j++ )
1847 for( k=0 ; k<2 ; k++ )
1853 return neighbors[
d];
1856 template<
class NodeData ,
class Real >
1860 if( node!=neighbors[
d].neighbors[2][2][2] )
1862 neighbors[
d].clear();
1864 if( !node->
parent ) neighbors[
d].neighbors[2][2][2]=node;
1867 setNeighbors( node->
parent , xStart , xEnd , yStart , yEnd , zStart , zEnd );
1869 int x1 , y1 , z1 , x2 , y2 , z2 , ii , jj , kk;
1873 for(
int i=xStart ; i<xEnd ; i++ )
1878 for(
int j=yStart ; j<yEnd ; j++ )
1883 for(
int k=zStart ; k<zEnd ; k++ )
1898 return neighbors[
d];
1901 template<
class NodeData ,
class Real >
1905 if( node!=neighbors[
d].neighbors[2][2][2] )
1907 neighbors[
d].clear();
1909 if(!node->
parent) neighbors[
d].neighbors[2][2][2]=node;
1912 getNeighbors( node->
parent );
1914 int x1,y1,z1,x2,y2,z2,ii,jj,kk;
1918 for(
int i=0;i<5;i++)
1923 for(
int j=0;j<5;j++)
1928 for(
int k=0;k<5;k++)
1940 return neighbors[
d];
1943 template <
class NodeData,
class Real>
1945 FILE* fp=fopen(fileName,
"wb");
1952 template <
class NodeData,
class Real>
1959 template <
class NodeData,
class Real>
1961 FILE* fp=fopen(fileName,
"rb");
1968 template <
class NodeData,
class Real>
1983 template<
class NodeData,
class Real>
1989 template<
class NodeData,
class Real>
static int CornerIndex(int depth, int offSet)
static void FactorEdgeIndex(int idx, int &orientation, int &i, int &j)
static void FactorCornerIndex(int idx, int &x, int &y, int &z)
static void FaceCorners(int idx, int &c1, int &c2, int &c3, int &c4)
static int CornerIndex(int x, int y, int z)
static void EdgeCorners(int idx, int &c1, int &c2)
ConstNeighbors3 & getNeighbors(const OctNode *node)
ConstNeighbors5 & getNeighbors(const OctNode *node)
const OctNode * neighbors[5][5][5]
Neighbors3 & getNeighbors(OctNode *root, Point3D< Real > p, int d)
Neighbors3 & setNeighbors(OctNode *root, Point3D< Real > p, int d)
Neighbors5 & setNeighbors(OctNode *node, int xStart=0, int xEnd=5, int yStart=0, int yEnd=5, int zStart=0, int zEnd=5)
Neighbors5 & getNeighbors(OctNode *node)
OctNode * neighbors[3][3][3]
OctNode * neighbors[5][5][5]
int maxDepthLeaves(int maxDepth) const
static const int OffsetShift1
void depthAndOffset(int &depth, int offset[DIMENSION]) const
static void ProcessNodeAdjacentNodes(int maxDepth, OctNode *node1, int width1, OctNode *node2, int width2, NodeAdjacencyFunction *F, int processCurrent=1)
static const int OffsetShift2
static int CompareBackwardDepths(const void *v1, const void *v2)
static int CompareForwardDepths(const void *v1, const void *v2)
const OctNode * prevBranch(const OctNode *current) const
int write(const char *fileName) const
static const int OffsetMask
void processNodeNodes(OctNode *node, NodeAdjacencyFunction *F, int processCurrent=1)
bool isInside(Point3D< Real > p) const
static void ProcessMaxDepthNodeAdjacentNodes(int maxDepth, OctNode *node1, int width1, OctNode *node2, int width2, int depth, NodeAdjacencyFunction *F, int processCurrent=1)
static void DepthAndOffset(const long long &index, int &depth, int offset[DIMENSION])
static void CenterAndWidth(const long long &index, Point3D< Real > ¢er, Real &width)
static Allocator< OctNode > internalAllocator
void processNodeEdges(OctNode *node, NodeAdjacencyFunction *F, int eIndex, int processCurrent=1)
int read(const char *fileName)
static int Depth(const long long &index)
static int CompareForwardPointerDepths(const void *v1, const void *v2)
OctNode * getNearestLeaf(const Point3D< Real > &p)
static int CornerIndex(const Point3D< Real > ¢er, const Point3D< Real > &p)
static int Overlap2(const int &depth1, const int offSet1[DIMENSION], const Real &multiplier1, const int &depth2, const int offSet2[DIMENSION], const Real &multiplier2)
OctNode * edgeNeighbor(int edgeIndex, int forceChildren=0)
static const int OffsetShift
const OctNode * nextBranch(const OctNode *current) const
static void ProcessPointAdjacentNodes(int maxDepth, const int center1[3], OctNode *node2, int width2, PointAdjacencyFunction *F, int processCurrent=1)
void setFullDepth(int maxDepth)
static void ProcessTerminatingNodeAdjacentNodes(int maxDepth, OctNode *node1, int width1, OctNode *node2, int width2, TerminatingNodeAdjacencyFunction *F, int processCurrent=1)
OctNode & operator=(const OctNode< NodeData2, Real > &node)
const OctNode * nextNode(const OctNode *currentNode=NULL) const
OctNode * cornerNeighbor(int cornerIndex, int forceChildren=0)
int width(int maxDepth) const
void processNodeFaces(OctNode *node, NodeAdjacencyFunction *F, int fIndex, int processCurrent=1)
static int CommonEdge(const OctNode *node1, int eIndex1, const OctNode *node2, int eIndex2)
static void SetAllocator(int blockSize)
const OctNode * root(void) const
static int CompareByDepthAndZIndex(const void *v1, const void *v2)
void centerAndWidth(Point3D< Real > ¢er, Real &width) const
void centerIndex(int maxDepth, int index[DIMENSION]) const
const OctNode * nextLeaf(const OctNode *currentLeaf=NULL) const
static int CompareByDepthAndXYZ(const void *v1, const void *v2)
static void ProcessFixedDepthNodeAdjacentNodes(int maxDepth, OctNode *node1, int width1, OctNode *node2, int width2, int depth, NodeAdjacencyFunction *F, int processCurrent=1)
static int CompareBackwardPointerDepths(const void *v1, const void *v2)
static const int OffsetShift3
static int UseAllocator(void)
static void Index(int depth, const int offset[3], short &d, short off[DIMENSION])
void printRange(void) const
static const int DepthShift
static const int DepthMask
OctNode * faceNeighbor(int faceIndex, int forceChildren=0)
void processNodeCorners(OctNode *node, NodeAdjacencyFunction *F, int cIndex, int processCurrent=1)
An exception that is thrown when the arguments number or type is wrong/unhandled.
An exception that is thrown when initialization fails.
double SquareDistance(const Point3D< Real > &p1, const Point3D< Real > &p2)
long long _InterleaveBits(int p[3])