viewer.cpp 19.3 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
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

#include "viewer.h"
Pierre Kraemer's avatar
Pierre Kraemer committed
26
#include "Utils/chrono.h"
Pierre Kraemer's avatar
Pierre Kraemer committed
27 28 29 30 31 32 33

Viewer::Viewer() :
	m_renderStyle(FLAT),
	m_drawVertices(false),
	m_drawEdges(false),
	m_drawFaces(true),
	m_drawNormals(false),
34
	m_drawTopo(false),
untereiner's avatar
untereiner committed
35
	m_drawBoundaryTopo(true),
Pierre Kraemer's avatar
Pierre Kraemer committed
36 37 38 39 40 41 42 43
	m_render(NULL),
	m_phongShader(NULL),
	m_flatShader(NULL),
	m_vectorShader(NULL),
	m_simpleColorShader(NULL),
	m_pointSprite(NULL)
{
	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()
{
Sylvain Thery's avatar
Sylvain Thery committed
81 82 83
	Utils::GLSLShader::setCurrentOGLVersion(3) ;
	CGoGNout << "GL VERSION = "<< glGetString(GL_VERSION)<< CGoGNendl;
	Utils::GLSLShader::areShadersSupported();
Pierre Kraemer's avatar
Pierre Kraemer committed
84 85

	m_render = new Algo::Render::GL2::MapRender() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
86
	m_topoRender = new Algo::Render::GL2::TopoRenderMap<PFP>() ;
87 88

	m_topoRender->setInitialDartsColor(0.25f, 0.25f, 0.25f) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113

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

	m_flatShader = new Utils::ShaderFlat() ;
	m_flatShader->setAttributePosition(m_positionVBO) ;
	m_flatShader->setAmbiant(colClear) ;
	m_flatShader->setDiffuse(colDif) ;
	m_flatShader->setExplode(faceShrinkage) ;

	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
114
	Geom::Vec4f c(0.0f, 0.0f, 0.0f, 1.0f) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
115 116 117
	m_simpleColorShader->setColor(c) ;

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

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

void Viewer::cb_redraw()
{
	if(m_drawVertices)
	{
132
		m_pointSprite->setSize(vertexScaleFactor) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
		m_render->draw(m_pointSprite, Algo::Render::GL2::POINTS) ;
	}

	if(m_drawEdges)
	{
		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) ;
		switch(m_renderStyle)
		{
			case FLAT :
				m_flatShader->setExplode(faceShrinkage) ;
				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) ;
	}
160 161 162 163 164 165 166 167 168 169 170 171 172

	if(m_drawTopo)
	{
		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) ;
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
173 174 175 176 177 178
}

void Viewer::cb_Open()
{
	std::string filters("all (*.*);; trian (*.trian);; ctm (*.ctm);; off (*.off);; ply (*.ply)") ;
	std::string filename = selectFile("Open Mesh", "", filters) ;
179 180
	if (filename.empty())
		return ;
Pierre Kraemer's avatar
Pierre Kraemer committed
181 182 183 184 185

	importMesh(filename) ;
	updateGL() ;
}

186 187
void Viewer::cb_Save()
{
188
	std::string filters("all (*.*);; map (*.map);; off (*.off);; ply (*.ply)") ;
189
	std::string filename = selectFileSave("Save Mesh", "", filters) ;
190

191 192
	if (!filename.empty())
		exportMesh(filename) ;
193 194
}

195 196
void Viewer::cb_keyPress(int keycode)
{
197
	switch(keycode)
Sylvain Thery's avatar
Sylvain Thery committed
198
	{
199 200 201
		case 'c' :
			myMap.check();
			break;
Sylvain Thery's avatar
Sylvain Thery committed
202

203
		case 'a':
Sylvain Thery's avatar
Sylvain Thery committed
204
		{
205 206 207 208 209 210 211
			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
212
			{
213 214
				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
215
				{
216 217 218 219 220 221 222 223 224
					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
225
				}
226
				myMap.swapAttributes(position, pos2);
Sylvain Thery's avatar
Sylvain Thery committed
227
			}
228 229 230 231 232
			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
233
		}
234
			break;
Sylvain Thery's avatar
Sylvain Thery committed
235

236 237 238 239
		case 'b':
		{
			Utils::Chrono ch;
			ch.start();
Sylvain Thery's avatar
Sylvain Thery committed
240

241 242 243
			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
244

245
			for (int i=0; i< 6; ++i)
Sylvain Thery's avatar
Sylvain Thery committed
246
			{
247
				foreach_cell<VERTEX>(myMap, [&] (Vertex d)
Sylvain Thery's avatar
Sylvain Thery committed
248
				{
249 250 251 252 253 254 255 256
					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
257
				});
258 259 260 261 262 263 264
				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
265
		}
266 267 268 269 270 271 272 273 274 275 276 277 278 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
			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
307

308
		case 'e':
Sylvain Thery's avatar
Sylvain Thery committed
309
		{
310 311 312 313 314 315 316
			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
317
			{
318 319
				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
320
				{
321 322 323 324 325 326 327 328 329
					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
330
				}
331
				myMap.swapAttributes(position,pos2);
Sylvain Thery's avatar
Sylvain Thery committed
332
			}
333 334 335 336 337
			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
338
		}
339
			break;
Sylvain Thery's avatar
Sylvain Thery committed
340

341 342 343 344
		case 'f':
		{
			Utils::Chrono ch;
			ch.start();
Sylvain Thery's avatar
Sylvain Thery committed
345

346 347 348
			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
349

350
			for (int i=0; i< 10; ++i)
Sylvain Thery's avatar
Sylvain Thery committed
351
			{
352
				foreach_cell<VERTEX>(myMap, [&] (Vertex d)
Sylvain Thery's avatar
Sylvain Thery committed
353
				{
354 355 356 357 358 359 360 361
					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
362
				});
363 364 365 366 367 368 369
				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
370
		}
371
			break;
Sylvain Thery's avatar
Sylvain Thery committed
372

373
		case'A':
374
		{
375 376 377 378
			myMap.disableQuickTraversal<VERTEX>() ;
#define NBLOOP 5
			Utils::Chrono ch;
			ch.start();
379
			{
380 381
				TraversorCell<MAP, VERTEX, FORCE_CELL_MARKING> trav(myMap,true);
				for(unsigned int i=0; i<NBLOOP; ++i)
382
				{
383 384 385 386
					for (Cell<VERTEX> v = trav.begin(), e = trav.end(); v.dart != e.dart; v = trav.next())
					{
						normal[v][0] = 0.0f;
					}
387
				}
388
				std::cout << "FORCE_CELL_MARKING "<< ch.elapsed()<< " ms "<< std::endl;
389
			}
Sylvain Thery's avatar
Sylvain Thery committed
390

391
			ch.start();
Sylvain Thery's avatar
Sylvain Thery committed
392
			{
393 394
				TraversorCell<MAP, VERTEX> trav(myMap);
				for(unsigned int i=0; i<NBLOOP; ++i)
395
				{
396 397 398 399
					for (Cell<VERTEX> v = trav.begin(), e = trav.end(); v.dart != e.dart; v = trav.next())
					{
						normal[v][0] = 0.0f;
					}
400
				}
401
				std::cout << "auto "<< ch.elapsed()<< " ms "<< std::endl;
Sylvain Thery's avatar
Sylvain Thery committed
402
			}
403

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

417
			ch.start();
418
			{
419 420
				TraversorCell<MAP, VERTEX, FORCE_DART_MARKING> trav(myMap,true);
				for(unsigned int i=0; i<NBLOOP; ++i)
421
				{
422 423 424 425
					for (Cell<VERTEX> v = trav.begin(), e = trav.end(); v.dart != e.dart; v = trav.next())
					{
						normal[v][0] = 0.0f;
					}
426
				}
427
				std::cout << "FORCE_DART_MARKING "<< ch.elapsed()<< " ms "<< std::endl;
428
			}
429 430
			myMap.enableQuickTraversal<MAP, VERTEX>() ;
			ch.start();
431
			{
432 433
				TraversorCell<MAP, VERTEX> trav(myMap);
				for(unsigned int i=0; i<NBLOOP; ++i)
434
				{
435 436 437 438
					for (Cell<VERTEX> v = trav.begin(), e = trav.end(); v.dart != e.dart; v = trav.next())
					{
						normal[v][0] = 0.0f;
					}
439
				}
440
				std::cout << "auto (quick) "<< ch.elapsed()<< " ms "<< std::endl;
441 442
			}

443
			ch.start();
444
			{
445 446
				TraversorCell<MAP, VERTEX, FORCE_QUICK_TRAVERSAL> trav(myMap);
				for(unsigned int i=0; i<NBLOOP; ++i)
447
				{
448 449 450 451
					for (Cell<VERTEX> v = trav.begin(), e = trav.end(); v.dart != e.dart; v = trav.next())
					{
						normal[v][0] = 0.0f;
					}
452
				}
453
				std::cout << "FORCE_QUICK_TRAVERSAL "<< ch.elapsed()<< " ms "<< std::endl;
454 455
			}

456 457
		}
			break;
Sylvain Thery's avatar
Sylvain Thery committed
458

459 460
		case'Z':
		{
Sylvain Thery's avatar
Sylvain Thery committed
461

462 463 464 465 466 467
			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
468

469
			ch.start();
Sylvain Thery's avatar
Sylvain Thery committed
470
			CGoGN::Parallel::NumberOfThreads = 2;
471 472
			for (unsigned int i=0; i<4; ++i)
				Algo::Surface::Geometry::Parallel::computeNormalVertices<PFP>(myMap, position, normal) ;
Sylvain Thery's avatar
Sylvain Thery committed
473
			std::cout << "Algo::Surface::Geometry::Parallel::computeNormalVertices2 "<< ch.elapsed()<< " ms "<< std::endl;
Sylvain Thery's avatar
Sylvain Thery committed
474

Sylvain Thery's avatar
Sylvain Thery committed
475
			ch.start();
Sylvain Thery's avatar
Sylvain Thery committed
476
			CGoGN::Parallel::NumberOfThreads = 3;
477 478
			for (unsigned int i=0; i<4; ++i)
				Algo::Surface::Geometry::Parallel::computeNormalVertices<PFP>(myMap, position, normal) ;
Sylvain Thery's avatar
Sylvain Thery committed
479
			std::cout << "Algo::Surface::Geometry::Parallel::computeNormalVertices3 "<< ch.elapsed()<< " ms "<< std::endl;
Sylvain Thery's avatar
Sylvain Thery committed
480

481
			ch.start();
Sylvain Thery's avatar
Sylvain Thery committed
482 483 484 485
			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
486

Sylvain Thery's avatar
Sylvain Thery committed
487 488
			ch.start();
			CGoGN::Parallel::NumberOfThreads = 8;
489
			for (unsigned int i=0; i<4; ++i)
Sylvain Thery's avatar
Sylvain Thery committed
490 491
				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
492 493


494 495 496 497 498 499 500 501 502
			//		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
503

504
			//		std::cout << "Parallel::foreach_cell_EO "<< ch.elapsed()<< " ms "<< std::endl;
Sylvain Thery's avatar
Sylvain Thery committed
505 506


507 508
		}
			break;
Sylvain Thery's avatar
Sylvain Thery committed
509 510


511 512 513
		default:
			break;
	}
514 515
}

Pierre Kraemer's avatar
Pierre Kraemer committed
516 517
void Viewer::importMesh(std::string& filename)
{
518 519
	myMap.clear(true) ;

520 521 522 523 524 525
	size_t pos = filename.rfind(".");    // position of "." in filename
	std::string extension = filename.substr(pos);

	if (extension == std::string(".map"))
	{
		myMap.loadMapBin(filename);
526
		position = myMap.getAttribute<VEC3, VERTEX, MAP>("position") ;
527 528
	}
	else
Pierre Kraemer's avatar
Pierre Kraemer committed
529
	{
530
		std::vector<std::string> attrNames ;
531
		if(!Algo::Surface::Import::importMesh<PFP>(myMap, filename.c_str(), attrNames))
532 533 534 535
		{
			CGoGNerr << "could not import " << filename << CGoGNendl ;
			return;
		}
536
		position = myMap.getAttribute<PFP::VEC3, VERTEX, MAP>(attrNames[0]) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
537
	}
538

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

541 542 543
	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
544

Pierre Kraemer's avatar
Pierre Kraemer committed
545
	m_topoRender->updateData(myMap, position, 0.85f, 0.85f, m_drawBoundaryTopo) ;
546

547 548
	bb = Algo::Geometry::computeBoundingBox<PFP>(myMap, position) ;
	normalBaseSize = bb.diagSize() / 100.0f ;
549
	//	vertexBaseSize = normalBaseSize / 5.0f ;
Sylvain Thery's avatar
MAJ MC  
Sylvain Thery committed
550

551
	normal = myMap.getAttribute<VEC3, VERTEX, MAP>("normal") ;
Pierre Kraemer's avatar
Pierre Kraemer committed
552
	if(!normal.isValid())
553
		normal = myMap.addAttribute<VEC3, VERTEX, MAP>("normal") ;
Pierre Kraemer's avatar
Pierre Kraemer committed
554

Pierre Kraemer's avatar
Pierre Kraemer committed
555 556
	Utils::Chrono c;
	c.start();
557
	Algo::Surface::Geometry::computeNormalVertices<PFP>(myMap, position, normal) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
558
	std::cout << "compute normals -> " << c.elapsed() << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
559 560 561 562

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

563
	setParamObject(bb.maxSize(), bb.center().data()) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
564
	updateGLMatrices() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
565 566

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

569
void Viewer::exportMesh(std::string& filename, bool askExportMode)
570
{
571 572
	size_t pos = filename.rfind(".") ;    // position of "." in filename
	std::string extension = filename.substr(pos) ;
573

574
	if (extension == std::string(".off"))
575
		Algo::Surface::Export::exportOFF<PFP>(myMap, position, filename.c_str()) ;
576
	else if (extension.compare(0, 4, std::string(".ply")) == 0)
577
	{
578
		int ascii = 0 ;
579 580 581
		if (askExportMode)
			Utils::QT::inputValues(Utils::QT::VarCombo("binary mode;ascii mode",ascii,"Save in")) ;

582
		std::vector<VertexAttribute<VEC3, MAP>*> attributes ;
583
		attributes.push_back(&position) ;
584
		Algo::Surface::Export::exportPLYnew<PFP>(myMap, attributes, filename.c_str(), !ascii) ;
585
	}
586 587
	else if (extension == std::string(".map"))
		myMap.saveMapBin(filename) ;
588 589
	else
		std::cerr << "Cannot save file " << filename << " : unknown or unhandled extension" << std::endl ;
590 591
}

Pierre Kraemer's avatar
Pierre Kraemer committed
592 593 594 595 596 597 598 599
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
600
	vertexScaleFactor = i / 500.0f ;
Pierre Kraemer's avatar
Pierre Kraemer committed
601 602 603 604 605 606 607 608 609 610 611 612
	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
613 614 615 616 617 618 619 620 621 622 623
	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
624 625 626 627 628 629 630 631 632
	updateGL() ;
}

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

633 634 635 636 637 638
void Viewer::slot_drawTopo(bool b)
{
	m_drawTopo = b ;
	updateGL() ;
}

Pierre Kraemer's avatar
Pierre Kraemer committed
639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660
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) ;
661
	sqt.show() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
662

663
	if(argc >= 2)
Pierre Kraemer's avatar
Pierre Kraemer committed
664 665 666
	{
		std::string filename(argv[1]) ;
		sqt.importMesh(filename) ;
667 668 669 670
		if(argc >= 3)
		{
			std::string filenameExp(argv[2]) ;
			std::cout << "Exporting " << filename << " as " << filenameExp << " ... "<< std::flush ;
671
			sqt.exportMesh(filenameExp, false) ;
672 673 674 675
			std::cout << "done!" << std::endl ;

			return (0) ;
		}
Pierre Kraemer's avatar
Pierre Kraemer committed
676 677 678 679 680 681
	}

	sqt.initGUI() ;

	return app.exec() ;
}