tuto_mt.cpp 12.7 KB
Newer Older
Sylvain Thery's avatar
Sylvain Thery committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
/*******************************************************************************
* 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.           *
*                                                                              *
* Web site: https://iggservis.u-strasbg.fr/CGoGN/                              *
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

#include <iostream>

27
#include "tuto_mt.h"
Sylvain Thery's avatar
Sylvain Thery committed
28 29 30 31 32 33 34 35 36

#include "Topology/generic/parameters.h"
#include "Topology/map/map2.h"
#include "Topology/generic/embeddedMap2.h"

#include "Geometry/vector_gen.h"

#include "Algo/Import/import.h"
#include "Algo/Geometry/boundingbox.h"
37 38
#include "Algo/Render/GL1/map_glRender.h"
#include "Utils/GLSLShader.h"
Sylvain Thery's avatar
Sylvain Thery committed
39 40
#include "Algo/Geometry/area.h"
#include "Algo/Geometry/normal.h"
41 42
#include "Algo/Modelisation/polyhedron.h"

Sylvain Thery's avatar
Sylvain Thery committed
43 44
#include "Algo/Parallel/parallel_foreach.h"

Sylvain Thery's avatar
Sylvain Thery committed
45

46
// for file input
Sylvain Thery's avatar
Sylvain Thery committed
47
 #include "Utils/qtInputs.h"
Sylvain Thery's avatar
Sylvain Thery committed
48 49 50 51

using namespace CGoGN ;


Sylvain Thery's avatar
Sylvain Thery committed
52 53


Sylvain Thery's avatar
Sylvain Thery committed
54 55 56 57 58 59 60 61 62 63
/**
 * Struct that contains some informations about the types of the manipulated objects
 * Mainly here to be used by the algorithms that are parameterized by it
 */
struct PFP: public PFP_STANDARD
{
	// definition of the map
	typedef EmbeddedMap2<Map2> MAP;
};

64 65 66 67 68 69 70 71 72 73 74 75

// declaration of the map
PFP::MAP myMap;
// this selector is going to select all the darts
SelectorTrue allDarts;

// attribute handlers
AttributeHandler<PFP::VEC3> position;
AttributeHandler<PFP::VEC3> normal;

// open file
void MyQT::cb_Open()
Sylvain Thery's avatar
Sylvain Thery committed
76
{
77 78
	// set some filters
	std::string filters("all (*.*);; trian (*.trian);; ctm (*.ctm);; off (*.off);; ply (*.ply)");
Sylvain Thery's avatar
Sylvain Thery committed
79

80
	std::string filename = selectFile("OpenMesh","",filters);
Sylvain Thery's avatar
Sylvain Thery committed
81

82 83 84 85 86 87
	std::vector<std::string> attrNames ;
	if(!Algo::Import::importMesh<PFP>(myMap, filename.c_str(), attrNames))
	{
		CGoGNerr << "could not import " << filename << CGoGNendl ;
		return;
	}
Sylvain Thery's avatar
Sylvain Thery committed
88

89 90 91 92 93
	// recuper l'attribut pour la position des points (créé lors de l'import)
	position = myMap.getAttribute<PFP::VEC3>(VERTEX_ORBIT, attrNames[0]) ;

	if (!normal.isValid())
		normal = myMap.addAttribute<PFP::VEC3>(VERTEX_ORBIT, "normal");
Sylvain Thery's avatar
Sylvain Thery committed
94

95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
	Algo::Geometry::computeNormalVertices<PFP>(myMap, position, normal) ;

    //  bounding box
    Geom::BoundingBox<PFP::VEC3> bb = Algo::Geometry::computeBoundingBox<PFP>(myMap, position);
    float lWidthObj = std::max<PFP::REAL>(std::max<PFP::REAL>(bb.size(0), bb.size(1)), bb.size(2));
    Geom::Vec3f lPosObj = (bb.min() +  bb.max()) / PFP::REAL(2);


    // envoit info BB a l'interface
	setParamObject(lWidthObj,lPosObj.data());
	updateGLMatrices();
}

