Coupure prévue mardi 3 Août au matin pour maintenance du serveur. Nous faisons au mieux pour que celle-ci soit la plus brève possible.

viewer.cpp 20.8 KB
Newer Older
Pierre Kraemer's avatar
Pierre Kraemer committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps  *
* version 0.1                                                                  *
* Copyright (C) 2009, IGG Team, LSIIT, University of Strasbourg                *
*                                                                              *
* 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
27
28
29
30
31
32
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

#include "viewer.h"

Viewer::Viewer() :
	m_renderStyle(FLAT),
	m_drawVertices(false),
	m_drawEdges(false),
	m_drawFaces(true),
	m_drawNormals(false),
33
	m_drawTopo(false),
34
	m_drawBoundaryTopo(false),
Pierre Kraemer's avatar
Pierre Kraemer committed
35
36
37
38
39
	m_render(NULL),
	m_phongShader(NULL),
	m_flatShader(NULL),
	m_vectorShader(NULL),
	m_simpleColorShader(NULL),
40
41
	m_pointSprite(NULL),
	m_nbFrames(0)
Pierre Kraemer's avatar
Pierre Kraemer committed
42
43
{
	normalScaleFactor = 1.0f ;
Sylvain Thery's avatar
MAJ MC  
Sylvain Thery committed
44
	vertexScaleFactor = 0.1f ;
Pierre Kraemer's avatar
Pierre Kraemer committed
45
46
47
	faceShrinkage = 1.0f ;

	colClear = Geom::Vec4f(0.2f, 0.2f, 0.2f, 0.1f) ;
48
	colDif = Geom::Vec4f(0.3f, 0.5f, 0.2f, 1.0f) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
49
50
51
52
53
54
55
	colSpec = Geom::Vec4f(0.9f, 0.9f, 0.9f, 1.0f) ;
	colNormal = Geom::Vec4f(1.0f, 0.0f, 0.0f, 1.0f) ;
	shininess = 80.0f ;
}

void Viewer::initGUI()
{
56
	setDock(&dock) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
57

58
59
60
61
	dock.check_drawVertices->setChecked(false) ;
	dock.check_drawEdges->setChecked(false) ;
	dock.check_drawFaces->setChecked(true) ;
	dock.check_drawNormals->setChecked(false) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
62

63
64
	dock.slider_verticesSize->setVisible(false) ;
	dock.slider_normalsSize->setVisible(false) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
65

66
67
	dock.slider_verticesSize->setSliderPosition(50) ;
	dock.slider_normalsSize->setSliderPosition(50) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
68
69
70
71
72
73

	setCallBack( dock.check_drawVertices, SIGNAL(toggled(bool)), SLOT(slot_drawVertices(bool)) ) ;
	setCallBack( dock.slider_verticesSize, SIGNAL(valueChanged(int)), SLOT(slot_verticesSize(int)) ) ;
	setCallBack( dock.check_drawEdges, SIGNAL(toggled(bool)), SLOT(slot_drawEdges(bool)) ) ;
	setCallBack( dock.check_drawFaces, SIGNAL(toggled(bool)), SLOT(slot_drawFaces(bool)) ) ;
	setCallBack( dock.combo_faceLighting, SIGNAL(currentIndexChanged(int)), SLOT(slot_faceLighting(int)) ) ;
74
	setCallBack( dock.check_drawTopo, SIGNAL(toggled(bool)), SLOT(slot_drawTopo(bool)) ) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
75
76
77
78
79
80
	setCallBack( dock.check_drawNormals, SIGNAL(toggled(bool)), SLOT(slot_drawNormals(bool)) ) ;
	setCallBack( dock.slider_normalsSize, SIGNAL(valueChanged(int)), SLOT(slot_normalsSize(int)) ) ;
}

