#include "common.h"
///////////////////////////////////////////////////////////////////////////////
// save and read vector field files in ascii format
// #define SAVE_READ_VECTOR_FIELD_ASCII
#ifndef WIN32
struct timeval tv;
unsigned long startTime, crtTime, prevTime;
unsigned long phaseCompletionTime, elapsedTime;
#else
DWORD startTime, crtTime, prevTime;
DWORD phaseCompletionTime, elapsedTime;
#endif
void SetStartTime() {
#ifdef WIN32
startTime = GetTickCount();
#else
gettimeofday(&tv, NULL);
startTime = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
#endif
prevTime = startTime;
return;
}
void PrintElapsedTime(const char* message) {
#ifdef WIN32
crtTime = GetTickCount();
#else
gettimeofday(&tv, NULL);
crtTime = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
#endif
phaseCompletionTime = crtTime - prevTime;
elapsedTime = crtTime - startTime;
prevTime = crtTime;
if(strlen(message) == 0) {
printf("Total time: %d ms.\n", elapsedTime);
}
else {
if(strcmp(message, " ") == 0) {
printf("completed in: %d ms. Total time: %d ms.\n", phaseCompletionTime, elapsedTime);
}
else {
printf("%s\n"
"\tcompleted in: %d ms. Total time: %d ms.\n", message, phaseCompletionTime, elapsedTime);
}
}
return;
}
/*
// for the following function to give accurate results, the following conditions must apply:
// 1. the volume has no holes in it
// 2. the object is padded by at least one plane of empty voxels in every direction
//
bool SetFlags(unsigned char *vol, int L, int M, int N, unsigned char **flags) {
long idx, idx2, slsz, upperlimit;
int i, j, k, s;
if(((*flags) = new unsigned char[L*M*N]) == NULL) {
printf("Error allocating memory for the flags array !! Abort.\n");
exit(1);
}
slsz = L*M; // slice size
long neighborhood[6] = {-1, +1, -L, +L, -slsz, +slsz}; // only face neighbors
// 1
// set flag to INTERIOR for all the voxels that have a non 0 value
// and to EXTERIOR for all the 0 voxels.
upperlimit = L*M*N;
for(i=0; i < upperlimit; i++) {
(*flags)[i] = INTERIOR;
if(vol[i] == 0) {
(*flags)[i] = EXTERIOR;
}
}
// 2
// look at the INTERIOR voxels. If an INTERIOR voxel has an EXTERIOR neighbor,
// then it is a SURFace voxel
// look only at the neighbors defined by neighborhood.
for (k = 1; k < N-1; k++) {
for (j = 1; j < M-1; j++) {
for (i = 1; i < L-1; i++) {
idx = k*slsz + j*L + i;
if((*flags)[idx] == INTERIOR) {
for(s=0; s < 6; s++) {
idx2 = idx + neighborhood[s];
if((*flags)[idx2] == EXTERIOR) {
(*flags)[idx] = SURF;
break;
}
}
}
}
}
}
return true;
}
*/
bool ReadVolume(char *filename, int L, int M, int N, unsigned char **vol) {
FILE* fvol;
size_t read;
if ((fvol = fopen(filename,"rb")) == NULL) {
printf("\nCannot open input file %s\n", filename);
(*vol) = NULL;
return false;
}
if(((*vol) = new unsigned char[L*M*N]) == NULL) {
printf("\nError allocating memory for the volume. Not enough memory ?\n");
return false;
}
read = fread((*vol), sizeof(unsigned char), L*M*N, fvol);
if ( read < ((size_t) L*M*N)) {
printf("\n\
Read only %ld values before the end of input file. Expected: %ld.\n",
read, L*M*N);
delete [] (*vol);
(*vol) = NULL;
return false;
}
fclose(fvol);
return true;
}
///////////////////////////////////////////////////////////////////////////////
// write volume data from a given file
///////////////////////////////////////////////////////////////////////////////
bool SaveVolume(char *filename, int L, int M, int N, unsigned char *vol) {
FILE* fvol;
size_t wrote;
if ((fvol = fopen(filename,"wb")) == NULL) {
printf("\nCannot open output file %s\n", filename);
return false;
}
wrote = fwrite(vol, sizeof(unsigned char), L*M*N, fvol);
if ( wrote < ((size_t) L*M*N)) {
printf("\n\
Wrote only %ld values to output file. Expected: %ld.\n",
wrote, L*M*N);
return false;
}
fclose(fvol);
return true;
}
bool IsLineCrossingBoundary(
short x1, short y1, short z1,
short x2, short y2, short z2,
int sX, int sY, int sZ,
unsigned char* flags)
{
double t, step, tmp;
double x, y, z;
long slsz, idx;
// if the 2 voxels are the same, return false;
if( (x1 == x2) &&
(y1 == y2) &&
(z1 == z2))
{
return false;
}
// calculate optimum step that will take us to another voxel each time we move
step = 2.00;
// step for the X direction
t = abs(x2 - x1);
if(t > 0.00) {
tmp = 1.00 / t;
if(tmp < step) {
step = tmp;
}
}
// step for the Y direction
t = abs(y2 - y1);
if(t > 0.00) {
tmp = 1.00 / t;
if(tmp < step) {
step = tmp;
}
}
// step for the Z direction
t = abs(z2 - z1);
if(t > 0.00) {
tmp = 1.00 / t;
if(tmp < step) {
step = tmp;
}
}
#ifdef _DEBUG
// the 2 voxels are not identical so there will be a step value of at most 1.00
// but just to make sure, I will check
if(step > 1.00) {
printf("Vizibility test: OOPS - step value is > 1.00. Abort\n");
exit(1);
}
#endif
slsz = sX*sY; // slice size
// sample the line between the 2 points at <step> intervals, and check each
// of the sample points whether they are in one of the "blank" voxels
t = 0.00;
while (t <= 1.00) {
x = x1 + (x2 - x1)*t;
y = y1 + (y2 - y1)*t;
z = z1 + (z2 - z1)*t;
// index of voxel in the flags array
idx = ((int)z)*slsz + ((int)y)*sX + ((int)x);
#ifdef _DEBUG
// this should not happen, but just in case...
if((idx < 0) || (idx > sX*sY*sZ)) {
printf("Vizibility test: OOPS - line gets out of volume bounds ! Abort\n");
exit(1);
}
#endif
//
if(flags[idx] == EXTERIOR) {
return true;
}
t = t + step;
}
// line did not intersect any "blank" voxels
return false;
}
///////////////////////////////////////////////////////////////////////////////
// function SaveSkeleton - saves the skeleton to a file
// mode - 0 (default) saves skeleton as points, with the segment specified
// for each point
// format: X Y Z segment 0.5\n
// 1 saves the skeleton as line segments (2 points per line)
// format: X1 Y1 Z1 X2 Y2 Z2 segment\n
//
///////////////////////////////////////////////////////////////////////////////
bool SaveSkeleton(Skeleton *Skel, // [in] skeleton structure to be saved
char *file, // [in] output file name
char mode /*=0*/, // [in] output: 0 - points, 1 - lines
float *distField /*= NULL*/, // [in] distance field
int L /*= 0*/, // [in] size of original volume
int M /*= 0*/, // needed in distField is not NULL
int N /*= 0*/
)
{
int i, j;
FILE *fskelout;
float spx, spy, spz;
float dt;
if((distField != NULL) && ((L <= 0) || (M <= 0) || (N <= 0))) {
printf("\
SaveSkeleton: \n\
Please provide the size of the original volume if using a distance field !\n"
);
return false;
}
#ifdef TRACE
printf("Starting Save Skeleton ...n");
printf("Skeleton:\n");
printf("\tnumPoints = %d; sizePoints = %d\n", Skel->numPoints,
Skel->sizePoints);
printf("\tnumSegments = %d; sizeSegments = %d\n", Skel->numSegments,
Skel->sizeSegments);
printf("Segments:\n");
printf("\tLEFT\tFIRST\tLAST\tRIGHT\n");
for(i=0; i < Skel->numSegments; i++) {
printf("\t%d\t%d\t%d\t%d\n", Skel->Segments[i][SKEL_SEG_LEFT],
Skel->Segments[i][SKEL_SEG_FIRST],
Skel->Segments[i][SKEL_SEG_LAST],
Skel->Segments[i][SKEL_SEG_RIGHT]);
}
printf("-----\n");
fflush(stdout);
#endif
// open the file
if ((fskelout = fopen(file,"w")) == NULL) {
printf("Cannot open output file %s for writing\n", file);
exit(1);
}
switch(mode) {
c
评论0