viewer.cpp 19.7 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
48
49
50
51
52
53
54
55
	faceShrinkage = 1.0f ;

	colClear = Geom::Vec4f(0.2f, 0.2f, 0.2f, 0.1f) ;
	colDif = Geom::Vec4f(0.8f, 0.9f, 0.7f, 1.0f) ;
	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
95
96
97
98
99
100
101
102

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

	m_phongShader = new Utils::ShaderPhong() ;
	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) ;

103
	m_flatShader = new Utils::ShaderSimpleFlat() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
104
105
106
	m_flatShader->setAttributePosition(m_positionVBO) ;
	m_flatShader->setAmbiant(colClear) ;
	m_flatShader->setDiffuse(colDif) ;
107
108
//	m_flatShader->setDiffuseBack(Geom::Vec4f(0,0,0,0)) ;
//	m_flatShader->setExplode(faceShrinkage) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
109
110
111
112
113
114
115
116

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

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

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

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

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

	if(m_drawEdges)
	{
142
		glDepthFunc(GL_LEQUAL);
Pierre Kraemer's avatar
Pierre Kraemer committed
143
144
145
146
147
148
149
150
151
152
		glLineWidth(1.0f) ;
		m_render->draw(m_simpleColorShader, Algo::Render::GL2::LINES) ;
	}

	if(m_drawFaces)
	{
		glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) ;
		glEnable(GL_LIGHTING) ;
		glEnable(GL_POLYGON_OFFSET_FILL) ;
		glPolygonOffset(1.0f, 1.0f) ;
153
		glDepthFunc(GL_LESS);
Pierre Kraemer's avatar
Pierre Kraemer committed
154
155
156
157
158
159
160
161
162
163
164
		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) ;
	}
165
166
167

	if(m_drawTopo)
	{
168
		glDepthFunc(GL_LEQUAL);
169
170
171
172
173
174
175
176
177
178
		m_topoRender->drawTopo() ;
	}

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

	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
187
188
189
190
191
192
}

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

	importMesh(filename) ;
	updateGL() ;
}

200
201
void Viewer::cb_Save()
{
202
	std::string filters("all (*.*);; map (*.map);; off (*.off);; ply (*.ply)") ;
203
	std::string filename = selectFileSave("Save Mesh", "", filters) ;
204

205
206
	if (!filename.empty())
		exportMesh(filename) ;
207
208
}

