/** * 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
* Start the program using:
*
* @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.
*
* @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);
}
* % gcc -Wall fromMRtoAR.c -Iinclude -lm -o fromMRtoAR.exe
*
*
* % 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
*
*
* 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
*
*