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 chunk_size = header_.n_vertices_ * OMFormat::vector_size(chunk_header_);
391  _is.ignore(chunk_size);
392  bytes_ += chunk_size;
393  break;
394  }
395 
396  }
397 
398  // all chunk data has been read..?!
399  return vidx == header_.n_vertices_;
400 }
401 
402 
403 //-----------------------------------------------------------------------------
404 
405 bool _OMReader_::read_binary_face_chunk(std::istream &_is, BaseImporter &_bi, Options &_opt, bool _swap) const
406 {
407  using OMFormat::Chunk;
408 
409  assert( chunk_header_.entity_ == Chunk::Entity_Face);
410 
411  size_t fidx = 0;
412  OpenMesh::Vec3f v3f; // normal
413  OpenMesh::Vec3uc v3uc; // rgb
415 
416  switch (chunk_header_.type_) {
417  case Chunk::Type_Topology:
418  {
419  if (header_.version_ < OMFormat::mk_version(2,0))
420  {
421  // add faces based on vertex indices
422  BaseImporter::VHandles vhandles;
423  size_t nV = 0;
424  size_t vidx = 0;
425 
426  switch (header_.mesh_) {
427  case 'T':
428  nV = 3;
429  break;
430  case 'Q':
431  nV = 4;
432  break;
433  }
434 
435  for (; fidx < header_.n_faces_; ++fidx) {
436  if (header_.mesh_ == 'P')
437  bytes_ += restore(_is, nV, Chunk::Integer_16, _swap);
438 
439  vhandles.clear();
440  for (size_t j = 0; j < nV; ++j) {
441  bytes_ += restore(_is, vidx, Chunk::Integer_Size(chunk_header_.bits_), _swap);
442 
443  vhandles.push_back(VertexHandle(int(vidx)));
444  }
445 
446  _bi.add_face(vhandles);
447  }
448  }
449  else
450  {
451  // add faces by simply setting an incident halfedge
452  for (; fidx < header_.n_faces_; ++fidx)
453  {
454  int halfedge_id = 0;
455  bytes_ += restore( _is, halfedge_id, OMFormat::Chunk::Integer_Size(chunk_header_.bits_), _swap );
456 
457  _bi.add_face(HalfedgeHandle(halfedge_id));
458  }
459  }
460  }
461  break;
462 
463  case Chunk::Type_Normal:
464  assert( OMFormat::dimensions(chunk_header_) == size_t(OpenMesh::Vec3f::dim()));
465 
466  fileOptions_ += Options::FaceNormal;
467  for (; fidx < header_.n_faces_ && !_is.eof(); ++fidx) {
468  bytes_ += vector_restore(_is, v3f, _swap);
469  if( fileOptions_.face_has_normal() && _opt.face_has_normal())
470  _bi.set_normal(FaceHandle(int(fidx)), v3f);
471  }
472  break;
473 
474  case Chunk::Type_Color:
475 
476  assert( OMFormat::dimensions(chunk_header_) == 3);
477 
478  fileOptions_ += Options::FaceColor;
479  for (; fidx < header_.n_faces_ && !_is.eof(); ++fidx) {
480  bytes_ += vector_restore(_is, v3uc, _swap);
481  if( fileOptions_.face_has_color() && _opt.face_has_color())
482  _bi.set_color(FaceHandle(int(fidx)), v3uc);
483  }
484  break;
485  case Chunk::Type_Status:
486  {
487  assert( OMFormat::dimensions(chunk_header_) == 1);
488 
489  fileOptions_ += Options::Status;
490 
491  for (; fidx < header_.n_faces_ && !_is.eof(); ++fidx) {
492  bytes_ += restore(_is, status, _swap);
493  if (fileOptions_.face_has_status() && _opt.face_has_status())
494  _bi.set_status(FaceHandle(int(fidx)), status);
495  }
496  break;
497  }
498 
499  case Chunk::Type_Custom:
500 
501  bytes_ += restore_binary_custom_data(_is, _bi.kernel()->_get_fprop(property_name_), header_.n_faces_, _swap);
502 
503  fidx = header_.n_faces_;
504 
505  break;
506 
507  default: // skip unknown chunks
508  {
509  omerr() << "Unknown chunk type ignore!\n";
510  size_t chunk_size = OMFormat::chunk_data_size(header_, chunk_header_);
511  _is.ignore(chunk_size);
512  bytes_ += chunk_size;
513  }
514  }
515  return fidx == header_.n_faces_;
516 }
517 
518 
519 //-----------------------------------------------------------------------------
520 
521 bool _OMReader_::read_binary_edge_chunk(std::istream &_is, BaseImporter &_bi, Options &_opt, bool _swap) const
522 {
523  using OMFormat::Chunk;
524 
525  assert( chunk_header_.entity_ == Chunk::Entity_Edge);
526 
527  size_t b = bytes_;
528 
530 
531  switch (chunk_header_.type_) {
532  case Chunk::Type_Custom:
533 
534  bytes_ += restore_binary_custom_data(_is, _bi.kernel()->_get_eprop(property_name_), header_.n_edges_, _swap);
535 
536  break;
537 
538  case Chunk::Type_Status:
539  {
540  assert( OMFormat::dimensions(chunk_header_) == 1);
541 
542  fileOptions_ += Options::Status;
543 
544  for (size_t eidx = 0; eidx < header_.n_edges_ && !_is.eof(); ++eidx) {
545  bytes_ += restore(_is, status, _swap);
546  if (fileOptions_.edge_has_status() && _opt.edge_has_status())
547  _bi.set_status(EdgeHandle(int(eidx)), status);
548  }
549  break;
550  }
551 
552  default:
553  // skip unknown type
554  size_t chunk_size = OMFormat::chunk_data_size(header_, chunk_header_);
555  _is.ignore(chunk_size);
556  bytes_ += chunk_size;
557  }
558 
559  return b < bytes_;
560 }
561 
562 
563 //-----------------------------------------------------------------------------
564 
565 bool _OMReader_::read_binary_halfedge_chunk(std::istream &_is, BaseImporter &_bi, Options & _opt, bool _swap) const
566 {
567  using OMFormat::Chunk;
568 
569  assert( chunk_header_.entity_ == Chunk::Entity_Halfedge);
570 
571  size_t b = bytes_;
573 
574  switch (chunk_header_.type_) {
575  case Chunk::Type_Custom:
576 
577  bytes_ += restore_binary_custom_data(_is, _bi.kernel()->_get_hprop(property_name_), 2 * header_.n_edges_, _swap);
578  break;
579 
580  case Chunk::Type_Topology:
581  {
582  std::vector<HalfedgeHandle> next_halfedges;
583  for (size_t e_idx = 0; e_idx < header_.n_edges_; ++e_idx)
584  {
585  int next_id_0 = -1;
586  int to_vertex_id_0 = -1;
587  int face_id_0 = -1;
588  bytes_ += restore( _is, next_id_0, OMFormat::Chunk::Integer_Size(chunk_header_.bits_), _swap );
589  bytes_ += restore( _is, to_vertex_id_0, OMFormat::Chunk::Integer_Size(chunk_header_.bits_), _swap );
590  bytes_ += restore( _is, face_id_0, OMFormat::Chunk::Integer_Size(chunk_header_.bits_), _swap );
591 
592  int next_id_1 = -1;
593  int to_vertex_id_1 = -1;
594  int face_id_1 = -1;
595  bytes_ += restore( _is, next_id_1, OMFormat::Chunk::Integer_Size(chunk_header_.bits_), _swap );
596  bytes_ += restore( _is, to_vertex_id_1, OMFormat::Chunk::Integer_Size(chunk_header_.bits_), _swap );
597  bytes_ += restore( _is, face_id_1, OMFormat::Chunk::Integer_Size(chunk_header_.bits_), _swap );
598 
599  auto heh0 = _bi.add_edge(VertexHandle(to_vertex_id_1), VertexHandle(to_vertex_id_0));
600  auto heh1 = HalfedgeHandle(heh0.idx() + 1);
601 
602  next_halfedges.push_back(HalfedgeHandle(next_id_0));
603  next_halfedges.push_back(HalfedgeHandle(next_id_1));
604 
605  _bi.set_face(heh0, FaceHandle(face_id_0));
606  _bi.set_face(heh1, FaceHandle(face_id_1));
607  }
608 
609  for (size_t i = 0; i < next_halfedges.size(); ++i)
610  _bi.set_next(HalfedgeHandle(static_cast<int>(i)), next_halfedges[i]);
611  }
612 
613  break;
614 
615  case Chunk::Type_Status:
616  {
617  assert( OMFormat::dimensions(chunk_header_) == 1);
618 
619  fileOptions_ += Options::Status;
620 
621  for (size_t hidx = 0; hidx < header_.n_edges_ * 2 && !_is.eof(); ++hidx) {
622  bytes_ += restore(_is, status, _swap);
623  if (fileOptions_.halfedge_has_status() && _opt.halfedge_has_status())
624  _bi.set_status(HalfedgeHandle(int(hidx)), status);
625  }
626  break;
627  }
628 
629  default:
630  // skip unknown chunk
631  omerr() << "Unknown chunk type ignored!\n";
632  size_t chunk_size = OMFormat::chunk_data_size(header_, chunk_header_);
633  _is.ignore(chunk_size);
634  bytes_ += chunk_size;
635  }
636 
637  return b < bytes_;
638 }
639 
640 
641 //-----------------------------------------------------------------------------
642 
643 bool _OMReader_::read_binary_mesh_chunk(std::istream &_is, BaseImporter &_bi, Options & /* _opt */, bool _swap) const
644 {
645  using OMFormat::Chunk;
646 
647  assert( chunk_header_.entity_ == Chunk::Entity_Mesh);
648 
649  size_t b = bytes_;
650 
651  switch (chunk_header_.type_) {
652  case Chunk::Type_Custom:
653 
654  bytes_ += restore_binary_custom_data(_is, _bi.kernel()->_get_mprop(property_name_), 1, _swap);
655 
656  break;
657 
658  default:
659  // skip unknown chunk
660  size_t chunk_size = OMFormat::chunk_data_size(header_, chunk_header_);
661  _is.ignore(chunk_size);
662  bytes_ += chunk_size;
663  }
664 
665  return b < bytes_;
666 }
667 
668 
669 //-----------------------------------------------------------------------------
670 
671 
672 size_t _OMReader_::restore_binary_custom_data(std::istream& _is, BaseProperty* _bp, size_t _n_elem, bool _swap) const
673 {
674  assert( !_bp || (_bp->name() == property_name_));
675 
676  using OMFormat::Chunk;
677 
678  size_t bytes = 0;
679  Chunk::esize_t block_size;
680  Chunk::PropertyName custom_prop;
681 
682  bytes += restore(_is, block_size, OMFormat::Chunk::Integer_32, _swap);
683 
684  if (_bp) {
685  size_t n_bytes = _bp->size_of(_n_elem);
686 
687  if (((n_bytes == BaseProperty::UnknownSize) || (n_bytes == block_size))
688  && (_bp->element_size() == BaseProperty::UnknownSize || (_n_elem * _bp->element_size() == block_size))) {
689 #if defined(OM_DEBUG)
690  size_t b;
691  bytes += (b=_bp->restore( _is, _swap ));
692 #else
693  bytes += _bp->restore(_is, _swap);
694 #endif
695 
696 #if defined(OM_DEBUG)
697  assert( block_size == b );
698 #endif
699 
700  assert( block_size == _bp->size_of());
701 
702  block_size = 0;
703  } else {
704  omerr() << "Warning! Property " << _bp->name() << " not loaded: " << "Mismatching data sizes!n";
705  }
706  }
707 
708  if (block_size) {
709  _is.ignore(block_size);
710  bytes += block_size;
711  }
712 
713  return bytes;
714 }
715 
716 
717 //-----------------------------------------------------------------------------
718 
719 //=============================================================================
720 } // namespace IO
721 } // namespace OpenMesh
722 //=============================================================================
Swap byte order in binary mode.
Definition: Options.hh:103
Handle for a edge entity.
Definition: Handles.hh:134
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
Handle for a face entity.
Definition: Handles.hh:141
_OMReader_ __OMReaderInstance
Declare the single entity of the OM reader.
Definition: OMReader.cc:73
Has (r) / store (w) vertex colors.
Definition: Options.hh:105
Has (r) / store (w) face colors.
Definition: Options.hh:109
Handle for a halfedge entity.
Definition: Handles.hh:127
Handle for a vertex entity.
Definition: Handles.hh:120
static constexpr int dim()
returns dimension of the vector (deprecated)
Definition: Vector11T.hh:102
bool register_module(BaseReader *_bl)
Definition: IOManager.hh:217
virtual size_t size_of() const
Return size of property in bytes.
bool read(const std::string &_filename, BaseImporter &_bi, Options &_opt) override
Definition: OMReader.cc:90
virtual size_t element_size() const =0
Size of one element in bytes or UnknownSize if not known.
const std::string & name() const
Return the name of the property.
Set options for reader/writer modules.
Definition: Options.hh:90
Has (r) / store (w) status properties.
Definition: Options.hh:114
virtual size_t restore(std::istream &_istr, bool _swap)=0
Has (r) / store (w) vertex normals.
Definition: Options.hh:104
static const size_t UnknownSize
Indicates an error when a size is returned by a member.
Definition: BaseProperty.hh:65
virtual bool can_u_read(const std::string &_filename) const override
Returns true if writer can parse _filename (checks extension). _filename can also provide an extensio...
Definition: OMReader.cc:234
_IOManager_ & IOManager()
Definition: IOManager.cc:72
Has (r) / store (w) face normals.
Definition: Options.hh:108
big endian (Motorola&#39;s 68x family, DEC Alpha, MIPS)
Definition: Endian.hh:79
Set binary mode for r/w.
Definition: Options.hh:100
Has (r) / store (w) texture coordinates.
Definition: Options.hh:106
static Type local()
Return endian type of host system.
Definition: Endian.hh:83