PLYReader.cc 20.6 KB
Newer Older
Jan Möbius's avatar
Jan Möbius committed
1
2
3
/*===========================================================================*\
 *                                                                           *
 *                               OpenMesh                                    *
4
 *      Copyright (C) 2001-2009 by Computer Graphics Group, RWTH Aachen      *
Jan Möbius's avatar
Jan Möbius committed
5
6
 *                           www.openmesh.org                                *
 *                                                                           *
Mike Kremer's avatar
Mike Kremer committed
7
 *---------------------------------------------------------------------------*
8
 *  This file is part of OpenMesh.                                           *
Jan Möbius's avatar
Jan Möbius committed
9
 *                                                                           *
Mike Kremer's avatar
Mike Kremer committed
10
 *  OpenMesh is free software: you can redistribute it and/or modify         *
11
12
13
14
 *  it under the terms of the GNU Lesser General Public License as           *
 *  published by the Free Software Foundation, either version 3 of           *
 *  the License, or (at your option) any later version with the              *
 *  following exceptions:                                                    *
Jan Möbius's avatar
Jan Möbius committed
15
 *                                                                           *
16
17
18
19
20
21
22
 *  If other files instantiate templates or use macros                       *
 *  or inline functions from this file, or you compile this file and         *
 *  link it with other files to produce an executable, this file does        *
 *  not by itself cause the resulting executable to be covered by the        *
 *  GNU Lesser General Public License. This exception does not however       *
 *  invalidate any other reasons why the executable file might be            *
 *  covered by the GNU Lesser General Public License.                        *
Jan Möbius's avatar
Jan Möbius committed
23
 *                                                                           *
24
25
26
27
 *  OpenMesh is distributed in the hope that it will be useful,              *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
 *  GNU Lesser General Public License for more details.                      *
Jan Möbius's avatar
Jan Möbius committed
28
 *                                                                           *
29
30
31
32
 *  You should have received a copy of the GNU LesserGeneral Public          *
 *  License along with OpenMesh.  If not,                                    *
 *  see <http://www.gnu.org/licenses/>.                                      *
 *                                                                           *
Mike Kremer's avatar
Mike Kremer committed
33
 \*===========================================================================*/
34
35

/*===========================================================================*\
Mike Kremer's avatar
Mike Kremer committed
36
 *                                                                           *
37
38
 *   $Revision$                                                         *
 *   $Date$                   *
Jan Möbius's avatar
Jan Möbius committed
39
 *                                                                           *
Mike Kremer's avatar
Mike Kremer committed
40
 \*===========================================================================*/
Jan Möbius's avatar
Jan Möbius committed
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

#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/importer/BaseImporter.hh>
#include <OpenMesh/Core/IO/IOManager.hh>
#include <OpenMesh/Core/Utils/color_cast.hh>
#include <OpenMesh/Core/IO/SR_store.hh>

//STL
#include <fstream>
#include <memory>

#ifndef WIN32
#include <string.h>
#endif

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