// new
void MyQT::cb_New()
Sylvain Thery's avatar
Sylvain Thery committed
110
{
111 112
	if (!position.isValid())
		position = myMap.addAttribute<PFP::VEC3>(VERTEX_ORBIT, "position");
Sylvain Thery's avatar
Sylvain Thery committed
113

114 115 116 117
	// create a sphere
	Algo::Modelisation::Polyhedron<PFP> prim(myMap, position);
	prim.cylinder_topo(16,16, true, true); // topo of sphere is a closed cylinder
	prim.embedSphere(10.0f);
Sylvain Thery's avatar
Sylvain Thery committed
118

119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
	if (!normal.isValid())
		normal = myMap.addAttribute<PFP::VEC3>(VERTEX_ORBIT, "normal");

	Algo::Geometry::computeNormalVertices<PFP>(myMap, position, normal) ;


   //  bounding box
	Geom::BoundingBox<PFP::VEC3> bb = Algo::Geometry::computeBoundingBox<PFP>(myMap, position);
	float lWidthObj = std::max<PFP::REAL>(std::max<PFP::REAL>(bb.size(0), bb.size(1)), bb.size(2));
	Geom::Vec3f lPosObj = (bb.min() +  bb.max()) / PFP::REAL(2);

	setParamObject(lWidthObj,lPosObj.data());

	updateGLMatrices();
}

void MyQT::cb_initGL()
{
// Old school openGL ;)
	Utils::GLSLShader::setCurrentOGLVersion(1);

	glewInit();

	// init lighting parameters
	float lightPosition[4]= {0.0f,0.0f,10000.0f,1.0f};
	float lightColor[4]= {0.9f,0.9f,0.9f,1.0f};

	glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
	glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor);
	glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
	glEnable(GL_LIGHT0);
	glEnable(GL_COLOR_MATERIAL);
	glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
}
Sylvain Thery's avatar
Sylvain Thery committed
154

155 156 157 158


void MyQT::cb_redraw()
{
Sylvain Thery's avatar
Sylvain Thery committed
159
	// draw the lines
160 161 162 163 164 165
	glDisable(GL_LIGHTING);
	glColor3f(0.0f, 0.0f, 0.3f);
	glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
	glDisable(GL_LIGHTING);
	glEnable(GL_SMOOTH);
	Algo::Render::GL1::renderTriQuadPoly<PFP>(myMap,Algo::Render::GL1::LINE, 1.0f,position, normal);
Sylvain Thery's avatar
Sylvain Thery committed
166 167 168 169

	// draw the faces
	glEnable(GL_POLYGON_OFFSET_FILL);
	glPolygonOffset(1.0f, 1.0f);
170 171 172 173
	glColor3f(0.1f, 0.8f, 0.0f);
	glEnable(GL_LIGHTING);
	glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
	Algo::Render::GL1::renderTriQuadPoly<PFP>(myMap,Algo::Render::GL1::SMOOTH, 1.0f,position, normal);
Sylvain Thery's avatar
Sylvain Thery committed
174 175 176 177 178 179 180
	glDisable(GL_POLYGON_OFFSET_FILL);

}




181 182


183 184
template <typename XXX>
class ThreadArea: public Algo::Parallel::CGoGNThread<typename XXX::MAP>
Sylvain Thery's avatar
Sylvain Thery committed
185 186
{
protected:
187
	const typename XXX::TVEC3& m_positions;
Sylvain Thery's avatar
Sylvain Thery committed
188 189
	float area;
public:
190 191 192 193
	ThreadArea(typename XXX::MAP& map, const typename XXX::TVEC3& pos, unsigned int th):
		Algo::Parallel::CGoGNThread<typename XXX::MAP>(map,th),
		m_positions(pos),
		area(0.0f) {}
Sylvain Thery's avatar
Sylvain Thery committed
194 195 196

	void operator()()
	{
197 198 199 200
		// 3 times just for fun !!!
		area += Algo::Geometry::totalArea<XXX>(this->m_map, m_positions, SelectorTrue(), this->m_threadId);
		area += Algo::Geometry::totalArea<XXX>(this->m_map, m_positions, SelectorTrue(), this->m_threadId);
		area += Algo::Geometry::totalArea<XXX>(this->m_map, m_positions, SelectorTrue(), this->m_threadId);
Sylvain Thery's avatar
Sylvain Thery committed
201 202
	}

203
	float getTripleValue() { return area;}
Sylvain Thery's avatar
Sylvain Thery committed
204 205 206
};


