Developer Documentation
OMReader.cc
1 /* ========================================================================= *
2  * *
3  * OpenMesh *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openmesh.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenMesh. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39  * *
40  * ========================================================================= */
41 
42 
43 
44 
45 //== INCLUDES =================================================================
46 
47 
48 //STL
49 #include <vector>
50 #include <istream>
51 #include <fstream>
52 
53 // OpenMesh
56 #include <OpenMesh/Core/Utils/Endian.hh>
57 #include <OpenMesh/Core/IO/OMFormat.hh>
58 #include <OpenMesh/Core/IO/reader/OMReader.hh>
59 #include <OpenMesh/Core/IO/writer/OMWriter.hh>
60 
61 
62 //=== NAMESPACES ==============================================================
63 
64 
65 namespace OpenMesh {
66 namespace IO {
67 
68 
69 //=== INSTANCIATE =============================================================
70 
71 
72 // register the OMReader singleton with MeshReader
74 _OMReader_& OMReader() { return __OMReaderInstance; }
75 
76 
77 
78 //=== IMPLEMENTATION ==========================================================
79 
80 
81 _OMReader_::_OMReader_()
82 {
83  IOManager().register_module(this);
84 }
85 
86 
87 //-----------------------------------------------------------------------------
88 
89 
90 bool _OMReader_::read(const std::string& _filename, BaseImporter& _bi, Options& _opt)
91 {
92  // check whether importer can give us an OpenMesh BaseKernel
93  if (!_bi.kernel())
94  return false;
95 
96  _opt += Options::Binary; // only binary format supported!
97  fileOptions_ = Options::Binary;
98 
99  // Open file
100  std::ifstream ifs(_filename.c_str(), std::ios::binary);
101 
102  /* Clear formatting flag skipws (Skip whitespaces). If set, operator>> will
103  * skip bytes set to whitespace chars (e.g. 0x20 bytes) in
104  * Property<bool>::restore.
105  */
106  ifs.unsetf(std::ios::skipws);
107 
108  if (!ifs.is_open() || !ifs.good()) {
109  omerr() << "[OMReader] : cannot not open file " << _filename << std::endl;
110  return false;
111  }
112 
113  // Pass stream to read method, remember result
114  bool result = read(ifs, _bi, _opt);
115 
116  // close input stream
117  ifs.close();
118 
119  _opt = _opt & fileOptions_;
120 
121  return result;
122 }
123 
124 //-----------------------------------------------------------------------------
125 
126 
127 bool _OMReader_::read(std::istream& _is, BaseImporter& _bi, Options& _opt)
128 {
129  // check whether importer can give us an OpenMesh BaseKernel
130  if (!_bi.kernel())
131  return false;
132 
133  _opt += Options::Binary; // only binary format supported!
134  fileOptions_ = Options::Binary;
135 
136  if (!_is.good()) {
137  omerr() << "[OMReader] : cannot read from stream " << std::endl;
138  return false;
139  }
140 
141  // Pass stream to read method, remember result
142  bool result = read_binary(_is, _bi, _opt);
143 
144  if (result)
145  _opt += Options::Binary;
146 
147  _opt = _opt & fileOptions_;
148 
149  return result;
150 }
151 
152 
153 
154 //-----------------------------------------------------------------------------
155 
156 bool _OMReader_::read_ascii(std::istream& /* _is */, BaseImporter& /* _bi */, Options& /* _opt */) const
157 {
158  // not supported yet!
159  return false;
160 }
161 
162 
163 //-----------------------------------------------------------------------------
164 
165 bool _OMReader_::read_binary(std::istream& _is, BaseImporter& _bi, Options& _opt) const
166 {
167  bool swap = _opt.check(Options::Swap) || (Endian::local() == Endian::MSB);
168 
169  // Initialize byte counter
170  bytes_ = 0;
171 
172  bytes_ += restore(_is, header_, swap);
173 
174 
175  if (header_.version_ > _OMWriter_::get_version())
176  {
177  omerr() << "File uses .om version " << OMFormat::as_string(header_.version_) << " but reader only "
178  << "supports up to version " << OMFormat::as_string(_OMWriter_::get_version()) << ".\n"
179  << "Please update your OpenMesh." << std::endl;
180  return false;
181  }
182 
183 
184  while (!_is.eof()) {
185  bytes_ += restore(_is, chunk_header_, swap);
186 
187  if (_is.eof())
188  break;
189 
190  // Is this a named property restore the name
191  if (chunk_header_.name_) {
192  OMFormat::Chunk::PropertyName pn;
193  bytes_ += restore(_is, property_name_, swap);
194  }
195 
196  // Read in the property data. If it is an anonymous or unknown named
197  // property, then skip data.
198  switch (chunk_header_.entity_) {
199  case OMFormat::Chunk::Entity_Vertex:
200  if (!read_binary_vertex_chunk(_is, _bi, _opt, swap))
201  return false;
202  break;
203  case OMFormat::Chunk::Entity_Face:
204  if (!read_binary_face_chunk(_is, _bi, _opt, swap))
205  return false;
206  break;
207  case OMFormat::Chunk::Entity_Edge:
208  if (!read_binary_edge_chunk(_is, _bi, _opt, swap))
209  return false;
210  break;
211  case OMFormat::Chunk::Entity_Halfedge:
212  if (!read_binary_halfedge_chunk(_is, _bi, _opt, swap))
213  return false;
214  break;
215  case OMFormat::Chunk::Entity_Mesh:
216  if (!read_binary_mesh_chunk(_is, _bi, _opt, swap))
217  return false;
218  break;
219  case OMFormat::Chunk::Entity_Sentinel:
220  return true;
221  default:
222  return false;
223  }
224 
225  }
226 
227  // File was successfully parsed.
228  return true;
229 }
230 
231 
232 //-----------------------------------------------------------------------------
233 
234 bool _OMReader_::can_u_read(const std::string& _filename) const
235 {
236  // !!! Assuming BaseReader::can_u_parse( std::string& )
237  // does not call BaseReader::read_magic()!!!
238  if (this->BaseReader::can_u_read(_filename)) {
239  std::ifstream ifile(_filename.c_str());
240  if (ifile && can_u_read(ifile))
241  return true;
242  }
243  return false;
244 }
245 
246 //-----------------------------------------------------------------------------
247 
248 bool _OMReader_::can_u_read(std::istream& _is) const
249 {
250  std::vector<char> evt;
251  evt.reserve(20);
252 
253  // read first 4 characters into a buffer
254  while (evt.size() < 4)
255  evt.push_back(static_cast<char>(_is.get()));
256 
257  // put back all read characters
258  std::vector<char>::reverse_iterator it = evt.rbegin();
259  while (it != evt.rend())
260  _is.putback(*it++);
261 
262  // evaluate header information
263  OMFormat::Header *hdr = (OMFormat::Header*) &evt[0];
264 
265  // first two characters must be 'OM'
266  if (hdr->magic_[0] != 'O' || hdr->magic_[1] != 'M')
267  return false;
268 
269  // 3rd characters defines the mesh type:
270  switch (hdr->mesh_) {
271  case 'T': // Triangle Mesh
272  case 'Q': // Quad Mesh
273  case 'P': // Polygonal Mesh
274  break;
275  default: // ?
276  return false;
277  }
278 
279  // 4th characters encodes the version
280  return supports(hdr->version_);
281 }
282 
283 //-----------------------------------------------------------------------------
284 
285 bool _OMReader_::supports(const OMFormat::uint8 /* version */) const
286 {
287  return true;
288 }
289 
290 
291 //-----------------------------------------------------------------------------
292 
293 bool _OMReader_::read_binary_vertex_chunk(std::istream &_is, BaseImporter &_bi, Options &_opt, bool _swap) const
294 {
295  using OMFormat::Chunk;
296 
297  assert( chunk_header_.entity_ == Chunk::Entity_Vertex);
298 
299  OpenMesh::Vec3f v3f;
300  OpenMesh::Vec2f v2f;
301  OpenMesh::Vec3uc v3uc; // rgb
303 
304  OMFormat::Chunk::PropertyName custom_prop;
305 
306  size_t vidx = 0;
307  switch (chunk_header_.type_) {
308  case Chunk::Type_Pos:
309  assert( OMFormat::dimensions(chunk_header_) == size_t(OpenMesh::Vec3f::dim()));
310 
311  for (; vidx < header_.n_vertices_ && !_is.eof(); ++vidx) {
312  bytes_ += vector_restore(_is, v3f, _swap);
313  _bi.add_vertex(v3f);
314  }
315  break;
316 
317  case Chunk::Type_Normal:
318  assert( OMFormat::dimensions(chunk_header_) == size_t(OpenMesh::Vec3f::dim()));
319 
320  fileOptions_ += Options::VertexNormal;
321  for (; vidx < header_.n_vertices_ && !_is.eof(); ++vidx) {
322  bytes_ += vector_restore(_is, v3f, _swap);
323  if (fileOptions_.vertex_has_normal() && _opt.vertex_has_normal())
324  _bi.set_normal(VertexHandle(int(vidx)), v3f);
325  }
326  break;
327 
328  case Chunk::Type_Texcoord:
329  assert( OMFormat::dimensions(chunk_header_) == size_t(OpenMesh::Vec2f::dim()));
330 
331  fileOptions_ += Options::VertexTexCoord;
332  for (; vidx < header_.n_vertices_ && !_is.eof(); ++vidx) {
333  bytes_ += vector_restore(_is, v2f, _swap);
334  if (fileOptions_.vertex_has_texcoord() && _opt.vertex_has_texcoord())
335  _bi.set_texcoord(VertexHandle(int(vidx)), v2f);
336  }
337  break;
338 
339  case Chunk::Type_Color:
340 
341  assert( OMFormat::dimensions(chunk_header_) == 3);
342 
343  fileOptions_ += Options::VertexColor;
344 
345  for (; vidx < header_.n_vertices_ && !_is.eof(); ++vidx) {
346  bytes_ += vector_restore(_is, v3uc, _swap);
347  if (fileOptions_.vertex_has_color() && _opt.vertex_has_color())
348  _bi.set_color(VertexHandle(int(vidx)), v3uc);
349  }
350  break;
351 
352  case Chunk::Type_Status:
353  {
354  assert( OMFormat::dimensions(chunk_header_) == 1);
355 
356  fileOptions_ += Options::Status;
357 
358  for (; vidx < header_.n_vertices_ && !_is.eof(); ++vidx) {
359  bytes_ += restore(_is, status, _swap);
360  if (fileOptions_.vertex_has_status() && _opt.vertex_has_status())
361  _bi.set_status(VertexHandle(int(vidx)), status);
362  }
363  break;
364  }
365 
366  case Chunk::Type_Custom:
367 
368  bytes_ += restore_binary_custom_data(_is, _bi.kernel()->_get_vprop(property_name_), header_.n_vertices_, _swap);
369 
370  vidx = header_.n_vertices_;
371 
372  break;
373 
374  case Chunk::Type_Topology:
375  {
376  for (; vidx < header_.n_vertices_; ++vidx)
377  {
378  int halfedge_id = 0;
379  bytes_ += restore( _is, halfedge_id, OMFormat::Chunk::Integer_Size(chunk_header_.bits_), _swap );
380 
381  _bi.set_halfedge(VertexHandle(static_cast<int>(vidx)), HalfedgeHandle(halfedge_id));
382  }
383  }
384 
385  break;
386 
387  default: // skip unknown chunks
388  {
389  omerr() << "Unknown chunk type ignored!\n";
390  size_t size_of = header_.n_vertices_ * OMFormat::vector_size(chunk_header_);
391  _is.ignore(size_of);
392  bytes_ += size_of;
393  }
394  }
395 
396  // all chunk data has been read..?!
397  return vidx == header_.n_vertices_;
398 }
399 
400 
401 //-----------------------------------------------------------------------------
402 
403 bool _OMReader_::read_binary_face_chunk(std::istream &_is, BaseImporter &_bi, Options &_opt, bool _swap) const
404 {
405  using OMFormat::Chunk;
406 
407  assert( chunk_header_.entity_ == Chunk::Entity_Face);
408 
409  size_t fidx = 0;
410  OpenMesh::Vec3f v3f; // normal
411  OpenMesh::Vec3uc v3uc; // rgb
413 
414  switch (chunk_header_.type_) {
415  case Chunk::Type_Topology:
416  {
417  if (header_.version_ < OMFormat::mk_version(2,0))
418  {
419  // add faces based on vertex indices
420  BaseImporter::VHandles vhandles;
421  size_t nV = 0;
422  size_t vidx = 0;
423 
424  switch (header_.mesh_) {
425  case 'T':
426  nV = 3;
427  break;
428  case 'Q':
429  nV = 4;
430  break;
431  }
432 
433  for (; fidx < header_.n_faces_; ++fidx) {
434  if (header_.mesh_ == 'P')
435  bytes_ += restore(_is, nV, Chunk::Integer_16, _swap);
436 
437  vhandles.clear();
438  for (size_t j = 0; j < nV; ++j) {
439  bytes_ += restore(_is, vidx, Chunk::Integer_Size(chunk_header_.bits_), _swap);
440 
441  vhandles.push_back(VertexHandle(int(vidx)));
442  }
443 
444  _bi.add_face(vhandles);
445  }
446  }
447  else
448  {
449  // add faces by simply setting an incident halfedge
450  for (; fidx < header_.n_faces_; ++fidx)
451  {
452  int halfedge_id = 0;
453  bytes_ += restore( _is, halfedge_id, OMFormat::Chunk::Integer_Size(chunk_header_.bits_), _swap );
454 
455  _bi.add_face(HalfedgeHandle(halfedge_id));
456  }
457  }
458  }
459  break;
460 
461  case Chunk::Type_Normal:
462  assert( OMFormat::dimensions(chunk_header_) == size_t(OpenMesh::Vec3f::dim()));
463 
464  fileOptions_ += Options::FaceNormal;
465  for (; fidx < header_.n_faces_ && !_is.eof(); ++fidx) {
466  bytes_ += vector_restore(_is, v3f, _swap);
467  if( fileOptions_.face_has_normal() && _opt.face_has_normal())
468  _bi.set_normal(FaceHandle(int(fidx)), v3f);
469  }
470  break;
471 
472  case Chunk::Type_Color:
473 
474  assert( OMFormat::dimensions(chunk_header_) == 3);
475 
476  fileOptions_ += Options::FaceColor;
477  for (; fidx < header_.n_faces_ && !_is.eof(); ++fidx) {
478  bytes_ += vector_restore(_is, v3uc, _swap);
479  if( fileOptions_.face_has_color() && _opt.face_has_color())
480  _bi.set_color(FaceHandle(int(fidx)), v3uc);
481  }
482  break;
483  case Chunk::Type_Status:
484  {
485  assert( OMFormat::dimensions(chunk_header_) == 1);
486 
487  fileOptions_ += Options::Status;
488 
489  for (; fidx < header_.n_faces_ && !_is.eof(); ++fidx) {
490  bytes_ += restore(_is, status, _swap);
491  if (fileOptions_.face_has_status() && _opt.face_has_status())
492  _bi.set_status(FaceHandle(int(fidx)), status);
493  }
494  break;
495  }
496 
497  case Chunk::Type_Custom:
498 
499  bytes_ += restore_binary_custom_data(_is, _bi.kernel()->_get_fprop(property_name_), header_.n_faces_, _swap);
500 
501  fidx = header_.n_faces_;
502 
503  break;
504 
505  default: // skip unknown chunks
506  {
507  omerr() << "Unknown chunk type ignore!\n";
508  size_t size_of = OMFormat::chunk_data_size(header_, chunk_header_);
509  _is.ignore(size_of);
510  bytes_ += size_of;
511  }
512  }
513  return fidx == header_.n_faces_;
514 }
515 
516 
517 //-----------------------------------------------------------------------------
518 
519 bool _OMReader_::read_binary_edge_chunk(std::istream &_is, BaseImporter &_bi, Options &_opt, bool _swap) const
520 {
521  using OMFormat::Chunk;
522 
523  assert( chunk_header_.entity_ == Chunk::Entity_Edge);
524 
525  size_t b = bytes_;
526 
528 
529  switch (chunk_header_.type_) {
530  case Chunk::Type_Custom:
531 
532  bytes_ += restore_binary_custom_data(_is, _bi.kernel()->_get_eprop(property_name_), header_.n_edges_, _swap);
533 
534  break;
535 
536  case Chunk::Type_Status:
537  {
538  assert( OMFormat::dimensions(chunk_header_) == 1);
539 
540  fileOptions_ += Options::Status;
541 
542  for (size_t eidx = 0; eidx < header_.n_edges_ && !_is.eof(); ++eidx) {
543  bytes_ += restore(_is, status, _swap);
544  if (fileOptions_.edge_has_status() && _opt.edge_has_status())
545  _bi.set_status(EdgeHandle(int(eidx)), status);
546  }
547  break;
548  }
549 
550  default:
551  // skip unknown type
552  size_t size_of = OMFormat::chunk_data_size(header_, chunk_header_);
553  _is.ignore(size_of);
554  bytes_ += size_of;
555  }
556 
557  return b < bytes_;
558 }
559 
560 
561 //-----------------------------------------------------------------------------
562 
563 bool _OMReader_::read_binary_halfedge_chunk(std::istream &_is, BaseImporter &_bi, Options & _opt, bool _swap) const
564 {
565  using OMFormat::Chunk;
566 
567  assert( chunk_header_.entity_ == Chunk::Entity_Halfedge);
568 
569  size_t b = bytes_;
571 
572  switch (chunk_header_.type_) {
573  case Chunk::Type_Custom:
574 
575  bytes_ += restore_binary_custom_data(_is, _bi.kernel()->_get_hprop(property_name_), 2 * header_.n_edges_, _swap);
576  break;
577 
578  case Chunk::Type_Topology:
579  {
580  std::vector<HalfedgeHandle> next_halfedges;
581  for (size_t e_idx = 0; e_idx < header_.n_edges_; ++e_idx)
582  {
583  int next_id_0 = -1;
584  int to_vertex_id_0 = -1;
585  int face_id_0 = -1;
586  bytes_ += restore( _is, next_id_0, OMFormat::Chunk::Integer_Size(chunk_header_.bits_), _swap );
587  bytes_ += restore( _is, to_vertex_id_0, OMFormat::Chunk::Integer_Size(chunk_header_.bits_), _swap );
588  bytes_ += restore( _is, face_id_0, OMFormat::Chunk::Integer_Size(chunk_header_.bits_), _swap );
589 
590  int next_id_1 = -1;
591  int to_vertex_id_1 = -1;
592  int face_id_1 = -1;
593  bytes_ += restore( _is, next_id_1, OMFormat::Chunk::Integer_Size(chunk_header_.bits_), _swap );
594  bytes_ += restore( _is, to_vertex_id_1, OMFormat::Chunk::Integer_Size(chunk_header_.bits_), _swap );
595  bytes_ += restore( _is, face_id_1, OMFormat::Chunk::Integer_Size(chunk_header_.bits_), _swap );
596 
597  auto heh0 = _bi.add_edge(VertexHandle(to_vertex_id_1), VertexHandle(to_vertex_id_0));
598  auto heh1 = HalfedgeHandle(heh0.idx() + 1);
599 
600  next_halfedges.push_back(HalfedgeHandle(next_id_0));
601  next_halfedges.push_back(HalfedgeHandle(next_id_1));
602 
603  _bi.set_face(heh0, FaceHandle(face_id_0));
604  _bi.set_face(heh1, FaceHandle(face_id_1));
605  }
606 
607  for (size_t i = 0; i < next_halfedges.size(); ++i)
608  _bi.set_next(HalfedgeHandle(static_cast<int>(i)), next_halfedges[i]);
609  }
610 
611  break;
612 
613  case Chunk::Type_Status:
614  {
615  assert( OMFormat::dimensions(chunk_header_) == 1);
616 
617  fileOptions_ += Options::Status;
618 
619  for (size_t hidx = 0; hidx < header_.n_edges_ * 2 && !_is.eof(); ++hidx) {
620  bytes_ += restore(_is, status, _swap);
621  if (fileOptions_.halfedge_has_status() && _opt.halfedge_has_status())
622  _bi.set_status(HalfedgeHandle(int(hidx)), status);
623  }
624  break;
625  }
626 
627  default:
628  // skip unknown chunk
629  omerr() << "Unknown chunk type ignored!\n";
630  size_t size_of = OMFormat::chunk_data_size(header_, chunk_header_);
631  _is.ignore(size_of);
632  bytes_ += size_of;
633  }
634 
635  return b < bytes_;
636 }
637 
638 
639 //-----------------------------------------------------------------------------
640 
641 bool _OMReader_::read_binary_mesh_chunk(std::istream &_is, BaseImporter &_bi, Options & /* _opt */, bool _swap) const
642 {
643  using OMFormat::Chunk;
644 
645  assert( chunk_header_.entity_ == Chunk::Entity_Mesh);
646 
647  size_t b = bytes_;
648 
649  switch (chunk_header_.type_) {
650  case Chunk::Type_Custom:
651 
652  bytes_ += restore_binary_custom_data(_is, _bi.kernel()->_get_mprop(property_name_), 1, _swap);
653 
654  break;
655 
656  default:
657  // skip unknown chunk
658  size_t size_of = OMFormat::chunk_data_size(header_, chunk_header_);
659  _is.ignore(size_of);
660  bytes_ += size_of;
661  }
662 
663  return b < bytes_;
664 }
665 
666 
667 //-----------------------------------------------------------------------------
668 
669 
670 size_t _OMReader_::restore_binary_custom_data(std::istream& _is, BaseProperty* _bp, size_t _n_elem, bool _swap) const
671 {
672  assert( !_bp || (_bp->name() == property_name_));
673 
674  using OMFormat::Chunk;
675 
676  size_t bytes = 0;
677  Chunk::esize_t block_size;
678  Chunk::PropertyName custom_prop;
679 
680  bytes += restore(_is, block_size, OMFormat::Chunk::Integer_32, _swap);
681 
682  if (_bp) {
683  size_t n_bytes = _bp->size_of(_n_elem);
684 
685  if (((n_bytes == BaseProperty::UnknownSize) || (n_bytes == block_size))
686  && (_bp->element_size() == BaseProperty::UnknownSize || (_n_elem * _bp->element_size() == block_size))) {
687 #if defined(OM_DEBUG)
688  size_t b;
689  bytes += (b=_bp->restore( _is, _swap ));
690 #else
691  bytes += _bp->restore(_is, _swap);
692 #endif
693 
694 #if defined(OM_DEBUG)
695  assert( block_size == b );
696 #endif
697 
698  assert( block_size == _bp->size_of());
699 
700  block_size = 0;
701  } else {
702  omerr() << "Warning! Property " << _bp->name() << " not loaded: " << "Mismatching data sizes!n";
703  }
704  }
705 
706  if (block_size) {
707  _is.ignore(block_size);
708  bytes += block_size;
709  }
710 
711  return bytes;
712 }
713 
714 
715 //-----------------------------------------------------------------------------
716 
717 //=============================================================================
718 } // namespace IO
719 } // namespace OpenMesh
720 //=============================================================================
Has (r) / store (w) vertex colors.
Definition: Options.hh:105
Swap byte order in binary mode.
Definition: Options.hh:103
Handle for a vertex entity.
Definition: Handles.hh:120
size_t size_of(const T &_v)
Definition: StoreRestore.hh:89
virtual bool can_u_read(const std::string &_filename) const
Returns true if writer can parse _filename (checks extension). _filename can also provide an extensio...
Definition: BaseReader.cc:77
bool register_module(BaseReader *_bl)
Definition: IOManager.hh:217
Has (r) / store (w) face colors.
Definition: Options.hh:109
static const size_t UnknownSize
Indicates an error when a size is returned by a member.
Definition: BaseProperty.hh:65
Handle for a halfedge entity.
Definition: Handles.hh:127
Has (r) / store (w) face normals.
Definition: Options.hh:108
_IOManager_ & IOManager()
Definition: IOManager.cc:72
virtual size_t restore(std::istream &_istr, bool _swap)=0
virtual bool can_u_read(const std::string &_filename) const
Returns true if writer can parse _filename (checks extension). _filename can also provide an extensio...
Definition: OMReader.cc:234
big endian (Motorola&#39;s 68x family, DEC Alpha, MIPS)
Definition: Endian.hh:79
const std::string & name() const
Return the name of the property.
Has (r) / store (w) texture coordinates.
Definition: Options.hh:106
static Type local()
Return endian type of host system.
Definition: Endian.hh:83
Has (r) / store (w) status properties.
Definition: Options.hh:114
bool read(const std::string &_filename, BaseImporter &_bi, Options &_opt)
Definition: OMReader.cc:90
Handle for a face entity.
Definition: Handles.hh:141
_OMReader_ __OMReaderInstance
Declare the single entity of the OM reader.
Definition: OMReader.cc:73
virtual size_t size_of() const
Return size of property in bytes.
Set options for reader/writer modules.
Definition: Options.hh:90
Handle for a edge entity.
Definition: Handles.hh:134
static constexpr int dim()
returns dimension of the vector (deprecated)
Definition: Vector11T.hh:102
Set binary mode for r/w.
Definition: Options.hh:100
virtual size_t element_size() const =0
Size of one element in bytes or UnknownSize if not known.
Has (r) / store (w) vertex normals.
Definition: Options.hh:104