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 //} 09486 09488 //} 09489 09492 //queue4->reset() ; 09493 //ele = queue4->getNext() ; 09494 //while ( ele != NULL ) 09495 //{ 09496 //queue2->prepend( ele->x, ele->y, ele->z) ; 09497 //ele = queue4->remove() ; 09498 //} 09499 09500 //if ( deleted == 0 ) 09501 //{ 09502 //printf("No more deletable nodes.\n"); 09503 //break ; 09504 //} 09505 //else 09506 //{ 09507 //printf("Deleted: %d\n", deleted) ; 09508 //} 09509 //} 09510 //} 09511 09515 void Volume::threshold( double thr ) 09516 { 09517 threshold( thr, 0, 1, 0, true) ; 09518 } 09519 09520 void Volume::threshold( double thr, int out, int in ) 09521 { 09522 threshold( thr, out, in, out, true) ; 09523 } 09524 09525 void Volume::threshold( double thr, int out, int in, int boundary) 09526 { 09527 threshold(thr, out, in, boundary, true); 09528 } 09529 09530 void Volume::threshold( double thr, int out, int in, int boundary, bool markBoundary) 09531 { 09532 float val; 09533 for ( int i = 0 ; i < getSizeX() ; i ++ ) 09534 for ( int j = 0 ; j < getSizeY() ; j ++ ) 09535 for ( int k = 0 ; k < getSizeZ() ; k ++ ) 09536 { 09537 val = (float)getDataAt(i, j, k); 09538 if(markBoundary) { 09539 if ( i > 1 && i < getSizeX() - 2 && j > 1 && j < getSizeY() - 2 && k > 1 && k < getSizeZ() - 2 ) { 09540 if(val < thr) { 09541 setDataAt(i, j, k, out); 09542 } else { 09543 setDataAt(i, j, k, in); 09544 } 09545 } 09546 else 09547 { 09548 setDataAt(i, j, k, boundary); 09549 } 09550 } else { 09551 if(val < thr) { 09552 setDataAt(i, j, k, out); 09553 } else { 09554 setDataAt(i, j, k, in); 09555 } 09556 } 09557 } 09558 } 09559 09560 //void Volume::threshold2( double thr, int out, int in ) 09561 //{ 09562 //for ( int i = 0 ; i < getSizeX() ; i ++ ) 09563 //for ( int j = 0 ; j < getSizeY() ; j ++ ) 09564 //for ( int k = 0 ; k < getSizeZ() ; k ++ ) { 09565 //double val = getDataAt(i, j, k); 09566 //if(val <= thr) { 09567 //setDataAt(i, j, k, out); 09568 //} else { 09569 //setDataAt(i, j, k, in); 09570 //} 09571 //} 09572 //} 09573 09574 //void Volume::smooth( float alpha ) 09575 //{ 09576 //VolumeData * smoothedData = new VolumeData(getSizeX(), getSizeY(), getSizeZ(), 0, 0, 0, volData); 09577 09578 //for (int i = 1; i < getSizeX() - 1; i++) 09579 //for (int j = 1; j < getSizeY() - 1; j++) 09580 //for (int k = 1; k < getSizeZ() - 1; k++) { 09581 //float v = (float)getDataAt( i - 1, j, k ) + 09582 //(float)getDataAt( i + 1, j, k ) + 09583 //(float)getDataAt( i, j - 1, k ) + 09584 //(float)getDataAt( i, j + 1, k ) + 09585 //(float)getDataAt( i, j, k - 1 ) + 09586 //(float)getDataAt( i, j, k + 1 ) ; 09587 //smoothedData->SetDataAt(i, j, k, smoothedData->GetDataAt(i, j, k) * alpha + ( 1 - alpha ) * v / 6); 09588 //} 09589 //delete volData; 09590 //volData = smoothedData; 09591 //} 09592 09593 //void Volume::normalize( double min, double max ) 09594 //{ 09595 //double imin = getMin() ; 09596 //double imax = getMax() ; 09597 //double irange = imax - imin ; 09598 //double range = max - min ; 09599 09600 //int size = volData->GetMaxIndex(); 09601 //for(int i = 0 ; i < size ; i ++) { 09602 //setDataAt(i, ((getDataAt(i) - (float)imin ) / (float)irange) * (float)range + (float)min); 09603 //} 09604 //} 09605 09606 //void Volume::normalize( double min, double max, double thresh, double ithresh ) 09607 //{ 09608 //double imin = getMin() ; 09609 //double imax = getMax() ; 09610 //double irange1 = ithresh - imin ; 09611 //double irange2 = imax - ithresh ; 09612 //double range1 = thresh - min; 09613 //double range2 = max - thresh ; 09614 09615 //int size = volData->GetMaxIndex(); 09616 //for (int i = 0; i < size; i++) { 09617 //if (getDataAt(i) < ithresh) { 09618 //setDataAt(i, ((getDataAt(i) - (float)imin ) / (float)irange1) * (float)range1 + (float)min); 09619 //} 09620 //else 09621 //{ 09622 //setDataAt(i, (float)max - (( (float)imax - getDataAt(i)) / (float)irange2) * (float)range2); 09623 //} 09624 //} 09625 //} 09626 09628 09629 //Volume * Volume::getDataRange(int x, int y, int z, int radius) { 09630 //Volume * range = new Volume(radius*2+1, radius*2+1, radius*2+1); 09631 //for(int xx = x-radius; xx <= x+radius; xx++) { 09632 //for(int yy = y-radius; yy <= y+radius; yy++) { 09633 //for(int zz = z-radius; zz <= z+radius; zz++) { 09634 //range->setDataAt(xx-x+radius, yy-y+radius, zz-z+radius, getDataAt(xx, yy, zz)); 09635 //} 09636 //} 09637 //} 09638 //return range; 09639 //} 09640 09642 //double Volume::getInterpDataAt( double x, double y, double z ) 09643 //{ 09645 //double rad = getSizeX() / 4.0 ; 09646 //double cent = ( getSizeX() - 1 ) / 2.0 ; 09647 09648 //double ox = x - cent ; 09649 //double oy = y - cent ; 09650 //double oz = z - cent ; 09651 09652 //double a = -0.3 ; 09653 //double nx = ox ; 09654 //double ny = cos( a ) * oy + sin( a ) * oz ; 09655 //double nz = - sin( a ) * oy + cos( a ) * oz ; 09656 09657 //double b = 1.4 ; 09658 //double nnx = cos( b ) * nx + sin( b ) * ny - 2; 09659 //double nny = -sin( b ) * nx + cos ( b ) * ny - 1; 09660 //double nnz = nz + 1; 09661 09662 //double dis = nnx * nnx + nny * nny ; 09663 //return 10 - 10 * dis / ( rad * rad ) ; 09664 //*/ 09665 09666 //double rvalue ; 09667 //int hx = (int) ceil( x ) ; 09668 //int lx = (int) floor( x ) ; 09669 //int hy = (int) ceil( y ) ; 09670 //int ly = (int) floor( y ) ; 09671 //int hz = (int) ceil( z ) ; 09672 //int lz = (int) floor( z ) ; 09673 09674 //double x1 = x - lx, x2 = 1 - x1 ; 09675 //double r1 = x2 * getDataAt( lx, ly, lz) + x1 * getDataAt( hx, ly, lz ) ; 09676 //double r2 = x2 * getDataAt( lx, ly, hz) + x1 * getDataAt( hx, ly, hz ) ; 09677 //double r3 = x2 * getDataAt( lx, hy, lz) + x1 * getDataAt( hx, hy, lz ) ; 09678 //double r4 = x2 * getDataAt( lx, hy, hz) + x1 * getDataAt( hx, hy, hz ) ; 09679 09680 //double y1 = y - ly, y2 = 1 - y1 ; 09681 //double r5 = y2 * r1 + y1 * r3 ; 09682 //double r6 = y2 * r2 + y1 * r4 ; 09683 09684 //double z1 = z - lz, z2 = 1 - z1 ; 09685 //rvalue = z2 * r5 + z1 * r6 ; 09686 09687 //return rvalue ; 09688 //} 09689 09691 //void Volume::rotateX ( double a ) 09692 //{ 09693 //int i ; 09694 //int sizeX = getSizeX(), sizeY = getSizeY(), sizeZ = getSizeZ(); 09695 09696 //if ( sizeX != sizeY || sizeX != sizeZ) { 09697 //return ; 09698 //} 09699 09700 //VolumeData * newData = new VolumeData(sizeX, sizeY, sizeZ, 0, 0, 0, volData); 09701 09702 //double cent = ( sizeX - 1 ) / 2.0 ; 09703 //for ( i = 0 ; i < sizeX ; i ++ ) 09704 //for ( int j = 0 ; j < sizeY ; j ++ ) 09705 //for ( int k = 0 ; k < sizeZ ; k ++ ) 09706 //{ 09707 //double x = i - cent ; 09708 //double y = j - cent ; 09709 //double z = k - cent ; 09710 09711 //double nx = x + cent ; 09712 //double ny = cos( a ) * y + sin( a ) * z + cent ; 09713 //double nz = - sin( a ) * y + cos( a ) * z + cent ; 09714 09715 //if ( nx < 0 ) { 09716 //nx = 0 ; 09717 //} else if ( nx > sizeX - 1 ) { 09718 //nx = sizeX - 1 ; 09719 //} 09720 09721 //if ( ny < 0 ) { 09722 //ny = 0 ; 09723 //} else if ( ny > sizeY - 1 ) { 09724 //ny = sizeY - 1 ; 09725 //} 09726 09727 //if ( nz < 0 ) { 09728 //nz = 0 ; 09729 //} else if ( nz > sizeZ - 1 ) { 09730 //nz = sizeZ - 1 ; 09731 //} 09732 09733 //newData->SetDataAt(i, j, k, (float)getInterpDataAt( nx, ny, nz )); 09734 //} 09735 09736 //delete volData; 09737 //volData = newData; 09738 //} 09739 09740 09742 //void Volume::toMathematicaFile( char* fname ) 09743 //{ 09744 //FILE* fout = fopen( fname, "w" ) ; 09745 09746 //fprintf( fout, "{" ) ; 09747 //for ( int i = 0 ; i < getSizeX() ; i ++ ) 09748 //{ 09749 //fprintf( fout, "{" ) ; 09750 //for ( int j = 0 ; j < getSizeY() ; j ++ ) 09751 //{ 09752 //fprintf( fout, "{" ) ; 09753 //for ( int k = 0 ; k < getSizeZ() ; k ++ ) 09754 //{ 09755 //fprintf( fout, "%.15f", getDataAt( i, j, k ) ) ; 09756 //if ( k < getSizeZ() - 1 ) 09757 //{ 09758 //fprintf( fout, "," ) ; 09759 //} 09760 //} 09761 //fprintf( fout, "}" ) ; 09762 //if ( j < getSizeY() - 1 ) 09763 //{ 09764 //fprintf( fout, ",\n" ) ; 09765 //} else { 09766 //fprintf( fout, "\n" ) ; 09767 //} 09768 //} 09769 //fprintf( fout, "}" ) ; 09770 //if ( i < getSizeX() - 1 ) 09771 //{ 09772 //fprintf( fout, ",\n\n\n" ) ; 09773 //} else { 09774 //fprintf( fout, "\n\n\n" ) ; 09775 //} 09776 //} 09777 //fprintf(fout,"}") ; 09778 09779 //fclose( fout ) ; 09780 09781 //} 09782 09784 //void Volume::toMathematicaFile( char* fname, int lx, int hx, int ly, int hy, int lz, int hz ) 09785 //{ 09786 //FILE* fout = fopen( fname, "w" ) ; 09787 09788 //fprintf( fout, "{" ) ; 09789 //for ( int i = lx ; i < hx ; i ++ ) 09790 //{ 09791 //fprintf( fout, "{" ) ; 09792 //for ( int j = ly ; j < hy ; j ++ ) 09793 //{ 09794 //fprintf( fout, "{" ) ; 09795 //for ( int k = lz ; k < hz ; k ++ ) 09796 //{ 09797 //fprintf( fout, "%.15f", getDataAt( i, j, k ) ) ; 09798 //if ( k < hz - 1 ) 09799 //{ 09800 //fprintf( fout, "," ) ; 09801 //} 09802 //} 09803 //fprintf( fout, "}" ) ; 09804 //if ( j < hy - 1 ) 09805 //{ 09806 //fprintf( fout, "," ) ; 09807 //} 09808 //} 09809 //fprintf( fout, "}" ) ; 09810 //if ( i < hx - 1 ) 09811 //{ 09812 //fprintf( fout, "," ) ; 09813 //} 09814 //} 09815 //fprintf(fout,"}") ; 09816 09817 //fclose( fout ) ; 09818 09819 //} 09820 09821 //void Volume::toOFFCells( char* fname ) 09822 //{ 09823 //toOFFCells( fname, 0.0001f ) ; 09824 //} 09825 //void Volume::toOFFCells2( char* fname ) 09826 //{ 09827 //toOFFCells2( fname, 0.0001f ) ; 09828 //} 09829 09830 //void Volume::toOFFCells2( char* fname, float thr ) 09831 //{ 09832 //int i, j, k ; 09833 //Volume* indvol = new Volume( getSizeX(), getSizeY(), getSizeZ(), -1 ) ; 09834 09836 //int numverts = 0, numfaces = 0 ; 09837 //for ( i = 0 ; i < getSizeX() ; i ++ ) 09838 //for ( j = 0 ; j < getSizeY() ; j ++ ) 09839 //for ( k = 0 ; k < getSizeZ() ; k ++ ) 09840 //{ 09841 //if ( getDataAt( i, j, k ) >= thr ) 09842 //{ 09843 //indvol->setDataAt( i,j,k, numverts ) ; 09844 //numverts ++ ; 09845 09846 //for ( int mi = 0 ; mi < 3 ; mi ++ ) 09847 //{ 09848 //int find = mi * 4 + 3 ; 09849 //int isFace = 1 ; 09850 //for ( int mj = 0 ; mj < 4 ; mj ++ ) 09851 //{ 09852 //int nx = i + sheetNeighbor[find][mj][0] ; 09853 //int ny = j + sheetNeighbor[find][mj][1] ; 09854 //int nz = k + sheetNeighbor[find][mj][2] ; 09855 09856 //if ( getDataAt( nx, ny, nz ) < thr ) 09857 //{ 09858 //isFace = 0 ; 09859 //break ; 09860 //} 09861 //} 09862 //if ( isFace ) 09863 //{ 09864 //numfaces ++ ; 09865 //} 09866 09867 //int eind = mi * 2 + 1 ; 09868 //if ( getDataAt( i + neighbor6[eind][0], j + neighbor6[eind][1], k + neighbor6[eind][2]) >= thr ) 09869 //{ 09870 //numfaces ++ ; 09871 //} 09872 //} 09873 //} 09874 //} 09875 09876 //FILE* fin = fopen( fname, "w" ) ; 09877 //fprintf( fin, "OFF\n" ) ; 09878 //fprintf( fin, "%d %d 0\n", numverts, numfaces ) ; 09879 09881 //for ( i = 0 ; i < getSizeX() ; i ++ ) 09882 //for ( j = 0 ; j < getSizeY() ; j ++ ) 09883 //for ( k = 0 ; k < getSizeZ() ; k ++ ) 09884 //{ 09885 //if ( getDataAt( i,j,k ) >= thr ) 09886 //{ 09887 //fprintf( fin, "%d %d %d\n", i, j, k ) ; 09888 //} 09889 //} 09890 09892 //for ( i = 0 ; i < getSizeX() ; i ++ ) 09893 //for ( j = 0 ; j < getSizeY() ; j ++ ) 09894 //for ( k = 0 ; k < getSizeZ() ; k ++ ) 09895 //{ 09896 //if ( getDataAt( i,j,k ) >= thr ) 09897 //{ 09898 //int thisvt = (int)( indvol->getDataAt( i,j,k ) ); 09899 //for ( int mi = 0 ; mi < 3 ; mi ++ ) 09900 //{ 09901 //int find = mi * 4 + 3 ; 09902 //int isFace = 1 ; 09903 //int vts[4] ; 09904 //for ( int mj = 0 ; mj < 4 ; mj ++ ) 09905 //{ 09906 //int nx = i + sheetNeighbor[find][mj][0] ; 09907 //int ny = j + sheetNeighbor[find][mj][1] ; 09908 //int nz = k + sheetNeighbor[find][mj][2] ; 09909 09910 //vts[ mj ] = (int)( indvol->getDataAt( nx, ny, nz ) ); 09911 09912 //if ( getDataAt( nx, ny, nz ) < thr ) 09913 //{ 09914 //isFace = 0 ; 09915 //break ; 09916 //} 09917 //} 09918 //if ( isFace ) 09919 //{ 09920 //fprintf( fin, "4 %d %d %d %d\n", vts[0], vts[1], vts[3], vts[2] ) ; 09921 //} 09922 09923 //int eind = mi * 2 + 1 ; 09924 //int mx = i + neighbor6[eind][0] ; 09925 //int my = j + neighbor6[eind][1] ; 09926 //int mz = k + neighbor6[eind][2] ; 09927 //int vt = (int)( indvol->getDataAt( mx, my, mz ) ); 09928 //if ( getDataAt( mx, my, mz ) >= thr ) 09929 //{ 09930 //fprintf( fin, "4 %d %d %d %d\n", thisvt, thisvt, vt, vt ) ; 09931 //} 09932 //} 09933 //} 09934 //} 09935 09936 //fclose( fin ) ; 09937 //delete indvol ; 09938 //} 09939 09940 //void Volume::toOFFCells( char* fname, float thr ) 09941 //{ 09942 //int i, j, k ; 09944 09946 //int numverts = 0, numfaces = 0 ; 09947 //for ( i = 0 ; i < getSizeX() ; i ++ ) 09948 //for ( j = 0 ; j < getSizeY() ; j ++ ) 09949 //for ( k = 0 ; k < getSizeZ() ; k ++ ) 09950 //{ 09951 //if ( getDataAt( i, j, k ) >= thr ) 09952 //{ 09953 //numverts += 8 ; 09954 //for ( int mi = 0 ; mi < 6 ; mi ++ ) 09955 //{ 09956 //if ( getDataAt( i + neighbor6[mi][0], j + neighbor6[mi][1], k + neighbor6[mi][2] ) < thr ) 09957 //{ 09958 //numfaces ++ ; 09959 //} 09960 //} 09961 //} 09962 //} 09963 09964 //FILE* fin = fopen( fname, "w" ) ; 09965 //fprintf( fin, "OFF\n" ) ; 09966 //fprintf( fin, "%d %d 0\n", numverts, numfaces ) ; 09967 09969 //for ( i = 0 ; i < getSizeX() ; i ++ ) 09970 //for ( j = 0 ; j < getSizeY() ; j ++ ) 09971 //for ( k = 0 ; k < getSizeZ() ; k ++ ) 09972 //{ 09973 //if ( getDataAt( i,j,k ) >= thr ) 09974 //{ 09975 //float ox = i - 0.5f ; 09976 //float oy = j - 0.5f ; 09977 //float oz = k - 0.5f ; 09978 09979 //for ( int mi = 0 ; mi < 2 ; mi ++ ) 09980 //for ( int mj = 0 ; mj < 2 ; mj ++ ) 09981 //for ( int mk = 0 ; mk < 2 ; mk ++ ) 09982 //{ 09983 //fprintf( fin, "%f %f %f\n", ox + mi, oy + mj, oz + mk ) ; 09984 //} 09985 //} 09986 //} 09987 09989 //int ct = 0 ; 09990 //for ( i = 0 ; i < getSizeX() ; i ++ ) 09991 //for ( j = 0 ; j < getSizeY() ; j ++ ) 09992 //for ( k = 0 ; k < getSizeZ() ; k ++ ) 09993 //{ 09994 //if ( getDataAt( i,j,k ) >= thr ) 09995 //{ 09996 //for ( int mi = 0 ; mi < 6 ; mi ++ ) 09997 //{ 09998 //if ( getDataAt( i + neighbor6[mi][0], j + neighbor6[mi][1], k + neighbor6[mi][2] ) < thr ) 09999 //{ 10000 //fprintf( fin, "4 %d %d %d %d\n", cubeFaces[mi][0] + ct, cubeFaces[mi][1] + ct, cubeFaces[mi][2] + ct, cubeFaces[mi][3] + ct ) ; 10001 //} 10002 //} 10003 10004 //ct += 8 ; 10005 //} 10006 //} 10007 10008 //fclose( fin ) ; 10010 //} 10011 10012 //void Volume::segment( float threshold, Volume* lowvol, Volume* highvol, char* mrcfile ) 10013 //{ 10014 //int i,j,k ; 10015 //Volume* segvol = new Volume( getSizeX(), getSizeY(), getSizeZ(), 0 ) ; 10016 10017 //for ( i = 0 ; i < getSizeX() ; i ++ ) 10018 //for ( j = 0 ; j < getSizeY() ; j ++ ) 10019 //for ( k = 0 ; k < getSizeZ() ; k ++ ) 10020 //{ 10021 //if ( lowvol->getDataAt(i,j,k) > 0 ) 10022 //{ 10023 //segvol->setDataAt( i,j,k, 1 ) ; 10024 //} 10025 //else if ( highvol->getDataAt(i,j,k) > 0 ) 10026 //{ 10027 //segvol->setDataAt( i,j,k, 2 ) ; 10028 //} 10029 //else 10030 //{ 10031 //segvol->setDataAt( i,j,k, 0 ) ; 10032 //} 10033 //} 10034 10035 //writeSegmentation( threshold, segvol, NULL, mrcfile ) ; 10036 //} 10037 10038 //void Volume::segment( float threshold, Volume* vol, int maxDis, char* mrcfile ) 10039 //{ 10040 //int i,j; 10041 //Volume* testvol = NULL ; 10042 //Volume* disvol = new Volume( getSizeX(), getSizeY(), getSizeZ() ) ; 10043 //printf("Writing distance transform to %d levels.\n", maxDis); 10044 10045 //int totNodes = 0 ; 10046 //int size = getSizeX() * getSizeY() * getSizeZ() ; 10047 //for ( i = maxDis ; i >= 0 ; i -- ) 10048 //{ 10049 //if ( i == 1 ) continue ; 10050 10051 //int nodes = 0 ; 10052 //testvol = new Volume( getSizeX(), getSizeY(), getSizeZ(), 0, 0, 0, vol ) ; 10053 //testvol->erodeSheet( i ) ; 10054 10055 //for ( j = 0 ; j < size ; j ++ ) 10056 //{ 10057 //if ( disvol->getDataAt(j) == 0 && testvol->getDataAt(j) > 0 ) 10058 //{ 10059 //disvol->setDataAt( j, i + 1 ) ; 10060 //nodes ++ ; 10061 //} 10062 //} 10063 //printf("Level %d has %d nodes.\n", i, nodes ); 10064 //totNodes += nodes ; 10065 //delete testvol ; 10066 //} 10067 //printf("Totally %d nodes.\n", totNodes ); 10068 10069 //writeSegmentation( threshold, disvol, NULL, mrcfile ) ; 10070 //} 10071 10074 //void Volume::writeSegmentation( float threshold, Volume* segvol, char* txtfile, char* mrcfile ) 10075 //{ 10076 //printf("Start segmentation.\n") ; 10077 //int i,j,k ; 10078 //Volume* vvol = new Volume( getSizeX(), getSizeY(), getSizeZ(), 0 ) ; 10079 //Volume* tvol1 = new Volume( getSizeX(), getSizeY(), getSizeZ(), 0 ) ; 10080 //Volume* tvol2 = new Volume( getSizeX(), getSizeY(), getSizeZ(), 0 ) ; 10081 10083 //GridQueue2* queue = new GridQueue2() ; 10084 //GridQueue2* queue2 = new GridQueue2() ; 10085 //GridQueue2* queue3 = new GridQueue2() ; 10086 //for ( i = 0 ; i < getSizeX() ; i ++ ) 10087 //for ( j = 0 ; j < getSizeY() ; j ++ ) 10088 //for ( k = 0 ; k < getSizeZ() ; k ++ ) 10089 //{ 10090 //if ( getDataAt( i,j,k ) < threshold || segvol->getDataAt(i,j,k) <= 0 ) 10091 //{ 10092 //continue ; 10093 //} 10094 10095 //vvol->setDataAt(i,j,k,1) ; 10096 //queue->prepend( i,j,k ) ; 10097 //} 10098 10100 //printf("Dilation...") ; 10101 //int ox, oy, oz ; 10102 //gridQueueEle* ele ; 10103 //while ( queue->getNumElements() > 0 ) 10104 //{ 10108 10110 //queue->reset() ; 10111 //ele = queue->getNext() ; 10112 //while ( ele != NULL ) 10113 //{ 10114 //ox = ele->x ; 10115 //oy = ele->y ; 10116 //oz = ele->z ; 10117 //double seg = segvol->getDataAt(ox,oy,oz) ; 10118 //int isBorder = 0 ; 10119 10120 //for ( int m = 0 ; m < 6 ; m ++ ) 10121 //{ 10122 //int nx = ox + neighbor6[m][0] ; 10123 //int ny = oy + neighbor6[m][1] ; 10124 //int nz = oz + neighbor6[m][2] ; 10125 //if ( getDataAt( nx, ny, nz ) >= threshold && vvol->getDataAt( nx, ny, nz ) == 0 ) 10126 //{ 10127 //double ct = (int) tvol1->getDataAt(nx,ny,nz) ; 10128 //double val = tvol2->getDataAt(nx,ny,nz) ; 10129 10130 //tvol1->setDataAt(nx,ny,nz, ct + 1 ) ; 10131 //tvol2->setDataAt(nx,ny,nz, val + seg ) ; 10132 10133 //if (ct == 0) 10134 //{ 10135 //queue2->prepend( nx, ny, nz ) ; 10136 //} 10137 //} 10138 //else if ( getDataAt( nx, ny, nz ) < threshold ) 10139 //{ 10140 //isBorder = 1 ; 10141 //} 10142 //} 10143 10144 //if ( isBorder ) 10145 //{ 10146 //queue3->prepend( ox, oy, oz ) ; 10147 //} 10148 10149 //ele = queue->remove() ; 10150 //} 10151 10153 //queue2->reset() ; 10154 //while ( ( ele = queue2->getNext() ) != NULL ) 10155 //{ 10156 //ox = ele->x ; 10157 //oy = ele->y ; 10158 //oz = ele->z ; 10159 10160 //double ct = (int) tvol1->getDataAt(ox,oy,oz) ; 10161 //double val = tvol2->getDataAt(ox,oy,oz) ; 10162 10163 //if ( ct == 0 ) 10164 //{ 10165 //printf("Wrong! %f\n", ct) ; 10166 //} 10167 //segvol->setDataAt(ox,oy,oz, val / ct ) ; 10168 //vvol->setDataAt(ox,oy,oz, 1 ) ; 10169 //} 10170 10172 //GridQueue2* temp = queue2 ; 10173 //queue2 = queue ; 10174 //queue = temp ; 10175 //} 10176 //printf("Done.\n") ; 10177 10179 //for ( i = 0 ; i < getSizeX() * getSizeY() * getSizeZ() ; i ++ ) 10180 //{ 10181 //if ( getDataAt(i) >= threshold && segvol->getDataAt(i) == 0 ) 10182 //{ 10183 //segvol->setDataAt(i, 1) ; 10184 //} 10185 //else 10186 //{ 10187 //segvol->setDataAt(i, 0) ; 10188 //} 10189 //} 10190 //*/ 10191 10195 10196 10198 //printf("Growing out one layer...\n") ; 10200 //queue2->reset() ; 10201 //queue3->reset() ; 10202 //ele = queue3->getNext() ; 10203 //while ( ele != NULL ) 10204 //{ 10205 //ox = ele->x ; 10206 //oy = ele->y ; 10207 //oz = ele->z ; 10208 //double seg = segvol->getDataAt(ox,oy,oz) ; 10209 10210 //for ( int mx = -1 ; mx < 2 ; mx ++ ) 10211 //for ( int my = -1 ; my < 2 ; my ++ ) 10212 //for ( int mz = -1 ; mz < 2 ; mz ++ ) 10213 //{ 10214 //int nx = ox + mx ; // neighbor6[m][0] ; 10215 //int ny = oy + my ; // neighbor6[m][1] ; 10216 //int nz = oz + mz ; // neighbor6[m][2] ; 10217 //if ( vvol->getDataAt( nx, ny, nz ) == 0 ) 10218 //{ 10219 //double ct = (int) tvol1->getDataAt(nx,ny,nz) ; 10220 //double val = tvol2->getDataAt(nx,ny,nz) ; 10221 10222 //tvol1->setDataAt(nx,ny,nz, ct + 1 ) ; 10223 //tvol2->setDataAt(nx,ny,nz, val + seg ) ; 10224 10225 //if (ct == 0) 10226 //{ 10227 //queue2->prepend( nx, ny, nz ) ; 10228 //} 10229 //} 10230 //} 10231 //ele = queue3->remove() ; 10232 //} 10233 10235 //queue2->reset() ; 10236 //while ( ( ele = queue2->getNext() ) != NULL ) 10237 //{ 10238 //ox = ele->x ; 10239 //oy = ele->y ; 10240 //oz = ele->z ; 10241 10242 //double ct = tvol1->getDataAt(ox,oy,oz) ; 10243 //double val = tvol2->getDataAt(ox,oy,oz) ; 10244 10245 //if ( ct == 0 ) 10246 //{ 10247 //printf("Wrong! %f\n", ct) ; 10248 //} 10249 //segvol->setDataAt(ox,oy,oz, val / ct ) ; 10250 //} 10251 10252 //printf("Writing...") ; 10253 //segvol->toMRCFile( mrcfile ) ; 10254 //segvol->toMRCFile( "../colors.mrc" ) ; 10255 //printf("Done.\n") ; 10256 10257 //printf("Segmentation...") ; 10258 //for ( i = 0 ; i < getSizeX() * getSizeY() * getSizeZ() ; i ++ ) 10259 //{ 10260 //float segval = (float)segvol->getDataAt(i) ; 10262 //if ( segval > 1.5f ) 10263 //{ 10264 //tvol1->setDataAt(i, getDataAt(i) ) ; 10265 //} 10266 //else 10267 //{ 10268 //tvol1->setDataAt(i, -1) ; 10269 //} 10270 10272 //if ( segval < 1.5f && segval >= 1 ) 10273 //{ 10274 //tvol2->setDataAt(i, getDataAt(i) ) ; 10275 //} 10276 //else 10277 //{ 10278 //tvol2->setDataAt(i, -1) ; 10279 //} 10280 //} 10281 //char nname[1024] ; 10282 //sprintf( nname, "%s_sheet.mrc", mrcfile ) ; 10283 //tvol1->toMRCFile( nname ) ; 10284 //sprintf( nname, "%s_helix.mrc", mrcfile ) ; 10285 //tvol2->toMRCFile( nname ) ; 10286 //printf("Done.\n") ; 10287 //return ; 10288 10290 //if ( txtfile != NULL ) 10291 //{ 10292 //printf("Writing to %s...", txtfile) ; 10294 //queue->reset() ; 10295 //for ( i = 0 ; i < getSizeX() ; i ++ ) 10296 //for ( j = 0 ; j < getSizeY() ; j ++ ) 10297 //for ( k = 0 ; k < getSizeZ() ; k ++ ) 10298 //{ 10299 //if ( getDataAt( i, j, k ) >= threshold ) 10300 //{ 10301 //for ( int m = 0 ; m < 6 ; m ++ ) 10302 //{ 10303 //if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < threshold ) 10304 //{ 10305 //queue->prepend( i, j, k ) ; 10306 //break ; 10307 //} 10308 //} 10309 //} 10310 //} 10311 10312 //FILE* fout = fopen( txtfile, "w" ) ; 10313 //fprintf( fout, "%d\n", queue->getNumElements() ) ; 10314 //queue->reset() ; 10315 //while( (ele=queue->getNext()) != NULL ) 10316 //{ 10317 //ox = ele->x ; 10318 //oy = ele->y ; 10319 //oz = ele->z ; 10320 //fprintf( fout, "%d %d %d %f\n", ox, oy, oz, segvol->getDataAt(ox,oy,oz) ) ; 10321 //} 10322 //fclose( fout ) ; 10323 //printf("Done.\n") ; 10324 //} 10325 //*/ 10326 //} 10327 10328 //void Volume::floodFill( float thr ) 10329 //{ 10330 //int i; 10332 //#ifdef VERBOSE 10333 //printf("Thresholding the volume to 0/1...\n") ; 10334 //#endif 10335 //threshold( thr, 0, 1 ) ; 10336 10338 //Volume* tvol = new Volume( getSizeX(), getSizeY(), getSizeZ(), 0 ) ; 10339 //GridQueue2* queue = new GridQueue2() ; 10340 //gridQueueEle* ele ; 10341 //queue->prepend( 0, 0, 0 ) ; 10342 //tvol->setDataAt( 0,0,0, -1 ) ; 10343 10345 //printf("Flood filling...\n") ; 10346 //queue->reset() ; 10347 //ele = queue->getNext() ; 10348 //int ct = 1 ; 10349 //while( ele != NULL ) 10350 //{ 10351 //int ox = ele->x ; 10352 //int oy = ele->y ; 10353 //int oz = ele->z ; 10354 //queue->remove() ; 10355 10356 //for ( int m = 0 ; m < 6 ; m ++ ) 10357 //{ 10358 //int nx = ox + neighbor6[m][0] ; 10359 //int ny = oy + neighbor6[m][1] ; 10360 //int nz = oz + neighbor6[m][2] ; 10361 //if ( nx < 0 || nx >= getSizeX() || ny < 0 || ny >= getSizeY() || nz < 0 || nz >= getSizeZ() ) 10362 //{ 10363 //continue ; 10364 //} 10365 //if ( tvol->getDataAt( nx, ny, nz ) == 0 && getDataAt( nx, ny, nz ) == 0 ) 10366 //{ 10367 //queue->prepend( nx, ny, nz ) ; 10368 //tvol->setDataAt(nx,ny,nz, -1) ; 10369 //ct ++ ; 10370 10371 //if ( ct % 100000 == 0 ) 10372 //{ 10373 //printf("%d nodes processed.\n", ct); 10374 //} 10375 //} 10376 //} 10377 10378 //queue->reset() ; 10379 //ele = queue->getNext() ; 10380 //} 10381 //printf("Done.\n") ; 10382 10384 //for ( i = 0 ; i < getSizeX()*getSizeY()*getSizeZ() ; i ++ ) 10385 //{ 10386 //this->setDataAt(i, tvol->getDataAt(i) ) ; 10387 //} 10388 //} 10389 10390 //void Volume::reduceComponent( int size ) 10391 //{ 10392 //int i, j, k ; 10393 //Volume* tvol = new Volume( getSizeX(), getSizeY(), getSizeZ(), 0 ) ; 10394 //GridQueue2* queue = new GridQueue2() ; 10395 //GridQueue2* queue2 = new GridQueue2() ; 10396 //gridQueueEle* ele ; 10397 //int numC = 0, numBC = 0 ; 10398 10399 //for ( i = 0 ; i < getSizeX() ; i ++ ) 10400 //for ( j = 0 ; j < getSizeY() ; j ++ ) 10401 //for ( k = 0 ; k < getSizeZ() ; k ++ ) 10402 //{ 10403 //if ( getDataAt(i,j,k) == 1 && tvol->getDataAt(i,j,k) == 0 ) 10404 //{ 10405 //numC ++ ; 10407 //queue->prepend( i,j,k ) ; 10408 //queue2->prepend( i,j,k ) ; 10409 //tvol->setDataAt( i,j,k, 1 ) ; 10410 //int ct = 1 ; 10411 10412 //queue->reset() ; 10413 //ele = queue->getNext() ; 10414 //while( ele != NULL ) 10415 //{ 10416 //int ox = ele->x ; 10417 //int oy = ele->y ; 10418 //int oz = ele->z ; 10419 //queue->remove() ; 10420 10421 //for ( int m = 0 ; m < 6 ; m ++ ) 10422 //{ 10423 //int nx = ox + neighbor6[m][0] ; 10424 //int ny = oy + neighbor6[m][1] ; 10425 //int nz = oz + neighbor6[m][2] ; 10426 //if ( nx < 0 || nx >= getSizeX() || ny < 0 || ny >= getSizeY() || nz < 0 || nz >= getSizeZ() ) 10427 //{ 10428 //continue ; 10429 //} 10430 //if ( tvol->getDataAt( nx, ny, nz ) == 0 && getDataAt( nx, ny, nz ) == 1 ) 10431 //{ 10432 //queue->prepend( nx, ny, nz ) ; 10433 //queue2->prepend( nx, ny, nz ) ; 10434 //tvol->setDataAt( nx, ny, nz, 1 ) ; 10435 //ct ++ ; 10436 //} 10437 //} 10438 10439 //queue->reset() ; 10440 //ele = queue->getNext() ; 10441 //} 10442 10443 //if ( ct < size ) 10444 //{ 10446 10447 //queue2->reset() ; 10448 //ele = queue2->getNext() ; 10449 //while ( ele != NULL ) 10450 //{ 10451 //setDataAt( ele->x, ele->y, ele->z, 0 ) ; 10452 //ele = queue2->remove() ; 10453 //} 10454 //queue2->reset() ; 10455 10456 //} 10457 //else 10458 //{ 10459 //queue2 = new GridQueue2() ; 10460 //numBC ++ ; 10461 //} 10462 //} 10463 //} 10464 10465 //printf("Total number of components: %d Remained: %d\n", numC, numBC ) ; 10466 10467 //} 10468 10469 //void Volume::reduceComponent2( int num ) 10470 //{ 10471 //int i, j, k ; 10472 //Volume* tvol = new Volume( getSizeX(), getSizeY(), getSizeZ(), 0 ) ; 10473 //GridQueue2* queue = new GridQueue2() ; 10474 //GridQueue2* queue2 = new GridQueue2() ; 10475 //gridQueueEle* ele ; 10476 //int numC = 0, numBC = 0 ; 10477 //int* tops = new int[ num ] ; 10478 //int* topinds = new int[ num ] ; 10479 //for ( i = 0 ; i < num ; i ++ ) 10480 //{ 10481 //tops[i] = 0 ; 10482 //topinds[i] = -1 ; 10483 //} 10484 10485 //for ( i = 0 ; i < getSizeX() ; i ++ ) 10486 //for ( j = 0 ; j < getSizeY() ; j ++ ) 10487 //for ( k = 0 ; k < getSizeZ() ; k ++ ) 10488 //{ 10489 //if ( getDataAt(i,j,k) == 1 && tvol->getDataAt(i,j,k) == 0 ) 10490 //{ 10491 //numC ++ ; 10493 //queue->prepend( i,j,k ) ; 10494 //queue2->prepend( i,j,k ) ; 10495 //tvol->setDataAt( i,j,k, 1 ) ; 10496 //int ct = 1 ; 10497 10498 //queue->reset() ; 10499 //ele = queue->getNext() ; 10500 //while( ele != NULL ) 10501 //{ 10502 //int ox = ele->x ; 10503 //int oy = ele->y ; 10504 //int oz = ele->z ; 10505 //queue->remove() ; 10506 10507 //for ( int m = 0 ; m < 6 ; m ++ ) 10508 //{ 10509 //int nx = ox + neighbor6[m][0] ; 10510 //int ny = oy + neighbor6[m][1] ; 10511 //int nz = oz + neighbor6[m][2] ; 10512 //if ( nx < 0 || nx >= getSizeX() || ny < 0 || ny >= getSizeY() || nz < 0 || nz >= getSizeZ() ) 10513 //{ 10514 //continue ; 10515 //} 10516 //if ( tvol->getDataAt( nx, ny, nz ) == 0 && getDataAt( nx, ny, nz ) == 1 ) 10517 //{ 10518 //queue->prepend( nx, ny, nz ) ; 10519 //queue2->prepend( nx, ny, nz ) ; 10520 //tvol->setDataAt( nx, ny, nz, 1 ) ; 10521 //ct ++ ; 10522 //} 10523 //} 10524 10525 //queue->reset() ; 10526 //ele = queue->getNext() ; 10527 //} 10528 10529 //queue2->reset() ; 10530 //ele = queue2->getNext() ; 10531 //while ( ele != NULL ) 10532 //{ 10533 //ele = queue2->remove() ; 10534 //} 10535 //queue2->reset() ; 10536 10537 //for ( int ind = 0 ; ind < num ; ind ++ ) 10538 //{ 10539 //if ( ct > tops[ ind ] ) 10540 //{ 10541 //for ( int nind = num - 1 ; nind > ind ; nind -- ) 10542 //{ 10543 //tops[nind] = tops[ nind - 1 ] ; 10544 //topinds[nind] = topinds[ nind - 1 ] ; 10545 //} 10546 //tops[ ind ] = ct ; 10547 //topinds[ ind ] = numC ; 10548 //break ; 10549 //} 10550 //} 10551 //} 10552 //} 10553 10554 //printf("%d components total, %d selected components:\n", numC, num) ; 10555 //for ( i = 0 ; i < num ; i ++ ) 10556 //{ 10557 //printf("Id %d: size %d\n", topinds[i], tops[i] ) ; 10558 //} 10559 10560 //tvol->fill( 0 ) ; 10561 10562 //numC = 0 ; 10563 //for ( i = 0 ; i < getSizeX() ; i ++ ) 10564 //for ( j = 0 ; j < getSizeY() ; j ++ ) 10565 //for ( k = 0 ; k < getSizeZ() ; k ++ ) 10566 //{ 10567 //if ( getDataAt(i,j,k) == 1 && tvol->getDataAt(i,j,k) == 0 ) 10568 //{ 10569 //numC ++ ; 10571 //queue->prepend( i,j,k ) ; 10572 //queue2->prepend( i,j,k ) ; 10573 //tvol->setDataAt( i,j,k, 1 ) ; 10574 //int ct = 1 ; 10575 10576 //queue->reset() ; 10577 //ele = queue->getNext() ; 10578 //while( ele != NULL ) 10579 //{ 10580 //int ox = ele->x ; 10581 //int oy = ele->y ; 10582 //int oz = ele->z ; 10583 //queue->remove() ; 10584 10585 //for ( int m = 0 ; m < 6 ; m ++ ) 10586 //{ 10587 //int nx = ox + neighbor6[m][0] ; 10588 //int ny = oy + neighbor6[m][1] ; 10589 //int nz = oz + neighbor6[m][2] ; 10590 //if ( nx < 0 || nx >= getSizeX() || ny < 0 || ny >= getSizeY() || nz < 0 || nz >= getSizeZ() ) 10591 //{ 10592 //continue ; 10593 //} 10594 //if ( tvol->getDataAt( nx, ny, nz ) == 0 && getDataAt( nx, ny, nz ) == 1 ) 10595 //{ 10596 //queue->prepend( nx, ny, nz ) ; 10597 //queue2->prepend( nx, ny, nz ) ; 10598 //tvol->setDataAt( nx, ny, nz, 1 ) ; 10599 //ct ++ ; 10600 //} 10601 //} 10602 10603 //queue->reset() ; 10604 //ele = queue->getNext() ; 10605 //} 10606 10607 //int removing = 1 ; 10608 //for ( int ind = 0 ; ind < num ; ind ++ ) 10609 //{ 10610 //if ( topinds[ ind ] == numC ) 10611 //{ 10612 //removing = 0 ; 10613 //break ; 10614 //} 10615 //} 10616 10617 //if ( removing ) 10618 //{ 10620 10621 //queue2->reset() ; 10622 //ele = queue2->getNext() ; 10623 //while ( ele != NULL ) 10624 //{ 10625 //setDataAt( ele->x, ele->y, ele->z, 0 ) ; 10626 //ele = queue2->remove() ; 10627 //} 10628 //queue2->reset() ; 10629 10630 //} 10631 //else 10632 //{ 10633 //queue2 = new GridQueue2() ; 10634 //numBC ++ ; 10635 //} 10636 //} 10637 //} 10638 10639 //printf("Total number of components: %d Remained: %d\n", numC, numBC ) ; 10640 //delete tvol ; 10641 //} 10642 10643 //void Volume::floodFillPQR( int offset ) 10644 //{ 10645 //int i; 10646 10648 //GridQueue2* queue = new GridQueue2() ; 10649 //gridQueueEle* ele ; 10650 //queue->prepend( 0, 0, 0 ) ; 10651 10653 //printf("Flood filling outside from (0,0,0)...\n") ; 10654 //int ct = 1 ; 10656 //queue->reset() ; 10657 //ele = queue->getNext() ; 10658 //while( ele != NULL ) 10659 //{ 10660 //int ox = ele->x ; 10661 //int oy = ele->y ; 10662 //int oz = ele->z ; 10663 //queue->remove() ; 10664 10665 //int boundary = 0 ; 10666 //for ( int m = 0 ; m < 6 ; m ++ ) 10667 //{ 10668 //int nx = ox + neighbor6[m][0] ; 10669 //int ny = oy + neighbor6[m][1] ; 10670 //int nz = oz + neighbor6[m][2] ; 10671 //if ( nx < 0 || nx >= getSizeX() || ny < 0 || ny >= getSizeY() || nz < 0 || nz >= getSizeZ() ) 10672 //{ 10673 //continue ; 10674 //} 10675 //if ( tvol->getDataAt( nx, ny, nz ) == 0 && getDataAt( nx, ny, nz ) == 0 ) 10676 //{ 10677 //queue->prepend( nx, ny, nz ) ; 10678 //tvol->setDataAt( nx, ny, nz, 1 ) ; 10679 //ct ++ ; 10680 //if ( ct % 100000 == 0 ) 10681 //{ 10682 //printf("%d nodes processed.\n", ct); 10683 //} 10684 //} 10685 //else if ( getDataAt( nx, ny, nz ) == 1 ) 10686 //{ 10687 //boundary = 1 ; 10688 //} 10689 //} 10690 10691 //if ( boundary ) 10692 //{ 10693 //tvol->setDataAt( ox, oy, oz, 2 ) ; 10694 //} 10695 10696 //queue->reset() ; 10697 //ele = queue->getNext() ; 10698 //} 10699 //printf("Done.\n") ; 10700 //for ( i = 0 ; i < getSizeX()*getSizeY()*getSizeZ() ; i ++ ) 10701 //{ 10702 10703 //if ( tvol->getDataAt(i) == 2 ) 10704 //{ 10705 //setDataAt( i, 1 ) ; 10706 //} 10707 //} 10708 //*/ 10709 10710 10712 //int maxRounds = 1 ; 10713 //for ( int rounds = 0 ; rounds < maxRounds ; rounds ++ ) 10714 //{ 10715 10716 //int isSolid = 0 ; 10717 //for ( i = 0 ; i < getSizeX() ; i ++ ) 10718 //{ 10719 //if ( getDataAt( i, getSizeY() / 2, getSizeZ() / 2 ) == 1 ) 10720 //{ 10721 //isSolid = 1 ; 10722 //} 10723 //else if ( isSolid == 1 ) 10724 //{ 10725 //break ; 10726 //} 10727 //} 10728 10729 //Volume* invol = new Volume( getSizeX(), getSizeY(), getSizeZ(), 0 ) ; 10730 //queue->prepend( i, getSizeY()/2, getSizeZ()/2 ) ; 10731 //invol->setDataAt( i, getSizeY()/2, getSizeZ()/2, 1 ) ; 10732 //printf("Flood filling inside from (%d,%d,%d)...\n",i, getSizeY()/2, getSizeZ()/2) ; 10733 10735 //queue->reset() ; 10736 //ele = queue->getNext() ; 10737 //ct = 1 ; 10738 //while( ele != NULL ) 10739 //{ 10740 //int ox = ele->x ; 10741 //int oy = ele->y ; 10742 //int oz = ele->z ; 10743 //queue->remove() ; 10744 10745 //int boundary = 0 ; 10746 //for ( int m = 0 ; m < 6 ; m ++ ) 10747 //{ 10748 //int nx = ox + neighbor6[m][0] ; 10749 //int ny = oy + neighbor6[m][1] ; 10750 //int nz = oz + neighbor6[m][2] ; 10751 //if ( nx < 0 || nx >= getSizeX() || ny < 0 || ny >= getSizeY() || nz < 0 || nz >= getSizeZ() ) 10752 //{ 10753 //continue ; 10754 //} 10755 //if ( invol->getDataAt( nx, ny, nz ) == 0 && getDataAt( nx, ny, nz ) == 0 ) 10756 //{ 10757 //queue->prepend( nx, ny, nz ) ; 10758 //invol->setDataAt( nx, ny, nz, 1 ) ; 10759 //ct ++ ; 10760 //if ( ct % 100000 == 0 ) 10761 //{ 10762 //printf("%d nodes processed.\n", ct); 10763 //} 10764 //} 10765 //else if ( getDataAt( nx, ny, nz ) == 1 ) 10766 //{ 10767 //boundary = 1 ; 10768 //} 10769 //} 10770 10771 //if ( boundary ) 10772 //{ 10773 //invol->setDataAt( ox, oy, oz, 2 ) ; 10774 //} 10775 10776 //queue->reset() ; 10777 //ele = queue->getNext() ; 10778 //} 10779 //printf("Done.\n") ; 10780 10782 //for ( i = 0 ; i < getSizeX()*getSizeY()*getSizeZ() ; i ++ ) 10783 //{ 10785 //if ( tvol->getDataAt(i) == 2 ) 10786 //{ 10787 //setDataAt( i, 1 ) ; 10788 //} 10789 //*/ 10790 //if ( invol->getDataAt(i) == 2 ) 10791 //{ 10792 //setDataAt( i, 1 ) ; 10793 //} 10794 10796 //else if ( tvol->getDataAt(i) == 0 && invol->getDataAt(i) == 0 ) 10797 //{ 10798 //setDataAt( i, 1 ) ; 10799 //} 10800 //*/ 10801 //} 10802 10803 //delete invol ; 10804 10805 //} 10806 10808 10809 //} 10810 10811 10812 //void Volume::writeDistances( char* fname, int maxDis ) 10813 //{ 10814 //int i, j, k ; 10815 //Volume* testvol = NULL ; 10816 //Volume* disvol = new Volume( getSizeX(), getSizeY(), getSizeZ() ) ; 10817 //printf("Writing distance transform to %d levels.\n", maxDis); 10818 10819 //int totNodes = 0 ; 10820 //int size = getSizeX() * getSizeY() * getSizeZ() ; 10821 //float score = 10 ; 10822 //for ( i = maxDis ; i >= 0 ; i -- ) 10823 //{ 10824 //int nodes = 0 ; 10825 //testvol = new Volume( getSizeX(), getSizeY(), getSizeZ(), 0, 0, 0, this ) ; 10826 //testvol->erodeSheet( i ) ; 10827 10828 //for ( j = 0 ; j < size ; j ++ ) 10829 //{ 10830 //if ( disvol->getDataAt(j) == 0 && testvol->getDataAt(j) > 0 ) 10831 //{ 10832 //disvol->setDataAt( j, i + 1 ) ; 10833 //nodes ++ ; 10834 //} 10835 //} 10836 //printf("Level %d has %d nodes.\n", i, nodes ); 10837 //totNodes += nodes ; 10838 //score -= 0.5f ; 10839 //delete testvol ; 10840 //} 10841 //printf("Totally %d nodes.\n", totNodes ); 10842 10844 //FILE* fout = fopen( fname, "w" ) ; 10845 //fprintf( fout, "%d\n", totNodes ) ; 10846 //int ct = 0 ; 10847 //for ( i = 0 ; i < getSizeX() ; i ++ ) 10848 //for ( j = 0 ; j < getSizeY() ; j ++ ) 10849 //for ( k = 0 ; k < getSizeZ() ; k ++ ) 10850 //{ 10851 //float val = (float)disvol->getDataAt(i,j,k) ; 10852 //if ( val > 0 ) 10853 //{ 10854 //fprintf( fout, "%d %d %d %f\n", i, j, k, val ) ; 10855 //ct ++ ; 10856 //} 10857 //} 10858 10859 //if ( ct != totNodes ) 10860 //{ 10861 //printf("Counting wrong! %d %d\n", totNodes, ct) ; 10862 //} 10863 //fclose( fout ) ; 10864 10865 //} 10866 10867 //void Volume::toPQRFile( char* fname, float spc, float minx, float miny, float minz, int padding ) 10868 //{ 10869 //FILE* fout = fopen( fname, "w" ) ; 10870 //int i, j, k ; 10871 10872 //for ( i = 0 ; i < getSizeX() ; i ++ ) 10873 //for ( j = 0 ; j < getSizeY() ; j ++ ) 10874 //for ( k = 0 ; k < getSizeZ() ; k ++ ) 10875 //{ 10876 //if ( i < padding || i >= getSizeX() - padding || j < padding || j >= getSizeY() - padding || k < padding || k >= getSizeZ() - padding ) 10877 //{ 10878 //continue ; 10879 //} 10880 //float val = (float)this->getDataAt(i,j,k) ; 10881 //if ( val > 0 ) 10882 //{ 10883 //float x = (i - padding) * spc + minx ; 10884 //float y = (j - padding) * spc + miny ; 10885 //float z = (k - padding) * spc + minz ; 10886 //fprintf( fout, "ATOM 1 X DUM 1 %4.3f %4.3f %4.3f 0.000 0.000\n", x, y, z ) ; 10887 //} 10888 //} 10889 10890 //fclose( fout ) ; 10891 //} 10892 10893 //void Volume::toMRCFile( char* fname ) 10894 //{ 10895 //FILE* fout = fopen( fname, "wb" ) ; 10896 10898 //int sizeX = getSizeX(); 10899 //int sizeY = getSizeY(); 10900 //int sizeZ = getSizeZ(); 10901 //fwrite( &sizeX, sizeof( int ), 1, fout ) ; 10902 //fwrite( &sizeY, sizeof( int ), 1, fout ) ; 10903 //fwrite( &sizeZ, sizeof( int ), 1, fout ) ; 10904 10905 //int mode = 2 ; 10906 //fwrite( &mode, sizeof ( int ), 1, fout ) ; 10907 10908 //int off[3] = {0,0,0} ; 10909 //int intv[3] = { getSizeX() - 1, getSizeY() - 1, getSizeZ() - 1 } ; 10910 //fwrite( off, sizeof( int ), 3, fout ) ; 10911 //fwrite( intv, sizeof( int ), 3, fout ) ; 10912 10913 //float cella[3] = {getSpacingX() * (float)(getSizeX()), getSpacingY() * (float)(getSizeY()), getSpacingZ() * (float)(getSizeZ())}; 10914 //float cellb[3] = {90,90,90} ; 10915 //fwrite( cella, sizeof( float ), 3, fout ) ; 10916 //fwrite( cellb, sizeof( float ), 3, fout ) ; 10917 10918 //int cols[3] = {1,2,3} ; 10919 //fwrite( cols, sizeof( int ), 3, fout ) ; 10920 10921 //double dmin = 100000, dmax = -100000 ; 10922 //int i ; 10923 //int size = volData->GetMaxIndex(); 10924 //for (i = 0 ; i < size; i++) { 10925 //float val = (float)getDataAt(i); 10926 //if (val < dmin) { 10927 //dmin = val; 10928 //} 10929 //if (val > dmax) { 10930 //dmax = val; 10931 //} 10932 //} 10933 //float ds[3] = {(float)dmin, (float)dmax, (float)0} ; 10934 //fwrite( ds, sizeof( float ), 3, fout ) ; 10935 10936 //int zero = 0 ; 10937 //for (i = 23 ; i <= 49 ; i ++ ) 10938 //{ 10939 //fwrite( &zero, sizeof( int ), 1, fout ); 10940 //} 10941 10942 //float origins[3]; 10943 //origins[0] = getOriginX() / getSpacingX() + 0.5f * (float)getSizeX(); 10944 //origins[1] = getOriginY() / getSpacingY() + 0.5f * (float)getSizeY(); 10945 //origins[2] = getOriginZ() / getSpacingZ() + 0.5f * (float)getSizeZ(); 10946 10947 //fwrite( origins, sizeof( float ), 3, fout) ; 10948 10949 //for (i = 53 ; i <= 256 ; i ++ ) 10950 //{ 10951 //fwrite( &zero, sizeof( int ), 1, fout ) ; 10952 //} 10953 10955 //for ( int z = 0 ; z < getSizeZ() ; z ++ ) 10956 //for ( int y = 0 ; y < getSizeY() ; y ++ ) 10957 //for ( int x = 0 ; x < getSizeX() ; x ++ ) 10958 //{ 10959 //float d = (float)getDataAt(x,y,z) ; 10960 //fwrite( &d, sizeof( float ), 1, fout ) ; 10961 //} 10962 10963 //fclose( fout ) ; 10964 //}