Blender V2.61 - r43446

octree.h

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * Contributor(s): Tao Ju
00019  *
00020  * ***** END GPL LICENSE BLOCK *****
00021  */
00022 
00023 #ifndef OCTREE_H
00024 #define OCTREE_H
00025 
00026 #include <stdio.h>
00027 #include <math.h>
00028 #include "GeoCommon.h"
00029 #include "Projections.h"
00030 #include "ModelReader.h"
00031 #include "MemoryAllocator.h"
00032 #include "cubes.h"
00033 #include "Queue.h"
00034 #include "manifold_table.h"
00035 #include "dualcon.h"
00036 
00045 /* Global defines */
00046 // Uncomment to see debug information
00047 // #define IN_DEBUG_MODE
00048 
00049 // Uncomment to see more output messages during repair
00050 // #define IN_VERBOSE_MODE
00051 
00052 /* Set scan convert params */
00053 // Uncomment to use Dual Contouring on Hermit representation
00054 // for better sharp feature reproduction, but more mem is required
00055 // The number indicates how far do we allow the minimizer to shoot
00056 // outside the cell
00057 #define USE_HERMIT 1.0f
00058 
00059 #ifdef USE_HERMIT
00060 //#define CINDY
00061 #endif
00062 
00064 
00065 //#define TESTMANIFOLD
00066 
00067 
00068 /* Set output options */
00069 // Comment out to prevent writing output files
00070 #define OUTPUT_REPAIRED
00071 
00072 
00073 /* Set node bytes */
00074 #ifdef USE_HERMIT
00075 #define EDGE_BYTES 16
00076 #define EDGE_FLOATS 4
00077 #else
00078 #define EDGE_BYTES 4
00079 #define EDGE_FLOATS 1
00080 #endif
00081 
00082 #define CINDY_BYTES 0
00083 
00084 /*#define LEAF_EXTRA_BYTES FLOOD_BYTES + CINDY_BYTES
00085 
00086 #ifdef USE_HERMIT
00087 #define LEAF_NODE_BYTES 7 + LEAF_EXTRA_BYTES
00088 #else
00089 #define LEAF_NODE_BYTES 3 + LEAF_EXTRA_BYTES
00090 #endif*/
00091 
00092 #define INTERNAL_NODE_BYTES 2
00093 #define POINTER_BYTES 8
00094 #define FLOOD_FILL_BYTES 2
00095 
00096 #define signtype short
00097 #define nodetype int
00098 #define numtype int
00099 
00100 /* Global variables */
00101 extern const int edgemask[3];
00102 extern const int faceMap[6][4];
00103 extern const int cellProcFaceMask[12][3];
00104 extern const int cellProcEdgeMask[6][5];
00105 extern const int faceProcFaceMask[3][4][3];
00106 extern const int edgeProcEdgeMask[3][2][5];
00107 extern const int faceProcEdgeMask[3][4][6];
00108 extern const int processEdgeMask[3][4];
00109 extern const int dirCell[3][4][3]; 
00110 extern const int dirEdge[3][4];
00111 
00116 struct PathElement
00117 {
00118     // Origin
00119     int pos[3] ;
00120 
00121     // link
00122     PathElement* next ;
00123 };
00124 
00125 struct PathList
00126 {
00127     // Head
00128     PathElement* head ;
00129     PathElement* tail ;
00130 
00131     // Length of the list
00132     int length ;
00133 
00134     // Next list
00135     PathList* next ;
00136 };
00137 
00138 
00142 class Octree
00143 {
00144 public:
00145     /* Public members */
00146 
00148     VirtualMemoryAllocator * alloc[ 9 ] ;
00149     VirtualMemoryAllocator * leafalloc[ 4 ] ;
00150 
00152     UCHAR* root ;
00153 
00155     ModelReader* reader ;
00156 
00158     Cubes* cubes ;
00159 
00161     int dimen ;
00162     int mindimen, minshift ;
00163 
00165     int maxDepth ;
00166     
00168     float origin[3];
00169     float range;
00170 
00172     int nodeCount ;
00173     int nodeSpace ;
00174     int nodeCounts[ 9 ] ;
00175 
00176     int actualQuads, actualVerts ;
00177 
00178     PathList* ringList ;
00179 
00180     int maxTrianglePerCell ;
00181     int outType ; // 0 for OFF, 1 for PLY, 2 for VOL
00182 
00183     // For flood filling
00184     int use_flood_fill;
00185     float thresh ;
00186 
00187     int use_manifold;
00188 
00189     // testing
00190     FILE* testfout ;
00191 
00192     float hermite_num;
00193 
00194     DualConMode mode;
00195 
00196     int leaf_node_bytes;
00197     int leaf_extra_bytes;
00198     int flood_bytes;
00199 
00200 public:
00204     Octree ( ModelReader* mr,
00205              DualConAllocOutput alloc_output_func,
00206              DualConAddVert add_vert_func,
00207              DualConAddQuad add_quad_func,
00208              DualConFlags flags, DualConMode mode, int depth,
00209              float threshold, float hermite_num ) ;
00210 
00214     ~Octree ( ) ;
00215 
00219     void scanConvert() ;
00220 
00221     void *getOutputMesh() { return output_mesh; }
00222 
00223 private:
00224     /* Helper functions */
00225     
00229     void initMemory ( ) ;
00230 
00234     void freeMemory ( ) ;
00235 
00239     void printMemUsage( ) ;
00240 
00241 
00245     void resetMinimalEdges( ) ;
00246 
00247     void cellProcParity ( UCHAR* node, int leaf, int depth ) ;
00248     void faceProcParity ( UCHAR* node[2], int leaf[2], int depth[2], int maxdep, int dir ) ;
00249     void edgeProcParity ( UCHAR* node[4], int leaf[4], int depth[4], int maxdep, int dir ) ;
00250 
00251     void processEdgeParity ( UCHAR* node[4], int depths[4], int maxdep, int dir ) ;
00252 
00256     void addTrian ( );
00257     void addTrian ( Triangle* trian, int triind );
00258     UCHAR* addTrian ( UCHAR* node, Projections* p, int height );
00259 
00263     UCHAR* updateCell( UCHAR* node, Projections* p ) ;
00264 
00265     /* Routines to detect and patch holes */
00266     int numRings ;
00267     int totRingLengths ;
00268     int maxRingLength ;
00269 
00273     void trace ( ) ;
00277     UCHAR* trace ( UCHAR* node, int* st, int len, int depth, PathList*& paths ) ;
00281     void findPaths ( UCHAR* node[2], int leaf[2], int depth[2], int* st[2], int maxdep, int dir, PathList*& paths ) ;
00286     void combinePaths ( PathList*& list1, PathList* list2, PathList* paths, PathList*& rings ) ;
00290     PathList* combineSinglePath ( PathList*& head1, PathList* pre1, PathList*& list1, PathList*& head2, PathList* pre2, PathList*& list2 ) ;
00291     
00295     UCHAR* patch ( UCHAR* node, int st[3], int len, PathList* rings ) ;
00296     UCHAR* patchSplit ( UCHAR* node, int st[3], int len, PathList* rings, int dir, PathList*& nrings1, PathList*& nrings2 ) ;
00297     UCHAR* patchSplitSingle ( UCHAR* node, int st[3], int len, PathElement* head, int dir, PathList*& nrings1, PathList*& nrings2 ) ;
00298     UCHAR* connectFace ( UCHAR* node, int st[3], int len, int dir, PathElement* f1, PathElement* f2 ) ;
00299     UCHAR* locateCell( UCHAR* node, int st[3], int len, int ori[3], int dir, int side, UCHAR*& rleaf, int rst[3], int& rlen ) ;
00300     void compressRing ( PathElement*& ring ) ;
00301     void getFacePoint( PathElement* leaf, int dir, int& x, int& y, float& p, float& q ) ;
00302     UCHAR* patchAdjacent( UCHAR* node, int len, int st1[3], UCHAR* leaf1, int st2[3], UCHAR* leaf2, int walkdir, int inc, int dir, int side, float alpha ) ;
00303     int findPair ( PathElement* head, int pos, int dir, PathElement*& pre1, PathElement*& pre2 ) ;
00304     int getSide( PathElement* e, int pos, int dir ) ;
00305     int isEqual( PathElement* e1, PathElement* e2 ) ;
00306     void preparePrimalEdgesMask( UCHAR* node ) ;
00307     void testFacePoint( PathElement* e1, PathElement* e2 ) ;
00308     
00312     void deletePath ( PathList*& head, PathList* pre, PathList*& curr ) ;
00313     void printPath( PathList* path ) ;
00314     void printPath( PathElement* path ) ;
00315     void printElement( PathElement* ele ) ;
00316     void printPaths( PathList* path ) ;
00317     void checkElement ( PathElement* ele ) ;
00318     void checkPath( PathElement* path ) ;
00319 
00320 
00325     void buildSigns( ) ;
00326     void buildSigns( unsigned char table[], UCHAR* node, int isLeaf, int sg, int rvalue[8] ) ;
00327 
00328     /************************************************************************/
00329     /* To remove disconnected components */
00330     /************************************************************************/
00331     void floodFill( ) ;
00332     void clearProcessBits( UCHAR* node, int height ) ;
00333     int floodFill( UCHAR* node, int st[3], int len, int height, int threshold ) ;
00334 
00338     void writeOut();
00339     void writeOFF ( char* fname ) ;
00340     void writePLY ( char* fname ) ;
00341     void writeOpenEdges( FILE* fout ) ;
00342     void writeAllEdges( FILE* fout, int mode ) ;
00343     void writeAllEdges( FILE* fout, UCHAR* node, int height, int st[3], int len, int mode ) ;
00344     
00345     void writeOctree( char* fname ) ;
00346     void writeOctree( FILE* fout, UCHAR* node, int depth ) ;
00347 #ifdef USE_HERMIT
00348     void writeOctreeGeom( char* fname ) ;
00349     void writeOctreeGeom( FILE* fout, UCHAR* node, int st[3], int len, int depth ) ;
00350 #endif
00351 #ifdef USE_HERMIT
00352     void writeDCF ( char* fname ) ;
00353     void writeDCF ( FILE* fout, UCHAR* node, int height, int st[3], int len ) ;
00354     void countEdges ( UCHAR* node, int height, int& nedge, int mode ) ;
00355     void countIntersection( UCHAR* node, int height, int& nedge, int& ncell, int& nface ) ;
00356     void generateMinimizer( UCHAR* node, int st[3], int len, int height, int& offset ) ;
00357     void computeMinimizer( UCHAR* leaf, int st[3], int len, float rvalue[3] ) ;
00362     void cellProcContour ( UCHAR* node, int leaf, int depth ) ;
00363     void faceProcContour ( UCHAR* node[2], int leaf[2], int depth[2], int maxdep, int dir ) ;
00364     void edgeProcContour ( UCHAR* node[4], int leaf[4], int depth[4], int maxdep, int dir ) ;
00365     void processEdgeWrite ( UCHAR* node[4], int depths[4], int maxdep, int dir ) ;
00366 #else
00367     void countIntersection( UCHAR* node, int height, int& nquad, int& nvert ) ;
00368     void writeVertex( UCHAR* node, int st[3], int len, int height, int& offset, FILE* fout ) ;
00369     void writeQuad( UCHAR* node, int st[3], int len, int height, FILE* fout ) ;
00370 #endif
00371 
00375     void writeModel( char* fname ) ;
00376 
00377     /************************************************************************/
00378     /* Write out original vertex tags */
00379     /************************************************************************/
00380 #ifdef CINDY
00381     void writeTags( char* fname ) ;
00382     void readVertices( ) ;
00383     void readVertex(  UCHAR* node, int st[3], int len, int height, float v[3], int index ) ;
00384     void outputTags( UCHAR* node, int height, FILE* fout ) ;
00385     void clearCindyBits( UCHAR* node, int height ) ;
00386 #endif
00387 
00388     /* output callbacks/data */
00389     DualConAllocOutput alloc_output;
00390     DualConAddVert add_vert;
00391     DualConAddQuad add_quad;
00392     void *output_mesh;
00393     
00394 private:
00395     /************ Operators for all nodes ************/
00396 
00413 
00414     int numChildrenTable[ 256 ] ;
00415     int childrenCountTable[ 256 ][ 8 ] ;
00416     int childrenIndexTable[ 256 ][ 8 ] ;
00417     int numEdgeTable[ 8 ] ;
00418     int edgeCountTable[ 8 ][ 3 ] ;
00419 
00421     void buildTable ( )
00422     {
00423         for ( int i = 0 ; i < 256 ; i ++ )
00424         {
00425             numChildrenTable[ i ] = 0 ;
00426             int count = 0 ;
00427             for ( int j = 0 ; j < 8 ; j ++ )
00428             {
00429                 numChildrenTable[ i ] += ( ( i >> j ) & 1 ) ;
00430                 childrenCountTable[ i ][ j ] = count ;
00431                 childrenIndexTable[ i ][ count ] = j ;
00432                 count += ( ( i >> j ) & 1 ) ;
00433             }
00434         }
00435 
00436         for ( int i = 0 ; i < 8 ; i ++ )
00437         {
00438             numEdgeTable[ i ] = 0 ;
00439             int count = 0 ;
00440             for ( int j = 0 ; j < 3 ; j ++ )
00441             {
00442                 numEdgeTable[ i ] += ( ( i >> j ) & 1 ) ;
00443                 edgeCountTable[ i ][ j ] = count ;
00444                 count += ( ( i >> j ) & 1 ) ;
00445             }
00446         }
00447     };
00448 
00449     int getSign( UCHAR* node, int height, int index )
00450     {
00451         if ( height == 0 )
00452         {
00453             return getSign( node, index ) ;
00454         }
00455         else
00456         {
00457             if ( hasChild( node, index ) )
00458             {
00459                 return getSign( getChild( node, getChildCount( node, index ) ), height - 1, index ) ;
00460             }
00461             else
00462             {
00463                 return getSign( getChild( node, 0 ), height - 1, 7 - getChildIndex( node, 0 ) ) ;
00464             }
00465         }
00466     }
00467 
00468     /************ Operators for leaf nodes ************/
00469 
00470     void printInfo( int st[3] )
00471     {
00472         printf("INFO AT: %d %d %d\n", st[0] >> minshift, st[1] >>minshift, st[2] >> minshift ) ;
00473         UCHAR* leaf = locateLeafCheck( st ) ;
00474         if ( leaf == NULL )
00475         {
00476             printf("Leaf not exists!\n") ;
00477         }
00478         else
00479         {
00480             printInfo( leaf ) ;
00481         }
00482     }
00483 
00484     void printInfo( UCHAR* leaf )
00485     {
00486         /*
00487         printf("Edge mask: ") ;
00488         for ( int i = 0 ; i < 12 ; i ++ )
00489         {
00490             printf("%d ", getEdgeParity( leaf, i ) ) ;
00491         }
00492         printf("\n") ;
00493         printf("Stored edge mask: ") ;
00494         for ( i = 0 ; i < 3 ; i ++ )
00495         {
00496             printf("%d ", getStoredEdgesParity( leaf, i ) ) ;
00497         }
00498         printf("\n") ;
00499         */
00500         printf("Sign mask: ") ;
00501         for ( int i = 0 ; i < 8 ; i ++ )
00502         {
00503             printf("%d ", getSign( leaf, i ) ) ;
00504         }
00505         printf("\n") ;
00506 
00507     }
00508 
00510     int getSign ( UCHAR* leaf, int index )
00511     {
00512         return (( leaf[2] >> index ) & 1 );     
00513     };
00514 
00516     void setSign ( UCHAR* leaf, int index ) 
00517     {
00518         leaf[2] |= ( 1 << index ) ;
00519     };
00520 
00521     void setSign ( UCHAR* leaf, int index, int sign ) 
00522     {
00523         leaf[2] &= ( ~ ( 1 << index ) ) ;
00524         leaf[2] |= ( ( sign & 1 ) << index ) ;
00525     };
00526 
00527     int getSignMask( UCHAR* leaf )
00528     {
00529         return leaf[2] ;
00530     }
00531 
00532     void setInProcessAll( int st[3], int dir )
00533     {
00534         int nst[3], eind ;
00535         for ( int i = 0 ; i < 4 ; i ++ )
00536         {
00537             nst[0] = st[0] + dirCell[dir][i][0] * mindimen ;
00538             nst[1] = st[1] + dirCell[dir][i][1] * mindimen ;
00539             nst[2] = st[2] + dirCell[dir][i][2] * mindimen ;
00540             eind = dirEdge[dir][i] ;
00541 
00542             UCHAR* cell = locateLeafCheck( nst ) ;
00543             if ( cell == NULL )
00544             {
00545                 printf("Wrong!\n") ;
00546             }
00547             setInProcess( cell, eind ) ;
00548         }
00549     }
00550 
00551     void flipParityAll( int st[3], int dir )
00552     {
00553         int nst[3], eind ;
00554         for ( int i = 0 ; i < 4 ; i ++ )
00555         {
00556             nst[0] = st[0] + dirCell[dir][i][0] * mindimen ;
00557             nst[1] = st[1] + dirCell[dir][i][1] * mindimen ;
00558             nst[2] = st[2] + dirCell[dir][i][2] * mindimen ;
00559             eind = dirEdge[dir][i] ;
00560 
00561             UCHAR* cell = locateLeaf( nst ) ;
00562             flipEdge( cell, eind ) ;
00563         }
00564     }
00565 
00566     void setInProcess( UCHAR* leaf, int eind )
00567     {
00568         // leaf[1] |= ( 1 << 7 ) ;
00569         ( (USHORT*) (leaf + leaf_node_bytes - (flood_bytes + CINDY_BYTES)))[0] |= ( 1 << eind ) ;
00570     }
00571     void setOutProcess( UCHAR* leaf, int eind )
00572     {
00573         // leaf[1] &= ( ~ ( 1 << 7 ) ) ;
00574         ( (USHORT*) (leaf + leaf_node_bytes - (flood_bytes + CINDY_BYTES)))[0] &= ( ~ ( 1 << eind ) ) ;
00575     }
00576 
00577     int isInProcess( UCHAR* leaf, int eind )
00578     {
00579         //int a = ( ( leaf[1] >> 7 ) & 1 ) ;
00580         int a = ( ( ( (USHORT*) (leaf + leaf_node_bytes - (flood_bytes + CINDY_BYTES)))[0] >> eind ) & 1 ) ;
00581         return a ;
00582     }
00583 
00584 #ifndef USE_HERMIT
00585 
00586     void setEdgeIntersectionIndex( UCHAR* leaf, int count, int index )
00587     {
00588         ((int *)( leaf + leaf_node_bytes ))[ count ] = index ;
00589     }
00590 
00592     int getEdgeIntersectionIndex( UCHAR* leaf, int count )
00593     {
00594         return  ((int *)( leaf + leaf_node_bytes ))[ count ] ;
00595     }
00596 
00598     void fillEdgeIntersectionIndices( UCHAR* leaf, int st[3], int len, int inds[12] )
00599     {
00600         int i ;
00601 
00602         // The three primal edges are easy
00603         int pmask[3] = { 0, 4, 8 } ;
00604         for ( i = 0 ; i < 3 ; i ++ )
00605         {
00606             if ( getEdgeParity( leaf, pmask[i] ) )
00607             {
00608                 inds[pmask[i]] = getEdgeIntersectionIndex( leaf, getEdgeCount( leaf, i ) ) ;
00609             }
00610         }
00611         
00612         // 3 face adjacent cubes
00613         int fmask[3][2] = {{6,10},{2,9},{1,5}} ;
00614         int femask[3][2] = {{1,2},{0,2},{0,1}} ;
00615         for ( i = 0 ; i < 3 ; i ++ )
00616         {
00617             int e1 = getEdgeParity( leaf, fmask[i][0] ) ;
00618             int e2 = getEdgeParity( leaf, fmask[i][1] ) ;
00619             if ( e1 || e2 )
00620             {
00621                 int nst[3] = {st[0], st[1], st[2]} ;
00622                 nst[ i ] += len ;
00623                 // int nstt[3] = {0, 0, 0} ;
00624                 // nstt[ i ] += 1 ;
00625                 UCHAR* node = locateLeaf( nst ) ;
00626                 
00627                 if ( e1 )
00628                 {
00629                     inds[ fmask[i][0] ] = getEdgeIntersectionIndex( node, getEdgeCount( node, femask[i][0] ) ) ;
00630                 }
00631                 if ( e2 )
00632                 {
00633                     inds[ fmask[i][1] ] = getEdgeIntersectionIndex( node, getEdgeCount( node, femask[i][1] ) ) ;
00634                 }
00635             }
00636         }
00637         
00638         // 3 edge adjacent cubes
00639         int emask[3] = {3, 7, 11} ;
00640         int eemask[3] = {0, 1, 2} ;
00641         for ( i = 0 ; i < 3 ; i ++ )
00642         {
00643             if ( getEdgeParity( leaf, emask[i] ) )
00644             {
00645                 int nst[3] = {st[0] + len, st[1] + len, st[2] + len} ;
00646                 nst[ i ] -= len ;
00647                 // int nstt[3] = {1, 1, 1} ;
00648                 // nstt[ i ] -= 1 ;
00649                 UCHAR* node = locateLeaf( nst ) ;
00650                 
00651                 inds[ emask[i] ] = getEdgeIntersectionIndex( node, getEdgeCount( node, eemask[i] ) ) ;
00652             }
00653         }
00654     }
00655 
00656 
00657 #endif
00658     
00660     void generateSigns ( UCHAR* leaf, UCHAR table[], int start )
00661     {
00662         leaf[2] = table[ ( ((USHORT *) leaf)[ 0 ] ) & ( ( 1 << 12 ) - 1 ) ] ; 
00663 
00664         if ( ( start ^ leaf[2] ) & 1 ) 
00665         {
00666             leaf[2] = ~ ( leaf[2] ) ;
00667         }
00668     }
00669 
00671     int getEdgeParity( UCHAR* leaf, int index ) 
00672     {
00673         int a = ( ( ((USHORT *) leaf)[ 0 ] >> index ) & 1 ) ;
00674         return  a ;
00675     };
00676 
00678     int getFaceParity ( UCHAR* leaf, int index )
00679     {
00680         int a = getEdgeParity( leaf, faceMap[ index ][ 0 ] ) + 
00681                 getEdgeParity( leaf, faceMap[ index ][ 1 ] ) + 
00682                 getEdgeParity( leaf, faceMap[ index ][ 2 ] ) + 
00683                 getEdgeParity( leaf, faceMap[ index ][ 3 ] ) ;
00684         return ( a & 1 ) ;
00685     }
00686     int getFaceEdgeNum ( UCHAR* leaf, int index )
00687     {
00688         int a = getEdgeParity( leaf, faceMap[ index ][ 0 ] ) + 
00689                 getEdgeParity( leaf, faceMap[ index ][ 1 ] ) + 
00690                 getEdgeParity( leaf, faceMap[ index ][ 2 ] ) + 
00691                 getEdgeParity( leaf, faceMap[ index ][ 3 ] ) ;
00692         return a ;
00693     }
00694 
00696     void flipEdge( UCHAR* leaf, int index ) 
00697     {
00698         ((USHORT *) leaf)[ 0 ] ^= ( 1 << index ) ;  
00699     };
00701     void setEdge( UCHAR* leaf, int index ) 
00702     {
00703         ((USHORT *) leaf)[ 0 ] |= ( 1 << index ) ;  
00704     };
00706     void resetEdge( UCHAR* leaf, int index ) 
00707     {
00708         ((USHORT *) leaf)[ 0 ] &= ( ~ ( 1 << index ) ) ;    
00709     };
00710 
00712     void createPrimalEdgesMask( UCHAR* leaf )
00713     {
00714         int mask = (( leaf[0] & 1 ) | ( (leaf[0] >> 3) & 2 ) | ( (leaf[1] & 1) << 2 ) ) ;
00715         leaf[1] |= ( mask << 4 ) ;
00716 
00717     }
00718 
00719     void setStoredEdgesParity( UCHAR* leaf, int pindex )
00720     {
00721         leaf[1] |= ( 1 << ( 4 + pindex ) ) ;
00722     }
00723     int getStoredEdgesParity( UCHAR* leaf, int pindex )
00724     {
00725         return ( ( leaf[1] >> ( 4 + pindex ) ) & 1 ) ;
00726     }
00727 
00728     UCHAR* flipEdge( UCHAR* leaf, int index, float alpha ) 
00729     {
00730         flipEdge( leaf, index ) ;
00731 
00732         if ( ( index & 3 ) == 0 )
00733         {
00734             int ind = index / 4 ;
00735             if ( getEdgeParity( leaf, index ) && ! getStoredEdgesParity( leaf, ind ) )
00736             {
00737                 // Create a new node
00738                 int num = getNumEdges( leaf ) + 1 ;
00739                 setStoredEdgesParity( leaf, ind ) ;
00740                 int count = getEdgeCount( leaf, ind ) ;
00741                 UCHAR* nleaf = createLeaf( num ) ;
00742                 for ( int i = 0 ; i < leaf_node_bytes ; i ++ )
00743                 {
00744                     nleaf[i] = leaf[i] ;
00745                 }
00746 
00747                 setEdgeOffset( nleaf, alpha, count ) ;
00748 
00749                 if ( num > 1 )
00750                 {
00751                     float * pts = ( float * ) ( leaf + leaf_node_bytes ) ;
00752                     float * npts = ( float * ) ( nleaf + leaf_node_bytes ) ;
00753                     for ( int i = 0 ; i < count ; i ++ )
00754                     {
00755                         for ( int j = 0 ; j < EDGE_FLOATS ; j ++ )
00756                         {
00757                             npts[i * EDGE_FLOATS + j] = pts[i * EDGE_FLOATS + j] ;
00758                         }
00759                     }
00760                     for ( int i = count + 1 ; i < num ; i ++ )
00761                     {
00762                         for ( int j = 0 ; j < EDGE_FLOATS ; j ++ )
00763                         {
00764                             npts[i * EDGE_FLOATS + j] = pts[ (i - 1) * EDGE_FLOATS + j] ;
00765                         }
00766                     }
00767                 }
00768 
00769                 
00770                 removeLeaf( num-1, leaf ) ;
00771                 leaf = nleaf ;
00772             }
00773         }
00774 
00775         return leaf ;
00776     };
00777 
00779     void updateParent( UCHAR* node, int len, int st[3], UCHAR* leaf ) 
00780     {
00781         // First, locate the parent
00782         int count ;
00783         UCHAR* parent = locateParent( node, len, st, count ) ;
00784 
00785         // UPdate
00786         setChild( parent, count, leaf ) ;
00787     }
00788 
00789     void updateParent( UCHAR* node, int len, int st[3] ) 
00790     {
00791         if ( len == dimen )
00792         {
00793             root = node ;
00794             return ;
00795         }
00796 
00797         // First, locate the parent
00798         int count ;
00799         UCHAR* parent = locateParent( len, st, count ) ;
00800 
00801         // UPdate
00802         setChild( parent, count, node ) ;
00803     }
00804 
00806     int getEdgeIntersectionByIndex( int st[3], int index, float pt[3], int check )
00807     {
00808         // First, locat the leaf
00809         UCHAR* leaf ;
00810         if ( check )
00811         {
00812             leaf = locateLeafCheck( st ) ;
00813         }
00814         else
00815         {
00816             leaf = locateLeaf( st ) ;
00817         }
00818 
00819         if ( leaf && getStoredEdgesParity( leaf, index ) )
00820         {
00821             float off = getEdgeOffset( leaf, getEdgeCount( leaf, index ) ) ;
00822             pt[0] = (float) st[0] ;
00823             pt[1] = (float) st[1] ;
00824             pt[2] = (float) st[2] ;
00825             pt[index] += off * mindimen ;
00826 
00827             return 1 ;
00828         }
00829         else
00830         {
00831             return 0 ;
00832         }
00833     }
00834 
00836     int getPrimalEdgesMask( UCHAR* leaf )
00837     {
00838         // return (( leaf[0] & 1 ) | ( (leaf[0] >> 3) & 2 ) | ( (leaf[1] & 1) << 2 ) ) ;
00839         return ( ( leaf[1] >> 4 ) & 7 ) ;
00840     }
00841 
00842     int getPrimalEdgesMask2( UCHAR* leaf )
00843     {
00844         return (( leaf[0] & 1 ) | ( (leaf[0] >> 3) & 2 ) | ( (leaf[1] & 1) << 2 ) ) ;
00845     }
00846 
00848     int getEdgeCount( UCHAR* leaf, int index )
00849     {
00850         return edgeCountTable[ getPrimalEdgesMask( leaf ) ][ index ] ;
00851     }
00852     int getNumEdges( UCHAR* leaf )
00853     {
00854         return numEdgeTable[ getPrimalEdgesMask( leaf ) ] ;
00855     }
00856 
00857     int getNumEdges2( UCHAR* leaf )
00858     {
00859         return numEdgeTable[ getPrimalEdgesMask2( leaf ) ] ;
00860     }
00861 
00863     void setEdgeOffset( UCHAR* leaf, float pt, int count )
00864     {
00865         float * pts = ( float * ) ( leaf + leaf_node_bytes ) ;
00866 #ifdef USE_HERMIT
00867         pts[ EDGE_FLOATS * count ] = pt ;
00868         pts[ EDGE_FLOATS * count + 1 ] = 0 ;
00869         pts[ EDGE_FLOATS * count + 2 ] = 0 ;
00870         pts[ EDGE_FLOATS * count + 3 ] = 0 ;
00871 #else
00872         pts[ count ] = pt ;
00873 #endif
00874     }
00875 
00877     void setEdgeOffsets( UCHAR* leaf, float pt[3], int len )
00878     {
00879         float * pts = ( float * ) ( leaf + leaf_node_bytes ) ;
00880         for ( int i = 0 ; i < len ; i ++ )
00881         {
00882             pts[i] = pt[i] ;
00883         }
00884     }
00885 
00887     float getEdgeOffset( UCHAR* leaf, int count )
00888     {
00889 #ifdef USE_HERMIT
00890         return (( float * ) ( leaf + leaf_node_bytes ))[ 4 * count ] ;
00891 #else
00892         return (( float * ) ( leaf + leaf_node_bytes ))[ count ] ;
00893 #endif
00894     }
00895 
00897     UCHAR* updateEdgeOffsets( UCHAR* leaf, int oldlen, int newlen, float offs[3] )
00898     {
00899         // First, create a new leaf node
00900         UCHAR* nleaf = createLeaf( newlen ) ;
00901         for ( int i = 0 ; i < leaf_node_bytes ; i ++ )
00902         {
00903             nleaf[i] = leaf[i] ;
00904         }
00905 
00906         // Next, fill in the offsets
00907         setEdgeOffsets( nleaf, offs, newlen ) ;
00908 
00909         // Finally, delete the old leaf
00910         removeLeaf( oldlen, leaf ) ;
00911 
00912         return nleaf ;
00913     }
00914 
00916     void setOriginalIndex( UCHAR* leaf, int index )
00917     {
00918         ((int *)( leaf + leaf_node_bytes ))[ 0 ] = index ;
00919     }
00920     int getOriginalIndex( UCHAR* leaf )
00921     {
00922         return  ((int *)( leaf + leaf_node_bytes ))[ 0 ] ;
00923     }
00924 #ifdef USE_HERMIT
00925 
00926     void setMinimizerIndex( UCHAR* leaf, int index )
00927     {
00928         ((int *)( leaf + leaf_node_bytes - leaf_extra_bytes - 4 ))[ 0 ] = index ;
00929     }
00930 
00932     int getMinimizerIndex( UCHAR* leaf )
00933     {
00934         return ((int *)( leaf + leaf_node_bytes - leaf_extra_bytes - 4 ))[ 0 ] ;
00935     }
00936     
00937     int getMinimizerIndex( UCHAR* leaf, int eind )
00938     {
00939         int add = manifold_table[ getSignMask( leaf ) ].pairs[ eind ][ 0 ] - 1 ;
00940         if ( add < 0 )
00941         {
00942             printf("Manifold components wrong!\n") ;
00943         }
00944         return ((int *)( leaf + leaf_node_bytes - leaf_extra_bytes - 4 ))[ 0 ] + add ;
00945     }
00946 
00947     void getMinimizerIndices( UCHAR* leaf, int eind, int inds[2] )
00948     {
00949         const int* add = manifold_table[ getSignMask( leaf ) ].pairs[ eind ] ;
00950         inds[0] = ((int *)( leaf + leaf_node_bytes - leaf_extra_bytes - 4 ))[ 0 ] + add[0] - 1 ;
00951         if ( add[0] == add[1] )
00952         {
00953             inds[1] = -1 ;
00954         }
00955         else
00956         {
00957             inds[1] = ((int *)( leaf + leaf_node_bytes - leaf_extra_bytes - 4 ))[ 0 ] + add[1] - 1 ;
00958         }
00959     }
00960 
00961 
00963     void setEdgeOffsetNormal( UCHAR* leaf, float pt, float a, float b, float c, int count )
00964     {
00965         float * pts = ( float * ) ( leaf + leaf_node_bytes ) ;
00966         pts[ 4 * count ] = pt ;
00967         pts[ 4 * count + 1 ] = a ;
00968         pts[ 4 * count + 2 ] = b ;
00969         pts[ 4 * count + 3 ] = c ;
00970     }
00971 
00972     float getEdgeOffsetNormal( UCHAR* leaf, int count, float& a, float& b, float& c )
00973     {
00974         float * pts = ( float * ) ( leaf + leaf_node_bytes ) ;
00975         a = pts[ 4 * count + 1 ] ;
00976         b = pts[ 4 * count + 2 ] ;
00977         c = pts[ 4 * count + 3 ] ;
00978         return pts[ 4 * count ] ;
00979     }
00980 
00982     void setEdgeOffsetsNormals( UCHAR* leaf, float pt[], float a[], float b[], float c[], int len )
00983     {
00984         float * pts = ( float * ) ( leaf + leaf_node_bytes ) ;
00985         for ( int i = 0 ; i < len ; i ++ )
00986         {
00987             if ( pt[i] > 1 || pt[i] < 0 )
00988             {
00989                 printf("\noffset: %f\n", pt[i]) ;
00990             }
00991             pts[ i * 4 ] = pt[i] ;
00992             pts[ i * 4 + 1 ] = a[i] ;
00993             pts[ i * 4 + 2 ] = b[i] ;
00994             pts[ i * 4 + 3 ] = c[i] ;
00995         }
00996     }
00997 
00999     void getEdgeIntersectionByIndex( UCHAR* leaf, int index, int st[3], int len, float pt[3], float nm[3] )
01000     {
01001         int count = getEdgeCount( leaf, index ) ;
01002         float * pts = ( float * ) ( leaf + leaf_node_bytes ) ;
01003         
01004         float off = pts[ 4 * count ] ;
01005         
01006         pt[0] =  (float) st[0] ;
01007         pt[1] =  (float) st[1] ;
01008         pt[2] =  (float) st[2] ;
01009         pt[ index ] += ( off * len ) ;
01010 
01011         nm[0] = pts[ 4 * count + 1 ] ;
01012         nm[1] = pts[ 4 * count + 2 ] ;
01013         nm[2] = pts[ 4 * count + 3 ] ;
01014     }
01015 
01016     float getEdgeOffsetNormalByIndex( UCHAR* leaf, int index, float nm[3] )
01017     {
01018         int count = getEdgeCount( leaf, index ) ;
01019         float * pts = ( float * ) ( leaf + leaf_node_bytes ) ;
01020         
01021         float off = pts[ 4 * count ] ;
01022         
01023         nm[0] = pts[ 4 * count + 1 ] ;
01024         nm[1] = pts[ 4 * count + 2 ] ;
01025         nm[2] = pts[ 4 * count + 3 ] ;
01026 
01027         return off ;
01028     }
01029 
01030     void fillEdgeIntersections( UCHAR* leaf, int st[3], int len, float pts[12][3], float norms[12][3] )
01031     {
01032         int i ;
01033         // int stt[3] = { 0, 0, 0 } ;
01034 
01035         // The three primal edges are easy
01036         int pmask[3] = { 0, 4, 8 } ;
01037         for ( i = 0 ; i < 3 ; i ++ )
01038         {
01039             if ( getEdgeParity( leaf, pmask[i] ) )
01040             {
01041                 // getEdgeIntersectionByIndex( leaf, i, stt, 1, pts[ pmask[i] ], norms[ pmask[i] ] ) ;
01042                 getEdgeIntersectionByIndex( leaf, i, st, len, pts[ pmask[i] ], norms[ pmask[i] ] ) ;
01043             }
01044         }
01045         
01046         // 3 face adjacent cubes
01047         int fmask[3][2] = {{6,10},{2,9},{1,5}} ;
01048         int femask[3][2] = {{1,2},{0,2},{0,1}} ;
01049         for ( i = 0 ; i < 3 ; i ++ )
01050         {
01051             int e1 = getEdgeParity( leaf, fmask[i][0] ) ;
01052             int e2 = getEdgeParity( leaf, fmask[i][1] ) ;
01053             if ( e1 || e2 )
01054             {
01055                 int nst[3] = {st[0], st[1], st[2]} ;
01056                 nst[ i ] += len ;
01057                 // int nstt[3] = {0, 0, 0} ;
01058                 // nstt[ i ] += 1 ;
01059                 UCHAR* node = locateLeaf( nst ) ;
01060                 
01061                 if ( e1 )
01062                 {
01063                     // getEdgeIntersectionByIndex( node, femask[i][0], nstt, 1, pts[ fmask[i][0] ], norms[ fmask[i][0] ] ) ;
01064                     getEdgeIntersectionByIndex( node, femask[i][0], nst, len, pts[ fmask[i][0] ], norms[ fmask[i][0] ] ) ;
01065                 }
01066                 if ( e2 )
01067                 {
01068                     // getEdgeIntersectionByIndex( node, femask[i][1], nstt, 1, pts[ fmask[i][1] ], norms[ fmask[i][1] ] ) ;
01069                     getEdgeIntersectionByIndex( node, femask[i][1], nst, len, pts[ fmask[i][1] ], norms[ fmask[i][1] ] ) ;
01070                 }
01071             }
01072         }
01073         
01074         // 3 edge adjacent cubes
01075         int emask[3] = {3, 7, 11} ;
01076         int eemask[3] = {0, 1, 2} ;
01077         for ( i = 0 ; i < 3 ; i ++ )
01078         {
01079             if ( getEdgeParity( leaf, emask[i] ) )
01080             {
01081                 int nst[3] = {st[0] + len, st[1] + len, st[2] + len} ;
01082                 nst[ i ] -= len ;
01083                 // int nstt[3] = {1, 1, 1} ;
01084                 // nstt[ i ] -= 1 ;
01085                 UCHAR* node = locateLeaf( nst ) ;
01086                 
01087                 // getEdgeIntersectionByIndex( node, eemask[i], nstt, 1, pts[ emask[i] ], norms[ emask[i] ] ) ;
01088                 getEdgeIntersectionByIndex( node, eemask[i], nst, len, pts[ emask[i] ], norms[ emask[i] ] ) ;
01089             }
01090         }
01091     }
01092 
01093 
01094     void fillEdgeIntersections( UCHAR* leaf, int st[3], int len, float pts[12][3], float norms[12][3], int parity[12] )
01095     {
01096         int i ;
01097         for ( i = 0 ; i < 12 ; i ++ )
01098         {
01099             parity[ i ] = 0 ;
01100         }
01101         // int stt[3] = { 0, 0, 0 } ;
01102 
01103         // The three primal edges are easy
01104         int pmask[3] = { 0, 4, 8 } ;
01105         for ( i = 0 ; i < 3 ; i ++ )
01106         {
01107             if ( getStoredEdgesParity( leaf, i ) )
01108             {
01109                 // getEdgeIntersectionByIndex( leaf, i, stt, 1, pts[ pmask[i] ], norms[ pmask[i] ] ) ;
01110                 getEdgeIntersectionByIndex( leaf, i, st, len, pts[ pmask[i] ], norms[ pmask[i] ] ) ;
01111                 parity[ pmask[i] ] = 1 ;
01112             }
01113         }
01114         
01115         // 3 face adjacent cubes
01116         int fmask[3][2] = {{6,10},{2,9},{1,5}} ;
01117         int femask[3][2] = {{1,2},{0,2},{0,1}} ;
01118         for ( i = 0 ; i < 3 ; i ++ )
01119         {
01120             {
01121                 int nst[3] = {st[0], st[1], st[2]} ;
01122                 nst[ i ] += len ;
01123                 // int nstt[3] = {0, 0, 0} ;
01124                 // nstt[ i ] += 1 ;
01125                 UCHAR* node = locateLeafCheck( nst ) ;
01126                 if ( node == NULL )
01127                 {
01128                     continue ;
01129                 }
01130         
01131                 int e1 = getStoredEdgesParity( node, femask[i][0] ) ;
01132                 int e2 = getStoredEdgesParity( node, femask[i][1] ) ;
01133                 
01134                 if ( e1 )
01135                 {
01136                     // getEdgeIntersectionByIndex( node, femask[i][0], nstt, 1, pts[ fmask[i][0] ], norms[ fmask[i][0] ] ) ;
01137                     getEdgeIntersectionByIndex( node, femask[i][0], nst, len, pts[ fmask[i][0] ], norms[ fmask[i][0] ] ) ;
01138                     parity[ fmask[i][0] ] = 1 ;
01139                 }
01140                 if ( e2 )
01141                 {
01142                     // getEdgeIntersectionByIndex( node, femask[i][1], nstt, 1, pts[ fmask[i][1] ], norms[ fmask[i][1] ] ) ;
01143                     getEdgeIntersectionByIndex( node, femask[i][1], nst, len, pts[ fmask[i][1] ], norms[ fmask[i][1] ] ) ;
01144                     parity[ fmask[i][1] ] = 1 ;
01145                 }
01146             }
01147         }
01148         
01149         // 3 edge adjacent cubes
01150         int emask[3] = {3, 7, 11} ;
01151         int eemask[3] = {0, 1, 2} ;
01152         for ( i = 0 ; i < 3 ; i ++ )
01153         {
01154 //          if ( getEdgeParity( leaf, emask[i] ) )
01155             {
01156                 int nst[3] = {st[0] + len, st[1] + len, st[2] + len} ;
01157                 nst[ i ] -= len ;
01158                 // int nstt[3] = {1, 1, 1} ;
01159                 // nstt[ i ] -= 1 ;
01160                 UCHAR* node = locateLeafCheck( nst ) ;
01161                 if ( node == NULL )
01162                 {
01163                     continue ;
01164                 }
01165                 
01166                 if ( getStoredEdgesParity( node, eemask[i] ) )
01167                 {
01168                     // getEdgeIntersectionByIndex( node, eemask[i], nstt, 1, pts[ emask[i] ], norms[ emask[i] ] ) ;
01169                     getEdgeIntersectionByIndex( node, eemask[i], nst, len, pts[ emask[i] ], norms[ emask[i] ] ) ;
01170                     parity[ emask[ i ] ] = 1 ;
01171                 }
01172             }
01173         }
01174     }
01175 
01176     void fillEdgeOffsetsNormals( UCHAR* leaf, int st[3], int len, float pts[12], float norms[12][3], int parity[12] )
01177     {
01178         int i ;
01179         for ( i = 0 ; i < 12 ; i ++ )
01180         {
01181             parity[ i ] = 0 ;
01182         }
01183         // int stt[3] = { 0, 0, 0 } ;
01184 
01185         // The three primal edges are easy
01186         int pmask[3] = { 0, 4, 8 } ;
01187         for ( i = 0 ; i < 3 ; i ++ )
01188         {
01189             if ( getStoredEdgesParity( leaf, i ) )
01190             {
01191                 pts[ pmask[i] ] = getEdgeOffsetNormalByIndex( leaf, i, norms[ pmask[i] ] ) ;
01192                 parity[ pmask[i] ] = 1 ;
01193             }
01194         }
01195         
01196         // 3 face adjacent cubes
01197         int fmask[3][2] = {{6,10},{2,9},{1,5}} ;
01198         int femask[3][2] = {{1,2},{0,2},{0,1}} ;
01199         for ( i = 0 ; i < 3 ; i ++ )
01200         {
01201             {
01202                 int nst[3] = {st[0], st[1], st[2]} ;
01203                 nst[ i ] += len ;
01204                 // int nstt[3] = {0, 0, 0} ;
01205                 // nstt[ i ] += 1 ;
01206                 UCHAR* node = locateLeafCheck( nst ) ;
01207                 if ( node == NULL )
01208                 {
01209                     continue ;
01210                 }
01211         
01212                 int e1 = getStoredEdgesParity( node, femask[i][0] ) ;
01213                 int e2 = getStoredEdgesParity( node, femask[i][1] ) ;
01214                 
01215                 if ( e1 )
01216                 {
01217                     pts[ fmask[i][0] ] = getEdgeOffsetNormalByIndex( node, femask[i][0], norms[ fmask[i][0] ] ) ;
01218                     parity[ fmask[i][0] ] = 1 ;
01219                 }
01220                 if ( e2 )
01221                 {
01222                     pts[ fmask[i][1] ] = getEdgeOffsetNormalByIndex( node, femask[i][1], norms[ fmask[i][1] ] ) ;
01223                     parity[ fmask[i][1] ] = 1 ;
01224                 }
01225             }
01226         }
01227         
01228         // 3 edge adjacent cubes
01229         int emask[3] = {3, 7, 11} ;
01230         int eemask[3] = {0, 1, 2} ;
01231         for ( i = 0 ; i < 3 ; i ++ )
01232         {
01233 //          if ( getEdgeParity( leaf, emask[i] ) )
01234             {
01235                 int nst[3] = {st[0] + len, st[1] + len, st[2] + len} ;
01236                 nst[ i ] -= len ;
01237                 // int nstt[3] = {1, 1, 1} ;
01238                 // nstt[ i ] -= 1 ;
01239                 UCHAR* node = locateLeafCheck( nst ) ;
01240                 if ( node == NULL )
01241                 {
01242                     continue ;
01243                 }
01244                 
01245                 if ( getStoredEdgesParity( node, eemask[i] ) )
01246                 {
01247                     pts[ emask[i] ] = getEdgeOffsetNormalByIndex( node, eemask[i], norms[ emask[i] ] ) ;
01248                     parity[ emask[ i ] ] = 1 ;
01249                 }
01250             }
01251         }
01252     }
01253 
01254 
01256     UCHAR* updateEdgeOffsetsNormals( UCHAR* leaf, int oldlen, int newlen, float offs[3], float a[3], float b[3], float c[3] )
01257     {
01258         // First, create a new leaf node
01259         UCHAR* nleaf = createLeaf( newlen ) ;
01260         for ( int i = 0 ; i < leaf_node_bytes ; i ++ )
01261         {
01262             nleaf[i] = leaf[i] ;
01263         }
01264 
01265         // Next, fill in the offsets
01266         setEdgeOffsetsNormals( nleaf, offs, a, b, c, newlen ) ;
01267 
01268         // Finally, delete the old leaf
01269         removeLeaf( oldlen, leaf ) ;
01270 
01271         return nleaf ;
01272     }
01273 #endif
01274 
01277     
01278     UCHAR* locateLeaf( int st[3] )
01279     {
01280         UCHAR* node = root ;
01281         for ( int i = GRID_DIMENSION - 1 ; i > GRID_DIMENSION - maxDepth - 1 ; i -- )
01282         {
01283             int index = ( ( ( st[0] >> i ) & 1 ) << 2 ) | 
01284                         ( ( ( st[1] >> i ) & 1 ) << 1 ) | 
01285                         ( ( ( st[2] >> i ) & 1 ) ) ;
01286             node = getChild( node, getChildCount( node, index ) ) ;
01287         }
01288 
01289         return node ;
01290     }
01291     
01292     UCHAR* locateLeaf( UCHAR* node, int len, int st[3] )
01293     {
01294         int index ;
01295         for ( int i = len / 2 ; i >= mindimen ; i >>= 1 )
01296         {
01297             index = ( ( ( st[0] & i ) ? 4 : 0 ) | 
01298                     ( ( st[1] & i ) ? 2 : 0 ) | 
01299                     ( ( st[2] & i ) ? 1 : 0 ) ) ;
01300             node = getChild( node, getChildCount( node, index ) ) ;
01301         }
01302 
01303         return node ;
01304     }
01305     UCHAR* locateLeafCheck( int st[3] )
01306     {
01307         UCHAR* node = root ;
01308         for ( int i = GRID_DIMENSION - 1 ; i > GRID_DIMENSION - maxDepth - 1 ; i -- )
01309         {
01310             int index = ( ( ( st[0] >> i ) & 1 ) << 2 ) | 
01311                         ( ( ( st[1] >> i ) & 1 ) << 1 ) | 
01312                         ( ( ( st[2] >> i ) & 1 ) ) ;
01313             if ( ! hasChild( node, index ) )
01314             {
01315                 return NULL ;
01316             }
01317             node = getChild( node, getChildCount( node, index ) ) ;
01318         }
01319 
01320         return node ;
01321     }
01322     UCHAR* locateParent( int len, int st[3], int& count )
01323     {
01324         UCHAR* node = root ;
01325         UCHAR* pre = NULL ;
01326         int index = 0 ;
01327         for ( int i = dimen / 2 ; i >= len ; i >>= 1 )
01328         {
01329             index = ( ( ( st[0] & i ) ? 4 : 0 ) | 
01330                     ( ( st[1] & i ) ? 2 : 0 ) | 
01331                     ( ( st[2] & i ) ? 1 : 0 ) ) ;
01332             pre = node ;
01333             node = getChild( node, getChildCount( node, index ) ) ;
01334         }
01335 
01336         count = getChildCount( pre, index ) ;
01337         return pre ;
01338     }
01339     UCHAR* locateParent( UCHAR* papa, int len, int st[3], int& count )
01340     {
01341         UCHAR* node = papa ;
01342         UCHAR* pre = NULL ;
01343         int index = 0;
01344         for ( int i = len / 2 ; i >= mindimen ; i >>= 1 )
01345         {
01346             index = ( ( ( st[0] & i ) ? 4 : 0 ) | 
01347                     ( ( st[1] & i ) ? 2 : 0 ) | 
01348                     ( ( st[2] & i ) ? 1 : 0 ) ) ;
01349             pre = node ;
01350             node = getChild( node, getChildCount( node, index ) ) ;
01351         }
01352 
01353         count = getChildCount( pre, index ) ;
01354         return pre ;
01355     }
01356     /************ Operators for internal nodes ************/
01357 
01359     void printNode( UCHAR* node )
01360     {
01361         printf("Address: %p ", node ) ;
01362         printf("Leaf Mask: ") ;
01363         for ( int i = 0 ; i < 8 ; i ++ )
01364         {
01365             printf( "%d ", isLeaf( node, i ) ) ;
01366         }
01367         printf("Child Mask: ") ;
01368         for ( int i = 0 ; i < 8 ; i ++ )
01369         {
01370             printf( "%d ", hasChild( node, i ) ) ;
01371         }
01372         printf("\n") ;
01373     }
01374 
01376     int getSize ( int length )
01377     {
01378         return INTERNAL_NODE_BYTES + length * 4 ;   
01379     };
01380 
01382     int hasChild( UCHAR* node, int index )
01383     {
01384         return ( node[0] >> index ) & 1 ;
01385     };
01386 
01388     int isLeaf ( UCHAR* node, int index )
01389     {
01390         return ( node[1] >> index ) & 1 ;
01391     };
01392 
01394     UCHAR* getChild ( UCHAR* node, int count )
01395     {
01396         return (( UCHAR ** ) ( node + INTERNAL_NODE_BYTES )) [ count ] ;    
01397     };
01398 
01400     int getNumChildren( UCHAR* node )
01401     {
01402         return numChildrenTable[ node[0] ] ;
01403     };
01404 
01406     int getChildCount( UCHAR* node, int index )
01407     {
01408         return childrenCountTable[ node[0] ][ index ] ;
01409     }
01410     int getChildIndex( UCHAR* node, int count )
01411     {
01412         return childrenIndexTable[ node[0] ][ count ] ;
01413     }
01414     int* getChildCounts( UCHAR* node )
01415     {
01416         return childrenCountTable[ node[0] ] ;
01417     }
01418 
01420     void fillChildren( UCHAR* node, UCHAR* chd[ 8 ], int leaf[ 8 ] )
01421     {
01422         int count = 0 ;
01423         for ( int i = 0 ; i < 8 ; i ++ )
01424         {   
01425             leaf[ i ] = isLeaf( node, i ) ;
01426             if ( hasChild( node, i ) )
01427             {
01428                 chd[ i ] = getChild( node, count ) ;
01429                 count ++ ;
01430             }
01431             else
01432             {
01433                 chd[ i ] = NULL ;
01434                 leaf[ i ] = 0 ;
01435             }
01436         }
01437     }
01438 
01440     void setChild ( UCHAR* node, int count, UCHAR* chd )
01441     {
01442         (( UCHAR ** ) ( node + INTERNAL_NODE_BYTES )) [ count ] = chd ;
01443     }
01444     void setInternalChild ( UCHAR* node, int index, int count, UCHAR* chd )
01445     {
01446         setChild( node, count, chd ) ;
01447         node[0] |= ( 1 << index ) ;
01448     };
01449     void setLeafChild ( UCHAR* node, int index, int count, UCHAR* chd )
01450     {
01451         setChild( node, count, chd ) ;
01452         node[0] |= ( 1 << index ) ;
01453         node[1] |= ( 1 << index ) ;
01454     };
01455 
01459     UCHAR* addChild( UCHAR* node, int index, UCHAR* chd, int aLeaf )
01460     {
01461         // Create new internal node
01462         int num = getNumChildren( node ) ;
01463         UCHAR* rnode = createInternal( num + 1 ) ;
01464 
01465         // Establish children
01466         int i ;
01467         int count1 = 0, count2 = 0 ;
01468         for ( i = 0 ; i < 8 ; i ++ )
01469         {
01470             if ( i == index )
01471             {
01472                 if ( aLeaf )
01473                 {
01474                     setLeafChild( rnode, i, count2, chd ) ;
01475                 }
01476                 else
01477                 {
01478                     setInternalChild( rnode, i, count2, chd ) ;
01479                 }
01480                 count2 ++ ;
01481             }
01482             else if ( hasChild( node, i ) )
01483             {
01484                 if ( isLeaf( node, i ) )
01485                 {
01486                     setLeafChild( rnode, i, count2, getChild( node, count1 ) ) ;
01487                 }
01488                 else
01489                 {
01490                     setInternalChild( rnode, i, count2, getChild( node, count1 ) ) ;
01491                 }
01492                 count1 ++ ;
01493                 count2 ++ ;
01494             }
01495         }
01496 
01497         removeInternal( num, node ) ;
01498         return rnode ;
01499     }
01500 
01502     UCHAR* createInternal( int length )
01503     {
01504         UCHAR* inode = alloc[ length ]->allocate( ) ;
01505         inode[0] = inode[1] = 0 ;
01506         return inode ;
01507     };
01508     UCHAR* createLeaf( int length )
01509     {
01510         if ( length > 3 )
01511         {
01512             printf("wierd");
01513         }
01514         UCHAR* lnode = leafalloc[ length ]->allocate( ) ;
01515         lnode[0] = lnode[1] = lnode[2] = 0 ;
01516 
01517         return lnode ;
01518     };
01519 
01520     void removeInternal ( int num, UCHAR* node )
01521     {
01522         alloc[ num ]->deallocate( node ) ;
01523     }
01524 
01525     void removeLeaf ( int num, UCHAR* leaf )
01526     {
01527         if ( num > 3 || num < 0 )
01528         {
01529             printf("wierd");
01530         }
01531         leafalloc[ num ]->deallocate( leaf ) ;
01532     }
01533 
01535     UCHAR* addLeafChild ( UCHAR* par, int index, int count, UCHAR* leaf )
01536     {
01537         int num = getNumChildren( par ) + 1 ;
01538         UCHAR* npar = createInternal( num ) ;
01539         npar[0] = par[0] ;
01540         npar[1] = par[1] ;
01541         
01542         if ( num == 1 )
01543         {
01544             setLeafChild( npar, index, 0, leaf ) ;
01545         }
01546         else
01547         {
01548             int i ;
01549             for ( i = 0 ; i < count ; i ++ )
01550             {
01551                 setChild( npar, i, getChild( par, i ) ) ;
01552             }
01553             setLeafChild( npar, index, count, leaf ) ;
01554             for ( i = count + 1 ; i < num ; i ++ )
01555             {
01556                 setChild( npar, i, getChild( par, i - 1 ) ) ;
01557             }
01558         }
01559         
01560         removeInternal( num-1, par ) ;
01561         return npar ;
01562     };
01563 
01564     UCHAR* addInternalChild ( UCHAR* par, int index, int count, UCHAR* node )
01565     {
01566         int num = getNumChildren( par ) + 1 ;
01567         UCHAR* npar = createInternal( num ) ;
01568         npar[0] = par[0] ;
01569         npar[1] = par[1] ;
01570         
01571         if ( num == 1 )
01572         {
01573             setInternalChild( npar, index, 0, node ) ;
01574         }
01575         else
01576         {
01577             int i ;
01578             for ( i = 0 ; i < count ; i ++ )
01579             {
01580                 setChild( npar, i, getChild( par, i ) ) ;
01581             }
01582             setInternalChild( npar, index, count, node ) ;
01583             for ( i = count + 1 ; i < num ; i ++ )
01584             {
01585                 setChild( npar, i, getChild( par, i - 1 ) ) ;
01586             }
01587         }
01588         
01589         removeInternal( num-1, par ) ;
01590         return npar ;
01591     };
01592 };
01593 
01594 
01595 
01596 #endif