viewer.cpp 19.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
* 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 81 82 83
	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()
{
	Utils::GLSLShader::setCurrentOGLVersion(2) ;

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

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

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

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

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

void Viewer::cb_redraw()
{
	if(m_drawVertices)
	{
130
		m_pointSprite->setSize(vertexScaleFactor) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
131 132 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
		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) ;
	}
158 159 160 161 162 163 164 165 166 167 168 169 170

	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
171 172 173 174 175 176
}

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

	importMesh(filename) ;
	updateGL() ;
}

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

189 190
	if (!filename.empty())
		exportMesh(filename) ;
191 192
}

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

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

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

239 240 241
			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
242

243
			for (int i=0; i< 6; ++i)
Sylvain Thery's avatar
Sylvain Thery committed
244
			{
245
				foreach_cell<VERTEX>(myMap, [&] (Vertex d)
Sylvain Thery's avatar
Sylvain Thery committed
246
				{
247 248 249 250 251 252 253 254
					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
255
				});
256 257 258 259 260 261 262
				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
263
		}
264 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
			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
305

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

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

344 345 346
			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
347

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

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

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

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

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

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

454 455
		}
			break;
Sylvain Thery's avatar
Sylvain Thery committed
456

457 458
		case'Z':
		{
Sylvain Thery's avatar
Sylvain Thery committed
459

460 461
			Utils::Chrono ch;
			ch.start();
Sylvain Thery's avatar
Sylvain Thery committed
462

463 464 465
			for (unsigned int i=0; i<4; ++i)
				Algo::Surface::Geometry::computeNormalVertices<PFP>(myMap, position, normal) ;
			std::cout << "Algo::Surface::Geometry::Parallel::computeNormalVertices "<< ch.elapsed()<< " ms "<< std::endl;
Sylvain Thery's avatar
Sylvain Thery committed
466

467
			ch.start();
Sylvain Thery's avatar
Sylvain Thery committed
468

469 470 471 472
			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
473

474
			ch.start();
Sylvain Thery's avatar
Sylvain Thery committed
475

476 477 478 479
			CGoGN::Parallel::NumberOfThreads = 2;
			for (unsigned int i=0; i<4; ++i)
				Algo::Surface::Geometry::Parallel::computeNormalVertices<PFP>(myMap, position, normal) ;
			std::cout << "Algo::Surface::Geometry::Parallel::computeNormalVertices2 "<< 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 486
			CGoGN::Parallel::NumberOfThreads = 3;
			for (unsigned int i=0; i<4; ++i)
				Algo::Surface::Geometry::Parallel::computeNormalVertices<PFP>(myMap, position, normal) ;
			std::cout << "Algo::Surface::Geometry::Parallel::computeNormalVertices3 "<< ch.elapsed()<< " ms "<< std::endl;
Sylvain Thery's avatar
Sylvain Thery committed
487

488
			ch.start();
Sylvain Thery's avatar
Sylvain Thery committed
489

490 491 492 493
			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
494

495
			ch.start();
Sylvain Thery's avatar
Sylvain Thery committed
496

497 498 499 500
			CGoGN::Parallel::NumberOfThreads = 8;
			for (unsigned int i=0; i<4; ++i)
				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
501

502
			ch.start();
Sylvain Thery's avatar
Sylvain Thery committed
503

504 505 506 507 508
			for (unsigned int i=0; i<4; ++i)
				Parallel::foreach_cell<VERTEX>(myMap, [&] (Vertex v, unsigned int th)
				{
					normal[v] = Algo::Surface::Geometry::vertexNormal<PFP>(myMap,v,position);
				}, false, FORCE_CELL_MARKING);
Sylvain Thery's avatar
Sylvain Thery committed
509

510
			std::cout << "Parallel::foreach_cell "<< ch.elapsed()<< " ms "<< std::endl;
Sylvain Thery's avatar
Sylvain Thery committed
511

512 513 514 515 516 517 518 519 520
			//		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
521

522
			//		std::cout << "Parallel::foreach_cell_EO "<< ch.elapsed()<< " ms "<< std::endl;
Sylvain Thery's avatar
Sylvain Thery committed
523 524


525 526
		}
			break;
Sylvain Thery's avatar
Sylvain Thery committed
527 528


529 530 531
		default:
			break;
	}
532 533
}

Pierre Kraemer's avatar
Pierre Kraemer committed
534 535
void Viewer::importMesh(std::string& filename)
{
536 537
	myMap.clear(true) ;

538 539 540 541 542 543
	size_t pos = filename.rfind(".");    // position of "." in filename
	std::string extension = filename.substr(pos);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	sqt.initGUI() ;

	return app.exec() ;
}