FlowVis 1.0

FlowVis/Framework/FlowData.cpp

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,&timesteps,&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 }
 All Classes Functions Variables Friends