NGL  6.5
The NCCA Graphics Library
NCCAPointBake.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2010 Jon Macey
3 
4  This program is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17 
18 #include "NCCAPointBake.h"
19 #include "rapidxml/rapidxml.hpp"
20 #include <boost/lexical_cast.hpp>
21 #include <boost/tokenizer.hpp>
22 #include <cstring>
23 //----------------------------------------------------------------------------------------------------------------------
26 //----------------------------------------------------------------------------------------------------------------------
27 
28 namespace ngl
29 {
30  typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
31 
32 //----------------------------------------------------------------------------------------------------------------------
34 {
35  m_numFrames=0;
36  m_currFrame=0;
37  m_nVerts=0;
38  m_startFrame=0;
39  m_endFrame=0;
40  m_mesh=0;
41  m_binFile=false;
42 }
43 
44 bool NCCAPointBake::loadPointBake(const std::string &_fileName) noexcept
45 {
46  m_numFrames=0;
47  m_currFrame=0;
48  m_nVerts=0;
49  m_startFrame=0;
50  m_endFrame=0;
51  m_mesh=0;
52  m_binFile=false;
53  rapidxml::xml_node<> * rootNode;
54  // Read the xml file into a vector
55  std::ifstream xmlFile (_fileName.c_str() );
56  if(!xmlFile.is_open())
57  {
58  std::cerr<<"Could not open file\n";
59  return false;
60  }
61  std::vector<char> buffer((std::istreambuf_iterator<char>(xmlFile)), std::istreambuf_iterator<char>());
62  buffer.push_back('\0');
64 
65  doc.parse<rapidxml::parse_trim_whitespace>(&buffer[0]);
66  rootNode=doc.first_node();
67  if(rootNode->name() !=std::string("NCCAPointBake"))
68  {
69  std::cerr<<"this is not a pointbake file \n";
70  return false;
71  }
72 
73  rapidxml::xml_node<> * child=rootNode->first_node("MeshName");
74  m_meshName=child->value();
75  std::cerr<<"found mesh "<<m_meshName<<"\n";
76 
77 
78  child=rootNode->first_node("NumVerts");
79  m_nVerts=boost::lexical_cast<unsigned int>(child->value());
80  std::cerr<<"NumVerts "<<m_nVerts<<"\n";
81  child=rootNode->first_node("StartFrame");
82  m_startFrame=boost::lexical_cast<unsigned int>(child->value());
83  std::cerr<<"StartFrame"<<m_startFrame<<"\n";
84  child=rootNode->first_node("EndFrame");
85  m_endFrame=boost::lexical_cast<unsigned int>(child->value());
86  std::cerr<<"EndFrame"<<m_endFrame<<"\n";
87  child=rootNode->first_node("NumFrames");
88  m_numFrames=boost::lexical_cast< unsigned int>(child->value());
89  std::cerr<<"EndFrame "<<m_numFrames<<"\n";
90  //first allocate base pointer [vertex]
91  m_data.resize(m_numFrames);
92  //cout <<"Size is now"<<m_data.size()<<endl;
93  //now for each of these we need to allocate more space
94  // NOTE the use of a reference here as we are changing the size
95  for(auto &data : m_data)
96  {
97  data.resize(m_nVerts);
98  }
99  unsigned int CurrentFrame=0;
100  // this is the line we wish to parse
101  std::string lineBuffer;
102  // say which separators should be used in this
103  // case Spaces, Tabs and return \ new line
104  boost::char_separator<char> sep(" \t\r\n");
105  // now traverse each frame and grab the data
106  for(child=rootNode->first_node("Frame"); child; child=child->next_sibling())
107  {
108  std::cerr<<"doing frame "<<child->first_attribute("number")->value()<<"\n";
109  CurrentFrame=boost::lexical_cast<unsigned int>(child->first_attribute("number")->value());
110  CurrentFrame-=m_startFrame;
111  std::flush(std::cerr);
112 
113  for(rapidxml::xml_node<> * vertex=child->first_node("Vertex"); vertex; vertex=vertex->next_sibling())
114  {
115  unsigned int index=boost::lexical_cast<unsigned int>(vertex->first_attribute("number")->value());
116  lineBuffer=vertex->value();
117  tokenizer tokens(lineBuffer, sep);
118  tokenizer::iterator firstWord = tokens.begin();
119  Real x=boost::lexical_cast<Real>(*firstWord++);
120  Real y=boost::lexical_cast<Real>(*firstWord++);
121  Real z=boost::lexical_cast<Real>(*firstWord++);
122  m_data[CurrentFrame][index].set(x,y,z);
123 
124  }
125 
126  }
127  return true;
128 }
129 
130 
131 
132 
133 //----------------------------------------------------------------------------------------------------------------------
135 {
136 
137 }
138 //----------------------------------------------------------------------------------------------------------------------
139 NCCAPointBake::NCCAPointBake( const std::string &_fileName) noexcept
140 {
141  loadPointBake(_fileName);
142 }
143 //----------------------------------------------------------------------------------------------------------------------
144 void NCCAPointBake::setFrame( const unsigned int _frame) noexcept
145 {
146  m_currFrame=_frame;
147 }
148 
149 bool NCCAPointBake::loadBinaryPointBake( const std::string &_fileName) noexcept
150 {
151  // open a file stream for ip in binary mode
152  std::fstream file;
153  file.open(_fileName.c_str(),std::ios::in | std::ios::binary);
154  // see if it worked
155  if (!file.is_open())
156  {
157  std::cerr<<"problems Opening File "<<_fileName<<std::endl;
158  return false;
159  }
160  // lets read in the header and see if the file is valid
161  char header[11];
162  file.read(header,10*sizeof(char));
163  header[10]=0; // for strcmp we need \n
164  // basically I used the magick string ngl::bin (I presume unique in files!) and
165  // we test against it.
166  if(strcmp(header,"ngl::binpb"))
167  {
168  // best close the file and exit
169  file.close();
170  std::cout<<"this is not an ngl::binpb file "<<std::endl;
171  return false;
172  }
173 
175  //file.read(reinterpret_cast <char *> (&m_nVerts),sizeof(unsigned long int));
176 
177  file.read(reinterpret_cast <char *>(&m_numFrames),sizeof(unsigned int));
178  file.read(reinterpret_cast <char *>(&m_currFrame),sizeof(unsigned int));
179  file.read(reinterpret_cast <char *>(&m_nVerts),sizeof(unsigned int));
180  file.read(reinterpret_cast <char *>(&m_startFrame),sizeof(unsigned int));
181  file.read(reinterpret_cast <char *>(&m_binFile),sizeof(bool));
182  std::cout <<"Loaded header\n";
183  std::cout<<m_numFrames<<"\n";
184  std::cout<<m_currFrame<<"\n";
185  std::cout<<m_nVerts<<"\n";
186  std::cout<<m_startFrame<<"\n";
187  std::cout<<m_binFile<<"\n";
188 
189  m_data.resize(m_numFrames);
190  for(unsigned int frame =0; frame<m_numFrames; ++frame)
191  {
192  m_data[frame].resize(m_nVerts);
193  for(unsigned int v=0; v< m_nVerts; ++v)
194  {
195  file.read( reinterpret_cast <char *>(&m_data[frame][v].m_x),sizeof(Real));
196  file.read( reinterpret_cast <char *>(&m_data[frame][v].m_y),sizeof(Real));
197  file.read( reinterpret_cast <char *>(&m_data[frame][v].m_z),sizeof(Real));
198  }
199  }
200  return true;
201 }
202 
203 bool NCCAPointBake::saveBinaryPointBake( const std::string &_fileName) noexcept
204 {
205  // so basically we need to save all the state data from the abstract mesh
206  // then map the vbo on the gpu and dump that in one go, this means we have to
207  // call CreateVBO first the Save
208  std::fstream file;
209  file.open(_fileName.c_str(),std::ios::out | std::ios::binary);
210  if (!file.is_open())
211  {
212  std::cerr<<"problems Opening File "<<_fileName<<std::endl;
213  return false;
214  }
215 
216  // lets write out our own Magic Number file ID
217  const std::string header("ngl::binpb");
218  file.write(header.c_str(),static_cast<long>(header.length()));
219  m_binFile=true;
220  file.write(reinterpret_cast <char *>(&m_numFrames),sizeof(unsigned int));
221  file.write(reinterpret_cast <char *>(&m_currFrame),sizeof(unsigned int));
222  file.write(reinterpret_cast <char *>(&m_nVerts),sizeof(unsigned int));
223  file.write(reinterpret_cast <char *>(&m_startFrame),sizeof(unsigned int));
224  file.write(reinterpret_cast <char *>(&m_binFile),sizeof(bool));
225  std::cout<<m_numFrames<<"\n";
226  std::cout<<m_currFrame<<"\n";
227  std::cout<<m_nVerts<<"\n";
228  std::cout<<m_startFrame<<"\n";
229  std::cout<<m_binFile<<"\n";
230 
231  // now write out data
232  for(unsigned int frame =0; frame<m_numFrames; ++frame)
233  {
234  for(unsigned int v=0; v< m_nVerts; ++v)
235  {
236  file.write( reinterpret_cast <char *>(&m_data[frame][v].m_x),sizeof(Real));
237  file.write( reinterpret_cast <char *>(&m_data[frame][v].m_y),sizeof(Real));
238  file.write( reinterpret_cast <char *>(&m_data[frame][v].m_z),sizeof(Real));
239  }
240  }
241 
242  file.close();
243  return true;
244 }
245 
246 void NCCAPointBake::setMeshToFrame( const unsigned int _frame) noexcept
247 {
248  // map the m_obj's vbo dat
249  Real *ptr=m_mesh->mapVAOVerts();
250  std::vector <Face> faces=m_mesh->getFaceList();
251  //unsigned int nFaces=faces.size();
252  // loop for each of the faces
253  unsigned int step=0;
254  for(auto face : faces)
255  {
256  // now for each triangle in the face (remember we ensured tri when loading)
257  // loop for all the verts and set the new vert value
258  // the data is packed uv, nx,ny,nz then x,y,z
259  // as we only want to change x,y,z, we need to skip over
260  // stuff
261 
262  for(unsigned int j=0;j<3;++j)
263  {
264  ptr[step+5]=m_data[_frame][face.m_vert[j]].m_x;
265  ptr[step+6]=m_data[_frame][face.m_vert[j]].m_y;
266  ptr[step+7]=m_data[_frame][face.m_vert[j]].m_z;
267  step+=8;
268  }
269 
270  }
271 
272  // unmap the vbo as we have finished updating
273  m_mesh->unMapVAO();
274  m_currFrame=_frame;
275  }
276 
277 
278 
279 
280 //----------------------------------------------------------------------------------------------------------------------
282 {
283  std::cout<<"doing attach mesh\n";
284  if(_mesh->m_nVerts != m_nVerts)
285  {
286  std::cerr <<" Mesh can't be attached to this data as vert count does not match\n";
287  std::cerr<<"mesh verts "<<_mesh->m_nVerts<<" file verts "<<m_nVerts<<"\n";
288  return false;
289  }
290 
291  else
292  {
293  m_mesh=_mesh;
294  return true;
295  }
296 
297 }
298 
299 
300 //----------------------------------------------------------------------------------------------------------------------
301 std::vector<Vec3> & NCCAPointBake::getRawDataPointerAtFrame(unsigned int _f) noexcept
302 {
303  NGL_ASSERT(_f<=m_numFrames);
304  return m_data[_f];
305 }
306 
307 
308 
309 } // end ngl namespace
310 //----------------------------------------------------------------------------------------------------------------------
This file contains rapidxml parser and DOM implementation.
GLdouble GLdouble z
Definition: glew.h:1562
bool loadBinaryPointBake(const std::string &_fileName) noexcept
method to load a binary point baked file
void setFrame(const unsigned int frame) noexcept
Set the current Frame and map the clip for that frame to the obj.
Ch * value() const
Definition: rapidxml.hpp:692
unsigned int m_startFrame
the start frame
std::vector< std::vector< Vec3 > > m_data
The actual data of the clip stored per vertex in sequence v0 - vn and then per frame frame index is a...
bool attachMesh(AbstractMesh *_mesh) noexcept
method to attach a mesh to the data this method will check for basic vetex compatibility and then re-...
GLint GLint GLint GLint GLint GLint y
Definition: glew.h:1255
unsigned int m_nVerts
Number of verts in the actual clip.
void parse(Ch *text)
Definition: rapidxml.hpp:1381
bool m_binFile
flag to indicate if we have a binary or xml based file loaded
GLint GLenum GLsizei GLint GLsizei const void * data
Definition: glew.h:1382
bool saveBinaryPointBake(const std::string &_fileName) noexcept
method to save a binary point baked file basically re-ordered data only
implementation files for RibExport class
Definition: AABB.cpp:22
GLuint in
Definition: glew.h:11550
boost::tokenizer< boost::char_separator< char > > tokenizer
xml_node< Ch > * first_node(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const
Definition: rapidxml.hpp:936
PRECISION Real
create a variable called Real which is the main data type we use (GLfloat for most cases) ...
Definition: Types.h:127
~NCCAPointBake() noexcept
the dtor erases all clip data allocated and also destroys the Obj reference held in the clip ...
simple point baked animation data for animation data export
an abstract base mesh used to build specific meshes such as Obj
Definition: AbstractMesh.h:105
const GLuint GLenum const void * binary
Definition: glew.h:3514
const GLdouble * v
Definition: glew.h:1394
bool loadPointBake(const std::string &_fileName) noexcept
method to load a point baked file
unsigned int m_numFrames
the number of frames in the clip file
std::string m_meshName
the name of the mesh
AbstractMesh * m_mesh
pointer to mesh attatched to data
xml_attribute< Ch > * first_attribute(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const
Definition: rapidxml.hpp:1025
GLuint buffer
Definition: glew.h:1683
const int parse_trim_whitespace
Definition: rapidxml.hpp:238
Real * mapVAOVerts() noexcept
map the VBO vertex data
std::vector< Face > getFaceList() noexcept
accessor for the Face data
Definition: AbstractMesh.h:225
GLuint index
Definition: glew.h:1817
xml_node< Ch > * next_sibling(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const
Definition: rapidxml.hpp:1004
std::vector< Vec3 > & getRawDataPointerAtFrame(unsigned int _f) noexcept
get a Raw data pointer to the un-sorted PointBake for a particular frame
GLint GLint GLint GLint GLint x
Definition: glew.h:1255
#define NGL_ASSERT(X)
re-define the standard assert to work for ngl first check to see if assert is defined and undef it th...
Definition: NGLassert.h:53
void unMapVAO() noexcept
unmap the VBO based
void setMeshToFrame(const unsigned int _frame) noexcept
set the attached mesh to the current frame
NCCAPointBake() noexcept
ctor for the clip
unsigned int m_currFrame
Current active frame when animating.
unsigned int m_endFrame
the end frame
GLsizei const GLchar *const * string
Definition: glew.h:1847
GLenum GLuint GLint GLenum face
Definition: glew.h:4628