export.hpp 32.3 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 PURPOSE. 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
26
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

#include "Topology/generic/attributeHandler.h"
#include "Topology/generic/autoAttributeHandler.h"
27
28
#include "Topology/generic/traversor/traversorCell.h"
#include "Topology/generic/traversor/traversor2.h"
Pierre Kraemer's avatar
Pierre Kraemer committed
29
30
#include "Topology/generic/cellmarker.h"

Sylvain Thery's avatar
Sylvain Thery committed
31
32
#include "Utils/compress.h"

Pierre Kraemer's avatar
Pierre Kraemer committed
33
34
35
36
37
38
namespace CGoGN
{

namespace Algo
{

39
40
41
namespace Surface
{

Pierre Kraemer's avatar
Pierre Kraemer committed
42
43
44
45
namespace Export
{

template <typename PFP>
Pierre Kraemer's avatar
Pierre Kraemer committed
46
bool exportPLY(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP::IMPL>& position, const char* filename, bool binary)
Pierre Kraemer's avatar
Pierre Kraemer committed
47
48
49
{
	typedef typename PFP::MAP MAP;
	
50
	// open file
51
	std::ofstream out ;
52
	if (!binary)
53
		out.open(filename, std::ios::out) ;
54
55
56
	else
		out.open(filename, std::ios::out | std::ios::binary) ;

Pierre Kraemer's avatar
Pierre Kraemer committed
57
58
	if (!out.good())
	{
59
		CGoGNerr << "Unable to open file " << CGoGNendl ;
Pierre Kraemer's avatar
Pierre Kraemer committed
60
61
62
63
64
65
66
67
68
69
70
71
72
		return false ;
	}

	unsigned int nbDarts = map.getNbDarts() ;
	std::vector<unsigned int> facesSize ;
	std::vector<std::vector<unsigned int> > facesIdx ;
	facesSize.reserve(nbDarts/3) ;
	facesIdx.reserve(nbDarts/3) ;
	std::map<unsigned int, unsigned int> vIndex ;
	unsigned int vCpt = 0 ;
	std::vector<unsigned int> vertices ;
	vertices.reserve(nbDarts/6) ;

73
	// Go over all faces
Pierre Kraemer's avatar
Pierre Kraemer committed
74
	CellMarker<MAP, VERTEX> markV(map) ;
75
	TraversorF<MAP> t(map) ;
76
	for(Dart d = t.begin(); d != t.end(); d = t.next())
Pierre Kraemer's avatar
Pierre Kraemer committed
77
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
78
79
80
81
82
		std::vector<unsigned int> fidx ;
		fidx.reserve(8) ;
		unsigned int degree = 0 ;
		Traversor2FV<typename PFP::MAP> tfv(map, d) ;
		for(Dart it = tfv.begin(); it != tfv.end(); it = tfv.next())
Pierre Kraemer's avatar
Pierre Kraemer committed
83
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
84
			++degree ;
85
			unsigned int vNum = map.template getEmbedding<VERTEX>(it) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
86
			if(!markV.isMarked(it))
Pierre Kraemer's avatar
Pierre Kraemer committed
87
			{
Pierre Kraemer's avatar
Pierre Kraemer committed
88
89
90
				markV.mark(it) ;
				vIndex[vNum] = vCpt++ ;
				vertices.push_back(vNum) ;
91
			}
Pierre Kraemer's avatar
Pierre Kraemer committed
92
			fidx.push_back(vIndex[vNum]) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
93
		}
Pierre Kraemer's avatar
Pierre Kraemer committed
94
95
		facesSize.push_back(degree) ;
		facesIdx.push_back(fidx) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
96
97
	}

98
	// Start writing the file
99
	out << "ply" << std::endl ;
100
	// ascii or binary
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
	if (!binary)
		out << "format ascii 1.0" << std::endl ;
	else
	{	// test endianness
		union
		{
		    uint32_t i ;
		    char c[4] ;
		} bint = {0x01020304} ;
		if (bint.c[0] == 1) // big endian
			out << "format binary_big_endian 1.0" << std::endl ;
		else
			out << "format binary_little_endian 1.0" << std::endl ;
	}

	out << "comment File generated by the CGoGN library" << std::endl ;
	out << "comment See : http://cgogn.unistra.fr/" << std::endl ;
118
119
	out << "comment or contact : cgogn@unistra.fr" << std::endl ;
	// Vertex elements
120
	out << "element vertex " << vertices.size() << std::endl ;
121
	// Position property
122
123
	if (position.isValid())
	{
124
125
126
		out << "property " << nameOfTypePly(position[0][0]) << " x" << std::endl ;
		out << "property " << nameOfTypePly(position[0][1]) << " y" << std::endl ;
		out << "property " << nameOfTypePly(position[0][2]) << " z" << std::endl ;
127
	}
128
	// Face element
129
	out << "element face " << facesSize.size() << std::endl ;
130
	out << "property list uint8 uint" << 8 * sizeof(facesIdx[0][0]) << " vertex_indices" << std::endl ;
131
	out << "end_header" << std::endl ;
Pierre Kraemer's avatar
Pierre Kraemer committed
132

133
	if (!binary)	// ascii
Pierre Kraemer's avatar
Pierre Kraemer committed
134
	{
135
		// ascii vertices
136
137
138
		for(unsigned int i = 0; i < vertices.size(); ++i)
			out << position[vertices[i]] << std::endl ;

139
		// ascii faces
140
141
142
143
144
145
146
		for(unsigned int i = 0; i < facesSize.size(); ++i)
		{
			out << facesSize[i] ;
			for(unsigned int j = 0; j < facesIdx[i].size(); ++j)
				out << " " << facesIdx[i][j] ;
			out << std::endl ;
		}
Pierre Kraemer's avatar
Pierre Kraemer committed
147
	}
148
	else // binary
Pierre Kraemer's avatar
Pierre Kraemer committed
149
	{
150
		// binary vertices
151
152
153
		for(unsigned int i = 0; i < vertices.size(); ++i)
		{
			Geom::Vec3f v = position[vertices[i]] ;
154
			out.write((char*)(&(v[0])), sizeof(v)) ;
155
156
		}

157
		// binary faces
158
159
160
161
		for(unsigned int i = 0; i < facesSize.size(); ++i)
		{
			unsigned char nbe = facesSize[i] ;
			out.write((char*)(&nbe), sizeof(unsigned char)) ;
162
163
164
165
166
167
168
169
170
171
			out.write((char*)(&(facesIdx[i][0])), facesSize[i] * sizeof(facesIdx[i][0])) ;
		}
	}