207 208
template <typename XXX>
class ThreadNormals: public Algo::Parallel::CGoGNThread<typename XXX::MAP>
Sylvain Thery's avatar
Sylvain Thery committed
209 210
{
protected:
211 212
	const typename XXX::TVEC3& m_positions;
	typename XXX::TVEC3& m_normals;
Sylvain Thery's avatar
Sylvain Thery committed
213
public:
214 215 216 217
	ThreadNormals(typename XXX::MAP& map, const typename XXX::TVEC3& pos, typename XXX::TVEC3& norm, unsigned int th):
		Algo::Parallel::CGoGNThread<typename XXX::MAP>(map,th),
		m_positions(pos),
		m_normals(norm) {}
Sylvain Thery's avatar
Sylvain Thery committed
218 219 220

	void operator()()
	{
221
		Algo::Geometry::computeNormalVertices<XXX>(this->m_map, m_positions, m_normals, SelectorTrue(), this->m_threadId);
Sylvain Thery's avatar
Sylvain Thery committed
222 223
	}

224
};
Sylvain Thery's avatar
Sylvain Thery committed
225 226 227


//
228 229
//template<typename XXX>
//class Thread0
Sylvain Thery's avatar
Sylvain Thery committed
230 231
//{
//protected:
232 233 234 235
//	typename XXX::MAP& m_map;
//	MyGlutWin& m_mgw;
//	unsigned int m_th;
//	SelectorTrue m_selt;
Sylvain Thery's avatar
Sylvain Thery committed
236
//public:
237 238
//	Thread0(typename XXX::MAP& map,MyGlutWin& mgw, unsigned int th):
//		m_map(map), m_mgw(mgw), m_th(th) {}
Sylvain Thery's avatar
Sylvain Thery committed
239 240 241
//
//	void operator()()
//	{
242
//		CGoGNout << "Begin render init"<<CGoGNendl;
243
//		m_mgw.useContext();
Sylvain Thery's avatar
Sylvain Thery committed
244
//
245
//		// instanciation of the renderer (here using VBOs)
246
//		m_mgw.m_render = new Algo::Render::VBO::MapRender_VBO();
Sylvain Thery's avatar
Sylvain Thery committed
247
//
248
//	    // update the renderer (geometry and primitives)
249
//	    m_mgw.m_render->updateData(Algo::Render::VBO::POSITIONS, position);
Sylvain Thery's avatar
Sylvain Thery committed
250
//
251 252
//	    m_mgw.m_render->initPrimitives<PFP>(m_map, m_selt, Algo::Render::VBO::TRIANGLES,m_th);
//	    m_mgw.m_render->initPrimitives<PFP>(m_map, m_selt, Algo::Render::VBO::LINES,m_th);
Sylvain Thery's avatar
Sylvain Thery committed
253
//
254
//	    m_mgw.releaseContext();
255
//	    CGoGNout<< "Render OK "<< CGoGNendl;
Sylvain Thery's avatar
Sylvain Thery committed
256 257 258 259 260 261
//
//	}
//};



