EMAN2
volume.cpp
Go to the documentation of this file.
00001 // Copyright (C) 2005-2008 Washington University in St Louis, Baylor College of Medicine.  All rights reserved
00002 // Author:        Tao Ju (taoju@cse.wustl.edu), Refactored by Sasakthi Abeysinghe (sasakthi.abeysinghe@wustl.edu)
00003 // Description:   Volumetric data definition
00004 
00005 #include "volume.h"
00006 
00007 using namespace wustl_mm::SkeletonMaker;
00008 
00009                 Volume::Volume(EMData* em) //eman2
00010                 {
00011                         this->volData = new VolumeData(em);
00012                 }
00013                 Volume::Volume(int x, int y, int z) {
00014                         volData = new VolumeData(x, y, z);
00015                 }
00016 
00017                 Volume::Volume(int x, int y, int z, float val) {
00018                         volData = new VolumeData(x, y, z, val);
00019                 }
00020 
00021                 Volume::Volume(int x, int y, int z, int offx, int offy, int offz, Volume * vol) {
00022                         volData = new VolumeData(x, y, z, offx, offy, offz, vol->getVolumeData());
00023                 }
00024 
00025 
00026                 Volume::~Volume( )
00027                 {
00028                         delete volData;
00029                 }
00030 
00031                 EMData* Volume::get_emdata() //eman2
00032                 {
00033                         return this->getVolumeData()->get_emdata();
00034                 }
00035 
00036                 int Volume::getSizeX() {
00037                         return volData->GetSizeX();
00038                 }
00039 
00040                 int Volume::getSizeY() {
00041                         return volData->GetSizeY();
00042                 }
00043 
00044                 int Volume::getSizeZ() {
00045                         return volData->GetSizeZ();
00046                 }
00047 
00048                 int Volume::getIndex(int x, int y, int z) {
00049                         return volData->GetIndex(x, y, z);
00050                 }
00051 
00052                 void Volume::setDataAt( int x, int y, int z, double d ) {
00053                         volData->SetDataAt(x, y, z, (float)d);
00054                 }
00055 
00056                 void Volume::setDataAt( int index, double d ) {
00057                         volData->SetDataAt(index, (float)d);
00058                 }
00059 
00060                 double Volume::getDataAt( int x, int y, int z )
00061                 {
00062                         return volData->GetDataAt(x, y, z);
00063                 }
00064 
00065                 double Volume::getDataAt( int index ) {
00066                         return volData->GetDataAt(index);
00067                 }
00068 
00069                 VolumeData * Volume::getVolumeData() {
00070                         return volData;
00071                 }
00072 
00073                 void Volume::setSpacing(float spx, float spy, float spz ) {
00074                         volData->SetSpacing(spx, spy, spz);
00075                 }
00076 
00077                 void Volume::setOrigin(float orgX, float orgY, float orgZ) {
00078                         volData->SetOrigin(orgX, orgY, orgZ);
00079                 }
00080 
00081                 float Volume::getSpacingX() {
00082                         return volData->GetSpacingX();
00083                 }
00084 
00085                 float Volume::getSpacingY() {
00086                         return volData->GetSpacingY();
00087                 }
00088 
00089                 float Volume::getSpacingZ() {
00090                         return volData->GetSpacingZ();
00091                 }
00092 
00093                 float Volume::getOriginX() {
00094                         return volData->GetOriginX();
00095                 }
00096 
00097                 float Volume::getOriginY() {
00098                         return volData->GetOriginY();
00099                 }
00100 
00101                 float Volume::getOriginZ() {
00102                         return volData->GetOriginZ();
00103                 }
00104 
00105                 //Volume * Volume::getPseudoDensity( ) {
00108                         //int i, j, k ;
00109                         //Volume * res = new Volume(getSizeX(), getSizeY(), getSizeZ(), 0, 0, 0, this);
00110                         //int size = getSizeX() * getSizeY() * getSizeZ() ;
00111                         //srand(123) ;
00112 
00113                         //for ( i = 0 ; i < getSizeX() ; i ++ )
00114                                 //for ( j = 0 ; j < getSizeY() ; j ++ )
00115                                         //for ( k = 0 ; k < getSizeZ() ; k ++ ) {
00116                                                 //if ( res->getDataAt( i, j, k ) > 0 ) {
00117                                                         //int ct = 0 ;
00118                                                         //for ( int m = 0 ; m < 6 ; m ++ ) {
00119                                                                 //if ( res->getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) > 0 ) {
00120                                                                         //ct ++ ;
00121                                                                 //}
00122                                                         //}
00123                                                         //res->setDataAt( i,j,k, (k/(float)getSizeZ())*(k/(float)getSizeZ()) ) ;
00124                                                         //if ( ct > 2 ) {
00126                                                         //} else {
00128                                                         //}
00129                                                 //}
00130                                         //}
00131 
00133                         //for ( i = 0 ; i < 20 ; i ++ )
00134                         //{
00135                                 //printf("Smoothing round %d\n", i) ;
00136                                 //res->smooth( 0.5f ) ;
00137                         //}
00138                         //*/
00139 
00140                         //Volume * tvol = new Volume( getSizeX(), getSizeY(), getSizeZ(), 0, 0, 0, res);
00141                         //float d, ad, ct, temp;
00142                         //for ( int it = 0 ; it < 3 ; it ++ )
00143                         //for ( i = 0 ; i < getSizeX() ; i ++ )
00144                                 //for ( j = 0 ; j < getSizeY() ; j ++ )
00145                                         //for ( k = 0 ; k < getSizeZ() ; k ++ ) {
00146                                                 //if ( (d = (float)tvol->getDataAt( i, j, k )) > 0 ) {
00147                                                         //ad = 0 ; ct = 0 ;
00148                                                         //for ( int m = 0 ; m < 6 ; m ++ ) {
00149                                                                 //if ( (temp = (float)tvol->getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] )) > 0 ) {
00150                                                                         //ad += temp;
00151                                                                         //ct ++ ;
00152                                                                 //}
00153                                                         //}
00154                                                         //if ( ct > 0 ) {
00155                                                                 //res->setDataAt( i, j, k, ( d + ad/ct ) / 2 ) ;
00156                                                         //}
00157                                                 //}
00158                                         //}
00159 
00160                         //delete tvol;
00161                         //tvol = new Volume( getSizeX(), getSizeY(), getSizeZ(), 0, 0, 0, res ) ;
00162                         //for ( i = 0 ; i < 40 ; i ++ )
00163                         //{
00164                                 //printf("Smoothing round %d\n", i) ;
00165                                 //res->smooth( 0.5f ) ;
00166                                 //continue ;
00167 
00176 
00177                         //}
00178 
00179 
00180                         //return res ;
00181                 //}
00182 
00183 
00184                 //Volume * Volume::getDistanceField(int rad, float randf) {
00188 
00190                         //int i, j, k ;
00191                         //Volume * res = new Volume(getSizeX(), getSizeY(), getSizeZ(), 0, 0, 0, this);
00192                         //srand( 123 ) ;
00193 
00194                         //for ( i = 0 ; i < getSizeX() ; i ++ )
00195                                 //for ( j = 0 ; j < getSizeY() ; j ++ )
00196                                         //for ( k = 0 ; k < getSizeZ() ; k ++ ) {
00197                                                 //if ( getDataAt(i, j, k) > 0 ) {
00198                                                         //float mag = 1 + randf * (float) rand() / (float) RAND_MAX ;
00199                                                         //int lx = max(0,i-rad) ;
00200                                                         //int ly = max(0,j-rad) ;
00201                                                         //int lz = max(0,k-rad) ;
00202                                                         //int hx = min(getSizeX()-1,i+rad) ;
00203                                                         //int hy = min(getSizeY()-1,j+rad) ;
00204                                                         //int hz = min(getSizeZ()-1,k+rad) ;
00205                                                         //int x,y,z;
00206                                                         //for ( x = lx ; x <= hx ; x ++ )
00207                                                                 //for ( y = ly ; y <= hy ; y ++ )
00208                                                                         //for ( z = lz ; z <= hz ; z ++ ) {
00209                                                                                 //float val = 1 - (float) sqrt((double)((x-i)*(x-i) + (y-j)*(y-j) + (z-k)*(z-k))) / (float) rad ;
00210                                                                                 //val *= mag ;
00211                                                                                 //if ( res->getDataAt( x, y, z ) < val ) {
00212                                                                                         //res->setDataAt( x, y, z, val ) ;
00213                                                                                 //}
00214                                                                         //}
00215                                                 //}
00216                                         //}
00217 
00219                         //for ( i = 0 ; i < 2 ; i ++ )
00220                         //{
00221                                 //printf("Smoothing round %d\n", i) ;
00222                                 //res->smooth( 0.5f ) ;
00223                         //}
00224 
00225 
00226                         //return res ;
00227                 //}
00228 
00229 
00230                 //int Volume::getNonZeroVoxelCount() {
00231                         //int count = 0;
00232                         //for(int x = 0; x < getSizeX(); x++){
00233                                 //for(int y = 0; y < getSizeY(); y++){
00234                                         //for(int z = 0; z < getSizeZ(); z++){
00235                                                 //if(this->getDataAt(x, y, z) > 0.0) {
00236                                                         //count++;
00237                                                 //}
00238                                         //}
00239                                 //}
00240                         //}
00241                         //return count;
00242                 //}
00243                 //void Volume::print() {
00244                         //for(int x = 0; x < getSizeX(); x++) {
00245                                 //printf("{ ");
00246                                 //for(int y = 0; y < getSizeY(); y++) {
00247                                         //printf("{ ");
00248                                         //for(int z = 0; z < getSizeZ(); z++) {
00249                                                 //printf("%f, ", getDataAt(x, y, z));
00250                                         //}
00251                                         //printf("} ");
00252                                 //}
00253                                 //printf("} ");
00254                         //}
00255                         //printf("\n");
00256                 //}
00257 
00258 
00259                 //void Volume::subtract( Volume* vol ) {
00260                         //int i, j, k ;
00261                         //for ( i = 0 ; i < getSizeX() ; i ++ )
00262                                 //for ( j = 0 ; j < getSizeY() ; j ++ )
00263                                         //for ( k = 0 ; k < getSizeZ() ; k ++ ) {
00264                                                 //if ( getDataAt( i, j, k ) > 0 ) {
00265                                                         //if ( vol->getDataAt(i,j,k) > 0 ) {
00266                                                                 //setDataAt( i, j, k, 0 ) ;
00267                                                         //}
00268                                                 //}
00269                                         //}
00270 
00271                 //}
00272 
00273                 void Volume::pad (int padBy, double padValue) {
00274                         volData->Pad(padBy, padValue);
00275                 }
00276 
00277                 //void Volume::applyMask(Volume * maskVol, double maskValue, bool keepMaskValue) {
00278                         //for(int x = 0; x < maskVol->getSizeX(); x++) {
00279                                 //for(int y = 0; y < maskVol->getSizeY(); y++) {
00280                                         //for(int z = 0; z < maskVol->getSizeZ(); z++) {
00281                                                 //if(((maskVol->getDataAt(x, y, z) == maskValue) && !keepMaskValue) ||
00282                                                         //((maskVol->getDataAt(x, y, z) != maskValue) && keepMaskValue)) {
00283                                                         //setDataAt(x, y, z, 0);
00284                                                 //}
00285                                         //}
00286                                 //}
00287                         //}
00288                 //}
00289 
00290                 //double Volume::getMin() {
00291                         //int size = volData->GetMaxIndex();
00292                         //double rvalue = volData->GetDataAt(0);
00293                         //for (int i=1; i < size; i++) {
00294                                 //float val = volData->GetDataAt(i);
00295                                 //if ( rvalue > val) {
00296                                         //rvalue = val;
00297                                 //}
00298                         //}
00299                         //return rvalue;
00300                 //}
00301 
00302                 //double Volume::getMax() {
00303                         //int size = volData->GetMaxIndex();
00304                         //double rvalue = volData->GetDataAt(0);
00305                         //for (int i=1; i < size; i++) {
00306                                 //float val = volData->GetDataAt(i);
00307                                 //if ( rvalue < val) {
00308                                         //rvalue = val;
00309                                 //}
00310                         //}
00311                         //return rvalue ;
00312                 //}
00313 
00314                 //double Volume::getMaxValuePosition(int& maxX, int& maxY, int& maxZ) {
00315                         //double maxVal = getDataAt(0,0,0);
00316                         //maxX = 0; maxY = 0; maxZ = 0;
00317                         //double data;
00318 
00319                         //for(int x = 0; x < getSizeX(); x++) {
00320                                 //for(int y = 0; y < getSizeY(); y++) {
00321                                         //for(int z = 0; z < getSizeZ(); z++) {
00322                                                 //data = getDataAt(x, y, z);
00323                                                 //if(data > maxVal) {
00324                                                         //maxVal = data;
00325                                                         //maxX = x; maxY = y; maxZ = z;
00326                                                 //}
00327                                         //}
00328                                 //}
00329                         //}
00330                         //return maxVal;
00331                 //}
00332 
00333                 //double Volume::getLocalMax(int x, int y, int z, int radius) {
00334                         //double mx = getDataAt(x, y, z);
00335                         //for(int xx = x - radius; xx <= x + radius; xx++) {
00336                                 //for(int yy = y - radius; yy <= y + radius; yy++) {
00337                                         //for(int zz = z - radius; zz <= z + radius; zz++) {
00338                                                 //mx = max(mx, getDataAt(xx, yy, zz));
00339                                         //}
00340                                 //}
00341                         //}
00342                         //return mx;
00343                 //}
00344 
00345                 //double Volume::getLocalMin(int x, int y, int z, int radius) {
00346                         //double mn = getDataAt(x, y, z);
00347                         //for(int xx = x - radius; xx <= x + radius; xx++) {
00348                                 //for(int yy = y - radius; yy <= y + radius; yy++) {
00349                                         //for(int zz = z - radius; zz <= z + radius; zz++) {
00350                                                 //mn = min(mn, getDataAt(xx, yy, zz));
00351                                         //}
00352                                 //}
00353                         //}
00354                         //return mn;
00355                 //}
00356 
00357                 //void Volume::fill( double val )
00358                 //{
00359                         //for(int x = 0; x < getSizeX(); x++) {
00360                                 //for(int y = 0; y < getSizeY(); y++) {
00361                                         //for(int z = 0; z < getSizeZ(); z++) {
00362                                                 //setDataAt(x, y, z, val);
00363                                         //}
00364                                 //}
00365                         //}
00366                 //}
00367 
00368                 //int Volume::isBertrandBorder( int ox, int oy, int oz, int dir ) {
00369                         //int nx = ox + neighbor6[dir][0] ;
00370                         //int ny = oy + neighbor6[dir][1] ;
00371                         //int nz = oz + neighbor6[dir][2] ;
00372                         //if ( getDataAt( nx, ny, nz) < 0 ) {
00373                                 //return 1 ;
00374                         //}
00375                         //return 0 ;
00376                 //}
00377 
00378                 //int Volume::isBertrandEndPoint( int ox, int oy, int oz ) {
00379                         //double vox[3][3][3] ;
00380 
00381                         //int i, j, k ;
00382                         //for ( i = -1 ; i < 2 ; i ++ )
00383                                 //for ( j = -1 ; j < 2 ; j ++ )
00384                                         //for ( k = -1 ; k < 2 ; k ++ ) {
00385                                                 //double tval = getDataAt( ox + i, oy + j, oz + k ) ;
00386                                                         //vox[ i + 1 ][ j + 1 ][ k + 1 ] = tval ;
00387                                         //}
00388 
00390                         //int xx6 = 0 ;
00391                         //for ( i = 0 ; i < 6 ; i ++ ) {
00392                                 //if ( vox[ neighbor6[i][0] + 1 ][ neighbor6[i][1] + 1 ][ neighbor6[i][2] + 1 ] >= 0 ) {
00393                                         //xx6 ++ ;
00394                                 //}
00395                         //}
00396 
00398                         //int a26 = 0, na26 = 0 ;
00399                         //for ( i = 0 ; i < 3 ; i += 2 )
00400                                 //for ( j = 0 ; j < 3 ; j += 2 )
00401                                         //for ( k = 0 ; k < 3 ; k += 2 ) {
00402                                                 //if ( vox[1][j][k] < 0 ) {
00403                                                         //continue ;
00404                                                 //}
00405                                                 //if ( vox[i][1][k] < 0 ) {
00406                                                         //continue ;
00407                                                 //}
00408                                                 //if ( vox[i][j][1] < 0 ) {
00409                                                         //continue ;
00410                                                 //}
00411                                                 //if ( vox[i][1][1] < 0 ) {
00412                                                         //continue ;
00413                                                 //}
00414                                                 //if ( vox[1][j][1] < 0 ) {
00415                                                         //continue ;
00416                                                 //}
00417                                                 //if ( vox[1][1][k] < 0 ) {
00418                                                         //continue ;
00419                                                 //}
00420                                                 //if ( vox[i][j][k] >= 0 ) {
00421                                                         //a26 ++ ;
00422                                                 //} else {
00423                                                         //na26 ++ ;
00424                                                 //}
00425                                         //}
00426 
00427                         //if (( na26 == 0 ) && ( a26 != 0 ) && ( xx6 <= a26 + 2 ))  {
00428                                 //return 0 ;
00429                         //}
00430                         //if ( isFeatureFace(ox,oy,oz) ) {
00432                         //}
00433                         //return 1 ;
00434                 //}
00435 
00436                 //int Volume::isHelix( int ox, int oy, int oz ) {
00437                         //int cn = 12 ;
00438                         //int nx, ny, nz ;
00439                         //int i, j, k ;
00440 
00441                         //double vox[3][3][3] ;
00442                         //for ( i = -1 ; i < 2 ; i ++ )
00443                                 //for ( j = -1 ; j < 2; j ++ )
00444                                         //for ( k = -1 ; k < 2 ; k ++ ) {
00445                                                 //vox[i+1][j+1][k+1] = getDataAt( ox + i, oy + j, oz + k ) ;
00446                                         //}
00447 
00448                         //for ( i = 0 ; i < 12 ; i ++ ) {
00449                                 //for ( j = 0 ; j < 4 ; j ++ ) {
00450                                         //nx = sheetNeighbor[i][j][0] + 1;
00451                                         //ny = sheetNeighbor[i][j][1] + 1;
00452                                         //nz = sheetNeighbor[i][j][2] + 1;
00453 
00454                                         //if ( vox[nx][ny][nz] <= 0 ) {
00455                                                 //cn -- ;
00456                                                 //break ;
00457                                         //}
00458                                 //}
00459                         //}
00460 
00461                         //if ( cn >= 1 ) {
00462                                 //return 0 ;
00463                         //} else {
00464                                 //return 1 ;
00465                         //}
00466                 //}
00467 
00468                 //int Volume::isSheet( int ox, int oy, int oz ) {
00469                         //int cn = 12 ;
00470                         //int nx, ny, nz ;
00471 
00472                         //for ( int i = 0 ; i < 12 ; i ++ ) {
00473                                 //for ( int j = 0 ; j < 4 ; j ++ ) {
00474                                         //nx = ox + sheetNeighbor[i][j][0] ;
00475                                         //ny = oy + sheetNeighbor[i][j][1] ;
00476                                         //nz = oz + sheetNeighbor[i][j][2] ;
00477 
00478                                         //if ( getDataAt( nx, ny, nz ) <= 0 ) {
00479                                                 //cn -- ;
00480                                                 //break ;
00481                                         //}
00482                                 //}
00483                         //}
00484                         //return ( cn >= 3 ) ;
00485                 //}
00486 
00487                 //Volume * Volume::getSheets( int minSize ) {
00488                         //int i, j, k ;
00489 
00491                         //printf("Initialize volume at %d %d %d\n", getSizeX(), getSizeY(), getSizeZ() ) ;
00492                         //Volume* svol = new Volume( getSizeX(), getSizeY(), getSizeZ() ) ;
00493 
00495                         //int sheets[MAX_SHEETS] ;
00496                         //for ( i = 0 ; i < MAX_SHEETS ; i ++ ) {
00497                                 //sheets[ i ] = 0 ;
00498                         //}
00499                         //int totSheets = 1 ;
00500 
00502                         //printf("Start clustering...\n" ) ;
00503                         //int ox, oy, oz ;
00504                         //for ( i = 0 ; i < getSizeX() ; i ++ )
00505                                 //for ( j = 0 ; j < getSizeY() ; j ++ )
00506                                         //for ( k = 0 ; k < getSizeZ() ; k ++ ) {
00507                                                 //if ( getDataAt(i,j,k) <= 0 || svol->getDataAt(i,j,k) != 0 ) {
00509                                                         //continue ;
00510                                                 //}
00511                                                 //if ( ! isSheet( i, j, k ) ) {
00513                                                         //continue ;
00514                                                 //}
00515 
00517                                                 //int numNodes = 1 ;
00518                                                 //svol->setDataAt( i, j, k, totSheets ) ;
00519                                                 //GridQueue* queue = new GridQueue() ;
00520                                                 //queue->pushQueue( i, j, k ) ;
00521                                                 //while ( queue->popQueue(ox, oy, oz) ) {
00523                                                         //if ( isSheet( ox, oy, oz ) ) {
00524                                                                 //for ( int m = 0 ; m < 6 ; m ++ ) {
00525                                                                         //int nx = ox + neighbor6[m][0] ;
00526                                                                         //int ny = oy + neighbor6[m][1] ;
00527                                                                         //int nz = oz + neighbor6[m][2] ;
00528 
00529                                                                         //if ( getDataAt(nx,ny,nz) > 0 && svol->getDataAt(nx,ny,nz) == 0 ) {
00530                                                                                 //svol->setDataAt(nx,ny,nz,totSheets);
00531                                                                                 //queue->pushQueue(nx,ny,nz) ;
00532                                                                                 //numNodes ++ ;
00533                                                                         //}
00534                                                                 //}
00535                                                         //}
00536                                                 //}
00537 
00538                                                 //delete queue ;
00539                                                 //if ( numNodes > 0 ) {
00541                                                         //sheets[ totSheets ] = numNodes ;
00542                                                         //totSheets ++ ;
00543                                                 //}
00544                                         //}
00545 
00547                         //printf("Removing small clusters.\n") ;
00548                         //for ( i = 0 ; i < getSizeX() ; i ++ )
00549                                 //for ( j = 0 ; j < getSizeY() ; j ++ )
00550                                         //for ( k = 0 ; k < getSizeZ() ; k ++ ) {
00551                                                 //int cnt = (int) svol->getDataAt(i,j,k) ;
00552                                                 //if ( cnt > 0 && sheets[ cnt ] < minSize ) {
00553                                                         //svol->setDataAt(i,j,k,-1) ;
00554                                                 //}
00555                                         //}
00556 
00558                         //#ifdef VERBOSE
00559                         //printf("Thresholding the volume to 0/1...\n") ;
00560                         //#endif
00561                         //svol->threshold( 0.1, 0, 1 ) ;
00562 
00563                         //return svol ;
00564                 //}
00565 
00566                 //Volume * Volume::getHelices( int minSize ) {
00567                         //printf("Segmenting helices from eroded volume.\n") ;
00568                         //int i, j, k ;
00569 
00571                         //printf("Initialize volume at %d %d %d\n", getSizeX(), getSizeY(), getSizeZ() ) ;
00572                         //Volume* svol = new Volume( getSizeX(), getSizeY(), getSizeZ() ) ;
00573 
00575                         //int helices[MAX_SHEETS] ;
00576                         //for ( i = 0 ; i < MAX_SHEETS ; i ++ ) {
00577                                 //helices[ i ] = 0 ;
00578                         //}
00579                         //int totHelices = 1 ;
00580 
00582                         //printf("Start clustering...\n" ) ;
00583                         //int ox, oy, oz ;
00584                         //for ( i = 0 ; i < getSizeX() ; i ++ )
00585                                 //for ( j = 0 ; j < getSizeY() ; j ++ )
00586                                         //for ( k = 0 ; k < getSizeZ() ; k ++ ) {
00587                                                 //if ( getDataAt(i,j,k) <= 0 || svol->getDataAt(i,j,k) != 0 ) {
00589                                                         //continue ;
00590                                                 //}
00591                                                 //if ( ! isHelix( i, j, k ) ) {
00593                                                         //continue ;
00594                                                 //}
00595 
00597                                                 //int numNodes = 1 ;
00598                                                 //svol->setDataAt( i, j, k, totHelices ) ;
00599                                                 //GridQueue* queue = new GridQueue() ;
00600                                                 //queue->pushQueue( i, j, k ) ;
00601                                                 //while ( queue->popQueue(ox, oy, oz) )
00602                                                 //{
00604                                                         //if ( isHelix( ox, oy, oz ) ) {
00605                                                                 //for ( int m = 0 ; m < 6 ; m ++ ) {
00606                                                                         //int nx = ox + neighbor6[m][0] ;
00607                                                                         //int ny = oy + neighbor6[m][1] ;
00608                                                                         //int nz = oz + neighbor6[m][2] ;
00609 
00610                                                                         //if ( getDataAt(nx,ny,nz) > 0 && svol->getDataAt(nx,ny,nz) == 0 ) {
00611                                                                                 //svol->setDataAt(nx,ny,nz,totHelices);
00612                                                                                 //queue->pushQueue(nx,ny,nz) ;
00613                                                                                 //numNodes ++ ;
00614                                                                         //}
00615                                                                 //}
00616                                                         //}
00617                                                 //}
00618 
00619                                                 //delete queue ;
00620                                                 //if ( numNodes > 0 ) {
00622                                                         //helices[ totHelices ] = numNodes ;
00623                                                         //totHelices ++ ;
00624                                                 //}
00625                                         //}
00626 
00628                         //printf("Removing small clusters.\n") ;
00629                         //for ( i = 0 ; i < getSizeX() ; i ++ )
00630                                 //for ( j = 0 ; j < getSizeY() ; j ++ )
00631                                         //for ( k = 0 ; k < getSizeZ() ; k ++ ) {
00632                                                 //int cnt = (int) svol->getDataAt(i,j,k) ;
00633                                                 //if ( cnt > 0 && helices[ cnt ] < minSize ) {
00634                                                         //svol->setDataAt(i,j,k,-1) ;
00635                                                 //}
00636                                         //}
00637 
00639                         //#ifdef VERBOSE
00640                         //printf("Thresholding the volume to 0/1...\n") ;
00641                         //#endif
00642                         //svol->threshold( 0.1, 0, 1 ) ;
00643 
00644                         //return svol ;
00645 
00646                 //}
00647 
00648                 //int Volume::isEndPoint( int ox, int oy, int oz ) {
00649                         //if ( getDataAt( ox - 1, oy, oz ) < 0 && getDataAt( ox + 1, oy, oz ) < 0 ) {
00650                                 //return 1 ;
00651                         //}
00652                         //if ( getDataAt( ox, oy - 1, oz ) < 0 && getDataAt( ox, oy + 1, oz ) < 0 ) {
00653                                 //return 1 ;
00654                         //}
00655                         //if ( getDataAt( ox, oy, oz - 1 ) < 0 && getDataAt( ox, oy, oz + 1 ) < 0 ) {
00656                                 //return 1 ;
00657                         //}
00658                         //return 0 ;
00659                 //}
00660 
00661                 int Volume::getNumNeighbor6( int ox, int oy, int oz ) {
00662                         int rvalue = 0 ;
00663                         for ( int i = 0 ; i < 6 ; i ++ ) {
00664                                 int nx = ox + neighbor6[i][0] ;
00665                                 int ny = oy + neighbor6[i][1] ;
00666                                 int nz = oz + neighbor6[i][2] ;
00667                                 if ( getDataAt( nx, ny, nz ) >= 0 ) {
00668                                         rvalue ++ ;
00669                                 }
00670                         }
00671 
00672                         return rvalue ;
00673                 }
00674                 //int Volume::testIsSheetEnd( int ox, int oy, int oz ) {
00676                         //int i, j ;
00677                         //int nx, ny, nz ;
00678 
00679                         //int edge[6] = { 0,0,0,0,0,0 } ;
00680                         //int faceflag[ 12 ] ;
00681                         //int hasNoiseFace = 0 ;
00682                         //int tot = 0 ;
00683 
00684                         //for ( i = 0 ; i < 12 ; i ++ ) {
00685                                 //faceflag[ i ] = 1 ;
00686                                 //int hasNoise = 0 ;
00687 
00688                                 //for ( j = 0 ; j < 4 ; j ++ ) {
00689                                         //nx = ox + sheetNeighbor[i][j][0] ;
00690                                         //ny = oy + sheetNeighbor[i][j][1] ;
00691                                         //nz = oz + sheetNeighbor[i][j][2] ;
00692 
00693                                         //if ( getDataAt( nx, ny, nz ) == 0 ) {
00694                                                 //hasNoise = 1 ;
00695                                         //}
00696                                         //if ( getDataAt( nx, ny, nz ) < 0 ) {
00697                                                 //faceflag[ i ] = 0 ;
00698                                                 //break ;
00699                                         //}
00700                                 //}
00701                                 //if ( faceflag[ i ] == 1 && hasNoise ) {
00702                                         //hasNoiseFace ++ ;
00704                                 //}
00705 
00706                                 //if ( faceflag[ i ] ) {
00707                                         //int e0 = faceEdges[ i ][ 0 ], e1 = faceEdges[ i ][ 1 ] ;
00708                                         //edge[ e0 ] ++ ;
00709                                         //edge[ e1 ] ++ ;
00710                                         //tot ++ ;
00711                                 //}
00712                         //}
00713 
00714                         //if ( hasNoiseFace == tot ) {
00715                                 //return 0 ;
00716                         //}
00717 
00718                         //if ( tot == 0 ) {
00719                                 //return 0 ;
00720                         //}
00721 
00723                         //int numones = 0 ;
00724                         //for ( i = 0 ; i < 6 ; i ++ ) {
00725                                 //if ( edge[ i ] == 1 ) {
00726                                         //numones ++ ;
00727                                 //}
00728                         //}
00729                         //while( numones > 0 ) {
00730                                 //int e ;
00731                                 //for ( i = 0 ; i < 6 ; i ++ ) {
00732                                         //if ( edge[ i ] == 1 ) {
00733                                                 //e = i ;
00734                                                 //break ;
00735                                         //}
00736                                 //}
00737 
00738                                 //int f, e2 ;
00739                                 //for ( j = 0 ; j < 4 ; j ++ ) {
00740                                         //f = edgeFaces[ e ][ j ] ;
00741                                         //if ( faceflag[ f ] ) {
00742                                                 //break ;
00743                                         //}
00744                                 //}
00745 
00746                                 //if ( faceEdges[ f ][ 0 ] == e ) {
00747                                         //e2 = faceEdges[ f ][ 1 ] ;
00748                                 //}  else {
00749                                         //e2 = faceEdges[ f ][ 0 ] ;
00750                                 //}
00751 
00752                                 //edge[ e ] -- ;
00753                                 //numones -- ;
00754                                 //edge[ e2 ] -- ;
00755                                 //faceflag[ f ] = 0 ;
00756                                 //tot -- ;
00757 
00758                                 //if ( edge[ e2 ] == 1 ) {
00759                                         //numones ++ ;
00760                                 //} else if ( edge[ e2 ] == 0 ) {
00761                                         //numones -- ;
00762                                 //}
00763                         //}
00764 
00765                         //if ( tot > 0 ) {
00766                                 //return 0 ;
00767                         //}
00768                         //return 1 ;
00769                 //}
00770 
00771                 //int Volume::isNoiseSheetEnd( int ox, int oy, int oz ) {
00772                         //int i, j ;
00773                         //int nx, ny, nz ;
00774 
00775                         //int edge[6] = { 0,0,0,0,0,0 } ;
00776                         //int faceflag[ 12 ] ;
00777                         //int hasNoiseFace = 0 ;
00778                         //int tot = 0 ;
00779 
00780                         //for ( i = 0 ; i < 12 ; i ++ ) {
00781                                 //faceflag[ i ] = 1 ;
00782                                 //int hasNoise = 0 ;
00783 
00784                                 //for ( j = 0 ; j < 4 ; j ++ ) {
00785                                         //nx = ox + sheetNeighbor[i][j][0] ;
00786                                         //ny = oy + sheetNeighbor[i][j][1] ;
00787                                         //nz = oz + sheetNeighbor[i][j][2] ;
00788 
00789                                         //if ( getDataAt( nx, ny, nz ) == 0 ) {
00790                                                 //hasNoise = 1 ;
00791                                         //}
00792                                         //if ( getDataAt( nx, ny, nz ) < 0 ) {
00793                                                 //faceflag[ i ] = 0 ;
00794                                                 //break ;
00795                                         //}
00796                                 //}
00797                                 //if ( faceflag[ i ] == 1 && hasNoise ) {
00798                                         //hasNoiseFace ++ ;
00800                                 //}
00801 
00802                                 //if ( faceflag[ i ] ) {
00803                                         //int e0 = faceEdges[ i ][ 0 ], e1 = faceEdges[ i ][ 1 ] ;
00804                                         //edge[ e0 ] ++ ;
00805                                         //edge[ e1 ] ++ ;
00806                                         //tot ++ ;
00807                                 //}
00808                         //}
00809 
00810                         //if ( hasNoiseFace < tot ) {
00811                                 //return 0 ;
00812                         //}
00813 
00814                         //if ( tot == 0 ) {
00815                                 //return 0 ;
00816                         //}
00817 
00819                         //int numones = 0 ;
00820                         //for ( i = 0 ; i < 6 ; i ++ ) {
00821                                 //if ( edge[ i ] == 1 )
00822                                 //{
00823                                         //numones ++ ;
00824                                 //}
00825                         //}
00826                         //while( numones > 0 ) {
00827                                 //int e ;
00828                                 //for ( i = 0 ; i < 6 ; i ++ ) {
00829                                         //if ( edge[ i ] == 1 ) {
00830                                                 //e = i ;
00831                                                 //break ;
00832                                         //}
00833                                 //}
00834 
00835                                 //int f, e2 ;
00836                                 //for ( j = 0 ; j < 4 ; j ++ ) {
00837                                         //f = edgeFaces[ e ][ j ] ;
00838                                         //if ( faceflag[ f ] ) {
00839                                                 //break ;
00840                                         //}
00841                                 //}
00842 
00843                                 //if ( faceEdges[ f ][ 0 ] == e ) {
00844                                         //e2 = faceEdges[ f ][ 1 ] ;
00845                                 //} else {
00846                                         //e2 = faceEdges[ f ][ 0 ] ;
00847                                 //}
00848 
00849                                 //edge[ e ] -- ;
00850                                 //numones -- ;
00851                                 //edge[ e2 ] -- ;
00852                                 //faceflag[ f ] = 0 ;
00853                                 //tot -- ;
00854 
00855                                 //if ( edge[ e2 ] == 1 ) {
00856                                         //numones ++ ;
00857                                 //} else if ( edge[ e2 ] == 0 ) {
00858                                         //numones -- ;
00859                                 //}
00860                         //}
00861 
00862                         //if ( tot > 0 ) {
00863                                 //return 0 ;
00864                         //}
00865                         //return 1 ;
00866                 //}
00867 
00868                 //int Volume::isInternal( int ox, int oy, int oz ) {
00870                         //int i, j, k ;
00871 
00872                         //for ( i = -1 ; i < 2 ; i ++ )
00873                                 //for ( j = -1 ; j < 2 ; j ++ )
00874                                         //for ( k = -1 ; k < 2 ; k ++ ) {
00875                                                 //if ( getDataAt( ox + i, oy + j, oz + k ) <= 0 ) {
00876                                                         //return 0 ;
00877                                                 //}
00878                                         //}
00879                         //return 1 ;
00880                 //}
00881 
00882                 //int Volume::isInternal2( int ox, int oy, int oz ) {
00884                         //int i, j, k ;
00885 
00886                         //for ( i = -1 ; i < 2 ; i ++ )
00887                                 //for ( j = -1 ; j < 2 ; j ++ )
00888                                         //for ( k = -1 ; k < 2 ; k ++ ) {
00889                                                 //if ( getDataAt( ox + i, oy + j, oz + k ) < 0 ) {
00890                                                         //return 0 ;
00891                                                 //}
00892                                         //}
00893 
00894                         //return 1 ;
00895                 //}
00896 
00897                 //int Volume::hasIsolatedFace( int ox, int oy, int oz ) {
00898                         //int i, j, k ;
00899                         //int nx, ny, nz ;
00900 
00901                         //double vox[3][3][3] ;
00902                         //for ( i = -1 ; i < 2 ; i ++ )
00903                                 //for ( j = -1 ; j < 2 ; j ++ )
00904                                         //for ( k = -1 ; k < 2 ; k ++ ) {
00905                                                 //vox[ i + 1 ][ j + 1 ][ k + 1 ] = getDataAt( ox + i, oy + j, oz + k ) ;
00906                                         //}
00907 
00908                         //int cells[8] = { 1, 1, 1, 1, 1, 1, 1, 1 } ;
00909                         //for ( i = 0 ; i < 8 ; i ++ ) {
00910                                 //int x = ( ( i >> 2 ) & 1 ) ;
00911                                 //int y = ( ( i >> 1 ) & 1 ) ;
00912                                 //int z = ( i & 1 ) ;
00913                                 //for ( j = 0 ; j < 8 ; j ++ ) {
00914                                         //nx = x + ( ( j >> 2 ) & 1 ) ;
00915                                         //ny = y + ( ( j >> 1 ) & 1 ) ;
00916                                         //nz = z + ( j & 1 ) ;
00917 
00918                                         //if ( vox[nx][ny][nz] < 0 ) {
00919                                                 //cells[i] = 0 ;
00920                                                 //break;
00921                                         //}
00922                                 //}
00923                         //}
00924 
00925                         //for ( i = 0 ; i < 12 ; i ++ ) {
00926                                 //if ( cells[ faceCells[i][0] ] == 1 || cells[ faceCells[i][1] ] == 1 ) {
00927                                         //continue ;
00928                                 //}
00929                                 //int flag = 1 ;
00930                                 //for ( j = 0 ; j < 4 ; j ++ ) {
00931                                         //nx = 1 + sheetNeighbor[i][j][0] ;
00932                                         //ny = 1 + sheetNeighbor[i][j][1] ;
00933                                         //nz = 1 + sheetNeighbor[i][j][2] ;
00934 
00935                                         //if ( vox[nx][ny][nz] < 0 ) {
00936                                                 //flag = 0 ;
00937                                                 //break;
00938                                         //}
00939                                 //}
00940                                 //if ( flag ) {
00941                                         //return 1 ;
00942                                 //}
00943                         //}
00944 
00945                         //return 0 ;
00946                 //}
00947 
00948                 //int Volume::hasIsolatedEdge( int ox, int oy, int oz ) {
00949                         //int i, j, k ;
00950                         //int nx, ny, nz ;
00951 
00952                         //double vox[3][3][3] ;
00953                         //for ( i = -1 ; i < 2 ; i ++ )
00954                                 //for ( j = -1 ; j < 2 ; j ++ )
00955                                         //for ( k = -1 ; k < 2 ; k ++ ) {
00956                                                 //vox[ i + 1 ][ j + 1 ][ k + 1 ] = getDataAt( ox + i, oy + j, oz + k ) ;
00957                                         //}
00958 
00959                         //int edge[6] = { 0,0,0,0,0,0 } ;
00960 
00961                         //for ( i = 0 ; i < 12 ; i ++ ) {
00962                                 //int flag = 1 ;
00963                                 //for ( j = 0 ; j < 4 ; j ++ ) {
00964                                         //nx = 1 + sheetNeighbor[i][j][0] ;
00965                                         //ny = 1 + sheetNeighbor[i][j][1] ;
00966                                         //nz = 1 + sheetNeighbor[i][j][2] ;
00967 
00968                                         //if ( vox[nx][ny][nz] < 0 ) {
00969                                                 //flag = 0 ;
00970                                                 //break ;
00971                                         //}
00972                                 //}
00973 
00974                                 //if ( flag ) {
00975                                         //int e0 = faceEdges[ i ][ 0 ], e1 = faceEdges[ i ][ 1 ] ;
00976                                         //edge[ e0 ] ++ ;
00977                                         //edge[ e1 ] ++ ;
00978                                 //}
00979                         //}
00980 
00981                         //for ( i = 0 ; i < 6 ; i ++ ) {
00982                                 //if ( edge[i] ) {
00983                                         //continue ;
00984                                 //}
00985 
00986                                 //nx = 1 + neighbor6[i][0] ;
00987                                 //ny = 1 + neighbor6[i][1] ;
00988                                 //nz = 1 + neighbor6[i][2] ;
00989 
00990                                 //if ( vox[nx][ny][nz] >= 0 ) {
00991                                         //return 1 ;
00992                                 //}
00993 
00994                         //}
00995 
00996                         //return 0 ;
00997                 //}
00998 
00999                 //int Volume::countFace( int ox, int oy, int oz, int m ) {
01000                         //int facenum = 4 ;
01001                         //for ( int i = 0 ; i < 4 ; i ++ ) {
01002                                 //for ( int j = 0 ; j < 4 ; j ++ ) {
01003                                         //int nx = ox + sheetNeighbor[edgeFaces[m][i]][j][0] ;
01004                                         //int ny = oy + sheetNeighbor[edgeFaces[m][i]][j][1] ;
01005                                         //int nz = oz + sheetNeighbor[edgeFaces[m][i]][j][2] ;
01006 
01007                                         //if ( getDataAt( nx, ny, nz ) < 0 ) {
01008                                                 //facenum -- ;
01009                                                 //break ;
01010                                         //}
01011                                 //}
01012                         //}
01013 
01014                         //return facenum;
01015                 //}
01016                 int Volume::hasCell( int ox, int oy, int oz ) {
01017                         for ( int i = 0 ; i < 2 ; i ++ )
01018                                 for ( int j = 0 ; j < 2 ; j ++ )
01019                                         for ( int k = 0 ; k < 2 ; k ++ ) {
01020                                                 if ( getDataAt( ox + i, oy + j, oz + k ) < 0 ) {
01021                                                         return 0 ;
01022                                                 }
01023                                         }
01024                         return 1 ;
01025                 }
01026 
01027                 Volume * Volume::markCellFace( ) {
01028                         int i, j, k ;
01029                         Volume* fvol = new Volume( getSizeX(), getSizeY(), getSizeZ() ) ;
01030 
01031                         //return fvol ;
01032 
01033                         for ( i = 0 ; i < getSizeX() ; i ++ )
01034                                 for ( j = 0 ; j < getSizeY() ; j ++ )
01035                                         for ( k = 0 ; k < getSizeZ() ; k ++ )
01036                                         {
01037                                                 if( getDataAt(i,j,k) >= 0 )
01038                                                 {
01039                                                         if ( hasCell(i,j,k) )
01040                                                         {
01041                                                                 for ( int m = 0 ; m < 6 ; m ++ )
01042                                                                 {
01043                                                                         int nx = i + neighbor6[m][0] ;
01044                                                                         int ny = j + neighbor6[m][1] ;
01045                                                                         int nz = k + neighbor6[m][2] ;
01046                                                                         if ( ! hasCell(nx,ny,nz) )
01047                                                                         {
01048                                                                                 fvol->setDataAt(i,j,k,(double)(1<<m)) ;
01049                                                                                 break ;
01050                                                                         }
01051                                                                 }
01052                                                         }
01053                                                 }
01054                                         }
01055 
01056 
01057                         return fvol ;
01058                 }
01059 
01060                 //Volume * Volume::markFaceEdge( ) {
01061                         //int x,y,z, i,j ;
01062                         //Volume* fvol = new Volume( getSizeX(), getSizeY(), getSizeZ() ) ;
01063 
01065 
01066                         //for ( x = 0 ; x < getSizeX() ; x ++ )
01067                                 //for ( y = 0 ; y < getSizeY() ; y ++ )
01068                                         //for ( z = 0 ; z < getSizeZ() ; z ++ )
01069                                         //{
01070                                                 //if( getDataAt(x,y,z) >= 0 )
01071                                                 //{
01072 
01073                                                         //for ( i = 0 ; i < 3 ; i ++ )
01074                                                         //{
01075                                                                 //int hasFace = 1 ;
01076                                                                 //for ( j = 0 ; j < 4 ; j ++ )
01077                                                                 //{
01078                                                                         //int nx = x + sheetNeighbor[4 * i + 3][j][0] ;
01079                                                                         //int ny = y + sheetNeighbor[4 * i + 3][j][1] ;
01080                                                                         //int nz = z + sheetNeighbor[4 * i + 3][j][2] ;
01081 
01082                                                                         //if ( getDataAt( nx, ny, nz ) < 0 )
01083                                                                         //{
01084                                                                                 //hasFace = 0 ;
01085                                                                                 //break ;
01086                                                                         //}
01087                                                                 //}
01088 
01089                                                                 //if ( hasFace )
01090                                                                 //{
01092                                                                         //switch( i )
01093                                                                         //{
01094                                                                         //case 0:
01095                                                                                 //if ( countFace( x, y, z, 0 ) == 1 )
01096                                                                                 //{
01097                                                                                         //fvol->setDataAt(x, y, z, (double)(1<<0)) ;
01098                                                                                         //break ;
01099                                                                                 //}
01100                                                                                 //if ( countFace( x, y, z, 2 ) == 1 )
01101                                                                                 //{
01102                                                                                         //fvol->setDataAt(x, y, z, (double)(1<<2)) ;
01103                                                                                         //break ;
01104                                                                                 //}
01105                                                                                 //if ( countFace( x, y + 1, z, 0 ) == 1 )
01106                                                                                 //{
01107                                                                                         //fvol->setDataAt(x, y + 1, z, (double)(1<<0)) ;
01108                                                                                         //break ;
01109                                                                                 //}
01110                                                                                 //if ( countFace( x, y, z + 1, 2 ) == 1 )
01111                                                                                 //{
01112                                                                                         //fvol->setDataAt(x, y, z + 1, (double)(1<<2)) ;
01113                                                                                         //break ;
01114                                                                                 //}
01115                                                                                 //printf("Hmmm... a face with no open edges.\n");
01116                                                                                 //break ;
01117                                                                         //case 1:
01118                                                                                 //if ( countFace( x, y, z, 0 ) == 1 )
01119                                                                                 //{
01120                                                                                         //fvol->setDataAt(x, y, z, (double)(1<<0)) ;
01121                                                                                         //break ;
01122                                                                                 //}
01123                                                                                 //if ( countFace( x, y, z, 4 ) == 1 )
01124                                                                                 //{
01125                                                                                         //fvol->setDataAt(x, y, z, (double)(1<<4)) ;
01126                                                                                         //break ;
01127                                                                                 //}
01128                                                                                 //if ( countFace( x + 1, y, z, 0 ) == 1 )
01129                                                                                 //{
01130                                                                                         //fvol->setDataAt(x + 1, y, z, (double)(1<<0)) ;
01131                                                                                         //break ;
01132                                                                                 //}
01133                                                                                 //if ( countFace( x, y, z + 1, 4 ) == 1 )
01134                                                                                 //{
01135                                                                                         //fvol->setDataAt(x, y, z + 1, (double)(1<<4)) ;
01136                                                                                         //break ;
01137                                                                                 //}
01138                                                                                 //printf("Hmmm... a face with no open edges.\n");
01139                                                                                 //break ;
01140                                                                         //case 2:
01141                                                                                 //if ( countFace( x, y, z, 2 ) == 1 )
01142                                                                                 //{
01143                                                                                         //fvol->setDataAt(x, y, z, (double)(1<<2)) ;
01144                                                                                         //break ;
01145                                                                                 //}
01146                                                                                 //if ( countFace( x, y, z, 4 ) == 1 )
01147                                                                                 //{
01148                                                                                         //fvol->setDataAt(x, y, z, (double)(1<<4)) ;
01149                                                                                         //break ;
01150                                                                                 //}
01151                                                                                 //if ( countFace( x + 1, y, z, 2 ) == 1 )
01152                                                                                 //{
01153                                                                                         //fvol->setDataAt(x + 1, y, z, (double)(1<<2)) ;
01154                                                                                         //break ;
01155                                                                                 //}
01156                                                                                 //if ( countFace( x, y + 1, z, 4 ) == 1 )
01157                                                                                 //{
01158                                                                                         //fvol->setDataAt(x, y + 1, z, (double)(1<<4)) ;
01159                                                                                         //break ;
01160                                                                                 //}
01161                                                                                 //printf("Hmmm... a face with no open edges.\n");
01162                                                                                 //break ;
01163                                                                         //}
01164                                                                 //}
01165                                                         //}
01166 
01167                                                 //}
01168                                         //}
01169 
01170 
01171                         //return fvol ;
01172                 //}
01173 
01174                 int Volume::hasCompleteSheet( int ox, int oy, int oz, Volume* fvol ) {
01175                         int i, j, k ;
01176                         int nx, ny, nz ;
01177 
01178                         int edge[6] = { 0,0,0,0,0,0 } ;
01179                         int faceflag[ 12 ] ;
01180                         int tot = 0 ;
01181                         int cellflag[ 8 ] ;
01182 
01183                         int ct = 0 ;
01184                         for (  i = -1 ; i < 1 ; i ++ )
01185                                 for (  j = -1 ; j < 1 ; j ++ )
01186                                         for (  k = -1 ; k < 1 ; k ++ )
01187                                         {
01188                                                 if ( hasCell( ox + i, oy + j, oz + k ) )
01189                                                 {
01190                                                         cellflag[ ct ] = 1 ;
01191                                                 }
01192                                                 else
01193                                                 {
01194                                                         cellflag[ ct ] = 0 ;
01195                                                 }
01196                                                 ct ++ ;
01197                                         }
01198 
01199                         for ( i = 0 ; i < 12 ; i ++ )
01200                         {
01201                                 faceflag[ i ] = 1 ;
01202                                 for ( j = 0 ; j < 4 ; j ++ )
01203                                 {
01204                                         nx = ox + sheetNeighbor[i][j][0] ;
01205                                         ny = oy + sheetNeighbor[i][j][1] ;
01206                                         nz = oz + sheetNeighbor[i][j][2] ;
01207 
01208                                         if ( getDataAt( nx, ny, nz ) < 0 )
01209                                         {
01210                                                 faceflag[ i ] = 0 ;
01211                                                 break ;
01212                                         }
01213                                 }
01214 
01215                                 if ( faceflag[ i ] )
01216                                 {
01217                                         if ( cellflag[ faceCells[i][0] ] ^ cellflag[ faceCells[i][1] ] )
01218                                         {
01219                                                 int v1 = (int)( fvol->getDataAt(
01220                                                         ox - 1 + (( faceCells[i][0] >> 2 ) & 1 ),
01221                                                         oy - 1 + (( faceCells[i][0] >> 1 ) & 1 ),
01222                                                         oz - 1 + (( faceCells[i][0] ) & 1)) ) ;
01223                                                 int v2 = (int)( fvol->getDataAt(
01224                                                         ox - 1 + (( faceCells[i][1] >> 2 ) & 1 ),
01225                                                         oy - 1 + (( faceCells[i][1] >> 1 ) & 1 ),
01226                                                         oz - 1 + (( faceCells[i][1] ) & 1)) ) ;
01227                                                 if ( ((v1 >> (2 * (2 - i/4))) & 1) ||
01228                                                          ((v2 >> (2 * (2 - i/4) + 1 )) & 1) )
01229                                                 {
01230                                                         faceflag[ i ] = 0 ;
01231                                                 }
01232                                         }
01233                                 }
01234 
01235                                 if ( faceflag[ i ] )
01236                                 {
01237                                         int e0 = faceEdges[ i ][ 0 ], e1 = faceEdges[ i ][ 1 ] ;
01238                                         edge[ e0 ] ++ ;
01239                                         edge[ e1 ] ++ ;
01240                                         tot ++ ;
01241                                 }
01242                         }
01243 
01244                         // Removing 1s
01245                         int numones = 0 ;
01246                         for ( i = 0 ; i < 6 ; i ++ )
01247                         {
01248                                 if ( edge[ i ] == 1 )
01249                                 {
01250                                         numones ++ ;
01251                                 }
01252                         }
01253                         while( numones > 0 )
01254                         {
01255                                 int e = 0;
01256                                 for ( i = 0 ; i < 6 ; i ++ )
01257                                 {
01258                                         if ( edge[ i ] == 1 )
01259                                         {
01260                                                 e = i ;
01261                                                 break ;
01262                                         }
01263                                 }
01264                                 /*
01265                                 if ( edge[ e ] != 1 )
01266                                 {
01267                                         printf("Wrong Again!********\n") ;
01268                                 }
01269                                 */
01270 
01271                                 int f, e2 ;
01272                                 for ( j = 0 ; j < 4 ; j ++ )
01273                                 {
01274                                         f = edgeFaces[ e ][ j ] ;
01275                                         if ( faceflag[ f ] )
01276                                         {
01277                                                 break ;
01278                                         }
01279                                 }
01280 
01281                                 /*
01282                                 if ( faceflag[ f ] == 0 )
01283                                 {
01284                                         printf("Wrong!********\n") ;
01285                                 }
01286                                 */
01287 
01288                                 if ( faceEdges[ f ][ 0 ] == e )
01289                                 {
01290                                         e2 = faceEdges[ f ][ 1 ] ;
01291                                 }
01292                                 else
01293                                 {
01294                                         e2 = faceEdges[ f ][ 0 ] ;
01295                                 }
01296 
01297 
01298                                 edge[ e ] -- ;
01299                                 numones -- ;
01300                                 edge[ e2 ] -- ;
01301                                 faceflag[ f ] = 0 ;
01302                                 tot -- ;
01303 
01304                                 if ( edge[ e2 ] == 1 )
01305                                 {
01306                                         numones ++ ;
01307                                 }
01308                                 else if ( edge[ e2 ] == 0 )
01309                                 {
01310                                         numones -- ;
01311                                 }
01312                         }
01313 
01314                         if ( tot > 0 )
01315                         {
01316                                 return 1 ;
01317                         }
01318 
01319                         return 0 ;
01320                 }
01321 
01322                 int Volume::hasCompleteSheet( int ox, int oy, int oz ) {
01323                         // Returns 1 if it lies in the middle of a sheet
01324                         int temp = countIntEuler( ox, oy, oz ) ;
01325                         if ( temp > 0 )
01326                         {
01327                                 return 1 ;
01328                         }
01329                         else
01330                         {
01331                                 return 0 ;
01332                         }
01333                 }
01334 
01335                 //int Volume::hasCompleteSheetSlow( int ox, int oy, int oz ) {
01336                         //int i, j ;
01337                         //int nx, ny, nz ;
01338 
01339                         //int edge[6] = { 0,0,0,0,0,0 } ;
01340                         //int faceflag[ 12 ] ;
01341                         //int tot = 0 ;
01342 
01343                         //for ( i = 0 ; i < 12 ; i ++ )
01344                         //{
01345                                 //faceflag[ i ] = 1 ;
01346                                 //for ( j = 0 ; j < 4 ; j ++ )
01347                                 //{
01348                                         //nx = ox + sheetNeighbor[i][j][0] ;
01349                                         //ny = oy + sheetNeighbor[i][j][1] ;
01350                                         //nz = oz + sheetNeighbor[i][j][2] ;
01351 
01352                                         //if ( getDataAt( nx, ny, nz ) < 0 )
01353                                         //{
01354                                                 //faceflag[ i ] = 0 ;
01355                                                 //break ;
01356                                         //}
01357                                 //}
01358 
01359                                 //if ( faceflag[ i ] )
01360                                 //{
01361                                         //int e0 = faceEdges[ i ][ 0 ], e1 = faceEdges[ i ][ 1 ] ;
01362                                         //edge[ e0 ] ++ ;
01363                                         //edge[ e1 ] ++ ;
01364                                         //tot ++ ;
01365                                 //}
01366                         //}
01367 
01369                         //int numones = 0 ;
01370                         //for ( i = 0 ; i < 6 ; i ++ )
01371                         //{
01372                                 //if ( edge[ i ] == 1 )
01373                                 //{
01374                                         //numones ++ ;
01375                                 //}
01376                         //}
01377                         //while( numones > 0 )
01378                         //{
01379                                 //int e ;
01380                                 //for ( i = 0 ; i < 6 ; i ++ )
01381                                 //{
01382                                         //if ( edge[ i ] == 1 )
01383                                         //{
01384                                                 //e = i ;
01385                                                 //break ;
01386                                         //}
01387                                 //}
01389                                 //if ( edge[ e ] != 1 )
01390                                 //{
01391                                         //printf("Wrong Again!********\n") ;
01392                                 //}
01393                                 //*/
01394 
01395                                 //int f, e2 ;
01396                                 //for ( j = 0 ; j < 4 ; j ++ )
01397                                 //{
01398                                         //f = edgeFaces[ e ][ j ] ;
01399                                         //if ( faceflag[ f ] )
01400                                         //{
01401                                                 //break ;
01402                                         //}
01403                                 //}
01404 
01406                                 //if ( faceflag[ f ] == 0 )
01407                                 //{
01408                                         //printf("Wrong!********\n") ;
01409                                 //}
01410                                 //*/
01411 
01412                                 //if ( faceEdges[ f ][ 0 ] == e )
01413                                 //{
01414                                         //e2 = faceEdges[ f ][ 1 ] ;
01415                                 //}
01416                                 //else
01417                                 //{
01418                                         //e2 = faceEdges[ f ][ 0 ] ;
01419                                 //}
01420 
01421 
01422                                 //edge[ e ] -- ;
01423                                 //numones -- ;
01424                                 //edge[ e2 ] -- ;
01425                                 //faceflag[ f ] = 0 ;
01426                                 //tot -- ;
01427 
01428                                 //if ( edge[ e2 ] == 1 )
01429                                 //{
01430                                         //numones ++ ;
01431                                 //}
01432                                 //else if ( edge[ e2 ] == 0 )
01433                                 //{
01434                                         //numones -- ;
01435                                 //}
01436                         //}
01437 
01439                         //if ( tot > 0 )
01440                         //{
01442                                 //{
01444                                 //}
01445                                 //return 1 ;
01446                         //}
01447                         //else
01448                         //{
01450                                 //{
01452                                 //}
01453                                 //return 0 ;
01454                         //}
01455                 //}
01456                 int Volume::hasCompleteHelix( int ox, int oy, int oz )
01457                 {
01458                         // Returns 1 if it has a complete helix
01459                         int i ;
01460                         int c1 = 0;
01461                         int nx, ny, nz ;
01462                         int j ;
01463 
01464                         for ( i = 0 ; i < 6 ; i ++ )
01465                         {
01466                                 nx = ox + neighbor6[i][0] ;
01467                                 ny = oy + neighbor6[i][1] ;
01468                                 nz = oz + neighbor6[i][2] ;
01469                                 if ( getDataAt( nx, ny, nz ) >= 0 )
01470                                 {
01471                                         c1 ++ ;
01472                                         j = i ;
01473                                 }
01474 
01475                         }
01476 
01477                         if ( c1 > 1 ) // || c1 == 0 )
01478                         {
01479                                 return 1 ;
01480                         }
01481 
01482                         return 0 ;
01483 
01484                         /*
01485                         ox = ox + neighbor6[j][0] ;
01486                         oy = oy + neighbor6[j][1] ;
01487                         oz = oz + neighbor6[j][2] ;
01488                         c1 = 0 ;
01489                         for ( i = 0 ; i < 6 ; i ++ )
01490                         {
01491                                 nx = ox + neighbor6[i][0] ;
01492                                 ny = oy + neighbor6[i][1] ;
01493                                 nz = oz + neighbor6[i][2] ;
01494                                 if ( getDataAt( nx, ny, nz ) >= 0 )
01495                                 {
01496                                         c1 ++ ;
01497                                 }
01498 
01499                         }
01500 
01501                         if ( c1 > 1 )
01502                         {
01503                                 return 0 ;
01504                         }
01505                         else
01506                         {
01507                                 return 1 ;
01508                         }
01509                         */
01510                 }
01511 
01512                 int Volume::hasCompleteHelix( int ox, int oy, int oz, Volume* fvol )
01513                 {
01514 
01515                         int i ;
01516                         int c1 = 0;
01517                         int nx, ny, nz ;
01518                         int j ;
01519 
01520                         for ( i = 0 ; i < 6 ; i ++ )
01521                         {
01522                                 nx = ox + neighbor6[i][0] ;
01523                                 ny = oy + neighbor6[i][1] ;
01524                                 nz = oz + neighbor6[i][2] ;
01525                                 if ( getDataAt( nx, ny, nz ) >= 0 )
01526                                 {
01527                                         if ( i % 2 == 0 )
01528                                         {
01529                                                 nx = ox ;
01530                                                 ny = oy ;
01531                                                 nz = oz ;
01532                                         }
01533 
01534                                         int val = (int)fvol->getDataAt( nx, ny, nz) ;
01535                                         if ( (( val >> ( 2 * ( i / 2 ) ) ) & 1) == 0 )
01536                                         {
01537                                                 c1 ++ ;
01538                                                 j = i ;
01539                                         }
01540                                 }
01541 
01542                         }
01543 
01544                         if ( c1 > 1 )
01545                         {
01546                                 return 1 ;
01547                         }
01548 
01549                         return 0 ;
01550 
01551                         /*
01552                         ox = ox + neighbor6[j][0] ;
01553                         oy = oy + neighbor6[j][1] ;
01554                         oz = oz + neighbor6[j][2] ;
01555                         c1 = 0 ;
01556                         for ( i = 0 ; i < 6 ; i ++ )
01557                         {
01558                                 nx = ox + neighbor6[i][0] ;
01559                                 ny = oy + neighbor6[i][1] ;
01560                                 nz = oz + neighbor6[i][2] ;
01561                                 if ( getDataAt( nx, ny, nz ) >= 0 )
01562                                 {
01563                                         c1 ++ ;
01564                                 }
01565 
01566                         }
01567 
01568                         if ( c1 > 1 )
01569                         {
01570                                 return 0 ;
01571                         }
01572                         else
01573                         {
01574                                 return 1 ;
01575                         }
01576                         */
01577                 }
01578 
01579                 int Volume::isHelixEnd( int ox, int oy, int oz, Volume* nvol ) {
01580                         // Returns 1 if it is a curve endpoint
01581                         int i ;
01582                         int c1 = 0 , c2 = 0 ;
01583                         int nx, ny, nz ;
01584 
01585                         for ( i = 0 ; i < 6 ; i ++ )
01586                         {
01587                                 nx = ox + neighbor6[i][0] ;
01588                                 ny = oy + neighbor6[i][1] ;
01589                                 nz = oz + neighbor6[i][2] ;
01590 
01591                                 double val = getDataAt( nx, ny, nz ) ;
01592 
01593                                 if ( val >= 0 )
01594                                 {
01595                                         c1 ++ ;
01596                                         if ( val > 0 && val < MAX_ERODE && nvol->getDataAt( nx, ny, nz ) == 0 )
01597                                         {
01598                                                 c2 ++ ;
01599                                         }
01600                                 }
01601 
01602                         }
01603 
01604                         if ( c1 == 1 && c2 == 1 )
01605                         {
01606                                 return 1 ;
01607                         }
01608 
01609                         return 0 ;
01610                 }
01611 
01612                 //int Volume::isFeature18( int ox, int oy, int oz )
01613                 //{
01617                         //if ( getDataAt( ox, oy, oz ) <= 0 )
01618                         //{
01619                                 //return 0 ;
01620                         //}
01621 
01622                         //for ( int i = 0 ; i < 3 ; i ++ )
01623                                 //for ( int j = 0 ; j < 3 ; j ++ )
01624                                         //for ( int k = 0 ; k < 3 ; k ++ )
01625                                         //{
01626                                                 //if ( i == 1 || j == 1 || k == 1 )
01627                                                 //{
01628                                                         //if( getDataAt( ox - 1 + i, oy - 1 + j, oz - 1 + k ) == 0 )
01629                                                         //{
01630                                                                 //return 0 ;
01631                                                         //}
01632                                                 //}
01633                                         //}
01634                         //return 1 ;
01635                 //}
01636 
01637                 //int Volume::isEdgeEnd( int ox, int oy, int oz )
01638                 //{
01639                         //int i ;
01640                         //int c1 = 0 ;
01641                         //int nx, ny, nz ;
01642 
01643                         //for ( i = 0 ; i < 6 ; i ++ )
01644                         //{
01645                                 //nx = ox + neighbor6[i][0] ;
01646                                 //ny = oy + neighbor6[i][1] ;
01647                                 //nz = oz + neighbor6[i][2] ;
01648 
01649                                 //double val = getDataAt( nx, ny, nz ) ;
01650 
01651                                 //if ( val >= 0 )
01652                                 //{
01653                                         //c1 ++ ;
01654                                 //}
01655 
01656                         //}
01657 
01658                         //if ( c1 == 1 )
01659                         //{
01660                                 //return 1 ;
01661                         //}
01662 
01663                         //return 0 ;
01664                 //}
01665 
01666                 //int Volume::isFaceEnd( int ox, int oy, int oz )
01667                 //{
01669 
01670                         //int i, j, k ;
01671                         //int nx, ny, nz ;
01672 
01673                         //double vox[3][3][3] ;
01674                         //for ( i = -1 ; i < 2 ; i ++ )
01675                                 //for ( j = -1 ; j < 2 ; j ++ )
01676                                         //for ( k = -1 ; k < 2 ; k ++ )
01677                                         //{
01678                                                 //vox[ i + 1 ][ j + 1 ][ k + 1 ] = getDataAt( ox + i, oy + j, oz + k ) ;
01679                                         //}
01680 
01681                         //int edge[6] = { 4,4,4,4,4,4 } ;
01682                         //int edge2[6] = { 4,4,4,4,4,4 } ;
01683 
01684                         //for ( i = 0 ; i < 12 ; i ++ )
01685                         //{
01686                                 //for ( j = 0 ; j < 4 ; j ++ )
01687                                 //{
01688                                         //nx = 1 + sheetNeighbor[i][j][0] ;
01689                                         //ny = 1 + sheetNeighbor[i][j][1] ;
01690                                         //nz = 1 + sheetNeighbor[i][j][2] ;
01691 
01692                                         //if ( vox[nx][ny][nz] < 0 )
01693                                         //{
01694                                                 //edge[ faceEdges[ i ][ 0 ] ] -- ;
01695                                                 //edge[ faceEdges[ i ][ 1 ] ] -- ;
01696                                                 //break ;
01697                                         //}
01698                                 //}
01699                                 //for ( j = 0 ; j < 4 ; j ++ )
01700                                 //{
01701                                         //nx = 1 + sheetNeighbor[i][j][0] ;
01702                                         //ny = 1 + sheetNeighbor[i][j][1] ;
01703                                         //nz = 1 + sheetNeighbor[i][j][2] ;
01704 
01705                                         //if ( vox[nx][ny][nz] < 2 )
01706                                         //{
01707                                                 //edge2[ faceEdges[ i ][ 0 ] ] -- ;
01708                                                 //edge2[ faceEdges[ i ][ 1 ] ] -- ;
01709                                                 //break ;
01710                                         //}
01711                                 //}
01712                         //}
01713 
01714                         //for ( i = 0 ; i < 6 ; i ++ )
01715                         //{
01716                                 //if ( edge[ i ] == 1 && edge2[ i ] == 1 )
01717                                 //{
01718                                         //return 1 ;
01719                                 //}
01720                         //}
01721 
01722                         //return 0 ;
01723                 //}
01724 
01725                 //int Volume::isNoise( int ox, int oy, int oz, int noise )
01726                 //{
01727                         //if ( getDataAt(ox,oy,oz) == 1 )
01728                         //{
01729                                 //return 1 ;
01730                         //}
01731 
01732                         //if ( noise > 0 )
01733                         //{
01734                                 //for ( int i = 0 ; i < 6 ; i ++ )
01735                                 //{
01736                                         //int nx = ox + neighbor6[i][0] ;
01737                                         //int ny = oy + neighbor6[i][1] ;
01738                                         //int nz = oz + neighbor6[i][2] ;
01739 
01740                                         //if ( getDataAt( nx, ny, nz ) > 0 )
01741                                         //{
01742                                                 //if ( isNoise( nx, ny, nz, noise - 1 ) )
01743                                                 //{
01744                                                         //return 1 ;
01745                                                 //}
01746                                         //}
01747                                 //}
01748                         //}
01749 
01750                         //return 0 ;
01751 
01752                 //}
01753 
01754                 //int Volume::isNoiseHelixEnd( int ox, int oy, int oz )
01755                 //{
01756 
01757                         //int i ;
01758                         //int c1 = 0 , c2 = 0 ;
01759                         //int nx, ny, nz ;
01760 
01761                         //for ( i = 0 ; i < 6 ; i ++ )
01762                         //{
01763                                 //nx = ox + neighbor6[i][0] ;
01764                                 //ny = oy + neighbor6[i][1] ;
01765                                 //nz = oz + neighbor6[i][2] ;
01766 
01767                                 //double val = getDataAt( nx, ny, nz ) ;
01768 
01769                                 //if ( val >= 0 )
01770                                 //{
01771                                         //c1 ++ ;
01772                                         //if ( val > 0 && val < MAX_ERODE )
01773                                         //{
01774                                                 //c2 ++ ;
01775                                         //}
01776                                 //}
01777 
01778                         //}
01779 
01780                         //if ( c1 == 1 && c2 == 0 )
01781                         //{
01782                                 //return 1 ;
01783                         //}
01784 
01785                         //return 0 ;
01786                 //}
01787 
01788 
01789                 int Volume::isHelixEnd( int ox, int oy, int oz ) {
01790 
01791                         int i ;
01792                         int c1 = 0 , c2 = 0 ;
01793                         int nx, ny, nz ;
01794 
01795                         for ( i = 0 ; i < 6 ; i ++ )
01796                         {
01797                                 nx = ox + neighbor6[i][0] ;
01798                                 ny = oy + neighbor6[i][1] ;
01799                                 nz = oz + neighbor6[i][2] ;
01800 
01801                                 double val = getDataAt( nx, ny, nz ) ;
01802 
01803                                 if ( val >= 0 )
01804                                 {
01805                                         c1 ++ ;
01806                                         if ( getNumNeighbor6(nx,ny,nz) < 6 ) // if ( val > 0 && val < MAX_ERODE )
01807                                         {
01808                                                 c2 ++ ;
01809                                         }
01810                                 }
01811 
01812                         }
01813 
01814                         if ( c1 == 1 && c2 == 1 )
01815                         {
01816                                 return 1 ;
01817                         }
01818 
01819                         return 0 ;
01820                 }
01821                 int Volume::isSheetEnd( int ox, int oy, int oz, Volume* nvol )
01822                 {
01823                         // Returns 1 if it contains a sheet boundary. Noise-resistant
01824                         int i, j ;
01825                         int nx, ny, nz ;
01826 
01827                         int edge[6] = { 0,0,0,0,0,0 } ;
01828                         int faceflag[ 12 ] ;
01829                         int hasFeatureFace = 0 ;
01830                         int tot = 0 ;
01831 
01832                         for ( i = 0 ; i < 12 ; i ++ )
01833                         {
01834                                 faceflag[ i ] = 1 ;
01835                                 int hasFeature = 1 ;
01836 
01837                                 for ( j = 0 ; j < 4 ; j ++ )
01838                                 {
01839                                         nx = ox + sheetNeighbor[i][j][0] ;
01840                                         ny = oy + sheetNeighbor[i][j][1] ;
01841                                         nz = oz + sheetNeighbor[i][j][2] ;
01842 
01843                                         if ( getDataAt( nx, ny, nz ) == 0 || nvol->getDataAt( nx, ny, nz ) == 1 )
01844                                         {
01845                                                 hasFeature = 0 ;
01846                                         }
01847                                         if ( getDataAt( nx, ny, nz ) < 0 )
01848                                         {
01849                                                 faceflag[ i ] = 0 ;
01850                                                 break ;
01851                                         }
01852                                 }
01853                                 if ( faceflag[ i ] == 1 && hasFeature )
01854                                 {
01855                                         hasFeatureFace ++ ;
01856                                         // return 0 ;
01857                                 }
01858 
01859                                 if ( faceflag[ i ] )
01860                                 {
01861                                         int e0 = faceEdges[ i ][ 0 ], e1 = faceEdges[ i ][ 1 ] ;
01862                                         edge[ e0 ] ++ ;
01863                                         edge[ e1 ] ++ ;
01864                                         tot ++ ;
01865                                 }
01866                         }
01867 
01868                         if ( tot == 0 || hasFeatureFace == 0 )
01869                         {
01870                                 return 0 ;
01871                         }
01872 
01873                         // Removing 1s
01874                         int numones = 0 ;
01875                         for ( i = 0 ; i < 6 ; i ++ )
01876                         {
01877                                 if ( edge[ i ] == 1 )
01878                                 {
01879                                         numones ++ ;
01880                                 }
01881                         }
01882                         while( numones > 0 )
01883                         {
01884                                 int e = 0;
01885                                 for ( i = 0 ; i < 6 ; i ++ )
01886                                 {
01887                                         if ( edge[ i ] == 1 )
01888                                         {
01889                                                 e = i ;
01890                                                 break ;
01891                                         }
01892                                 }
01893                                 /*
01894                                 if ( edge[ e ] != 1 )
01895                                 {
01896                                         printf("Wrong Again!********\n") ;
01897                                 }
01898                                 */
01899 
01900                                 int f, e2 ;
01901                                 for ( j = 0 ; j < 4 ; j ++ )
01902                                 {
01903                                         f = edgeFaces[ e ][ j ] ;
01904                                         if ( faceflag[ f ] )
01905                                         {
01906                                                 break ;
01907                                         }
01908                                 }
01909 
01910                                 /*
01911                                 if ( faceflag[ f ] == 0 )
01912                                 {
01913                                         printf("Wrong!********\n") ;
01914                                 }
01915                                 */
01916 
01917                                 if ( faceEdges[ f ][ 0 ] == e )
01918                                 {
01919                                         e2 = faceEdges[ f ][ 1 ] ;
01920                                 }
01921                                 else
01922                                 {
01923                                         e2 = faceEdges[ f ][ 0 ] ;
01924                                 }
01925 
01926 
01927                                 edge[ e ] -- ;
01928                                 numones -- ;
01929                                 edge[ e2 ] -- ;
01930                                 faceflag[ f ] = 0 ;
01931                                 tot -- ;
01932 
01933                                 if ( edge[ e2 ] == 1 )
01934                                 {
01935                                         numones ++ ;
01936                                 }
01937                                 else if ( edge[ e2 ] == 0 )
01938                                 {
01939                                         numones -- ;
01940                                 }
01941                         }
01942 
01943                         if ( tot > 0 )
01944                         {
01945                                 return 0 ;
01946                         }
01947 
01948                         return 1 ;
01949                 }
01950 
01951                 //int Volume::getNumFaces( int ox, int oy, int oz )
01952                 //{
01953                         //int i, j ;
01954                         //int nx, ny, nz ;
01955 
01956                         //int faces = 12 ;
01957                         //for ( i = 0 ; i < 12 ; i ++ )
01958                         //{
01959                                 //for ( j = 0 ; j < 4 ; j ++ )
01960                                 //{
01961                                         //nx = ox + sheetNeighbor[i][j][0] ;
01962                                         //ny = oy + sheetNeighbor[i][j][1] ;
01963                                         //nz = oz + sheetNeighbor[i][j][2] ;
01964 
01965                                         //if ( getDataAt( nx, ny, nz ) < 0 )
01966                                         //{
01967                                                 //faces -- ;
01968                                                 //break ;
01969                                         //}
01970                                 //}
01971                         //}
01972 
01973                         //return faces ;
01974                 //}
01975 
01976                 //int Volume::getNumCells( int ox, int oy, int oz )
01977                 //{
01978                         //int i, j, k ;
01979 
01980                         //int cells = 0 ;
01981 
01982                         //for (  i = -1 ; i < 1 ; i ++ )
01983                                 //for (  j = -1 ; j < 1 ; j ++ )
01984                                         //for (  k = -1 ; k < 1 ; k ++ )
01985                                         //{
01986                                                 //if ( hasCell( ox + i, oy + j, oz + k ) )
01987                                                 //{
01988                                                         //cells ++ ;
01989                                                 //}
01990                                         //}
01991 
01993                         //return cells ;
01994                 //}
01995 
01996 
01997                 //int Volume::getNumIsolatedEdges( int ox, int oy, int oz )
01998                 //{
01999                         //int i, j, k ;
02000                         //int nx, ny, nz ;
02001 
02002                         //double vox[3][3][3] ;
02003                         //for ( i = -1 ; i < 2 ; i ++ )
02004                                 //for ( j = -1 ; j < 2 ; j ++ )
02005                                         //for ( k = -1 ; k < 2 ; k ++ )
02006                                         //{
02007                                                 //vox[ i + 1 ][ j + 1 ][ k + 1 ] = getDataAt( ox + i, oy + j, oz + k ) ;
02008                                         //}
02009 
02010 
02011                         //int edge[6] = { 0,0,0,0,0,0 } ;
02012 
02013                         //for ( i = 0 ; i < 12 ; i ++ )
02014                         //{
02015                                 //int flag = 1 ;
02016                                 //for ( j = 0 ; j < 4 ; j ++ )
02017                                 //{
02018                                         //nx = 1 + sheetNeighbor[i][j][0] ;
02019                                         //ny = 1 + sheetNeighbor[i][j][1] ;
02020                                         //nz = 1 + sheetNeighbor[i][j][2] ;
02021 
02022                                         //if ( vox[nx][ny][nz] < 0 )
02023                                         //{
02024                                                 //flag = 0 ;
02025                                                 //break ;
02026                                         //}
02027                                 //}
02028 
02029                                 //if ( flag )
02030                                 //{
02031                                         //int e0 = faceEdges[ i ][ 0 ], e1 = faceEdges[ i ][ 1 ] ;
02032                                         //edge[ e0 ] ++ ;
02033                                         //edge[ e1 ] ++ ;
02034                                 //}
02035                         //}
02036 
02037                         //int edges = 0 ;
02038                         //for ( i = 0 ; i < 6 ; i ++ )
02039                         //{
02040                                 //if ( edge[i] )
02041                                 //{
02042                                         //continue ;
02043                                 //}
02044 
02045                                 //nx = 1 + neighbor6[i][0] ;
02046                                 //ny = 1 + neighbor6[i][1] ;
02047                                 //nz = 1 + neighbor6[i][2] ;
02048 
02049                                 //if ( vox[nx][ny][nz] >= 0 )
02050                                 //{
02051                                         //edges ++ ;
02052                                 //}
02053 
02054                         //}
02055 
02056                         //return edges ;
02057                 //}
02058 
02059                 //int Volume::getNumIsolatedFaces( int ox, int oy, int oz )
02060                 //{
02061                         //int i, j, k ;
02062                         //int nx, ny, nz ;
02063 
02064                         //int faces = 0 ;
02065                         //int cellflag[ 8 ] ;
02066 
02067                         //int ct = 0 ;
02068                         //for (  i = -1 ; i < 1 ; i ++ )
02069                                 //for (  j = -1 ; j < 1 ; j ++ )
02070                                         //for (  k = -1 ; k < 1 ; k ++ )
02071                                         //{
02072                                                 //if ( hasCell( ox + i, oy + j, oz + k ) )
02073                                                 //{
02074                                                         //cellflag[ ct ] = 1 ;
02075                                                 //}
02076                                                 //else
02077                                                 //{
02078                                                         //cellflag[ ct ] = 0 ;
02079                                                 //}
02080                                                 //ct ++ ;
02081                                         //}
02082 
02083                         //for ( i = 0 ; i < 12 ; i ++ )
02084                         //{
02085                                 //int hasFace = 1 ;
02086                                 //for ( j = 0 ; j < 4 ; j ++ )
02087                                 //{
02088                                         //nx = ox + sheetNeighbor[i][j][0] ;
02089                                         //ny = oy + sheetNeighbor[i][j][1] ;
02090                                         //nz = oz + sheetNeighbor[i][j][2] ;
02091 
02092                                         //if ( getDataAt( nx, ny, nz ) < 0 )
02093                                         //{
02094                                                 //hasFace = 0 ;
02095                                                 //break ;
02096                                         //}
02097                                 //}
02098 
02099                                 //if ( hasFace )
02100                                 //{
02101                                         //if (cellflag[ faceCells[i][0] ] == 0 && cellflag[ faceCells[i][1] ] == 0 )
02102                                         //{
02103                                                 //faces ++ ;
02104                                         //}
02105                                 //}
02106                         //}
02107 
02109                         //return faces ;
02110                 //}
02111 
02112                 //int Volume::isFeatureFace2( int ox, int oy, int oz )
02113                 //{
02114                         //int i ;
02115                         //int nx, ny, nz ;
02116 
02117                         //for ( i = 0 ; i < 6 ; i ++ )
02118                         //{
02119                                 //nx = ox + neighbor6[i][0] ;
02120                                 //ny = oy + neighbor6[i][1] ;
02121                                 //nz = oz + neighbor6[i][2] ;
02122 
02123                                 //double val = getDataAt( nx, ny, nz ) ;
02124 
02125                                 //if ( val == 0 )
02126                                 //{
02127                                         //return 0 ;
02128                                 //}
02129 
02130                         //}
02131 
02132                         //return 1 ;
02133                 //}
02134 
02135                 int Volume::isFeatureFace( int ox, int oy, int oz )
02136                 {
02137                         // return 1 ;
02138 
02139                         int i, j ;
02140                         int nx, ny, nz ;
02141 
02142                         int faces = 12 ;
02143                         for ( i = 0 ; i < 12 ; i ++ )
02144                         {
02145                                 int ct = 0 ;
02146                                 for ( j = 0 ; j < 4 ; j ++ )
02147                                 {
02148                                         nx = ox + sheetNeighbor[i][j][0] ;
02149                                         ny = oy + sheetNeighbor[i][j][1] ;
02150                                         nz = oz + sheetNeighbor[i][j][2] ;
02151 
02152                                         if ( getDataAt( nx, ny, nz ) < 0 )
02153                                         {
02154                                                 ct = -1 ;
02155                                                 break ;
02156                                         }
02157                                         else if ( getNumNeighbor6( nx, ny, nz ) == 6 )
02158                                         {
02159                                                 ct = -1 ;
02160                                                 break ;
02161                                         }
02162         //                              else if ( getDataAt( nx, ny, nz ) == 0 )
02163         //                              {
02164         //                                      ct ++ ;
02165         //                              }
02166 
02167 
02168                                 }
02169                                 if ( ct == -1 || ct >= 1 )
02170                                 {
02171                                         faces -- ;
02172                                 }
02173                         }
02174 
02175                         if ( faces > 0 )
02176                         {
02177                                 return 1 ;
02178                         }
02179                         return 0 ;
02180 
02181                 }
02182 
02183                 //int Volume::hasFeatureFace( int ox, int oy, int oz )
02184                 //{
02185                         //int i, j, k ;
02186                         //int nx, ny, nz ;
02187 
02188                         //int faceflag ;
02189                         //int cellflag[ 8 ] ;
02190 
02192                         //int ct = 0 ;
02193                         //for (  i = -1 ; i < 1 ; i ++ )
02194                                 //for (  j = -1 ; j < 1 ; j ++ )
02195                                         //for (  k = -1 ; k < 1 ; k ++ )
02196                                         //{
02197                                                 //if ( hasCell( ox + i, oy + j, oz + k ) )
02198                                                 //{
02199                                                         //cellflag[ ct ] = 1 ;
02200                                                 //}
02201                                                 //else
02202                                                 //{
02203                                                         //cellflag[ ct ] = 0 ;
02204                                                 //}
02205                                                 //ct ++ ;
02206                                         //}
02207 
02209                         //for ( i = 0 ; i < 12 ; i ++ )
02210                         //{
02211                                 //faceflag = 1 ;
02212                                 //for ( j = 0 ; j < 4 ; j ++ )
02213                                 //{
02214                                         //nx = ox + sheetNeighbor[i][j][0] ;
02215                                         //ny = oy + sheetNeighbor[i][j][1] ;
02216                                         //nz = oz + sheetNeighbor[i][j][2] ;
02217 
02218                                         //if ( getDataAt( nx, ny, nz ) < 0 )
02219                                         //{
02220                                                 //faceflag = 0 ;
02221                                                 //break ;
02222                                         //}
02223                                 //}
02224 
02225                                 //if ( faceflag )
02226                                 //{
02227                                         //if ( cellflag[ faceCells[i][0] ] == 0 && cellflag[ faceCells[i][1] ] == 0 )
02228                                         //{
02229                                                 //return 1 ;
02230                                         //}
02231                                 //}
02232                         //}
02233 
02234                         //return 0 ;
02235 
02236                 //}
02237 
02238                 int Volume::isSheetEnd( int ox, int oy, int oz )
02239                 {
02240                         return ( ( hasCompleteSheet(ox,oy,oz) == 0 ) && isFeatureFace(ox,oy,oz) ) ;
02241 
02243                         //
02244                         //int i, j, k ;
02245                         //int nx, ny, nz ;
02246 
02247                         //double vox[3][3][3] ;
02248                         //for ( i = -1 ; i < 2 ; i ++ )
02249                         //      for ( j = -1 ; j < 2 ; j ++ )
02250                         //              for ( k = -1 ; k < 2 ; k ++ )
02251                         //              {
02252                         //                      vox[ i + 1 ][ j + 1 ][ k + 1 ] = getDataAt( ox + i, oy + j, oz + k ) ;
02253                         //              }
02254 
02255                         //int edge[6] = { 4,4,4,4,4,4 } ;
02256                         //int edge2[6] = { 4,4,4,4,4,4 } ;
02257 
02258                         //for ( i = 0 ; i < 12 ; i ++ )
02259                         //{
02260                         //      for ( j = 0 ; j < 4 ; j ++ )
02261                         //      {
02262                         //              nx = 1 + sheetNeighbor[i][j][0] ;
02263                         //              ny = 1 + sheetNeighbor[i][j][1] ;
02264                         //              nz = 1 + sheetNeighbor[i][j][2] ;
02265 
02266                         //              if ( vox[nx][ny][nz] < 0 )
02267                         //              {
02268                         //                      edge[ faceEdges[ i ][ 0 ] ] -- ;
02269                         //                      edge[ faceEdges[ i ][ 1 ] ] -- ;
02270                         //                      break ;
02271                         //              }
02272                         //      }
02273 
02274                         //      for ( j = 0 ; j < 4 ; j ++ )
02275                         //      {
02276                         //              nx = 1 + sheetNeighbor[i][j][0] ;
02277                         //              ny = 1 + sheetNeighbor[i][j][1] ;
02278                         //              nz = 1 + sheetNeighbor[i][j][2] ;
02279 
02280                         //              if ( vox[nx][ny][nz] <= 0 )
02281                         //              {
02282                         //                      edge2[ faceEdges[ i ][ 0 ] ] -- ;
02283                         //                      edge2[ faceEdges[ i ][ 1 ] ] -- ;
02284                         //                      break ;
02285                         //              }
02286                         //      }
02287                         //}
02288 
02289                         //
02291                         //for ( i = 0 ; i < 6 ; i ++ )
02292                         //{
02293                         //      nx = 1 + neighbor6[i][0] ;
02294                         //      ny = 1 + neighbor6[i][1] ;
02295                         //      nz = 1 + neighbor6[i][2] ;
02296                         //      if ( edge[i] == 0 && vox[nx][ny][nz] >= 0 )
02297                         //      {
02298                         //              return 0 ;
02299                         //      }
02300                         //}
02301                         //*/
02302                         //
02303 
02304 
02305                         //for ( i = 0 ; i < 6 ; i ++ )
02306                         //{
02307                         //      if ( edge[ i ] == 1 && edge2[ i ] == 1 )
02308                         //      {
02309                         //              return 1 ;
02310                         //      }
02311                         //}
02312 
02313                         //return 0 ;
02314                 }
02315 
02316                 int Volume::isSimple( int ox, int oy, int oz )
02317                 {
02318                         /* Test if this is a simple voxel */
02319                         // int flag = 0 ;
02320                         double vox[3][3][3] ;
02321 
02322                         int i, j, k ;
02323                         for ( i = -1 ; i < 2 ; i ++ )
02324                                 for ( j = -1 ; j < 2 ; j ++ )
02325                                         for ( k = -1 ; k < 2 ; k ++ )
02326                                         {
02327                                                 double tval = getDataAt( ox + i, oy + j, oz + k ) ;
02328 
02329                                                 /*
02330                                                 if ( tval == 0 || tval > (va )
02331                                                 {
02332                                                         flag = 1 ;
02333                                                 }
02334                                                 */
02335                                                 /*
02336                                                 if ( tval < 0 && tval == - curwid )
02337                                                 {
02338                                                 printf("Here %d", (int)-tval) ;
02339                                                 vox[ i + 1 ][ j + 1 ][ k + 1 ] = - tval ;
02340                                                 }
02341                                                 else
02342                                                 */
02343                                                 {
02344                                                         vox[ i + 1 ][ j + 1 ][ k + 1 ] = tval ;
02345                                                 }
02346                                         }
02347 
02348                                 /* Debugging
02349                                 printf("{") ;
02350                                 for ( i = 0 ; i < 3 ; i ++ )
02351                                 {
02352                                         if ( i ) printf(",") ;
02353                                         printf("{") ;
02354                                         for ( j = 0 ; j < 3 ; j ++ )
02355                                         {
02356                                                 if ( j ) printf(",") ;
02357                                                 printf("{") ;
02358                                                 for ( k = 0 ; k < 3 ; k ++ )
02359                                                 {
02360                                                         if ( k ) printf(",") ;
02361                                                         printf("%d", (vox[i][j][k] >=0 ? 1: 0));
02362                                                 }
02363                                                 printf("}") ;
02364                                         }
02365                                         printf("}") ;
02366                                 }
02367                                 printf("} Int: %d, Ext: %d\n", countInt( vox ), countExt( vox )) ;
02368                                 */
02369 
02370                         if ( countInt( vox ) == 1 && countExt( vox ) == 1 )
02371                         {
02372                                 return 1 ;
02373                         }
02374                         else
02375                         {
02376                                 return 0 ;
02377                         }
02378                 }
02379 
02380 
02381                 int Volume::isPiercable( int ox, int oy, int oz )
02382                 {
02383                         /* Test if this is a simple voxel */
02384                         // int flag = 0 ;
02385                         double vox[3][3][3] ;
02386 
02387                         int i, j, k ;
02388                         for ( i = -1 ; i < 2 ; i ++ )
02389                                 for ( j = -1 ; j < 2 ; j ++ )
02390                                         for ( k = -1 ; k < 2 ; k ++ )
02391                                         {
02392                                                 double tval = getDataAt( ox + i, oy + j, oz + k ) ;
02393 
02394                                                 /*
02395                                                 if ( tval == 0 || tval > (va )
02396                                                 {
02397                                                         flag = 1 ;
02398                                                 }
02399                                                 */
02400                                                 /*
02401                                                 if ( tval < 0 && tval == - curwid )
02402                                                 {
02403                                                 printf("Here %d", (int)-tval) ;
02404                                                 vox[ i + 1 ][ j + 1 ][ k + 1 ] = - tval ;
02405                                                 }
02406                                                 else
02407                                                 */
02408                                                 {
02409                                                         vox[ i + 1 ][ j + 1 ][ k + 1 ] = tval ;
02410                                                 }
02411                                         }
02412 
02413                                 /* Debugging
02414                                 printf("{") ;
02415                                 for ( i = 0 ; i < 3 ; i ++ )
02416                                 {
02417                                         if ( i ) printf(",") ;
02418                                         printf("{") ;
02419                                         for ( j = 0 ; j < 3 ; j ++ )
02420                                         {
02421                                                 if ( j ) printf(",") ;
02422                                                 printf("{") ;
02423                                                 for ( k = 0 ; k < 3 ; k ++ )
02424                                                 {
02425                                                         if ( k ) printf(",") ;
02426                                                         printf("%d", (vox[i][j][k] >=0 ? 1: 0));
02427                                                 }
02428                                                 printf("}") ;
02429                                         }
02430                                         printf("}") ;
02431                                 }
02432                                 printf("} Int: %d, Ext: %d\n", countInt( vox ), countExt( vox )) ;
02433                                 */
02434 
02435                         if ( countInt( vox ) == 1 && countExt( vox ) != 1 )
02436                         {
02437                                 return 1 ;
02438                         }
02439                         else
02440                         {
02441                                 return 0 ;
02442                         }
02443                 }
02444 
02445 
02446                 //int Volume::isSimple2( int v[3][3][3] )
02447                 //{
02449                         //double vox[3][3][3] ;
02450 
02451                         //int i, j, k ;
02452                         //for ( i = 0 ; i < 3 ; i ++ )
02453                                 //for ( j = 0 ; j < 3 ; j ++ )
02454                                         //for ( k = 0 ; k < 3 ; k ++ )
02455                                         //{
02456                                                 //if ( v[i][j][k] == 0 )
02457                                                 //{
02458                                                         //vox[ i ][ j ][ k ] = 1 ;
02459                                                 //}
02460                                                 //else
02461                                                 //{
02462                                                         //vox[i][j][k] = -1 ;
02463                                                 //}
02464                                         //}
02465                         //if ( countInt( vox ) == 1 && countExt( vox ) == 1 )
02466                         //{
02467                                 //return 1 ;
02468                         //}
02469                         //else
02470                         //{
02471                                 //printf("Int: %d Ext: %d\n",countInt( vox ),countExt( vox ) );
02472                                 //return 0 ;
02473                         //}
02474                 //}
02475 
02476                 //int Volume::getNumPotComplex3( int ox, int oy, int oz )
02477                 //{
02479 
02480 
02481                         //int i, j, k ;
02482                         //if ( ! isSimple( ox, oy, oz ) || isSheetEnd( ox, oy, oz ) )
02483                         //{
02484                                 //return 60 ;
02485                         //}
02486                         //double val = getDataAt( ox, oy, oz ) ;
02487 
02488                         //int nx, ny, nz ;
02489 
02490 
02491                         //int numSimple = 0 ;
02492                         //for ( i = -1 ; i < 2 ; i ++ )
02493                                 //for ( j = -1 ; j < 2 ; j ++ )
02494                                         //for ( k = -1 ; k < 2 ; k ++ )
02495                                         //{
02496                                                 //nx = ox + i ;
02497                                                 //ny = oy + j ;
02498                                                 //nz = oz + k ;
02499                                                 //if ( getDataAt( nx, ny, nz ) > 0 )
02500                                                 //{
02501                                                         //if ( isSimple( nx, ny, nz ) && ! isSheetEnd( nx, ny, nz ) )
02502                                                         //{
02503                                                                 //numSimple ++ ;
02504                                                         //}
02505                                                 //}
02506                                         //}
02507                         //numSimple -- ;
02508 
02509                         //setDataAt( ox, oy, oz, -val ) ;
02510 
02511                         //int numPotSimple = 0 ;
02512                         //for ( i = -1 ; i < 2 ; i ++ )
02513                                 //for ( j = -1 ; j < 2 ; j ++ )
02514                                         //for ( k = -1 ; k < 2 ; k ++ )
02515                                         //{
02516                                                 //nx = ox + i ;
02517                                                 //ny = oy + j ;
02518                                                 //nz = oz + k ;
02519                                                 //if ( getDataAt( nx, ny, nz ) > 0 )
02520                                                 //{
02521                                                         //if ( isSimple( nx, ny, nz ) && ! isSheetEnd( nx, ny, nz ) )
02522                                                         //{
02523                                                                 //numPotSimple ++ ;
02524                                                         //}
02525                                                 //}
02526                                         //}
02527 
02528 
02529                         //setDataAt( ox, oy, oz, val ) ;
02530 
02531 
02532 
02533 
02534                         //return 30 - ( numPotSimple  - numSimple ) ;
02535                 //}
02536 
02537                 //int Volume::getNumPotComplex4( int ox, int oy, int oz )
02538                 //{
02539 
02540                         //int cells = getNumCells(ox,oy,oz) ;
02542                         //int faces = getNumFaces(ox,oy,oz) ;
02544 
02545                         //return ( cells * 6 - 2 * faces ) ; // + 2 * ( faces * 4 - 4 * iedges ) ;
02546                 //}
02547 
02548                 int Volume::getNumPotComplex( int ox, int oy, int oz )
02549                 {
02550                         //return 0 ;
02551 
02552                         int i;
02553                         double val = getDataAt( ox, oy, oz ) ;
02554                         if ( val <= 0 )
02555                         {
02556                 //              return 70 ;
02557                         }
02558 
02559                         // return getNumNeighbor6( ox, oy, oz ) ;
02560 
02561                         // int v = ((getNumNeighbor6( ox, oy, oz ) & 255) << 24) ;
02562                         //int v = 0  ;
02563 
02564                         int rvalue = 0, nx, ny, nz ;
02565                         setDataAt( ox, oy, oz, -val ) ;
02566 
02567                         /*
02568                         for ( i = -1 ; i < 2 ; i ++ )
02569                                 for ( j = -1 ; j < 2 ; j ++ )
02570                                         for ( k = -1 ; k < 2 ; k ++ )
02571                                         {
02572                                                 nx = ox + i ;
02573                                                 ny = oy + j ;
02574                                                 nz = oz + k ;
02575                                                 if ( getDataAt( nx, ny, nz ) == val )
02576                                                 {
02577                                                         if ( isSheetEnd( nx, ny, nz) || ! isSimple ( nx, ny, nz ) )
02578                                                         {
02579                                                                 rvalue ++ ;
02580                                                         }
02581                                                 }
02582                                         }
02583                         */
02584 
02585                         for ( i = 0 ; i < 6 ; i ++ )
02586                         {
02587                                 nx = ox + neighbor6[i][0] ;
02588                                 ny = oy + neighbor6[i][1] ;
02589                                 nz = oz + neighbor6[i][2] ;
02590 
02591                                 if ( getDataAt(nx,ny,nz) >= 0 )
02592                                 {
02593                                         int num = getNumNeighbor6( nx, ny, nz ) ;
02594                                         if ( num > rvalue )
02595                                         {
02596                                                 rvalue = num ;
02597                                         }
02598                                 }
02599                         }
02600 
02601 
02602                         setDataAt( ox, oy, oz, val ) ;
02603 
02604                         return rvalue + getNumNeighbor6( ox, oy, oz ) * 10 ;
02605                         /*
02606                         int v = (((rvalue + getNumNeighbor6( ox, oy, oz ) * 10) & 255) << 24) ;
02607                         v |= ( ( ox & 255 ) << 16 )  ;
02608                         v |= ( ( oy & 255 ) << 8 ) ;
02609                         v |= ( ( oz & 255 ) ) ;
02610                         return v ;
02611                         */
02612 
02613                 }
02614 
02615                 int Volume::getNumPotComplex2( int ox, int oy, int oz )
02616                 {
02617                         return getNumPotComplex( ox, oy, oz ) ;
02618 
02619                         //int i, j, k ;
02620                         //double val = getDataAt( ox, oy, oz ) ;
02621                         //if ( val <= 0 )
02622                         //{
02623                         //      return 0 ;
02624                         //}
02625 
02626                         //int rvalue = 0, nx, ny, nz ;
02627                         //setDataAt( ox, oy, oz, -val ) ;
02628 
02629                         //for ( i = -1 ; i < 2 ; i ++ )
02630                         //      for ( j = -1 ; j < 2 ; j ++ )
02631                         //              for ( k = -1 ; k < 2 ; k ++ )
02632                         //              {
02633                         //                      nx = ox + i ;
02634                         //                      ny = oy + j ;
02635                         //                      nz = oz + k ;
02636                         //                      if ( getDataAt( nx, ny, nz ) == val )
02637                         //                      {
02638                         //                              if ( isHelixEnd( nx, ny, nz) || ! isSimple ( nx, ny, nz ) )
02639                         //                              {
02640                         //                                      rvalue ++ ;
02641                         //                              }
02642                         //                      }
02643                         //              }
02644 
02645                         //setDataAt( ox, oy, oz, val ) ;
02646 
02647                         //return rvalue + getNumNeighbor6( ox, oy, oz ) * 30 ;
02648                 }
02649 
02650                 //int Volume::getNumNeighbor( int ox, int oy, int oz )
02651                 //{
02652                         //int rvalue = 0 ;
02653                         //double val = getDataAt( ox, oy, oz ) ;
02654                         //for ( int i = 0 ; i < 6 ; i ++ )
02655                         //{
02656                                 //int nx = ox + neighbor6[i][0] ;
02657                                 //int ny = oy + neighbor6[i][1] ;
02658                                 //int nz = oz + neighbor6[i][2] ;
02659 
02660                                 //if ( getDataAt( nx, ny, nz ) == val )
02661                                 //{
02662                                         //rvalue ++ ;
02663                                 //}
02664                         //}
02666                         //for ( int i = -1 ; i < 2 ; i ++ )
02667                                 //for ( int j = -1 ; j < 2 ; j ++ )
02668                                         //for ( int k = -1 ; k < 2 ; k ++ )
02669                                         //{
02670                                                 //int nx = ox + i ;
02671                                                 //int ny = oy + j ;
02672                                                 //int nz = oz + k ;
02673 
02674                                                 //if ( getDataAt( nx, ny, nz ) == val )
02675                                                 //{
02676                                                         //rvalue ++ ;
02677                                                 //}
02678                                         //}
02679                         //*/
02680                         //return rvalue ;
02681                 //}
02682 
02683 
02684                 //void Volume::setScoreNeighbor( GridQueue* queue )
02685                 //{
02687                         //gridQueueEle* ele = queue->getHead() ;
02688                         //while ( ele != NULL )
02689                         //{
02690                                 //ele->score = getNumNeighbor( ele->x, ele->y, ele->z ) ;
02691                                 //ele = ele->next ;
02692                         //}
02693 
02694                         //queue->sort( queue->getNumElements() ) ;
02695                 //}
02696 
02697 
02698                 int Volume::components6( int vox[3][3][3] )
02699                 {
02700                         // Stupid flood fill
02701                         int tot = 0 ;
02702                         int queue[27][3] ;
02703                         int vis[3][3][3] ;
02704                         int head = 0, tail = 1 ;
02705                         int i, j, k ;
02706                         for ( i = 0 ; i < 3 ; i ++ )
02707                                 for ( j = 0 ; j < 3 ; j ++ )
02708                                         for ( k = 0 ; k < 3 ; k ++ )
02709                                         {
02710                                                 vis[i][j][k] = 0 ;
02711                                                 if ( vox[i][j][k] )
02712                                                 {
02713                                                         if ( tot == 0 )
02714                                                         {
02715                                                                 queue[0][0] = i ;
02716                                                                 queue[0][1] = j ;
02717                                                                 queue[0][2] = k ;
02718                                                                 vis[i][j][k] = 1 ;
02719                                                         }
02720                                                         tot ++ ;
02721                                                 }
02722                                         }
02723                         if ( tot == 0 )
02724                         {
02725                                 return 0 ;
02726                         }
02727                         // printf("total: %d\n", tot) ;
02728 
02729                         int ct = 1 ;
02730                         while ( head != tail )
02731                         {
02732                                 int x = queue[head][0] ;
02733                                 int y = queue[head][1] ;
02734                                 int z = queue[head][2] ;
02735                                 head ++ ;
02736 
02737                                 for ( i = 0 ; i < 6 ; i ++ )
02738                                 {
02739                                         int nx = x + neighbor6[i][0] ;
02740                                         int ny = y + neighbor6[i][1] ;
02741                                         int nz = z + neighbor6[i][2] ;
02742                                         if ( nx >=0 && nx < 3 && ny >=0 && ny < 3 && nz >=0 && nz < 3 )
02743                                         {
02744                                                 if ( vox[nx][ny][nz] && ! vis[nx][ny][nz] )
02745                                                 {
02746                                                         queue[tail][0] = nx ;
02747                                                         queue[tail][1] = ny ;
02748                                                         queue[tail][2] = nz ;
02749                                                         tail ++ ;
02750                                                         vis[nx][ny][nz] = 1 ;
02751                                                         ct ++ ;
02752                                                 }
02753                                         }
02754                                 }
02755                         }
02756 
02757                         if ( ct == tot )
02758                         {
02759                                 return 1 ;
02760                         }
02761                         else
02762                         {
02763                                 return 2 ;
02764                         }
02765 
02766                 }
02767                 int Volume::components26( int vox[3][3][3] )
02768                 {
02769                         // Stupid flood fill
02770                         int tot = 0 ;
02771                         int queue[27][3] ;
02772                         int vis[3][3][3] ;
02773                         int head = 0, tail = 1 ;
02774                         int i, j, k ;
02775                         for ( i = 0 ; i < 3 ; i ++ )
02776                                 for ( j = 0 ; j < 3 ; j ++ )
02777                                         for ( k = 0 ; k < 3 ; k ++ )
02778                                         {
02779                                                 vis[i][j][k] = 0 ;
02780                                                 if ( vox[i][j][k] )
02781                                                 {
02782                                                         if ( tot == 0 )
02783                                                         {
02784                                                                 queue[0][0] = i ;
02785                                                                 queue[0][1] = j ;
02786                                                                 queue[0][2] = k ;
02787                                                                 vis[i][j][k] = 1 ;
02788                                                         }
02789                                                         tot ++ ;
02790                                                 }
02791                                         }
02792                         if ( tot == 0 )
02793                         {
02794                                 return 0 ;
02795                         }
02796 
02797                         int ct = 1 ;
02798                         while ( head != tail )
02799                         {
02800                                 int x = queue[head][0] ;
02801                                 int y = queue[head][1] ;
02802                                 int z = queue[head][2] ;
02803                                 head ++ ;
02804 
02805                                 for ( i = -1 ; i < 2 ; i ++ )
02806                                         for ( j = -1 ; j < 2 ; j ++ )
02807                                                 for ( k = -1 ; k < 2 ; k ++ )
02808                                                 {
02809                                                         int nx = x + i ;
02810                                                         int ny = y + j ;
02811                                                         int nz = z + k ;
02812                                                         if ( nx >=0 && nx < 3 && ny >=0 && ny < 3 && nz >=0 && nz < 3 )
02813                                                         {
02814                                                                 if ( vox[nx][ny][nz] && ! vis[nx][ny][nz] )
02815                                                                 {
02816                                                                         queue[tail][0] = nx ;
02817                                                                         queue[tail][1] = ny ;
02818                                                                         queue[tail][2] = nz ;
02819                                                                         tail ++ ;
02820                                                                         vis[nx][ny][nz] = 1 ;
02821                                                                         ct ++ ;
02822                                                                 }
02823                                                         }
02824                                                 }
02825                         }
02826 
02827                         if ( ct == tot )
02828                         {
02829                                 return 1 ;
02830                         }
02831                         else
02832                         {
02833                                 return 2 ;
02834                         }
02835 
02836                 }
02837 
02838                 int Volume::countExt( double vox[3][3][3] )
02839                 {
02840                         int tvox[3][3][3] ;
02841 
02842                         for ( int i = 0 ; i < 3 ; i ++ )
02843                                 for ( int j = 0 ; j < 3 ; j ++ )
02844                                         for ( int k = 0 ; k < 3 ; k ++ )
02845                                         {
02846                                                 if ( vox[i][j][k] < 0 )
02847                                                 {
02848                                                         tvox[i][j][k] = 1 ;
02849                                                 }
02850                                                 else
02851                                                 {
02852                                                         tvox[i][j][k] = 0 ;
02853                                                 }
02854                                         }
02855 
02856                         return components26( tvox ) ;
02857                 }
02858 
02859                 int Volume::countInt( double vox[3][3][3] )
02860                 {
02861                         int i, j, k ;
02862                         int tvox[3][3][3] ;
02863 
02864                         for ( i = 0 ; i < 3 ; i ++ )
02865                                 for ( j = 0 ; j < 3 ; j ++ )
02866                                         for ( k = 0 ; k < 3 ; k ++ )
02867                                         {
02868                                                 tvox[i][j][k] = 0 ;
02869                                         }
02870 
02871                         for ( i = 0 ; i < 6 ; i ++ )
02872                         {
02873                                 int nx = 1 + neighbor6[i][0] ;
02874                                 int ny = 1 + neighbor6[i][1] ;
02875                                 int nz = 1 + neighbor6[i][2] ;
02876                                 if ( vox[ nx ][ ny ][ nz ] >= 0 )
02877                                 {
02878                                         tvox[ nx ][ ny ][ nz ] = 1 ;
02879                                         for ( j = 0 ; j < 4 ; j ++ )
02880                                         {
02881                                                 int nnx = neighbor64[i][j][0] + nx ;
02882                                                 int nny = neighbor64[i][j][1] + ny ;
02883                                                 int nnz = neighbor64[i][j][2] + nz ;
02884                                                 if ( vox[ nnx ][ nny ][ nnz ] >= 0 )
02885                                                 {
02886                                                         tvox[ nnx ][ nny ][ nnz ] = 1 ;
02887                                                 }
02888                                         }
02889                                 }
02890                         }
02891 
02892                         return components6( tvox ) ;
02893                 }
02894 
02895                 int Volume::countIntEuler( int ox, int oy, int oz )
02896                 {
02897                         int nv = 0 , ne = 0, nc = 0 ;
02898 
02899                         int i, j, k ;
02900                         int tvox[3][3][3] ;
02901                         double vox[3][3][3] ;
02902 
02903                         for ( i = 0 ; i < 3 ; i ++ )
02904                                 for ( j = 0 ; j < 3 ; j ++ )
02905                                         for ( k = 0 ; k < 3 ; k ++ )
02906                                         {
02907                                                 vox[i][j][k] = getDataAt( ox - 1 + i, oy - 1 + j, oz - 1 + k ) ;
02908                                                 tvox[i][j][k] = 0 ;
02909                                         }
02910 
02911                         for ( i = 0 ; i < 6 ; i ++ )
02912                         {
02913                                 int nx = 1 + neighbor6[i][0] ;
02914                                 int ny = 1 + neighbor6[i][1] ;
02915                                 int nz = 1 + neighbor6[i][2] ;
02916                                 if ( vox[nx][ny][nz] >= 0 )
02917                                 {
02918                                         tvox[ nx ][ ny ][ nz ] = 1 ;
02919 
02920                                         nv ++ ;
02921 
02922                                         for ( j = 0 ; j < 4 ; j ++ )
02923                                         {
02924                                                 int nnx = neighbor64[i][j][0] + nx ;
02925                                                 int nny = neighbor64[i][j][1] + ny ;
02926                                                 int nnz = neighbor64[i][j][2] + nz ;
02927                                                 if ( vox[nnx][nny][nnz] >= 0 )
02928                                                 {
02929                                                         if ( tvox[nnx][nny][nnz] == 0 )
02930                                                         {
02931                                                                 tvox[nnx][nny][nnz] = 1 ;
02932                                                                 nv ++ ;
02933                                                         }
02934 
02935                                                         ne ++ ;
02936                                                 }
02937                                         }
02938                                 }
02939                         }
02940 
02941                         nc = components6( tvox ) ;
02942 
02943                         return ( nc - ( nv - ne ) ) ;
02944                 }
02945 
02946                 //void Volume::erodeNoTopo( float thr, int wid )
02947                 //{
02949                         //int i, j, k ;
02951                         //#ifdef VERBOSE
02952                         //printf("Thresholding the volume to -MAX_ERODE/0...\n") ;
02953                         //#endif
02954                         //threshold( thr, -MAX_ERODE, 0 ) ;
02955 
02957                         //#ifdef VERBOSE
02958                         //printf("Initializing queue...\n") ;
02959                         //#endif
02960                         //GridQueue* queue = new GridQueue( ) ;
02961 
02962                         //for ( i = 0 ; i < getSizeX() ; i ++ )
02963                                 //for ( j = 0 ; j < getSizeY() ; j ++ )
02964                                         //for ( k = 0 ; k < getSizeZ() ; k ++ )
02965                                         //{
02966                                                 //if ( getDataAt( i, j, k ) >= 0 )
02967                                                 //{
02968                                                         //for ( int m = 0 ; m < 6 ; m ++ )
02969                                                         //{
02970                                                                 //if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
02971                                                                 //{
02972                                                                         //setDataAt( i, j, k, 1 ) ;
02973                                                                         //queue->pushQueue( i, j, k ) ;
02974                                                                         //break ;
02975                                                                 //}
02976                                                         //}
02977                                                 //}
02978                                         //}
02979                         //#ifdef VERBOSE
02980                         //printf("Total %d nodes\n", queue->getNumElements() ) ;
02981 
02983                         //printf("Start erosion to %d...\n", wid) ;
02984                         //#endif
02985                         //double val = 0;
02986                         //int ox, oy, oz ;
02987                         //int curwid = 0 ;
02988                         //int total = 0, ct = 0 ;
02989                         //while ( 1 )
02990                         //{
02991                                 //if ( ct == total )
02992                                 //{
02993                                         //#ifdef VERBOSE
02994                                         //printf("Layer %d has %d nodes.\n", (int) curwid, total ) ;
02995                                         //#endif
02996                                         //curwid ++ ;
02997                                         //ct = 0 ;
02998                                         //total = queue->getNumElements() ;
02999                                         //if ( total == 0 )
03000                                         //{
03001                                                 //break ;
03002                                         //}
03003                                 //}
03004 
03005                                 //queue->popQueue(ox, oy, oz) ;
03006                                 //val = getDataAt( ox, oy, oz ) ;
03007                                 //if ( val > wid )
03008                                 //{
03009                                         //break ;
03010                                 //}
03011                                 //ct ++ ;
03012 
03013                                 //setDataAt( ox, oy, oz, -val ) ;
03014 
03015 
03016                                 //for ( int m = 0 ; m < 6 ; m ++ )
03017                                 //{
03018                                         //int nx = ox + neighbor6[m][0] ;
03019                                         //int ny = oy + neighbor6[m][1] ;
03020                                         //int nz = oz + neighbor6[m][2] ;
03021                                         //if ( getDataAt( nx, ny, nz ) == 0 )
03022                                         //{
03023                                                 //setDataAt( nx, ny, nz, val + 1 ) ;
03024                                                 //queue->pushQueue( nx, ny, nz ) ;
03025                                         //}
03026                                 //}
03027                         //}
03028 
03030                         //#ifdef VERBOSE
03031                         //printf("Thresholding the volume to 0/1...\n") ;
03032                         //#endif
03033                         //threshold( 0, 0, 1 ) ;
03034 
03035                 //}
03036 
03037                 //void Volume::erodeTopo( float thr, int wid )
03038                 //{
03040                         //int i, j, k ;
03042                         //#ifdef VERBOSE
03043                         //printf("Thresholding the volume to -MAX_ERODE/0...\n") ;
03044                         //#endif
03045                         //threshold( thr, -MAX_ERODE, 0 ) ;
03046 
03048                         //#ifdef VERBOSE
03049                         //printf("Initializing queue...\n") ;
03050                         //#endif
03051                         //GridQueue* queue = new GridQueue( ) ;
03052 
03053                         //for ( i = 0 ; i < getSizeX() ; i ++ )
03054                                 //for ( j = 0 ; j < getSizeY() ; j ++ )
03055                                         //for ( k = 0 ; k < getSizeZ() ; k ++ )
03056                                         //{
03057                                                 //if ( getDataAt( i, j, k ) >= 0 )
03058                                                 //{
03059                                                         //for ( int m = 0 ; m < 6 ; m ++ )
03060                                                         //{
03061                                                                 //if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
03062                                                                 //{
03063                                                                         //setDataAt( i, j, k, 1 ) ;
03064                                                                         //queue->pushQueue( i, j, k ) ;
03065                                                                         //break ;
03066                                                                 //}
03067                                                         //}
03068                                                 //}
03069                                         //}
03070                         //#ifdef VERBOSE
03071                         //printf("Total %d nodes\n", queue->getNumElements() ) ;
03072 
03074                         //printf("Start erosion to %d...\n", wid) ;
03075                         //#endif
03076 
03077                         //double val = 0;
03078                         //int ox, oy, oz ;
03079                         //int curwid = 0 ;
03080                         //int total = 0, ct = 0 ;
03081                         //while ( 1 )
03082                         //{
03083                                 //if ( ct == total )
03084                                 //{
03085                                         //#ifdef VERBOSE
03086                                         //printf("Layer %d has %d nodes.\n", (int) curwid, total ) ;
03087                                         //#endif
03088                                         //curwid ++ ;
03089                                         //ct = 0 ;
03090                                         //total = queue->getNumElements() ;
03091                                         //if ( total == 0 )
03092                                         //{
03093                                                 //break ;
03094                                         //}
03095                                 //}
03096 
03097                                 //queue->popQueue(ox, oy, oz) ;
03098                                 //val = getDataAt( ox, oy, oz ) ;
03099                                 //if ( val > wid )
03100                                 //{
03101                                         //break ;
03102                                 //}
03103                                 //ct ++ ;
03104 
03105                                 //if (  isSimple( ox, oy, oz ) )
03106                                 //{
03108                                         //setDataAt( ox, oy, oz, -val ) ;
03109                                 //}
03110                                 //else
03111                                 //{
03113                                         //setDataAt( ox, oy, oz, val + 1 ) ;
03114                                         //queue->pushQueue( ox, oy, oz ) ;
03115                                 //}
03116 
03117 
03118                                 //for ( int m = 0 ; m < 6 ; m ++ )
03119                                 //{
03120                                         //int nx = ox + neighbor6[m][0] ;
03121                                         //int ny = oy + neighbor6[m][1] ;
03122                                         //int nz = oz + neighbor6[m][2] ;
03123                                         //if ( getDataAt( nx, ny, nz ) == 0 )
03124                                         //{
03125                                                 //setDataAt( nx, ny, nz, val + 1 ) ;
03126                                                 //queue->pushQueue( nx, ny, nz ) ;
03127                                         //}
03128                                 //}
03129                         //}
03130 
03132                         //#ifdef VERBOSE
03133                         //printf("Thresholding the volume to 0/1...\n") ;
03134                         //#endif
03135                         //threshold( 0, 0, 1 ) ;
03136 
03137                 //}
03138 
03139                 //void Volume::erode2( float thr, int wid )
03140                 //{
03141                         //int i, j, k ;
03143                         //#ifdef VERBOSE
03144                         //printf("Thresholding the volume to -MAX_ERODE/0...\n") ;
03145                         //#endif
03146                         //threshold( thr, -MAX_ERODE, 0 ) ;
03147 
03149                         //#ifdef VERBOSE
03150                         //printf("Initializing queue...\n") ;
03151                         //#endif
03152                         //GridQueue2* queue = new GridQueue2( ) ;
03153                         //GridQueue2* queue2 = new GridQueue2( ) ;
03154 
03155                         //for ( i = 0 ; i < getSizeX() ; i ++ )
03156                                 //for ( j = 0 ; j < getSizeY() ; j ++ )
03157                                         //for ( k = 0 ; k < getSizeZ() ; k ++ )
03158                                         //{
03159                                                 //if ( getDataAt( i, j, k ) >= 0 )
03160                                                 //{
03161                                                         //for ( int m = 0 ; m < 6 ; m ++ )
03162                                                         //{
03163                                                                 //if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
03164                                                                 //{
03165                                                                         //setDataAt( i, j, k, 1 ) ;
03166                                                                         //queue->prepend( i, j, k ) ;
03167                                                                         //break ;
03168                                                                 //}
03169                                                         //}
03170                                                 //}
03171                                         //}
03172                         //#ifdef VERBOSE
03173                         //printf("Total %d nodes\n", queue->getNumElements() ) ;
03174 
03177                         //printf("Start erosion to %d...\n", wid) ;
03178                         //#endif
03179                         //gridQueueEle* ele ;
03180                         //int ox, oy, oz ;
03181 
03182                         //for ( int curwid = 1 ; curwid <= wid ; curwid ++ )
03183                         //{
03184                                 //int numComplex = 0, numSimple = 0 ;
03185                                 //#ifdef VERBOSE
03186                                 //printf("Processing %d nodes in layer %d\n", queue->getNumElements(), curwid) ;
03187                                 //#endif
03188 
03190                                 //while ( ( ele = queue->getNext() ) != NULL )
03191                                 //{
03192                                         //for ( int m = 0 ; m < 6 ; m ++ )
03193                                         //{
03194                                                 //int nx = ele->x + neighbor6[m][0] ;
03195                                                 //int ny = ele->y + neighbor6[m][1] ;
03196                                                 //int nz = ele->z + neighbor6[m][2] ;
03197                                                 //if ( getDataAt( nx, ny, nz ) == 0 )
03198                                                 //{
03199                                                         //setDataAt( nx, ny, nz, curwid + 1 ) ;
03200                                                         //queue2->prepend( nx, ny, nz ) ;
03201                                                 //}
03202                                         //}
03203 
03204                                 //}
03205                                 //*/
03206 
03208                                 //int seed[3] = {-1,-1,-1};
03209                                 //queue->reset() ;
03210                                 //while ( queue->getNumElements() > 0 )
03211                                 //{
03212                                         //if ( seed[0] < 0 ) printf("After initial scoring...\n");
03213                                         //queue->reset() ;
03214                                         //ele = queue->getNext() ;
03215 
03217                                         //while ( ele != NULL )
03218                                         //{
03219                                                 //ox = ele->x ;
03220                                                 //oy = ele->y ;
03221                                                 //oz = ele->z ;
03222 
03224                                                 //if ( seed[0] < 0 ||
03225                                                         //( ox < seed[0] + 2 && ox > seed[0] - 2 &&
03226                                                         //oy < seed[1] + 2 && oy > seed[1] - 2 &&
03227                                                         //oz < seed[2] + 2 && oz > seed[2] - 2 ) )
03228                                                 //{
03229                                                         //if ( ! isSimple( ox, oy, oz ) )
03230                                                         //{
03232                                                                 //setDataAt( ox, oy, oz, curwid + 1 ) ;
03233                                                                 //queue2->prepend( ox, oy, oz ) ;
03234                                                                 //ele = queue->remove() ;
03235 
03236                                                                 //numComplex ++ ;
03237                                                         //}
03238                                                         //else
03239                                                         //{
03240                                                                 //ele = queue->getNext() ;
03241                                                         //}
03242                                                 //}
03243                                                 //else
03244                                                 //{
03245                                                         //ele = queue->getNext() ;
03246                                                 //}
03247                                         //}
03248 
03250                                         //queue->reset() ;
03251                                         //ele = queue->getNext() ;
03252                                         //int preScore = -1;
03253                                         //while ( ele != NULL )
03254                                         //{
03255                                                 //ox = ele->x ;
03256                                                 //oy = ele->y ;
03257                                                 //oz = ele->z ;
03258 
03260                                                 //if ( seed[0] < 0 ||
03261                                                         //( ox < seed[0] + 3 && ox > seed[0] - 3 &&
03262                                                           //oy < seed[1] + 3 && oy > seed[1] - 3 &&
03263                                                           //oz < seed[2] + 3 && oz > seed[2] - 3 ) )
03264                                                 //{
03265                                                         //ele->score = getNumPotComplex( ox, oy, oz ) ;
03266                                                 //}
03267 
03268 
03269                                                 //if ( ele->score < preScore )
03270                                                 //{
03272                                                         //ele = queue->swap() ;
03273                                                 //}
03274                                                 //else
03275                                                 //{
03276                                                         //preScore = ele->score ;
03277                                                 //}
03278 
03280                                                 //if ( ele->next == NULL )
03281                                                 //{
03282                                                         //ox = ele->x ;
03283                                                         //oy = ele->y ;
03284                                                         //oz = ele->z ;
03285                                                         //setDataAt( ox, oy, oz, -1 ) ;
03287                                                         //seed[0] = ox ;
03288                                                         //seed[1] = oy ;
03289                                                         //seed[2] = oz ;
03290                                                         //queue->remove() ;
03292 
03293 
03294                                                         //for ( int m = 0 ; m < 6 ; m ++ )
03295                                                         //{
03296                                                                 //int nx = ox + neighbor6[m][0] ;
03297                                                                 //int ny = oy + neighbor6[m][1] ;
03298                                                                 //int nz = oz + neighbor6[m][2] ;
03299                                                                 //if ( getDataAt( nx, ny, nz ) == 0 )
03300                                                                 //{
03301                                                                         //setDataAt( nx, ny, nz, curwid + 1 ) ;
03302                                                                         //queue2->prepend( nx, ny, nz ) ;
03303                                                                 //}
03304                                                         //}
03305 
03306 
03307                                                         //numSimple ++ ;
03308                                                         //ele = NULL ;
03309                                                 //}
03310                                                 //else
03311                                                 //{
03312                                                         //ele = queue->getNext() ;
03313                                                 //}
03314                                         //}
03315 
03316                                 //}
03317 
03318                                 //delete queue ;
03319                                 //queue = queue2 ;
03320                                 //queue2 = new GridQueue2() ;
03321                                 //#ifdef VERBOSE
03322                                 //printf("%d complex, %d simple\n", numComplex, numSimple) ;
03323                                 //#endif
03324 
03325                                 //if ( numSimple == 0 )
03326                                 //{
03327                                         //break ;
03328                                 //}
03329                         //}
03330 
03332                         //#ifdef VERBOSE
03333                         //printf("Thresholding the volume to 0/1...\n") ;
03334                         //#endif
03335                         //threshold( 0, 0, 1 ) ;
03336 
03337                 //}
03338 
03339                 //void Volume::erodeShapeTopo( float thr, int wid )
03340                 //{
03342                         //int i, j, k ;
03344                         //#ifdef VERBOSE
03345                         //printf("Thresholding the volume to -MAX_ERODE/0...\n") ;
03346                         //#endif
03347                         //threshold( thr, -MAX_ERODE, 0 ) ;
03348 
03350                         //#ifdef VERBOSE
03351                         //printf("Initializing queue...\n") ;
03352                         //#endif
03353                         //GridQueue2* queue2 = new GridQueue2( ) ;
03354                         //GridQueue2* queue3 = new GridQueue2( ) ;
03355                         //PriorityQueue <gridPoint,int> * queue = new PriorityQueue <gridPoint,int> ( MAX_QUEUELEN );
03356 
03357                         //for ( i = 0 ; i < getSizeX() ; i ++ )
03358                                 //for ( j = 0 ; j < getSizeY() ; j ++ )
03359                                         //for ( k = 0 ; k < getSizeZ() ; k ++ )
03360                                         //{
03361                                                 //if ( getDataAt( i, j, k ) >= 0 )
03362                                                 //{
03363                                                         //for ( int m = 0 ; m < 6 ; m ++ )
03364                                                         //{
03365                                                                 //if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
03366                                                                 //{
03367                                                                         //setDataAt( i, j, k, 1 ) ;
03368                                                                         //queue2->prepend( i, j, k ) ;
03369                                                                         //break ;
03370                                                                 //}
03371                                                         //}
03372                                                 //}
03373                                         //}
03374                         //#ifdef VERBOSE
03375                         //printf("Total %d nodes\n", queue2->getNumElements() ) ;
03376 
03377 
03380                         //printf("Start erosion to %d...\n", wid) ;
03381                         //#endif
03382                         //gridQueueEle* ele ;
03383                         //gridPoint* gp ;
03384                         //int ox, oy, oz ;
03385                         //int score ;
03386                         //Volume* scrvol = new Volume( this->getSizeX() , this->getSizeY(), this->getSizeZ() ) ;
03387                         //for ( i = 0 ; i < getSizeX() * getSizeY() * getSizeZ() ; i ++ )
03388                         //{
03389                                 //scrvol->setDataAt( i, -1 ) ;
03390                         //}
03391 
03392                         //for ( int curwid = 1 ; curwid <= wid ; curwid ++ )
03393                         //{
03397 
03398                                 //int numComplex = 0, numSimple = 0 ;
03399                                 //#ifdef VERBOSE
03400                                 //printf("Processing %d nodes in layer %d\n", queue2->getNumElements(), curwid) ;
03401                                 //#endif
03402 
03406                                 //queue2->reset() ;
03407                                 //ele = queue2->getNext() ;
03408                                 //while ( ele != NULL )
03409                                 //{
03410                                         //ox = ele->x ;
03411                                         //oy = ele->y ;
03412                                         //oz = ele->z ;
03413 
03415                                         //if ( ! isSimple( ox, oy, oz ) )
03416                                         //{
03418                                                 //setDataAt( ox, oy, oz, curwid + 1 ) ;
03419                                                 //queue3->prepend( ox, oy, oz ) ;
03420                                                 //ele = queue2->remove() ;
03421 
03422                                                 //numComplex ++ ;
03423                                         //}
03424                                         //else
03425                                         //{
03426                                                 //ele = queue2->getNext() ;
03427                                         //}
03428                                 //}
03429 
03433                                 //queue2->reset() ;
03434                                 //ele = queue2->getNext() ;
03435                                 //while ( ele != NULL )
03436                                 //{
03437                                         //ox = ele->x ;
03438                                         //oy = ele->y ;
03439                                         //oz = ele->z ;
03440 
03442                                         //score = getNumPotComplex( ox, oy, oz ) ;
03443                                         //scrvol->setDataAt( ox, oy, oz, score ) ;
03444 
03446                                         //gp = new gridPoint ;
03447                                         //gp->x = ox ;
03448                                         //gp->y = oy ;
03449                                         //gp->z = oz ;
03450                                         //queue->add( gp, -score ) ;
03451 
03452                                         //ele = queue2->remove() ;
03453                                 //}
03454 
03457                                 //delete queue2 ;
03458                                 //queue2 = queue3 ;
03459                                 //queue3 = new GridQueue2( ) ;
03460 
03462                                 //while ( ! queue->isEmpty() )
03463                                 //{
03465                                         //queue->remove( gp, score ) ;
03466                                         //ox = gp->x ;
03467                                         //oy = gp->y ;
03468                                         //oz = gp->z ;
03469                                         //delete gp ;
03470                                         //score = -score ;
03471 
03475                                         //if ( getDataAt( ox, oy, oz ) != curwid || (int) scrvol->getDataAt( ox, oy, oz ) != score )
03476                                         //{
03477                                                 //continue ;
03478                                         //}
03479 
03481                                         //setDataAt( ox, oy, oz, -1 ) ;
03482                                         //numSimple ++ ;
03484 
03486                                         //for ( int m = 0 ; m < 6 ; m ++ )
03487                                         //{
03488                                                 //int nx = ox + neighbor6[m][0] ;
03489                                                 //int ny = oy + neighbor6[m][1] ;
03490                                                 //int nz = oz + neighbor6[m][2] ;
03491                                                 //if ( getDataAt( nx, ny, nz ) == 0 )
03492                                                 //{
03493                                                         //setDataAt( nx, ny, nz, curwid + 1 ) ;
03494                                                         //queue2->prepend( nx, ny, nz ) ;
03495                                                 //}
03496                                         //}
03497 
03500                                         //for ( i = -1 ; i < 2 ; i ++ )
03501                                                 //for ( j = -1 ; j < 2 ; j ++ )
03502                                                         //for ( k = -1 ; k < 2 ; k ++ )
03503                                                         //{
03504                                                                 //int nx = ox + i ;
03505                                                                 //int ny = oy + j ;
03506                                                                 //int nz = oz + k ;
03507 
03509                                                                 //if ( getDataAt( nx, ny, nz ) == curwid && ! isSimple( nx, ny, nz ) )
03510                                                                 //{
03512                                                                         //setDataAt( nx, ny, nz, curwid + 1 ) ;
03513                                                                         //queue2->prepend( nx, ny, nz ) ;
03514                                                                         //numComplex ++ ;
03515                                                                 //}
03516                                                         //}
03517 
03521                                         //for ( i = -2 ; i < 3 ;i ++ )
03522                                                 //for ( j = -2 ; j < 3 ; j ++ )
03523                                                         //for ( k = -2 ; k < 3 ; k ++ )
03524                                                         //{
03525                                                                 //int nx = ox + i ;
03526                                                                 //int ny = oy + j ;
03527                                                                 //int nz = oz + k ;
03528 
03529                                                                 //if ( getDataAt( nx, ny, nz ) == curwid )
03530                                                                 //{
03532                                                                         //score = getNumPotComplex( nx, ny, nz ) ;
03533 
03534                                                                         //if ( score != (int) scrvol->getDataAt( nx, ny, nz ) )
03535                                                                         //{
03537                                                                                 //scrvol->setDataAt( nx, ny, nz, score ) ;
03539                                                                                 //gp = new gridPoint ;
03540                                                                                 //gp->x = nx ;
03541                                                                                 //gp->y = ny ;
03542                                                                                 //gp->z = nz ;
03543                                                                                 //queue->add( gp, -score ) ;
03544                                                                         //}
03545                                                                 //}
03546                                                         //}
03547                                                         //*/
03548 
03549                                 //}
03550 
03551                                 //#ifdef VERBOSE
03552                                 //printf("%d complex, %d simple\n", numComplex, numSimple) ;
03553                                 //#endif
03554                                 //if ( numSimple == 0 )
03555                                 //{
03556                                         //break ;
03557                                 //}
03558                         //}
03559 
03561                         //#ifdef VERBOSE
03562                         //printf("Thresholding the volume to 0/1...\n") ;
03563                         //#endif
03564                         //threshold( 0, 0, 1 ) ;
03565                         //delete queue;
03566 
03567                 //}
03568 
03569 
03570                 //void Volume::erodeAtom( float thr, int wid, Volume* avol )
03571                 //{
03573                         //int i, j, k ;
03575                         //#ifdef VERBOSE
03576                         //printf("Thresholding the volume to -MAX_ERODE/0...\n") ;
03577                         //#endif
03578                         //threshold( thr, -MAX_ERODE, 0 ) ;
03579 
03581                         //#ifdef VERBOSE
03582                         //printf("Initializing queue...\n") ;
03583                         //#endif
03584                         //GridQueue2* queue2 = new GridQueue2( ) ;
03585                         //GridQueue2* queue3 = new GridQueue2( ) ;
03586                         //PriorityQueue <gridPoint,int> * queue = new PriorityQueue <gridPoint,int> ( MAX_QUEUELEN );
03587 
03588                         //for ( i = 0 ; i < getSizeX() ; i ++ )
03589                                 //for ( j = 0 ; j < getSizeY() ; j ++ )
03590                                         //for ( k = 0 ; k < getSizeZ() ; k ++ )
03591                                         //{
03592                                                 //if ( getDataAt( i, j, k ) >= 0 )
03593                                                 //{
03594                                                         //if ( avol->getDataAt(i,j,k) > 0 )
03595                                                         //{
03596                                                                 //setDataAt( i, j, k, MAX_ERODE ) ;
03597                                                         //}
03598                                                         //else
03599                                                         //{
03600                                                                 //for ( int m = 0 ; m < 6 ; m ++ )
03601                                                                 //{
03602                                                                         //if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
03603                                                                         //{
03604                                                                                 //setDataAt( i, j, k, 1 ) ;
03605                                                                                 //queue2->prepend( i, j, k ) ;
03606                                                                                 //break ;
03607                                                                         //}
03608                                                                 //}
03609                                                         //}
03610                                                 //}
03611                                         //}
03612                         //#ifdef VERBOSE
03613                         //printf("Total %d nodes\n", queue2->getNumElements() ) ;
03614 
03615 
03618                         //printf("Start erosion to %d...\n", wid) ;
03619                         //#endif
03620 
03621                         //gridQueueEle* ele ;
03622                         //gridPoint* gp ;
03623                         //int ox, oy, oz ;
03624                         //int score ;
03625                         //Volume* scrvol = new Volume( this->getSizeX() , this->getSizeY(), this->getSizeZ() ) ;
03626                         //for ( i = 0 ; i < getSizeX() * getSizeY() * getSizeZ() ; i ++ )
03627                         //{
03628                                 //scrvol->setDataAt( i, -1 ) ;
03629                         //}
03630 
03631                         //for ( int curwid = 1 ; curwid <= wid ; curwid ++ )
03632                         //{
03636 
03637                                 //int numComplex = 0, numSimple = 0 ;
03638                                 //#ifdef VERBOSE
03639                                 //printf("Processing %d nodes in layer %d\n", queue2->getNumElements(), curwid) ;
03640                                 //#endif
03641 
03645                                 //queue2->reset() ;
03646                                 //ele = queue2->getNext() ;
03647                                 //while ( ele != NULL )
03648                                 //{
03649                                         //ox = ele->x ;
03650                                         //oy = ele->y ;
03651                                         //oz = ele->z ;
03652 
03654                                         //if ( ! isSimple( ox, oy, oz ) )
03655                                         //{
03657                                                 //setDataAt( ox, oy, oz, curwid + 1 ) ;
03658                                                 //queue3->prepend( ox, oy, oz ) ;
03659                                                 //ele = queue2->remove() ;
03660 
03661                                                 //numComplex ++ ;
03662                                         //}
03663                                         //else
03664                                         //{
03665                                                 //ele = queue2->getNext() ;
03666                                         //}
03667                                 //}
03668 
03672                                 //queue2->reset() ;
03673                                 //ele = queue2->getNext() ;
03674                                 //while ( ele != NULL )
03675                                 //{
03676                                         //ox = ele->x ;
03677                                         //oy = ele->y ;
03678                                         //oz = ele->z ;
03679 
03681                                         //score = getNumPotComplex( ox, oy, oz ) ;
03682                                         //scrvol->setDataAt( ox, oy, oz, score ) ;
03683 
03685                                         //gp = new gridPoint ;
03686                                         //gp->x = ox ;
03687                                         //gp->y = oy ;
03688                                         //gp->z = oz ;
03689                                         //queue->add( gp, -score ) ;
03690 
03691                                         //ele = queue2->remove() ;
03692                                 //}
03693 
03696                                 //delete queue2 ;
03697                                 //queue2 = queue3 ;
03698                                 //queue3 = new GridQueue2( ) ;
03699 
03701                                 //while ( ! queue->isEmpty() )
03702                                 //{
03704                                         //queue->remove( gp, score ) ;
03705                                         //ox = gp->x ;
03706                                         //oy = gp->y ;
03707                                         //oz = gp->z ;
03708                                         //delete gp ;
03709                                         //score = -score ;
03710 
03714                                         //if ( getDataAt( ox, oy, oz ) != curwid || (int) scrvol->getDataAt( ox, oy, oz ) != score )
03715                                         //{
03716                                                 //continue ;
03717                                         //}
03718 
03720                                         //setDataAt( ox, oy, oz, -1 ) ;
03721                                         //numSimple ++ ;
03723 
03725                                         //for ( int m = 0 ; m < 6 ; m ++ )
03726                                         //{
03727                                                 //int nx = ox + neighbor6[m][0] ;
03728                                                 //int ny = oy + neighbor6[m][1] ;
03729                                                 //int nz = oz + neighbor6[m][2] ;
03730                                                 //if ( getDataAt( nx, ny, nz ) == 0 )
03731                                                 //{
03732                                                         //setDataAt( nx, ny, nz, curwid + 1 ) ;
03733                                                         //queue2->prepend( nx, ny, nz ) ;
03734                                                 //}
03735                                         //}
03736 
03739                                         //for ( i = -1 ; i < 2 ; i ++ )
03740                                                 //for ( j = -1 ; j < 2 ; j ++ )
03741                                                         //for ( k = -1 ; k < 2 ; k ++ )
03742                                                         //{
03743                                                                 //int nx = ox + i ;
03744                                                                 //int ny = oy + j ;
03745                                                                 //int nz = oz + k ;
03746 
03748                                                                 //if ( getDataAt( nx, ny, nz ) == curwid && ! isSimple( nx, ny, nz ) )
03749 
03750                                                                 //{
03752                                                                         //setDataAt( nx, ny, nz, curwid + 1 ) ;
03753                                                                         //queue2->prepend( nx, ny, nz ) ;
03754                                                                         //numComplex ++ ;
03755                                                                 //}
03756                                                         //}
03757 
03761                                         //for ( i = -2 ; i < 3 ;i ++ )
03762                                                 //for ( j = -2 ; j < 3 ; j ++ )
03763                                                         //for ( k = -2 ; k < 3 ; k ++ )
03764                                                         //{
03765                                                                 //int nx = ox + i ;
03766                                                                 //int ny = oy + j ;
03767                                                                 //int nz = oz + k ;
03768 
03769                                                                 //if ( getDataAt( nx, ny, nz ) == curwid )
03770                                                                 //{
03772                                                                         //score = getNumPotComplex( nx, ny, nz ) ;
03773 
03774                                                                         //if ( score != (int) scrvol->getDataAt( nx, ny, nz ) )
03775                                                                         //{
03777                                                                                 //scrvol->setDataAt( nx, ny, nz, score ) ;
03779                                                                                 //gp = new gridPoint ;
03780                                                                                 //gp->x = nx ;
03781                                                                                 //gp->y = ny ;
03782                                                                                 //gp->z = nz ;
03783                                                                                 //queue->add( gp, -score ) ;
03784                                                                         //}
03785                                                                 //}
03786                                                         //}
03787                                                         //*/
03788 
03789                                 //}
03790                                 //#ifdef VERBOSE
03791                                 //printf("%d complex, %d simple\n", numComplex, numSimple) ;
03792                                 //#endif
03793 
03794                                 //if ( numSimple == 0 )
03795                                 //{
03796                                                 //break ;
03797                                 //}
03798                         //}
03799 
03801                         //#ifdef VERBOSE
03802                         //printf("Thresholding the volume to 0/1...\n") ;
03803                         //#endif
03804                         //threshold( 0, 0, 1 ) ;
03805                         //delete queue;
03806 
03807                 //}
03808 
03810                 //*  Assuming the current volume has already been thresholded to 0/1
03811                 //*/
03812                 void Volume::curveSkeleton( Volume* grayvol, float lowthr, float highthr, Volume* svol )
03813                 {
03814                         int i, j, k ;
03815                         // First, threshold the volume
03816                         #ifdef VERBOSE
03817                         printf("Thresholding the volume to -1/0...\n") ;
03818                         #endif
03819                         threshold( 0.5f, -1, 0 ) ;
03820 
03821                         // Next, apply convergent erosion
03822                         // by preserving: complex nodes, curve end-points, and sheet points
03823 
03824                         // Next, initialize the linked queue
03825                         #ifdef VERBOSE
03826                         printf("Initializing queue...\n") ;
03827                         #endif
03828                         GridQueue2* queue2 = new GridQueue2( ) ;
03829                         GridQueue2* queue3 = new GridQueue2( ) ;
03830                         GridQueue2* queue4 = new GridQueue2( ) ;
03831                         PriorityQueue <gridPoint,int> * queue = new PriorityQueue <gridPoint,int> ( MAX_QUEUELEN );
03832 
03833                         for ( i = 0 ; i < getSizeX() ; i ++ )
03834                                 for ( j = 0 ; j < getSizeY() ; j ++ )
03835                                         for ( k = 0 ; k < getSizeZ() ; k ++ )
03836                                         {
03837                                                 if ( getDataAt( i, j, k ) >= 0 )
03838                                                 {
03839                                                         float v = (float)grayvol->getDataAt(i,j,k) ;
03840                                                         if ( v <= lowthr || v > highthr || svol->getDataAt(i,j,k) > 0 )
03841                                                         {
03842                                                                 setDataAt( i, j, k, MAX_ERODE ) ;
03843                                                         }
03844                                                         else
03845                                                         {
03846                                                                 for ( int m = 0 ; m < 6 ; m ++ )
03847                                                                 {
03848                                                                         if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
03849                                                                         {
03850                                                                                 // setDataAt( i, j, k, 1 ) ;
03851                                                                                 queue2->prepend( i, j, k ) ;
03852                                                                                 break ;
03853                                                                         }
03854                                                                 }
03855                                                         }
03856                                                 }
03857                                         }
03858                         int wid = MAX_ERODE ;
03859                         #ifdef VERBOSE
03860                         printf("Total %d nodes\n", queue2->getNumElements() ) ;
03861                         printf("Start erosion to %d...\n", wid) ;
03862                         #endif
03863 
03864 
03865                         // Perform erosion
03866                         gridQueueEle* ele ;
03867                         gridPoint* gp ;
03868                         int ox, oy, oz ;
03869                         int score ;
03870                         Volume* scrvol = new Volume( this->getSizeX() , this->getSizeY(), this->getSizeZ() ) ;
03871                         for ( i = 0 ; i < getSizeX() * getSizeY() * getSizeZ() ; i ++ )
03872                         {
03873                                 scrvol->setDataAt( i, -1 ) ;
03874                         }
03875 
03876         #ifdef  NOISE_DIS_HELIX
03877                         Volume* noisevol = new Volume( getSizeX(), getSizeY(), getSizeZ() ) ;
03878         #endif
03879 
03880                         for ( int curwid = 1 ; curwid <= wid ; curwid ++ )
03881                         {
03882                                 // At the start of each iteration,
03883                                 // queue2 holds all the nodes for this layer
03884                                 // queue3 and queue are empty
03885 
03886                                 int numComplex = 0, numSimple = 0 ;
03887                                 #ifdef VERBOSE
03888                                 printf("Processing %d nodes in layer %d\n", queue2->getNumElements(), curwid) ;
03889                                 #endif
03890 
03891                                 /*
03892                                 We first need to assign curwid + 1 to every node in this layer
03893                                 */
03894                                 queue2->reset() ;
03895                                 ele = queue2->getNext() ;
03896                                 while ( ele != NULL )
03897                                 {
03898                                         ox = ele->x ;
03899                                         oy = ele->y ;
03900                                         oz = ele->z ;
03901 
03902                                         if ( getDataAt(ox,oy,oz) == curwid )
03903                                         {
03904                                                 ele = queue2->remove() ;
03905                                         }
03906                                         else
03907                                         {
03908                                                 setDataAt(ox,oy,oz, curwid) ;
03909                                                 ele = queue2->getNext() ;
03910                                         }
03911                                 }
03912                                 queue4->reset() ;
03913                                 ele = queue4->getNext() ;
03914                                 while ( ele != NULL )
03915                                 {
03916                                         ox = ele->x ;
03917                                         oy = ele->y ;
03918                                         oz = ele->z ;
03919 
03920                                         queue2->prepend(ox,oy,oz) ;
03921                                         ele = queue4->remove() ;
03922                                 }
03923 
03924                                 // Now queue2 holds all the nodes for this layer
03925 
03926         #ifdef NOISE_DIS_HELIX
03927                                 /* Extra step: classify nodes in queue2 into noise and non-noise nodes */
03928                                 queue2->reset() ;
03929 
03930                                 // First run
03931                                 int flag = 0 ;
03932                                 while ( ( ele = queue2->getNext() ) != NULL )
03933                                 {
03934                                         ox = ele->x ;
03935                                         oy = ele->y ;
03936                                         oz = ele->z ;
03937                                         if ( NOISE_DIS_HELIX <= 1 )
03938                                         {
03939                                                 noisevol->setDataAt( ox, oy, oz, 0 ) ;
03940                                         }
03941                                         else
03942                                         {
03943                                                 flag = 0 ;
03944                                                 for ( int m = 0 ; m < 6 ; m ++ )
03945                                                 {
03946                                                         int nx = ox + neighbor6[m][0] ;
03947                                                         int ny = oy + neighbor6[m][1] ;
03948                                                         int nz = oz + neighbor6[m][2] ;
03949                                                         if ( getDataAt( nx, ny, nz ) == 0 )
03950                                                         {
03951                                                                 noisevol->setDataAt( ox, oy, oz, 1 ) ;
03952                                                                 flag = 1 ;
03953                                                                 break ;
03954                                                         }
03955                                                 }
03956                                                 if ( ! flag )
03957                                                 {
03958                                                         noisevol->setDataAt( ox, oy, oz, 0 ) ;
03959                                                 }
03960                                         }
03961                                 }
03962 
03963                                 int cur, visited ;
03964                                 for ( cur = 1 ; cur < NOISE_DIS_HELIX ; cur ++ )
03965                                 {
03966                                         queue2->reset() ;
03967                                         int count = 0 ;
03968                                         visited = 0 ;
03969 
03970                                         while ( ( ele = queue2->getNext() ) != NULL )
03971                                         {
03972                                                 ox = ele->x ;
03973                                                 oy = ele->y ;
03974                                                 oz = ele->z ;
03975 
03976                                                 if ( noisevol->getDataAt( ox, oy, oz ) == 1 )
03977                                                 {
03978                                                         visited ++ ;
03979                                                         continue ;
03980                                                 }
03981 
03982                                                 flag = 0 ;
03983                                                 for ( int m = 0 ; m < 6 ; m ++ )
03984                                                 {
03985                                                         int nx = ox + neighbor6[m][0] ;
03986                                                         int ny = oy + neighbor6[m][1] ;
03987                                                         int nz = oz + neighbor6[m][2] ;
03988                                                         if ( getDataAt( nx, ny, nz ) > 0 && noisevol->getDataAt( nx, ny, nz ) == 1 )
03989                                                         {
03990                                                                 noisevol->setDataAt( ox, oy, oz, 1 ) ;
03991                                                                 visited ++ ;
03992                                                                 count ++ ;
03993                                                                 break ;
03994                                                         }
03995                                                 }
03996                                         }
03997 
03998                                         if ( count == 0 )
03999                                         {
04000                                                 break ;
04001                                         }
04002                                 }
04003                                 printf("Maximum feature distance: %d Un-touched: %d\n", cur, queue2->getNumElements() - visited ) ;
04004 
04005 
04006         #endif
04007                                 /* Commented out for debugging
04008 
04009                                 // First,
04010                                 // check for complex nodes in queue2
04011                                 // move them from queue2 to queue3
04012                                 queue2->reset() ;
04013                                 ele = queue2->getNext() ;
04014                                 while ( ele != NULL )
04015                                 {
04016                                         ox = ele->x ;
04017                                         oy = ele->y ;
04018                                         oz = ele->z ;
04019 
04020                                         // Check simple
04021         #ifndef NOISE_DIS_HELIX
04022                                         if ( isHelixEnd( ox, oy, oz ) || ! isSimple( ox, oy, oz ) )
04023         #else
04024                                         if ( isHelixEnd( ox, oy, oz, noisevol ) || ! isSimple( ox, oy, oz ) )
04025         #endif
04026                                         {
04027                                                 // Complex, set to next layer
04028                                                 setDataAt( ox, oy, oz, curwid + 1 ) ;
04029                                                 queue3->prepend( ox, oy, oz ) ;
04030                                                 ele = queue2->remove() ;
04031 
04032                                                 numComplex ++ ;
04033                                         }
04034                                         else
04035                                         {
04036                                                 ele = queue2->getNext() ;
04037                                         }
04038                                 }
04039                                 */
04040 
04041                                 // Next,
04042                                 // Compute score for each node left in queue2
04043                                 // move them into priority queue
04044                                 queue2->reset() ;
04045                                 ele = queue2->getNext() ;
04046                                 while ( ele != NULL )
04047                                 {
04048                                         ox = ele->x ;
04049                                         oy = ele->y ;
04050                                         oz = ele->z ;
04051 
04052                                         // Compute score
04053                                         score = getNumPotComplex2( ox, oy, oz ) ;
04054                                         scrvol->setDataAt( ox, oy, oz, score ) ;
04055 
04056                                         // Push to queue
04057                                         gp = new gridPoint ;
04058                                         gp->x = ox ;
04059                                         gp->y = oy ;
04060                                         gp->z = oz ;
04061                                         // queue->add( gp, -score ) ;
04062                                         queue->add( gp, score ) ;
04063 
04064                                         ele = queue2->remove() ;
04065                                 }
04066 
04067                                 // Rename queue3 to be queue2,
04068                                 // Clear queue3
04069                                 // From now on, queue2 holds nodes of next level
04070                                 delete queue2 ;
04071                                 queue2 = queue3 ;
04072                                 queue3 = new GridQueue2( ) ;
04073 
04074                                 // Next, start priority queue iteration
04075                                 while ( ! queue->isEmpty() )
04076                                 {
04077                                         // Retrieve the node with the highest score
04078                                         queue->remove( gp, score ) ;
04079                                         ox = gp->x ;
04080                                         oy = gp->y ;
04081                                         oz = gp->z ;
04082                                         delete gp ;
04083         //                              score = -score ;
04084 
04085                                         // Ignore the node
04086                                         // if it has been processed before
04087                                         // or it has an updated score
04088                                         if ( getDataAt( ox, oy, oz ) != curwid || (int) scrvol->getDataAt( ox, oy, oz ) != score )
04089                                         {
04090                                                 continue ;
04091                                         }
04092 
04093                                         /* Commented out for debugging
04094 
04095                                         // Remove this simple node
04096                                         setDataAt( ox, oy, oz, -1 ) ;
04097                                         numSimple ++ ;
04098                                         // printf("Highest score: %d\n", score) ;
04099                                         */
04100 
04101                                         /* Added for debugging */
04102                                         // Check simple
04103         #ifndef NOISE_DIS_HELIX
04104                                         // if ( hasIsolatedEdge( ox, oy, oz ) && ! isNoiseHelixEnd( ox, oy, oz ) )
04105                                         if ( isHelixEnd( ox, oy, oz ) || ! isSimple( ox, oy, oz ) )
04106         #else
04107                                         if ( isHelixEnd( ox, oy, oz ) || ! isSimple( ox, oy, oz ) )
04108         #endif
04109                                         {
04110                                                 // Complex, set to next layer
04111                                                 setDataAt( ox, oy, oz, curwid + 1 ) ;
04112                                                 queue4->prepend( ox, oy, oz ) ;
04113                                                 numComplex ++ ;
04114                                         }
04115                                         else
04116                                         {
04117                                                 setDataAt( ox, oy, oz, -1 ) ;
04118                                                 numSimple ++ ;
04119 
04120 
04121                                         /* Adding ends */
04122                                                 // Move its neighboring unvisited node to queue2
04123                                                 for ( int m = 0 ; m < 6 ; m ++ )
04124                                                 {
04125                                                         int nx = ox + neighbor6[m][0] ;
04126                                                         int ny = oy + neighbor6[m][1] ;
04127                                                         int nz = oz + neighbor6[m][2] ;
04128                                                         if ( getDataAt( nx, ny, nz ) == 0 )
04129                                                         {
04130                                                                 // setDataAt( nx, ny, nz, curwid + 1 ) ;
04131                                                                 queue2->prepend( nx, ny, nz ) ;
04132                                                         }
04133                                                 }
04134 
04135                                         }
04136 
04137 
04138                                         /* Commented out for debugging
04139 
04140                                         // Find complex nodes in its 3x3 neighborhood
04141                                         // move them to queue2
04142                                         for ( i = -1 ; i < 2 ; i ++ )
04143                                                 for ( j = -1 ; j < 2 ; j ++ )
04144                                                         for ( k = -1 ; k < 2 ; k ++ )
04145                                                         {
04146                                                                 int nx = ox + i ;
04147                                                                 int ny = oy + j ;
04148                                                                 int nz = oz + k ;
04149 
04150                                                                 // Check simple
04151                                                                 if ( getDataAt( nx, ny, nz ) == curwid &&
04152                                                                         // ( isSheetEnd( ox, oy, oz ) || ! isSimple( nx, ny, nz )) )
04153         #ifndef NOISE_DIS_HELIX
04154                                                                         ( isHelixEnd( nx, ny, nz ) || ! isSimple( nx, ny, nz ) ) )
04155         #else
04156                                                                         ( isHelixEnd( nx, ny, nz, noisevol ) || ! isSimple( nx, ny, nz ) ) )
04157         #endif
04158 
04159                                                                 {
04160                                                                         // Complex, set to next layer
04161                                                                         setDataAt( nx, ny, nz, curwid + 1 ) ;
04162                                                                         queue2->prepend( nx, ny, nz ) ;
04163                                                                         numComplex ++ ;
04164                                                                 }
04165                                                         }
04166                                         */
04167 
04168                                         // Update scores for nodes in its 5x5 neighborhood
04169                                         // insert them back into priority queue
04170 
04171                                         for ( i = -2 ; i < 3 ;i ++ )
04172                                                 for ( j = -2 ; j < 3 ; j ++ )
04173                                                         for ( k = -2 ; k < 3 ; k ++ )
04174                                                         {
04175                                                                 int nx = ox + i ;
04176                                                                 int ny = oy + j ;
04177                                                                 int nz = oz + k ;
04178 
04179                                                                 if ( getDataAt( nx, ny, nz ) == curwid )
04180                                                                 {
04181                                                                         // Compute score
04182                                                                         score = getNumPotComplex2( nx, ny, nz ) ;
04183 
04184                                                                         if ( score != (int) scrvol->getDataAt( nx, ny, nz ) )
04185                                                                         {
04186                                                                                 // printf("Update\n") ;
04187                                                                                 scrvol->setDataAt( nx, ny, nz, score ) ;
04188                                                                                 // Push to queue
04189                                                                                 gp = new gridPoint ;
04190                                                                                 gp->x = nx ;
04191                                                                                 gp->y = ny ;
04192                                                                                 gp->z = nz ;
04193                                                                                 // queue->add( gp, -score ) ;
04194                                                                                 queue->add( gp, score ) ;
04195                                                                         }
04196                                                                 }
04197                                                         }
04198 
04199 
04200                                 }
04201 
04202                                 #ifdef VERBOSE
04203                                 printf("%d complex, %d simple\n", numComplex, numSimple) ;
04204                                 #endif
04205 
04206                                 if ( numSimple == 0 )
04207                                 {
04208                                         if ( queue2->getNumElements() > 0 )
04209                                         {
04210                                                 printf("*************************wierd here*************************\n");
04211                                         }
04212                                                 break ;
04213                                 }
04214                         }
04215 
04216                         // Remove all internal voxels (contained in manifold surfaces)
04217                         queue2->reset() ;
04218                         queue4->reset() ;
04219                         ele = queue4->getNext() ;
04220                         while ( ele != NULL )
04221                         {
04222                                 ox = ele->x ;
04223                                 oy = ele->y ;
04224                                 oz = ele->z ;
04225 
04226                                 if ( isPiercable(ox,oy,oz) == 1 )  // hasCompleteSheet( ox, oy, oz ) == 1 ) //
04227                                 {
04228                                         queue2->prepend(ox,oy,oz) ;
04229                                 //      setDataAt( ox, oy, oz, -1 ) ;
04230                                 }
04231                                 ele = queue4->remove() ;
04232                         }
04233 
04234                         for ( i = 0 ; i < getSizeX() ; i ++ )
04235                                 for ( j = 0 ; j < getSizeY() ; j ++ )
04236                                         for ( k = 0 ; k < getSizeZ() ; k ++ )
04237                                         {
04238                                                 if ( getDataAt( i, j, k ) == 0 && isPiercable(i,j,k) ) //hasCompleteSheet(i,j,k) == 1) //
04239                                                 {
04240                                                         queue2->prepend( i, j, k ) ;
04241                                                 }
04242                                         }
04243                         queue2->reset() ;
04244                         ele = queue2->getNext() ;
04245                         while ( ele != NULL )
04246                         {
04247                                 ox = ele->x ;
04248                                 oy = ele->y ;
04249                                 oz = ele->z ;
04250                                 setDataAt( ox, oy, oz, -1 ) ;
04251                                 ele = queue2->remove() ;
04252                         }
04253 
04254 
04255                         // Finally, clean up
04256                         delete scrvol;
04257                         delete queue;
04258                         delete queue2;
04259                         delete queue3;
04260                         delete queue4;
04261                         #ifdef VERBOSE
04262                         printf("Thresholding the volume to 0/1...\n") ;
04263                         #endif
04264                         threshold( 0, 0, 1 ) ;
04265                 }
04266 
04267                 // Compute curve skeleton
04268                 void Volume::curveSkeleton( float thr, Volume* svol )
04269                 {
04270                         int i, j, k ;
04271                         // First, threshold the volume
04272                         #ifdef VERBOSE
04273                         printf("Thresholding the volume to -1/0...\n") ;
04274                         #endif
04275                         threshold( thr, -1, 0 ) ;
04276 
04277                         // Next, apply convergent erosion
04278                         // by preserving: complex nodes, curve end-points, and sheet points
04279 
04280                         // Next, initialize the linked queue
04281                         #ifdef VERBOSE
04282                         printf("Initializing queue...\n") ;
04283                         #endif
04284                         GridQueue2* queue2 = new GridQueue2( ) ;
04285                         GridQueue2* queue3 = new GridQueue2( ) ;
04286                         GridQueue2* queue4 = new GridQueue2( ) ;
04287                         PriorityQueue <gridPoint,int> * queue = new PriorityQueue <gridPoint,int> ( MAX_QUEUELEN );
04288 
04289                         for ( i = 0 ; i < getSizeX() ; i ++ )
04290                                 for ( j = 0 ; j < getSizeY() ; j ++ )
04291                                         for ( k = 0 ; k < getSizeZ() ; k ++ )
04292                                         {
04293                                                 if ( getDataAt( i, j, k ) >= 0 )
04294                                                 {
04295                                                         if ( svol->getDataAt(i,j,k) > 0 )
04296                                                         {
04297                                                                 setDataAt( i, j, k, MAX_ERODE ) ;
04298                                                         }
04299                                                         else
04300                                                         {
04301                                                                 for ( int m = 0 ; m < 6 ; m ++ )
04302                                                                 {
04303                                                                         if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
04304                                                                         {
04305                                                                                 // setDataAt( i, j, k, 1 ) ;
04306                                                                                 queue2->prepend( i, j, k ) ;
04307                                                                                 break ;
04308                                                                         }
04309                                                                 }
04310                                                         }
04311                                                 }
04312                                         }
04313 
04314                         int wid = MAX_ERODE ;
04315                         #ifdef VERBOSE
04316                         printf("Total %d nodes\n", queue2->getNumElements() ) ;
04317                         printf("Start erosion to %d...\n", wid) ;
04318                         #endif
04319 
04320 
04321                         // Perform erosion
04322                         gridQueueEle* ele ;
04323                         gridPoint* gp ;
04324                         int ox, oy, oz ;
04325                         int score ;
04326                         Volume* scrvol = new Volume( this->getSizeX() , this->getSizeY(), this->getSizeZ() ) ;
04327                         for ( i = 0 ; i < getSizeX() * getSizeY() * getSizeZ() ; i ++ )
04328                         {
04329                                 scrvol->setDataAt( i, -1 ) ;
04330                         }
04331 
04332         #ifdef  NOISE_DIS_HELIX
04333                         Volume* noisevol = new Volume( getSizeX(), getSizeY(), getSizeZ() ) ;
04334         #endif
04335 
04336                         for ( int curwid = 1 ; curwid <= wid ; curwid ++ )
04337                         {
04338                                 // At the start of each iteration,
04339                                 // queue2 holds all the nodes for this layer
04340                                 // queue3 and queue are empty
04341 
04342                                 int numComplex = 0, numSimple = 0 ;
04343                                 #ifdef VERBOSE
04344                                 printf("Processing %d nodes in layer %d\n", queue2->getNumElements(), curwid) ;
04345                                 #endif
04346 
04347                                 /*
04348                                 We first need to assign curwid + 1 to every node in this layer
04349                                 */
04350                                 queue2->reset() ;
04351                                 ele = queue2->getNext() ;
04352                                 while ( ele != NULL )
04353                                 {
04354                                         ox = ele->x ;
04355                                         oy = ele->y ;
04356                                         oz = ele->z ;
04357 
04358                                         if ( getDataAt(ox,oy,oz) == curwid )
04359                                         {
04360                                                 ele = queue2->remove() ;
04361                                         }
04362                                         else
04363                                         {
04364                                                 setDataAt(ox,oy,oz, curwid) ;
04365                                                 ele = queue2->getNext() ;
04366                                         }
04367                                 }
04368                                 queue4->reset() ;
04369                                 ele = queue4->getNext() ;
04370                                 while ( ele != NULL )
04371                                 {
04372                                         ox = ele->x ;
04373                                         oy = ele->y ;
04374                                         oz = ele->z ;
04375 
04376                                         queue2->prepend(ox,oy,oz) ;
04377                                         ele = queue4->remove() ;
04378                                 }
04379 
04380                                 // Now queue2 holds all the nodes for this layer
04381 
04382         #ifdef NOISE_DIS_HELIX
04383                                 /* Extra step: classify nodes in queue2 into noise and non-noise nodes */
04384                                 queue2->reset() ;
04385 
04386                                 // First run
04387                                 int flag = 0 ;
04388                                 while ( ( ele = queue2->getNext() ) != NULL )
04389                                 {
04390                                         ox = ele->x ;
04391                                         oy = ele->y ;
04392                                         oz = ele->z ;
04393                                         if ( NOISE_DIS_HELIX <= 1 )
04394                                         {
04395                                                 noisevol->setDataAt( ox, oy, oz, 0 ) ;
04396                                         }
04397                                         else
04398                                         {
04399                                                 flag = 0 ;
04400                                                 for ( int m = 0 ; m < 6 ; m ++ )
04401                                                 {
04402                                                         int nx = ox + neighbor6[m][0] ;
04403                                                         int ny = oy + neighbor6[m][1] ;
04404                                                         int nz = oz + neighbor6[m][2] ;
04405                                                         if ( getDataAt( nx, ny, nz ) == 0 )
04406                                                         {
04407                                                                 noisevol->setDataAt( ox, oy, oz, 1 ) ;
04408                                                                 flag = 1 ;
04409                                                                 break ;
04410                                                         }
04411                                                 }
04412                                                 if ( ! flag )
04413                                                 {
04414                                                         noisevol->setDataAt( ox, oy, oz, 0 ) ;
04415                                                 }
04416                                         }
04417                                 }
04418 
04419                                 int cur, visited ;
04420                                 for ( cur = 1 ; cur < NOISE_DIS_HELIX ; cur ++ )
04421                                 {
04422                                         queue2->reset() ;
04423                                         int count = 0 ;
04424                                         visited = 0 ;
04425 
04426                                         while ( ( ele = queue2->getNext() ) != NULL )
04427                                         {
04428                                                 ox = ele->x ;
04429                                                 oy = ele->y ;
04430                                                 oz = ele->z ;
04431 
04432                                                 if ( noisevol->getDataAt( ox, oy, oz ) == 1 )
04433                                                 {
04434                                                         visited ++ ;
04435                                                         continue ;
04436                                                 }
04437 
04438                                                 flag = 0 ;
04439                                                 for ( int m = 0 ; m < 6 ; m ++ )
04440                                                 {
04441                                                         int nx = ox + neighbor6[m][0] ;
04442                                                         int ny = oy + neighbor6[m][1] ;
04443                                                         int nz = oz + neighbor6[m][2] ;
04444                                                         if ( getDataAt( nx, ny, nz ) > 0 && noisevol->getDataAt( nx, ny, nz ) == 1 )
04445                                                         {
04446                                                                 noisevol->setDataAt( ox, oy, oz, 1 ) ;
04447                                                                 visited ++ ;
04448                                                                 count ++ ;
04449                                                                 break ;
04450                                                         }
04451                                                 }
04452                                         }
04453 
04454                                         if ( count == 0 )
04455                                         {
04456                                                 break ;
04457                                         }
04458                                 }
04459                                 printf("Maximum feature distance: %d Un-touched: %d\n", cur, queue2->getNumElements() - visited ) ;
04460 
04461 
04462         #endif
04463                                 /* Commented out for debugging
04464 
04465                                 // First,
04466                                 // check for complex nodes in queue2
04467                                 // move them from queue2 to queue3
04468                                 queue2->reset() ;
04469                                 ele = queue2->getNext() ;
04470                                 while ( ele != NULL )
04471                                 {
04472                                         ox = ele->x ;
04473                                         oy = ele->y ;
04474                                         oz = ele->z ;
04475 
04476                                         // Check simple
04477         #ifndef NOISE_DIS_HELIX
04478                                         if ( isHelixEnd( ox, oy, oz ) || ! isSimple( ox, oy, oz ) )
04479         #else
04480                                         if ( isHelixEnd( ox, oy, oz, noisevol ) || ! isSimple( ox, oy, oz ) )
04481         #endif
04482                                         {
04483                                                 // Complex, set to next layer
04484                                                 setDataAt( ox, oy, oz, curwid + 1 ) ;
04485                                                 queue3->prepend( ox, oy, oz ) ;
04486                                                 ele = queue2->remove() ;
04487 
04488                                                 numComplex ++ ;
04489                                         }
04490                                         else
04491                                         {
04492                                                 ele = queue2->getNext() ;
04493                                         }
04494                                 }
04495                                 */
04496 
04497                                 // Next,
04498                                 // Compute score for each node left in queue2
04499                                 // move them into priority queue
04500                                 queue2->reset() ;
04501                                 ele = queue2->getNext() ;
04502                                 while ( ele != NULL )
04503                                 {
04504                                         ox = ele->x ;
04505                                         oy = ele->y ;
04506                                         oz = ele->z ;
04507 
04508                                         // Compute score
04509                                         score = getNumPotComplex2( ox, oy, oz ) ;
04510                                         scrvol->setDataAt( ox, oy, oz, score ) ;
04511 
04512                                         // Push to queue
04513                                         gp = new gridPoint ;
04514                                         gp->x = ox ;
04515                                         gp->y = oy ;
04516                                         gp->z = oz ;
04517                                         // queue->add( gp, -score ) ;
04518                                         queue->add( gp, score ) ;
04519 
04520                                         ele = queue2->remove() ;
04521                                 }
04522 
04523                                 // Rename queue3 to be queue2,
04524                                 // Clear queue3
04525                                 // From now on, queue2 holds nodes of next level
04526                                 delete queue2 ;
04527                                 queue2 = queue3 ;
04528                                 queue3 = new GridQueue2( ) ;
04529 
04530                                 // Next, start priority queue iteration
04531                                 while ( ! queue->isEmpty() )
04532                                 {
04533                                         // Retrieve the node with the highest score
04534                                         queue->remove( gp, score ) ;
04535                                         ox = gp->x ;
04536                                         oy = gp->y ;
04537                                         oz = gp->z ;
04538                                         delete gp ;
04539         //                              score = -score ;
04540 
04541                                         // Ignore the node
04542                                         // if it has been processed before
04543                                         // or it has an updated score
04544                                         if ( getDataAt( ox, oy, oz ) != curwid || (int) scrvol->getDataAt( ox, oy, oz ) != score )
04545                                         {
04546                                                 continue ;
04547                                         }
04548 
04549                                         /* Commented out for debugging
04550 
04551                                         // Remove this simple node
04552                                         setDataAt( ox, oy, oz, -1 ) ;
04553                                         numSimple ++ ;
04554                                         // printf("Highest score: %d\n", score) ;
04555                                         */
04556 
04557                                         /* Added for debugging */
04558                                         // Check simple
04559         #ifndef NOISE_DIS_HELIX
04560                                         // if ( hasIsolatedEdge( ox, oy, oz ) && ! isNoiseHelixEnd( ox, oy, oz ) )
04561                                         if ( isHelixEnd( ox, oy, oz ) || ! isSimple( ox, oy, oz ) )
04562         #else
04563                                         if ( isHelixEnd( ox, oy, oz ) || ! isSimple( ox, oy, oz ) )
04564         #endif
04565                                         {
04566                                                 // Complex, set to next layer
04567                                                 setDataAt( ox, oy, oz, curwid + 1 ) ;
04568                                                 queue4->prepend( ox, oy, oz ) ;
04569                                                 numComplex ++ ;
04570                                         }
04571                                         else
04572                                         {
04573                                                 setDataAt( ox, oy, oz, -1 ) ;
04574                                                 numSimple ++ ;
04575                                         }
04576                                         /* Adding ends */
04577 
04578                                         // Move its neighboring unvisited node to queue2
04579                                         for ( int m = 0 ; m < 6 ; m ++ )
04580                                         {
04581                                                 int nx = ox + neighbor6[m][0] ;
04582                                                 int ny = oy + neighbor6[m][1] ;
04583                                                 int nz = oz + neighbor6[m][2] ;
04584                                                 if ( getDataAt( nx, ny, nz ) == 0 )
04585                                                 {
04586                                                         // setDataAt( nx, ny, nz, curwid + 1 ) ;
04587                                                         queue2->prepend( nx, ny, nz ) ;
04588                                                 }
04589                                         }
04590 
04591                                         /* Commented out for debugging
04592 
04593                                         // Find complex nodes in its 3x3 neighborhood
04594                                         // move them to queue2
04595                                         for ( i = -1 ; i < 2 ; i ++ )
04596                                                 for ( j = -1 ; j < 2 ; j ++ )
04597                                                         for ( k = -1 ; k < 2 ; k ++ )
04598                                                         {
04599                                                                 int nx = ox + i ;
04600                                                                 int ny = oy + j ;
04601                                                                 int nz = oz + k ;
04602 
04603                                                                 // Check simple
04604                                                                 if ( getDataAt( nx, ny, nz ) == curwid &&
04605                                                                         // ( isSheetEnd( ox, oy, oz ) || ! isSimple( nx, ny, nz )) )
04606         #ifndef NOISE_DIS_HELIX
04607                                                                         ( isHelixEnd( nx, ny, nz ) || ! isSimple( nx, ny, nz ) ) )
04608         #else
04609                                                                         ( isHelixEnd( nx, ny, nz, noisevol ) || ! isSimple( nx, ny, nz ) ) )
04610         #endif
04611 
04612                                                                 {
04613                                                                         // Complex, set to next layer
04614                                                                         setDataAt( nx, ny, nz, curwid + 1 ) ;
04615                                                                         queue2->prepend( nx, ny, nz ) ;
04616                                                                         numComplex ++ ;
04617                                                                 }
04618                                                         }
04619                                         */
04620 
04621                                         // Update scores for nodes in its 5x5 neighborhood
04622                                         // insert them back into priority queue
04623 
04624                                         for ( i = -2 ; i < 3 ;i ++ )
04625                                                 for ( j = -2 ; j < 3 ; j ++ )
04626                                                         for ( k = -2 ; k < 3 ; k ++ )
04627                                                         {
04628                                                                 int nx = ox + i ;
04629                                                                 int ny = oy + j ;
04630                                                                 int nz = oz + k ;
04631 
04632                                                                 if ( getDataAt( nx, ny, nz ) == curwid )
04633                                                                 {
04634                                                                         // Compute score
04635                                                                         score = getNumPotComplex2( nx, ny, nz ) ;
04636 
04637                                                                         if ( score != (int) scrvol->getDataAt( nx, ny, nz ) )
04638                                                                         {
04639                                                                                 // printf("Update\n") ;
04640                                                                                 scrvol->setDataAt( nx, ny, nz, score ) ;
04641                                                                                 // Push to queue
04642                                                                                 gp = new gridPoint ;
04643                                                                                 gp->x = nx ;
04644                                                                                 gp->y = ny ;
04645                                                                                 gp->z = nz ;
04646                                                                                 // queue->add( gp, -score ) ;
04647                                                                                 queue->add( gp, score ) ;
04648                                                                         }
04649                                                                 }
04650                                                         }
04651 
04652 
04653                                 }
04654 
04655                                 #ifdef VERBOSE
04656                                 printf("%d complex, %d simple\n", numComplex, numSimple) ;
04657                                 #endif
04658 
04659                                 if ( numSimple == 0 )
04660                                 {
04661                                                 break ;
04662                                 }
04663                         }
04664 
04665                         // Finally, clean up
04666                         delete scrvol;
04667                         delete queue;
04668                         delete queue2;
04669                         delete queue3;
04670                         delete queue4;
04671                         #ifdef VERBOSE
04672                         printf("Thresholding the volume to 0/1...\n") ;
04673                         #endif
04674                         threshold( 0, 0, 1 ) ;
04675                 }
04676 
04677                 // Compute curve skeleton in 2D
04678                 void Volume::curveSkeleton2D( float thr, Volume* svol )
04679                 {
04680                         int i, j, k ;
04681                         // First, threshold the volume
04682                         #ifdef VERBOSE
04683                         printf("Thresholding the volume to -1/0...\n") ;
04684                         #endif
04685                         threshold( thr, -1, 0 ) ;
04686 
04687                         // Next, apply convergent erosion
04688                         // by preserving: complex nodes, curve end-points, and sheet points
04689 
04690                         // Next, initialize the linked queue
04691                         #ifdef VERBOSE
04692                         printf("Initializing queue...\n") ;
04693                         #endif
04694                         GridQueue2* queue2 = new GridQueue2( ) ;
04695                         GridQueue2* queue3 = new GridQueue2( ) ;
04696                         GridQueue2* queue4 = new GridQueue2( ) ;
04697                         PriorityQueue <gridPoint,int> * queue = new PriorityQueue <gridPoint,int> ( MAX_QUEUELEN );
04698 
04699                         for ( i = 0 ; i < getSizeX() ; i ++ )
04700                                 for ( j = 0 ; j < getSizeY() ; j ++ )
04701                                         for ( k = 0 ; k < getSizeZ() ; k ++ )
04702                                         {
04703                                                 if ( getDataAt( i, j, k ) >= 0 )
04704                                                 {
04705                                                         if ( svol->getDataAt(i,j,k) > 0 )
04706                                                         {
04707                                                                 setDataAt( i, j, k, MAX_ERODE ) ;
04708                                                         }
04709                                                         else
04710                                                         {
04711                                                                 for ( int m = 0 ; m < 4 ; m ++ )
04712                                                                 {
04713                                                                         if ( getDataAt( i + neighbor4[m][0], j + neighbor4[m][1], k ) < 0 )
04714                                                                         {
04715                                                                                 // setDataAt( i, j, k, 1 ) ;
04716                                                                                 queue2->prepend( i, j, k ) ;
04717                                                                                 break ;
04718                                                                         }
04719                                                                 }
04720                                                         }
04721                                                 }
04722                                         }
04723                         int wid = MAX_ERODE ;
04724                         #ifdef VERBOSE
04725                         printf("Total %d nodes\n", queue2->getNumElements() ) ;
04726                         printf("Start erosion to %d...\n", wid) ;
04727                         #endif
04728 
04729 
04730                         // Perform erosion
04731                         gridQueueEle* ele ;
04732                         gridPoint* gp ;
04733                         int ox, oy, oz ;
04734                         int score ;
04735                         Volume* scrvol = new Volume( this->getSizeX() , this->getSizeY(), this->getSizeZ() ) ;
04736                         for ( i = 0 ; i < getSizeX() * getSizeY() * getSizeZ() ; i ++ )
04737                         {
04738                                 scrvol->setDataAt( i, -1 ) ;
04739                         }
04740 
04741         #ifdef  NOISE_DIS_HELIX
04742                         Volume* noisevol = new Volume( getSizeX(), getSizeY(), getSizeZ() ) ;
04743         #endif
04744 
04745                         for ( int curwid = 1 ; curwid <= wid ; curwid ++ )
04746                         {
04747                                 // At the start of each iteration,
04748                                 // queue2 holds all the nodes for this layer
04749                                 // queue3 and queue are empty
04750 
04751                                 int numComplex = 0, numSimple = 0 ;
04752                                 #ifdef VERBOSE
04753                                 printf("Processing %d nodes in layer %d\n", queue2->getNumElements(), curwid) ;
04754                                 #endif
04755 
04756                                 /*
04757                                 We first need to assign curwid + 1 to every node in this layer
04758                                 */
04759                                 queue2->reset() ;
04760                                 ele = queue2->getNext() ;
04761                                 while ( ele != NULL )
04762                                 {
04763                                         ox = ele->x ;
04764                                         oy = ele->y ;
04765                                         oz = ele->z ;
04766 
04767                                         if ( getDataAt(ox,oy,oz) == curwid )
04768                                         {
04769                                                 ele = queue2->remove() ;
04770                                         }
04771                                         else
04772                                         {
04773                                                 setDataAt(ox,oy,oz, curwid) ;
04774                                                 ele = queue2->getNext() ;
04775                                         }
04776                                 }
04777                                 queue4->reset() ;
04778                                 ele = queue4->getNext() ;
04779                                 while ( ele != NULL )
04780                                 {
04781                                         ox = ele->x ;
04782                                         oy = ele->y ;
04783                                         oz = ele->z ;
04784 
04785                                         queue2->prepend(ox,oy,oz) ;
04786                                         ele = queue4->remove() ;
04787                                 }
04788 
04789                                 // Now queue2 holds all the nodes for this layer
04790 
04791                                 #ifdef NOISE_DIS_HELIX
04792                                 /* Extra step: classify nodes in queue2 into noise and non-noise nodes */
04793                                 queue2->reset() ;
04794 
04795                                 // First run
04796                                 int flag = 0 ;
04797                                 while ( ( ele = queue2->getNext() ) != NULL )
04798                                 {
04799                                         ox = ele->x ;
04800                                         oy = ele->y ;
04801                                         oz = ele->z ;
04802                                         if ( NOISE_DIS_HELIX <= 1 )
04803                                         {
04804                                                 noisevol->setDataAt( ox, oy, oz, 0 ) ;
04805                                         }
04806                                         else
04807                                         {
04808                                                 flag = 0 ;
04809                                                 for ( int m = 0 ; m < 6 ; m ++ )
04810                                                 {
04811                                                         int nx = ox + neighbor6[m][0] ;
04812                                                         int ny = oy + neighbor6[m][1] ;
04813                                                         int nz = oz + neighbor6[m][2] ;
04814                                                         if ( getDataAt( nx, ny, nz ) == 0 )
04815                                                         {
04816                                                                 noisevol->setDataAt( ox, oy, oz, 1 ) ;
04817                                                                 flag = 1 ;
04818                                                                 break ;
04819                                                         }
04820                                                 }
04821                                                 if ( ! flag )
04822                                                 {
04823                                                         noisevol->setDataAt( ox, oy, oz, 0 ) ;
04824                                                 }
04825                                         }
04826                                 }
04827 
04828                                 int cur, visited ;
04829                                 for ( cur = 1 ; cur < NOISE_DIS_HELIX ; cur ++ )
04830                                 {
04831                                         queue2->reset() ;
04832                                         int count = 0 ;
04833                                         visited = 0 ;
04834 
04835                                         while ( ( ele = queue2->getNext() ) != NULL )
04836                                         {
04837                                                 ox = ele->x ;
04838                                                 oy = ele->y ;
04839                                                 oz = ele->z ;
04840 
04841                                                 if ( noisevol->getDataAt( ox, oy, oz ) == 1 )
04842                                                 {
04843                                                         visited ++ ;
04844                                                         continue ;
04845                                                 }
04846 
04847                                                 flag = 0 ;
04848                                                 for ( int m = 0 ; m < 6 ; m ++ )
04849                                                 {
04850                                                         int nx = ox + neighbor6[m][0] ;
04851                                                         int ny = oy + neighbor6[m][1] ;
04852                                                         int nz = oz + neighbor6[m][2] ;
04853                                                         if ( getDataAt( nx, ny, nz ) > 0 && noisevol->getDataAt( nx, ny, nz ) == 1 )
04854                                                         {
04855                                                                 noisevol->setDataAt( ox, oy, oz, 1 ) ;
04856                                                                 visited ++ ;
04857                                                                 count ++ ;
04858                                                                 break ;
04859                                                         }
04860                                                 }
04861                                         }
04862 
04863                                         if ( count == 0 )
04864                                         {
04865                                                 break ;
04866                                         }
04867                                 }
04868                                 printf("Maximum feature distance: %d Un-touched: %d\n", cur, queue2->getNumElements() - visited ) ;
04869 
04870 
04871                                 #endif
04872                                 /* Commented out for debugging
04873 
04874                                 // First,
04875                                 // check for complex nodes in queue2
04876                                 // move them from queue2 to queue3
04877                                 queue2->reset() ;
04878                                 ele = queue2->getNext() ;
04879                                 while ( ele != NULL )
04880                                 {
04881                                         ox = ele->x ;
04882                                         oy = ele->y ;
04883                                         oz = ele->z ;
04884 
04885                                         // Check simple
04886         #ifndef NOISE_DIS_HELIX
04887                                         if ( isHelixEnd( ox, oy, oz ) || ! isSimple( ox, oy, oz ) )
04888         #else
04889                                         if ( isHelixEnd( ox, oy, oz, noisevol ) || ! isSimple( ox, oy, oz ) )
04890         #endif
04891                                         {
04892                                                 // Complex, set to next layer
04893                                                 setDataAt( ox, oy, oz, curwid + 1 ) ;
04894                                                 queue3->prepend( ox, oy, oz ) ;
04895                                                 ele = queue2->remove() ;
04896 
04897                                                 numComplex ++ ;
04898                                         }
04899                                         else
04900                                         {
04901                                                 ele = queue2->getNext() ;
04902                                         }
04903                                 }
04904                                 */
04905 
04906                                 // Next,
04907                                 // Compute score for each node left in queue2
04908                                 // move them into priority queue
04909                                 queue2->reset() ;
04910                                 ele = queue2->getNext() ;
04911                                 while ( ele != NULL )
04912                                 {
04913                                         ox = ele->x ;
04914                                         oy = ele->y ;
04915                                         oz = ele->z ;
04916 
04917                                         // Compute score
04918                                         score = getNumPotComplex2( ox, oy, oz ) ;
04919                                         //score = getNumNeighbor6( ox, oy, oz ) ;
04920                                         scrvol->setDataAt( ox, oy, oz, score ) ;
04921 
04922                                         // Push to queue
04923                                         gp = new gridPoint ;
04924                                         gp->x = ox ;
04925                                         gp->y = oy ;
04926                                         gp->z = oz ;
04927                                         // queue->add( gp, -score ) ;
04928                                         queue->add( gp, score ) ;
04929 
04930                                         ele = queue2->remove() ;
04931                                 }
04932 
04933                                 // Rename queue3 to be queue2,
04934                                 // Clear queue3
04935                                 // From now on, queue2 holds nodes of next level
04936                                 delete queue2 ;
04937                                 queue2 = queue3 ;
04938                                 queue3 = new GridQueue2( ) ;
04939 
04940                                 // Next, start priority queue iteration
04941                                 while ( ! queue->isEmpty() )
04942                                 {
04943                                         // Retrieve the node with the highest score
04944                                         queue->remove( gp, score ) ;
04945                                         ox = gp->x ;
04946                                         oy = gp->y ;
04947                                         oz = gp->z ;
04948                                         delete gp ;
04949         //                              score = -score ;
04950 
04951                                         // Ignore the node
04952                                         // if it has been processed before
04953                                         // or it has an updated score
04954                                         if ( getDataAt( ox, oy, oz ) != curwid || (int) scrvol->getDataAt( ox, oy, oz ) != score )
04955                                         {
04956                                                 continue ;
04957                                         }
04958 
04959                                         /* Commented out for debugging
04960 
04961                                         // Remove this simple node
04962                                         setDataAt( ox, oy, oz, -1 ) ;
04963                                         numSimple ++ ;
04964                                         // printf("Highest score: %d\n", score) ;
04965                                         */
04966 
04967                                         /* Added for debugging */
04968                                         // Check simple
04969                                         #ifndef NOISE_DIS_HELIX
04970                                         // if ( hasIsolatedEdge( ox, oy, oz ) && ! isNoiseHelixEnd( ox, oy, oz ) )
04971                                         if ( isHelixEnd( ox, oy, oz ) || ! isSimple( ox, oy, oz ) )
04972                                         #else
04973                                         if ( isHelixEnd( ox, oy, oz ) || ! isSimple( ox, oy, oz ) )
04974                                         #endif
04975                                         {
04976                                                 // Complex, set to next layer
04977                                                 setDataAt( ox, oy, oz, curwid + 1 ) ;
04978                                                 queue4->prepend( ox, oy, oz ) ;
04979                                                 numComplex ++ ;
04980                                         }
04981                                         else
04982                                         {
04983                                                 setDataAt( ox, oy, oz, -1 ) ;
04984                                                 numSimple ++ ;
04985                                         }
04986                                         /* Adding ends */
04987 
04988                                         // Move its neighboring unvisited node to queue2
04989                                         for ( int m = 0 ; m < 4 ; m ++ )
04990                                         {
04991                                                 int nx = ox + neighbor4[m][0] ;
04992                                                 int ny = oy + neighbor4[m][1] ;
04993                                                 int nz = oz ;
04994                                                 if ( getDataAt( nx, ny, nz ) == 0 )
04995                                                 {
04996                                                         // setDataAt( nx, ny, nz, curwid + 1 ) ;
04997                                                         queue2->prepend( nx, ny, nz ) ;
04998                                                 }
04999                                         }
05000 
05001                                         /* Commented out for debugging
05002 
05003                                         // Find complex nodes in its 3x3 neighborhood
05004                                         // move them to queue2
05005                                         for ( i = -1 ; i < 2 ; i ++ )
05006                                                 for ( j = -1 ; j < 2 ; j ++ )
05007                                                         for ( k = -1 ; k < 2 ; k ++ )
05008                                                         {
05009                                                                 int nx = ox + i ;
05010                                                                 int ny = oy + j ;
05011                                                                 int nz = oz + k ;
05012 
05013                                                                 // Check simple
05014                                                                 if ( getDataAt( nx, ny, nz ) == curwid &&
05015                                                                         // ( isSheetEnd( ox, oy, oz ) || ! isSimple( nx, ny, nz )) )
05016         #ifndef NOISE_DIS_HELIX
05017                                                                         ( isHelixEnd( nx, ny, nz ) || ! isSimple( nx, ny, nz ) ) )
05018         #else
05019                                                                         ( isHelixEnd( nx, ny, nz, noisevol ) || ! isSimple( nx, ny, nz ) ) )
05020         #endif
05021 
05022                                                                 {
05023                                                                         // Complex, set to next layer
05024                                                                         setDataAt( nx, ny, nz, curwid + 1 ) ;
05025                                                                         queue2->prepend( nx, ny, nz ) ;
05026                                                                         numComplex ++ ;
05027                                                                 }
05028                                                         }
05029                                         */
05030 
05031                                         // Update scores for nodes in its 5x5 neighborhood
05032                                         // insert them back into priority queue
05033 
05034                                         for ( i = -2 ; i < 3 ;i ++ )
05035                                                 for ( j = -2 ; j < 3 ; j ++ )
05036                                                         for ( k = -2 ; k < 3 ; k ++ )
05037                                                         {
05038                                                                 int nx = ox + i ;
05039                                                                 int ny = oy + j ;
05040                                                                 int nz = oz + k ;
05041 
05042                                                                 if ( getDataAt( nx, ny, nz ) == curwid )
05043                                                                 {
05044                                                                         // Compute score
05045                                                                         score = getNumPotComplex2( nx, ny, nz ) ;
05046                                                                         //score = getNumNeighbor6( nx, ny, nz ) ;
05047 
05048                                                                         if ( score != (int) scrvol->getDataAt( nx, ny, nz ) )
05049                                                                         {
05050                                                                                 // printf("Update\n") ;
05051                                                                                 scrvol->setDataAt( nx, ny, nz, score ) ;
05052                                                                                 // Push to queue
05053                                                                                 gp = new gridPoint ;
05054                                                                                 gp->x = nx ;
05055                                                                                 gp->y = ny ;
05056                                                                                 gp->z = nz ;
05057                                                                                 // queue->add( gp, -score ) ;
05058                                                                                 queue->add( gp, score ) ;
05059                                                                         }
05060                                                                 }
05061                                                         }
05062 
05063 
05064                                 }
05065 
05066                                 #ifdef VERBOSE
05067                                 printf("%d complex, %d simple\n", numComplex, numSimple) ;
05068                                 #endif
05069 
05070                                 if ( numSimple == 0 )
05071                                 {
05072                                                 break ;
05073                                 }
05074                         }
05075 
05076                         // Finally, clean up
05077                         #ifdef VERBOSE
05078                         printf("Thresholding the volume to 0/1...\n") ;
05079                         #endif
05080                         threshold( 0, 0, 1 ) ;
05081                         delete scrvol;
05082                         delete queue;
05083                         delete queue2;
05084                         delete queue3;
05085                         delete queue4;
05086                 }
05087 
05088                 // Compute minimal skeleton
05089                 void Volume::skeleton( float thr, int )
05090                 {
05091                         int i, j, k ;
05092                         // First, threshold the volume
05093                         #ifdef VERBOSE
05094                         printf("Thresholding the volume to -1/0...\n") ;
05095                         #endif
05096                         threshold( thr, -1, 0 ) ;
05097 
05098                         // Next, apply convergent erosion
05099                         // by preserving: complex nodes, curve end-points, and sheet points
05100 
05101                         // Next, initialize the linked queue
05102                         #ifdef VERBOSE
05103                         printf("Initializing queue...\n") ;
05104                         #endif
05105                         GridQueue2* queue2 = new GridQueue2( ) ;
05106                         GridQueue2* queue = new GridQueue2( ) ;
05107 
05108                         for ( i = 0 ; i < getSizeX() ; i ++ )
05109                                 for ( j = 0 ; j < getSizeY() ; j ++ )
05110                                         for ( k = 0 ; k < getSizeZ() ; k ++ )
05111                                         {
05112                                                 if ( getDataAt( i, j, k ) >= 0 )
05113                                                 {
05114                                                         {
05115                                                                 for ( int m = 0 ; m < 6 ; m ++ )
05116                                                                 {
05117                                                                         if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
05118                                                                         {
05119                                                                                 setDataAt( i, j, k, 1 ) ;
05120                                                                                 queue2->prepend( i, j, k ) ;
05121                                                                                 break ;
05122                                                                         }
05123                                                                 }
05124                                                         }
05125                                                 }
05126                                         }
05127                         int wid = 0 ;
05128                         #ifdef VERBOSE
05129                         printf("Total %d nodes\n", queue2->getNumElements() ) ;
05130                         printf("Start erosion to %d...\n", wid) ;
05131                         #endif
05132 
05133                         // Perform erosion
05134                         gridQueueEle* ele ;
05135                         int ox, oy, oz ;
05136 
05137                         while( 1 )
05138                         {
05139                                 wid ++ ;
05140 
05141                                 // At the start of each iteration,
05142                                 // queue2 holds all the nodes for this layer
05143                                 // queue is empty
05144 
05145                                 int numComplex = 0, numSimple = 0 ;
05146                                 #ifdef VERBOSE
05147                                 printf("Processing %d nodes in layer %d\n", queue2->getNumElements(), wid) ;
05148                                 #endif
05149 
05150                                 // Rename queue2 to be queue,
05151                                 // Clear queue2
05152                                 // From now on, queue2 holds nodes of next level
05153                                 delete queue ;
05154                                 queue = queue2 ;
05155                                 queue2 = new GridQueue2( ) ;
05156 
05157                                 // Next, start queue iteration
05158                                 queue->reset() ;
05159                                 ele = queue->getNext();
05160                                 while ( ele != NULL )
05161                                 {
05162                                         ox = ele->x ;
05163                                         oy = ele->y ;
05164                                         oz = ele->z ;
05165         //                              delete ele ;
05166 
05167                                         // Check simple
05168                                         if ( ! isSimple( ox, oy, oz ) )
05169                                         {
05170                                                 // Complex, set to next layer
05171                                                 queue2->prepend( ox, oy, oz ) ;
05172                                                 numComplex ++ ;
05173                                         }
05174                                         /*
05175                                         else if ( ox == off || oy == off || oz == off ||
05176                                                 ox == getSizeX() - off - 1 || oy == getSizeY() - off - 1 || oz == getSizeZ() - off - 1 )
05177                                         {
05178                                                 // Wall, don't erode, set to next layer
05179                                                 queue2->prepend( ox, oy, oz ) ;
05180                                                 numComplex ++ ;
05181                                         }
05182                                         */
05183                                         else
05184                                         {
05185                                                 setDataAt( ox, oy, oz, -1 ) ;
05186                                                 numSimple ++ ;
05187 
05188                                                 for ( int m = 0 ; m < 6 ; m ++ )
05189                                                 {
05190                                                         int nx = ox + neighbor6[m][0] ;
05191                                                         int ny = oy + neighbor6[m][1] ;
05192                                                         int nz = oz + neighbor6[m][2] ;
05193                                                         if ( getDataAt( nx, ny, nz ) == 0 )
05194                                                         {
05195                                                                 setDataAt( nx, ny, nz, 1 ) ;
05196                                                                 queue2->prepend( nx, ny, nz ) ;
05197                                                         }
05198                                                 }
05199 
05200                                         }
05201 
05202                                         ele = queue->remove() ;
05203                                 }
05204                                 #ifdef VERBOSE
05205                                 printf("Level %d: %d complex, %d simple\n", wid, numComplex, numSimple) ;
05206                                 #endif
05207 
05208                                 if ( numSimple == 0 )
05209                                 {
05210                                         break ;
05211                                 }
05212                         }
05213 
05214                         // Finally, clean up
05215                         delete queue;
05216                         delete queue2;
05217                         #ifdef VERBOSE
05218                         printf("Thresholding the volume to 0/1...\n") ;
05219                         #endif
05220                         threshold( 0, 0, 1 ) ;
05221                 }
05222 
05224                 //void Volume::skeleton2( float thr, int off )
05225                 //{
05226                         //int i, j, k ;
05228                         //#ifdef VERBOSE
05229                         //printf("Thresholding the volume to -1/0...\n") ;
05230                         //#endif
05231                         //threshold( thr, -1, 0 ) ;
05232 
05235 
05237                         //#ifdef VERBOSE
05238                         //printf("Initializing queue...\n") ;
05239                         //#endif
05240                         //GridQueue2* queue2 = new GridQueue2( ) ;
05241                         //GridQueue2* queue3 = new GridQueue2( ) ;
05242                         //PriorityQueue <gridPoint,int> * queue = new PriorityQueue <gridPoint,int> ( MAX_QUEUELEN );
05243 
05244                         //for ( i = 0 ; i < getSizeX() ; i ++ )
05245                                 //for ( j = 0 ; j < getSizeY() ; j ++ )
05246                                         //for ( k = 0 ; k < getSizeZ() ; k ++ )
05247                                         //{
05248                                                 //if ( getDataAt( i, j, k ) >= 0 )
05249                                                 //{
05250                                                         //if ( i == off || j == off || k == off ||
05251                                                                  //i == getSizeX() - off - 1 || j == getSizeY() - off - 1 || k == getSizeZ() - off - 1 )
05252                                                         //{
05253                                                                 //setDataAt( i, j, k, MAX_ERODE ) ;
05254                                                         //}
05255                                                         //else
05256                                                         //{
05257                                                                 //for ( int m = 0 ; m < 6 ; m ++ )
05258                                                                 //{
05259                                                                         //if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
05260                                                                         //{
05261                                                                                 //setDataAt( i, j, k, 1 ) ;
05262                                                                                 //queue2->prepend( i, j, k ) ;
05263                                                                                 //break ;
05264                                                                         //}
05265                                                                 //}
05266                                                         //}
05267                                                 //}
05268                                         //}
05269                         //int wid = MAX_ERODE ;
05270                         //#ifdef VERBOSE
05271                         //printf("Total %d nodes\n", queue2->getNumElements() ) ;
05272 
05273 
05275                         //printf("Start erosion to %d...\n", wid) ;
05276                         //#endif
05277 
05278                         //gridQueueEle* ele ;
05279                         //gridPoint* gp ;
05280                         //int ox, oy, oz ;
05281                         //int score ;
05282 
05283                         //Volume* scrvol = new Volume( this->getSizeX() , this->getSizeY(), this->getSizeZ() ) ;
05284                         //for ( i = 0 ; i < getSizeX() * getSizeY() * getSizeZ() ; i ++ )
05285                         //{
05286                                 //scrvol->setDataAt( i, -1 ) ;
05287                         //}
05288 
05289 
05290                         //for ( int curwid = 1 ; curwid <= wid ; curwid ++ )
05291                         //{
05295 
05296                                 //int numComplex = 0, numSimple = 0 ;
05297                                 //#ifdef VERBOSE
05298                                 //printf("Processing %d nodes in layer %d\n", queue2->getNumElements(), curwid) ;
05299                                 //#endif
05300 
05304                                 //queue2->reset() ;
05305                                 //ele = queue2->getNext() ;
05306                                 //while ( ele != NULL )
05307                                 //{
05308                                         //ox = ele->x ;
05309                                         //oy = ele->y ;
05310                                         //oz = ele->z ;
05311 
05313                                         //score = getNumPotComplex2( ox, oy, oz ) ;
05314                                         //scrvol->setDataAt( ox, oy, oz, score ) ;
05315 
05317                                         //gp = new gridPoint ;
05318                                         //gp->x = ox ;
05319                                         //gp->y = oy ;
05320                                         //gp->z = oz ;
05322                                         //queue->add( gp, score ) ;
05323 
05324                                         //ele = queue2->remove() ;
05325                                 //}
05326 
05330                                 //delete queue2 ;
05331                                 //queue2 = queue3 ;
05332                                 //queue3 = new GridQueue2( ) ;
05333 
05335                                 //while ( ! queue->isEmpty() )
05336                                 //{
05338                                         //queue->remove( gp, score ) ;
05339                                         //ox = gp->x ;
05340                                         //oy = gp->y ;
05341                                         //oz = gp->z ;
05342                                         //delete gp ;
05344 
05348                                         //if ( getDataAt( ox, oy, oz ) != curwid || (int) scrvol->getDataAt( ox, oy, oz ) != score )
05349                                         //{
05350                                                 //continue ;
05351                                         //}
05352 
05355                                         //if ( ! isSimple( ox, oy, oz ) )
05356                                         //{
05358                                                 //setDataAt( ox, oy, oz, curwid + 1 ) ;
05359                                                 //queue2->prepend( ox, oy, oz ) ;
05360                                                 //numComplex ++ ;
05361                                         //}
05362                                         //else
05363                                         //{
05364                                                 //setDataAt( ox, oy, oz, -1 ) ;
05365                                                 //numSimple ++ ;
05366                                         //}
05368 
05370                                         //for ( int m = 0 ; m < 6 ; m ++ )
05371                                         //{
05372                                                 //int nx = ox + neighbor6[m][0] ;
05373                                                 //int ny = oy + neighbor6[m][1] ;
05374                                                 //int nz = oz + neighbor6[m][2] ;
05375                                                 //if ( getDataAt( nx, ny, nz ) == 0 )
05376                                                 //{
05377                                                         //setDataAt( nx, ny, nz, curwid + 1 ) ;
05378                                                         //queue2->prepend( nx, ny, nz ) ;
05379                                                 //}
05380                                         //}
05381 
05385                                         //for ( i = -2 ; i < 3 ;i ++ )
05386                                                 //for ( j = -2 ; j < 3 ; j ++ )
05387                                                         //for ( k = -2 ; k < 3 ; k ++ )
05388                                                         //{
05389                                                                 //int nx = ox + i ;
05390                                                                 //int ny = oy + j ;
05391                                                                 //int nz = oz + k ;
05392 
05393                                                                 //if ( getDataAt( nx, ny, nz ) == curwid )
05394                                                                 //{
05396                                                                         //score = getNumPotComplex2( nx, ny, nz ) ;
05397 
05398                                                                         //if ( score != (int) scrvol->getDataAt( nx, ny, nz ) )
05399                                                                         //{
05401                                                                                 //scrvol->setDataAt( nx, ny, nz, score ) ;
05403                                                                                 //gp = new gridPoint ;
05404                                                                                 //gp->x = nx ;
05405                                                                                 //gp->y = ny ;
05406                                                                                 //gp->z = nz ;
05408                                                                                 //queue->add( gp, score ) ;
05409                                                                         //}
05410                                                                 //}
05411                                                         //}
05412 
05413                                                 //*/
05414                                 //}
05415                                 //#ifdef VERBOSE
05416                                 //printf("%d complex, %d simple\n", numComplex, numSimple) ;
05417                                 //#endif
05418 
05419                                 //if ( numSimple == 0 )
05420                                 //{
05421                                                 //break ;
05422                                 //}
05423                         //}
05424 
05426                         //delete scrvol ;
05427                         //delete queue;
05428                         //#ifdef VERBOSE
05429                         //printf("Thresholding the volume to 0/1...\n") ;
05430                         //#endif
05431                         //threshold( 0, 0, 1 ) ;
05432                 //}
05433 
05435                 //*  Assuming the current volume has already been thresholded to 0/1
05436                 //*/
05437                 //void Volume::pointSkeleton( Volume* grayvol, float lowthr, float highthr, Volume* svol, Volume* hvol )
05438                 //{
05439                         //int i, j, k ;
05441                         //#ifdef VERBOSE
05442                         //printf("Thresholding the volume to -1/0...\n") ;
05443                         //#endif
05444                         //threshold( 0.5f, -1, 0 ) ;
05445 
05448 
05450                         //#ifdef VERBOSE
05451                         //printf("Initializing queue...\n") ;
05452                         //#endif
05453                         //GridQueue2* queue2 = new GridQueue2( ) ;
05454                         //GridQueue2* queue3 = new GridQueue2( ) ;
05455                         //PriorityQueue <gridPoint,int> * queue = new PriorityQueue <gridPoint,int> ( MAX_QUEUELEN );
05456 
05457                         //for ( i = 0 ; i < getSizeX() ; i ++ )
05458                                 //for ( j = 0 ; j < getSizeY() ; j ++ )
05459                                         //for ( k = 0 ; k < getSizeZ() ; k ++ )
05460                                         //{
05461                                                 //if ( getDataAt( i, j, k ) >= 0 )
05462                                                 //{
05463                                                         //float v = (float)grayvol->getDataAt( i, j, k ) ;
05464                                                         //if ( v <= lowthr || v > highthr || svol->getDataAt(i,j,k) > 0 || hvol->getDataAt(i,j,k) > 0 )
05465                                                         //{
05466                                                                 //setDataAt( i, j, k, MAX_ERODE ) ;
05467                                                         //}
05468                                                         //else
05469                                                         //{
05470                                                                 //for ( int m = 0 ; m < 6 ; m ++ )
05471                                                                 //{
05472                                                                         //if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
05473                                                                         //{
05474                                                                                 //setDataAt( i, j, k, 1 ) ;
05475                                                                                 //queue2->prepend( i, j, k ) ;
05476                                                                                 //break ;
05477                                                                         //}
05478                                                                 //}
05479                                                         //}
05480                                                 //}
05481                                         //}
05482                         //#ifdef VERBOSE
05483                         //printf("Total %d nodes\n", queue2->getNumElements() ) ;
05484                         //#endif
05485 
05486 
05488                         //int wid = MAX_ERODE ;
05489                         //#ifdef VERBOSE
05490                         //printf("Start erosion to %d...\n", wid) ;
05491                         //#endif
05492                         //gridQueueEle* ele ;
05493                         //gridPoint* gp ;
05494                         //int ox, oy, oz ;
05495                         //int score ;
05496                         //Volume* scrvol = new Volume( this->getSizeX() , this->getSizeY(), this->getSizeZ() ) ;
05497                         //for ( i = 0 ; i < getSizeX() * getSizeY() * getSizeZ() ; i ++ )
05498                         //{
05499                                 //scrvol->setDataAt( i, -1 ) ;
05500                         //}
05501 
05502 
05503                         //for ( int curwid = 1 ; curwid <= wid ; curwid ++ )
05504                         //{
05508 
05509                                 //int numComplex = 0, numSimple = 0 ;
05510                                 //#ifdef VERBOSE
05511                                 //printf("Processing %d nodes in layer %d\n", queue2->getNumElements(), curwid) ;
05512                                 //#endif
05513 
05514 
05518                                 //queue2->reset() ;
05519                                 //ele = queue2->getNext() ;
05520                                 //while ( ele != NULL )
05521                                 //{
05522                                         //ox = ele->x ;
05523                                         //oy = ele->y ;
05524                                         //oz = ele->z ;
05525 
05527                                         //score = getNumPotComplex2( ox, oy, oz ) ;
05528                                         //scrvol->setDataAt( ox, oy, oz, score ) ;
05529 
05531                                         //gp = new gridPoint ;
05532                                         //gp->x = ox ;
05533                                         //gp->y = oy ;
05534                                         //gp->z = oz ;
05536                                         //queue->add( gp, score ) ;
05537 
05538                                         //ele = queue2->remove() ;
05539                                 //}
05540 
05544                                 //delete queue2 ;
05545                                 //queue2 = queue3 ;
05546                                 //queue3 = new GridQueue2( ) ;
05547 
05549                                 //while ( ! queue->isEmpty() )
05550                                 //{
05552                                         //queue->remove( gp, score ) ;
05553                                         //ox = gp->x ;
05554                                         //oy = gp->y ;
05555                                         //oz = gp->z ;
05556                                         //delete gp ;
05558 
05562                                         //if ( getDataAt( ox, oy, oz ) != curwid || (int) scrvol->getDataAt( ox, oy, oz ) != score )
05563                                         //{
05564                                                 //continue ;
05565                                         //}
05566 
05569                                         //if ( ! isSimple( ox, oy, oz ) )
05570                                         //{
05572                                                 //setDataAt( ox, oy, oz, curwid + 1 ) ;
05573                                                 //queue2->prepend( ox, oy, oz ) ;
05574                                                 //numComplex ++ ;
05575                                         //}
05576                                         //else
05577                                         //{
05578                                                 //setDataAt( ox, oy, oz, -1 ) ;
05579                                                 //numSimple ++ ;
05581 
05583                                                 //for ( int m = 0 ; m < 6 ; m ++ )
05584                                                 //{
05585                                                         //int nx = ox + neighbor6[m][0] ;
05586                                                         //int ny = oy + neighbor6[m][1] ;
05587                                                         //int nz = oz + neighbor6[m][2] ;
05588                                                         //if ( getDataAt( nx, ny, nz ) == 0 )
05589                                                         //{
05590                                                                 //setDataAt( nx, ny, nz, curwid + 1 ) ;
05591                                                                 //queue2->prepend( nx, ny, nz ) ;
05592                                                         //}
05593                                                 //}
05594 
05595                                         //}
05596 
05599 
05600                                         //for ( i = -2 ; i < 3 ;i ++ )
05601                                                 //for ( j = -2 ; j < 3 ; j ++ )
05602                                                         //for ( k = -2 ; k < 3 ; k ++ )
05603                                                         //{
05604                                                                 //int nx = ox + i ;
05605                                                                 //int ny = oy + j ;
05606                                                                 //int nz = oz + k ;
05607 
05608                                                                 //if ( getDataAt( nx, ny, nz ) == curwid )
05609                                                                 //{
05611                                                                         //score = getNumPotComplex2( nx, ny, nz ) ;
05612 
05613                                                                         //if ( score != (int) scrvol->getDataAt( nx, ny, nz ) )
05614                                                                         //{
05616                                                                                 //scrvol->setDataAt( nx, ny, nz, score ) ;
05618                                                                                 //gp = new gridPoint ;
05619                                                                                 //gp->x = nx ;
05620                                                                                 //gp->y = ny ;
05621                                                                                 //gp->z = nz ;
05623                                                                                 //queue->add( gp, score ) ;
05624                                                                         //}
05625                                                                 //}
05626                                                         //}
05627 
05628 
05629                                 //}
05630                                 //#ifdef VERBOSE
05631                                 //printf("%d complex, %d simple\n", numComplex, numSimple) ;
05632                                 //#endif
05633 
05634                                 //if ( numSimple == 0 )
05635                                 //{
05636                                                 //break ;
05637                                 //}
05638                         //}
05639 
05641                         //queue2->reset() ;
05642                         //ele = queue2->getNext() ;
05643                         //while ( ele != NULL )
05644                         //{
05645                                 //ox = ele->x ;
05646                                 //oy = ele->y ;
05647                                 //oz = ele->z ;
05648 
05649                                 //if ( hasCompleteHelix( ox, oy, oz ) == 1 )
05650                                 //{
05651                                         //ele = queue2->getNext() ;
05652                                 //}
05653                                 //else
05654                                 //{
05655                                         //ele = queue2->remove() ;
05656                                 //}
05657                         //}
05658 
05659                         //for ( i = 0 ; i < getSizeX() ; i ++ )
05660                                 //for ( j = 0 ; j < getSizeY() ; j ++ )
05661                                         //for ( k = 0 ; k < getSizeZ() ; k ++ )
05662                                         //{
05663                                                 //if ( getDataAt( i, j, k ) == 0 && hasCompleteHelix(i,j,k) == 1)
05664                                                 //{
05665                                                         //queue2->prepend( i, j, k ) ;
05666                                                 //}
05667                                         //}
05668                         //queue2->reset() ;
05669                         //ele = queue2->getNext() ;
05670                         //while ( ele != NULL )
05671                         //{
05672                                 //ox = ele->x ;
05673                                 //oy = ele->y ;
05674                                 //oz = ele->z ;
05675                                 //setDataAt( ox, oy, oz, -1 ) ;
05676                                 //ele = queue2->remove() ;
05677                         //}
05678 
05680                         //delete scrvol;
05681                         //delete queue;
05682                         //delete queue2;
05683                         //delete queue3;
05684                         //#ifdef VERBOSE
05685                         //printf("Thresholding the volume to 0/1...\n") ;
05686                         //#endif
05687                         //threshold( 0, 0, 1 ) ;
05688                 //}
05689 
05690 
05691                 // Compute minimal skeleton
05692                 void Volume::skeleton( float thr, Volume* svol, Volume* hvol )
05693                 {
05694                         int i, j, k ;
05695                         // First, threshold the volume
05696                         #ifdef VERBOSE
05697                         printf("Thresholding the volume to -1/0...\n") ;
05698                         #endif
05699                         threshold( thr, -1, 0 ) ;
05700 
05701                         // Next, apply convergent erosion
05702                         // by preserving: complex nodes, curve end-points, and sheet points
05703 
05704                         // Next, initialize the linked queue
05705                         #ifdef VERBOSE
05706                         printf("Initializing queue...\n") ;
05707                         #endif
05708                         GridQueue2* queue2 = new GridQueue2( ) ;
05709                         GridQueue2* queue3 = new GridQueue2( ) ;
05710                         PriorityQueue <gridPoint,int> * queue = new PriorityQueue <gridPoint,int> ( MAX_QUEUELEN );
05711 
05712                         for ( i = 0 ; i < getSizeX() ; i ++ )
05713                                 for ( j = 0 ; j < getSizeY() ; j ++ )
05714                                         for ( k = 0 ; k < getSizeZ() ; k ++ )
05715                                         {
05716                                                 if ( getDataAt( i, j, k ) >= 0 )
05717                                                 {
05718                                                         if ( svol->getDataAt(i,j,k) > 0 || hvol->getDataAt(i,j,k) > 0 )
05719                                                         {
05720                                                                 setDataAt( i, j, k, MAX_ERODE ) ;
05721                                                         }
05722                                                         else
05723                                                         {
05724                                                                 for ( int m = 0 ; m < 6 ; m ++ )
05725                                                                 {
05726                                                                         if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
05727                                                                         {
05728                                                                                 setDataAt( i, j, k, 1 ) ;
05729                                                                                 queue2->prepend( i, j, k ) ;
05730                                                                                 break ;
05731                                                                         }
05732                                                                 }
05733                                                         }
05734                                                 }
05735                                         }
05736                         int wid = MAX_ERODE ;
05737                         #ifdef VERBOSE
05738                         printf("Total %d nodes\n", queue2->getNumElements() ) ;
05739 
05740 
05741                         // Perform erosion
05742                         printf("Start erosion to %d...\n", wid) ;
05743                         #endif
05744                         gridQueueEle* ele ;
05745                         gridPoint* gp ;
05746                         int ox, oy, oz ;
05747                         int score ;
05748                         Volume* scrvol = new Volume( this->getSizeX() , this->getSizeY(), this->getSizeZ() ) ;
05749                         for ( i = 0 ; i < getSizeX() * getSizeY() * getSizeZ() ; i ++ )
05750                         {
05751                                 scrvol->setDataAt( i, -1 ) ;
05752                         }
05753 
05754 
05755                         for ( int curwid = 1 ; curwid <= wid ; curwid ++ )
05756                         {
05757                                 // At the start of each iteration,
05758                                 // queue2 holds all the nodes for this layer
05759                                 // queue3 and queue are empty
05760 
05761                                 int numComplex = 0, numSimple = 0 ;
05762                                 #ifdef VERBOSE
05763                                 printf("Processing %d nodes in layer %d\n", queue2->getNumElements(), curwid) ;
05764                                 #endif
05765 
05766 
05767                                 // Next,
05768                                 // Compute score for each node left in queue2
05769                                 // move them into priority queue
05770                                 queue2->reset() ;
05771                                 ele = queue2->getNext() ;
05772                                 while ( ele != NULL )
05773                                 {
05774                                         ox = ele->x ;
05775                                         oy = ele->y ;
05776                                         oz = ele->z ;
05777 
05778                                         // Compute score
05779                                         score = getNumPotComplex2( ox, oy, oz ) ;
05780                                         scrvol->setDataAt( ox, oy, oz, score ) ;
05781 
05782                                         // Push to queue
05783                                         gp = new gridPoint ;
05784                                         gp->x = ox ;
05785                                         gp->y = oy ;
05786                                         gp->z = oz ;
05787                                         // queue->add( gp, -score ) ;
05788                                         queue->add( gp, score ) ;
05789 
05790                                         ele = queue2->remove() ;
05791                                 }
05792 
05793                                 // Rename queue3 to be queue2,
05794                                 // Clear queue3
05795                                 // From now on, queue2 holds nodes of next level
05796                                 delete queue2 ;
05797                                 queue2 = queue3 ;
05798                                 queue3 = new GridQueue2( ) ;
05799 
05800                                 // Next, start priority queue iteration
05801                                 while ( ! queue->isEmpty() )
05802                                 {
05803                                         // Retrieve the node with the highest score
05804                                         queue->remove( gp, score ) ;
05805                                         ox = gp->x ;
05806                                         oy = gp->y ;
05807                                         oz = gp->z ;
05808                                         delete gp ;
05809         //                              score = -score ;
05810 
05811                                         // Ignore the node
05812                                         // if it has been processed before
05813                                         // or it has an updated score
05814                                         if ( getDataAt( ox, oy, oz ) != curwid || (int) scrvol->getDataAt( ox, oy, oz ) != score )
05815                                         {
05816                                                 continue ;
05817                                         }
05818 
05819                                         /* Added for debugging */
05820                                         // Check simple
05821                                         if ( ! isSimple( ox, oy, oz ) )
05822                                         {
05823                                                 // Complex, set to next layer
05824                                                 setDataAt( ox, oy, oz, curwid + 1 ) ;
05825                                                 queue2->prepend( ox, oy, oz ) ;
05826                                                 numComplex ++ ;
05827                                         }
05828                                         else
05829                                         {
05830                                                 setDataAt( ox, oy, oz, -1 ) ;
05831                                                 numSimple ++ ;
05832                                         }
05833                                         /* Adding ends */
05834 
05835                                         // Move its neighboring unvisited node to queue2
05836                                         for ( int m = 0 ; m < 6 ; m ++ )
05837                                         {
05838                                                 int nx = ox + neighbor6[m][0] ;
05839                                                 int ny = oy + neighbor6[m][1] ;
05840                                                 int nz = oz + neighbor6[m][2] ;
05841                                                 if ( getDataAt( nx, ny, nz ) == 0 )
05842                                                 {
05843                                                         setDataAt( nx, ny, nz, curwid + 1 ) ;
05844                                                         queue2->prepend( nx, ny, nz ) ;
05845                                                 }
05846                                         }
05847 
05848                                         // Update scores for nodes in its 5x5 neighborhood
05849                                         // insert them back into priority queue
05850 
05851                                         for ( i = -2 ; i < 3 ;i ++ )
05852                                                 for ( j = -2 ; j < 3 ; j ++ )
05853                                                         for ( k = -2 ; k < 3 ; k ++ )
05854                                                         {
05855                                                                 int nx = ox + i ;
05856                                                                 int ny = oy + j ;
05857                                                                 int nz = oz + k ;
05858 
05859                                                                 if ( getDataAt( nx, ny, nz ) == curwid )
05860                                                                 {
05861                                                                         // Compute score
05862                                                                         score = getNumPotComplex2( nx, ny, nz ) ;
05863 
05864                                                                         if ( score != (int) scrvol->getDataAt( nx, ny, nz ) )
05865                                                                         {
05866                                                                                 // printf("Update\n") ;
05867                                                                                 scrvol->setDataAt( nx, ny, nz, score ) ;
05868                                                                                 // Push to queue
05869                                                                                 gp = new gridPoint ;
05870                                                                                 gp->x = nx ;
05871                                                                                 gp->y = ny ;
05872                                                                                 gp->z = nz ;
05873                                                                                 // queue->add( gp, -score ) ;
05874                                                                                 queue->add( gp, score ) ;
05875                                                                         }
05876                                                                 }
05877                                                         }
05878 
05879 
05880                                 }
05881 
05882                                 #ifdef VERBOSE
05883                                 printf("%d complex, %d simple\n", numComplex, numSimple) ;
05884                                 #endif
05885 
05886                                 if ( numSimple == 0 )
05887                                 {
05888                                         delete queue2 ;
05889                                         break ;
05890                                 }
05891                         }
05892 
05893                         // Finally, clean up
05894                         #ifdef VERBOSE
05895                         printf("Thresholding the volume to 0/1...\n") ;
05896                         #endif
05897                         threshold( 0, 0, 1 ) ;
05898                         delete scrvol;
05899                         delete queue;
05900                         delete queue3;
05901                 }
05902 
05903 
05904                 // Apply helix erosion
05905                 void Volume::erodeHelix( )
05906                 {
05907                         erodeHelix( 3 ) ;
05908                 }
05909 
05910 
05911                 void Volume::erodeHelix( int disthr )
05912                 {
05913                         int i, j, k ;
05914                         // First, threshold the volume
05915                         //printf("Thresholding the volume to -1/0...\n") ;
05916                         threshold( 0.1f, -1, 0 ) ;
05917 
05918                         /* Debug: remove faces */
05919                         //Volume* facevol = markFaceEdge() ;
05920                         /* End debugging */
05921 
05922                         // Next, initialize the linked queue
05923                         //printf("Initializing queue...\n") ;
05924                         Volume * fvol = new Volume( getSizeX(), getSizeY(), getSizeZ() ) ;
05925                         GridQueue2* queue2 = new GridQueue2( ) ;
05926                         GridQueue2* queue3 = new GridQueue2( ) ;
05927                         GridQueue2** queues = new GridQueue2* [ 10000 ] ;
05928 
05929                         for ( i = 0 ; i < getSizeX() ; i ++ )
05930                                 for ( j = 0 ; j < getSizeY() ; j ++ )
05931                                         for ( k = 0 ; k < getSizeZ() ; k ++ )
05932                                         {
05933                                                 if ( getDataAt( i, j, k ) >= 0 )
05934                                                 {
05935                                                         if ( ! hasCompleteHelix( i, j, k ) )
05936                                                         // if ( ! hasCompleteHelix( i, j, k, facevol ) )
05937                                                         {
05938                                                                 queue2->prepend( i, j, k ) ;
05939                                                                 fvol->setDataAt( i, j, k, -1 ) ;
05940                                                         }
05941                                                 }
05942                                         }
05943                         //printf("Total %d nodes\n", queue2->getNumElements() ) ;
05944 
05945                         // Start erosion
05946                         gridQueueEle* ele ;
05947                         int dis = -1 ;
05948                         while ( queue2->getNumElements() > 0 )
05949                         {
05950                                 // First, set distance
05951                                 dis -- ;
05952                                 queues[ - dis ] = new GridQueue2( ) ;
05953                                 //printf("Distance transform to %d...", dis) ;
05954                                 queue2->reset() ;
05955                                 while( ( ele = queue2->getNext() ) != NULL )
05956                                 {
05957                                         setDataAt( ele->x, ele->y, ele->z, dis ) ;
05958                                         queues[ -dis ]->prepend( ele->x, ele->y, ele->z ) ;
05959                                 }
05960                                 //printf("%d nodes\n", queues[-dis]->getNumElements()) ;
05961 
05962                                 // Next, find next layer
05963                                 queue2->reset() ;
05964                                 ele = queue2->getNext() ;
05965                                 while ( ele != NULL )
05966                                 {
05967                                         for ( int m = 0 ; m < 6 ; m ++ )
05968                                         {
05969                                                 int nx = ele->x + neighbor6[m][0] ;
05970                                                 int ny = ele->y + neighbor6[m][1] ;
05971                                                 int nz = ele->z + neighbor6[m][2] ;
05972                                                 if ( getDataAt( nx, ny, nz ) == 0 )
05973                                                 {
05974                                                         fvol->setDataAt( nx, ny, nz, dis ) ;
05975 
05976                                                         if ( ! hasCompleteHelix( nx, ny, nz ) )
05977                                                         // if ( ! hasCompleteHelix( nx, ny, nz, facevol ) )
05978                                                         {
05979                                                                 setDataAt( nx, ny, nz, 1 ) ;
05980                                                                 queue3->prepend( nx, ny, nz ) ;
05981                                                         }
05982                                                 }
05983                                         }
05984 
05985                                         ele = queue2->remove() ;
05986                                 }
05987 
05988                                 // Next, swap queues
05989                                 GridQueue2* temp = queue2 ;
05990                                 queue2 = queue3 ;
05991                                 queue3 = temp ;
05992                         }
05993 
05994                         // Deal with closed rings
05995                         dis -- ;
05996                         queues[ - dis ] = new GridQueue2( ) ;
05997                         #ifdef VERBOSE
05998                         printf("Detecting closed rings %d...", dis) ;
05999                         #endif
06000                         int ftot = 0 ;
06001                         for ( i = 0 ; i < getSizeX() ; i ++ )
06002                                 for ( j = 0 ; j < getSizeY() ; j ++ )
06003                                         for ( k = 0 ; k < getSizeZ() ; k ++ )
06004                                         {
06005                                                 if ( getDataAt( i, j, k ) == 0 )
06006                                                 {
06007                                                         setDataAt( i, j, k, dis ) ;
06008                                                         queues[ -dis ]->prepend( i, j, k ) ;
06009         /*
06010                                                         int fval = (int) fvol->getDataAt( i, j, k ) ;
06011                                                         if ( fval == 0)
06012                                                         {
06013                                                                 // queues[ -dis ]->prepend( i, j, k ) ;
06014                                                         }
06015                                                         else
06016                                                         {
06017                                                                 setDataAt( i, j, k, fval - 1 ) ;
06018                                                                 // queues[ -fval + 1 ]->prepend( i, j, k ) ;
06019                                                         }
06020         */
06021                                                         ftot ++ ;
06022                                                 }
06023                                         }
06024                         #ifdef VERBOSE
06025                         printf("%d nodes\n", ftot) ;
06026                         #endif
06027 
06028 
06029                         // return ;
06030 
06031                         /* Find local minimum: to help determine erosion level
06032                         int cts[ 64 ] ;
06033                         for ( i = 0 ; i <= - dis ; i ++ )
06034                         {
06035                                 cts[ i ] = 0 ;
06036                         }
06037                         for ( i = 0 ; i < getSizeX() ; i ++ )
06038                                 for ( j = 0 ; j < getSizeY() ; j ++ )
06039                                         for ( k = 0 ; k < getSizeZ() ; k ++ )
06040                                         {
06041                                                 double val = getDataAt( i, j, k ) ;
06042                                                 if ( val < -1 )
06043                                                 {
06044                                                         int min = 1 ;
06045                                                         for ( int m = 0 ; m < 6 ; m ++ )
06046                                                         {
06047                                                                 int nx = i + neighbor6[m][0] ;
06048                                                                 int ny = j + neighbor6[m][1] ;
06049                                                                 int nz = k + neighbor6[m][2] ;
06050                                                                 if ( getDataAt( nx, ny, nz ) < val )
06051                                                                 {
06052                                                                         min = 0 ;
06053                                                                         break ;
06054                                                                 }
06055                                                         }
06056 
06057                                                         if ( min )
06058                                                         {
06059                                                                 cts[ (int) - val ] ++ ;
06060                                                         }
06061                                                 }
06062                                         }
06063 
06064                         for ( i = 2 ; i <= - dis ; i ++ )
06065                         {
06066                                 printf("Local minima: %d with %d nodes.\n", -i, cts[ i ] ) ;
06067                         }
06068                         */
06069 
06070                         // Dilate back
06071                         // Starting from nodes with distance - 2 - disthr
06072 
06073                         if ( disthr + 2 > - dis )
06074                         {
06075                                 disthr = - dis - 2 ;
06076                         }
06077                         int d;
06078 
06079                         for ( d = - dis ; d > disthr + 1 ; d -- )
06080                         {
06081                                 queues[ d ]->reset() ;
06082                                 while ( (ele = queues[ d ]->getNext() ) != NULL )
06083                                 {
06084                                         setDataAt( ele->x, ele->y, ele->z, d ) ;
06085                                 }
06086                         }
06087 
06088 
06089                         for ( d = disthr + 1 ; d >= 2 ; d -- )
06090                         {
06091                                 //delete queue3 ;
06092                                 //queue3 = new GridQueue2( ) ;
06093                                 queues[ d ]->reset() ;
06094                                 ele = queues[ d ]->getNext() ;
06095                                 while ( ele != NULL )
06096                                 {
06097                                         int dilatable = 0 ;
06098                                         for ( int m = 0 ; m < 6 ; m ++ )
06099                                                         {
06100                                                                 int nx = ele->x + neighbor6[m][0] ;
06101                                                                 int ny = ele->y + neighbor6[m][1] ;
06102                                                                 int nz = ele->z + neighbor6[m][2] ;
06103                                                                 if ( getDataAt( nx, ny, nz ) == d + 1 )
06104                                                                 {
06105                                                                         dilatable = 1 ;
06106                                                                         break ;
06107                                                                 }
06108                                                         }
06109 
06110 
06111                                         if ( ! dilatable )
06112                                         {
06113                                                 /*
06114                                                 setDataAt( ele->x, ele->y, ele->z, - 1 ) ;
06115                                                 */
06116 
06117                                                 setDataAt( ele->x, ele->y, ele->z, - d + 1 ) ;
06118                                                 if ( d > 2 )
06119                                                 {
06120                                                         queues[ d - 1 ]->prepend( ele->x, ele->y, ele->z ) ;
06121                                                 }
06122                                                 ele = queues[ d ]->remove() ;
06123                                         }
06124                                         else
06125                                         {
06126                                                 setDataAt( ele->x, ele->y, ele->z, d ) ;
06127                                                 ele = queues[ d ]->getNext() ;
06128                                         }
06129 
06130                                 }
06131 
06132                                 /* Debug: extract minimal set */
06133                                 while ( 1 )
06134                                 {
06135                                         int num = 0 ;
06136                                         queues[ d ]->reset() ;
06137                                         ele = queues[ d ]->getNext() ;
06138                                         while ( ele != NULL )
06139                                         {
06140                                                 int critical = 0 ;
06141                                                 setDataAt( ele->x, ele->y, ele->z, -1 ) ;
06142 
06143                                                 for ( i = -1 ; i < 2 ; i ++ )
06144                                                 {
06145                                                         for ( j = -1 ; j < 2 ; j ++ )
06146                                                         {
06147                                                                 for ( k = -1 ; k < 2 ; k ++ )
06148                                                                 {
06149                                                                         if ( i != 0 && j != 0 && k != 0 )
06150                                                                         {
06151                                                                                 continue ;
06152                                                                         }
06153                                                                         int nx = ele->x + i ;
06154                                                                         int ny = ele->y + j ;
06155                                                                         int nz = ele->z + k ;
06156                                                                         if ( getDataAt(nx,ny,nz) == d + 1 && !hasCompleteHelix( nx,ny,nz ) ) //, facevol ) )
06157                                                                         {
06158                                                                                 critical = 1 ;
06159                                                                                 break ;
06160                                                                         }
06161                                                                 }
06162                                                                 if ( critical )
06163                                                                 {
06164                                                                         break ;
06165                                                                 }
06166                                                         }
06167                                                         if ( critical )
06168                                                         {
06169                                                                 break ;
06170                                                         }
06171                                                 }
06172 
06173                                                 if ( critical )
06174                                                 {
06175                                                         setDataAt( ele->x, ele->y, ele->z, d ) ;
06176                                                         ele = queues[ d ]->getNext() ;
06177                                                 }
06178                                                 else
06179                                                 {
06180                                                         setDataAt( ele->x, ele->y, ele->z, - d + 1 ) ;
06181                                                         if ( d > 2 )
06182                                                         {
06183                                                                 queues[ d - 1 ]->prepend( ele->x, ele->y, ele->z ) ;
06184                                                         }
06185                                                         ele = queues[ d ]->remove() ;
06186                                                         num ++ ;
06187                                                 }
06188 
06189                                         }
06190 
06191                                         #ifdef VERBOSE
06192                                         printf("Non-minimal: %d\n", num) ;
06193                                         #endif
06194 
06195                                         if ( num == 0 )
06196                                         {
06197                                                 break ;
06198                                         }
06199                                 }
06200 
06201 
06202                                 /* End of debugging */
06203 
06204                                 /*
06205                                 queue3->reset() ;
06206                                 ele = queue3->getNext() ;
06207                                 while ( ele != NULL )
06208                                 {
06209                                         setDataAt( ele->x, ele->y, ele->z, - 1 ) ;
06210                                         ele = queue3->remove() ;
06211                                 }
06212                                 */
06213                         }
06214 
06215                         // Finally, threshold the volume
06216                         #ifdef VERBOSE
06217                         //printf("Thresholding the volume to 0/1...\n") ;
06218                         #endif
06219                         //threshold( -1, 1, 0, 0 ) ;
06220                         threshold( 0, 0, 1 ) ;
06221                         delete fvol ;
06222                         delete queue2;
06223                         delete queue3;
06224                         for ( d = -dis ; d >= 2 ; d -- ) {
06225                                 delete queues[d];
06226                         }
06227                         delete [] queues;
06228 
06229                 }
06230 
06231 
06232 
06233                 // Apply sheet erosion
06234                 int Volume::erodeSheet( )
06235                 {
06236                         return erodeSheet( 3 ) ;
06237                 }
06238 
06239 
06240                 int Volume::erodeSheet( int disthr )
06241                 {
06242                         int i, j, k ;
06243                         // First, threshold the volume
06244                         //printf("Thresholding the volume to -1/0...\n") ;
06245                         threshold( 0.1f, -1, 0 ) ;
06246 
06247                         /* Debug: remove cells */
06248                         Volume* facevol = markCellFace() ;
06249                         /* End debugging */
06250 
06251                         // Next, initialize the linked queue
06252                         //printf("Initializing queue...\n") ;
06253                         Volume * fvol = new Volume( getSizeX(), getSizeY(), getSizeZ() ) ;
06254                         GridQueue2* queue2 = new GridQueue2( ) ;
06255                         GridQueue2* queue3 = new GridQueue2( ) ;
06256                         GridQueue2** queues = new GridQueue2* [ 10000 ] ;
06257 
06258                         for ( i = 0 ; i < getSizeX() ; i ++ )
06259                                 for ( j = 0 ; j < getSizeY() ; j ++ )
06260                                         for ( k = 0 ; k < getSizeZ() ; k ++ )
06261                                         {
06262                                                 if ( getDataAt( i, j, k ) >= 0 )
06263                                                 {
06264                                                         if ( ! hasCompleteSheet( i, j, k ) )
06265                                                         //if ( ! hasCompleteSheet( i, j, k, facevol ) )
06266                                                         {
06267                                                                 queue2->prepend( i, j, k ) ;
06268                                                                 fvol->setDataAt( i, j, k, -1 ) ;
06269                                                         }
06270                                                 }
06271                                         }
06272                         #ifdef VERBOSE
06273                         printf("Total %d nodes\n", queue2->getNumElements() ) ;
06274                         #endif
06275 
06276                         // Start erosion
06277                         gridQueueEle* ele ;
06278                         int dis = -1 ;
06279                         while ( queue2->getNumElements() > 0 )
06280                         {
06281                                 // First, set distance
06282                                 dis -- ;
06283                                 queues[ - dis ] = new GridQueue2( ) ;
06284                                 //printf("Distance transform to %d...", dis) ;
06285                                 queue2->reset() ;
06286                                 while( ( ele = queue2->getNext() ) != NULL )
06287                                 {
06288                                         setDataAt( ele->x, ele->y, ele->z, dis ) ;
06289                                         queues[ -dis ]->prepend( ele->x, ele->y, ele->z ) ;
06290                                 }
06291                                 //printf("%d nodes\n", queues[-dis]->getNumElements()) ;
06292 
06293                                 // Next, find next layer
06294                                 queue2->reset() ;
06295                                 ele = queue2->getNext() ;
06296                                 while ( ele != NULL )
06297                                 {
06298                                         // for ( int m = 0 ; m < 6 ; m ++ )
06299                                         for ( int mx = -1 ; mx < 2 ; mx ++ )
06300                                                 for ( int my = -1 ; my < 2 ; my ++ )
06301                                                         for ( int mz = -1 ; mz < 2 ; mz ++ )
06302                                                         {
06303                                                                 if ( mx != 0 && my != 0 && mz != 0 )
06304                                                                 {
06305                                                                         continue ;
06306                                                                 }
06307                                                                 //int nx = ele->x + neighbor6[m][0] ;
06308                                                                 //int ny = ele->y + neighbor6[m][1] ;
06309                                                                 //int nz = ele->z + neighbor6[m][2] ;
06310                                                                 int nx = ele->x + mx ;
06311                                                                 int ny = ele->y + my ;
06312                                                                 int nz = ele->z + mz ;
06313 
06314                                                                 if ( getDataAt( nx, ny, nz ) == 0 )
06315                                                                 {
06316                                                                         fvol->setDataAt( nx, ny, nz, dis ) ;
06317 
06318                                                                         if  ( ! hasCompleteSheet( nx, ny, nz ) )
06319                                                                         // if  ( ! hasCompleteSheet( nx, ny, nz, facevol ) )
06320                                                                         {
06321                                                                                 setDataAt( nx, ny, nz, 1 ) ;
06322                                                                                 queue3->prepend( nx, ny, nz ) ;
06323                                                                         }
06324                                                                 }
06325                                                         }
06326 
06327                                         ele = queue2->remove() ;
06328                                 }
06329 
06330                                 // Next, swap queues
06331                                 GridQueue2* temp = queue2 ;
06332                                 queue2 = queue3 ;
06333                                 queue3 = temp ;
06334                         }
06335 
06336                         /* Deal with closed rings */
06337 
06338                         dis -- ;
06339                         queues[ - dis ] = new GridQueue2( ) ;
06340                         #ifdef VERBOSE
06341                         printf("Detecting closed rings %d...", dis) ;
06342                         #endif
06343                         int ftot = 0 ;
06344                         for ( i = 0 ; i < getSizeX() ; i ++ )
06345                                 for ( j = 0 ; j < getSizeY() ; j ++ )
06346                                         for ( k = 0 ; k < getSizeZ() ; k ++ )
06347                                         {
06348                                                 if ( getDataAt( i, j, k ) == 0 )
06349                                                 {
06350                                                         /*
06351                                                         int fval = (int) fvol->getDataAt( i, j, k ) ;
06352                                                         if ( fval == 0)
06353                                                         {
06354                                                                 setDataAt( i, j, k, dis - 2 ) ;
06355                                                                 // queues[ -dis ]->prepend( i, j, k ) ;
06356                                                         }
06357                                                         else
06358                                                         {
06359                                                                 setDataAt( i, j, k, fval - 1 ) ;
06360                                                                 queues[ -fval + 1 ]->prepend( i, j, k ) ;
06361                                                         }
06362                                                         */
06363                                                         setDataAt( i, j, k, dis ) ;
06364                                                         queues[ -dis ]->prepend( i, j, k ) ;
06365 
06366                                                         ftot ++ ;
06367                                                 }
06368                                         }
06369                         #ifdef VERBOSE
06370                         printf("%d nodes\n", ftot) ;
06371                         #endif
06372 
06373 
06374                         /* Find local minimum: to help determine erosion level
06375                         int cts[ 64 ] ;
06376                         for ( i = 0 ; i <= - dis ; i ++ )
06377                         {
06378                                 cts[ i ] = 0 ;
06379                         }
06380                         for ( i = 0 ; i < getSizeX() ; i ++ )
06381                                 for ( j = 0 ; j < getSizeY() ; j ++ )
06382                                         for ( k = 0 ; k < getSizeZ() ; k ++ )
06383                                         {
06384                                                 double val = getDataAt( i, j, k ) ;
06385                                                 if ( val < -1 )
06386                                                 {
06387                                                         int min = 1 ;
06388                                                         for ( int m = 0 ; m < 6 ; m ++ )
06389                                                         {
06390                                                                 int nx = i + neighbor6[m][0] ;
06391                                                                 int ny = j + neighbor6[m][1] ;
06392                                                                 int nz = k + neighbor6[m][2] ;
06393                                                                 if ( getDataAt( nx, ny, nz ) < val )
06394                                                                 {
06395                                                                         min = 0 ;
06396                                                                         break ;
06397                                                                 }
06398                                                         }
06399 
06400                                                         if ( min )
06401                                                         {
06402                                                                 cts[ (int) - val ] ++ ;
06403                                                         }
06404                                                 }
06405                                         }
06406 
06407                         for ( i = 2 ; i <= - dis ; i ++ )
06408                         {
06409                                 printf("Local minima: %d with %d nodes.\n", -i, cts[ i ] ) ;
06410                         }
06411                         */
06412 
06413                         // return ;
06414 
06415                         // Dilate back
06416                         // Starting from nodes with distance - 2 - disthr
06417                         int d ;
06418                         if ( disthr + 2 > - dis )
06419                         {
06420                                 disthr = - dis - 2 ;
06421 
06422                         }
06423                         for ( d = - dis ; d > disthr + 1 ; d -- )
06424                         {
06425                                 queues[ d ]->reset() ;
06426                                 while ( (ele = queues[ d ]->getNext() ) != NULL )
06427                                 {
06428                                         setDataAt( ele->x, ele->y, ele->z, d ) ;
06429                                 }
06430                         }
06431 
06432                         for (d = disthr + 1 ; d >= 2 ; d -- )
06433                         {
06434 
06435                                 //delete queue3 ;
06436                                 //queue3 = new GridQueue2( ) ;
06437                                 queues[ d ]->reset() ;
06438                                 ele = queues[ d ]->getNext() ;
06439                                 while ( ele != NULL )
06440                                 {
06441                                         int dilatable = 0 ;
06442                                         // for ( int m = 0 ; m < 6 ; m ++ )
06443                                         /*
06444                                         for ( int mx = -1 ; mx < 2 ; mx ++ )
06445                                         for ( int my = -1 ; my < 2 ; my ++ )
06446                                         for ( int mz = -1 ; mz < 2 ; mz ++ )
06447                                         {
06448                                         if ( mx == 0 || my == 0 || mz == 0 )
06449                                         {
06450                                         int nx = ele->x + mx ; // neighbor6[m][0] ;
06451                                         int ny = ele->y + my ; // neighbor6[m][1] ;
06452                                         int nz = ele->z + mz ; // neighbor6[m][2] ;
06453                                         if ( getDataAt( nx, ny, nz ) == - d - 1 )
06454                                         {
06455                                         dilatable = 1 ;
06456                                         break ;
06457                                         }
06458                                         }
06459                                         }
06460                                         */
06461                                         for ( i = 0 ; i < 12 ; i ++ )
06462                                         {
06463                                                 int flag = 1, flag2 = 0 ;
06464                                                 for ( j = 0 ; j < 4 ; j ++ )
06465                                                 {
06466                                                         int nx = ele->x + sheetNeighbor[i][j][0] ;
06467                                                         int ny = ele->y + sheetNeighbor[i][j][1] ;
06468                                                         int nz = ele->z + sheetNeighbor[i][j][2] ;
06469 
06470                                                         double val = getDataAt( nx, ny, nz ) ;
06471 
06472                                                         if ( val > - d && val < 0)
06473                                                         {
06474                                                                 flag = 0 ;
06475                                                                 break ;
06476                                                         }
06477                                                         if ( val == d + 1 )
06478                                                         {
06479                                                                 flag2 ++ ;
06480                                                         }
06481                                                 }
06482 
06483                                                 if ( flag && flag2 )
06484                                                 {
06485                                                         dilatable = 1 ;
06486                                                         break ;
06487                                                 }
06488                                         }
06489 
06490                                         if ( ! dilatable )
06491                                         {
06492                                                 // setDataAt( ele->x, ele->y, ele->z, - 1 ) ;
06493                                                 // queue3->prepend( ele->x, ele->y, ele->z ) ;
06494 
06495                                                 setDataAt( ele->x, ele->y, ele->z, - d + 1 ) ;
06496                                                 if ( d > 2 )
06497                                                 {
06498                                                         queues[ d - 1 ]->prepend( ele->x, ele->y, ele->z ) ;
06499                                                 }
06500                                                 ele = queues[ d ]->remove() ;
06501                                         }
06502                                         else
06503                                         {
06504                                                 setDataAt( ele->x, ele->y, ele->z, d ) ;
06505                                                 ele = queues[ d ]->getNext() ;
06506                                         }
06507                                 }
06508 
06509                                 /* Debug: extract minimal set */
06510                                 while ( 1 )
06511                                 {
06512                                         int num = 0 ;
06513                                         queues[ d ]->reset() ;
06514                                         ele = queues[ d ]->getNext() ;
06515                                         while ( ele != NULL )
06516                                         {
06517                                                 int critical = 0 ;
06518                                                 setDataAt( ele->x, ele->y, ele->z, -1 ) ;
06519 
06520                                                 for ( i = -1 ; i < 2 ; i ++ )
06521                                                 {
06522                                                         for ( j = -1 ; j < 2 ; j ++ )
06523                                                         {
06524                                                                 for ( k = -1 ; k < 2 ; k ++ )
06525                                                                 {
06526                                                                         if ( i != 0 && j != 0 && k != 0 )
06527                                                                         {
06528                                                                                 continue ;
06529                                                                         }
06530                                                                         int nx = ele->x + i ;
06531                                                                         int ny = ele->y + j ;
06532                                                                         int nz = ele->z + k ;
06533                                                                         // if ( getDataAt(nx,ny,nz) == d + 1 && !hasCompleteSheet( nx,ny,nz, facevol ) )
06534                                                                         if ( getDataAt(nx,ny,nz) == d + 1 && !hasCompleteSheet( nx,ny,nz ) )
06535                                                                         {
06536                                                                                 critical = 1 ;
06537                                                                                 break ;
06538                                                                         }
06539                                                                 }
06540                                                                 if ( critical )
06541                                                                 {
06542                                                                         break ;
06543                                                                 }
06544                                                         }
06545                                                         if ( critical )
06546                                                         {
06547                                                                 break ;
06548                                                         }
06549                                                 }
06550 
06551                                                 if ( critical )
06552                                                 {
06553                                                         setDataAt( ele->x, ele->y, ele->z, d ) ;
06554                                                         ele = queues[ d ]->getNext() ;
06555                                                 }
06556                                                 else
06557                                                 {
06558                                                         setDataAt( ele->x, ele->y, ele->z, - d + 1 ) ;
06559                                                         if ( d > 2 )
06560                                                         {
06561                                                                 queues[ d - 1 ]->prepend( ele->x, ele->y, ele->z ) ;
06562                                                         }
06563                                                         ele = queues[ d ]->remove() ;
06564                                                         num ++ ;
06565                                                 }
06566 
06567                                         }
06568                                         #ifdef VERBOSE
06569                                         printf("Non-minimal: %d\n", num) ;
06570                                         #endif
06571 
06572                                         if ( num == 0 )
06573                                         {
06574                                                 break ;
06575                                         }
06576                                 }
06577 
06578 
06579                                 /* End of debugging */
06580 
06581                                 /*
06582                                 queue3->reset() ;
06583                                 ele = queue3->getNext() ;
06584                                 while ( ele != NULL )
06585                                 {
06586                                         setDataAt( ele->x, ele->y, ele->z, - 1 ) ;
06587                                         ele = queue3->remove() ;
06588                                 }
06589                                 */
06590                         }
06591 
06592 
06593                         // Finally, threshold the volume
06594                         #ifdef VERBOSE
06595                         //printf("Thresholding the volume to 0/1...\n") ;
06596                         #endif
06597                         //threshold( -1, 1, 0, 0 ) ;
06598                         threshold( 0, 0, 1 ) ;
06599 
06600                         delete facevol ;
06601                         delete fvol ;
06602                         delete queue2;
06603                         delete queue3;
06604                         for (d = -dis ; d >= 2 ; d -- ) {
06605                                 delete queues[d];
06606                         }
06607                         delete [] queues;
06608 
06609                         return - dis - 1 ;
06610                 }
06611 
06612                 //void Volume::erodeSheetOld( int disthr )
06613                 //{
06614                         //int i, j, k ;
06616                         //#ifdef VERBOSE
06617                         //printf("Thresholding the volume to -1/0...\n") ;
06618                         //#endif
06619                         //threshold( 0.1f, -1, 0 ) ;
06620 
06622                         //#ifdef VERBOSE
06623                         //printf("Initializing queue...\n") ;
06624                         //#endif
06625                         //GridQueue2* queue2 = new GridQueue2( ) ;
06626                         //GridQueue2* queue3 = new GridQueue2( ) ;
06627                         //GridQueue2** queues = new GridQueue2* [ 64 ] ;
06628 
06629                         //for ( i = 0 ; i < getSizeX() ; i ++ )
06630                                 //for ( j = 0 ; j < getSizeY() ; j ++ )
06631                                         //for ( k = 0 ; k < getSizeZ() ; k ++ )
06632                                         //{
06633                                                 //if ( getDataAt( i, j, k ) >= 0 )
06634                                                 //{
06635                                                         //if ( ! hasCompleteSheet( i, j, k ) )
06636                                                         //{
06637                                                                 //queue2->prepend( i, j, k ) ;
06638                                                         //}
06639                                                 //}
06640                                         //}
06641                         //printf("Total %d nodes\n", queue2->getNumElements() ) ;
06642 
06644                         //gridQueueEle* ele ;
06645                         //int dis = -1 ;
06646                         //while ( queue2->getNumElements() > 0 )
06647                         //{
06649                                 //dis -- ;
06650                                 //queues[ - dis ] = new GridQueue2( ) ;
06651                                 //printf("Distance transform to %d...", dis) ;
06652                                 //queue2->reset() ;
06653                                 //while( ( ele = queue2->getNext() ) != NULL )
06654                                 //{
06655                                         //setDataAt( ele->x, ele->y, ele->z, dis ) ;
06656                                         //queues[ -dis ]->prepend( ele->x, ele->y, ele->z ) ;
06657                                 //}
06658                                 //printf("%d nodes\n", queues[-dis]->getNumElements()) ;
06659 
06661                                 //queue2->reset() ;
06662                                 //ele = queue2->getNext() ;
06663                                 //while ( ele != NULL )
06664                                 //{
06665                                         //for ( int m = 0 ; m < 6 ; m ++ )
06666                                         //{
06667                                                 //int nx = ele->x + neighbor6[m][0] ;
06668                                                 //int ny = ele->y + neighbor6[m][1] ;
06669                                                 //int nz = ele->z + neighbor6[m][2] ;
06670                                                 //if ( getDataAt( nx, ny, nz ) == 0 && ! hasCompleteSheet( nx, ny, nz ) )
06671                                                 //{
06672                                                         //setDataAt( nx, ny, nz, 1 ) ;
06673                                                         //queue3->prepend( nx, ny, nz ) ;
06674                                                 //}
06675                                         //}
06676 
06677                                         //ele = queue2->remove() ;
06678                                 //}
06679 
06681                                 //GridQueue2* temp = queue2 ;
06682                                 //queue2 = queue3 ;
06683                                 //queue3 = temp ;
06684                         //}
06685 
06687                         //for ( i = 0 ; i < getSizeX() ; i ++ )
06688                                 //for ( j = 0 ; j < getSizeY() ; j ++ )
06689                                         //for ( k = 0 ; k < getSizeZ() ; k ++ )
06690                                         //{
06691                                                 //if ( getDataAt( i, j, k ) == 0 )
06692                                                 //{
06693                                                         //setDataAt( i, j, k, dis - 1 ) ;
06694                                                 //}
06695                                         //}
06696                         //*/
06697 
06699                         //int cts[ 64 ] ;
06700                         //for ( i = 0 ; i <= - dis ; i ++ )
06701                         //{
06702                                 //cts[ i ] = 0 ;
06703                         //}
06704                         //for ( i = 0 ; i < getSizeX() ; i ++ )
06705                                 //for ( j = 0 ; j < getSizeY() ; j ++ )
06706                                         //for ( k = 0 ; k < getSizeZ() ; k ++ )
06707                                         //{
06708                                                 //double val = getDataAt( i, j, k ) ;
06709                                                 //if ( val < -1 )
06710                                                 //{
06711                                                         //int min = 1 ;
06712                                                         //for ( int m = 0 ; m < 6 ; m ++ )
06713                                                         //{
06714                                                                 //int nx = i + neighbor6[m][0] ;
06715                                                                 //int ny = j + neighbor6[m][1] ;
06716                                                                 //int nz = k + neighbor6[m][2] ;
06717                                                                 //if ( getDataAt( nx, ny, nz ) < val )
06718                                                                 //{
06719                                                                         //min = 0 ;
06720                                                                         //break ;
06721                                                                 //}
06722                                                         //}
06723 
06724                                                         //if ( min )
06725                                                         //{
06726                                                                 //cts[ (int) - val ] ++ ;
06727                                                         //}
06728                                                 //}
06729                                         //}
06730 
06731                         //for ( i = 2 ; i <= - dis ; i ++ )
06732                         //{
06733                                 //printf("Local minima: %d with %d nodes.\n", -i, cts[ i ] ) ;
06734                         //}
06735 
06736 
06738 
06741 
06742                         //for ( int d = disthr + 1 ; d >= 2 ; d -- )
06743                         //{
06744                                 //delete queue3 ;
06745                                 //queue3 = new GridQueue2( ) ;
06746                                 //queues[ d ]->reset() ;
06747                                 //while ( (ele = queues[ d ]->getNext() ) != NULL )
06748                                 //{
06749                                         //int dilatable = 0 ;
06752                                         //for ( int mx = -1 ; mx < 2 ; mx ++ )
06753                                                 //for ( int my = -1 ; my < 2 ; my ++ )
06754                                                         //for ( int mz = -1 ; mz < 2 ; mz ++ )
06755                                                         //{
06756                                                                 //if ( mx == 0 || my == 0 || mz == 0 )
06757                                                                 //{
06758                                                                         //int nx = ele->x + mx ; // neighbor6[m][0] ;
06759                                                                         //int ny = ele->y + my ; // neighbor6[m][1] ;
06760                                                                         //int nz = ele->z + mz ; // neighbor6[m][2] ;
06761                                                                         //if ( getDataAt( nx, ny, nz ) == - d - 1 )
06762                                                                         //{
06763                                                                                 //dilatable = 1 ;
06764                                                                                 //break ;
06765                                                                         //}
06766                                                                 //}
06767                                                         //}
06768                                         //*/
06769                                         //for ( i = 0 ; i < 12 ; i ++ )
06770                                         //{
06771                                                 //int flag = 1, flag2 = 0 ;
06772                                                 //for ( j = 0 ; j < 4 ; j ++ )
06773                                                 //{
06774                                                         //int nx = ele->x + sheetNeighbor[i][j][0] ;
06775                                                         //int ny = ele->y + sheetNeighbor[i][j][1] ;
06776                                                         //int nz = ele->z + sheetNeighbor[i][j][2] ;
06777 
06778                                                         //double val = getDataAt( nx, ny, nz ) ;
06779 
06780                                                         //if ( val > - d )
06781                                                         //{
06782                                                                 //flag = 0 ;
06783                                                                 //break ;
06784                                                         //}
06785                                                         //if ( val == - d - 1 )
06786                                                         //{
06787                                                                 //flag2 ++ ;
06788                                                         //}
06789                                                 //}
06790 
06791                                                 //if ( flag && flag2 )
06792                                                 //{
06793                                                         //dilatable = 1 ;
06794                                                         //break ;
06795                                                 //}
06796                                         //}
06797 
06798                                         //if ( ! dilatable )
06799                                         //{
06801                                                 //queue3->prepend( ele->x, ele->y, ele->z ) ;
06803                                                 //setDataAt( ele->x, ele->y, ele->z, - d + 1 ) ;
06804                                                 //if ( d > 2 )
06805                                                 //{
06806                                                         //queues[ d - 1 ]->prepend( ele->x, ele->y, ele->z ) ;
06807                                                 //}
06808                                                 //*/
06809                                         //}
06810                                 //}
06811 
06812                                 //queue3->reset() ;
06813                                 //ele = queue3->getNext() ;
06814                                 //while ( ele != NULL )
06815                                 //{
06816                                         //setDataAt( ele->x, ele->y, ele->z, - 1 ) ;
06817                                         //ele = queue3->remove() ;
06818                                 //}
06819                         //}
06820 
06822                         //#ifdef VERBOSE
06823                         //printf("Thresholding the volume to 0/1...\n") ;
06824                         //#endif
06825                         //threshold( -1, 1, 0, 0 ) ;
06826                 //}
06827 
06828 
06829 
06830                 //void Volume::addNoise( float thr, float pos )
06831                 //{
06832                         //int i, j, k ;
06833                         //#ifdef VERBOSE
06834                         //printf("Thresholding the volume to -MAX_ERODE/0...\n") ;
06835                         //#endif
06836                         //threshold( thr, -MAX_ERODE, 0 ) ;
06837                         //Volume* tvol = new Volume( getSizeX(), getSizeY(), getSizeZ(), 0, 0, 0, this ) ;
06838 
06839                         //for ( i = 0 ; i < getSizeX() ; i ++ )
06840                                 //for ( j = 0 ; j < getSizeY() ; j ++ )
06841                                         //for ( k = 0 ; k < getSizeZ() ; k ++ )
06842                                         //{
06843                                                 //if ( tvol->getDataAt( i, j, k ) >= 0  && isSimple( i, j, k ) )
06844                                                 //{
06845                                                         //for ( int m = 0 ; m < 6 ; m ++ )
06846                                                         //{
06847                                                                 //if ( tvol->getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
06848                                                                 //{
06849                                                                         //if ( rand() < RAND_MAX * pos )
06850                                                                         //{
06851                                                                                 //setDataAt( i, j, k, thr - 1 ) ;
06852                                                                         //}
06853                                                                         //break ;
06854                                                                 //}
06855                                                         //}
06856                                                 //}
06857                                         //}
06858 
06859                 //}
06860 
06868                 //void Volume::sequentialSkeleton( float thr, int type, int noise )
06869                 //{
06870                         //int i, j, k, m ;
06872                         //#ifdef VERBOSE
06873                         //printf("Thresholding the volume to -1/0...\n") ;
06874                         //#endif
06875                         //threshold( thr, -1, 0 ) ;
06876 
06883 
06885                         //#ifdef VERBOSE
06886                         //printf("Initializing queue...\n") ;
06887                         //#endif
06888                         //GridQueue2* queue2 = new GridQueue2( ) ;
06889                         //GridQueue2* queue3 = new GridQueue2( ) ;
06890                         //gridQueueEle* ele ;
06891 
06892                         //for ( i = 0 ; i < getSizeX() ; i ++ )
06893                                 //for ( j = 0 ; j < getSizeY() ; j ++ )
06894                                         //for ( k = 0 ; k < getSizeZ() ; k ++ )
06895                                         //{
06896                                                 //if ( getDataAt( i, j, k ) >= 0 )
06897                                                 //{
06898                                                         //for ( m = 0 ; m < 6 ; m ++ )
06899                                                         //{
06900                                                                 //if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
06901                                                                 //{
06902                                                                         //setDataAt( i, j, k, 1 ) ;
06903                                                                         //queue2->prepend( i, j, k ) ;
06904                                                                         //break ;
06905                                                                 //}
06906                                                         //}
06907                                                 //}
06908                                         //}
06910 
06911 
06913                         //int dis = 0 ;
06914                         //int ox, oy, oz ;
06915                         //int nx, ny, nz ;
06916                         //while ( queue2->getNumElements() > 0 )
06917                         //{
06918                                 //dis ++ ;
06919                                 //printf("At distance %d, there are %d nodes.\n", dis, queue2->getNumElements()) ;
06920 
06924 
06926                                 //queue2->reset() ;
06927                                 //while ( (ele = queue2->getNext()) != NULL )
06928                                 //{
06929                                         //ox = ele->x ;
06930                                         //oy = ele->y ;
06931                                         //oz = ele->z ;
06932 
06933                                         //setDataAt( ox, oy, oz, 2 ) ;
06934                                         //for ( m = 0 ; m < 6 ; m ++ )
06935                                         //{
06936                                                         //nx = ox + neighbor6[m][0] ;
06937                                                         //ny = oy + neighbor6[m][1] ;
06938                                                         //nz = oz + neighbor6[m][2] ;
06939                                                         //if ( getDataAt( nx, ny, nz ) == 0 )
06940                                                         //{
06941                                                                 //setDataAt( nx, ny, nz, 1 ) ;
06942                                                                 //queue3->prepend( nx, ny, nz ) ;
06943                                                         //}
06944                                         //}
06945                                 //}
06946 
06948                                 //queue2->reset() ;
06949                                 //ele = queue2->getNext() ;
06950                                 //while ( ele != NULL )
06951                                 //{
06952                                         //ox = ele->x ;
06953                                         //oy = ele->y ;
06954                                         //oz = ele->z ;
06955 
06956                                         //if ( (! isSimple( ox, oy, oz ))  ||
06957                                                  //( ( ( type == 0 && isEdgeEnd( ox, oy, oz ) ) ||
06958                                                          //( type == 1 && isFaceEnd( ox, oy, oz ) ) ) && ! isNoise( ox, oy, oz, noise ) ) )
06959                                         //{
06960                                                 //setDataAt( ox, oy, oz, 3 ) ;
06961                                                 //ele = queue2->remove() ;
06962                                         //}
06963                                         //else
06964                                         //{
06965                                                 //ele = queue2->getNext() ;
06966                                         //}
06967                                 //}
06968 
06970                                 //queue2->reset() ;
06971                                 //while ( ( ele = queue2->getNext() ) != NULL )
06972                                 //{
06973                                         //ox = ele->x ;
06974                                         //oy = ele->y ;
06975                                         //oz = ele->z ;
06976                                         //queue2->remove() ;
06977                                         //queue2->reset() ;
06978 
06979                                         //if ( getDataAt(ox,oy,oz) != 2 )
06980                                         //{
06981                                                 //continue ;
06982                                         //}
06983 
06984                                         //if ( ( ( ( type == 0 && isEdgeEnd( ox, oy, oz ) ) ||
06985                                                                          //( type == 1 && isFaceEnd( ox, oy, oz ) ) ) && ! isNoise( ox, oy, oz, noise ) ) )
06986                                         //{
06987                                                 //setDataAt( ox, oy, oz, 3 ) ;
06988                                         //}
06989                                         //else
06990                                         //{
06991                                                 //setDataAt( ox, oy, oz, -1 ) ;
06992                                         //}
06993 
06994                                         //for ( i = -1 ; i < 2 ; i ++ )
06995                                                 //for ( j = -1 ; j < 2 ; j ++ )
06996                                                         //for ( k = -1 ; k < 2 ; k ++ )
06997                                                         //{
06998                                                                 //nx = ox + i ;
06999                                                                 //ny = oy + j ;
07000                                                                 //nz = oz + k ;
07001                                                                 //int val = (int)( getDataAt( nx, ny, nz ) ) ;
07002                                                                 //if ( val > 1 )
07003                                                                 //{
07004                                                                         //int complex = 0 ;
07005                                                                         //if ( (! isSimple( nx, ny, nz ))  ||
07006                                                                                 //( ( ( type == 0 && isEdgeEnd( nx, ny, nz ) ) ||
07007                                                                                 //( type == 1 && isFaceEnd( nx, ny, nz ) ) ) && ! isNoise( nx, ny, nz, noise ) ) )
07008                                                                         //{
07009                                                                                 //complex = 1 ;
07010                                                                         //}
07011 
07012                                                                         //if ( val == 2 && complex )
07013                                                                         //{
07015                                                                                 //setDataAt( nx, ny, nz, 3 ) ;
07016                                                                         //}
07017                                                                         //else if ( val == 3 && ! complex )
07018                                                                         //{
07020                                                                                 //setDataAt( nx, ny, nz, 2 ) ;
07021                                                                                 //queue2->prepend( nx, ny, nz ) ;
07022                                                                         //}
07023 
07024                                                                 //}
07025                                                         //}
07026 
07027                                         //queue2->reset() ;
07028                                 //}
07029 
07031                                 //GridQueue2* temp = queue3 ;
07032                                 //queue3 = queue2 ;
07033                                 //queue2 = temp ;
07034                         //}
07035 
07036 
07038                         //#ifdef VERBOSE
07039                         //printf("Thresholding the volume to 0/1...\n") ;
07040                         //#endif
07041                         //threshold( 0, 0, 1 ) ;
07042 
07043                 //}
07044 
07045                 //void Volume::dumbsurfaceSkeleton( float thr )
07046                 //{
07047                         //int i, j, k ;
07049                         //#ifdef VERBOSE
07050                         //printf("Thresholding the volume to -MAX_ERODE/0...\n") ;
07051                         //#endif
07052                         //threshold( thr, -MAX_ERODE, 0 ) ;
07053 
07055                         //#ifdef VERBOSE
07056                         //printf("Initializing queue...\n") ;
07057                         //#endif
07058                         //GridQueue2* queue2 = new GridQueue2( ) ;
07059                         //gridQueueEle* ele ;
07060 
07061 
07062                         //while ( 1 )
07063                         //{
07064                                 //int n = 0 ;
07065 
07066                                 //queue2->reset() ;
07067                                 //for ( i = 0 ; i < getSizeX() ; i ++ )
07068                                         //for ( j = 0 ; j < getSizeY() ; j ++ )
07069                                                 //for ( k = 0 ; k < getSizeZ() ; k ++ )
07070                                                 //{
07071                                                         //if ( getDataAt( i, j, k ) == 0 )
07072                                                         //{
07073                                                                 //{
07074                                                                         //for ( int m = 0 ; m < 6 ; m ++ )
07075                                                                         //{
07076                                                                                 //if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
07077                                                                                 //{
07078                                                                                         //queue2->prepend( i, j, k ) ;
07079                                                                                         //break ;
07080                                                                                 //}
07081                                                                         //}
07082                                                                 //}
07083                                                         //}
07084                                                 //}
07085 
07086                                 //queue2->reset() ;
07087                                 //ele = queue2->getNext() ;
07088                                 //while ( ele != NULL )
07089                                 //{
07090                                         //int ox = ele->x ;
07091                                         //int oy = ele->y ;
07092                                         //int oz = ele->z ;
07093                                         //if ( isSimple( ox, oy, oz ) && hasCompleteSheet( ox, oy, oz ) == 1 )
07094                                         //{
07095                                                 //setDataAt( ox, oy, oz, -1 ) ;
07096                                                 //n ++ ;
07097                                         //}
07098 
07099                                         //ele = queue2->remove() ;
07100                                 //}
07101 
07102                                 //if ( n == 0 )
07103                                 //{
07104                                         //break ;
07105                                 //}
07106 
07107                                 //printf("%d simple nodes found.\n", n);
07108                         //}
07109 
07110 
07112                         //#ifdef VERBOSE
07113                         //printf("Thresholding the volume to 0/1...\n") ;
07114                         //#endif
07115                         //threshold( 0, 0, 1 ) ;
07116                 //}
07117 
07119                 //*  Assuming the current volume has already been thresholded to 0/1
07120                 //*/
07121                 //void Volume::surfaceSkeleton( Volume* grayvol, float lowthr, float highthr ) {
07122                         //int i, j, k ;
07123                         //threshold( 0.5f, -MAX_ERODE, 0 ) ;
07124 
07125                         //GridQueue2* queue2 = new GridQueue2( ) ;
07126                         //GridQueue2* queue3 = new GridQueue2( ) ;
07127                         //GridQueue2* queue4 = new GridQueue2( ) ;
07128 
07129                         //PriorityQueue <gridPoint,int> * queue = new PriorityQueue <gridPoint,int> ( MAX_QUEUELEN );
07130                         //int ct = 0 ;
07131 
07132                         //for ( i = 0 ; i < getSizeX() ; i ++ )
07133                                 //for ( j = 0 ; j < getSizeY() ; j ++ )
07134                                         //for ( k = 0 ; k < getSizeZ() ; k ++ )
07135                                         //{
07136                                                 //if ( getDataAt( i, j, k ) >= 0 )
07137                                                 //{
07138                                                         //float v = (float)grayvol->getDataAt(i,j,k) ;
07139                                                         //if ( v > highthr || v <= lowthr )
07140                                                         //{
07141                                                                 //setDataAt( i, j, k, MAX_ERODE ) ;
07142                                                         //}
07143                                                         //else
07144                                                         //{
07145                                                                 //ct ++ ;
07146 
07147                                                                 //for ( int m = 0 ; m < 6 ; m ++ )
07148                                                                 //{
07149                                                                         //if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
07150                                                                         //{
07151                                                                                 //queue2->prepend( i, j, k ) ;
07152                                                                                 //break ;
07153                                                                         //}
07154                                                                 //}
07155                                                         //}
07156                                                 //}
07157                                         //}
07158 
07159 
07161                         //int wid = MAX_ERODE ;
07162                         //gridQueueEle* ele ;
07163                         //gridPoint* gp ;
07164                         //int ox, oy, oz ;
07165                         //int score ;
07166                         //Volume* scrvol = new Volume( this->getSizeX() , this->getSizeY(), this->getSizeZ() ) ;
07167                         //for ( i = 0 ; i < getSizeX() * getSizeY() * getSizeZ() ; i ++ )
07168                         //{
07169                                 //scrvol->setDataAt( i, -1 ) ;
07170                         //}
07171 
07172                         //#ifdef  NOISE_DIS_SHEET
07173                         //Volume* noisevol = new Volume( getSizeX(), getSizeY(), getSizeZ() ) ;
07174                         //#endif
07175 
07176                         //for ( int curwid = 1 ; curwid <= wid ; curwid ++ )
07177                         //{
07178 
07179 
07180                                 //int numComplex = 0, numSimple = 0 ;
07181                                 //#ifdef VERBOSE
07182                                 //printf("Processing %d nodes in layer %d\n", queue2->getNumElements(), curwid) ;
07183                                 //#endif
07184 
07185                                 //queue2->reset() ;
07186                                 //ele = queue2->getNext() ;
07187                                 //while ( ele != NULL )
07188                                 //{
07189                                         //ox = ele->x ;
07190                                         //oy = ele->y ;
07191                                         //oz = ele->z ;
07192 
07193                                         //if ( getDataAt(ox,oy,oz) == curwid )
07194                                         //{
07195                                                 //ele = queue2->remove() ;
07196                                         //}
07197                                         //else
07198                                         //{
07199                                                 //setDataAt(ox,oy,oz, curwid) ;
07200                                                 //ele = queue2->getNext() ;
07201                                         //}
07202                                 //}
07203                                 //queue4->reset() ;
07204                                 //ele = queue4->getNext() ;
07205                                 //while ( ele != NULL )
07206                                 //{
07207                                         //ox = ele->x ;
07208                                         //oy = ele->y ;
07209                                         //oz = ele->z ;
07210 
07211                                         //queue2->prepend(ox,oy,oz) ;
07212                                         //ele = queue4->remove() ;
07213                                 //}
07214 
07216 
07217                                 //#ifdef NOISE_DIS_SHEET
07219                                 //queue2->reset() ;
07220 
07222                                 //int flag = 0 ;
07223                                 //while ( ( ele = queue2->getNext() ) != NULL )
07224                                 //{
07225                                         //ox = ele->x ;
07226                                         //oy = ele->y ;
07227                                         //oz = ele->z ;
07228                                         //if ( NOISE_DIS_SHEET <= 1 )
07229                                         //{
07230                                                 //noisevol->setDataAt( ox, oy, oz, 0 ) ;
07231                                         //}
07232                                         //else
07233                                         //{
07234                                                 //flag = 0 ;
07235                                                 //for ( int m = 0 ; m < 6 ; m ++ )
07236                                                 //{
07237                                                         //int nx = ox + neighbor6[m][0] ;
07238                                                         //int ny = oy + neighbor6[m][1] ;
07239                                                         //int nz = oz + neighbor6[m][2] ;
07240                                                         //if ( getDataAt( nx, ny, nz ) == 0 )
07241                                                         //{
07242                                                                 //noisevol->setDataAt( ox, oy, oz, 1 ) ;
07243                                                                 //flag = 1 ;
07244                                                                 //break ;
07245                                                         //}
07246                                                 //}
07247                                                 //if ( ! flag )
07248                                                 //{
07249                                                         //noisevol->setDataAt( ox, oy, oz, 0 ) ;
07250                                                 //}
07251                                         //}
07252                                 //}
07253 
07254                                 //for ( int cur = 1 ; cur < NOISE_DIS_SHEET ; cur ++ )
07255                                 //{
07256                                         //queue2->reset() ;
07257                                         //int count = 0 ;
07258 
07259                                         //while ( ( ele = queue2->getNext() ) != NULL )
07260                                         //{
07261                                                 //ox = ele->x ;
07262                                                 //oy = ele->y ;
07263                                                 //oz = ele->z ;
07264 
07265                                                 //if ( noisevol->getDataAt( ox, oy, oz ) == 1 )
07266                                                 //{
07267                                                         //continue ;
07268                                                 //}
07269 
07270                                                 //flag = 0 ;
07271                                                 //for ( int m = 0 ; m < 6 ; m ++ )
07272                                                 //{
07273                                                         //int nx = ox + neighbor6[m][0] ;
07274                                                         //int ny = oy + neighbor6[m][1] ;
07275                                                         //int nz = oz + neighbor6[m][2] ;
07276                                                         //if ( getDataAt( nx, ny, nz ) > 0 && noisevol->getDataAt( nx, ny, nz ) == 1 )
07277                                                         //{
07278                                                                 //noisevol->setDataAt( ox, oy, oz, 1 ) ;
07279                                                                 //count ++ ;
07280                                                                 //break ;
07281                                                         //}
07282                                                 //}
07283                                         //}
07284 
07285                                         //if ( count == 0 )
07286                                         //{
07287                                                 //break ;
07288                                         //}
07289                                 //}
07290 
07291 
07292                                 //#endif
07293 
07294                                 //queue2->reset() ;
07295                                 //ele = queue2->getNext() ;
07296                                 //while ( ele != NULL )
07297                                 //{
07298                                         //ox = ele->x ;
07299                                         //oy = ele->y ;
07300                                         //oz = ele->z ;
07301 
07303                                         //score = getNumPotComplex( ox, oy, oz ) ;
07304                                         //scrvol->setDataAt( ox, oy, oz, score ) ;
07305 
07307                                         //gp = new gridPoint ;
07308                                         //gp->x = ox ;
07309                                         //gp->y = oy ;
07310                                         //gp->z = oz ;
07312                                         //queue->add( gp, score ) ;
07313 
07314                                         //ele = queue2->remove() ;
07315                                 //}
07316 
07317 
07318                                 //delete queue2 ;
07319                                 //queue2 = queue3 ;
07320                                 //queue3 = new GridQueue2( ) ;
07321 
07322                                 //int nowComplex = 0 ;
07323 
07325                                 //while ( ! queue->isEmpty() )
07326                                 //{
07328                                         //queue->remove( gp, score ) ;
07329                                         //ox = gp->x ;
07330                                         //oy = gp->y ;
07331                                         //oz = gp->z ;
07332                                         //delete gp ;
07333 
07334                                         //if ( getDataAt( ox, oy, oz ) != curwid || (int) scrvol->getDataAt( ox, oy, oz ) != score )
07335                                         //{
07336                                                 //continue ;
07337                                         //}
07338 
07339 
07340                                         //#ifndef NOISE_DIS_SHEET
07342                                         //if ( (! isSimple( ox, oy, oz )) || isSheetEnd( ox, oy, oz ) )
07344                                         //#else
07346                                         //if ( ! isSimple( ox, oy, oz ) || isSheetEnd( ox, oy, oz, noisevol ) || isHelixEnd( ox, oy, oz, noisevol ))
07348                                         //#endif
07349                                         //{
07351                                                 //setDataAt( ox, oy, oz, curwid + 1 ) ;
07352                                                 //queue4->prepend( ox, oy, oz ) ;
07353                                                 //numComplex ++ ;
07354 
07355                                                 //nowComplex = 1 ;
07356                                         //}
07357                                         //else
07358                                         //{
07359                                                 //setDataAt( ox, oy, oz, -1 ) ;
07360                                                 //numSimple ++ ;
07361 
07362                                                 //for ( int m = 0 ; m < 6 ; m ++ )
07363                                                 //{
07364                                                         //int nx = ox + neighbor6[m][0] ;
07365                                                         //int ny = oy + neighbor6[m][1] ;
07366                                                         //int nz = oz + neighbor6[m][2] ;
07367                                                         //if ( getDataAt( nx, ny, nz ) == 0 )
07368                                                         //{
07370                                                                 //queue2->prepend( nx, ny, nz ) ;
07371                                                         //}
07372                                                 //}
07373 
07374                                                 //if ( nowComplex )
07375                                                 //{
07376 
07378                                                 //}
07379                                         //}
07380 
07383 
07384                                         //for ( i = -2 ; i < 3 ;i ++ )
07385                                                 //for ( j = -2 ; j < 3 ; j ++ )
07386                                                         //for ( k = -2 ; k < 3 ; k ++ )
07387                                                         //{
07388                                                                 //int nx = ox + i ;
07389                                                                 //int ny = oy + j ;
07390                                                                 //int nz = oz + k ;
07391 
07392                                                                 //if ( getDataAt( nx, ny, nz ) == curwid )
07393                                                                 //{
07395                                                                         //score = getNumPotComplex( nx, ny, nz ) ;
07396 
07397                                                                         //if ( score != (int) scrvol->getDataAt( nx, ny, nz ) )
07398                                                                         //{
07400                                                                                 //scrvol->setDataAt( nx, ny, nz, score ) ;
07402                                                                                 //gp = new gridPoint ;
07403                                                                                 //gp->x = nx ;
07404                                                                                 //gp->y = ny ;
07405                                                                                 //gp->z = nz ;
07407                                                                                 //queue->add( gp, score ) ;
07408                                                                         //}
07409                                                                 //}
07410                                                         //}
07411 
07412 
07413                                 //}
07414 
07415                                 //if ( numSimple == 0 )
07416                                 //{
07417                                         //if ( queue2->getNumElements() > 0 )
07418                                         //{
07419                                                 //printf("*************************wierd**********************\n");
07420                                         //}
07421                                                 //break ;
07422                                 //}
07423                         //}
07424 
07426 
07427                         //queue4->reset() ;
07428                         //ele = queue4->getNext() ;
07429                         //while ( ele != NULL )
07430                         //{
07431                                 //ele = queue4->remove() ;
07432                         //}
07433 
07434                         //queue2->reset() ;
07435                         //for ( i = 0 ; i < getSizeX() ; i ++ )
07436                                 //for ( j = 0 ; j < getSizeY() ; j ++ )
07437                                         //for ( k = 0 ; k < getSizeZ() ; k ++ )
07438                                         //{
07439                                                 //if ( getDataAt( i, j, k ) == 0 && isInternal2( i,j,k ) == 1 )
07440                                                 //{
07441                                                         //queue2->prepend( i, j, k ) ;
07442                                                 //}
07443                                         //}
07444                         //queue2->reset() ;
07445                         //ele = queue2->getNext() ;
07446                         //while ( ele != NULL )
07447                         //{
07448                                 //ox = ele->x ;
07449                                 //oy = ele->y ;
07450                                 //oz = ele->z ;
07451                                 //setDataAt( ox, oy, oz, -1 ) ;
07452                                 //ele = queue2->remove() ;
07453                         //}
07454 
07455 
07456 
07458                         //delete scrvol;
07459                         //delete queue;
07460                         //delete queue2;
07461                         //delete queue3;
07462                         //delete queue4;
07463                         //#ifdef VERBOSE
07464                         //printf("Thresholding the volume to 0/1...\n") ;
07465                         //#endif
07466                         //threshold( 0, 0, 1 ) ;
07467 
07468                 //}
07469 
07470                 //void Volume::surfaceSkeleton( float thr )
07471                 //{
07472                         //int i, j, k ;
07474                         //printf("Thresholding the volume to -MAX_ERODE/0...\n") ;
07475                         //threshold( thr, -MAX_ERODE, 0 ) ;
07476 
07478                         //printf("Initializing queue...\n") ;
07479                         //GridQueue2* queue2 = new GridQueue2( ) ;
07480                         //GridQueue2* queue3 = new GridQueue2( ) ;
07481                         //GridQueue2* queue4 = new GridQueue2( ) ;
07482 
07483                         //PriorityQueue <gridPoint,int> * queue = new PriorityQueue <gridPoint,int> ( MAX_QUEUELEN );
07484 
07485                         //for ( i = 0 ; i < getSizeX() ; i ++ )
07486                                 //for ( j = 0 ; j < getSizeY() ; j ++ )
07487                                         //for ( k = 0 ; k < getSizeZ() ; k ++ )
07488                                         //{
07489                                                 //if ( getDataAt( i, j, k ) >= 0 )
07490                                                 //{
07491                                                         //{
07492                                                                 //for ( int m = 0 ; m < 6 ; m ++ )
07493                                                                 //{
07494                                                                         //if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
07495                                                                         //{
07497                                                                                 //queue2->prepend( i, j, k ) ;
07498                                                                                 //break ;
07499                                                                         //}
07500                                                                 //}
07501                                                         //}
07502                                                 //}
07503                                         //}
07504                         //int wid = MAX_ERODE ;
07505                         //#ifdef VERBOSE
07506                         //printf("Total %d nodes\n", queue2->getNumElements() ) ;
07507 
07508 
07510                         //printf("Start erosion to %d...\n", wid) ;
07511                         //#endif
07512                         //gridQueueEle* ele ;
07513                         //gridPoint* gp ;
07514                         //int ox, oy, oz ;
07515                         //int score ;
07516                         //Volume* scrvol = new Volume( this->getSizeX() , this->getSizeY(), this->getSizeZ() ) ;
07517                         //for ( i = 0 ; i < getSizeX() * getSizeY() * getSizeZ() ; i ++ )
07518                         //{
07519                                 //scrvol->setDataAt( i, -1 ) ;
07520                         //}
07521 
07522         //#ifdef  NOISE_DIS_SHEET
07523                         //Volume* noisevol = new Volume( getSizeX(), getSizeY(), getSizeZ() ) ;
07524         //#endif
07525 
07526                         //for ( int curwid = 1 ; curwid <= wid ; curwid ++ )
07527                         //{
07531 
07532                                 //int numComplex = 0, numSimple = 0 ;
07533                                 //printf("Processing %d nodes in layer %d\n", queue2->getNumElements(), curwid) ;
07534 
07536                                 //We first need to assign curwid + 1 to every node in this layer
07537                                 //*/
07538                                 //queue2->reset() ;
07539                                 //ele = queue2->getNext() ;
07540                                 //while ( ele != NULL )
07541                                 //{
07542                                         //ox = ele->x ;
07543                                         //oy = ele->y ;
07544                                         //oz = ele->z ;
07545 
07546                                         //if ( getDataAt(ox,oy,oz) == curwid )
07547                                         //{
07548                                                 //ele = queue2->remove() ;
07549                                         //}
07550                                         //else
07551                                         //{
07552                                                 //setDataAt(ox,oy,oz, curwid) ;
07553                                                 //ele = queue2->getNext() ;
07554                                         //}
07555                                 //}
07556                                 //queue4->reset() ;
07557                                 //ele = queue4->getNext() ;
07558                                 //while ( ele != NULL )
07559                                 //{
07560                                         //ox = ele->x ;
07561                                         //oy = ele->y ;
07562                                         //oz = ele->z ;
07563 
07564                                         //queue2->prepend(ox,oy,oz) ;
07565                                         //ele = queue4->remove() ;
07566                                 //}
07567 
07569 
07570         //#ifdef NOISE_DIS_SHEET
07572                                 //queue2->reset() ;
07573 
07575                                 //int flag = 0 ;
07576                                 //while ( ( ele = queue2->getNext() ) != NULL )
07577                                 //{
07578                                         //ox = ele->x ;
07579                                         //oy = ele->y ;
07580                                         //oz = ele->z ;
07581                                         //if ( NOISE_DIS_SHEET <= 1 )
07582                                         //{
07583                                                 //noisevol->setDataAt( ox, oy, oz, 0 ) ;
07584                                         //}
07585                                         //else
07586                                         //{
07587                                                 //flag = 0 ;
07588                                                 //for ( int m = 0 ; m < 6 ; m ++ )
07589                                                 //{
07590                                                         //int nx = ox + neighbor6[m][0] ;
07591                                                         //int ny = oy + neighbor6[m][1] ;
07592                                                         //int nz = oz + neighbor6[m][2] ;
07593                                                         //if ( getDataAt( nx, ny, nz ) == 0 )
07594                                                         //{
07595                                                                 //noisevol->setDataAt( ox, oy, oz, 1 ) ;
07596                                                                 //flag = 1 ;
07597                                                                 //break ;
07598                                                         //}
07599                                                 //}
07600                                                 //if ( ! flag )
07601                                                 //{
07602                                                         //noisevol->setDataAt( ox, oy, oz, 0 ) ;
07603                                                 //}
07604                                         //}
07605                                 //}
07606 
07607                                 //for ( int cur = 1 ; cur < NOISE_DIS_SHEET ; cur ++ )
07608                                 //{
07609                                         //queue2->reset() ;
07610                                         //int count = 0 ;
07611 
07612                                         //while ( ( ele = queue2->getNext() ) != NULL )
07613                                         //{
07614                                                 //ox = ele->x ;
07615                                                 //oy = ele->y ;
07616                                                 //oz = ele->z ;
07617 
07618                                                 //if ( noisevol->getDataAt( ox, oy, oz ) == 1 )
07619                                                 //{
07620                                                         //continue ;
07621                                                 //}
07622 
07623                                                 //flag = 0 ;
07624                                                 //for ( int m = 0 ; m < 6 ; m ++ )
07625                                                 //{
07626                                                         //int nx = ox + neighbor6[m][0] ;
07627                                                         //int ny = oy + neighbor6[m][1] ;
07628                                                         //int nz = oz + neighbor6[m][2] ;
07629                                                         //if ( getDataAt( nx, ny, nz ) > 0 && noisevol->getDataAt( nx, ny, nz ) == 1 )
07630                                                         //{
07631                                                                 //noisevol->setDataAt( ox, oy, oz, 1 ) ;
07632                                                                 //count ++ ;
07633                                                                 //break ;
07634                                                         //}
07635                                                 //}
07636                                         //}
07637 
07638                                         //if ( count == 0 )
07639                                         //{
07640                                                 //break ;
07641                                         //}
07642                                 //}
07643 
07644 
07645         //#endif
07646 
07648 
07652                                 //queue2->reset() ;
07653                                 //ele = queue2->getNext() ;
07654                                 //while ( ele != NULL )
07655                                 //{
07656                                         //ox = ele->x ;
07657                                         //oy = ele->y ;
07658                                         //oz = ele->z ;
07659 
07661         //#ifndef NOISE_DIS_SHEET
07662                                         //if ( isSheetEnd( ox, oy, oz ) || ! isSimple( ox, oy, oz ) )
07663         //#else
07664                                         //if ( isSheetEnd( ox, oy, oz, noisevol ) || ! isSimple( ox, oy, oz ) )
07665         //#endif
07666                                         //{
07668                                                 //setDataAt( ox, oy, oz, curwid + 1 ) ;
07669                                                 //queue3->prepend( ox, oy, oz ) ;
07670                                                 //ele = queue2->remove() ;
07671 
07672                                                 //numComplex ++ ;
07673                                         //}
07674                                         //else
07675                                         //{
07676                                                 //ele = queue2->getNext() ;
07677                                         //}
07678                                 //}
07679                                 //*/
07680 
07681 
07685                                 //queue2->reset() ;
07686                                 //ele = queue2->getNext() ;
07687                                 //while ( ele != NULL )
07688                                 //{
07689                                         //ox = ele->x ;
07690                                         //oy = ele->y ;
07691                                         //oz = ele->z ;
07692 
07694                                         //score = getNumPotComplex( ox, oy, oz ) ;
07695                                         //scrvol->setDataAt( ox, oy, oz, score ) ;
07696 
07698                                         //gp = new gridPoint ;
07699                                         //gp->x = ox ;
07700                                         //gp->y = oy ;
07701                                         //gp->z = oz ;
07703                                         //queue->add( gp, score ) ;
07704 
07705                                         //ele = queue2->remove() ;
07706                                 //}
07707 
07711                                 //delete queue2 ;
07712                                 //queue2 = queue3 ;
07713                                 //queue3 = new GridQueue2( ) ;
07714 
07715                                 //int nowComplex = 0 ;
07716 
07718                                 //while ( ! queue->isEmpty() )
07719                                 //{
07721                                         //queue->remove( gp, score ) ;
07722                                         //ox = gp->x ;
07723                                         //oy = gp->y ;
07724                                         //oz = gp->z ;
07725                                         //delete gp ;
07728 
07732                                         //if ( getDataAt( ox, oy, oz ) != curwid || (int) scrvol->getDataAt( ox, oy, oz ) != score )
07733                                         //{
07734                                                 //continue ;
07735                                         //}
07736 
07738 
07740                                         //setDataAt( ox, oy, oz, -1 ) ;
07741                                         //numSimple ++ ;
07743                                         //*/
07744 
07747         //#ifndef NOISE_DIS_SHEET
07749                                         //if ( (! isSimple( ox, oy, oz )) || isSheetEnd( ox, oy, oz ) )
07751         //#else
07753                                         //if ( ! isSimple( ox, oy, oz ) || isSheetEnd( ox, oy, oz, noisevol ) || isHelixEnd( ox, oy, oz, noisevol ))
07755         //#endif
07756                                         //{
07758                                                 //setDataAt( ox, oy, oz, curwid + 1 ) ;
07759                                                 //queue4->prepend( ox, oy, oz ) ;
07760                                                 //numComplex ++ ;
07761 
07762                                                 //nowComplex = 1 ;
07763                                         //}
07764                                         //else
07765                                         //{
07766                                                 //setDataAt( ox, oy, oz, -1 ) ;
07767                                                 //numSimple ++ ;
07768 
07769                                                 //if ( nowComplex )
07770                                                 //{
07771 
07773                                                 //}
07774                                         //}
07776 
07778                                         //for ( int m = 0 ; m < 6 ; m ++ )
07779                                         //{
07780                                                 //int nx = ox + neighbor6[m][0] ;
07781                                                 //int ny = oy + neighbor6[m][1] ;
07782                                                 //int nz = oz + neighbor6[m][2] ;
07783                                                 //if ( getDataAt( nx, ny, nz ) == 0 )
07784                                                 //{
07786                                                         //queue2->prepend( nx, ny, nz ) ;
07787                                                 //}
07788                                         //}
07789 
07791 
07794                                         //for ( i = -1 ; i < 2 ; i ++ )
07795                                                 //for ( j = -1 ; j < 2 ; j ++ )
07796                                                         //for ( k = -1 ; k < 2 ; k ++ )
07797                                                         //{
07798                                                                 //int nx = ox + i ;
07799                                                                 //int ny = oy + j ;
07800                                                                 //int nz = oz + k ;
07801 
07803                                                                 //if ( getDataAt( nx, ny, nz ) == curwid &&
07805         //#ifndef NOISE_DIS_SHEET
07806                                                                         //( isSheetEnd( nx, ny, nz ) || ! isSimple( nx, ny, nz ) ) )
07807         //#else
07808                                                                         //( isSheetEnd( nx, ny, nz, noisevol ) || ! isSimple( nx, ny, nz ) ) )
07809         //#endif
07810 
07811                                                                 //{
07813                                                                         //setDataAt( nx, ny, nz, curwid + 1 ) ;
07814                                                                         //queue2->prepend( nx, ny, nz ) ;
07815                                                                         //numComplex ++ ;
07816                                                                 //}
07817                                                         //}
07818                                         //*/
07819 
07822 
07823                                         //for ( i = -2 ; i < 3 ;i ++ )
07824                                                 //for ( j = -2 ; j < 3 ; j ++ )
07825                                                         //for ( k = -2 ; k < 3 ; k ++ )
07826                                                         //{
07827                                                                 //int nx = ox + i ;
07828                                                                 //int ny = oy + j ;
07829                                                                 //int nz = oz + k ;
07830 
07831                                                                 //if ( getDataAt( nx, ny, nz ) == curwid )
07832                                                                 //{
07834                                                                         //score = getNumPotComplex( nx, ny, nz ) ;
07835 
07836                                                                         //if ( score != (int) scrvol->getDataAt( nx, ny, nz ) )
07837                                                                         //{
07839                                                                                 //scrvol->setDataAt( nx, ny, nz, score ) ;
07841                                                                                 //gp = new gridPoint ;
07842                                                                                 //gp->x = nx ;
07843                                                                                 //gp->y = ny ;
07844                                                                                 //gp->z = nz ;
07846                                                                                 //queue->add( gp, score ) ;
07847                                                                         //}
07848                                                                 //}
07849                                                         //}
07850 
07851 
07852                                 //}
07853 
07854                                 //printf("%d complex, %d simple\n", numComplex, numSimple) ;
07855 
07856                                 //if ( numSimple == 0 )
07857                                 //{
07858                                                 //break ;
07859                                 //}
07860                         //}
07861 
07863                         //printf("Thresholding the volume to 0/1...\n") ;
07864                         //threshold( 0, 0, 1 ) ;
07865 
07866                 //}
07867 
07868                 //void Volume::surfaceSkeleton( float thr, Volume* svol )
07869                 //{
07870                         //int i, j, k ;
07872                         //printf("Thresholding the volume to -MAX_ERODE/0...\n") ;
07873                         //threshold( thr, -MAX_ERODE, 0 ) ;
07874 
07876                         //printf("Initializing queue...\n") ;
07877                         //GridQueue2* queue2 = new GridQueue2( ) ;
07878                         //GridQueue2* queue3 = new GridQueue2( ) ;
07879                         //GridQueue2* queue4 = new GridQueue2( ) ;
07880 
07881                         //PriorityQueue <gridPoint,int> * queue = new PriorityQueue <gridPoint,int> ( MAX_QUEUELEN );
07882 
07883                         //for ( i = 0 ; i < getSizeX() ; i ++ )
07884                                 //for ( j = 0 ; j < getSizeY() ; j ++ )
07885                                         //for ( k = 0 ; k < getSizeZ() ; k ++ )
07886                                         //{
07887                                                 //if ( getDataAt( i, j, k ) >= 0 )
07888                                                 //{
07889                                                         //if ( svol->getDataAt(i,j,k) > 0 )
07890                                                         //{
07891                                                                 //setDataAt( i, j, k, MAX_ERODE ) ;
07892                                                         //}
07893                                                         //else
07894                                                         //{
07895                                                                 //for ( int m = 0 ; m < 6 ; m ++ )
07896                                                                 //{
07897                                                                         //if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
07898                                                                         //{
07900                                                                                 //queue2->prepend( i, j, k ) ;
07901                                                                                 //break ;
07902                                                                         //}
07903                                                                 //}
07904                                                         //}
07905                                                 //}
07906                                         //}
07907                         //int wid = MAX_ERODE ;
07908                         //#ifdef VERBOSE
07909                         //printf("Total %d nodes\n", queue2->getNumElements() ) ;
07910 
07911 
07913                         //printf("Start erosion to %d...\n", wid) ;
07914                         //#endif
07915                         //gridQueueEle* ele ;
07916                         //gridPoint* gp ;
07917                         //int ox, oy, oz ;
07918                         //int score ;
07919                         //Volume* scrvol = new Volume( this->getSizeX() , this->getSizeY(), this->getSizeZ() ) ;
07920                         //for ( i = 0 ; i < getSizeX() * getSizeY() * getSizeZ() ; i ++ )
07921                         //{
07922                                 //scrvol->setDataAt( i, -1 ) ;
07923                         //}
07924 
07925         //#ifdef  NOISE_DIS_SHEET
07926                         //Volume* noisevol = new Volume( getSizeX(), getSizeY(), getSizeZ() ) ;
07927         //#endif
07928 
07929                         //for ( int curwid = 1 ; curwid <= wid ; curwid ++ )
07930                         //{
07934 
07935                                 //int numComplex = 0, numSimple = 0 ;
07936                                 //printf("Processing %d nodes in layer %d\n", queue2->getNumElements(), curwid) ;
07937 
07939                                 //We first need to assign curwid + 1 to every node in this layer
07940                                 //*/
07941                                 //queue2->reset() ;
07942                                 //ele = queue2->getNext() ;
07943                                 //while ( ele != NULL )
07944                                 //{
07945                                         //ox = ele->x ;
07946                                         //oy = ele->y ;
07947                                         //oz = ele->z ;
07948 
07949                                         //if ( getDataAt(ox,oy,oz) == curwid )
07950                                         //{
07951                                                 //ele = queue2->remove() ;
07952                                         //}
07953                                         //else
07954                                         //{
07955                                                 //setDataAt(ox,oy,oz, curwid) ;
07956                                                 //ele = queue2->getNext() ;
07957                                         //}
07958                                 //}
07959                                 //queue4->reset() ;
07960                                 //ele = queue4->getNext() ;
07961                                 //while ( ele != NULL )
07962                                 //{
07963                                         //ox = ele->x ;
07964                                         //oy = ele->y ;
07965                                         //oz = ele->z ;
07966 
07967                                         //queue2->prepend(ox,oy,oz) ;
07968                                         //ele = queue4->remove() ;
07969                                 //}
07970 
07972 
07973         //#ifdef NOISE_DIS_SHEET
07975                                 //queue2->reset() ;
07976 
07978                                 //int flag = 0 ;
07979                                 //while ( ( ele = queue2->getNext() ) != NULL )
07980                                 //{
07981                                         //ox = ele->x ;
07982                                         //oy = ele->y ;
07983                                         //oz = ele->z ;
07984                                         //if ( NOISE_DIS_SHEET <= 1 )
07985                                         //{
07986                                                 //noisevol->setDataAt( ox, oy, oz, 0 ) ;
07987                                         //}
07988                                         //else
07989                                         //{
07990                                                 //flag = 0 ;
07991                                                 //for ( int m = 0 ; m < 6 ; m ++ )
07992                                                 //{
07993                                                         //int nx = ox + neighbor6[m][0] ;
07994                                                         //int ny = oy + neighbor6[m][1] ;
07995                                                         //int nz = oz + neighbor6[m][2] ;
07996                                                         //if ( getDataAt( nx, ny, nz ) == 0 )
07997                                                         //{
07998                                                                 //noisevol->setDataAt( ox, oy, oz, 1 ) ;
07999                                                                 //flag = 1 ;
08000                                                                 //break ;
08001                                                         //}
08002                                                 //}
08003                                                 //if ( ! flag )
08004                                                 //{
08005                                                         //noisevol->setDataAt( ox, oy, oz, 0 ) ;
08006                                                 //}
08007                                         //}
08008                                 //}
08009 
08010                                 //for ( int cur = 1 ; cur < NOISE_DIS_SHEET ; cur ++ )
08011                                 //{
08012                                         //queue2->reset() ;
08013                                         //int count = 0 ;
08014 
08015                                         //while ( ( ele = queue2->getNext() ) != NULL )
08016                                         //{
08017                                                 //ox = ele->x ;
08018                                                 //oy = ele->y ;
08019                                                 //oz = ele->z ;
08020 
08021                                                 //if ( noisevol->getDataAt( ox, oy, oz ) == 1 )
08022                                                 //{
08023                                                         //continue ;
08024                                                 //}
08025 
08026                                                 //flag = 0 ;
08027                                                 //for ( int m = 0 ; m < 6 ; m ++ )
08028                                                 //{
08029                                                         //int nx = ox + neighbor6[m][0] ;
08030                                                         //int ny = oy + neighbor6[m][1] ;
08031                                                         //int nz = oz + neighbor6[m][2] ;
08032                                                         //if ( getDataAt( nx, ny, nz ) > 0 && noisevol->getDataAt( nx, ny, nz ) == 1 )
08033                                                         //{
08034                                                                 //noisevol->setDataAt( ox, oy, oz, 1 ) ;
08035                                                                 //count ++ ;
08036                                                                 //break ;
08037                                                         //}
08038                                                 //}
08039                                         //}
08040 
08041                                         //if ( count == 0 )
08042                                         //{
08043                                                 //break ;
08044                                         //}
08045                                 //}
08046 
08047 
08048         //#endif
08049 
08051 
08055                                 //queue2->reset() ;
08056                                 //ele = queue2->getNext() ;
08057                                 //while ( ele != NULL )
08058                                 //{
08059                                         //ox = ele->x ;
08060                                         //oy = ele->y ;
08061                                         //oz = ele->z ;
08062 
08064         //#ifndef NOISE_DIS_SHEET
08065                                         //if ( isSheetEnd( ox, oy, oz ) || ! isSimple( ox, oy, oz ) )
08066         //#else
08067                                         //if ( isSheetEnd( ox, oy, oz, noisevol ) || ! isSimple( ox, oy, oz ) )
08068         //#endif
08069                                         //{
08071                                                 //setDataAt( ox, oy, oz, curwid + 1 ) ;
08072                                                 //queue3->prepend( ox, oy, oz ) ;
08073                                                 //ele = queue2->remove() ;
08074 
08075                                                 //numComplex ++ ;
08076                                         //}
08077                                         //else
08078                                         //{
08079                                                 //ele = queue2->getNext() ;
08080                                         //}
08081                                 //}
08082                                 //*/
08083 
08084 
08088                                 //queue2->reset() ;
08089                                 //ele = queue2->getNext() ;
08090                                 //while ( ele != NULL )
08091                                 //{
08092                                         //ox = ele->x ;
08093                                         //oy = ele->y ;
08094                                         //oz = ele->z ;
08095 
08097                                         //score = getNumPotComplex( ox, oy, oz ) ;
08098                                         //scrvol->setDataAt( ox, oy, oz, score ) ;
08099 
08101                                         //gp = new gridPoint ;
08102                                         //gp->x = ox ;
08103                                         //gp->y = oy ;
08104                                         //gp->z = oz ;
08106                                         //queue->add( gp, score ) ;
08107 
08108                                         //ele = queue2->remove() ;
08109                                 //}
08110 
08114                                 //delete queue2 ;
08115                                 //queue2 = queue3 ;
08116                                 //queue3 = new GridQueue2( ) ;
08117 
08118                                 //int nowComplex = 0 ;
08119 
08121                                 //while ( ! queue->isEmpty() )
08122                                 //{
08124                                         //queue->remove( gp, score ) ;
08125                                         //ox = gp->x ;
08126                                         //oy = gp->y ;
08127                                         //oz = gp->z ;
08128                                         //delete gp ;
08131 
08135                                         //if ( getDataAt( ox, oy, oz ) != curwid || (int) scrvol->getDataAt( ox, oy, oz ) != score )
08136                                         //{
08137                                                 //continue ;
08138                                         //}
08139 
08141 
08143                                         //setDataAt( ox, oy, oz, -1 ) ;
08144                                         //numSimple ++ ;
08146                                         //*/
08147 
08150         //#ifndef NOISE_DIS_SHEET
08152                                         //if ( (! isSimple( ox, oy, oz )) || isSheetEnd( ox, oy, oz ) )
08154         //#else
08156                                         //if ( ! isSimple( ox, oy, oz ) || isSheetEnd( ox, oy, oz, noisevol ) || isHelixEnd( ox, oy, oz, noisevol ))
08158         //#endif
08159                                         //{
08161                                                 //setDataAt( ox, oy, oz, curwid + 1 ) ;
08162                                                 //queue4->prepend( ox, oy, oz ) ;
08163                                                 //numComplex ++ ;
08164 
08165                                                 //nowComplex = 1 ;
08166                                         //}
08167                                         //else
08168                                         //{
08169                                                 //setDataAt( ox, oy, oz, -1 ) ;
08170                                                 //numSimple ++ ;
08171 
08172                                                 //if ( nowComplex )
08173                                                 //{
08174 
08176                                                 //}
08177                                         //}
08179 
08181                                         //for ( int m = 0 ; m < 6 ; m ++ )
08182                                         //{
08183                                                 //int nx = ox + neighbor6[m][0] ;
08184                                                 //int ny = oy + neighbor6[m][1] ;
08185                                                 //int nz = oz + neighbor6[m][2] ;
08186                                                 //if ( getDataAt( nx, ny, nz ) == 0 )
08187                                                 //{
08189                                                         //queue2->prepend( nx, ny, nz ) ;
08190                                                 //}
08191                                         //}
08192 
08194 
08197                                         //for ( i = -1 ; i < 2 ; i ++ )
08198                                                 //for ( j = -1 ; j < 2 ; j ++ )
08199                                                         //for ( k = -1 ; k < 2 ; k ++ )
08200                                                         //{
08201                                                                 //int nx = ox + i ;
08202                                                                 //int ny = oy + j ;
08203                                                                 //int nz = oz + k ;
08204 
08206                                                                 //if ( getDataAt( nx, ny, nz ) == curwid &&
08208         //#ifndef NOISE_DIS_SHEET
08209                                                                         //( isSheetEnd( nx, ny, nz ) || ! isSimple( nx, ny, nz ) ) )
08210         //#else
08211                                                                         //( isSheetEnd( nx, ny, nz, noisevol ) || ! isSimple( nx, ny, nz ) ) )
08212         //#endif
08213 
08214                                                                 //{
08216                                                                         //setDataAt( nx, ny, nz, curwid + 1 ) ;
08217                                                                         //queue2->prepend( nx, ny, nz ) ;
08218                                                                         //numComplex ++ ;
08219                                                                 //}
08220                                                         //}
08221                                         //*/
08222 
08225 
08226                                         //for ( i = -2 ; i < 3 ;i ++ )
08227                                                 //for ( j = -2 ; j < 3 ; j ++ )
08228                                                         //for ( k = -2 ; k < 3 ; k ++ )
08229                                                         //{
08230                                                                 //int nx = ox + i ;
08231                                                                 //int ny = oy + j ;
08232                                                                 //int nz = oz + k ;
08233 
08234                                                                 //if ( getDataAt( nx, ny, nz ) == curwid )
08235                                                                 //{
08237                                                                         //score = getNumPotComplex( nx, ny, nz ) ;
08238 
08239                                                                         //if ( score != (int) scrvol->getDataAt( nx, ny, nz ) )
08240                                                                         //{
08242                                                                                 //scrvol->setDataAt( nx, ny, nz, score ) ;
08244                                                                                 //gp = new gridPoint ;
08245                                                                                 //gp->x = nx ;
08246                                                                                 //gp->y = ny ;
08247                                                                                 //gp->z = nz ;
08249                                                                                 //queue->add( gp, score ) ;
08250                                                                         //}
08251                                                                 //}
08252                                                         //}
08253 
08254 
08255                                 //}
08256 
08257                                 //printf("%d complex, %d simple\n", numComplex, numSimple) ;
08258 
08259                                 //if ( numSimple == 0 )
08260                                 //{
08261                                                 //break ;
08262                                 //}
08263                         //}
08264 
08266                         //printf("Thresholding the volume to 0/1...\n") ;
08267                         //threshold( 0, 0, 1 ) ;
08268 
08269                 //}
08270 
08271                 //void Volume::surfaceSkeletonOld( float thr )
08272                 //{
08273                         //int i, j, k ;
08275                         //#ifdef VERBOSE
08276                         //printf("Thresholding the volume to -MAX_ERODE/0...\n") ;
08277                         //#endif
08278                         //threshold( thr, -MAX_ERODE, 0 ) ;
08279 
08281                         //#ifdef VERBOSE
08282                         //printf("Initializing queue...\n") ;
08283                         //#endif
08284                         //GridQueue2* queue2 = new GridQueue2( ) ;
08285                         //GridQueue2* queue3 = new GridQueue2( ) ;
08286                         //GridQueue2* queue4 = new GridQueue2( ) ;
08287 
08288                         //PriorityQueue <gridPoint,int> * queue = new PriorityQueue <gridPoint,int> ( MAX_QUEUELEN );
08289 
08290                         //for ( i = 0 ; i < getSizeX() ; i ++ )
08291                                 //for ( j = 0 ; j < getSizeY() ; j ++ )
08292                                         //for ( k = 0 ; k < getSizeZ() ; k ++ )
08293                                         //{
08294                                                 //if ( getDataAt( i, j, k ) >= 0 )
08295                                                 //{
08296                                                         //{
08297                                                                 //for ( int m = 0 ; m < 6 ; m ++ )
08298                                                                 //{
08299                                                                         //if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
08300                                                                         //{
08302                                                                                 //queue2->prepend( i, j, k ) ;
08303                                                                                 //break ;
08304                                                                         //}
08305                                                                 //}
08306                                                         //}
08307                                                 //}
08308                                         //}
08309                         //#ifdef VERBOSE
08310                         //printf("Total %d nodes\n", queue2->getNumElements() ) ;
08311                         //#endif
08312 
08314                         //int wid = MAX_ERODE ;
08315                         //#ifdef VERBOSE
08316                         //printf("Start erosion to %d...\n", wid) ;
08317                         //#endif
08318                         //gridQueueEle* ele ;
08319                         //gridPoint* gp ;
08320                         //int ox, oy, oz ;
08321                         //int score ;
08322                         //Volume* scrvol = new Volume( this->getSizeX() , this->getSizeY(), this->getSizeZ() ) ;
08323                         //for ( i = 0 ; i < getSizeX() * getSizeY() * getSizeZ() ; i ++ )
08324                         //{
08325                                 //scrvol->setDataAt( i, -1 ) ;
08326                         //}
08327 
08328         //#ifdef  NOISE_DIS_SHEET
08329                         //Volume* noisevol = new Volume( getSizeX(), getSizeY(), getSizeZ() ) ;
08330         //#endif
08331 
08332                         //for ( int curwid = 1 ; curwid <= wid ; curwid ++ )
08333                         //{
08337 
08338                                 //int numComplex = 0, numSimple = 0 ;
08339                                 //#ifdef VERBOSE
08340                                 //printf("Processing %d nodes in layer %d\n", queue2->getNumElements(), curwid) ;
08341                                 //#endif
08342 
08344                                 //We first need to assign curwid + 1 to every node in this layer
08345                                 //*/
08346                                 //queue2->reset() ;
08347                                 //ele = queue2->getNext() ;
08348                                 //while ( ele != NULL )
08349                                 //{
08350                                         //ox = ele->x ;
08351                                         //oy = ele->y ;
08352                                         //oz = ele->z ;
08353 
08354                                         //if ( getDataAt(ox,oy,oz) == curwid )
08355                                         //{
08356                                                 //ele = queue2->remove() ;
08357                                         //}
08358                                         //else
08359                                         //{
08360                                                 //setDataAt(ox,oy,oz, curwid) ;
08361                                                 //ele = queue2->getNext() ;
08362                                         //}
08363                                 //}
08364                                 //queue4->reset() ;
08365                                 //ele = queue4->getNext() ;
08366                                 //while ( ele != NULL )
08367                                 //{
08368                                         //ox = ele->x ;
08369                                         //oy = ele->y ;
08370                                         //oz = ele->z ;
08371 
08372                                         //queue2->prepend(ox,oy,oz) ;
08373                                         //ele = queue4->remove() ;
08374                                 //}
08375 
08377 
08378         //#ifdef NOISE_DIS_SHEET
08380                                 //queue2->reset() ;
08381 
08383                                 //int flag = 0 ;
08384                                 //while ( ( ele = queue2->getNext() ) != NULL )
08385                                 //{
08386                                         //ox = ele->x ;
08387                                         //oy = ele->y ;
08388                                         //oz = ele->z ;
08389                                         //if ( NOISE_DIS_SHEET <= 1 )
08390                                         //{
08391                                                 //noisevol->setDataAt( ox, oy, oz, 0 ) ;
08392                                         //}
08393                                         //else
08394                                         //{
08395                                                 //flag = 0 ;
08396                                                 //for ( int m = 0 ; m < 6 ; m ++ )
08397                                                 //{
08398                                                         //int nx = ox + neighbor6[m][0] ;
08399                                                         //int ny = oy + neighbor6[m][1] ;
08400                                                         //int nz = oz + neighbor6[m][2] ;
08401                                                         //if ( getDataAt( nx, ny, nz ) == 0 )
08402                                                         //{
08403                                                                 //noisevol->setDataAt( ox, oy, oz, 1 ) ;
08404                                                                 //flag = 1 ;
08405                                                                 //break ;
08406                                                         //}
08407                                                 //}
08408                                                 //if ( ! flag )
08409                                                 //{
08410                                                         //noisevol->setDataAt( ox, oy, oz, 0 ) ;
08411                                                 //}
08412                                         //}
08413                                 //}
08414 
08415                                 //for ( int cur = 1 ; cur < NOISE_DIS_SHEET ; cur ++ )
08416                                 //{
08417                                         //queue2->reset() ;
08418                                         //int count = 0 ;
08419 
08420                                         //while ( ( ele = queue2->getNext() ) != NULL )
08421                                         //{
08422                                                 //ox = ele->x ;
08423                                                 //oy = ele->y ;
08424                                                 //oz = ele->z ;
08425 
08426                                                 //if ( noisevol->getDataAt( ox, oy, oz ) == 1 )
08427                                                 //{
08428                                                         //continue ;
08429                                                 //}
08430 
08431                                                 //flag = 0 ;
08432                                                 //for ( int m = 0 ; m < 6 ; m ++ )
08433                                                 //{
08434                                                         //int nx = ox + neighbor6[m][0] ;
08435                                                         //int ny = oy + neighbor6[m][1] ;
08436                                                         //int nz = oz + neighbor6[m][2] ;
08437                                                         //if ( getDataAt( nx, ny, nz ) > 0 && noisevol->getDataAt( nx, ny, nz ) == 1 )
08438                                                         //{
08439                                                                 //noisevol->setDataAt( ox, oy, oz, 1 ) ;
08440                                                                 //count ++ ;
08441                                                                 //break ;
08442                                                         //}
08443                                                 //}
08444                                         //}
08445 
08446                                         //if ( count == 0 )
08447                                         //{
08448                                                 //break ;
08449                                         //}
08450                                 //}
08451 
08452 
08453         //#endif
08454 
08456 
08460                                 //queue2->reset() ;
08461                                 //ele = queue2->getNext() ;
08462                                 //while ( ele != NULL )
08463                                 //{
08464                                         //ox = ele->x ;
08465                                         //oy = ele->y ;
08466                                         //oz = ele->z ;
08467 
08469         //#ifndef NOISE_DIS_SHEET
08470                                         //if ( isSheetEnd( ox, oy, oz ) || ! isSimple( ox, oy, oz ) )
08471         //#else
08472                                         //if ( isSheetEnd( ox, oy, oz, noisevol ) || ! isSimple( ox, oy, oz ) )
08473         //#endif
08474                                         //{
08476                                                 //setDataAt( ox, oy, oz, curwid + 1 ) ;
08477                                                 //queue3->prepend( ox, oy, oz ) ;
08478                                                 //ele = queue2->remove() ;
08479 
08480                                                 //numComplex ++ ;
08481                                         //}
08482                                         //else
08483                                         //{
08484                                                 //ele = queue2->getNext() ;
08485                                         //}
08486                                 //}
08487                                 //*/
08488 
08489 
08493                                 //queue2->reset() ;
08494                                 //ele = queue2->getNext() ;
08495                                 //while ( ele != NULL )
08496                                 //{
08497                                         //ox = ele->x ;
08498                                         //oy = ele->y ;
08499                                         //oz = ele->z ;
08500 
08502                                         //score = getNumPotComplex( ox, oy, oz ) ;
08503                                         //scrvol->setDataAt( ox, oy, oz, score ) ;
08504 
08506                                         //gp = new gridPoint ;
08507                                         //gp->x = ox ;
08508                                         //gp->y = oy ;
08509                                         //gp->z = oz ;
08511                                         //queue->add( gp, score ) ;
08512 
08513                                         //ele = queue2->remove() ;
08514                                 //}
08515 
08519                                 //delete queue2 ;
08520                                 //queue2 = queue3 ;
08521                                 //queue3 = new GridQueue2( ) ;
08522 
08524                                 //while ( ! queue->isEmpty() )
08525                                 //{
08527                                         //queue->remove( gp, score ) ;
08528                                         //ox = gp->x ;
08529                                         //oy = gp->y ;
08530                                         //oz = gp->z ;
08531                                         //delete gp ;
08534 
08538                                         //if ( getDataAt( ox, oy, oz ) != curwid || (int) scrvol->getDataAt( ox, oy, oz ) != score )
08539                                         //{
08540                                                 //continue ;
08541                                         //}
08542 
08544 
08546                                         //setDataAt( ox, oy, oz, -1 ) ;
08547                                         //numSimple ++ ;
08549                                         //*/
08550 
08553         //#ifndef NOISE_DIS_SHEET
08555                                         //if ( (! isSimple( ox, oy, oz )) || isSheetEnd( ox, oy, oz ) )
08557         //#else
08559                                         //if ( ! isSimple( ox, oy, oz ) || isSheetEnd( ox, oy, oz, noisevol ) || isHelixEnd( ox, oy, oz, noisevol ))
08561         //#endif
08562                                         //{
08564                                                 //setDataAt( ox, oy, oz, curwid + 1 ) ;
08565                                                 //queue4->prepend( ox, oy, oz ) ;
08566                                                 //numComplex ++ ;
08567 
08568                                         //}
08569                                         //else
08570                                         //{
08571                                                 //setDataAt( ox, oy, oz, -1 ) ;
08572                                                 //numSimple ++ ;
08573 
08574                                         //}
08576 
08578                                         //for ( int m = 0 ; m < 6 ; m ++ )
08579                                         //{
08580                                                 //int nx = ox + neighbor6[m][0] ;
08581                                                 //int ny = oy + neighbor6[m][1] ;
08582                                                 //int nz = oz + neighbor6[m][2] ;
08583                                                 //if ( getDataAt( nx, ny, nz ) == 0 )
08584                                                 //{
08586                                                         //queue2->prepend( nx, ny, nz ) ;
08587                                                 //}
08588                                         //}
08589 
08591 
08594                                         //for ( i = -1 ; i < 2 ; i ++ )
08595                                                 //for ( j = -1 ; j < 2 ; j ++ )
08596                                                         //for ( k = -1 ; k < 2 ; k ++ )
08597                                                         //{
08598                                                                 //int nx = ox + i ;
08599                                                                 //int ny = oy + j ;
08600                                                                 //int nz = oz + k ;
08601 
08603                                                                 //if ( getDataAt( nx, ny, nz ) == curwid &&
08605         //#ifndef NOISE_DIS_SHEET
08606                                                                         //( isSheetEnd( nx, ny, nz ) || ! isSimple( nx, ny, nz ) ) )
08607         //#else
08608                                                                         //( isSheetEnd( nx, ny, nz, noisevol ) || ! isSimple( nx, ny, nz ) ) )
08609         //#endif
08610 
08611                                                                 //{
08613                                                                         //setDataAt( nx, ny, nz, curwid + 1 ) ;
08614                                                                         //queue2->prepend( nx, ny, nz ) ;
08615                                                                         //numComplex ++ ;
08616                                                                 //}
08617                                                         //}
08618                                         //*/
08619 
08622 
08623                                         //for ( i = -2 ; i < 3 ;i ++ )
08624                                                 //for ( j = -2 ; j < 3 ; j ++ )
08625                                                         //for ( k = -2 ; k < 3 ; k ++ )
08626                                                         //{
08627                                                                 //int nx = ox + i ;
08628                                                                 //int ny = oy + j ;
08629                                                                 //int nz = oz + k ;
08630 
08631                                                                 //if ( getDataAt( nx, ny, nz ) == curwid )
08632                                                                 //{
08634                                                                         //score = getNumPotComplex( nx, ny, nz ) ;
08635 
08636                                                                         //if ( score != (int) scrvol->getDataAt( nx, ny, nz ) )
08637                                                                         //{
08639                                                                                 //scrvol->setDataAt( nx, ny, nz, score ) ;
08641                                                                                 //gp = new gridPoint ;
08642                                                                                 //gp->x = nx ;
08643                                                                                 //gp->y = ny ;
08644                                                                                 //gp->z = nz ;
08646                                                                                 //queue->add( gp, score ) ;
08647                                                                         //}
08648                                                                 //}
08649                                                         //}
08650 
08651 
08652                                 //}
08653                                 //#ifdef VERBOSE
08654                                 //printf("%d complex, %d simple\n", numComplex, numSimple) ;
08655                                 //#endif
08656 
08657                                 //if ( numSimple == 0 )
08658                                 //{
08659                                                 //break ;
08660                                 //}
08661                         //}
08662 
08664                         //#ifdef VERBOSE
08665                         //printf("Thresholding the volume to 0/1...\n") ;
08666                         //#endif
08667                         //threshold( 0, 0, 1 ) ;
08668                         //delete queue;
08669 
08670                 //}
08671 
08672                 void Volume::surfaceSkeletonPres( float thr, Volume * preserve )
08673                 {
08674                         int i, j, k ;
08675                         // First, threshold the volume
08676                         #ifdef VERBOSE
08677                         printf("Thresholding the volume to -MAX_ERODE/0...\n") ;
08678                         #endif
08679                         threshold( thr, -MAX_ERODE, 0 ) ;
08680 
08681                         // Next, initialize the linked queue
08682                         #ifdef VERBOSE
08683                         printf("Initializing queue...\n") ;
08684                         #endif
08685                         GridQueue2* queue2 = new GridQueue2( ) ;
08686                         GridQueue2* queue3 = new GridQueue2( ) ;
08687                         GridQueue2* queue4 = new GridQueue2( ) ;
08688 
08689                         PriorityQueue <gridPoint,int> * queue = new PriorityQueue <gridPoint,int> ( MAX_QUEUELEN );
08690 
08691                         for ( i = 0 ; i < getSizeX() ; i ++ )
08692                                 for ( j = 0 ; j < getSizeY() ; j ++ )
08693                                         for ( k = 0 ; k < getSizeZ() ; k ++ )
08694                                         {
08695                                                 if ( getDataAt( i, j, k ) >= 0 ) {
08696                                                         if(preserve->getDataAt(i, j, k) > 0) {
08697                                                                 setDataAt(i, j, k, MAX_ERODE);
08698                                                         } else {
08699                                                                 for ( int m = 0 ; m < 6 ; m ++ )
08700                                                                 {
08701                                                                         if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
08702                                                                         {
08703                                                                                 // setDataAt( i, j, k, 1 ) ;
08704                                                                                 queue2->prepend( i, j, k ) ;
08705                                                                                 break ;
08706                                                                         }
08707                                                                 }
08708                                                         }
08709                                                 }
08710                                         }
08711                         int wid = MAX_ERODE ;
08712                         #ifdef VERBOSE
08713                         printf("Total %d nodes\n", queue2->getNumElements() ) ;
08714                         printf("Start erosion to %d...\n", wid) ;
08715                         #endif
08716 
08717 
08718                         // Perform erosion
08719                         gridQueueEle* ele ;
08720                         gridPoint* gp ;
08721                         int ox, oy, oz ;
08722                         int score ;
08723                         Volume* scrvol = new Volume( this->getSizeX() , this->getSizeY(), this->getSizeZ() ) ;
08724                         for ( i = 0 ; i < getSizeX() * getSizeY() * getSizeZ() ; i ++ )
08725                         {
08726                                 scrvol->setDataAt( i, -1 ) ;
08727                         }
08728 
08729         #ifdef  NOISE_DIS_SHEET
08730                         Volume* noisevol = new Volume( getSizeX(), getSizeY(), getSizeZ() ) ;
08731         #endif
08732 
08733                         for ( int curwid = 1 ; curwid <= wid ; curwid ++ )
08734                         {
08735                                 // At the start of each iteration,
08736                                 // queue2 and queue4 holds all the nodes for this layer
08737                                 // queue3 and queue are empty
08738 
08739                                 int numComplex = 0, numSimple = 0 ;
08740                                 #ifdef VERBOSE
08741                                 printf("Processing %d nodes in layer %d\n", queue2->getNumElements(), curwid) ;
08742                                 #endif
08743 
08744                                 /*
08745                                 We first need to assign curwid + 1 to every node in this layer
08746                                 */
08747                                 queue2->reset() ;
08748                                 ele = queue2->getNext() ;
08749                                 while ( ele != NULL )
08750                                 {
08751                                         ox = ele->x ;
08752                                         oy = ele->y ;
08753                                         oz = ele->z ;
08754 
08755                                         if ( getDataAt(ox,oy,oz) == curwid )
08756                                         {
08757                                                 ele = queue2->remove() ;
08758                                         }
08759                                         else
08760                                         {
08761                                                 setDataAt(ox,oy,oz, curwid) ;
08762                                                 ele = queue2->getNext() ;
08763                                         }
08764                                 }
08765                                 queue4->reset() ;
08766                                 ele = queue4->getNext() ;
08767                                 while ( ele != NULL )
08768                                 {
08769                                         ox = ele->x ;
08770                                         oy = ele->y ;
08771                                         oz = ele->z ;
08772 
08773                                         queue2->prepend(ox,oy,oz) ;
08774                                         ele = queue4->remove() ;
08775                                 }
08776 
08777                                 // Now queue2 holds all the nodes for this layer
08778 
08779         #ifdef NOISE_DIS_SHEET
08780                                 /* Extra step: classify nodes in queue2 into noise and non-noise nodes */
08781                                 queue2->reset() ;
08782 
08783                                 // First run
08784                                 int flag = 0 ;
08785                                 while ( ( ele = queue2->getNext() ) != NULL )
08786                                 {
08787                                         ox = ele->x ;
08788                                         oy = ele->y ;
08789                                         oz = ele->z ;
08790                                         if ( NOISE_DIS_SHEET <= 1 )
08791                                         {
08792                                                 noisevol->setDataAt( ox, oy, oz, 0 ) ;
08793                                         }
08794                                         else
08795                                         {
08796                                                 flag = 0 ;
08797                                                 for ( int m = 0 ; m < 6 ; m ++ )
08798                                                 {
08799                                                         int nx = ox + neighbor6[m][0] ;
08800                                                         int ny = oy + neighbor6[m][1] ;
08801                                                         int nz = oz + neighbor6[m][2] ;
08802                                                         if ( getDataAt( nx, ny, nz ) == 0 )
08803                                                         {
08804                                                                 noisevol->setDataAt( ox, oy, oz, 1 ) ;
08805                                                                 flag = 1 ;
08806                                                                 break ;
08807                                                         }
08808                                                 }
08809                                                 if ( ! flag )
08810                                                 {
08811                                                         noisevol->setDataAt( ox, oy, oz, 0 ) ;
08812                                                 }
08813                                         }
08814                                 }
08815 
08816                                 for ( int cur = 1 ; cur < NOISE_DIS_SHEET ; cur ++ )
08817                                 {
08818                                         queue2->reset() ;
08819                                         int count = 0 ;
08820 
08821                                         while ( ( ele = queue2->getNext() ) != NULL )
08822                                         {
08823                                                 ox = ele->x ;
08824                                                 oy = ele->y ;
08825                                                 oz = ele->z ;
08826 
08827                                                 if ( noisevol->getDataAt( ox, oy, oz ) == 1 )
08828                                                 {
08829                                                         continue ;
08830                                                 }
08831 
08832                                                 flag = 0 ;
08833                                                 for ( int m = 0 ; m < 6 ; m ++ )
08834                                                 {
08835                                                         int nx = ox + neighbor6[m][0] ;
08836                                                         int ny = oy + neighbor6[m][1] ;
08837                                                         int nz = oz + neighbor6[m][2] ;
08838                                                         if ( getDataAt( nx, ny, nz ) > 0 && noisevol->getDataAt( nx, ny, nz ) == 1 )
08839                                                         {
08840                                                                 noisevol->setDataAt( ox, oy, oz, 1 ) ;
08841                                                                 count ++ ;
08842                                                                 break ;
08843                                                         }
08844                                                 }
08845                                         }
08846 
08847                                         if ( count == 0 )
08848                                         {
08849                                                 break ;
08850                                         }
08851                                 }
08852 
08853 
08854         #endif
08855 
08856                                 /* Commented for debugging
08857 
08858                                 // First,
08859                                 // check for complex nodes in queue2
08860                                 // move them from queue2 to queue3
08861                                 queue2->reset() ;
08862                                 ele = queue2->getNext() ;
08863                                 while ( ele != NULL )
08864                                 {
08865                                         ox = ele->x ;
08866                                         oy = ele->y ;
08867                                         oz = ele->z ;
08868 
08869                                         // Check simple
08870         #ifndef NOISE_DIS_SHEET
08871                                         if ( isSheetEnd( ox, oy, oz ) || ! isSimple( ox, oy, oz ) )
08872         #else
08873                                         if ( isSheetEnd( ox, oy, oz, noisevol ) || ! isSimple( ox, oy, oz ) )
08874         #endif
08875                                         {
08876                                                 // Complex, set to next layer
08877                                                 setDataAt( ox, oy, oz, curwid + 1 ) ;
08878                                                 queue3->prepend( ox, oy, oz ) ;
08879                                                 ele = queue2->remove() ;
08880 
08881                                                 numComplex ++ ;
08882                                         }
08883                                         else
08884                                         {
08885                                                 ele = queue2->getNext() ;
08886                                         }
08887                                 }
08888                                 */
08889 
08890 
08891                                 // Next,
08892                                 // Compute score for each node left in queue2
08893                                 // move them into priority queue
08894                                 queue2->reset() ;
08895                                 ele = queue2->getNext() ;
08896                                 while ( ele != NULL )
08897                                 {
08898                                         ox = ele->x ;
08899                                         oy = ele->y ;
08900                                         oz = ele->z ;
08901 
08902                                         // Compute score
08903                                         score = getNumPotComplex( ox, oy, oz ) ;
08904                                         scrvol->setDataAt( ox, oy, oz, score ) ;
08905 
08906                                         // Push to queue
08907                                         gp = new gridPoint ;
08908                                         gp->x = ox ;
08909                                         gp->y = oy ;
08910                                         gp->z = oz ;
08911                                         // queue->add( gp, -score ) ;
08912                                         queue->add( gp, score ) ;
08913 
08914                                         ele = queue2->remove() ;
08915                                 }
08916 
08917                                 // Rename queue3 to be queue2,
08918                                 // Clear queue3
08919                                 // From now on, queue2 holds nodes of next level
08920                                 delete queue2 ;
08921                                 queue2 = queue3 ;
08922                                 queue3 = new GridQueue2( ) ;
08923 
08924 
08925                                 // Next, start priority queue iteration
08926                                 while ( ! queue->isEmpty() )
08927                                 {
08928                                         // Retrieve the node with the highest score
08929                                         queue->remove( gp, score ) ;
08930                                         ox = gp->x ;
08931                                         oy = gp->y ;
08932                                         oz = gp->z ;
08933                                         delete gp ;
08934                                         // printf("%d\n", score);
08935         //                              score = -score ;
08936 
08937                                         // Ignore the node
08938                                         // if it has been processed before
08939                                         // or it has an updated score
08940                                         if ( getDataAt( ox, oy, oz ) != curwid || (int) scrvol->getDataAt( ox, oy, oz ) != score )
08941                                         {
08942                                                 continue ;
08943                                         }
08944 
08945                                         /* Commented for debugging
08946 
08947                                         // Remove this simple node
08948                                         setDataAt( ox, oy, oz, -1 ) ;
08949                                         numSimple ++ ;
08950                                         // printf("Highest score: %d\n", score) ;
08951                                         */
08952 
08953                                         /* Added for debugging */
08954                                         // Check simple
08955         #ifndef NOISE_DIS_SHEET
08956                                         // if ( hasFeatureFace( ox, oy, oz ) )
08957                                         if ( (! isSimple( ox, oy, oz )) || isSheetEnd( ox, oy, oz ) )
08958                                         // if ( hasIsolatedFace(ox,oy,oz)  && (! isNoiseSheetEnd(ox,oy,oz)))
08959         #else
08960                                         // if ( ! isSimple( ox, oy, oz ) || isSheetEnd( ox, oy, oz, noisevol ) )
08961                                         if ( ! isSimple( ox, oy, oz ) || isSheetEnd( ox, oy, oz, noisevol ) || isHelixEnd( ox, oy, oz, noisevol ))
08962                                         // if ( isBertrandEndPoint( ox, oy, oz ) )
08963         #endif
08964                                         {
08965                                                 // Complex, set to next layer
08966                                                 setDataAt( ox, oy, oz, curwid + 1 ) ;
08967                                                 queue4->prepend( ox, oy, oz ) ;
08968                                                 numComplex ++ ;
08969 
08970                                         }
08971                                         else
08972                                         {
08973                                                 setDataAt( ox, oy, oz, -1 ) ;
08974                                                 numSimple ++ ;
08975 
08976                                         }
08977                                         /* Adding ends */
08978 
08979                                         // Move its neighboring unvisited node to queue2
08980                                         for ( int m = 0 ; m < 6 ; m ++ )
08981                                         {
08982                                                 int nx = ox + neighbor6[m][0] ;
08983                                                 int ny = oy + neighbor6[m][1] ;
08984                                                 int nz = oz + neighbor6[m][2] ;
08985                                                 if ( getDataAt( nx, ny, nz ) == 0 )
08986                                                 {
08987                                                         // setDataAt( nx, ny, nz, curwid + 1 ) ;
08988                                                         queue2->prepend( nx, ny, nz ) ;
08989                                                 }
08990                                         }
08991 
08992                                         /* Commented for debugging
08993 
08994                                         // Find complex nodes in its 3x3 neighborhood
08995                                         // move them to queue2
08996                                         for ( i = -1 ; i < 2 ; i ++ )
08997                                                 for ( j = -1 ; j < 2 ; j ++ )
08998                                                         for ( k = -1 ; k < 2 ; k ++ )
08999                                                         {
09000                                                                 int nx = ox + i ;
09001                                                                 int ny = oy + j ;
09002                                                                 int nz = oz + k ;
09003 
09004                                                                 // Check simple
09005                                                                 if ( getDataAt( nx, ny, nz ) == curwid &&
09006                                                                         // ( isSheetEnd( ox, oy, oz ) || ! isSimple( nx, ny, nz )) )
09007         #ifndef NOISE_DIS_SHEET
09008                                                                         ( isSheetEnd( nx, ny, nz ) || ! isSimple( nx, ny, nz ) ) )
09009         #else
09010                                                                         ( isSheetEnd( nx, ny, nz, noisevol ) || ! isSimple( nx, ny, nz ) ) )
09011         #endif
09012 
09013                                                                 {
09014                                                                         // Complex, set to next layer
09015                                                                         setDataAt( nx, ny, nz, curwid + 1 ) ;
09016                                                                         queue2->prepend( nx, ny, nz ) ;
09017                                                                         numComplex ++ ;
09018                                                                 }
09019                                                         }
09020                                         */
09021 
09022                                         // Update scores for nodes in its 5x5 neighborhood
09023                                         // insert them back into priority queue
09024 
09025                                         for ( i = -2 ; i < 3 ;i ++ )
09026                                                 for ( j = -2 ; j < 3 ; j ++ )
09027                                                         for ( k = -2 ; k < 3 ; k ++ )
09028                                                         {
09029                                                                 int nx = ox + i ;
09030                                                                 int ny = oy + j ;
09031                                                                 int nz = oz + k ;
09032 
09033                                                                 if ( getDataAt( nx, ny, nz ) == curwid )
09034                                                                 {
09035                                                                         // Compute score
09036                                                                         score = getNumPotComplex( nx, ny, nz ) ;
09037 
09038                                                                         if ( score != (int) scrvol->getDataAt( nx, ny, nz ) )
09039                                                                         {
09040                                                                                 // printf("Update\n") ;
09041                                                                                 scrvol->setDataAt( nx, ny, nz, score ) ;
09042                                                                                 // Push to queue
09043                                                                                 gp = new gridPoint ;
09044                                                                                 gp->x = nx ;
09045                                                                                 gp->y = ny ;
09046                                                                                 gp->z = nz ;
09047                                                                                 // queue->add( gp, -score ) ;
09048                                                                                 queue->add( gp, score ) ;
09049                                                                         }
09050                                                                 }
09051                                                         }
09052 
09053 
09054                                 }
09055 
09056                                 #ifdef VERBOSE
09057                                 printf("%d complex, %d simple\n", numComplex, numSimple) ;
09058                                 #endif
09059 
09060                                 if ( numSimple == 0 )
09061                                 {
09062                                                 break ;
09063                                 }
09064                         }
09065 
09066                         // Finally, clean up
09067                         #ifdef VERBOSE
09068                         printf("Thresholding the volume to 0/1...\n") ;
09069                         #endif
09070                         threshold( 0, 0, 1 ) ;
09071 
09072                         delete scrvol;
09073                         delete queue;
09074                         delete queue2;
09075                         delete queue3;
09076                         delete queue4;
09077 
09078                 }
09079 
09081                 //void Volume::bertrandSurfaceSkeleton2( float thr )
09082                 //{
09083                         //int i, j, k ;
09084 
09086                         //#ifdef VERBOSE
09087                         //printf("Thresholding the volume to -MAX_ERODE/0...\n") ;
09088                         //#endif
09089                         //threshold( thr, -MAX_ERODE, 0 ) ;
09090 
09091 
09093                         //printf("Initializing queues...\n") ;
09094                         //GridQueue2* queue2 = new GridQueue2( ) ;
09095                         //GridQueue2* queue3 = new GridQueue2( ) ;
09096                         //GridQueue2* queue4 = new GridQueue2( ) ;
09097                         //Volume* fvol = new Volume( this->getSizeX(), this->getSizeY(), this->getSizeZ(), 0 ) ;
09098 
09099                         //for ( i = 0 ; i < getSizeX() ; i ++ )
09100                                 //for ( j = 0 ; j < getSizeY() ; j ++ )
09101                                         //for ( k = 0 ; k < getSizeZ() ; k ++ )
09102                                         //{
09103                                                 //if ( getDataAt( i, j, k ) == 0 )
09104                                                 //{
09105                                                         //for ( int m = 0 ; m < 6 ; m ++ )
09106                                                         //{
09107                                                                 //if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
09108                                                                 //{
09109                                                                         //fvol->setDataAt( i, j, k, 1 ) ;
09110                                                                         //queue2->prepend( i, j, k ) ;
09111                                                                         //break ;
09112                                                                 //}
09113                                                         //}
09114                                                 //}
09115                                         //}
09116                         //printf("Total %d nodes\n", queue2->getNumElements() ) ;
09117 
09119                         //int it = 0 ;
09120                         //gridQueueEle* ele ;
09121                         //while ( ++ it )
09122                         //{
09123                                 //printf("Iteration %d... nodes in queue: %d...", it, queue2->getNumElements()) ;
09124 
09126 
09127                                 //int deleted = 0 ;
09128                                 //for ( i = 0 ; i < 6 ; i ++ )
09129                                 //{
09134 
09135                                         //queue2->reset() ;
09136                                         //ele = queue2->getNext() ;
09137 
09139                                         //while ( ele != NULL )
09140                                         //{
09141                                                 //int ox = ele->x ;
09142                                                 //int oy = ele->y ;
09143                                                 //int oz = ele->z ;
09144 
09145                                                 //if ( isBertrandBorder( ox,oy,oz, i ) )
09146                                                 //{
09147                                                         //if ( ! isBertrandEndPoint( ox,oy,oz ) )
09148                                                         //{
09150                                                                 //ele = queue2->remove() ;
09151                                                                 //queue3->prepend( ox, oy, oz ) ;
09152 
09154                                                                 //for ( int m = 0 ; m < 6 ; m ++ )
09155                                                                 //{
09156                                                                         //int nx = ox + neighbor6[m][0] ;
09157                                                                         //int ny = oy + neighbor6[m][1] ;
09158                                                                         //int nz = oz + neighbor6[m][2] ;
09159                                                                         //if ( fvol->getDataAt( nx, ny, nz ) == 0 )
09160                                                                         //{
09161                                                                                 //fvol->setDataAt( nx, ny, nz, 1 ) ;
09162                                                                                 //queue4->prepend( nx, ny, nz ) ;
09163                                                                         //}
09164                                                                 //}
09165                                                         //}
09166                                                         //else
09167                                                         //{
09168                                                                 //ele = queue2->getNext() ;
09169                                                         //}
09170                                                 //}
09171                                                 //else
09172                                                 //{
09173                                                         //ele = queue2->getNext() ;
09174                                                 //}
09175                                         //}
09176 
09180 
09182                                         //if ( queue3->getNumElements() == 0 )
09183                                         //{
09185                                         //}
09186                                         //else
09187                                         //{
09188                                                 //queue3->reset() ;
09189                                                 //ele = queue3->getNext() ;
09190                                                 //while ( ele != NULL )
09191                                                 //{
09192                                                         //setDataAt( ele->x, ele->y, ele->z, -1 ) ;
09193                                                         //ele = queue3->remove() ;
09194                                                         //deleted ++ ;
09195                                                 //}
09196                                         //}
09197 
09199                                 //}
09200 
09203                                 //queue4->reset() ;
09204                                 //ele = queue4->getNext() ;
09205                                 //while ( ele != NULL )
09206                                 //{
09207                                         //queue2->prepend( ele->x, ele->y, ele->z) ;
09208                                         //ele = queue4->remove() ;
09209                                 //}
09210 
09211                                 //if ( deleted == 0 )
09212                                 //{
09213                                         //printf("No more deletable nodes.\n");
09214                                         //break ;
09215                                 //}
09216                                 //else
09217                                 //{
09218                                         //printf("Deleted: %d\n", deleted) ;
09219                                 //}
09220                         //}
09221 
09223                         //#ifdef VERBOSE
09224                         //printf("Thresholding the volume to 0/1...\n") ;
09225                         //#endif
09226                         //threshold( 0, 0, 1 ) ;
09227 
09228                 //}
09229 
09230 
09231 
09232                 //void Volume::bertrandSurfaceSkeleton( float thr )
09233                 //{
09234                         //int i, j, k ;
09235 
09237                         //#ifdef VERBOSE
09238                         //printf("Thresholding the volume to -MAX_ERODE/0...\n") ;
09239                         //#endif
09240                         //threshold( thr, -MAX_ERODE, 0 ) ;
09241 
09243                         //GridQueue2* queue2 = new GridQueue2( ) ;
09244                         //int dir = 0, ct = 0 ;
09245                         //while( ++ct )
09246                         //{
09247                                 //printf("Round %d, direction %d...", ct, dir) ;
09248                                 //queue2->reset() ;
09249 
09250                                 //for ( i = 0 ; i < getSizeX() ; i ++ )
09251                                         //for ( j = 0 ; j < getSizeY() ; j ++ )
09252                                                 //for ( k = 0 ; k < getSizeZ() ; k ++ )
09253                                                 //{
09254                                                         //if ( getDataAt(i,j,k) >= 0 )
09255                                                         //{
09256                                                                 //if ( isBertrandBorder( i,j,k, dir ) )
09257                                                                 //{
09258                                                                         //if ( ! isBertrandEndPoint( i,j,k ) )
09259                                                                         //{
09260                                                                                 //queue2->prepend( i,j,k ) ;
09261                                                                         //}
09262                                                                 //}
09263                                                         //}
09264 
09265                                                 //}
09266 
09267 
09268                                 //if ( queue2->getNumElements() == 0 )
09269                                 //{
09270                                         //printf("Done.\n");
09271                                         //break ;
09272                                 //}
09273                                 //else
09274                                 //{
09275                                         //queue2->reset() ;
09276                                         //printf("%d nodes deleted.\n", queue2->getNumElements()) ;
09277                                         //gridQueueEle* ele = queue2->getNext() ;
09278                                         //while ( ele != NULL )
09279                                         //{
09280                                                 //setDataAt( ele->x, ele->y, ele->z, -1 ) ;
09281                                                 //ele = queue2->remove() ;
09282                                         //}
09283                                 //}
09284                                 //dir = ( dir + 1 ) % 6 ;
09285                         //}
09286 
09288                         //#ifdef VERBOSE
09289                         //printf("Thresholding the volume to 0/1...\n") ;
09290                         //#endif
09291                         //threshold( 0, 0, 1 ) ;
09292                 //}
09293 
09294 
09296                 //void Volume::palagyiSurfaceSkeleton( float thr )
09297                 //{
09298                         //int i, j, k ;
09299 
09301                         //#ifdef VERBOSE
09302                         //printf("Thresholding the volume to 0/1...\n") ;
09303                         //#endif
09304                         //threshold( thr, 0, 1 ) ;
09305 
09307                         //printf("Initializing surface endpoints templates...\n") ;
09308                         //ThinningTemplate* US[6] ;
09309 
09310                         //int b0[] = {12,13} ;
09311                         //int w0[] = {2, 5, 8, 11, 14, 17, 20, 23, 26} ;
09312                         //int ob0[] = {10, 16} ;
09313                         //int ob20[] = {4, 22} ;
09314                         //int nu[] = {0} ;
09315                         //US[0] = new ThinningTemplate( b0, 2, w0, 9, ob0, 2, ob20, 2, nu, 0, nu, 0 ) ;
09316                         //US[1] = new ThinningTemplate( US[0], 0, 1 ) ;
09318                         //int b01[] = {13,16} ;
09319                         //int w01[] = {0,1,2,9,10,11,18,19,20} ;
09320                         //int ob01[] = {12, 14} ;
09321                         //int ob201[] = {4, 22} ;
09322                         //US[1] = new ThinningTemplate( b01, 2, w01, 9, ob01, 2, ob201, 2, nu, 0, nu, 0 ) ;
09323                         //*/
09324 
09325                         //int b1[] = {12,13,16,22} ;
09326                         //int w1[] = {2,10,11,14} ;
09327                         //int ow[] = {1,5} ;
09328                         //US[2] = new ThinningTemplate( b1, 4, w1, 4, nu, 0, nu, 0, ow, 2, nu, 0 ) ;
09329                         //US[3] = new ThinningTemplate( US[2], 0 ) ;
09330 
09331                         //int b2[] = {2,12,13,16,22} ;
09332                         //int w2[] = {10,11,14} ;
09333                         //int op[] = {1,5} ;
09334                         //US[4] = new ThinningTemplate( b2, 5, w2, 3, nu, 0, nu, 0, nu, 0, op, 2 ) ;
09335                         //US[5] = new ThinningTemplate( US[4], 0 ) ;
09336 
09337                         //ThinningTemplate * NE[6], * WD[6], * ES[6], * UW[6], * ND[6], * SW[6], * UN[6], * ED[6], * NW[6], * UE[6], * SD[6] ;
09338 
09339                         //for ( i = 0 ; i < 6 ; i ++ )
09340                         //{
09341                                 //SD[i] = new ThinningTemplate( US[i], 0, 1 ) ;
09342                                 //ND[i] = new ThinningTemplate( SD[i], 0, 1 ) ;
09343                                 //UN[i] = new ThinningTemplate( ND[i], 0, 1 ) ;
09344 
09345                                 //ES[i] = new ThinningTemplate( US[i], 1, 1 ) ;
09346                                 //NE[i] = new ThinningTemplate( ES[i], 2, 1 ) ;
09347                                 //NW[i] = new ThinningTemplate( NE[i], 2, 1 ) ;
09348                                 //SW[i] = new ThinningTemplate( NW[i], 2, 1 ) ;
09349 
09350                                 //UE[i] = new ThinningTemplate( US[i], 2, 1 ) ;
09351                                 //ED[i] = new ThinningTemplate( UE[i], 1, 1 ) ;
09352                                 //WD[i] = new ThinningTemplate( ED[i], 1, 1 ) ;
09353                                 //UW[i] = new ThinningTemplate( WD[i], 1, 1 ) ;
09354                         //}
09355 
09356                         //ThinningTemplate** alltemps[12] = { US, NE, WD, ES, UW, ND, SW, UN, ED, NW, UE, SD } ;
09357 
09359                         //printf("Initializing queues...\n") ;
09360                         //GridQueue2* queue2 = new GridQueue2( ) ;
09361                         //GridQueue2* queue3 = new GridQueue2( ) ;
09362                         //GridQueue2* queue4 = new GridQueue2( ) ;
09363                         //Volume* fvol = new Volume( this->getSizeX(), this->getSizeY(), this->getSizeZ(), 0 ) ;
09364 
09365                         //for ( i = 0 ; i < getSizeX() ; i ++ )
09366                                 //for ( j = 0 ; j < getSizeY() ; j ++ )
09367                                         //for ( k = 0 ; k < getSizeZ() ; k ++ )
09368                                         //{
09369                                                 //if ( getDataAt( i, j, k ) == 1 )
09370                                                 //{
09371                                                         //for ( int m = 0 ; m < 6 ; m ++ )
09372                                                         //{
09373                                                                 //if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) == 0 )
09374                                                                 //{
09375                                                                         //fvol->setDataAt( i, j, k, 1 ) ;
09376                                                                         //queue2->prepend( i, j, k ) ;
09377                                                                         //break ;
09378                                                                 //}
09379                                                         //}
09380                                                 //}
09381                                         //}
09382                         //printf("Total %d nodes\n", queue2->getNumElements() ) ;
09383 
09385                         //int it = 0 ;
09386                         //int vox[3][3][3] ;
09387                         //gridQueueEle* ele ;
09388                         //while ( queue2->getNumElements() > 0 )
09389                         //{
09390                                 //printf("Iteration %d... nodes in queue: %d...", it, queue2->getNumElements()) ;
09391 
09393 
09394                                 //int deleted = 0 ;
09395                                 //for ( i = 0 ; i < 12 ; i ++ )
09396                                 //{
09401 
09402                                         //queue2->reset() ;
09403                                         //ele = queue2->getNext()               ;
09404 
09406                                         //while ( ele != NULL )
09407                                         //{
09408                                                 //int ox = ele->x ;
09409                                                 //int oy = ele->y ;
09410                                                 //int oz = ele->z ;
09411 
09413                                                 //int match = 0 ;
09414                                                 //for ( int ci = -1 ; ci < 2 ; ci ++ )
09415                                                         //for ( int cj = -1 ; cj < 2 ; cj ++ )
09416                                                                 //for ( int ck = -1 ; ck < 2 ; ck ++ )
09417                                                                 //{
09418                                                                         //vox[ ci + 1 ][cj + 1][ck + 1] = (int)getDataAt( ox + ci, oy + cj, oz + ck ) ;
09419                                                                 //}
09420 
09421                                                 //for ( j = 0 ; j < 6 ; j ++ )
09423                                                 //{
09424                                                         //if ( alltemps[i][j]->isMatch( vox ) )
09425                                                         //{
09427                                                                 //if ( ! isSimple2( vox ) )
09428                                                                 //{
09429                                                                         //printf("Wrong! %d %d\n", i, j) ;
09430                                                                         //for ( int cci = 0 ; cci < 3 ; cci ++ )
09431                                                                         //{
09432                                                                                 //for ( int ccj = 0 ; ccj < 3 ; ccj ++ )
09433                                                                                 //{
09434                                                                                         //for ( int cck = 0 ; cck < 3 ; cck ++ )
09435                                                                                         //{
09436                                                                                                 //printf("%d ",vox[ cci ][ccj][cck]);
09437                                                                                         //}
09438                                                                                         //printf(" , ") ;
09439                                                                                 //}
09440                                                                                 //printf("\n") ;
09441                                                                         //}
09442                                                                         //exit(0) ;
09443                                                                 //}
09444 
09446                                                                 //ele = queue2->remove() ;
09447                                                                 //queue3->prepend( ox, oy, oz ) ;
09448 
09450                                                                 //for ( int m = 0 ; m < 6 ; m ++ )
09451                                                                 //{
09452                                                                         //int nx = ox + neighbor6[m][0] ;
09453                                                                         //int ny = oy + neighbor6[m][1] ;
09454                                                                         //int nz = oz + neighbor6[m][2] ;
09455                                                                         //if ( fvol->getDataAt( nx, ny, nz ) == 0 )
09456                                                                         //{
09457                                                                                 //fvol->setDataAt( nx, ny, nz, 1 ) ;
09458                                                                                 //queue4->prepend( nx, ny, nz ) ;
09459                                                                         //}
09460                                                                 //}
09461 
09462                                                                 //match = 1 ;
09463                                                                 //break ;
09464                                                         //}
09465                                                 //}
09466 
09467                                                 //if ( match == 0 )
09468                                                 //{
09469                                                         //ele = queue2->getNext() ;
09470                                                 //}
09471                                         //}
09472 
09476 
09478                                         //queue3->reset() ;
09479                                         //ele = queue3->getNext() ;
09480                                         //while ( ele != NULL )
09481                                         //{
09482                                                 //setDataAt( ele->x, ele->y, ele->z, 0 ) ;
09483                                                 //ele = queue3->remove() ;
09484                                                 //deleted ++ ;
09485