tuto_mt.cpp 12.7 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 73
	// set some filters
	std::string filters("all (*.*);; trian (*.trian);; ctm (*.ctm);; off (*.off);; ply (*.ply)");
Sylvain Thery's avatar
Sylvain Thery committed
74

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

77 78 79 80 81 82
	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 85 86 87 88
	// 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
89

90 91 92 93 94 95 96 97 98 99 100 101 102 103
	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
104
{
105 106
	if (!position.isValid())
		position = myMap.addAttribute<PFP::VEC3>(VERTEX_ORBIT, "position");
Sylvain Thery's avatar
Sylvain Thery committed
107

108 109 110 111
	// 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
112

113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
	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()
{
Pierre Kraemer's avatar
Pierre Kraemer committed
130
	// Old school openGL ;)
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
	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
147

148 149
void MyQT::cb_redraw()
{
Sylvain Thery's avatar
Sylvain Thery committed
150
	// draw the lines
151 152 153 154 155 156
	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
157 158 159 160

	// draw the faces
	glEnable(GL_POLYGON_OFFSET_FILL);
	glPolygonOffset(1.0f, 1.0f);
161 162 163 164
	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
165 166 167 168
	glDisable(GL_POLYGON_OFFSET_FILL);
}


169 170
template <typename XXX>
class ThreadArea: public Algo::Parallel::CGoGNThread<typename XXX::MAP>
Sylvain Thery's avatar
Sylvain Thery committed
171 172
{
protected:
173
	const typename XXX::TVEC3& m_positions;
Sylvain Thery's avatar
Sylvain Thery committed
174 175
	float area;
public:
Pierre Kraemer's avatar
Pierre Kraemer committed
176
	ThreadArea(typename XXX::MAP& map, const typename XXX::TVEC3& pos, unsigned int th) :
177 178
		Algo::Parallel::CGoGNThread<typename XXX::MAP>(map,th),
		m_positions(pos),
Pierre Kraemer's avatar
Pierre Kraemer committed
179 180
		area(0.0f)
	{}
Sylvain Thery's avatar
Sylvain Thery committed
181 182 183

	void operator()()
	{
184 185 186 187
		// 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
188 189
	}

Pierre Kraemer's avatar
Pierre Kraemer committed
190
	float getTripleValue() { return area; }
Sylvain Thery's avatar
Sylvain Thery committed
191 192 193
};


194 195
template <typename XXX>
class ThreadNormals: public Algo::Parallel::CGoGNThread<typename XXX::MAP>
Sylvain Thery's avatar
Sylvain Thery committed
196 197
{
protected:
198 199
	const typename XXX::TVEC3& m_positions;
	typename XXX::TVEC3& m_normals;
Sylvain Thery's avatar
Sylvain Thery committed
200
public:
201 202 203
	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
204 205
		m_normals(norm)
	{}
Sylvain Thery's avatar
Sylvain Thery committed
206 207 208

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

212
};
Sylvain Thery's avatar
Sylvain Thery committed
213 214


215 216
//template<typename XXX>
//class Thread0
Sylvain Thery's avatar
Sylvain Thery committed
217 218
//{
//protected:
219 220 221 222
//	typename XXX::MAP& m_map;
//	MyGlutWin& m_mgw;
//	unsigned int m_th;
//	SelectorTrue m_selt;
Sylvain Thery's avatar
Sylvain Thery committed
223
//public:
224 225
//	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
226 227 228
//
//	void operator()()
//	{
229
//		CGoGNout << "Begin render init"<<CGoGNendl;
230
//		m_mgw.useContext();
Sylvain Thery's avatar
Sylvain Thery committed
231
//
232
//		// instanciation of the renderer (here using VBOs)
233
//		m_mgw.m_render = new Algo::Render::VBO::MapRender_VBO();
Sylvain Thery's avatar
Sylvain Thery committed
234
//
235
//	    // update the renderer (geometry and primitives)
236
//	    m_mgw.m_render->updateData(Algo::Render::VBO::POSITIONS, position);
Sylvain Thery's avatar
Sylvain Thery committed
237
//
238 239
//	    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
240
//
241
//	    m_mgw.releaseContext();
242
//	    CGoGNout<< "Render OK "<< CGoGNendl;
Sylvain Thery's avatar
Sylvain Thery committed
243 244 245 246 247 248
//
//	}
//};



249 250
template <typename XXX>
class calculFunctor1 : public Algo::Parallel::FunctorMapThreaded<typename XXX::MAP>
Sylvain Thery's avatar
Sylvain Thery committed
251 252
{
protected:
253 254
	typename XXX::TVEC3& m_positions;
	typename XXX::TVEC3& m_normals;
Sylvain Thery's avatar
Sylvain Thery committed
255
public:
256 257
	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
258 259 260

	bool operator()(Dart d)
	{
261 262 263 264 265 266 267
		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
268
		n += n1+n2+n3;
Sylvain Thery's avatar
Sylvain Thery committed
269 270
		n.normalize();
		m_normals[d] =  n;
271
//		m_normals[d] = Algo::Geometry::vertexNormal<XXX>(this->m_map, d, m_positions);
Sylvain Thery's avatar
Sylvain Thery committed
272 273
		return false;
	}
274 275 276 277 278 279

	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
280 281 282
};


283 284
template <typename XXX>
class LengthEdgeFunctor : public Algo::Parallel::FunctorMapThreadedResult<typename XXX::MAP, std::pair<double,unsigned int> >
Sylvain Thery's avatar
Sylvain Thery committed
285
{
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316
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);}

};


