Go to the documentation of this file.00001 #ifndef OPENTISSUE_KINEMATICS_SKINNING_IO_SKINNING_CAL3D_XML_READ_H
00002 #define OPENTISSUE_KINEMATICS_SKINNING_IO_SKINNING_CAL3D_XML_READ_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <TinyXML/tinyxml.h>
00013
00014 #include <list>
00015 #include <cassert>
00016 #include <string>
00017 #include <sstream>
00018 #include <iostream>
00019
00020 namespace OpenTissue
00021 {
00022 namespace skinning
00023 {
00024
00025
00030 template<typename skin_type_lst>
00031 bool cal3d_xml_read(std::string const & filename, skin_type_lst & skin_lst)
00032 {
00033 typedef typename skin_type_lst::value_type value_type;
00034 typedef typename value_type::vector3_type vector3_type;
00035 typedef typename value_type::real_type real_type;
00036 typedef typename value_type::vertex_handle vertex_handle;
00037 typedef typename value_type::vertex_iterator vertex_iterator;
00038 typedef typename value_type::face_handle face_handle;
00039
00040 #ifdef TIXML_USE_STL
00041 TiXmlDocument xml_document(filename);
00042 #else
00043 TiXmlDocument xml_document(filename.c_str());
00044 #endif
00045
00046 if(!xml_document.LoadFile())
00047 {
00048 std::cerr << "file: " << filename << " not found" << std::endl;
00049 return false;
00050 }
00051
00052 std::stringstream str;
00053 TiXmlNode* node;
00054 TiXmlElement * xml_skin = xml_document.FirstChildElement( "MESH" );
00055 TiXmlElement * xml_mesh = xml_skin->FirstChildElement();
00056
00057 for( ; xml_mesh; xml_mesh=xml_mesh->NextSiblingElement())
00058 {
00059
00060 value_type skin;
00061 skin.clear();
00062
00063 if(xml_mesh)
00064 {
00065 skin.m_material_idx = -1;
00066 if(xml_mesh->Attribute("MATERIAL"))
00067 {
00068 std::istringstream str_stream(xml_mesh->Attribute("MATERIAL"));
00069 str_stream >> skin.m_material_idx;
00070 }
00071 }
00072
00073 TiXmlElement * xml_vertex = xml_mesh->FirstChildElement( "VERTEX" );
00074
00075 for( ; xml_vertex; xml_vertex=xml_vertex->NextSiblingElement("VERTEX") )
00076 {
00077 vertex_handle h = skin.add_vertex();
00078 assert(!h.is_null() || !"cal3d_xml_read(): Could not create vertex");
00079 vertex_iterator vertex = skin.get_vertex_iterator(h);
00080 if(xml_vertex->Attribute("idx"))
00081 {
00082 unsigned int idx;
00083 std::istringstream str_stream(xml_vertex->Attribute("ID"));
00084 str_stream >> idx;
00085 if(h.get_idx()!=idx)
00086 {
00087 std::cerr << "cal3d_xml_read(): Error in vertex indices" << std::endl;
00088 }
00089 }
00090
00091 TiXmlElement * xml_pos = xml_vertex->FirstChildElement( "POS" );
00092 float tx, ty, tz;
00093
00094 if( xml_pos )
00095 {
00096 node = xml_pos->FirstChild();
00097 TiXmlText* positiondata = node->ToText();
00098 str.clear();
00099 str << positiondata->Value();
00100 str >> tx >> ty >> tz;
00101
00102 vertex->m_coord(0) = tx;
00103 vertex->m_coord(1) = ty;
00104 vertex->m_coord(2) = tz;
00105 }
00106
00107 TiXmlElement * xml_norm = xml_vertex->FirstChildElement( "NORM" );
00108 float nx, ny, nz;
00109
00110 if( xml_norm )
00111 {
00112 node = xml_norm->FirstChild();
00113 TiXmlText* normaldata = node->ToText();
00114 str.clear();
00115 str << normaldata->Value();
00116 str >> nx >> ny >> nz;
00117
00118 vertex->m_normal(0) = nx;
00119 vertex->m_normal(1) = ny;
00120 vertex->m_normal(2) = nz;
00121 }
00122
00123 vertex->m_original_coord = vertex->m_coord;
00124 vertex->m_original_normal = vertex->m_normal;
00125
00126 vertex->m_influences = 0;
00127 if(xml_vertex->Attribute("NUMINFLUENCES"))
00128 {
00129 std::istringstream str_stream(xml_vertex->Attribute("NUMINFLUENCES"));
00130 str_stream >> vertex->m_influences;
00131 }
00132
00133
00134 TiXmlElement * xml_influence = xml_vertex->FirstChildElement( "INFLUENCE" );
00135 for(unsigned int cnt = 0 ; xml_influence; xml_influence=xml_influence->NextSiblingElement("INFLUENCE"),++cnt )
00136 {
00137 if(cnt>=6)
00138 {
00139 std::cout << "cal3d_xml_read(): exceeded available space for influences" << std::endl;
00140 break;
00141 }
00142 vertex->m_bone[cnt] = -1;
00143 vertex->m_weight[cnt] = 0;
00144
00145 if(xml_influence->Attribute("ID"))
00146 {
00147 std::istringstream str_stream(xml_influence->Attribute("ID"));
00148 str_stream >> vertex->m_bone[cnt];
00149 }
00150
00151 float weight = 0;
00152
00153 node = xml_influence->FirstChild();
00154 TiXmlText* weightdata = node->ToText();
00155 str.clear();
00156 str << weightdata->Value();
00157 str >> weight;
00158 vertex->m_weight[cnt] = weight;
00159 }
00160 }
00161
00162 TiXmlElement * xml_face = xml_mesh->FirstChildElement( "FACE" );
00163
00164 for( ; xml_face; xml_face=xml_face->NextSiblingElement("FACE") )
00165 {
00166 if(!xml_face->Attribute("VERTEXID"))
00167 {
00168 std::cerr << "xml_read(): Error missing vertices in face tag" << std::endl;
00169 }
00170 std::istringstream str_stream(xml_face->Attribute("VERTEXID"));
00171 std::list<vertex_handle> handles;
00172 while(!str_stream.eof())
00173 {
00174 unsigned int idx;
00175 str_stream >> idx;
00176 vertex_handle vh = skin.get_vertex_handle( idx );
00177 assert(!vh.is_null() || !"cal3d_xml_read(): Could not find vertex");
00178 handles.push_back( vh );
00179 }
00180 face_handle h = skin.add_face(handles.begin(),handles.end());
00181 assert(!h.is_null() || !"cal3d_xml_read() : Internal error, could not create face");
00182 }
00183
00184 skin_lst.push_back( skin );
00185
00186 }
00187
00188
00189
00190
00191 xml_document.Clear();
00192 return true;
00193 }
00194
00195 }
00196
00197 }
00198
00199
00200 #endif