OMReader.cc 17.5 KB
Newer Older
Jan Möbius's avatar
Jan Möbius committed
1
/* ========================================================================= *
Jan Möbius's avatar
Jan Möbius committed
2
3
 *                                                                           *
 *                               OpenMesh                                    *
Jan Möbius's avatar
Jan Möbius committed
4
 *           Copyright (c) 2001-2015, RWTH-Aachen University                 *
Jan Möbius's avatar
Typo    
Jan Möbius committed
5
 *           Department of Computer Graphics and Multimedia                  *
Jan Möbius's avatar
Jan Möbius committed
6
7
 *                          All rights reserved.                             *
 *                            www.openmesh.org                               *
Jan Möbius's avatar
Jan Möbius committed
8
 *                                                                           *
9
 *---------------------------------------------------------------------------*
Jan Möbius's avatar
Jan Möbius committed
10
11
 * This file is part of OpenMesh.                                            *
 *---------------------------------------------------------------------------*
12
 *                                                                           *
Jan Möbius's avatar
Jan Möbius committed
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 * Redistribution and use in source and binary forms, with or without        *
 * modification, are permitted provided that the following conditions        *
 * are met:                                                                  *
 *                                                                           *
 * 1. Redistributions of source code must retain the above copyright notice, *
 *    this list of conditions and the following disclaimer.                  *
 *                                                                           *
 * 2. Redistributions in binary form must reproduce the above copyright      *
 *    notice, this list of conditions and the following disclaimer in the    *
 *    documentation and/or other materials provided with the distribution.   *
 *                                                                           *
 * 3. Neither the name of the copyright holder nor the names of its          *
 *    contributors may be used to endorse or promote products derived from   *
 *    this software without specific prior written permission.               *
 *                                                                           *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       *
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A           *
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  *
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,       *
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR        *
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    *
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      *
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        *
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              *
Jan Möbius's avatar
Jan Möbius committed
39
40
 *                                                                           *
 * ========================================================================= */
41
42

/*===========================================================================*\
43
 *                                                                           *
44
45
 *   $Revision$                                                         *
 *   $Date$                   *
Jan Möbius's avatar
Jan Möbius committed
46
47
48
49
50
51
52
53
 *                                                                           *
\*===========================================================================*/


//== INCLUDES =================================================================


//STL
54
55
#include <vector>
#include <istream>
Jan Möbius's avatar
Jan Möbius committed
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <fstream>

// OpenMesh
#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/System/omstream.hh>
#include <OpenMesh/Core/Utils/Endian.hh>
#include <OpenMesh/Core/IO/OMFormat.hh>
#include <OpenMesh/Core/IO/reader/OMReader.hh>


//=== NAMESPACES ==============================================================