262 263
template <typename XXX>
class calculFunctor1 : public Algo::Parallel::FunctorMapThreaded<typename XXX::MAP>
Sylvain Thery's avatar
Sylvain Thery committed
264 265
{
protected:
266 267
	typename XXX::TVEC3& m_positions;
	typename XXX::TVEC3& m_normals;
Sylvain Thery's avatar
Sylvain Thery committed
268
public:
269 270
	calculFunctor1( typename XXX::MAP& map, typename XXX::TVEC3& pos, typename XXX::TVEC3& norm, unsigned int id=0):
		Algo::Parallel::FunctorMapThreaded<typename XXX::MAP>(map,id), m_positions(pos), m_normals(norm) {}
Sylvain Thery's avatar
Sylvain Thery committed
271 272 273

	bool operator()(Dart d)
	{
274 275 276 277 278 279 280
		typename XXX::VEC3 n1 = Algo::Geometry::vertexNormal<XXX>(this->m_map, d, m_positions);
		typename XXX::VEC3 n2 = Algo::Geometry::vertexNormal<XXX>(this->m_map, this->m_map.phi1(d), m_positions);
		typename XXX::VEC3 n3 = Algo::Geometry::vertexNormal<XXX>(this->m_map, this->m_map.phi_1(d), m_positions);
		typename XXX::VEC3 n = n1+n2+n3;
		n1 = Algo::Geometry::vertexNormal<XXX>(this->m_map, d, m_positions);
		n2 = Algo::Geometry::vertexNormal<XXX>(this->m_map, this->m_map.phi1(d), m_positions);
		n3 = Algo::Geometry::vertexNormal<XXX>(this->m_map, this->m_map.phi_1(d), m_positions);
Sylvain Thery's avatar
Sylvain Thery committed
281
		n += n1+n2+n3;
Sylvain Thery's avatar
Sylvain Thery committed
282 283
		n.normalize();
		m_normals[d] =  n;
284
//		m_normals[d] = Algo::Geometry::vertexNormal<XXX>(this->m_map, d, m_positions);
Sylvain Thery's avatar
Sylvain Thery committed
285 286
		return false;
	}
287 288 289 290 291 292

	Algo::Parallel::FunctorMapThreaded<typename XXX::MAP>* duplicate(unsigned int id)
	{
		calculFunctor1<XXX>* copy = new calculFunctor1<XXX>(this->m_map,m_positions,m_normals,id);
		return reinterpret_cast<Algo::Parallel::FunctorMapThreaded<typename XXX::MAP>*>(copy);
	}
Sylvain Thery's avatar
Sylvain Thery committed
293 294 295 296
};



297 298 299 300 301 302




template <typename XXX>
class LengthEdgeFunctor : public Algo::Parallel::FunctorMapThreadedResult<typename XXX::MAP, std::pair<double,unsigned int> >
Sylvain Thery's avatar
Sylvain Thery committed
303
{
304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336
protected:
	typename XXX::TVEC3& m_positions;
	double m_length;
	unsigned int m_nb;
public:
	LengthEdgeFunctor( typename XXX::MAP& map, typename XXX::TVEC3& pos, unsigned int id=0):
		Algo::Parallel::FunctorMapThreadedResult< typename XXX::MAP, std::pair<double,unsigned int> >(map,id),
		m_positions(pos),
		m_length(0.0),
		m_nb(0) {}

	bool operator()(Dart d)
	{
		Dart dd = this->m_map.phi2(d);
		typename XXX::VEC3 V = m_positions[dd] - m_positions[d];
		m_length += V.norm();
		m_nb++;
		return false;
	}

	Algo::Parallel::FunctorMapThreaded<typename XXX::MAP>* duplicate(unsigned int id)
	{
		LengthEdgeFunctor<XXX>* copy = new LengthEdgeFunctor<XXX>(this->m_map,m_positions,id);
		return reinterpret_cast<Algo::Parallel::FunctorMapThreaded<typename XXX::MAP>*>(copy);
	}

	std::pair<double,unsigned int> getResult() { return std::pair<double,unsigned int>(m_length,m_nb);}

};




