EMAN2
volume.cpp
Go to the documentation of this file.
1// Copyright (C) 2005-2008 Washington University in St Louis, Baylor College of Medicine. All rights reserved
2// Author: Tao Ju (taoju@cse.wustl.edu), Refactored by Sasakthi Abeysinghe (sasakthi.abeysinghe@wustl.edu)
3// Description: Volumetric data definition
4
5#include "volume.h"
6
7using namespace wustl_mm::SkeletonMaker;
8
9 Volume::Volume(EMData* em) //eman2
10 {
11 this->volData = new VolumeData(em);
12 }
13 Volume::Volume(int x, int y, int z) {
14 volData = new VolumeData(x, y, z);
15 }
16
17 Volume::Volume(int x, int y, int z, float val) {
18 volData = new VolumeData(x, y, z, val);
19 }
20
21 Volume::Volume(int x, int y, int z, int offx, int offy, int offz, Volume * vol) {
22 volData = new VolumeData(x, y, z, offx, offy, offz, vol->getVolumeData());
23 }
24
25
27 {
28 delete volData;
29 }
30
32 {
33 return this->getVolumeData()->get_emdata();
34 }
35
37 return volData->GetSizeX();
38 }
39
41 return volData->GetSizeY();
42 }
43
45 return volData->GetSizeZ();
46 }
47
48 int Volume::getIndex(int x, int y, int z) {
49 return volData->GetIndex(x, y, z);
50 }
51
52 void Volume::setDataAt( int x, int y, int z, double d ) {
53 volData->SetDataAt(x, y, z, (float)d);
54 }
55
56 void Volume::setDataAt( int index, double d ) {
57 volData->SetDataAt(index, (float)d);
58 }
59
60 double Volume::getDataAt( int x, int y, int z )
61 {
62 return volData->GetDataAt(x, y, z);
63 }
64
65 double Volume::getDataAt( int index ) {
66 return volData->GetDataAt(index);
67 }
68
70 return volData;
71 }
72
73 void Volume::setSpacing(float spx, float spy, float spz ) {
74 volData->SetSpacing(spx, spy, spz);
75 }
76
77 void Volume::setOrigin(float orgX, float orgY, float orgZ) {
78 volData->SetOrigin(orgX, orgY, orgZ);
79 }
80
82 return volData->GetSpacingX();
83 }
84
86 return volData->GetSpacingY();
87 }
88
90 return volData->GetSpacingZ();
91 }
92
94 return volData->GetOriginX();
95 }
96
98 return volData->GetOriginY();
99 }
100
102 return volData->GetOriginZ();
103 }
104
105 //Volume * Volume::getPseudoDensity( ) {
108 //int i, j, k ;
109 //Volume * res = new Volume(getSizeX(), getSizeY(), getSizeZ(), 0, 0, 0, this);
110 //int size = getSizeX() * getSizeY() * getSizeZ() ;
111 //srand(123) ;
112
113 //for ( i = 0 ; i < getSizeX() ; i ++ )
114 //for ( j = 0 ; j < getSizeY() ; j ++ )
115 //for ( k = 0 ; k < getSizeZ() ; k ++ ) {
116 //if ( res->getDataAt( i, j, k ) > 0 ) {
117 //int ct = 0 ;
118 //for ( int m = 0 ; m < 6 ; m ++ ) {
119 //if ( res->getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) > 0 ) {
120 //ct ++ ;
121 //}
122 //}
123 //res->setDataAt( i,j,k, (k/(float)getSizeZ())*(k/(float)getSizeZ()) ) ;
124 //if ( ct > 2 ) {
126 //} else {
128 //}
129 //}
130 //}
131
133 //for ( i = 0 ; i < 20 ; i ++ )
134 //{
135 //printf("Smoothing round %d\n", i) ;
136 //res->smooth( 0.5f ) ;
137 //}
138 //*/
139
140 //Volume * tvol = new Volume( getSizeX(), getSizeY(), getSizeZ(), 0, 0, 0, res);
141 //float d, ad, ct, temp;
142 //for ( int it = 0 ; it < 3 ; it ++ )
143 //for ( i = 0 ; i < getSizeX() ; i ++ )
144 //for ( j = 0 ; j < getSizeY() ; j ++ )
145 //for ( k = 0 ; k < getSizeZ() ; k ++ ) {
146 //if ( (d = (float)tvol->getDataAt( i, j, k )) > 0 ) {
147 //ad = 0 ; ct = 0 ;
148 //for ( int m = 0 ; m < 6 ; m ++ ) {
149 //if ( (temp = (float)tvol->getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] )) > 0 ) {
150 //ad += temp;
151 //ct ++ ;
152 //}
153 //}
154 //if ( ct > 0 ) {
155 //res->setDataAt( i, j, k, ( d + ad/ct ) / 2 ) ;
156 //}
157 //}
158 //}
159
160 //delete tvol;
161 //tvol = new Volume( getSizeX(), getSizeY(), getSizeZ(), 0, 0, 0, res ) ;
162 //for ( i = 0 ; i < 40 ; i ++ )
163 //{
164 //printf("Smoothing round %d\n", i) ;
165 //res->smooth( 0.5f ) ;
166 //continue ;
167
176
177 //}
178
179
180 //return res ;
181 //}
182
183
184 //Volume * Volume::getDistanceField(int rad, float randf) {
188
190 //int i, j, k ;
191 //Volume * res = new Volume(getSizeX(), getSizeY(), getSizeZ(), 0, 0, 0, this);
192 //srand( 123 ) ;
193
194 //for ( i = 0 ; i < getSizeX() ; i ++ )
195 //for ( j = 0 ; j < getSizeY() ; j ++ )
196 //for ( k = 0 ; k < getSizeZ() ; k ++ ) {
197 //if ( getDataAt(i, j, k) > 0 ) {
198 //float mag = 1 + randf * (float) rand() / (float) RAND_MAX ;
199 //int lx = max(0,i-rad) ;
200 //int ly = max(0,j-rad) ;
201 //int lz = max(0,k-rad) ;
202 //int hx = min(getSizeX()-1,i+rad) ;
203 //int hy = min(getSizeY()-1,j+rad) ;
204 //int hz = min(getSizeZ()-1,k+rad) ;
205 //int x,y,z;
206 //for ( x = lx ; x <= hx ; x ++ )
207 //for ( y = ly ; y <= hy ; y ++ )
208 //for ( z = lz ; z <= hz ; z ++ ) {
209 //float val = 1 - (float) sqrt((double)((x-i)*(x-i) + (y-j)*(y-j) + (z-k)*(z-k))) / (float) rad ;
210 //val *= mag ;
211 //if ( res->getDataAt( x, y, z ) < val ) {
212 //res->setDataAt( x, y, z, val ) ;
213 //}
214 //}
215 //}
216 //}
217
219 //for ( i = 0 ; i < 2 ; i ++ )
220 //{
221 //printf("Smoothing round %d\n", i) ;
222 //res->smooth( 0.5f ) ;
223 //}
224
225
226 //return res ;
227 //}
228
229
230 //int Volume::getNonZeroVoxelCount() {
231 //int count = 0;
232 //for(int x = 0; x < getSizeX(); x++){
233 //for(int y = 0; y < getSizeY(); y++){
234 //for(int z = 0; z < getSizeZ(); z++){
235 //if(this->getDataAt(x, y, z) > 0.0) {
236 //count++;
237 //}
238 //}
239 //}
240 //}
241 //return count;
242 //}
243 //void Volume::print() {
244 //for(int x = 0; x < getSizeX(); x++) {
245 //printf("{ ");
246 //for(int y = 0; y < getSizeY(); y++) {
247 //printf("{ ");
248 //for(int z = 0; z < getSizeZ(); z++) {
249 //printf("%f, ", getDataAt(x, y, z));
250 //}
251 //printf("} ");
252 //}
253 //printf("} ");
254 //}
255 //printf("\n");
256 //}
257
258
259 //void Volume::subtract( Volume* vol ) {
260 //int i, j, k ;
261 //for ( i = 0 ; i < getSizeX() ; i ++ )
262 //for ( j = 0 ; j < getSizeY() ; j ++ )
263 //for ( k = 0 ; k < getSizeZ() ; k ++ ) {
264 //if ( getDataAt( i, j, k ) > 0 ) {
265 //if ( vol->getDataAt(i,j,k) > 0 ) {
266 //setDataAt( i, j, k, 0 ) ;
267 //}
268 //}
269 //}
270
271 //}
272
273 void Volume::pad (int padBy, double padValue) {
274 volData->Pad(padBy, padValue);
275 }
276
277 //void Volume::applyMask(Volume * maskVol, double maskValue, bool keepMaskValue) {
278 //for(int x = 0; x < maskVol->getSizeX(); x++) {
279 //for(int y = 0; y < maskVol->getSizeY(); y++) {
280 //for(int z = 0; z < maskVol->getSizeZ(); z++) {
281 //if(((maskVol->getDataAt(x, y, z) == maskValue) && !keepMaskValue) ||
282 //((maskVol->getDataAt(x, y, z) != maskValue) && keepMaskValue)) {
283 //setDataAt(x, y, z, 0);
284 //}
285 //}
286 //}
287 //}
288 //}
289
290 //double Volume::getMin() {
291 //int size = volData->GetMaxIndex();
292 //double rvalue = volData->GetDataAt(0);
293 //for (int i=1; i < size; i++) {
294 //float val = volData->GetDataAt(i);
295 //if ( rvalue > val) {
296 //rvalue = val;
297 //}
298 //}
299 //return rvalue;
300 //}
301
302 //double Volume::getMax() {
303 //int size = volData->GetMaxIndex();
304 //double rvalue = volData->GetDataAt(0);
305 //for (int i=1; i < size; i++) {
306 //float val = volData->GetDataAt(i);
307 //if ( rvalue < val) {
308 //rvalue = val;
309 //}
310 //}
311 //return rvalue ;
312 //}
313
314 //double Volume::getMaxValuePosition(int& maxX, int& maxY, int& maxZ) {
315 //double maxVal = getDataAt(0,0,0);
316 //maxX = 0; maxY = 0; maxZ = 0;
317 //double data;
318
319 //for(int x = 0; x < getSizeX(); x++) {
320 //for(int y = 0; y < getSizeY(); y++) {
321 //for(int z = 0; z < getSizeZ(); z++) {
322 //data = getDataAt(x, y, z);
323 //if(data > maxVal) {
324 //maxVal = data;
325 //maxX = x; maxY = y; maxZ = z;
326 //}
327 //}
328 //}
329 //}
330 //return maxVal;
331 //}
332
333 //double Volume::getLocalMax(int x, int y, int z, int radius) {
334 //double mx = getDataAt(x, y, z);
335 //for(int xx = x - radius; xx <= x + radius; xx++) {
336 //for(int yy = y - radius; yy <= y + radius; yy++) {
337 //for(int zz = z - radius; zz <= z + radius; zz++) {
338 //mx = max(mx, getDataAt(xx, yy, zz));
339 //}
340 //}
341 //}
342 //return mx;
343 //}
344
345 //double Volume::getLocalMin(int x, int y, int z, int radius) {
346 //double mn = getDataAt(x, y, z);
347 //for(int xx = x - radius; xx <= x + radius; xx++) {
348 //for(int yy = y - radius; yy <= y + radius; yy++) {
349 //for(int zz = z - radius; zz <= z + radius; zz++) {
350 //mn = min(mn, getDataAt(xx, yy, zz));
351 //}
352 //}
353 //}
354 //return mn;
355 //}
356
357 //void Volume::fill( double val )
358 //{
359 //for(int x = 0; x < getSizeX(); x++) {
360 //for(int y = 0; y < getSizeY(); y++) {
361 //for(int z = 0; z < getSizeZ(); z++) {
362 //setDataAt(x, y, z, val);
363 //}
364 //}
365 //}
366 //}
367
368 //int Volume::isBertrandBorder( int ox, int oy, int oz, int dir ) {
369 //int nx = ox + neighbor6[dir][0] ;
370 //int ny = oy + neighbor6[dir][1] ;
371 //int nz = oz + neighbor6[dir][2] ;
372 //if ( getDataAt( nx, ny, nz) < 0 ) {
373 //return 1 ;
374 //}
375 //return 0 ;
376 //}
377
378 //int Volume::isBertrandEndPoint( int ox, int oy, int oz ) {
379 //double vox[3][3][3] ;
380
381 //int i, j, k ;
382 //for ( i = -1 ; i < 2 ; i ++ )
383 //for ( j = -1 ; j < 2 ; j ++ )
384 //for ( k = -1 ; k < 2 ; k ++ ) {
385 //double tval = getDataAt( ox + i, oy + j, oz + k ) ;
386 //vox[ i + 1 ][ j + 1 ][ k + 1 ] = tval ;
387 //}
388
390 //int xx6 = 0 ;
391 //for ( i = 0 ; i < 6 ; i ++ ) {
392 //if ( vox[ neighbor6[i][0] + 1 ][ neighbor6[i][1] + 1 ][ neighbor6[i][2] + 1 ] >= 0 ) {
393 //xx6 ++ ;
394 //}
395 //}
396
398 //int a26 = 0, na26 = 0 ;
399 //for ( i = 0 ; i < 3 ; i += 2 )
400 //for ( j = 0 ; j < 3 ; j += 2 )
401 //for ( k = 0 ; k < 3 ; k += 2 ) {
402 //if ( vox[1][j][k] < 0 ) {
403 //continue ;
404 //}
405 //if ( vox[i][1][k] < 0 ) {
406 //continue ;
407 //}
408 //if ( vox[i][j][1] < 0 ) {
409 //continue ;
410 //}
411 //if ( vox[i][1][1] < 0 ) {
412 //continue ;
413 //}
414 //if ( vox[1][j][1] < 0 ) {
415 //continue ;
416 //}
417 //if ( vox[1][1][k] < 0 ) {
418 //continue ;
419 //}
420 //if ( vox[i][j][k] >= 0 ) {
421 //a26 ++ ;
422 //} else {
423 //na26 ++ ;
424 //}
425 //}
426
427 //if (( na26 == 0 ) && ( a26 != 0 ) && ( xx6 <= a26 + 2 )) {
428 //return 0 ;
429 //}
430 //if ( isFeatureFace(ox,oy,oz) ) {
432 //}
433 //return 1 ;
434 //}
435
436 //int Volume::isHelix( int ox, int oy, int oz ) {
437 //int cn = 12 ;
438 //int nx, ny, nz ;
439 //int i, j, k ;
440
441 //double vox[3][3][3] ;
442 //for ( i = -1 ; i < 2 ; i ++ )
443 //for ( j = -1 ; j < 2; j ++ )
444 //for ( k = -1 ; k < 2 ; k ++ ) {
445 //vox[i+1][j+1][k+1] = getDataAt( ox + i, oy + j, oz + k ) ;
446 //}
447
448 //for ( i = 0 ; i < 12 ; i ++ ) {
449 //for ( j = 0 ; j < 4 ; j ++ ) {
450 //nx = sheetNeighbor[i][j][0] + 1;
451 //ny = sheetNeighbor[i][j][1] + 1;
452 //nz = sheetNeighbor[i][j][2] + 1;
453
454 //if ( vox[nx][ny][nz] <= 0 ) {
455 //cn -- ;
456 //break ;
457 //}
458 //}
459 //}
460
461 //if ( cn >= 1 ) {
462 //return 0 ;
463 //} else {
464 //return 1 ;
465 //}
466 //}
467
468 //int Volume::isSheet( int ox, int oy, int oz ) {
469 //int cn = 12 ;
470 //int nx, ny, nz ;
471
472 //for ( int i = 0 ; i < 12 ; i ++ ) {
473 //for ( int j = 0 ; j < 4 ; j ++ ) {
474 //nx = ox + sheetNeighbor[i][j][0] ;
475 //ny = oy + sheetNeighbor[i][j][1] ;
476 //nz = oz + sheetNeighbor[i][j][2] ;
477
478 //if ( getDataAt( nx, ny, nz ) <= 0 ) {
479 //cn -- ;
480 //break ;
481 //}
482 //}
483 //}
484 //return ( cn >= 3 ) ;
485 //}
486
487 //Volume * Volume::getSheets( int minSize ) {
488 //int i, j, k ;
489
491 //printf("Initialize volume at %d %d %d\n", getSizeX(), getSizeY(), getSizeZ() ) ;
492 //Volume* svol = new Volume( getSizeX(), getSizeY(), getSizeZ() ) ;
493
495 //int sheets[MAX_SHEETS] ;
496 //for ( i = 0 ; i < MAX_SHEETS ; i ++ ) {
497 //sheets[ i ] = 0 ;
498 //}
499 //int totSheets = 1 ;
500
502 //printf("Start clustering...\n" ) ;
503 //int ox, oy, oz ;
504 //for ( i = 0 ; i < getSizeX() ; i ++ )
505 //for ( j = 0 ; j < getSizeY() ; j ++ )
506 //for ( k = 0 ; k < getSizeZ() ; k ++ ) {
507 //if ( getDataAt(i,j,k) <= 0 || svol->getDataAt(i,j,k) != 0 ) {
509 //continue ;
510 //}
511 //if ( ! isSheet( i, j, k ) ) {
513 //continue ;
514 //}
515
517 //int numNodes = 1 ;
518 //svol->setDataAt( i, j, k, totSheets ) ;
519 //GridQueue* queue = new GridQueue() ;
520 //queue->pushQueue( i, j, k ) ;
521 //while ( queue->popQueue(ox, oy, oz) ) {
523 //if ( isSheet( ox, oy, oz ) ) {
524 //for ( int m = 0 ; m < 6 ; m ++ ) {
525 //int nx = ox + neighbor6[m][0] ;
526 //int ny = oy + neighbor6[m][1] ;
527 //int nz = oz + neighbor6[m][2] ;
528
529 //if ( getDataAt(nx,ny,nz) > 0 && svol->getDataAt(nx,ny,nz) == 0 ) {
530 //svol->setDataAt(nx,ny,nz,totSheets);
531 //queue->pushQueue(nx,ny,nz) ;
532 //numNodes ++ ;
533 //}
534 //}
535 //}
536 //}
537
538 //delete queue ;
539 //if ( numNodes > 0 ) {
541 //sheets[ totSheets ] = numNodes ;
542 //totSheets ++ ;
543 //}
544 //}
545
547 //printf("Removing small clusters.\n") ;
548 //for ( i = 0 ; i < getSizeX() ; i ++ )
549 //for ( j = 0 ; j < getSizeY() ; j ++ )
550 //for ( k = 0 ; k < getSizeZ() ; k ++ ) {
551 //int cnt = (int) svol->getDataAt(i,j,k) ;
552 //if ( cnt > 0 && sheets[ cnt ] < minSize ) {
553 //svol->setDataAt(i,j,k,-1) ;
554 //}
555 //}
556
558 //#ifdef VERBOSE
559 //printf("Thresholding the volume to 0/1...\n") ;
560 //#endif
561 //svol->threshold( 0.1, 0, 1 ) ;
562
563 //return svol ;
564 //}
565
566 //Volume * Volume::getHelices( int minSize ) {
567 //printf("Segmenting helices from eroded volume.\n") ;
568 //int i, j, k ;
569
571 //printf("Initialize volume at %d %d %d\n", getSizeX(), getSizeY(), getSizeZ() ) ;
572 //Volume* svol = new Volume( getSizeX(), getSizeY(), getSizeZ() ) ;
573
575 //int helices[MAX_SHEETS] ;
576 //for ( i = 0 ; i < MAX_SHEETS ; i ++ ) {
577 //helices[ i ] = 0 ;
578 //}
579 //int totHelices = 1 ;
580
582 //printf("Start clustering...\n" ) ;
583 //int ox, oy, oz ;
584 //for ( i = 0 ; i < getSizeX() ; i ++ )
585 //for ( j = 0 ; j < getSizeY() ; j ++ )
586 //for ( k = 0 ; k < getSizeZ() ; k ++ ) {
587 //if ( getDataAt(i,j,k) <= 0 || svol->getDataAt(i,j,k) != 0 ) {
589 //continue ;
590 //}
591 //if ( ! isHelix( i, j, k ) ) {
593 //continue ;
594 //}
595
597 //int numNodes = 1 ;
598 //svol->setDataAt( i, j, k, totHelices ) ;
599 //GridQueue* queue = new GridQueue() ;
600 //queue->pushQueue( i, j, k ) ;
601 //while ( queue->popQueue(ox, oy, oz) )
602 //{
604 //if ( isHelix( ox, oy, oz ) ) {
605 //for ( int m = 0 ; m < 6 ; m ++ ) {
606 //int nx = ox + neighbor6[m][0] ;
607 //int ny = oy + neighbor6[m][1] ;
608 //int nz = oz + neighbor6[m][2] ;
609
610 //if ( getDataAt(nx,ny,nz) > 0 && svol->getDataAt(nx,ny,nz) == 0 ) {
611 //svol->setDataAt(nx,ny,nz,totHelices);
612 //queue->pushQueue(nx,ny,nz) ;
613 //numNodes ++ ;
614 //}
615 //}
616 //}
617 //}
618
619 //delete queue ;
620 //if ( numNodes > 0 ) {
622 //helices[ totHelices ] = numNodes ;
623 //totHelices ++ ;
624 //}
625 //}
626
628 //printf("Removing small clusters.\n") ;
629 //for ( i = 0 ; i < getSizeX() ; i ++ )
630 //for ( j = 0 ; j < getSizeY() ; j ++ )
631 //for ( k = 0 ; k < getSizeZ() ; k ++ ) {
632 //int cnt = (int) svol->getDataAt(i,j,k) ;
633 //if ( cnt > 0 && helices[ cnt ] < minSize ) {
634 //svol->setDataAt(i,j,k,-1) ;
635 //}
636 //}
637
639 //#ifdef VERBOSE
640 //printf("Thresholding the volume to 0/1...\n") ;
641 //#endif
642 //svol->threshold( 0.1, 0, 1 ) ;
643
644 //return svol ;
645
646 //}
647
648 //int Volume::isEndPoint( int ox, int oy, int oz ) {
649 //if ( getDataAt( ox - 1, oy, oz ) < 0 && getDataAt( ox + 1, oy, oz ) < 0 ) {
650 //return 1 ;
651 //}
652 //if ( getDataAt( ox, oy - 1, oz ) < 0 && getDataAt( ox, oy + 1, oz ) < 0 ) {
653 //return 1 ;
654 //}
655 //if ( getDataAt( ox, oy, oz - 1 ) < 0 && getDataAt( ox, oy, oz + 1 ) < 0 ) {
656 //return 1 ;
657 //}
658 //return 0 ;
659 //}
660
661 int Volume::getNumNeighbor6( int ox, int oy, int oz ) {
662 int rvalue = 0 ;
663 for ( int i = 0 ; i < 6 ; i ++ ) {
664 int nx = ox + neighbor6[i][0] ;
665 int ny = oy + neighbor6[i][1] ;
666 int nz = oz + neighbor6[i][2] ;
667 if ( getDataAt( nx, ny, nz ) >= 0 ) {
668 rvalue ++ ;
669 }
670 }
671
672 return rvalue ;
673 }
674 //int Volume::testIsSheetEnd( int ox, int oy, int oz ) {
676 //int i, j ;
677 //int nx, ny, nz ;
678
679 //int edge[6] = { 0,0,0,0,0,0 } ;
680 //int faceflag[ 12 ] ;
681 //int hasNoiseFace = 0 ;
682 //int tot = 0 ;
683
684 //for ( i = 0 ; i < 12 ; i ++ ) {
685 //faceflag[ i ] = 1 ;
686 //int hasNoise = 0 ;
687
688 //for ( j = 0 ; j < 4 ; j ++ ) {
689 //nx = ox + sheetNeighbor[i][j][0] ;
690 //ny = oy + sheetNeighbor[i][j][1] ;
691 //nz = oz + sheetNeighbor[i][j][2] ;
692
693 //if ( getDataAt( nx, ny, nz ) == 0 ) {
694 //hasNoise = 1 ;
695 //}
696 //if ( getDataAt( nx, ny, nz ) < 0 ) {
697 //faceflag[ i ] = 0 ;
698 //break ;
699 //}
700 //}
701 //if ( faceflag[ i ] == 1 && hasNoise ) {
702 //hasNoiseFace ++ ;
704 //}
705
706 //if ( faceflag[ i ] ) {
707 //int e0 = faceEdges[ i ][ 0 ], e1 = faceEdges[ i ][ 1 ] ;
708 //edge[ e0 ] ++ ;
709 //edge[ e1 ] ++ ;
710 //tot ++ ;
711 //}
712 //}
713
714 //if ( hasNoiseFace == tot ) {
715 //return 0 ;
716 //}
717
718 //if ( tot == 0 ) {
719 //return 0 ;
720 //}
721
723 //int numones = 0 ;
724 //for ( i = 0 ; i < 6 ; i ++ ) {
725 //if ( edge[ i ] == 1 ) {
726 //numones ++ ;
727 //}
728 //}
729 //while( numones > 0 ) {
730 //int e ;
731 //for ( i = 0 ; i < 6 ; i ++ ) {
732 //if ( edge[ i ] == 1 ) {
733 //e = i ;
734 //break ;
735 //}
736 //}
737
738 //int f, e2 ;
739 //for ( j = 0 ; j < 4 ; j ++ ) {
740 //f = edgeFaces[ e ][ j ] ;
741 //if ( faceflag[ f ] ) {
742 //break ;
743 //}
744 //}
745
746 //if ( faceEdges[ f ][ 0 ] == e ) {
747 //e2 = faceEdges[ f ][ 1 ] ;
748 //} else {
749 //e2 = faceEdges[ f ][ 0 ] ;
750 //}
751
752 //edge[ e ] -- ;
753 //numones -- ;
754 //edge[ e2 ] -- ;
755 //faceflag[ f ] = 0 ;
756 //tot -- ;
757
758 //if ( edge[ e2 ] == 1 ) {
759 //numones ++ ;
760 //} else if ( edge[ e2 ] == 0 ) {
761 //numones -- ;
762 //}
763 //}
764
765 //if ( tot > 0 ) {
766 //return 0 ;
767 //}
768 //return 1 ;
769 //}
770
771 //int Volume::isNoiseSheetEnd( int ox, int oy, int oz ) {
772 //int i, j ;
773 //int nx, ny, nz ;
774
775 //int edge[6] = { 0,0,0,0,0,0 } ;
776 //int faceflag[ 12 ] ;
777 //int hasNoiseFace = 0 ;
778 //int tot = 0 ;
779
780 //for ( i = 0 ; i < 12 ; i ++ ) {
781 //faceflag[ i ] = 1 ;
782 //int hasNoise = 0 ;
783
784 //for ( j = 0 ; j < 4 ; j ++ ) {
785 //nx = ox + sheetNeighbor[i][j][0] ;
786 //ny = oy + sheetNeighbor[i][j][1] ;
787 //nz = oz + sheetNeighbor[i][j][2] ;
788
789 //if ( getDataAt( nx, ny, nz ) == 0 ) {
790 //hasNoise = 1 ;
791 //}
792 //if ( getDataAt( nx, ny, nz ) < 0 ) {
793 //faceflag[ i ] = 0 ;
794 //break ;
795 //}
796 //}
797 //if ( faceflag[ i ] == 1 && hasNoise ) {
798 //hasNoiseFace ++ ;
800 //}
801
802 //if ( faceflag[ i ] ) {
803 //int e0 = faceEdges[ i ][ 0 ], e1 = faceEdges[ i ][ 1 ] ;
804 //edge[ e0 ] ++ ;
805 //edge[ e1 ] ++ ;
806 //tot ++ ;
807 //}
808 //}
809
810 //if ( hasNoiseFace < tot ) {
811 //return 0 ;
812 //}
813
814 //if ( tot == 0 ) {
815 //return 0 ;
816 //}
817
819 //int numones = 0 ;
820 //for ( i = 0 ; i < 6 ; i ++ ) {
821 //if ( edge[ i ] == 1 )
822 //{
823 //numones ++ ;
824 //}
825 //}
826 //while( numones > 0 ) {
827 //int e ;
828 //for ( i = 0 ; i < 6 ; i ++ ) {
829 //if ( edge[ i ] == 1 ) {
830 //e = i ;
831 //break ;
832 //}
833 //}
834
835 //int f, e2 ;
836 //for ( j = 0 ; j < 4 ; j ++ ) {
837 //f = edgeFaces[ e ][ j ] ;
838 //if ( faceflag[ f ] ) {
839 //break ;
840 //}
841 //}
842
843 //if ( faceEdges[ f ][ 0 ] == e ) {
844 //e2 = faceEdges[ f ][ 1 ] ;
845 //} else {
846 //e2 = faceEdges[ f ][ 0 ] ;
847 //}
848
849 //edge[ e ] -- ;
850 //numones -- ;
851 //edge[ e2 ] -- ;
852 //faceflag[ f ] = 0 ;
853 //tot -- ;
854
855 //if ( edge[ e2 ] == 1 ) {
856 //numones ++ ;
857 //} else if ( edge[ e2 ] == 0 ) {
858 //numones -- ;
859 //}
860 //}
861
862 //if ( tot > 0 ) {
863 //return 0 ;
864 //}
865 //return 1 ;
866 //}
867
868 //int Volume::isInternal( int ox, int oy, int oz ) {
870 //int i, j, k ;
871
872 //for ( i = -1 ; i < 2 ; i ++ )
873 //for ( j = -1 ; j < 2 ; j ++ )
874 //for ( k = -1 ; k < 2 ; k ++ ) {
875 //if ( getDataAt( ox + i, oy + j, oz + k ) <= 0 ) {
876 //return 0 ;
877 //}
878 //}
879 //return 1 ;
880 //}
881
882 //int Volume::isInternal2( int ox, int oy, int oz ) {
884 //int i, j, k ;
885
886 //for ( i = -1 ; i < 2 ; i ++ )
887 //for ( j = -1 ; j < 2 ; j ++ )
888 //for ( k = -1 ; k < 2 ; k ++ ) {
889 //if ( getDataAt( ox + i, oy + j, oz + k ) < 0 ) {
890 //return 0 ;
891 //}
892 //}
893
894 //return 1 ;
895 //}
896
897 //int Volume::hasIsolatedFace( int ox, int oy, int oz ) {
898 //int i, j, k ;
899 //int nx, ny, nz ;
900
901 //double vox[3][3][3] ;
902 //for ( i = -1 ; i < 2 ; i ++ )
903 //for ( j = -1 ; j < 2 ; j ++ )
904 //for ( k = -1 ; k < 2 ; k ++ ) {
905 //vox[ i + 1 ][ j + 1 ][ k + 1 ] = getDataAt( ox + i, oy + j, oz + k ) ;
906 //}
907
908 //int cells[8] = { 1, 1, 1, 1, 1, 1, 1, 1 } ;
909 //for ( i = 0 ; i < 8 ; i ++ ) {
910 //int x = ( ( i >> 2 ) & 1 ) ;
911 //int y = ( ( i >> 1 ) & 1 ) ;
912 //int z = ( i & 1 ) ;
913 //for ( j = 0 ; j < 8 ; j ++ ) {
914 //nx = x + ( ( j >> 2 ) & 1 ) ;
915 //ny = y + ( ( j >> 1 ) & 1 ) ;
916 //nz = z + ( j & 1 ) ;
917
918 //if ( vox[nx][ny][nz] < 0 ) {
919 //cells[i] = 0 ;
920 //break;
921 //}
922 //}
923 //}
924
925 //for ( i = 0 ; i < 12 ; i ++ ) {
926 //if ( cells[ faceCells[i][0] ] == 1 || cells[ faceCells[i][1] ] == 1 ) {
927 //continue ;
928 //}
929 //int flag = 1 ;
930 //for ( j = 0 ; j < 4 ; j ++ ) {
931 //nx = 1 + sheetNeighbor[i][j][0] ;
932 //ny = 1 + sheetNeighbor[i][j][1] ;
933 //nz = 1 + sheetNeighbor[i][j][2] ;
934
935 //if ( vox[nx][ny][nz] < 0 ) {
936 //flag = 0 ;
937 //break;
938 //}
939 //}
940 //if ( flag ) {
941 //return 1 ;
942 //}
943 //}
944
945 //return 0 ;
946 //}
947
948 //int Volume::hasIsolatedEdge( int ox, int oy, int oz ) {
949 //int i, j, k ;
950 //int nx, ny, nz ;
951
952 //double vox[3][3][3] ;
953 //for ( i = -1 ; i < 2 ; i ++ )
954 //for ( j = -1 ; j < 2 ; j ++ )
955 //for ( k = -1 ; k < 2 ; k ++ ) {
956 //vox[ i + 1 ][ j + 1 ][ k + 1 ] = getDataAt( ox + i, oy + j, oz + k ) ;
957 //}
958
959 //int edge[6] = { 0,0,0,0,0,0 } ;
960
961 //for ( i = 0 ; i < 12 ; i ++ ) {
962 //int flag = 1 ;
963 //for ( j = 0 ; j < 4 ; j ++ ) {
964 //nx = 1 + sheetNeighbor[i][j][0] ;
965 //ny = 1 + sheetNeighbor[i][j][1] ;
966 //nz = 1 + sheetNeighbor[i][j][2] ;
967
968 //if ( vox[nx][ny][nz] < 0 ) {
969 //flag = 0 ;
970 //break ;
971 //}
972 //}
973
974 //if ( flag ) {
975 //int e0 = faceEdges[ i ][ 0 ], e1 = faceEdges[ i ][ 1 ] ;
976 //edge[ e0 ] ++ ;
977 //edge[ e1 ] ++ ;
978 //}
979 //}
980
981 //for ( i = 0 ; i < 6 ; i ++ ) {
982 //if ( edge[i] ) {
983 //continue ;
984 //}
985
986 //nx = 1 + neighbor6[i][0] ;
987 //ny = 1 + neighbor6[i][1] ;
988 //nz = 1 + neighbor6[i][2] ;
989
990 //if ( vox[nx][ny][nz] >= 0 ) {
991 //return 1 ;
992 //}
993
994 //}
995
996 //return 0 ;
997 //}
998
999 //int Volume::countFace( int ox, int oy, int oz, int m ) {
1000 //int facenum = 4 ;
1001 //for ( int i = 0 ; i < 4 ; i ++ ) {
1002 //for ( int j = 0 ; j < 4 ; j ++ ) {
1003 //int nx = ox + sheetNeighbor[edgeFaces[m][i]][j][0] ;
1004 //int ny = oy + sheetNeighbor[edgeFaces[m][i]][j][1] ;
1005 //int nz = oz + sheetNeighbor[edgeFaces[m][i]][j][2] ;
1006
1007 //if ( getDataAt( nx, ny, nz ) < 0 ) {
1008 //facenum -- ;
1009 //break ;
1010 //}
1011 //}
1012 //}
1013
1014 //return facenum;
1015 //}
1016 int Volume::hasCell( int ox, int oy, int oz ) {
1017 for ( int i = 0 ; i < 2 ; i ++ )
1018 for ( int j = 0 ; j < 2 ; j ++ )
1019 for ( int k = 0 ; k < 2 ; k ++ ) {
1020 if ( getDataAt( ox + i, oy + j, oz + k ) < 0 ) {
1021 return 0 ;
1022 }
1023 }
1024 return 1 ;
1025 }
1026
1028 int i, j, k ;
1029 Volume* fvol = new Volume( getSizeX(), getSizeY(), getSizeZ() ) ;
1030
1031 //return fvol ;
1032
1033 for ( i = 0 ; i < getSizeX() ; i ++ )
1034 for ( j = 0 ; j < getSizeY() ; j ++ )
1035 for ( k = 0 ; k < getSizeZ() ; k ++ )
1036 {
1037 if( getDataAt(i,j,k) >= 0 )
1038 {
1039 if ( hasCell(i,j,k) )
1040 {
1041 for ( int m = 0 ; m < 6 ; m ++ )
1042 {
1043 int nx = i + neighbor6[m][0] ;
1044 int ny = j + neighbor6[m][1] ;
1045 int nz = k + neighbor6[m][2] ;
1046 if ( ! hasCell(nx,ny,nz) )
1047 {
1048 fvol->setDataAt(i,j,k,(double)(1<<m)) ;
1049 break ;
1050 }
1051 }
1052 }
1053 }
1054 }
1055
1056
1057 return fvol ;
1058 }
1059
1060 //Volume * Volume::markFaceEdge( ) {
1061 //int x,y,z, i,j ;
1062 //Volume* fvol = new Volume( getSizeX(), getSizeY(), getSizeZ() ) ;
1063
1065
1066 //for ( x = 0 ; x < getSizeX() ; x ++ )
1067 //for ( y = 0 ; y < getSizeY() ; y ++ )
1068 //for ( z = 0 ; z < getSizeZ() ; z ++ )
1069 //{
1070 //if( getDataAt(x,y,z) >= 0 )
1071 //{
1072
1073 //for ( i = 0 ; i < 3 ; i ++ )
1074 //{
1075 //int hasFace = 1 ;
1076 //for ( j = 0 ; j < 4 ; j ++ )
1077 //{
1078 //int nx = x + sheetNeighbor[4 * i + 3][j][0] ;
1079 //int ny = y + sheetNeighbor[4 * i + 3][j][1] ;
1080 //int nz = z + sheetNeighbor[4 * i + 3][j][2] ;
1081
1082 //if ( getDataAt( nx, ny, nz ) < 0 )
1083 //{
1084 //hasFace = 0 ;
1085 //break ;
1086 //}
1087 //}
1088
1089 //if ( hasFace )
1090 //{
1092 //switch( i )
1093 //{
1094 //case 0:
1095 //if ( countFace( x, y, z, 0 ) == 1 )
1096 //{
1097 //fvol->setDataAt(x, y, z, (double)(1<<0)) ;
1098 //break ;
1099 //}
1100 //if ( countFace( x, y, z, 2 ) == 1 )
1101 //{
1102 //fvol->setDataAt(x, y, z, (double)(1<<2)) ;
1103 //break ;
1104 //}
1105 //if ( countFace( x, y + 1, z, 0 ) == 1 )
1106 //{
1107 //fvol->setDataAt(x, y + 1, z, (double)(1<<0)) ;
1108 //break ;
1109 //}
1110 //if ( countFace( x, y, z + 1, 2 ) == 1 )
1111 //{
1112 //fvol->setDataAt(x, y, z + 1, (double)(1<<2)) ;
1113 //break ;
1114 //}
1115 //printf("Hmmm... a face with no open edges.\n");
1116 //break ;
1117 //case 1:
1118 //if ( countFace( x, y, z, 0 ) == 1 )
1119 //{
1120 //fvol->setDataAt(x, y, z, (double)(1<<0)) ;
1121 //break ;
1122 //}
1123 //if ( countFace( x, y, z, 4 ) == 1 )
1124 //{
1125 //fvol->setDataAt(x, y, z, (double)(1<<4)) ;
1126 //break ;
1127 //}
1128 //if ( countFace( x + 1, y, z, 0 ) == 1 )
1129 //{
1130 //fvol->setDataAt(x + 1, y, z, (double)(1<<0)) ;
1131 //break ;
1132 //}
1133 //if ( countFace( x, y, z + 1, 4 ) == 1 )
1134 //{
1135 //fvol->setDataAt(x, y, z + 1, (double)(1<<4)) ;
1136 //break ;
1137 //}
1138 //printf("Hmmm... a face with no open edges.\n");
1139 //break ;
1140 //case 2:
1141 //if ( countFace( x, y, z, 2 ) == 1 )
1142 //{
1143 //fvol->setDataAt(x, y, z, (double)(1<<2)) ;
1144 //break ;
1145 //}
1146 //if ( countFace( x, y, z, 4 ) == 1 )
1147 //{
1148 //fvol->setDataAt(x, y, z, (double)(1<<4)) ;
1149 //break ;
1150 //}
1151 //if ( countFace( x + 1, y, z, 2 ) == 1 )
1152 //{
1153 //fvol->setDataAt(x + 1, y, z, (double)(1<<2)) ;
1154 //break ;
1155 //}
1156 //if ( countFace( x, y + 1, z, 4 ) == 1 )
1157 //{
1158 //fvol->setDataAt(x, y + 1, z, (double)(1<<4)) ;
1159 //break ;
1160 //}
1161 //printf("Hmmm... a face with no open edges.\n");
1162 //break ;
1163 //}
1164 //}
1165 //}
1166
1167 //}
1168 //}
1169
1170
1171 //return fvol ;
1172 //}
1173
1174 int Volume::hasCompleteSheet( int ox, int oy, int oz, Volume* fvol ) {
1175 int i, j, k ;
1176 int nx, ny, nz ;
1177
1178 int edge[6] = { 0,0,0,0,0,0 } ;
1179 int faceflag[ 12 ] ;
1180 int tot = 0 ;
1181 int cellflag[ 8 ] ;
1182
1183 int ct = 0 ;
1184 for ( i = -1 ; i < 1 ; i ++ )
1185 for ( j = -1 ; j < 1 ; j ++ )
1186 for ( k = -1 ; k < 1 ; k ++ )
1187 {
1188 if ( hasCell( ox + i, oy + j, oz + k ) )
1189 {
1190 cellflag[ ct ] = 1 ;
1191 }
1192 else
1193 {
1194 cellflag[ ct ] = 0 ;
1195 }
1196 ct ++ ;
1197 }
1198
1199 for ( i = 0 ; i < 12 ; i ++ )
1200 {
1201 faceflag[ i ] = 1 ;
1202 for ( j = 0 ; j < 4 ; j ++ )
1203 {
1204 nx = ox + sheetNeighbor[i][j][0] ;
1205 ny = oy + sheetNeighbor[i][j][1] ;
1206 nz = oz + sheetNeighbor[i][j][2] ;
1207
1208 if ( getDataAt( nx, ny, nz ) < 0 )
1209 {
1210 faceflag[ i ] = 0 ;
1211 break ;
1212 }
1213 }
1214
1215 if ( faceflag[ i ] )
1216 {
1217 if ( cellflag[ faceCells[i][0] ] ^ cellflag[ faceCells[i][1] ] )
1218 {
1219 int v1 = (int)( fvol->getDataAt(
1220 ox - 1 + (( faceCells[i][0] >> 2 ) & 1 ),
1221 oy - 1 + (( faceCells[i][0] >> 1 ) & 1 ),
1222 oz - 1 + (( faceCells[i][0] ) & 1)) ) ;
1223 int v2 = (int)( fvol->getDataAt(
1224 ox - 1 + (( faceCells[i][1] >> 2 ) & 1 ),
1225 oy - 1 + (( faceCells[i][1] >> 1 ) & 1 ),
1226 oz - 1 + (( faceCells[i][1] ) & 1)) ) ;
1227 if ( ((v1 >> (2 * (2 - i/4))) & 1) ||
1228 ((v2 >> (2 * (2 - i/4) + 1 )) & 1) )
1229 {
1230 faceflag[ i ] = 0 ;
1231 }
1232 }
1233 }
1234
1235 if ( faceflag[ i ] )
1236 {
1237 int e0 = faceEdges[ i ][ 0 ], e1 = faceEdges[ i ][ 1 ] ;
1238 edge[ e0 ] ++ ;
1239 edge[ e1 ] ++ ;
1240 tot ++ ;
1241 }
1242 }
1243
1244 // Removing 1s
1245 int numones = 0 ;
1246 for ( i = 0 ; i < 6 ; i ++ )
1247 {
1248 if ( edge[ i ] == 1 )
1249 {
1250 numones ++ ;
1251 }
1252 }
1253 while( numones > 0 )
1254 {
1255 int e = 0;
1256 for ( i = 0 ; i < 6 ; i ++ )
1257 {
1258 if ( edge[ i ] == 1 )
1259 {
1260 e = i ;
1261 break ;
1262 }
1263 }
1264 /*
1265 if ( edge[ e ] != 1 )
1266 {
1267 printf("Wrong Again!********\n") ;
1268 }
1269 */
1270
1271 int f, e2 ;
1272 for ( j = 0 ; j < 4 ; j ++ )
1273 {
1274 f = edgeFaces[ e ][ j ] ;
1275 if ( faceflag[ f ] )
1276 {
1277 break ;
1278 }
1279 }
1280
1281 /*
1282 if ( faceflag[ f ] == 0 )
1283 {
1284 printf("Wrong!********\n") ;
1285 }
1286 */
1287
1288 if ( faceEdges[ f ][ 0 ] == e )
1289 {
1290 e2 = faceEdges[ f ][ 1 ] ;
1291 }
1292 else
1293 {
1294 e2 = faceEdges[ f ][ 0 ] ;
1295 }
1296
1297
1298 edge[ e ] -- ;
1299 numones -- ;
1300 edge[ e2 ] -- ;
1301 faceflag[ f ] = 0 ;
1302 tot -- ;
1303
1304 if ( edge[ e2 ] == 1 )
1305 {
1306 numones ++ ;
1307 }
1308 else if ( edge[ e2 ] == 0 )
1309 {
1310 numones -- ;
1311 }
1312 }
1313
1314 if ( tot > 0 )
1315 {
1316 return 1 ;
1317 }
1318
1319 return 0 ;
1320 }
1321
1322 int Volume::hasCompleteSheet( int ox, int oy, int oz ) {
1323 // Returns 1 if it lies in the middle of a sheet
1324 int temp = countIntEuler( ox, oy, oz ) ;
1325 if ( temp > 0 )
1326 {
1327 return 1 ;
1328 }
1329 else
1330 {
1331 return 0 ;
1332 }
1333 }
1334
1335 //int Volume::hasCompleteSheetSlow( int ox, int oy, int oz ) {
1336 //int i, j ;
1337 //int nx, ny, nz ;
1338
1339 //int edge[6] = { 0,0,0,0,0,0 } ;
1340 //int faceflag[ 12 ] ;
1341 //int tot = 0 ;
1342
1343 //for ( i = 0 ; i < 12 ; i ++ )
1344 //{
1345 //faceflag[ i ] = 1 ;
1346 //for ( j = 0 ; j < 4 ; j ++ )
1347 //{
1348 //nx = ox + sheetNeighbor[i][j][0] ;
1349 //ny = oy + sheetNeighbor[i][j][1] ;
1350 //nz = oz + sheetNeighbor[i][j][2] ;
1351
1352 //if ( getDataAt( nx, ny, nz ) < 0 )
1353 //{
1354 //faceflag[ i ] = 0 ;
1355 //break ;
1356 //}
1357 //}
1358
1359 //if ( faceflag[ i ] )
1360 //{
1361 //int e0 = faceEdges[ i ][ 0 ], e1 = faceEdges[ i ][ 1 ] ;
1362 //edge[ e0 ] ++ ;
1363 //edge[ e1 ] ++ ;
1364 //tot ++ ;
1365 //}
1366 //}
1367
1369 //int numones = 0 ;
1370 //for ( i = 0 ; i < 6 ; i ++ )
1371 //{
1372 //if ( edge[ i ] == 1 )
1373 //{
1374 //numones ++ ;
1375 //}
1376 //}
1377 //while( numones > 0 )
1378 //{
1379 //int e ;
1380 //for ( i = 0 ; i < 6 ; i ++ )
1381 //{
1382 //if ( edge[ i ] == 1 )
1383 //{
1384 //e = i ;
1385 //break ;
1386 //}
1387 //}
1389 //if ( edge[ e ] != 1 )
1390 //{
1391 //printf("Wrong Again!********\n") ;
1392 //}
1393 //*/
1394
1395 //int f, e2 ;
1396 //for ( j = 0 ; j < 4 ; j ++ )
1397 //{
1398 //f = edgeFaces[ e ][ j ] ;
1399 //if ( faceflag[ f ] )
1400 //{
1401 //break ;
1402 //}
1403 //}
1404
1406 //if ( faceflag[ f ] == 0 )
1407 //{
1408 //printf("Wrong!********\n") ;
1409 //}
1410 //*/
1411
1412 //if ( faceEdges[ f ][ 0 ] == e )
1413 //{
1414 //e2 = faceEdges[ f ][ 1 ] ;
1415 //}
1416 //else
1417 //{
1418 //e2 = faceEdges[ f ][ 0 ] ;
1419 //}
1420
1421
1422 //edge[ e ] -- ;
1423 //numones -- ;
1424 //edge[ e2 ] -- ;
1425 //faceflag[ f ] = 0 ;
1426 //tot -- ;
1427
1428 //if ( edge[ e2 ] == 1 )
1429 //{
1430 //numones ++ ;
1431 //}
1432 //else if ( edge[ e2 ] == 0 )
1433 //{
1434 //numones -- ;
1435 //}
1436 //}
1437
1439 //if ( tot > 0 )
1440 //{
1442 //{
1444 //}
1445 //return 1 ;
1446 //}
1447 //else
1448 //{
1450 //{
1452 //}
1453 //return 0 ;
1454 //}
1455 //}
1456 int Volume::hasCompleteHelix( int ox, int oy, int oz )
1457 {
1458 // Returns 1 if it has a complete helix
1459 int i ;
1460 int c1 = 0;
1461 int nx, ny, nz ;
1462 int j ;
1463
1464 for ( i = 0 ; i < 6 ; i ++ )
1465 {
1466 nx = ox + neighbor6[i][0] ;
1467 ny = oy + neighbor6[i][1] ;
1468 nz = oz + neighbor6[i][2] ;
1469 if ( getDataAt( nx, ny, nz ) >= 0 )
1470 {
1471 c1 ++ ;
1472 j = i ;
1473 }
1474
1475 }
1476
1477 if ( c1 > 1 ) // || c1 == 0 )
1478 {
1479 return 1 ;
1480 }
1481
1482 return 0 ;
1483
1484 /*
1485 ox = ox + neighbor6[j][0] ;
1486 oy = oy + neighbor6[j][1] ;
1487 oz = oz + neighbor6[j][2] ;
1488 c1 = 0 ;
1489 for ( i = 0 ; i < 6 ; i ++ )
1490 {
1491 nx = ox + neighbor6[i][0] ;
1492 ny = oy + neighbor6[i][1] ;
1493 nz = oz + neighbor6[i][2] ;
1494 if ( getDataAt( nx, ny, nz ) >= 0 )
1495 {
1496 c1 ++ ;
1497 }
1498
1499 }
1500
1501 if ( c1 > 1 )
1502 {
1503 return 0 ;
1504 }
1505 else
1506 {
1507 return 1 ;
1508 }
1509 */
1510 }
1511
1512 int Volume::hasCompleteHelix( int ox, int oy, int oz, Volume* fvol )
1513 {
1514
1515 int i ;
1516 int c1 = 0;
1517 int nx, ny, nz ;
1518 int j ;
1519
1520 for ( i = 0 ; i < 6 ; i ++ )
1521 {
1522 nx = ox + neighbor6[i][0] ;
1523 ny = oy + neighbor6[i][1] ;
1524 nz = oz + neighbor6[i][2] ;
1525 if ( getDataAt( nx, ny, nz ) >= 0 )
1526 {
1527 if ( i % 2 == 0 )
1528 {
1529 nx = ox ;
1530 ny = oy ;
1531 nz = oz ;
1532 }
1533
1534 int val = (int)fvol->getDataAt( nx, ny, nz) ;
1535 if ( (( val >> ( 2 * ( i / 2 ) ) ) & 1) == 0 )
1536 {
1537 c1 ++ ;
1538 j = i ;
1539 }
1540 }
1541
1542 }
1543
1544 if ( c1 > 1 )
1545 {
1546 return 1 ;
1547 }
1548
1549 return 0 ;
1550
1551 /*
1552 ox = ox + neighbor6[j][0] ;
1553 oy = oy + neighbor6[j][1] ;
1554 oz = oz + neighbor6[j][2] ;
1555 c1 = 0 ;
1556 for ( i = 0 ; i < 6 ; i ++ )
1557 {
1558 nx = ox + neighbor6[i][0] ;
1559 ny = oy + neighbor6[i][1] ;
1560 nz = oz + neighbor6[i][2] ;
1561 if ( getDataAt( nx, ny, nz ) >= 0 )
1562 {
1563 c1 ++ ;
1564 }
1565
1566 }
1567
1568 if ( c1 > 1 )
1569 {
1570 return 0 ;
1571 }
1572 else
1573 {
1574 return 1 ;
1575 }
1576 */
1577 }
1578
1579 int Volume::isHelixEnd( int ox, int oy, int oz, Volume* nvol ) {
1580 // Returns 1 if it is a curve endpoint
1581 int i ;
1582 int c1 = 0 , c2 = 0 ;
1583 int nx, ny, nz ;
1584
1585 for ( i = 0 ; i < 6 ; i ++ )
1586 {
1587 nx = ox + neighbor6[i][0] ;
1588 ny = oy + neighbor6[i][1] ;
1589 nz = oz + neighbor6[i][2] ;
1590
1591 double val = getDataAt( nx, ny, nz ) ;
1592
1593 if ( val >= 0 )
1594 {
1595 c1 ++ ;
1596 if ( val > 0 && val < MAX_ERODE && nvol->getDataAt( nx, ny, nz ) == 0 )
1597 {
1598 c2 ++ ;
1599 }
1600 }
1601
1602 }
1603
1604 if ( c1 == 1 && c2 == 1 )
1605 {
1606 return 1 ;
1607 }
1608
1609 return 0 ;
1610 }
1611
1612 //int Volume::isFeature18( int ox, int oy, int oz )
1613 //{
1617 //if ( getDataAt( ox, oy, oz ) <= 0 )
1618 //{
1619 //return 0 ;
1620 //}
1621
1622 //for ( int i = 0 ; i < 3 ; i ++ )
1623 //for ( int j = 0 ; j < 3 ; j ++ )
1624 //for ( int k = 0 ; k < 3 ; k ++ )
1625 //{
1626 //if ( i == 1 || j == 1 || k == 1 )
1627 //{
1628 //if( getDataAt( ox - 1 + i, oy - 1 + j, oz - 1 + k ) == 0 )
1629 //{
1630 //return 0 ;
1631 //}
1632 //}
1633 //}
1634 //return 1 ;
1635 //}
1636
1637 //int Volume::isEdgeEnd( int ox, int oy, int oz )
1638 //{
1639 //int i ;
1640 //int c1 = 0 ;
1641 //int nx, ny, nz ;
1642
1643 //for ( i = 0 ; i < 6 ; i ++ )
1644 //{
1645 //nx = ox + neighbor6[i][0] ;
1646 //ny = oy + neighbor6[i][1] ;
1647 //nz = oz + neighbor6[i][2] ;
1648
1649 //double val = getDataAt( nx, ny, nz ) ;
1650
1651 //if ( val >= 0 )
1652 //{
1653 //c1 ++ ;
1654 //}
1655
1656 //}
1657
1658 //if ( c1 == 1 )
1659 //{
1660 //return 1 ;
1661 //}
1662
1663 //return 0 ;
1664 //}
1665
1666 //int Volume::isFaceEnd( int ox, int oy, int oz )
1667 //{
1669
1670 //int i, j, k ;
1671 //int nx, ny, nz ;
1672
1673 //double vox[3][3][3] ;
1674 //for ( i = -1 ; i < 2 ; i ++ )
1675 //for ( j = -1 ; j < 2 ; j ++ )
1676 //for ( k = -1 ; k < 2 ; k ++ )
1677 //{
1678 //vox[ i + 1 ][ j + 1 ][ k + 1 ] = getDataAt( ox + i, oy + j, oz + k ) ;
1679 //}
1680
1681 //int edge[6] = { 4,4,4,4,4,4 } ;
1682 //int edge2[6] = { 4,4,4,4,4,4 } ;
1683
1684 //for ( i = 0 ; i < 12 ; i ++ )
1685 //{
1686 //for ( j = 0 ; j < 4 ; j ++ )
1687 //{
1688 //nx = 1 + sheetNeighbor[i][j][0] ;
1689 //ny = 1 + sheetNeighbor[i][j][1] ;
1690 //nz = 1 + sheetNeighbor[i][j][2] ;
1691
1692 //if ( vox[nx][ny][nz] < 0 )
1693 //{
1694 //edge[ faceEdges[ i ][ 0 ] ] -- ;
1695 //edge[ faceEdges[ i ][ 1 ] ] -- ;
1696 //break ;
1697 //}
1698 //}
1699 //for ( j = 0 ; j < 4 ; j ++ )
1700 //{
1701 //nx = 1 + sheetNeighbor[i][j][0] ;
1702 //ny = 1 + sheetNeighbor[i][j][1] ;
1703 //nz = 1 + sheetNeighbor[i][j][2] ;
1704
1705 //if ( vox[nx][ny][nz] < 2 )
1706 //{
1707 //edge2[ faceEdges[ i ][ 0 ] ] -- ;
1708 //edge2[ faceEdges[ i ][ 1 ] ] -- ;
1709 //break ;
1710 //}
1711 //}
1712 //}
1713
1714 //for ( i = 0 ; i < 6 ; i ++ )
1715 //{
1716 //if ( edge[ i ] == 1 && edge2[ i ] == 1 )
1717 //{
1718 //return 1 ;
1719 //}
1720 //}
1721
1722 //return 0 ;
1723 //}
1724
1725 //int Volume::isNoise( int ox, int oy, int oz, int noise )
1726 //{
1727 //if ( getDataAt(ox,oy,oz) == 1 )
1728 //{
1729 //return 1 ;
1730 //}
1731
1732 //if ( noise > 0 )
1733 //{
1734 //for ( int i = 0 ; i < 6 ; i ++ )
1735 //{
1736 //int nx = ox + neighbor6[i][0] ;
1737 //int ny = oy + neighbor6[i][1] ;
1738 //int nz = oz + neighbor6[i][2] ;
1739
1740 //if ( getDataAt( nx, ny, nz ) > 0 )
1741 //{
1742 //if ( isNoise( nx, ny, nz, noise - 1 ) )
1743 //{
1744 //return 1 ;
1745 //}
1746 //}
1747 //}
1748 //}
1749
1750 //return 0 ;
1751
1752 //}
1753
1754 //int Volume::isNoiseHelixEnd( int ox, int oy, int oz )
1755 //{
1756
1757 //int i ;
1758 //int c1 = 0 , c2 = 0 ;
1759 //int nx, ny, nz ;
1760
1761 //for ( i = 0 ; i < 6 ; i ++ )
1762 //{
1763 //nx = ox + neighbor6[i][0] ;
1764 //ny = oy + neighbor6[i][1] ;
1765 //nz = oz + neighbor6[i][2] ;
1766
1767 //double val = getDataAt( nx, ny, nz ) ;
1768
1769 //if ( val >= 0 )
1770 //{
1771 //c1 ++ ;
1772 //if ( val > 0 && val < MAX_ERODE )
1773 //{
1774 //c2 ++ ;
1775 //}
1776 //}
1777
1778 //}
1779
1780 //if ( c1 == 1 && c2 == 0 )
1781 //{
1782 //return 1 ;
1783 //}
1784
1785 //return 0 ;
1786 //}
1787
1788
1789 int Volume::isHelixEnd( int ox, int oy, int oz ) {
1790
1791 int i ;
1792 int c1 = 0 , c2 = 0 ;
1793 int nx, ny, nz ;
1794
1795 for ( i = 0 ; i < 6 ; i ++ )
1796 {
1797 nx = ox + neighbor6[i][0] ;
1798 ny = oy + neighbor6[i][1] ;
1799 nz = oz + neighbor6[i][2] ;
1800
1801 double val = getDataAt( nx, ny, nz ) ;
1802
1803 if ( val >= 0 )
1804 {
1805 c1 ++ ;
1806 if ( getNumNeighbor6(nx,ny,nz) < 6 ) // if ( val > 0 && val < MAX_ERODE )
1807 {
1808 c2 ++ ;
1809 }
1810 }
1811
1812 }
1813
1814 if ( c1 == 1 && c2 == 1 )
1815 {
1816 return 1 ;
1817 }
1818
1819 return 0 ;
1820 }
1821 int Volume::isSheetEnd( int ox, int oy, int oz, Volume* nvol )
1822 {
1823 // Returns 1 if it contains a sheet boundary. Noise-resistant
1824 int i, j ;
1825 int nx, ny, nz ;
1826
1827 int edge[6] = { 0,0,0,0,0,0 } ;
1828 int faceflag[ 12 ] ;
1829 int hasFeatureFace = 0 ;
1830 int tot = 0 ;
1831
1832 for ( i = 0 ; i < 12 ; i ++ )
1833 {
1834 faceflag[ i ] = 1 ;
1835 int hasFeature = 1 ;
1836
1837 for ( j = 0 ; j < 4 ; j ++ )
1838 {
1839 nx = ox + sheetNeighbor[i][j][0] ;
1840 ny = oy + sheetNeighbor[i][j][1] ;
1841 nz = oz + sheetNeighbor[i][j][2] ;
1842
1843 if ( getDataAt( nx, ny, nz ) == 0 || nvol->getDataAt( nx, ny, nz ) == 1 )
1844 {
1845 hasFeature = 0 ;
1846 }
1847 if ( getDataAt( nx, ny, nz ) < 0 )
1848 {
1849 faceflag[ i ] = 0 ;
1850 break ;
1851 }
1852 }
1853 if ( faceflag[ i ] == 1 && hasFeature )
1854 {
1855 hasFeatureFace ++ ;
1856 // return 0 ;
1857 }
1858
1859 if ( faceflag[ i ] )
1860 {
1861 int e0 = faceEdges[ i ][ 0 ], e1 = faceEdges[ i ][ 1 ] ;
1862 edge[ e0 ] ++ ;
1863 edge[ e1 ] ++ ;
1864 tot ++ ;
1865 }
1866 }
1867
1868 if ( tot == 0 || hasFeatureFace == 0 )
1869 {
1870 return 0 ;
1871 }
1872
1873 // Removing 1s
1874 int numones = 0 ;
1875 for ( i = 0 ; i < 6 ; i ++ )
1876 {
1877 if ( edge[ i ] == 1 )
1878 {
1879 numones ++ ;
1880 }
1881 }
1882 while( numones > 0 )
1883 {
1884 int e = 0;
1885 for ( i = 0 ; i < 6 ; i ++ )
1886 {
1887 if ( edge[ i ] == 1 )
1888 {
1889 e = i ;
1890 break ;
1891 }
1892 }
1893 /*
1894 if ( edge[ e ] != 1 )
1895 {
1896 printf("Wrong Again!********\n") ;
1897 }
1898 */
1899
1900 int f, e2 ;
1901 for ( j = 0 ; j < 4 ; j ++ )
1902 {
1903 f = edgeFaces[ e ][ j ] ;
1904 if ( faceflag[ f ] )
1905 {
1906 break ;
1907 }
1908 }
1909
1910 /*
1911 if ( faceflag[ f ] == 0 )
1912 {
1913 printf("Wrong!********\n") ;
1914 }
1915 */
1916
1917 if ( faceEdges[ f ][ 0 ] == e )
1918 {
1919 e2 = faceEdges[ f ][ 1 ] ;
1920 }
1921 else
1922 {
1923 e2 = faceEdges[ f ][ 0 ] ;
1924 }
1925
1926
1927 edge[ e ] -- ;
1928 numones -- ;
1929 edge[ e2 ] -- ;
1930 faceflag[ f ] = 0 ;
1931 tot -- ;
1932
1933 if ( edge[ e2 ] == 1 )
1934 {
1935 numones ++ ;
1936 }
1937 else if ( edge[ e2 ] == 0 )
1938 {
1939 numones -- ;
1940 }
1941 }
1942
1943 if ( tot > 0 )
1944 {
1945 return 0 ;
1946 }
1947
1948 return 1 ;
1949 }
1950
1951 //int Volume::getNumFaces( int ox, int oy, int oz )
1952 //{
1953 //int i, j ;
1954 //int nx, ny, nz ;
1955
1956 //int faces = 12 ;
1957 //for ( i = 0 ; i < 12 ; i ++ )
1958 //{
1959 //for ( j = 0 ; j < 4 ; j ++ )
1960 //{
1961 //nx = ox + sheetNeighbor[i][j][0] ;
1962 //ny = oy + sheetNeighbor[i][j][1] ;
1963 //nz = oz + sheetNeighbor[i][j][2] ;
1964
1965 //if ( getDataAt( nx, ny, nz ) < 0 )
1966 //{
1967 //faces -- ;
1968 //break ;
1969 //}
1970 //}
1971 //}
1972
1973 //return faces ;
1974 //}
1975
1976 //int Volume::getNumCells( int ox, int oy, int oz )
1977 //{
1978 //int i, j, k ;
1979
1980 //int cells = 0 ;
1981
1982 //for ( i = -1 ; i < 1 ; i ++ )
1983 //for ( j = -1 ; j < 1 ; j ++ )
1984 //for ( k = -1 ; k < 1 ; k ++ )
1985 //{
1986 //if ( hasCell( ox + i, oy + j, oz + k ) )
1987 //{
1988 //cells ++ ;
1989 //}
1990 //}
1991
1993 //return cells ;
1994 //}
1995
1996
1997 //int Volume::getNumIsolatedEdges( int ox, int oy, int oz )
1998 //{
1999 //int i, j, k ;
2000 //int nx, ny, nz ;
2001
2002 //double vox[3][3][3] ;
2003 //for ( i = -1 ; i < 2 ; i ++ )
2004 //for ( j = -1 ; j < 2 ; j ++ )
2005 //for ( k = -1 ; k < 2 ; k ++ )
2006 //{
2007 //vox[ i + 1 ][ j + 1 ][ k + 1 ] = getDataAt( ox + i, oy + j, oz + k ) ;
2008 //}
2009
2010
2011 //int edge[6] = { 0,0,0,0,0,0 } ;
2012
2013 //for ( i = 0 ; i < 12 ; i ++ )
2014 //{
2015 //int flag = 1 ;
2016 //for ( j = 0 ; j < 4 ; j ++ )
2017 //{
2018 //nx = 1 + sheetNeighbor[i][j][0] ;
2019 //ny = 1 + sheetNeighbor[i][j][1] ;
2020 //nz = 1 + sheetNeighbor[i][j][2] ;
2021
2022 //if ( vox[nx][ny][nz] < 0 )
2023 //{
2024 //flag = 0 ;
2025 //break ;
2026 //}
2027 //}
2028
2029 //if ( flag )
2030 //{
2031 //int e0 = faceEdges[ i ][ 0 ], e1 = faceEdges[ i ][ 1 ] ;
2032 //edge[ e0 ] ++ ;
2033 //edge[ e1 ] ++ ;
2034 //}
2035 //}
2036
2037 //int edges = 0 ;
2038 //for ( i = 0 ; i < 6 ; i ++ )
2039 //{
2040 //if ( edge[i] )
2041 //{
2042 //continue ;
2043 //}
2044
2045 //nx = 1 + neighbor6[i][0] ;
2046 //ny = 1 + neighbor6[i][1] ;
2047 //nz = 1 + neighbor6[i][2] ;
2048
2049 //if ( vox[nx][ny][nz] >= 0 )
2050 //{
2051 //edges ++ ;
2052 //}
2053
2054 //}
2055
2056 //return edges ;
2057 //}
2058
2059 //int Volume::getNumIsolatedFaces( int ox, int oy, int oz )
2060 //{
2061 //int i, j, k ;
2062 //int nx, ny, nz ;
2063
2064 //int faces = 0 ;
2065 //int cellflag[ 8 ] ;
2066
2067 //int ct = 0 ;
2068 //for ( i = -1 ; i < 1 ; i ++ )
2069 //for ( j = -1 ; j < 1 ; j ++ )
2070 //for ( k = -1 ; k < 1 ; k ++ )
2071 //{
2072 //if ( hasCell( ox + i, oy + j, oz + k ) )
2073 //{
2074 //cellflag[ ct ] = 1 ;
2075 //}
2076 //else
2077 //{
2078 //cellflag[ ct ] = 0 ;
2079 //}
2080 //ct ++ ;
2081 //}
2082
2083 //for ( i = 0 ; i < 12 ; i ++ )
2084 //{
2085 //int hasFace = 1 ;
2086 //for ( j = 0 ; j < 4 ; j ++ )
2087 //{
2088 //nx = ox + sheetNeighbor[i][j][0] ;
2089 //ny = oy + sheetNeighbor[i][j][1] ;
2090 //nz = oz + sheetNeighbor[i][j][2] ;
2091
2092 //if ( getDataAt( nx, ny, nz ) < 0 )
2093 //{
2094 //hasFace = 0 ;
2095 //break ;
2096 //}
2097 //}
2098
2099 //if ( hasFace )
2100 //{
2101 //if (cellflag[ faceCells[i][0] ] == 0 && cellflag[ faceCells[i][1] ] == 0 )
2102 //{
2103 //faces ++ ;
2104 //}
2105 //}
2106 //}
2107
2109 //return faces ;
2110 //}
2111
2112 //int Volume::isFeatureFace2( int ox, int oy, int oz )
2113 //{
2114 //int i ;
2115 //int nx, ny, nz ;
2116
2117 //for ( i = 0 ; i < 6 ; i ++ )
2118 //{
2119 //nx = ox + neighbor6[i][0] ;
2120 //ny = oy + neighbor6[i][1] ;
2121 //nz = oz + neighbor6[i][2] ;
2122
2123 //double val = getDataAt( nx, ny, nz ) ;
2124
2125 //if ( val == 0 )
2126 //{
2127 //return 0 ;
2128 //}
2129
2130 //}
2131
2132 //return 1 ;
2133 //}
2134
2135 int Volume::isFeatureFace( int ox, int oy, int oz )
2136 {
2137 // return 1 ;
2138
2139 int i, j ;
2140 int nx, ny, nz ;
2141
2142 int faces = 12 ;
2143 for ( i = 0 ; i < 12 ; i ++ )
2144 {
2145 int ct = 0 ;
2146 for ( j = 0 ; j < 4 ; j ++ )
2147 {
2148 nx = ox + sheetNeighbor[i][j][0] ;
2149 ny = oy + sheetNeighbor[i][j][1] ;
2150 nz = oz + sheetNeighbor[i][j][2] ;
2151
2152 if ( getDataAt( nx, ny, nz ) < 0 )
2153 {
2154 ct = -1 ;
2155 break ;
2156 }
2157 else if ( getNumNeighbor6( nx, ny, nz ) == 6 )
2158 {
2159 ct = -1 ;
2160 break ;
2161 }
2162 // else if ( getDataAt( nx, ny, nz ) == 0 )
2163 // {
2164 // ct ++ ;
2165 // }
2166
2167
2168 }
2169 if ( ct == -1 || ct >= 1 )
2170 {
2171 faces -- ;
2172 }
2173 }
2174
2175 if ( faces > 0 )
2176 {
2177 return 1 ;
2178 }
2179 return 0 ;
2180
2181 }
2182
2183 //int Volume::hasFeatureFace( int ox, int oy, int oz )
2184 //{
2185 //int i, j, k ;
2186 //int nx, ny, nz ;
2187
2188 //int faceflag ;
2189 //int cellflag[ 8 ] ;
2190
2192 //int ct = 0 ;
2193 //for ( i = -1 ; i < 1 ; i ++ )
2194 //for ( j = -1 ; j < 1 ; j ++ )
2195 //for ( k = -1 ; k < 1 ; k ++ )
2196 //{
2197 //if ( hasCell( ox + i, oy + j, oz + k ) )
2198 //{
2199 //cellflag[ ct ] = 1 ;
2200 //}
2201 //else
2202 //{
2203 //cellflag[ ct ] = 0 ;
2204 //}
2205 //ct ++ ;
2206 //}
2207
2209 //for ( i = 0 ; i < 12 ; i ++ )
2210 //{
2211 //faceflag = 1 ;
2212 //for ( j = 0 ; j < 4 ; j ++ )
2213 //{
2214 //nx = ox + sheetNeighbor[i][j][0] ;
2215 //ny = oy + sheetNeighbor[i][j][1] ;
2216 //nz = oz + sheetNeighbor[i][j][2] ;
2217
2218 //if ( getDataAt( nx, ny, nz ) < 0 )
2219 //{
2220 //faceflag = 0 ;
2221 //break ;
2222 //}
2223 //}
2224
2225 //if ( faceflag )
2226 //{
2227 //if ( cellflag[ faceCells[i][0] ] == 0 && cellflag[ faceCells[i][1] ] == 0 )
2228 //{
2229 //return 1 ;
2230 //}
2231 //}
2232 //}
2233
2234 //return 0 ;
2235
2236 //}
2237
2238 int Volume::isSheetEnd( int ox, int oy, int oz )
2239 {
2240 return ( ( hasCompleteSheet(ox,oy,oz) == 0 ) && isFeatureFace(ox,oy,oz) ) ;
2241
2243 //
2244 //int i, j, k ;
2245 //int nx, ny, nz ;
2246
2247 //double vox[3][3][3] ;
2248 //for ( i = -1 ; i < 2 ; i ++ )
2249 // for ( j = -1 ; j < 2 ; j ++ )
2250 // for ( k = -1 ; k < 2 ; k ++ )
2251 // {
2252 // vox[ i + 1 ][ j + 1 ][ k + 1 ] = getDataAt( ox + i, oy + j, oz + k ) ;
2253 // }
2254
2255 //int edge[6] = { 4,4,4,4,4,4 } ;
2256 //int edge2[6] = { 4,4,4,4,4,4 } ;
2257
2258 //for ( i = 0 ; i < 12 ; i ++ )
2259 //{
2260 // for ( j = 0 ; j < 4 ; j ++ )
2261 // {
2262 // nx = 1 + sheetNeighbor[i][j][0] ;
2263 // ny = 1 + sheetNeighbor[i][j][1] ;
2264 // nz = 1 + sheetNeighbor[i][j][2] ;
2265
2266 // if ( vox[nx][ny][nz] < 0 )
2267 // {
2268 // edge[ faceEdges[ i ][ 0 ] ] -- ;
2269 // edge[ faceEdges[ i ][ 1 ] ] -- ;
2270 // break ;
2271 // }
2272 // }
2273
2274 // for ( j = 0 ; j < 4 ; j ++ )
2275 // {
2276 // nx = 1 + sheetNeighbor[i][j][0] ;
2277 // ny = 1 + sheetNeighbor[i][j][1] ;
2278 // nz = 1 + sheetNeighbor[i][j][2] ;
2279
2280 // if ( vox[nx][ny][nz] <= 0 )
2281 // {
2282 // edge2[ faceEdges[ i ][ 0 ] ] -- ;
2283 // edge2[ faceEdges[ i ][ 1 ] ] -- ;
2284 // break ;
2285 // }
2286 // }
2287 //}
2288
2289 //
2291 //for ( i = 0 ; i < 6 ; i ++ )
2292 //{
2293 // nx = 1 + neighbor6[i][0] ;
2294 // ny = 1 + neighbor6[i][1] ;
2295 // nz = 1 + neighbor6[i][2] ;
2296 // if ( edge[i] == 0 && vox[nx][ny][nz] >= 0 )
2297 // {
2298 // return 0 ;
2299 // }
2300 //}
2301 //*/
2302 //
2303
2304
2305 //for ( i = 0 ; i < 6 ; i ++ )
2306 //{
2307 // if ( edge[ i ] == 1 && edge2[ i ] == 1 )
2308 // {
2309 // return 1 ;
2310 // }
2311 //}
2312
2313 //return 0 ;
2314 }
2315
2316 int Volume::isSimple( int ox, int oy, int oz )
2317 {
2318 /* Test if this is a simple voxel */
2319 // int flag = 0 ;
2320 double vox[3][3][3] ;
2321
2322 int i, j, k ;
2323 for ( i = -1 ; i < 2 ; i ++ )
2324 for ( j = -1 ; j < 2 ; j ++ )
2325 for ( k = -1 ; k < 2 ; k ++ )
2326 {
2327 double tval = getDataAt( ox + i, oy + j, oz + k ) ;
2328
2329 /*
2330 if ( tval == 0 || tval > (va )
2331 {
2332 flag = 1 ;
2333 }
2334 */
2335 /*
2336 if ( tval < 0 && tval == - curwid )
2337 {
2338 printf("Here %d", (int)-tval) ;
2339 vox[ i + 1 ][ j + 1 ][ k + 1 ] = - tval ;
2340 }
2341 else
2342 */
2343 {
2344 vox[ i + 1 ][ j + 1 ][ k + 1 ] = tval ;
2345 }
2346 }
2347
2348 /* Debugging
2349 printf("{") ;
2350 for ( i = 0 ; i < 3 ; i ++ )
2351 {
2352 if ( i ) printf(",") ;
2353 printf("{") ;
2354 for ( j = 0 ; j < 3 ; j ++ )
2355 {
2356 if ( j ) printf(",") ;
2357 printf("{") ;
2358 for ( k = 0 ; k < 3 ; k ++ )
2359 {
2360 if ( k ) printf(",") ;
2361 printf("%d", (vox[i][j][k] >=0 ? 1: 0));
2362 }
2363 printf("}") ;
2364 }
2365 printf("}") ;
2366 }
2367 printf("} Int: %d, Ext: %d\n", countInt( vox ), countExt( vox )) ;
2368 */
2369
2370 if ( countInt( vox ) == 1 && countExt( vox ) == 1 )
2371 {
2372 return 1 ;
2373 }
2374 else
2375 {
2376 return 0 ;
2377 }
2378 }
2379
2380
2381 int Volume::isPiercable( int ox, int oy, int oz )
2382 {
2383 /* Test if this is a simple voxel */
2384 // int flag = 0 ;
2385 double vox[3][3][3] ;
2386
2387 int i, j, k ;
2388 for ( i = -1 ; i < 2 ; i ++ )
2389 for ( j = -1 ; j < 2 ; j ++ )
2390 for ( k = -1 ; k < 2 ; k ++ )
2391 {
2392 double tval = getDataAt( ox + i, oy + j, oz + k ) ;
2393
2394 /*
2395 if ( tval == 0 || tval > (va )
2396 {
2397 flag = 1 ;
2398 }
2399 */
2400 /*
2401 if ( tval < 0 && tval == - curwid )
2402 {
2403 printf("Here %d", (int)-tval) ;
2404 vox[ i + 1 ][ j + 1 ][ k + 1 ] = - tval ;
2405 }
2406 else
2407 */
2408 {
2409 vox[ i + 1 ][ j + 1 ][ k + 1 ] = tval ;
2410 }
2411 }
2412
2413 /* Debugging
2414 printf("{") ;
2415 for ( i = 0 ; i < 3 ; i ++ )
2416 {
2417 if ( i ) printf(",") ;
2418 printf("{") ;
2419 for ( j = 0 ; j < 3 ; j ++ )
2420 {
2421 if ( j ) printf(",") ;
2422 printf("{") ;
2423 for ( k = 0 ; k < 3 ; k ++ )
2424 {
2425 if ( k ) printf(",") ;
2426 printf("%d", (vox[i][j][k] >=0 ? 1: 0));
2427 }
2428 printf("}") ;
2429 }
2430 printf("}") ;
2431 }
2432 printf("} Int: %d, Ext: %d\n", countInt( vox ), countExt( vox )) ;
2433 */
2434
2435 if ( countInt( vox ) == 1 && countExt( vox ) != 1 )
2436 {
2437 return 1 ;
2438 }
2439 else
2440 {
2441 return 0 ;
2442 }
2443 }
2444
2445
2446 //int Volume::isSimple2( int v[3][3][3] )
2447 //{
2449 //double vox[3][3][3] ;
2450
2451 //int i, j, k ;
2452 //for ( i = 0 ; i < 3 ; i ++ )
2453 //for ( j = 0 ; j < 3 ; j ++ )
2454 //for ( k = 0 ; k < 3 ; k ++ )
2455 //{
2456 //if ( v[i][j][k] == 0 )
2457 //{
2458 //vox[ i ][ j ][ k ] = 1 ;
2459 //}
2460 //else
2461 //{
2462 //vox[i][j][k] = -1 ;
2463 //}
2464 //}
2465 //if ( countInt( vox ) == 1 && countExt( vox ) == 1 )
2466 //{
2467 //return 1 ;
2468 //}
2469 //else
2470 //{
2471 //printf("Int: %d Ext: %d\n",countInt( vox ),countExt( vox ) );
2472 //return 0 ;
2473 //}
2474 //}
2475
2476 //int Volume::getNumPotComplex3( int ox, int oy, int oz )
2477 //{
2479
2480
2481 //int i, j, k ;
2482 //if ( ! isSimple( ox, oy, oz ) || isSheetEnd( ox, oy, oz ) )
2483 //{
2484 //return 60 ;
2485 //}
2486 //double val = getDataAt( ox, oy, oz ) ;
2487
2488 //int nx, ny, nz ;
2489
2490
2491 //int numSimple = 0 ;
2492 //for ( i = -1 ; i < 2 ; i ++ )
2493 //for ( j = -1 ; j < 2 ; j ++ )
2494 //for ( k = -1 ; k < 2 ; k ++ )
2495 //{
2496 //nx = ox + i ;
2497 //ny = oy + j ;
2498 //nz = oz + k ;
2499 //if ( getDataAt( nx, ny, nz ) > 0 )
2500 //{
2501 //if ( isSimple( nx, ny, nz ) && ! isSheetEnd( nx, ny, nz ) )
2502 //{
2503 //numSimple ++ ;
2504 //}
2505 //}
2506 //}
2507 //numSimple -- ;
2508
2509 //setDataAt( ox, oy, oz, -val ) ;
2510
2511 //int numPotSimple = 0 ;
2512 //for ( i = -1 ; i < 2 ; i ++ )
2513 //for ( j = -1 ; j < 2 ; j ++ )
2514 //for ( k = -1 ; k < 2 ; k ++ )
2515 //{
2516 //nx = ox + i ;
2517 //ny = oy + j ;
2518 //nz = oz + k ;
2519 //if ( getDataAt( nx, ny, nz ) > 0 )
2520 //{
2521 //if ( isSimple( nx, ny, nz ) && ! isSheetEnd( nx, ny, nz ) )
2522 //{
2523 //numPotSimple ++ ;
2524 //}
2525 //}
2526 //}
2527
2528
2529 //setDataAt( ox, oy, oz, val ) ;
2530
2531
2532
2533
2534 //return 30 - ( numPotSimple - numSimple ) ;
2535 //}
2536
2537 //int Volume::getNumPotComplex4( int ox, int oy, int oz )
2538 //{
2539
2540 //int cells = getNumCells(ox,oy,oz) ;
2542 //int faces = getNumFaces(ox,oy,oz) ;
2544
2545 //return ( cells * 6 - 2 * faces ) ; // + 2 * ( faces * 4 - 4 * iedges ) ;
2546 //}
2547
2548 int Volume::getNumPotComplex( int ox, int oy, int oz )
2549 {
2550 //return 0 ;
2551
2552 int i;
2553 double val = getDataAt( ox, oy, oz ) ;
2554 if ( val <= 0 )
2555 {
2556 // return 70 ;
2557 }
2558
2559 // return getNumNeighbor6( ox, oy, oz ) ;
2560
2561 // int v = ((getNumNeighbor6( ox, oy, oz ) & 255) << 24) ;
2562 //int v = 0 ;
2563
2564 int rvalue = 0, nx, ny, nz ;
2565 setDataAt( ox, oy, oz, -val ) ;
2566
2567 /*
2568 for ( i = -1 ; i < 2 ; i ++ )
2569 for ( j = -1 ; j < 2 ; j ++ )
2570 for ( k = -1 ; k < 2 ; k ++ )
2571 {
2572 nx = ox + i ;
2573 ny = oy + j ;
2574 nz = oz + k ;
2575 if ( getDataAt( nx, ny, nz ) == val )
2576 {
2577 if ( isSheetEnd( nx, ny, nz) || ! isSimple ( nx, ny, nz ) )
2578 {
2579 rvalue ++ ;
2580 }
2581 }
2582 }
2583 */
2584
2585 for ( i = 0 ; i < 6 ; i ++ )
2586 {
2587 nx = ox + neighbor6[i][0] ;
2588 ny = oy + neighbor6[i][1] ;
2589 nz = oz + neighbor6[i][2] ;
2590
2591 if ( getDataAt(nx,ny,nz) >= 0 )
2592 {
2593 int num = getNumNeighbor6( nx, ny, nz ) ;
2594 if ( num > rvalue )
2595 {
2596 rvalue = num ;
2597 }
2598 }
2599 }
2600
2601
2602 setDataAt( ox, oy, oz, val ) ;
2603
2604 return rvalue + getNumNeighbor6( ox, oy, oz ) * 10 ;
2605 /*
2606 int v = (((rvalue + getNumNeighbor6( ox, oy, oz ) * 10) & 255) << 24) ;
2607 v |= ( ( ox & 255 ) << 16 ) ;
2608 v |= ( ( oy & 255 ) << 8 ) ;
2609 v |= ( ( oz & 255 ) ) ;
2610 return v ;
2611 */
2612
2613 }
2614
2615 int Volume::getNumPotComplex2( int ox, int oy, int oz )
2616 {
2617 return getNumPotComplex( ox, oy, oz ) ;
2618
2619 //int i, j, k ;
2620 //double val = getDataAt( ox, oy, oz ) ;
2621 //if ( val <= 0 )
2622 //{
2623 // return 0 ;
2624 //}
2625
2626 //int rvalue = 0, nx, ny, nz ;
2627 //setDataAt( ox, oy, oz, -val ) ;
2628
2629 //for ( i = -1 ; i < 2 ; i ++ )
2630 // for ( j = -1 ; j < 2 ; j ++ )
2631 // for ( k = -1 ; k < 2 ; k ++ )
2632 // {
2633 // nx = ox + i ;
2634 // ny = oy + j ;
2635 // nz = oz + k ;
2636 // if ( getDataAt( nx, ny, nz ) == val )
2637 // {
2638 // if ( isHelixEnd( nx, ny, nz) || ! isSimple ( nx, ny, nz ) )
2639 // {
2640 // rvalue ++ ;
2641 // }
2642 // }
2643 // }
2644
2645 //setDataAt( ox, oy, oz, val ) ;
2646
2647 //return rvalue + getNumNeighbor6( ox, oy, oz ) * 30 ;
2648 }
2649
2650 //int Volume::getNumNeighbor( int ox, int oy, int oz )
2651 //{
2652 //int rvalue = 0 ;
2653 //double val = getDataAt( ox, oy, oz ) ;
2654 //for ( int i = 0 ; i < 6 ; i ++ )
2655 //{
2656 //int nx = ox + neighbor6[i][0] ;
2657 //int ny = oy + neighbor6[i][1] ;
2658 //int nz = oz + neighbor6[i][2] ;
2659
2660 //if ( getDataAt( nx, ny, nz ) == val )
2661 //{
2662 //rvalue ++ ;
2663 //}
2664 //}
2666 //for ( int i = -1 ; i < 2 ; i ++ )
2667 //for ( int j = -1 ; j < 2 ; j ++ )
2668 //for ( int k = -1 ; k < 2 ; k ++ )
2669 //{
2670 //int nx = ox + i ;
2671 //int ny = oy + j ;
2672 //int nz = oz + k ;
2673
2674 //if ( getDataAt( nx, ny, nz ) == val )
2675 //{
2676 //rvalue ++ ;
2677 //}
2678 //}
2679 //*/
2680 //return rvalue ;
2681 //}
2682
2683
2684 //void Volume::setScoreNeighbor( GridQueue* queue )
2685 //{
2687 //gridQueueEle* ele = queue->getHead() ;
2688 //while ( ele != NULL )
2689 //{
2690 //ele->score = getNumNeighbor( ele->x, ele->y, ele->z ) ;
2691 //ele = ele->next ;
2692 //}
2693
2694 //queue->sort( queue->getNumElements() ) ;
2695 //}
2696
2697
2698 int Volume::components6( int vox[3][3][3] )
2699 {
2700 // Stupid flood fill
2701 int tot = 0 ;
2702 int queue[27][3] ;
2703 int vis[3][3][3] ;
2704 int head = 0, tail = 1 ;
2705 int i, j, k ;
2706 for ( i = 0 ; i < 3 ; i ++ )
2707 for ( j = 0 ; j < 3 ; j ++ )
2708 for ( k = 0 ; k < 3 ; k ++ )
2709 {
2710 vis[i][j][k] = 0 ;
2711 if ( vox[i][j][k] )
2712 {
2713 if ( tot == 0 )
2714 {
2715 queue[0][0] = i ;
2716 queue[0][1] = j ;
2717 queue[0][2] = k ;
2718 vis[i][j][k] = 1 ;
2719 }
2720 tot ++ ;
2721 }
2722 }
2723 if ( tot == 0 )
2724 {
2725 return 0 ;
2726 }
2727 // printf("total: %d\n", tot) ;
2728
2729 int ct = 1 ;
2730 while ( head != tail )
2731 {
2732 int x = queue[head][0] ;
2733 int y = queue[head][1] ;
2734 int z = queue[head][2] ;
2735 head ++ ;
2736
2737 for ( i = 0 ; i < 6 ; i ++ )
2738 {
2739 int nx = x + neighbor6[i][0] ;
2740 int ny = y + neighbor6[i][1] ;
2741 int nz = z + neighbor6[i][2] ;
2742 if ( nx >=0 && nx < 3 && ny >=0 && ny < 3 && nz >=0 && nz < 3 )
2743 {
2744 if ( vox[nx][ny][nz] && ! vis[nx][ny][nz] )
2745 {
2746 queue[tail][0] = nx ;
2747 queue[tail][1] = ny ;
2748 queue[tail][2] = nz ;
2749 tail ++ ;
2750 vis[nx][ny][nz] = 1 ;
2751 ct ++ ;
2752 }
2753 }
2754 }
2755 }
2756
2757 if ( ct == tot )
2758 {
2759 return 1 ;
2760 }
2761 else
2762 {
2763 return 2 ;
2764 }
2765
2766 }
2767 int Volume::components26( int vox[3][3][3] )
2768 {
2769 // Stupid flood fill
2770 int tot = 0 ;
2771 int queue[27][3] ;
2772 int vis[3][3][3] ;
2773 int head = 0, tail = 1 ;
2774 int i, j, k ;
2775 for ( i = 0 ; i < 3 ; i ++ )
2776 for ( j = 0 ; j < 3 ; j ++ )
2777 for ( k = 0 ; k < 3 ; k ++ )
2778 {
2779 vis[i][j][k] = 0 ;
2780 if ( vox[i][j][k] )
2781 {
2782 if ( tot == 0 )
2783 {
2784 queue[0][0] = i ;
2785 queue[0][1] = j ;
2786 queue[0][2] = k ;
2787 vis[i][j][k] = 1 ;
2788 }
2789 tot ++ ;
2790 }
2791 }
2792 if ( tot == 0 )
2793 {
2794 return 0 ;
2795 }
2796
2797 int ct = 1 ;
2798 while ( head != tail )
2799 {
2800 int x = queue[head][0] ;
2801 int y = queue[head][1] ;
2802 int z = queue[head][2] ;
2803 head ++ ;
2804
2805 for ( i = -1 ; i < 2 ; i ++ )
2806 for ( j = -1 ; j < 2 ; j ++ )
2807 for ( k = -1 ; k < 2 ; k ++ )
2808 {
2809 int nx = x + i ;
2810 int ny = y + j ;
2811 int nz = z + k ;
2812 if ( nx >=0 && nx < 3 && ny >=0 && ny < 3 && nz >=0 && nz < 3 )
2813 {
2814 if ( vox[nx][ny][nz] && ! vis[nx][ny][nz] )
2815 {
2816 queue[tail][0] = nx ;
2817 queue[tail][1] = ny ;
2818 queue[tail][2] = nz ;
2819 tail ++ ;
2820 vis[nx][ny][nz] = 1 ;
2821 ct ++ ;
2822 }
2823 }
2824 }
2825 }
2826
2827 if ( ct == tot )
2828 {
2829 return 1 ;
2830 }
2831 else
2832 {
2833 return 2 ;
2834 }
2835
2836 }
2837
2838 int Volume::countExt( double vox[3][3][3] )
2839 {
2840 int tvox[3][3][3] ;
2841
2842 for ( int i = 0 ; i < 3 ; i ++ )
2843 for ( int j = 0 ; j < 3 ; j ++ )
2844 for ( int k = 0 ; k < 3 ; k ++ )
2845 {
2846 if ( vox[i][j][k] < 0 )
2847 {
2848 tvox[i][j][k] = 1 ;
2849 }
2850 else
2851 {
2852 tvox[i][j][k] = 0 ;
2853 }
2854 }
2855
2856 return components26( tvox ) ;
2857 }
2858
2859 int Volume::countInt( double vox[3][3][3] )
2860 {
2861 int i, j, k ;
2862 int tvox[3][3][3] ;
2863
2864 for ( i = 0 ; i < 3 ; i ++ )
2865 for ( j = 0 ; j < 3 ; j ++ )
2866 for ( k = 0 ; k < 3 ; k ++ )
2867 {
2868 tvox[i][j][k] = 0 ;
2869 }
2870
2871 for ( i = 0 ; i < 6 ; i ++ )
2872 {
2873 int nx = 1 + neighbor6[i][0] ;
2874 int ny = 1 + neighbor6[i][1] ;
2875 int nz = 1 + neighbor6[i][2] ;
2876 if ( vox[ nx ][ ny ][ nz ] >= 0 )
2877 {
2878 tvox[ nx ][ ny ][ nz ] = 1 ;
2879 for ( j = 0 ; j < 4 ; j ++ )
2880 {
2881 int nnx = neighbor64[i][j][0] + nx ;
2882 int nny = neighbor64[i][j][1] + ny ;
2883 int nnz = neighbor64[i][j][2] + nz ;
2884 if ( vox[ nnx ][ nny ][ nnz ] >= 0 )
2885 {
2886 tvox[ nnx ][ nny ][ nnz ] = 1 ;
2887 }
2888 }
2889 }
2890 }
2891
2892 return components6( tvox ) ;
2893 }
2894
2895 int Volume::countIntEuler( int ox, int oy, int oz )
2896 {
2897 int nv = 0 , ne = 0, nc = 0 ;
2898
2899 int i, j, k ;
2900 int tvox[3][3][3] ;
2901 double vox[3][3][3] ;
2902
2903 for ( i = 0 ; i < 3 ; i ++ )
2904 for ( j = 0 ; j < 3 ; j ++ )
2905 for ( k = 0 ; k < 3 ; k ++ )
2906 {
2907 vox[i][j][k] = getDataAt( ox - 1 + i, oy - 1 + j, oz - 1 + k ) ;
2908 tvox[i][j][k] = 0 ;
2909 }
2910
2911 for ( i = 0 ; i < 6 ; i ++ )
2912 {
2913 int nx = 1 + neighbor6[i][0] ;
2914 int ny = 1 + neighbor6[i][1] ;
2915 int nz = 1 + neighbor6[i][2] ;
2916 if ( vox[nx][ny][nz] >= 0 )
2917 {
2918 tvox[ nx ][ ny ][ nz ] = 1 ;
2919
2920 nv ++ ;
2921
2922 for ( j = 0 ; j < 4 ; j ++ )
2923 {
2924 int nnx = neighbor64[i][j][0] + nx ;
2925 int nny = neighbor64[i][j][1] + ny ;
2926 int nnz = neighbor64[i][j][2] + nz ;
2927 if ( vox[nnx][nny][nnz] >= 0 )
2928 {
2929 if ( tvox[nnx][nny][nnz] == 0 )
2930 {
2931 tvox[nnx][nny][nnz] = 1 ;
2932 nv ++ ;
2933 }
2934
2935 ne ++ ;
2936 }
2937 }
2938 }
2939 }
2940
2941 nc = components6( tvox ) ;
2942
2943 return ( nc - ( nv - ne ) ) ;
2944 }
2945
2946 //void Volume::erodeNoTopo( float thr, int wid )
2947 //{
2949 //int i, j, k ;
2951 //#ifdef VERBOSE
2952 //printf("Thresholding the volume to -MAX_ERODE/0...\n") ;
2953 //#endif
2954 //threshold( thr, -MAX_ERODE, 0 ) ;
2955
2957 //#ifdef VERBOSE
2958 //printf("Initializing queue...\n") ;
2959 //#endif
2960 //GridQueue* queue = new GridQueue( ) ;
2961
2962 //for ( i = 0 ; i < getSizeX() ; i ++ )
2963 //for ( j = 0 ; j < getSizeY() ; j ++ )
2964 //for ( k = 0 ; k < getSizeZ() ; k ++ )
2965 //{
2966 //if ( getDataAt( i, j, k ) >= 0 )
2967 //{
2968 //for ( int m = 0 ; m < 6 ; m ++ )
2969 //{
2970 //if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
2971 //{
2972 //setDataAt( i, j, k, 1 ) ;
2973 //queue->pushQueue( i, j, k ) ;
2974 //break ;
2975 //}
2976 //}
2977 //}
2978 //}
2979 //#ifdef VERBOSE
2980 //printf("Total %d nodes\n", queue->getNumElements() ) ;
2981
2983 //printf("Start erosion to %d...\n", wid) ;
2984 //#endif
2985 //double val = 0;
2986 //int ox, oy, oz ;
2987 //int curwid = 0 ;
2988 //int total = 0, ct = 0 ;
2989 //while ( 1 )
2990 //{
2991 //if ( ct == total )
2992 //{
2993 //#ifdef VERBOSE
2994 //printf("Layer %d has %d nodes.\n", (int) curwid, total ) ;
2995 //#endif
2996 //curwid ++ ;
2997 //ct = 0 ;
2998 //total = queue->getNumElements() ;
2999 //if ( total == 0 )
3000 //{
3001 //break ;
3002 //}
3003 //}
3004
3005 //queue->popQueue(ox, oy, oz) ;
3006 //val = getDataAt( ox, oy, oz ) ;
3007 //if ( val > wid )
3008 //{
3009 //break ;
3010 //}
3011 //ct ++ ;
3012
3013 //setDataAt( ox, oy, oz, -val ) ;
3014
3015
3016 //for ( int m = 0 ; m < 6 ; m ++ )
3017 //{
3018 //int nx = ox + neighbor6[m][0] ;
3019 //int ny = oy + neighbor6[m][1] ;
3020 //int nz = oz + neighbor6[m][2] ;
3021 //if ( getDataAt( nx, ny, nz ) == 0 )
3022 //{
3023 //setDataAt( nx, ny, nz, val + 1 ) ;
3024 //queue->pushQueue( nx, ny, nz ) ;
3025 //}
3026 //}
3027 //}
3028
3030 //#ifdef VERBOSE
3031 //printf("Thresholding the volume to 0/1...\n") ;
3032 //#endif
3033 //threshold( 0, 0, 1 ) ;
3034
3035 //}
3036
3037 //void Volume::erodeTopo( float thr, int wid )
3038 //{
3040 //int i, j, k ;
3042 //#ifdef VERBOSE
3043 //printf("Thresholding the volume to -MAX_ERODE/0...\n") ;
3044 //#endif
3045 //threshold( thr, -MAX_ERODE, 0 ) ;
3046
3048 //#ifdef VERBOSE
3049 //printf("Initializing queue...\n") ;
3050 //#endif
3051 //GridQueue* queue = new GridQueue( ) ;
3052
3053 //for ( i = 0 ; i < getSizeX() ; i ++ )
3054 //for ( j = 0 ; j < getSizeY() ; j ++ )
3055 //for ( k = 0 ; k < getSizeZ() ; k ++ )
3056 //{
3057 //if ( getDataAt( i, j, k ) >= 0 )
3058 //{
3059 //for ( int m = 0 ; m < 6 ; m ++ )
3060 //{
3061 //if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
3062 //{
3063 //setDataAt( i, j, k, 1 ) ;
3064 //queue->pushQueue( i, j, k ) ;
3065 //break ;
3066 //}
3067 //}
3068 //}
3069 //}
3070 //#ifdef VERBOSE
3071 //printf("Total %d nodes\n", queue->getNumElements() ) ;
3072
3074 //printf("Start erosion to %d...\n", wid) ;
3075 //#endif
3076
3077 //double val = 0;
3078 //int ox, oy, oz ;
3079 //int curwid = 0 ;
3080 //int total = 0, ct = 0 ;
3081 //while ( 1 )
3082 //{
3083 //if ( ct == total )
3084 //{
3085 //#ifdef VERBOSE
3086 //printf("Layer %d has %d nodes.\n", (int) curwid, total ) ;
3087 //#endif
3088 //curwid ++ ;
3089 //ct = 0 ;
3090 //total = queue->getNumElements() ;
3091 //if ( total == 0 )
3092 //{
3093 //break ;
3094 //}
3095 //}
3096
3097 //queue->popQueue(ox, oy, oz) ;
3098 //val = getDataAt( ox, oy, oz ) ;
3099 //if ( val > wid )
3100 //{
3101 //break ;
3102 //}
3103 //ct ++ ;
3104
3105 //if ( isSimple( ox, oy, oz ) )
3106 //{
3108 //setDataAt( ox, oy, oz, -val ) ;
3109 //}
3110 //else
3111 //{
3113 //setDataAt( ox, oy, oz, val + 1 ) ;
3114 //queue->pushQueue( ox, oy, oz ) ;
3115 //}
3116
3117
3118 //for ( int m = 0 ; m < 6 ; m ++ )
3119 //{
3120 //int nx = ox + neighbor6[m][0] ;
3121 //int ny = oy + neighbor6[m][1] ;
3122 //int nz = oz + neighbor6[m][2] ;
3123 //if ( getDataAt( nx, ny, nz ) == 0 )
3124 //{
3125 //setDataAt( nx, ny, nz, val + 1 ) ;
3126 //queue->pushQueue( nx, ny, nz ) ;
3127 //}
3128 //}
3129 //}
3130
3132 //#ifdef VERBOSE
3133 //printf("Thresholding the volume to 0/1...\n") ;
3134 //#endif
3135 //threshold( 0, 0, 1 ) ;
3136
3137 //}
3138
3139 //void Volume::erode2( float thr, int wid )
3140 //{
3141 //int i, j, k ;
3143 //#ifdef VERBOSE
3144 //printf("Thresholding the volume to -MAX_ERODE/0...\n") ;
3145 //#endif
3146 //threshold( thr, -MAX_ERODE, 0 ) ;
3147
3149 //#ifdef VERBOSE
3150 //printf("Initializing queue...\n") ;
3151 //#endif
3152 //GridQueue2* queue = new GridQueue2( ) ;
3153 //GridQueue2* queue2 = new GridQueue2( ) ;
3154
3155 //for ( i = 0 ; i < getSizeX() ; i ++ )
3156 //for ( j = 0 ; j < getSizeY() ; j ++ )
3157 //for ( k = 0 ; k < getSizeZ() ; k ++ )
3158 //{
3159 //if ( getDataAt( i, j, k ) >= 0 )
3160 //{
3161 //for ( int m = 0 ; m < 6 ; m ++ )
3162 //{
3163 //if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
3164 //{
3165 //setDataAt( i, j, k, 1 ) ;
3166 //queue->prepend( i, j, k ) ;
3167 //break ;
3168 //}
3169 //}
3170 //}
3171 //}
3172 //#ifdef VERBOSE
3173 //printf("Total %d nodes\n", queue->getNumElements() ) ;
3174
3177 //printf("Start erosion to %d...\n", wid) ;
3178 //#endif
3179 //gridQueueEle* ele ;
3180 //int ox, oy, oz ;
3181
3182 //for ( int curwid = 1 ; curwid <= wid ; curwid ++ )
3183 //{
3184 //int numComplex = 0, numSimple = 0 ;
3185 //#ifdef VERBOSE
3186 //printf("Processing %d nodes in layer %d\n", queue->getNumElements(), curwid) ;
3187 //#endif
3188
3190 //while ( ( ele = queue->getNext() ) != NULL )
3191 //{
3192 //for ( int m = 0 ; m < 6 ; m ++ )
3193 //{
3194 //int nx = ele->x + neighbor6[m][0] ;
3195 //int ny = ele->y + neighbor6[m][1] ;
3196 //int nz = ele->z + neighbor6[m][2] ;
3197 //if ( getDataAt( nx, ny, nz ) == 0 )
3198 //{
3199 //setDataAt( nx, ny, nz, curwid + 1 ) ;
3200 //queue2->prepend( nx, ny, nz ) ;
3201 //}
3202 //}
3203
3204 //}
3205 //*/
3206
3208 //int seed[3] = {-1,-1,-1};
3209 //queue->reset() ;
3210 //while ( queue->getNumElements() > 0 )
3211 //{
3212 //if ( seed[0] < 0 ) printf("After initial scoring...\n");
3213 //queue->reset() ;
3214 //ele = queue->getNext() ;
3215
3217 //while ( ele != NULL )
3218 //{
3219 //ox = ele->x ;
3220 //oy = ele->y ;
3221 //oz = ele->z ;
3222
3224 //if ( seed[0] < 0 ||
3225 //( ox < seed[0] + 2 && ox > seed[0] - 2 &&
3226 //oy < seed[1] + 2 && oy > seed[1] - 2 &&
3227 //oz < seed[2] + 2 && oz > seed[2] - 2 ) )
3228 //{
3229 //if ( ! isSimple( ox, oy, oz ) )
3230 //{
3232 //setDataAt( ox, oy, oz, curwid + 1 ) ;
3233 //queue2->prepend( ox, oy, oz ) ;
3234 //ele = queue->remove() ;
3235
3236 //numComplex ++ ;
3237 //}
3238 //else
3239 //{
3240 //ele = queue->getNext() ;
3241 //}
3242 //}
3243 //else
3244 //{
3245 //ele = queue->getNext() ;
3246 //}
3247 //}
3248
3250 //queue->reset() ;
3251 //ele = queue->getNext() ;
3252 //int preScore = -1;
3253 //while ( ele != NULL )
3254 //{
3255 //ox = ele->x ;
3256 //oy = ele->y ;
3257 //oz = ele->z ;
3258
3260 //if ( seed[0] < 0 ||
3261 //( ox < seed[0] + 3 && ox > seed[0] - 3 &&
3262 //oy < seed[1] + 3 && oy > seed[1] - 3 &&
3263 //oz < seed[2] + 3 && oz > seed[2] - 3 ) )
3264 //{
3265 //ele->score = getNumPotComplex( ox, oy, oz ) ;
3266 //}
3267
3268
3269 //if ( ele->score < preScore )
3270 //{
3272 //ele = queue->swap() ;
3273 //}
3274 //else
3275 //{
3276 //preScore = ele->score ;
3277 //}
3278
3280 //if ( ele->next == NULL )
3281 //{
3282 //ox = ele->x ;
3283 //oy = ele->y ;
3284 //oz = ele->z ;
3285 //setDataAt( ox, oy, oz, -1 ) ;
3287 //seed[0] = ox ;
3288 //seed[1] = oy ;
3289 //seed[2] = oz ;
3290 //queue->remove() ;
3292
3293
3294 //for ( int m = 0 ; m < 6 ; m ++ )
3295 //{
3296 //int nx = ox + neighbor6[m][0] ;
3297 //int ny = oy + neighbor6[m][1] ;
3298 //int nz = oz + neighbor6[m][2] ;
3299 //if ( getDataAt( nx, ny, nz ) == 0 )
3300 //{
3301 //setDataAt( nx, ny, nz, curwid + 1 ) ;
3302 //queue2->prepend( nx, ny, nz ) ;
3303 //}
3304 //}
3305
3306
3307 //numSimple ++ ;
3308 //ele = NULL ;
3309 //}
3310 //else
3311 //{
3312 //ele = queue->getNext() ;
3313 //}
3314 //}
3315
3316 //}
3317
3318 //delete queue ;
3319 //queue = queue2 ;
3320 //queue2 = new GridQueue2() ;
3321 //#ifdef VERBOSE
3322 //printf("%d complex, %d simple\n", numComplex, numSimple) ;
3323 //#endif
3324
3325 //if ( numSimple == 0 )
3326 //{
3327 //break ;
3328 //}
3329 //}
3330
3332 //#ifdef VERBOSE
3333 //printf("Thresholding the volume to 0/1...\n") ;
3334 //#endif
3335 //threshold( 0, 0, 1 ) ;
3336
3337 //}
3338
3339 //void Volume::erodeShapeTopo( float thr, int wid )
3340 //{
3342 //int i, j, k ;
3344 //#ifdef VERBOSE
3345 //printf("Thresholding the volume to -MAX_ERODE/0...\n") ;
3346 //#endif
3347 //threshold( thr, -MAX_ERODE, 0 ) ;
3348
3350 //#ifdef VERBOSE
3351 //printf("Initializing queue...\n") ;
3352 //#endif
3353 //GridQueue2* queue2 = new GridQueue2( ) ;
3354 //GridQueue2* queue3 = new GridQueue2( ) ;
3355 //PriorityQueue <gridPoint,int> * queue = new PriorityQueue <gridPoint,int> ( MAX_QUEUELEN );
3356
3357 //for ( i = 0 ; i < getSizeX() ; i ++ )
3358 //for ( j = 0 ; j < getSizeY() ; j ++ )
3359 //for ( k = 0 ; k < getSizeZ() ; k ++ )
3360 //{
3361 //if ( getDataAt( i, j, k ) >= 0 )
3362 //{
3363 //for ( int m = 0 ; m < 6 ; m ++ )
3364 //{
3365 //if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
3366 //{
3367 //setDataAt( i, j, k, 1 ) ;
3368 //queue2->prepend( i, j, k ) ;
3369 //break ;
3370 //}
3371 //}
3372 //}
3373 //}
3374 //#ifdef VERBOSE
3375 //printf("Total %d nodes\n", queue2->getNumElements() ) ;
3376
3377
3380 //printf("Start erosion to %d...\n", wid) ;
3381 //#endif
3382 //gridQueueEle* ele ;
3383 //gridPoint* gp ;
3384 //int ox, oy, oz ;
3385 //int score ;
3386 //Volume* scrvol = new Volume( this->getSizeX() , this->getSizeY(), this->getSizeZ() ) ;
3387 //for ( i = 0 ; i < getSizeX() * getSizeY() * getSizeZ() ; i ++ )
3388 //{
3389 //scrvol->setDataAt( i, -1 ) ;
3390 //}
3391
3392 //for ( int curwid = 1 ; curwid <= wid ; curwid ++ )
3393 //{
3397
3398 //int numComplex = 0, numSimple = 0 ;
3399 //#ifdef VERBOSE
3400 //printf("Processing %d nodes in layer %d\n", queue2->getNumElements(), curwid) ;
3401 //#endif
3402
3406 //queue2->reset() ;
3407 //ele = queue2->getNext() ;
3408 //while ( ele != NULL )
3409 //{
3410 //ox = ele->x ;
3411 //oy = ele->y ;
3412 //oz = ele->z ;
3413
3415 //if ( ! isSimple( ox, oy, oz ) )
3416 //{
3418 //setDataAt( ox, oy, oz, curwid + 1 ) ;
3419 //queue3->prepend( ox, oy, oz ) ;
3420 //ele = queue2->remove() ;
3421
3422 //numComplex ++ ;
3423 //}
3424 //else
3425 //{
3426 //ele = queue2->getNext() ;
3427 //}
3428 //}
3429
3433 //queue2->reset() ;
3434 //ele = queue2->getNext() ;
3435 //while ( ele != NULL )
3436 //{
3437 //ox = ele->x ;
3438 //oy = ele->y ;
3439 //oz = ele->z ;
3440
3442 //score = getNumPotComplex( ox, oy, oz ) ;
3443 //scrvol->setDataAt( ox, oy, oz, score ) ;
3444
3446 //gp = new gridPoint ;
3447 //gp->x = ox ;
3448 //gp->y = oy ;
3449 //gp->z = oz ;
3450 //queue->add( gp, -score ) ;
3451
3452 //ele = queue2->remove() ;
3453 //}
3454
3457 //delete queue2 ;
3458 //queue2 = queue3 ;
3459 //queue3 = new GridQueue2( ) ;
3460
3462 //while ( ! queue->isEmpty() )
3463 //{
3465 //queue->remove( gp, score ) ;
3466 //ox = gp->x ;
3467 //oy = gp->y ;
3468 //oz = gp->z ;
3469 //delete gp ;
3470 //score = -score ;
3471
3475 //if ( getDataAt( ox, oy, oz ) != curwid || (int) scrvol->getDataAt( ox, oy, oz ) != score )
3476 //{
3477 //continue ;
3478 //}
3479
3481 //setDataAt( ox, oy, oz, -1 ) ;
3482 //numSimple ++ ;
3484
3486 //for ( int m = 0 ; m < 6 ; m ++ )
3487 //{
3488 //int nx = ox + neighbor6[m][0] ;
3489 //int ny = oy + neighbor6[m][1] ;
3490 //int nz = oz + neighbor6[m][2] ;
3491 //if ( getDataAt( nx, ny, nz ) == 0 )
3492 //{
3493 //setDataAt( nx, ny, nz, curwid + 1 ) ;
3494 //queue2->prepend( nx, ny, nz ) ;
3495 //}
3496 //}
3497
3500 //for ( i = -1 ; i < 2 ; i ++ )
3501 //for ( j = -1 ; j < 2 ; j ++ )
3502 //for ( k = -1 ; k < 2 ; k ++ )
3503 //{
3504 //int nx = ox + i ;
3505 //int ny = oy + j ;
3506 //int nz = oz + k ;
3507
3509 //if ( getDataAt( nx, ny, nz ) == curwid && ! isSimple( nx, ny, nz ) )
3510 //{
3512 //setDataAt( nx, ny, nz, curwid + 1 ) ;
3513 //queue2->prepend( nx, ny, nz ) ;
3514 //numComplex ++ ;
3515 //}
3516 //}
3517
3521 //for ( i = -2 ; i < 3 ;i ++ )
3522 //for ( j = -2 ; j < 3 ; j ++ )
3523 //for ( k = -2 ; k < 3 ; k ++ )
3524 //{
3525 //int nx = ox + i ;
3526 //int ny = oy + j ;
3527 //int nz = oz + k ;
3528
3529 //if ( getDataAt( nx, ny, nz ) == curwid )
3530 //{
3532 //score = getNumPotComplex( nx, ny, nz ) ;
3533
3534 //if ( score != (int) scrvol->getDataAt( nx, ny, nz ) )
3535 //{
3537 //scrvol->setDataAt( nx, ny, nz, score ) ;
3539 //gp = new gridPoint ;
3540 //gp->x = nx ;
3541 //gp->y = ny ;
3542 //gp->z = nz ;
3543 //queue->add( gp, -score ) ;
3544 //}
3545 //}
3546 //}
3547 //*/
3548
3549 //}
3550
3551 //#ifdef VERBOSE
3552 //printf("%d complex, %d simple\n", numComplex, numSimple) ;
3553 //#endif
3554 //if ( numSimple == 0 )
3555 //{
3556 //break ;
3557 //}
3558 //}
3559
3561 //#ifdef VERBOSE
3562 //printf("Thresholding the volume to 0/1...\n") ;
3563 //#endif
3564 //threshold( 0, 0, 1 ) ;
3565 //delete queue;
3566
3567 //}
3568
3569
3570 //void Volume::erodeAtom( float thr, int wid, Volume* avol )
3571 //{
3573 //int i, j, k ;
3575 //#ifdef VERBOSE
3576 //printf("Thresholding the volume to -MAX_ERODE/0...\n") ;
3577 //#endif
3578 //threshold( thr, -MAX_ERODE, 0 ) ;
3579
3581 //#ifdef VERBOSE
3582 //printf("Initializing queue...\n") ;
3583 //#endif
3584 //GridQueue2* queue2 = new GridQueue2( ) ;
3585 //GridQueue2* queue3 = new GridQueue2( ) ;
3586 //PriorityQueue <gridPoint,int> * queue = new PriorityQueue <gridPoint,int> ( MAX_QUEUELEN );
3587
3588 //for ( i = 0 ; i < getSizeX() ; i ++ )
3589 //for ( j = 0 ; j < getSizeY() ; j ++ )
3590 //for ( k = 0 ; k < getSizeZ() ; k ++ )
3591 //{
3592 //if ( getDataAt( i, j, k ) >= 0 )
3593 //{
3594 //if ( avol->getDataAt(i,j,k) > 0 )
3595 //{
3596 //setDataAt( i, j, k, MAX_ERODE ) ;
3597 //}
3598 //else
3599 //{
3600 //for ( int m = 0 ; m < 6 ; m ++ )
3601 //{
3602 //if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
3603 //{
3604 //setDataAt( i, j, k, 1 ) ;
3605 //queue2->prepend( i, j, k ) ;
3606 //break ;
3607 //}
3608 //}
3609 //}
3610 //}
3611 //}
3612 //#ifdef VERBOSE
3613 //printf("Total %d nodes\n", queue2->getNumElements() ) ;
3614
3615
3618 //printf("Start erosion to %d...\n", wid) ;
3619 //#endif
3620
3621 //gridQueueEle* ele ;
3622 //gridPoint* gp ;
3623 //int ox, oy, oz ;
3624 //int score ;
3625 //Volume* scrvol = new Volume( this->getSizeX() , this->getSizeY(), this->getSizeZ() ) ;
3626 //for ( i = 0 ; i < getSizeX() * getSizeY() * getSizeZ() ; i ++ )
3627 //{
3628 //scrvol->setDataAt( i, -1 ) ;
3629 //}
3630
3631 //for ( int curwid = 1 ; curwid <= wid ; curwid ++ )
3632 //{
3636
3637 //int numComplex = 0, numSimple = 0 ;
3638 //#ifdef VERBOSE
3639 //printf("Processing %d nodes in layer %d\n", queue2->getNumElements(), curwid) ;
3640 //#endif
3641
3645 //queue2->reset() ;
3646 //ele = queue2->getNext() ;
3647 //while ( ele != NULL )
3648 //{
3649 //ox = ele->x ;
3650 //oy = ele->y ;
3651 //oz = ele->z ;
3652
3654 //if ( ! isSimple( ox, oy, oz ) )
3655 //{
3657 //setDataAt( ox, oy, oz, curwid + 1 ) ;
3658 //queue3->prepend( ox, oy, oz ) ;
3659 //ele = queue2->remove() ;
3660
3661 //numComplex ++ ;
3662 //}
3663 //else
3664 //{
3665 //ele = queue2->getNext() ;
3666 //}
3667 //}
3668
3672 //queue2->reset() ;
3673 //ele = queue2->getNext() ;
3674 //while ( ele != NULL )
3675 //{
3676 //ox = ele->x ;
3677 //oy = ele->y ;
3678 //oz = ele->z ;
3679
3681 //score = getNumPotComplex( ox, oy, oz ) ;
3682 //scrvol->setDataAt( ox, oy, oz, score ) ;
3683
3685 //gp = new gridPoint ;
3686 //gp->x = ox ;
3687 //gp->y = oy ;
3688 //gp->z = oz ;
3689 //queue->add( gp, -score ) ;
3690
3691 //ele = queue2->remove() ;
3692 //}
3693
3696 //delete queue2 ;
3697 //queue2 = queue3 ;
3698 //queue3 = new GridQueue2( ) ;
3699
3701 //while ( ! queue->isEmpty() )
3702 //{
3704 //queue->remove( gp, score ) ;
3705 //ox = gp->x ;
3706 //oy = gp->y ;
3707 //oz = gp->z ;
3708 //delete gp ;
3709 //score = -score ;
3710
3714 //if ( getDataAt( ox, oy, oz ) != curwid || (int) scrvol->getDataAt( ox, oy, oz ) != score )
3715 //{
3716 //continue ;
3717 //}
3718
3720 //setDataAt( ox, oy, oz, -1 ) ;
3721 //numSimple ++ ;
3723
3725 //for ( int m = 0 ; m < 6 ; m ++ )
3726 //{
3727 //int nx = ox + neighbor6[m][0] ;
3728 //int ny = oy + neighbor6[m][1] ;
3729 //int nz = oz + neighbor6[m][2] ;
3730 //if ( getDataAt( nx, ny, nz ) == 0 )
3731 //{
3732 //setDataAt( nx, ny, nz, curwid + 1 ) ;
3733 //queue2->prepend( nx, ny, nz ) ;
3734 //}
3735 //}
3736
3739 //for ( i = -1 ; i < 2 ; i ++ )
3740 //for ( j = -1 ; j < 2 ; j ++ )
3741 //for ( k = -1 ; k < 2 ; k ++ )
3742 //{
3743 //int nx = ox + i ;
3744 //int ny = oy + j ;
3745 //int nz = oz + k ;
3746
3748 //if ( getDataAt( nx, ny, nz ) == curwid && ! isSimple( nx, ny, nz ) )
3749
3750 //{
3752 //setDataAt( nx, ny, nz, curwid + 1 ) ;
3753 //queue2->prepend( nx, ny, nz ) ;
3754 //numComplex ++ ;
3755 //}
3756 //}
3757
3761 //for ( i = -2 ; i < 3 ;i ++ )
3762 //for ( j = -2 ; j < 3 ; j ++ )
3763 //for ( k = -2 ; k < 3 ; k ++ )
3764 //{
3765 //int nx = ox + i ;
3766 //int ny = oy + j ;
3767 //int nz = oz + k ;
3768
3769 //if ( getDataAt( nx, ny, nz ) == curwid )
3770 //{
3772 //score = getNumPotComplex( nx, ny, nz ) ;
3773
3774 //if ( score != (int) scrvol->getDataAt( nx, ny, nz ) )
3775 //{
3777 //scrvol->setDataAt( nx, ny, nz, score ) ;
3779 //gp = new gridPoint ;
3780 //gp->x = nx ;
3781 //gp->y = ny ;
3782 //gp->z = nz ;
3783 //queue->add( gp, -score ) ;
3784 //}
3785 //}
3786 //}
3787 //*/
3788
3789 //}
3790 //#ifdef VERBOSE
3791 //printf("%d complex, %d simple\n", numComplex, numSimple) ;
3792 //#endif
3793
3794 //if ( numSimple == 0 )
3795 //{
3796 //break ;
3797 //}
3798 //}
3799
3801 //#ifdef VERBOSE
3802 //printf("Thresholding the volume to 0/1...\n") ;
3803 //#endif
3804 //threshold( 0, 0, 1 ) ;
3805 //delete queue;
3806
3807 //}
3808
3810 //* Assuming the current volume has already been thresholded to 0/1
3811 //*/
3812 void Volume::curveSkeleton( Volume* grayvol, float lowthr, float highthr, Volume* svol )
3813 {
3814 int i, j, k ;
3815 // First, threshold the volume
3816 #ifdef VERBOSE
3817 printf("Thresholding the volume to -1/0...\n") ;
3818 #endif
3819 threshold( 0.5f, -1, 0 ) ;
3820
3821 // Next, apply convergent erosion
3822 // by preserving: complex nodes, curve end-points, and sheet points
3823
3824 // Next, initialize the linked queue
3825 #ifdef VERBOSE
3826 printf("Initializing queue...\n") ;
3827 #endif
3828 GridQueue2* queue2 = new GridQueue2( ) ;
3829 GridQueue2* queue3 = new GridQueue2( ) ;
3830 GridQueue2* queue4 = new GridQueue2( ) ;
3832
3833 for ( i = 0 ; i < getSizeX() ; i ++ )
3834 for ( j = 0 ; j < getSizeY() ; j ++ )
3835 for ( k = 0 ; k < getSizeZ() ; k ++ )
3836 {
3837 if ( getDataAt( i, j, k ) >= 0 )
3838 {
3839 float v = (float)grayvol->getDataAt(i,j,k) ;
3840 if ( v <= lowthr || v > highthr || svol->getDataAt(i,j,k) > 0 )
3841 {
3842 setDataAt( i, j, k, MAX_ERODE ) ;
3843 }
3844 else
3845 {
3846 for ( int m = 0 ; m < 6 ; m ++ )
3847 {
3848 if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
3849 {
3850 // setDataAt( i, j, k, 1 ) ;
3851 queue2->prepend( i, j, k ) ;
3852 break ;
3853 }
3854 }
3855 }
3856 }
3857 }
3858 int wid = MAX_ERODE ;
3859 #ifdef VERBOSE
3860 printf("Total %d nodes\n", queue2->getNumElements() ) ;
3861 printf("Start erosion to %d...\n", wid) ;
3862 #endif
3863
3864
3865 // Perform erosion
3866 gridQueueEle* ele ;
3867 gridPoint* gp ;
3868 int ox, oy, oz ;
3869 int score ;
3870 Volume* scrvol = new Volume( this->getSizeX() , this->getSizeY(), this->getSizeZ() ) ;
3871 for ( i = 0 ; i < getSizeX() * getSizeY() * getSizeZ() ; i ++ )
3872 {
3873 scrvol->setDataAt( i, -1 ) ;
3874 }
3875
3876 #ifdef NOISE_DIS_HELIX
3877 Volume* noisevol = new Volume( getSizeX(), getSizeY(), getSizeZ() ) ;
3878 #endif
3879
3880 for ( int curwid = 1 ; curwid <= wid ; curwid ++ )
3881 {
3882 // At the start of each iteration,
3883 // queue2 holds all the nodes for this layer
3884 // queue3 and queue are empty
3885
3886 int numComplex = 0, numSimple = 0 ;
3887 #ifdef VERBOSE
3888 printf("Processing %d nodes in layer %d\n", queue2->getNumElements(), curwid) ;
3889 #endif
3890
3891 /*
3892 We first need to assign curwid + 1 to every node in this layer
3893 */
3894 queue2->reset() ;
3895 ele = queue2->getNext() ;
3896 while ( ele != NULL )
3897 {
3898 ox = ele->x ;
3899 oy = ele->y ;
3900 oz = ele->z ;
3901
3902 if ( getDataAt(ox,oy,oz) == curwid )
3903 {
3904 ele = queue2->remove() ;
3905 }
3906 else
3907 {
3908 setDataAt(ox,oy,oz, curwid) ;
3909 ele = queue2->getNext() ;
3910 }
3911 }
3912 queue4->reset() ;
3913 ele = queue4->getNext() ;
3914 while ( ele != NULL )
3915 {
3916 ox = ele->x ;
3917 oy = ele->y ;
3918 oz = ele->z ;
3919
3920 queue2->prepend(ox,oy,oz) ;
3921 ele = queue4->remove() ;
3922 }
3923
3924 // Now queue2 holds all the nodes for this layer
3925
3926 #ifdef NOISE_DIS_HELIX
3927 /* Extra step: classify nodes in queue2 into noise and non-noise nodes */
3928 queue2->reset() ;
3929
3930 // First run
3931 int flag = 0 ;
3932 while ( ( ele = queue2->getNext() ) != NULL )
3933 {
3934 ox = ele->x ;
3935 oy = ele->y ;
3936 oz = ele->z ;
3937 if ( NOISE_DIS_HELIX <= 1 )
3938 {
3939 noisevol->setDataAt( ox, oy, oz, 0 ) ;
3940 }
3941 else
3942 {
3943 flag = 0 ;
3944 for ( int m = 0 ; m < 6 ; m ++ )
3945 {
3946 int nx = ox + neighbor6[m][0] ;
3947 int ny = oy + neighbor6[m][1] ;
3948 int nz = oz + neighbor6[m][2] ;
3949 if ( getDataAt( nx, ny, nz ) == 0 )
3950 {
3951 noisevol->setDataAt( ox, oy, oz, 1 ) ;
3952 flag = 1 ;
3953 break ;
3954 }
3955 }
3956 if ( ! flag )
3957 {
3958 noisevol->setDataAt( ox, oy, oz, 0 ) ;
3959 }
3960 }
3961 }
3962
3963 int cur, visited ;
3964 for ( cur = 1 ; cur < NOISE_DIS_HELIX ; cur ++ )
3965 {
3966 queue2->reset() ;
3967 int count = 0 ;
3968 visited = 0 ;
3969
3970 while ( ( ele = queue2->getNext() ) != NULL )
3971 {
3972 ox = ele->x ;
3973 oy = ele->y ;
3974 oz = ele->z ;
3975
3976 if ( noisevol->getDataAt( ox, oy, oz ) == 1 )
3977 {
3978 visited ++ ;
3979 continue ;
3980 }
3981
3982 flag = 0 ;
3983 for ( int m = 0 ; m < 6 ; m ++ )
3984 {
3985 int nx = ox + neighbor6[m][0] ;
3986 int ny = oy + neighbor6[m][1] ;
3987 int nz = oz + neighbor6[m][2] ;
3988 if ( getDataAt( nx, ny, nz ) > 0 && noisevol->getDataAt( nx, ny, nz ) == 1 )
3989 {
3990 noisevol->setDataAt( ox, oy, oz, 1 ) ;
3991 visited ++ ;
3992 count ++ ;
3993 break ;
3994 }
3995 }
3996 }
3997
3998 if ( count == 0 )
3999 {
4000 break ;
4001 }
4002 }
4003 printf("Maximum feature distance: %d Un-touched: %d\n", cur, queue2->getNumElements() - visited ) ;
4004
4005
4006 #endif
4007 /* Commented out for debugging
4008
4009 // First,
4010 // check for complex nodes in queue2
4011 // move them from queue2 to queue3
4012 queue2->reset() ;
4013 ele = queue2->getNext() ;
4014 while ( ele != NULL )
4015 {
4016 ox = ele->x ;
4017 oy = ele->y ;
4018 oz = ele->z ;
4019
4020 // Check simple
4021 #ifndef NOISE_DIS_HELIX
4022 if ( isHelixEnd( ox, oy, oz ) || ! isSimple( ox, oy, oz ) )
4023 #else
4024 if ( isHelixEnd( ox, oy, oz, noisevol ) || ! isSimple( ox, oy, oz ) )
4025 #endif
4026 {
4027 // Complex, set to next layer
4028 setDataAt( ox, oy, oz, curwid + 1 ) ;
4029 queue3->prepend( ox, oy, oz ) ;
4030 ele = queue2->remove() ;
4031
4032 numComplex ++ ;
4033 }
4034 else
4035 {
4036 ele = queue2->getNext() ;
4037 }
4038 }
4039 */
4040
4041 // Next,
4042 // Compute score for each node left in queue2
4043 // move them into priority queue
4044 queue2->reset() ;
4045 ele = queue2->getNext() ;
4046 while ( ele != NULL )
4047 {
4048 ox = ele->x ;
4049 oy = ele->y ;
4050 oz = ele->z ;
4051
4052 // Compute score
4053 score = getNumPotComplex2( ox, oy, oz ) ;
4054 scrvol->setDataAt( ox, oy, oz, score ) ;
4055
4056 // Push to queue
4057 gp = new gridPoint ;
4058 gp->x = ox ;
4059 gp->y = oy ;
4060 gp->z = oz ;
4061 // queue->add( gp, -score ) ;
4062 queue->add( gp, score ) ;
4063
4064 ele = queue2->remove() ;
4065 }
4066
4067 // Rename queue3 to be queue2,
4068 // Clear queue3
4069 // From now on, queue2 holds nodes of next level
4070 delete queue2 ;
4071 queue2 = queue3 ;
4072 queue3 = new GridQueue2( ) ;
4073
4074 // Next, start priority queue iteration
4075 while ( ! queue->isEmpty() )
4076 {
4077 // Retrieve the node with the highest score
4078 queue->remove( gp, score ) ;
4079 ox = gp->x ;
4080 oy = gp->y ;
4081 oz = gp->z ;
4082 delete gp ;
4083 // score = -score ;
4084
4085 // Ignore the node
4086 // if it has been processed before
4087 // or it has an updated score
4088 if ( getDataAt( ox, oy, oz ) != curwid || (int) scrvol->getDataAt( ox, oy, oz ) != score )
4089 {
4090 continue ;
4091 }
4092
4093 /* Commented out for debugging
4094
4095 // Remove this simple node
4096 setDataAt( ox, oy, oz, -1 ) ;
4097 numSimple ++ ;
4098 // printf("Highest score: %d\n", score) ;
4099 */
4100
4101 /* Added for debugging */
4102 // Check simple
4103 #ifndef NOISE_DIS_HELIX
4104 // if ( hasIsolatedEdge( ox, oy, oz ) && ! isNoiseHelixEnd( ox, oy, oz ) )
4105 if ( isHelixEnd( ox, oy, oz ) || ! isSimple( ox, oy, oz ) )
4106 #else
4107 if ( isHelixEnd( ox, oy, oz ) || ! isSimple( ox, oy, oz ) )
4108 #endif
4109 {
4110 // Complex, set to next layer
4111 setDataAt( ox, oy, oz, curwid + 1 ) ;
4112 queue4->prepend( ox, oy, oz ) ;
4113 numComplex ++ ;
4114 }
4115 else
4116 {
4117 setDataAt( ox, oy, oz, -1 ) ;
4118 numSimple ++ ;
4119
4120
4121 /* Adding ends */
4122 // Move its neighboring unvisited node to queue2
4123 for ( int m = 0 ; m < 6 ; m ++ )
4124 {
4125 int nx = ox + neighbor6[m][0] ;
4126 int ny = oy + neighbor6[m][1] ;
4127 int nz = oz + neighbor6[m][2] ;
4128 if ( getDataAt( nx, ny, nz ) == 0 )
4129 {
4130 // setDataAt( nx, ny, nz, curwid + 1 ) ;
4131 queue2->prepend( nx, ny, nz ) ;
4132 }
4133 }
4134
4135 }
4136
4137
4138 /* Commented out for debugging
4139
4140 // Find complex nodes in its 3x3 neighborhood
4141 // move them to queue2
4142 for ( i = -1 ; i < 2 ; i ++ )
4143 for ( j = -1 ; j < 2 ; j ++ )
4144 for ( k = -1 ; k < 2 ; k ++ )
4145 {
4146 int nx = ox + i ;
4147 int ny = oy + j ;
4148 int nz = oz + k ;
4149
4150 // Check simple
4151 if ( getDataAt( nx, ny, nz ) == curwid &&
4152 // ( isSheetEnd( ox, oy, oz ) || ! isSimple( nx, ny, nz )) )
4153 #ifndef NOISE_DIS_HELIX
4154 ( isHelixEnd( nx, ny, nz ) || ! isSimple( nx, ny, nz ) ) )
4155 #else
4156 ( isHelixEnd( nx, ny, nz, noisevol ) || ! isSimple( nx, ny, nz ) ) )
4157 #endif
4158
4159 {
4160 // Complex, set to next layer
4161 setDataAt( nx, ny, nz, curwid + 1 ) ;
4162 queue2->prepend( nx, ny, nz ) ;
4163 numComplex ++ ;
4164 }
4165 }
4166 */
4167
4168 // Update scores for nodes in its 5x5 neighborhood
4169 // insert them back into priority queue
4170
4171 for ( i = -2 ; i < 3 ;i ++ )
4172 for ( j = -2 ; j < 3 ; j ++ )
4173 for ( k = -2 ; k < 3 ; k ++ )
4174 {
4175 int nx = ox + i ;
4176 int ny = oy + j ;
4177 int nz = oz + k ;
4178
4179 if ( getDataAt( nx, ny, nz ) == curwid )
4180 {
4181 // Compute score
4182 score = getNumPotComplex2( nx, ny, nz ) ;
4183
4184 if ( score != (int) scrvol->getDataAt( nx, ny, nz ) )
4185 {
4186 // printf("Update\n") ;
4187 scrvol->setDataAt( nx, ny, nz, score ) ;
4188 // Push to queue
4189 gp = new gridPoint ;
4190 gp->x = nx ;
4191 gp->y = ny ;
4192 gp->z = nz ;
4193 // queue->add( gp, -score ) ;
4194 queue->add( gp, score ) ;
4195 }
4196 }
4197 }
4198
4199
4200 }
4201
4202 #ifdef VERBOSE
4203 printf("%d complex, %d simple\n", numComplex, numSimple) ;
4204 #endif
4205
4206 if ( numSimple == 0 )
4207 {
4208 if ( queue2->getNumElements() > 0 )
4209 {
4210 printf("*************************wierd here*************************\n");
4211 }
4212 break ;
4213 }
4214 }
4215
4216 // Remove all internal voxels (contained in manifold surfaces)
4217 queue2->reset() ;
4218 queue4->reset() ;
4219 ele = queue4->getNext() ;
4220 while ( ele != NULL )
4221 {
4222 ox = ele->x ;
4223 oy = ele->y ;
4224 oz = ele->z ;
4225
4226 if ( isPiercable(ox,oy,oz) == 1 ) // hasCompleteSheet( ox, oy, oz ) == 1 ) //
4227 {
4228 queue2->prepend(ox,oy,oz) ;
4229 // setDataAt( ox, oy, oz, -1 ) ;
4230 }
4231 ele = queue4->remove() ;
4232 }
4233
4234 for ( i = 0 ; i < getSizeX() ; i ++ )
4235 for ( j = 0 ; j < getSizeY() ; j ++ )
4236 for ( k = 0 ; k < getSizeZ() ; k ++ )
4237 {
4238 if ( getDataAt( i, j, k ) == 0 && isPiercable(i,j,k) ) //hasCompleteSheet(i,j,k) == 1) //
4239 {
4240 queue2->prepend( i, j, k ) ;
4241 }
4242 }
4243 queue2->reset() ;
4244 ele = queue2->getNext() ;
4245 while ( ele != NULL )
4246 {
4247 ox = ele->x ;
4248 oy = ele->y ;
4249 oz = ele->z ;
4250 setDataAt( ox, oy, oz, -1 ) ;
4251 ele = queue2->remove() ;
4252 }
4253
4254
4255 // Finally, clean up
4256 delete scrvol;
4257 delete queue;
4258 delete queue2;
4259 delete queue3;
4260 delete queue4;
4261 #ifdef VERBOSE
4262 printf("Thresholding the volume to 0/1...\n") ;
4263 #endif
4264 threshold( 0, 0, 1 ) ;
4265 }
4266
4267 // Compute curve skeleton
4268 void Volume::curveSkeleton( float thr, Volume* svol )
4269 {
4270 int i, j, k ;
4271 // First, threshold the volume
4272 #ifdef VERBOSE
4273 printf("Thresholding the volume to -1/0...\n") ;
4274 #endif
4275 threshold( thr, -1, 0 ) ;
4276
4277 // Next, apply convergent erosion
4278 // by preserving: complex nodes, curve end-points, and sheet points
4279
4280 // Next, initialize the linked queue
4281 #ifdef VERBOSE
4282 printf("Initializing queue...\n") ;
4283 #endif
4284 GridQueue2* queue2 = new GridQueue2( ) ;
4285 GridQueue2* queue3 = new GridQueue2( ) ;
4286 GridQueue2* queue4 = new GridQueue2( ) ;
4288
4289 for ( i = 0 ; i < getSizeX() ; i ++ )
4290 for ( j = 0 ; j < getSizeY() ; j ++ )
4291 for ( k = 0 ; k < getSizeZ() ; k ++ )
4292 {
4293 if ( getDataAt( i, j, k ) >= 0 )
4294 {
4295 if ( svol->getDataAt(i,j,k) > 0 )
4296 {
4297 setDataAt( i, j, k, MAX_ERODE ) ;
4298 }
4299 else
4300 {
4301 for ( int m = 0 ; m < 6 ; m ++ )
4302 {
4303 if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
4304 {
4305 // setDataAt( i, j, k, 1 ) ;
4306 queue2->prepend( i, j, k ) ;
4307 break ;
4308 }
4309 }
4310 }
4311 }
4312 }
4313
4314 int wid = MAX_ERODE ;
4315 #ifdef VERBOSE
4316 printf("Total %d nodes\n", queue2->getNumElements() ) ;
4317 printf("Start erosion to %d...\n", wid) ;
4318 #endif
4319
4320
4321 // Perform erosion
4322 gridQueueEle* ele ;
4323 gridPoint* gp ;
4324 int ox, oy, oz ;
4325 int score ;
4326 Volume* scrvol = new Volume( this->getSizeX() , this->getSizeY(), this->getSizeZ() ) ;
4327 for ( i = 0 ; i < getSizeX() * getSizeY() * getSizeZ() ; i ++ )
4328 {
4329 scrvol->setDataAt( i, -1 ) ;
4330 }
4331
4332 #ifdef NOISE_DIS_HELIX
4333 Volume* noisevol = new Volume( getSizeX(), getSizeY(), getSizeZ() ) ;
4334 #endif
4335
4336 for ( int curwid = 1 ; curwid <= wid ; curwid ++ )
4337 {
4338 // At the start of each iteration,
4339 // queue2 holds all the nodes for this layer
4340 // queue3 and queue are empty
4341
4342 int numComplex = 0, numSimple = 0 ;
4343 #ifdef VERBOSE
4344 printf("Processing %d nodes in layer %d\n", queue2->getNumElements(), curwid) ;
4345 #endif
4346
4347 /*
4348 We first need to assign curwid + 1 to every node in this layer
4349 */
4350 queue2->reset() ;
4351 ele = queue2->getNext() ;
4352 while ( ele != NULL )
4353 {
4354 ox = ele->x ;
4355 oy = ele->y ;
4356 oz = ele->z ;
4357
4358 if ( getDataAt(ox,oy,oz) == curwid )
4359 {
4360 ele = queue2->remove() ;
4361 }
4362 else
4363 {
4364 setDataAt(ox,oy,oz, curwid) ;
4365 ele = queue2->getNext() ;
4366 }
4367 }
4368 queue4->reset() ;
4369 ele = queue4->getNext() ;
4370 while ( ele != NULL )
4371 {
4372 ox = ele->x ;
4373 oy = ele->y ;
4374 oz = ele->z ;
4375
4376 queue2->prepend(ox,oy,oz) ;
4377 ele = queue4->remove() ;
4378 }
4379
4380 // Now queue2 holds all the nodes for this layer
4381
4382 #ifdef NOISE_DIS_HELIX
4383 /* Extra step: classify nodes in queue2 into noise and non-noise nodes */
4384 queue2->reset() ;
4385
4386 // First run
4387 int flag = 0 ;
4388 while ( ( ele = queue2->getNext() ) != NULL )
4389 {
4390 ox = ele->x ;
4391 oy = ele->y ;
4392 oz = ele->z ;
4393 if ( NOISE_DIS_HELIX <= 1 )
4394 {
4395 noisevol->setDataAt( ox, oy, oz, 0 ) ;
4396 }
4397 else
4398 {
4399 flag = 0 ;
4400 for ( int m = 0 ; m < 6 ; m ++ )
4401 {
4402 int nx = ox + neighbor6[m][0] ;
4403 int ny = oy + neighbor6[m][1] ;
4404 int nz = oz + neighbor6[m][2] ;
4405 if ( getDataAt( nx, ny, nz ) == 0 )
4406 {
4407 noisevol->setDataAt( ox, oy, oz, 1 ) ;
4408 flag = 1 ;
4409 break ;
4410 }
4411 }
4412 if ( ! flag )
4413 {
4414 noisevol->setDataAt( ox, oy, oz, 0 ) ;
4415 }
4416 }
4417 }
4418
4419 int cur, visited ;
4420 for ( cur = 1 ; cur < NOISE_DIS_HELIX ; cur ++ )
4421 {
4422 queue2->reset() ;
4423 int count = 0 ;
4424 visited = 0 ;
4425
4426 while ( ( ele = queue2->getNext() ) != NULL )
4427 {
4428 ox = ele->x ;
4429 oy = ele->y ;
4430 oz = ele->z ;
4431
4432 if ( noisevol->getDataAt( ox, oy, oz ) == 1 )
4433 {
4434 visited ++ ;
4435 continue ;
4436 }
4437
4438 flag = 0 ;
4439 for ( int m = 0 ; m < 6 ; m ++ )
4440 {
4441 int nx = ox + neighbor6[m][0] ;
4442 int ny = oy + neighbor6[m][1] ;
4443 int nz = oz + neighbor6[m][2] ;
4444 if ( getDataAt( nx, ny, nz ) > 0 && noisevol->getDataAt( nx, ny, nz ) == 1 )
4445 {
4446 noisevol->setDataAt( ox, oy, oz, 1 ) ;
4447 visited ++ ;
4448 count ++ ;
4449 break ;
4450 }
4451 }
4452 }
4453
4454 if ( count == 0 )
4455 {
4456 break ;
4457 }
4458 }
4459 printf("Maximum feature distance: %d Un-touched: %d\n", cur, queue2->getNumElements() - visited ) ;
4460
4461
4462 #endif
4463 /* Commented out for debugging
4464
4465 // First,
4466 // check for complex nodes in queue2
4467 // move them from queue2 to queue3
4468 queue2->reset() ;
4469 ele = queue2->getNext() ;
4470 while ( ele != NULL )
4471 {
4472 ox = ele->x ;
4473 oy = ele->y ;
4474 oz = ele->z ;
4475
4476 // Check simple
4477 #ifndef NOISE_DIS_HELIX
4478 if ( isHelixEnd( ox, oy, oz ) || ! isSimple( ox, oy, oz ) )
4479 #else
4480 if ( isHelixEnd( ox, oy, oz, noisevol ) || ! isSimple( ox, oy, oz ) )
4481 #endif
4482 {
4483 // Complex, set to next layer
4484 setDataAt( ox, oy, oz, curwid + 1 ) ;
4485 queue3->prepend( ox, oy, oz ) ;
4486 ele = queue2->remove() ;
4487
4488 numComplex ++ ;
4489 }
4490 else
4491 {
4492 ele = queue2->getNext() ;
4493 }
4494 }
4495 */
4496
4497 // Next,
4498 // Compute score for each node left in queue2
4499 // move them into priority queue
4500 queue2->reset() ;
4501 ele = queue2->getNext() ;
4502 while ( ele != NULL )
4503 {
4504 ox = ele->x ;
4505 oy = ele->y ;
4506 oz = ele->z ;
4507
4508 // Compute score
4509 score = getNumPotComplex2( ox, oy, oz ) ;
4510 scrvol->setDataAt( ox, oy, oz, score ) ;
4511
4512 // Push to queue
4513 gp = new gridPoint ;
4514 gp->x = ox ;
4515 gp->y = oy ;
4516 gp->z = oz ;
4517 // queue->add( gp, -score ) ;
4518 queue->add( gp, score ) ;
4519
4520 ele = queue2->remove() ;
4521 }
4522
4523 // Rename queue3 to be queue2,
4524 // Clear queue3
4525 // From now on, queue2 holds nodes of next level
4526 delete queue2 ;
4527 queue2 = queue3 ;
4528 queue3 = new GridQueue2( ) ;
4529
4530 // Next, start priority queue iteration
4531 while ( ! queue->isEmpty() )
4532 {
4533 // Retrieve the node with the highest score
4534 queue->remove( gp, score ) ;
4535 ox = gp->x ;
4536 oy = gp->y ;
4537 oz = gp->z ;
4538 delete gp ;
4539 // score = -score ;
4540
4541 // Ignore the node
4542 // if it has been processed before
4543 // or it has an updated score
4544 if ( getDataAt( ox, oy, oz ) != curwid || (int) scrvol->getDataAt( ox, oy, oz ) != score )
4545 {
4546 continue ;
4547 }
4548
4549 /* Commented out for debugging
4550
4551 // Remove this simple node
4552 setDataAt( ox, oy, oz, -1 ) ;
4553 numSimple ++ ;
4554 // printf("Highest score: %d\n", score) ;
4555 */
4556
4557 /* Added for debugging */
4558 // Check simple
4559 #ifndef NOISE_DIS_HELIX
4560 // if ( hasIsolatedEdge( ox, oy, oz ) && ! isNoiseHelixEnd( ox, oy, oz ) )
4561 if ( isHelixEnd( ox, oy, oz ) || ! isSimple( ox, oy, oz ) )
4562 #else
4563 if ( isHelixEnd( ox, oy, oz ) || ! isSimple( ox, oy, oz ) )
4564 #endif
4565 {
4566 // Complex, set to next layer
4567 setDataAt( ox, oy, oz, curwid + 1 ) ;
4568 queue4->prepend( ox, oy, oz ) ;
4569 numComplex ++ ;
4570 }
4571 else
4572 {
4573 setDataAt( ox, oy, oz, -1 ) ;
4574 numSimple ++ ;
4575 }
4576 /* Adding ends */
4577
4578 // Move its neighboring unvisited node to queue2
4579 for ( int m = 0 ; m < 6 ; m ++ )
4580 {
4581 int nx = ox + neighbor6[m][0] ;
4582 int ny = oy + neighbor6[m][1] ;
4583 int nz = oz + neighbor6[m][2] ;
4584 if ( getDataAt( nx, ny, nz ) == 0 )
4585 {
4586 // setDataAt( nx, ny, nz, curwid + 1 ) ;
4587 queue2->prepend( nx, ny, nz ) ;
4588 }
4589 }
4590
4591 /* Commented out for debugging
4592
4593 // Find complex nodes in its 3x3 neighborhood
4594 // move them to queue2
4595 for ( i = -1 ; i < 2 ; i ++ )
4596 for ( j = -1 ; j < 2 ; j ++ )
4597 for ( k = -1 ; k < 2 ; k ++ )
4598 {
4599 int nx = ox + i ;
4600 int ny = oy + j ;
4601 int nz = oz + k ;
4602
4603 // Check simple
4604 if ( getDataAt( nx, ny, nz ) == curwid &&
4605 // ( isSheetEnd( ox, oy, oz ) || ! isSimple( nx, ny, nz )) )
4606 #ifndef NOISE_DIS_HELIX
4607 ( isHelixEnd( nx, ny, nz ) || ! isSimple( nx, ny, nz ) ) )
4608 #else
4609 ( isHelixEnd( nx, ny, nz, noisevol ) || ! isSimple( nx, ny, nz ) ) )
4610 #endif
4611
4612 {
4613 // Complex, set to next layer
4614 setDataAt( nx, ny, nz, curwid + 1 ) ;
4615 queue2->prepend( nx, ny, nz ) ;
4616 numComplex ++ ;
4617 }
4618 }
4619 */
4620
4621 // Update scores for nodes in its 5x5 neighborhood
4622 // insert them back into priority queue
4623
4624 for ( i = -2 ; i < 3 ;i ++ )
4625 for ( j = -2 ; j < 3 ; j ++ )
4626 for ( k = -2 ; k < 3 ; k ++ )
4627 {
4628 int nx = ox + i ;
4629 int ny = oy + j ;
4630 int nz = oz + k ;
4631
4632 if ( getDataAt( nx, ny, nz ) == curwid )
4633 {
4634 // Compute score
4635 score = getNumPotComplex2( nx, ny, nz ) ;
4636
4637 if ( score != (int) scrvol->getDataAt( nx, ny, nz ) )
4638 {
4639 // printf("Update\n") ;
4640 scrvol->setDataAt( nx, ny, nz, score ) ;
4641 // Push to queue
4642 gp = new gridPoint ;
4643 gp->x = nx ;
4644 gp->y = ny ;
4645 gp->z = nz ;
4646 // queue->add( gp, -score ) ;
4647 queue->add( gp, score ) ;
4648 }
4649 }
4650 }
4651
4652
4653 }
4654
4655 #ifdef VERBOSE
4656 printf("%d complex, %d simple\n", numComplex, numSimple) ;
4657 #endif
4658
4659 if ( numSimple == 0 )
4660 {
4661 break ;
4662 }
4663 }
4664
4665 // Finally, clean up
4666 delete scrvol;
4667 delete queue;
4668 delete queue2;
4669 delete queue3;
4670 delete queue4;
4671 #ifdef VERBOSE
4672 printf("Thresholding the volume to 0/1...\n") ;
4673 #endif
4674 threshold( 0, 0, 1 ) ;
4675 }
4676
4677 // Compute curve skeleton in 2D
4678 void Volume::curveSkeleton2D( float thr, Volume* svol )
4679 {
4680 int i, j, k ;
4681 // First, threshold the volume
4682 #ifdef VERBOSE
4683 printf("Thresholding the volume to -1/0...\n") ;
4684 #endif
4685 threshold( thr, -1, 0 ) ;
4686
4687 // Next, apply convergent erosion
4688 // by preserving: complex nodes, curve end-points, and sheet points
4689
4690 // Next, initialize the linked queue
4691 #ifdef VERBOSE
4692 printf("Initializing queue...\n") ;
4693 #endif
4694 GridQueue2* queue2 = new GridQueue2( ) ;
4695 GridQueue2* queue3 = new GridQueue2( ) ;
4696 GridQueue2* queue4 = new GridQueue2( ) ;
4698
4699 for ( i = 0 ; i < getSizeX() ; i ++ )
4700 for ( j = 0 ; j < getSizeY() ; j ++ )
4701 for ( k = 0 ; k < getSizeZ() ; k ++ )
4702 {
4703 if ( getDataAt( i, j, k ) >= 0 )
4704 {
4705 if ( svol->getDataAt(i,j,k) > 0 )
4706 {
4707 setDataAt( i, j, k, MAX_ERODE ) ;
4708 }
4709 else
4710 {
4711 for ( int m = 0 ; m < 4 ; m ++ )
4712 {
4713 if ( getDataAt( i + neighbor4[m][0], j + neighbor4[m][1], k ) < 0 )
4714 {
4715 // setDataAt( i, j, k, 1 ) ;
4716 queue2->prepend( i, j, k ) ;
4717 break ;
4718 }
4719 }
4720 }
4721 }
4722 }
4723 int wid = MAX_ERODE ;
4724 #ifdef VERBOSE
4725 printf("Total %d nodes\n", queue2->getNumElements() ) ;
4726 printf("Start erosion to %d...\n", wid) ;
4727 #endif
4728
4729
4730 // Perform erosion
4731 gridQueueEle* ele ;
4732 gridPoint* gp ;
4733 int ox, oy, oz ;
4734 int score ;
4735 Volume* scrvol = new Volume( this->getSizeX() , this->getSizeY(), this->getSizeZ() ) ;
4736 for ( i = 0 ; i < getSizeX() * getSizeY() * getSizeZ() ; i ++ )
4737 {
4738 scrvol->setDataAt( i, -1 ) ;
4739 }
4740
4741 #ifdef NOISE_DIS_HELIX
4742 Volume* noisevol = new Volume( getSizeX(), getSizeY(), getSizeZ() ) ;
4743 #endif
4744
4745 for ( int curwid = 1 ; curwid <= wid ; curwid ++ )
4746 {
4747 // At the start of each iteration,
4748 // queue2 holds all the nodes for this layer
4749 // queue3 and queue are empty
4750
4751 int numComplex = 0, numSimple = 0 ;
4752 #ifdef VERBOSE
4753 printf("Processing %d nodes in layer %d\n", queue2->getNumElements(), curwid) ;
4754 #endif
4755
4756 /*
4757 We first need to assign curwid + 1 to every node in this layer
4758 */
4759 queue2->reset() ;
4760 ele = queue2->getNext() ;
4761 while ( ele != NULL )
4762 {
4763 ox = ele->x ;
4764 oy = ele->y ;
4765 oz = ele->z ;
4766
4767 if ( getDataAt(ox,oy,oz) == curwid )
4768 {
4769 ele = queue2->remove() ;
4770 }
4771 else
4772 {
4773 setDataAt(ox,oy,oz, curwid) ;
4774 ele = queue2->getNext() ;
4775 }
4776 }
4777 queue4->reset() ;
4778 ele = queue4->getNext() ;
4779 while ( ele != NULL )
4780 {
4781 ox = ele->x ;
4782 oy = ele->y ;
4783 oz = ele->z ;
4784
4785 queue2->prepend(ox,oy,oz) ;
4786 ele = queue4->remove() ;
4787 }
4788
4789 // Now queue2 holds all the nodes for this layer
4790
4791 #ifdef NOISE_DIS_HELIX
4792 /* Extra step: classify nodes in queue2 into noise and non-noise nodes */
4793 queue2->reset() ;
4794
4795 // First run
4796 int flag = 0 ;
4797 while ( ( ele = queue2->getNext() ) != NULL )
4798 {
4799 ox = ele->x ;
4800 oy = ele->y ;
4801 oz = ele->z ;
4802 if ( NOISE_DIS_HELIX <= 1 )
4803 {
4804 noisevol->setDataAt( ox, oy, oz, 0 ) ;
4805 }
4806 else
4807 {
4808 flag = 0 ;
4809 for ( int m = 0 ; m < 6 ; m ++ )
4810 {
4811 int nx = ox + neighbor6[m][0] ;
4812 int ny = oy + neighbor6[m][1] ;
4813 int nz = oz + neighbor6[m][2] ;
4814 if ( getDataAt( nx, ny, nz ) == 0 )
4815 {
4816 noisevol->setDataAt( ox, oy, oz, 1 ) ;
4817 flag = 1 ;
4818 break ;
4819 }
4820 }
4821 if ( ! flag )
4822 {
4823 noisevol->setDataAt( ox, oy, oz, 0 ) ;
4824 }
4825 }
4826 }
4827
4828 int cur, visited ;
4829 for ( cur = 1 ; cur < NOISE_DIS_HELIX ; cur ++ )
4830 {
4831 queue2->reset() ;
4832 int count = 0 ;
4833 visited = 0 ;
4834
4835 while ( ( ele = queue2->getNext() ) != NULL )
4836 {
4837 ox = ele->x ;
4838 oy = ele->y ;
4839 oz = ele->z ;
4840
4841 if ( noisevol->getDataAt( ox, oy, oz ) == 1 )
4842 {
4843 visited ++ ;
4844 continue ;
4845 }
4846
4847 flag = 0 ;
4848 for ( int m = 0 ; m < 6 ; m ++ )
4849 {
4850 int nx = ox + neighbor6[m][0] ;
4851 int ny = oy + neighbor6[m][1] ;
4852 int nz = oz + neighbor6[m][2] ;
4853 if ( getDataAt( nx, ny, nz ) > 0 && noisevol->getDataAt( nx, ny, nz ) == 1 )
4854 {
4855 noisevol->setDataAt( ox, oy, oz, 1 ) ;
4856 visited ++ ;
4857 count ++ ;
4858 break ;
4859 }
4860 }
4861 }
4862
4863 if ( count == 0 )
4864 {
4865 break ;
4866 }
4867 }
4868 printf("Maximum feature distance: %d Un-touched: %d\n", cur, queue2->getNumElements() - visited ) ;
4869
4870
4871 #endif
4872 /* Commented out for debugging
4873
4874 // First,
4875 // check for complex nodes in queue2
4876 // move them from queue2 to queue3
4877 queue2->reset() ;
4878 ele = queue2->getNext() ;
4879 while ( ele != NULL )
4880 {
4881 ox = ele->x ;
4882 oy = ele->y ;
4883 oz = ele->z ;
4884
4885 // Check simple
4886 #ifndef NOISE_DIS_HELIX
4887 if ( isHelixEnd( ox, oy, oz ) || ! isSimple( ox, oy, oz ) )
4888 #else
4889 if ( isHelixEnd( ox, oy, oz, noisevol ) || ! isSimple( ox, oy, oz ) )
4890 #endif
4891 {
4892 // Complex, set to next layer
4893 setDataAt( ox, oy, oz, curwid + 1 ) ;
4894 queue3->prepend( ox, oy, oz ) ;
4895 ele = queue2->remove() ;
4896
4897 numComplex ++ ;
4898 }
4899 else
4900 {
4901 ele = queue2->getNext() ;
4902 }
4903 }
4904 */
4905
4906 // Next,
4907 // Compute score for each node left in queue2
4908 // move them into priority queue
4909 queue2->reset() ;
4910 ele = queue2->getNext() ;
4911 while ( ele != NULL )
4912 {
4913 ox = ele->x ;
4914 oy = ele->y ;
4915 oz = ele->z ;
4916
4917 // Compute score
4918 score = getNumPotComplex2( ox, oy, oz ) ;
4919 //score = getNumNeighbor6( ox, oy, oz ) ;
4920 scrvol->setDataAt( ox, oy, oz, score ) ;
4921
4922 // Push to queue
4923 gp = new gridPoint ;
4924 gp->x = ox ;
4925 gp->y = oy ;
4926 gp->z = oz ;
4927 // queue->add( gp, -score ) ;
4928 queue->add( gp, score ) ;
4929
4930 ele = queue2->remove() ;
4931 }
4932
4933 // Rename queue3 to be queue2,
4934 // Clear queue3
4935 // From now on, queue2 holds nodes of next level
4936 delete queue2 ;
4937 queue2 = queue3 ;
4938 queue3 = new GridQueue2( ) ;
4939
4940 // Next, start priority queue iteration
4941 while ( ! queue->isEmpty() )
4942 {
4943 // Retrieve the node with the highest score
4944 queue->remove( gp, score ) ;
4945 ox = gp->x ;
4946 oy = gp->y ;
4947 oz = gp->z ;
4948 delete gp ;
4949 // score = -score ;
4950
4951 // Ignore the node
4952 // if it has been processed before
4953 // or it has an updated score
4954 if ( getDataAt( ox, oy, oz ) != curwid || (int) scrvol->getDataAt( ox, oy, oz ) != score )
4955 {
4956 continue ;
4957 }
4958
4959 /* Commented out for debugging
4960
4961 // Remove this simple node
4962 setDataAt( ox, oy, oz, -1 ) ;
4963 numSimple ++ ;
4964 // printf("Highest score: %d\n", score) ;
4965 */
4966
4967 /* Added for debugging */
4968 // Check simple
4969 #ifndef NOISE_DIS_HELIX
4970 // if ( hasIsolatedEdge( ox, oy, oz ) && ! isNoiseHelixEnd( ox, oy, oz ) )
4971 if ( isHelixEnd( ox, oy, oz ) || ! isSimple( ox, oy, oz ) )
4972 #else
4973 if ( isHelixEnd( ox, oy, oz ) || ! isSimple( ox, oy, oz ) )
4974 #endif
4975 {
4976 // Complex, set to next layer
4977 setDataAt( ox, oy, oz, curwid + 1 ) ;
4978 queue4->prepend( ox, oy, oz ) ;
4979 numComplex ++ ;
4980 }
4981 else
4982 {
4983 setDataAt( ox, oy, oz, -1 ) ;
4984 numSimple ++ ;
4985 }
4986 /* Adding ends */
4987
4988 // Move its neighboring unvisited node to queue2
4989 for ( int m = 0 ; m < 4 ; m ++ )
4990 {
4991 int nx = ox + neighbor4[m][0] ;
4992 int ny = oy + neighbor4[m][1] ;
4993 int nz = oz ;
4994 if ( getDataAt( nx, ny, nz ) == 0 )
4995 {
4996 // setDataAt( nx, ny, nz, curwid + 1 ) ;
4997 queue2->prepend( nx, ny, nz ) ;
4998 }
4999 }
5000
5001 /* Commented out for debugging
5002
5003 // Find complex nodes in its 3x3 neighborhood
5004 // move them to queue2
5005 for ( i = -1 ; i < 2 ; i ++ )
5006 for ( j = -1 ; j < 2 ; j ++ )
5007 for ( k = -1 ; k < 2 ; k ++ )
5008 {
5009 int nx = ox + i ;
5010 int ny = oy + j ;
5011 int nz = oz + k ;
5012
5013 // Check simple
5014 if ( getDataAt( nx, ny, nz ) == curwid &&
5015 // ( isSheetEnd( ox, oy, oz ) || ! isSimple( nx, ny, nz )) )
5016 #ifndef NOISE_DIS_HELIX
5017 ( isHelixEnd( nx, ny, nz ) || ! isSimple( nx, ny, nz ) ) )
5018 #else
5019 ( isHelixEnd( nx, ny, nz, noisevol ) || ! isSimple( nx, ny, nz ) ) )
5020 #endif
5021
5022 {
5023 // Complex, set to next layer
5024 setDataAt( nx, ny, nz, curwid + 1 ) ;
5025 queue2->prepend( nx, ny, nz ) ;
5026 numComplex ++ ;
5027 }
5028 }
5029 */
5030
5031 // Update scores for nodes in its 5x5 neighborhood
5032 // insert them back into priority queue
5033
5034 for ( i = -2 ; i < 3 ;i ++ )
5035 for ( j = -2 ; j < 3 ; j ++ )
5036 for ( k = -2 ; k < 3 ; k ++ )
5037 {
5038 int nx = ox + i ;
5039 int ny = oy + j ;
5040 int nz = oz + k ;
5041
5042 if ( getDataAt( nx, ny, nz ) == curwid )
5043 {
5044 // Compute score
5045 score = getNumPotComplex2( nx, ny, nz ) ;
5046 //score = getNumNeighbor6( nx, ny, nz ) ;
5047
5048 if ( score != (int) scrvol->getDataAt( nx, ny, nz ) )
5049 {
5050 // printf("Update\n") ;
5051 scrvol->setDataAt( nx, ny, nz, score ) ;
5052 // Push to queue
5053 gp = new gridPoint ;
5054 gp->x = nx ;
5055 gp->y = ny ;
5056 gp->z = nz ;
5057 // queue->add( gp, -score ) ;
5058 queue->add( gp, score ) ;
5059 }
5060 }
5061 }
5062
5063
5064 }
5065
5066 #ifdef VERBOSE
5067 printf("%d complex, %d simple\n", numComplex, numSimple) ;
5068 #endif
5069
5070 if ( numSimple == 0 )
5071 {
5072 break ;
5073 }
5074 }
5075
5076 // Finally, clean up
5077 #ifdef VERBOSE
5078 printf("Thresholding the volume to 0/1...\n") ;
5079 #endif
5080 threshold( 0, 0, 1 ) ;
5081 delete scrvol;
5082 delete queue;
5083 delete queue2;
5084 delete queue3;
5085 delete queue4;
5086 }
5087
5088 // Compute minimal skeleton
5089 void Volume::skeleton( float thr, int )
5090 {
5091 int i, j, k ;
5092 // First, threshold the volume
5093 #ifdef VERBOSE
5094 printf("Thresholding the volume to -1/0...\n") ;
5095 #endif
5096 threshold( thr, -1, 0 ) ;
5097
5098 // Next, apply convergent erosion
5099 // by preserving: complex nodes, curve end-points, and sheet points
5100
5101 // Next, initialize the linked queue
5102 #ifdef VERBOSE
5103 printf("Initializing queue...\n") ;
5104 #endif
5105 GridQueue2* queue2 = new GridQueue2( ) ;
5106 GridQueue2* queue = new GridQueue2( ) ;
5107
5108 for ( i = 0 ; i < getSizeX() ; i ++ )
5109 for ( j = 0 ; j < getSizeY() ; j ++ )
5110 for ( k = 0 ; k < getSizeZ() ; k ++ )
5111 {
5112 if ( getDataAt( i, j, k ) >= 0 )
5113 {
5114 {
5115 for ( int m = 0 ; m < 6 ; m ++ )
5116 {
5117 if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
5118 {
5119 setDataAt( i, j, k, 1 ) ;
5120 queue2->prepend( i, j, k ) ;
5121 break ;
5122 }
5123 }
5124 }
5125 }
5126 }
5127 int wid = 0 ;
5128 #ifdef VERBOSE
5129 printf("Total %d nodes\n", queue2->getNumElements() ) ;
5130 printf("Start erosion to %d...\n", wid) ;
5131 #endif
5132
5133 // Perform erosion
5134 gridQueueEle* ele ;
5135 int ox, oy, oz ;
5136
5137 while( 1 )
5138 {
5139 wid ++ ;
5140
5141 // At the start of each iteration,
5142 // queue2 holds all the nodes for this layer
5143 // queue is empty
5144
5145 int numComplex = 0, numSimple = 0 ;
5146 #ifdef VERBOSE
5147 printf("Processing %d nodes in layer %d\n", queue2->getNumElements(), wid) ;
5148 #endif
5149
5150 // Rename queue2 to be queue,
5151 // Clear queue2
5152 // From now on, queue2 holds nodes of next level
5153 delete queue ;
5154 queue = queue2 ;
5155 queue2 = new GridQueue2( ) ;
5156
5157 // Next, start queue iteration
5158 queue->reset() ;
5159 ele = queue->getNext();
5160 while ( ele != NULL )
5161 {
5162 ox = ele->x ;
5163 oy = ele->y ;
5164 oz = ele->z ;
5165 // delete ele ;
5166
5167 // Check simple
5168 if ( ! isSimple( ox, oy, oz ) )
5169 {
5170 // Complex, set to next layer
5171 queue2->prepend( ox, oy, oz ) ;
5172 numComplex ++ ;
5173 }
5174 /*
5175 else if ( ox == off || oy == off || oz == off ||
5176 ox == getSizeX() - off - 1 || oy == getSizeY() - off - 1 || oz == getSizeZ() - off - 1 )
5177 {
5178 // Wall, don't erode, set to next layer
5179 queue2->prepend( ox, oy, oz ) ;
5180 numComplex ++ ;
5181 }
5182 */
5183 else
5184 {
5185 setDataAt( ox, oy, oz, -1 ) ;
5186 numSimple ++ ;
5187
5188 for ( int m = 0 ; m < 6 ; m ++ )
5189 {
5190 int nx = ox + neighbor6[m][0] ;
5191 int ny = oy + neighbor6[m][1] ;
5192 int nz = oz + neighbor6[m][2] ;
5193 if ( getDataAt( nx, ny, nz ) == 0 )
5194 {
5195 setDataAt( nx, ny, nz, 1 ) ;
5196 queue2->prepend( nx, ny, nz ) ;
5197 }
5198 }
5199
5200 }
5201
5202 ele = queue->remove() ;
5203 }
5204 #ifdef VERBOSE
5205 printf("Level %d: %d complex, %d simple\n", wid, numComplex, numSimple) ;
5206 #endif
5207
5208 if ( numSimple == 0 )
5209 {
5210 break ;
5211 }
5212 }
5213
5214 // Finally, clean up
5215 delete queue;
5216 delete queue2;
5217 #ifdef VERBOSE
5218 printf("Thresholding the volume to 0/1...\n") ;
5219 #endif
5220 threshold( 0, 0, 1 ) ;
5221 }
5222
5224 //void Volume::skeleton2( float thr, int off )
5225 //{
5226 //int i, j, k ;
5228 //#ifdef VERBOSE
5229 //printf("Thresholding the volume to -1/0...\n") ;
5230 //#endif
5231 //threshold( thr, -1, 0 ) ;
5232
5235
5237 //#ifdef VERBOSE
5238 //printf("Initializing queue...\n") ;
5239 //#endif
5240 //GridQueue2* queue2 = new GridQueue2( ) ;
5241 //GridQueue2* queue3 = new GridQueue2( ) ;
5242 //PriorityQueue <gridPoint,int> * queue = new PriorityQueue <gridPoint,int> ( MAX_QUEUELEN );
5243
5244 //for ( i = 0 ; i < getSizeX() ; i ++ )
5245 //for ( j = 0 ; j < getSizeY() ; j ++ )
5246 //for ( k = 0 ; k < getSizeZ() ; k ++ )
5247 //{
5248 //if ( getDataAt( i, j, k ) >= 0 )
5249 //{
5250 //if ( i == off || j == off || k == off ||
5251 //i == getSizeX() - off - 1 || j == getSizeY() - off - 1 || k == getSizeZ() - off - 1 )
5252 //{
5253 //setDataAt( i, j, k, MAX_ERODE ) ;
5254 //}
5255 //else
5256 //{
5257 //for ( int m = 0 ; m < 6 ; m ++ )
5258 //{
5259 //if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
5260 //{
5261 //setDataAt( i, j, k, 1 ) ;
5262 //queue2->prepend( i, j, k ) ;
5263 //break ;
5264 //}
5265 //}
5266 //}
5267 //}
5268 //}
5269 //int wid = MAX_ERODE ;
5270 //#ifdef VERBOSE
5271 //printf("Total %d nodes\n", queue2->getNumElements() ) ;
5272
5273
5275 //printf("Start erosion to %d...\n", wid) ;
5276 //#endif
5277
5278 //gridQueueEle* ele ;
5279 //gridPoint* gp ;
5280 //int ox, oy, oz ;
5281 //int score ;
5282
5283 //Volume* scrvol = new Volume( this->getSizeX() , this->getSizeY(), this->getSizeZ() ) ;
5284 //for ( i = 0 ; i < getSizeX() * getSizeY() * getSizeZ() ; i ++ )
5285 //{
5286 //scrvol->setDataAt( i, -1 ) ;
5287 //}
5288
5289
5290 //for ( int curwid = 1 ; curwid <= wid ; curwid ++ )
5291 //{
5295
5296 //int numComplex = 0, numSimple = 0 ;
5297 //#ifdef VERBOSE
5298 //printf("Processing %d nodes in layer %d\n", queue2->getNumElements(), curwid) ;
5299 //#endif
5300
5304 //queue2->reset() ;
5305 //ele = queue2->getNext() ;
5306 //while ( ele != NULL )
5307 //{
5308 //ox = ele->x ;
5309 //oy = ele->y ;
5310 //oz = ele->z ;
5311
5313 //score = getNumPotComplex2( ox, oy, oz ) ;
5314 //scrvol->setDataAt( ox, oy, oz, score ) ;
5315
5317 //gp = new gridPoint ;
5318 //gp->x = ox ;
5319 //gp->y = oy ;
5320 //gp->z = oz ;
5322 //queue->add( gp, score ) ;
5323
5324 //ele = queue2->remove() ;
5325 //}
5326
5330 //delete queue2 ;
5331 //queue2 = queue3 ;
5332 //queue3 = new GridQueue2( ) ;
5333
5335 //while ( ! queue->isEmpty() )
5336 //{
5338 //queue->remove( gp, score ) ;
5339 //ox = gp->x ;
5340 //oy = gp->y ;
5341 //oz = gp->z ;
5342 //delete gp ;
5344
5348 //if ( getDataAt( ox, oy, oz ) != curwid || (int) scrvol->getDataAt( ox, oy, oz ) != score )
5349 //{
5350 //continue ;
5351 //}
5352
5355 //if ( ! isSimple( ox, oy, oz ) )
5356 //{
5358 //setDataAt( ox, oy, oz, curwid + 1 ) ;
5359 //queue2->prepend( ox, oy, oz ) ;
5360 //numComplex ++ ;
5361 //}
5362 //else
5363 //{
5364 //setDataAt( ox, oy, oz, -1 ) ;
5365 //numSimple ++ ;
5366 //}
5368
5370 //for ( int m = 0 ; m < 6 ; m ++ )
5371 //{
5372 //int nx = ox + neighbor6[m][0] ;
5373 //int ny = oy + neighbor6[m][1] ;
5374 //int nz = oz + neighbor6[m][2] ;
5375 //if ( getDataAt( nx, ny, nz ) == 0 )
5376 //{
5377 //setDataAt( nx, ny, nz, curwid + 1 ) ;
5378 //queue2->prepend( nx, ny, nz ) ;
5379 //}
5380 //}
5381
5385 //for ( i = -2 ; i < 3 ;i ++ )
5386 //for ( j = -2 ; j < 3 ; j ++ )
5387 //for ( k = -2 ; k < 3 ; k ++ )
5388 //{
5389 //int nx = ox + i ;
5390 //int ny = oy + j ;
5391 //int nz = oz + k ;
5392
5393 //if ( getDataAt( nx, ny, nz ) == curwid )
5394 //{
5396 //score = getNumPotComplex2( nx, ny, nz ) ;
5397
5398 //if ( score != (int) scrvol->getDataAt( nx, ny, nz ) )
5399 //{
5401 //scrvol->setDataAt( nx, ny, nz, score ) ;
5403 //gp = new gridPoint ;
5404 //gp->x = nx ;
5405 //gp->y = ny ;
5406 //gp->z = nz ;
5408 //queue->add( gp, score ) ;
5409 //}
5410 //}
5411 //}
5412
5413 //*/
5414 //}
5415 //#ifdef VERBOSE
5416 //printf("%d complex, %d simple\n", numComplex, numSimple) ;
5417 //#endif
5418
5419 //if ( numSimple == 0 )
5420 //{
5421 //break ;
5422 //}
5423 //}
5424
5426 //delete scrvol ;
5427 //delete queue;
5428 //#ifdef VERBOSE
5429 //printf("Thresholding the volume to 0/1...\n") ;
5430 //#endif
5431 //threshold( 0, 0, 1 ) ;
5432 //}
5433
5435 //* Assuming the current volume has already been thresholded to 0/1
5436 //*/
5437 //void Volume::pointSkeleton( Volume* grayvol, float lowthr, float highthr, Volume* svol, Volume* hvol )
5438 //{
5439 //int i, j, k ;
5441 //#ifdef VERBOSE
5442 //printf("Thresholding the volume to -1/0...\n") ;
5443 //#endif
5444 //threshold( 0.5f, -1, 0 ) ;
5445
5448
5450 //#ifdef VERBOSE
5451 //printf("Initializing queue...\n") ;
5452 //#endif
5453 //GridQueue2* queue2 = new GridQueue2( ) ;
5454 //GridQueue2* queue3 = new GridQueue2( ) ;
5455 //PriorityQueue <gridPoint,int> * queue = new PriorityQueue <gridPoint,int> ( MAX_QUEUELEN );
5456
5457 //for ( i = 0 ; i < getSizeX() ; i ++ )
5458 //for ( j = 0 ; j < getSizeY() ; j ++ )
5459 //for ( k = 0 ; k < getSizeZ() ; k ++ )
5460 //{
5461 //if ( getDataAt( i, j, k ) >= 0 )
5462 //{
5463 //float v = (float)grayvol->getDataAt( i, j, k ) ;
5464 //if ( v <= lowthr || v > highthr || svol->getDataAt(i,j,k) > 0 || hvol->getDataAt(i,j,k) > 0 )
5465 //{
5466 //setDataAt( i, j, k, MAX_ERODE ) ;
5467 //}
5468 //else
5469 //{
5470 //for ( int m = 0 ; m < 6 ; m ++ )
5471 //{
5472 //if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
5473 //{
5474 //setDataAt( i, j, k, 1 ) ;
5475 //queue2->prepend( i, j, k ) ;
5476 //break ;
5477 //}
5478 //}
5479 //}
5480 //}
5481 //}
5482 //#ifdef VERBOSE
5483 //printf("Total %d nodes\n", queue2->getNumElements() ) ;
5484 //#endif
5485
5486
5488 //int wid = MAX_ERODE ;
5489 //#ifdef VERBOSE
5490 //printf("Start erosion to %d...\n", wid) ;
5491 //#endif
5492 //gridQueueEle* ele ;
5493 //gridPoint* gp ;
5494 //int ox, oy, oz ;
5495 //int score ;
5496 //Volume* scrvol = new Volume( this->getSizeX() , this->getSizeY(), this->getSizeZ() ) ;
5497 //for ( i = 0 ; i < getSizeX() * getSizeY() * getSizeZ() ; i ++ )
5498 //{
5499 //scrvol->setDataAt( i, -1 ) ;
5500 //}
5501
5502
5503 //for ( int curwid = 1 ; curwid <= wid ; curwid ++ )
5504 //{
5508
5509 //int numComplex = 0, numSimple = 0 ;
5510 //#ifdef VERBOSE
5511 //printf("Processing %d nodes in layer %d\n", queue2->getNumElements(), curwid) ;
5512 //#endif
5513
5514
5518 //queue2->reset() ;
5519 //ele = queue2->getNext() ;
5520 //while ( ele != NULL )
5521 //{
5522 //ox = ele->x ;
5523 //oy = ele->y ;
5524 //oz = ele->z ;
5525
5527 //score = getNumPotComplex2( ox, oy, oz ) ;
5528 //scrvol->setDataAt( ox, oy, oz, score ) ;
5529
5531 //gp = new gridPoint ;
5532 //gp->x = ox ;
5533 //gp->y = oy ;
5534 //gp->z = oz ;
5536 //queue->add( gp, score ) ;
5537
5538 //ele = queue2->remove() ;
5539 //}
5540
5544 //delete queue2 ;
5545 //queue2 = queue3 ;
5546 //queue3 = new GridQueue2( ) ;
5547
5549 //while ( ! queue->isEmpty() )
5550 //{
5552 //queue->remove( gp, score ) ;
5553 //ox = gp->x ;
5554 //oy = gp->y ;
5555 //oz = gp->z ;
5556 //delete gp ;
5558
5562 //if ( getDataAt( ox, oy, oz ) != curwid || (int) scrvol->getDataAt( ox, oy, oz ) != score )
5563 //{
5564 //continue ;
5565 //}
5566
5569 //if ( ! isSimple( ox, oy, oz ) )
5570 //{
5572 //setDataAt( ox, oy, oz, curwid + 1 ) ;
5573 //queue2->prepend( ox, oy, oz ) ;
5574 //numComplex ++ ;
5575 //}
5576 //else
5577 //{
5578 //setDataAt( ox, oy, oz, -1 ) ;
5579 //numSimple ++ ;
5581
5583 //for ( int m = 0 ; m < 6 ; m ++ )
5584 //{
5585 //int nx = ox + neighbor6[m][0] ;
5586 //int ny = oy + neighbor6[m][1] ;
5587 //int nz = oz + neighbor6[m][2] ;
5588 //if ( getDataAt( nx, ny, nz ) == 0 )
5589 //{
5590 //setDataAt( nx, ny, nz, curwid + 1 ) ;
5591 //queue2->prepend( nx, ny, nz ) ;
5592 //}
5593 //}
5594
5595 //}
5596
5599
5600 //for ( i = -2 ; i < 3 ;i ++ )
5601 //for ( j = -2 ; j < 3 ; j ++ )
5602 //for ( k = -2 ; k < 3 ; k ++ )
5603 //{
5604 //int nx = ox + i ;
5605 //int ny = oy + j ;
5606 //int nz = oz + k ;
5607
5608 //if ( getDataAt( nx, ny, nz ) == curwid )
5609 //{
5611 //score = getNumPotComplex2( nx, ny, nz ) ;
5612
5613 //if ( score != (int) scrvol->getDataAt( nx, ny, nz ) )
5614 //{
5616 //scrvol->setDataAt( nx, ny, nz, score ) ;
5618 //gp = new gridPoint ;
5619 //gp->x = nx ;
5620 //gp->y = ny ;
5621 //gp->z = nz ;
5623 //queue->add( gp, score ) ;
5624 //}
5625 //}
5626 //}
5627
5628
5629 //}
5630 //#ifdef VERBOSE
5631 //printf("%d complex, %d simple\n", numComplex, numSimple) ;
5632 //#endif
5633
5634 //if ( numSimple == 0 )
5635 //{
5636 //break ;
5637 //}
5638 //}
5639
5641 //queue2->reset() ;
5642 //ele = queue2->getNext() ;
5643 //while ( ele != NULL )
5644 //{
5645 //ox = ele->x ;
5646 //oy = ele->y ;
5647 //oz = ele->z ;
5648
5649 //if ( hasCompleteHelix( ox, oy, oz ) == 1 )
5650 //{
5651 //ele = queue2->getNext() ;
5652 //}
5653 //else
5654 //{
5655 //ele = queue2->remove() ;
5656 //}
5657 //}
5658
5659 //for ( i = 0 ; i < getSizeX() ; i ++ )
5660 //for ( j = 0 ; j < getSizeY() ; j ++ )
5661 //for ( k = 0 ; k < getSizeZ() ; k ++ )
5662 //{
5663 //if ( getDataAt( i, j, k ) == 0 && hasCompleteHelix(i,j,k) == 1)
5664 //{
5665 //queue2->prepend( i, j, k ) ;
5666 //}
5667 //}
5668 //queue2->reset() ;
5669 //ele = queue2->getNext() ;
5670 //while ( ele != NULL )
5671 //{
5672 //ox = ele->x ;
5673 //oy = ele->y ;
5674 //oz = ele->z ;
5675 //setDataAt( ox, oy, oz, -1 ) ;
5676 //ele = queue2->remove() ;
5677 //}
5678
5680 //delete scrvol;
5681 //delete queue;
5682 //delete queue2;
5683 //delete queue3;
5684 //#ifdef VERBOSE
5685 //printf("Thresholding the volume to 0/1...\n") ;
5686 //#endif
5687 //threshold( 0, 0, 1 ) ;
5688 //}
5689
5690
5691 // Compute minimal skeleton
5692 void Volume::skeleton( float thr, Volume* svol, Volume* hvol )
5693 {
5694 int i, j, k ;
5695 // First, threshold the volume
5696 #ifdef VERBOSE
5697 printf("Thresholding the volume to -1/0...\n") ;
5698 #endif
5699 threshold( thr, -1, 0 ) ;
5700
5701 // Next, apply convergent erosion
5702 // by preserving: complex nodes, curve end-points, and sheet points
5703
5704 // Next, initialize the linked queue
5705 #ifdef VERBOSE
5706 printf("Initializing queue...\n") ;
5707 #endif
5708 GridQueue2* queue2 = new GridQueue2( ) ;
5709 GridQueue2* queue3 = new GridQueue2( ) ;
5711
5712 for ( i = 0 ; i < getSizeX() ; i ++ )
5713 for ( j = 0 ; j < getSizeY() ; j ++ )
5714 for ( k = 0 ; k < getSizeZ() ; k ++ )
5715 {
5716 if ( getDataAt( i, j, k ) >= 0 )
5717 {
5718 if ( svol->getDataAt(i,j,k) > 0 || hvol->getDataAt(i,j,k) > 0 )
5719 {
5720 setDataAt( i, j, k, MAX_ERODE ) ;
5721 }
5722 else
5723 {
5724 for ( int m = 0 ; m < 6 ; m ++ )
5725 {
5726 if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
5727 {
5728 setDataAt( i, j, k, 1 ) ;
5729 queue2->prepend( i, j, k ) ;
5730 break ;
5731 }
5732 }
5733 }
5734 }
5735 }
5736 int wid = MAX_ERODE ;
5737 #ifdef VERBOSE
5738 printf("Total %d nodes\n", queue2->getNumElements() ) ;
5739
5740
5741 // Perform erosion
5742 printf("Start erosion to %d...\n", wid) ;
5743 #endif
5744 gridQueueEle* ele ;
5745 gridPoint* gp ;
5746 int ox, oy, oz ;
5747 int score ;
5748 Volume* scrvol = new Volume( this->getSizeX() , this->getSizeY(), this->getSizeZ() ) ;
5749 for ( i = 0 ; i < getSizeX() * getSizeY() * getSizeZ() ; i ++ )
5750 {
5751 scrvol->setDataAt( i, -1 ) ;
5752 }
5753
5754
5755 for ( int curwid = 1 ; curwid <= wid ; curwid ++ )
5756 {
5757 // At the start of each iteration,
5758 // queue2 holds all the nodes for this layer
5759 // queue3 and queue are empty
5760
5761 int numComplex = 0, numSimple = 0 ;
5762 #ifdef VERBOSE
5763 printf("Processing %d nodes in layer %d\n", queue2->getNumElements(), curwid) ;
5764 #endif
5765
5766
5767 // Next,
5768 // Compute score for each node left in queue2
5769 // move them into priority queue
5770 queue2->reset() ;
5771 ele = queue2->getNext() ;
5772 while ( ele != NULL )
5773 {
5774 ox = ele->x ;
5775 oy = ele->y ;
5776 oz = ele->z ;
5777
5778 // Compute score
5779 score = getNumPotComplex2( ox, oy, oz ) ;
5780 scrvol->setDataAt( ox, oy, oz, score ) ;
5781
5782 // Push to queue
5783 gp = new gridPoint ;
5784 gp->x = ox ;
5785 gp->y = oy ;
5786 gp->z = oz ;
5787 // queue->add( gp, -score ) ;
5788 queue->add( gp, score ) ;
5789
5790 ele = queue2->remove() ;
5791 }
5792
5793 // Rename queue3 to be queue2,
5794 // Clear queue3
5795 // From now on, queue2 holds nodes of next level
5796 delete queue2 ;
5797 queue2 = queue3 ;
5798 queue3 = new GridQueue2( ) ;
5799
5800 // Next, start priority queue iteration
5801 while ( ! queue->isEmpty() )
5802 {
5803 // Retrieve the node with the highest score
5804 queue->remove( gp, score ) ;
5805 ox = gp->x ;
5806 oy = gp->y ;
5807 oz = gp->z ;
5808 delete gp ;
5809 // score = -score ;
5810
5811 // Ignore the node
5812 // if it has been processed before
5813 // or it has an updated score
5814 if ( getDataAt( ox, oy, oz ) != curwid || (int) scrvol->getDataAt( ox, oy, oz ) != score )
5815 {
5816 continue ;
5817 }
5818
5819 /* Added for debugging */
5820 // Check simple
5821 if ( ! isSimple( ox, oy, oz ) )
5822 {
5823 // Complex, set to next layer
5824 setDataAt( ox, oy, oz, curwid + 1 ) ;
5825 queue2->prepend( ox, oy, oz ) ;
5826 numComplex ++ ;
5827 }
5828 else
5829 {
5830 setDataAt( ox, oy, oz, -1 ) ;
5831 numSimple ++ ;
5832 }
5833 /* Adding ends */
5834
5835 // Move its neighboring unvisited node to queue2
5836 for ( int m = 0 ; m < 6 ; m ++ )
5837 {
5838 int nx = ox + neighbor6[m][0] ;
5839 int ny = oy + neighbor6[m][1] ;
5840 int nz = oz + neighbor6[m][2] ;
5841 if ( getDataAt( nx, ny, nz ) == 0 )
5842 {
5843 setDataAt( nx, ny, nz, curwid + 1 ) ;
5844 queue2->prepend( nx, ny, nz ) ;
5845 }
5846 }
5847
5848 // Update scores for nodes in its 5x5 neighborhood
5849 // insert them back into priority queue
5850
5851 for ( i = -2 ; i < 3 ;i ++ )
5852 for ( j = -2 ; j < 3 ; j ++ )
5853 for ( k = -2 ; k < 3 ; k ++ )
5854 {
5855 int nx = ox + i ;
5856 int ny = oy + j ;
5857 int nz = oz + k ;
5858
5859 if ( getDataAt( nx, ny, nz ) == curwid )
5860 {
5861 // Compute score
5862 score = getNumPotComplex2( nx, ny, nz ) ;
5863
5864 if ( score != (int) scrvol->getDataAt( nx, ny, nz ) )
5865 {
5866 // printf("Update\n") ;
5867 scrvol->setDataAt( nx, ny, nz, score ) ;
5868 // Push to queue
5869 gp = new gridPoint ;
5870 gp->x = nx ;
5871 gp->y = ny ;
5872 gp->z = nz ;
5873 // queue->add( gp, -score ) ;
5874 queue->add( gp, score ) ;
5875 }
5876 }
5877 }
5878
5879
5880 }
5881
5882 #ifdef VERBOSE
5883 printf("%d complex, %d simple\n", numComplex, numSimple) ;
5884 #endif
5885
5886 if ( numSimple == 0 )
5887 {
5888 delete queue2 ;
5889 break ;
5890 }
5891 }
5892
5893 // Finally, clean up
5894 #ifdef VERBOSE
5895 printf("Thresholding the volume to 0/1...\n") ;
5896 #endif
5897 threshold( 0, 0, 1 ) ;
5898 delete scrvol;
5899 delete queue;
5900 delete queue3;
5901 }
5902
5903
5904 // Apply helix erosion
5906 {
5907 erodeHelix( 3 ) ;
5908 }
5909
5910
5911 void Volume::erodeHelix( int disthr )
5912 {
5913 int i, j, k ;
5914 // First, threshold the volume
5915 //printf("Thresholding the volume to -1/0...\n") ;
5916 threshold( 0.1f, -1, 0 ) ;
5917
5918 /* Debug: remove faces */
5919 //Volume* facevol = markFaceEdge() ;
5920 /* End debugging */
5921
5922 // Next, initialize the linked queue
5923 //printf("Initializing queue...\n") ;
5924 Volume * fvol = new Volume( getSizeX(), getSizeY(), getSizeZ() ) ;
5925 GridQueue2* queue2 = new GridQueue2( ) ;
5926 GridQueue2* queue3 = new GridQueue2( ) ;
5927 GridQueue2** queues = new GridQueue2* [ 10000 ] ;
5928
5929 for ( i = 0 ; i < getSizeX() ; i ++ )
5930 for ( j = 0 ; j < getSizeY() ; j ++ )
5931 for ( k = 0 ; k < getSizeZ() ; k ++ )
5932 {
5933 if ( getDataAt( i, j, k ) >= 0 )
5934 {
5935 if ( ! hasCompleteHelix( i, j, k ) )
5936 // if ( ! hasCompleteHelix( i, j, k, facevol ) )
5937 {
5938 queue2->prepend( i, j, k ) ;
5939 fvol->setDataAt( i, j, k, -1 ) ;
5940 }
5941 }
5942 }
5943 //printf("Total %d nodes\n", queue2->getNumElements() ) ;
5944
5945 // Start erosion
5946 gridQueueEle* ele ;
5947 int dis = -1 ;
5948 while ( queue2->getNumElements() > 0 )
5949 {
5950 // First, set distance
5951 dis -- ;
5952 queues[ - dis ] = new GridQueue2( ) ;
5953 //printf("Distance transform to %d...", dis) ;
5954 queue2->reset() ;
5955 while( ( ele = queue2->getNext() ) != NULL )
5956 {
5957 setDataAt( ele->x, ele->y, ele->z, dis ) ;
5958 queues[ -dis ]->prepend( ele->x, ele->y, ele->z ) ;
5959 }
5960 //printf("%d nodes\n", queues[-dis]->getNumElements()) ;
5961
5962 // Next, find next layer
5963 queue2->reset() ;
5964 ele = queue2->getNext() ;
5965 while ( ele != NULL )
5966 {
5967 for ( int m = 0 ; m < 6 ; m ++ )
5968 {
5969 int nx = ele->x + neighbor6[m][0] ;
5970 int ny = ele->y + neighbor6[m][1] ;
5971 int nz = ele->z + neighbor6[m][2] ;
5972 if ( getDataAt( nx, ny, nz ) == 0 )
5973 {
5974 fvol->setDataAt( nx, ny, nz, dis ) ;
5975
5976 if ( ! hasCompleteHelix( nx, ny, nz ) )
5977 // if ( ! hasCompleteHelix( nx, ny, nz, facevol ) )
5978 {
5979 setDataAt( nx, ny, nz, 1 ) ;
5980 queue3->prepend( nx, ny, nz ) ;
5981 }
5982 }
5983 }
5984
5985 ele = queue2->remove() ;
5986 }
5987
5988 // Next, swap queues
5989 GridQueue2* temp = queue2 ;
5990 queue2 = queue3 ;
5991 queue3 = temp ;
5992 }
5993
5994 // Deal with closed rings
5995 dis -- ;
5996 queues[ - dis ] = new GridQueue2( ) ;
5997 #ifdef VERBOSE
5998 printf("Detecting closed rings %d...", dis) ;
5999 #endif
6000 int ftot = 0 ;
6001 for ( i = 0 ; i < getSizeX() ; i ++ )
6002 for ( j = 0 ; j < getSizeY() ; j ++ )
6003 for ( k = 0 ; k < getSizeZ() ; k ++ )
6004 {
6005 if ( getDataAt( i, j, k ) == 0 )
6006 {
6007 setDataAt( i, j, k, dis ) ;
6008 queues[ -dis ]->prepend( i, j, k ) ;
6009 /*
6010 int fval = (int) fvol->getDataAt( i, j, k ) ;
6011 if ( fval == 0)
6012 {
6013 // queues[ -dis ]->prepend( i, j, k ) ;
6014 }
6015 else
6016 {
6017 setDataAt( i, j, k, fval - 1 ) ;
6018 // queues[ -fval + 1 ]->prepend( i, j, k ) ;
6019 }
6020 */
6021 ftot ++ ;
6022 }
6023 }
6024 #ifdef VERBOSE
6025 printf("%d nodes\n", ftot) ;
6026 #endif
6027
6028
6029 // return ;
6030
6031 /* Find local minimum: to help determine erosion level
6032 int cts[ 64 ] ;
6033 for ( i = 0 ; i <= - dis ; i ++ )
6034 {
6035 cts[ i ] = 0 ;
6036 }
6037 for ( i = 0 ; i < getSizeX() ; i ++ )
6038 for ( j = 0 ; j < getSizeY() ; j ++ )
6039 for ( k = 0 ; k < getSizeZ() ; k ++ )
6040 {
6041 double val = getDataAt( i, j, k ) ;
6042 if ( val < -1 )
6043 {
6044 int min = 1 ;
6045 for ( int m = 0 ; m < 6 ; m ++ )
6046 {
6047 int nx = i + neighbor6[m][0] ;
6048 int ny = j + neighbor6[m][1] ;
6049 int nz = k + neighbor6[m][2] ;
6050 if ( getDataAt( nx, ny, nz ) < val )
6051 {
6052 min = 0 ;
6053 break ;
6054 }
6055 }
6056
6057 if ( min )
6058 {
6059 cts[ (int) - val ] ++ ;
6060 }
6061 }
6062 }
6063
6064 for ( i = 2 ; i <= - dis ; i ++ )
6065 {
6066 printf("Local minima: %d with %d nodes.\n", -i, cts[ i ] ) ;
6067 }
6068 */
6069
6070 // Dilate back
6071 // Starting from nodes with distance - 2 - disthr
6072
6073 if ( disthr + 2 > - dis )
6074 {
6075 disthr = - dis - 2 ;
6076 }
6077 int d;
6078
6079 for ( d = - dis ; d > disthr + 1 ; d -- )
6080 {
6081 queues[ d ]->reset() ;
6082 while ( (ele = queues[ d ]->getNext() ) != NULL )
6083 {
6084 setDataAt( ele->x, ele->y, ele->z, d ) ;
6085 }
6086 }
6087
6088
6089 for ( d = disthr + 1 ; d >= 2 ; d -- )
6090 {
6091 //delete queue3 ;
6092 //queue3 = new GridQueue2( ) ;
6093 queues[ d ]->reset() ;
6094 ele = queues[ d ]->getNext() ;
6095 while ( ele != NULL )
6096 {
6097 int dilatable = 0 ;
6098 for ( int m = 0 ; m < 6 ; m ++ )
6099 {
6100 int nx = ele->x + neighbor6[m][0] ;
6101 int ny = ele->y + neighbor6[m][1] ;
6102 int nz = ele->z + neighbor6[m][2] ;
6103 if ( getDataAt( nx, ny, nz ) == d + 1 )
6104 {
6105 dilatable = 1 ;
6106 break ;
6107 }
6108 }
6109
6110
6111 if ( ! dilatable )
6112 {
6113 /*
6114 setDataAt( ele->x, ele->y, ele->z, - 1 ) ;
6115 */
6116
6117 setDataAt( ele->x, ele->y, ele->z, - d + 1 ) ;
6118 if ( d > 2 )
6119 {
6120 queues[ d - 1 ]->prepend( ele->x, ele->y, ele->z ) ;
6121 }
6122 ele = queues[ d ]->remove() ;
6123 }
6124 else
6125 {
6126 setDataAt( ele->x, ele->y, ele->z, d ) ;
6127 ele = queues[ d ]->getNext() ;
6128 }
6129
6130 }
6131
6132 /* Debug: extract minimal set */
6133 while ( 1 )
6134 {
6135 int num = 0 ;
6136 queues[ d ]->reset() ;
6137 ele = queues[ d ]->getNext() ;
6138 while ( ele != NULL )
6139 {
6140 int critical = 0 ;
6141 setDataAt( ele->x, ele->y, ele->z, -1 ) ;
6142
6143 for ( i = -1 ; i < 2 ; i ++ )
6144 {
6145 for ( j = -1 ; j < 2 ; j ++ )
6146 {
6147 for ( k = -1 ; k < 2 ; k ++ )
6148 {
6149 if ( i != 0 && j != 0 && k != 0 )
6150 {
6151 continue ;
6152 }
6153 int nx = ele->x + i ;
6154 int ny = ele->y + j ;
6155 int nz = ele->z + k ;
6156 if ( getDataAt(nx,ny,nz) == d + 1 && !hasCompleteHelix( nx,ny,nz ) ) //, facevol ) )
6157 {
6158 critical = 1 ;
6159 break ;
6160 }
6161 }
6162 if ( critical )
6163 {
6164 break ;
6165 }
6166 }
6167 if ( critical )
6168 {
6169 break ;
6170 }
6171 }
6172
6173 if ( critical )
6174 {
6175 setDataAt( ele->x, ele->y, ele->z, d ) ;
6176 ele = queues[ d ]->getNext() ;
6177 }
6178 else
6179 {
6180 setDataAt( ele->x, ele->y, ele->z, - d + 1 ) ;
6181 if ( d > 2 )
6182 {
6183 queues[ d - 1 ]->prepend( ele->x, ele->y, ele->z ) ;
6184 }
6185 ele = queues[ d ]->remove() ;
6186 num ++ ;
6187 }
6188
6189 }
6190
6191 #ifdef VERBOSE
6192 printf("Non-minimal: %d\n", num) ;
6193 #endif
6194
6195 if ( num == 0 )
6196 {
6197 break ;
6198 }
6199 }
6200
6201
6202 /* End of debugging */
6203
6204 /*
6205 queue3->reset() ;
6206 ele = queue3->getNext() ;
6207 while ( ele != NULL )
6208 {
6209 setDataAt( ele->x, ele->y, ele->z, - 1 ) ;
6210 ele = queue3->remove() ;
6211 }
6212 */
6213 }
6214
6215 // Finally, threshold the volume
6216 #ifdef VERBOSE
6217 //printf("Thresholding the volume to 0/1...\n") ;
6218 #endif
6219 //threshold( -1, 1, 0, 0 ) ;
6220 threshold( 0, 0, 1 ) ;
6221 delete fvol ;
6222 delete queue2;
6223 delete queue3;
6224 for ( d = -dis ; d >= 2 ; d -- ) {
6225 delete queues[d];
6226 }
6227 delete [] queues;
6228
6229 }
6230
6231
6232
6233 // Apply sheet erosion
6235 {
6236 return erodeSheet( 3 ) ;
6237 }
6238
6239
6240 int Volume::erodeSheet( int disthr )
6241 {
6242 int i, j, k ;
6243 // First, threshold the volume
6244 //printf("Thresholding the volume to -1/0...\n") ;
6245 threshold( 0.1f, -1, 0 ) ;
6246
6247 /* Debug: remove cells */
6248 Volume* facevol = markCellFace() ;
6249 /* End debugging */
6250
6251 // Next, initialize the linked queue
6252 //printf("Initializing queue...\n") ;
6253 Volume * fvol = new Volume( getSizeX(), getSizeY(), getSizeZ() ) ;
6254 GridQueue2* queue2 = new GridQueue2( ) ;
6255 GridQueue2* queue3 = new GridQueue2( ) ;
6256 GridQueue2** queues = new GridQueue2* [ 10000 ] ;
6257
6258 for ( i = 0 ; i < getSizeX() ; i ++ )
6259 for ( j = 0 ; j < getSizeY() ; j ++ )
6260 for ( k = 0 ; k < getSizeZ() ; k ++ )
6261 {
6262 if ( getDataAt( i, j, k ) >= 0 )
6263 {
6264 if ( ! hasCompleteSheet( i, j, k ) )
6265 //if ( ! hasCompleteSheet( i, j, k, facevol ) )
6266 {
6267 queue2->prepend( i, j, k ) ;
6268 fvol->setDataAt( i, j, k, -1 ) ;
6269 }
6270 }
6271 }
6272 #ifdef VERBOSE
6273 printf("Total %d nodes\n", queue2->getNumElements() ) ;
6274 #endif
6275
6276 // Start erosion
6277 gridQueueEle* ele ;
6278 int dis = -1 ;
6279 while ( queue2->getNumElements() > 0 )
6280 {
6281 // First, set distance
6282 dis -- ;
6283 queues[ - dis ] = new GridQueue2( ) ;
6284 //printf("Distance transform to %d...", dis) ;
6285 queue2->reset() ;
6286 while( ( ele = queue2->getNext() ) != NULL )
6287 {
6288 setDataAt( ele->x, ele->y, ele->z, dis ) ;
6289 queues[ -dis ]->prepend( ele->x, ele->y, ele->z ) ;
6290 }
6291 //printf("%d nodes\n", queues[-dis]->getNumElements()) ;
6292
6293 // Next, find next layer
6294 queue2->reset() ;
6295 ele = queue2->getNext() ;
6296 while ( ele != NULL )
6297 {
6298 // for ( int m = 0 ; m < 6 ; m ++ )
6299 for ( int mx = -1 ; mx < 2 ; mx ++ )
6300 for ( int my = -1 ; my < 2 ; my ++ )
6301 for ( int mz = -1 ; mz < 2 ; mz ++ )
6302 {
6303 if ( mx != 0 && my != 0 && mz != 0 )
6304 {
6305 continue ;
6306 }
6307 //int nx = ele->x + neighbor6[m][0] ;
6308 //int ny = ele->y + neighbor6[m][1] ;
6309 //int nz = ele->z + neighbor6[m][2] ;
6310 int nx = ele->x + mx ;
6311 int ny = ele->y + my ;
6312 int nz = ele->z + mz ;
6313
6314 if ( getDataAt( nx, ny, nz ) == 0 )
6315 {
6316 fvol->setDataAt( nx, ny, nz, dis ) ;
6317
6318 if ( ! hasCompleteSheet( nx, ny, nz ) )
6319 // if ( ! hasCompleteSheet( nx, ny, nz, facevol ) )
6320 {
6321 setDataAt( nx, ny, nz, 1 ) ;
6322 queue3->prepend( nx, ny, nz ) ;
6323 }
6324 }
6325 }
6326
6327 ele = queue2->remove() ;
6328 }
6329
6330 // Next, swap queues
6331 GridQueue2* temp = queue2 ;
6332 queue2 = queue3 ;
6333 queue3 = temp ;
6334 }
6335
6336 /* Deal with closed rings */
6337
6338 dis -- ;
6339 queues[ - dis ] = new GridQueue2( ) ;
6340 #ifdef VERBOSE
6341 printf("Detecting closed rings %d...", dis) ;
6342 #endif
6343 int ftot = 0 ;
6344 for ( i = 0 ; i < getSizeX() ; i ++ )
6345 for ( j = 0 ; j < getSizeY() ; j ++ )
6346 for ( k = 0 ; k < getSizeZ() ; k ++ )
6347 {
6348 if ( getDataAt( i, j, k ) == 0 )
6349 {
6350 /*
6351 int fval = (int) fvol->getDataAt( i, j, k ) ;
6352 if ( fval == 0)
6353 {
6354 setDataAt( i, j, k, dis - 2 ) ;
6355 // queues[ -dis ]->prepend( i, j, k ) ;
6356 }
6357 else
6358 {
6359 setDataAt( i, j, k, fval - 1 ) ;
6360 queues[ -fval + 1 ]->prepend( i, j, k ) ;
6361 }
6362 */
6363 setDataAt( i, j, k, dis ) ;
6364 queues[ -dis ]->prepend( i, j, k ) ;
6365
6366 ftot ++ ;
6367 }
6368 }
6369 #ifdef VERBOSE
6370 printf("%d nodes\n", ftot) ;
6371 #endif
6372
6373
6374 /* Find local minimum: to help determine erosion level
6375 int cts[ 64 ] ;
6376 for ( i = 0 ; i <= - dis ; i ++ )
6377 {
6378 cts[ i ] = 0 ;
6379 }
6380 for ( i = 0 ; i < getSizeX() ; i ++ )
6381 for ( j = 0 ; j < getSizeY() ; j ++ )
6382 for ( k = 0 ; k < getSizeZ() ; k ++ )
6383 {
6384 double val = getDataAt( i, j, k ) ;
6385 if ( val < -1 )
6386 {
6387 int min = 1 ;
6388 for ( int m = 0 ; m < 6 ; m ++ )
6389 {
6390 int nx = i + neighbor6[m][0] ;
6391 int ny = j + neighbor6[m][1] ;
6392 int nz = k + neighbor6[m][2] ;
6393 if ( getDataAt( nx, ny, nz ) < val )
6394 {
6395 min = 0 ;
6396 break ;
6397 }
6398 }
6399
6400 if ( min )
6401 {
6402 cts[ (int) - val ] ++ ;
6403 }
6404 }
6405 }
6406
6407 for ( i = 2 ; i <= - dis ; i ++ )
6408 {
6409 printf("Local minima: %d with %d nodes.\n", -i, cts[ i ] ) ;
6410 }
6411 */
6412
6413 // return ;
6414
6415 // Dilate back
6416 // Starting from nodes with distance - 2 - disthr
6417 int d ;
6418 if ( disthr + 2 > - dis )
6419 {
6420 disthr = - dis - 2 ;
6421
6422 }
6423 for ( d = - dis ; d > disthr + 1 ; d -- )
6424 {
6425 queues[ d ]->reset() ;
6426 while ( (ele = queues[ d ]->getNext() ) != NULL )
6427 {
6428 setDataAt( ele->x, ele->y, ele->z, d ) ;
6429 }
6430 }
6431
6432 for (d = disthr + 1 ; d >= 2 ; d -- )
6433 {
6434
6435 //delete queue3 ;
6436 //queue3 = new GridQueue2( ) ;
6437 queues[ d ]->reset() ;
6438 ele = queues[ d ]->getNext() ;
6439 while ( ele != NULL )
6440 {
6441 int dilatable = 0 ;
6442 // for ( int m = 0 ; m < 6 ; m ++ )
6443 /*
6444 for ( int mx = -1 ; mx < 2 ; mx ++ )
6445 for ( int my = -1 ; my < 2 ; my ++ )
6446 for ( int mz = -1 ; mz < 2 ; mz ++ )
6447 {
6448 if ( mx == 0 || my == 0 || mz == 0 )
6449 {
6450 int nx = ele->x + mx ; // neighbor6[m][0] ;
6451 int ny = ele->y + my ; // neighbor6[m][1] ;
6452 int nz = ele->z + mz ; // neighbor6[m][2] ;
6453 if ( getDataAt( nx, ny, nz ) == - d - 1 )
6454 {
6455 dilatable = 1 ;
6456 break ;
6457 }
6458 }
6459 }
6460 */
6461 for ( i = 0 ; i < 12 ; i ++ )
6462 {
6463 int flag = 1, flag2 = 0 ;
6464 for ( j = 0 ; j < 4 ; j ++ )
6465 {
6466 int nx = ele->x + sheetNeighbor[i][j][0] ;
6467 int ny = ele->y + sheetNeighbor[i][j][1] ;
6468 int nz = ele->z + sheetNeighbor[i][j][2] ;
6469
6470 double val = getDataAt( nx, ny, nz ) ;
6471
6472 if ( val > - d && val < 0)
6473 {
6474 flag = 0 ;
6475 break ;
6476 }
6477 if ( val == d + 1 )
6478 {
6479 flag2 ++ ;
6480 }
6481 }
6482
6483 if ( flag && flag2 )
6484 {
6485 dilatable = 1 ;
6486 break ;
6487 }
6488 }
6489
6490 if ( ! dilatable )
6491 {
6492 // setDataAt( ele->x, ele->y, ele->z, - 1 ) ;
6493 // queue3->prepend( ele->x, ele->y, ele->z ) ;
6494
6495 setDataAt( ele->x, ele->y, ele->z, - d + 1 ) ;
6496 if ( d > 2 )
6497 {
6498 queues[ d - 1 ]->prepend( ele->x, ele->y, ele->z ) ;
6499 }
6500 ele = queues[ d ]->remove() ;
6501 }
6502 else
6503 {
6504 setDataAt( ele->x, ele->y, ele->z, d ) ;
6505 ele = queues[ d ]->getNext() ;
6506 }
6507 }
6508
6509 /* Debug: extract minimal set */
6510 while ( 1 )
6511 {
6512 int num = 0 ;
6513 queues[ d ]->reset() ;
6514 ele = queues[ d ]->getNext() ;
6515 while ( ele != NULL )
6516 {
6517 int critical = 0 ;
6518 setDataAt( ele->x, ele->y, ele->z, -1 ) ;
6519
6520 for ( i = -1 ; i < 2 ; i ++ )
6521 {
6522 for ( j = -1 ; j < 2 ; j ++ )
6523 {
6524 for ( k = -1 ; k < 2 ; k ++ )
6525 {
6526 if ( i != 0 && j != 0 && k != 0 )
6527 {
6528 continue ;
6529 }
6530 int nx = ele->x + i ;
6531 int ny = ele->y + j ;
6532 int nz = ele->z + k ;
6533 // if ( getDataAt(nx,ny,nz) == d + 1 && !hasCompleteSheet( nx,ny,nz, facevol ) )
6534 if ( getDataAt(nx,ny,nz) == d + 1 && !hasCompleteSheet( nx,ny,nz ) )
6535 {
6536 critical = 1 ;
6537 break ;
6538 }
6539 }
6540 if ( critical )
6541 {
6542 break ;
6543 }
6544 }
6545 if ( critical )
6546 {
6547 break ;
6548 }
6549 }
6550
6551 if ( critical )
6552 {
6553 setDataAt( ele->x, ele->y, ele->z, d ) ;
6554 ele = queues[ d ]->getNext() ;
6555 }
6556 else
6557 {
6558 setDataAt( ele->x, ele->y, ele->z, - d + 1 ) ;
6559 if ( d > 2 )
6560 {
6561 queues[ d - 1 ]->prepend( ele->x, ele->y, ele->z ) ;
6562 }
6563 ele = queues[ d ]->remove() ;
6564 num ++ ;
6565 }
6566
6567 }
6568 #ifdef VERBOSE
6569 printf("Non-minimal: %d\n", num) ;
6570 #endif
6571
6572 if ( num == 0 )
6573 {
6574 break ;
6575 }
6576 }
6577
6578
6579 /* End of debugging */
6580
6581 /*
6582 queue3->reset() ;
6583 ele = queue3->getNext() ;
6584 while ( ele != NULL )
6585 {
6586 setDataAt( ele->x, ele->y, ele->z, - 1 ) ;
6587 ele = queue3->remove() ;
6588 }
6589 */
6590 }
6591
6592
6593 // Finally, threshold the volume
6594 #ifdef VERBOSE
6595 //printf("Thresholding the volume to 0/1...\n") ;
6596 #endif
6597 //threshold( -1, 1, 0, 0 ) ;
6598 threshold( 0, 0, 1 ) ;
6599
6600 delete facevol ;
6601 delete fvol ;
6602 delete queue2;
6603 delete queue3;
6604 for (d = -dis ; d >= 2 ; d -- ) {
6605 delete queues[d];
6606 }
6607 delete [] queues;
6608
6609 return - dis - 1 ;
6610 }
6611
6612 //void Volume::erodeSheetOld( int disthr )
6613 //{
6614 //int i, j, k ;
6616 //#ifdef VERBOSE
6617 //printf("Thresholding the volume to -1/0...\n") ;
6618 //#endif
6619 //threshold( 0.1f, -1, 0 ) ;
6620
6622 //#ifdef VERBOSE
6623 //printf("Initializing queue...\n") ;
6624 //#endif
6625 //GridQueue2* queue2 = new GridQueue2( ) ;
6626 //GridQueue2* queue3 = new GridQueue2( ) ;
6627 //GridQueue2** queues = new GridQueue2* [ 64 ] ;
6628
6629 //for ( i = 0 ; i < getSizeX() ; i ++ )
6630 //for ( j = 0 ; j < getSizeY() ; j ++ )
6631 //for ( k = 0 ; k < getSizeZ() ; k ++ )
6632 //{
6633 //if ( getDataAt( i, j, k ) >= 0 )
6634 //{
6635 //if ( ! hasCompleteSheet( i, j, k ) )
6636 //{
6637 //queue2->prepend( i, j, k ) ;
6638 //}
6639 //}
6640 //}
6641 //printf("Total %d nodes\n", queue2->getNumElements() ) ;
6642
6644 //gridQueueEle* ele ;
6645 //int dis = -1 ;
6646 //while ( queue2->getNumElements() > 0 )
6647 //{
6649 //dis -- ;
6650 //queues[ - dis ] = new GridQueue2( ) ;
6651 //printf("Distance transform to %d...", dis) ;
6652 //queue2->reset() ;
6653 //while( ( ele = queue2->getNext() ) != NULL )
6654 //{
6655 //setDataAt( ele->x, ele->y, ele->z, dis ) ;
6656 //queues[ -dis ]->prepend( ele->x, ele->y, ele->z ) ;
6657 //}
6658 //printf("%d nodes\n", queues[-dis]->getNumElements()) ;
6659
6661 //queue2->reset() ;
6662 //ele = queue2->getNext() ;
6663 //while ( ele != NULL )
6664 //{
6665 //for ( int m = 0 ; m < 6 ; m ++ )
6666 //{
6667 //int nx = ele->x + neighbor6[m][0] ;
6668 //int ny = ele->y + neighbor6[m][1] ;
6669 //int nz = ele->z + neighbor6[m][2] ;
6670 //if ( getDataAt( nx, ny, nz ) == 0 && ! hasCompleteSheet( nx, ny, nz ) )
6671 //{
6672 //setDataAt( nx, ny, nz, 1 ) ;
6673 //queue3->prepend( nx, ny, nz ) ;
6674 //}
6675 //}
6676
6677 //ele = queue2->remove() ;
6678 //}
6679
6681 //GridQueue2* temp = queue2 ;
6682 //queue2 = queue3 ;
6683 //queue3 = temp ;
6684 //}
6685
6687 //for ( i = 0 ; i < getSizeX() ; i ++ )
6688 //for ( j = 0 ; j < getSizeY() ; j ++ )
6689 //for ( k = 0 ; k < getSizeZ() ; k ++ )
6690 //{
6691 //if ( getDataAt( i, j, k ) == 0 )
6692 //{
6693 //setDataAt( i, j, k, dis - 1 ) ;
6694 //}
6695 //}
6696 //*/
6697
6699 //int cts[ 64 ] ;
6700 //for ( i = 0 ; i <= - dis ; i ++ )
6701 //{
6702 //cts[ i ] = 0 ;
6703 //}
6704 //for ( i = 0 ; i < getSizeX() ; i ++ )
6705 //for ( j = 0 ; j < getSizeY() ; j ++ )
6706 //for ( k = 0 ; k < getSizeZ() ; k ++ )
6707 //{
6708 //double val = getDataAt( i, j, k ) ;
6709 //if ( val < -1 )
6710 //{
6711 //int min = 1 ;
6712 //for ( int m = 0 ; m < 6 ; m ++ )
6713 //{
6714 //int nx = i + neighbor6[m][0] ;
6715 //int ny = j + neighbor6[m][1] ;
6716 //int nz = k + neighbor6[m][2] ;
6717 //if ( getDataAt( nx, ny, nz ) < val )
6718 //{
6719 //min = 0 ;
6720 //break ;
6721 //}
6722 //}
6723
6724 //if ( min )
6725 //{
6726 //cts[ (int) - val ] ++ ;
6727 //}
6728 //}
6729 //}
6730
6731 //for ( i = 2 ; i <= - dis ; i ++ )
6732 //{
6733 //printf("Local minima: %d with %d nodes.\n", -i, cts[ i ] ) ;
6734 //}
6735
6736
6738
6741
6742 //for ( int d = disthr + 1 ; d >= 2 ; d -- )
6743 //{
6744 //delete queue3 ;
6745 //queue3 = new GridQueue2( ) ;
6746 //queues[ d ]->reset() ;
6747 //while ( (ele = queues[ d ]->getNext() ) != NULL )
6748 //{
6749 //int dilatable = 0 ;
6752 //for ( int mx = -1 ; mx < 2 ; mx ++ )
6753 //for ( int my = -1 ; my < 2 ; my ++ )
6754 //for ( int mz = -1 ; mz < 2 ; mz ++ )
6755 //{
6756 //if ( mx == 0 || my == 0 || mz == 0 )
6757 //{
6758 //int nx = ele->x + mx ; // neighbor6[m][0] ;
6759 //int ny = ele->y + my ; // neighbor6[m][1] ;
6760 //int nz = ele->z + mz ; // neighbor6[m][2] ;
6761 //if ( getDataAt( nx, ny, nz ) == - d - 1 )
6762 //{
6763 //dilatable = 1 ;
6764 //break ;
6765 //}
6766 //}
6767 //}
6768 //*/
6769 //for ( i = 0 ; i < 12 ; i ++ )
6770 //{
6771 //int flag = 1, flag2 = 0 ;
6772 //for ( j = 0 ; j < 4 ; j ++ )
6773 //{
6774 //int nx = ele->x + sheetNeighbor[i][j][0] ;
6775 //int ny = ele->y + sheetNeighbor[i][j][1] ;
6776 //int nz = ele->z + sheetNeighbor[i][j][2] ;
6777
6778 //double val = getDataAt( nx, ny, nz ) ;
6779
6780 //if ( val > - d )
6781 //{
6782 //flag = 0 ;
6783 //break ;
6784 //}
6785 //if ( val == - d - 1 )
6786 //{
6787 //flag2 ++ ;
6788 //}
6789 //}
6790
6791 //if ( flag && flag2 )
6792 //{
6793 //dilatable = 1 ;
6794 //break ;
6795 //}
6796 //}
6797
6798 //if ( ! dilatable )
6799 //{
6801 //queue3->prepend( ele->x, ele->y, ele->z ) ;
6803 //setDataAt( ele->x, ele->y, ele->z, - d + 1 ) ;
6804 //if ( d > 2 )
6805 //{
6806 //queues[ d - 1 ]->prepend( ele->x, ele->y, ele->z ) ;
6807 //}
6808 //*/
6809 //}
6810 //}
6811
6812 //queue3->reset() ;
6813 //ele = queue3->getNext() ;
6814 //while ( ele != NULL )
6815 //{
6816 //setDataAt( ele->x, ele->y, ele->z, - 1 ) ;
6817 //ele = queue3->remove() ;
6818 //}
6819 //}
6820
6822 //#ifdef VERBOSE
6823 //printf("Thresholding the volume to 0/1...\n") ;
6824 //#endif
6825 //threshold( -1, 1, 0, 0 ) ;
6826 //}
6827
6828
6829
6830 //void Volume::addNoise( float thr, float pos )
6831 //{
6832 //int i, j, k ;
6833 //#ifdef VERBOSE
6834 //printf("Thresholding the volume to -MAX_ERODE/0...\n") ;
6835 //#endif
6836 //threshold( thr, -MAX_ERODE, 0 ) ;
6837 //Volume* tvol = new Volume( getSizeX(), getSizeY(), getSizeZ(), 0, 0, 0, this ) ;
6838
6839 //for ( i = 0 ; i < getSizeX() ; i ++ )
6840 //for ( j = 0 ; j < getSizeY() ; j ++ )
6841 //for ( k = 0 ; k < getSizeZ() ; k ++ )
6842 //{
6843 //if ( tvol->getDataAt( i, j, k ) >= 0 && isSimple( i, j, k ) )
6844 //{
6845 //for ( int m = 0 ; m < 6 ; m ++ )
6846 //{
6847 //if ( tvol->getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
6848 //{
6849 //if ( rand() < RAND_MAX * pos )
6850 //{
6851 //setDataAt( i, j, k, thr - 1 ) ;
6852 //}
6853 //break ;
6854 //}
6855 //}
6856 //}
6857 //}
6858
6859 //}
6860
6868 //void Volume::sequentialSkeleton( float thr, int type, int noise )
6869 //{
6870 //int i, j, k, m ;
6872 //#ifdef VERBOSE
6873 //printf("Thresholding the volume to -1/0...\n") ;
6874 //#endif
6875 //threshold( thr, -1, 0 ) ;
6876
6883
6885 //#ifdef VERBOSE
6886 //printf("Initializing queue...\n") ;
6887 //#endif
6888 //GridQueue2* queue2 = new GridQueue2( ) ;
6889 //GridQueue2* queue3 = new GridQueue2( ) ;
6890 //gridQueueEle* ele ;
6891
6892 //for ( i = 0 ; i < getSizeX() ; i ++ )
6893 //for ( j = 0 ; j < getSizeY() ; j ++ )
6894 //for ( k = 0 ; k < getSizeZ() ; k ++ )
6895 //{
6896 //if ( getDataAt( i, j, k ) >= 0 )
6897 //{
6898 //for ( m = 0 ; m < 6 ; m ++ )
6899 //{
6900 //if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
6901 //{
6902 //setDataAt( i, j, k, 1 ) ;
6903 //queue2->prepend( i, j, k ) ;
6904 //break ;
6905 //}
6906 //}
6907 //}
6908 //}
6910
6911
6913 //int dis = 0 ;
6914 //int ox, oy, oz ;
6915 //int nx, ny, nz ;
6916 //while ( queue2->getNumElements() > 0 )
6917 //{
6918 //dis ++ ;
6919 //printf("At distance %d, there are %d nodes.\n", dis, queue2->getNumElements()) ;
6920
6924
6926 //queue2->reset() ;
6927 //while ( (ele = queue2->getNext()) != NULL )
6928 //{
6929 //ox = ele->x ;
6930 //oy = ele->y ;
6931 //oz = ele->z ;
6932
6933 //setDataAt( ox, oy, oz, 2 ) ;
6934 //for ( m = 0 ; m < 6 ; m ++ )
6935 //{
6936 //nx = ox + neighbor6[m][0] ;
6937 //ny = oy + neighbor6[m][1] ;
6938 //nz = oz + neighbor6[m][2] ;
6939 //if ( getDataAt( nx, ny, nz ) == 0 )
6940 //{
6941 //setDataAt( nx, ny, nz, 1 ) ;
6942 //queue3->prepend( nx, ny, nz ) ;
6943 //}
6944 //}
6945 //}
6946
6948 //queue2->reset() ;
6949 //ele = queue2->getNext() ;
6950 //while ( ele != NULL )
6951 //{
6952 //ox = ele->x ;
6953 //oy = ele->y ;
6954 //oz = ele->z ;
6955
6956 //if ( (! isSimple( ox, oy, oz )) ||
6957 //( ( ( type == 0 && isEdgeEnd( ox, oy, oz ) ) ||
6958 //( type == 1 && isFaceEnd( ox, oy, oz ) ) ) && ! isNoise( ox, oy, oz, noise ) ) )
6959 //{
6960 //setDataAt( ox, oy, oz, 3 ) ;
6961 //ele = queue2->remove() ;
6962 //}
6963 //else
6964 //{
6965 //ele = queue2->getNext() ;
6966 //}
6967 //}
6968
6970 //queue2->reset() ;
6971 //while ( ( ele = queue2->getNext() ) != NULL )
6972 //{
6973 //ox = ele->x ;
6974 //oy = ele->y ;
6975 //oz = ele->z ;
6976 //queue2->remove() ;
6977 //queue2->reset() ;
6978
6979 //if ( getDataAt(ox,oy,oz) != 2 )
6980 //{
6981 //continue ;
6982 //}
6983
6984 //if ( ( ( ( type == 0 && isEdgeEnd( ox, oy, oz ) ) ||
6985 //( type == 1 && isFaceEnd( ox, oy, oz ) ) ) && ! isNoise( ox, oy, oz, noise ) ) )
6986 //{
6987 //setDataAt( ox, oy, oz, 3 ) ;
6988 //}
6989 //else
6990 //{
6991 //setDataAt( ox, oy, oz, -1 ) ;
6992 //}
6993
6994 //for ( i = -1 ; i < 2 ; i ++ )
6995 //for ( j = -1 ; j < 2 ; j ++ )
6996 //for ( k = -1 ; k < 2 ; k ++ )
6997 //{
6998 //nx = ox + i ;
6999 //ny = oy + j ;
7000 //nz = oz + k ;
7001 //int val = (int)( getDataAt( nx, ny, nz ) ) ;
7002 //if ( val > 1 )
7003 //{
7004 //int complex = 0 ;
7005 //if ( (! isSimple( nx, ny, nz )) ||
7006 //( ( ( type == 0 && isEdgeEnd( nx, ny, nz ) ) ||
7007 //( type == 1 && isFaceEnd( nx, ny, nz ) ) ) && ! isNoise( nx, ny, nz, noise ) ) )
7008 //{
7009 //complex = 1 ;
7010 //}
7011
7012 //if ( val == 2 && complex )
7013 //{
7015 //setDataAt( nx, ny, nz, 3 ) ;
7016 //}
7017 //else if ( val == 3 && ! complex )
7018 //{
7020 //setDataAt( nx, ny, nz, 2 ) ;
7021 //queue2->prepend( nx, ny, nz ) ;
7022 //}
7023
7024 //}
7025 //}
7026
7027 //queue2->reset() ;
7028 //}
7029
7031 //GridQueue2* temp = queue3 ;
7032 //queue3 = queue2 ;
7033 //queue2 = temp ;
7034 //}
7035
7036
7038 //#ifdef VERBOSE
7039 //printf("Thresholding the volume to 0/1...\n") ;
7040 //#endif
7041 //threshold( 0, 0, 1 ) ;
7042
7043 //}
7044
7045 //void Volume::dumbsurfaceSkeleton( float thr )
7046 //{
7047 //int i, j, k ;
7049 //#ifdef VERBOSE
7050 //printf("Thresholding the volume to -MAX_ERODE/0...\n") ;
7051 //#endif
7052 //threshold( thr, -MAX_ERODE, 0 ) ;
7053
7055 //#ifdef VERBOSE
7056 //printf("Initializing queue...\n") ;
7057 //#endif
7058 //GridQueue2* queue2 = new GridQueue2( ) ;
7059 //gridQueueEle* ele ;
7060
7061
7062 //while ( 1 )
7063 //{
7064 //int n = 0 ;
7065
7066 //queue2->reset() ;
7067 //for ( i = 0 ; i < getSizeX() ; i ++ )
7068 //for ( j = 0 ; j < getSizeY() ; j ++ )
7069 //for ( k = 0 ; k < getSizeZ() ; k ++ )
7070 //{
7071 //if ( getDataAt( i, j, k ) == 0 )
7072 //{
7073 //{
7074 //for ( int m = 0 ; m < 6 ; m ++ )
7075 //{
7076 //if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
7077 //{
7078 //queue2->prepend( i, j, k ) ;
7079 //break ;
7080 //}
7081 //}
7082 //}
7083 //}
7084 //}
7085
7086 //queue2->reset() ;
7087 //ele = queue2->getNext() ;
7088 //while ( ele != NULL )
7089 //{
7090 //int ox = ele->x ;
7091 //int oy = ele->y ;
7092 //int oz = ele->z ;
7093 //if ( isSimple( ox, oy, oz ) && hasCompleteSheet( ox, oy, oz ) == 1 )
7094 //{
7095 //setDataAt( ox, oy, oz, -1 ) ;
7096 //n ++ ;
7097 //}
7098
7099 //ele = queue2->remove() ;
7100 //}
7101
7102 //if ( n == 0 )
7103 //{
7104 //break ;
7105 //}
7106
7107 //printf("%d simple nodes found.\n", n);
7108 //}
7109
7110
7112 //#ifdef VERBOSE
7113 //printf("Thresholding the volume to 0/1...\n") ;
7114 //#endif
7115 //threshold( 0, 0, 1 ) ;
7116 //}
7117
7119 //* Assuming the current volume has already been thresholded to 0/1
7120 //*/
7121 //void Volume::surfaceSkeleton( Volume* grayvol, float lowthr, float highthr ) {
7122 //int i, j, k ;
7123 //threshold( 0.5f, -MAX_ERODE, 0 ) ;
7124
7125 //GridQueue2* queue2 = new GridQueue2( ) ;
7126 //GridQueue2* queue3 = new GridQueue2( ) ;
7127 //GridQueue2* queue4 = new GridQueue2( ) ;
7128
7129 //PriorityQueue <gridPoint,int> * queue = new PriorityQueue <gridPoint,int> ( MAX_QUEUELEN );
7130 //int ct = 0 ;
7131
7132 //for ( i = 0 ; i < getSizeX() ; i ++ )
7133 //for ( j = 0 ; j < getSizeY() ; j ++ )
7134 //for ( k = 0 ; k < getSizeZ() ; k ++ )
7135 //{
7136 //if ( getDataAt( i, j, k ) >= 0 )
7137 //{
7138 //float v = (float)grayvol->getDataAt(i,j,k) ;
7139 //if ( v > highthr || v <= lowthr )
7140 //{
7141 //setDataAt( i, j, k, MAX_ERODE ) ;
7142 //}
7143 //else
7144 //{
7145 //ct ++ ;
7146
7147 //for ( int m = 0 ; m < 6 ; m ++ )
7148 //{
7149 //if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
7150 //{
7151 //queue2->prepend( i, j, k ) ;
7152 //break ;
7153 //}
7154 //}
7155 //}
7156 //}
7157 //}
7158
7159
7161 //int wid = MAX_ERODE ;
7162 //gridQueueEle* ele ;
7163 //gridPoint* gp ;
7164 //int ox, oy, oz ;
7165 //int score ;
7166 //Volume* scrvol = new Volume( this->getSizeX() , this->getSizeY(), this->getSizeZ() ) ;
7167 //for ( i = 0 ; i < getSizeX() * getSizeY() * getSizeZ() ; i ++ )
7168 //{
7169 //scrvol->setDataAt( i, -1 ) ;
7170 //}
7171
7172 //#ifdef NOISE_DIS_SHEET
7173 //Volume* noisevol = new Volume( getSizeX(), getSizeY(), getSizeZ() ) ;
7174 //#endif
7175
7176 //for ( int curwid = 1 ; curwid <= wid ; curwid ++ )
7177 //{
7178
7179
7180 //int numComplex = 0, numSimple = 0 ;
7181 //#ifdef VERBOSE
7182 //printf("Processing %d nodes in layer %d\n", queue2->getNumElements(), curwid) ;
7183 //#endif
7184
7185 //queue2->reset() ;
7186 //ele = queue2->getNext() ;
7187 //while ( ele != NULL )
7188 //{
7189 //ox = ele->x ;
7190 //oy = ele->y ;
7191 //oz = ele->z ;
7192
7193 //if ( getDataAt(ox,oy,oz) == curwid )
7194 //{
7195 //ele = queue2->remove() ;
7196 //}
7197 //else
7198 //{
7199 //setDataAt(ox,oy,oz, curwid) ;
7200 //ele = queue2->getNext() ;
7201 //}
7202 //}
7203 //queue4->reset() ;
7204 //ele = queue4->getNext() ;
7205 //while ( ele != NULL )
7206 //{
7207 //ox = ele->x ;
7208 //oy = ele->y ;
7209 //oz = ele->z ;
7210
7211 //queue2->prepend(ox,oy,oz) ;
7212 //ele = queue4->remove() ;
7213 //}
7214
7216
7217 //#ifdef NOISE_DIS_SHEET
7219 //queue2->reset() ;
7220
7222 //int flag = 0 ;
7223 //while ( ( ele = queue2->getNext() ) != NULL )
7224 //{
7225 //ox = ele->x ;
7226 //oy = ele->y ;
7227 //oz = ele->z ;
7228 //if ( NOISE_DIS_SHEET <= 1 )
7229 //{
7230 //noisevol->setDataAt( ox, oy, oz, 0 ) ;
7231 //}
7232 //else
7233 //{
7234 //flag = 0 ;
7235 //for ( int m = 0 ; m < 6 ; m ++ )
7236 //{
7237 //int nx = ox + neighbor6[m][0] ;
7238 //int ny = oy + neighbor6[m][1] ;
7239 //int nz = oz + neighbor6[m][2] ;
7240 //if ( getDataAt( nx, ny, nz ) == 0 )
7241 //{
7242 //noisevol->setDataAt( ox, oy, oz, 1 ) ;
7243 //flag = 1 ;
7244 //break ;
7245 //}
7246 //}
7247 //if ( ! flag )
7248 //{
7249 //noisevol->setDataAt( ox, oy, oz, 0 ) ;
7250 //}
7251 //}
7252 //}
7253
7254 //for ( int cur = 1 ; cur < NOISE_DIS_SHEET ; cur ++ )
7255 //{
7256 //queue2->reset() ;
7257 //int count = 0 ;
7258
7259 //while ( ( ele = queue2->getNext() ) != NULL )
7260 //{
7261 //ox = ele->x ;
7262 //oy = ele->y ;
7263 //oz = ele->z ;
7264
7265 //if ( noisevol->getDataAt( ox, oy, oz ) == 1 )
7266 //{
7267 //continue ;
7268 //}
7269
7270 //flag = 0 ;
7271 //for ( int m = 0 ; m < 6 ; m ++ )
7272 //{
7273 //int nx = ox + neighbor6[m][0] ;
7274 //int ny = oy + neighbor6[m][1] ;
7275 //int nz = oz + neighbor6[m][2] ;
7276 //if ( getDataAt( nx, ny, nz ) > 0 && noisevol->getDataAt( nx, ny, nz ) == 1 )
7277 //{
7278 //noisevol->setDataAt( ox, oy, oz, 1 ) ;
7279 //count ++ ;
7280 //break ;
7281 //}
7282 //}
7283 //}
7284
7285 //if ( count == 0 )
7286 //{
7287 //break ;
7288 //}
7289 //}
7290
7291
7292 //#endif
7293
7294 //queue2->reset() ;
7295 //ele = queue2->getNext() ;
7296 //while ( ele != NULL )
7297 //{
7298 //ox = ele->x ;
7299 //oy = ele->y ;
7300 //oz = ele->z ;
7301
7303 //score = getNumPotComplex( ox, oy, oz ) ;
7304 //scrvol->setDataAt( ox, oy, oz, score ) ;
7305
7307 //gp = new gridPoint ;
7308 //gp->x = ox ;
7309 //gp->y = oy ;
7310 //gp->z = oz ;
7312 //queue->add( gp, score ) ;
7313
7314 //ele = queue2->remove() ;
7315 //}
7316
7317
7318 //delete queue2 ;
7319 //queue2 = queue3 ;
7320 //queue3 = new GridQueue2( ) ;
7321
7322 //int nowComplex = 0 ;
7323
7325 //while ( ! queue->isEmpty() )
7326 //{
7328 //queue->remove( gp, score ) ;
7329 //ox = gp->x ;
7330 //oy = gp->y ;
7331 //oz = gp->z ;
7332 //delete gp ;
7333
7334 //if ( getDataAt( ox, oy, oz ) != curwid || (int) scrvol->getDataAt( ox, oy, oz ) != score )
7335 //{
7336 //continue ;
7337 //}
7338
7339
7340 //#ifndef NOISE_DIS_SHEET
7342 //if ( (! isSimple( ox, oy, oz )) || isSheetEnd( ox, oy, oz ) )
7344 //#else
7346 //if ( ! isSimple( ox, oy, oz ) || isSheetEnd( ox, oy, oz, noisevol ) || isHelixEnd( ox, oy, oz, noisevol ))
7348 //#endif
7349 //{
7351 //setDataAt( ox, oy, oz, curwid + 1 ) ;
7352 //queue4->prepend( ox, oy, oz ) ;
7353 //numComplex ++ ;
7354
7355 //nowComplex = 1 ;
7356 //}
7357 //else
7358 //{
7359 //setDataAt( ox, oy, oz, -1 ) ;
7360 //numSimple ++ ;
7361
7362 //for ( int m = 0 ; m < 6 ; m ++ )
7363 //{
7364 //int nx = ox + neighbor6[m][0] ;
7365 //int ny = oy + neighbor6[m][1] ;
7366 //int nz = oz + neighbor6[m][2] ;
7367 //if ( getDataAt( nx, ny, nz ) == 0 )
7368 //{
7370 //queue2->prepend( nx, ny, nz ) ;
7371 //}
7372 //}
7373
7374 //if ( nowComplex )
7375 //{
7376
7378 //}
7379 //}
7380
7383
7384 //for ( i = -2 ; i < 3 ;i ++ )
7385 //for ( j = -2 ; j < 3 ; j ++ )
7386 //for ( k = -2 ; k < 3 ; k ++ )
7387 //{
7388 //int nx = ox + i ;
7389 //int ny = oy + j ;
7390 //int nz = oz + k ;
7391
7392 //if ( getDataAt( nx, ny, nz ) == curwid )
7393 //{
7395 //score = getNumPotComplex( nx, ny, nz ) ;
7396
7397 //if ( score != (int) scrvol->getDataAt( nx, ny, nz ) )
7398 //{
7400 //scrvol->setDataAt( nx, ny, nz, score ) ;
7402 //gp = new gridPoint ;
7403 //gp->x = nx ;
7404 //gp->y = ny ;
7405 //gp->z = nz ;
7407 //queue->add( gp, score ) ;
7408 //}
7409 //}
7410 //}
7411
7412
7413 //}
7414
7415 //if ( numSimple == 0 )
7416 //{
7417 //if ( queue2->getNumElements() > 0 )
7418 //{
7419 //printf("*************************wierd**********************\n");
7420 //}
7421 //break ;
7422 //}
7423 //}
7424
7426
7427 //queue4->reset() ;
7428 //ele = queue4->getNext() ;
7429 //while ( ele != NULL )
7430 //{
7431 //ele = queue4->remove() ;
7432 //}
7433
7434 //queue2->reset() ;
7435 //for ( i = 0 ; i < getSizeX() ; i ++ )
7436 //for ( j = 0 ; j < getSizeY() ; j ++ )
7437 //for ( k = 0 ; k < getSizeZ() ; k ++ )
7438 //{
7439 //if ( getDataAt( i, j, k ) == 0 && isInternal2( i,j,k ) == 1 )
7440 //{
7441 //queue2->prepend( i, j, k ) ;
7442 //}
7443 //}
7444 //queue2->reset() ;
7445 //ele = queue2->getNext() ;
7446 //while ( ele != NULL )
7447 //{
7448 //ox = ele->x ;
7449 //oy = ele->y ;
7450 //oz = ele->z ;
7451 //setDataAt( ox, oy, oz, -1 ) ;
7452 //ele = queue2->remove() ;
7453 //}
7454
7455
7456
7458 //delete scrvol;
7459 //delete queue;
7460 //delete queue2;
7461 //delete queue3;
7462 //delete queue4;
7463 //#ifdef VERBOSE
7464 //printf("Thresholding the volume to 0/1...\n") ;
7465 //#endif
7466 //threshold( 0, 0, 1 ) ;
7467
7468 //}
7469
7470 //void Volume::surfaceSkeleton( float thr )
7471 //{
7472 //int i, j, k ;
7474 //printf("Thresholding the volume to -MAX_ERODE/0...\n") ;
7475 //threshold( thr, -MAX_ERODE, 0 ) ;
7476
7478 //printf("Initializing queue...\n") ;
7479 //GridQueue2* queue2 = new GridQueue2( ) ;
7480 //GridQueue2* queue3 = new GridQueue2( ) ;
7481 //GridQueue2* queue4 = new GridQueue2( ) ;
7482
7483 //PriorityQueue <gridPoint,int> * queue = new PriorityQueue <gridPoint,int> ( MAX_QUEUELEN );
7484
7485 //for ( i = 0 ; i < getSizeX() ; i ++ )
7486 //for ( j = 0 ; j < getSizeY() ; j ++ )
7487 //for ( k = 0 ; k < getSizeZ() ; k ++ )
7488 //{
7489 //if ( getDataAt( i, j, k ) >= 0 )
7490 //{
7491 //{
7492 //for ( int m = 0 ; m < 6 ; m ++ )
7493 //{
7494 //if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
7495 //{
7497 //queue2->prepend( i, j, k ) ;
7498 //break ;
7499 //}
7500 //}
7501 //}
7502 //}
7503 //}
7504 //int wid = MAX_ERODE ;
7505 //#ifdef VERBOSE
7506 //printf("Total %d nodes\n", queue2->getNumElements() ) ;
7507
7508
7510 //printf("Start erosion to %d...\n", wid) ;
7511 //#endif
7512 //gridQueueEle* ele ;
7513 //gridPoint* gp ;
7514 //int ox, oy, oz ;
7515 //int score ;
7516 //Volume* scrvol = new Volume( this->getSizeX() , this->getSizeY(), this->getSizeZ() ) ;
7517 //for ( i = 0 ; i < getSizeX() * getSizeY() * getSizeZ() ; i ++ )
7518 //{
7519 //scrvol->setDataAt( i, -1 ) ;
7520 //}
7521
7522 //#ifdef NOISE_DIS_SHEET
7523 //Volume* noisevol = new Volume( getSizeX(), getSizeY(), getSizeZ() ) ;
7524 //#endif
7525
7526 //for ( int curwid = 1 ; curwid <= wid ; curwid ++ )
7527 //{
7531
7532 //int numComplex = 0, numSimple = 0 ;
7533 //printf("Processing %d nodes in layer %d\n", queue2->getNumElements(), curwid) ;
7534
7536 //We first need to assign curwid + 1 to every node in this layer
7537 //*/
7538 //queue2->reset() ;
7539 //ele = queue2->getNext() ;
7540 //while ( ele != NULL )
7541 //{
7542 //ox = ele->x ;
7543 //oy = ele->y ;
7544 //oz = ele->z ;
7545
7546 //if ( getDataAt(ox,oy,oz) == curwid )
7547 //{
7548 //ele = queue2->remove() ;
7549 //}
7550 //else
7551 //{
7552 //setDataAt(ox,oy,oz, curwid) ;
7553 //ele = queue2->getNext() ;
7554 //}
7555 //}
7556 //queue4->reset() ;
7557 //ele = queue4->getNext() ;
7558 //while ( ele != NULL )
7559 //{
7560 //ox = ele->x ;
7561 //oy = ele->y ;
7562 //oz = ele->z ;
7563
7564 //queue2->prepend(ox,oy,oz) ;
7565 //ele = queue4->remove() ;
7566 //}
7567
7569
7570 //#ifdef NOISE_DIS_SHEET
7572 //queue2->reset() ;
7573
7575 //int flag = 0 ;
7576 //while ( ( ele = queue2->getNext() ) != NULL )
7577 //{
7578 //ox = ele->x ;
7579 //oy = ele->y ;
7580 //oz = ele->z ;
7581 //if ( NOISE_DIS_SHEET <= 1 )
7582 //{
7583 //noisevol->setDataAt( ox, oy, oz, 0 ) ;
7584 //}
7585 //else
7586 //{
7587 //flag = 0 ;
7588 //for ( int m = 0 ; m < 6 ; m ++ )
7589 //{
7590 //int nx = ox + neighbor6[m][0] ;
7591 //int ny = oy + neighbor6[m][1] ;
7592 //int nz = oz + neighbor6[m][2] ;
7593 //if ( getDataAt( nx, ny, nz ) == 0 )
7594 //{
7595 //noisevol->setDataAt( ox, oy, oz, 1 ) ;
7596 //flag = 1 ;
7597 //break ;
7598 //}
7599 //}
7600 //if ( ! flag )
7601 //{
7602 //noisevol->setDataAt( ox, oy, oz, 0 ) ;
7603 //}
7604 //}
7605 //}
7606
7607 //for ( int cur = 1 ; cur < NOISE_DIS_SHEET ; cur ++ )
7608 //{
7609 //queue2->reset() ;
7610 //int count = 0 ;
7611
7612 //while ( ( ele = queue2->getNext() ) != NULL )
7613 //{
7614 //ox = ele->x ;
7615 //oy = ele->y ;
7616 //oz = ele->z ;
7617
7618 //if ( noisevol->getDataAt( ox, oy, oz ) == 1 )
7619 //{
7620 //continue ;
7621 //}
7622
7623 //flag = 0 ;
7624 //for ( int m = 0 ; m < 6 ; m ++ )
7625 //{
7626 //int nx = ox + neighbor6[m][0] ;
7627 //int ny = oy + neighbor6[m][1] ;
7628 //int nz = oz + neighbor6[m][2] ;
7629 //if ( getDataAt( nx, ny, nz ) > 0 && noisevol->getDataAt( nx, ny, nz ) == 1 )
7630 //{
7631 //noisevol->setDataAt( ox, oy, oz, 1 ) ;
7632 //count ++ ;
7633 //break ;
7634 //}
7635 //}
7636 //}
7637
7638 //if ( count == 0 )
7639 //{
7640 //break ;
7641 //}
7642 //}
7643
7644
7645 //#endif
7646
7648
7652 //queue2->reset() ;
7653 //ele = queue2->getNext() ;
7654 //while ( ele != NULL )
7655 //{
7656 //ox = ele->x ;
7657 //oy = ele->y ;
7658 //oz = ele->z ;
7659
7661 //#ifndef NOISE_DIS_SHEET
7662 //if ( isSheetEnd( ox, oy, oz ) || ! isSimple( ox, oy, oz ) )
7663 //#else
7664 //if ( isSheetEnd( ox, oy, oz, noisevol ) || ! isSimple( ox, oy, oz ) )
7665 //#endif
7666 //{
7668 //setDataAt( ox, oy, oz, curwid + 1 ) ;
7669 //queue3->prepend( ox, oy, oz ) ;
7670 //ele = queue2->remove() ;
7671
7672 //numComplex ++ ;
7673 //}
7674 //else
7675 //{
7676 //ele = queue2->getNext() ;
7677 //}
7678 //}
7679 //*/
7680
7681
7685 //queue2->reset() ;
7686 //ele = queue2->getNext() ;
7687 //while ( ele != NULL )
7688 //{
7689 //ox = ele->x ;
7690 //oy = ele->y ;
7691 //oz = ele->z ;
7692
7694 //score = getNumPotComplex( ox, oy, oz ) ;
7695 //scrvol->setDataAt( ox, oy, oz, score ) ;
7696
7698 //gp = new gridPoint ;
7699 //gp->x = ox ;
7700 //gp->y = oy ;
7701 //gp->z = oz ;
7703 //queue->add( gp, score ) ;
7704
7705 //ele = queue2->remove() ;
7706 //}
7707
7711 //delete queue2 ;
7712 //queue2 = queue3 ;
7713 //queue3 = new GridQueue2( ) ;
7714
7715 //int nowComplex = 0 ;
7716
7718 //while ( ! queue->isEmpty() )
7719 //{
7721 //queue->remove( gp, score ) ;
7722 //ox = gp->x ;
7723 //oy = gp->y ;
7724 //oz = gp->z ;
7725 //delete gp ;
7728
7732 //if ( getDataAt( ox, oy, oz ) != curwid || (int) scrvol->getDataAt( ox, oy, oz ) != score )
7733 //{
7734 //continue ;
7735 //}
7736
7738
7740 //setDataAt( ox, oy, oz, -1 ) ;
7741 //numSimple ++ ;
7743 //*/
7744
7747 //#ifndef NOISE_DIS_SHEET
7749 //if ( (! isSimple( ox, oy, oz )) || isSheetEnd( ox, oy, oz ) )
7751 //#else
7753 //if ( ! isSimple( ox, oy, oz ) || isSheetEnd( ox, oy, oz, noisevol ) || isHelixEnd( ox, oy, oz, noisevol ))
7755 //#endif
7756 //{
7758 //setDataAt( ox, oy, oz, curwid + 1 ) ;
7759 //queue4->prepend( ox, oy, oz ) ;
7760 //numComplex ++ ;
7761
7762 //nowComplex = 1 ;
7763 //}
7764 //else
7765 //{
7766 //setDataAt( ox, oy, oz, -1 ) ;
7767 //numSimple ++ ;
7768
7769 //if ( nowComplex )
7770 //{
7771
7773 //}
7774 //}
7776
7778 //for ( int m = 0 ; m < 6 ; m ++ )
7779 //{
7780 //int nx = ox + neighbor6[m][0] ;
7781 //int ny = oy + neighbor6[m][1] ;
7782 //int nz = oz + neighbor6[m][2] ;
7783 //if ( getDataAt( nx, ny, nz ) == 0 )
7784 //{
7786 //queue2->prepend( nx, ny, nz ) ;
7787 //}
7788 //}
7789
7791
7794 //for ( i = -1 ; i < 2 ; i ++ )
7795 //for ( j = -1 ; j < 2 ; j ++ )
7796 //for ( k = -1 ; k < 2 ; k ++ )
7797 //{
7798 //int nx = ox + i ;
7799 //int ny = oy + j ;
7800 //int nz = oz + k ;
7801
7803 //if ( getDataAt( nx, ny, nz ) == curwid &&
7805 //#ifndef NOISE_DIS_SHEET
7806 //( isSheetEnd( nx, ny, nz ) || ! isSimple( nx, ny, nz ) ) )
7807 //#else
7808 //( isSheetEnd( nx, ny, nz, noisevol ) || ! isSimple( nx, ny, nz ) ) )
7809 //#endif
7810
7811 //{
7813 //setDataAt( nx, ny, nz, curwid + 1 ) ;
7814 //queue2->prepend( nx, ny, nz ) ;
7815 //numComplex ++ ;
7816 //}
7817 //}
7818 //*/
7819
7822
7823 //for ( i = -2 ; i < 3 ;i ++ )
7824 //for ( j = -2 ; j < 3 ; j ++ )
7825 //for ( k = -2 ; k < 3 ; k ++ )
7826 //{
7827 //int nx = ox + i ;
7828 //int ny = oy + j ;
7829 //int nz = oz + k ;
7830
7831 //if ( getDataAt( nx, ny, nz ) == curwid )
7832 //{
7834 //score = getNumPotComplex( nx, ny, nz ) ;
7835
7836 //if ( score != (int) scrvol->getDataAt( nx, ny, nz ) )
7837 //{
7839 //scrvol->setDataAt( nx, ny, nz, score ) ;
7841 //gp = new gridPoint ;
7842 //gp->x = nx ;
7843 //gp->y = ny ;
7844 //gp->z = nz ;
7846 //queue->add( gp, score ) ;
7847 //}
7848 //}
7849 //}
7850
7851
7852 //}
7853
7854 //printf("%d complex, %d simple\n", numComplex, numSimple) ;
7855
7856 //if ( numSimple == 0 )
7857 //{
7858 //break ;
7859 //}
7860 //}
7861
7863 //printf("Thresholding the volume to 0/1...\n") ;
7864 //threshold( 0, 0, 1 ) ;
7865
7866 //}
7867
7868 //void Volume::surfaceSkeleton( float thr, Volume* svol )
7869 //{
7870 //int i, j, k ;
7872 //printf("Thresholding the volume to -MAX_ERODE/0...\n") ;
7873 //threshold( thr, -MAX_ERODE, 0 ) ;
7874
7876 //printf("Initializing queue...\n") ;
7877 //GridQueue2* queue2 = new GridQueue2( ) ;
7878 //GridQueue2* queue3 = new GridQueue2( ) ;
7879 //GridQueue2* queue4 = new GridQueue2( ) ;
7880
7881 //PriorityQueue <gridPoint,int> * queue = new PriorityQueue <gridPoint,int> ( MAX_QUEUELEN );
7882
7883 //for ( i = 0 ; i < getSizeX() ; i ++ )
7884 //for ( j = 0 ; j < getSizeY() ; j ++ )
7885 //for ( k = 0 ; k < getSizeZ() ; k ++ )
7886 //{
7887 //if ( getDataAt( i, j, k ) >= 0 )
7888 //{
7889 //if ( svol->getDataAt(i,j,k) > 0 )
7890 //{
7891 //setDataAt( i, j, k, MAX_ERODE ) ;
7892 //}
7893 //else
7894 //{
7895 //for ( int m = 0 ; m < 6 ; m ++ )
7896 //{
7897 //if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
7898 //{
7900 //queue2->prepend( i, j, k ) ;
7901 //break ;
7902 //}
7903 //}
7904 //}
7905 //}
7906 //}
7907 //int wid = MAX_ERODE ;
7908 //#ifdef VERBOSE
7909 //printf("Total %d nodes\n", queue2->getNumElements() ) ;
7910
7911
7913 //printf("Start erosion to %d...\n", wid) ;
7914 //#endif
7915 //gridQueueEle* ele ;
7916 //gridPoint* gp ;
7917 //int ox, oy, oz ;
7918 //int score ;
7919 //Volume* scrvol = new Volume( this->getSizeX() , this->getSizeY(), this->getSizeZ() ) ;
7920 //for ( i = 0 ; i < getSizeX() * getSizeY() * getSizeZ() ; i ++ )
7921 //{
7922 //scrvol->setDataAt( i, -1 ) ;
7923 //}
7924
7925 //#ifdef NOISE_DIS_SHEET
7926 //Volume* noisevol = new Volume( getSizeX(), getSizeY(), getSizeZ() ) ;
7927 //#endif
7928
7929 //for ( int curwid = 1 ; curwid <= wid ; curwid ++ )
7930 //{
7934
7935 //int numComplex = 0, numSimple = 0 ;
7936 //printf("Processing %d nodes in layer %d\n", queue2->getNumElements(), curwid) ;
7937
7939 //We first need to assign curwid + 1 to every node in this layer
7940 //*/
7941 //queue2->reset() ;
7942 //ele = queue2->getNext() ;
7943 //while ( ele != NULL )
7944 //{
7945 //ox = ele->x ;
7946 //oy = ele->y ;
7947 //oz = ele->z ;
7948
7949 //if ( getDataAt(ox,oy,oz) == curwid )
7950 //{
7951 //ele = queue2->remove() ;
7952 //}
7953 //else
7954 //{
7955 //setDataAt(ox,oy,oz, curwid) ;
7956 //ele = queue2->getNext() ;
7957 //}
7958 //}
7959 //queue4->reset() ;
7960 //ele = queue4->getNext() ;
7961 //while ( ele != NULL )
7962 //{
7963 //ox = ele->x ;
7964 //oy = ele->y ;
7965 //oz = ele->z ;
7966
7967 //queue2->prepend(ox,oy,oz) ;
7968 //ele = queue4->remove() ;
7969 //}
7970
7972
7973 //#ifdef NOISE_DIS_SHEET
7975 //queue2->reset() ;
7976
7978 //int flag = 0 ;
7979 //while ( ( ele = queue2->getNext() ) != NULL )
7980 //{
7981 //ox = ele->x ;
7982 //oy = ele->y ;
7983 //oz = ele->z ;
7984 //if ( NOISE_DIS_SHEET <= 1 )
7985 //{
7986 //noisevol->setDataAt( ox, oy, oz, 0 ) ;
7987 //}
7988 //else
7989 //{
7990 //flag = 0 ;
7991 //for ( int m = 0 ; m < 6 ; m ++ )
7992 //{
7993 //int nx = ox + neighbor6[m][0] ;
7994 //int ny = oy + neighbor6[m][1] ;
7995 //int nz = oz + neighbor6[m][2] ;
7996 //if ( getDataAt( nx, ny, nz ) == 0 )
7997 //{
7998 //noisevol->setDataAt( ox, oy, oz, 1 ) ;
7999 //flag = 1 ;
8000 //break ;
8001 //}
8002 //}
8003 //if ( ! flag )
8004 //{
8005 //noisevol->setDataAt( ox, oy, oz, 0 ) ;
8006 //}
8007 //}
8008 //}
8009
8010 //for ( int cur = 1 ; cur < NOISE_DIS_SHEET ; cur ++ )
8011 //{
8012 //queue2->reset() ;
8013 //int count = 0 ;
8014
8015 //while ( ( ele = queue2->getNext() ) != NULL )
8016 //{
8017 //ox = ele->x ;
8018 //oy = ele->y ;
8019 //oz = ele->z ;
8020
8021 //if ( noisevol->getDataAt( ox, oy, oz ) == 1 )
8022 //{
8023 //continue ;
8024 //}
8025
8026 //flag = 0 ;
8027 //for ( int m = 0 ; m < 6 ; m ++ )
8028 //{
8029 //int nx = ox + neighbor6[m][0] ;
8030 //int ny = oy + neighbor6[m][1] ;
8031 //int nz = oz + neighbor6[m][2] ;
8032 //if ( getDataAt( nx, ny, nz ) > 0 && noisevol->getDataAt( nx, ny, nz ) == 1 )
8033 //{
8034 //noisevol->setDataAt( ox, oy, oz, 1 ) ;
8035 //count ++ ;
8036 //break ;
8037 //}
8038 //}
8039 //}
8040
8041 //if ( count == 0 )
8042 //{
8043 //break ;
8044 //}
8045 //}
8046
8047
8048 //#endif
8049
8051
8055 //queue2->reset() ;
8056 //ele = queue2->getNext() ;
8057 //while ( ele != NULL )
8058 //{
8059 //ox = ele->x ;
8060 //oy = ele->y ;
8061 //oz = ele->z ;
8062
8064 //#ifndef NOISE_DIS_SHEET
8065 //if ( isSheetEnd( ox, oy, oz ) || ! isSimple( ox, oy, oz ) )
8066 //#else
8067 //if ( isSheetEnd( ox, oy, oz, noisevol ) || ! isSimple( ox, oy, oz ) )
8068 //#endif
8069 //{
8071 //setDataAt( ox, oy, oz, curwid + 1 ) ;
8072 //queue3->prepend( ox, oy, oz ) ;
8073 //ele = queue2->remove() ;
8074
8075 //numComplex ++ ;
8076 //}
8077 //else
8078 //{
8079 //ele = queue2->getNext() ;
8080 //}
8081 //}
8082 //*/
8083
8084
8088 //queue2->reset() ;
8089 //ele = queue2->getNext() ;
8090 //while ( ele != NULL )
8091 //{
8092 //ox = ele->x ;
8093 //oy = ele->y ;
8094 //oz = ele->z ;
8095
8097 //score = getNumPotComplex( ox, oy, oz ) ;
8098 //scrvol->setDataAt( ox, oy, oz, score ) ;
8099
8101 //gp = new gridPoint ;
8102 //gp->x = ox ;
8103 //gp->y = oy ;
8104 //gp->z = oz ;
8106 //queue->add( gp, score ) ;
8107
8108 //ele = queue2->remove() ;
8109 //}
8110
8114 //delete queue2 ;
8115 //queue2 = queue3 ;
8116 //queue3 = new GridQueue2( ) ;
8117
8118 //int nowComplex = 0 ;
8119
8121 //while ( ! queue->isEmpty() )
8122 //{
8124 //queue->remove( gp, score ) ;
8125 //ox = gp->x ;
8126 //oy = gp->y ;
8127 //oz = gp->z ;
8128 //delete gp ;
8131
8135 //if ( getDataAt( ox, oy, oz ) != curwid || (int) scrvol->getDataAt( ox, oy, oz ) != score )
8136 //{
8137 //continue ;
8138 //}
8139
8141
8143 //setDataAt( ox, oy, oz, -1 ) ;
8144 //numSimple ++ ;
8146 //*/
8147
8150 //#ifndef NOISE_DIS_SHEET
8152 //if ( (! isSimple( ox, oy, oz )) || isSheetEnd( ox, oy, oz ) )
8154 //#else
8156 //if ( ! isSimple( ox, oy, oz ) || isSheetEnd( ox, oy, oz, noisevol ) || isHelixEnd( ox, oy, oz, noisevol ))
8158 //#endif
8159 //{
8161 //setDataAt( ox, oy, oz, curwid + 1 ) ;
8162 //queue4->prepend( ox, oy, oz ) ;
8163 //numComplex ++ ;
8164
8165 //nowComplex = 1 ;
8166 //}
8167 //else
8168 //{
8169 //setDataAt( ox, oy, oz, -1 ) ;
8170 //numSimple ++ ;
8171
8172 //if ( nowComplex )
8173 //{
8174
8176 //}
8177 //}
8179
8181 //for ( int m = 0 ; m < 6 ; m ++ )
8182 //{
8183 //int nx = ox + neighbor6[m][0] ;
8184 //int ny = oy + neighbor6[m][1] ;
8185 //int nz = oz + neighbor6[m][2] ;
8186 //if ( getDataAt( nx, ny, nz ) == 0 )
8187 //{
8189 //queue2->prepend( nx, ny, nz ) ;
8190 //}
8191 //}
8192
8194
8197 //for ( i = -1 ; i < 2 ; i ++ )
8198 //for ( j = -1 ; j < 2 ; j ++ )
8199 //for ( k = -1 ; k < 2 ; k ++ )
8200 //{
8201 //int nx = ox + i ;
8202 //int ny = oy + j ;
8203 //int nz = oz + k ;
8204
8206 //if ( getDataAt( nx, ny, nz ) == curwid &&
8208 //#ifndef NOISE_DIS_SHEET
8209 //( isSheetEnd( nx, ny, nz ) || ! isSimple( nx, ny, nz ) ) )
8210 //#else
8211 //( isSheetEnd( nx, ny, nz, noisevol ) || ! isSimple( nx, ny, nz ) ) )
8212 //#endif
8213
8214 //{
8216 //setDataAt( nx, ny, nz, curwid + 1 ) ;
8217 //queue2->prepend( nx, ny, nz ) ;
8218 //numComplex ++ ;
8219 //}
8220 //}
8221 //*/
8222
8225
8226 //for ( i = -2 ; i < 3 ;i ++ )
8227 //for ( j = -2 ; j < 3 ; j ++ )
8228 //for ( k = -2 ; k < 3 ; k ++ )
8229 //{
8230 //int nx = ox + i ;
8231 //int ny = oy + j ;
8232 //int nz = oz + k ;
8233
8234 //if ( getDataAt( nx, ny, nz ) == curwid )
8235 //{
8237 //score = getNumPotComplex( nx, ny, nz ) ;
8238
8239 //if ( score != (int) scrvol->getDataAt( nx, ny, nz ) )
8240 //{
8242 //scrvol->setDataAt( nx, ny, nz, score ) ;
8244 //gp = new gridPoint ;
8245 //gp->x = nx ;
8246 //gp->y = ny ;
8247 //gp->z = nz ;
8249 //queue->add( gp, score ) ;
8250 //}
8251 //}
8252 //}
8253
8254
8255 //}
8256
8257 //printf("%d complex, %d simple\n", numComplex, numSimple) ;
8258
8259 //if ( numSimple == 0 )
8260 //{
8261 //break ;
8262 //}
8263 //}
8264
8266 //printf("Thresholding the volume to 0/1...\n") ;
8267 //threshold( 0, 0, 1 ) ;
8268
8269 //}
8270
8271 //void Volume::surfaceSkeletonOld( float thr )
8272 //{
8273 //int i, j, k ;
8275 //#ifdef VERBOSE
8276 //printf("Thresholding the volume to -MAX_ERODE/0...\n") ;
8277 //#endif
8278 //threshold( thr, -MAX_ERODE, 0 ) ;
8279
8281 //#ifdef VERBOSE
8282 //printf("Initializing queue...\n") ;
8283 //#endif
8284 //GridQueue2* queue2 = new GridQueue2( ) ;
8285 //GridQueue2* queue3 = new GridQueue2( ) ;
8286 //GridQueue2* queue4 = new GridQueue2( ) ;
8287
8288 //PriorityQueue <gridPoint,int> * queue = new PriorityQueue <gridPoint,int> ( MAX_QUEUELEN );
8289
8290 //for ( i = 0 ; i < getSizeX() ; i ++ )
8291 //for ( j = 0 ; j < getSizeY() ; j ++ )
8292 //for ( k = 0 ; k < getSizeZ() ; k ++ )
8293 //{
8294 //if ( getDataAt( i, j, k ) >= 0 )
8295 //{
8296 //{
8297 //for ( int m = 0 ; m < 6 ; m ++ )
8298 //{
8299 //if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
8300 //{
8302 //queue2->prepend( i, j, k ) ;
8303 //break ;
8304 //}
8305 //}
8306 //}
8307 //}
8308 //}
8309 //#ifdef VERBOSE
8310 //printf("Total %d nodes\n", queue2->getNumElements() ) ;
8311 //#endif
8312
8314 //int wid = MAX_ERODE ;
8315 //#ifdef VERBOSE
8316 //printf("Start erosion to %d...\n", wid) ;
8317 //#endif
8318 //gridQueueEle* ele ;
8319 //gridPoint* gp ;
8320 //int ox, oy, oz ;
8321 //int score ;
8322 //Volume* scrvol = new Volume( this->getSizeX() , this->getSizeY(), this->getSizeZ() ) ;
8323 //for ( i = 0 ; i < getSizeX() * getSizeY() * getSizeZ() ; i ++ )
8324 //{
8325 //scrvol->setDataAt( i, -1 ) ;
8326 //}
8327
8328 //#ifdef NOISE_DIS_SHEET
8329 //Volume* noisevol = new Volume( getSizeX(), getSizeY(), getSizeZ() ) ;
8330 //#endif
8331
8332 //for ( int curwid = 1 ; curwid <= wid ; curwid ++ )
8333 //{
8337
8338 //int numComplex = 0, numSimple = 0 ;
8339 //#ifdef VERBOSE
8340 //printf("Processing %d nodes in layer %d\n", queue2->getNumElements(), curwid) ;
8341 //#endif
8342
8344 //We first need to assign curwid + 1 to every node in this layer
8345 //*/
8346 //queue2->reset() ;
8347 //ele = queue2->getNext() ;
8348 //while ( ele != NULL )
8349 //{
8350 //ox = ele->x ;
8351 //oy = ele->y ;
8352 //oz = ele->z ;
8353
8354 //if ( getDataAt(ox,oy,oz) == curwid )
8355 //{
8356 //ele = queue2->remove() ;
8357 //}
8358 //else
8359 //{
8360 //setDataAt(ox,oy,oz, curwid) ;
8361 //ele = queue2->getNext() ;
8362 //}
8363 //}
8364 //queue4->reset() ;
8365 //ele = queue4->getNext() ;
8366 //while ( ele != NULL )
8367 //{
8368 //ox = ele->x ;
8369 //oy = ele->y ;
8370 //oz = ele->z ;
8371
8372 //queue2->prepend(ox,oy,oz) ;
8373 //ele = queue4->remove() ;
8374 //}
8375
8377
8378 //#ifdef NOISE_DIS_SHEET
8380 //queue2->reset() ;
8381
8383 //int flag = 0 ;
8384 //while ( ( ele = queue2->getNext() ) != NULL )
8385 //{
8386 //ox = ele->x ;
8387 //oy = ele->y ;
8388 //oz = ele->z ;
8389 //if ( NOISE_DIS_SHEET <= 1 )
8390 //{
8391 //noisevol->setDataAt( ox, oy, oz, 0 ) ;
8392 //}
8393 //else
8394 //{
8395 //flag = 0 ;
8396 //for ( int m = 0 ; m < 6 ; m ++ )
8397 //{
8398 //int nx = ox + neighbor6[m][0] ;
8399 //int ny = oy + neighbor6[m][1] ;
8400 //int nz = oz + neighbor6[m][2] ;
8401 //if ( getDataAt( nx, ny, nz ) == 0 )
8402 //{
8403 //noisevol->setDataAt( ox, oy, oz, 1 ) ;
8404 //flag = 1 ;
8405 //break ;
8406 //}
8407 //}
8408 //if ( ! flag )
8409 //{
8410 //noisevol->setDataAt( ox, oy, oz, 0 ) ;
8411 //}
8412 //}
8413 //}
8414
8415 //for ( int cur = 1 ; cur < NOISE_DIS_SHEET ; cur ++ )
8416 //{
8417 //queue2->reset() ;
8418 //int count = 0 ;
8419
8420 //while ( ( ele = queue2->getNext() ) != NULL )
8421 //{
8422 //ox = ele->x ;
8423 //oy = ele->y ;
8424 //oz = ele->z ;
8425
8426 //if ( noisevol->getDataAt( ox, oy, oz ) == 1 )
8427 //{
8428 //continue ;
8429 //}
8430
8431 //flag = 0 ;
8432 //for ( int m = 0 ; m < 6 ; m ++ )
8433 //{
8434 //int nx = ox + neighbor6[m][0] ;
8435 //int ny = oy + neighbor6[m][1] ;
8436 //int nz = oz + neighbor6[m][2] ;
8437 //if ( getDataAt( nx, ny, nz ) > 0 && noisevol->getDataAt( nx, ny, nz ) == 1 )
8438 //{
8439 //noisevol->setDataAt( ox, oy, oz, 1 ) ;
8440 //count ++ ;
8441 //break ;
8442 //}
8443 //}
8444 //}
8445
8446 //if ( count == 0 )
8447 //{
8448 //break ;
8449 //}
8450 //}
8451
8452
8453 //#endif
8454
8456
8460 //queue2->reset() ;
8461 //ele = queue2->getNext() ;
8462 //while ( ele != NULL )
8463 //{
8464 //ox = ele->x ;
8465 //oy = ele->y ;
8466 //oz = ele->z ;
8467
8469 //#ifndef NOISE_DIS_SHEET
8470 //if ( isSheetEnd( ox, oy, oz ) || ! isSimple( ox, oy, oz ) )
8471 //#else
8472 //if ( isSheetEnd( ox, oy, oz, noisevol ) || ! isSimple( ox, oy, oz ) )
8473 //#endif
8474 //{
8476 //setDataAt( ox, oy, oz, curwid + 1 ) ;
8477 //queue3->prepend( ox, oy, oz ) ;
8478 //ele = queue2->remove() ;
8479
8480 //numComplex ++ ;
8481 //}
8482 //else
8483 //{
8484 //ele = queue2->getNext() ;
8485 //}
8486 //}
8487 //*/
8488
8489
8493 //queue2->reset() ;
8494 //ele = queue2->getNext() ;
8495 //while ( ele != NULL )
8496 //{
8497 //ox = ele->x ;
8498 //oy = ele->y ;
8499 //oz = ele->z ;
8500
8502 //score = getNumPotComplex( ox, oy, oz ) ;
8503 //scrvol->setDataAt( ox, oy, oz, score ) ;
8504
8506 //gp = new gridPoint ;
8507 //gp->x = ox ;
8508 //gp->y = oy ;
8509 //gp->z = oz ;
8511 //queue->add( gp, score ) ;
8512
8513 //ele = queue2->remove() ;
8514 //}
8515
8519 //delete queue2 ;
8520 //queue2 = queue3 ;
8521 //queue3 = new GridQueue2( ) ;
8522
8524 //while ( ! queue->isEmpty() )
8525 //{
8527 //queue->remove( gp, score ) ;
8528 //ox = gp->x ;
8529 //oy = gp->y ;
8530 //oz = gp->z ;
8531 //delete gp ;
8534
8538 //if ( getDataAt( ox, oy, oz ) != curwid || (int) scrvol->getDataAt( ox, oy, oz ) != score )
8539 //{
8540 //continue ;
8541 //}
8542
8544
8546 //setDataAt( ox, oy, oz, -1 ) ;
8547 //numSimple ++ ;
8549 //*/
8550
8553 //#ifndef NOISE_DIS_SHEET
8555 //if ( (! isSimple( ox, oy, oz )) || isSheetEnd( ox, oy, oz ) )
8557 //#else
8559 //if ( ! isSimple( ox, oy, oz ) || isSheetEnd( ox, oy, oz, noisevol ) || isHelixEnd( ox, oy, oz, noisevol ))
8561 //#endif
8562 //{
8564 //setDataAt( ox, oy, oz, curwid + 1 ) ;
8565 //queue4->prepend( ox, oy, oz ) ;
8566 //numComplex ++ ;
8567
8568 //}
8569 //else
8570 //{
8571 //setDataAt( ox, oy, oz, -1 ) ;
8572 //numSimple ++ ;
8573
8574 //}
8576
8578 //for ( int m = 0 ; m < 6 ; m ++ )
8579 //{
8580 //int nx = ox + neighbor6[m][0] ;
8581 //int ny = oy + neighbor6[m][1] ;
8582 //int nz = oz + neighbor6[m][2] ;
8583 //if ( getDataAt( nx, ny, nz ) == 0 )
8584 //{
8586 //queue2->prepend( nx, ny, nz ) ;
8587 //}
8588 //}
8589
8591
8594 //for ( i = -1 ; i < 2 ; i ++ )
8595 //for ( j = -1 ; j < 2 ; j ++ )
8596 //for ( k = -1 ; k < 2 ; k ++ )
8597 //{
8598 //int nx = ox + i ;
8599 //int ny = oy + j ;
8600 //int nz = oz + k ;
8601
8603 //if ( getDataAt( nx, ny, nz ) == curwid &&
8605 //#ifndef NOISE_DIS_SHEET
8606 //( isSheetEnd( nx, ny, nz ) || ! isSimple( nx, ny, nz ) ) )
8607 //#else
8608 //( isSheetEnd( nx, ny, nz, noisevol ) || ! isSimple( nx, ny, nz ) ) )
8609 //#endif
8610
8611 //{
8613 //setDataAt( nx, ny, nz, curwid + 1 ) ;
8614 //queue2->prepend( nx, ny, nz ) ;
8615 //numComplex ++ ;
8616 //}
8617 //}
8618 //*/
8619
8622
8623 //for ( i = -2 ; i < 3 ;i ++ )
8624 //for ( j = -2 ; j < 3 ; j ++ )
8625 //for ( k = -2 ; k < 3 ; k ++ )
8626 //{
8627 //int nx = ox + i ;
8628 //int ny = oy + j ;
8629 //int nz = oz + k ;
8630
8631 //if ( getDataAt( nx, ny, nz ) == curwid )
8632 //{
8634 //score = getNumPotComplex( nx, ny, nz ) ;
8635
8636 //if ( score != (int) scrvol->getDataAt( nx, ny, nz ) )
8637 //{
8639 //scrvol->setDataAt( nx, ny, nz, score ) ;
8641 //gp = new gridPoint ;
8642 //gp->x = nx ;
8643 //gp->y = ny ;
8644 //gp->z = nz ;
8646 //queue->add( gp, score ) ;
8647 //}
8648 //}
8649 //}
8650
8651
8652 //}
8653 //#ifdef VERBOSE
8654 //printf("%d complex, %d simple\n", numComplex, numSimple) ;
8655 //#endif
8656
8657 //if ( numSimple == 0 )
8658 //{
8659 //break ;
8660 //}
8661 //}
8662
8664 //#ifdef VERBOSE
8665 //printf("Thresholding the volume to 0/1...\n") ;
8666 //#endif
8667 //threshold( 0, 0, 1 ) ;
8668 //delete queue;
8669
8670 //}
8671
8672 void Volume::surfaceSkeletonPres( float thr, Volume * preserve )
8673 {
8674 int i, j, k ;
8675 // First, threshold the volume
8676 #ifdef VERBOSE
8677 printf("Thresholding the volume to -MAX_ERODE/0...\n") ;
8678 #endif
8679 threshold( thr, -MAX_ERODE, 0 ) ;
8680
8681 // Next, initialize the linked queue
8682 #ifdef VERBOSE
8683 printf("Initializing queue...\n") ;
8684 #endif
8685 GridQueue2* queue2 = new GridQueue2( ) ;
8686 GridQueue2* queue3 = new GridQueue2( ) ;
8687 GridQueue2* queue4 = new GridQueue2( ) ;
8688
8690
8691 for ( i = 0 ; i < getSizeX() ; i ++ )
8692 for ( j = 0 ; j < getSizeY() ; j ++ )
8693 for ( k = 0 ; k < getSizeZ() ; k ++ )
8694 {
8695 if ( getDataAt( i, j, k ) >= 0 ) {
8696 if(preserve->getDataAt(i, j, k) > 0) {
8697 setDataAt(i, j, k, MAX_ERODE);
8698 } else {
8699 for ( int m = 0 ; m < 6 ; m ++ )
8700 {
8701 if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
8702 {
8703 // setDataAt( i, j, k, 1 ) ;
8704 queue2->prepend( i, j, k ) ;
8705 break ;
8706 }
8707 }
8708 }
8709 }
8710 }
8711 int wid = MAX_ERODE ;
8712 #ifdef VERBOSE
8713 printf("Total %d nodes\n", queue2->getNumElements() ) ;
8714 printf("Start erosion to %d...\n", wid) ;
8715 #endif
8716
8717
8718 // Perform erosion
8719 gridQueueEle* ele ;
8720 gridPoint* gp ;
8721 int ox, oy, oz ;
8722 int score ;
8723 Volume* scrvol = new Volume( this->getSizeX() , this->getSizeY(), this->getSizeZ() ) ;
8724 for ( i = 0 ; i < getSizeX() * getSizeY() * getSizeZ() ; i ++ )
8725 {
8726 scrvol->setDataAt( i, -1 ) ;
8727 }
8728
8729 #ifdef NOISE_DIS_SHEET
8730 Volume* noisevol = new Volume( getSizeX(), getSizeY(), getSizeZ() ) ;
8731 #endif
8732
8733 for ( int curwid = 1 ; curwid <= wid ; curwid ++ )
8734 {
8735 // At the start of each iteration,
8736 // queue2 and queue4 holds all the nodes for this layer
8737 // queue3 and queue are empty
8738
8739 int numComplex = 0, numSimple = 0 ;
8740 #ifdef VERBOSE
8741 printf("Processing %d nodes in layer %d\n", queue2->getNumElements(), curwid) ;
8742 #endif
8743
8744 /*
8745 We first need to assign curwid + 1 to every node in this layer
8746 */
8747 queue2->reset() ;
8748 ele = queue2->getNext() ;
8749 while ( ele != NULL )
8750 {
8751 ox = ele->x ;
8752 oy = ele->y ;
8753 oz = ele->z ;
8754
8755 if ( getDataAt(ox,oy,oz) == curwid )
8756 {
8757 ele = queue2->remove() ;
8758 }
8759 else
8760 {
8761 setDataAt(ox,oy,oz, curwid) ;
8762 ele = queue2->getNext() ;
8763 }
8764 }
8765 queue4->reset() ;
8766 ele = queue4->getNext() ;
8767 while ( ele != NULL )
8768 {
8769 ox = ele->x ;
8770 oy = ele->y ;
8771 oz = ele->z ;
8772
8773 queue2->prepend(ox,oy,oz) ;
8774 ele = queue4->remove() ;
8775 }
8776
8777 // Now queue2 holds all the nodes for this layer
8778
8779 #ifdef NOISE_DIS_SHEET
8780 /* Extra step: classify nodes in queue2 into noise and non-noise nodes */
8781 queue2->reset() ;
8782
8783 // First run
8784 int flag = 0 ;
8785 while ( ( ele = queue2->getNext() ) != NULL )
8786 {
8787 ox = ele->x ;
8788 oy = ele->y ;
8789 oz = ele->z ;
8790 if ( NOISE_DIS_SHEET <= 1 )
8791 {
8792 noisevol->setDataAt( ox, oy, oz, 0 ) ;
8793 }
8794 else
8795 {
8796 flag = 0 ;
8797 for ( int m = 0 ; m < 6 ; m ++ )
8798 {
8799 int nx = ox + neighbor6[m][0] ;
8800 int ny = oy + neighbor6[m][1] ;
8801 int nz = oz + neighbor6[m][2] ;
8802 if ( getDataAt( nx, ny, nz ) == 0 )
8803 {
8804 noisevol->setDataAt( ox, oy, oz, 1 ) ;
8805 flag = 1 ;
8806 break ;
8807 }
8808 }
8809 if ( ! flag )
8810 {
8811 noisevol->setDataAt( ox, oy, oz, 0 ) ;
8812 }
8813 }
8814 }
8815
8816 for ( int cur = 1 ; cur < NOISE_DIS_SHEET ; cur ++ )
8817 {
8818 queue2->reset() ;
8819 int count = 0 ;
8820
8821 while ( ( ele = queue2->getNext() ) != NULL )
8822 {
8823 ox = ele->x ;
8824 oy = ele->y ;
8825 oz = ele->z ;
8826
8827 if ( noisevol->getDataAt( ox, oy, oz ) == 1 )
8828 {
8829 continue ;
8830 }
8831
8832 flag = 0 ;
8833 for ( int m = 0 ; m < 6 ; m ++ )
8834 {
8835 int nx = ox + neighbor6[m][0] ;
8836 int ny = oy + neighbor6[m][1] ;
8837 int nz = oz + neighbor6[m][2] ;
8838 if ( getDataAt( nx, ny, nz ) > 0 && noisevol->getDataAt( nx, ny, nz ) == 1 )
8839 {
8840 noisevol->setDataAt( ox, oy, oz, 1 ) ;
8841 count ++ ;
8842 break ;
8843 }
8844 }
8845 }
8846
8847 if ( count == 0 )
8848 {
8849 break ;
8850 }
8851 }
8852
8853
8854 #endif
8855
8856 /* Commented for debugging
8857
8858 // First,
8859 // check for complex nodes in queue2
8860 // move them from queue2 to queue3
8861 queue2->reset() ;
8862 ele = queue2->getNext() ;
8863 while ( ele != NULL )
8864 {
8865 ox = ele->x ;
8866 oy = ele->y ;
8867 oz = ele->z ;
8868
8869 // Check simple
8870 #ifndef NOISE_DIS_SHEET
8871 if ( isSheetEnd( ox, oy, oz ) || ! isSimple( ox, oy, oz ) )
8872 #else
8873 if ( isSheetEnd( ox, oy, oz, noisevol ) || ! isSimple( ox, oy, oz ) )
8874 #endif
8875 {
8876 // Complex, set to next layer
8877 setDataAt( ox, oy, oz, curwid + 1 ) ;
8878 queue3->prepend( ox, oy, oz ) ;
8879 ele = queue2->remove() ;
8880
8881 numComplex ++ ;
8882 }
8883 else
8884 {
8885 ele = queue2->getNext() ;
8886 }
8887 }
8888 */
8889
8890
8891 // Next,
8892 // Compute score for each node left in queue2
8893 // move them into priority queue
8894 queue2->reset() ;
8895 ele = queue2->getNext() ;
8896 while ( ele != NULL )
8897 {
8898 ox = ele->x ;
8899 oy = ele->y ;
8900 oz = ele->z ;
8901
8902 // Compute score
8903 score = getNumPotComplex( ox, oy, oz ) ;
8904 scrvol->setDataAt( ox, oy, oz, score ) ;
8905
8906 // Push to queue
8907 gp = new gridPoint ;
8908 gp->x = ox ;
8909 gp->y = oy ;
8910 gp->z = oz ;
8911 // queue->add( gp, -score ) ;
8912 queue->add( gp, score ) ;
8913
8914 ele = queue2->remove() ;
8915 }
8916
8917 // Rename queue3 to be queue2,
8918 // Clear queue3
8919 // From now on, queue2 holds nodes of next level
8920 delete queue2 ;
8921 queue2 = queue3 ;
8922 queue3 = new GridQueue2( ) ;
8923
8924
8925 // Next, start priority queue iteration
8926 while ( ! queue->isEmpty() )
8927 {
8928 // Retrieve the node with the highest score
8929 queue->remove( gp, score ) ;
8930 ox = gp->x ;
8931 oy = gp->y ;
8932 oz = gp->z ;
8933 delete gp ;
8934 // printf("%d\n", score);
8935 // score = -score ;
8936
8937 // Ignore the node
8938 // if it has been processed before
8939 // or it has an updated score
8940 if ( getDataAt( ox, oy, oz ) != curwid || (int) scrvol->getDataAt( ox, oy, oz ) != score )
8941 {
8942 continue ;
8943 }
8944
8945 /* Commented for debugging
8946
8947 // Remove this simple node
8948 setDataAt( ox, oy, oz, -1 ) ;
8949 numSimple ++ ;
8950 // printf("Highest score: %d\n", score) ;
8951 */
8952
8953 /* Added for debugging */
8954 // Check simple
8955 #ifndef NOISE_DIS_SHEET
8956 // if ( hasFeatureFace( ox, oy, oz ) )
8957 if ( (! isSimple( ox, oy, oz )) || isSheetEnd( ox, oy, oz ) )
8958 // if ( hasIsolatedFace(ox,oy,oz) && (! isNoiseSheetEnd(ox,oy,oz)))
8959 #else
8960 // if ( ! isSimple( ox, oy, oz ) || isSheetEnd( ox, oy, oz, noisevol ) )
8961 if ( ! isSimple( ox, oy, oz ) || isSheetEnd( ox, oy, oz, noisevol ) || isHelixEnd( ox, oy, oz, noisevol ))
8962 // if ( isBertrandEndPoint( ox, oy, oz ) )
8963 #endif
8964 {
8965 // Complex, set to next layer
8966 setDataAt( ox, oy, oz, curwid + 1 ) ;
8967 queue4->prepend( ox, oy, oz ) ;
8968 numComplex ++ ;
8969
8970 }
8971 else
8972 {
8973 setDataAt( ox, oy, oz, -1 ) ;
8974 numSimple ++ ;
8975
8976 }
8977 /* Adding ends */
8978
8979 // Move its neighboring unvisited node to queue2
8980 for ( int m = 0 ; m < 6 ; m ++ )
8981 {
8982 int nx = ox + neighbor6[m][0] ;
8983 int ny = oy + neighbor6[m][1] ;
8984 int nz = oz + neighbor6[m][2] ;
8985 if ( getDataAt( nx, ny, nz ) == 0 )
8986 {
8987 // setDataAt( nx, ny, nz, curwid + 1 ) ;
8988 queue2->prepend( nx, ny, nz ) ;
8989 }
8990 }
8991
8992 /* Commented for debugging
8993
8994 // Find complex nodes in its 3x3 neighborhood
8995 // move them to queue2
8996 for ( i = -1 ; i < 2 ; i ++ )
8997 for ( j = -1 ; j < 2 ; j ++ )
8998 for ( k = -1 ; k < 2 ; k ++ )
8999 {
9000 int nx = ox + i ;
9001 int ny = oy + j ;
9002 int nz = oz + k ;
9003
9004 // Check simple
9005 if ( getDataAt( nx, ny, nz ) == curwid &&
9006 // ( isSheetEnd( ox, oy, oz ) || ! isSimple( nx, ny, nz )) )
9007 #ifndef NOISE_DIS_SHEET
9008 ( isSheetEnd( nx, ny, nz ) || ! isSimple( nx, ny, nz ) ) )
9009 #else
9010 ( isSheetEnd( nx, ny, nz, noisevol ) || ! isSimple( nx, ny, nz ) ) )
9011 #endif
9012
9013 {
9014 // Complex, set to next layer
9015 setDataAt( nx, ny, nz, curwid + 1 ) ;
9016 queue2->prepend( nx, ny, nz ) ;
9017 numComplex ++ ;
9018 }
9019 }
9020 */
9021
9022 // Update scores for nodes in its 5x5 neighborhood
9023 // insert them back into priority queue
9024
9025 for ( i = -2 ; i < 3 ;i ++ )
9026 for ( j = -2 ; j < 3 ; j ++ )
9027 for ( k = -2 ; k < 3 ; k ++ )
9028 {
9029 int nx = ox + i ;
9030 int ny = oy + j ;
9031 int nz = oz + k ;
9032
9033 if ( getDataAt( nx, ny, nz ) == curwid )
9034 {
9035 // Compute score
9036 score = getNumPotComplex( nx, ny, nz ) ;
9037
9038 if ( score != (int) scrvol->getDataAt( nx, ny, nz ) )
9039 {
9040 // printf("Update\n") ;
9041 scrvol->setDataAt( nx, ny, nz, score ) ;
9042 // Push to queue
9043 gp = new gridPoint ;
9044 gp->x = nx ;
9045 gp->y = ny ;
9046 gp->z = nz ;
9047 // queue->add( gp, -score ) ;
9048 queue->add( gp, score ) ;
9049 }
9050 }
9051 }
9052
9053
9054 }
9055
9056 #ifdef VERBOSE
9057 printf("%d complex, %d simple\n", numComplex, numSimple) ;
9058 #endif
9059
9060 if ( numSimple == 0 )
9061 {
9062 break ;
9063 }
9064 }
9065
9066 // Finally, clean up
9067 #ifdef VERBOSE
9068 printf("Thresholding the volume to 0/1...\n") ;
9069 #endif
9070 threshold( 0, 0, 1 ) ;
9071
9072 delete scrvol;
9073 delete queue;
9074 delete queue2;
9075 delete queue3;
9076 delete queue4;
9077
9078 }
9079
9081 //void Volume::bertrandSurfaceSkeleton2( float thr )
9082 //{
9083 //int i, j, k ;
9084
9086 //#ifdef VERBOSE
9087 //printf("Thresholding the volume to -MAX_ERODE/0...\n") ;
9088 //#endif
9089 //threshold( thr, -MAX_ERODE, 0 ) ;
9090
9091
9093 //printf("Initializing queues...\n") ;
9094 //GridQueue2* queue2 = new GridQueue2( ) ;
9095 //GridQueue2* queue3 = new GridQueue2( ) ;
9096 //GridQueue2* queue4 = new GridQueue2( ) ;
9097 //Volume* fvol = new Volume( this->getSizeX(), this->getSizeY(), this->getSizeZ(), 0 ) ;
9098
9099 //for ( i = 0 ; i < getSizeX() ; i ++ )
9100 //for ( j = 0 ; j < getSizeY() ; j ++ )
9101 //for ( k = 0 ; k < getSizeZ() ; k ++ )
9102 //{
9103 //if ( getDataAt( i, j, k ) == 0 )
9104 //{
9105 //for ( int m = 0 ; m < 6 ; m ++ )
9106 //{
9107 //if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) < 0 )
9108 //{
9109 //fvol->setDataAt( i, j, k, 1 ) ;
9110 //queue2->prepend( i, j, k ) ;
9111 //break ;
9112 //}
9113 //}
9114 //}
9115 //}
9116 //printf("Total %d nodes\n", queue2->getNumElements() ) ;
9117
9119 //int it = 0 ;
9120 //gridQueueEle* ele ;
9121 //while ( ++ it )
9122 //{
9123 //printf("Iteration %d... nodes in queue: %d...", it, queue2->getNumElements()) ;
9124
9126
9127 //int deleted = 0 ;
9128 //for ( i = 0 ; i < 6 ; i ++ )
9129 //{
9134
9135 //queue2->reset() ;
9136 //ele = queue2->getNext() ;
9137
9139 //while ( ele != NULL )
9140 //{
9141 //int ox = ele->x ;
9142 //int oy = ele->y ;
9143 //int oz = ele->z ;
9144
9145 //if ( isBertrandBorder( ox,oy,oz, i ) )
9146 //{
9147 //if ( ! isBertrandEndPoint( ox,oy,oz ) )
9148 //{
9150 //ele = queue2->remove() ;
9151 //queue3->prepend( ox, oy, oz ) ;
9152
9154 //for ( int m = 0 ; m < 6 ; m ++ )
9155 //{
9156 //int nx = ox + neighbor6[m][0] ;
9157 //int ny = oy + neighbor6[m][1] ;
9158 //int nz = oz + neighbor6[m][2] ;
9159 //if ( fvol->getDataAt( nx, ny, nz ) == 0 )
9160 //{
9161 //fvol->setDataAt( nx, ny, nz, 1 ) ;
9162 //queue4->prepend( nx, ny, nz ) ;
9163 //}
9164 //}
9165 //}
9166 //else
9167 //{
9168 //ele = queue2->getNext() ;
9169 //}
9170 //}
9171 //else
9172 //{
9173 //ele = queue2->getNext() ;
9174 //}
9175 //}
9176
9180
9182 //if ( queue3->getNumElements() == 0 )
9183 //{
9185 //}
9186 //else
9187 //{
9188 //queue3->reset() ;
9189 //ele = queue3->getNext() ;
9190 //while ( ele != NULL )
9191 //{
9192 //setDataAt( ele->x, ele->y, ele->z, -1 ) ;
9193 //ele = queue3->remove() ;
9194 //deleted ++ ;
9195 //}
9196 //}
9197
9199 //}
9200
9203 //queue4->reset() ;
9204 //ele = queue4->getNext() ;
9205 //while ( ele != NULL )
9206 //{
9207 //queue2->prepend( ele->x, ele->y, ele->z) ;
9208 //ele = queue4->remove() ;
9209 //}
9210
9211 //if ( deleted == 0 )
9212 //{
9213 //printf("No more deletable nodes.\n");
9214 //break ;
9215 //}
9216 //else
9217 //{
9218 //printf("Deleted: %d\n", deleted) ;
9219 //}
9220 //}
9221
9223 //#ifdef VERBOSE
9224 //printf("Thresholding the volume to 0/1...\n") ;
9225 //#endif
9226 //threshold( 0, 0, 1 ) ;
9227
9228 //}
9229
9230
9231
9232 //void Volume::bertrandSurfaceSkeleton( float thr )
9233 //{
9234 //int i, j, k ;
9235
9237 //#ifdef VERBOSE
9238 //printf("Thresholding the volume to -MAX_ERODE/0...\n") ;
9239 //#endif
9240 //threshold( thr, -MAX_ERODE, 0 ) ;
9241
9243 //GridQueue2* queue2 = new GridQueue2( ) ;
9244 //int dir = 0, ct = 0 ;
9245 //while( ++ct )
9246 //{
9247 //printf("Round %d, direction %d...", ct, dir) ;
9248 //queue2->reset() ;
9249
9250 //for ( i = 0 ; i < getSizeX() ; i ++ )
9251 //for ( j = 0 ; j < getSizeY() ; j ++ )
9252 //for ( k = 0 ; k < getSizeZ() ; k ++ )
9253 //{
9254 //if ( getDataAt(i,j,k) >= 0 )
9255 //{
9256 //if ( isBertrandBorder( i,j,k, dir ) )
9257 //{
9258 //if ( ! isBertrandEndPoint( i,j,k ) )
9259 //{
9260 //queue2->prepend( i,j,k ) ;
9261 //}
9262 //}
9263 //}
9264
9265 //}
9266
9267
9268 //if ( queue2->getNumElements() == 0 )
9269 //{
9270 //printf("Done.\n");
9271 //break ;
9272 //}
9273 //else
9274 //{
9275 //queue2->reset() ;
9276 //printf("%d nodes deleted.\n", queue2->getNumElements()) ;
9277 //gridQueueEle* ele = queue2->getNext() ;
9278 //while ( ele != NULL )
9279 //{
9280 //setDataAt( ele->x, ele->y, ele->z, -1 ) ;
9281 //ele = queue2->remove() ;
9282 //}
9283 //}
9284 //dir = ( dir + 1 ) % 6 ;
9285 //}
9286
9288 //#ifdef VERBOSE
9289 //printf("Thresholding the volume to 0/1...\n") ;
9290 //#endif
9291 //threshold( 0, 0, 1 ) ;
9292 //}
9293
9294
9296 //void Volume::palagyiSurfaceSkeleton( float thr )
9297 //{
9298 //int i, j, k ;
9299
9301 //#ifdef VERBOSE
9302 //printf("Thresholding the volume to 0/1...\n") ;
9303 //#endif
9304 //threshold( thr, 0, 1 ) ;
9305
9307 //printf("Initializing surface endpoints templates...\n") ;
9308 //ThinningTemplate* US[6] ;
9309
9310 //int b0[] = {12,13} ;
9311 //int w0[] = {2, 5, 8, 11, 14, 17, 20, 23, 26} ;
9312 //int ob0[] = {10, 16} ;
9313 //int ob20[] = {4, 22} ;
9314 //int nu[] = {0} ;
9315 //US[0] = new ThinningTemplate( b0, 2, w0, 9, ob0, 2, ob20, 2, nu, 0, nu, 0 ) ;
9316 //US[1] = new ThinningTemplate( US[0], 0, 1 ) ;
9318 //int b01[] = {13,16} ;
9319 //int w01[] = {0,1,2,9,10,11,18,19,20} ;
9320 //int ob01[] = {12, 14} ;
9321 //int ob201[] = {4, 22} ;
9322 //US[1] = new ThinningTemplate( b01, 2, w01, 9, ob01, 2, ob201, 2, nu, 0, nu, 0 ) ;
9323 //*/
9324
9325 //int b1[] = {12,13,16,22} ;
9326 //int w1[] = {2,10,11,14} ;
9327 //int ow[] = {1,5} ;
9328 //US[2] = new ThinningTemplate( b1, 4, w1, 4, nu, 0, nu, 0, ow, 2, nu, 0 ) ;
9329 //US[3] = new ThinningTemplate( US[2], 0 ) ;
9330
9331 //int b2[] = {2,12,13,16,22} ;
9332 //int w2[] = {10,11,14} ;
9333 //int op[] = {1,5} ;
9334 //US[4] = new ThinningTemplate( b2, 5, w2, 3, nu, 0, nu, 0, nu, 0, op, 2 ) ;
9335 //US[5] = new ThinningTemplate( US[4], 0 ) ;
9336
9337 //ThinningTemplate * NE[6], * WD[6], * ES[6], * UW[6], * ND[6], * SW[6], * UN[6], * ED[6], * NW[6], * UE[6], * SD[6] ;
9338
9339 //for ( i = 0 ; i < 6 ; i ++ )
9340 //{
9341 //SD[i] = new ThinningTemplate( US[i], 0, 1 ) ;
9342 //ND[i] = new ThinningTemplate( SD[i], 0, 1 ) ;
9343 //UN[i] = new ThinningTemplate( ND[i], 0, 1 ) ;
9344
9345 //ES[i] = new ThinningTemplate( US[i], 1, 1 ) ;
9346 //NE[i] = new ThinningTemplate( ES[i], 2, 1 ) ;
9347 //NW[i] = new ThinningTemplate( NE[i], 2, 1 ) ;
9348 //SW[i] = new ThinningTemplate( NW[i], 2, 1 ) ;
9349
9350 //UE[i] = new ThinningTemplate( US[i], 2, 1 ) ;
9351 //ED[i] = new ThinningTemplate( UE[i], 1, 1 ) ;
9352 //WD[i] = new ThinningTemplate( ED[i], 1, 1 ) ;
9353 //UW[i] = new ThinningTemplate( WD[i], 1, 1 ) ;
9354 //}
9355
9356 //ThinningTemplate** alltemps[12] = { US, NE, WD, ES, UW, ND, SW, UN, ED, NW, UE, SD } ;
9357
9359 //printf("Initializing queues...\n") ;
9360 //GridQueue2* queue2 = new GridQueue2( ) ;
9361 //GridQueue2* queue3 = new GridQueue2( ) ;
9362 //GridQueue2* queue4 = new GridQueue2( ) ;
9363 //Volume* fvol = new Volume( this->getSizeX(), this->getSizeY(), this->getSizeZ(), 0 ) ;
9364
9365 //for ( i = 0 ; i < getSizeX() ; i ++ )
9366 //for ( j = 0 ; j < getSizeY() ; j ++ )
9367 //for ( k = 0 ; k < getSizeZ() ; k ++ )
9368 //{
9369 //if ( getDataAt( i, j, k ) == 1 )
9370 //{
9371 //for ( int m = 0 ; m < 6 ; m ++ )
9372 //{
9373 //if ( getDataAt( i + neighbor6[m][0], j + neighbor6[m][1], k + neighbor6[m][2] ) == 0 )
9374 //{
9375 //fvol->setDataAt( i, j, k, 1 ) ;
9376 //queue2->prepend( i, j, k ) ;
9377 //break ;
9378 //}
9379 //}
9380 //}
9381 //}
9382 //printf("Total %d nodes\n", queue2->getNumElements() ) ;
9383
9385 //int it = 0 ;
9386 //int vox[3][3][3] ;
9387 //gridQueueEle* ele ;
9388 //while ( queue2->getNumElements() > 0 )
9389 //{
9390 //printf("Iteration %d... nodes in queue: %d...", it, queue2->getNumElements()) ;
9391
9393
9394 //int deleted = 0 ;
9395 //for ( i = 0 ; i < 12 ; i ++ )
9396 //{
9401
9402 //queue2->reset() ;
9403 //ele = queue2->getNext() ;
9404
9406 //while ( ele != NULL )
9407 //{
9408 //int ox = ele->x ;
9409 //int oy = ele->y ;
9410 //int oz = ele->z ;
9411
9413 //int match = 0 ;
9414 //for ( int ci = -1 ; ci < 2 ; ci ++ )
9415 //for ( int cj = -1 ; cj < 2 ; cj ++ )
9416 //for ( int ck = -1 ; ck < 2 ; ck ++ )
9417 //{
9418 //vox[ ci + 1 ][cj + 1][ck + 1] = (int)getDataAt( ox + ci, oy + cj, oz + ck ) ;
9419 //}
9420
9421 //for ( j = 0 ; j < 6 ; j ++ )
9423 //{
9424 //if ( alltemps[i][j]->isMatch( vox ) )
9425 //{
9427 //if ( ! isSimple2( vox ) )
9428 //{
9429 //printf("Wrong! %d %d\n", i, j) ;
9430 //for ( int cci = 0 ; cci < 3 ; cci ++ )
9431 //{
9432 //for ( int ccj = 0 ; ccj < 3 ; ccj ++ )
9433 //{
9434 //for ( int cck = 0 ; cck < 3 ; cck ++ )
9435 //{
9436 //printf("%d ",vox[ cci ][ccj][cck]);
9437 //}
9438 //printf(" , ") ;
9439 //}
9440 //printf("\n") ;
9441 //}
9442 //exit(0) ;
9443 //}
9444
9446 //ele = queue2->remove() ;
9447 //queue3->prepend( ox, oy, oz ) ;
9448
9450 //for ( int m = 0 ; m < 6 ; m ++ )
9451 //{
9452 //int nx = ox + neighbor6[m][0] ;
9453 //int ny = oy + neighbor6[m][1] ;
9454 //int nz = oz + neighbor6[m][2] ;
9455 //if ( fvol->getDataAt( nx, ny, nz ) == 0 )
9456 //{
9457 //fvol->setDataAt( nx, ny, nz, 1 ) ;
9458 //queue4->prepend( nx, ny, nz ) ;
9459 //}
9460 //}
9461
9462 //match = 1 ;
9463 //break ;
9464 //}
9465 //}
9466
9467 //if ( match == 0 )
9468 //{
9469 //ele = queue2->getNext() ;
9470 //}
9471 //}
9472
9476
9478 //queue3->reset() ;
9479 //ele = queue3->getNext() ;
9480 //while ( ele != NULL )
9481 //{
9482 //setDataAt( ele->x, ele->y, ele->z, 0 ) ;
9483 //ele = queue3->remove() ;
9484 //deleted ++ ;
9485 //}
9486
9488 //}
9489
9492 //queue4->reset() ;
9493 //ele = queue4->getNext() ;
9494 //while ( ele != NULL )
9495 //{
9496 //queue2->prepend( ele->x, ele->y, ele->z) ;
9497 //ele = queue4->remove() ;
9498 //}
9499
9500 //if ( deleted == 0 )
9501 //{
9502 //printf("No more deletable nodes.\n");
9503 //break ;
9504 //}
9505 //else
9506 //{
9507 //printf("Deleted: %d\n", deleted) ;
9508 //}
9509 //}
9510 //}
9511
9515 void Volume::threshold( double thr )
9516 {
9517 threshold( thr, 0, 1, 0, true) ;
9518 }
9519
9520 void Volume::threshold( double thr, int out, int in )
9521 {
9522 threshold( thr, out, in, out, true) ;
9523 }
9524
9525 void Volume::threshold( double thr, int out, int in, int boundary)
9526 {
9527 threshold(thr, out, in, boundary, true);
9528 }
9529
9530 void Volume::threshold( double thr, int out, int in, int boundary, bool markBoundary)
9531 {
9532 float val;
9533 for ( int i = 0 ; i < getSizeX() ; i ++ )
9534 for ( int j = 0 ; j < getSizeY() ; j ++ )
9535 for ( int k = 0 ; k < getSizeZ() ; k ++ )
9536 {
9537 val = (float)getDataAt(i, j, k);
9538 if(markBoundary) {
9539 if ( i > 1 && i < getSizeX() - 2 && j > 1 && j < getSizeY() - 2 && k > 1 && k < getSizeZ() - 2 ) {
9540 if(val < thr) {
9541 setDataAt(i, j, k, out);
9542 } else {
9543 setDataAt(i, j, k, in);
9544 }
9545 }
9546 else
9547 {
9548 setDataAt(i, j, k, boundary);
9549 }
9550 } else {
9551 if(val < thr) {
9552 setDataAt(i, j, k, out);
9553 } else {
9554 setDataAt(i, j, k, in);
9555 }
9556 }
9557 }
9558 }
9559
9560 //void Volume::threshold2( double thr, int out, int in )
9561 //{
9562 //for ( int i = 0 ; i < getSizeX() ; i ++ )
9563 //for ( int j = 0 ; j < getSizeY() ; j ++ )
9564 //for ( int k = 0 ; k < getSizeZ() ; k ++ ) {
9565 //double val = getDataAt(i, j, k);
9566 //if(val <= thr) {
9567 //setDataAt(i, j, k, out);
9568 //} else {
9569 //setDataAt(i, j, k, in);
9570 //}
9571 //}
9572 //}
9573
9574 //void Volume::smooth( float alpha )
9575 //{
9576 //VolumeData * smoothedData = new VolumeData(getSizeX(), getSizeY(), getSizeZ(), 0, 0, 0, volData);
9577
9578 //for (int i = 1; i < getSizeX() - 1; i++)
9579 //for (int j = 1; j < getSizeY() - 1; j++)
9580 //for (int k = 1; k < getSizeZ() - 1; k++) {
9581 //float v = (float)getDataAt( i - 1, j, k ) +
9582 //(float)getDataAt( i + 1, j, k ) +
9583 //(float)getDataAt( i, j - 1, k ) +
9584 //(float)getDataAt( i, j + 1, k ) +
9585 //(float)getDataAt( i, j, k - 1 ) +
9586 //(float)getDataAt( i, j, k + 1 ) ;
9587 //smoothedData->SetDataAt(i, j, k, smoothedData->GetDataAt(i, j, k) * alpha + ( 1 - alpha ) * v / 6);
9588 //}
9589 //delete volData;
9590 //volData = smoothedData;
9591 //}
9592
9593 //void Volume::normalize( double min, double max )
9594 //{
9595 //double imin = getMin() ;
9596 //double imax = getMax() ;
9597 //double irange = imax - imin ;
9598 //double range = max - min ;
9599
9600 //int size = volData->GetMaxIndex();
9601 //for(int i = 0 ; i < size ; i ++) {
9602 //setDataAt(i, ((getDataAt(i) - (float)imin ) / (float)irange) * (float)range + (float)min);
9603 //}
9604 //}
9605
9606 //void Volume::normalize( double min, double max, double thresh, double ithresh )
9607 //{
9608 //double imin = getMin() ;
9609 //double imax = getMax() ;
9610 //double irange1 = ithresh - imin ;
9611 //double irange2 = imax - ithresh ;
9612 //double range1 = thresh - min;
9613 //double range2 = max - thresh ;
9614
9615 //int size = volData->GetMaxIndex();
9616 //for (int i = 0; i < size; i++) {
9617 //if (getDataAt(i) < ithresh) {
9618 //setDataAt(i, ((getDataAt(i) - (float)imin ) / (float)irange1) * (float)range1 + (float)min);
9619 //}
9620 //else
9621 //{
9622 //setDataAt(i, (float)max - (( (float)imax - getDataAt(i)) / (float)irange2) * (float)range2);
9623 //}
9624 //}
9625 //}
9626
9628
9629 //Volume * Volume::getDataRange(int x, int y, int z, int radius) {
9630 //Volume * range = new Volume(radius*2+1, radius*2+1, radius*2+1);
9631 //for(int xx = x-radius; xx <= x+radius; xx++) {
9632 //for(int yy = y-radius; yy <= y+radius; yy++) {
9633 //for(int zz = z-radius; zz <= z+radius; zz++) {
9634 //range->setDataAt(xx-x+radius, yy-y+radius, zz-z+radius, getDataAt(xx, yy, zz));
9635 //}
9636 //}
9637 //}
9638 //return range;
9639 //}
9640
9642 //double Volume::getInterpDataAt( double x, double y, double z )
9643 //{
9645 //double rad = getSizeX() / 4.0 ;
9646 //double cent = ( getSizeX() - 1 ) / 2.0 ;
9647
9648 //double ox = x - cent ;
9649 //double oy = y - cent ;
9650 //double oz = z - cent ;
9651
9652 //double a = -0.3 ;
9653 //double nx = ox ;
9654 //double ny = cos( a ) * oy + sin( a ) * oz ;
9655 //double nz = - sin( a ) * oy + cos( a ) * oz ;
9656
9657 //double b = 1.4 ;
9658 //double nnx = cos( b ) * nx + sin( b ) * ny - 2;
9659 //double nny = -sin( b ) * nx + cos ( b ) * ny - 1;
9660 //double nnz = nz + 1;
9661
9662 //double dis = nnx * nnx + nny * nny ;
9663 //return 10 - 10 * dis / ( rad * rad ) ;
9664 //*/
9665
9666 //double rvalue ;
9667 //int hx = (int) ceil( x ) ;
9668 //int lx = (int) floor( x ) ;
9669 //int hy = (int) ceil( y ) ;
9670 //int ly = (int) floor( y ) ;
9671 //int hz = (int) ceil( z ) ;
9672 //int lz = (int) floor( z ) ;
9673
9674 //double x1 = x - lx, x2 = 1 - x1 ;
9675 //double r1 = x2 * getDataAt( lx, ly, lz) + x1 * getDataAt( hx, ly, lz ) ;
9676 //double r2 = x2 * getDataAt( lx, ly, hz) + x1 * getDataAt( hx, ly, hz ) ;
9677 //double r3 = x2 * getDataAt( lx, hy, lz) + x1 * getDataAt( hx, hy, lz ) ;
9678 //double r4 = x2 * getDataAt( lx, hy, hz) + x1 * getDataAt( hx, hy, hz ) ;
9679
9680 //double y1 = y - ly, y2 = 1 - y1 ;
9681 //double r5 = y2 * r1 + y1 * r3 ;
9682 //double r6 = y2 * r2 + y1 * r4 ;
9683
9684 //double z1 = z - lz, z2 = 1 - z1 ;
9685 //rvalue = z2 * r5 + z1 * r6 ;
9686
9687 //return rvalue ;
9688 //}
9689
9691 //void Volume::rotateX ( double a )
9692 //{
9693 //int i ;
9694 //int sizeX = getSizeX(), sizeY = getSizeY(), sizeZ = getSizeZ();
9695
9696 //if ( sizeX != sizeY || sizeX != sizeZ) {
9697 //return ;
9698 //}
9699
9700 //VolumeData * newData = new VolumeData(sizeX, sizeY, sizeZ, 0, 0, 0, volData);
9701
9702 //double cent = ( sizeX - 1 ) / 2.0 ;
9703 //for ( i = 0 ; i < sizeX ; i ++ )
9704 //for ( int j = 0 ; j < sizeY ; j ++ )
9705 //for ( int k = 0 ; k < sizeZ ; k ++ )
9706 //{
9707 //double x = i - cent ;
9708 //double y = j - cent ;
9709 //double z = k - cent ;
9710
9711 //double nx = x + cent ;
9712 //double ny = cos( a ) * y + sin( a ) * z + cent ;
9713 //double nz = - sin( a ) * y + cos( a ) * z + cent ;
9714
9715 //if ( nx < 0 ) {
9716 //nx = 0 ;
9717 //} else if ( nx > sizeX - 1 ) {
9718 //nx = sizeX - 1 ;
9719 //}
9720
9721 //if ( ny < 0 ) {
9722 //ny = 0 ;
9723 //} else if ( ny > sizeY - 1 ) {
9724 //ny = sizeY - 1 ;
9725 //}
9726
9727 //if ( nz < 0 ) {
9728 //nz = 0 ;
9729 //} else if ( nz > sizeZ - 1 ) {
9730 //nz = sizeZ - 1 ;
9731 //}
9732
9733 //newData->SetDataAt(i, j, k, (float)getInterpDataAt( nx, ny, nz ));
9734 //}
9735
9736 //delete volData;
9737 //volData = newData;
9738 //}
9739
9740
9742 //void Volume::toMathematicaFile( char* fname )
9743 //{
9744 //FILE* fout = fopen( fname, "w" ) ;
9745
9746 //fprintf( fout, "{" ) ;
9747 //for ( int i = 0 ; i < getSizeX() ; i ++ )
9748 //{
9749 //fprintf( fout, "{" ) ;
9750 //for ( int j = 0 ; j < getSizeY() ; j ++ )
9751 //{
9752 //fprintf( fout, "{" ) ;
9753 //for ( int k = 0 ; k < getSizeZ() ; k ++ )
9754 //{
9755 //fprintf( fout, "%.15f", getDataAt( i, j, k ) ) ;
9756 //if ( k < getSizeZ() - 1 )
9757 //{
9758 //fprintf( fout, "," ) ;
9759 //}
9760 //}
9761 //fprintf( fout, "}" ) ;
9762 //if ( j < getSizeY() - 1 )
9763 //{
9764 //fprintf( fout, ",\n" ) ;
9765 //} else {
9766 //fprintf( fout, "\n" ) ;
9767 //}
9768 //}
9769 //fprintf( fout, "}" ) ;
9770 //if ( i < getSizeX() - 1 )
9771 //{
9772 //fprintf( fout, ",\n\n\n" ) ;
9773 //} else {
9774 //fprintf( fout, "\n\n\n" ) ;
9775 //}
9776 //}
9777 //fprintf(fout,"}") ;
9778
9779 //fclose( fout ) ;
9780
9781 //}
9782
9784 //void Volume::toMathematicaFile( char* fname, int lx, int hx, int ly, int hy, int lz, int hz )
9785 //{
9786 //FILE* fout = fopen( fname, "w" ) ;
9787
9788 //fprintf( fout, "{" ) ;
9789 //for ( int i = lx ; i < hx ; i ++ )
9790 //{
9791 //fprintf( fout, "{" ) ;
9792 //for ( int j = ly ; j < hy ; j ++ )
9793 //{
9794 //fprintf( fout, "{" ) ;
9795 //for ( int k = lz ; k < hz ; k ++ )
9796 //{
9797 //fprintf( fout, "%.15f", getDataAt( i, j, k ) ) ;
9798 //if ( k < hz - 1 )
9799 //{
9800 //fprintf( fout, "," ) ;
9801 //}
9802 //}
9803 //fprintf( fout, "}" ) ;
9804 //if ( j < hy - 1 )
9805 //{
9806 //fprintf( fout, "," ) ;
9807 //}
9808 //}
9809 //fprintf( fout, "}" ) ;
9810 //if ( i < hx - 1 )
9811 //{
9812 //fprintf( fout, "," ) ;
9813 //}
9814 //}
9815 //fprintf(fout,"}") ;
9816
9817 //fclose( fout ) ;
9818
9819 //}
9820
9821 //void Volume::toOFFCells( char* fname )
9822 //{
9823 //toOFFCells( fname, 0.0001f ) ;
9824 //}
9825 //void Volume::toOFFCells2( char* fname )
9826 //{
9827 //toOFFCells2( fname, 0.0001f ) ;
9828 //}
9829
9830 //void Volume::toOFFCells2( char* fname, float thr )
9831 //{
9832 //int i, j, k ;
9833 //Volume* indvol = new Volume( getSizeX(), getSizeY(), getSizeZ(), -1 ) ;
9834
9836 //int numverts = 0, numfaces = 0 ;
9837 //for ( i = 0 ; i < getSizeX() ; i ++ )
9838 //for ( j = 0 ; j < getSizeY() ; j ++ )
9839 //for ( k = 0 ; k < getSizeZ() ; k ++ )
9840 //{
9841 //if ( getDataAt( i, j, k ) >= thr )
9842 //{
9843 //indvol->setDataAt( i,j,k, numverts ) ;
9844 //numverts ++ ;
9845
9846 //for ( int mi = 0 ; mi < 3 ; mi ++ )
9847 //{
9848 //int find = mi * 4 + 3 ;
9849 //int isFace = 1 ;
9850 //for ( int mj = 0 ; mj < 4 ; mj ++ )
9851 //{
9852 //int nx = i + sheetNeighbor[find][mj][0] ;
9853 //int ny = j + sheetNeighbor[find][mj][1] ;
9854 //int nz = k + sheetNeighbor[find][mj][2] ;
9855
9856 //if ( getDataAt( nx, ny, nz ) < thr )
9857 //{
9858 //isFace = 0 ;
9859 //break ;
9860 //}
9861 //}
9862 //if ( isFace )
9863 //{
9864 //numfaces ++ ;
9865 //}
9866
9867 //int eind = mi * 2 + 1 ;
9868 //if ( getDataAt( i + neighbor6[eind][0], j + neighbor6[eind][1], k + neighbor6[eind][2]) >= thr )
9869 //{
9870 //numfaces ++ ;
9871 //}
9872 //}
9873 //}
9874 //}
9875
9876 //FILE* fin = fopen( fname, "w" ) ;
9877 //fprintf( fin, "OFF\n" ) ;
9878 //fprintf( fin, "%d %d 0\n", numverts, numfaces ) ;
9879
9881 //for ( i = 0 ; i < getSizeX() ; i ++ )
9882 //for ( j = 0 ; j < getSizeY() ; j ++ )
9883 //for ( k = 0 ; k < getSizeZ() ; k ++ )
9884 //{
9885 //if ( getDataAt( i,j,k ) >= thr )
9886 //{
9887 //fprintf( fin, "%d %d %d\n", i, j, k ) ;
9888 //}
9889 //}
9890
9892 //for ( i = 0 ; i < getSizeX() ; i ++ )
9893 //for ( j = 0 ; j < getSizeY() ; j ++ )
9894 //for ( k = 0 ; k < getSizeZ() ; k ++ )
9895 //{
9896 //if ( getDataAt( i,j,k ) >= thr )
9897 //{
9898 //int thisvt = (int)( indvol->getDataAt( i,j,k ) );
9899 //for ( int mi = 0 ; mi < 3 ; mi ++ )
9900 //{
9901 //int find = mi * 4 + 3 ;
9902 //int isFace = 1 ;
9903 //int vts[4] ;
9904 //for ( int mj = 0 ; mj < 4 ; mj ++ )
9905 //{
9906 //int nx = i + sheetNeighbor[find][mj][0] ;
9907 //int ny = j + sheetNeighbor[find][mj][1] ;
9908 //int nz = k + sheetNeighbor[find][mj][2] ;
9909
9910 //vts[ mj ] = (int)( indvol->getDataAt( nx, ny, nz ) );
9911
9912 //if ( getDataAt( nx, ny, nz ) < thr )
9913 //{
9914 //isFace = 0 ;
9915 //break ;
9916 //}
9917 //}
9918 //if ( isFace )
9919 //{
9920 //fprintf( fin, "4 %d %d %d %d\n", vts[0], vts[1], vts[3], vts[2] ) ;
9921 //}
9922
9923 //int eind = mi * 2 + 1 ;
9924 //int mx = i + neighbor6[eind][0] ;
9925 //int my = j + neighbor6[eind][1] ;
9926 //int mz = k + neighbor6[eind][2] ;
9927 //int vt = (int)( indvol->getDataAt( mx, my, mz ) );
9928 //if ( getDataAt( mx, my, mz ) >= thr )
9929 //{
9930 //fprintf( fin, "4 %d %d %d %d\n", thisvt, thisvt, vt, vt ) ;
9931 //}
9932 //}
9933 //}
9934 //}
9935
9936 //fclose( fin ) ;
9937 //delete indvol ;
9938 //}
9939
9940 //void Volume::toOFFCells( char* fname, float thr )
9941 //{
9942 //int i, j, k ;
9944
9946 //int numverts = 0, numfaces = 0 ;
9947 //for ( i = 0 ; i < getSizeX() ; i ++ )
9948 //for ( j = 0 ; j < getSizeY() ; j ++ )
9949 //for ( k = 0 ; k < getSizeZ() ; k ++ )
9950 //{
9951 //if ( getDataAt( i, j, k ) >= thr )
9952 //{
9953 //numverts += 8 ;
9954 //for ( int mi = 0 ; mi < 6 ; mi ++ )
9955 //{
9956 //if ( getDataAt( i + neighbor6[mi][0], j + neighbor6[mi][1], k + neighbor6[mi][2] ) < thr )
9957 //{
9958 //numfaces ++ ;
9959 //}
9960 //}
9961 //}
9962 //}
9963
9964 //FILE* fin = fopen( fname, "w" ) ;
9965 //fprintf( fin, "OFF\n" ) ;
9966 //fprintf( fin, "%d %d 0\n", numverts, numfaces ) ;
9967
9969 //for ( i = 0 ; i < getSizeX() ; i ++ )
9970 //for ( j = 0 ; j < getSizeY() ; j ++ )
9971 //for ( k = 0 ; k < getSizeZ() ; k ++ )
9972 //{
9973 //if ( getDataAt( i,j,k ) >= thr )
9974 //{
9975 //float ox = i - 0.5f ;
9976 //float oy = j - 0.5f ;
9977 //float oz = k - 0.5f ;
9978
9979 //for ( int mi = 0 ; mi < 2 ; mi ++ )
9980 //for ( int mj = 0 ; mj < 2 ; mj ++ )
9981 //for ( int mk = 0 ; mk < 2 ; mk ++ )
9982 //{
9983 //fprintf( fin, "%f %f %f\n", ox + mi, oy + mj, oz + mk ) ;
9984 //}
9985 //}
9986 //}
9987
9989 //int ct = 0 ;
9990 //for ( i = 0 ; i < getSizeX() ; i ++ )
9991 //for ( j = 0 ; j < getSizeY() ; j ++ )
9992 //for ( k = 0 ; k < getSizeZ() ; k ++ )
9993 //{
9994 //if ( getDataAt( i,j,k ) >= thr )
9995 //{
9996 //for ( int mi = 0 ; mi < 6 ; mi ++ )
9997 //{
9998 //if ( getDataAt( i + neighbor6[mi][0], j + neighbor6[mi][1], k + neighbor6[mi][2] ) < thr )
9999 //{
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 //}
EMData stores an image's data and defines core image processing routines.
Definition: emdata.h:82
Template class for a priority queue.
void remove(ValueT *&v, KeyT &k)
Remove an element.
void add(ValueT *v, KeyT k)
Add an element.
bool isEmpty()
Test whether empty.
void prepend(int xx, int yy, int zz)
Definition: grid_queue2.cpp:55
void SetOrigin(float originX, float originY, float originZ)
void SetSpacing(float spacingX, float spacingY, float spacingZ)
void Pad(int padBy, double padValue)
void SetDataAt(int x, int y, int z, float value)
float GetDataAt(int x, int y, int z)
int GetIndex(int x, int y, int z)
void skeleton(float thr, int off)
Definition: volume.cpp:5089
int components6(int vox[3][3][3])
Definition: volume.cpp:2698
int isHelixEnd(int ox, int oy, int oz, Volume *nvol)
Definition: volume.cpp:1579
void setOrigin(float orgX, float orgY, float orgZ)
Definition: volume.cpp:77
int isSimple(int ox, int oy, int oz)
Definition: volume.cpp:2316
int countInt(double vox[3][3][3])
Definition: volume.cpp:2859
int getIndex(int x, int y, int z)
Definition: volume.cpp:48
int hasCell(int ox, int oy, int oz)
Definition: volume.cpp:1016
int countIntEuler(int ox, int oy, int oz)
Definition: volume.cpp:2895
int isPiercable(int ox, int oy, int oz)
Definition: volume.cpp:2381
void pad(int padBy, double padValue)
Definition: volume.cpp:273
int isSheetEnd(int ox, int oy, int oz, Volume *nvol)
Definition: volume.cpp:1821
int getNumPotComplex(int ox, int oy, int oz)
Definition: volume.cpp:2548
int hasCompleteHelix(int ox, int oy, int oz)
Definition: volume.cpp:1456
void curveSkeleton(Volume *grayvol, float lowthr, float highthr, Volume *svol)
insert them back into priority queue
Definition: volume.cpp:3812
int components26(int vox[3][3][3])
Definition: volume.cpp:2767
void surfaceSkeletonPres(float thr, Volume *preserve)
for ( int m = 0 ; m < 6 ; m ++ )
Definition: volume.cpp:8672
int countExt(double vox[3][3][3])
Definition: volume.cpp:2838
int getNumPotComplex2(int ox, int oy, int oz)
Definition: volume.cpp:2615
int hasCompleteSheet(int ox, int oy, int oz, Volume *fvol)
Definition: volume.cpp:1174
int isFeatureFace(int ox, int oy, int oz)
Definition: volume.cpp:2135
void curveSkeleton2D(float thr, Volume *svol)
Definition: volume.cpp:4678
void threshold(double thr)
Definition: volume.cpp:9515
double getDataAt(int x, int y, int z)
Definition: volume.cpp:60
void setSpacing(float spx, float spy, float spz)
Definition: volume.cpp:73
int getNumNeighbor6(int ox, int oy, int oz)
Definition: volume.cpp:661
void setDataAt(int x, int y, int z, double d)
Definition: volume.cpp:52
VolumeData * getVolumeData()
Definition: volume.cpp:69
const int neighbor64[6][4][3]
Definition: volume.h:29
const int neighbor6[6][3]
Definition: volume.h:27
const int edgeFaces[6][4]
Definition: volume.h:63
const int faceCells[12][2]
Definition: volume.h:54
const int sheetNeighbor[12][4][3]
Definition: volume.h:37
const int faceEdges[12][2]
Definition: volume.h:59
const int neighbor4[4][2]
Definition: volume.h:28
#define y(i, j)
Definition: projector.cpp:1516
#define x(i)
Definition: projector.cpp:1517
#define MAX_ERODE
Definition: volume.h:20
#define MAX_QUEUELEN
Definition: volume.h:19