/** * The idea behind fromMRtoAR.c is to read a set of * uniform resolution volume data stored as cubes and output in adaptive * resolution represented cubes. *

*

* @file fromFloatToCube.c * @author Robert S Laramee * @start date Wed 12 July 00 */ #include #include /* for atoi(), atof() */ #define INVALID -2 #define MAXTHRESHOLD 1.0 #define MINTHRESHOLD 0.0 float threshold = INVALID; int totalNumCubes = INVALID; /** * Make sure you declare this structure before its used, even in the * function prototypes. */ struct cube { /* a cube has 8 vertex values */ float p0; float p1; float p2; float p3; float p4; float p5; float p6; float p7; int xIndex; /* and 3 index values indicating the x, y, and z */ int yIndex; /* coordinates (in block space) of its 0th */ int zIndex; /* vertex */ }; /** * @return the current threshold value */ float getThreshold() { return threshold; } /** * @param the new threshold value */ void setThreshold(float newVal) { if ((newVal < MINTHRESHOLD) || (newVal > MAXTHRESHOLD)) { fprintf(stderr, "*** Error, fromMRtoAR.setThreshold() invalid " " threshold %f, exiting...\n", newVal); exit(1); } else { threshold = newVal; } } /** * @return the total number of cubes in the volume */ int getTotalNumCubes() { return totalNumCubes; } /** * @param the total number of cubes in the volume */ void setTotalNumCubes(int newTotal) { if ( (newTotal < 0) || (newTotal > (256*256*256)) ) { fprintf(stderr, "*** Error, fromMRtoAR.setTotalNumCubes() invalid" "new total: %d, exiting...\n", newTotal); exit(1); } else { totalNumCubes = newTotal; } } /* function prototypes */ int outputARcubes(FILE *inputFile); int readCube(FILE *inputFile, struct cube *cube_ptr); int read8Cubes(FILE* inputFile, struct cube cubes[8]); int isAboveThreshold(struct cube *cube_ptr); int areAboveThreshold(struct cube siblingCubes[8]); float computeMinimum(struct cube *cube_ptr); float computeMaximum(struct cube *cube_ptr); int outputCube(struct cube *cube_ptr); int output8Cubes(struct cube cubes[8]); void printCube(struct cube *cube_ptr); /* Compile the program using: *

 * % gcc -Wall fromMRtoAR.c -Iinclude -lm -o fromMRtoAR.exe
 * 
*

* Start the program using: *

 * % fromMRtoAR.exe [input file] [threshold] > [output file] 
 *   e.g.
 * % fromMRtoAR.exe ~rlaramee/data/level6/headLev6sort.ascii 2 2 2 0.01 > \
 *                  ~rlaramee/data/level6/headLev6AR.ascii
 * 
*