void Viewer::cb_initGL()
{
81
82
83
84
85
	int major = 0;
	int minor = 0;
	glGetIntegerv(GL_MAJOR_VERSION, &major);
	glGetIntegerv(GL_MINOR_VERSION, &minor);
	CGoGNout <<"Using GL "<< major <<"."<< minor << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
86
87

	m_render = new Algo::Render::GL2::MapRender() ;
88
	m_topoRender = new Algo::Render::GL2::TopoRender() ;
89

90
	m_topoRender->setInitialDartsColor(1.0f, 1.00f, 1.00f) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
91
92
93
94

	m_positionVBO = new Utils::VBO() ;
	m_normalVBO = new Utils::VBO() ;

95
	m_phongShader = new Utils::ShaderPhong(true,false,false) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
96
97
98
99
100
101
	m_phongShader->setAttributePosition(m_positionVBO) ;
	m_phongShader->setAttributeNormal(m_normalVBO) ;
	m_phongShader->setAmbiant(colClear) ;
	m_phongShader->setDiffuse(colDif) ;
	m_phongShader->setSpecular(colSpec) ;
	m_phongShader->setShininess(shininess) ;
102
	m_phongShader->setBackColor(Geom::Vec4f(0,0,0.2,0)) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
103

104
	m_flatShader = new Utils::ShaderSimpleFlat(true,false) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
105
106
107
	m_flatShader->setAttributePosition(m_positionVBO) ;
	m_flatShader->setAmbiant(colClear) ;
	m_flatShader->setDiffuse(colDif) ;
108
109
	m_flatShader->setBackColor(Geom::Vec4f(0,0,0.2,0)) ;

Pierre Kraemer's avatar
Pierre Kraemer committed
110
111
112
113
114
115

	m_vectorShader = new Utils::ShaderVectorPerVertex() ;
	m_vectorShader->setAttributePosition(m_positionVBO) ;
	m_vectorShader->setAttributeVector(m_normalVBO) ;
	m_vectorShader->setColor(colNormal) ;

116
	m_simpleColorShader = new Utils::ShaderSimpleColor(true) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
117
	m_simpleColorShader->setAttributePosition(m_positionVBO) ;
Sylvain Thery's avatar
Sylvain Thery committed
118
	Geom::Vec4f c(0.0f, 0.0f, 0.0f, 1.0f) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
119
120
	m_simpleColorShader->setColor(c) ;

121

Pierre Kraemer's avatar
Pierre Kraemer committed
122
	m_pointSprite = new Utils::PointSprite() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
123
	m_pointSprite->setAttributePosition(m_positionVBO) ;
124
	m_pointSprite->setColor(Geom::Vec4f(0.0f, 0.0f, 1.0f, 1.0f)) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
125
126
127
128
129
130
131
132
133
134
135
136

	registerShader(m_phongShader) ;
	registerShader(m_flatShader) ;
	registerShader(m_vectorShader) ;
	registerShader(m_simpleColorShader) ;
	registerShader(m_pointSprite) ;
}

void Viewer::cb_redraw()
{
	if(m_drawVertices)
	{
137
		m_pointSprite->setSize(vertexScaleFactor) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
138
139
140
141
142
		m_render->draw(m_pointSprite, Algo::Render::GL2::POINTS) ;
	}

	if(m_drawEdges)
	{
143
		m_simpleColorShader->setColor(Geom::Vec4f(1.,1.,0.,0.));
Pierre Kraemer's avatar
Pierre Kraemer committed
144
145
146
147
		glLineWidth(1.0f) ;
		m_render->draw(m_simpleColorShader, Algo::Render::GL2::LINES) ;
	}

148
149
150
151
152
153
	if(m_drawTopo)
	{
		glDepthFunc(GL_LEQUAL);
		m_topoRender->drawTopo() ;
	}

Pierre Kraemer's avatar
Pierre Kraemer committed
154
155
156
	if(m_drawFaces)
	{
		glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) ;
157
158
159
160
161
		if (m_drawEdges||m_drawTopo)
		{
			glEnable(GL_POLYGON_OFFSET_FILL) ;
			glPolygonOffset(1.0f, 1.0f) ;
		}
Pierre Kraemer's avatar
Pierre Kraemer committed
162
163
164
165
166
167
168
169
170
171
172
		switch(m_renderStyle)
		{
			case FLAT :
				m_render->draw(m_flatShader, Algo::Render::GL2::TRIANGLES) ;
				break ;
			case PHONG :
				m_render->draw(m_phongShader, Algo::Render::GL2::TRIANGLES) ;
				break ;
		}
		glDisable(GL_POLYGON_OFFSET_FILL) ;
	}
173

174

175
176
177
178
179
180
181
182

	if(m_drawNormals)
	{
		float size = normalBaseSize * normalScaleFactor ;
		m_vectorShader->setScale(size) ;
		glLineWidth(1.0f) ;
		m_render->draw(m_vectorShader, Algo::Render::GL2::POINTS) ;
	}