	out.close() ;

	return true ;
}

template <typename PFP>
Pierre Kraemer's avatar
Pierre Kraemer committed
172
bool exportPLYnew(typename PFP::MAP& map, const std::vector<VertexAttribute<typename PFP::VEC3, typename PFP::MAP::IMPL>*>& attributeHandlers, const char* filename, bool binary)
173
174
{
	typedef typename PFP::MAP MAP;
Pierre Kraemer's avatar
Pierre Kraemer committed
175
	typedef typename PFP::MAP::IMPL MAP_IMPL;
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
	typedef typename PFP::VEC3 VEC3;

	// open file
	std::ofstream out ;
	if (!binary)
		out.open(filename, std::ios::out) ;
	else
		out.open(filename, std::ios::out | std::ios::binary) ;

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

	unsigned int nbDarts = map.getNbDarts() ;
	std::vector<unsigned int> facesSize ;
	std::vector<std::vector<unsigned int> > facesIdx ;
	facesSize.reserve(nbDarts/3) ;
	facesIdx.reserve(nbDarts/3) ;
	std::map<unsigned int, unsigned int> vIndex ;
	unsigned int vCpt = 0 ;
	std::vector<unsigned int> vertices ;
	vertices.reserve(nbDarts/6) ;

	// Go over all faces
Pierre Kraemer's avatar
Pierre Kraemer committed
202
	CellMarker<MAP, VERTEX> markV(map) ;
203
	TraversorF<MAP> t(map) ;
204
205
206
207
208
	for(Dart d = t.begin(); d != t.end(); d = t.next())
	{
		std::vector<unsigned int> fidx ;
		fidx.reserve(8) ;
		unsigned int degree = 0 ;
Pierre Kraemer's avatar
Pierre Kraemer committed
209
		Traversor2FV<MAP> tfv(map, d) ;
210
211
212
		for(Dart it = tfv.begin(); it != tfv.end(); it = tfv.next())
		{
			++degree ;
213
			unsigned int vNum = map.template getEmbedding<VERTEX>(it) ;
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
			if(!markV.isMarked(it))
			{
				markV.mark(it) ;
				vIndex[vNum] = vCpt++ ;
				vertices.push_back(vNum) ;
			}
			fidx.push_back(vIndex[vNum]) ;
		}
		facesSize.push_back(degree) ;
		facesIdx.push_back(fidx) ;
	}

	// Start writing the file
	out << "ply" << std::endl ;
	// ascii or binary
	if (!binary)
		out << "format ascii 1.0" << std::endl ;
	else
	{	// test endianness
		union
		{
		    uint32_t i ;
		    char c[4] ;
		} bint = {0x01020304} ;
		if (bint.c[0] == 1) // big endian
			out << "format binary_big_endian 1.0" << std::endl ;
		else
			out << "format binary_little_endian 1.0" << std::endl ;
	}

	out << "comment File generated by the CGoGN library" << std::endl ;
	out << "comment See : http://cgogn.unistra.fr/" << std::endl ;
	out << "comment or contact : cgogn@unistra.fr" << std::endl ;
	// Vertex elements
	out << "element vertex " << vertices.size() << std::endl ;
Pierre Kraemer's avatar
Pierre Kraemer committed
249
	for (typename std::vector<VertexAttribute<VEC3, MAP_IMPL>* >::const_iterator attrHandler = attributeHandlers.begin() ; attrHandler != attributeHandlers.end() ; ++attrHandler)
250
	{
251
		if ((*attrHandler)->isValid() && ((*attrHandler)->getOrbit() == VERTEX) )
252
		{
253
			if ((*attrHandler)->name().compare("position") == 0)  // Vertex position property
254
			{
255
256
257
				out << "property " << nameOfTypePly((*(*attrHandler))[0][0]) << " x" << std::endl ;
				out << "property " << nameOfTypePly((*(*attrHandler))[0][1]) << " y" << std::endl ;
				out << "property " << nameOfTypePly((*(*attrHandler))[0][2]) << " z" << std::endl ;
258
			}
259
			else if ((*attrHandler)->name().compare("normal") == 0)	// normal property
260
			{
261
262
263
				out << "property " << nameOfTypePly((*(*attrHandler))[0][0]) << " nx" << std::endl ;
				out << "property " << nameOfTypePly((*(*attrHandler))[0][1]) << " ny" << std::endl ;
				out << "property " << nameOfTypePly((*(*attrHandler))[0][2]) << " nz" << std::endl ;
264
			}
265
			else if ((*attrHandler)->name().compare("color") == 0)	// vertex color property
266
			{
267
268
269
				out << "property " << nameOfTypePly((*(*attrHandler))[0][0]) << " r" << std::endl ;
				out << "property " << nameOfTypePly((*(*attrHandler))[0][1]) << " g" << std::endl ;
				out << "property " << nameOfTypePly((*(*attrHandler))[0][2]) << " b" << std::endl ;
270
271
272
			}
			else // other vertex properties
			{
273
274
275
				out << "property " << nameOfTypePly((*(*attrHandler))[0][0]) << " " << (*attrHandler)->name() << "_0" << std::endl ;
				out << "property " << nameOfTypePly((*(*attrHandler))[0][1]) << " " << (*attrHandler)->name() << "_1" << std::endl ;
				out << "property " << nameOfTypePly((*(*attrHandler))[0][2]) << " " << (*attrHandler)->name() << "_2" << std::endl ;
276
277
278
279
280
281
			}
		}
	}

	// Face element
	out << "element face " << facesSize.size() << std::endl ;
282
	out << "property list uint8 " << nameOfTypePly(facesIdx[0][0]) << " vertex_indices" << std::endl ;
283
284
285
286
287
288
	out << "end_header" << std::endl ;

	if (!binary)	// ascii
	{
		// ascii vertices
		for(unsigned int i = 0; i < vertices.size(); ++i)
289
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
290
			for (typename std::vector<VertexAttribute<VEC3, MAP_IMPL>* >::const_iterator attrHandler = attributeHandlers.begin() ; attrHandler != attributeHandlers.end() ; ++attrHandler)
291
				if ((*attrHandler)->isValid() && (*attrHandler)->getOrbit() == VERTEX)
292
293
294
					out << (*(*attrHandler))[vertices[i]] ;
			out << std::endl ;
		}
295
296
297
298
299
300
301
302
303
304
305
306
307
308

		// ascii faces
		for(unsigned int i = 0; i < facesSize.size(); ++i)
		{
			out << facesSize[i] ;
			for(unsigned int j = 0; j < facesIdx[i].size(); ++j)
				out << " " << facesIdx[i][j] ;
			out << std::endl ;
		}
	}
	else // binary
	{
		// binary vertices
		for(unsigned int i = 0; i < vertices.size(); ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
309
			for (typename std::vector<VertexAttribute<VEC3, MAP_IMPL>*>::const_iterator attrHandler = attributeHandlers.begin() ; attrHandler != attributeHandlers.end() ; ++attrHandler)
310
				if ((*attrHandler)->isValid() && (*attrHandler)->getOrbit() == VERTEX)
311
				{
Pierre Kraemer's avatar
Pierre Kraemer committed
312
					const VEC3& v = (*(*attrHandler))[vertices[i]] ;
313
314
315
316
317
318
					out.write((char*)(&(v[0])), sizeof(v)) ;
				}

		// binary faces
		for(unsigned int i = 0; i < facesSize.size(); ++i)
		{
319
			uint8_t nbe = facesSize[i] ;
320
			out.write((char*)(&nbe), sizeof(uint8_t)) ;
321
			out.write((char*)(&(facesIdx[i][0])), facesSize[i] * sizeof(facesIdx[i][0])) ;
322
		}
Pierre Kraemer's avatar
Pierre Kraemer committed
323
324
325
	}

	out.close() ;
326

Pierre Kraemer's avatar
Pierre Kraemer committed
327
328
329
330
	return true ;
}

template <typename PFP>
Pierre Kraemer's avatar
Pierre Kraemer committed
331
bool exportOFF(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP::IMPL>& position, const char* filename)
Pierre Kraemer's avatar
Pierre Kraemer committed
332
333
334
335
336
337
338
{
	typedef typename PFP::MAP MAP;
	typedef typename PFP::VEC3 VEC3;
	
	std::ofstream out(filename, std::ios::out) ;
	if (!out.good())
	{
339
		CGoGNerr << "Unable to open file " << CGoGNendl ;
Pierre Kraemer's avatar
Pierre Kraemer committed
340
341
342
343
344
345
346
347
348
349
350
351
352
		return false ;
	}

	unsigned int nbDarts = map.getNbDarts() ;
	std::vector<unsigned int> facesSize ;
	std::vector<std::vector<unsigned int> > facesIdx ;
	facesSize.reserve(nbDarts/3) ;
	facesIdx.reserve(nbDarts/3) ;
	std::map<unsigned int, unsigned int> vIndex ;
	unsigned int vCpt = 0 ;
	std::vector<unsigned int> vertices ;
	vertices.reserve(nbDarts/6) ;

Pierre Kraemer's avatar
Pierre Kraemer committed
353
	CellMarker<MAP, VERTEX> markV(map) ;
354
	TraversorF<MAP> t(map) ;
355
	for(Dart d = t.begin(); d != t.end(); d = t.next())
Pierre Kraemer's avatar
Pierre Kraemer committed
356
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
357
358
359
360
361
		std::vector<unsigned int> fidx ;
		fidx.reserve(8) ;
		unsigned int degree = 0 ;
		Traversor2FV<typename PFP::MAP> tfv(map, d) ;
		for(Dart it = tfv.begin(); it != tfv.end(); it = tfv.next())
Pierre Kraemer's avatar
Pierre Kraemer committed
362
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
363
			++degree ;
364
			unsigned int vNum = map.template getEmbedding<VERTEX>(it) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
365
			if(!markV.isMarked(it))
Pierre Kraemer's avatar
Pierre Kraemer committed
366
			{
Pierre Kraemer's avatar
Pierre Kraemer committed
367
368
369
				markV.mark(it) ;
				vIndex[vNum] = vCpt++ ;
				vertices.push_back(vNum) ;
370
			}
Pierre Kraemer's avatar
Pierre Kraemer committed
371
			fidx.push_back(vIndex[vNum]) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
372
		}
Pierre Kraemer's avatar
Pierre Kraemer committed
373
374
		facesSize.push_back(degree) ;
		facesIdx.push_back(fidx) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
375
376
	}

377
378
	out << "OFF" << std::endl ;
	out << vertices.size() << " " << facesSize.size() << " " << 0 << std::endl ;
Pierre Kraemer's avatar
Pierre Kraemer committed
379
380
381
382