* @param argv[1] -the input data file name * @param argv[2] -the number of cubes along the x dimension * @param argv[3] -the number of cubes along the y dimension * @param argv[4] -the number of cubes along the z dimension * @param argv[5] -the threshold value that determines which cubes are * "trimmed" from the representation */ int main(int argc , char *argv[]) { FILE *inputFile; char *inputFileName; int totalOutput = 0; /* check command line arguments */ if (argc != 6) { fprintf(stderr, "*** Error, usage: fromMRtoAR.exe [inputfile] " "[x] [y] [z] [threshold] > [output file]\n"); exit(1); } inputFileName = argv[1]; if ( !( inputFile = fopen(inputFileName,"rb"))){ fprintf(stderr, "*** Error, couldn't open input file: %s \n", inputFileName); exit(1); } setTotalNumCubes( (atoi(argv[2])) * (atoi(argv[3])) * (atoi(argv[4])) ); setThreshold(atof(argv[5])); fprintf(stdout, "# fromMRtoAR.main() input file is: \n# %s \n", inputFileName); fprintf(stderr, "# fromMRtoAR.main() input file is: \n# %s \n", inputFileName); fprintf(stdout, "# fromMRtoAR.main() with total cubes: %d x %d x %d = " "%d\n", atoi(argv[2]), atoi(argv[3]), atoi(argv[4]), getTotalNumCubes()); fprintf(stderr, "# fromMRtoAR.main() with total cubes: %d x %d x %d = " "%d\n", atoi(argv[2]), atoi(argv[3]), atoi(argv[4]), getTotalNumCubes()); fprintf(stdout, "# fromMRtoAR.main() with threshold: %f\n", getThreshold()); fprintf(stderr, "# fromMRtoAR.main() with threshold: %f\n", getThreshold()); totalOutput = outputARcubes(inputFile); if (fclose(inputFile)) { fprintf(stderr, "*** Error fromMRtoAR.main() closing input " "file \n"); } else { fprintf(stderr, "# fromMRtoAR.main(): closed input file\n"); } fprintf(stdout, "# fromMRtoAR.main() output: %d cubes \n", totalOutput); fprintf(stderr, "# fromMRtoAR.main() output: %d cubes \n", totalOutput); return 0; } /** * This function outputs the volume data in AR reprepresentation. * Note, we have to read, test, and write cubes 8 at a time in order * to generate a complete AR representation. * Eight either stay or leave. *

* @param inputFile a handle to the input file * @return the total number of cubes output */ int outputARcubes(FILE *inputFile) { int debug = 1; int i = 0; int totalRead = 0; int totalOutput = 0; struct cube siblingCubes[8]; /* read 8 cubes at a time */ if (debug == 0) { fprintf(stdout, "# fromFloatToCube.outputVolumeOfCubes()\n"); } /* FOR EACH SET OF 8 CUBES */ for (i = 0; i < (getTotalNumCubes()/8) ; i++) { /* totalRead = totalRead + readCube(inputFile, cube_ptr); */ totalRead = totalRead + read8Cubes(inputFile, siblingCubes); if (areAboveThreshold(siblingCubes) == 1) { totalOutput = totalOutput + output8Cubes(siblingCubes); } fflush(inputFile); /* important before we read the next 8 cubes */ } /* end FOR EACH CUBE */ if (debug == 1) fprintf(stderr, "# fromMRtoAR.outputARCubes()" " returning: %d\n", totalRead); return totalOutput; } /** * For now, the threshold is set simply by the different between the * maximum and minimum scalar values. By checking the 8 children, * we are less likely to throw away needed cubes. *

* @param cube_ptr a pointer to the cube structure * @return 1 is within the threshold set by the user */ int areAboveThreshold(struct cube siblingCubes[8]) { int debug = 0; int i = 0; float singleMinimum = 1.0; float singleMaximum = 0.0; float totalMinimum = 1.0; float totalMaximum = 0.0; float difference = 0.0; for (i = 0; i < 8; i++) { singleMinimum = computeMinimum(&siblingCubes[i]); if (singleMinimum < totalMinimum) totalMinimum = singleMinimum; singleMaximum = computeMaximum(&siblingCubes[i]); if (singleMaximum > totalMaximum) totalMaximum = singleMaximum; } difference = totalMaximum - totalMinimum; if (debug == 1) fprintf(stdout, "# areWithinThreshold(), totalMax: %f, " "totalMin: %f, diff: %f\n", totalMaximum, totalMinimum, difference); if (difference > getThreshold()) { return 1; } else { return 0; } } /** * For now, the threshold is set simply by the different between the * maximum and minimum scalar values. *

* @param cube_ptr a pointer to the cube structure * @return 1 is within the threshold set by the user */ int isAboveThreshold(struct cube *cube_ptr) { int debug = 0; float minimum = computeMinimum(cube_ptr); float maximum = computeMaximum(cube_ptr); float difference = maximum - minimum; if (debug == 1) fprintf(stdout, "# fromMRtoAR.isWithinThreshold(), max: %f, " "min: %f, diff: %f\n", maximum, minimum, difference); if (difference > getThreshold()) { return 1; } else { return 0; } } /** * @param cube_ptr a pointer to a cube object * @return the minimum scalar value of the cube's 8 vertices */ float computeMinimum(struct cube *cube_ptr) { int i = 0; float p[8]; float minimum = 1.0; p[0] = cube_ptr->p0; p[1] = cube_ptr->p1; p[2] = cube_ptr->p2; p[3] = cube_ptr->p3; p[4] = cube_ptr->p4; p[5] = cube_ptr->p5; p[6] = cube_ptr->p6; p[7] = cube_ptr->p7; for (i = 0; i < 8; i++) { if (p[i] < minimum) { minimum = p[i]; } } return minimum; } /** * @param cube_ptr a pointer to a cube object * @return the maximum scalar value of the cube's 8 vertices */ float computeMaximum(struct cube *cube_ptr) { int i = 0; float p[8]; float maximum = 0.0; p[0] = cube_ptr->p0; p[1] = cube_ptr->p1; p[2] = cube_ptr->p2; p[3] = cube_ptr->p3; p[4] = cube_ptr->p4; p[5] = cube_ptr->p5; p[6] = cube_ptr->p6; p[7] = cube_ptr->p7; for (i = 0; i < 8; i++) { if (p[i] > maximum) { maximum = p[i]; } } return maximum; } /** * This method reads the cubes. *

 *              P3_____________P2   This is the cube representation
 *              /|            /|    for Bob's cube's.  It is the
 *             / |           / |    same as the VTK's.
 *    y     P7____________P6/  |    
 *    ^      |   |         |   |    
 *    |      |   |         |   |    
 *    |      |   |         |   |
 *    |--->  | P0|_________|___|P1
 *   /    x  |  /          |  /
 *  /        | /           | /
 * z         |_____________|/
 *          P4             P5
 * 
*

* @param inputFile a handle to the input file * @param cube_ptr a pointer to the cube structure * @return 1 if the cube was read properly */ int readCube(FILE *inputFile, struct cube *cube_ptr) { int debug = 0; if (debug == 1) fprintf(stdout, "# fromMRtoAR.readCube()\n"); /* read a cube */ fscanf(inputFile, "%f %f %f %f %f %f %f %f\n", &cube_ptr->p0, &cube_ptr->p1, &cube_ptr->p2, &cube_ptr->p3, &cube_ptr->p4, &cube_ptr->p5, &cube_ptr->p6, &cube_ptr->p7); fscanf(inputFile, "%d %d %d\n", &cube_ptr->xIndex, &cube_ptr->yIndex, &cube_ptr->zIndex); if (debug == 1) printCube(cube_ptr); return 1; } /** * A parent cube has 8 child cubes to read *

* @param level the level of resolution at which to read the cubes * @param cubes[8] an array to store a cube structures * @return the number of cubes read (should be 8) */ int read8Cubes(FILE* inputFile, struct cube cubes[8]) { int i = 0; int debug = 0; int numRead = 0; for (i = 0; i < 8; i++) { if (debug == 1) fprintf(stdout, "# read8cubes() i = %d\n", i); numRead = numRead + readCube(inputFile, &cubes[i]); } if (numRead != 8) fprintf(stderr, "*** Error, read8cubes() read " "only %d cubes\n", numRead); return numRead; } /** * @param cube_ptr a pointer to a cube * @return 1 IF the cube was output */ int outputCube(struct cube *c) { int debug = 0; if (debug == 1) fprintf(stdout, "# fromMRtoAR.outputCube()\n"); fprintf(stdout, "%f %f %f %f %f %f %f %f\n", c->p0, c->p1, c->p2, c->p3, c->p4, c->p5, c->p6, c->p7); fprintf(stdout, "%d %d %d \n", c->xIndex, c->yIndex, c->zIndex); return 1; } /** * @param cubes an array of 8 cubes * @return the total number of cubes output */ int output8Cubes(struct cube cubes[8]) { int i = 0; int debug = 0; int numOutput = 0; if (debug == 1) fprintf(stdout, "# fromMRtoAR.output8Cubes()\n"); for (i = 0; i < 8; i++) { numOutput = numOutput + outputCube(&cubes[i]); } if (numOutput != 8) fprintf(stderr, "*** Warning, " "fromMRtoAR.output8Cubes() num ouput = %d\n", numOutput); return numOutput; } /** * @param c the cube to print out */ void printCube(struct cube *c) { int debug = 0; if (debug == 1) fprintf(stdout, "fromMRtoMR.printCube()"); fprintf(stdout, "%f %f %f %f %f %f %f %f\n", c->p0, c->p1, c->p2, c->p3, c->p4, c->p5, c->p6, c->p7); fprintf(stdout, "%d %d %d \n", c->xIndex, c->yIndex, c->zIndex); }