PLYReader.cc 41.2 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
 *                                                                           *
Mike Kremer's avatar
Mike Kremer committed
9
 *---------------------------------------------------------------------------*
Jan Möbius's avatar
Jan Möbius committed
10
11
12
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
 * This file is part of OpenMesh.                                            *
 *---------------------------------------------------------------------------*
 *                                                                           *
 * 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

/*===========================================================================*\
Mike Kremer's avatar
Mike Kremer committed
43
 *                                                                           *
44
45
 *   $Revision$                                                         *
 *   $Date$                   *
Jan Möbius's avatar
Jan Möbius committed
46
 *                                                                           *
Mike Kremer's avatar
Mike Kremer committed
47
 \*===========================================================================*/
Jan Möbius's avatar
Jan Möbius committed
48
49
50
51
52
53
54
55
56
57
58
59
60
61

#define LINE_LEN 4096

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

// OpenMesh
#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/System/omstream.hh>
#include <OpenMesh/Core/IO/reader/PLYReader.hh>
#include <OpenMesh/Core/IO/IOManager.hh>
#include <OpenMesh/Core/Utils/color_cast.hh>

//STL
#include <fstream>
62
#include <iostream>
Jan Möbius's avatar
Jan Möbius committed
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <memory>

#ifndef WIN32
#endif

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


