#include "StdAfx.h" #include "close_filter.h" //returns number of fiber neighs char count_neighs6(DS_1b_cube * cube, unsigned short int z, unsigned short int y, unsigned short int x) { //check bounds //if ( (z <= 0) || (z+1 >= cube->wZ) || (y <= 0) || (y+1 >= cube->wY) || (x <= 0) || (x+1 >= cube->wX) ) // return -1; unsigned char cnt = 0; //check z bounds if (z > 0) if (cube->get_spot(z-1, y, x)) ++cnt; if (z+1 < cube->wZ) if (cube->get_spot(z+1, y, x)) ++cnt; //check y bounds if (y > 0) if (cube->get_spot(z, y-1, x)) ++cnt; if (y+1 < cube->wY) if (cube->get_spot(z, y+1, x)) ++cnt; //check x bounds if (x > 0) if (cube->get_spot(z, y, x-1)) ++cnt; if (x+1 < cube->wX) if (cube->get_spot(z, y, x+1)) ++cnt; return cnt; } void dilate6(DS_1b_cube * cube, unsigned short int z, unsigned short int y, unsigned short int x, unsigned char min_neighs) { if (!cube->get_spot(z, y, x)) { unsigned char bound_cnt = 0; //count how many boundaries we are on (max 3) if (z == (cube->wZ - 1)) ++bound_cnt; else if (z == 0) ++bound_cnt; if (y == (cube->wY - 1)) ++bound_cnt; else if (y == 0) ++bound_cnt; if (x == (cube->wX - 1)) ++bound_cnt; else if (x == 0) ++bound_cnt; switch (bound_cnt) { case 0: //not on a boundary if ( count_neighs6(cube, z, y, x) >= min_neighs ) cube->set_spot_1(z, y, x); break; case 1: //on one boundary if ( count_neighs6(cube, z, y, x) >= ((float)min_neighs/6)*5 ) cube->set_spot_1(z, y, x); break; case 2: //on two boundaries (edge) if ( count_neighs6(cube, z, y, x) >= ((float)min_neighs/6)*4 ) cube->set_spot_1(z, y, x); break; case 3: //on three boundaries (corner) if ( count_neighs6(cube, z, y, x) >= ((float)min_neighs/6)*3 ) cube->set_spot_1(z, y, x); break; default:; //shouldn't happen.. } } } void erode6(DS_1b_cube * cube, unsigned short int z, unsigned short int y, unsigned short int x, unsigned char min_neighs) { if (cube->get_spot(z, y, x)) { unsigned char bound_cnt = 0; //count how many boundaries we are on (max 3) if (z == (cube->wZ - 1)) ++bound_cnt; else if (z == 0) ++bound_cnt; if (y == (cube->wY - 1)) ++bound_cnt; else if (y == 0) ++bound_cnt; if (x == (cube->wX - 1)) ++bound_cnt; else if (x == 0) ++bound_cnt; switch (bound_cnt) { case 0: //not on a boundary if ( 6-count_neighs6(cube, z, y, x) >= min_neighs ) cube->set_spot_0(z, y, x); break; case 1: //on one boundary if ( 5-count_neighs6(cube, z, y, x) >= ((float)min_neighs/6)*5 ) cube->set_spot_0(z, y, x); break; case 2: //on two boundaries (edge) if ( 4-count_neighs6(cube, z, y, x) >= ((float)min_neighs/6)*4 ) cube->set_spot_0(z, y, x); break; case 3: //on three boundaries (corner) if ( 3-count_neighs6(cube, z, y, x) >= ((float)min_neighs/6)*3 ) cube->set_spot_0(z, y, x); break; default:; //shouldn't happen.. } } } char count_neighs26(DS_1b_cube * cube, unsigned short int z, unsigned short int y, unsigned short int x) { unsigned char cnt = 0; for (int i = z-1; i <= z+1; i++) for (int j = y-1; j <= y+1; j++) for (int k = x-1; k <= x+1; k++) { if ( (i != z) || (j !=y ) || (k != x) ) //skip if original voxel { //check bounds if ( (i < 0) || (i >= cube->wZ) || (j < 0) || (j >= cube->wY) || (k < 0) || (k >= cube->wX) ) continue; else if (cube->get_spot((unsigned short)i, (unsigned short)j, (unsigned short)k)) ++cnt; } } return cnt; } void dilate26(DS_1b_cube * cube, unsigned short int z, unsigned short int y, unsigned short int x, unsigned char min_neighs) { if (!cube->get_spot(z, y, x)) {//dilate unsigned char bound_cnt = 0; //count how many boundaries we are on (max 3) if (z == (cube->wZ - 1)) ++bound_cnt; else if (z == 0) ++bound_cnt; if (y == (cube->wY - 1)) ++bound_cnt; else if (y == 0) ++bound_cnt; if (x == (cube->wX - 1)) ++bound_cnt; else if (x == 0) ++bound_cnt; switch (bound_cnt) { case 0: //not on a boundary if ( count_neighs26(cube, z, y, x) >= min_neighs ) cube->set_spot_1(z, y, x); break; case 1: //on one boundary if ( count_neighs26(cube, z, y, x) >= ((float)min_neighs/26)*17 ) cube->set_spot_1(z, y, x); break; case 2: //on two boundaries (edge) if ( count_neighs26(cube, z, y, x) >= ((float)min_neighs/26)*11 ) cube->set_spot_1(z, y, x); break; case 3: //on three boundaries (corner) if ( count_neighs26(cube, z, y, x) >= ((float)min_neighs/26)*7 ) cube->set_spot_1(z, y, x); break; default:; //shouldn't happen.. } } } void erode26(DS_1b_cube * cube, unsigned short int z, unsigned short int y, unsigned short int x, unsigned char min_neighs) { if (cube->get_spot(z, y, x)) {//dilate unsigned char bound_cnt = 0; //count how many boundaries we are on (max 3) if (z == (cube->wZ - 1)) ++bound_cnt; else if (z == 0) ++bound_cnt; if (y == (cube->wY - 1)) ++bound_cnt; else if (y == 0) ++bound_cnt; if (x == (cube->wX - 1)) ++bound_cnt; else if (x == 0) ++bound_cnt; switch (bound_cnt) { case 0: //not on a boundary if ( 26-count_neighs26(cube, z, y, x) >= min_neighs ) cube->set_spot_0(z, y, x); break; case 1: //on one boundary if ( 17-count_neighs26(cube, z, y, x) >= ((float)min_neighs/26)*17 ) cube->set_spot_0(z, y, x); break; case 2: //on two boundaries (edge) if ( 11-count_neighs26(cube, z, y, x) >= ((float)min_neighs/26)*11 ) cube->set_spot_0(z, y, x); break; case 3: //on three boundaries (corner) if ( 7-count_neighs26(cube, z, y, x) >= ((float)min_neighs/26)*7 ) cube->set_spot_0(z, y, x); break; default:; //shouldn't happen.. } } } short int close_filter(DS_1b_cube * cube, short neighs, bool ext, short iters, void * dlg) { unsigned short int x, y, z; char win_txt[100]; PoroMediaDialogShare* ShareDlg = (PoroMediaDialogShare*) dlg; ////progress control ShareDlg->pbar_simulation_progress.SetPos(0); ShareDlg->pbar_simulation_progress.SetStep(1); ShareDlg->pbar_simulation_progress.SetRange(0, 2*(cube->wZ)*iters); unsigned char min_neighs = (unsigned char)neighs; if (ext) { int i; //for pores for (i = 0; i < iters; i++) { sprintf(win_txt, "Close pore filter (%d/%d iterations)...", i, iters); ShareDlg->txt_field_progress.SetWindowText(win_txt); for (z = 0; z < cube->wZ; z++) { for (y = 0; y < cube->wY; y++) for (x = 0; x < cube->wX; x++) dilate26(cube, z, y, x, min_neighs); ShareDlg->pbar_simulation_progress.StepIt(); } } //for fibers for (i = 0; i < iters; i++) { sprintf(win_txt, "Close fiber filter (%d/%d iterations)...", i, iters); ShareDlg->txt_field_progress.SetWindowText(win_txt); for (z = 0; z < (cube->wZ); z++) { for (y = 0; y < (cube->wY); y++) for (x = 0; x < (cube->wX); x++) erode26(cube, z, y, x, min_neighs); ShareDlg->pbar_simulation_progress.StepIt(); } } } else { //for pores for (int i = 0; i < iters; i++) { sprintf(win_txt, "Close pore filter (%d/%d iterations)...", i, iters); ShareDlg->txt_field_progress.SetWindowText(win_txt); for (z = 0; z < (cube->wZ); z++) { for (y = 0; y < (cube->wY); y++) for (x = 0; x < (cube->wX); x++) dilate6(cube, z, y, x, min_neighs); ShareDlg->pbar_simulation_progress.StepIt(); } } //for fibers for (int i = 0; i < iters; i++) { sprintf(win_txt, "Close fiber filter (%d/%d iterations)...", i, iters); ShareDlg->txt_field_progress.SetWindowText(win_txt); for (z = 0; z < (cube->wZ); z++) { for (y = 0; y < (cube->wY); y++) for (x = 0; x < (cube->wX); x++) erode6(cube, z, y, x, min_neighs); ShareDlg->pbar_simulation_progress.StepIt(); } } } return 0; }