317
void MyQT::menu_slot1()
318
{
Sylvain Thery's avatar
Sylvain Thery committed
319 320 321
	// cree un handler pour les normales aux sommets
	AttributeHandler<PFP::VEC3> normal2 = myMap.addAttribute<PFP::VEC3>(VERTEX_ORBIT, "normal2");

322 323
	// ajout de 4 threads pour les markers
	myMap.addThreadMarker(4);
Sylvain Thery's avatar
Sylvain Thery committed
324

325
	//Algorithmes en //
Sylvain Thery's avatar
Sylvain Thery committed
326

327 328
	boost::thread thread1( ThreadArea<PFP>(myMap,position,1));
	boost::thread thread2( ThreadNormals<PFP>(myMap,position,normal,2));
Sylvain Thery's avatar
Sylvain Thery committed
329 330 331
	thread1.join();
	thread2.join();

332 333 334
	// parallelisation de boucle sans resultat
	calculFunctor1<PFP> tf1(myMap,position,normal);
	Algo::Parallel::foreach_orbit<PFP>(myMap,VERTEX_ORBIT, tf1,4);
335
	CGoGNout << "ok:"<< CGoGNendl;
336 337

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

339 340 341 342 343 344 345
	// 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);
346
	CGoGNout << "length :" <<le.first/le.second<< CGoGNendl;
Sylvain Thery's avatar
Sylvain Thery committed
347

348 349
	// on enleve les markers ajoutes
	myMap.removeThreadMarker(4);
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368
}


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
369

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

Sylvain Thery's avatar
Sylvain Thery committed
373 374 375 376 377 378
 	int xx = 3;
 	double yy = 2.5;
 	bool zz=true;
 	int kk=32;
 	int cc=2;

Sylvain Thery's avatar
oups  
Sylvain Thery committed
379 380
 	{
 	using namespace CGoGN::Utils::QT;
Sylvain Thery's avatar
Sylvain Thery committed
381

thery's avatar
thery committed
382
 	inputValues(	VarInteger(0,20,xx, "Entier",
Sylvain Thery's avatar
Sylvain Thery committed
383 384 385 386 387 388 389 390 391 392
 					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;

393
	return app.exec();
Sylvain Thery's avatar
Sylvain Thery committed
394
}