183
184
185
186
187
188
189
190

	m_nbFrames++;
	if (m_nbFrames >=100)
	{
		std::cout << 100000.0/m_frame_ch.elapsed()<< " fps"<<std::endl;
		m_nbFrames = 0;
		m_frame_ch.start();
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
191
192
193
194
195
196
}

void Viewer::cb_Open()
{
	std::string filters("all (*.*);; trian (*.trian);; ctm (*.ctm);; off (*.off);; ply (*.ply)") ;
	std::string filename = selectFile("Open Mesh", "", filters) ;
197
198
	if (filename.empty())
		return ;
Pierre Kraemer's avatar
Pierre Kraemer committed
199
200
201
202
203

	importMesh(filename) ;
	updateGL() ;
}

204
205
void Viewer::cb_Save()
{
206
	std::string filters("all (*.*);; map (*.map);; off (*.off);; ply (*.ply)") ;
207
	std::string filename = selectFileSave("Save Mesh", "", filters) ;
208

209
210
	if (!filename.empty())
		exportMesh(filename) ;
211
212
}

213
214
void Viewer::cb_keyPress(int keycode)
{
215
	switch(keycode)
Sylvain Thery's avatar
Sylvain Thery committed
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
	case 'n':
		m_flatShader->setNoClippingPlane();
		m_phongShader->setNoClippingPlane();
		m_topoRender->setNoClippingPlane();
		m_simpleColorShader->setNoClippingPlane();
		m_pointSprite->setNoClippingPlane();
		m_vectorShader->setNoClippingPlane();

		break;
	case 'N':
	{
		const Geom::Vec3f& Pc = bb.center();
		const Geom::Vec3f& Nc = bb.diag();
		Geom::Vec4f planeClip(Nc[0],Nc[1],Nc[2],-(Pc*Nc));

		m_flatShader->setClippingPlane(planeClip);
		m_phongShader->setClippingPlane(planeClip);
		m_topoRender->setClippingPlane(planeClip);
		m_simpleColorShader->setClippingPlane(planeClip);
		m_pointSprite->setClippingPlane(planeClip);
		m_vectorShader->setClippingPlane(planeClip);

	}
		break;


243
244
245
		case 'c' :
			myMap.check();
			break;
Sylvain Thery's avatar
Sylvain Thery committed
246

247
		case 'a':
Sylvain Thery's avatar
Sylvain Thery committed
248
		{
249
250
251
252
253
254
255
			Utils::Chrono ch;
			ch.start();
			VertexAttribute<VEC3, MAP> pos2 = myMap.getAttribute<VEC3, VERTEX, MAP>("pos2") ;
			if(!pos2.isValid())
				pos2 = myMap.addAttribute<VEC3, VERTEX, MAP>("pos2") ;

			for (int i=0; i< 10; ++i)
Sylvain Thery's avatar
Sylvain Thery committed
256
			{
257
258
				TraversorV<MAP> trav(myMap);
				for (Dart d=trav.begin(), d_end = trav.end(); d!=d_end ; d = trav.next())
Sylvain Thery's avatar
Sylvain Thery committed
259
				{
260
261
262
263
264
265
266
267
268
					pos2[d] = VEC3(0,0,0);
					int nb=0;
					Traversor2VVaF<MAP> trf(myMap,d);
					for (Dart e = trf.begin(),e_end =trf.end() ; e != e_end; e = trf.next())
					{
						pos2[d] += position[e];
						nb++;
					}
					pos2[d]/=nb;
Sylvain Thery's avatar
Sylvain Thery committed
269
				}
270
				myMap.swapAttributes(position, pos2);
Sylvain Thery's avatar
Sylvain Thery committed
271
			}
272
273
274
275
276
			std::cout << "Traversor "<< ch.elapsed()<< " ms "<< std::endl;
			Algo::Surface::Geometry::computeNormalVertices<PFP>(myMap, position, normal) ;
			m_positionVBO->updateData(position) ;
			m_normalVBO->updateData(normal) ;
			updateGL();
Sylvain Thery's avatar
Sylvain Thery committed
277
		}
278
			break;
Sylvain Thery's avatar
Sylvain Thery committed
279

280
281
282
283
		case 'b':
		{
			Utils::Chrono ch;
			ch.start();
Sylvain Thery's avatar
Sylvain Thery committed
284

285
286
287
			VertexAttribute<VEC3,MAP> pos2 = myMap.getAttribute<VEC3, VERTEX, MAP>("pos2") ;
			if(!pos2.isValid())
				pos2 = myMap.addAttribute<VEC3, VERTEX, MAP>("pos2") ;
Sylvain Thery's avatar
Sylvain Thery committed
288

289
			for (int i=0; i< 6; ++i)
Sylvain Thery's avatar
Sylvain Thery committed
290
			{
291
				foreach_cell<VERTEX>(myMap, [&] (Vertex d)
Sylvain Thery's avatar
Sylvain Thery committed
292
				{
293
294
295
296
297
298
299
300
					pos2[d] = VEC3(0,0,0);
					int nb=0;
					foreach_adjacent2<FACE>(myMap,d,[&](Vertex e)
					{
						pos2[d] += position[e];
						nb++;
					});
					pos2[d]/=nb;
Sylvain Thery's avatar
Sylvain Thery committed
301
				});
302
303
304
305
306
307
308
				myMap.swapAttributes(position,pos2);
			}
			std::cout << "Lambda "<< ch.elapsed()<< " ms "<< std::endl;
			Algo::Surface::Geometry::computeNormalVertices<PFP>(myMap, position, normal) ;
			m_positionVBO->updateData(position) ;
			m_normalVBO->updateData(normal) ;
			updateGL();
Sylvain Thery's avatar
Sylvain Thery committed
309
		}
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
			break;
		case 'B':
		{
			Utils::Chrono ch;
			ch.start();

			VertexAttribute<VEC3,MAP> pos2 = myMap.getAttribute<VEC3, VERTEX, MAP>("pos2") ;
			if(!pos2.isValid())
				pos2 = myMap.addAttribute<VEC3, VERTEX, MAP>("pos2") ;

			//		foreach_cell_EvenOddd<VERTEX>(myMap, [&] (Vertex d)
			//		{
			//			pos2[d] = VEC3(0,0,0);
			//			int nb=0;
			//			foreach_adjacent2<FACE>(myMap,d,[&](Vertex e)
			//			{
			//				pos2[d] += position[e];
			//				nb++;
			//			});
			//			pos2[d]/=nb;
			//		},
			//		[&] (Vertex d)
			//		{
			//			position[d] = VEC3(0,0,0);
			//			int nb=0;
			//			foreach_adjacent2<FACE>(myMap,d,[&](Vertex e)
			//			{
			//				position[d] += pos2[e];
			//				nb++;
			//			});
			//			position[d]/=nb;
			//		},
			//		3);

			//		std::cout << "Even/Odd "<< ch.elapsed()<< " ms "<< std::endl;
			Algo::Surface::Geometry::computeNormalVertices<PFP>(myMap, position, normal) ;
			m_positionVBO->updateData(position) ;
			m_normalVBO->updateData(normal) ;
			updateGL();
		}
			break;
Sylvain Thery's avatar
Sylvain Thery committed
351

352
		case 'e':
Sylvain Thery's avatar
Sylvain Thery committed
353
		{
354
355
356
357
358
359
360
			Utils::Chrono ch;
			ch.start();
			VertexAttribute<VEC3,MAP> pos2 = myMap.getAttribute<VEC3, VERTEX, MAP>("pos2") ;
			if(!pos2.isValid())
				pos2 = myMap.addAttribute<VEC3, VERTEX, MAP>("pos2") ;

			for (int i=0; i< 10; ++i)
Sylvain Thery's avatar
Sylvain Thery committed
361
			{
362
363
				TraversorV<MAP> trav(myMap);
				for (Dart d=trav.begin(), d_end = trav.end(); d!=d_end ; d = trav.next())
Sylvain Thery's avatar
Sylvain Thery committed
364
				{
365
366
367
368
369
370
371
372
373
					pos2[d] = VEC3(0,0,0);
					int nb=0;
					Traversor2VE<MAP> trf(myMap,d);
					for (Dart e = trf.begin(),e_end =trf.end() ; e != e_end; e = trf.next())
					{
						pos2[d] += position[myMap.phi1(e)];
						nb++;
					}
					pos2[d]/=nb;
Sylvain Thery's avatar
Sylvain Thery committed
374
				}
375
				myMap.swapAttributes(position,pos2);
Sylvain Thery's avatar
Sylvain Thery committed
376
			}
377
378
379
380
381
			std::cout << "Traversor "<< ch.elapsed()<< " ms "<< std::endl;
			Algo::Surface::Geometry::computeNormalVertices<PFP>(myMap, position, normal) ;
			m_positionVBO->updateData(position) ;
			m_normalVBO->updateData(normal) ;
			updateGL();
Sylvain Thery's avatar
Sylvain Thery committed
382
		}
383
			break;
Sylvain Thery's avatar
Sylvain Thery committed
384

385
386
387
388
		case 'f':
		{
			Utils::Chrono ch;
			ch.start();
Sylvain Thery's avatar
Sylvain Thery committed
389

390
391
392
			VertexAttribute<VEC3,MAP> pos2 = myMap.getAttribute<VEC3, VERTEX, MAP>("pos2") ;
			if(!pos2.isValid())
				pos2 = myMap.addAttribute<VEC3, VERTEX, MAP>("pos2") ;
Sylvain Thery's avatar
Sylvain Thery committed
393

394
			for (int i=0; i< 10; ++i)
Sylvain Thery's avatar
Sylvain Thery committed
395
			{
396
				foreach_cell<VERTEX>(myMap, [&] (Vertex d)
Sylvain Thery's avatar
Sylvain Thery committed
397
				{
398
399
400
401
402
403
404
405
					pos2[d] = VEC3(0,0,0);
					int nb=0;
					foreach_incident2<EDGE>(myMap,d,[&](Edge e)
					{
						pos2[d] += position[myMap.phi1(e)];
						nb++;
					});
					pos2[d]/=nb;
Sylvain Thery's avatar
Sylvain Thery committed
406
				});
407
408
409
410
411
412
413
				myMap.swapAttributes(position,pos2);
			}
			std::cout << "Lambda "<< ch.elapsed()<< " ms "<< std::endl;
			Algo::Surface::Geometry::computeNormalVertices<PFP>(myMap, position, normal) ;
			m_positionVBO->updateData(position) ;
			m_normalVBO->updateData(normal) ;
			updateGL();
Sylvain Thery's avatar
Sylvain Thery committed
414
		}
415
			break;
Sylvain Thery's avatar
Sylvain Thery committed
416

417
		case'A':
418
		{
419
420
421
422
			myMap.disableQuickTraversal<VERTEX>() ;
#define NBLOOP 5
			Utils::Chrono ch;
			ch.start();
423
			{
424
425
				TraversorCell<MAP, VERTEX, FORCE_CELL_MARKING> trav(myMap,true);
				for(unsigned int i=0; i<NBLOOP; ++i)
426
				{
427
428
429
430
					for (Cell<VERTEX> v = trav.begin(), e = trav.end(); v.dart != e.dart; v = trav.next())
					{
						normal[v][0] = 0.0f;
					}
431
				}
432
				std::cout << "FORCE_CELL_MARKING "<< ch.elapsed()<< " ms "<< std::endl;
433
			}
Sylvain Thery's avatar
Sylvain Thery committed
434

435
			ch.start();
Sylvain Thery's avatar
Sylvain Thery committed
436
			{
437
438
				TraversorCell<MAP, VERTEX> trav(myMap);
				for(unsigned int i=0; i<NBLOOP; ++i)
439
				{
440
441
442
443
					for (Cell<VERTEX> v = trav.begin(), e = trav.end(); v.dart != e.dart; v = trav.next())
					{
						normal[v][0] = 0.0f;
					}
444
				}
445
				std::cout << "auto "<< ch.elapsed()<< " ms "<< std::endl;
Sylvain Thery's avatar
Sylvain Thery committed
446
			}
447

448
			ch.start();
449
			{
450
451
				TraversorCell<MAP, VERTEX> trav(myMap,true);
				for(unsigned int i=0; i<NBLOOP; ++i)
452
				{
453
454
455
456
					for (Cell<VERTEX> v = trav.begin(), e = trav.end(); v.dart != e.dart; v = trav.next())
					{
						normal[v][0] = 0.0f;
					}
457
				}
458
				std::cout << "auto forcedart "<< ch.elapsed()<< " ms "<< std::endl;
459
460
			}

461
			ch.start();
462
			{
463
464
				TraversorCell<MAP, VERTEX, FORCE_DART_MARKING> trav(myMap,true);
				for(unsigned int i=0; i<NBLOOP; ++i)
465
				{
466
467
468
469
					for (Cell<VERTEX> v = trav.begin(), e = trav.end(); v.dart != e.dart; v = trav.next())
					{
						normal[v][0] = 0.0f;
					}
470
				}
471
				std::cout << "FORCE_DART_MARKING "<< ch.elapsed()<< " ms "<< std::endl;
472
			}
473
474
			myMap.enableQuickTraversal<MAP, VERTEX>() ;
			ch.start();
475
			{
476
477
				TraversorCell<MAP, VERTEX> trav(myMap);
				for(unsigned int i=0; i<NBLOOP; ++i)
478
				{
479
480
481
482
					for (Cell<VERTEX> v = trav.begin(), e = trav.end(); v.dart != e.dart; v = trav.next())
					{
						normal[v][0] = 0.0f;
					}
483
				}
484
				std::cout << "auto (quick) "<< ch.elapsed()<< " ms "<< std::endl;
485
486
			}

487
			ch.start();
488
			{
489
490
				TraversorCell<MAP, VERTEX, FORCE_QUICK_TRAVERSAL> trav(myMap);
				for(unsigned int i=0; i<NBLOOP; ++i)
491
				{
492
493
494
495
					for (Cell<VERTEX> v = trav.begin(), e = trav.end(); v.dart != e.dart; v = trav.next())
					{
						normal[v][0] = 0.0f;
					}
496
				}
497
				std::cout << "FORCE_QUICK_TRAVERSAL "<< ch.elapsed()<< " ms "<< std::endl;
498
499
			}

500
501
		}
			break;
Sylvain Thery's avatar
Sylvain Thery committed
502

503
504
		case'Z':
		{
Sylvain Thery's avatar
Sylvain Thery committed
505

506
507
508
509
510
511
			Utils::Chrono ch;
			ch.start();
			CGoGN::Parallel::NumberOfThreads = 1;
			for (unsigned int i=0; i<4; ++i)
				Algo::Surface::Geometry::Parallel::computeNormalVertices<PFP>(myMap, position, normal) ;
			std::cout << "Algo::Surface::Geometry::Parallel::computeNormalVertices1 "<< ch.elapsed()<< " ms "<< std::endl;
Sylvain Thery's avatar
Sylvain Thery committed
512

513
			ch.start();
Sylvain Thery's avatar
Sylvain Thery committed
514
			CGoGN::Parallel::NumberOfThreads = 2;
515
516
			for (unsigned int i=0; i<4; ++i)
				Algo::Surface::Geometry::Parallel::computeNormalVertices<PFP>(myMap, position, normal) ;
Sylvain Thery's avatar
Sylvain Thery committed
517
			std::cout << "Algo::Surface::Geometry::Parallel::computeNormalVertices2 "<< ch.elapsed()<< " ms "<< std::endl;
Sylvain Thery's avatar
Sylvain Thery committed
518

Sylvain Thery's avatar
Sylvain Thery committed
519
			ch.start();
Sylvain Thery's avatar
Sylvain Thery committed
520
			CGoGN::Parallel::NumberOfThreads = 3;
521
522
			for (unsigned int i=0; i<4; ++i)
				Algo::Surface::Geometry::Parallel::computeNormalVertices<PFP>(myMap, position, normal) ;
Sylvain Thery's avatar
Sylvain Thery committed
523
			std::cout << "Algo::Surface::Geometry::Parallel::computeNormalVertices3 "<< ch.elapsed()<< " ms "<< std::endl;
Sylvain Thery's avatar
Sylvain Thery committed
524

525
			ch.start();
Sylvain Thery's avatar
Sylvain Thery committed
526
527
528
529
			CGoGN::Parallel::NumberOfThreads = 4;
			for (unsigned int i=0; i<4; ++i)
				Algo::Surface::Geometry::Parallel::computeNormalVertices<PFP>(myMap, position, normal) ;
			std::cout << "Algo::Surface::Geometry::Parallel::computeNormalVertices4 "<< ch.elapsed()<< " ms "<< std::endl;
Sylvain Thery's avatar
Sylvain Thery committed
530

Sylvain Thery's avatar
Sylvain Thery committed
531
532
			ch.start();
			CGoGN::Parallel::NumberOfThreads = 8;
533
			for (unsigned int i=0; i<4; ++i)
Sylvain Thery's avatar
Sylvain Thery committed
534
535
				Algo::Surface::Geometry::Parallel::computeNormalVertices<PFP>(myMap, position, normal) ;
			std::cout << "Algo::Surface::Geometry::Parallel::computeNormalVertices8 "<< ch.elapsed()<< " ms "<< std::endl;
Sylvain Thery's avatar
Sylvain Thery committed
536
537


538
539
540
541
542
543
544
545
546
			//		ch.start();
			//		Parallel::foreach_cell_EO<VERTEX>(myMap,[&](Vertex v, unsigned int thr)
			//		{
			//			normal[v] = Algo::Surface::Geometry::vertexNormal<PFP>(myMap,v,position);
			//		},
			//		[&](Vertex v, unsigned int th)
			//		{
			//			normal[v] = Algo::Surface::Geometry::vertexNormal<PFP>(myMap,v,position);
			//		},2,4,false,FORCE_CELL_MARKING);
Sylvain Thery's avatar
Sylvain Thery committed
547

548
			//		std::cout << "Parallel::foreach_cell_EO "<< ch.elapsed()<< " ms "<< std::endl;
Sylvain Thery's avatar
Sylvain Thery committed
549
550


551
552
		}
			break;
Sylvain Thery's avatar
Sylvain Thery committed
553
554


555
556
557
		default:
			break;
	}
