FlowVis 1.0
|
00001 #include "FlowData.h" 00002 #include <math.h> 00003 #include "reverseBytes.h" 00004 00005 FlowData::FlowData() 00006 { 00007 //mark all the channel slots as free 00008 for(int i = 0; i < max_channels; i++) 00009 { 00010 channels[i] = NULL; 00011 freeChannel[i] = true; 00012 } 00013 } 00014 00015 FlowData::~FlowData() 00016 { 00017 //delete all the channels 00018 for(int i = 0; i < max_channels; i++) 00019 if (!freeChannel[i]) 00020 deleteChannel(i); 00021 } 00022 00023 void FlowData::getGeometry(int &x,int &y) 00024 { 00025 x = geometry.getDimX(); 00026 y = geometry.getDimY(); 00027 } 00028 bool FlowData::loadDataset(string filename, bool bigEndian) 00029 { 00030 FILE* griFile = NULL; 00031 FILE* datFile = NULL; 00032 char header[40]; 00033 00034 //localize the last dot in the filename 00035 int lastdot = filename.find_last_of(".",filename.length()-1); 00036 if (lastdot != string::npos) 00037 //if there is a dot, remove everything behind it 00038 filename = filename.substr(0,lastdot); 00039 00041 // GRID FILE 00043 string griName = filename+".gri"; 00044 00045 std::cout << "- Loading grid file '" << griName << "' ... " << std::endl; 00046 //open the grid file 00047 griFile = fopen(griName.c_str(),"rb"); 00048 00049 if (!griFile) 00050 { 00051 std::cerr << "+ Error loading grid file:" << griName << std::endl << std::endl; 00052 return false; 00053 } 00054 //save the header 00055 fread(header,40,1,griFile); 00056 //pass the grid file to the geometry class to process it 00057 if (!geometry.readFromFile(header,griFile,bigEndian)) 00058 return false; 00059 //close the file 00060 fclose(griFile); 00061 00062 int dimX,dimY,dimZ,numChannels; 00063 float DT; 00064 //read some neceassry data from the header 00065 sscanf(header,"SN4DB %d %d %d %d %d %f",&dimX,&dimY,&dimZ,&numChannels,×teps,&DT); 00066 printf("Channels: %d\nTimesteps: %d\n",numChannels,timesteps); 00067 00069 // DAT FILE 00071 //since this framework handles only one timestep, we use only a single dat file 00072 char suffix[16]; 00073 sprintf(suffix,".%.5u.dat",0); //the second dot and the following 5 specify that a minimum of 5 numbers will be written 00074 string datName = filename.append(suffix); 00075 std::cout << "- Loading grid file '" << datName << "' ... " << std::endl; 00076 //open the dat file 00077 datFile = fopen(datName.c_str(),"rb"); 00078 if (!datFile) 00079 { 00080 std::cerr << "+ Error loading dat file:" << datName << std::endl << std::endl; 00081 return false; 00082 } 00083 //let's prepare the channels 00084 numChannels += 3; //add the 3 components of the velocity vector to the number of additional chanenls 00085 int* ch = new int[numChannels]; //create a storage for addresses our channels 00086 00087 //because reading big chunks of data is much faster than single values, 00088 //we read the data into a temporary array and then copy it to the channels 00089 float* tmpArray = new float[numChannels*geometry.getDimX()*geometry.getDimY()]; //create temporary storage 00090 int result = fread(tmpArray,sizeof(float),numChannels*geometry.getDimX()*geometry.getDimY(),datFile); //read the data 00091 //have we read the whole data file? 00092 if (result != numChannels*geometry.getDimX()*geometry.getDimY()) 00093 { 00094 std::cerr << "+ Error reading dat file:" << datName << std::endl << std::endl; 00095 return false; 00096 } 00097 //close the file, it is no longer needed 00098 fclose(datFile); 00099 00100 //if swap the byte order, if the file is encoded big-endian 00101 if (bigEndian) 00102 for(int j = 0; j < numChannels*geometry.getDimX()*geometry.getDimY(); j++) 00103 tmpArray[j] = reverseBytes<float>(tmpArray[j]); 00104 //assign the data to the appropriate channels 00105 for (int j = 0; j < (numChannels); j++) 00106 { 00107 //create the new channel 00108 ch[j] = createChannel(); 00109 //copy the values of the jth channel from tmpArray, which carries numChannels 00110 channels[ch[j]]->copyValues(tmpArray,(numChannels),j); 00111 } 00112 delete[] ch; 00113 delete[] tmpArray; 00114 00115 numofChannels = numChannels; 00116 return true; 00117 } 00118 00119 int FlowData::createChannel() 00120 { 00121 //find the first unused channel slot 00122 int i = 0; 00123 while ((!freeChannel[i])&&(i < max_channels)) i++; 00124 //if there is a free slot 00125 if (i < max_channels) 00126 { 00127 std::cout << "Creating channel at " << i << " ... "; 00128 //create a new channel 00129 channels[i] = new FlowChannel(&geometry); 00130 //remember the slot 00131 freeChannel[i] = false; 00132 //return the adress of the new channel 00133 return i; 00134 } 00135 //there is no free channel 00136 else 00137 { 00138 return -1; 00139 std::cerr << "There is no free channel slot!" << std::endl; 00140 } 00141 } 00142 00143 void FlowData::deleteChannel(int i) 00144 { 00145 //if the address is really occupied 00146 if (!freeChannel[i]) 00147 { 00148 std::cout << "Deleting channel at " << i << " ... "; 00149 //delete the channel instance 00150 delete channels[i]; 00151 channels[i] = NULL; 00152 //free the slot 00153 freeChannel[i] = true; 00154 } 00155 else std::cout << "Tried to delete a non-existing channel at " << i << "." << std::endl; 00156 } 00157 00158 FlowChannel* FlowData::getChannel(int i) 00159 { 00160 return channels[i]; 00161 } 00162 00163 int FlowData::createChannelGeometry(int dimension) 00164 { 00165 int result = createChannel(); 00166 //just take the dimension as if it was an offset to the geometryData array 00167 channels[result]->copyValues((float*)geometry.geometryData, 3, dimension); 00168 return result; 00169 } 00170 00171 int FlowData::createChannelValue(int ch) 00172 { 00173 int result = createChannel(); 00174 00175 FlowChannel* channel = getChannel(ch); 00176 00177 float value; 00178 for(int i=0; i < geometry.getDimX() * geometry.getDimY(); i++) 00179 { 00180 value = channel->getValue(i); 00181 //if(value >0) 00182 // std::cout << "value > 0" << std::endl; 00183 channels[result]->setValue(i, value ); 00184 } 00185 return result; 00186 } 00187 int FlowData::createChannelVectorLength(FlowChannel* chX, FlowChannel* chY, FlowChannel* chZ) 00188 { 00189 int result = createChannel(); 00190 //check whether we deal with 2D or 3D vectors 00191 if (chZ) 00192 for (int i = 0; i < geometry.getDimX()*geometry.getDimY(); i++) 00193 //save the vector length 00194 channels[result]->setValue(i,sqrt(chX->getValue(i)*chX->getValue(i) + chY->getValue(i)*chY->getValue(i) + chZ->getValue(i)*chZ->getValue(i))); 00195 else 00196 for (int i = 0; i < geometry.getDimX()*geometry.getDimY(); i++) 00197 channels[result]->setValue(i,sqrt(chX->getValue(i)*chX->getValue(i) + chY->getValue(i)*chY->getValue(i))); 00198 00199 return result; 00200 } 00201 00202 int FlowData::createChannelVectorLength(int chX, int chY, int chZ) 00203 { 00204 //just a wrapper for the method above 00205 if (chZ >= 0) 00206 return createChannelVectorLength(getChannel(chX),getChannel(chY),getChannel(chZ)); 00207 else return createChannelVectorLength(getChannel(chX),getChannel(chY)); 00208 } 00209 00210 int FlowData::getNumTimesteps() 00211 { 00212 return timesteps; 00213 }