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