namespace OpenMesh {
namespace IO {

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

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


Mike Kremer's avatar
Mike Kremer committed
74
75
76
77
_PLYReader_ __PLYReaderInstance;
_PLYReader_& PLYReader() {
	return __PLYReaderInstance;
}
Jan Möbius's avatar
Jan Möbius committed
78
79
80
81

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


Mike Kremer's avatar
Mike Kremer committed
82
83
_PLYReader_::_PLYReader_() {
	IOManager().register_module(this);
Jan Möbius's avatar
Jan Möbius committed
84
85
86
87
88
}

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


Mike Kremer's avatar
Mike Kremer committed
89
90
91
bool _PLYReader_::read(const std::string& _filename, BaseImporter& _bi, Options& _opt) {
	std::fstream in(_filename.c_str(), (options_.is_binary() ? std::ios_base::binary | std::ios_base::in
			: std::ios_base::in));
Jan Möbius's avatar
Jan Möbius committed
92

Mike Kremer's avatar
Mike Kremer committed
93
94
95
96
	if (!in) {
		omerr() << "[PLYReader] : cannot not open file " << _filename << std::endl;
		return false;
	}
Jan Möbius's avatar
Jan Möbius committed
97

Mike Kremer's avatar
Mike Kremer committed
98
	bool result = read(in, _bi, _opt);
Jan Möbius's avatar
Jan Möbius committed
99

Mike Kremer's avatar
Mike Kremer committed
100
101
	in.close();
	return result;
Jan Möbius's avatar
Jan Möbius committed
102
103
104
105
106
}

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


Mike Kremer's avatar
Mike Kremer committed
107
108
109
bool _PLYReader_::read(std::fstream& _in, BaseImporter& _bi, Options& _opt) const {
	// filter relevant options for reading
	bool swap = _opt.check(Options::Swap);
Jan Möbius's avatar
Jan Möbius committed
110

Mike Kremer's avatar
Mike Kremer committed
111
	userOptions_ = _opt;
Jan Möbius's avatar
Jan Möbius committed
112

Mike Kremer's avatar
Mike Kremer committed
113
114
	// build options to be returned
	_opt.clear();
Jan Möbius's avatar
Jan Möbius committed
115

116
	if (options_.vertex_has_normal() && userOptions_.vertex_has_normal()) {
Mike Kremer's avatar
Mike Kremer committed
117
		_opt += Options::VertexNormal;
118
119
	}
	if (options_.vertex_has_texcoord() && userOptions_.vertex_has_texcoord()) {
Mike Kremer's avatar
Mike Kremer committed
120
		_opt += Options::VertexTexCoord;
121
122
	}
	if (options_.vertex_has_color() && userOptions_.vertex_has_color()) {
Mike Kremer's avatar
Mike Kremer committed
123
		_opt += Options::VertexColor;
124
125
	}
	if (options_.face_has_color() && userOptions_.face_has_color()) {
Mike Kremer's avatar
Mike Kremer committed
126
		_opt += Options::FaceColor;
127
128
	}
	if (options_.is_binary()) {
Mike Kremer's avatar
Mike Kremer committed
129
		_opt += Options::Binary;
130
	}
Jan Möbius's avatar
Jan Möbius committed
131

Mike Kremer's avatar
Mike Kremer committed
132
133
134
	//    //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
135

Mike Kremer's avatar
Mike Kremer committed
136
	return (options_.is_binary() ? read_binary(_in, _bi, swap) : read_ascii(_in, _bi));
Jan Möbius's avatar
Jan Möbius committed
137
138
139
140
141

}

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

Mike Kremer's avatar
Mike Kremer committed
142
143
144
145
146
147
148
149
150
151
152
153
154
155
bool _PLYReader_::read_ascii(std::fstream& _in, BaseImporter& _bi) const {

	omlog() << "[PLYReader] : read ascii file\n";

	// 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;
	OpenMesh::Vec3f v;
	std::string trash;
156
	OpenMesh::Vec2f t;
Mike Kremer's avatar
Mike Kremer committed
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
	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) {
		v[0] = 0.0;
		v[1] = 0.0;
		v[2] = 0.0;

175
176
177
		t[0] = 0.0;
		t[1] = 0.0;

Mike Kremer's avatar
Mike Kremer committed
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
		c[0] = 0;
		c[1] = 0;
		c[2] = 0;
		c[3] = 255;

		for (uint propertyIndex = 0; propertyIndex < vertexPropertyCount_; ++propertyIndex) {
			switch (vertexPropertyMap_[propertyIndex].first) {
			case XCOORD:
				_in >> v[0];
				break;
			case YCOORD:
				_in >> v[1];
				break;
			case ZCOORD:
				_in >> v[2];
				break;
194
195
196
197
198
199
			case TEXX:
				_in >> t[0];
				break;
			case TEXY:
				_in >> t[1];
				break;
Mike Kremer's avatar
Mike Kremer committed
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
			case COLORRED:
				if (vertexPropertyMap_[propertyIndex].second == ValueTypeFLOAT32) {
					_in >> tmp;
					c[0] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
				} else
					_in >> c[0];
				break;
			case COLORGREEN:
				if (vertexPropertyMap_[propertyIndex].second == ValueTypeFLOAT32) {
					_in >> tmp;
					c[1] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
				} else
					_in >> c[1];
				break;
			case COLORBLUE:
				if (vertexPropertyMap_[propertyIndex].second == ValueTypeFLOAT32) {
					_in >> tmp;
					c[2] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
				} else
					_in >> c[2];
				break;
			case COLORALPHA:
				if (vertexPropertyMap_[propertyIndex].second == ValueTypeFLOAT32) {
					_in >> tmp;
					c[3] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
				} else
					_in >> c[3];
				break;
			default:
				_in >> trash;
				break;
			}
		}

		vh = _bi.add_vertex(v);
235
		_bi.set_texcoord(vh, t);
Mike Kremer's avatar
Mike Kremer committed
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
		_bi.set_color(vh, Vec4uc(c));
	}

