00001
00033 #include "MetaFile.h"
00034
00035 #include <iostream>
00036 #include <string>
00037 #include <fstream>
00038 #include <sstream>
00039 #include <vector>
00040
00041 #include <opencv/cv.h>
00042
00043 #include "DUtils.h"
00044 #include "DUtilsCV.h"
00045 #include "rapidxml.hpp"
00046 #include "rapidxml_print.hpp"
00047
00048 using namespace std;
00049 using namespace rapidxml;
00050
00051
00052
00053
00054
00055 void MetaFile::readFile(const std::string &filename, MetaData &data)
00056 {
00057 data.reset();
00058
00059 fstream f(filename.c_str(), ios::in);
00060 if(!f.is_open()) throw string("MetaFile: cannot open ") + filename;
00061
00062 f.seekg(0, ios_base::end);
00063 long length = f.tellg();
00064 f.seekg(0, ios::beg);
00065
00066 char *buffer = new char [length+1];
00067 f.read(buffer, length);
00068 buffer[length] = '\0';
00069
00070 f.close();
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 xml_document<> doc;
00093 doc.parse<0>(buffer);
00094
00095 vector<xml_node<>* > upnodes;
00096
00097 xml_node<> *node = doc.first_node();
00098 node = node->first_node();
00099
00100 while(node != NULL)
00101 {
00102 std::string property = node->name();
00103 std::string value = node->value();
00104
00105 if(property == "name")
00106 data.Name = value;
00107 else if(property == "type")
00108 data.Type = value;
00109 else if(property == "faces")
00110 data.NFaces = MetaFile::parse<int>(value);
00111 else if(property == "dimensions")
00112 parseDimensions(data, node);
00113
00114 node = node->next_sibling();
00115 }
00116
00117 if(data.Type == "planar" && data.Dimensions.Planar.Faces.empty())
00118 {
00119
00120 data.Dimensions.Planar.Faces.resize(data.NFaces);
00121 data.Dimensions.Planar.Faces[0].Width = data.Dimensions.Planar.Width;
00122 data.Dimensions.Planar.Faces[0].Height = data.Dimensions.Planar.Height;
00123 data.Dimensions.Planar.Faces[0].oTf = cv::Mat::eye(4, 4, CV_64F);
00124 }
00125
00126 delete [] buffer;
00127 }
00128
00129
00130
00131 void MetaFile::parseDimensions(MetaFile::MetaData &data,
00132 rapidxml::xml_node<> *node)
00133 {
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148 node = node->first_node();
00149 while(node != NULL)
00150 {
00151 std::string property = node->name();
00152 std::string value = node->value();
00153
00154 if(property == "scale")
00155 data.Dimensions.Volume.Scale = MetaFile::parse<float>(value);
00156 else if(property == "width")
00157 data.Dimensions.Planar.Width = MetaFile::parse<float>(value);
00158 else if(property == "height")
00159 data.Dimensions.Planar.Height = MetaFile::parse<float>(value);
00160 else if(property == "depth")
00161 data.Dimensions.Planar.Depth = MetaFile::parse<float>(value);
00162 else if(property == "face")
00163 parseFace(data, node);
00164
00165 node = node->next_sibling();
00166 }
00167
00168 }
00169
00170
00171
00172 void MetaFile::parseFace(MetaFile::MetaData &data,
00173 rapidxml::xml_node<> *node)
00174 {
00175
00176
00177
00178
00179
00180
00181
00182
00183 int face_idx = -1;
00184 float w, h;
00185 w = h = 0;
00186 cv::Mat oTf;
00187
00188 node = node->first_node();
00189 while(node != NULL)
00190 {
00191 std::string property = node->name();
00192 std::string value = node->value();
00193
00194 if(property == "index")
00195 face_idx = MetaFile::parse<int>(value);
00196 else if(property == "width")
00197 w = MetaFile::parse<float>(value);
00198 else if(property == "height")
00199 h = MetaFile::parse<float>(value);
00200 else if(property == "oTf")
00201 {
00202 vector<string> vs;
00203 DUtils::StringFunctions::split(value, vs);
00204 vector<double> v = MetaFile::parse<double>(vs);
00205
00206 if(!v.empty())
00207 {
00208 oTf = (cv::Mat_<double>(4, 4) <<
00209 v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8],
00210 v[9], v[10], v[11], v[12], v[13], v[14], v[15]);
00211 }
00212 }
00213
00214 node = node->next_sibling();
00215 }
00216
00217 if(face_idx != -1)
00218 {
00219 if((int)data.Dimensions.Planar.Faces.size() <= face_idx)
00220 data.Dimensions.Planar.Faces.resize(face_idx + 1);
00221
00222 data.Dimensions.Planar.Faces[face_idx].Width = w;
00223 data.Dimensions.Planar.Faces[face_idx].Height = h;
00224 data.Dimensions.Planar.Faces[face_idx].oTf = oTf;
00225 }
00226
00227 }
00228
00229
00230
00231 void MetaFile::saveFile(const std::string &filename, const MetaData &data)
00232 {
00233 fstream f(filename.c_str(), ios::out);
00234 if(!f.is_open()) throw string("MetaFile: cannot open ") + filename;
00235
00236 xml_document<> doc;
00237 char *node_name = doc.allocate_string("model");
00238 xml_node<> *root_node = doc.allocate_node(node_element, node_name);
00239 doc.append_node(root_node);
00240
00241 string sscale = MetaFile::stringfy(data.Dimensions.Volume.Scale);
00242 string snfaces = MetaFile::stringfy(data.NFaces);
00243 string swidth = MetaFile::stringfy(data.Dimensions.Planar.Width);
00244 string sheight = MetaFile::stringfy(data.Dimensions.Planar.Height);
00245 string sdepth = MetaFile::stringfy(data.Dimensions.Planar.Depth);
00246
00247 root_node->append_node(doc.allocate_node(node_element,
00248 "name", data.Name.c_str() ));
00249
00250 root_node->append_node(doc.allocate_node(node_element,
00251 "type", data.Type.c_str() ));
00252
00253 root_node->append_node(doc.allocate_node(node_element,
00254 "faces", snfaces.c_str() ));
00255
00256 xml_node<> *dim_node = doc.allocate_node(node_element, "dimensions");
00257 root_node->append_node(dim_node);
00258
00259 if(data.Type == "planar")
00260 {
00261 dim_node->append_node(doc.allocate_node(node_element,
00262 "width", swidth.c_str() ));
00263 dim_node->append_node(doc.allocate_node(node_element,
00264 "height", sheight.c_str() ));
00265 dim_node->append_node(doc.allocate_node(node_element,
00266 "depth", sdepth.c_str() ));
00267
00268 for(unsigned int i = 0; i < data.Dimensions.Planar.Faces.size(); ++i)
00269 {
00270 xml_node<> *face_node = doc.allocate_node(node_element, "face");
00271 dim_node->append_node(face_node);
00272
00273 char *sindex = doc.allocate_string(MetaFile::stringfy(i).c_str());
00274 char *sw = doc.allocate_string(MetaFile::stringfy(
00275 data.Dimensions.Planar.Faces[i].Width).c_str());
00276 char *sh = doc.allocate_string(MetaFile::stringfy(
00277 data.Dimensions.Planar.Faces[i].Height).c_str());
00278
00279 face_node->append_node(doc.allocate_node(node_element, "index", sindex));
00280 face_node->append_node(doc.allocate_node(node_element, "width", sw));
00281 face_node->append_node(doc.allocate_node(node_element, "height", sh));
00282
00283 if(!data.Dimensions.Planar.Faces[i].oTf.empty())
00284 {
00285 double d[16];
00286 DUtilsCV::Types::vectorize(data.Dimensions.Planar.Faces[i].oTf, d);
00287
00288 char *sotf = doc.allocate_string(MetaFile::stringfy(d, 16).c_str());
00289
00290 face_node->append_node(doc.allocate_node(node_element, "oTf", sotf));
00291 }
00292 }
00293
00294 }
00295 else if(data.Type == "3D")
00296 {
00297 dim_node->append_node(doc.allocate_node(node_element,
00298 "scale", sscale.c_str() ));
00299 }
00300
00301 f << doc;
00302
00303 f.close();
00304 }
00305
00306
00307
00308