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

Sylvain Thery's avatar
Sylvain Thery committed
467 468 469 470 471
//			ch.start();
//			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
472

Sylvain Thery's avatar
Sylvain Thery committed
473 474 475 476 477
//			ch.start();
//			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
478

479 480 481 482 483
			ch.start();
			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 487 488 489
//			ch.start();
//			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
490

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

Sylvain Thery's avatar
Sylvain Thery committed
497

498
			ch.start();
Sylvain Thery's avatar
Sylvain Thery committed
499

500 501 502 503
			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);
Sylvain Thery's avatar
Sylvain Thery committed
504
				}, FORCE_CELL_MARKING);
Sylvain Thery's avatar
Sylvain Thery committed
505

506
			std::cout << "Parallel::foreach_cell "<< ch.elapsed()<< " ms "<< std::endl;
Sylvain Thery's avatar
Sylvain Thery committed
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
	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
558

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

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

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

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

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

577
	setParamObject(bb.maxSize(), bb.center().data()) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
578
	updateGLMatrices() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
579 580

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

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

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

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

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

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

647 648 649 650 651 652
void Viewer::slot_drawTopo(bool b)
{
	m_drawTopo = b ;
	updateGL() ;
}

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

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

			return (0) ;
		}
Pierre Kraemer's avatar
Pierre Kraemer committed
690 691 692 693 694 695
	}

	sqt.initGUI() ;

	return app.exec() ;
}