Blender V2.61 - r43446
|
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