Coupure prévue mardi 3 Août au matin pour maintenance du serveur. Nous faisons au mieux pour que celle-ci soit la plus brève possible.

tuto_mt.cpp 13.1 KB
Newer Older
Sylvain Thery's avatar
Sylvain Thery committed
1
2
3
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps  *
* version 0.1                                                                  *
4
* Copyright (C) 2009-2011, IGG Team, LSIIT, University of Strasbourg           *
Sylvain Thery's avatar
Sylvain Thery committed
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
*                                                                              *
* 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.u-strasbg.fr/                                         *
Sylvain Thery's avatar
Sylvain Thery committed
21
22
23
24
25
26
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

#include <iostream>

27
#include "tuto_mt.h"
Sylvain Thery's avatar
Sylvain Thery committed
28
29

#include "Topology/generic/parameters.h"
Pierre Kraemer's avatar
Pierre Kraemer committed
30
#include "Topology/map/embeddedMap2.h"
Sylvain Thery's avatar
Sylvain Thery committed
31
32
33
34
35

#include "Geometry/vector_gen.h"

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

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

44
// for file input
Sylvain Thery's avatar
Sylvain Thery committed
45
 #include "Utils/qtInputs.h"
Sylvain Thery's avatar
Sylvain Thery committed
46
47
48
49
50
51
52
53
54
55

using namespace CGoGN ;

