tuto_mt.cpp 13.2 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 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"

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

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
	typedef EmbeddedMap2<Map2> MAP;
};

60 61 62 63 64 65 66 67 68 69 70
// 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
71
{
72
	// set some filters
Sylvain Thery's avatar
Sylvain Thery committed
73 74 75 76 77 78 79 80 81 82
//	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
83

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

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

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

97 98 99 100 101 102 103 104 105 106 107 108 109 110
	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
111
{
112
	if (!position.isValid())
113
		position = myMap.addAttribute<PFP::VEC3>(VERTEX, "position");
Sylvain Thery's avatar
Sylvain Thery committed
114

115 116 117 118
	// 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
119

120
	if (!normal.isValid())
121
		normal = myMap.addAttribute<PFP::VEC3>(VERTEX, "normal");
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136

	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
137
	// Old school openGL ;)
138 139 140 141 142
	Utils::GLSLShader::setCurrentOGLVersion(1);

	glewInit();

	// init lighting parameters
Sylvain Thery's avatar
Sylvain Thery committed
143
	float lightPosition[4]= {10.0f,10.0f,10000.0f,1.0f};
144 145 146
	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
147
	glEnable(GL_LIGHT0);
148 149
	glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor);
	glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
Sylvain Thery's avatar
Sylvain Thery committed
150 151 152 153
	glEnable(GL_NORMALIZE);
//	glDisable(GL_CULL_FACE);
//	glFrontFace(GL_CCW);

154
}
Sylvain Thery's avatar
Sylvain Thery committed
155

156 157
void MyQT::cb_redraw()
{
Sylvain Thery's avatar
Sylvain Thery committed
158 159 160 161 162
    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
163
	// draw the lines
Sylvain Thery's avatar
Sylvain Thery committed
164 165 166 167 168 169
//	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
170 171 172 173

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

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


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

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

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


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

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

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


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



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

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

	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
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
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);}

};


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

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

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

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

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

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

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

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


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
387

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

Sylvain Thery's avatar
Sylvain Thery committed
391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411
 	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
412

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