	// faces
	// #N <v1> <v2> .. <v(n-1)> [color spec]
	for (i = 0; i < faceCount_; ++i) {
		// nV = number of Vertices for current face
		_in >> nV;

		if (nV == 3) {
			vhandles.resize(3);
			_in >> j;
			_in >> k;
			_in >> l;

			vhandles[0] = VertexHandle(j);
			vhandles[1] = VertexHandle(k);
			vhandles[2] = VertexHandle(l);
		} else {
			vhandles.clear();
			for (j = 0; j < nV; ++j) {
				_in >> idx;
				vhandles.push_back(VertexHandle(idx));
			}
		}

		FaceHandle fh = _bi.add_face(vhandles);

	}

	// File was successfully parsed.
	return true;
Jan Möbius's avatar
Jan Möbius committed
268
269
270
271
}

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

Mike Kremer's avatar
Mike Kremer committed
272
273
274
275
276
277
278
279
280
281
282
283
bool _PLYReader_::read_binary(std::fstream& _in, BaseImporter& _bi, bool /*_swap*/) const {

	omlog() << "[PLYReader] : read binary file format\n";

	// 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;
284
285
	OpenMesh::Vec3f v;  // Vertex
	OpenMesh::Vec2f t;  // TexCoords
Mike Kremer's avatar
Mike Kremer committed
286
287
	BaseImporter::VHandles vhandles;
	VertexHandle vh;
288
	OpenMesh::Vec4i c;  // Color
Mike Kremer's avatar
Mike Kremer committed
289
290
291
292
293
294
295
296
297
298
	float tmp;

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

	// read vertices:
	for (i = 0; i < vertexCount_ && !_in.eof(); ++i) {
		v[0] = 0.0;
		v[1] = 0.0;
		v[2] = 0.0;

299
300
301
		t[0] = 0.0;
		t[1] = 0.0;

Mike Kremer's avatar
Mike Kremer committed
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
		c[0] = 0;
		c[1] = 0;
		c[2] = 0;
		c[3] = 255;

		for (uint propertyIndex = 0; propertyIndex < vertexPropertyCount_; ++propertyIndex) {
			switch (vertexPropertyMap_[propertyIndex].first) {
			case XCOORD:
				readValue(vertexPropertyMap_[propertyIndex].second, _in, v[0]);
				break;
			case YCOORD:
				readValue(vertexPropertyMap_[propertyIndex].second, _in, v[1]);
				break;
			case ZCOORD:
				readValue(vertexPropertyMap_[propertyIndex].second, _in, v[2]);
				break;
318
319
320
321
322
323
			case TEXX:
				readValue(vertexPropertyMap_[propertyIndex].second, _in, t[0]);
				break;
			case TEXY:
				readValue(vertexPropertyMap_[propertyIndex].second, _in, t[1]);
				break;
Mike Kremer's avatar
Mike Kremer committed
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
			case COLORRED:
				if (vertexPropertyMap_[propertyIndex].second == ValueTypeFLOAT32) {
					readValue(vertexPropertyMap_[propertyIndex].second, _in, tmp);

					c[0] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
				} else
					readValue(vertexPropertyMap_[propertyIndex].second, _in, c[0]);
				break;
			case COLORGREEN:
				if (vertexPropertyMap_[propertyIndex].second == ValueTypeFLOAT32) {
					readValue(vertexPropertyMap_[propertyIndex].second, _in, tmp);
					c[1] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
				} else
					readValue(vertexPropertyMap_[propertyIndex].second, _in, c[1]);
				break;
			case COLORBLUE:
				if (vertexPropertyMap_[propertyIndex].second == ValueTypeFLOAT32) {
					readValue(vertexPropertyMap_[propertyIndex].second, _in, tmp);
					c[2] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
				} else
					readValue(vertexPropertyMap_[propertyIndex].second, _in, c[2]);
				break;
			case COLORALPHA:
				if (vertexPropertyMap_[propertyIndex].second == ValueTypeFLOAT32) {
					readValue(vertexPropertyMap_[propertyIndex].second, _in, tmp);
					c[3] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
				} else
					readValue(vertexPropertyMap_[propertyIndex].second, _in, c[3]);
				break;
			default:
				break;
			}

		}

		vh = _bi.add_vertex(v);
360
		_bi.set_texcoord(vh, t);
Mike Kremer's avatar
Mike Kremer committed
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
		_bi.set_color(vh, Vec4uc(c));
	}

	for (i = 0; i < faceCount_; ++i) {
		// Read number of vertices for the current face
		readValue(faceIndexType_, _in, nV);

		if (nV == 3) {
			vhandles.resize(3);
			readValue(faceEntryType_, _in, j);
			readValue(faceEntryType_, _in, k);
			readValue(faceEntryType_, _in, l);

			vhandles[0] = VertexHandle(j);
			vhandles[1] = VertexHandle(k);
			vhandles[2] = VertexHandle(l);
		} else {
			vhandles.clear();
			for (j = 0; j < nV; ++j) {
				readValue(faceEntryType_, _in, idx);
				vhandles.push_back(VertexHandle(idx));
			}
		}

		FaceHandle fh = _bi.add_face(vhandles);
	}

	return true;
Jan Möbius's avatar
Jan Möbius committed
389
390
391
392
393
}

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


394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
//-----------------------------------------------------------------------------


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

	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;
	}
}

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

	int32_t tmp_int32_t;
	uint8_t tmp_uchar;

	switch (_type) {
	case ValueTypeINT:
	case ValueTypeINT32:
		restore(_in, tmp_int32_t, options_.check(Options::MSB));
		_value = tmp_int32_t;
		break;
	case ValueTypeUCHAR:
		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;
	}
}

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

	int32_t tmp_int32_t;
	uint8_t tmp_uchar;

	switch (_type) {
	case ValueTypeINT:
	case ValueTypeINT32:
		restore(_in, tmp_int32_t, options_.check(Options::MSB));
		_value = tmp_int32_t;
		break;
	case ValueTypeUCHAR:
		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;
	}
}

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

