tuto5.cpp 12.3 KB
Newer Older
Pierre Kraemer's avatar
Pierre Kraemer 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           *
Pierre Kraemer's avatar
Pierre Kraemer 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/                                         *
Pierre Kraemer's avatar
Pierre Kraemer committed
21 22 23 24
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

25
#include "tuto5.h"
Pierre Kraemer's avatar
Pierre Kraemer committed
26

27
#include <iostream>
Pierre Kraemer's avatar
Pierre Kraemer committed
28

29
#include "Topology/generic/parameters.h"
Pierre Kraemer's avatar
Pierre Kraemer committed
30
#include "Topology/map/embeddedMap3.h"
Pierre Kraemer's avatar
Pierre Kraemer committed
31

32

Pierre Kraemer's avatar
Pierre Kraemer committed
33 34
#include "Geometry/vector_gen.h"
#include "Algo/Geometry/boundingbox.h"
35
#include "Algo/Render/GL2/mapRender.h"
36
#include "Utils/Shaders/shaderSimpleColor.h"
37

Pierre Kraemer's avatar
Pierre Kraemer committed
38 39 40 41
#include "Algo/Modelisation/primitives3d.h"
#include "Algo/Modelisation/polyhedron.h"
#include "Algo/Modelisation/subdivision.h"

42
#include "Algo/Render/GL2/topo3Render.h"
Pierre Kraemer's avatar
Pierre Kraemer committed
43 44

#include "Topology/generic/cellmarker.h"
45
#include "Utils/text3d.h"
Pierre Kraemer's avatar
Pierre Kraemer committed
46

47
#include "Utils/pointSprite.h"
48
#include "Utils/Shaders/shaderVectorPerVertex.h"
Sylvain Thery's avatar
Sylvain Thery committed
49 50
#include "Utils/cgognStream.h"

51
#include "Algo/Render/SVG/mapSVGRender.h"
Pierre Kraemer's avatar
Pierre Kraemer committed
52 53 54

using namespace CGoGN ;

55 56
struct PFP: public PFP_STANDARD
{
Pierre Kraemer's avatar
Pierre Kraemer committed
57
	// definition de la carte
Pierre Kraemer's avatar
Pierre Kraemer committed
58
	typedef EmbeddedMap3 MAP;
Pierre Kraemer's avatar
Pierre Kraemer committed
59 60 61 62 63 64 65
	//typedef Map3 MAP;
};

PFP::MAP myMap;
PFP::TVEC3 position ;
Dart dglobal;

66
void MyQT::balls_onoff(bool x)
Pierre Kraemer's avatar
Pierre Kraemer committed
67
{
68 69
	render_balls = !render_balls;
	updateGL();
Sylvain Thery's avatar
Sylvain Thery committed
70
	CGoGNerr << " balls_onoff  "<< CGoGNendl;
71
}
Pierre Kraemer's avatar
Pierre Kraemer committed
72

73 74 75 76
void MyQT::vectors_onoff(bool x)
{
	render_vectors = !render_vectors;
	updateGL();
Sylvain Thery's avatar
Sylvain Thery committed
77
	CGoGNerr << " vectors_onoff  "<< CGoGNflush;
78
}
Pierre Kraemer's avatar
Pierre Kraemer committed
79

80 81 82 83
void MyQT::text_onoff(bool x)
{
	render_text = !render_text;
	updateGL();
Sylvain Thery's avatar
Sylvain Thery committed
84
	CGoGNerr << " text_onoff  " << CGoGNflush;
85
}
86

Sylvain Thery's avatar
Sylvain Thery committed
87

88 89 90 91
void MyQT::topo_onoff(bool x)
{
	render_topo = !render_topo;
	updateGL();
Sylvain Thery's avatar
Sylvain Thery committed
92
	CGoGNerr << " topo_onoff  " << CGoGNflush;
93
}
94

95 96 97 98 99
void MyQT::slider_balls(int x)
{
	m_sprite->setSize(0.05f*x);
	updateGL();
}
100

101 102 103 104 105
void MyQT::slider_vectors(int x)
{
	m_lines->setScale(0.02*x);
	updateGL();
}
Pierre Kraemer's avatar
Pierre Kraemer committed
106

107 108 109 110 111
void MyQT::slider_text(int x)
{
	m_strings->setScale(0.02f*x);
	updateGL();
}
Pierre Kraemer's avatar
Pierre Kraemer committed
112