	for(unsigned int i = 0; i < vertices.size(); ++i)
	{
		const VEC3& v = position[vertices[i]] ;
383
		out << v[0] << " " << v[1] << " " << v[2] << std::endl ;
Pierre Kraemer's avatar
Pierre Kraemer committed
384
385
386
387
388
389
	}
	for(unsigned int i = 0; i < facesSize.size(); ++i)
	{
		out << facesSize[i] ;
		for(unsigned int j = 0; j < facesIdx[i].size(); ++j)
			out << " " << facesIdx[i][j] ;
390
		out << std::endl ;
Pierre Kraemer's avatar
Pierre Kraemer committed
391
392
393
394
395
	}

	out.close() ;
	return true ;
}
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
396
/*
397
template <typename PFP>
Lionel Untereiner's avatar
Lionel Untereiner committed
398
bool exportOBJ(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& position, const char* filename)
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
{
	typedef typename PFP::MAP MAP;
	typedef typename PFP::VEC3 VEC3;

	std::ofstream out(filename, std::ios::out) ;
	if (!out.good())
	{
		CGoGNerr << "Unable to open file " << CGoGNendl ;
		return false ;
	}

	unsigned int nbDarts = map.getNbDarts() ;
	std::vector<unsigned int> facesSize ;
	std::vector<std::vector<unsigned int> > facesIdx ;
	facesSize.reserve(nbDarts/3) ;
	facesIdx.reserve(nbDarts/3) ;
	std::map<unsigned int, unsigned int> vIndex ;
	unsigned int vCpt = 0 ;
	std::vector<unsigned int> vertices ;
	vertices.reserve(nbDarts/6) ;

Thomas's avatar
Thomas committed
420
	CellMarker<VERTEX> markV(map) ;
421
	TraversorF<MAP> t(map) ;
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
459
460
461
462
	for(Dart d = t.begin(); d != t.end(); d = t.next())
	{
		std::vector<unsigned int> fidx ;
		fidx.reserve(8) ;
		Traversor2FV<typename PFP::MAP> tfv(map, d) ;
		for(Dart it = tfv.begin(); it != tfv.end(); it = tfv.next())
		{
			unsigned int vNum = map.getEmbedding(VERTEX, it) ;
			if(!markV.isMarked(it))
			{
				markV.mark(it) ;
				vIndex[vNum] = vCpt++ ;
				vertices.push_back(vNum) ;
			}
			fidx.push_back(vIndex[vNum]+1) ;
		}
		facesIdx.push_back(fidx) ;
	}

	out << "#OBJ - Export from CGoGN" << std::endl ;

	for(unsigned int i = 0; i < vertices.size(); ++i)
	{
		const VEC3& v = position[vertices[i]] ;
		out << "v " << v[0] << " " << v[1] << " " << v[2] << std::endl ;
	}

	out << std::endl;

	for(unsigned int i = 0; i < facesIdx.size(); ++i)
	{
		out << "f ";
		for(unsigned int j = 0; j < facesIdx[i].size(); ++j)
			out << " " << facesIdx[i][j] ;
		out << std::endl ;
	}

	out.close() ;
	return true ;
}

463
template <typename PFP>
464
bool exportPlyPTMgeneric(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& position, const char* filename)
465
466
467
{
	typedef typename PFP::MAP MAP;
	typedef typename PFP::VEC3 VEC3;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
468
	typedef typename PFP::REAL REAL;
469
470
471
472

	std::ofstream out(filename, std::ios::out) ;
	if (!out.good())
	{
473
		CGoGNerr << "Unable to open file " << filename << CGoGNendl ;
474
475
476
		return false ;
	}

477
	VertexAutoAttribute<unsigned int> tableVertLab(map);
478
479
480
481
482
483
484
485
486

	unsigned int nbDarts = map.getNbDarts() ;

	std::vector<unsigned int> vertices;
	std::vector<unsigned int> faces;

	vertices.reserve(nbDarts/5);	// TODO non optimal reservation
	faces.reserve(nbDarts/3);

487
	CellMarker<VERTEX> markV(map);
488
	TraversorF<MAP> t(map) ;
489
490
	unsigned int lab = 0;
	unsigned int nbf = 0;
491
	for(Dart d = t.begin(); d != t.end(); d = t.next())
492
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
493
494
495
		std::vector<unsigned int> face ;
		Traversor2FV<typename PFP::MAP> tfv(map, d) ;
		for(Dart it = tfv.begin(); it != tfv.end(); it = tfv.next())
496
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
497
			if (!markV.isMarked(it))
498
			{
Pierre Kraemer's avatar
Pierre Kraemer committed
499
500
				markV.mark(it);
				tableVertLab[it] = lab++;
501
				vertices.push_back(map.template getEmbedding<VERTEX>(it));
502
			}
Pierre Kraemer's avatar
Pierre Kraemer committed
503
504
			face.push_back(tableVertLab[it]);
		}
505

Pierre Kraemer's avatar
Pierre Kraemer committed
506
507
508
		faces.push_back(face.size()) ;
		for (unsigned int i = 0 ; i < face.size() ; ++i)
			faces.push_back(face.at(i)) ;
509

Pierre Kraemer's avatar
Pierre Kraemer committed
510
		++nbf;
511
512
	}

513
514
	VertexAttribute<VEC3> frame[3] ;
	VertexAttribute<VEC3> colorPTM[15] ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
515
516
517
518

	frame[0] = map.template getAttribute<VEC3>(VERTEX, "frame_T") ;
	frame[1] = map.template getAttribute<VEC3>(VERTEX, "frame_B") ;
	frame[2] = map.template getAttribute<VEC3>(VERTEX, "frame_N") ;
519
	for (unsigned int i = 0 ; i < 15 ; ++i)
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
520
521
522
523
524
	{
		std::stringstream name ;
		name << "colorPTM_a" << i ;
		colorPTM[i] = map.template getAttribute<VEC3>(VERTEX,name.str()) ;
	}
525
	const unsigned int nbCoefs = colorPTM[14].isValid() ? 15 : (colorPTM[9].isValid() ? 10 : 6) ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
526

527
528
	out << "ply" << std::endl ;
	out << "format ascii 1.0" << std::endl ;
529
	out << "comment ply PTM (K. Vanhoey generic format)" << std::endl ;
530
531
532
533
534
535
536
537
538
539
540
541
542
	out << "element vertex " << vertices.size() << std::endl ;
	out << "property float x" << std::endl ;
	out << "property float y" << std::endl ;
	out << "property float z" << std::endl ;
	out << "property float tx" << std::endl ;
	out << "property float ty" << std::endl ;
	out << "property float tz" << std::endl ;
	out << "property float bx" << std::endl ;
	out << "property float by" << std::endl ;
	out << "property float bz" << std::endl ;
	out << "property float nx" << std::endl ;
	out << "property float ny" << std::endl ;
	out << "property float nz" << std::endl ;
543
	for(unsigned int coefI = 0 ; coefI < nbCoefs ; ++coefI)
544
		out << "property float C0_a" << coefI << std::endl ;
545
	for(unsigned int coefI = 0 ; coefI < nbCoefs ; ++coefI)
546
		out << "property float C1_a" << coefI << std::endl ;
547
	for(unsigned int coefI = 0 ; coefI < nbCoefs ; ++coefI)
548
		out << "property float C2_a" << coefI << std::endl ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
549

550
551
552
	VertexAttribute<REAL> errL2 = map.template getAttribute<REAL>(VERTEX, "errL2") ;
	VertexAttribute<REAL> errLmax = map.template getAttribute<REAL>(VERTEX, "errLmax") ;
	VertexAttribute<REAL> stdDev = map.template getAttribute<REAL>(VERTEX, "stdDev") ;
553
554
555
556
557
558
	if (errL2.isValid())
		out << "property float errL2" << std::endl ;
	if (errLmax.isValid())
		out << "property float errLmax" << std::endl ;
	if (stdDev.isValid())
		out << "property float stdDev" << std::endl ;
559
560
561
562
563

	out << "element face " << nbf << std::endl ;
	out << "property list uchar int vertex_indices" << std::endl ;
	out << "end_header" << std::endl ;

564
565
566
	for(unsigned int i = 0; i < vertices.size(); ++i)
	{
		unsigned int vi = vertices[i];
567
568
		 // position
		for(unsigned int coord = 0 ; coord < 3 ; ++coord)
569
			out << position[vi][coord] << " " ;
570
571
572
		 // frame
		for(unsigned int axis = 0 ; axis < 3 ; ++axis)
			for (unsigned int coord = 0 ; coord < 3 ; ++coord)
573
				out << frame[axis][vi][coord] << " " ;
574
575
		 // coefficients
		for (unsigned int channel = 0 ; channel < 3 ; ++channel)
576
577
			for(unsigned int coefI = 0 ; coefI < nbCoefs ; ++coefI)
				out << colorPTM[coefI][vi][channel] << " "  ;
578
579
		 // fitting errors (if any)
		if (errL2.isValid())
580
581
582
583
584
585
			out << errL2[vi] << " " ;
		if (errLmax.isValid())
			out << errLmax[vi] << " " ;
		if (stdDev.isValid())
			out << stdDev[vi] << " " ;
		out << std::endl ;
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
	}

	std::vector<unsigned int>::iterator it = faces.begin();
	while (it != faces.end())
	{
		unsigned int nbe = *it++;
		out << nbe ;
		for(unsigned int j = 0; j < nbe; ++j)
			out << " " << *it++;
		out << std::endl ;
	}

	out.close() ;
	return true ;
}
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
601
*/
602
/*
603
template <typename PFP>
604
bool exportPlySLFgeneric(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& position, const char* filename)
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
{
	typedef typename PFP::MAP MAP;
	typedef typename PFP::VEC3 VEC3;
	typedef typename PFP::REAL REAL;

	std::ofstream out(filename, std::ios::out) ;
	if (!out.good())
	{
		CGoGNerr << "Unable to open file " << filename << CGoGNendl ;
		return false ;
	}

	AutoAttributeHandler<unsigned int> tableVertLab(map, VERTEX);

	unsigned int nbDarts = map.getNbDarts() ;

	std::vector<unsigned int> vertices;
	std::vector<unsigned int> faces;

	vertices.reserve(nbDarts/5);	// TODO non optimal reservation
	faces.reserve(nbDarts/3);

	CellMarker markV(map, VERTEX);
628
	TraversorF<MAP> t(map) ;
629
630
631
632
633
634
635
636
637
638
639
640
	unsigned int lab = 0;
	unsigned int nbf = 0;
	for(Dart d = t.begin(); d != t.end(); d = t.next())
	{
		std::vector<unsigned int> face ;
		Traversor2FV<typename PFP::MAP> tfv(map, d) ;
		for(Dart it = tfv.begin(); it != tfv.end(); it = tfv.next())
		{
			if (!markV.isMarked(it))
			{
				markV.mark(it);
				tableVertLab[it] = lab++;
641
				vertices.push_back(map.getEmbedding<VERTEX>(it));
642
643
644
645
646
647
648
649
650
651
652
			}
			face.push_back(tableVertLab[it]);
		}

		faces.push_back(face.size()) ;
		for (unsigned int i = 0 ; i < face.size() ; ++i)
			faces.push_back(face.at(i)) ;

		++nbf;
	}

653
	VertexAttribute<typename PFP::VEC3> frame[3] ;
654
	std::vector<TVEC3> coefs ;
655
656
657
658

	frame[0] = map.template getAttribute<VEC3>(VERTEX, "frame_T") ;
	frame[1] = map.template getAttribute<VEC3>(VERTEX, "frame_B") ;
	frame[2] = map.template getAttribute<VEC3>(VERTEX, "frame_N") ;
659
660
661

	unsigned int i = 0 ;
	do {
662
		std::stringstream name ;
663
664
665
666
667
668
669
		name << "SLFcoefs_" << i++ ;
		coefs.push_back(map.template getAttribute<VEC3>(VERTEX, name.str())) ;
	} while (coefs[i-1].isValid()) ;
	const unsigned int nbCoefs = i - 1 ; // last valid one is i-2

	for(unsigned int coefI = 0 ; coefI < nbCoefs ; ++coefI)
		assert(coefs[coefI].isValid()) ;
670

671
672
673
674
	std::string file(filename) ;
	size_t pos = file.rfind(".") ; // position of "." in filename
	std::string extension = file.substr(pos) ;

675
676
	out << "ply" << std::endl ;
	out << "format ascii 1.0" << std::endl ;
kenneth's avatar
kenneth committed
677
	out << "comment ply SLF (K. Vanhoey generic format): SLF_" << (((extension == ".plyPTMext") || extension == ".plyPTMextBin" ) ? "PTMext" : "SHreal") << std::endl ;
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
	out << "element vertex " << vertices.size() << std::endl ;
	out << "property float x" << std::endl ;
	out << "property float y" << std::endl ;
	out << "property float z" << std::endl ;
	out << "property float tx" << std::endl ;
	out << "property float ty" << std::endl ;
	out << "property float tz" << std::endl ;
	out << "property float bx" << std::endl ;
	out << "property float by" << std::endl ;
	out << "property float bz" << std::endl ;
	out << "property float nx" << std::endl ;
	out << "property float ny" << std::endl ;
	out << "property float nz" << std::endl ;
	for(unsigned int coefI = 0 ; coefI < nbCoefs ; ++coefI)
		out << "property float C0_" << coefI << std::endl ;
	for(unsigned int coefI = 0 ; coefI < nbCoefs ; ++coefI)
		out << "property float C1_" << coefI << std::endl ;
	for(unsigned int coefI = 0 ; coefI < nbCoefs ; ++coefI)
		out << "property float C2_" << coefI << std::endl ;

	out << "element face " << nbf << std::endl ;
	out << "property list uchar int vertex_indices" << std::endl ;
	out << "end_header" << std::endl ;

	for(unsigned int i = 0; i < vertices.size(); ++i)
	{
		unsigned int vi = vertices[i];
		 // position
		for(unsigned int coord = 0 ; coord < 3 ; ++coord)
			out << position[vi][coord] << " " ;
		 // frame
		for(unsigned int axis = 0 ; axis < 3 ; ++axis)
			for (unsigned int coord = 0 ; coord < 3 ; ++coord)
				out << frame[axis][vi][coord] << " " ;
		 // coefficients
		for (unsigned int channel = 0 ; channel < 3 ; ++channel)
			for(unsigned int coefI = 0 ; coefI < nbCoefs ; ++coefI)
				out << coefs[coefI][vi][channel] << " "  ;

		out << std::endl ;
	}

	std::vector<unsigned int>::iterator it = faces.begin();
	while (it != faces.end())
	{
		unsigned int nbe = *it++;
		out << nbe ;
		for(unsigned int j = 0; j < nbe; ++j)
			out << " " << *it++;
		out << std::endl ;
	}

	out.close() ;
	return true ;
}

Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
734
template <typename PFP>
735
bool exportPlySLFgenericBin(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& position, const char* filename)
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
736
737
738
739
740
{
	typedef typename PFP::MAP MAP;
	typedef typename PFP::VEC3 VEC3;
	typedef typename PFP::REAL REAL;

741
	std::ofstream out(filename, std::ios::out) ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
	if (!out.good())
	{
		CGoGNerr << "Unable to open file " << filename << CGoGNendl ;
		return false ;
	}

	AutoAttributeHandler<unsigned int> tableVertLab(map, VERTEX);

	unsigned int nbDarts = map.getNbDarts() ;

	std::vector<unsigned int> vertices;
	std::vector<unsigned int> faces;

	vertices.reserve(nbDarts/5);	// TODO non optimal reservation
	faces.reserve(nbDarts/3);

	CellMarker markV(map, VERTEX);
759
	TraversorF<MAP> t(map) ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
760
761
762
763
764
765
766
767
768
769
770
771
	unsigned int lab = 0;
	unsigned int nbf = 0;
	for(Dart d = t.begin(); d != t.end(); d = t.next())
	{
		std::vector<unsigned int> face ;
		Traversor2FV<typename PFP::MAP> tfv(map, d) ;
		for(Dart it = tfv.begin(); it != tfv.end(); it = tfv.next())
		{
			if (!markV.isMarked(it))
			{
				markV.mark(it);
				tableVertLab[it] = lab++;
772
				vertices.push_back(map.getEmbedding<VERTEX>(it));
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
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
			}
			face.push_back(tableVertLab[it]);
		}

		faces.push_back(face.size()) ;
		for (unsigned int i = 0 ; i < face.size() ; ++i)
			faces.push_back(face.at(i)) ;

		++nbf;
	}

	TVEC3 frame[3] ;
	std::vector<TVEC3> coefs ;

	frame[0] = map.template getAttribute<VEC3>(VERTEX, "frame_T") ;
	frame[1] = map.template getAttribute<VEC3>(VERTEX, "frame_B") ;
	frame[2] = map.template getAttribute<VEC3>(VERTEX, "frame_N") ;

	unsigned int i = 0 ;
	do {
		std::stringstream name ;
		name << "SLFcoefs_" << i++ ;
		coefs.push_back(map.template getAttribute<VEC3>(VERTEX, name.str())) ;
	} while (coefs[i-1].isValid()) ;
	const unsigned int nbCoefs = i - 1 ; // last valid one is i-2

	for(unsigned int coefI = 0 ; coefI < nbCoefs ; ++coefI)
		assert(coefs[coefI].isValid()) ;

	std::string file(filename) ;
	size_t pos = file.rfind(".") ; // position of "." in filename
	std::string extension = file.substr(pos) ;

806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
	out << "ply" << std::endl ;
	out << "format ascii 1.0" << std::endl ;
	out << "comment ply SLF (K. Vanhoey generic format): SLF_" << ((extension == ".plyPTMext") ? "PTMext" : "SHreal") << std::endl ;
	out << "element vertex " << vertices.size() << std::endl ;
	out << "property float x" << std::endl ;
	out << "property float y" << std::endl ;
	out << "property float z" << std::endl ;
	out << "property float tx" << std::endl ;
	out << "property float ty" << std::endl ;
	out << "property float tz" << std::endl ;
	out << "property float bx" << std::endl ;
	out << "property float by" << std::endl ;
	out << "property float bz" << std::endl ;
	out << "property float nx" << std::endl ;
	out << "property float ny" << std::endl ;
	out << "property float nz" << std::endl ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
822
	for(unsigned int coefI = 0 ; coefI < nbCoefs ; ++coefI)
823
		out << "property float C0_" << coefI << std::endl ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
824
	for(unsigned int coefI = 0 ; coefI < nbCoefs ; ++coefI)
825
		out << "property float C1_" << coefI << std::endl ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
826
	for(unsigned int coefI = 0 ; coefI < nbCoefs ; ++coefI)
827
		out << "property float C2_" << coefI << std::endl ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
828

829
830
831
	out << "element face " << nbf << std::endl ;
	out << "property list uchar int vertex_indices" << std::endl ;
	out << "end_header" << std::endl ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
832
833
834
835
836
837

	for(unsigned int i = 0; i < vertices.size(); ++i)
	{
		unsigned int vi = vertices[i];
		 // position
		for(unsigned int coord = 0 ; coord < 3 ; ++coord)
838
839
840
841
		{
			const float& floatofdouble = position[vi][coord] ;
			out.write((char*)(&floatofdouble), sizeof(float)) ;
		}
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
842
843
844
		 // frame
		for(unsigned int axis = 0 ; axis < 3 ; ++axis)
			for (unsigned int coord = 0 ; coord < 3 ; ++coord)
845
846
847
848
			{
				const float& floatofdouble = frame[axis][vi][coord] ;
				out.write((char*)(&floatofdouble), sizeof(float)) ;
			}
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
849
850
851
		 // coefficients
		for (unsigned int channel = 0 ; channel < 3 ; ++channel)
			for(unsigned int coefI = 0 ; coefI < nbCoefs ; ++coefI)
852
853
854
855
			{
				const float& floatofdouble = coefs[coefI][vi][channel] ;
				out.write((char*)(&floatofdouble), sizeof(float)) ;
			}
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
856
857
858
859
860
861
	}

	std::vector<unsigned int>::iterator it = faces.begin();
	while (it != faces.end())
	{
		unsigned int nbe = *it++;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
862
		out.write((char*)&nbe, sizeof(unsigned int)) ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
863
		for(unsigned int j = 0; j < nbe; ++j)
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
864
865
866
867
		{
			unsigned int index = *it++ ;
			out.write((char*)(&index), sizeof(unsigned int)) ;
		}
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
868
869
870
871
872
	}

	out.close() ;
	return true ;
}
873

Pierre Kraemer's avatar
Pierre Kraemer committed
874
template <typename PFP>
875
bool exportPLYPTM(typename PFP::MAP& map, const char* filename, const VertexAttribute<typename PFP::VEC3>& position, const VertexAttribute<typename PFP::VEC3> frame[3], const VertexAttribute<typename PFP::VEC3> colorPTM[6])
Pierre Kraemer's avatar
Pierre Kraemer committed
876
877
878
879
880
881
882
{
	typedef typename PFP::MAP MAP;
	typedef typename PFP::VEC3 VEC3;

	std::ofstream out(filename, std::ios::out) ;
	if (!out.good())
	{
883
		CGoGNerr << "Unable to open file " << CGoGNendl ;
Pierre Kraemer's avatar
Pierre Kraemer committed
884
885
886
		return false ;
	}

887
	VertexAutoAttribute<unsigned int> tableVertLab(map);
Pierre Kraemer's avatar
Pierre Kraemer committed
888
889
890
891
892
893
894
895
896

	unsigned int nbDarts = map.getNbDarts() ;

	std::vector<unsigned int> vertices;
	std::vector<unsigned int> faces;

	vertices.reserve(nbDarts/5);	// TODO non optimal reservation
	faces.reserve(nbDarts/3);

897
	CellMarker<VERTEX> markV(map);
898
	TraversorF<MAP> t(map) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
899
900
	unsigned int lab = 0;
	unsigned int nbf = 0;
901
	for(Dart d = t.begin(); d != t.end(); d = t.next())
Pierre Kraemer's avatar
Pierre Kraemer committed
902
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
903
904
905
		std::vector<unsigned int> face ;
		Traversor2FV<typename PFP::MAP> tfv(map, d) ;
		for(Dart it = tfv.begin(); it != tfv.end(); it = tfv.next())
Pierre Kraemer's avatar
Pierre Kraemer committed
906
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
907
			if (!markV.isMarked(it))
Pierre Kraemer's avatar
Pierre Kraemer committed
908
			{
Pierre Kraemer's avatar
Pierre Kraemer committed
909
910
				markV.mark(it);
				tableVertLab[it] = lab++;
911
				vertices.push_back(map.template getEmbedding<VERTEX>(it));
912
			}
Pierre Kraemer's avatar
Pierre Kraemer committed
913
914
			face.push_back(tableVertLab[it]);
		}
915

Pierre Kraemer's avatar
Pierre Kraemer committed
916
917
918
		faces.push_back(face.size()) ;
		for (unsigned int i = 0 ; i < face.size() ; ++i)
			faces.push_back(face.at(i)) ;
919

Pierre Kraemer's avatar
Pierre Kraemer committed
920
		++nbf;
Pierre Kraemer's avatar
Pierre Kraemer committed
921
922
	}

923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
	out << "ply" << std::endl ;
	out << "format ascii 1.0" << std::endl ;
	out << "comment ply PTM (F. Larue format)" << std::endl ;
	out << "element vertex " << vertices.size() << std::endl ;
	out << "property float x" << std::endl ;
	out << "property float y" << std::endl ;
	out << "property float z" << std::endl ;
	out << "property float tx" << std::endl ;
	out << "property float ty" << std::endl ;
	out << "property float tz" << std::endl ;
	out << "property float bx" << std::endl ;
	out << "property float by" << std::endl ;
	out << "property float bz" << std::endl ;
	out << "property float nx" << std::endl ;
	out << "property float ny" << std::endl ;
	out << "property float nz" << std::endl ;
	out << "property float L1_a" << std::endl ;
	out << "property float L1_b" << std::endl ;
	out << "property float L1_c" << std::endl ;
	out << "property float L1_d" << std::endl ;
	out << "property float L1_e" << std::endl ;
	out << "property float L1_f" << std::endl ;
	out << "property float L2_a" << std::endl ;
	out << "property float L2_b" << std::endl ;
	out << "property float L2_c" << std::endl ;
	out << "property float L2_d" << std::endl ;
	out << "property float L2_e" << std::endl ;
	out << "property float L2_f" << std::endl ;
	out << "property float L3_a" << std::endl ;
	out << "property float L3_b" << std::endl ;
	out << "property float L3_c" << std::endl ;
	out << "property float L3_d" << std::endl ;
	out << "property float L3_e" << std::endl ;
	out << "property float L3_f" << std::endl ;
	out << "element face " << nbf << std::endl ;
	out << "property list uchar int vertex_indices" << std::endl ;
	out << "end_header" << std::endl ;
Pierre Kraemer's avatar
Pierre Kraemer committed
960
961
962
963

	for(unsigned int i = 0; i < vertices.size(); ++i)
	{
		unsigned int vi = vertices[i];
964
965
966
967
968
969
		out << position[vi][0] << " " << position[vi][1] << " " << position[vi][2] << " " ;
		out << frame[0][vi][0] << " " << frame[0][vi][1] << " " << frame[0][vi][2] << " " ;
		out << frame[1][vi][0] << " " << frame[1][vi][1] << " " << frame[1][vi][2] << " " ;
		out << frame[2][vi][0] << " " << frame[2][vi][1] << " " << frame[2][vi][2] << " " ;
		out << colorPTM[0][vi][0] << " " << colorPTM[1][vi][0] << " " << colorPTM[2][vi][0] << " " << colorPTM[3][vi][0] << " " << colorPTM[4][vi][0] << " " << colorPTM[5][vi][0] <<" " ;
		out << colorPTM[0][vi][1] << " " << colorPTM[1][vi][1] << " " << colorPTM[2][vi][1] << " " << colorPTM[3][vi][1] << " " << colorPTM[4][vi][1] << " " << colorPTM[5][vi][1] <<" " ;
970
		out << colorPTM[0][vi][2] << " " << colorPTM[1][vi][2] << " " << colorPTM[2][vi][2] << " " << colorPTM[3][vi][2] << " " << colorPTM[4][vi][2] << " " << colorPTM[5][vi][2] << std::endl ;
Pierre Kraemer's avatar
Pierre Kraemer committed
971
972
	}

973
	std::vector<unsigned int>::iterator it = faces.begin();
Pierre Kraemer's avatar
Pierre Kraemer committed
974
975
976
977
978
979
	while (it != faces.end())
	{
		unsigned int nbe = *it++;
		out << nbe ;
		for(unsigned int j = 0; j < nbe; ++j)
			out << " " << *it++;
980
		out << std::endl ;
Pierre Kraemer's avatar
Pierre Kraemer committed
981
982
983
984
	}

	out.close() ;
	return true ;
985
}
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
986
*/
Pierre Kraemer's avatar
Pierre Kraemer committed
987

Lionel Untereiner's avatar
Lionel Untereiner committed
988
template <typename PFP>
Pierre Kraemer's avatar
Pierre Kraemer committed
989
bool exportChoupi(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP::IMPL>& position, const char* filename)
Lionel Untereiner's avatar
Lionel Untereiner committed
990
991
992
993
994
995
996
997
998
999
{
	typedef typename PFP::MAP MAP;

	std::ofstream out(filename, std::ios::out) ;
	if (!out.good())
	{
		CGoGNerr << "Unable to open file " << CGoGNendl ;
		return false ;
	}

1000
	out << map.template getNbOrbits<VERTEX>() << " " << map.template getNbOrbits<EDGE>() << std::endl;
For faster browsing, not all history is shown. View entire blame