00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <stdlib.h>
00030 #include <math.h>
00031 #include <algorithm>
00032
00034
00036
00037 namespace pcl
00038 {
00039 namespace poisson
00040 {
00041
00042 template<class NodeData,class Real> const int OctNode<NodeData,Real>::DepthShift=5;
00043 template<class NodeData,class Real> const int OctNode<NodeData,Real>::OffsetShift=19;
00044 template<class NodeData,class Real> const int OctNode<NodeData,Real>::DepthMask=(1<<DepthShift)-1;
00045 template<class NodeData,class Real> const int OctNode<NodeData,Real>::OffsetMask=(1<<OffsetShift)-1;
00046 template<class NodeData,class Real> const int OctNode<NodeData,Real>::OffsetShift1=DepthShift;
00047 template<class NodeData,class Real> const int OctNode<NodeData,Real>::OffsetShift2=OffsetShift1+OffsetShift;
00048 template<class NodeData,class Real> const int OctNode<NodeData,Real>::OffsetShift3=OffsetShift2+OffsetShift;
00049
00050 template<class NodeData,class Real> int OctNode<NodeData,Real>::UseAlloc=0;
00051 template<class NodeData,class Real> Allocator<OctNode<NodeData,Real> > OctNode<NodeData,Real>::internalAllocator;
00052
00053 template<class NodeData,class Real>
00054 void OctNode<NodeData,Real>::SetAllocator(int blockSize)
00055 {
00056 if(blockSize>0)
00057 {
00058 UseAlloc=1;
00059 internalAllocator.set(blockSize);
00060 }
00061 else{UseAlloc=0;}
00062 }
00063 template<class NodeData,class Real>
00064 int OctNode<NodeData,Real>::UseAllocator(void){return UseAlloc;}
00065
00066 template <class NodeData,class Real>
00067 OctNode<NodeData,Real>::OctNode(void){
00068 parent=children=NULL;
00069 d=off[0]=off[1]=off[2]=0;
00070 }
00071
00072 template <class NodeData,class Real>
00073 OctNode<NodeData,Real>::~OctNode(void){
00074 if(!UseAlloc){if(children){delete[] children;}}
00075 parent=children=NULL;
00076 }
00077 template <class NodeData,class Real>
00078 void OctNode<NodeData,Real>::setFullDepth(int maxDepth){
00079 if( maxDepth )
00080 {
00081 if( !children ) initChildren();
00082 for( int i=0 ; i<8 ; i++ ) children[i].setFullDepth( maxDepth-1 );
00083 }
00084 }
00085
00086 template <class NodeData,class Real>
00087 int OctNode<NodeData,Real>::initChildren(void){
00088 int i,j,k;
00089
00090 if(UseAlloc){children=internalAllocator.newElements(8);}
00091 else{
00092 if(children){delete[] children;}
00093 children=NULL;
00094 children=new OctNode[Cube::CORNERS];
00095 }
00096 if(!children){
00097 fprintf(stderr,"Failed to initialize children in OctNode::initChildren\n");
00098 exit(0);
00099 return 0;
00100 }
00101 int d,off[3];
00102 depthAndOffset(d,off);
00103 for(i=0;i<2;i++){
00104 for(j=0;j<2;j++){
00105 for(k=0;k<2;k++){
00106 int idx=Cube::CornerIndex(i,j,k);
00107 children[idx].parent=this;
00108 children[idx].children=NULL;
00109 int off2[3];
00110 off2[0]=(off[0]<<1)+i;
00111 off2[1]=(off[1]<<1)+j;
00112 off2[2]=(off[2]<<1)+k;
00113 Index(d+1,off2,children[idx].d,children[idx].off);
00114 }
00115 }
00116 }
00117 return 1;
00118 }
00119 template <class NodeData,class Real>
00120 inline void OctNode<NodeData,Real>::Index(int depth,const int offset[3],short& d,short off[3]){
00121 d=short(depth);
00122 off[0]=short((1<<depth)+offset[0]-1);
00123 off[1]=short((1<<depth)+offset[1]-1);
00124 off[2]=short((1<<depth)+offset[2]-1);
00125 }
00126
00127 template<class NodeData,class Real>
00128 inline void OctNode<NodeData,Real>::depthAndOffset(int& depth,int offset[3]) const {
00129 depth=int(d);
00130 offset[0]=(int(off[0])+1)&(~(1<<depth));
00131 offset[1]=(int(off[1])+1)&(~(1<<depth));
00132 offset[2]=(int(off[2])+1)&(~(1<<depth));
00133 }
00134 template<class NodeData,class Real>
00135 inline int OctNode<NodeData,Real>::depth(void) const {return int(d);}
00136 template<class NodeData,class Real>
00137 inline void OctNode<NodeData,Real>::DepthAndOffset(const long long& index,int& depth,int offset[3]){
00138 depth=int(index&DepthMask);
00139 offset[0]=(int((index>>OffsetShift1)&OffsetMask)+1)&(~(1<<depth));
00140 offset[1]=(int((index>>OffsetShift2)&OffsetMask)+1)&(~(1<<depth));
00141 offset[2]=(int((index>>OffsetShift3)&OffsetMask)+1)&(~(1<<depth));
00142 }
00143 template<class NodeData,class Real>
00144 inline int OctNode<NodeData,Real>::Depth(const long long& index){return int(index&DepthMask);}
00145 template <class NodeData,class Real>
00146 void OctNode<NodeData,Real>::centerAndWidth(Point3D<Real>& center,Real& width) const{
00147 int depth,offset[3];
00148 depth=int(d);
00149 offset[0]=(int(off[0])+1)&(~(1<<depth));
00150 offset[1]=(int(off[1])+1)&(~(1<<depth));
00151 offset[2]=(int(off[2])+1)&(~(1<<depth));
00152 width=Real(1.0/(1<<depth));
00153 for(int dim=0;dim<DIMENSION;dim++){center.coords[dim]=Real(0.5+offset[dim])*width;}
00154 }
00155 template< class NodeData , class Real >
00156 bool OctNode< NodeData , Real >::isInside( Point3D< Real > p ) const
00157 {
00158 Point3D< Real > c;
00159 Real w;
00160 centerAndWidth( c , w );
00161 w /= 2;
00162 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);
00163 }
00164 template <class NodeData,class Real>
00165 inline void OctNode<NodeData,Real>::CenterAndWidth(const long long& index,Point3D<Real>& center,Real& width){
00166 int depth,offset[3];
00167 depth=index&DepthMask;
00168 offset[0]=(int((index>>OffsetShift1)&OffsetMask)+1)&(~(1<<depth));
00169 offset[1]=(int((index>>OffsetShift2)&OffsetMask)+1)&(~(1<<depth));
00170 offset[2]=(int((index>>OffsetShift3)&OffsetMask)+1)&(~(1<<depth));
00171 width=Real(1.0/(1<<depth));
00172 for(int dim=0;dim<DIMENSION;dim++){center.coords[dim]=Real(0.5+offset[dim])*width;}
00173 }
00174
00175 template <class NodeData,class Real>
00176 int OctNode<NodeData,Real>::maxDepth(void) const{
00177 if(!children){return 0;}
00178 else{
00179 int c,d;
00180 for(int i=0;i<Cube::CORNERS;i++){
00181 d=children[i].maxDepth();
00182 if(!i || d>c){c=d;}
00183 }
00184 return c+1;
00185 }
00186 }
00187 template <class NodeData,class Real>
00188 int OctNode<NodeData,Real>::nodes(void) const{
00189 if(!children){return 1;}
00190 else{
00191 int c=0;
00192 for(int i=0;i<Cube::CORNERS;i++){c+=children[i].nodes();}
00193 return c+1;
00194 }
00195 }
00196 template <class NodeData,class Real>
00197 int OctNode<NodeData,Real>::leaves(void) const{
00198 if(!children){return 1;}
00199 else{
00200 int c=0;
00201 for(int i=0;i<Cube::CORNERS;i++){c+=children[i].leaves();}
00202 return c;
00203 }
00204 }
00205 template<class NodeData,class Real>
00206 int OctNode<NodeData,Real>::maxDepthLeaves(int maxDepth) const{
00207 if(depth()>maxDepth){return 0;}
00208 if(!children){return 1;}
00209 else{
00210 int c=0;
00211 for(int i=0;i<Cube::CORNERS;i++){c+=children[i].maxDepthLeaves(maxDepth);}
00212 return c;
00213 }
00214 }
00215 template <class NodeData,class Real>
00216 const OctNode<NodeData,Real>* OctNode<NodeData,Real>::root(void) const{
00217 const OctNode* temp=this;
00218 while(temp->parent){temp=temp->parent;}
00219 return temp;
00220 }
00221
00222
00223 template <class NodeData,class Real>
00224 const OctNode<NodeData,Real>* OctNode<NodeData,Real>::nextBranch( const OctNode* current ) const
00225 {
00226 if( !current->parent || current==this ) return NULL;
00227 if(current-current->parent->children==Cube::CORNERS-1) return nextBranch( current->parent );
00228 else return current+1;
00229 }
00230 template <class NodeData,class Real>
00231 OctNode<NodeData,Real>* OctNode<NodeData,Real>::nextBranch(OctNode* current){
00232 if(!current->parent || current==this){return NULL;}
00233 if(current-current->parent->children==Cube::CORNERS-1){return nextBranch(current->parent);}
00234 else{return current+1;}
00235 }
00236 template< class NodeData , class Real >
00237 const OctNode< NodeData , Real >* OctNode< NodeData , Real >::prevBranch( const OctNode* current ) const
00238 {
00239 if( !current->parent || current==this ) return NULL;
00240 if( current-current->parent->children==0 ) return prevBranch( current->parent );
00241 else return current-1;
00242 }
00243 template< class NodeData , class Real >
00244 OctNode< NodeData , Real >* OctNode< NodeData , Real >::prevBranch( OctNode* current )
00245 {
00246 if( !current->parent || current==this ) return NULL;
00247 if( current-current->parent->children==0 ) return prevBranch( current->parent );
00248 else return current-1;
00249 }
00250 template <class NodeData,class Real>
00251 const OctNode<NodeData,Real>* OctNode<NodeData,Real>::nextLeaf(const OctNode* current) const{
00252 if(!current){
00253 const OctNode<NodeData,Real>* temp=this;
00254 while(temp->children){temp=&temp->children[0];}
00255 return temp;
00256 }
00257 if(current->children){return current->nextLeaf();}
00258 const OctNode* temp=nextBranch(current);
00259 if(!temp){return NULL;}
00260 else{return temp->nextLeaf();}
00261 }
00262 template <class NodeData,class Real>
00263 OctNode<NodeData,Real>* OctNode<NodeData,Real>::nextLeaf(OctNode* current){
00264 if(!current){
00265 OctNode<NodeData,Real>* temp=this;
00266 while(temp->children){temp=&temp->children[0];}
00267 return temp;
00268 }
00269 if(current->children){return current->nextLeaf();}
00270 OctNode* temp=nextBranch(current);
00271 if(!temp){return NULL;}
00272 else{return temp->nextLeaf();}
00273 }
00274
00275 template <class NodeData,class Real>
00276 const OctNode<NodeData,Real>* OctNode<NodeData,Real>::nextNode( const OctNode* current ) const
00277 {
00278 if( !current ) return this;
00279 else if( current->children ) return ¤t->children[0];
00280 else return nextBranch(current);
00281 }
00282 template <class NodeData,class Real>
00283 OctNode<NodeData,Real>* OctNode<NodeData,Real>::nextNode( OctNode* current )
00284 {
00285 if( !current ) return this;
00286 else if( current->children ) return ¤t->children[0];
00287 else return nextBranch( current );
00288 }
00289
00290 template <class NodeData,class Real>
00291 void OctNode<NodeData,Real>::printRange(void) const{
00292 Point3D<Real> center;
00293 Real width;
00294 centerAndWidth(center,width);
00295 for(int dim=0;dim<DIMENSION;dim++){
00296 printf("%[%f,%f]",center.coords[dim]-width/2,center.coords[dim]+width/2);
00297 if(dim<DIMENSION-1){printf("x");}
00298 else printf("\n");
00299 }
00300 }
00301
00302 template <class NodeData,class Real>
00303 void OctNode<NodeData,Real>::AdjacencyCountFunction::Function(const OctNode<NodeData,Real>* node1,const OctNode<NodeData,Real>* node2){count++;}
00304
00305 template <class NodeData,class Real>
00306 template<class NodeAdjacencyFunction>
00307 void OctNode<NodeData,Real>::processNodeNodes(OctNode* node,NodeAdjacencyFunction* F,int processCurrent){
00308 if(processCurrent){F->Function(this,node);}
00309 if(children){__processNodeNodes(node,F);}
00310 }
00311 template <class NodeData,class Real>
00312 template<class NodeAdjacencyFunction>
00313 void OctNode<NodeData,Real>::processNodeFaces(OctNode* node,NodeAdjacencyFunction* F,int fIndex,int processCurrent){
00314 if(processCurrent){F->Function(this,node);}
00315 if(children){
00316 int c1,c2,c3,c4;
00317 Cube::FaceCorners(fIndex,c1,c2,c3,c4);
00318 __processNodeFaces(node,F,c1,c2,c3,c4);
00319 }
00320 }
00321 template <class NodeData,class Real>
00322 template<class NodeAdjacencyFunction>
00323 void OctNode<NodeData,Real>::processNodeEdges(OctNode* node,NodeAdjacencyFunction* F,int eIndex,int processCurrent){
00324 if(processCurrent){F->Function(this,node);}
00325 if(children){
00326 int c1,c2;
00327 Cube::EdgeCorners(eIndex,c1,c2);
00328 __processNodeEdges(node,F,c1,c2);
00329 }
00330 }
00331 template <class NodeData,class Real>
00332 template<class NodeAdjacencyFunction>
00333 void OctNode<NodeData,Real>::processNodeCorners(OctNode* node,NodeAdjacencyFunction* F,int cIndex,int processCurrent){
00334 if(processCurrent){F->Function(this,node);}
00335 OctNode<NodeData,Real>* temp=this;
00336 while(temp->children){
00337 temp=&temp->children[cIndex];
00338 F->Function(temp,node);
00339 }
00340 }
00341 template <class NodeData,class Real>
00342 template<class NodeAdjacencyFunction>
00343 void OctNode<NodeData,Real>::__processNodeNodes(OctNode* node,NodeAdjacencyFunction* F){
00344 F->Function(&children[0],node);
00345 F->Function(&children[1],node);
00346 F->Function(&children[2],node);
00347 F->Function(&children[3],node);
00348 F->Function(&children[4],node);
00349 F->Function(&children[5],node);
00350 F->Function(&children[6],node);
00351 F->Function(&children[7],node);
00352 if(children[0].children){children[0].__processNodeNodes(node,F);}
00353 if(children[1].children){children[1].__processNodeNodes(node,F);}
00354 if(children[2].children){children[2].__processNodeNodes(node,F);}
00355 if(children[3].children){children[3].__processNodeNodes(node,F);}
00356 if(children[4].children){children[4].__processNodeNodes(node,F);}
00357 if(children[5].children){children[5].__processNodeNodes(node,F);}
00358 if(children[6].children){children[6].__processNodeNodes(node,F);}
00359 if(children[7].children){children[7].__processNodeNodes(node,F);}
00360 }
00361 template <class NodeData,class Real>
00362 template<class NodeAdjacencyFunction>
00363 void OctNode<NodeData,Real>::__processNodeEdges(OctNode* node,NodeAdjacencyFunction* F,int cIndex1,int cIndex2){
00364 F->Function(&children[cIndex1],node);
00365 F->Function(&children[cIndex2],node);
00366 if(children[cIndex1].children){children[cIndex1].__processNodeEdges(node,F,cIndex1,cIndex2);}
00367 if(children[cIndex2].children){children[cIndex2].__processNodeEdges(node,F,cIndex1,cIndex2);}
00368 }
00369 template <class NodeData,class Real>
00370 template<class NodeAdjacencyFunction>
00371 void OctNode<NodeData,Real>::__processNodeFaces(OctNode* node,NodeAdjacencyFunction* F,int cIndex1,int cIndex2,int cIndex3,int cIndex4){
00372 F->Function(&children[cIndex1],node);
00373 F->Function(&children[cIndex2],node);
00374 F->Function(&children[cIndex3],node);
00375 F->Function(&children[cIndex4],node);
00376 if(children[cIndex1].children){children[cIndex1].__processNodeFaces(node,F,cIndex1,cIndex2,cIndex3,cIndex4);}
00377 if(children[cIndex2].children){children[cIndex2].__processNodeFaces(node,F,cIndex1,cIndex2,cIndex3,cIndex4);}
00378 if(children[cIndex3].children){children[cIndex3].__processNodeFaces(node,F,cIndex1,cIndex2,cIndex3,cIndex4);}
00379 if(children[cIndex4].children){children[cIndex4].__processNodeFaces(node,F,cIndex1,cIndex2,cIndex3,cIndex4);}
00380 }
00381 template<class NodeData,class Real>
00382 template<class NodeAdjacencyFunction>
00383 void OctNode<NodeData,Real>::ProcessNodeAdjacentNodes(int maxDepth,OctNode* node1,int width1,OctNode* node2,int width2,NodeAdjacencyFunction* F,int processCurrent){
00384 int c1[3],c2[3],w1,w2;
00385 node1->centerIndex(maxDepth+1,c1);
00386 node2->centerIndex(maxDepth+1,c2);
00387 w1=node1->width(maxDepth+1);
00388 w2=node2->width(maxDepth+1);
00389
00390 ProcessNodeAdjacentNodes(c1[0]-c2[0],c1[1]-c2[1],c1[2]-c2[2],node1,(width1*w1)>>1,node2,(width2*w2)>>1,w2,F,processCurrent);
00391 }
00392 template<class NodeData,class Real>
00393 template<class NodeAdjacencyFunction>
00394 void OctNode<NodeData,Real>::ProcessNodeAdjacentNodes(int dx,int dy,int dz,
00395 OctNode<NodeData,Real>* node1,int radius1,
00396 OctNode<NodeData,Real>* node2,int radius2,int width2,
00397 NodeAdjacencyFunction* F,int processCurrent){
00398 if(!Overlap(dx,dy,dz,radius1+radius2)){return;}
00399 if(processCurrent){F->Function(node2,node1);}
00400 if(!node2->children){return;}
00401 __ProcessNodeAdjacentNodes(-dx,-dy,-dz,node1,radius1,node2,radius2,width2/2,F);
00402 }
00403 template<class NodeData,class Real>
00404 template<class TerminatingNodeAdjacencyFunction>
00405 void OctNode<NodeData,Real>::ProcessTerminatingNodeAdjacentNodes(int maxDepth,OctNode* node1,int width1,OctNode* node2,int width2,TerminatingNodeAdjacencyFunction* F,int processCurrent){
00406 int c1[3],c2[3],w1,w2;
00407 node1->centerIndex(maxDepth+1,c1);
00408 node2->centerIndex(maxDepth+1,c2);
00409 w1=node1->width(maxDepth+1);
00410 w2=node2->width(maxDepth+1);
00411
00412 ProcessTerminatingNodeAdjacentNodes(c1[0]-c2[0],c1[1]-c2[1],c1[2]-c2[2],node1,(width1*w1)>>1,node2,(width2*w2)>>1,w2,F,processCurrent);
00413 }
00414 template<class NodeData,class Real>
00415 template<class TerminatingNodeAdjacencyFunction>
00416 void OctNode<NodeData,Real>::ProcessTerminatingNodeAdjacentNodes(int dx,int dy,int dz,
00417 OctNode<NodeData,Real>* node1,int radius1,
00418 OctNode<NodeData,Real>* node2,int radius2,int width2,
00419 TerminatingNodeAdjacencyFunction* F,int processCurrent)
00420 {
00421 if(!Overlap(dx,dy,dz,radius1+radius2)){return;}
00422 if(processCurrent){F->Function(node2,node1);}
00423 if(!node2->children){return;}
00424 __ProcessTerminatingNodeAdjacentNodes(-dx,-dy,-dz,node1,radius1,node2,radius2,width2/2,F);
00425 }
00426 template<class NodeData,class Real>
00427 template<class PointAdjacencyFunction>
00428 void OctNode<NodeData,Real>::ProcessPointAdjacentNodes( int maxDepth , const int c1[3] , OctNode* node2 , int width2 , PointAdjacencyFunction* F , int processCurrent )
00429 {
00430 int c2[3] , w2;
00431 node2->centerIndex( maxDepth+1 , c2 );
00432 w2 = node2->width( maxDepth+1 );
00433 ProcessPointAdjacentNodes( c1[0]-c2[0] , c1[1]-c2[1] , c1[2]-c2[2] , node2 , (width2*w2)>>1 , w2 , F , processCurrent );
00434 }
00435 template<class NodeData,class Real>
00436 template<class PointAdjacencyFunction>
00437 void OctNode<NodeData,Real>::ProcessPointAdjacentNodes(int dx,int dy,int dz,
00438 OctNode<NodeData,Real>* node2,int radius2,int width2,
00439 PointAdjacencyFunction* F,int processCurrent)
00440 {
00441 if( !Overlap(dx,dy,dz,radius2) ) return;
00442 if( processCurrent ) F->Function(node2);
00443 if( !node2->children ) return;
00444 __ProcessPointAdjacentNodes( -dx , -dy , -dz , node2 , radius2 , width2>>1 , F );
00445 }
00446 template<class NodeData,class Real>
00447 template<class NodeAdjacencyFunction>
00448 void OctNode<NodeData,Real>::ProcessFixedDepthNodeAdjacentNodes(int maxDepth,
00449 OctNode<NodeData,Real>* node1,int width1,
00450 OctNode<NodeData,Real>* node2,int width2,
00451 int depth,NodeAdjacencyFunction* F,int processCurrent)
00452 {
00453 int c1[3],c2[3],w1,w2;
00454 node1->centerIndex(maxDepth+1,c1);
00455 node2->centerIndex(maxDepth+1,c2);
00456 w1=node1->width(maxDepth+1);
00457 w2=node2->width(maxDepth+1);
00458
00459 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);
00460 }
00461 template<class NodeData,class Real>
00462 template<class NodeAdjacencyFunction>
00463 void OctNode<NodeData,Real>::ProcessFixedDepthNodeAdjacentNodes(int dx,int dy,int dz,
00464 OctNode<NodeData,Real>* node1,int radius1,
00465 OctNode<NodeData,Real>* node2,int radius2,int width2,
00466 int depth,NodeAdjacencyFunction* F,int processCurrent)
00467 {
00468 int d=node2->depth();
00469 if(d>depth){return;}
00470 if(!Overlap(dx,dy,dz,radius1+radius2)){return;}
00471 if(d==depth){if(processCurrent){F->Function(node2,node1);}}
00472 else{
00473 if(!node2->children){return;}
00474 __ProcessFixedDepthNodeAdjacentNodes(-dx,-dy,-dz,node1,radius1,node2,radius2,width2/2,depth-1,F);
00475 }
00476 }
00477 template<class NodeData,class Real>
00478 template<class NodeAdjacencyFunction>
00479 void OctNode<NodeData,Real>::ProcessMaxDepthNodeAdjacentNodes(int maxDepth,
00480 OctNode<NodeData,Real>* node1,int width1,
00481 OctNode<NodeData,Real>* node2,int width2,
00482 int depth,NodeAdjacencyFunction* F,int processCurrent)
00483 {
00484 int c1[3],c2[3],w1,w2;
00485 node1->centerIndex(maxDepth+1,c1);
00486 node2->centerIndex(maxDepth+1,c2);
00487 w1=node1->width(maxDepth+1);
00488 w2=node2->width(maxDepth+1);
00489 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);
00490 }
00491 template<class NodeData,class Real>
00492 template<class NodeAdjacencyFunction>
00493 void OctNode<NodeData,Real>::ProcessMaxDepthNodeAdjacentNodes(int dx,int dy,int dz,
00494 OctNode<NodeData,Real>* node1,int radius1,
00495 OctNode<NodeData,Real>* node2,int radius2,int width2,
00496 int depth,NodeAdjacencyFunction* F,int processCurrent)
00497 {
00498 int d=node2->depth();
00499 if(d>depth){return;}
00500 if(!Overlap(dx,dy,dz,radius1+radius2)){return;}
00501 if(processCurrent){F->Function(node2,node1);}
00502 if(d<depth && node2->children){__ProcessMaxDepthNodeAdjacentNodes(-dx,-dy,-dz,node1,radius1,node2,radius2,width2>>1,depth-1,F);}
00503 }
00504 template <class NodeData,class Real>
00505 template<class NodeAdjacencyFunction>
00506 void OctNode<NodeData,Real>::__ProcessNodeAdjacentNodes(int dx,int dy,int dz,
00507 OctNode* node1,int radius1,
00508 OctNode* node2,int radius2,int cWidth2,
00509 NodeAdjacencyFunction* F)
00510 {
00511 int cWidth=cWidth2>>1;
00512 int radius=radius2>>1;
00513 int o=ChildOverlap(dx,dy,dz,radius1+radius,cWidth);
00514 if(o){
00515 int dx1=dx-cWidth;
00516 int dx2=dx+cWidth;
00517 int dy1=dy-cWidth;
00518 int dy2=dy+cWidth;
00519 int dz1=dz-cWidth;
00520 int dz2=dz+cWidth;
00521 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);}}
00522 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);}}
00523 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);}}
00524 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);}}
00525 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);}}
00526 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);}}
00527 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);}}
00528 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);}}
00529 }
00530 }
00531 template <class NodeData,class Real>
00532 template<class TerminatingNodeAdjacencyFunction>
00533 void OctNode<NodeData,Real>::__ProcessTerminatingNodeAdjacentNodes(int dx,int dy,int dz,
00534 OctNode* node1,int radius1,
00535 OctNode* node2,int radius2,int cWidth2,
00536 TerminatingNodeAdjacencyFunction* F)
00537 {
00538 int cWidth=cWidth2>>1;
00539 int radius=radius2>>1;
00540 int o=ChildOverlap(dx,dy,dz,radius1+radius,cWidth);
00541 if(o){
00542 int dx1=dx-cWidth;
00543 int dx2=dx+cWidth;
00544 int dy1=dy-cWidth;
00545 int dy2=dy+cWidth;
00546 int dz1=dz-cWidth;
00547 int dz2=dz+cWidth;
00548 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);}}
00549 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);}}
00550 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);}}
00551 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);}}
00552 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);}}
00553 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);}}
00554 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);}}
00555 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);}}
00556 }
00557 }
00558 template <class NodeData,class Real>
00559 template<class PointAdjacencyFunction>
00560 void OctNode<NodeData,Real>::__ProcessPointAdjacentNodes(int dx,int dy,int dz,
00561 OctNode* node2,int radius2,int cWidth2,
00562 PointAdjacencyFunction* F)
00563 {
00564 int cWidth=cWidth2>>1;
00565 int radius=radius2>>1;
00566 int o=ChildOverlap(dx,dy,dz,radius,cWidth);
00567 if( o )
00568 {
00569 int dx1=dx-cWidth;
00570 int dx2=dx+cWidth;
00571 int dy1=dy-cWidth;
00572 int dy2=dy+cWidth;
00573 int dz1=dz-cWidth;
00574 int dz2=dz+cWidth;
00575 if(o& 1){F->Function(&node2->children[0]);if(node2->children[0].children){__ProcessPointAdjacentNodes(dx1,dy1,dz1,&node2->children[0],radius,cWidth,F);}}
00576 if(o& 2){F->Function(&node2->children[1]);if(node2->children[1].children){__ProcessPointAdjacentNodes(dx2,dy1,dz1,&node2->children[1],radius,cWidth,F);}}
00577 if(o& 4){F->Function(&node2->children[2]);if(node2->children[2].children){__ProcessPointAdjacentNodes(dx1,dy2,dz1,&node2->children[2],radius,cWidth,F);}}
00578 if(o& 8){F->Function(&node2->children[3]);if(node2->children[3].children){__ProcessPointAdjacentNodes(dx2,dy2,dz1,&node2->children[3],radius,cWidth,F);}}
00579 if(o& 16){F->Function(&node2->children[4]);if(node2->children[4].children){__ProcessPointAdjacentNodes(dx1,dy1,dz2,&node2->children[4],radius,cWidth,F);}}
00580 if(o& 32){F->Function(&node2->children[5]);if(node2->children[5].children){__ProcessPointAdjacentNodes(dx2,dy1,dz2,&node2->children[5],radius,cWidth,F);}}
00581 if(o& 64){F->Function(&node2->children[6]);if(node2->children[6].children){__ProcessPointAdjacentNodes(dx1,dy2,dz2,&node2->children[6],radius,cWidth,F);}}
00582 if(o&128){F->Function(&node2->children[7]);if(node2->children[7].children){__ProcessPointAdjacentNodes(dx2,dy2,dz2,&node2->children[7],radius,cWidth,F);}}
00583 }
00584 }
00585 template <class NodeData,class Real>
00586 template<class NodeAdjacencyFunction>
00587 void OctNode<NodeData,Real>::__ProcessFixedDepthNodeAdjacentNodes(int dx,int dy,int dz,
00588 OctNode* node1,int radius1,
00589 OctNode* node2,int radius2,int cWidth2,
00590 int depth,NodeAdjacencyFunction* F)
00591 {
00592 int cWidth=cWidth2>>1;
00593 int radius=radius2>>1;
00594 int o=ChildOverlap(dx,dy,dz,radius1+radius,cWidth);
00595 if(o){
00596 int dx1=dx-cWidth;
00597 int dx2=dx+cWidth;
00598 int dy1=dy-cWidth;
00599 int dy2=dy+cWidth;
00600 int dz1=dz-cWidth;
00601 int dz2=dz+cWidth;
00602 if(node2->depth()==depth){
00603 if(o& 1){F->Function(&node2->children[0],node1);}
00604 if(o& 2){F->Function(&node2->children[1],node1);}
00605 if(o& 4){F->Function(&node2->children[2],node1);}
00606 if(o& 8){F->Function(&node2->children[3],node1);}
00607 if(o& 16){F->Function(&node2->children[4],node1);}
00608 if(o& 32){F->Function(&node2->children[5],node1);}
00609 if(o& 64){F->Function(&node2->children[6],node1);}
00610 if(o&128){F->Function(&node2->children[7],node1);}
00611 }
00612 else{
00613 if(o& 1){if(node2->children[0].children){__ProcessFixedDepthNodeAdjacentNodes(dx1,dy1,dz1,node1,radius1,&node2->children[0],radius,cWidth,depth,F);}}
00614 if(o& 2){if(node2->children[1].children){__ProcessFixedDepthNodeAdjacentNodes(dx2,dy1,dz1,node1,radius1,&node2->children[1],radius,cWidth,depth,F);}}
00615 if(o& 4){if(node2->children[2].children){__ProcessFixedDepthNodeAdjacentNodes(dx1,dy2,dz1,node1,radius1,&node2->children[2],radius,cWidth,depth,F);}}
00616 if(o& 8){if(node2->children[3].children){__ProcessFixedDepthNodeAdjacentNodes(dx2,dy2,dz1,node1,radius1,&node2->children[3],radius,cWidth,depth,F);}}
00617 if(o& 16){if(node2->children[4].children){__ProcessFixedDepthNodeAdjacentNodes(dx1,dy1,dz2,node1,radius1,&node2->children[4],radius,cWidth,depth,F);}}
00618 if(o& 32){if(node2->children[5].children){__ProcessFixedDepthNodeAdjacentNodes(dx2,dy1,dz2,node1,radius1,&node2->children[5],radius,cWidth,depth,F);}}
00619 if(o& 64){if(node2->children[6].children){__ProcessFixedDepthNodeAdjacentNodes(dx1,dy2,dz2,node1,radius1,&node2->children[6],radius,cWidth,depth,F);}}
00620 if(o&128){if(node2->children[7].children){__ProcessFixedDepthNodeAdjacentNodes(dx2,dy2,dz2,node1,radius1,&node2->children[7],radius,cWidth,depth,F);}}
00621 }
00622 }
00623 }
00624 template <class NodeData,class Real>
00625 template<class NodeAdjacencyFunction>
00626 void OctNode<NodeData,Real>::__ProcessMaxDepthNodeAdjacentNodes(int dx,int dy,int dz,
00627 OctNode* node1,int radius1,
00628 OctNode* node2,int radius2,int cWidth2,
00629 int depth,NodeAdjacencyFunction* F)
00630 {
00631 int cWidth=cWidth2>>1;
00632 int radius=radius2>>1;
00633 int o=ChildOverlap(dx,dy,dz,radius1+radius,cWidth);
00634 if(o){
00635 int dx1=dx-cWidth;
00636 int dx2=dx+cWidth;
00637 int dy1=dy-cWidth;
00638 int dy2=dy+cWidth;
00639 int dz1=dz-cWidth;
00640 int dz2=dz+cWidth;
00641 if(node2->depth()<=depth){
00642 if(o& 1){F->Function(&node2->children[0],node1);}
00643 if(o& 2){F->Function(&node2->children[1],node1);}
00644 if(o& 4){F->Function(&node2->children[2],node1);}
00645 if(o& 8){F->Function(&node2->children[3],node1);}
00646 if(o& 16){F->Function(&node2->children[4],node1);}
00647 if(o& 32){F->Function(&node2->children[5],node1);}
00648 if(o& 64){F->Function(&node2->children[6],node1);}
00649 if(o&128){F->Function(&node2->children[7],node1);}
00650 }
00651 if(node2->depth()<depth){
00652 if(o& 1){if(node2->children[0].children){__ProcessMaxDepthNodeAdjacentNodes(dx1,dy1,dz1,node1,radius1,&node2->children[0],radius,cWidth,depth,F);}}
00653 if(o& 2){if(node2->children[1].children){__ProcessMaxDepthNodeAdjacentNodes(dx2,dy1,dz1,node1,radius1,&node2->children[1],radius,cWidth,depth,F);}}
00654 if(o& 4){if(node2->children[2].children){__ProcessMaxDepthNodeAdjacentNodes(dx1,dy2,dz1,node1,radius1,&node2->children[2],radius,cWidth,depth,F);}}
00655 if(o& 8){if(node2->children[3].children){__ProcessMaxDepthNodeAdjacentNodes(dx2,dy2,dz1,node1,radius1,&node2->children[3],radius,cWidth,depth,F);}}
00656 if(o& 16){if(node2->children[4].children){__ProcessMaxDepthNodeAdjacentNodes(dx1,dy1,dz2,node1,radius1,&node2->children[4],radius,cWidth,depth,F);}}
00657 if(o& 32){if(node2->children[5].children){__ProcessMaxDepthNodeAdjacentNodes(dx2,dy1,dz2,node1,radius1,&node2->children[5],radius,cWidth,depth,F);}}
00658 if(o& 64){if(node2->children[6].children){__ProcessMaxDepthNodeAdjacentNodes(dx1,dy2,dz2,node1,radius1,&node2->children[6],radius,cWidth,depth,F);}}
00659 if(o&128){if(node2->children[7].children){__ProcessMaxDepthNodeAdjacentNodes(dx2,dy2,dz2,node1,radius1,&node2->children[7],radius,cWidth,depth,F);}}
00660 }
00661 }
00662 }
00663 template <class NodeData,class Real>
00664 inline int OctNode<NodeData,Real>::ChildOverlap(int dx,int dy,int dz,int d,int cRadius2)
00665 {
00666 int w1=d-cRadius2;
00667 int w2=d+cRadius2;
00668 int overlap=0;
00669
00670 int test=0,test1=0;
00671 if(dx<w2 && dx>-w1){test =1;}
00672 if(dx<w1 && dx>-w2){test|=2;}
00673
00674 if(!test){return 0;}
00675 if(dz<w2 && dz>-w1){test1 =test;}
00676 if(dz<w1 && dz>-w2){test1|=test<<4;}
00677
00678 if(!test1){return 0;}
00679 if(dy<w2 && dy>-w1){overlap =test1;}
00680 if(dy<w1 && dy>-w2){overlap|=test1<<2;}
00681 return overlap;
00682 }
00683
00684 template <class NodeData,class Real>
00685 OctNode<NodeData,Real>* OctNode<NodeData,Real>::getNearestLeaf(const Point3D<Real>& p){
00686 Point3D<Real> center;
00687 Real width;
00688 OctNode<NodeData,Real>* temp;
00689 int cIndex;
00690 if(!children){return this;}
00691 centerAndWidth(center,width);
00692 temp=this;
00693 while(temp->children){
00694 cIndex=CornerIndex(center,p);
00695 temp=&temp->children[cIndex];
00696 width/=2;
00697 if(cIndex&1){center.coords[0]+=width/2;}
00698 else {center.coords[0]-=width/2;}
00699 if(cIndex&2){center.coords[1]+=width/2;}
00700 else {center.coords[1]-=width/2;}
00701 if(cIndex&4){center.coords[2]+=width/2;}
00702 else {center.coords[2]-=width/2;}
00703 }
00704 return temp;
00705 }
00706 template <class NodeData,class Real>
00707 const OctNode<NodeData,Real>* OctNode<NodeData,Real>::getNearestLeaf(const Point3D<Real>& p) const{
00708 int nearest;
00709 Real temp,dist2;
00710 if(!children){return this;}
00711 for(int i=0;i<Cube::CORNERS;i++){
00712 temp=SquareDistance(children[i].center,p);
00713 if(!i || temp<dist2){
00714 dist2=temp;
00715 nearest=i;
00716 }
00717 }
00718 return children[nearest].getNearestLeaf(p);
00719 }
00720
00721 template <class NodeData,class Real>
00722 int OctNode<NodeData,Real>::CommonEdge(const OctNode<NodeData,Real>* node1,int eIndex1,const OctNode<NodeData,Real>* node2,int eIndex2){
00723 int o1,o2,i1,i2,j1,j2;
00724
00725 Cube::FactorEdgeIndex(eIndex1,o1,i1,j1);
00726 Cube::FactorEdgeIndex(eIndex2,o2,i2,j2);
00727 if(o1!=o2){return 0;}
00728
00729 int dir[2];
00730 int idx1[2];
00731 int idx2[2];
00732 switch(o1){
00733 case 0: dir[0]=1; dir[1]=2; break;
00734 case 1: dir[0]=0; dir[1]=2; break;
00735 case 2: dir[0]=0; dir[1]=1; break;
00736 };
00737 int d1,d2,off1[3],off2[3];
00738 node1->depthAndOffset(d1,off1);
00739 node2->depthAndOffset(d2,off2);
00740 idx1[0]=off1[dir[0]]+(1<<d1)+i1;
00741 idx1[1]=off1[dir[1]]+(1<<d1)+j1;
00742 idx2[0]=off2[dir[0]]+(1<<d2)+i2;
00743 idx2[1]=off2[dir[1]]+(1<<d2)+j2;
00744 if(d1>d2){
00745 idx2[0]<<=(d1-d2);
00746 idx2[1]<<=(d1-d2);
00747 }
00748 else{
00749 idx1[0]<<=(d2-d1);
00750 idx1[1]<<=(d2-d1);
00751 }
00752 if(idx1[0]==idx2[0] && idx1[1]==idx2[1]){return 1;}
00753 else {return 0;}
00754 }
00755 template<class NodeData,class Real>
00756 int OctNode<NodeData,Real>::CornerIndex(const Point3D<Real>& center,const Point3D<Real>& p){
00757 int cIndex=0;
00758 if(p.coords[0]>center.coords[0]){cIndex|=1;}
00759 if(p.coords[1]>center.coords[1]){cIndex|=2;}
00760 if(p.coords[2]>center.coords[2]){cIndex|=4;}
00761 return cIndex;
00762 }
00763 template <class NodeData,class Real>
00764 template<class NodeData2>
00765 OctNode<NodeData,Real>& OctNode<NodeData,Real>::operator = (const OctNode<NodeData2,Real>& node){
00766 int i;
00767 if(children){delete[] children;}
00768 children=NULL;
00769
00770 d=node.depth ();
00771 for(i=0;i<DIMENSION;i++){this->offset[i] = node.offset[i];}
00772 if(node.children){
00773 initChildren();
00774 for(i=0;i<Cube::CORNERS;i++){children[i] = node.children[i];}
00775 }
00776 return *this;
00777 }
00778 template <class NodeData,class Real>
00779 int OctNode<NodeData,Real>::CompareForwardDepths(const void* v1,const void* v2){
00780 return ((const OctNode<NodeData,Real>*)v1)->depth-((const OctNode<NodeData,Real>*)v2)->depth;
00781 }
00782 template< class NodeData , class Real >
00783 int OctNode< NodeData , Real >::CompareByDepthAndXYZ( const void* v1 , const void* v2 )
00784 {
00785 const OctNode<NodeData,Real> *n1 = (*(const OctNode< NodeData , Real >**)v1);
00786 const OctNode<NodeData,Real> *n2 = (*(const OctNode< NodeData , Real >**)v2);
00787 if( n1->d!=n2->d ) return int(n1->d)-int(n2->d);
00788 else if( n1->off[0]!=n2->off[0] ) return int(n1->off[0]) - int(n2->off[0]);
00789 else if( n1->off[1]!=n2->off[1] ) return int(n1->off[1]) - int(n2->off[1]);
00790 else if( n1->off[2]!=n2->off[2] ) return int(n1->off[2]) - int(n2->off[2]);
00791 return 0;
00792 }
00793
00794 long long _InterleaveBits( int p[3] )
00795 {
00796 long long key = 0;
00797 for( int i=0 ; i<32 ; i++ ) key |= ( ( p[0] & (1<<i) )<<(2*i) ) | ( ( p[1] & (1<<i) )<<(2*i+1) ) | ( ( p[2] & (1<<i) )<<(2*i+2) );
00798 return key;
00799 }
00800 template <class NodeData,class Real>
00801 int OctNode<NodeData,Real>::CompareByDepthAndZIndex( const void* v1 , const void* v2 )
00802 {
00803 const OctNode<NodeData,Real>* n1 = (*(const OctNode<NodeData,Real>**)v1);
00804 const OctNode<NodeData,Real>* n2 = (*(const OctNode<NodeData,Real>**)v2);
00805 int d1 , off1[3] , d2 , off2[3];
00806 n1->depthAndOffset( d1 , off1 ) , n2->depthAndOffset( d2 , off2 );
00807 if ( d1>d2 ) return 1;
00808 else if( d1<d2 ) return -1;
00809 long long k1 = _InterleaveBits( off1 ) , k2 = _InterleaveBits( off2 );
00810 if ( k1>k2 ) return 1;
00811 else if( k1<k2 ) return -1;
00812 else return 0;
00813 }
00814
00815 template <class NodeData,class Real>
00816 int OctNode<NodeData,Real>::CompareForwardPointerDepths( const void* v1 , const void* v2 )
00817 {
00818 const OctNode<NodeData,Real>* n1 = (*(const OctNode<NodeData,Real>**)v1);
00819 const OctNode<NodeData,Real>* n2 = (*(const OctNode<NodeData,Real>**)v2);
00820 if(n1->d!=n2->d){return int(n1->d)-int(n2->d);}
00821 while( n1->parent!=n2->parent )
00822 {
00823 n1=n1->parent;
00824 n2=n2->parent;
00825 }
00826 if(n1->off[0]!=n2->off[0]){return int(n1->off[0])-int(n2->off[0]);}
00827 if(n1->off[1]!=n2->off[1]){return int(n1->off[1])-int(n2->off[1]);}
00828 return int(n1->off[2])-int(n2->off[2]);
00829 return 0;
00830 }
00831 template <class NodeData,class Real>
00832 int OctNode<NodeData,Real>::CompareBackwardDepths(const void* v1,const void* v2){
00833 return ((const OctNode<NodeData,Real>*)v2)->depth-((const OctNode<NodeData,Real>*)v1)->depth;
00834 }
00835 template <class NodeData,class Real>
00836 int OctNode<NodeData,Real>::CompareBackwardPointerDepths(const void* v1,const void* v2){
00837 return (*(const OctNode<NodeData,Real>**)v2)->depth()-(*(const OctNode<NodeData,Real>**)v1)->depth();
00838 }
00839 template <class NodeData,class Real>
00840 inline int OctNode<NodeData,Real>::Overlap2(const int &depth1,const int offSet1[DIMENSION],const Real& multiplier1,const int &depth2,const int offSet2[DIMENSION],const Real& multiplier2){
00841 int d=depth2-depth1;
00842 Real w=multiplier2+multiplier1*(1<<d);
00843 Real w2=Real((1<<(d-1))-0.5);
00844 if(
00845 fabs(Real(offSet2[0]-(offSet1[0]<<d))-w2)>=w ||
00846 fabs(Real(offSet2[1]-(offSet1[1]<<d))-w2)>=w ||
00847 fabs(Real(offSet2[2]-(offSet1[2]<<d))-w2)>=w
00848 ){return 0;}
00849 return 1;
00850 }
00851 template <class NodeData,class Real>
00852 inline int OctNode<NodeData,Real>::Overlap(int c1,int c2,int c3,int dWidth){
00853 if(c1>=dWidth || c1<=-dWidth || c2>=dWidth || c2<=-dWidth || c3>=dWidth || c3<=-dWidth){return 0;}
00854 else{return 1;}
00855 }
00856 template <class NodeData,class Real>
00857 OctNode<NodeData,Real>* OctNode<NodeData,Real>::faceNeighbor(int faceIndex,int forceChildren){return __faceNeighbor(faceIndex>>1,faceIndex&1,forceChildren);}
00858 template <class NodeData,class Real>
00859 const OctNode<NodeData,Real>* OctNode<NodeData,Real>::faceNeighbor(int faceIndex) const {return __faceNeighbor(faceIndex>>1,faceIndex&1);}
00860 template <class NodeData,class Real>
00861 OctNode<NodeData,Real>* OctNode<NodeData,Real>::__faceNeighbor(int dir,int off,int forceChildren){
00862 if(!parent){return NULL;}
00863 int pIndex=int(this-parent->children);
00864 pIndex^=(1<<dir);
00865 if((pIndex & (1<<dir))==(off<<dir)){return &parent->children[pIndex];}
00866 else{
00867 OctNode* temp=parent->__faceNeighbor(dir,off,forceChildren);
00868 if(!temp){return NULL;}
00869 if(!temp->children){
00870 if(forceChildren){temp->initChildren();}
00871 else{return temp;}
00872 }
00873 return &temp->children[pIndex];
00874 }
00875 }
00876 template <class NodeData,class Real>
00877 const OctNode<NodeData,Real>* OctNode<NodeData,Real>::__faceNeighbor(int dir,int off) const {
00878 if(!parent){return NULL;}
00879 int pIndex=int(this-parent->children);
00880 pIndex^=(1<<dir);
00881 if((pIndex & (1<<dir))==(off<<dir)){return &parent->children[pIndex];}
00882 else{
00883 const OctNode* temp=parent->__faceNeighbor(dir,off);
00884 if(!temp || !temp->children){return temp;}
00885 else{return &temp->children[pIndex];}
00886 }
00887 }
00888
00889 template <class NodeData,class Real>
00890 OctNode<NodeData,Real>* OctNode<NodeData,Real>::edgeNeighbor(int edgeIndex,int forceChildren){
00891 int idx[2],o,i[2];
00892 Cube::FactorEdgeIndex(edgeIndex,o,i[0],i[1]);
00893 switch(o){
00894 case 0: idx[0]=1; idx[1]=2; break;
00895 case 1: idx[0]=0; idx[1]=2; break;
00896 case 2: idx[0]=0; idx[1]=1; break;
00897 };
00898 return __edgeNeighbor(o,i,idx,forceChildren);
00899 }
00900 template <class NodeData,class Real>
00901 const OctNode<NodeData,Real>* OctNode<NodeData,Real>::edgeNeighbor(int edgeIndex) const {
00902 int idx[2],o,i[2];
00903 Cube::FactorEdgeIndex(edgeIndex,o,i[0],i[1]);
00904 switch(o){
00905 case 0: idx[0]=1; idx[1]=2; break;
00906 case 1: idx[0]=0; idx[1]=2; break;
00907 case 2: idx[0]=0; idx[1]=1; break;
00908 };
00909 return __edgeNeighbor(o,i,idx);
00910 }
00911 template <class NodeData,class Real>
00912 const OctNode<NodeData,Real>* OctNode<NodeData,Real>::__edgeNeighbor(int o,const int i[2],const int idx[2]) const{
00913 if(!parent){return NULL;}
00914 int pIndex=int(this-parent->children);
00915 int aIndex,x[DIMENSION];
00916
00917 Cube::FactorCornerIndex(pIndex,x[0],x[1],x[2]);
00918 aIndex=(~((i[0] ^ x[idx[0]]) | ((i[1] ^ x[idx[1]])<<1))) & 3;
00919 pIndex^=(7 ^ (1<<o));
00920 if(aIndex==1) {
00921 const OctNode* temp=parent->__faceNeighbor(idx[0],i[0]);
00922 if(!temp || !temp->children){return NULL;}
00923 else{return &temp->children[pIndex];}
00924 }
00925 else if(aIndex==2) {
00926 const OctNode* temp=parent->__faceNeighbor(idx[1],i[1]);
00927 if(!temp || !temp->children){return NULL;}
00928 else{return &temp->children[pIndex];}
00929 }
00930 else if(aIndex==0) {
00931 return &parent->children[pIndex];
00932 }
00933 else if(aIndex==3) {
00934 const OctNode* temp=parent->__edgeNeighbor(o,i,idx);
00935 if(!temp || !temp->children){return temp;}
00936 else{return &temp->children[pIndex];}
00937 }
00938 else{return NULL;}
00939 }
00940 template <class NodeData,class Real>
00941 OctNode<NodeData,Real>* OctNode<NodeData,Real>::__edgeNeighbor(int o,const int i[2],const int idx[2],int forceChildren){
00942 if(!parent){return NULL;}
00943 int pIndex=int(this-parent->children);
00944 int aIndex,x[DIMENSION];
00945
00946 Cube::FactorCornerIndex(pIndex,x[0],x[1],x[2]);
00947 aIndex=(~((i[0] ^ x[idx[0]]) | ((i[1] ^ x[idx[1]])<<1))) & 3;
00948 pIndex^=(7 ^ (1<<o));
00949 if(aIndex==1) {
00950 OctNode* temp=parent->__faceNeighbor(idx[0],i[0],0);
00951 if(!temp || !temp->children){return NULL;}
00952 else{return &temp->children[pIndex];}
00953 }
00954 else if(aIndex==2) {
00955 OctNode* temp=parent->__faceNeighbor(idx[1],i[1],0);
00956 if(!temp || !temp->children){return NULL;}
00957 else{return &temp->children[pIndex];}
00958 }
00959 else if(aIndex==0) {
00960 return &parent->children[pIndex];
00961 }
00962 else if(aIndex==3) {
00963 OctNode* temp=parent->__edgeNeighbor(o,i,idx,forceChildren);
00964 if(!temp){return NULL;}
00965 if(!temp->children){
00966 if(forceChildren){temp->initChildren();}
00967 else{return temp;}
00968 }
00969 return &temp->children[pIndex];
00970 }
00971 else{return NULL;}
00972 }
00973
00974 template <class NodeData,class Real>
00975 const OctNode<NodeData,Real>* OctNode<NodeData,Real>::cornerNeighbor(int cornerIndex) const {
00976 int pIndex,aIndex=0;
00977 if(!parent){return NULL;}
00978
00979 pIndex=int(this-parent->children);
00980 aIndex=(cornerIndex ^ pIndex);
00981 pIndex=(~pIndex)&7;
00982 if(aIndex==7){
00983 return &parent->children[pIndex];
00984 }
00985 else if(aIndex==0){
00986 const OctNode* temp=((const OctNode*)parent)->cornerNeighbor(cornerIndex);
00987 if(!temp || !temp->children){return temp;}
00988 else{return &temp->children[pIndex];}
00989 }
00990 else if(aIndex==6){
00991 const OctNode* temp=((const OctNode*)parent)->__faceNeighbor(0,cornerIndex & 1);
00992 if(!temp || !temp->children){return NULL;}
00993 else{return & temp->children[pIndex];}
00994 }
00995 else if(aIndex==5){
00996 const OctNode* temp=((const OctNode*)parent)->__faceNeighbor(1,(cornerIndex & 2)>>1);
00997 if(!temp || !temp->children){return NULL;}
00998 else{return & temp->children[pIndex];}
00999 }
01000 else if(aIndex==3){
01001 const OctNode* temp=((const OctNode*)parent)->__faceNeighbor(2,(cornerIndex & 4)>>2);
01002 if(!temp || !temp->children){return NULL;}
01003 else{return & temp->children[pIndex];}
01004 }
01005 else if(aIndex==4){
01006 const OctNode* temp=((const OctNode*)parent)->edgeNeighbor(8 | (cornerIndex & 1) | (cornerIndex & 2) );
01007 if(!temp || !temp->children){return NULL;}
01008 else{return & temp->children[pIndex];}
01009 }
01010 else if(aIndex==2){
01011 const OctNode* temp=((const OctNode*)parent)->edgeNeighbor(4 | (cornerIndex & 1) | ((cornerIndex & 4)>>1) );
01012 if(!temp || !temp->children){return NULL;}
01013 else{return & temp->children[pIndex];}
01014 }
01015 else if(aIndex==1){
01016 const OctNode* temp=((const OctNode*)parent)->edgeNeighbor(((cornerIndex & 2) | (cornerIndex & 4))>>1 );
01017 if(!temp || !temp->children){return NULL;}
01018 else{return & temp->children[pIndex];}
01019 }
01020 else{return NULL;}
01021 }
01022 template <class NodeData,class Real>
01023 OctNode<NodeData,Real>* OctNode<NodeData,Real>::cornerNeighbor(int cornerIndex,int forceChildren){
01024 int pIndex,aIndex=0;
01025 if(!parent){return NULL;}
01026
01027 pIndex=int(this-parent->children);
01028 aIndex=(cornerIndex ^ pIndex);
01029 pIndex=(~pIndex)&7;
01030 if(aIndex==7){
01031 return &parent->children[pIndex];
01032 }
01033 else if(aIndex==0){
01034 OctNode* temp=((OctNode*)parent)->cornerNeighbor(cornerIndex,forceChildren);
01035 if(!temp){return NULL;}
01036 if(!temp->children){
01037 if(forceChildren){temp->initChildren();}
01038 else{return temp;}
01039 }
01040 return &temp->children[pIndex];
01041 }
01042 else if(aIndex==6){
01043 OctNode* temp=((OctNode*)parent)->__faceNeighbor(0,cornerIndex & 1,0);
01044 if(!temp || !temp->children){return NULL;}
01045 else{return & temp->children[pIndex];}
01046 }
01047 else if(aIndex==5){
01048 OctNode* temp=((OctNode*)parent)->__faceNeighbor(1,(cornerIndex & 2)>>1,0);
01049 if(!temp || !temp->children){return NULL;}
01050 else{return & temp->children[pIndex];}
01051 }
01052 else if(aIndex==3){
01053 OctNode* temp=((OctNode*)parent)->__faceNeighbor(2,(cornerIndex & 4)>>2,0);
01054 if(!temp || !temp->children){return NULL;}
01055 else{return & temp->children[pIndex];}
01056 }
01057 else if(aIndex==4){
01058 OctNode* temp=((OctNode*)parent)->edgeNeighbor(8 | (cornerIndex & 1) | (cornerIndex & 2) );
01059 if(!temp || !temp->children){return NULL;}
01060 else{return & temp->children[pIndex];}
01061 }
01062 else if(aIndex==2){
01063 OctNode* temp=((OctNode*)parent)->edgeNeighbor(4 | (cornerIndex & 1) | ((cornerIndex & 4)>>1) );
01064 if(!temp || !temp->children){return NULL;}
01065 else{return & temp->children[pIndex];}
01066 }
01067 else if(aIndex==1){
01068 OctNode* temp=((OctNode*)parent)->edgeNeighbor(((cornerIndex & 2) | (cornerIndex & 4))>>1 );
01069 if(!temp || !temp->children){return NULL;}
01070 else{return & temp->children[pIndex];}
01071 }
01072 else{return NULL;}
01073 }
01075
01077 template<class NodeData,class Real>
01078 OctNode<NodeData,Real>::Neighbors3::Neighbors3(void){clear();}
01079 template<class NodeData,class Real>
01080 void OctNode<NodeData,Real>::Neighbors3::clear(void){
01081 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;}}}
01082 }
01083 template<class NodeData,class Real>
01084 OctNode<NodeData,Real>::NeighborKey3::NeighborKey3(void){ neighbors=NULL; }
01085 template<class NodeData,class Real>
01086 OctNode<NodeData,Real>::NeighborKey3::~NeighborKey3(void)
01087 {
01088 if( neighbors ) delete[] neighbors;
01089 neighbors = NULL;
01090 }
01091
01092 template<class NodeData,class Real>
01093 void OctNode<NodeData,Real>::NeighborKey3::set( int d )
01094 {
01095 if( neighbors ) delete[] neighbors;
01096 neighbors = NULL;
01097 if( d<0 ) return;
01098 neighbors = new Neighbors3[d+1];
01099 }
01100 template< class NodeData , class Real >
01101 typename OctNode<NodeData,Real>::Neighbors3& OctNode<NodeData,Real>::NeighborKey3::setNeighbors( OctNode<NodeData,Real>* root , Point3D< Real > p , int d )
01102 {
01103 if( !neighbors[d].neighbors[1][1][1] || !neighbors[d].neighbors[1][1][1]->isInside( p ) )
01104 {
01105 neighbors[d].clear();
01106
01107 if( !d ) neighbors[d].neighbors[1][1][1] = root;
01108 else
01109 {
01110 Neighbors3& temp = setNeighbors( root , p , d-1 );
01111
01112 int i , j , k , x1 , y1 , z1 , x2 , y2 , z2;
01113 Point3D< Real > c;
01114 Real w;
01115 temp.neighbors[1][1][1]->centerAndWidth( c , w );
01116 int idx = CornerIndex( c , p );
01117 Cube::FactorCornerIndex( idx , x1 , y1 , z1 );
01118 Cube::FactorCornerIndex( (~idx)&7 , x2 , y2 , z2 );
01119
01120 if( !temp.neighbors[1][1][1]->children ) temp.neighbors[1][1][1]->initChildren();
01121 for( i=0 ; i<2 ; i++ ) for( j=0 ; j<2 ; j++ ) for( k=0 ; k<2 ; k++ )
01122 neighbors[d].neighbors[x2+i][y2+j][z2+k] = &temp.neighbors[1][1][1]->children[Cube::CornerIndex(i,j,k)];
01123
01124
01125
01126 i=x1<<1;
01127 if( temp.neighbors[i][1][1] )
01128 {
01129 if( !temp.neighbors[i][1][1]->children ) temp.neighbors[i][1][1]->initChildren();
01130 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)];
01131 }
01132 j=y1<<1;
01133 if( temp.neighbors[1][j][1] )
01134 {
01135 if( !temp.neighbors[1][j][1]->children ) temp.neighbors[1][j][1]->initChildren();
01136 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)];
01137 }
01138 k=z1<<1;
01139 if( temp.neighbors[1][1][k] )
01140 {
01141 if( !temp.neighbors[1][1][k]->children ) temp.neighbors[1][1][k]->initChildren();
01142 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)];
01143 }
01144
01145
01146 i=x1<<1 , j=y1<<1;
01147 if( temp.neighbors[i][j][1] )
01148 {
01149 if( !temp.neighbors[i][j][1]->children ) temp.neighbors[i][j][1]->initChildren();
01150 for( k=0 ; k<2 ; k++ ) neighbors[d].neighbors[i][j][z2+k] = &temp.neighbors[i][j][1]->children[Cube::CornerIndex(x2,y2,k)];
01151 }
01152 i=x1<<1 , k=z1<<1;
01153 if( temp.neighbors[i][1][k] )
01154 {
01155 if( !temp.neighbors[i][1][k]->children ) temp.neighbors[i][1][k]->initChildren();
01156 for( j=0 ; j<2 ; j++ ) neighbors[d].neighbors[i][y2+j][k] = &temp.neighbors[i][1][k]->children[Cube::CornerIndex(x2,j,z2)];
01157 }
01158 j=y1<<1 , k=z1<<1;
01159 if( temp.neighbors[1][j][k] )
01160 {
01161 if( !temp.neighbors[1][j][k]->children ) temp.neighbors[1][j][k]->initChildren();
01162 for( i=0 ; i<2 ; i++ ) neighbors[d].neighbors[x2+i][j][k] = &temp.neighbors[1][j][k]->children[Cube::CornerIndex(i,y2,z2)];
01163 }
01164
01165
01166 i=x1<<1 , j=y1<<1 , k=z1<<1;
01167 if( temp.neighbors[i][j][k] )
01168 {
01169 if( !temp.neighbors[i][j][k]->children ) temp.neighbors[i][j][k]->initChildren();
01170 neighbors[d].neighbors[i][j][k] = &temp.neighbors[i][j][k]->children[Cube::CornerIndex(x2,y2,z2)];
01171 }
01172 }
01173 }
01174 return neighbors[d];
01175 }
01176 template< class NodeData , class Real >
01177 typename OctNode<NodeData,Real>::Neighbors3& OctNode<NodeData,Real>::NeighborKey3::getNeighbors( OctNode<NodeData,Real>* root , Point3D< Real > p , int d )
01178 {
01179 if( !neighbors[d].neighbors[1][1][1] || !neighbors[d].neighbors[1][1][1]->isInside( p ) )
01180 {
01181 neighbors[d].clear();
01182
01183 if( !d ) neighbors[d].neighbors[1][1][1] = root;
01184 else
01185 {
01186 Neighbors3& temp = getNeighbors( root , p , d-1 );
01187
01188 int i , j , k , x1 , y1 , z1 , x2 , y2 , z2;
01189 Point3D< Real > c;
01190 Real w;
01191 temp.neighbors[1][1][1]->centerAndWidth( c , w );
01192 int idx = CornerIndex( c , p );
01193 Cube::FactorCornerIndex( idx , x1 , y1 , z1 );
01194 Cube::FactorCornerIndex( (~idx)&7 , x2 , y2 , z2 );
01195
01196 if( !temp.neighbors[1][1][1] || !temp.neighbors[1][1][1]->children )
01197 {
01198 fprintf( stderr , "[ERROR] Couldn't find node at appropriate depth\n" );
01199 exit( 0 );
01200 }
01201 for( i=0 ; i<2 ; i++ ) for( j=0 ; j<2 ; j++ ) for( k=0 ; k<2 ; k++ )
01202 neighbors[d].neighbors[x2+i][y2+j][z2+k] = &temp.neighbors[1][1][1]->children[Cube::CornerIndex(i,j,k)];
01203
01204
01205
01206 i=x1<<1;
01207 if( temp.neighbors[i][1][1] )
01208 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)];
01209 j=y1<<1;
01210 if( temp.neighbors[1][j][1] )
01211 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)];
01212 k=z1<<1;
01213 if( temp.neighbors[1][1][k] )
01214 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)];
01215
01216
01217 i=x1<<1 , j=y1<<1;
01218 if( temp.neighbors[i][j][1] )
01219 for( k=0 ; k<2 ; k++ ) neighbors[d].neighbors[i][j][z2+k] = &temp.neighbors[i][j][1]->children[Cube::CornerIndex(x2,y2,k)];
01220 i=x1<<1 , k=z1<<1;
01221 if( temp.neighbors[i][1][k] )
01222 for( j=0 ; j<2 ; j++ ) neighbors[d].neighbors[i][y2+j][k] = &temp.neighbors[i][1][k]->children[Cube::CornerIndex(x2,j,z2)];
01223 j=y1<<1 , k=z1<<1;
01224 if( temp.neighbors[1][j][k] )
01225 for( i=0 ; i<2 ; i++ ) neighbors[d].neighbors[x2+i][j][k] = &temp.neighbors[1][j][k]->children[Cube::CornerIndex(i,y2,z2)];
01226
01227
01228 i=x1<<1 , j=y1<<1 , k=z1<<1;
01229 if( temp.neighbors[i][j][k] )
01230 neighbors[d].neighbors[i][j][k] = &temp.neighbors[i][j][k]->children[Cube::CornerIndex(x2,y2,z2)];
01231 }
01232 }
01233 return neighbors[d];
01234 }
01235
01236 template< class NodeData , class Real >
01237 typename OctNode<NodeData,Real>::Neighbors3& OctNode<NodeData,Real>::NeighborKey3::setNeighbors( OctNode<NodeData,Real>* node )
01238 {
01239 int d = node->depth();
01240 if( node==neighbors[d].neighbors[1][1][1] )
01241 {
01242 bool reset = false;
01243 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;
01244 if( reset ) neighbors[d].neighbors[1][1][1] = NULL;
01245 }
01246 if( node!=neighbors[d].neighbors[1][1][1] )
01247 {
01248 neighbors[d].clear();
01249
01250 if( !node->parent ) neighbors[d].neighbors[1][1][1] = node;
01251 else
01252 {
01253 int i,j,k,x1,y1,z1,x2,y2,z2;
01254 int idx=int(node-node->parent->children);
01255 Cube::FactorCornerIndex( idx ,x1,y1,z1);
01256 Cube::FactorCornerIndex((~idx)&7,x2,y2,z2);
01257 for(i=0;i<2;i++){
01258 for(j=0;j<2;j++){
01259 for(k=0;k<2;k++){
01260 neighbors[d].neighbors[x2+i][y2+j][z2+k]=&node->parent->children[Cube::CornerIndex(i,j,k)];
01261 }
01262 }
01263 }
01264 Neighbors3& temp=setNeighbors(node->parent);
01265
01266
01267 i=x1<<1;
01268 if(temp.neighbors[i][1][1]){
01269 if(!temp.neighbors[i][1][1]->children){temp.neighbors[i][1][1]->initChildren();}
01270 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)];}}
01271 }
01272 j=y1<<1;
01273 if(temp.neighbors[1][j][1]){
01274 if(!temp.neighbors[1][j][1]->children){temp.neighbors[1][j][1]->initChildren();}
01275 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)];}}
01276 }
01277 k=z1<<1;
01278 if(temp.neighbors[1][1][k]){
01279 if(!temp.neighbors[1][1][k]->children){temp.neighbors[1][1][k]->initChildren();}
01280 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)];}}
01281 }
01282
01283
01284 i=x1<<1; j=y1<<1;
01285 if(temp.neighbors[i][j][1]){
01286 if(!temp.neighbors[i][j][1]->children){temp.neighbors[i][j][1]->initChildren();}
01287 for(k=0;k<2;k++){neighbors[d].neighbors[i][j][z2+k]=&temp.neighbors[i][j][1]->children[Cube::CornerIndex(x2,y2,k)];}
01288 }
01289 i=x1<<1; k=z1<<1;
01290 if(temp.neighbors[i][1][k]){
01291 if(!temp.neighbors[i][1][k]->children){temp.neighbors[i][1][k]->initChildren();}
01292 for(j=0;j<2;j++){neighbors[d].neighbors[i][y2+j][k]=&temp.neighbors[i][1][k]->children[Cube::CornerIndex(x2,j,z2)];}
01293 }
01294 j=y1<<1; k=z1<<1;
01295 if(temp.neighbors[1][j][k]){
01296 if(!temp.neighbors[1][j][k]->children){temp.neighbors[1][j][k]->initChildren();}
01297 for(i=0;i<2;i++){neighbors[d].neighbors[x2+i][j][k]=&temp.neighbors[1][j][k]->children[Cube::CornerIndex(i,y2,z2)];}
01298 }
01299
01300
01301 i=x1<<1; j=y1<<1; k=z1<<1;
01302 if(temp.neighbors[i][j][k]){
01303 if(!temp.neighbors[i][j][k]->children){temp.neighbors[i][j][k]->initChildren();}
01304 neighbors[d].neighbors[i][j][k]=&temp.neighbors[i][j][k]->children[Cube::CornerIndex(x2,y2,z2)];
01305 }
01306 }
01307 }
01308 return neighbors[d];
01309 }
01310
01311
01312 template< class NodeData , class Real >
01313 typename OctNode<NodeData,Real>::Neighbors3& OctNode<NodeData,Real>::NeighborKey3::setNeighbors( OctNode<NodeData,Real>* node , bool flags[3][3][3] )
01314 {
01315 int d = node->depth();
01316 if( node==neighbors[d].neighbors[1][1][1] )
01317 {
01318 bool reset = false;
01319 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;
01320 if( reset ) neighbors[d].neighbors[1][1][1] = NULL;
01321 }
01322 if( node!=neighbors[d].neighbors[1][1][1] )
01323 {
01324 neighbors[d].clear();
01325
01326 if( !node->parent ) neighbors[d].neighbors[1][1][1] = node;
01327 else
01328 {
01329 int x1,y1,z1,x2,y2,z2;
01330 int idx=int(node-node->parent->children);
01331 Cube::FactorCornerIndex( idx ,x1,y1,z1);
01332 Cube::FactorCornerIndex((~idx)&7,x2,y2,z2);
01333 for( int i=0 ; i<2 ; i++ )
01334 for( int j=0 ; j<2 ; j++ )
01335 for( int k=0 ; k<2 ; k++ )
01336 neighbors[d].neighbors[x2+i][y2+j][z2+k]=&node->parent->children[Cube::CornerIndex(i,j,k)];
01337
01338 Neighbors3& temp=setNeighbors( node->parent , flags );
01339
01340
01341 {
01342 int i=x1<<1;
01343 if( temp.neighbors[i][1][1] )
01344 {
01345 if( flags[i][1][1] && !temp.neighbors[i][1][1]->children ) temp.neighbors[i][1][1]->initChildren();
01346 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)];
01347 }
01348 }
01349 {
01350 int j = y1<<1;
01351 if( temp.neighbors[1][j][1] )
01352 {
01353 if( flags[1][j][1] && !temp.neighbors[1][j][1]->children ) temp.neighbors[1][j][1]->initChildren();
01354 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)];
01355 }
01356 }
01357 {
01358 int k = z1<<1;
01359 if( temp.neighbors[1][1][k] )
01360 {
01361 if( flags[1][1][k] && !temp.neighbors[1][1][k]->children ) temp.neighbors[1][1][k]->initChildren();
01362 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)];
01363 }
01364 }
01365
01366
01367 {
01368 int i=x1<<1 , j=y1<<1;
01369 if( temp.neighbors[i][j][1] )
01370 {
01371 if( flags[i][j][1] && !temp.neighbors[i][j][1]->children ) temp.neighbors[i][j][1]->initChildren();
01372 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)];
01373 }
01374 }
01375 {
01376 int i=x1<<1 , k=z1<<1;
01377 if( temp.neighbors[i][1][k] )
01378 {
01379 if( flags[i][1][k] && !temp.neighbors[i][1][k]->children ) temp.neighbors[i][1][k]->initChildren();
01380 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)];
01381 }
01382 }
01383 {
01384 int j=y1<<1 , k=z1<<1;
01385 if( temp.neighbors[1][j][k] )
01386 {
01387 if( flags[1][j][k] && !temp.neighbors[1][j][k]->children ) temp.neighbors[1][j][k]->initChildren();
01388 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)];
01389 }
01390 }
01391
01392
01393 {
01394 int i=x1<<1 , j=y1<<1 , k=z1<<1;
01395 if( temp.neighbors[i][j][k] )
01396 {
01397 if( flags[i][j][k] && !temp.neighbors[i][j][k]->children ) temp.neighbors[i][j][k]->initChildren();
01398 if( temp.neighbors[i][j][k]->children ) neighbors[d].neighbors[i][j][k] = &temp.neighbors[i][j][k]->children[Cube::CornerIndex(x2,y2,z2)];
01399 }
01400 }
01401 }
01402 }
01403 return neighbors[d];
01404 }
01405
01406 template<class NodeData,class Real>
01407 typename OctNode<NodeData,Real>::Neighbors3& OctNode<NodeData,Real>::NeighborKey3::getNeighbors(OctNode<NodeData,Real>* node){
01408 int d=node->depth();
01409 if(node!=neighbors[d].neighbors[1][1][1]){
01410 neighbors[d].clear();
01411
01412 if(!node->parent){neighbors[d].neighbors[1][1][1]=node;}
01413 else{
01414 int i,j,k,x1,y1,z1,x2,y2,z2;
01415 int idx=int(node-node->parent->children);
01416 Cube::FactorCornerIndex( idx ,x1,y1,z1);
01417 Cube::FactorCornerIndex((~idx)&7,x2,y2,z2);
01418 for(i=0;i<2;i++){
01419 for(j=0;j<2;j++){
01420 for(k=0;k<2;k++){
01421 neighbors[d].neighbors[x2+i][y2+j][z2+k]=&node->parent->children[Cube::CornerIndex(i,j,k)];
01422 }
01423 }
01424 }
01425 Neighbors3& temp=getNeighbors(node->parent);
01426
01427
01428 i=x1<<1;
01429 if(temp.neighbors[i][1][1] && temp.neighbors[i][1][1]->children){
01430 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)];}}
01431 }
01432 j=y1<<1;
01433 if(temp.neighbors[1][j][1] && temp.neighbors[1][j][1]->children){
01434 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)];}}
01435 }
01436 k=z1<<1;
01437 if(temp.neighbors[1][1][k] && temp.neighbors[1][1][k]->children){
01438 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)];}}
01439 }
01440
01441
01442 i=x1<<1; j=y1<<1;
01443 if(temp.neighbors[i][j][1] && temp.neighbors[i][j][1]->children){
01444 for(k=0;k<2;k++){neighbors[d].neighbors[i][j][z2+k]=&temp.neighbors[i][j][1]->children[Cube::CornerIndex(x2,y2,k)];}
01445 }
01446 i=x1<<1; k=z1<<1;
01447 if(temp.neighbors[i][1][k] && temp.neighbors[i][1][k]->children){
01448 for(j=0;j<2;j++){neighbors[d].neighbors[i][y2+j][k]=&temp.neighbors[i][1][k]->children[Cube::CornerIndex(x2,j,z2)];}
01449 }
01450 j=y1<<1; k=z1<<1;
01451 if(temp.neighbors[1][j][k] && temp.neighbors[1][j][k]->children){
01452 for(i=0;i<2;i++){neighbors[d].neighbors[x2+i][j][k]=&temp.neighbors[1][j][k]->children[Cube::CornerIndex(i,y2,z2)];}
01453 }
01454
01455
01456 i=x1<<1; j=y1<<1; k=z1<<1;
01457 if(temp.neighbors[i][j][k] && temp.neighbors[i][j][k]->children){
01458 neighbors[d].neighbors[i][j][k]=&temp.neighbors[i][j][k]->children[Cube::CornerIndex(x2,y2,z2)];
01459 }
01460 }
01461 }
01462 return neighbors[node->depth()];
01463 }
01464
01466
01468 template<class NodeData,class Real>
01469 OctNode<NodeData,Real>::ConstNeighbors3::ConstNeighbors3(void){clear();}
01470 template<class NodeData,class Real>
01471 void OctNode<NodeData,Real>::ConstNeighbors3::clear(void){
01472 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;}}}
01473 }
01474 template<class NodeData,class Real>
01475 OctNode<NodeData,Real>::ConstNeighborKey3::ConstNeighborKey3(void){neighbors=NULL;}
01476 template<class NodeData,class Real>
01477 OctNode<NodeData,Real>::ConstNeighborKey3::~ConstNeighborKey3(void){
01478 if(neighbors){delete[] neighbors;}
01479 neighbors=NULL;
01480 }
01481
01482 template<class NodeData,class Real>
01483 void OctNode<NodeData,Real>::ConstNeighborKey3::set(int d){
01484 if(neighbors){delete[] neighbors;}
01485 neighbors=NULL;
01486 if(d<0){return;}
01487 neighbors=new ConstNeighbors3[d+1];
01488 }
01489 template<class NodeData,class Real>
01490 typename OctNode<NodeData,Real>::ConstNeighbors3& OctNode<NodeData,Real>::ConstNeighborKey3::getNeighbors(const OctNode<NodeData,Real>* node){
01491 int d=node->depth();
01492 if(node!=neighbors[d].neighbors[1][1][1]){
01493 neighbors[d].clear();
01494
01495 if(!node->parent){neighbors[d].neighbors[1][1][1]=node;}
01496 else{
01497 int i,j,k,x1,y1,z1,x2,y2,z2;
01498 int idx=int(node-node->parent->children);
01499 Cube::FactorCornerIndex( idx ,x1,y1,z1);
01500 Cube::FactorCornerIndex((~idx)&7,x2,y2,z2);
01501 for(i=0;i<2;i++){
01502 for(j=0;j<2;j++){
01503 for(k=0;k<2;k++){
01504 neighbors[d].neighbors[x2+i][y2+j][z2+k]=&node->parent->children[Cube::CornerIndex(i,j,k)];
01505 }
01506 }
01507 }
01508 ConstNeighbors3& temp=getNeighbors(node->parent);
01509
01510
01511 i=x1<<1;
01512 if(temp.neighbors[i][1][1] && temp.neighbors[i][1][1]->children){
01513 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)];}}
01514 }
01515 j=y1<<1;
01516 if(temp.neighbors[1][j][1] && temp.neighbors[1][j][1]->children){
01517 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)];}}
01518 }
01519 k=z1<<1;
01520 if(temp.neighbors[1][1][k] && temp.neighbors[1][1][k]->children){
01521 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)];}}
01522 }
01523
01524
01525 i=x1<<1; j=y1<<1;
01526 if(temp.neighbors[i][j][1] && temp.neighbors[i][j][1]->children){
01527 for(k=0;k<2;k++){neighbors[d].neighbors[i][j][z2+k]=&temp.neighbors[i][j][1]->children[Cube::CornerIndex(x2,y2,k)];}
01528 }
01529 i=x1<<1; k=z1<<1;
01530 if(temp.neighbors[i][1][k] && temp.neighbors[i][1][k]->children){
01531 for(j=0;j<2;j++){neighbors[d].neighbors[i][y2+j][k]=&temp.neighbors[i][1][k]->children[Cube::CornerIndex(x2,j,z2)];}
01532 }
01533 j=y1<<1; k=z1<<1;
01534 if(temp.neighbors[1][j][k] && temp.neighbors[1][j][k]->children){
01535 for(i=0;i<2;i++){neighbors[d].neighbors[x2+i][j][k]=&temp.neighbors[1][j][k]->children[Cube::CornerIndex(i,y2,z2)];}
01536 }
01537
01538
01539 i=x1<<1; j=y1<<1; k=z1<<1;
01540 if(temp.neighbors[i][j][k] && temp.neighbors[i][j][k]->children){
01541 neighbors[d].neighbors[i][j][k]=&temp.neighbors[i][j][k]->children[Cube::CornerIndex(x2,y2,z2)];
01542 }
01543 }
01544 }
01545 return neighbors[node->depth()];
01546 }
01547 template<class NodeData,class Real>
01548 typename OctNode<NodeData,Real>::ConstNeighbors3& OctNode<NodeData,Real>::ConstNeighborKey3::getNeighbors( const OctNode<NodeData,Real>* node , int minDepth )
01549 {
01550 int d=node->depth();
01551 if( d<minDepth ) fprintf( stderr , "[ERROR] Node depth lower than min-depth: %d < %d\n" , d , minDepth ) , exit( 0 );
01552 if( node!=neighbors[d].neighbors[1][1][1] )
01553 {
01554 neighbors[d].clear();
01555
01556 if( d==minDepth ) neighbors[d].neighbors[1][1][1]=node;
01557 else
01558 {
01559 int i,j,k,x1,y1,z1,x2,y2,z2;
01560 int idx = int(node-node->parent->children);
01561 Cube::FactorCornerIndex( idx ,x1,y1,z1);
01562 Cube::FactorCornerIndex((~idx)&7,x2,y2,z2);
01563
01564 ConstNeighbors3& temp=getNeighbors( node->parent , minDepth );
01565
01566
01567 for( i=0 ; i<2 ; i++ ) for( j=0 ; j<2 ; j++ ) for( k=0 ; k<2 ; k++ )
01568 neighbors[d].neighbors[x2+i][y2+j][z2+k] = &node->parent->children[ Cube::CornerIndex(i,j,k) ];
01569
01570
01571 i=x1<<1;
01572 if( temp.neighbors[i][1][1] && temp.neighbors[i][1][1]->children )
01573 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)];
01574
01575 j=y1<<1;
01576 if( temp.neighbors[1][j][1] && temp.neighbors[1][j][1]->children )
01577 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)];
01578
01579 k=z1<<1;
01580 if( temp.neighbors[1][1][k] && temp.neighbors[1][1][k]->children )
01581 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)];
01582
01583
01584 i=x1<<1 , j=y1<<1;
01585 if( temp.neighbors[i][j][1] && temp.neighbors[i][j][1]->children )
01586 for( k=0 ; k<2 ; k++ ) neighbors[d].neighbors[i][j][z2+k] = &temp.neighbors[i][j][1]->children[Cube::CornerIndex(x2,y2,k)];
01587
01588 i=x1<<1 , k=z1<<1;
01589 if( temp.neighbors[i][1][k] && temp.neighbors[i][1][k]->children )
01590 for( j=0 ; j<2 ; j++ ) neighbors[d].neighbors[i][y2+j][k] = &temp.neighbors[i][1][k]->children[Cube::CornerIndex(x2,j,z2)];
01591
01592 j=y1<<1 , k=z1<<1;
01593 if( temp.neighbors[1][j][k] && temp.neighbors[1][j][k]->children )
01594 for( i=0 ; i<2 ; i++ ) neighbors[d].neighbors[x2+i][j][k] = &temp.neighbors[1][j][k]->children[Cube::CornerIndex(i,y2,z2)];
01595
01596
01597 i=x1<<1 , j=y1<<1 , k=z1<<1;
01598 if( temp.neighbors[i][j][k] && temp.neighbors[i][j][k]->children )
01599 neighbors[d].neighbors[i][j][k] = &temp.neighbors[i][j][k]->children[Cube::CornerIndex(x2,y2,z2)];
01600 }
01601 }
01602 return neighbors[node->depth()];
01603 }
01604
01605 template< class NodeData , class Real > OctNode< NodeData , Real >::Neighbors5::Neighbors5( void ){ clear(); }
01606 template< class NodeData , class Real > OctNode< NodeData , Real >::ConstNeighbors5::ConstNeighbors5( void ){ clear(); }
01607 template< class NodeData , class Real >
01608 void OctNode< NodeData , Real >::Neighbors5::clear( void )
01609 {
01610 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;
01611 }
01612 template< class NodeData , class Real >
01613 void OctNode< NodeData , Real >::ConstNeighbors5::clear( void )
01614 {
01615 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;
01616 }
01617 template< class NodeData , class Real >
01618 OctNode< NodeData , Real >::NeighborKey5::NeighborKey5( void )
01619 {
01620 _depth = -1;
01621 neighbors = NULL;
01622 }
01623 template< class NodeData , class Real >
01624 OctNode< NodeData , Real >::ConstNeighborKey5::ConstNeighborKey5( void )
01625 {
01626 _depth = -1;
01627 neighbors = NULL;
01628 }
01629 template< class NodeData , class Real >
01630 OctNode< NodeData , Real >::NeighborKey5::~NeighborKey5( void )
01631 {
01632 if( neighbors ) delete[] neighbors;
01633 neighbors = NULL;
01634 }
01635 template< class NodeData , class Real >
01636 OctNode< NodeData , Real >::ConstNeighborKey5::~ConstNeighborKey5( void )
01637 {
01638 if( neighbors ) delete[] neighbors;
01639 neighbors = NULL;
01640 }
01641 template< class NodeData , class Real >
01642 void OctNode< NodeData , Real >::NeighborKey5::set( int d )
01643 {
01644 if( neighbors ) delete[] neighbors;
01645 neighbors = NULL;
01646 if(d<0) return;
01647 _depth = d;
01648 neighbors=new Neighbors5[d+1];
01649 }
01650 template< class NodeData , class Real >
01651 void OctNode< NodeData , Real >::ConstNeighborKey5::set( int d )
01652 {
01653 if( neighbors ) delete[] neighbors;
01654 neighbors = NULL;
01655 if(d<0) return;
01656 _depth = d;
01657 neighbors=new ConstNeighbors5[d+1];
01658 }
01659 template< class NodeData , class Real >
01660 typename OctNode< NodeData , Real >::Neighbors5& OctNode< NodeData , Real >::NeighborKey5::getNeighbors( OctNode* node )
01661 {
01662 int d=node->depth();
01663 if( node!=neighbors[d].neighbors[2][2][2] )
01664 {
01665 neighbors[d].clear();
01666
01667 if( !node->parent ) neighbors[d].neighbors[2][2][2]=node;
01668 else
01669 {
01670 getNeighbors( node->parent );
01671 Neighbors5& temp = neighbors[d-1];
01672 int x1 , y1 , z1 , x2 , y2 , z2;
01673 int idx = int( node - node->parent->children );
01674 Cube::FactorCornerIndex( idx , x1 , y1 , z1 );
01675
01676 Neighbors5& n = neighbors[d];
01677 Cube::FactorCornerIndex( (~idx)&7 , x2 , y2 , z2 );
01678 int i , j , k;
01679 int fx0 = x2+1 , fy0 = y2+1 , fz0 = z2+1;
01680 int cx1 = x1*2+1 , cy1 = y1*2+1 , cz1 = z1*2+1;
01681 int cx2 = x2*2+1 , cy2 = y2*2+1 , cz2 = z2*2+1;
01682 int fx1 = x1*3 , fy1 = y1*3 , fz1 = z1*3;
01683 int fx2 = x2*4 , fy2 = y2*4 , fz2 = z2*4;
01684
01685
01686 for( i=0 ; i<2 ; i++ ) for( j=0 ; j<2 ; j++ ) for( k=0 ; k<2 ; k++ )
01687 n.neighbors[fx0+i][fy0+j][fz0+k] = node->parent->children + Cube::CornerIndex( i , j , k );
01688
01689
01690 if( temp.neighbors[cx1][2][2] && temp.neighbors[cx1][2][2]->children )
01691 for( i=0 ; i<2 ; i++ ) for( j=0 ; j<2 ; j++ ) for( k=0 ; k<2 ; k++ )
01692 n.neighbors[fx1+i][fy0+j][fz0+k] = temp.neighbors[cx1][2][2]->children + Cube::CornerIndex( i , j , k );
01693 if( temp.neighbors[2][cy1][2] && temp.neighbors[2][cy1][2]->children )
01694 for( i=0 ; i<2 ; i++ ) for( j=0 ; j<2 ; j++ ) for( k=0 ; k<2 ; k++ )
01695 n.neighbors[fx0+i][fy1+j][fz0+k] = temp.neighbors[2][cy1][2]->children + Cube::CornerIndex( i , j , k );
01696 if( temp.neighbors[2][2][cz1] && temp.neighbors[2][2][cz1]->children )
01697 for( i=0 ; i<2 ; i++ ) for( j=0 ; j<2 ; j++ ) for( k=0 ; k<2 ; k++ )
01698 n.neighbors[fx0+i][fy0+j][fz1+k] = temp.neighbors[2][2][cz1]->children + Cube::CornerIndex( i , j , k );
01699 if( temp.neighbors[cx2][2][2] && temp.neighbors[cx2][2][2]->children )
01700 for( j=0 ; j<2 ; j++ ) for( k=0 ; k<2 ; k++ )
01701 n.neighbors[fx2 ][fy0+j][fz0+k] = temp.neighbors[cx2][2][2]->children + Cube::CornerIndex( x1 , j , k );
01702 if( temp.neighbors[2][cy2][2] && temp.neighbors[2][cy2][2]->children )
01703 for( i=0 ; i<2 ; i++ ) for( k=0 ; k<2 ; k++ )
01704 n.neighbors[fx0+i][fy2 ][fz0+k] = temp.neighbors[2][cy2][2]->children + Cube::CornerIndex( i , y1 , k );
01705 if( temp.neighbors[2][2][cz2] && temp.neighbors[2][2][cz2]->children )
01706 for( i=0 ; i<2 ; i++ ) for( j=0 ; j<2 ; j++ )
01707 n.neighbors[fx0+i][fy0+j][fz2 ] = temp.neighbors[2][2][cz2]->children + Cube::CornerIndex( i , j , z1 );
01708
01709
01710 if( temp.neighbors[cx1][cy1][2] && temp.neighbors[cx1][cy1][2]->children )
01711 for( i=0 ; i<2 ; i++ ) for( j=0 ; j<2 ; j++ ) for( k=0 ; k<2 ; k++ )
01712 n.neighbors[fx1+i][fy1+j][fz0+k] = temp.neighbors[cx1][cy1][2]->children + Cube::CornerIndex( i , j , k );
01713 if( temp.neighbors[cx1][2][cz1] && temp.neighbors[cx1][2][cz1]->children )
01714 for( i=0 ; i<2 ; i++ ) for( j=0 ; j<2 ; j++ ) for( k=0 ; k<2 ; k++ )
01715 n.neighbors[fx1+i][fy0+j][fz1+k] = temp.neighbors[cx1][2][cz1]->children + Cube::CornerIndex( i , j , k );
01716 if( temp.neighbors[2][cy1][cz1] && temp.neighbors[2][cy1][cz1]->children )
01717 for( i=0 ; i<2 ; i++ ) for( j=0 ; j<2 ; j++ ) for( k=0 ; k<2 ; k++ )
01718 n.neighbors[fx0+i][fy1+j][fz1+k] = temp.neighbors[2][cy1][cz1]->children + Cube::CornerIndex( i , j , k );
01719 if( temp.neighbors[cx1][cy2][2] && temp.neighbors[cx1][cy2][2]->children )
01720 for( i=0 ; i<2 ; i++ ) for( k=0 ; k<2 ; k++ )
01721 n.neighbors[fx1+i][fy2 ][fz0+k] = temp.neighbors[cx1][cy2][2]->children + Cube::CornerIndex( i , y1 , k );
01722 if( temp.neighbors[cx1][2][cz2] && temp.neighbors[cx1][2][cz2]->children )
01723 for( i=0 ; i<2 ; i++ ) for( j=0 ; j<2 ; j++ )
01724 n.neighbors[fx1+i][fy0+j][fz2 ] = temp.neighbors[cx1][2][cz2]->children + Cube::CornerIndex( i , j , z1 );
01725 if( temp.neighbors[cx2][cy1][2] && temp.neighbors[cx2][cy1][2]->children )
01726 for( j=0 ; j<2 ; j++ ) for( k=0 ; k<2 ; k++ )
01727 n.neighbors[fx2 ][fy1+j][fz0+k] = temp.neighbors[cx2][cy1][2]->children + Cube::CornerIndex( x1 , j , k );
01728 if( temp.neighbors[2][cy1][cz2] && temp.neighbors[2][cy1][cz2]->children )
01729 for( i=0 ; i<2 ; i++ ) for( j=0 ; j<2 ; j++ )
01730 n.neighbors[fx0+i][fy1+j][fz2 ] = temp.neighbors[2][cy1][cz2]->children + Cube::CornerIndex( i , j , z1 );
01731 if( temp.neighbors[cx2][2][cz1] && temp.neighbors[cx2][2][cz1]->children )
01732 for( j=0 ; j<2 ; j++ ) for( k=0 ; k<2 ; k++ )
01733 n.neighbors[fx2 ][fy0+j][fz1+k] = temp.neighbors[cx2][2][cz1]->children + Cube::CornerIndex( x1 , j , k );
01734 if( temp.neighbors[2][cy2][cz1] && temp.neighbors[2][cy2][cz1]->children )
01735 for( i=0 ; i<2 ; i++ ) for( k=0 ; k<2 ; k++ )
01736 n.neighbors[fx0+i][fy2 ][fz1+k] = temp.neighbors[2][cy2][cz1]->children + Cube::CornerIndex( i , y1 , k );
01737 if( temp.neighbors[cx2][cy2][2] && temp.neighbors[cx2][cy2][2]->children )
01738 for( k=0 ; k<2 ; k++ )
01739 n.neighbors[fx2 ][fy2 ][fz0+k] = temp.neighbors[cx2][cy2][2]->children + Cube::CornerIndex( x1 , y1 , k );
01740 if( temp.neighbors[cx2][2][cz2] && temp.neighbors[cx2][2][cz2]->children )
01741 for( j=0 ; j<2 ; j++ )
01742 n.neighbors[fx2 ][fy0+j][fz2 ] = temp.neighbors[cx2][2][cz2]->children + Cube::CornerIndex( x1 , j , z1 );
01743 if( temp.neighbors[2][cy2][cz2] && temp.neighbors[2][cy2][cz2]->children )
01744 for( i=0 ; i<2 ; i++ )
01745 n.neighbors[fx0+i][fy2 ][fz2 ] = temp.neighbors[2][cy2][cz2]->children + Cube::CornerIndex( i , y1 , z1 );
01746
01747
01748 if( temp.neighbors[cx1][cy1][cz1] && temp.neighbors[cx1][cy1][cz1]->children )
01749 for( i=0 ; i<2 ; i++ ) for( j=0 ; j<2 ; j++ ) for( k=0 ; k<2 ; k++ )
01750 n.neighbors[fx1+i][fy1+j][fz1+k] = temp.neighbors[cx1][cy1][cz1]->children + Cube::CornerIndex( i , j , k );
01751 if( temp.neighbors[cx1][cy1][cz2] && temp.neighbors[cx1][cy1][cz2]->children )
01752 for( i=0 ; i<2 ; i++ ) for( j=0 ; j<2 ; j++ )
01753 n.neighbors[fx1+i][fy1+j][fz2 ] = temp.neighbors[cx1][cy1][cz2]->children + Cube::CornerIndex( i , j , z1 );
01754 if( temp.neighbors[cx1][cy2][cz1] && temp.neighbors[cx1][cy2][cz1]->children )
01755 for( i=0 ; i<2 ; i++ ) for( k=0 ; k<2 ; k++ )
01756 n.neighbors[fx1+i][fy2 ][fz1+k] = temp.neighbors[cx1][cy2][cz1]->children + Cube::CornerIndex( i , y1 , k );
01757 if( temp.neighbors[cx2][cy1][cz1] && temp.neighbors[cx2][cy1][cz1]->children )
01758 for( j=0 ; j<2 ; j++ ) for( k=0 ; k<2 ; k++ )
01759 n.neighbors[fx2 ][fy1+j][fz1+k] = temp.neighbors[cx2][cy1][cz1]->children + Cube::CornerIndex( x1 , j , k );
01760 if( temp.neighbors[cx1][cy2][cz2] && temp.neighbors[cx1][cy2][cz2]->children )
01761 for( i=0 ; i<2 ; i++ )
01762 n.neighbors[fx1+i][fy2 ][fz2 ] = temp.neighbors[cx1][cy2][cz2]->children + Cube::CornerIndex( i , y1 , z1 );
01763 if( temp.neighbors[cx2][cy1][cz2] && temp.neighbors[cx2][cy1][cz2]->children )
01764 for( j=0 ; j<2 ; j++ )
01765 n.neighbors[fx2 ][fy1+j][fz2 ] = temp.neighbors[cx2][cy1][cz2]->children + Cube::CornerIndex( x1 , j , z1 );
01766 if( temp.neighbors[cx2][cy2][cz1] && temp.neighbors[cx2][cy2][cz1]->children )
01767 for( k=0 ; k<2 ; k++ )
01768 n.neighbors[fx2 ][fy2 ][fz1+k] = temp.neighbors[cx2][cy2][cz1]->children + Cube::CornerIndex( x1 , y1 , k );
01769 if( temp.neighbors[cx2][cy2][cz2] && temp.neighbors[cx2][cy2][cz2]->children )
01770 n.neighbors[fx2 ][fy2 ][fz2 ] = temp.neighbors[cx2][cy2][cz2]->children + Cube::CornerIndex( x1 , y1 , z1 );
01771 }
01772 }
01773 return neighbors[d];
01774 }
01775 template< class NodeData , class Real >
01776 typename OctNode< NodeData , Real >::Neighbors5& OctNode< NodeData , Real >::NeighborKey5::setNeighbors( OctNode* node , int xStart , int xEnd , int yStart , int yEnd , int zStart , int zEnd )
01777 {
01778 int d=node->depth();
01779 if( node!=neighbors[d].neighbors[2][2][2] )
01780 {
01781 neighbors[d].clear();
01782
01783 if( !node->parent ) neighbors[d].neighbors[2][2][2]=node;
01784 else
01785 {
01786 setNeighbors( node->parent , xStart , xEnd , yStart , yEnd , zStart , zEnd );
01787 Neighbors5& temp = neighbors[d-1];
01788 int x1 , y1 , z1 , x2 , y2 , z2 , ii , jj , kk;
01789 int idx = int( node-node->parent->children );
01790 Cube::FactorCornerIndex( idx , x1 , y1 , z1 );
01791
01792 for( int i=xStart ; i<xEnd ; i++ )
01793 {
01794 x2 = i+x1;
01795 ii = x2&1;
01796 x2 = 1+(x2>>1);
01797 for( int j=yStart ; j<yEnd ; j++ )
01798 {
01799 y2 = j+y1;
01800 jj = y2&1;
01801 y2 = 1+(y2>>1);
01802 for( int k=zStart ; k<zEnd ; k++ )
01803 {
01804 z2 = k+z1;
01805 kk = z2&1;
01806 z2 = 1+(z2>>1);
01807 if(temp.neighbors[x2][y2][z2] )
01808 {
01809 if( !temp.neighbors[x2][y2][z2]->children ) temp.neighbors[x2][y2][z2]->initChildren();
01810 neighbors[d].neighbors[i][j][k] = temp.neighbors[x2][y2][z2]->children + Cube::CornerIndex(ii,jj,kk);
01811 }
01812 }
01813 }
01814 }
01815 }
01816 }
01817 return neighbors[d];
01818 }
01819 template< class NodeData , class Real >
01820 typename OctNode< NodeData , Real >::ConstNeighbors5& OctNode< NodeData , Real >::ConstNeighborKey5::getNeighbors( const OctNode* node )
01821 {
01822 int d=node->depth();
01823 if( node!=neighbors[d].neighbors[2][2][2] )
01824 {
01825 neighbors[d].clear();
01826
01827 if(!node->parent) neighbors[d].neighbors[2][2][2]=node;
01828 else
01829 {
01830 getNeighbors( node->parent );
01831 ConstNeighbors5& temp = neighbors[d-1];
01832 int x1,y1,z1,x2,y2,z2,ii,jj,kk;
01833 int idx=int(node-node->parent->children);
01834 Cube::FactorCornerIndex(idx,x1,y1,z1);
01835
01836 for(int i=0;i<5;i++)
01837 {
01838 x2=i+x1;
01839 ii=x2&1;
01840 x2=1+(x2>>1);
01841 for(int j=0;j<5;j++)
01842 {
01843 y2=j+y1;
01844 jj=y2&1;
01845 y2=1+(y2>>1);
01846 for(int k=0;k<5;k++)
01847 {
01848 z2=k+z1;
01849 kk=z2&1;
01850 z2=1+(z2>>1);
01851 if(temp.neighbors[x2][y2][z2] && temp.neighbors[x2][y2][z2]->children)
01852 neighbors[d].neighbors[i][j][k] = temp.neighbors[x2][y2][z2]->children + Cube::CornerIndex(ii,jj,kk);
01853 }
01854 }
01855 }
01856 }
01857 }
01858 return neighbors[d];
01859 }
01860
01861
01862 template <class NodeData,class Real>
01863 int OctNode<NodeData,Real>::write(const char* fileName) const{
01864 FILE* fp=fopen(fileName,"wb");
01865 if(!fp){return 0;}
01866 int ret=write(fp);
01867 fclose(fp);
01868 return ret;
01869 }
01870 template <class NodeData,class Real>
01871 int OctNode<NodeData,Real>::write(FILE* fp) const{
01872 fwrite(this,sizeof(OctNode<NodeData,Real>),1,fp);
01873 if(children){for(int i=0;i<Cube::CORNERS;i++){children[i].write(fp);}}
01874 return 1;
01875 }
01876 template <class NodeData,class Real>
01877 int OctNode<NodeData,Real>::read(const char* fileName){
01878 FILE* fp=fopen(fileName,"rb");
01879 if(!fp){return 0;}
01880 int ret=read(fp);
01881 fclose(fp);
01882 return ret;
01883 }
01884 template <class NodeData,class Real>
01885 int OctNode<NodeData,Real>::read(FILE* fp){
01886 fread(this,sizeof(OctNode<NodeData,Real>),1,fp);
01887 parent=NULL;
01888 if(children){
01889 children=NULL;
01890 initChildren();
01891 for(int i=0;i<Cube::CORNERS;i++){
01892 children[i].read(fp);
01893 children[i].parent=this;
01894 }
01895 }
01896 return 1;
01897 }
01898 template<class NodeData,class Real>
01899 int OctNode<NodeData,Real>::width(int maxDepth) const {
01900 int d=depth();
01901 return 1<<(maxDepth-d);
01902 }
01903 template<class NodeData,class Real>
01904 void OctNode<NodeData,Real>::centerIndex(int maxDepth,int index[DIMENSION]) const {
01905 int d,o[3];
01906 depthAndOffset(d,o);
01907 for(int i=0;i<DIMENSION;i++){index[i]=BinaryNode<Real>::CornerIndex(maxDepth,d+1,o[i]<<1,1);}
01908 }
01909
01910 }
01911 }