import2tablesSurface.hpp 41.9 KB
Newer Older
Pierre Kraemer's avatar
Pierre Kraemer committed
1
2
3
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps  *
* version 0.1                                                                  *
4
* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg           *
Pierre Kraemer's avatar
Pierre Kraemer committed
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
*                                                                              *
* This library is free software; you can redistribute it and/or modify it      *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your     *
* option) any later version.                                                   *
*                                                                              *
* This library 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 PURVEC3E. See the GNU Lesser General Public License  *
* for more details.                                                            *
*                                                                              *
* You should have received a copy of the GNU Lesser General Public License     *
* along with this library; if not, write to the Free Software Foundation,      *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.           *
*                                                                              *
20
* Web site: http://cgogn.unistra.fr/                                           *
Pierre Kraemer's avatar
Pierre Kraemer committed
21
22
23
24
25
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

#include "Algo/Import/importPlyData.h"
26
27
#include "Algo/Geometry/boundingbox.h"
#include "Topology/generic/autoAttributeHandler.h"
Pierre Kraemer's avatar
Pierre Kraemer committed
28

29
#include "Algo/Import/AHEM.h"
Pierre Kraemer's avatar
Pierre Kraemer committed
30

Sylvain Thery's avatar
Sylvain Thery committed
31
#ifdef WITH_ASSIMP
Pierre Kraemer's avatar
Pierre Kraemer committed
32
33
34
#include "assimp.h"
#include "aiPostProcess.h"
#include "aiScene.h"
Sylvain Thery's avatar
Sylvain Thery committed
35
#endif
Pierre Kraemer's avatar
Pierre Kraemer committed
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