337
void MyQT::menu_slot1()
338
{
339

Sylvain Thery's avatar
Sylvain Thery committed
340 341 342 343
	// cree un handler pour les normales aux sommets
	AttributeHandler<PFP::VEC3> normal2 = myMap.addAttribute<PFP::VEC3>(VERTEX_ORBIT, "normal2");


344 345
	// ajout de 4 threads pour les markers
	myMap.addThreadMarker(4);
Sylvain Thery's avatar
Sylvain Thery committed
346 347


348
	//Algorithmes en //
Sylvain Thery's avatar
Sylvain Thery committed
349

350 351
	boost::thread thread1( ThreadArea<PFP>(myMap,position,1));
	boost::thread thread2( ThreadNormals<PFP>(myMap,position,normal,2));
Sylvain Thery's avatar
Sylvain Thery committed
352 353 354
	thread1.join();
	thread2.join();

355 356 357
	// parallelisation de boucle sans resultat
	calculFunctor1<PFP> tf1(myMap,position,normal);
	Algo::Parallel::foreach_orbit<PFP>(myMap,VERTEX_ORBIT, tf1,4);
358
	CGoGNout << "ok:"<< CGoGNendl;
359 360 361


	// parallelisation de boucle avec resultats stockes
Sylvain Thery's avatar
Sylvain Thery committed
362

363 364 365 366 367 368 369
	// vector pour le resultat (ici paire double/int pour faire la moyenne des longueurs des aretes)
	std::vector<std::pair<double,unsigned int> > lengthp;
	LengthEdgeFunctor <PFP> tflef(myMap,position);			// le foncteur
	// on lance l'algo parallelise (4 threads, buffer de 16384 brins par thread)
	Algo::Parallel::foreach_orbit_res< PFP,std::pair<double,unsigned int> >(myMap,EDGE_ORBIT, tflef, 4 , 16384,lengthp);
	// on calcule la somme des resultats
	std::pair<double,unsigned int> le = Algo::Parallel::sumPairResult<double,unsigned int>(lengthp);
370
	CGoGNout << "length :" <<le.first/le.second<< CGoGNendl;
Sylvain Thery's avatar
Sylvain Thery committed
371 372


373 374
	// on enleve les markers ajoutes
	myMap.removeThreadMarker(4);
375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396
}




int main(int argc, char **argv)
{

	// interface:
	QApplication app(argc, argv);
	MyQT sqt;

	// ajout entree dans le menu application
	sqt.add_menu_entry("test threads", SLOT(menu_slot1()));

	// message d'aide
	sqt.setHelpMsg("Tuto:\n"
			"multi-threading \n"
			"utilisation GL 1.1\n"
			"file sector");

 	sqt.show();
Sylvain Thery's avatar
Sylvain Thery committed
397

398 399
 	sqt.statusMsg("Neww to create a sphere or Load for a mesh file");
 	CGoGNStream::allToConsole(&sqt);
Sylvain Thery's avatar
Sylvain Thery committed
400

Sylvain Thery's avatar
Sylvain Thery committed
401 402 403 404 405 406 407
 	int xx = 3;
 	double yy = 2.5;
 	bool zz=true;
 	int kk=32;
 	int cc=2;


Sylvain Thery's avatar
oups  
Sylvain Thery committed
408 409
 	{
 	using namespace CGoGN::Utils::QT;
Sylvain Thery's avatar
Sylvain Thery committed
410

thery's avatar
thery committed
411
 	inputValues(	VarInteger(0,20,xx, "Entier",
Sylvain Thery's avatar
Sylvain Thery committed
412 413 414 415 416 417 418 419 420 421
 					VarBool(zz, "Bool",
 					VarDbl(0.314,3.14,yy,"Double",
 					VarSlider(10,100,kk,"Slider",
 					VarCombo("Riri;Fifi;Loulou;Donald",cc,"Combo") )))));
 	}

 	std::cout << "Int:" << xx << "  Bool:"<<zz<< std::endl;
 	std::cout << "Dbl:" << yy << "  Slider:"<<kk<< std::endl;
 	std::cout << "Combo:" << cc << std::endl;

422
	return app.exec();
Sylvain Thery's avatar
Sylvain Thery committed
423
}