Mike Kremer's avatar
Mike Kremer committed
459
460
461
bool _PLYReader_::can_u_read(const std::string& _filename) const {
	// !!! Assuming BaseReader::can_u_parse( std::string& )
	// does not call BaseReader::read_magic()!!!
462

Mike Kremer's avatar
Mike Kremer committed
463
464
465
466
467
468
469
470
	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
471
472
473
474
}

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

Mike Kremer's avatar
Mike Kremer committed
475
476
477
478
479
480
481
482
483
484
485
std::string get_property_name(std::string _string1, std::string _string2) {
	if (_string1 == "float32" || _string1 == "uint8" || _string1 == "uchar" || _string1 == "float" || _string1
			== "int32")
		return _string2;

	if (_string2 == "float32" || _string2 == "uint8" || _string2 == "uchar" || _string2 == "float" || _string2
			== "int32")
		return _string1;

	std::cerr << "Unsupported entry type" << std::endl;
	return "Unsupported";
Jan Möbius's avatar
Jan Möbius committed
486
487
488
489
}

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

Mike Kremer's avatar
Mike Kremer committed
490
491
492
493
494
495
496
497
498
499
500
501
502
_PLYReader_::ValueType get_property_type(std::string _string1, std::string _string2) {
	if (_string1 == "float32" || _string2 == "float32")
		return _PLYReader_::ValueTypeFLOAT32;
	else if (_string1 == "uint8" || _string2 == "float32")
		return _PLYReader_::ValueTypeUINT8;
	else if (_string1 == "int32" || _string2 == "float32")
		return _PLYReader_::ValueTypeINT32;
	else if (_string1 == "uchar" || _string2 == "uchar")
		return _PLYReader_::ValueTypeUCHAR;
	else if (_string1 == "float" || _string2 == "float")
		return _PLYReader_::ValueTypeFLOAT;

	return _PLYReader_::Unsupported;
Jan Möbius's avatar
Jan Möbius committed
503
504
505
506
}

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