namespace CGoGN
{

namespace Algo
{

namespace Import
{

template<typename PFP>
ImportSurfacique::ImportType MeshTablesSurface<PFP>::getFileType(const std::string& filename)
{
	if ((filename.rfind(".trianbgz")!=std::string::npos) || (filename.rfind(".TRIANBGZ")!=std::string::npos))
		return ImportSurfacique::TRIANBGZ;
Pierre Kraemer's avatar
Pierre Kraemer committed
51

Pierre Kraemer's avatar
Pierre Kraemer committed
52
53
54
	if ((filename.rfind(".trian")!=std::string::npos) || (filename.rfind(".TRIAN")!=std::string::npos))
		return ImportSurfacique::TRIAN;

55
56
57
	if ((filename.rfind(".meshbin")!=std::string::npos) || (filename.rfind(".MESHBIN")!=std::string::npos))
		return ImportSurfacique::MESHBIN;

Pierre Kraemer's avatar
Pierre Kraemer committed
58
59
60
	if ((filename.rfind(".plyptm")!=std::string::npos) || (filename.rfind(".PLYGEN")!=std::string::npos))
		return ImportSurfacique::PLYPTM;

Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
61
	if ((filename.rfind(".plyPTMextBin")!=std::string::npos) || (filename.rfind(".plySHrealBin")!=std::string::npos))
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
62
		return ImportSurfacique::PLYSLFgenericBin;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
63

Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
64
65
66
	if ((filename.rfind(".plyPTMext")!=std::string::npos) || (filename.rfind(".plySHreal")!=std::string::npos))
		return ImportSurfacique::PLYSLFgeneric;

Pierre Kraemer's avatar
Pierre Kraemer committed
67
68
	if ((filename.rfind(".ply")!=std::string::npos) || (filename.rfind(".PLY")!=std::string::npos))
		return ImportSurfacique::PLY;
Pierre Kraemer's avatar
Pierre Kraemer committed
69

Pierre Kraemer's avatar
Pierre Kraemer committed
70
71
	if ((filename.rfind(".off")!=std::string::npos) || (filename.rfind(".OFF")!=std::string::npos))
		return ImportSurfacique::OFF;
Pierre Kraemer's avatar
Pierre Kraemer committed
72

Pierre Kraemer's avatar
Pierre Kraemer committed
73
74
	if ((filename.rfind(".obj")!=std::string::npos) || (filename.rfind(".OBJ")!=std::string::npos))
		return ImportSurfacique::OBJ;
Pierre Kraemer's avatar
Pierre Kraemer committed
75

76
77
78
	if ((filename.rfind(".ahem")!=std::string::npos) || (filename.rfind(".AHEM")!=std::string::npos))
		return ImportSurfacique::AHEM;

Pierre Kraemer's avatar
Pierre Kraemer committed
79
80
81
82
	return ImportSurfacique::UNKNOWNSURFACE;
}

template<typename PFP>
Pierre Kraemer's avatar
Pierre Kraemer committed
83
bool MeshTablesSurface<PFP>::importMesh(const std::string& filename, std::vector<std::string>& attrNames, ImportSurfacique::ImportType kind)
Pierre Kraemer's avatar
Pierre Kraemer committed
84
85
86
87
{
	if (kind == ImportSurfacique::UNKNOWNSURFACE)
		kind = getFileType(filename);

Pierre Kraemer's avatar
Pierre Kraemer committed
88
	attrNames.clear() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
89
90
91
92

	switch (kind)
	{
	case ImportSurfacique::TRIAN:
93
		CGoGNout << "TYPE: TRIAN" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
94
		return importTrian(filename, attrNames);
Pierre Kraemer's avatar
Pierre Kraemer committed
95
96
		break;
	case ImportSurfacique::TRIANBGZ:
97
		CGoGNout << "TYPE: TRIANBGZ" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
98
		return importTrianBinGz(filename, attrNames);
Pierre Kraemer's avatar
Pierre Kraemer committed
99
100
		break;
	case ImportSurfacique::OFF:
101
		CGoGNout << "TYPE: OFF" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
102
		return importOff(filename, attrNames);
Pierre Kraemer's avatar
Pierre Kraemer committed
103
		break;
104
105
106
107
	case ImportSurfacique::MESHBIN:
		CGoGNout << "TYPE: MESHBIN" << CGoGNendl;
		return importMeshBin(filename, attrNames);
		break;
Pierre Kraemer's avatar
Pierre Kraemer committed
108
	case ImportSurfacique::PLY:
109
		CGoGNout << "TYPE: PLY" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
110
		return importPly(filename, attrNames);
Pierre Kraemer's avatar
Pierre Kraemer committed
111
		break;
Pierre Kraemer's avatar
Pierre Kraemer committed
112
	case ImportSurfacique::PLYPTM:
113
		CGoGNout << "TYPE: PLYPTM" << CGoGNendl;
114
115
		return importPlyPTM(filename, attrNames);
		break;
116
117
118
	case ImportSurfacique::PLYSLFgeneric:
		CGoGNout << "TYPE: PLYSLFgeneric" << CGoGNendl;
		return importPlySLFgeneric(filename, attrNames);
Pierre Kraemer's avatar
Pierre Kraemer committed
119
		break;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
120
121
122
123
124
	case ImportSurfacique::PLYSLFgenericBin:
		CGoGNout << "TYPE: PLYSLFgenericBin" << CGoGNendl;
		return importPlySLFgenericBin(filename, attrNames);
		break;

Pierre Kraemer's avatar
Pierre Kraemer committed
125
	case ImportSurfacique::OBJ:
126
		CGoGNout << "TYPE: OBJ" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
127
		return importObj(filename, attrNames);
Pierre Kraemer's avatar
Pierre Kraemer committed
128
		break;
129
130
131
132
	case ImportSurfacique::AHEM:
		CGoGNout << "TYPE: AHEM" << CGoGNendl;
		return importAHEM(filename, attrNames);
		break;
Pierre Kraemer's avatar
Pierre Kraemer committed
133
	default:
Sylvain Thery's avatar
Sylvain Thery committed
134
	#ifdef WITH_ASSIMP
135
		CGoGNout << "TYPE: ASSIMP" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
136
		return importASSIMP(filename, attrNames);
Sylvain Thery's avatar
Sylvain Thery committed
137
138
139
	#else
		CGoGNout << "unsupported file type"<< CGoGNendl;		
	#endif
Pierre Kraemer's avatar
Pierre Kraemer committed
140
141
142
143
144
145
		break;
	}
	return false;
}

template<typename PFP>
Pierre Kraemer's avatar
Pierre Kraemer committed
146
bool MeshTablesSurface<PFP>::importTrian(const std::string& filename, std::vector<std::string>& attrNames)
Pierre Kraemer's avatar
Pierre Kraemer committed
147
{
148
	AttributeHandler<typename PFP::VEC3> positions =  m_map.template getAttribute<typename PFP::VEC3>(VERTEX, "position") ;
149
150

	if (!positions.isValid())
151
		positions = m_map.template addAttribute<typename PFP::VEC3>(VERTEX, "position") ;
152

Pierre Kraemer's avatar
Pierre Kraemer committed
153
154
	attrNames.push_back(positions.name()) ;

155
	AttributeContainer& container = m_map.getAttributeContainer(VERTEX) ;
156

Pierre Kraemer's avatar
Pierre Kraemer committed
157
158
159
160
	// open file
	std::ifstream fp(filename.c_str(), std::ios::in);
	if (!fp.good())
	{
161
		CGoGNerr << "Unable to open file " << filename << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
162
163
164
		return false;
	}

Pierre Kraemer's avatar
Pierre Kraemer committed
165
	// read nb of points
Pierre Kraemer's avatar
Pierre Kraemer committed
166
167
	fp >> m_nbVertices;

Pierre Kraemer's avatar
Pierre Kraemer committed
168
	// read points
Pierre Kraemer's avatar
Pierre Kraemer committed
169
170
171
	std::vector<unsigned int> verticesID;
	verticesID.reserve(m_nbVertices);

Pierre Kraemer's avatar
Pierre Kraemer committed
172
	for (unsigned int i = 0; i < m_nbVertices; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
173
174
175
176
177
	{
		VEC3 pos;
		fp >> pos[0];
		fp >> pos[1];
		fp >> pos[2];
Pierre Kraemer's avatar
Pierre Kraemer committed
178
179
		unsigned int id = container.insertLine();
		positions[id] = pos;
Pierre Kraemer's avatar
Pierre Kraemer committed
180
181
182
183
184
185
186
187
		verticesID.push_back(id);
	}

	// read nb of faces
	fp >> m_nbFaces;
	m_nbEdges.reserve(m_nbFaces);
	m_emb.reserve(3*m_nbFaces);

Pierre Kraemer's avatar
Pierre Kraemer committed
188
189
	// read indices of faces
	for (unsigned int i = 0; i < m_nbFaces; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
	{
		m_nbEdges.push_back(3);
		// read the three vertices of triangle
		int pt;
		fp >> pt;
		m_emb.push_back(verticesID[pt]);
		fp >> pt;
		m_emb.push_back(verticesID[pt]);
		fp >> pt;
		m_emb.push_back(verticesID[pt]);

		// neighbour not always good in files !!
		int neigh;
		fp >> neigh;
		fp >> neigh;
		fp >> neigh;
	}

	fp.close();
	return true;
}

template<typename PFP>
Pierre Kraemer's avatar
Pierre Kraemer committed
213
bool MeshTablesSurface<PFP>::importTrianBinGz(const std::string& filename, std::vector<std::string>& attrNames)
Pierre Kraemer's avatar
Pierre Kraemer committed
214
{
215
	AttributeHandler<typename PFP::VEC3> positions =  m_map.template getAttribute<typename PFP::VEC3>(VERTEX, "position") ;
216
217

	if (!positions.isValid())
218
		positions = m_map.template addAttribute<typename PFP::VEC3>(VERTEX, "position") ;
219

Pierre Kraemer's avatar
Pierre Kraemer committed
220
221
	attrNames.push_back(positions.name()) ;

222
	AttributeContainer& container = m_map.getAttributeContainer(VERTEX) ;
223

Pierre Kraemer's avatar
Pierre Kraemer committed
224
225
226
227
228
	// open file
	igzstream fs(filename.c_str(), std::ios::in|std::ios::binary);

	if (!fs.good())
	{
229
		CGoGNerr << "Unable to open file " << filename << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
230
231
		return false;
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
232

Pierre Kraemer's avatar
Pierre Kraemer committed
233
234
235
236
237
	// read nb of points
	fs.read(reinterpret_cast<char*>(&m_nbVertices), sizeof(int));

	// read points
	std::vector<unsigned int> verticesID;
Pierre Kraemer's avatar
Pierre Kraemer committed
238
	{	// juste pour limiter la portee des variables
Pierre Kraemer's avatar
Pierre Kraemer committed
239
240
		verticesID.reserve(m_nbVertices);
		float* buffer = new float[m_nbVertices*3];
Pierre Kraemer's avatar
Pierre Kraemer committed
241
		fs.read(reinterpret_cast<char*>(buffer), 3*m_nbVertices*sizeof(float));
Pierre Kraemer's avatar
Pierre Kraemer committed
242
		float *ptr = buffer;
Pierre Kraemer's avatar
Pierre Kraemer committed
243
		for (unsigned int i = 0; i < m_nbVertices; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
244
245
246
247
248
249
		{
			VEC3 pos;
			pos[0]= *ptr++;
			pos[1]= *ptr++;
			pos[2]= *ptr++;

Pierre Kraemer's avatar
Pierre Kraemer committed
250
251
			unsigned int id = container.insertLine();
			positions[id] = pos;
Pierre Kraemer's avatar
Pierre Kraemer committed
252
253
254
255
256
257
258
259
260
261
262
263

			verticesID.push_back(id);
		}
		delete[] buffer;
	}

	// read nb of faces
	fs.read(reinterpret_cast<char*>(&m_nbFaces), sizeof(int));
	m_nbEdges.reserve(m_nbFaces);
	m_emb.reserve(3*m_nbFaces);

	// read indices of faces
Pierre Kraemer's avatar
Pierre Kraemer committed
264
	{	// juste pour limiter la portee des variables
Pierre Kraemer's avatar
Pierre Kraemer committed
265
266
267
268
		int* buffer = new int[m_nbFaces*6];
		fs.read(reinterpret_cast<char*>(buffer),6*m_nbFaces*sizeof(float));
		int *ptr = buffer;

Pierre Kraemer's avatar
Pierre Kraemer committed
269
		for (unsigned int i = 0; i < m_nbFaces; i++)
Pierre Kraemer's avatar
Pierre Kraemer committed
270
271
272
273
274
275
276
277
278
279
280
281
282
		{
			m_nbEdges.push_back(3);
			m_emb.push_back(verticesID[*ptr++]);
			m_emb.push_back(verticesID[*ptr++]);
			m_emb.push_back(verticesID[*ptr++]);
		}
	}
	
	fs.close();
	return true;
}

template<typename PFP>
Pierre Kraemer's avatar
Pierre Kraemer committed
283
bool MeshTablesSurface<PFP>::importOff(const std::string& filename, std::vector<std::string>& attrNames)
Pierre Kraemer's avatar
Pierre Kraemer committed
284
{
285
	AttributeHandler<typename PFP::VEC3> positions = m_map.template getAttribute<typename PFP::VEC3>(VERTEX, "position") ;
286
287

	if (!positions.isValid())
288
		positions = m_map.template addAttribute<typename PFP::VEC3>(VERTEX, "position") ;
289

Pierre Kraemer's avatar
Pierre Kraemer committed
290
291
	attrNames.push_back(positions.name()) ;

292
	AttributeContainer& container = m_map.getAttributeContainer(VERTEX) ;
293

Pierre Kraemer's avatar
Pierre Kraemer committed
294
295
296
297
	// open file
	std::ifstream fp(filename.c_str(), std::ios::in);
	if (!fp.good())
	{
298
		CGoGNerr << "Unable to open file " << filename << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
299
300
301
302
303
304
305
306
307
		return false;
	}

    std::string ligne;

    // lecture de OFF
    std::getline (fp, ligne);
    if (ligne.rfind("OFF") == std::string::npos)
    {
308
309
		CGoGNerr << "Problem reading off file: not an off file" << CGoGNendl;
		CGoGNerr << ligne << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
310
		return false;
Pierre Kraemer's avatar
Pierre Kraemer committed
311
312
313
314
315
316
317
318
    }

    // lecture des nombres de sommets/faces/aretes
	int nbe;
    {
    	do
    	{
    		std::getline (fp, ligne);
Pierre Kraemer's avatar
Pierre Kraemer committed
319
    	} while (ligne.size() == 0);
Pierre Kraemer's avatar
Pierre Kraemer committed
320
321
322
323
324
325
326
327
328
329

	    std::stringstream oss(ligne);
		oss >> m_nbVertices;
		oss >> m_nbFaces;
		oss >> nbe;
    }

	//lecture sommets
	std::vector<unsigned int> verticesID;
	verticesID.reserve(m_nbVertices);
Pierre Kraemer's avatar
Pierre Kraemer committed
330
	for (unsigned int i = 0; i < m_nbVertices;++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
331
332
333
334
	{
    	do
    	{
    		std::getline (fp, ligne);
Pierre Kraemer's avatar
Pierre Kraemer committed
335
    	} while (ligne.size() == 0);
Pierre Kraemer's avatar
Pierre Kraemer committed
336
337
338
339
340
341
342
343
344
345

		std::stringstream oss(ligne);

		float x,y,z;
		oss >> x;
		oss >> y;
		oss >> z;
		// on peut ajouter ici la lecture de couleur si elle existe
		VEC3 pos(x,y,z);

Pierre Kraemer's avatar
Pierre Kraemer committed
346
347
		unsigned int id = container.insertLine();
		positions[id] = pos;
Pierre Kraemer's avatar
Pierre Kraemer committed
348
349
350
351
352
353
354
355
356

		verticesID.push_back(id);
	}

	// lecture faces
	// normalement nbVertices*8 devrait suffire largement
	m_nbEdges.reserve(m_nbFaces);
	m_emb.reserve(m_nbVertices*8);

Pierre Kraemer's avatar
Pierre Kraemer committed
357
	for (unsigned int i = 0; i < m_nbFaces; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
358
359
360
361
	{
    	do
    	{
    		std::getline (fp, ligne);
Pierre Kraemer's avatar
Pierre Kraemer committed
362
    	} while (ligne.size() == 0);
Pierre Kraemer's avatar
Pierre Kraemer committed
363
364

		std::stringstream oss(ligne);
Pierre Kraemer's avatar
Pierre Kraemer committed
365
		unsigned int n;
Pierre Kraemer's avatar
Pierre Kraemer committed
366
367
		oss >> n;
		m_nbEdges.push_back(n);
Pierre Kraemer's avatar
Pierre Kraemer committed
368
		for (unsigned int j = 0; j < n; ++j)
Pierre Kraemer's avatar
Pierre Kraemer committed
369
370
371
372
373
374
375
376
377
378
379
380
		{
			int index; // index du plongement
			oss >> index;
			m_emb.push_back(verticesID[index]);
		}
		// on peut ajouter ici la lecture de couleur si elle existe
	}

	fp.close();
	return true;
}

381
382
383
template<typename PFP>
bool MeshTablesSurface<PFP>::importMeshBin(const std::string& filename, std::vector<std::string>& attrNames)
{
384
	std::cout << filename << std::endl ;
385
386
387
	AttributeHandler<typename PFP::VEC3> positions = m_map.template getAttribute<typename PFP::VEC3>(VERTEX, "position") ;

	if (!positions.isValid())
388
389
	{
		std::cout << "Not valid" << std::endl ;
390
		positions = m_map.template addAttribute<typename PFP::VEC3>(VERTEX, "position") ;
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

	attrNames.push_back(positions.name()) ;

	AttributeContainer& container = m_map.getAttributeContainer(VERTEX) ;

	// open file
	std::ifstream fp(filename.c_str(), std::ios::in | std::ios::binary);
	if (!fp.good())
	{
		CGoGNerr << "Unable to open file " << filename << CGoGNendl;
		return false;
	}

	// Read header
    unsigned int Fmin, Fmax ;
    fp.read((char*)&m_nbVertices, sizeof(unsigned int)) ;
    fp.read((char*)&m_nbFaces, sizeof(unsigned int)) ;
    fp.read((char*)&Fmin, sizeof(unsigned int)) ;
    fp.read((char*)&Fmax, sizeof(unsigned int)) ;

    assert((Fmin == 3 && Fmax == 3) || !"Only triangular faces are handled yet") ;

    // Read foreach vertex
	std::vector<unsigned int> verticesID ;
	verticesID.reserve(m_nbVertices) ;

    for (unsigned int vxNum = 0 ; vxNum < m_nbVertices ; ++vxNum)
    {
420
    	Geom::Vec3f pos ;
421
422
423
424
425
426
427
428
429
    	fp.read((char*) &pos[0], sizeof(float)) ;
    	fp.read((char*) &pos[1], sizeof(float)) ;
    	fp.read((char*) &pos[2], sizeof(float)) ;

		unsigned int id = container.insertLine() ;
		positions[id] = pos ;

		verticesID.push_back(id) ;
    }
430
    std::cout << positions[0] << std::endl ;
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454

    // Read foreach face
	m_nbEdges.reserve(m_nbFaces) ;
	m_emb.reserve(m_nbVertices * 8) ;

	for (unsigned int fNum = 0; fNum < m_nbFaces; ++fNum)
	{
		const unsigned int faceSize = 3 ;
		fp.read((char*) &faceSize, sizeof(float)) ;
		m_nbEdges.push_back(faceSize) ;

		for (unsigned int i = 0 ; i < faceSize; ++i)
		{
			unsigned int index ; // index of embedding
			fp.read((char*) &index, sizeof(unsigned int)) ;
			m_emb.push_back(verticesID[index]) ;
		}
	}

	fp.close() ;
	return true ;
}


Pierre Kraemer's avatar
Pierre Kraemer committed
455
template <typename PFP>
Pierre Kraemer's avatar
Pierre Kraemer committed
456
bool MeshTablesSurface<PFP>::importObj(const std::string& filename, std::vector<std::string>& attrNames)
Pierre Kraemer's avatar
Pierre Kraemer committed
457
{
458
	AttributeHandler<typename PFP::VEC3> positions =  m_map.template getAttribute<typename PFP::VEC3>(VERTEX, "position") ;
459
460

	if (!positions.isValid())
461
		positions = m_map.template addAttribute<typename PFP::VEC3>(VERTEX, "position") ;
462

Pierre Kraemer's avatar
Pierre Kraemer committed
463
464
	attrNames.push_back(positions.name()) ;

465
	AttributeContainer& container = m_map.getAttributeContainer(VERTEX) ;
466

Pierre Kraemer's avatar
Pierre Kraemer committed
467
468
469
470
	// open file
	std::ifstream fp(filename.c_str(), std::ios::binary);
	if (!fp.good())
	{
471
		CGoGNerr << "Unable to open file " << filename << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
472
473
474
		return false;
	}

Pierre Kraemer's avatar
Pierre Kraemer committed
475
//	fp.seekg(0, std::ios::end);
Pierre Kraemer's avatar
Pierre Kraemer committed
476
//	int ab = fp.tellg();
Pierre Kraemer's avatar
Pierre Kraemer committed
477
//	fp.seekg(0, std::ios::beg);
Pierre Kraemer's avatar
Pierre Kraemer committed
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
//	int ac = fp.tellg();

    std::string ligne;
    std::string tag;

    do
    {
    	fp >> tag;
    	std::getline (fp, ligne);
    }while (tag != std::string("v"));

    // lecture des sommets
	std::vector<unsigned int> verticesID;
	verticesID.reserve(102400); // on tape large (400Ko wahouuuuu !!)

Pierre Kraemer's avatar
Pierre Kraemer committed
493
	unsigned int i = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
494
495
496
497
498
499
500
501
502
503
504
505
506
    do
    {
		if (tag == std::string("v"))
		{
			std::stringstream oss(ligne);
		
			float x,y,z;
			oss >> x;
			oss >> y;
			oss >> z;

			VEC3 pos(x,y,z);

Pierre Kraemer's avatar
Pierre Kraemer committed
507
508
			unsigned int id = container.insertLine();
			positions[id] = pos;
Pierre Kraemer's avatar
Pierre Kraemer committed
509
510
511
512
513
514

			verticesID.push_back(id);
			i++;
		}

		fp >> tag;
Pierre Kraemer's avatar
Pierre Kraemer committed
515
    	std::getline(fp, ligne);
Pierre Kraemer's avatar
Pierre Kraemer committed
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
    } while (!fp.eof());

	m_nbVertices = verticesID.size();

	// close/clear/open only way to go back to beginning of file
	fp.close();
	fp.clear();
	fp.open(filename.c_str());

	do
    {
    	fp >> tag;
    	std::getline (fp, ligne);
    } while (tag != std::string("f"));

	m_nbEdges.reserve(verticesID.size()*2);
	m_emb.reserve(verticesID.size()*8);

	std::vector<int> table;
535
	table.reserve(64); // NBV cotes pour une face devrait suffire
Pierre Kraemer's avatar
Pierre Kraemer committed
536
537
538
	m_nbFaces = 0;
    do
    {
Pierre Kraemer's avatar
Pierre Kraemer committed
539
    	if (tag == std::string("f")) // lecture d'une face
Pierre Kraemer's avatar
Pierre Kraemer committed
540
541
542
543
544
545
546
547
    	{
    		std::stringstream oss(ligne);
     		table.clear();
    		while (!oss.eof())  // lecture de tous les indices
    		{
    			std::string str;
    			oss >> str;

Pierre Kraemer's avatar
Pierre Kraemer committed
548
    			unsigned int ind = 0;
Sylvain Thery's avatar
Sylvain Thery committed
549

Pierre Kraemer's avatar
Pierre Kraemer committed
550
    			while ((ind<str.length()) && (str[ind]!='/'))
Pierre Kraemer's avatar
Pierre Kraemer committed
551
552
    				ind++;

Pierre Kraemer's avatar
Pierre Kraemer committed
553
				if (ind > 0)
Pierre Kraemer's avatar
Pierre Kraemer committed
554
555
				{
    				long index;
Pierre Kraemer's avatar
Pierre Kraemer committed
556
					std::stringstream iss(str.substr(0, ind));
Pierre Kraemer's avatar
Pierre Kraemer committed
557
558
559
560
561
					iss >> index;
		   			table.push_back(index);
				}
    		}

Pierre Kraemer's avatar
Pierre Kraemer committed
562
    		unsigned int n = table.size();
Pierre Kraemer's avatar
Pierre Kraemer committed
563
			m_nbEdges.push_back(short(n));
Pierre Kraemer's avatar
Pierre Kraemer committed
564
    		for (unsigned int j = 0; j < n; ++j)
Pierre Kraemer's avatar
Pierre Kraemer committed
565
    		{
Pierre Kraemer's avatar
Pierre Kraemer committed
566
    			int index = table[j] - 1; // les index commencent a 1 (boufonnerie d'obj ;)
Pierre Kraemer's avatar
Pierre Kraemer committed
567
568
569
570
571
				m_emb.push_back(verticesID[index]);
    		}
			m_nbFaces++;
    	}
		fp >> tag;
Pierre Kraemer's avatar
Pierre Kraemer committed
572
    	std::getline(fp, ligne);
Pierre Kraemer's avatar
Pierre Kraemer committed
573
574
575
576
577
578
579
     } while (!fp.eof());

	fp.close ();
	return true;
}

template<typename PFP>
Pierre Kraemer's avatar
Pierre Kraemer committed
580
bool MeshTablesSurface<PFP>::importPly(const std::string& filename, std::vector<std::string>& attrNames)
Pierre Kraemer's avatar
Pierre Kraemer committed
581
{
582
	AttributeHandler<typename PFP::VEC3> positions =  m_map.template getAttribute<typename PFP::VEC3>(VERTEX, "position") ;
583
584

	if (!positions.isValid())
585
		positions = m_map.template addAttribute<typename PFP::VEC3>(VERTEX, "position") ;
586

Pierre Kraemer's avatar
Pierre Kraemer committed
587
588
	attrNames.push_back(positions.name()) ;

589
	AttributeContainer& container = m_map.getAttributeContainer(VERTEX) ;
590

Pierre Kraemer's avatar
Pierre Kraemer committed
591
592
593
594
	PlyImportData pid;

	if (! pid.read_file(filename) )
	{
595
		CGoGNerr << "Unable to open file " << filename << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
596
597
598
		return false;
	}
	
599
600
601
602
603
604
605
606
	AttributeHandler<typename PFP::VEC3> colors = m_map.template getAttribute<typename PFP::VEC3>(VERTEX, "color") ;
	if (pid.hasColors())
	{
		if(!colors.isValid())
			colors = m_map.template addAttribute<typename PFP::VEC3>(VERTEX, "color") ;
		attrNames.push_back(colors.name()) ;
	}

Pierre Kraemer's avatar
Pierre Kraemer committed
607
608
609
610
611
612
613
    // lecture des nombres de sommets/aretes/faces
	m_nbVertices = pid.nbVertices();
	m_nbFaces = pid.nbFaces();
 
	//lecture sommets
	std::vector<unsigned int> verticesID;
	verticesID.reserve(m_nbVertices);
Pierre Kraemer's avatar
Pierre Kraemer committed
614
	for (unsigned int i = 0; i < m_nbVertices; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
615
616
	{
		VEC3 pos;
Pierre Kraemer's avatar
Pierre Kraemer committed
617
		pid.vertexPosition(i, pos);
Pierre Kraemer's avatar
Pierre Kraemer committed
618

Pierre Kraemer's avatar
Pierre Kraemer committed
619
620
		unsigned int id = container.insertLine();
		positions[id] = pos;
Pierre Kraemer's avatar
Pierre Kraemer committed
621

622
623
624
625
626
627
628
629
630
631
		if (pid.hasColors())
		{
			Geom::Vector<3, unsigned char> col ;
			pid.vertexColorUint8(i, col) ;
			colors[id][0] = col[0] ;
			colors[id][1] = col[1] ;
			colors[id][2] = col[2] ;
			colors[id] /= 255.0 ;
		}

Pierre Kraemer's avatar
Pierre Kraemer committed
632
633
634
635
636
637
		verticesID.push_back(id);
	}

	m_nbEdges.reserve(m_nbFaces);
	m_emb.reserve(m_nbVertices*8);

638
	for (unsigned int i = 0 ; i < m_nbFaces ; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
639
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
640
		unsigned int n = pid.getFaceValence(i);
Pierre Kraemer's avatar
Pierre Kraemer committed
641
642
		m_nbEdges.push_back(n);
		int* indices = pid.getFaceIndices(i);
Pierre Kraemer's avatar
Pierre Kraemer committed
643
		for (unsigned int j = 0; j < n; ++j)
Pierre Kraemer's avatar
Pierre Kraemer committed
644
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
645
			m_emb.push_back(verticesID[indices[j]]);
Pierre Kraemer's avatar
Pierre Kraemer committed
646
647
648
649
650
651
		}
	}

	return true;
}

652
/**
653
654
 * Import plySLF (K Vanhoey generic format).
 * It can handle bivariable polynomials and spherical harmonics of any degree and returns the appropriate attrNames
655
656
 * @param filename the file to import;
 * @param attrNames reference that will be filled with the attribute names
657
 * the number of attrNames returned depends on the degree of the polynomials / level of the SH :
658
659
 *  - 1 attrName for geometric position (VEC3) : name = "position" ;
 *  - 3 attrNames for local frame (3xVEC3) : names are "Frame_T" (Tangent), "Frame_B" (Binormal) and "Frame_N" (Normal) ;
660
 *  - N attrNames for the function coefficients (NxVEC3) : N RGB coefficients being successively the constants, the linears (v then u), the quadratics, etc. :  : a0 + a1*v + a2*u + a3*u*v + a4*v^2 + a5*u^2.
661
 *  Their names are : "SLFcoefs_<i>" (where <i> is a number from 0 to N-1).
662
663
664
665
666
 * N = 1 for constant polynomial,
 * N = 3 for linear polynomial,
 * N = 6 for quadratic polynomial,
 * N = 10 for cubic degree polynomial,
 * N = 15 for 4th degree polynomial,
667
668
 *
 * N = l*l for SH of level l,
669
 * ...
670
 *  - K remaining attrNames named "remainderNo<k>" where k is an integer from 0 to K-1.
671
672
 * @return bool : success.
 */
Pierre Kraemer's avatar
Pierre Kraemer committed
673
template <typename PFP>
674
bool MeshTablesSurface<PFP>::importPlySLFgeneric(const std::string& filename, std::vector<std::string>& attrNames)
675
{
676
677
	// Open file
	std::ifstream fp(filename.c_str(), std::ios::in) ;
678
679
	if (!fp.good())
	{
680
681
		CGoGNerr << "Unable to open file " << filename << CGoGNendl ;
		return false ;
682
683
	}

684
685
	// Read quantities : #vertices, #faces, #properties, degree of polynomials
    std::string tag ;
686

687
688
    fp >> tag;
	if (tag != std::string("ply")) // verify file type
689
	{
690
691
		CGoGNerr << filename << " is not a ply file !" <<  CGoGNout ;
		return false ;
692
693
	}

694
	do // go to #vertices
695
	{
696
697
698
699
		fp >> tag ;
	} while (tag != std::string("vertex")) ;
	unsigned int nbVertices ;
	fp >> nbVertices ; // Read #vertices
700

701
702
703
704
705
	bool position = false ;
	bool tangent = false ;
	bool binormal = false ;
	bool normal = false ;
	unsigned int nbProps = 0 ;			// # properties
706
	unsigned int nbCoefs = 0 ; 	// # coefficients per polynomial
707
	do // go to #faces and count #properties
708
	{
709
		fp >> tag ;
710
		if (tag == std::string("property"))
711
			++nbProps ;
712
713
714
715
716
717
718
719
720

		if (tag == std::string("x") || tag == std::string("y") || tag == std::string("z"))
			position = true ;
		else if (tag == std::string("tx") || tag == std::string("ty") || tag == std::string("tz"))
			tangent = true ;
		else if (tag == std::string("bx") || tag == std::string("by") || tag == std::string("bz"))
			binormal = true ;
		else if (tag == std::string("nx") || tag == std::string("ny") || tag == std::string("nz"))
			normal = true ;
721
		if (tag.substr(0,1) == std::string("C") && tag.substr(2,1) == std::string("_"))
722
			++nbCoefs ;
723
	} while (tag != std::string("face")) ;
724
	unsigned int nbRemainders = nbProps ;		// # remaining properties
725
726
	nbRemainders -= nbCoefs + 3*(position==true) + 3*(tangent==true) + 3*(binormal==true) + 3*(normal==true) ;
	nbCoefs /= 3 ;
727

728
	fp >> m_nbFaces ; // Read #vertices
729

730
731
732
733
	do // go to end of header
	{
		fp >> tag ;
	} while (tag != std::string("end_header")) ;
734

735
736
737
738
739
	// Define containers
	AttributeHandler<typename PFP::VEC3> positions = m_map.template getAttribute<typename PFP::VEC3>(VERTEX, "position") ;
	if (!positions.isValid())
		positions = m_map.template addAttribute<typename PFP::VEC3>(VERTEX, "position") ;
	attrNames.push_back(positions.name()) ;
740

741
742
743
744
745
746
747
	AttributeHandler<typename PFP::VEC3> *frame = new AttributeHandler<typename PFP::VEC3>[3] ;
	frame[0] = m_map.template addAttribute<typename PFP::VEC3>(VERTEX, "frame_T") ; // Tangent
	frame[1] = m_map.template addAttribute<typename PFP::VEC3>(VERTEX, "frame_B") ; // Bitangent
	frame[2] = m_map.template addAttribute<typename PFP::VEC3>(VERTEX, "frame_N") ; // Normal
	attrNames.push_back(frame[0].name()) ;
	attrNames.push_back(frame[1].name()) ;
	attrNames.push_back(frame[2].name()) ;
748

749
750
	AttributeHandler<typename PFP::VEC3> *SLFcoefs = new AttributeHandler<typename PFP::VEC3>[nbCoefs] ;
	for (unsigned int i = 0 ; i < nbCoefs ; ++i)
751
	{
752
		std::stringstream name ;
753
754
755
		name << "SLFcoefs_" << i ;
		SLFcoefs[i] = m_map.template addAttribute<typename PFP::VEC3>(VERTEX, name.str()) ;
		attrNames.push_back(SLFcoefs[i].name()) ;
756
	}
757

758
759
760
761
762
763
764
765
766
	AttributeHandler<typename PFP::REAL> *remainders = new AttributeHandler<typename PFP::REAL>[nbRemainders] ;
	for (unsigned int i = 0 ; i < nbRemainders ; ++i)
	{
		std::stringstream name ;
		name << "remainderNo" << i ;
		remainders[i] = m_map.template addAttribute<typename PFP::REAL>(VERTEX, name.str()) ;
		attrNames.push_back(remainders[i].name()) ;
	}

767
768
769
	// Read vertices
	std::vector<unsigned int> verticesID ;
	verticesID.reserve(nbVertices) ;
770

771
772
773
	float* properties = new float[nbProps] ;
	AttributeContainer& container = m_map.getAttributeContainer(VERTEX) ;
	for (unsigned int i = 0 ; i < nbVertices ; ++i) // Read and store properties for current vertex
774
	{
775
776
		unsigned int id = container.insertLine() ;
		verticesID.push_back(id) ;
777

778
779
		for (unsigned int j = 0 ; j < nbProps ; ++j) // get all properties
			fp >> properties[j] ;
780

781
782
		positions[id] = VEC3(properties[0],properties[1],properties[2]) ; // position
		for (unsigned int k = 0 ; k < 3 ; ++k) // frame
783
784
			for (unsigned int l = 0 ; l < 3 ; ++l)
				frame[k][id][l] = properties[3+(3*k+l)] ;
785
		for (unsigned int k = 0 ; k < 3 ; ++k) // coefficients
786
787
788
			for (unsigned int l = 0 ; l < nbCoefs ; ++l)
				SLFcoefs[l][id][k] = properties[12+(nbCoefs*k+l)] ;
		unsigned int cur = 12+3*nbCoefs ;
789
790
		for (unsigned int k = 0 ; k < nbRemainders ; ++k) // remaining data
			remainders[k][id] = properties[cur + k] ;
791
	}
792
793
	m_nbVertices = verticesID.size() ;
	delete[] properties ;
794

795
796
	// Read faces index
	m_nbEdges.reserve(m_nbFaces) ;
797
	m_emb.reserve(3 * m_nbFaces) ;
798
	for (unsigned int i = 0 ; i < m_nbFaces ; ++i)
799
	{
800
		// read the indices of vertices for current face
801
		unsigned int nbEdgesForFace ;
802
803
		fp >> nbEdgesForFace ;
		m_nbEdges.push_back(nbEdgesForFace);
804

805
806
		unsigned int vertexID ;
		for (unsigned int j=0 ; j < nbEdgesForFace ; ++j)
807
		{
808
809
			fp >> vertexID ;
			m_emb.push_back(verticesID[vertexID]);
810
811
812
		}
	}

813
814
815
816
	// Close file
	fp.close() ;

	return true ;
817
818
}

Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
819
820
821
822
823
824
825
826
827
828
829
template <typename PFP>
bool MeshTablesSurface<PFP>::importPlySLFgenericBin(const std::string& filename, std::vector<std::string>& attrNames)
{
	// Open file
	std::ifstream fp(filename.c_str(), std::ios::in | std::ios::binary) ;
	if (!fp.good())
	{
		CGoGNerr << "Unable to open file " << filename << CGoGNendl ;
		return false ;
	}

830
831
832
833
	// Read quantities : #vertices, #faces, #properties, degree of polynomials
    std::string tag ;

    fp >> tag;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
834
835
836
837
838
839
	if (tag != std::string("ply")) // verify file type
	{
		CGoGNerr << filename << " is not a ply file !" <<  CGoGNout ;
		return false ;
	}

Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
840
841
	do // go to #vertices
	{
842
		fp >> tag ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
843
844
	} while (tag != std::string("vertex")) ;
	unsigned int nbVertices ;
845
	fp >> nbVertices ; // Read #vertices
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
846
847
848
849
850
851

	bool position = false ;
	bool tangent = false ;
	bool binormal = false ;
	bool normal = false ;
	unsigned int nbProps = 0 ;			// # properties
852
	unsigned int nbCoefs = 0 ; 	// # coefficients per polynomial
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
853
854
	do // go to #faces and count #properties
	{
855
		fp >> tag ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
856
857
858
859
860
861
862
863
864
865
866
867
		if (tag == std::string("property"))
			++nbProps ;

		if (tag == std::string("x") || tag == std::string("y") || tag == std::string("z"))
			position = true ;
		else if (tag == std::string("tx") || tag == std::string("ty") || tag == std::string("tz"))
			tangent = true ;
		else if (tag == std::string("bx") || tag == std::string("by") || tag == std::string("bz"))
			binormal = true ;
		else if (tag == std::string("nx") || tag == std::string("ny") || tag == std::string("nz"))
			normal = true ;
		if (tag.substr(0,1) == std::string("C") && tag.substr(2,1) == std::string("_"))
868
			++nbCoefs ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
869
870
	} while (tag != std::string("face")) ;
	unsigned int nbRemainders = nbProps ;		// # remaining properties
871
872
	nbRemainders -= nbCoefs + 3*(position==true) + 3*(tangent==true) + 3*(binormal==true) + 3*(normal==true) ;
	nbCoefs /= 3 ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
873

874
	fp >> m_nbFaces ; // Read #vertices
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
875
876
877

	do // go to end of header
	{
878
		fp >> tag ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
879
880
	} while (tag != std::string("end_header")) ;

881
882
883
884
885
886
887
	char* endline = new char[1] ;
	fp.read(endline, sizeof(char)) ;
	if (*endline == '\r') // for windows
		fp.read(endline, sizeof(char)) ;
	assert(*endline == '\n') ;
	delete endline ;

Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
888
889
890
891
892
893
894
895
896
897
898
899
900
901
	// Define containers
	AttributeHandler<typename PFP::VEC3> positions = m_map.template getAttribute<typename PFP::VEC3>(VERTEX, "position") ;
	if (!positions.isValid())
		positions = m_map.template addAttribute<typename PFP::VEC3>(VERTEX, "position") ;
	attrNames.push_back(positions.name()) ;

	AttributeHandler<typename PFP::VEC3> *frame = new AttributeHandler<typename PFP::VEC3>[3] ;
	frame[0] = m_map.template addAttribute<typename PFP::VEC3>(VERTEX, "frame_T") ; // Tangent
	frame[1] = m_map.template addAttribute<typename PFP::VEC3>(VERTEX, "frame_B") ; // Bitangent
	frame[2] = m_map.template addAttribute<typename PFP::VEC3>(VERTEX, "frame_N") ; // Normal
	attrNames.push_back(frame[0].name()) ;
	attrNames.push_back(frame[1].name()) ;
	attrNames.push_back(frame[2].name()) ;

902
903
	AttributeHandler<typename PFP::VEC3> *SLFcoefs = new AttributeHandler<typename PFP::VEC3>[nbCoefs] ;
	for (unsigned int i = 0 ; i < nbCoefs ; ++i)
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
	{
		std::stringstream name ;
		name << "SLFcoefs_" << i ;
		SLFcoefs[i] = m_map.template addAttribute<typename PFP::VEC3>(VERTEX, name.str()) ;
		attrNames.push_back(SLFcoefs[i].name()) ;
	}

	AttributeHandler<typename PFP::REAL> *remainders = new AttributeHandler<typename PFP::REAL>[nbRemainders] ;
	for (unsigned int i = 0 ; i < nbRemainders ; ++i)
	{
		std::stringstream name ;
		name << "remainderNo" << i ;
		remainders[i] = m_map.template addAttribute<typename PFP::REAL>(VERTEX, name.str()) ;
		attrNames.push_back(remainders[i].name()) ;
	}

	// Read vertices
	std::vector<unsigned int> verticesID ;
	verticesID.reserve(nbVertices) ;

	float* properties = new float[nbProps] ;
	AttributeContainer& container = m_map.getAttributeContainer(VERTEX) ;
	for (unsigned int i = 0 ; i < nbVertices ; ++i) // Read and store properties for current vertex
	{
		unsigned int id = container.insertLine() ;
		verticesID.push_back(id) ;

931
932
		// for (unsigned int j = 0 ; j < nbProps ; ++j) // get all properties
		fp.read((char*)properties,nbProps * sizeof(float)) ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
933
934
935
936

		positions[id] = VEC3(properties[0],properties[1],properties[2]) ; // position
		for (unsigned int k = 0 ; k < 3 ; ++k) // frame
			for (unsigned int l = 0 ; l < 3 ; ++l)
937
				frame[k][id][l] = (typename PFP::REAL)(properties[3+(3*k+l)]) ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
938
		for (unsigned int k = 0 ; k < 3 ; ++k) // coefficients
939
			for (unsigned int l = 0 ; l < nbCoefs ; ++l)
940
				SLFcoefs[l][id][k] = (typename PFP::REAL)(properties[12+(nbCoefs*k+l)]) ;
941
		unsigned int cur = 12+3*nbCoefs ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
942
		for (unsigned int k = 0 ; k < nbRemainders ; ++k) // remaining data
943
			remainders[k][id] = (typename PFP::REAL)(properties[cur + k]) ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
944
945
946
947
948
949
950
951
952
953
	}
	m_nbVertices = verticesID.size() ;
	delete[] properties ;

	// Read faces index
	m_nbEdges.reserve(m_nbFaces) ;
	m_emb.reserve(3 * m_nbFaces) ;
	for (unsigned int i = 0 ; i < m_nbFaces ; ++i)
	{
		// read the indices of vertices for current face
954
955
		unsigned int nbEdgesForFace ;
		fp.read((char*)&(nbEdgesForFace), sizeof(unsigned int)) ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
956
957
		m_nbEdges.push_back(nbEdgesForFace);

958
959
		unsigned int vertexID ;
		for (unsigned int j=0 ; j < nbEdgesForFace ; ++j)
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
960
		{
961
			fp.read((char*)&vertexID, sizeof(unsigned int)) ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
962
963
964
965
966
967
			m_emb.push_back(verticesID[vertexID]);
		}
	}

	// Close file
	fp.close() ;
968

Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
969
970
971
	return true ;
}

972
973
974
975
/**
 * Import plyPTM (F Larue format).
 * It handles only 2nd degree polynomials
 * @param filename : the file to import;
976
977
978
 * @param attrNames : reference that will be filled with the attribute names ;
 *  - 1 attrName for geometric position (VEC3)
 *  - 3 attrNames for local frame (3xVEC3) : Tangent, Bitangent and Normal vector
979
980
 *  - 6 attrNames for the function coefficients (6xVEC3) : 6 RGB coefficients being successively the quadratic members, the linears and the constants (u then v) : a*u^2 + b*v^2 + c*uv + d*u + e*v +f.
  * @return bool : success.
981
982
 */
template <typename PFP>
983
bool MeshTablesSurface<PFP>::importPlyPTM(const std::string& filename, std::vector<std::string>& attrNames)
Pierre Kraemer's avatar
Pierre Kraemer committed
984
{
985
	AttributeHandler<typename PFP::VEC3> positions =  m_map.template getAttribute<typename PFP::VEC3>(VERTEX, "position") ;
986
987

	if (!positions.isValid())
988
		positions = m_map.template addAttribute<typename PFP::VEC3>(VERTEX, "position") ;
989

Pierre Kraemer's avatar
Pierre Kraemer committed
990
	attrNames.push_back(positions.name()) ;
991
992

	AttributeHandler<typename PFP::VEC3> frame[3] ;
993
994
995
	frame[0] = m_map.template addAttribute<typename PFP::VEC3>(VERTEX, "frame_T") ; // Tangent
	frame[1] = m_map.template addAttribute<typename PFP::VEC3>(VERTEX, "frame_B") ; // Bitangent
	frame[2] = m_map.template addAttribute<typename PFP::VEC3>(VERTEX, "frame_N") ; // Normal
996
997
998
999
	for (unsigned int i = 0 ; i < 3 ; ++i)
		attrNames.push_back(frame[i].name()) ;

	AttributeHandler<typename PFP::VEC3> colorPTM[6] ;
1000
1001
1002
1003
1004
1005
	colorPTM[0] = m_map.template addAttribute<typename PFP::VEC3>(VERTEX, "colorPTM_a") ;
	colorPTM[1] = m_map.template addAttribute<typename PFP::VEC3>(VERTEX, "colorPTM_b") ;
	colorPTM[2] = m_map.template addAttribute<typename PFP::VEC3>(VERTEX, "colorPTM_c") ;
	colorPTM[3] = m_map.template addAttribute<typename PFP::VEC3>(VERTEX, "colorPTM_d") ;
	colorPTM[4] = m_map.template addAttribute<typename PFP::VEC3>(VERTEX, "colorPTM_e") ;
	colorPTM[5] = m_map.template addAttribute<typename PFP::VEC3>(VERTEX, "colorPTM_f") ;
1006
1007
1008

	for (unsigned int i = 0 ; i < 6 ; ++i)
		attrNames.push_back(colorPTM[i].name()) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
1009

1010
	AttributeContainer& container = m_map.getAttributeContainer(VERTEX) ;
1011

Pierre Kraemer's avatar
Pierre Kraemer committed
1012
1013
1014
	std::ifstream fp(filename.c_str(), std::ios::binary);
	if (!fp.good())
	{
1015
		CGoGNerr << "Unable to open file " << filename<< CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
1016
1017
1018
1019
1020
1021
1022
1023
1024
		return false;
	}

    std::string ligne;
    std::string tag;

	fp >> tag;
	if (tag != std::string("ply"))
	{
1025
		CGoGNerr <<filename<< " is not a ply file !" <<  CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
		return false;
	}

	// va au nombre de sommets
	do
	{
		fp >> tag;
	} while (tag != std::string("vertex"));

	unsigned int nbp;
	fp >> nbp;
	// read points
	std::vector<unsigned int> verticesID;
	verticesID.reserve(nbp);

	// va au nombre de faces en comptant le nombre de "property"
	unsigned int nb_props = 0;
	do
	{
		fp >> tag;
		if (tag == std::string("property"))
			nb_props++;
	} while (tag != std::string("face"));

	fp >> m_nbFaces;
 	m_nbEdges.reserve(m_nbFaces);
	m_emb.reserve(3*m_nbFaces);

	// lecture des sommets

	// saute à la fin du header
	do
	{
		fp >> tag;
	} while (tag != std::string("end_header"));

	float* properties = new float[nb_props];

	for (unsigned int i = 0; i < nbp; ++i)
	{
		unsigned int id = container.insertLine();
		verticesID.push_back(id);

		for (unsigned int j = 0; j < nb_props; ++j)
		{
			fp >> properties[j];
		}

		positions[id] = VEC3(properties[0],properties[1],properties[2]);

		for (unsigned int k = 0 ; k < 3 ; ++k)
			for (unsigned int l = 0 ; l < 3 ; ++l)
1078
				frame[k][id][l] = properties[3+(3*k+l)] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
1079
1080
1081

		for (unsigned int k = 0 ; k < 3 ; ++k)
			for (unsigned int l = 0 ; l < 6 ; ++l)
1082
				colorPTM[l][id][k] = properties[12+(6*k+l)];
Pierre Kraemer's avatar
Pierre Kraemer committed
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
	}

	m_nbVertices = verticesID.size();
	delete[] properties;

// read indices of faces
	for (unsigned int i = 0; i < m_nbFaces; i++)
	{
		// read the indices vertices of face
		int nbe;
		fp >> nbe;
		m_nbEdges.push_back(nbe);

		int pt;
		for (int j=0; j<nbe; ++j)
		{
			fp >> pt;
			m_emb.push_back(verticesID[pt]);
		}
	}

	fp.close();
	return true;
1106
}
Pierre Kraemer's avatar
Pierre Kraemer committed
1107

1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166


template <typename PFP>
bool MeshTablesSurface<PFP>::importAHEM(const std::string& filename, std::vector<std::string>& attrNames)
{
	// Open file

	std::ifstream fp(filename.c_str(), std::ios::binary);

	if (!fp.good())
	{
		CGoGNerr << "Unable to open file " << filename << CGoGNendl;
		return false;
	}


	// Read header

	AHEMHeader hdr;

	fp.read((char*)&hdr, sizeof(AHEMHeader));

	if(hdr.magic != AHEM_MAGIC)
		CGoGNerr << "Warning: " << filename << " invalid magic" << CGoGNendl;


	m_nbVertices = hdr.meshHdr.vxCount;
	m_nbFaces = hdr.meshHdr.faceCount;


	// Read attributes

	AHEMAttributeDescriptor* ahemAttrDesc = new AHEMAttributeDescriptor[hdr.attributesChunkNumber];
	char** ahemAttrNames = new char*[hdr.attributesChunkNumber];

	for(unsigned int i = 0 ; i < hdr.attributesChunkNumber ; i++)
	{
		fp.read((char*)(ahemAttrDesc + i), sizeof(AHEMAttributeDescriptor));
		
		ahemAttrNames[i] = new char[ahemAttrDesc[i].nameSize + 1];
		fp.read(ahemAttrNames[i], ahemAttrDesc[i].nameSize);
		ahemAttrNames[i][ahemAttrDesc[i].nameSize] = '\0';
	}
	

	// Compute buffer size for largest chunk and allocate

	unsigned int bufferSize = hdr.meshHdr.meshChunkSize;

	for(unsigned int i = 0 ; i < hdr.attributesChunkNumber ; i++)
		if(ahemAttrDesc[i].attributeChunkSize > bufferSize)
			bufferSize = ahemAttrDesc[i].attributeChunkSize;


	char* buffer = new char[bufferSize];


    // Allocate vertices

Pierre Kraemer's avatar
Pierre Kraemer committed
1167
	AttributeContainer& vxContainer = m_map.getAttributeContainer(VERTEX);
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191