558
559
}

Pierre Kraemer's avatar
Pierre Kraemer committed
560
561
void Viewer::importMesh(std::string& filename)
{
562
563
	myMap.clear(true) ;

564
565
566
567
568
569
	size_t pos = filename.rfind(".");    // position of "." in filename
	std::string extension = filename.substr(pos);

	if (extension == std::string(".map"))
	{
		myMap.loadMapBin(filename);
570
		position = myMap.getAttribute<VEC3, VERTEX, MAP>("position") ;
571
572
	}
	else
Pierre Kraemer's avatar
Pierre Kraemer committed
573
	{
574
		std::vector<std::string> attrNames ;
Sylvain Thery's avatar
Sylvain Thery committed
575
		if(!Algo::Surface::Import::importMesh<PFP>(myMap, filename, attrNames))
576
577
578
579
		{
			CGoGNerr << "could not import " << filename << CGoGNendl ;
			return;
		}
580
		position = myMap.getAttribute<PFP::VEC3, VERTEX, MAP>(attrNames[0]) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
581
	}
582

583
	//	myMap.enableQuickTraversal<VERTEX>() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
584

585
586
587

	std::cout << "The mesh is " << (myMap.isOpen() ? "open" : "closed") << std::endl;

588
589
590
	m_render->initPrimitives<PFP>(myMap, Algo::Render::GL2::POINTS) ;
	m_render->initPrimitives<PFP>(myMap, Algo::Render::GL2::LINES) ;
	m_render->initPrimitives<PFP>(myMap, Algo::Render::GL2::TRIANGLES) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
591

592
	m_topoRender->updateData<PFP>(myMap, position, 0.85f, 0.85f, m_drawBoundaryTopo, true) ;
593

594
595
	bb = Algo::Geometry::computeBoundingBox<PFP>(myMap, position) ;
	normalBaseSize = bb.diagSize() / 100.0f ;
596
	//	vertexBaseSize = normalBaseSize / 5.0f ;
Sylvain Thery's avatar
MAJ MC  
Sylvain Thery committed
597

598
	normal = myMap.getAttribute<VEC3, VERTEX, MAP>("normal") ;
Pierre Kraemer's avatar
Pierre Kraemer committed
599
	if(!normal.isValid())
600
		normal = myMap.addAttribute<VEC3, VERTEX, MAP>("normal") ;
Pierre Kraemer's avatar
Pierre Kraemer committed
601

Pierre Kraemer's avatar
Pierre Kraemer committed
602
603
	Utils::Chrono c;
	c.start();
604
	Algo::Surface::Geometry::computeNormalVertices<PFP>(myMap, position, normal) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
605
	std::cout << "compute normals -> " << c.elapsed() << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
606
607
608
609

	m_positionVBO->updateData(position) ;
	m_normalVBO->updateData(normal) ;

610
	setParamObject(bb.maxSize(), bb.center().data()) ;
611
612
613
614
615
616
617
618
619
620
621
622

	const Geom::Vec3f& Pc = bb.center();
	const Geom::Vec3f& Nc = bb.diag();
	Geom::Vec4f planeClip(Nc[0],Nc[1],Nc[2],-(Pc*Nc));

//	m_flatShader->setClippingPlane(planeClip);
//	m_phongShader->setClippingPlane(planeClip);
//	m_topoRender->setClippingPlane(planeClip);
//	m_simpleColorShader->setClippingPlane(planeClip);
//	m_pointSprite->setClippingPlane(planeClip);
//	m_vectorShader->setClippingPlane(planeClip);

Pierre Kraemer's avatar
Pierre Kraemer committed
623
	updateGLMatrices() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
624
625

	std::cout << "#vertices -> " << Algo::Topo::getNbOrbits<VERTEX>(myMap) << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
626
627
}