113 114 115 116 117 118 119 120 121 122


void MyQT::animate()
{
//	transfoMatrix() = glm::rotate(transfoMatrix(), 0.5f, glm::vec3(0.5773f,0.5773f,0.5773f));
	transfoRotate( 0.5f, 0.5773f,0.5773f,0.5773f);
	updateGLMatrices();
}


123
void MyQT::storeVerticesInfo()
124 125
{

126
	CellMarker mv(myMap,VERTEX);
127 128 129 130 131 132 133
	for (Dart d=myMap.begin(); d!=myMap.end(); myMap.next(d))
	{
		if (!mv.isMarked(d))
		{
			mv.mark(d);
			std::stringstream ss;
			ss << d << " : "<< position[d];
134
			m_strings->addString(ss.str(),position[d]);
135 136 137 138
		}
	}
}

139
void MyQT::cb_initGL()
Pierre Kraemer's avatar
Pierre Kraemer committed
140
{
141 142 143 144 145
	// choose to use GL version 2
	Utils::GLSLShader::setCurrentOGLVersion(2);

	// create the render
	m_render = new Algo::Render::GL2::MapRender();
Pierre Kraemer's avatar
Pierre Kraemer committed
146

147
    m_render_topo = new Algo::Render::GL2::Topo3RenderMapD();
Pierre Kraemer's avatar
Pierre Kraemer committed
148

149 150 151
 	// create VBO for position
	m_positionVBO = new Utils::VBO();
	m_positionVBO->updateData(position);
Pierre Kraemer's avatar
Pierre Kraemer committed
152

153 154 155 156
	// using simple shader with color
	m_shader = new Utils::ShaderSimpleColor();
	m_shader->setAttributePosition(m_positionVBO);
	m_shader->setColor(Geom::Vec4f(0.,1.,0.,0.));
Sylvain Thery's avatar
Sylvain Thery committed
157

158 159
	m_sprite = new Utils::PointSprite();
	m_sprite->setAttributePosition(m_positionVBO);
Sylvain Thery's avatar
Sylvain Thery committed
160

thery's avatar
thery committed
161
    m_strings = new Utils::Strings3D(true, Geom::Vec3f(0.1f,0.0f,0.3f));
162 163
    storeVerticesInfo();
    m_strings->sendToVBO();
Sylvain Thery's avatar
Sylvain Thery committed
164

165 166 167
    // copy de contenu de VBO a la creation
	m_dataVBO = new Utils::VBO(*m_positionVBO);

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
168
	m_lines = new Utils::ShaderVectorPerVertex();
169
	m_lines->setAttributePosition(m_positionVBO);
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
170
	m_lines->setAttributeVector(m_dataVBO);
171
	m_lines->setScale(0.2f);
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
172
	m_lines->setColor(Geom::Vec4f(0.0f, 1.0f, 0.2f, 0.0f));
173 174 175 176

	// accede au buffer du VBO pour modification
	PFP::VEC3* data = static_cast<PFP::VEC3*>(m_dataVBO->lockPtr());
	for (unsigned int i=0; i< m_dataVBO->nbElts(); ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
177
	{
178
		data[i].normalize();
Pierre Kraemer's avatar
Pierre Kraemer committed
179
	}
180
	m_dataVBO->releasePtr();
Pierre Kraemer's avatar
Pierre Kraemer committed
181

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
182 183 184 185
	registerShader(m_shader);
	registerShader(m_strings);
	registerShader(m_sprite);
	registerShader(m_lines);
Pierre Kraemer's avatar
Pierre Kraemer committed
186

187 188 189
	m_render->initPrimitives<PFP>(myMap, allDarts, Algo::Render::GL2::TRIANGLES);
	m_render->initPrimitives<PFP>(myMap, allDarts, Algo::Render::GL2::LINES);
	m_render->initPrimitives<PFP>(myMap, allDarts, Algo::Render::GL2::POINTS);
Pierre Kraemer's avatar
Pierre Kraemer committed
190

thery's avatar
thery committed
191
	m_render_topo->updateData<PFP>(myMap, allDarts, position,  0.9f, 0.9f, 0.9f);
192 193 194


	// timer example for animation
195
	m_timer = new QTimer( this );
196
	connect( m_timer, SIGNAL(timeout()), SLOT(animate()) );
197
}
Pierre Kraemer's avatar
Pierre Kraemer committed
198

199 200 201 202
void MyQT::cb_redraw()
{
	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
	glEnable(GL_LIGHTING);
203

204
	m_render->draw(m_shader, Algo::Render::GL2::POINTS);
205

206 207 208
	glLineWidth(2.0f);
	m_shader->setColor(Geom::Vec4f(1.,1.,0.,0.));
	m_render->draw(m_shader, Algo::Render::GL2::LINES);
Pierre Kraemer's avatar
Pierre Kraemer committed
209

210 211
	glEnable(GL_POLYGON_OFFSET_FILL);
	glPolygonOffset(1.0f, 1.0f);
Pierre Kraemer's avatar
Pierre Kraemer committed
212

213 214
	if (render_topo)
		m_render_topo->drawTopo();
Pierre Kraemer's avatar
Pierre Kraemer committed
215

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
216 217 218 219
	Dart d = myMap.phi2(myMap.begin());
	m_render_topo->overdrawDart(d, 5, 1.0f, 0.0f, 1.0f);
	 d = myMap.phi1(myMap.begin());
	m_render_topo->overdrawDart(d, 5, 1.0f, 0.0f, 1.0f);
Pierre Kraemer's avatar
Pierre Kraemer committed
220

221
	glDisable(GL_POLYGON_OFFSET_FILL);
222

223
	if (render_text)
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
224
		m_strings->drawAll(Geom::Vec3f(0.0f, 1.0f, 1.0f));
225 226 227

	if (render_balls)
	{
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
228
		m_sprite->predraw(Geom::Vec3f(1.0f, 0.0f ,0.0f));
229 230 231 232 233
		m_render->draw(m_sprite, Algo::Render::GL2::POINTS);
		m_sprite->postdraw();
	}

	if (render_vectors)
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
234 235
	{
		glLineWidth(1.0f);
236
		m_render->draw(m_lines, Algo::Render::GL2::POINTS);
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
237
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
238 239
}

Sylvain Thery's avatar
Sylvain Thery committed
240 241 242 243
void MyQT::cb_mousePress(int button, int x, int y)
{
	if (Shift())
	{
244
		Dart d = m_render_topo->picking<PFP>(myMap, allDarts, x,y);
Sylvain Thery's avatar
Sylvain Thery committed
245 246
		if (d != Dart::nil())
		{
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
247
			CGoGNout << "Dart "<< d << " clicked" << CGoGNendl;
Sylvain Thery's avatar
Sylvain Thery committed
248 249 250 251 252 253 254 255
		}
		else
		{
			statusMsg("");
		}
	}
}

256 257 258 259 260 261 262
void MyQT::cb_keyPress(int code)
{
	if (code  == 's')
	{
		std::string filename = selectFileSave("Export SVG file ");
		CGoGNout << "Exporting "<<filename<<CGoGNendl;
		Algo::Render::SVG::SVGOut svg(filename,modelViewMatrix(),projectionMatrix());
Sylvain Thery's avatar
Sylvain Thery committed
263
//		svg.renderLinesToSVG<PFP>(myMap,position);
264 265 266 267
		svg.setColor(Geom::Vec3f(1.,0.,0.));
		svg.renderFacesToSVG<PFP>(myMap,position,0.8f);
		//svg destruction close the file
	}
268 269 270 271 272 273 274
	if (code  == 't')
	{
		if (m_timer->isActive())
			m_timer->stop();
		else
			m_timer->start(1000/30); // 30 fps
	}
275 276
}

277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
Dart embedCube()
{
	Dart d = Algo::Modelisation::Polyhedron<PFP>::createPolyhedron(myMap,6);

	myMap.closeMap();

	Dart dres = d;
	position[d] = PFP::VEC3(0,0,0);
	position[myMap.phi1(d)] = PFP::VEC3(1,0,0);
	position[myMap.phi1(myMap.phi1(d))] = PFP::VEC3(1,0,1);
	position[myMap.phi_1(d)] = PFP::VEC3(0,0,1);
	d = myMap.phi_1(myMap.phi2(myMap.phi_1(myMap.phi_1(myMap.phi2(myMap.phi_1(d))))));
	position[d] = PFP::VEC3(1,1,0);
	position[myMap.phi1(d)] = PFP::VEC3(0,1,0);
	position[myMap.phi1(myMap.phi1(d))] = PFP::VEC3(0,1,1);
	position[myMap.phi_1(d)] = PFP::VEC3(1,1,1);

	return myMap.phi2(myMap.phi1(dres));
}
296

297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315
Dart embedCube2()
{
	Dart d = Algo::Modelisation::Polyhedron<PFP>::createPolyhedron(myMap,6);

	myMap.closeMap();

	Dart dres = d;
	position[d] = PFP::VEC3(2,0,0);
	position[myMap.phi1(d)] = PFP::VEC3(3,0,0);
	position[myMap.phi1(myMap.phi1(d))] = PFP::VEC3(3,0,1);
	position[myMap.phi_1(d)] = PFP::VEC3(2,0,1);
	d = myMap.phi_1(myMap.phi2(myMap.phi_1(myMap.phi_1(myMap.phi2(myMap.phi_1(d))))));
	position[d] = PFP::VEC3(3,1,0);
	position[myMap.phi1(d)] = PFP::VEC3(2,1,0);
	position[myMap.phi1(myMap.phi1(d))] = PFP::VEC3(2,1,1);
	position[myMap.phi_1(d)] = PFP::VEC3(3,1,1);

	return myMap.phi2(myMap.phi_1(dres));
}
316

Pierre Kraemer's avatar
Pierre Kraemer committed
317 318
int main(int argc, char **argv)
{
319
	position = myMap.addAttribute<PFP::VEC3>(VERTEX, "position");
320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380
	Dart d1 = embedCube() ;
	Dart d2 = embedCube2() ;

	Dart dd = myMap.phi2(d1) ;

	myMap.check() ;
	std::cout << "nb darts -> " << myMap.getNbDarts() << std::endl ;

	myMap.sewVolumes(d1, d2);

	myMap.check() ;
	std::cout << "nb darts -> " << myMap.getNbDarts() << std::endl ;

	myMap.mergeVolumes(d1) ;

	myMap.check() ;
	std::cout << "nb darts -> " << myMap.getNbDarts() << std::endl ;

	std::vector<Dart> v ;
	v.push_back(dd) ;
	dd = myMap.phi1(myMap.phi2(myMap.phi1(dd))) ;
	v.push_back(dd) ;
	dd = myMap.phi1(myMap.phi2(myMap.phi1(dd))) ;
	v.push_back(dd) ;
	dd = myMap.phi1(myMap.phi2(myMap.phi1(dd))) ;
	v.push_back(dd) ;

	myMap.splitVolume(v) ;

	myMap.check() ;
	std::cout << "nb darts -> " << myMap.getNbDarts() << std::endl ;

	Dart f = myMap.phi2(v.front()) ;
	Dart f3 = myMap.phi3(f) ;
	myMap.unsewVolumes(f) ;

	myMap.check() ;
	std::cout << "nb darts -> " << myMap.getNbDarts() << std::endl ;

	myMap.sewVolumes(f, f3) ;

	myMap.check() ;
	std::cout << "nb darts -> " << myMap.getNbDarts() << std::endl ;

	myMap.splitFace(f, myMap.phi1(myMap.phi1(f))) ;

	myMap.check() ;
	std::cout << "nb darts -> " << myMap.getNbDarts() << std::endl ;

	PFP::VEC3 p = position[f] + position[myMap.phi_1(f)] ;
	p /= 2.0 ;
	myMap.cutEdge(myMap.phi_1(f)) ;
	position[myMap.phi_1(f)] = p ;

	myMap.check() ;
	std::cout << "nb darts -> " << myMap.getNbDarts() << std::endl ;

	myMap.uncutEdge(myMap.phi_1(myMap.phi_1(f))) ;

	myMap.check() ;
	std::cout << "nb darts -> " << myMap.getNbDarts() << std::endl ;
Sylvain Thery's avatar
bug  
Sylvain Thery committed
381

382
	myMap.deleteVolume(f) ;
Sylvain Thery's avatar
Sylvain Thery committed
383

384 385
	myMap.check() ;
	std::cout << "nb darts -> " << myMap.getNbDarts() << std::endl ;
Sylvain Thery's avatar
bug  
Sylvain Thery committed
386

387 388 389 390 391 392 393 394 395
//	Algo::Modelisation::Primitive3D<PFP> prim(myMap, position);
//
//	int nb=3;
//	if (argc>1)
//		nb = atoi(argv[1]);
//	dglobal = prim.hexaGrid_topo(nb,nb,nb);
//	prim.embedHexaGrid(1.0f,1.0f,1.0f);
//
//	myMap.closeMap();
Sylvain Thery's avatar
Sylvain Thery committed
396

397 398 399
    // un peu d'interface
	QApplication app(argc, argv);
	MyQT sqt;
Pierre Kraemer's avatar
Pierre Kraemer committed
400

401 402 403
	// interface de tuto5.ui
    Utils::QT::uiDockInterface dock;
    sqt.setDock(&dock);
Pierre Kraemer's avatar
Pierre Kraemer committed
404

405
 	// message d'aide
Sylvain Thery's avatar
Sylvain Thery committed
406
	sqt.setHelpMsg("Enter pour dock on/off\nShift Enter pour console on/off\nShift Click gauche pour selectionner un brin");
Pierre Kraemer's avatar
Pierre Kraemer committed
407

408
	CGoGNout.toStatusBar(&sqt);
thery's avatar
thery committed
409
	CGoGNout << "CGoGNOut StatusBar" << Geom::Vec3f(2.5f, 2.2f, 4.3f) << CGoGNendl;
Sylvain Thery's avatar
Sylvain Thery committed
410

411
	CGoGNout.toConsole(&sqt);
Sylvain Thery's avatar
Sylvain Thery committed
412

thery's avatar
thery committed
413
	CGoGNout << "CGoGNOut dans la console" << Geom::Vec3f(2.5f, 2.2f, 4.3f) << CGoGNendl;
Sylvain Thery's avatar
Sylvain Thery committed
414

415
	CGoGNout.toStatusBar(NULL);
Pierre Kraemer's avatar
Pierre Kraemer committed
416

417 418 419 420
	//  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);
Pierre Kraemer's avatar
Pierre Kraemer committed
421

422
    // envoit info BB a l'interface
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
423
	sqt.setParamObject(lWidthObj, lPosObj.data());
Pierre Kraemer's avatar
Pierre Kraemer committed
424

425 426 427 428
	sqt.setCallBack( dock.checkBox_balls, SIGNAL(toggled(bool)), SLOT(balls_onoff(bool)) );
	sqt.setCallBack( dock.checkBox_vectors, SIGNAL(toggled(bool)), SLOT(vectors_onoff(bool)) );
	sqt.setCallBack( dock.checkBox_text, SIGNAL(toggled(bool)), SLOT(text_onoff(bool)) );
	sqt.setCallBack( dock.checkBox_topo, SIGNAL(toggled(bool)), SLOT(topo_onoff(bool)) );
Pierre Kraemer's avatar
Pierre Kraemer committed
429

430 431 432
	sqt.setCallBack( dock.slider_balls, SIGNAL(valueChanged(int)), SLOT(slider_balls(int)) );
	sqt.setCallBack( dock.slider_vectors, SIGNAL(valueChanged(int)), SLOT(slider_vectors(int)) );
	sqt.setCallBack( dock.slider_text, SIGNAL(valueChanged(int)), SLOT(slider_text(int)) );
Pierre Kraemer's avatar
Pierre Kraemer committed
433

434
	sqt.show();
Pierre Kraemer's avatar
Pierre Kraemer committed
435

436 437 438
	sqt.slider_balls(50);
	sqt.slider_vectors(50);
	sqt.slider_text(50);
Pierre Kraemer's avatar
Pierre Kraemer committed
439

Sylvain Thery's avatar
Sylvain Thery committed
440 441
	GLint texSize;
	glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texSize);
442
	CGoGNdbg.toConsole(&sqt);
443
	CGoGNerr.toConsole(&sqt);
444
	CGoGNdbg << " TextureSize " <<  texSize << CGoGNendl;
445 446
	CGoGNerr << " test ERROR  " <<  5*7 << CGoGNflush;

Sylvain Thery's avatar
Sylvain Thery committed
447

Pierre Kraemer's avatar
Pierre Kraemer committed
448

449 450
	// et on attend la fin.
	return app.exec();
Pierre Kraemer's avatar
Pierre Kraemer committed
451
}