Waterflow
Visualize water in terrain
|
00001 00002 00003 00004 #include "xmlParsing.h" 00005 00006 // This file implement all the parsing functions for the XML file contents and an generating function for the Flowsource class. 00007 00008 00009 Flood_Fill_data::Flood_Fill_data(int in_x, int in_z, float in_height) 00010 { 00011 this->x = in_x; 00012 this->z = in_z; 00013 this->height = in_height; 00014 } 00015 00016 init_Data_struct::init_Data_struct(const char* XMLfile) 00017 { 00018 this->data_filename = loadMapPath(XMLfile); 00019 00020 this->velocity_save_path = loadVelSavePath(XMLfile); 00021 this->velocity_load_path = loadVelLoadPath(XMLfile); 00022 this->height_save_path = loadHeightSavePath(XMLfile); 00023 this->height_load_path = loadHeightLoadPath(XMLfile); 00024 00025 this->Flowsources = loadFlows(XMLfile); 00026 this->FFData = loadFFData(XMLfile); 00027 } 00028 00029 // Converts a string with CSV to a vector with floats. 00030 std::vector<float> fStrToVector(std::string str){ 00031 std::vector<float> valueVector; 00032 std::stringstream ss(str); 00033 std::string fValue; 00034 00035 while(std::getline(ss, fValue, ',')){ 00036 std::stringstream fs(fValue); 00037 float f = 0.0; 00038 fs >> f; 00039 valueVector.push_back(f); 00040 } 00041 return valueVector; 00042 } 00043 00044 //Converts a string with CSV to a vector with ints. 00045 std::vector<int> iStrToVector(std::string str){ 00046 std::vector<int> valueVector; 00047 std::stringstream ss(str); 00048 std::string iValue; 00049 00050 while(std::getline(ss, iValue, ',')){ 00051 std::stringstream is(iValue); 00052 int i = 0; 00053 is >> i; 00054 valueVector.push_back(i); 00055 } 00056 return valueVector; 00057 } 00058 00059 // This function parses the pressure values from the XML file by takeing the Pressure node, the PressureTime node and a pointer to a FlowSource object as input and adding the contents to the provided Object. 00060 void parsePressure(FlowSource* obj, pugi::xml_node pres, pugi::xml_node time){ 00061 std::string timestr = time.attribute("t").value(); 00062 std::string pstr = pres.attribute("p").value(); 00063 std::vector<float> timevec = fStrToVector(timestr); 00064 std::vector<float> pvec = fStrToVector(pstr); 00065 obj->setPressure(pvec, timevec); 00066 } 00067 00068 // This function parses the Position node and adds it to by pointer provided FlowSource Object. 00069 void parsePosition(FlowSource* obj, pugi::xml_node node){ 00070 int x, y, z; 00071 x = node.attribute("x").as_int(); 00072 y = node.attribute("y").as_int(); 00073 z = node.attribute("z").as_int(); 00074 obj->setPosition(x,y,z); 00075 } 00076 00077 // This function parses the xyz direction of A Normal node and the time of a NormalTime node, then adds the result to an FlowSource Object given by pointer. 00078 void parseNormal(FlowSource* obj, pugi::xml_node norm, pugi::xml_node time){ 00079 std::string timestr = time.attribute("t").value(); 00080 std::vector<float> ndir; 00081 std::vector<std::vector<float> > nvec; 00082 float x, y, z; 00083 for (pugi::xml_node_iterator it = norm.begin(); it != norm.end(); ++it){ 00084 x = it->attribute("x").as_float(); 00085 y = it->attribute("y").as_float(); 00086 z = it->attribute("z").as_float(); 00087 ndir = {x, y, z}; 00088 nvec.push_back(ndir); 00089 } 00090 std::vector<int> timevec = iStrToVector(timestr); 00091 obj->setNormal(nvec, timevec); 00092 } 00093 00094 00095 void parseTotalWater(FlowSource* obj, pugi::xml_node node){ 00096 float tot; 00097 tot = node.attribute("tot").as_float(); 00098 obj->setTotalWater(tot); 00099 } 00100 00101 void parseRadius(FlowSource* obj, pugi::xml_node node){ 00102 float r; 00103 r = node.attribute("r").as_float(); 00104 obj->setRadius(r); 00105 } 00106 00107 // This Function transverces all child nodes to a Sources node in a (by input) specified XML file. Fore every source specifed it adds a new FlowSource object and populates it with the contents in the XML file coresponding to the source. It returns a vector with pointers to the objects it creates. 00108 std::vector<FlowSource*> loadFlows(const char* xmlFile) { 00109 pugi::xml_document doc; 00110 std::vector<FlowSource*> srces; 00111 if (!doc.load_file(xmlFile)) return srces; 00112 pugi::xml_node sources = doc.child("Profile").child("Sources"); 00113 for (pugi::xml_node_iterator it = sources.begin(); it != sources.end(); ++it){ 00114 FlowSource* fsp; 00115 fsp = new FlowSource; 00116 parsePressure(fsp, it->child("Pressure"), it->child("TimeP")); 00117 parsePosition(fsp, it->child("Position")); 00118 parseNormal(fsp, it->child("Normals"), it->child("TimeN")); 00119 parseTotalWater(fsp, it->child("TotWater")); 00120 parseRadius(fsp, it->child("Radius")); 00121 srces.push_back(fsp); 00122 } 00123 return srces; 00124 } 00125 00126 bool flowChange(std::vector<FlowSource*> flows, float dt){ 00127 bool change = false; 00128 for(unsigned int i = 0; i < flows.size(); i++){ 00129 if(flows.at(i)->getChange(dt)){ 00130 change = true; 00131 } 00132 } 00133 return change; 00134 } 00135 00136 std::string loadMapPath(const char* xmlFile){ 00137 pugi::xml_document doc; 00138 if(!doc.load_file(xmlFile)) return "No XML file"; 00139 std::cout << "XML load success" << std::endl; 00140 std::string path = doc.child("Profile").child("Data").child("MapName").attribute("path").value(); 00141 return path; 00142 } 00143 00144 std::string loadVelLoadPath(const char* xmlFile){ 00145 pugi::xml_document doc; 00146 if(!doc.load_file(xmlFile)) return "No XML file"; 00147 std::string path = doc.child("Profile").child("Data").child("VelLoad").attribute("path").value(); 00148 return path; 00149 } 00150 00151 std::string loadHeightLoadPath(const char* xmlFile){ 00152 pugi::xml_document doc; 00153 if(!doc.load_file(xmlFile)) return "No XML file"; 00154 std::string path = doc.child("Profile").child("Data").child("HeightLoad").attribute("path").value(); 00155 return path; 00156 } 00157 00158 std::string loadVelSavePath(const char* xmlFile){ 00159 pugi::xml_document doc; 00160 if(!doc.load_file(xmlFile)) return "No XML file"; 00161 std::string path = doc.child("Profile").child("Data").child("VelSave").attribute("path").value(); 00162 return path; 00163 } 00164 00165 std::string loadHeightSavePath(const char* xmlFile){ 00166 pugi::xml_document doc; 00167 if(!doc.load_file(xmlFile)) return "No XML file"; 00168 std::string path = doc.child("Profile").child("Data").child("HeightSave").attribute("path").value(); 00169 return path; 00170 } 00171 00172 std::vector<Flood_Fill_data*> loadFFData(const char* xmlFile){ 00173 pugi::xml_document doc; 00174 doc.load_file(xmlFile); 00175 00176 std::vector<Flood_Fill_data*> out_data; 00177 pugi::xml_node floods = doc.child("Profile").child("Floods"); 00178 00179 for (pugi::xml_node_iterator it = floods.begin(); it != floods.end(); ++it){ 00180 Flood_Fill_data* Flood_Fill = new Flood_Fill_data(it->attribute("x").as_int(), it->attribute("z").as_int(), it->attribute("height").as_float()); 00181 00182 out_data.push_back(Flood_Fill); 00183 } 00184 return out_data; 00185 } 00186 00187 00188 void deleteAllFlows(std::vector<FlowSource*> srces){ 00189 for(auto it = srces.begin(); it != srces.end(); ++it){ 00190 delete *it; 00191 } 00192 } 00193