628
void Viewer::exportMesh(std::string& filename, bool askExportMode)
629
{
630
631
	size_t pos = filename.rfind(".") ;    // position of "." in filename
	std::string extension = filename.substr(pos) ;
632

633
	if (extension == std::string(".off"))
634
		Algo::Surface::Export::exportOFF<PFP>(myMap, position, filename.c_str()) ;
635
	else if (extension.compare(0, 4, std::string(".ply")) == 0)
636
	{
637
		int ascii = 0 ;
638
639
640
		if (askExportMode)
			Utils::QT::inputValues(Utils::QT::VarCombo("binary mode;ascii mode",ascii,"Save in")) ;

641
		std::vector<VertexAttribute<VEC3, MAP>*> attributes ;
642
		attributes.push_back(&position) ;
643
		Algo::Surface::Export::exportPLYnew<PFP>(myMap, attributes, filename.c_str(), !ascii) ;
644
	}
645
646
	else if (extension == std::string(".map"))
		myMap.saveMapBin(filename) ;
647
648
	else
		std::cerr << "Cannot save file " << filename << " : unknown or unhandled extension" << std::endl ;
649
650
}

Pierre Kraemer's avatar
Pierre Kraemer committed
651
652
653
654
655
656
657
658
void Viewer::slot_drawVertices(bool b)
{
	m_drawVertices = b ;
	updateGL() ;
}

