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/traversorCell.h"
#include "Topology/generic/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
50
{
	typedef typename PFP::MAP MAP;
	typedef typename PFP::VEC3 VEC3;
	
51
	// open file
52
	std::ofstream out ;
53
	if (!binary)
54
		out.open(filename, std::ios::out) ;
55
56
57
	else
		out.open(filename, std::ios::out | std::ios::binary) ;

Pierre Kraemer's avatar
Pierre Kraemer committed
58
59
	if (!out.good())
	{
60
		CGoGNerr << "Unable to open file " << CGoGNendl ;
Pierre Kraemer's avatar
Pierre Kraemer committed
61
62
63
64
65
66
67
68
69
70
71
72
73
		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) ;

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

99
	// Start writing the file
100
	out << "ply" << std::endl ;
101
	// ascii or binary
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
	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 ;
119
120
	out << "comment or contact : cgogn@unistra.fr" << std::endl ;
	// Vertex elements
121
	out << "element vertex " << vertices.size() << std::endl ;
122
	// Position property
123
124
	if (position.isValid())
	{
125
126
127
		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 ;
128
	}
129
	// Face element
130
	out << "element face " << facesSize.size() << std::endl ;
131
	out << "property list uint8 uint" << 8 * sizeof(facesIdx[0][0]) << " vertex_indices" << std::endl ;
132
	out << "end_header" << std::endl ;
Pierre Kraemer's avatar
Pierre Kraemer committed
133

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

140
		// ascii faces
141
142
143
144
145
146
147
		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
148
	}
149
	else // binary