namespace OpenMesh {
namespace IO {


//=== INSTANCIATE =============================================================


// register the OMReader singleton with MeshReader
_OMReader_  __OMReaderInstance;
_OMReader_&  OMReader() { return __OMReaderInstance; }



//=== IMPLEMENTATION ==========================================================


_OMReader_::_OMReader_()
{
87
  IOManager().register_module(this);
Jan Möbius's avatar
Jan Möbius committed
88
89
90
91
92
93
}


//-----------------------------------------------------------------------------


94
bool _OMReader_::read(const std::string& _filename, BaseImporter& _bi, Options& _opt)
Jan Möbius's avatar
Jan Möbius committed
95
96
{
  // check whether importer can give us an OpenMesh BaseKernel
97
98
  if (!_bi.kernel())
    return false;
Jan Möbius's avatar
Jan Möbius committed
99
100

  _opt += Options::Binary; // only binary format supported!
101
  fileOptions_ = Options::Binary;
Jan Möbius's avatar
Jan Möbius committed
102
103

  // Open file
104
  std::ifstream ifs(_filename.c_str(), std::ios::binary);
105
106
107
108
109
110
111

  /* Clear formatting flag skipws (Skip whitespaces). If set, operator>> will
   * skip bytes set to whitespace chars (e.g. 0x20 bytes) in
   * Property<bool>::restore.
   */
  ifs.unsetf(std::ios::skipws);

112
113
  if (!ifs.is_open() || !ifs.good()) {
    omerr() << "[OMReader] : cannot not open file " << _filename << std::endl;
Jan Möbius's avatar
Jan Möbius committed
114
115
    return false;
  }
116

Jan Möbius's avatar
Jan Möbius committed
117
118
  // Pass stream to read method, remember result
  bool result = read(ifs, _bi, _opt);
119

Jan Möbius's avatar
Jan Möbius committed
120
121
  // close input stream
  ifs.close();
122

123
124
  _opt = _opt & fileOptions_;

Jan Möbius's avatar
Jan Möbius committed
125
126
127
128
129
130
  return result;
}

//-----------------------------------------------------------------------------


131
bool _OMReader_::read(std::istream& _is, BaseImporter& _bi, Options& _opt)
Jan Möbius's avatar
Jan Möbius committed
132
{
133
  // check whether importer can give us an OpenMesh BaseKernel
134
135
  if (!_bi.kernel())
    return false;
136
137

  _opt += Options::Binary; // only binary format supported!
138
  fileOptions_ = Options::Binary;
139

140
141
  if (!_is.good()) {
    omerr() << "[OMReader] : cannot read from stream " << std::endl;
142
143
144
145
146
147
    return false;
  }

  // Pass stream to read method, remember result
  bool result = read_binary(_is, _bi, _opt);

148
149
  if (result)
    _opt += Options::Binary;
Jan Möbius's avatar
Jan Möbius committed
150

151
152
  _opt = _opt & fileOptions_;

153
  return result;
Jan Möbius's avatar
Jan Möbius committed
154
155
156
157
158
159
}



//-----------------------------------------------------------------------------

160
bool _OMReader_::read_ascii(std::istream& /* _is */, BaseImporter& /* _bi */, Options& /* _opt */) const
Jan Möbius's avatar
Jan Möbius committed
161
162
163
164
165
166
167
168
{
  // not supported yet!
  return false;
}


//-----------------------------------------------------------------------------

169
bool _OMReader_::read_binary(std::istream& _is, BaseImporter& _bi, Options& _opt) const
Jan Möbius's avatar
Jan Möbius committed
170
171
172
{
  bool swap = _opt.check(Options::Swap) || (Endian::local() == Endian::MSB);

173
  // Initialize byte counter
174
  bytes_ = 0;
Jan Möbius's avatar
Jan Möbius committed
175

176
  bytes_ += restore(_is, header_, swap);
Jan Möbius's avatar
Jan Möbius committed
177
178


179
180
  while (!_is.eof()) {
    bytes_ += restore(_is, chunk_header_, swap);
Jan Möbius's avatar
Jan Möbius committed
181

182
    if (_is.eof())
Jan Möbius's avatar
Jan Möbius committed
183
184
185
      break;

    // Is this a named property restore the name
186
    if (chunk_header_.name_) {
Jan Möbius's avatar
Jan Möbius committed
187
      OMFormat::Chunk::PropertyName pn;
188
      bytes_ += restore(_is, property_name_, swap);
Jan Möbius's avatar
Jan Möbius committed
189
190
191
192
    }

    // Read in the property data. If it is an anonymous or unknown named
    // property, then skip data.
193
    switch (chunk_header_.entity_) {
194
      case OMFormat::Chunk::Entity_Vertex:
195
196
197
        if (!read_binary_vertex_chunk(_is, _bi, _opt, swap))
          return false;
        break;
Jan Möbius's avatar
Jan Möbius committed
198
      case OMFormat::Chunk::Entity_Face:
199
200
201
        if (!read_binary_face_chunk(_is, _bi, _opt, swap))
          return false;
        break;
Jan Möbius's avatar
Jan Möbius committed
202
      case OMFormat::Chunk::Entity_Edge:
203
204
205
        if (!read_binary_edge_chunk(_is, _bi, _opt, swap))
          return false;
        break;
Jan Möbius's avatar
Jan Möbius committed
206
      case OMFormat::Chunk::Entity_Halfedge:
207
208
209
        if (!read_binary_halfedge_chunk(_is, _bi, _opt, swap))
          return false;
        break;
Jan Möbius's avatar
Jan Möbius committed
210
      case OMFormat::Chunk::Entity_Mesh:
211
212
213
        if (!read_binary_mesh_chunk(_is, _bi, _opt, swap))
          return false;
        break;
214
215
      case OMFormat::Chunk::Entity_Sentinel:
        return true;
Jan Möbius's avatar
Jan Möbius committed
216
      default:
217
        return false;
Jan Möbius's avatar
Jan Möbius committed
218
    }
Jan Möbius's avatar
Jan Möbius committed
219

Jan Möbius's avatar
Jan Möbius committed
220
221
222
223
224
225
226
227
228
  }

  // File was successfully parsed.
  return true;
}


//-----------------------------------------------------------------------------

229
bool _OMReader_::can_u_read(const std::string& _filename) const
Jan Möbius's avatar
Jan Möbius committed
230
231
232
{
  // !!! Assuming BaseReader::can_u_parse( std::string& )
  // does not call BaseReader::read_magic()!!!
233
234
235
  if (this->BaseReader::can_u_read(_filename)) {
    std::ifstream ifile(_filename.c_str());
    if (ifile && can_u_read(ifile))
236
      return true;
Jan Möbius's avatar
Jan Möbius committed
237
238
239
240
241
  }
  return false;
}

//-----------------------------------------------------------------------------
242

243
bool _OMReader_::can_u_read(std::istream& _is) const
Jan Möbius's avatar
Jan Möbius committed
244
245
246
247
248
{
  std::vector<char> evt;
  evt.reserve(20);

  // read first 4 characters into a buffer
249
250
  while (evt.size() < 4)
    evt.push_back(static_cast<char>(_is.get()));
Jan Möbius's avatar
Jan Möbius committed
251

252
  // put back all read characters
Jan Möbius's avatar
Jan Möbius committed
253
  std::vector<char>::reverse_iterator it = evt.rbegin();
254
255
  while (it != evt.rend())
    _is.putback(*it++);
Jan Möbius's avatar
Jan Möbius committed
256
257

  // evaluate header information
258
  OMFormat::Header *hdr = (OMFormat::Header*) &evt[0];
Jan Möbius's avatar
Jan Möbius committed
259
260
261
262
263
264

  // first two characters must be 'OM'
  if (hdr->magic_[0] != 'O' || hdr->magic_[1] != 'M')
    return false;

  // 3rd characters defines the mesh type:
265
  switch (hdr->mesh_) {
Jan Möbius's avatar
Jan Möbius committed
266
267
268
269
270
271
272
    case 'T': // Triangle Mesh
    case 'Q': // Quad Mesh
    case 'P': // Polygonal Mesh
      break;
    default:  // ?
      return false;
  }
273

Jan Möbius's avatar
Jan Möbius committed
274
  // 4th characters encodes the version
275
  return supports(hdr->version_);
Jan Möbius's avatar
Jan Möbius committed
276
277
278
279
}

//-----------------------------------------------------------------------------

280
bool _OMReader_::supports(const OMFormat::uint8 /* version */) const
Jan Möbius's avatar
Jan Möbius committed
281
282
283
284
285
286
287
{
  return true;
}


//-----------------------------------------------------------------------------

288
bool _OMReader_::read_binary_vertex_chunk(std::istream &_is, BaseImporter &_bi, Options &_opt, bool _swap) const
Jan Möbius's avatar
Jan Möbius committed
289
290
291
{
  using OMFormat::Chunk;

292
  assert( chunk_header_.entity_ == Chunk::Entity_Vertex);
293

294
295
  OpenMesh::Vec3f v3f;
  OpenMesh::Vec2f v2f;
Jan Möbius's avatar
Jan Möbius committed
296
297
298
299
  OpenMesh::Vec3uc v3uc; // rgb

  OMFormat::Chunk::PropertyName custom_prop;

300
301
  size_t vidx = 0;
  switch (chunk_header_.type_) {
Jan Möbius's avatar
Jan Möbius committed
302
    case Chunk::Type_Pos:
303
      assert( OMFormat::dimensions(chunk_header_) == size_t(OpenMesh::Vec3f::dim()));
Jan Möbius's avatar
Jan Möbius committed
304

305
306
307
      for (; vidx < header_.n_vertices_ && !_is.eof(); ++vidx) {
        bytes_ += vector_restore(_is, v3f, _swap);
        _bi.add_vertex(v3f);
Jan Möbius's avatar
Jan Möbius committed
308
309
310
311
      }
      break;

    case Chunk::Type_Normal:
312
      assert( OMFormat::dimensions(chunk_header_) == size_t(OpenMesh::Vec3f::dim()));
Jan Möbius's avatar
Jan Möbius committed
313

314
      fileOptions_ += Options::VertexNormal;
315
316
      for (; vidx < header_.n_vertices_ && !_is.eof(); ++vidx) {
        bytes_ += vector_restore(_is, v3f, _swap);
317
        if (fileOptions_.vertex_has_normal() && _opt.vertex_has_normal())
318
          _bi.set_normal(VertexHandle(int(vidx)), v3f);
Jan Möbius's avatar
Jan Möbius committed
319
320
321
322
      }
      break;

    case Chunk::Type_Texcoord:
323
      assert( OMFormat::dimensions(chunk_header_) == size_t(OpenMesh::Vec2f::dim()));
Jan Möbius's avatar
Jan Möbius committed
324

325
      fileOptions_ += Options::VertexTexCoord;
326
327
      for (; vidx < header_.n_vertices_ && !_is.eof(); ++vidx) {
        bytes_ += vector_restore(_is, v2f, _swap);
328
        if (fileOptions_.vertex_has_texcoord() && _opt.vertex_has_texcoord())
329
          _bi.set_texcoord(VertexHandle(int(vidx)), v2f);
Jan Möbius's avatar
Jan Möbius committed
330
      }
331
      break;
Jan Möbius's avatar
Jan Möbius committed
332
333
334

    case Chunk::Type_Color:

335
      assert( OMFormat::dimensions(chunk_header_) == 3);
Jan Möbius's avatar
Jan Möbius committed
336

337
      fileOptions_ += Options::VertexColor;
338

339
340
      for (; vidx < header_.n_vertices_ && !_is.eof(); ++vidx) {
        bytes_ += vector_restore(_is, v3uc, _swap);
341
        if (fileOptions_.vertex_has_color() && _opt.vertex_has_color())
342
          _bi.set_color(VertexHandle(int(vidx)), v3uc);
Jan Möbius's avatar
Jan Möbius committed
343
344
345
346
      }
      break;

    case Chunk::Type_Custom:
347

348
      bytes_ += restore_binary_custom_data(_is, _bi.kernel()->_get_vprop(property_name_), header_.n_vertices_, _swap);
Jan Möbius's avatar
Jan Möbius committed
349
350
351
352
353
354
355
356

      vidx = header_.n_vertices_;

      break;

    default: // skip unknown chunks
    {
      omerr() << "Unknown chunk type ignored!\n";
357
358
      size_t size_of = header_.n_vertices_ * OMFormat::vector_size(chunk_header_);
      _is.ignore(size_of);
Jan Möbius's avatar
Jan Möbius committed
359
360
361
362
363
364
365
366
367
368
369
      bytes_ += size_of;
    }
  }

  // all chunk data has been read..?!
  return vidx == header_.n_vertices_;
}


//-----------------------------------------------------------------------------

370
bool _OMReader_::read_binary_face_chunk(std::istream &_is, BaseImporter &_bi, Options &_opt, bool _swap) const
Jan Möbius's avatar
Jan Möbius committed
371
372
373
{
  using OMFormat::Chunk;

374
  assert( chunk_header_.entity_ == Chunk::Entity_Face);
Jan Möbius's avatar
Jan Möbius committed
375

376
377
  size_t fidx = 0;
  OpenMesh::Vec3f v3f;  // normal
Jan Möbius's avatar
Jan Möbius committed
378
379
  OpenMesh::Vec3uc v3uc; // rgb

380
381
382
383
384
385
386
387
388
389
390
391
392
  switch (chunk_header_.type_) {
    case Chunk::Type_Topology: {
      BaseImporter::VHandles vhandles;
      size_t nV = 0;
      size_t vidx = 0;

      switch (header_.mesh_) {
        case 'T':
          nV = 3;
          break;
        case 'Q':
          nV = 4;
          break;
Jan Möbius's avatar
Jan Möbius committed
393
      }
394

395
396
397
      for (; fidx < header_.n_faces_; ++fidx) {
        if (header_.mesh_ == 'P')
          bytes_ += restore(_is, nV, Chunk::Integer_16, _swap);
Jan Möbius's avatar
Jan Möbius committed
398

399
400
401
        vhandles.clear();
        for (size_t j = 0; j < nV; ++j) {
          bytes_ += restore(_is, vidx, Chunk::Integer_Size(chunk_header_.bits_), _swap);
Jan Möbius's avatar
Jan Möbius committed
402

403
          vhandles.push_back(VertexHandle(int(vidx)));
404
        }
Jan Möbius's avatar
Jan Möbius committed
405

406
        _bi.add_face(vhandles);
Jan Möbius's avatar
Jan Möbius committed
407
408
      }
    }
409
      break;
Jan Möbius's avatar
Jan Möbius committed
410
411

    case Chunk::Type_Normal:
412
      assert( OMFormat::dimensions(chunk_header_) == size_t(OpenMesh::Vec3f::dim()));
Jan Möbius's avatar
Jan Möbius committed
413

414
      fileOptions_ += Options::FaceNormal;
415
416
      for (; fidx < header_.n_faces_ && !_is.eof(); ++fidx) {
        bytes_ += vector_restore(_is, v3f, _swap);
417
        if( fileOptions_.face_has_normal() && _opt.face_has_normal())
418
          _bi.set_normal(FaceHandle(int(fidx)), v3f);
Jan Möbius's avatar
Jan Möbius committed
419
420
421
422
423
      }
      break;

    case Chunk::Type_Color:

424
      assert( OMFormat::dimensions(chunk_header_) == 3);
Jan Möbius's avatar
Jan Möbius committed
425

426
      fileOptions_ += Options::FaceColor;
427
428
      for (; fidx < header_.n_faces_ && !_is.eof(); ++fidx) {
        bytes_ += vector_restore(_is, v3uc, _swap);
429
        if( fileOptions_.face_has_color() && _opt.face_has_color())
430
          _bi.set_color(FaceHandle(int(fidx)), v3uc);
Jan Möbius's avatar
Jan Möbius committed
431
432
433
434
      }
      break;

    case Chunk::Type_Custom:
435

436
      bytes_ += restore_binary_custom_data(_is, _bi.kernel()->_get_fprop(property_name_), header_.n_faces_, _swap);
Jan Möbius's avatar
Jan Möbius committed
437
438
439
440

      fidx = header_.n_faces_;

      break;
441

Jan Möbius's avatar
Jan Möbius committed
442
443
444
445
    default: // skip unknown chunks
    {
      omerr() << "Unknown chunk type ignore!\n";
      size_t size_of = OMFormat::chunk_data_size(header_, chunk_header_);
446
      _is.ignore(size_of);
447
      bytes_ += size_of;
Jan Möbius's avatar
Jan Möbius committed
448
449
450
451
452
453
454
455
    }
  }
  return fidx == header_.n_faces_;
}


//-----------------------------------------------------------------------------

456
bool _OMReader_::read_binary_edge_chunk(std::istream &_is, BaseImporter &_bi, Options &/*_opt */, bool _swap) const
Jan Möbius's avatar
Jan Möbius committed
457
458
459
{
  using OMFormat::Chunk;

460
  assert( chunk_header_.entity_ == Chunk::Entity_Edge);
Jan Möbius's avatar
Jan Möbius committed
461

462
  size_t b = bytes_;
Jan Möbius's avatar
Jan Möbius committed
463

464
  switch (chunk_header_.type_) {
465
    case Chunk::Type_Custom:
Jan Möbius's avatar
Jan Möbius committed
466

467
      bytes_ += restore_binary_custom_data(_is, _bi.kernel()->_get_eprop(property_name_), header_.n_edges_, _swap);
Jan Möbius's avatar
Jan Möbius committed
468
469
470
471
472
473

      break;

    default:
      // skip unknown type
      size_t size_of = OMFormat::chunk_data_size(header_, chunk_header_);
474
      _is.ignore(size_of);
Jan Möbius's avatar
Jan Möbius committed
475
476
477
478
479
480
481
482
483
      bytes_ += size_of;
  }

  return b < bytes_;
}


//-----------------------------------------------------------------------------

484
bool _OMReader_::read_binary_halfedge_chunk(std::istream &_is, BaseImporter &_bi, Options &/* _opt */, bool _swap) const
Jan Möbius's avatar
Jan Möbius committed
485
486
487
{
  using OMFormat::Chunk;

488
  assert( chunk_header_.entity_ == Chunk::Entity_Halfedge);
Jan Möbius's avatar
Jan Möbius committed
489
490
491

  size_t b = bytes_;

492
  switch (chunk_header_.type_) {
Jan Möbius's avatar
Jan Möbius committed
493
494
    case Chunk::Type_Custom:

495
      bytes_ += restore_binary_custom_data(_is, _bi.kernel()->_get_hprop(property_name_), 2 * header_.n_edges_, _swap);
Jan Möbius's avatar
Jan Möbius committed
496
497
498
499
500
501
      break;

    default:
      // skip unknown chunk
      omerr() << "Unknown chunk type ignored!\n";
      size_t size_of = OMFormat::chunk_data_size(header_, chunk_header_);
502
      _is.ignore(size_of);
Jan Möbius's avatar
Jan Möbius committed
503
504
505
506
507
508
509
510
511
      bytes_ += size_of;
  }

  return b < bytes_;
}


//-----------------------------------------------------------------------------

512
bool _OMReader_::read_binary_mesh_chunk(std::istream &_is, BaseImporter &_bi, Options & /* _opt */, bool _swap) const
Jan Möbius's avatar
Jan Möbius committed
513
514
515
{
  using OMFormat::Chunk;

516
  assert( chunk_header_.entity_ == Chunk::Entity_Mesh);
Jan Möbius's avatar
Jan Möbius committed
517
518
519

  size_t b = bytes_;

520
  switch (chunk_header_.type_) {
Jan Möbius's avatar
Jan Möbius committed
521
    case Chunk::Type_Custom:
522

523
      bytes_ += restore_binary_custom_data(_is, _bi.kernel()->_get_mprop(property_name_), 1, _swap);
524

Jan Möbius's avatar
Jan Möbius committed
525
526
527
528
529
      break;

    default:
      // skip unknown chunk
      size_t size_of = OMFormat::chunk_data_size(header_, chunk_header_);
530
      _is.ignore(size_of);
Jan Möbius's avatar
Jan Möbius committed
531
532
533
534
535
536
537
538
539
540
      bytes_ += size_of;
  }

  return b < bytes_;
}


//-----------------------------------------------------------------------------


541
size_t _OMReader_::restore_binary_custom_data(std::istream& _is, BaseProperty* _bp, size_t _n_elem, bool _swap) const
542
{
543
  assert( !_bp || (_bp->name() == property_name_));
Jan Möbius's avatar
Jan Möbius committed
544
545
546

  using OMFormat::Chunk;

547
548
  size_t bytes = 0;
  Chunk::esize_t block_size;
Jan Möbius's avatar
Jan Möbius committed
549
550
  Chunk::PropertyName custom_prop;

551
  bytes += restore(_is, block_size, OMFormat::Chunk::Integer_32, _swap);
Jan Möbius's avatar
Jan Möbius committed
552

553
554
  if (_bp) {
    size_t n_bytes = _bp->size_of(_n_elem);
Jan Möbius's avatar
Jan Möbius committed
555

556
557
    if (((n_bytes == BaseProperty::UnknownSize) || (n_bytes == block_size))
        && (_bp->element_size() == BaseProperty::UnknownSize || (_n_elem * _bp->element_size() == block_size))) {
Jan Möbius's avatar
Jan Möbius committed
558
#if defined(OM_DEBUG)
Jan Möbius's avatar
Jan Möbius committed
559
      size_t b;
Jan Möbius's avatar
Jan Möbius committed
560
561
      bytes += (b=_bp->restore( _is, _swap ));
#else
562
      bytes += _bp->restore(_is, _swap);
Jan Möbius's avatar
Jan Möbius committed
563
#endif
564

Jan Möbius's avatar
Jan Möbius committed
565
566
567
#if defined(OM_DEBUG)
      assert( block_size == b );
#endif
568
569

      assert( block_size == _bp->size_of());
Jan Möbius's avatar
Jan Möbius committed
570
571

      block_size = 0;
572
573
    } else {
      omerr() << "Warning! Property " << _bp->name() << " not loaded: " << "Mismatching data sizes!n";
Jan Möbius's avatar
Jan Möbius committed
574
575
576
    }
  }

577
578
579
  if (block_size) {
    _is.ignore(block_size);
    bytes += block_size;
Jan Möbius's avatar
Jan Möbius committed
580
581
582
583
584
585
586
587
588
589
590
591
  }

  return bytes;
}


//-----------------------------------------------------------------------------

//=============================================================================
} // namespace IO
} // namespace OpenMesh
//=============================================================================