void Viewer::slot_verticesSize(int i)
{
Sylvain Thery's avatar
MAJ MC  
Sylvain Thery committed
659
	vertexScaleFactor = i / 500.0f ;
Pierre Kraemer's avatar
Pierre Kraemer committed
660
661
662
663
664
665
666
667
668
669
670
671
	updateGL() ;
}

void Viewer::slot_drawEdges(bool b)
{
	m_drawEdges = b ;
	updateGL() ;
}

void Viewer::slot_drawFaces(bool b)
{
	m_drawFaces = b ;
Sylvain Thery's avatar
Sylvain Thery committed
672
673
674
675
676
677
678
679
680
681
682
	if (b)
	{
		Geom::Vec4f c(0.0f, 0.0f, 0.0f, 1.0f) ;
		m_simpleColorShader->setColor(c) ;
	}
	else
	{
		Geom::Vec4f c(0.9f, 0.9f, 0.1f, 1.0f) ;
		m_simpleColorShader->setColor(c) ;
	}

Pierre Kraemer's avatar
Pierre Kraemer committed
683
684
685
686
687
688
689
690
691
	updateGL() ;
}

void Viewer::slot_faceLighting(int i)
{
	m_renderStyle = i ;
	updateGL() ;
}

692
693
694
695
696
697
void Viewer::slot_drawTopo(bool b)
{
	m_drawTopo = b ;
	updateGL() ;
}

