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
45
 #include "Utils/Qt/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
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
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
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
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
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
}