Mike Kremer's avatar
Mike Kremer committed
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
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
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
bool _PLYReader_::can_u_read(std::istream& _is) const {
	// Clear per file options
	options_.cleanup();

	// clear vertex property map, will be recreated
	vertexPropertyMap_.clear();
	vertexPropertyCount_ = 0;

	// read 1st line
	std::string line;
	std::getline(_is, line);

	//Check if this file is really a ply format
	if (line != "PLY" && line != "ply")
		return false;

	//   omlog() << "PLY header found" << std::endl;

	vertexCount_ = 0;
	faceCount_ = 0;
	vertexDimension_ = 0;

	std::string keyword;
	std::string fileType;
	std::string elementName = "";
	std::string propertyType;
	std::string propertyName;
	std::string listIndexType;
	std::string listEntryType;
	float version;

	_is >> keyword;
	_is >> fileType;
	_is >> version;

	if (_is.bad()) {
		omerr() << "Defect PLY header detected" << std::endl;
		return false;
	}

	if (fileType == "ascii") {
		options_ -= Options::Binary;
	} else if (fileType == "binary_little_endian") {
		options_ += Options::Binary;
		options_ += Options::LSB;
	} else if (fileType == "binary_big_endian") {
		options_ += Options::Binary;
		options_ += Options::MSB;
	} else {
		omerr() << "Unsupported PLY format: " << fileType << std::endl;
		return false;
	}

	unsigned int streamPos = _is.tellg();
	_is >> keyword;
	while (keyword != "end_header") {

		if (keyword == "comment") {
			std::getline(_is, line);
			omlog() << "PLY header comment : " << line << std::endl;
		} else if (keyword == "element") {
			_is >> elementName;
			if (elementName == "vertex") {
				_is >> vertexCount_;
			} else if (elementName == "face") {
				_is >> faceCount_;
			} else {
				omerr() << "PLY header unsupported element type: " << elementName << std::endl;
			}
		} else if (keyword == "property") {
			std::string tmp1;
			std::string tmp2;

			// Read first keyword, as it might be a list
			_is >> tmp1;

			if (tmp1 == "list") {
				if (elementName == "vertex") {
					omerr() << "List type not supported for vertices!" << std::endl;
				} else if (elementName == "face") {
					_is >> listIndexType;
					_is >> listEntryType;
					_is >> propertyName;

					if (listIndexType == "uint8") {
						faceIndexType_ = ValueTypeUINT8;
					} else if (listIndexType == "uchar") {
						faceIndexType_ = ValueTypeUCHAR;
					} else {
						omerr() << "Unsupported Index type for face list: " << listIndexType << std::endl;
					}

					if (listEntryType == "int32") {
						faceEntryType_ = ValueTypeINT32;
					} else if (listEntryType == "int") {
						faceEntryType_ = ValueTypeINT;
					} else {
						omerr() << "Unsupported Entry type for face list: " << listEntryType << std::endl;
					}

				}
			} else {
				// as this is not a list property, read second value of property
				_is >> tmp2;

				if (elementName == "vertex") {
					// Extract name and type of property
					// As the order seems to be different in some files, autodetect it.
					ValueType valueType = get_property_type(tmp1, tmp2);
					propertyName = get_property_name(tmp1, tmp2);

					if (propertyName == "x") {
						std::pair<VertexProperty, ValueType> entry(XCOORD, valueType);
						vertexPropertyMap_[vertexPropertyCount_] = entry;
						vertexDimension_++;
					} else if (propertyName == "y") {
						std::pair<VertexProperty, ValueType> entry(YCOORD, valueType);
						vertexPropertyMap_[vertexPropertyCount_] = entry;
						vertexDimension_++;
					} else if (propertyName == "z") {
						std::pair<VertexProperty, ValueType> entry(ZCOORD, valueType);
						vertexPropertyMap_[vertexPropertyCount_] = entry;
						vertexDimension_++;
630
631
632
633
634
635
636
637
					} else if (propertyName == "u" || propertyName == "s") {
						std::pair<VertexProperty, ValueType> entry(TEXX, valueType);
						vertexPropertyMap_[vertexPropertyCount_] = entry;
						options_ += Options::VertexTexCoord;
					} else if (propertyName == "v" || propertyName == "t") {
						std::pair<VertexProperty, ValueType> entry(TEXY, valueType);
						vertexPropertyMap_[vertexPropertyCount_] = entry;
						options_ += Options::VertexTexCoord;
Mike Kremer's avatar
Mike Kremer committed
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
					} else if (propertyName == "red") {
						std::pair<VertexProperty, ValueType> entry(COLORRED, valueType);
						vertexPropertyMap_[vertexPropertyCount_] = entry;
						options_ += Options::VertexColor;
					} else if (propertyName == "green") {
						std::pair<VertexProperty, ValueType> entry(COLORGREEN, valueType);
						vertexPropertyMap_[vertexPropertyCount_] = entry;
						options_ += Options::VertexColor;
					} else if (propertyName == "blue") {
						std::pair<VertexProperty, ValueType> entry(COLORBLUE, valueType);
						vertexPropertyMap_[vertexPropertyCount_] = entry;
						options_ += Options::VertexColor;
					} else if (propertyName == "alpha") {
						std::pair<VertexProperty, ValueType> entry(COLORALPHA, valueType);
						vertexPropertyMap_[vertexPropertyCount_] = entry;
						options_ += Options::VertexColor;
						options_ += Options::ColorAlpha;
					} else {
						std::pair<VertexProperty, ValueType> entry(UNSUPPORTED, valueType);
						vertexPropertyMap_[vertexPropertyCount_] = entry;
						std::cerr << "Unsupported property : " << propertyName << std::endl;
					}

					vertexPropertyCount_++;

				} else if (elementName == "face") {
					omerr() << "Properties not supported for faces " << std::endl;
				}

			}

		} else {
			omlog() << "Unsupported keyword : " << keyword << std::endl;
		}

		streamPos = _is.tellg();
		_is >> keyword;
		if (_is.bad()) {
			omerr() << "Error while reading PLY file header" << std::endl;
			return false;
		}
	}

	// As the binary data is directy after the end_header keyword
	// and the stream removes too many bytes, seek back to the right position
	if (options_.is_binary()) {
		_is.seekg(streamPos + 12);
	}

	return true;
Jan Möbius's avatar
Jan Möbius committed
688
689
690
691
692
693
}

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