viewer.cpp 19.2 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 462 463 464 465
			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
466

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

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

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

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


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

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


505 506
		}
			break;
Sylvain Thery's avatar
Sylvain Thery committed
507 508


509 510 511
		default:
			break;
	}
512 513
}

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

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

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

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

539 540 541
	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
542

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	sqt.initGUI() ;

	return app.exec() ;
}