209
210
void Viewer::cb_keyPress(int keycode)
{
211
	switch(keycode)
Sylvain Thery's avatar
Sylvain Thery committed
212
	{
213
214
215
		case 'c' :
			myMap.check();
			break;
Sylvain Thery's avatar
Sylvain Thery committed
216

217
		case 'a':
Sylvain Thery's avatar
Sylvain Thery committed
218
		{
219
220
221
222
223
224
225
			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
226
			{
227
228
				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
229
				{
230
231
232
233
234
235
236
237
238
					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
239
				}
240
				myMap.swapAttributes(position, pos2);
Sylvain Thery's avatar
Sylvain Thery committed
241
			}
242
243
244
245
246
			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
247
		}
248
			break;
Sylvain Thery's avatar
Sylvain Thery committed
249

250
251
252
253
		case 'b':
		{
			Utils::Chrono ch;
			ch.start();
Sylvain Thery's avatar
Sylvain Thery committed
254

255
256
257
			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
258

259
			for (int i=0; i< 6; ++i)
Sylvain Thery's avatar
Sylvain Thery committed
260
			{
261
				foreach_cell<VERTEX>(myMap, [&] (Vertex d)
Sylvain Thery's avatar
Sylvain Thery committed
262
				{
263
264
265
266
267
268
269
270
					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
271
				});
272
273
274
275
276
277
278
				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
279
		}
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
			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
321

322
		case 'e':
Sylvain Thery's avatar
Sylvain Thery committed
323
		{
324
325
326
327
328
329
330
			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
331
			{
332
333
				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
334
				{
335
336
337
338
339
340
341
342
343
					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
344
				}
345
				myMap.swapAttributes(position,pos2);
Sylvain Thery's avatar
Sylvain Thery committed
346
			}
347
348
349
350
351
			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
352
		}
353
			break;
Sylvain Thery's avatar
Sylvain Thery committed
354

355
356
357
358
		case 'f':
		{
			Utils::Chrono ch;
			ch.start();
Sylvain Thery's avatar
Sylvain Thery committed
359

360
361
362
			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
363

364
			for (int i=0; i< 10; ++i)
Sylvain Thery's avatar
Sylvain Thery committed
365
			{
366
				foreach_cell<VERTEX>(myMap, [&] (Vertex d)
Sylvain Thery's avatar
Sylvain Thery committed
367
				{
368
369
370
371
372
373
374
375
					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
376
				});
377
378
379
380
381
382
383
				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
384
		}
385
			break;
Sylvain Thery's avatar
Sylvain Thery committed
386

387
		case'A':
388
		{
389
390
391
392
			myMap.disableQuickTraversal<VERTEX>() ;
#define NBLOOP 5
			Utils::Chrono ch;
			ch.start();
393
			{
394
395
				TraversorCell<MAP, VERTEX, FORCE_CELL_MARKING> trav(myMap,true);
				for(unsigned int i=0; i<NBLOOP; ++i)
396
				{
397
398
399
400
					for (Cell<VERTEX> v = trav.begin(), e = trav.end(); v.dart != e.dart; v = trav.next())
					{
						normal[v][0] = 0.0f;
					}
401
				}
402
				std::cout << "FORCE_CELL_MARKING "<< ch.elapsed()<< " ms "<< std::endl;
403
			}
Sylvain Thery's avatar
Sylvain Thery committed
404

405
			ch.start();
Sylvain Thery's avatar
Sylvain Thery committed
406
			{
407
408
				TraversorCell<MAP, VERTEX> trav(myMap);
				for(unsigned int i=0; i<NBLOOP; ++i)
409
				{
410
411
412
413
					for (Cell<VERTEX> v = trav.begin(), e = trav.end(); v.dart != e.dart; v = trav.next())
					{
						normal[v][0] = 0.0f;
					}
414
				}
415
				std::cout << "auto "<< ch.elapsed()<< " ms "<< std::endl;
Sylvain Thery's avatar
Sylvain Thery committed
416
			}
417

418
			ch.start();
419
			{
420
421
				TraversorCell<MAP, VERTEX> trav(myMap,true);
				for(unsigned int i=0; i<NBLOOP; ++i)
422
				{
423
424
425
426
					for (Cell<VERTEX> v = trav.begin(), e = trav.end(); v.dart != e.dart; v = trav.next())
					{
						normal[v][0] = 0.0f;
					}
427
				}
428
				std::cout << "auto forcedart "<< ch.elapsed()<< " ms "<< std::endl;
429
430
			}

431
			ch.start();
432
			{
433
434
				TraversorCell<MAP, VERTEX, FORCE_DART_MARKING> trav(myMap,true);
				for(unsigned int i=0; i<NBLOOP; ++i)
435
				{
436
437
438
439
					for (Cell<VERTEX> v = trav.begin(), e = trav.end(); v.dart != e.dart; v = trav.next())
					{
						normal[v][0] = 0.0f;
					}
440
				}
441
				std::cout << "FORCE_DART_MARKING "<< ch.elapsed()<< " ms "<< std::endl;
442
			}
443
444
			myMap.enableQuickTraversal<MAP, VERTEX>() ;
			ch.start();
445
			{
446
447
				TraversorCell<MAP, VERTEX> trav(myMap);
				for(unsigned int i=0; i<NBLOOP; ++i)
448
				{
449
450
451
452
					for (Cell<VERTEX> v = trav.begin(), e = trav.end(); v.dart != e.dart; v = trav.next())
					{
						normal[v][0] = 0.0f;
					}
453
				}
454
				std::cout << "auto (quick) "<< ch.elapsed()<< " ms "<< std::endl;
455
456
			}

457
			ch.start();
458
			{
459
460
				TraversorCell<MAP, VERTEX, FORCE_QUICK_TRAVERSAL> trav(myMap);
				for(unsigned int i=0; i<NBLOOP; ++i)
461
				{
462
463
464
465
					for (Cell<VERTEX> v = trav.begin(), e = trav.end(); v.dart != e.dart; v = trav.next())
					{
						normal[v][0] = 0.0f;
					}
466
				}
467
				std::cout << "FORCE_QUICK_TRAVERSAL "<< ch.elapsed()<< " ms "<< std::endl;
468
469
			}

470
471
		}
			break;
Sylvain Thery's avatar
Sylvain Thery committed
472

473
474
		case'Z':
		{
Sylvain Thery's avatar
Sylvain Thery committed
475

476
477
478
479
480
481
			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
482

483
			ch.start();
Sylvain Thery's avatar
Sylvain Thery committed
484
			CGoGN::Parallel::NumberOfThreads = 2;
485
486
			for (unsigned int i=0; i<4; ++i)
				Algo::Surface::Geometry::Parallel::computeNormalVertices<PFP>(myMap, position, normal) ;
Sylvain Thery's avatar
Sylvain Thery committed
487
			std::cout << "Algo::Surface::Geometry::Parallel::computeNormalVertices2 "<< ch.elapsed()<< " ms "<< std::endl;
Sylvain Thery's avatar
Sylvain Thery committed
488

Sylvain Thery's avatar
Sylvain Thery committed
489
			ch.start();
Sylvain Thery's avatar
Sylvain Thery committed
490
			CGoGN::Parallel::NumberOfThreads = 3;
491
492
			for (unsigned int i=0; i<4; ++i)
				Algo::Surface::Geometry::Parallel::computeNormalVertices<PFP>(myMap, position, normal) ;
Sylvain Thery's avatar
Sylvain Thery committed
493
			std::cout << "Algo::Surface::Geometry::Parallel::computeNormalVertices3 "<< ch.elapsed()<< " ms "<< std::endl;
Sylvain Thery's avatar
Sylvain Thery committed
494

495
			ch.start();
Sylvain Thery's avatar
Sylvain Thery committed
496
497
498
499
			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
500

Sylvain Thery's avatar
Sylvain Thery committed
501
502
			ch.start();
			CGoGN::Parallel::NumberOfThreads = 8;
503
			for (unsigned int i=0; i<4; ++i)
Sylvain Thery's avatar
Sylvain Thery committed
504
505
				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
506
507


508
509
510
511
512
513
514
515
516
			//		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
517

518
			//		std::cout << "Parallel::foreach_cell_EO "<< ch.elapsed()<< " ms "<< std::endl;
Sylvain Thery's avatar
Sylvain Thery committed
519
520


521
522
		}
			break;
Sylvain Thery's avatar
Sylvain Thery committed
523
524


525
526
527
		default:
			break;
	}
528
529
}

Pierre Kraemer's avatar
Pierre Kraemer committed
530
531
void Viewer::importMesh(std::string& filename)
{
532
533
	myMap.clear(true) ;

534
535
536
537
538
539
	size_t pos = filename.rfind(".");    // position of "." in filename
	std::string extension = filename.substr(pos);

	if (extension == std::string(".map"))
	{
		myMap.loadMapBin(filename);
540
		position = myMap.getAttribute<VEC3, VERTEX, MAP>("position") ;
541
542
	}
	else
Pierre Kraemer's avatar
Pierre Kraemer committed
543
	{
544
		std::vector<std::string> attrNames ;
545
		if(!Algo::Surface::Import::importMesh<PFP>(myMap, filename.c_str(), attrNames))
546
547
548
549
		{
			CGoGNerr << "could not import " << filename << CGoGNendl ;
			return;
		}
550
		position = myMap.getAttribute<PFP::VEC3, VERTEX, MAP>(attrNames[0]) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
551
	}
552

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

555
556
557

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

558
559
560
	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
561

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

564
565
	bb = Algo::Geometry::computeBoundingBox<PFP>(myMap, position) ;
	normalBaseSize = bb.diagSize() / 100.0f ;
566
	//	vertexBaseSize = normalBaseSize / 5.0f ;
Sylvain Thery's avatar
MAJ MC    
Sylvain Thery committed
567

568
	normal = myMap.getAttribute<VEC3, VERTEX, MAP>("normal") ;
Pierre Kraemer's avatar
Pierre Kraemer committed
569
	if(!normal.isValid())
570
		normal = myMap.addAttribute<VEC3, VERTEX, MAP>("normal") ;
Pierre Kraemer's avatar
Pierre Kraemer committed
571

Pierre Kraemer's avatar
Pierre Kraemer committed
572
573
	Utils::Chrono c;
	c.start();
574
	Algo::Surface::Geometry::computeNormalVertices<PFP>(myMap, position, normal) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
575
	std::cout << "compute normals -> " << c.elapsed() << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
576
577
578
579

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

580
	setParamObject(bb.maxSize(), bb.center().data()) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
581
	updateGLMatrices() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
582
583

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

586
void Viewer::exportMesh(std::string& filename, bool askExportMode)
587
{
588
589
	size_t pos = filename.rfind(".") ;    // position of "." in filename
	std::string extension = filename.substr(pos) ;
590

591
	if (extension == std::string(".off"))
592
		Algo::Surface::Export::exportOFF<PFP>(myMap, position, filename.c_str()) ;
593
	else if (extension.compare(0, 4, std::string(".ply")) == 0)
594
	{
595
		int ascii = 0 ;
596
597
598
		if (askExportMode)
			Utils::QT::inputValues(Utils::QT::VarCombo("binary mode;ascii mode",ascii,"Save in")) ;

599
		std::vector<VertexAttribute<VEC3, MAP>*> attributes ;
600
		attributes.push_back(&position) ;
601
		Algo::Surface::Export::exportPLYnew<PFP>(myMap, attributes, filename.c_str(), !ascii) ;
602
	}
603
604
	else if (extension == std::string(".map"))
		myMap.saveMapBin(filename) ;
605
606
	else
		std::cerr << "Cannot save file " << filename << " : unknown or unhandled extension" << std::endl ;
607
608
}

Pierre Kraemer's avatar
Pierre Kraemer committed
609
610
611
612
613
614
615
616
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
617
	vertexScaleFactor = i / 500.0f ;
Pierre Kraemer's avatar
Pierre Kraemer committed
618
619
620
621
622
623
624
625
626
627
628
629
	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
630
631
632
633
634
635
636
637
638
639
640
	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
641
642
643
644
645
646
647
648
649
	updateGL() ;
}

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

650
651
652
653
654
655
void Viewer::slot_drawTopo(bool b)
{
	m_drawTopo = b ;
	updateGL() ;
}

Pierre Kraemer's avatar
Pierre Kraemer committed
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
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) ;
678
	sqt.show() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
679

680
	if(argc >= 2)
Pierre Kraemer's avatar
Pierre Kraemer committed
681
682
683
	{
		std::string filename(argv[1]) ;
		sqt.importMesh(filename) ;
684
685
686
687
		if(argc >= 3)
		{
			std::string filenameExp(argv[2]) ;
			std::cout << "Exporting " << filename << " as " << filenameExp << " ... "<< std::flush ;
688
			sqt.exportMesh(filenameExp, false) ;
689
690
691
692
			std::cout << "done!" << std::endl ;

			return (0) ;
		}
Pierre Kraemer's avatar
Pierre Kraemer committed
693
694
695
696
697
698
	}

	sqt.initGUI() ;

	return app.exec() ;
}