namespace OpenMesh {
namespace IO {

//=============================================================================

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


Mike Kremer's avatar
Mike Kremer committed
79
80
_PLYReader_ __PLYReaderInstance;
_PLYReader_& PLYReader() {
81
    return __PLYReaderInstance;
Mike Kremer's avatar
Mike Kremer committed
82
}
Jan Möbius's avatar
Jan Möbius committed
83
84
85
86

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


Mike Kremer's avatar
Mike Kremer committed
87
_PLYReader_::_PLYReader_() {
88
    IOManager().register_module(this);
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

    // Store sizes in byte of each property type
    scalar_size_[ValueTypeINT8] = 1;
    scalar_size_[ValueTypeUINT8] = 1;
    scalar_size_[ValueTypeINT16] = 2;
    scalar_size_[ValueTypeUINT16] = 2;
    scalar_size_[ValueTypeINT32] = 4;
    scalar_size_[ValueTypeUINT32] = 4;
    scalar_size_[ValueTypeFLOAT32] = 4;
    scalar_size_[ValueTypeFLOAT64] = 8;

    scalar_size_[ValueTypeCHAR] = 1;
    scalar_size_[ValueTypeUCHAR] = 1;
    scalar_size_[ValueTypeSHORT] = 2;
    scalar_size_[ValueTypeUSHORT] = 2;
    scalar_size_[ValueTypeINT] = 4;
    scalar_size_[ValueTypeUINT] = 4;
    scalar_size_[ValueTypeFLOAT] = 4;
    scalar_size_[ValueTypeDOUBLE] = 8;
Jan Möbius's avatar
Jan Möbius committed
108
109
110
111
112
}

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


Mike Kremer's avatar
Mike Kremer committed
113
bool _PLYReader_::read(const std::string& _filename, BaseImporter& _bi, Options& _opt) {
114

115
    std::fstream in(_filename.c_str(), (std::ios_base::binary | std::ios_base::in) );
Jan Möbius's avatar
Jan Möbius committed
116

117
118
119
120
    if (!in.is_open() || !in.good()) {
        omerr() << "[PLYReader] : cannot not open file " << _filename << std::endl;
        return false;
    }
Jan Möbius's avatar
Jan Möbius committed
121

122
    bool result = read(in, _bi, _opt);
Jan Möbius's avatar
Jan Möbius committed
123

124
125
    in.close();
    return result;
Jan Möbius's avatar
Jan Möbius committed
126
127
128
129
130
}

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


131
132
133
134
135
136
137
bool _PLYReader_::read(std::istream& _in, BaseImporter& _bi, Options& _opt) {

    if (!_in.good()) {
        omerr() << "[PLYReader] : cannot not use stream" << std::endl;
        return false;
    }

138
139
    // filter relevant options for reading
    bool swap = _opt.check(Options::Swap);
Jan Möbius's avatar
Jan Möbius committed
140

141
    userOptions_ = _opt;
Jan Möbius's avatar
Jan Möbius committed
142

143
144
    // build options to be returned
    _opt.clear();
Jan Möbius's avatar
Jan Möbius committed
145

146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
    if (options_.vertex_has_normal() && userOptions_.vertex_has_normal()) {
        _opt += Options::VertexNormal;
    }
    if (options_.vertex_has_texcoord() && userOptions_.vertex_has_texcoord()) {
        _opt += Options::VertexTexCoord;
    }
    if (options_.vertex_has_color() && userOptions_.vertex_has_color()) {
        _opt += Options::VertexColor;
    }
    if (options_.face_has_color() && userOptions_.face_has_color()) {
        _opt += Options::FaceColor;
    }
    if (options_.is_binary()) {
        _opt += Options::Binary;
    }
161
162
163
    if (options_.color_is_float()) {
        _opt += Options::ColorFloat;
    }
164
165
166
    if (options_.check(Options::Custom) && userOptions_.check(Options::Custom)) {
        _opt += Options::Custom;
    }
Jan Möbius's avatar
Jan Möbius committed
167

168
169
170
    //    //force user-choice for the alpha value when reading binary
    //    if ( options_.is_binary() && userOptions_.color_has_alpha() )
    //      options_ += Options::ColorAlpha;
Jan Möbius's avatar
Jan Möbius committed
171

172
    return (options_.is_binary() ? read_binary(_in, _bi, swap, _opt) : read_ascii(_in, _bi, _opt));
Jan Möbius's avatar
Jan Möbius committed
173
174
175

}

Matthias Möller's avatar
Matthias Möller committed
176
177
178
template<typename T, typename Handle>
struct Handle2Prop;

179
template<typename T>
Matthias Möller's avatar
Matthias Möller committed
180
struct Handle2Prop<T,VertexHandle>
181
{
Matthias Möller's avatar
Matthias Möller committed
182
183
  typedef OpenMesh::VPropHandleT<T> PropT;
};
184

Matthias Möller's avatar
Matthias Möller committed
185
186
187
188
189
template<typename T>
struct Handle2Prop<T,FaceHandle>
{
  typedef OpenMesh::FPropHandleT<T> PropT;
};
190

191
192
193
//read and assign custom properties with the given type. Also creates property, if not exist
template<bool binary, typename T, typename Handle>
void _PLYReader_::readCreateCustomProperty(std::istream& _in, BaseImporter& _bi, Handle _h, const std::string& _propName, const _PLYReader_::ValueType _valueType, const _PLYReader_::ValueType _listType) const
194
{
195
  if (_listType == Unsupported) //no list type defined -> property is not a list
Matthias Möller's avatar
Matthias Möller committed
196
197
198
199
  {
    //get/add property
    typename Handle2Prop<T,Handle>::PropT prop;
    if (!_bi.kernel()->get_property_handle(prop,_propName))
200
    {
Matthias Möller's avatar
Matthias Möller committed
201
      _bi.kernel()->add_property(prop,_propName);
202
203
      _bi.kernel()->property(prop).set_persistent(true);
    }
Matthias Möller's avatar
Matthias Möller committed
204
205
206

    //read and assign
    T in;
207
    read(_valueType, _in, in, OpenMesh::GenProg::Bool2Type<binary>());
Matthias Möller's avatar
Matthias Möller committed
208
209
210
211
212
213
214
    _bi.kernel()->property(prop,_h) = in;
  }
  else
  {
    //get/add property
    typename Handle2Prop<std::vector<T>,Handle>::PropT prop;
    if (!_bi.kernel()->get_property_handle(prop,_propName))
215
    {
Matthias Möller's avatar
Matthias Möller committed
216
      _bi.kernel()->add_property(prop,_propName);
217
218
      _bi.kernel()->property(prop).set_persistent(true);
    }
Matthias Möller's avatar
Matthias Möller committed
219
220
221

    //init vector
    int numberOfValues;
222
    read(_listType, _in, numberOfValues, OpenMesh::GenProg::Bool2Type<binary>());
Matthias Möller's avatar
Matthias Möller committed
223
224
225
226
227
228
    std::vector<T> vec;
    vec.reserve(numberOfValues);
    //read and assign
    for (int i = 0; i < numberOfValues; ++i)
    {
      T in;
229
      read(_valueType, _in, in, OpenMesh::GenProg::Bool2Type<binary>());
Matthias Möller's avatar
Matthias Möller committed
230
231
232
233
234
235
      vec.push_back(in);
    }
    _bi.kernel()->property(prop,_h) = vec;
  }
}

236
237
template<bool binary, typename Handle>
void _PLYReader_::readCustomProperty(std::istream& _in, BaseImporter& _bi, Handle _h, const std::string& _propName, const _PLYReader_::ValueType _valueType, const _PLYReader_::ValueType _listIndexType) const
Matthias Möller's avatar
Matthias Möller committed
238
{
239
240
241
242
  switch (_valueType)
  {
  case ValueTypeINT8:
  case ValueTypeCHAR:
243
      readCreateCustomProperty<binary,signed char>(_in,_bi,_h,_propName,_valueType,_listIndexType);
244
      break;
245
246
  case ValueTypeUINT8:
  case ValueTypeUCHAR:
247
      readCreateCustomProperty<binary,unsigned char>(_in,_bi,_h,_propName,_valueType,_listIndexType);
248
      break;
249
250
  case ValueTypeINT16:
  case ValueTypeSHORT:
251
      readCreateCustomProperty<binary,short>(_in,_bi,_h,_propName,_valueType,_listIndexType);
252
253
254
      break;
  case ValueTypeUINT16:
  case ValueTypeUSHORT:
255
      readCreateCustomProperty<binary,unsigned short>(_in,_bi,_h,_propName,_valueType,_listIndexType);
256
257
258
      break;
  case ValueTypeINT32:
  case ValueTypeINT:
259
      readCreateCustomProperty<binary,int>(_in,_bi,_h,_propName,_valueType,_listIndexType);
260
261
262
      break;
  case ValueTypeUINT32:
  case ValueTypeUINT:
263
      readCreateCustomProperty<binary,unsigned int>(_in,_bi,_h,_propName,_valueType,_listIndexType);
264
265
266
      break;
  case ValueTypeFLOAT32:
  case ValueTypeFLOAT:
267
      readCreateCustomProperty<binary,float>(_in,_bi,_h,_propName,_valueType,_listIndexType);
268
269
270
      break;
  case ValueTypeFLOAT64:
  case ValueTypeDOUBLE:
271
      readCreateCustomProperty<binary,double>(_in,_bi,_h,_propName,_valueType,_listIndexType);
272
273
274
275
276
277
      break;
  default:
      std::cerr << "unsupported type" << std::endl;
      break;
  }
}
278
279


Jan Möbius's avatar
Jan Möbius committed
280
281
//-----------------------------------------------------------------------------

282
bool _PLYReader_::read_ascii(std::istream& _in, BaseImporter& _bi, const Options& _opt) const {
Mike Kremer's avatar
Mike Kremer committed
283

284
285
286
287
288
289
290
291
    // Reparse the header
    if (!can_u_read(_in)) {
        omerr() << "[PLYReader] : Unable to parse header\n";
        return false;
    }

    unsigned int i, j, k, l, idx;
    unsigned int nV;
Jan Möbius's avatar
Jan Möbius committed
292
    OpenMesh::Vec3f v, n;
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
    std::string trash;
    OpenMesh::Vec2f t;
    OpenMesh::Vec4i c;
    float tmp;
    BaseImporter::VHandles vhandles;
    VertexHandle vh;

    _bi.reserve(vertexCount_, 3* vertexCount_ , faceCount_);

    if (vertexDimension_ != 3) {
        omerr() << "[PLYReader] : Only vertex dimension 3 is supported." << std::endl;
        return false;
    }

    // read vertices:
    for (i = 0; i < vertexCount_ && !_in.eof(); ++i) {
309
310
        vh = _bi.add_vertex();

311
312
313
314
        v[0] = 0.0;
        v[1] = 0.0;
        v[2] = 0.0;

Jan Möbius's avatar
Jan Möbius committed
315
316
317
318
        n[0] = 0.0;
        n[1] = 0.0;
        n[2] = 0.0;

319
320
321
322
323
324
325
326
        t[0] = 0.0;
        t[1] = 0.0;

        c[0] = 0;
        c[1] = 0;
        c[2] = 0;
        c[3] = 255;

Matthias Möller's avatar
Matthias Möller committed
327
328
        for (size_t propertyIndex = 0; propertyIndex < vertexProperties_.size(); ++propertyIndex) {
            switch (vertexProperties_[propertyIndex].property) {
329
330
331
332
333
334
335
336
337
            case XCOORD:
                _in >> v[0];
                break;
            case YCOORD:
                _in >> v[1];
                break;
            case ZCOORD:
                _in >> v[2];
                break;
Jan Möbius's avatar
Jan Möbius committed
338
339
340
341
342
343
344
345
346
            case XNORM:
                _in >> n[0];
                break;
            case YNORM:
                _in >> n[1];
                break;
            case ZNORM:
                _in >> n[2];
                break;
347
348
349
350
351
352
353
            case TEXX:
                _in >> t[0];
                break;
            case TEXY:
                _in >> t[1];
                break;
            case COLORRED:
Matthias Möller's avatar
Matthias Möller committed
354
355
                if (vertexProperties_[propertyIndex].value == ValueTypeFLOAT32 ||
                    vertexProperties_[propertyIndex].value == ValueTypeFLOAT) {
356
357
358
359
360
361
                    _in >> tmp;
                    c[0] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
                } else
                    _in >> c[0];
                break;
            case COLORGREEN:
Matthias Möller's avatar
Matthias Möller committed
362
363
                if (vertexProperties_[propertyIndex].value == ValueTypeFLOAT32 ||
                    vertexProperties_[propertyIndex].value == ValueTypeFLOAT) {
364
365
366
367
368
369
                    _in >> tmp;
                    c[1] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
                } else
                    _in >> c[1];
                break;
            case COLORBLUE:
Matthias Möller's avatar
Matthias Möller committed
370
371
                if (vertexProperties_[propertyIndex].value == ValueTypeFLOAT32 ||
                    vertexProperties_[propertyIndex].value == ValueTypeFLOAT) {
372
373
374
375
376
377
                    _in >> tmp;
                    c[2] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
                } else
                    _in >> c[2];
                break;
            case COLORALPHA:
Matthias Möller's avatar
Matthias Möller committed
378
379
                if (vertexProperties_[propertyIndex].value == ValueTypeFLOAT32 ||
                    vertexProperties_[propertyIndex].value == ValueTypeFLOAT) {
380
381
382
383
384
                    _in >> tmp;
                    c[3] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
                } else
                    _in >> c[3];
                break;
385
386
            case CUSTOM_PROP:
                if (_opt.check(Options::Custom))
387
                  readCustomProperty<false>(_in, _bi, vh, vertexProperties_[propertyIndex].name, vertexProperties_[propertyIndex].value, vertexProperties_[propertyIndex].listIndexType);
388
389
390
                else
                  _in >> trash;
                break;
391
392
393
394
395
396
            default:
                _in >> trash;
                break;
            }
        }

397
        _bi.set_point(vh, v);
398
399
400
401
402
403
        if (_opt.vertex_has_normal())
          _bi.set_normal(vh, n);
        if (_opt.vertex_has_texcoord())
          _bi.set_texcoord(vh, t);
        if (_opt.vertex_has_color())
          _bi.set_color(vh, Vec4uc(c));
404
405
406
407
    }

    // faces
    for (i = 0; i < faceCount_; ++i) {
Matthias Möller's avatar
Matthias Möller committed
408
409
410
411
      FaceHandle fh;
      for (size_t propertyIndex = 0; propertyIndex < faceProperties_.size(); ++propertyIndex) {
        PropertyInfo prop = faceProperties_[propertyIndex];
        switch (prop.property) {
412

Matthias Möller's avatar
Matthias Möller committed
413
414
415
416
417
        case VERTEX_INDICES:
          // nV = number of Vertices for current face
          _in >> nV;

          if (nV == 3) {
418
419
420
421
422
423
424
425
            vhandles.resize(3);
            _in >> j;
            _in >> k;
            _in >> l;

            vhandles[0] = VertexHandle(j);
            vhandles[1] = VertexHandle(k);
            vhandles[2] = VertexHandle(l);
Matthias Möller's avatar
Matthias Möller committed
426
          } else {
427
428
            vhandles.clear();
            for (j = 0; j < nV; ++j) {
Matthias Möller's avatar
Matthias Möller committed
429
430
              _in >> idx;
              vhandles.push_back(VertexHandle(idx));
431
            }
Matthias Möller's avatar
Matthias Möller committed
432
          }
433

Matthias Möller's avatar
Matthias Möller committed
434
435
436
437
438
          fh = _bi.add_face(vhandles);
          break;

        case CUSTOM_PROP:
          if (_opt.check(Options::Custom) && fh.is_valid())
439
            readCustomProperty<false>(_in, _bi, fh, prop.name, prop.value, prop.listIndexType);
Matthias Möller's avatar
Matthias Möller committed
440
441
442
443
444
445
446
447
448
          else
            _in >> trash;
          break;

        default:
          _in >> trash;
          break;
        }
      }
449
450
451
452
453

    }

    // File was successfully parsed.
    return true;
Jan Möbius's avatar
Jan Möbius committed
454
455
456
457
}

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

458
bool _PLYReader_::read_binary(std::istream& _in, BaseImporter& _bi, bool /*_swap*/, const Options& _opt) const {
Mike Kremer's avatar
Mike Kremer committed
459

460
461
462
463
464
465
    // Reparse the header
    if (!can_u_read(_in)) {
        omerr() << "[PLYReader] : Unable to parse header\n";
        return false;
    }

466
467
    OpenMesh::Vec3f        v, n;  // Vertex
    OpenMesh::Vec2f        t;  // TexCoords
468
    BaseImporter::VHandles vhandles;
469
470
471
    VertexHandle           vh;
    OpenMesh::Vec4i        c;  // Color
    float                  tmp;
472
473
474
475

    _bi.reserve(vertexCount_, 3* vertexCount_ , faceCount_);

    // read vertices:
Matthias Möller's avatar
Matthias Möller committed
476
    for (unsigned int i = 0; i < vertexCount_ && !_in.eof(); ++i) {
477
478
        vh = _bi.add_vertex();

479
480
481
482
        v[0] = 0.0;
        v[1] = 0.0;
        v[2] = 0.0;

Jan Möbius's avatar
Jan Möbius committed
483
484
485
486
        n[0] = 0.0;
        n[1] = 0.0;
        n[2] = 0.0;

487
488
489
490
491
492
493
494
        t[0] = 0.0;
        t[1] = 0.0;

        c[0] = 0;
        c[1] = 0;
        c[2] = 0;
        c[3] = 255;

Matthias Möller's avatar
Matthias Möller committed
495
496
        for (size_t propertyIndex = 0; propertyIndex < vertexProperties_.size(); ++propertyIndex) {
            switch (vertexProperties_[propertyIndex].property) {
497
            case XCOORD:
Matthias Möller's avatar
Matthias Möller committed
498
                readValue(vertexProperties_[propertyIndex].value, _in, v[0]);
499
500
                break;
            case YCOORD:
Matthias Möller's avatar
Matthias Möller committed
501
                readValue(vertexProperties_[propertyIndex].value, _in, v[1]);
502
503
                break;
            case ZCOORD:
Matthias Möller's avatar
Matthias Möller committed
504
                readValue(vertexProperties_[propertyIndex].value, _in, v[2]);
505
                break;
Jan Möbius's avatar
Jan Möbius committed
506
            case XNORM:
Matthias Möller's avatar
Matthias Möller committed
507
                readValue(vertexProperties_[propertyIndex].value, _in, n[0]);
Jan Möbius's avatar
Jan Möbius committed
508
509
                break;
            case YNORM:
Matthias Möller's avatar
Matthias Möller committed
510
                readValue(vertexProperties_[propertyIndex].value, _in, n[1]);
Jan Möbius's avatar
Jan Möbius committed
511
512
                break;
            case ZNORM:
Matthias Möller's avatar
Matthias Möller committed
513
                readValue(vertexProperties_[propertyIndex].value, _in, n[2]);
Jan Möbius's avatar
Jan Möbius committed
514
                break;
515
            case TEXX:
Matthias Möller's avatar
Matthias Möller committed
516
                readValue(vertexProperties_[propertyIndex].value, _in, t[0]);
517
518
                break;
            case TEXY:
Matthias Möller's avatar
Matthias Möller committed
519
                readValue(vertexProperties_[propertyIndex].value, _in, t[1]);
520
521
                break;
            case COLORRED:
Matthias Möller's avatar
Matthias Möller committed
522
523
524
                if (vertexProperties_[propertyIndex].value == ValueTypeFLOAT32 ||
                    vertexProperties_[propertyIndex].value == ValueTypeFLOAT) {
                    readValue(vertexProperties_[propertyIndex].value, _in, tmp);
525
526
527

                    c[0] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
                } else
Matthias Möller's avatar
Matthias Möller committed
528
                    readInteger(vertexProperties_[propertyIndex].value, _in, c[0]);
529

530
531
                break;
            case COLORGREEN:
Matthias Möller's avatar
Matthias Möller committed
532
533
534
                if (vertexProperties_[propertyIndex].value == ValueTypeFLOAT32 ||
                    vertexProperties_[propertyIndex].value == ValueTypeFLOAT) {
                    readValue(vertexProperties_[propertyIndex].value, _in, tmp);
535
536
                    c[1] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
                } else
Matthias Möller's avatar
Matthias Möller committed
537
                    readInteger(vertexProperties_[propertyIndex].value, _in, c[1]);
538

539
540
                break;
            case COLORBLUE:
Matthias Möller's avatar
Matthias Möller committed
541
542
543
                if (vertexProperties_[propertyIndex].value == ValueTypeFLOAT32 ||
                    vertexProperties_[propertyIndex].value == ValueTypeFLOAT) {
                    readValue(vertexProperties_[propertyIndex].value, _in, tmp);
544
545
                    c[2] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
                } else
Matthias Möller's avatar
Matthias Möller committed
546
                    readInteger(vertexProperties_[propertyIndex].value, _in, c[2]);
547

548
549
                break;
            case COLORALPHA:
Matthias Möller's avatar
Matthias Möller committed
550
551
552
                if (vertexProperties_[propertyIndex].value == ValueTypeFLOAT32 ||
                    vertexProperties_[propertyIndex].value == ValueTypeFLOAT) {
                    readValue(vertexProperties_[propertyIndex].value, _in, tmp);
553
554
                    c[3] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
                } else
Matthias Möller's avatar
Matthias Möller committed
555
                    readInteger(vertexProperties_[propertyIndex].value, _in, c[3]);
556

557
                break;
558
559
560
561
562
563
            case CUSTOM_PROP:
              if (_opt.check(Options::Custom))
                readCustomProperty<true>(_in, _bi, vh, vertexProperties_[propertyIndex].name, vertexProperties_[propertyIndex].value, vertexProperties_[propertyIndex].listIndexType);
              else
                consume_input(_in, scalar_size_[vertexProperties_[propertyIndex].value]);
              break;
564
            default:
565
                // Read unsupported property
Matthias Möller's avatar
Matthias Möller committed
566
                consume_input(_in, scalar_size_[vertexProperties_[propertyIndex].value]);
567
568
569
570
571
                break;
            }

        }

572
        _bi.set_point(vh,v);
573
574
575
576
577
578
        if (_opt.vertex_has_normal())
          _bi.set_normal(vh, n);
        if (_opt.vertex_has_texcoord())
          _bi.set_texcoord(vh, t);
        if (_opt.vertex_has_color())
          _bi.set_color(vh, Vec4uc(c));
579
580
    }

581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
    for (unsigned i = 0; i < faceCount_; ++i) {
      FaceHandle fh;
      for (size_t propertyIndex = 0; propertyIndex < faceProperties_.size(); ++propertyIndex)
      {
        PropertyInfo prop = faceProperties_[propertyIndex];
        switch (prop.property) {

        case VERTEX_INDICES:
          // nV = number of Vertices for current face
          unsigned int nV;
          readValue(prop.listIndexType, _in, nV);

          if (nV == 3) {
            vhandles.resize(3);
            unsigned int j,k,l;
            readInteger(prop.value, _in, j);
            readInteger(prop.value, _in, k);
            readInteger(prop.value, _in, l);

            vhandles[0] = VertexHandle(j);
            vhandles[1] = VertexHandle(k);
            vhandles[2] = VertexHandle(l);
          } else {
            vhandles.clear();
            for (unsigned j = 0; j < nV; ++j) {
              unsigned int idx;
              readInteger(prop.value, _in, idx);
              vhandles.push_back(VertexHandle(idx));
            }
Matthias Möller's avatar
Matthias Möller committed
610
          }
611

612
613
614
615
616
617
618
619
620
621
622
623
624
625
          fh = _bi.add_face(vhandles);
          break;

        case CUSTOM_PROP:
          if (_opt.check(Options::Custom) && fh.is_valid())
            readCustomProperty<true>(_in, _bi, fh, prop.name, prop.value, prop.listIndexType);
          else
            consume_input(_in, scalar_size_[vertexProperties_[propertyIndex].value]);
          break;

        default:
          consume_input(_in, scalar_size_[vertexProperties_[propertyIndex].value]);
          break;
        }
Matthias Möller's avatar
Matthias Möller committed
626
      }
627
628
629
    }

    return true;
Jan Möbius's avatar
Jan Möbius committed
630
631
632
}


633
634
635
//-----------------------------------------------------------------------------


636
void _PLYReader_::readValue(ValueType _type, std::istream& _in, float& _value) const {
637

638
639
640
641
642
643
644
645
646
647
648
649
    switch (_type) {
    case ValueTypeFLOAT32:
    case ValueTypeFLOAT:
        float32_t tmp;
        restore(_in, tmp, options_.check(Options::MSB));
        _value = tmp;
        break;
    default:
        _value = 0.0;
        std::cerr << "unsupported conversion type to float: " << _type << std::endl;
        break;
    }
650
651
}

652
653
654
655
656
657
658

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


void _PLYReader_::readValue(ValueType _type, std::istream& _in, double& _value) const {

    switch (_type) {
659

660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
        case ValueTypeFLOAT64:

        case ValueTypeDOUBLE:

            float64_t tmp;
            restore(_in, tmp, options_.check(Options::MSB));
            _value = tmp;

            break;

    default:

        _value = 0.0;
        std::cerr << "unsupported conversion type to double: " << _type << std::endl;

        break;
    }
}


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

682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
void _PLYReader_::readValue(ValueType _type, std::istream& _in, unsigned char& _value) const{
  unsigned int tmp;
  readValue(_type,_in,tmp);
  _value = tmp;
}

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

void _PLYReader_::readValue(ValueType _type, std::istream& _in, unsigned short& _value) const{
  unsigned int tmp;
  readValue(_type,_in,tmp);
  _value = tmp;
}

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

void _PLYReader_::readValue(ValueType _type, std::istream& _in, signed char& _value) const{
  int tmp;
  readValue(_type,_in,tmp);
  _value = tmp;
}
703

704
705
706
707
708
709
710
711
712
713
//-----------------------------------------------------------------------------

void _PLYReader_::readValue(ValueType _type, std::istream& _in, short& _value) const{
  int tmp;
  readValue(_type,_in,tmp);
  _value = tmp;
}


//-----------------------------------------------------------------------------
714
void _PLYReader_::readValue(ValueType _type, std::istream& _in, unsigned int& _value) const {
715

716
717
    uint32_t tmp_uint32_t;
    uint16_t tmp_uint16_t;
718
719
720
    uint8_t tmp_uchar;

    switch (_type) {
721
722
723
724

        case ValueTypeUINT:

        case ValueTypeUINT32:
725

726
727
728
            restore(_in, tmp_uint32_t, options_.check(Options::MSB));
            _value = tmp_uint32_t;

729
        break;
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754

        case ValueTypeUSHORT:

        case ValueTypeUINT16:

            restore(_in, tmp_uint16_t, options_.check(Options::MSB));
            _value = tmp_uint16_t;

            break;

        case ValueTypeUCHAR:

        case ValueTypeUINT8:

            restore(_in, tmp_uchar, options_.check(Options::MSB));
            _value = tmp_uchar;

            break;

        default:

            _value = 0;
            std::cerr << "unsupported conversion type to unsigned int: " << _type << std::endl;

            break;
755
    }
756
757
}

758
759
760
761

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


762
void _PLYReader_::readValue(ValueType _type, std::istream& _in, int& _value) const {
763

764
    int32_t tmp_int32_t;
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
    int16_t tmp_int16_t;
    int8_t tmp_char;

    switch (_type) {

        case ValueTypeINT:

        case ValueTypeINT32:

            restore(_in, tmp_int32_t, options_.check(Options::MSB));
            _value = tmp_int32_t;

            break;

        case ValueTypeSHORT:

        case ValueTypeINT16:

            restore(_in, tmp_int16_t, options_.check(Options::MSB));
            _value = tmp_int16_t;

            break;

        case ValueTypeCHAR:

        case ValueTypeINT8:

            restore(_in, tmp_char, options_.check(Options::MSB));
            _value = tmp_char;

            break;

        default:

            _value = 0;
            std::cerr << "unsupported conversion type to int: " << _type << std::endl;

            break;
    }
}


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


void _PLYReader_::readInteger(ValueType _type, std::istream& _in, int& _value) const {

    int32_t tmp_int32_t;
    uint32_t tmp_uint32_t;
    int8_t tmp_char;
815
816
817
    uint8_t tmp_uchar;

    switch (_type) {
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833

        case ValueTypeINT:

        case ValueTypeINT32:

            restore(_in, tmp_int32_t, options_.check(Options::MSB));
            _value = tmp_int32_t;

            break;

        case ValueTypeUINT:

        case ValueTypeUINT32:

            restore(_in, tmp_uint32_t, options_.check(Options::MSB));
            _value = tmp_uint32_t;
834

835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
            break;

        case ValueTypeCHAR:

        case ValueTypeINT8:

            restore(_in, tmp_char, options_.check(Options::MSB));
            _value = tmp_char;

            break;

        case ValueTypeUCHAR:

        case ValueTypeUINT8:

            restore(_in, tmp_uchar, options_.check(Options::MSB));
            _value = tmp_uchar;

            break;

        default:

            _value = 0;
            std::cerr << "unsupported conversion type to int: " << _type << std::endl;

            break;
861
    }
862
863
}

864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922

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


void _PLYReader_::readInteger(ValueType _type, std::istream& _in, unsigned int& _value) const {

    int32_t tmp_int32_t;
    uint32_t tmp_uint32_t;
    int8_t tmp_char;
    uint8_t tmp_uchar;

    switch (_type) {

        case ValueTypeUINT:

        case ValueTypeUINT32:

            restore(_in, tmp_uint32_t, options_.check(Options::MSB));
            _value = tmp_uint32_t;

            break;

        case ValueTypeINT:

        case ValueTypeINT32:

            restore(_in, tmp_int32_t, options_.check(Options::MSB));
            _value = tmp_int32_t;

            break;

        case ValueTypeUCHAR:

        case ValueTypeUINT8:

            restore(_in, tmp_uchar, options_.check(Options::MSB));
            _value = tmp_uchar;

            break;

        case ValueTypeCHAR:

        case ValueTypeINT8:

            restore(_in, tmp_char, options_.check(Options::MSB));
            _value = tmp_char;

            break;

        default:

            _value = 0;
            std::cerr << "unsupported conversion type to unsigned int: " << _type << std::endl;

            break;
    }
}


923
924
//------------------------------------------------------------------------------

925

Mike Kremer's avatar
Mike Kremer committed
926
bool _PLYReader_::can_u_read(const std::string& _filename) const {
927

928
929
930
931
932
933
934
935
936
937
938
    // !!! Assuming BaseReader::can_u_parse( std::string& )
    // does not call BaseReader::read_magic()!!!

    if (BaseReader::can_u_read(_filename)) {
        std::ifstream ifs(_filename.c_str());
        if (ifs.is_open() && can_u_read(ifs)) {
            ifs.close();
            return true;
        }
    }
    return false;
Jan Möbius's avatar
Jan Möbius committed
939
940
}

941
942


Jan Möbius's avatar
Jan Möbius committed
943
944
//-----------------------------------------------------------------------------

Mike Kremer's avatar
Mike Kremer committed
945
std::string get_property_name(std::string _string1, std::string _string2) {
946

947
948
949
950
    if (_string1 == "float32" || _string1 == "float64" || _string1 == "float" || _string1 == "double" ||
        _string1 == "int8" || _string1 == "uint8" || _string1 == "char" || _string1 == "uchar" ||
        _string1 == "int32" || _string1 == "uint32" || _string1 == "int" || _string1 == "uint" ||
        _string1 == "int16" || _string1 == "uint16" || _string1 == "short" || _string1 == "ushort")
951
        return _string2;
Mike Kremer's avatar
Mike Kremer committed
952

953
954
955
956
    if (_string2 == "float32" || _string2 == "float64" || _string2 == "float" || _string2 == "double" ||
        _string2 == "int8" || _string2 == "uint8" || _string2 == "char" || _string2 == "uchar" ||
        _string2 == "int32" || _string2 == "uint32" || _string2 == "int" || _string2 == "uint" ||
        _string2 == "int16" || _string2 == "uint16" || _string2 == "short" || _string2 == "ushort")
957
        return _string1;
Mike Kremer's avatar
Mike Kremer committed
958

959

960
961
    std::cerr << "Unsupported entry type" << std::endl;
    return "Unsupported";
Jan Möbius's avatar
Jan Möbius committed
962
963
964
965
}

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

Mike Kremer's avatar
Mike Kremer committed
966
_PLYReader_::ValueType get_property_type(std::string _string1, std::string _string2) {
967

968
    if (_string1 == "float32" || _string2 == "float32")
969

970
        return _PLYReader_::ValueTypeFLOAT32;
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989

    else if (_string1 == "float64" || _string2 == "float64")

        return _PLYReader_::ValueTypeFLOAT64;

    else if (_string1 == "float" || _string2 == "float")

        return _PLYReader_::ValueTypeFLOAT;

    else if (_string1 == "double" || _string2 == "double")

        return _PLYReader_::ValueTypeDOUBLE;

    else if (_string1 == "int8" || _string2 == "int8")

        return _PLYReader_::ValueTypeINT8;

    else if (_string1 == "uint8" || _string2 == "uint8")

990
        return _PLYReader_::ValueTypeUINT8;
991
992
993
994
995

    else if (_string1 == "char" || _string2 == "char")

        return _PLYReader_::ValueTypeCHAR;

996
    else if (_string1 == "uchar" || _string2 == "uchar")
997

998
        return _PLYReader_::ValueTypeUCHAR;
999
1000

    else if (_string1 == "int32" || _string2 == "int32")