Pierre Kraemer's avatar
Pierre Kraemer committed
150
	{
151
		// binary vertices
152
153
154
		for(unsigned int i = 0; i < vertices.size(); ++i)
		{
			Geom::Vec3f v = position[vertices[i]] ;
155
			out.write((char*)(&(v[0])), sizeof(v)) ;
156
157
		}

158
		// binary faces
159
160
161
162
		for(unsigned int i = 0; i < facesSize.size(); ++i)
		{
			unsigned char nbe = facesSize[i] ;
			out.write((char*)(&nbe), sizeof(unsigned char)) ;
163
164
165
166
167
168
169
170
171
172
			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
173
bool exportPLYnew(typename PFP::MAP& map, const std::vector<VertexAttribute<typename PFP::VEC3, typename PFP::MAP::IMPL>*>& attributeHandlers, const char* filename, bool binary)
174
175
{
	typedef typename PFP::MAP MAP;
Pierre Kraemer's avatar
Pierre Kraemer committed
176
	typedef typename PFP::MAP::IMPL MAP_IMPL;
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
202
	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
203
	CellMarker<MAP, VERTEX> markV(map) ;
204
	TraversorF<MAP> t(map) ;
205
206
207
208
209
	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
210
		Traversor2FV<MAP> tfv(map, d) ;
211
212
213
		for(Dart it = tfv.begin(); it != tfv.end(); it = tfv.next())
		{
			++degree ;
214
			unsigned int vNum = map.template getEmbedding<VERTEX>(it) ;
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
249
			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
250
	for (typename std::vector<VertexAttribute<VEC3, MAP_IMPL>* >::const_iterator attrHandler = attributeHandlers.begin() ; attrHandler != attributeHandlers.end() ; ++attrHandler)
251
	{
252
		if ((*attrHandler)->isValid() && ((*attrHandler)->getOrbit() == VERTEX) )
253
		{
254
			if ((*attrHandler)->name().compare("position") == 0)  // Vertex position property
255
			{
256
257
258
				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 ;
259
			}
260
			else if ((*attrHandler)->name().compare("normal") == 0)	// normal property
261
			{
262
263
264
				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 ;
265
			}
266
			else if ((*attrHandler)->name().compare("color") == 0)	// vertex color property
267
			{
268
269
270
				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 ;
271
272
273
			}
			else // other vertex properties
			{
274
275
276
				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 ;
277
278
279
280
281
282
			}
		}
	}

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

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

		// 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
310
			for (typename std::vector<VertexAttribute<VEC3, MAP_IMPL>*>::const_iterator attrHandler = attributeHandlers.begin() ; attrHandler != attributeHandlers.end() ; ++attrHandler)
311
				if ((*attrHandler)->isValid() && (*attrHandler)->getOrbit() == VERTEX)
312
				{
Pierre Kraemer's avatar
Pierre Kraemer committed
313
					const VEC3& v = (*(*attrHandler))[vertices[i]] ;
314
315
316
317
318
319
					out.write((char*)(&(v[0])), sizeof(v)) ;
				}

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

	out.close() ;
327

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

template <typename PFP>
Pierre Kraemer's avatar
Pierre Kraemer committed
332
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
333
334
335
336
337
338
339
{
	typedef typename PFP::MAP MAP;
	typedef typename PFP::VEC3 VEC3;
	
	std::ofstream out(filename, std::ios::out) ;
	if (!out.good())
	{
340
		CGoGNerr << "Unable to open file " << CGoGNendl ;
Pierre Kraemer's avatar
Pierre Kraemer committed
341
342
343
344
345
346
347
348
349
350
351
352
353
		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
354
	CellMarker<MAP, VERTEX> markV(map) ;
355
	TraversorF<MAP> t(map) ;
356
	for(Dart d = t.begin(); d != t.end(); d = t.next())
Pierre Kraemer's avatar
Pierre Kraemer committed
357
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
358
359
360
361
362
		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
363
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
364
			++degree ;
365
			unsigned int vNum = map.template getEmbedding<VERTEX>(it) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
366
			if(!markV.isMarked(it))
Pierre Kraemer's avatar
Pierre Kraemer committed
367
			{
Pierre Kraemer's avatar
Pierre Kraemer committed
368
369
370
				markV.mark(it) ;
				vIndex[vNum] = vCpt++ ;
				vertices.push_back(vNum) ;
371
			}
Pierre Kraemer's avatar
Pierre Kraemer committed
372
			fidx.push_back(vIndex[vNum]) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
373
		}
Pierre Kraemer's avatar
Pierre Kraemer committed
374
375
		facesSize.push_back(degree) ;
		facesIdx.push_back(fidx) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
376
377
	}

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

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

	out.close() ;
	return true ;
}
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
397
/*
398
template <typename PFP>
Lionel Untereiner's avatar
Lionel Untereiner committed
399
bool exportOBJ(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& position, const char* filename)
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
{
	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
421
	CellMarker<VERTEX> markV(map) ;
422
	TraversorF<MAP> t(map) ;
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
463
	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 ;
}

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

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

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

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

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

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

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

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

	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") ;
520
	for (unsigned int i = 0 ; i < 15 ; ++i)
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
521
522
523
524
525
	{
		std::stringstream name ;
		name << "colorPTM_a" << i ;
		colorPTM[i] = map.template getAttribute<VEC3>(VERTEX,name.str()) ;
	}
526
	const unsigned int nbCoefs = colorPTM[14].isValid() ? 15 : (colorPTM[9].isValid() ? 10 : 6) ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
527

528
529
	out << "ply" << std::endl ;
	out << "format ascii 1.0" << std::endl ;
530
	out << "comment ply PTM (K. Vanhoey generic format)" << std::endl ;
531
532
533
534
535
536
537
538
539
540
541
542
543
	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 ;
544
	for(unsigned int coefI = 0 ; coefI < nbCoefs ; ++coefI)
545
		out << "property float C0_a" << coefI << std::endl ;
546
	for(unsigned int coefI = 0 ; coefI < nbCoefs ; ++coefI)
547
		out << "property float C1_a" << coefI << std::endl ;
548
	for(unsigned int coefI = 0 ; coefI < nbCoefs ; ++coefI)
549
		out << "property float C2_a" << coefI << std::endl ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
550

551
552
553
	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") ;
554
555
556
557
558
559
	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 ;
560
561
562
563
564

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

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

	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
602
*/
603
/*
604
template <typename PFP>
605
bool exportPlySLFgeneric(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& position, const char* filename)
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
{
	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);
629
	TraversorF<MAP> t(map) ;
630
631
632
633
634
635
636
637
638
639
640
641
	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++;
642
				vertices.push_back(map.getEmbedding<VERTEX>(it));
643
644
645
646
647
648
649
650
651
652
653
			}
			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;
	}

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

	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") ;
660
661
662

	unsigned int i = 0 ;
	do {
663
		std::stringstream name ;
664
665
666
667
668
669
670
		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()) ;
671

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

676
677
	out << "ply" << std::endl ;
	out << "format ascii 1.0" << std::endl ;
kenneth's avatar
kenneth committed
678
	out << "comment ply SLF (K. Vanhoey generic format): SLF_" << (((extension == ".plyPTMext") || extension == ".plyPTMextBin" ) ? "PTMext" : "SHreal") << std::endl ;
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
734
	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
735
template <typename PFP>
736
bool exportPlySLFgenericBin(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& position, const char* filename)
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
737
738
739
740
741
{
	typedef typename PFP::MAP MAP;
	typedef typename PFP::VEC3 VEC3;
	typedef typename PFP::REAL REAL;

742
	std::ofstream out(filename, std::ios::out) ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
	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);
760
	TraversorF<MAP> t(map) ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
761
762
763
764
765
766
767
768
769
770
771
772
	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++;
773
				vertices.push_back(map.getEmbedding<VERTEX>(it));
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
			}
			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) ;

807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
	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
823
	for(unsigned int coefI = 0 ; coefI < nbCoefs ; ++coefI)
824
		out << "property float C0_" << coefI << std::endl ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
825
	for(unsigned int coefI = 0 ; coefI < nbCoefs ; ++coefI)
826
		out << "property float C1_" << coefI << std::endl ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
827
	for(unsigned int coefI = 0 ; coefI < nbCoefs ; ++coefI)
828
		out << "property float C2_" << coefI << std::endl ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
829

830
831
832
	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
833
834
835
836
837
838

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

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

	out.close() ;
	return true ;
}
874

Pierre Kraemer's avatar
Pierre Kraemer committed
875
template <typename PFP>
876
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
877
878
879
880
881
882
883
{
	typedef typename PFP::MAP MAP;
	typedef typename PFP::VEC3 VEC3;

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

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

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

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

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

Pierre Kraemer's avatar
Pierre Kraemer committed
921
		++nbf;
Pierre Kraemer's avatar
Pierre Kraemer committed
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
960
	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
961
962
963
964

	for(unsigned int i = 0; i < vertices.size(); ++i)
	{
		unsigned int vi = vertices[i];
965
966
967
968
969
970
		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] <<" " ;
971
		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
972
973
	}

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

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

Lionel Untereiner's avatar
Lionel Untereiner committed
989
template <typename PFP>
Pierre Kraemer's avatar
Pierre Kraemer committed
990
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
991
992
993
994
995
996
997
998
999
1000
1001
{
	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 ;
	}

1002
	out << map.template getNbOrbits<VERTEX>() << " " << map.template getNbOrbits<EDGE>() << std::endl;
Lionel Untereiner's avatar
Lionel Untereiner committed
1003

Pierre Kraemer's avatar
Pierre Kraemer committed
1004
	TraversorV<MAP> travV(map);
Lionel Untereiner's avatar
Lionel Untereiner committed
1005
1006
	for(Dart dit = travV.begin() ; dit != travV.end() ; dit = travV.next())
	{
1007
		out << map.template getEmbedding<VERTEX>(dit) << " " << position[dit] << std::endl;
Lionel Untereiner's avatar
Lionel Untereiner committed
1008
1009
	}

Pierre Kraemer's avatar
Pierre Kraemer committed
1010
	TraversorE<MAP> travE(map);
Lionel Untereiner's avatar
Lionel Untereiner committed
1011
1012
1013
	unsigned int indexE = 0;
	for(Dart dit = travE.begin() ; dit != travE.end() ; dit = travE.next())
	{
1014
		out << indexE << "  " << map.template getEmbedding<VERTEX>(dit) << " " << map.template getEmbedding<VERTEX>(map.phi2(dit)) << std::endl;
Lionel Untereiner's avatar
Lionel Untereiner committed
1015
1016
1017
1018
1019
1020
		++indexE;
	}

	out.close() ;
	return true ;
}
Pierre Kraemer's avatar
Pierre Kraemer committed
1021
1022
1023

} // namespace Export

Pierre Kraemer's avatar
Pierre Kraemer committed
1024
} // namespace Surface
1025

Pierre Kraemer's avatar
Pierre Kraemer committed
1026
1027
1028
} // namespace Algo

} // namespace CGoGN