Pierre Kraemer's avatar
Pierre Kraemer committed
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
void Viewer::slot_drawNormals(bool b)
{
	m_drawNormals = b ;
	updateGL() ;
}

void Viewer::slot_normalsSize(int i)
{
	normalScaleFactor = i / 50.0f ;
	updateGL() ;
}

/**********************************************************************************************
 *                                      MAIN FUNCTION                                         *
 **********************************************************************************************/

int main(int argc, char **argv)
{
	QApplication app(argc, argv) ;

	Viewer sqt ;
	sqt.setGeometry(0, 0, 1000, 800) ;
720
	sqt.show() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
721

722
	if(argc >= 2)
Pierre Kraemer's avatar
Pierre Kraemer committed
723
724
725
	{
		std::string filename(argv[1]) ;
		sqt.importMesh(filename) ;
726
727
728
729
		if(argc >= 3)
		{
			std::string filenameExp(argv[2]) ;
			std::cout << "Exporting " << filename << " as " << filenameExp << " ... "<< std::flush ;
730
			sqt.exportMesh(filenameExp, false) ;
731
732
733
734
			std::cout << "done!" << std::endl ;

			return (0) ;
		}
Pierre Kraemer's avatar
Pierre Kraemer committed
735
736
737
738
739
740
	}

	sqt.initGUI() ;

	return app.exec() ;
}