/**
 * 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
Pierre Kraemer's avatar
Pierre Kraemer committed
56
	typedef EmbeddedMap2 MAP;
Sylvain Thery's avatar
Sylvain Thery committed
57
58
};

59
60
61
62
63
64
65
66
67
68
69
// 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
70
{
71
	// set some filters
Sylvain Thery's avatar
Sylvain Thery committed
72
73
74
75
76
77
78
79
80
81
//	std::string filters("all (*.*);; trian (*.trian);; ctm (*.ctm);; off (*.off);; ply (*.ply)");
//
//	std::string filename = selectFile("OpenMesh","",filters);
//
//	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
82

83
	std::vector<std::string> attrNames ;
Sylvain Thery's avatar
Sylvain Thery committed
84
	if(!Algo::Import::importMesh<PFP>(myMap, "/home/thery/Data/liver.trian", attrNames))
85
	{
Sylvain Thery's avatar
Sylvain Thery committed
86
		CGoGNerr << "could not import xxx" << CGoGNendl ;
87
88
		return;
	}
Sylvain Thery's avatar
Sylvain Thery committed
89

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

	if (!normal.isValid())
94
		normal = myMap.addAttribute<PFP::VEC3>(VERTEX, "normal");
Sylvain Thery's avatar
Sylvain Thery committed
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
	if (!position.isValid())
112
		position = myMap.addAttribute<PFP::VEC3>(VERTEX, "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
	if (!normal.isValid())
120
		normal = myMap.addAttribute<PFP::VEC3>(VERTEX, "normal");
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

	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()
{
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
136
	// Old school openGL ;)
137
138
139
140
141
	Utils::GLSLShader::setCurrentOGLVersion(1);

	glewInit();

	// init lighting parameters
Sylvain Thery's avatar
Sylvain Thery committed
142
	float lightPosition[4]= {10.0f,10.0f,10000.0f,1.0f};
143
144
145
	float lightColor[4]= {0.9f,0.9f,0.9f,1.0f};

	glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
Sylvain Thery's avatar
Sylvain Thery committed
146
	glEnable(GL_LIGHT0);
147
148
	glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor);
	glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
Sylvain Thery's avatar
Sylvain Thery committed
149
150
151
152
	glEnable(GL_NORMALIZE);
//	glDisable(GL_CULL_FACE);
//	glFrontFace(GL_CCW);

153
}
Sylvain Thery's avatar
Sylvain Thery committed
154

155
156
void MyQT::cb_redraw()
{
Sylvain Thery's avatar
Sylvain Thery committed
157
158
159
160
161
    GLfloat diff[4]= {0.0f,1.0f,0.1f,1.0f};
    GLfloat amb[4]= {0.1f,0.0f,0.1f,1.0f};
    GLfloat spec[4]= {1.0f,1.0f,1.0f,1.0f};
    float shininess=125.0f;

Sylvain Thery's avatar
Sylvain Thery committed
162
	// draw the lines
Sylvain Thery's avatar
Sylvain Thery committed
163
164
165
166
167
168
//	glDisable(GL_LIGHTING);
//	glColor3f(0.0f, 0.0f, 0.3f);
//	glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
//	glDisable(GL_LIGHTING);
//
//	Algo::Render::GL1::renderTriQuadPoly<PFP>(myMap,Algo::Render::GL1::LINE, 1.0f,position, normal);
Sylvain Thery's avatar
Sylvain Thery committed
169
170
171
172

	// draw the faces
	glEnable(GL_POLYGON_OFFSET_FILL);
	glPolygonOffset(1.0f, 1.0f);
173
	glEnable(GL_LIGHTING);
Sylvain Thery's avatar
Sylvain Thery committed
174
	glEnable(GL_SMOOTH);
175
	glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
Sylvain Thery's avatar
Sylvain Thery committed
176
177
178
179
180

    glMaterialfv(GL_FRONT, GL_DIFFUSE, diff);
    glMaterialfv(GL_FRONT, GL_AMBIENT, amb);
    glMaterialfv(GL_FRONT,GL_SPECULAR,spec);
    glMaterialf( GL_FRONT, GL_SHININESS, shininess);
181
	Algo::Render::GL1::renderTriQuadPoly<PFP>(myMap,Algo::Render::GL1::SMOOTH, 1.0f,position, normal);
Sylvain Thery's avatar
Sylvain Thery committed
182
183
184
185
	glDisable(GL_POLYGON_OFFSET_FILL);
}


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

	void operator()()
	{
201
202
203
204
		// 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
205
206
	}

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
207
	float getTripleValue() { return area; }
Sylvain Thery's avatar
Sylvain Thery committed
208
209
210
};


211
212
template <typename XXX>
class ThreadNormals: public Algo::Parallel::CGoGNThread<typename XXX::MAP>
Sylvain Thery's avatar
Sylvain Thery committed
213
214
{
protected:
215
216
	const typename XXX::TVEC3& m_positions;
	typename XXX::TVEC3& m_normals;
Sylvain Thery's avatar
Sylvain Thery committed
217
public:
218
219
220
	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),
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
221
222
		m_normals(norm)
	{}
Sylvain Thery's avatar
Sylvain Thery committed
223
224
225

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

229
};
Sylvain Thery's avatar
Sylvain Thery committed
230
231


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



266
267
template <typename XXX>
class calculFunctor1 : public Algo::Parallel::FunctorMapThreaded<typename XXX::MAP>
Sylvain Thery's avatar
Sylvain Thery committed
268
269
{
protected:
270
271
	typename XXX::TVEC3& m_positions;
	typename XXX::TVEC3& m_normals;
Sylvain Thery's avatar
Sylvain Thery committed
272
public:
273
274
	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
275
276
277

	bool operator()(Dart d)
	{
278
279
280
281
282
283
284
		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
285
		n += n1+n2+n3;
Sylvain Thery's avatar
Sylvain Thery committed
286
287
		n.normalize();
		m_normals[d] =  n;
288
//		m_normals[d] = Algo::Geometry::vertexNormal<XXX>(this->m_map, d, m_positions);
Sylvain Thery's avatar
Sylvain Thery committed
289
290
		return false;
	}
291
292
293
294
295
296

	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
297
298
299
};


300
301
template <typename XXX>
class LengthEdgeFunctor : public Algo::Parallel::FunctorMapThreadedResult<typename XXX::MAP, std::pair<double,unsigned int> >
Sylvain Thery's avatar
Sylvain Thery committed
302
{
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
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);}

};


334
void MyQT::menu_slot1()
335
{
Sylvain Thery's avatar
Sylvain Thery committed
336
	// cree un handler pour les normales aux sommets
337
	AttributeHandler<PFP::VEC3> normal2 = myMap.addAttribute<PFP::VEC3>(VERTEX, "normal2");
Sylvain Thery's avatar
Sylvain Thery committed
338

339
340
	// ajout de 4 threads pour les markers
	myMap.addThreadMarker(4);
Sylvain Thery's avatar
Sylvain Thery committed
341

342
	//Algorithmes en //
Sylvain Thery's avatar
Sylvain Thery committed
343

344
345
	boost::thread thread1( ThreadArea<PFP>(myMap,position,1));
	boost::thread thread2( ThreadNormals<PFP>(myMap,position,normal,2));
Sylvain Thery's avatar
Sylvain Thery committed
346
347
348
	thread1.join();
	thread2.join();

349
350
	// parallelisation de boucle sans resultat
	calculFunctor1<PFP> tf1(myMap,position,normal);
351
	Algo::Parallel::foreach_orbit<PFP>(myMap,VERTEX, tf1,4);
352
	CGoGNout << "ok:"<< CGoGNendl;
353
354

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

356
357
358
359
	// 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)
360
	Algo::Parallel::foreach_orbit_res< PFP,std::pair<double,unsigned int> >(myMap,EDGE, tflef, 4 , 16384,lengthp);
361
362
	// on calcule la somme des resultats
	std::pair<double,unsigned int> le = Algo::Parallel::sumPairResult<double,unsigned int>(lengthp);
363
	CGoGNout << "length :" <<le.first/le.second<< CGoGNendl;
Sylvain Thery's avatar
Sylvain Thery committed
364

365
366
	// on enleve les markers ajoutes
	myMap.removeThreadMarker(4);
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
}


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
386

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

Sylvain Thery's avatar
Sylvain Thery committed
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
 	sqt.cb_Open();

// 	int xx = 3;
// 	double yy = 2.5;
// 	bool zz=true;
// 	int kk=32;
// 	int cc=2;
//
// 	{
// 	using namespace CGoGN::Utils::QT;
//
// 	inputValues(	VarInteger(0,20,xx, "Entier",
// 					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;
Sylvain Thery's avatar
Sylvain Thery committed
411

412
	return app.exec();
Sylvain Thery's avatar
Sylvain Thery committed
413
}