void write_rawiv_float(float *result,FILE* fp) { int i, j, k; float c_float; size_t fwrite_return; //#ifdef _LITTLE_ENDIAN if(!big_endian()) { swap_buffer((char *)minext, 3, sizeof(float)); swap_buffer((char *)maxext, 3, sizeof(float)); swap_buffer((char *)&nverts, 1, sizeof(int)); swap_buffer((char *)&ncells, 1, sizeof(int)); swap_buffer((char *)dim, 3, sizeof(unsigned int)); swap_buffer((char *)orig, 3, sizeof(float)); swap_buffer((char *)span, 3, sizeof(float)); } //#endif fwrite_return = fwrite(minext, sizeof(float), 3, fp); fwrite_return = fwrite(maxext, sizeof(float), 3, fp); fwrite_return = fwrite(&nverts, sizeof(int), 1, fp); fwrite_return = fwrite(&ncells, sizeof(int), 1, fp); fwrite_return = fwrite(dim, sizeof(unsigned int), 3, fp); fwrite_return = fwrite(orig, sizeof(float), 3, fp); fwrite_return = fwrite(span, sizeof(float), 3, fp); //#ifdef _LITTLE_ENDIAN if(!big_endian()) { swap_buffer((char *)minext, 3, sizeof(float)); swap_buffer((char *)maxext, 3, sizeof(float)); swap_buffer((char *)&nverts, 1, sizeof(int)); swap_buffer((char *)&ncells, 1, sizeof(int)); swap_buffer((char *)dim, 3, sizeof(unsigned int)); swap_buffer((char *)orig, 3, sizeof(float)); swap_buffer((char *)span, 3, sizeof(float)); } //#endif for (k=0; k<ZDIM; k++) for (j=0; j<YDIM; j++) for (i=0; i<XDIM; i++) { c_float = result[IndexVect(i,j,k)]; //#ifdef _LITTLE_ENDIAN if(!big_endian()) swap_buffer((char *)&c_float, 1, sizeof(float)); //#endif fwrite_return = fwrite(&c_float, sizeof(float), 1, fp); //#ifdef _LITTLE_ENDIAN if(!big_endian()) swap_buffer((char *)&c_float, 1, sizeof(float)); //#endif } fclose(fp); }
/*-Jesse-*************************************************************** This funtion simply inserts the voxel (x,y,z) into the appropriate place in our binary tree. The tree is sorted such that the time data for each parent is less than the time data for its children.*/ void InsertHeap(int x, int y, int z) { int pointer, parent; float t; t = tdata[IndexVect(x,y,z)]; min_heap->size++; pointer=min_heap->size; while (pointer > 1) { /*-Jesse-**************************************************** If time data for the new voxel is less than the time data for the current parent, then move the parent down to the child position and set pointer to index the empty slot for the previous parent*/ if (pointer%2 == 0) { parent=pointer/2; if (t < min_heap->t[parent-1]) { min_heap->x[pointer-1]=min_heap->x[parent-1]; min_heap->y[pointer-1]=min_heap->y[parent-1]; min_heap->z[pointer-1]=min_heap->z[parent-1]; min_heap->t[pointer-1]=min_heap->t[parent-1]; pointer=parent; } else break; } else if (pointer%2 == 1){ parent=(pointer-1)/2; if (t < min_heap->t[parent-1]) { min_heap->x[pointer-1]=min_heap->x[parent-1]; min_heap->y[pointer-1]=min_heap->y[parent-1]; min_heap->z[pointer-1]=min_heap->z[parent-1]; min_heap->t[pointer-1]=min_heap->t[parent-1]; pointer=parent; } else break; } } /*-Jesse-************************************************** Insert the new point into the empty slot left behind by the previous parent.*/ min_heap->x[pointer-1]=x; min_heap->y[pointer-1]=y; min_heap->z[pointer-1]=z; min_heap->t[pointer-1]=t; }
void load_lattice_file(char* input_name, unsigned int& xdim, unsigned int& ydim, unsigned int& zdim, float*& data, double*& dim_mat, bool padd, float padd_value) { FILE* fptr; unsigned int file_size, i, j, k, read_version, write_version, smsize, dim; unsigned int data_type, compression_type, elem_size, dsize; size_t read_size, uint_size, double_size; unsigned char* buffer; unsigned char* cptr; char* header; // Open file if ((fptr=fopen(input_name, "rb"))==NULL) {fputs("File error\n", stderr); exit(ENOENT);} // Obtain file size: fseek (fptr, 0, SEEK_END); file_size = ftell(fptr); rewind (fptr); // Allocate memory to contain the whole file: buffer = (unsigned char*) malloc (sizeof(unsigned char)*file_size); if (buffer == NULL) {fputs("Memory error\n", stderr); exit(ENOMEM);} // Copy the file into the buffer and close file read_size = fread(buffer, 1, file_size, fptr); if (read_size != file_size) {fputs("Reading error\n", stderr); exit(EIO);} fclose(fptr); printf("File size: %d\n", file_size); header = (char*)buffer; // Check header if (strncmp(header, "LATTICE*IBT*KA", 14)){ fputs("Not a Lattice file\n", stderr); exit(EIO); }; // Get the char pointer to the first data cptr = &buffer[14]; // Read 'read_version' read_version = get_uint(cptr); printf("read version: %d\n", read_version); // Read 'write_version' write_version = get_uint(cptr); printf("write version: %d\n", write_version); // Read 'smsize' smsize = get_uint(cptr); printf("smsize: %d\n", smsize); // Read 'xdim' xdim = get_uint(cptr); printf("xdim: %d\n", xdim); // Read 'ydim' ydim = get_uint(cptr); printf("ydim: %d\n", ydim); // Read 'zdim' zdim = get_uint(cptr); printf("zdim: %d\n", zdim); // Read 'dim' dim = get_uint(cptr); printf("dim: %d\n", dim); // Read 'dim mat' dim_mat = (double*) malloc (sizeof(double)*4*dim); printf("Dimension matrix"); for (i = 0; i < dim; i++){ printf("\n"); for (j = 0; j < 4; j++){ dim_mat[i*4 + j] = get_double(cptr); printf("%f, ", dim_mat[i*4 + j]); } } printf("\n"); // Read 'data_type' data_type = get_uint(cptr); printf("data_type: %d\n", data_type); // Read 'compression_type' compression_type = get_uint(cptr); printf("compression_type: %d\n", compression_type); if (compression_type){fputs("Compression type not supported\n", stderr); exit(EIO);} // Read 'elem_size' elem_size = get_uint(cptr); printf("elem_size: %d\n", elem_size); // Skip alignment cptr += 88; // Read 'dsize' dsize = get_uint(cptr); printf("dsize: %d\n", dsize); // If padd create a padding around the data of size 1 if (padd) { xdim+=2; ydim+=2; zdim+=2; } // Allocate memory data = (float*) malloc(sizeof(float)*xdim*ydim*zdim); // Read in data dependent on the data type switch (data_type) { case 0: if (padd) { // Initialize all data points with padd value for (i = 0; i < xdim*ydim*zdim; i++) data[i] = padd_value; for (k = 1; k < zdim-1; k++) for (j = 1; j < ydim-1; j++) for (i = 1; i < xdim-1; i++) data[IndexVect(i,j,k)] = (*cptr++ == 255) ? 0.0 : 1.0; } else for (k = 0; k < zdim; k++) for (j = 0; j < ydim; j++) for (i = 0; i < xdim; i++) data[IndexVect(i,j,k)] = (*cptr++ == 255) ? 0.0 : 1.0; break; case 4: if (padd) { // Initialize all data points with padd value for (i = 0; i < xdim*ydim*zdim; i++) data[i] = padd_value; // Fill inside of cell with data for (k = 1; k < zdim-1; k++) for (j = 1; j < ydim-1; j++) for (i = 1; i < xdim-1; i++) data[IndexVect(i,j,k)] = get_float(cptr); } else for (k = 0; k < zdim; k++) for (j = 0; j < ydim; j++) for (i = 0; i < xdim; i++) data[IndexVect(i,j,k)] = get_float(cptr); break; default: fputs("Data type not supported\n", stderr); exit(EIO); } // Release memory free(buffer); }
/*-Jesse-********************************************************************** This function iterates through every voxel adjacent to minVoxel, we'll refer to these voxels as adjacentVoxel. For each adjacentVoxel, we compute its marching time and then call set_index_and_time(adjacentVoxel, index of minVoxel, marchingTime). To compute marchingTime, we first compute the maximum density gradient at the adjacentVoxel. Then for each voxel adjacent to adjacentVoxel we compute Time = [exp(0.1*gradient) + timedata for the voxel adjacent to adjecentVoxel] and set marchingTime to be the minimum of all the Time values. Note that if the timedata for the voxel adjacent to the adjacentVoxel has not previously been set by any call to set_index_and_time(), then the timedata will be the original default value, which is MAX_TIME.*/ void GetTime(void) { int temp_x, temp_y, temp_z; float intens, time; char boundary; //boolean flag variable unsigned char index; index = seed_index[IndexVect(min_x,min_y,min_z)]; temp_x=max(min_x-1,0); temp_y=min_y; temp_z=min_z; /*-Jesse-********************************************************** If seed_index has not been previously set by set_index_and_time()*/ if (seed_index[IndexVect(temp_x,temp_y,temp_z)] >= 254) { boundary = 0; time = (float)(MAX_TIME+1.0); /*-Jesse-******************************************************** intens = EXP[0.1 * maximum density gradient at (temp_x,temp_y,temp_z)]*/ intens = GetImgGradient(temp_x, temp_y, temp_z); intens = (float)(exp(ALPHA*intens)); //currently ALPHA set to 0.1f /*-Jesse-************************************************ We now calculate the time for voxel (min_x-1,min_y,min_z). If (min_x-1,min_y,min_z) is next to a voxel that is below tlow or if it is next to a voxel whose index has been set to a value other than the index of (min_x,min_y,min_z), then we set the time to MAX_TIME. Otherwise we compute for each voxel next to (min_x-1,min_y,min_z), [intens + timedata for voxel next to (min_x-1, min_y,min_z)] and take the minimum of all these values as the time for (min_x-1, min_y, min_z). Then we call set_index_and_time() to set the index and time of (min_x-1, min_y, min_z).*/ modifyTime(max(temp_x-1,0), temp_y, temp_z); if(boundary == 0){ modifyTime(min(temp_x+1,XDIM-1), temp_y, temp_z); if(boundary == 0){ modifyTime(temp_x, max(temp_y-1,0), temp_z); if(boundary == 0){ modifyTime(temp_x, min(temp_y+1,YDIM-1), temp_z); if(boundary == 0){ modifyTime(temp_x, temp_y, max(temp_z-1,0)); if(boundary == 0){ modifyTime(temp_x, temp_y, min(temp_z+1,ZDIM-1)); } } } } } if (boundary == 1){ time=(float)(MAX_TIME+1.0); } set_index_and_time(temp_x,temp_y,temp_z,index,time); } /*-Jesse-*********************************************************** same as above except we calculate the time for (min_x+1,min_y,min_z) instead of (min_x-1,min_y,min_z).*/ temp_x=min(min_x+1,XDIM-1); temp_y=min_y; temp_z=min_z; if (seed_index[IndexVect(temp_x,temp_y,temp_z)] >= 254) { boundary = 0; time = (float)(MAX_TIME+1.0); intens = GetImgGradient(temp_x, temp_y, temp_z); intens = (float)(exp(ALPHA*intens)); modifyTime(max(temp_x-1,0), temp_y, temp_z) if(boundary == 0){ modifyTime(min(temp_x+1,XDIM-1), temp_y, temp_z); if(boundary == 0){ modifyTime(temp_x, max(temp_y-1,0), temp_z); if(boundary == 0){ modifyTime(temp_x, min(temp_y+1,YDIM-1), temp_z); if(boundary == 0){ modifyTime(temp_x, temp_y, max(temp_z-1,0)); if(boundary == 0){ modifyTime(temp_x, temp_y, min(temp_z+1,ZDIM-1)); } } } } } if (boundary == 1){ time=(float)(MAX_TIME+1.0); } set_index_and_time(temp_x,temp_y,temp_z,index,time); }
/*-Jesse-************************************************************************** set_index_and_time() takes the voxel passed to it, (ax,ay,az), and if its seedIndex has not previously been set then we set its seedIndex and tdata to the corresponding values passed to the function and insert the point into the heap. We then take advantage of the capsid's icosahedron properties and compute the other 59 symmetrical points. For each of these points if its seedIndex has not been set then we set its seedIndex and tdata to the corresponding values passed to the function, and insert into the heap.*/ void set_index_and_time(int ax, int ay,int az, unsigned char index, float t) { int i,j,k; int m,n; double cx,cy,cz; double mx,my,mz; double sx,sy,sz; double theta,phi; VECTOR sv; /*-Jesse-*************************************************************** (cx,cy,cz) is set to be a point on the first symmetry axis in FiveFold[]. We whift the point so that the axis goes through the origin.*/ cx = FiveFold[0].x-XDIM/2; cy = FiveFold[0].y-YDIM/2; cz = FiveFold[0].z-ZDIM/2; i = ax; j = ay; k = az; /*-Jesse-******************************************************************* If the seed_index has not previously been set, then set seed_index and tdata to the appropriate values passed to the algorithm. Then insert into the heap.*/ if (seed_index[IndexVect(i,j,k)] == 255) { seed_index[IndexVect(i,j,k)] = index; tdata[IndexVect(i,j,k)] = t; InsertHeap(i,j,k); } /*-Jesse-*********************************************************************** theta and phi are the spherical angles corresponding (cx,cy,cz) being treated as a voxel instead of an axis of rotation.*/ theta = atan2(cy,cx); phi = atan2(cz, sqrt(cx*cx+cy*cy)); /*-Jesse-********************************************************************** (i,j,k) is set to be the initial point passed to the function rotated about the 5-fold axis stored in (cx,cy,cz).*/ for (n = 1; n < 5; n++) { sv = Rotate((float)ax,(float)ay,(float)az,theta,phi,n*2.0f*PIE/5.0f, XDIM, YDIM, ZDIM); i = (int)(sv.x+0.5); j = (int)(sv.y+0.5); k = (int)(sv.z+0.5); /*-Jesse-********************************************************************** It is possible for the rotation to return a point outside our data set. If the rotation gives us a valid point and if the seed_index has not been previously set then we set seed_index, tdata, and insert into the heap.*/ if(i >= 0 && i < XDIM && j >= 0 && j < YDIM && k >= 0 && k < ZDIM && dataset[IndexVect(i,j,k)] > 0) { if (seed_index[IndexVect(i,j,k)] == 255) { seed_index[IndexVect(i,j,k)] = index; tdata[IndexVect(i,j,k)] = t; InsertHeap(i,j,k); } } } /*-Jesse-************************************************************************* We now make use of the icosahedral symmetry to find the 59 points symmetric to the point passed to set_index_and_time(). We have already found 4 of these points by rotating about (cx,cy,cz) above. We now wish to translate our point to the other axes of rotation and then rotate about each axis. In detail, suppose we have a voxel V1 that we have just rotated about axis A1 and we now wish to rotate about another axis A2. We first find the cross product of A1XA2 and the angle between A1 and A2. We rotate the voxel V1 about A1XA2 by the angle and we get a corresponding voxel V2 in relation to A2. We can then rotate V2 about A2. We then test if the resulting voxels are above tlow, if they are then we set their densities to be negative.*/ for (m = 1; m < 11; m++) { /*-Jesse-*************************************************** (mx,my,mz) is the m'th 5-fold axis centered at the origin.*/ mx = FiveFold[m].x-XDIM/2; my = FiveFold[m].y-YDIM/2; mz = FiveFold[m].z-ZDIM/2; /*-Jesse-*************************** (sx,sy,sz) = (cx,cy,cz)X(mx,my,mz)*/ sx = mz*cy-my*cz; sy = mx*cz-mz*cx; sz = my*cx-mx*cy; theta = atan2(sy,sx); phi = atan2(sz,sqrt(sx*sx+sy*sy)); if (m < 6) sv = Rotate((float)ax,(float)ay,(float)az,theta,phi,ANGL1,XDIM,YDIM,ZDIM); else sv = Rotate((float)ax,(float)ay,(float)az,theta,phi,ANGL2,XDIM,YDIM,ZDIM); /*-Jesse-************************************************************** (sx,sy,sz) = (ax,ay,az) rotated about (cx,cy,cz)X(mx,my,mz) by angle.*/ sx = sv.x; sy = sv.y; sz = sv.z; theta = atan2(my,mx); phi = atan2(mz, sqrt(mx*mx+my*my)); for (n = 0; n < 5; n++) { sv = Rotate(sx,sy,sz,theta,phi,n*2.0f*PIE/5.0f+PIE/5.0f,XDIM,YDIM,ZDIM); /*-Jesse-***************************************************************** (i,j,k) = (ax,ay,az) rotated about (cx,xy,xz)X(mx,my,mz) by angle and then rotated about (mx,my,mz)*/ i = (int)(sv.x+0.5); j = (int)(sv.y+0.5); k = (int)(sv.z+0.5); if(i >= 0 && i < XDIM && j >= 0 && j < YDIM && k >= 0 && k < ZDIM && dataset[IndexVect(i,j,k)] > 0) { if (seed_index[IndexVect(i,j,k)] == 255) { seed_index[IndexVect(i,j,k)] = index; tdata[IndexVect(i,j,k)] = t; InsertHeap(i,j,k); } } } } /*-Jesse-************************ (mx,my,mz) = second 5-fold axis*/ mx = FiveFold[1].x-XDIM/2; my = FiveFold[1].y-YDIM/2; mz = FiveFold[1].z-ZDIM/2; /*-Jesse-*************************** (sx,sy,sz) = (cx,cy,cz)X(mx,my,mz)*/ sx = mz*cy-my*cz; sy = mx*cz-mz*cx; sz = my*cx-mx*cy; theta = atan2(sy,sx); phi = atan2(sz,sqrt(sx*sx+sy*sy)); sv = Rotate((float)ax,(float)ay,(float)az,theta,phi,PIE,XDIM,YDIM,ZDIM); sx = sv.x; sy = sv.y; sz = sv.z; /*-Jesse-**************************************************************** (i,j,k) = (ax,ay,az) rotated about (cx,cy,cz)X(mx,my,mz) by 180 degrees*/ i = (int)(sx+0.5); j = (int)(sy+0.5); k = (int)(sz+0.5); if(i >= 0 && i < XDIM && j >= 0 && j < YDIM && k >= 0 && k < ZDIM && dataset[IndexVect(i,j,k)] > 0) { if (seed_index[IndexVect(i,j,k)] == 255) { seed_index[IndexVect(i,j,k)] = index; tdata[IndexVect(i,j,k)] = t; InsertHeap(i,j,k); } } /*-Jesse-********************** (mx,my,mz) = last 5-fold axis*/ mx = FiveFold[11].x-XDIM/2; my = FiveFold[11].y-YDIM/2; mz = FiveFold[11].z-ZDIM/2; theta = atan2(my,mx); phi = atan2(mz, sqrt(mx*mx+my*my)); for (n = 1; n < 5; n++) { sv = Rotate(sx,sy,sz,theta,phi,n*2.0f*PIE/5.0f,XDIM,YDIM,ZDIM); /*-Jesse-********************************************************************************** (i,j,k) = (cx,cy,cz)X[(cx,cy,cz)X(second 5-fold axis)] rotated about the last 5-fold axis*/ i = (int)(sv.x+0.5); j = (int)(sv.y+0.5); k = (int)(sv.z+0.5); if(i >= 0 && i < XDIM && j >= 0 && j < YDIM && k >= 0 && k < ZDIM && dataset[IndexVect(i,j,k)] > 0) { if (seed_index[IndexVect(i,j,k)] == 255) { seed_index[IndexVect(i,j,k)] = index; tdata[IndexVect(i,j,k)] = t; InsertHeap(i,j,k); } } } }
void write_rawv(int XDIM, int YDIM, int ZDIM, float *dataset, unsigned char *result, FILE* fp, FILE* fp2) { int i, j, k; unsigned char c; // float c_float; unsigned char c_unchar; unsigned int MagicNumW=0xBAADBEEF; unsigned int NumTimeStep, NumVariable; float MinXYZT[4], MaxXYZT[4]; unsigned char VariableType[100]; char *VariableName[100]; int m; NumTimeStep = 1; NumVariable = 4; MinXYZT[0]=0; MinXYZT[1]=0; MinXYZT[2]=0; MinXYZT[3]=0; MaxXYZT[0]=XDIM-1.f; MaxXYZT[1]=YDIM-1.f; MaxXYZT[2]=ZDIM-1.f; MaxXYZT[3]=1; VariableType[0] = 1; VariableName[0] = (char*)malloc(sizeof(char)*64); strcpy (VariableName[0], "red\n"); VariableType[1] = 1; VariableName[1] = (char*)malloc(sizeof(char)*64); strcpy (VariableName[1], "green"); VariableType[2] = 1; VariableName[2] = (char*)malloc(sizeof(char)*64); strcpy (VariableName[2], "blue"); VariableType[3] = 1; VariableName[3] = (char*)malloc(sizeof(char)*64); strcpy (VariableName[3], "alpha"); fwrite(&MagicNumW, sizeof(unsigned int), 1, fp2); fwrite(&XDIM, sizeof(unsigned int), 1, fp2); fwrite(&YDIM, sizeof(unsigned int), 1, fp2); fwrite(&ZDIM, sizeof(unsigned int), 1, fp2); fwrite(&NumTimeStep, sizeof(unsigned int), 1, fp2); fwrite(&NumVariable, sizeof(unsigned int), 1, fp2); fwrite(MinXYZT, sizeof(float), 4, fp2); fwrite(MaxXYZT, sizeof(float), 4, fp2); for (m=0; m<(int)NumVariable; m++) { fwrite(&VariableType[m], sizeof(unsigned char), 1, fp2); fwrite(&VariableName[m], sizeof(unsigned char), 64, fp2); } for (k=0; k<ZDIM; k++) for (j=0; j<YDIM; j++) for (i=0; i<XDIM; i++) { c = result[IndexVect(i,j,k)]; if (c == 1) { c_unchar = 255/*dataset[IndexVect(i,j,k)]/255.0*/; fwrite(&c_unchar, sizeof(u_char), 1, fp2); } else if (c == 2) { c_unchar = 0; fwrite(&c_unchar, sizeof(u_char), 1, fp2); } else { c_unchar = 0; fwrite(&c_unchar, sizeof(u_char), 1, fp2); } } for (k=0; k<ZDIM; k++) for (j=0; j<YDIM; j++) for (i=0; i<XDIM; i++) { c = result[IndexVect(i,j,k)]; if (c == 1) { c_unchar = 0; fwrite(&c_unchar, sizeof(u_char), 1, fp2); } else if (c == 2) { c_unchar = 255/*dataset[IndexVect(i,j,k)]/255.0*/; fwrite(&c_unchar, sizeof(u_char), 1, fp2); } else { c_unchar = 0; fwrite(&c_unchar, sizeof(u_char), 1, fp2); } } for (k=0; k<ZDIM; k++) for (j=0; j<YDIM; j++) for (i=0; i<XDIM; i++) { c = result[IndexVect(i,j,k)]; if (c == 1) { c_unchar = 0; fwrite(&c_unchar, sizeof(u_char), 1, fp2); } else if (c == 2) { c_unchar = 0; fwrite(&c_unchar, sizeof(u_char), 1, fp2); } else { c_unchar = 0; fwrite(&c_unchar, sizeof(u_char), 1, fp2); } } for (k=0; k<ZDIM; k++) for (j=0; j<YDIM; j++) for (i=0; i<XDIM; i++) { c = result[IndexVect(i,j,k)]; if (c == 1) { c_unchar = 255/*(dataset[IndexVect(i,j,k)]-125)/130.0*/; fwrite(&c_unchar, sizeof(u_char), 1, fp2); } else if (c == 2) { c_unchar = 255/*(dataset[IndexVect(i,j,k)]-125)/130.0*/; fwrite(&c_unchar, sizeof(u_char), 1, fp2); } else { c_unchar = 0; fwrite(&c_unchar, sizeof(u_char), 1, fp2); } } fclose(fp2); }
void read_data(int *xd, int *yd, int *zd, float **data, const char *input_name) { float c_float; u_char c_unchar; u_short c_unshort; int i,j,k; float *dataset; struct stat filestat; size_t size[3]; int datatype; int found; FILE *fp; if ((fp=fopen(input_name, "r"))==NULL){ printf("read error...\n"); exit(0); } stat(input_name, &filestat); /* reading RAWIV header */ fread(minext, sizeof(float), 3, fp); fread(maxext, sizeof(float), 3, fp); fread(&nverts, sizeof(int), 1, fp); fread(&ncells, sizeof(int), 1, fp); size[0] = 12 * sizeof(float) + 2 * sizeof(int) + 3 * sizeof(u_int) + nverts * sizeof(u_char); size[1] = 12 * sizeof(float) + 2 * sizeof(int) + 3 * sizeof(u_int) + nverts * sizeof(u_short); size[2] = 12 * sizeof(float) + 2 * sizeof(int) + 3 * sizeof(u_int) + nverts * sizeof(float); found = 0; for (i = 0; i < 3; i++) if (size[i] == filestat.st_size) { if (found == 0) { datatype = i; found = 1; } } if (found == 0) { printf("Corrupted file or unsupported dataset type\n"); exit(5); } fread(dim, sizeof(u_int), 3, fp); fread(orig, sizeof(float), 3, fp); fread(span, sizeof(float), 3, fp); XDIM = dim[0]; YDIM = dim[1]; ZDIM = dim[2]; dataset = (float *)malloc(sizeof(float)*XDIM*YDIM*ZDIM); /* reading the data */ maxraw = -99999999; minraw = 99999999; if (datatype == 0) { printf("data type: unsigned char \n"); for (i=0; i<ZDIM; i++) for (j=0; j<YDIM; j++) for (k=0; k<XDIM; k++) { fread(&c_unchar, sizeof(u_char), 1, fp); dataset[IndexVect(k,j,i)]=(float)c_unchar; if (c_unchar > maxraw) maxraw = c_unchar; if (c_unchar < minraw) minraw = c_unchar; } } else if (datatype == 1) { printf("data type: unsigned short \n"); for (i=0; i<ZDIM; i++) for (j=0; j<YDIM; j++) for (k=0; k<XDIM; k++) { fread(&c_unshort, sizeof(u_short), 1, fp); dataset[IndexVect(k,j,i)]=(float)c_unshort; if (c_unshort > maxraw) maxraw = c_unshort; if (c_unshort < minraw) minraw = c_unshort; } } else if (datatype == 2) { printf("data type: float \n"); for (i=0; i<ZDIM; i++) for (j=0; j<YDIM; j++) for (k=0; k<XDIM; k++) { fread(&c_float, sizeof(float), 1, fp); dataset[IndexVect(k,j,i)]=c_float; if (c_float > maxraw) maxraw = c_float; if (c_float < minraw) minraw = c_float; } } else { printf("error\n"); fclose(fp); exit(1); } fclose(fp); for (i=0; i<ZDIM; i++) for (j=0; j<YDIM; j++) for (k=0; k<XDIM; k++) dataset[IndexVect(k,j,i)] = 255*(dataset[IndexVect(k,j,i)] - minraw)/(maxraw-minraw); printf("minimum = %f, maximum = %f \n",minraw,maxraw); *xd = XDIM; *yd = YDIM; *zd = ZDIM; *data = dataset; }
void read_data(int *xd, int *yd, int *zd, float **data, /*float *span_t, float *orig_t,*/ const char *input_name) { float c_float; unsigned char c_unchar; unsigned short c_unshort; int i,j,k; float *dataset; struct stat filestat; size_t size[3]; int datatype = 0; int found; FILE *fp; size_t fread_return=0; if ((fp=fopen(input_name, "rb"))==NULL){ printf("read error...\n"); exit(0); } stat(input_name, &filestat); /* reading RAWIV header */ fread_return = fread(minext, sizeof(float), 3, fp); fread_return = fread(maxext, sizeof(float), 3, fp); fread_return = fread(&nverts, sizeof(int), 1, fp); fread_return = fread(&ncells, sizeof(int), 1, fp); //#ifdef _LITTLE_ENDIAN if(!big_endian()) { swap_buffer((char *)minext, 3, sizeof(float)); swap_buffer((char *)maxext, 3, sizeof(float)); swap_buffer((char *)&nverts, 1, sizeof(int)); swap_buffer((char *)&ncells, 1, sizeof(int)); } //#endif size[0] = 12 * sizeof(float) + 2 * sizeof(int) + 3 * sizeof(unsigned int) + nverts * sizeof(unsigned char); size[1] = 12 * sizeof(float) + 2 * sizeof(int) + 3 * sizeof(unsigned int) + nverts * sizeof(unsigned short); size[2] = 12 * sizeof(float) + 2 * sizeof(int) + 3 * sizeof(unsigned int) + nverts * sizeof(float); found = 0; for (i = 0; i < 3; i++) if (size[i] == (unsigned int)filestat.st_size) { if (found == 0) { datatype = i; found = 1; } } if (found == 0) { printf("Corrupted file or unsupported dataset type\n"); exit(5); } fread_return = fread(dim, sizeof(unsigned int), 3, fp); fread_return = fread(orig, sizeof(float), 3, fp); fread_return = fread(span, sizeof(float), 3, fp); //#ifdef _LITTLE_ENDIAN if(!big_endian()) { swap_buffer((char *)dim, 3, sizeof(unsigned int)); swap_buffer((char *)orig, 3, sizeof(float)); swap_buffer((char *)span, 3, sizeof(float)); } //#endif /* span_t[0] = span[0]; span_t[1] = span[1]; span_t[2] = span[2]; orig_t[0] = orig[0]; orig_t[1] = orig[1]; orig_t[2] = orig[2]; */ XDIM = dim[0]; YDIM = dim[1]; ZDIM = dim[2]; dataset = (float *)malloc(sizeof(float)*XDIM*YDIM*ZDIM); maxraw = -99999999.f; minraw = 99999999.f; if (datatype == 0) { printf("data type: unsigned char \n"); for (i=0; i<ZDIM; i++) for (j=0; j<YDIM; j++) for (k=0; k<XDIM; k++) { fread_return = fread(&c_unchar, sizeof(unsigned char), 1, fp); dataset[IndexVect(k,j,i)]=(float)c_unchar; if (c_unchar > maxraw) maxraw = c_unchar; if (c_unchar < minraw) minraw = c_unchar; } } else if (datatype == 1) { printf("data type: unsigned short \n"); for (i=0; i<ZDIM; i++) for (j=0; j<YDIM; j++) for (k=0; k<XDIM; k++) { fread_return = fread(&c_unshort, sizeof(unsigned short), 1, fp); //#ifdef _LITTLE_ENDIAN if(!big_endian()) swap_buffer((char *)&c_unshort, 1, sizeof(unsigned short)); //#endif dataset[IndexVect(k,j,i)]=(float)c_unshort; if (c_unshort > maxraw) maxraw = c_unshort; if (c_unshort < minraw) minraw = c_unshort; } } else if (datatype == 2) { printf("data type: float \n"); for (i=0; i<ZDIM; i++) for (j=0; j<YDIM; j++) for (k=0; k<XDIM; k++) { fread_return = fread(&c_float, sizeof(float), 1, fp); //#ifdef _LITTLE_ENDIAN if(!big_endian()) swap_buffer((char *)&c_float, 1, sizeof(float)); //#endif dataset[IndexVect(k,j,i)]=c_float; if (c_float > maxraw) maxraw = c_float; if (c_float < minraw) minraw = c_float; } } else { printf("error\n"); fclose(fp); exit(1); } fclose(fp); for (i=0; i<ZDIM; i++) for (j=0; j<YDIM; j++) for (k=0; k<XDIM; k++) dataset[IndexVect(k,j,i)] = 255*(dataset[IndexVect(k,j,i)] - minraw)/(maxraw-minraw); printf("minimum = %f, maximum = %f \n",minraw,maxraw); *xd = XDIM; *yd = YDIM; *zd = ZDIM; *data = dataset; loadedVolumeInfo.read(input_name); }
SurfaceMesh* SurfaceMesh_marchingCube(int xdim, int ydim, int zdim, float* dataset, float isovalue, float* intensity, float intensity_isovalue, SPNT **holelist) { int tempt_x, tempt_y, tempt_z; int i,j,k; int m,n,l; int number, ii, stack_size; float den1,den2,ratio; int v_num, t_num; FLTVECT *vertex; INT3VECT *triangle; int cellVerts[12]; unsigned char cellIndex; INT3VECT *mc_edge; unsigned char *mc_sign; SurfaceMesh *surfmesh; SPNT *hole_end, *hole_start; FLTVECT interior_seed; float max_density = -9999.0; bool use_intensity; // Check if we are using intensity values (neede for Lattice Data) use_intensity = intensity != NULL; // Initialize memory vertex = (FLTVECT*)malloc(sizeof(FLTVECT)*xdim*ydim*zdim); triangle = (INT3VECT*)malloc(sizeof(INT3VECT)*xdim*ydim*zdim); v_num = 0; t_num = 0; mc_edge = (INT3VECT*)malloc(sizeof(INT3VECT)*xdim*ydim*zdim); mc_sign = (unsigned char*)malloc(sizeof(unsigned char)*xdim*ydim*zdim); // preprocessing: removing small holes for (k=0; k<zdim; k++) for (j=0; j<ydim; j++) for (i=0; i<xdim; i++) { if (dataset[IndexVect(i,j,k)] > max_density) max_density = dataset[IndexVect(i,j,k)]; mc_sign[IndexVect(i,j,k)] = 0; } triangle[0].a = 0; triangle[0].b = 0; triangle[0].c = 0; mc_sign[0] = 1; stack_size = 1; while (stack_size > 0) { stack_size--; tempt_x = triangle[stack_size].a; tempt_y = triangle[stack_size].b; tempt_z = triangle[stack_size].c; for (k=max(tempt_z-1,0); k<=min(tempt_z+1,zdim-1); k++) for (j=max(tempt_y-1,0); j<=min(tempt_y+1,ydim-1); j++) for (i=max(tempt_x-1,0); i<=min(tempt_x+1,xdim-1); i++) { if (dataset[IndexVect(i,j,k)] < isovalue && mc_sign[IndexVect(i,j,k)] == 0) { mc_sign[IndexVect(i,j,k)] = 1; triangle[stack_size].a = i; triangle[stack_size].b = j; triangle[stack_size].c = k; stack_size++; } } } hole_start = NULL; hole_end = NULL; den1 = 0; for (l=0; l<zdim; l++) for (n=0; n<ydim; n++) for (m=0; m<xdim; m++) { if (dataset[IndexVect(m,n,l)] > den1) { den1 = dataset[IndexVect(m,n,l)]; interior_seed.x = (float)m; interior_seed.y = (float)n; interior_seed.z = (float)l; } if (dataset[IndexVect(m,n,l)] < isovalue && mc_sign[IndexVect(m,n,l)] == 0) { number = 1; triangle[0].a = m; triangle[0].b = n; triangle[0].c = l; mc_sign[0] = 1; stack_size = 1; while (stack_size > 0) { stack_size--; tempt_x = triangle[stack_size].a; tempt_y = triangle[stack_size].b; tempt_z = triangle[stack_size].c; for (k=max(tempt_z-1,0); k<=min(tempt_z+1,zdim-1); k++) for (j=max(tempt_y-1,0); j<=min(tempt_y+1,ydim-1); j++) for (i=max(tempt_x-1,0); i<=min(tempt_x+1,xdim-1); i++) { if (dataset[IndexVect(i,j,k)] < isovalue && mc_sign[IndexVect(i,j,k)] == 0) { mc_sign[IndexVect(i,j,k)] = 1; triangle[stack_size].a = i; triangle[stack_size].b = j; triangle[stack_size].c = k; stack_size++; number++; } } } printf("hole size: %d \n",number); if (number < MIN_VOLUME) { triangle[0].a = m; triangle[0].b = n; triangle[0].c = l; dataset[IndexVect(m,n,l)] = max_density; stack_size = 1; while (stack_size > 0) { stack_size--; tempt_x = triangle[stack_size].a; tempt_y = triangle[stack_size].b; tempt_z = triangle[stack_size].c; for (k=max(tempt_z-1,0); k<=min(tempt_z+1,zdim-1); k++) for (j=max(tempt_y-1,0); j<=min(tempt_y+1,ydim-1); j++) for (i=max(tempt_x-1,0); i<=min(tempt_x+1,xdim-1); i++) { if (dataset[IndexVect(i,j,k)] < isovalue) { dataset[IndexVect(i,j,k)] = max_density; triangle[stack_size].a = i; triangle[stack_size].b = j; triangle[stack_size].c = k; stack_size++; } } } } else { /* could be improved here ?????*/ if (hole_start == NULL) { hole_end = (SPNT*)malloc(sizeof(SPNT)); hole_start = hole_end; } else { hole_end->next = (SPNT*)malloc(sizeof(SPNT)); hole_end = hole_end->next; } hole_end->x = (float)m; hole_end->y = (float)n; hole_end->z = (float)l; } } } if (hole_end != NULL) hole_end->next = NULL; *holelist = hole_start; for (k=0; k<zdim; k++) for (j=0; j<ydim; j++) for (i=0; i<xdim; i++) { if (dataset[IndexVect(i,j,k)] > isovalue-0.0001 && dataset[IndexVect(i,j,k)] < isovalue+0.0001) dataset[IndexVect(i,j,k)] = isovalue+0.0001; mc_edge[IndexVect(i,j,k)].a = -1; mc_edge[IndexVect(i,j,k)].b = -1; mc_edge[IndexVect(i,j,k)].c = -1; if (dataset[IndexVect(i,j,k)] >= isovalue) mc_sign[IndexVect(i,j,k)] = 1; else mc_sign[IndexVect(i,j,k)] = 255; } for (tempt_z=0; tempt_z<zdim-1; tempt_z++) for (tempt_y=0; tempt_y<ydim-1; tempt_y++) for (tempt_x=0; tempt_x<xdim-1; tempt_x++) { for (ii = 0; ii < 12; ii++) cellVerts[ii] = -1; cellIndex = 0; if (mc_sign[IndexVect(tempt_x,tempt_y,tempt_z)] == 255) cellIndex |= 1; if (mc_sign[IndexVect(tempt_x,tempt_y+1,tempt_z)] == 255) cellIndex |= 2; if (mc_sign[IndexVect(tempt_x+1,tempt_y+1,tempt_z)] == 255) cellIndex |= 4; if (mc_sign[IndexVect(tempt_x+1,tempt_y,tempt_z)] == 255) cellIndex |= 8; if (mc_sign[IndexVect(tempt_x,tempt_y,tempt_z+1)] == 255) cellIndex |= 16; if (mc_sign[IndexVect(tempt_x,tempt_y+1,tempt_z+1)] == 255) cellIndex |= 32; if (mc_sign[IndexVect(tempt_x+1,tempt_y+1,tempt_z+1)] == 255) cellIndex |= 64; if (mc_sign[IndexVect(tempt_x+1,tempt_y,tempt_z+1)] == 255) cellIndex |= 128; if (edgeTable[cellIndex] & 1) { if (mc_edge[IndexVect(tempt_x, tempt_y, tempt_z)].b == -1) { if(use_intensity) { den1 = intensity[IndexVect(tempt_x, tempt_y, tempt_z)]; den2 = intensity[IndexVect(tempt_x, tempt_y+1, tempt_z)]; ratio = get_intensity_ratio(den1, den2, intensity_isovalue); } else { den1 = dataset[IndexVect(tempt_x, tempt_y, tempt_z)]; den2 = dataset[IndexVect(tempt_x, tempt_y+1, tempt_z)]; if (den1 != den2) ratio = (isovalue-den1)/(den2-den1); else ratio = 0; } vertex[v_num].x = (float)tempt_x; vertex[v_num].y = (float)tempt_y+ratio; vertex[v_num].z = (float)tempt_z; cellVerts[0] = v_num; mc_edge[IndexVect(tempt_x,tempt_y,tempt_z)].b = v_num; v_num++; } else cellVerts[0] = mc_edge[IndexVect(tempt_x, tempt_y, tempt_z)].b; } if (edgeTable[cellIndex] & 2) { if (mc_edge[IndexVect(tempt_x, tempt_y+1, tempt_z)].a == -1) { if(use_intensity) { den1 = intensity[IndexVect(tempt_x, tempt_y+1, tempt_z)]; den2 = intensity[IndexVect(tempt_x+1, tempt_y+1, tempt_z)]; ratio = get_intensity_ratio(den1, den2, intensity_isovalue); } else { den1 = dataset[IndexVect(tempt_x, tempt_y+1, tempt_z)]; den2 = dataset[IndexVect(tempt_x+1, tempt_y+1, tempt_z)]; if (den1 != den2) ratio = (isovalue-den1)/(den2-den1); else ratio = 0; } vertex[v_num].x = (float)tempt_x+ratio; vertex[v_num].y = (float)tempt_y+1; vertex[v_num].z = (float)tempt_z; cellVerts[1] = v_num; mc_edge[IndexVect(tempt_x, tempt_y+1, tempt_z)].a = v_num; v_num++; } else cellVerts[1] = mc_edge[IndexVect(tempt_x, tempt_y+1, tempt_z)].a; } if (edgeTable[cellIndex] & 4) { if (mc_edge[IndexVect(tempt_x+1,tempt_y,tempt_z)].b == -1) { if(use_intensity) { den1 = intensity[IndexVect(tempt_x+1, tempt_y, tempt_z)]; den2 = intensity[IndexVect(tempt_x+1, tempt_y+1, tempt_z)]; ratio = get_intensity_ratio(den1, den2, intensity_isovalue); } else { den1 = dataset[IndexVect(tempt_x+1, tempt_y, tempt_z)]; den2 = dataset[IndexVect(tempt_x+1, tempt_y+1, tempt_z)]; if (den1 != den2) ratio = (isovalue-den1)/(den2-den1); else ratio = 0; } vertex[v_num].x = (float)tempt_x+1; vertex[v_num].y = (float)tempt_y+ratio; vertex[v_num].z = (float)tempt_z; cellVerts[2] = v_num; mc_edge[IndexVect(tempt_x+1, tempt_y, tempt_z)].b = v_num; v_num++; } else cellVerts[2] = mc_edge[IndexVect(tempt_x+1, tempt_y, tempt_z)].b; } if (edgeTable[cellIndex] & 8) { if (mc_edge[IndexVect(tempt_x, tempt_y, tempt_z)].a == -1) { if(use_intensity) { den1 = intensity[IndexVect(tempt_x, tempt_y, tempt_z)]; den2 = intensity[IndexVect(tempt_x+1, tempt_y, tempt_z)]; ratio = get_intensity_ratio(den1, den2, intensity_isovalue); } else { den1 = dataset[IndexVect(tempt_x, tempt_y, tempt_z)]; den2 = dataset[IndexVect(tempt_x+1, tempt_y, tempt_z)]; if (den1 != den2) ratio = (isovalue-den1)/(den2-den1); else ratio = 0; } vertex[v_num].x = (float)tempt_x+ratio; vertex[v_num].y = (float)tempt_y; vertex[v_num].z = (float)tempt_z; cellVerts[3] = v_num; mc_edge[IndexVect(tempt_x, tempt_y, tempt_z)].a = v_num; v_num++; } else cellVerts[3] = mc_edge[IndexVect(tempt_x, tempt_y, tempt_z)].a; } if (edgeTable[cellIndex] & 16) { if (mc_edge[IndexVect(tempt_x,tempt_y,tempt_z+1)].b == -1) { if(use_intensity) { den1 = intensity[IndexVect(tempt_x, tempt_y, tempt_z+1)]; den2 = intensity[IndexVect(tempt_x, tempt_y+1, tempt_z+1)]; ratio = get_intensity_ratio(den1, den2, intensity_isovalue); } else { den1 = dataset[IndexVect(tempt_x, tempt_y, tempt_z+1)]; den2 = dataset[IndexVect(tempt_x, tempt_y+1, tempt_z+1)]; if (den1 != den2) ratio = (isovalue-den1)/(den2-den1); else ratio = 0; } vertex[v_num].x = (float)tempt_x; vertex[v_num].y = (float)tempt_y+ratio; vertex[v_num].z = (float)tempt_z+1; cellVerts[4] = v_num; mc_edge[IndexVect(tempt_x, tempt_y, tempt_z+1)].b = v_num; v_num++; } else cellVerts[4] = mc_edge[IndexVect(tempt_x, tempt_y, tempt_z+1)].b; } if (edgeTable[cellIndex] & 32) { if (mc_edge[IndexVect(tempt_x,tempt_y+1,tempt_z+1)].a == -1) { if(use_intensity) { den1 = intensity[IndexVect(tempt_x, tempt_y+1, tempt_z+1)]; den2 = intensity[IndexVect(tempt_x+1, tempt_y+1, tempt_z+1)]; ratio = get_intensity_ratio(den1, den2, intensity_isovalue); } else { den1 = dataset[IndexVect(tempt_x, tempt_y+1, tempt_z+1)]; den2 = dataset[IndexVect(tempt_x+1, tempt_y+1, tempt_z+1)]; if (den1 != den2) ratio = (isovalue-den1)/(den2-den1); else ratio = 0; } vertex[v_num].x = (float)tempt_x+ratio; vertex[v_num].y = (float)tempt_y+1; vertex[v_num].z = (float)tempt_z+1; cellVerts[5] = v_num; mc_edge[IndexVect(tempt_x, tempt_y+1, tempt_z+1)].a = v_num; v_num++; } else cellVerts[5] = mc_edge[IndexVect(tempt_x, tempt_y+1, tempt_z+1)].a; } if (edgeTable[cellIndex] & 64) { if (mc_edge[IndexVect(tempt_x+1, tempt_y, tempt_z+1)].b == -1) { if(use_intensity) { den1 = intensity[IndexVect(tempt_x+1, tempt_y, tempt_z+1)]; den2 = intensity[IndexVect(tempt_x+1, tempt_y+1, tempt_z+1)]; ratio = get_intensity_ratio(den1, den2, intensity_isovalue); } else { den1 = dataset[IndexVect(tempt_x+1, tempt_y, tempt_z+1)]; den2 = dataset[IndexVect(tempt_x+1, tempt_y+1, tempt_z+1)]; if (den1 != den2) ratio = (isovalue-den1)/(den2-den1); else ratio = 0; } vertex[v_num].x = (float)tempt_x+1; vertex[v_num].y = (float)tempt_y+ratio; vertex[v_num].z = (float)tempt_z+1; cellVerts[6] = v_num; mc_edge[IndexVect(tempt_x+1, tempt_y, tempt_z+1)].b = v_num; v_num++; } else cellVerts[6] = mc_edge[IndexVect(tempt_x+1, tempt_y, tempt_z+1)].b; } if (edgeTable[cellIndex] & 128) { if (mc_edge[IndexVect(tempt_x, tempt_y, tempt_z+1)].a == -1) { if(use_intensity) { den1 = intensity[IndexVect(tempt_x, tempt_y, tempt_z+1)]; den2 = intensity[IndexVect(tempt_x+1, tempt_y, tempt_z+1)]; ratio = get_intensity_ratio(den1, den2, intensity_isovalue); } else { den1 = dataset[IndexVect(tempt_x, tempt_y, tempt_z+1)]; den2 = dataset[IndexVect(tempt_x+1, tempt_y, tempt_z+1)]; if (den1 != den2) ratio = (isovalue-den1)/(den2-den1); else ratio = 0; } vertex[v_num].x = (float)tempt_x+ratio; vertex[v_num].y = (float)tempt_y; vertex[v_num].z = (float)tempt_z+1; cellVerts[7] = v_num; mc_edge[IndexVect(tempt_x, tempt_y, tempt_z+1)].a = v_num; v_num++; } else cellVerts[7] = mc_edge[IndexVect(tempt_x, tempt_y, tempt_z+1)].a; } if (edgeTable[cellIndex] & 256) { if (mc_edge[IndexVect(tempt_x, tempt_y, tempt_z)].c == -1) { if(use_intensity) { den1 = intensity[IndexVect(tempt_x, tempt_y, tempt_z)]; den2 = intensity[IndexVect(tempt_x, tempt_y, tempt_z+1)]; ratio = get_intensity_ratio(den1, den2, intensity_isovalue); } else { den1 = dataset[IndexVect(tempt_x, tempt_y, tempt_z)]; den2 = dataset[IndexVect(tempt_x, tempt_y, tempt_z+1)]; if (den1 != den2) ratio = (isovalue-den1)/(den2-den1); else ratio = 0; } vertex[v_num].x = (float)tempt_x; vertex[v_num].y = (float)tempt_y; vertex[v_num].z = (float)tempt_z+ratio; cellVerts[8] = v_num; mc_edge[IndexVect(tempt_x, tempt_y, tempt_z)].c = v_num; v_num++; } else cellVerts[8] = mc_edge[IndexVect(tempt_x,tempt_y,tempt_z)].c; } if (edgeTable[cellIndex] & 512) { if (mc_edge[IndexVect(tempt_x, tempt_y+1, tempt_z)].c == -1) { if(use_intensity) { den1 = intensity[IndexVect(tempt_x, tempt_y+1, tempt_z)]; den2 = intensity[IndexVect(tempt_x, tempt_y+1, tempt_z+1)]; ratio = get_intensity_ratio(den1, den2, intensity_isovalue); } else { den1 = dataset[IndexVect(tempt_x, tempt_y+1, tempt_z)]; den2 = dataset[IndexVect(tempt_x, tempt_y+1, tempt_z+1)]; if (den1 != den2) ratio = (isovalue-den1)/(den2-den1); else ratio = 0; } vertex[v_num].x = (float)tempt_x; vertex[v_num].y = (float)tempt_y+1; vertex[v_num].z = (float)tempt_z+ratio; cellVerts[9] = v_num; mc_edge[IndexVect(tempt_x, tempt_y+1, tempt_z)].c = v_num; v_num++; } else cellVerts[9] = mc_edge[IndexVect(tempt_x, tempt_y+1, tempt_z)].c; } if (edgeTable[cellIndex] & 1024) { if (mc_edge[IndexVect(tempt_x+1, tempt_y+1, tempt_z)].c == -1) { if(use_intensity) { den1 = intensity[IndexVect(tempt_x+1, tempt_y+1, tempt_z)]; den2 = intensity[IndexVect(tempt_x+1, tempt_y+1, tempt_z+1)]; ratio = get_intensity_ratio(den1, den2, intensity_isovalue); } else { den1 = dataset[IndexVect(tempt_x+1, tempt_y+1, tempt_z)]; den2 = dataset[IndexVect(tempt_x+1, tempt_y+1, tempt_z+1)]; if (den1 != den2) ratio = (isovalue-den1)/(den2-den1); else ratio = 0; } vertex[v_num].x = (float)tempt_x+1; vertex[v_num].y = (float)tempt_y+1; vertex[v_num].z = (float)tempt_z+ratio; cellVerts[10] = v_num; mc_edge[IndexVect(tempt_x+1, tempt_y+1, tempt_z)].c = v_num; v_num++; } else cellVerts[10] = mc_edge[IndexVect(tempt_x+1, tempt_y+1, tempt_z)].c; } if (edgeTable[cellIndex] & 2048) { if (mc_edge[IndexVect(tempt_x+1,tempt_y,tempt_z)].c == -1) { if(use_intensity) { den1 = intensity[IndexVect(tempt_x+1, tempt_y, tempt_z)]; den2 = intensity[IndexVect(tempt_x+1, tempt_y, tempt_z+1)]; ratio = get_intensity_ratio(den1, den2, intensity_isovalue); } else { den1 = dataset[IndexVect(tempt_x+1, tempt_y, tempt_z)]; den2 = dataset[IndexVect(tempt_x+1, tempt_y, tempt_z+1)]; if (den1 != den2) ratio = (isovalue-den1)/(den2-den1); else ratio = 0; } vertex[v_num].x = (float)tempt_x+1; vertex[v_num].y = (float)tempt_y; vertex[v_num].z = (float)tempt_z+ratio; cellVerts[11] = v_num; mc_edge[IndexVect(tempt_x+1, tempt_y, tempt_z)].c = v_num; v_num++; } else cellVerts[11] = mc_edge[IndexVect(tempt_x+1, tempt_y, tempt_z)].c; } ii = 0; while (triTable[cellIndex][ii] != -1) { triangle[t_num].a = cellVerts[triTable[cellIndex][ii++]]; triangle[t_num].b = cellVerts[triTable[cellIndex][ii++]]; triangle[t_num].c = cellVerts[triTable[cellIndex][ii++]]; t_num++; } } // Allocate memory surfmesh = SurfaceMesh_ctor(v_num, t_num); for (n = 0; n < surfmesh->nv; n++) { surfmesh->vertex[n].x = vertex[n].x; surfmesh->vertex[n].y = vertex[n].y; surfmesh->vertex[n].z = vertex[n].z; } for (n = 0; n < surfmesh->nf; n++) { surfmesh->face[n].a = triangle[n].a; surfmesh->face[n].b = triangle[n].b; surfmesh->face[n].c = triangle[n].c; } free(vertex); free(triangle); free(mc_edge); free(mc_sign); // Return created SurfaceMesh return surfmesh; }
CPNT* FindCriticalPoints(int xd,int yd,int zd,float *data, float tlow, int h_num, int k_num) { int i,j,k; int x,y,z; int u,v; CPNT *critical_end=NULL; CPNT *critical_start=NULL; float tmp; unsigned char *temp=NULL; float *temp_float=NULL; float max_grad,min_grad; unsigned long histogram[256]; unsigned long number, tri_num; dataset = data; XDIM = xd; YDIM = yd; ZDIM = zd; printf ("Find Critical Points ... \n"); printf ("XYZ Dim = %3d %3d %3d \n", xd, yd, zd); fflush (stdout); temp = (unsigned char*)malloc(sizeof(unsigned char)*XDIM*YDIM*ZDIM); for (k=0; k<ZDIM; k++) for (j=0; j<YDIM; j++) for (i=0; i<XDIM; i++) temp[IndexVect(i,j,k)] = 0; for (k=0; k<256; k++) histogram[k] = 0; number = 0; for (k=0; k<ZDIM; k++) for (j=0; j<YDIM; j++) for (i=0; i<XDIM; i++) { tmp = dataset[IndexVect(i,j,k)]; if (tmp > tlow) { u = 0; for (z=max2(k-1,0); z<=min2(k+1,ZDIM-1); z++) for (y=max2(j-1,0); y<=min2(j+1,YDIM-1); y++) for (x=max2(i-1,0); x<=min2(i+1,XDIM-1); x++){ if (tmp < dataset[IndexVect(x,y,z)]) u = 1; } if (u == 0) { temp[IndexVect(i,j,k)] = 1; // bigger than 26 neighbors v = (int)(tmp+0.5); histogram[v] += 1; number++; } } } tri_num = 3000*(h_num*h_num + k_num*k_num + h_num*k_num); number = 0; for (k=255; k>=0; k--) { number += histogram[k]; if (number > tri_num) break; } tmp = (float)k; if (tmp < tlow+20.0) tmp = tlow+20.0; // tmp = 282; printf("thigh = %f \n",tmp); fflush (stdout); critical_start = NULL; critical_end = NULL; number = 0; for (k=0; k<ZDIM; k++) { for (j=0; j<YDIM; j++) { for (i=0; i<XDIM; i++) { if (temp[IndexVect(i,j,k)] == 1 && dataset[IndexVect(i,j,k)] > tmp) { number++; if (critical_start == NULL) { critical_end = (CPNT*)malloc(sizeof(CPNT)); critical_end->next = NULL; critical_start = critical_end; } else { critical_end->next = (CPNT*)malloc(sizeof(CPNT)); critical_end = critical_end->next; critical_end->next = NULL; } critical_end->x = (unsigned short)i; critical_end->y = (unsigned short)j; critical_end->z = (unsigned short)k; } } } } printf("number of maximal critical points: %ld \n", number); printf("%ld < min2(50000, tri_num/5) = %ld\n", number, min2(50000, tri_num/5)); fflush (stdout); if (number < min2(50000, tri_num/5)) { temp_float = NULL; temp_float = (float*)malloc(sizeof(float)*XDIM*YDIM*ZDIM); if (temp_float==NULL) { printf ("temp_float is NULL)\n"); fflush (stdout); exit(1); } min_grad = 999999.0f; max_grad = 0.0f; for (k=0; k<ZDIM; k++) for (j=0; j<YDIM; j++) for (i=0; i<XDIM; i++) { if (dataset[IndexVect(i,j,k)] == 0) temp_float[IndexVect(i,j,k)] = 0.0f; else { u = 0; for (z=max2(k-1,0); z<=min2(k+1,ZDIM-1); z++) for (y=max2(j-1,0); y<=min2(j+1,YDIM-1); y++) for (x=max2(i-1,0); x<=min2(i+1,XDIM-1); x++){ if (dataset[IndexVect(x,y,z)] == 0) u = 1; } if (u == 0) temp_float[IndexVect(i,j,k)] = GetImgGradient(i,j,k); else temp_float[IndexVect(i,j,k)] = 0.0f; } if (temp_float[IndexVect(i,j,k)] > max_grad) max_grad = temp_float[IndexVect(i,j,k)]; if (temp_float[IndexVect(i,j,k)] < min_grad) min_grad = temp_float[IndexVect(i,j,k)]; } printf ("Min & Max Gradient = %.4f %.4f\n", min_grad, max_grad); fflush (stdout); for (k=0; k<ZDIM; k++) for (j=0; j<YDIM; j++) for (i=0; i<XDIM; i++) temp_float[IndexVect(i,j,k)] = 255.0f*(temp_float[IndexVect(i,j,k)]-min_grad)/(max_grad-min_grad); for (k=0; k<ZDIM; k++) for (j=0; j<YDIM; j++) for (i=0; i<XDIM; i++) temp[IndexVect(i,j,k)] = 0; for (k=0; k<256; k++) histogram[k] = 0; for (k=0; k<ZDIM; k++) for (j=0; j<YDIM; j++) for (i=0; i<XDIM; i++) { if (dataset[IndexVect(i,j,k)] > tlow) { u = 0; tmp = temp_float[IndexVect(i,j,k)]; for (z=max2(k-1,0); z<=min2(k+1,ZDIM-1); z++) for (y=max2(j-1,0); y<=min2(j+1,YDIM-1); y++) for (x=max2(i-1,0); x<=min2(i+1,XDIM-1); x++) { if (tmp < temp_float[IndexVect(x,y,z)]) u = 1; } if (u == 0) { temp[IndexVect(i,j,k)] = 1; // bigger than 26 neighbors v = (int)(tmp+0.5); histogram[v] += 1; } } } tri_num = number; number = 0; for (k=255; k>=0; k--) { number += histogram[k]; if (number > tri_num) break; } tmp = (float)k; if (tmp < tlow+20.0) tmp = tlow+20.0; printf("thigh = %f \n", tmp); printf ("here -- 1\n"); fflush (stdout); // do { printf ("tmp = %.4f\n", tmp); fflush (stdout); number = 0; for (k=0; k<ZDIM; k++) { for (j=0; j<YDIM; j++) { for (i=0; i<XDIM; i++) { if (temp[IndexVect(i,j,k)] == 1 && temp_float[IndexVect(i,j,k)] > tmp) { number++; if (critical_start == NULL) { critical_end = (CPNT*)malloc(sizeof(CPNT)); critical_end->next = NULL; critical_start = critical_end; } else { critical_end->next = (CPNT*)malloc(sizeof(CPNT)); critical_end = critical_end->next; critical_end->next = NULL; } critical_end->x = (unsigned short)i; critical_end->y = (unsigned short)j; critical_end->z = (unsigned short)k; } } } } tmp -= 10; // } while (number<=0 && tmp>0); printf("number of saddle critical points: %ld \n", number); fflush (stdout); free(temp_float); printf ("here -- 2\n"); fflush (stdout); } printf ("here -- 3\n"); fflush (stdout); free(temp); return critical_start; }
float GetImgGradient(int x, int y, int z) { int i,j,k; float grad_x,grad_y,grad_z; float gradient; grad_x=0.0; for (j=max2(y-1,0); j<=min2(y+1,YDIM-1); j++) for (k=max2(z-1,0); k<=min2(z+1,ZDIM-1); k++) { grad_x += dataset[IndexVect(min2(x+1,XDIM-1),j,k)]-dataset[IndexVect(max2(x-1,0),j,k)]; if (j==y || k==z) grad_x += dataset[IndexVect(min2(x+1,XDIM-1),j,k)]-dataset[IndexVect(max2(x-1,0),j,k)]; if (j==y && k==z) grad_x += 2.0f*(dataset[IndexVect(min2(x+1,XDIM-1),j,k)]-dataset[IndexVect(max2(x-1,0),j,k)]); } grad_y=0.0; for (i=max2(x-1,0); i<=min2(x+1,XDIM-1); i++) for (k=max2(z-1,0); k<=min2(z+1,ZDIM-1); k++) { grad_y += dataset[IndexVect(i,min2(y+1,YDIM-1),k)]-dataset[IndexVect(i,max2(y-1,0),k)]; if (i==x || k==z) grad_y += dataset[IndexVect(i,min2(y+1,YDIM-1),k)]-dataset[IndexVect(i,max2(y-1,0),k)]; if (i==x && k==z) grad_y += 2.0f*(dataset[IndexVect(i,min2(y+1,YDIM-1),k)]-dataset[IndexVect(i,max2(y-1,0),k)]); } grad_z=0.0; for (i=max2(x-1,0); i<=min2(x+1,XDIM-1); i++) for (j=max2(y-1,0); j<=min2(y+1,YDIM-1); j++) { grad_z += dataset[IndexVect(i,j,min2(z+1,ZDIM-1))]-dataset[IndexVect(i,j,max2(z-1,0))]; if (i==x || j==y) grad_z += dataset[IndexVect(i,j,min2(z+1,ZDIM-1))]-dataset[IndexVect(i,j,max2(z-1,0))]; if (i==x && j==y) grad_z += 2.0f*(dataset[IndexVect(i,j,min2(z+1,ZDIM-1))]-dataset[IndexVect(i,j,max2(z-1,0))]); } gradient=(float)sqrt(grad_x*grad_x+grad_y*grad_y+grad_z*grad_z); return(gradient/16.0f); }
void Diffuse(float *dataset, int XDIM, int YDIM, int ZDIM) { float cn, cs, ce, cw, cu, cd; /* six neighbors: north, south, east, west, up, down */ float delta_n, delta_s, delta_e, delta_w, delta_u, delta_d; float K_para = 5; float Lamda_para = 0.16f; float *tempt; int i,j,k,m; tempt = (float *)malloc(sizeof(float)*XDIM*YDIM*ZDIM); for (m=0; m<DIFF_ITER; m++) { if (m%2 == 0) printf ("Iteration = %d \n", m); for (k=0; k<ZDIM; k++) for (j=0; j<YDIM; j++) for (i=0; i<XDIM; i++) { if (j < YDIM-1) delta_s = dataset[IndexVect(i,j+1,k)] - dataset[IndexVect(i,j,k)]; else delta_s = 0.0; if (j > 0) delta_n = dataset[IndexVect(i,j-1,k)] - dataset[IndexVect(i,j,k)]; else delta_n = 0.0; if (i < XDIM-1) delta_e = dataset[IndexVect(i+1,j,k)] - dataset[IndexVect(i,j,k)]; else delta_e = 0.0; if (i > 0) delta_w = dataset[IndexVect(i-1,j,k)] - dataset[IndexVect(i,j,k)]; else delta_w = 0.0; if (k < ZDIM-1) delta_u = dataset[IndexVect(i,j,k+1)] - dataset[IndexVect(i,j,k)]; else delta_u = 0.0; if (k > 0) delta_d = dataset[IndexVect(i,j,k-1)] - dataset[IndexVect(i,j,k)]; else delta_d = 0.0; cn = 1.0f / (1.0f + ((delta_n * delta_n) / (K_para * K_para))); cs = 1.0f / (1.0f + ((delta_s * delta_s) / (K_para * K_para))); ce = 1.0f / (1.0f + ((delta_e * delta_e) / (K_para * K_para))); cw = 1.0f / (1.0f + ((delta_w * delta_w) / (K_para * K_para))); cu = 1.0f / (1.0f + ((delta_u * delta_u) / (K_para * K_para))); cd = 1.0f / (1.0f + ((delta_d * delta_d) / (K_para * K_para))); tempt[IndexVect(i,j,k)] =dataset[IndexVect(i,j,k)] + Lamda_para * (cn * delta_n + cs * delta_s + ce * delta_e + cw * delta_w + cu * delta_u + cd * delta_d); } for (k=0; k<ZDIM; k++) for (j=0; j<YDIM; j++) for (i=0; i<XDIM; i++) { dataset[IndexVect(i,j,k)] = tempt[IndexVect(i,j,k)]; } } free(tempt); }