MetaFile.cpp
Go to the documentation of this file.
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   // parse xml
00073   // Typical format:
00074   //  <model>
00075   //  <name>cabinet1</name>
00076   //  <type>planar</type>
00077   //  <faces>1</faces>
00078   //  <dimensions>
00079   //    <scale>0.5</scale>
00080   //    <width>0.35</width>
00081   //    <height>0.69</height>
00082   //    <depth>0.3</depth>
00083   //    <face>
00084   //      <index>0</index>
00085   //      <width>0.35</width>
00086   //      <height>0.35</height>
00087   //      <oTf>...</oTf>
00088   //    </face>
00089   //  </dimensions>
00090   //  </model>
00091 
00092   xml_document<> doc;
00093   doc.parse<0>(buffer);    // 0 means default parse flags
00094 
00095   vector<xml_node<>* > upnodes;
00096   
00097   xml_node<> *node = doc.first_node(); // <model>
00098   node = node->first_node(); // first "attribute"
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     // old xml version lacked dimensions of the face
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   // Typical structure:
00135   //  <dimensions>
00136   //    <scale>0.5</scale>
00137   //    <width>0.35</width>
00138   //    <height>0.69</height>
00139   //    <depth>0.3</depth>
00140   //    <face>
00141   //      <index>0</index>
00142   //      <width>0.35</width>
00143   //      <height>0.35</height>
00144   //      <oTf>...</oTf>
00145   //    </face>
00146   //  </dimensions>
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") // type == "3D"
00155       data.Dimensions.Volume.Scale = MetaFile::parse<float>(value);
00156     else if(property == "width") // type == "planar"
00157       data.Dimensions.Planar.Width = MetaFile::parse<float>(value);
00158     else if(property == "height") // type == "planar"
00159       data.Dimensions.Planar.Height = MetaFile::parse<float>(value);
00160     else if(property == "depth") // type == "planar"
00161       data.Dimensions.Planar.Depth = MetaFile::parse<float>(value);
00162     else if(property == "face") // type == "planar"
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   // Typical structure:
00176   //    <face>
00177   //      <index>0</index>
00178   //      <width>0.35</width>
00179   //      <height>0.35</height>
00180   //      <oTf>...</oTf>
00181   //    </face>
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 


re_vision
Author(s): Dorian Galvez-Lopez
autogenerated on Sun Jan 5 2014 11:31:59