surface_selection.cpp 26.2 KB
Newer Older
1 2 3 4 5 6 7 8
#include "surface_selection.h"

#include "schnapps.h"
#include "view.h"
#include "mapHandler.h"

#include "Algo/Selection/raySelector.h"
#include "Algo/Selection/collector.h"
Sylvain Thery's avatar
Sylvain Thery committed
9
#include "Algo/Geometry/centroid.h"
10 11 12 13 14 15 16 17 18 19 20

#include <QKeyEvent>
#include <QMouseEvent>

namespace CGoGN
{

namespace SCHNApps
{

Surface_Selection_Plugin::Surface_Selection_Plugin() :
21
	m_selecting(false),
22 23 24
	m_selectedVertices_dirty(false),
	m_selectedEdges_dirty(false),
	m_selectedFaces_dirty(false),
25 26
	m_selectionRadiusBase(1),
	m_selectionRadiusCoeff(1),
Sylvain Thery's avatar
Sylvain Thery committed
27
	m_normalAngleThreshold(float(10*M_PI/180))
28 29 30 31
{}

bool Surface_Selection_Plugin::enable()
{
32
	//	magic line that init static variables of GenericMap in the plugins
33
	GenericMap::copyAllStatics(m_schnapps->getStaticPointers());
34

35 36 37
	m_dockTab = new Surface_Selection_DockTab(m_schnapps, this);
	m_schnapps->addPluginDockTab(this, m_dockTab, "Surface_Selection");

38 39 40
	m_pointSprite = new CGoGN::Utils::PointSprite();
	m_selectedVerticesVBO = new Utils::VBO();

41
	m_selectedEdgesDrawer = new Utils::Drawer(1);
Pierre Kraemer's avatar
Pierre Kraemer committed
42
	m_selectedFacesDrawer = new Utils::Drawer();
43
	m_selectedFacesDrawer->setFaceShading(false);
Pierre Kraemer's avatar
Pierre Kraemer committed
44

45
	m_selectingCellDrawer = new Utils::Drawer(1);
Pierre Kraemer's avatar
Pierre Kraemer committed
46

47
	m_selectionSphereVBO = new Utils::VBO();
48

49
	registerShader(m_pointSprite);
50 51 52
	registerShader(m_selectedEdgesDrawer->getShaders());
	registerShader(m_selectedFacesDrawer->getShaders());
	registerShader(m_selectingCellDrawer->getShaders());
53 54

	connect(m_schnapps, SIGNAL(selectedMapChanged(MapHandlerGen*, MapHandlerGen*)), this, SLOT(selectedMapChanged(MapHandlerGen*, MapHandlerGen*)));
Pierre Kraemer's avatar
Pierre Kraemer committed
55
	connect(m_schnapps, SIGNAL(selectedCellSelectorChanged(CellSelectorGen*)), this, SLOT(updateSelectedCellsRendering()));
56

Pierre Kraemer's avatar
Pierre Kraemer committed
57 58 59 60 61
	MapHandlerGen* cur = m_schnapps->getSelectedMap();
	if(cur)
	{
		connect(cur, SIGNAL(attributeAdded(unsigned int, const QString&)), this, SLOT(selectedMapAttributeAdded(unsigned int, const QString&)));
		connect(cur, SIGNAL(attributeModified(unsigned int, const QString&)), this, SLOT(selectedMapAttributeModified(unsigned int, const QString&)));
62
		connect(cur, SIGNAL(connectivityModified()), this, SLOT(selectedMapConnectivityModified()));
63
		connect(cur, SIGNAL(boundingBoxModified()), this, SLOT(selectedMapBoundingBoxModified()));
64 65
		connect(cur, SIGNAL(cellSelectorRemoved(unsigned int, const QString&)), this, SLOT(updateRemovedSelector(unsigned int, const QString&)));

66
		m_selectionRadiusBase = cur->getBBdiagSize() / 50.0f;
Sylvain Thery's avatar
Sylvain Thery committed
67 68
		h_parameterSet[cur].basePSradius = cur->getBBdiagSize() / (std::sqrt(cur->getNbOrbits(EDGE)));
		h_parameterSet[cur].verticesScaleFactor = m_dockTab->slider_verticesScaleFactor->value() / 50.0f;
Pierre Kraemer's avatar
Pierre Kraemer committed
69
	}
70 71 72 73 74 75 76 77

	m_dockTab->updateMapParameters();

	return true;
}

void Surface_Selection_Plugin::disable()
{
78 79 80 81 82
	unregisterShader(m_pointSprite);
	unregisterShader(m_selectedEdgesDrawer->getShaders());
	unregisterShader(m_selectedFacesDrawer->getShaders());
	unregisterShader(m_selectingCellDrawer->getShaders());

83
	delete m_pointSprite;
84
	delete m_selectedVerticesVBO;
Pierre Kraemer's avatar
Pierre Kraemer committed
85 86 87 88 89

	delete m_selectedEdgesDrawer;
	delete m_selectedFacesDrawer;
	delete m_selectingCellDrawer;

90
	delete m_selectionSphereVBO;
91

Sylvain Thery's avatar
Sylvain Thery committed
92 93 94 95 96
	//disconnect(m_schnapps, SIGNAL(selectedViewChanged(View*, View*)), this, SLOT(selectedViewChanged(View*, View*)));
	//disconnect(m_schnapps, SIGNAL(mapRemoved(MapHandlerGen*)), this, SLOT(mapRemoved(MapHandlerGen*)));
	disconnect(m_schnapps, SIGNAL(selectedMapChanged(MapHandlerGen*, MapHandlerGen*)), this, SLOT(selectedMapChanged(MapHandlerGen*, MapHandlerGen*)));
	disconnect(m_schnapps, SIGNAL(selectedCellSelectorChanged(CellSelectorGen*)), this, SLOT(updateSelectedCellsRendering()));

97 98
}

99 100
void Surface_Selection_Plugin::drawMap(View* view, MapHandlerGen* map)
{
101
	if(map->isSelectedMap())
102
	{
103 104 105
		glEnable(GL_POLYGON_OFFSET_FILL);
		glPolygonOffset(-1.0f, -1.0f);

106
		const MapParameters& p = h_parameterSet[map];
107 108 109 110 111 112
		if(p.positionAttribute.isValid())
		{
			unsigned int orbit = m_schnapps->getCurrentOrbit();
			CellSelectorGen* selector = m_schnapps->getSelectedSelector(orbit);
			if(selector)
			{
113
//				unsigned int nbCells = map->getGenericMap()->getNbCells(orbit);
114
				switch(orbit)
115
				{
116
					case VERTEX : {
117 118 119 120 121
						if (selector->getNbSelectedCells() > 0)
						{
							if (m_selectedVertices_dirty)
								updateSelectedCellsRendering();
							m_pointSprite->setAttributePosition(m_selectedVerticesVBO);
Sylvain Thery's avatar
Sylvain Thery committed
122 123
							const QColor& col = p.color;
							m_pointSprite->setColor(Geom::Vec4f(col.redF(), col.greenF(), col.blueF(), 0.0f));
124
							m_pointSprite->setLightPosition(CGoGN::Geom::Vec3f(0.0f, 0.0f, 1.0f));
Sylvain Thery's avatar
Sylvain Thery committed
125
							m_pointSprite->setSize(p.basePSradius*p.verticesScaleFactor);
126 127 128 129
							m_pointSprite->enableVertexAttribs();
							glDrawArrays(GL_POINTS, 0, selector->getNbSelectedCells());
							m_pointSprite->disableVertexAttribs();
						}
130

131
						if(m_selecting && m_selectingVertex.valid())
132 133
						{
							std::vector<PFP2::VEC3> selectionPoint;
Pierre Kraemer's avatar
Pierre Kraemer committed
134
							selectionPoint.push_back(p.positionAttribute[m_selectingVertex]);
135
							m_selectionSphereVBO->updateData<3>(selectionPoint);
136 137 138 139 140
							m_pointSprite->setAttributePosition(m_selectionSphereVBO);
							m_pointSprite->setColor(CGoGN::Geom::Vec4f(0.0f, 0.0f, 1.0f, 0.5f));
							m_pointSprite->setLightPosition(CGoGN::Geom::Vec3f(0.0f, 0.0f, 1.0f));
							switch(p.selectionMethod)
							{
141
								case NormalAngle :
142 143 144 145
								case SingleCell : 
									m_pointSprite->setSize(p.basePSradius*p.verticesScaleFactor*2.0f);
									break;
								case WithinSphere : 
146
									m_pointSprite->setSize(m_selectionRadiusBase * m_selectionRadiusCoeff);
147 148 149 150 151 152 153 154 155 156 157 158
									break;
							}
							m_pointSprite->enableVertexAttribs();
							glEnable(GL_BLEND);
							glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
							glDrawArrays(GL_POINTS, 0, 1);
							glDisable(GL_BLEND);
							m_pointSprite->disableVertexAttribs();
						}
						break;
					}
					case EDGE : {
159 160 161 162 163 164
						if (selector->getNbSelectedCells() > 0)
						{
							if (m_selectedEdges_dirty)
								updateSelectedCellsRendering();
							m_selectedEdgesDrawer->callList();
						}
Pierre Kraemer's avatar
Pierre Kraemer committed
165

166
						if(m_selecting && m_selectingEdge.valid())
Pierre Kraemer's avatar
Pierre Kraemer committed
167 168 169
						{
							switch(p.selectionMethod)
							{
170
								case NormalAngle :
Pierre Kraemer's avatar
Pierre Kraemer committed
171
								case SingleCell : {
Pierre Kraemer's avatar
Pierre Kraemer committed
172 173 174 175 176
									PFP2::MAP* m = static_cast<MapHandler<PFP2>*>(map)->getMap();
									m_selectingCellDrawer->newList(GL_COMPILE_AND_EXECUTE);
									m_selectingCellDrawer->lineWidth(6.0f);
									m_selectingCellDrawer->color3f(0.0f, 0.0f, 1.0f);
									m_selectingCellDrawer->begin(GL_LINES);
177 178
									m_selectingCellDrawer->vertex(p.positionAttribute[m_selectingEdge.dart]);
									m_selectingCellDrawer->vertex(p.positionAttribute[m->phi1(m_selectingEdge.dart)]);
Pierre Kraemer's avatar
Pierre Kraemer committed
179 180
									m_selectingCellDrawer->end();
									m_selectingCellDrawer->endList();
Pierre Kraemer's avatar
Pierre Kraemer committed
181 182 183
									break;
								}
								case WithinSphere : {
184
//									PFP2::MAP* m = static_cast<MapHandler<PFP2>*>(map)->getMap();
185
									std::vector<PFP2::VEC3> selectionPoint;
186
									selectionPoint.push_back(p.positionAttribute[m_selectingEdge.dart]);
187
									m_selectionSphereVBO->updateData<3>(selectionPoint);
188 189 190 191

									m_pointSprite->setAttributePosition(m_selectionSphereVBO);
									m_pointSprite->setColor(CGoGN::Geom::Vec4f(0.0f, 0.0f, 1.0f, 0.5f));
									m_pointSprite->setLightPosition(CGoGN::Geom::Vec3f(0.0f, 0.0f, 1.0f));
192
									m_pointSprite->setSize(m_selectionRadiusBase * m_selectionRadiusCoeff);
193 194 195 196 197 198 199

									m_pointSprite->enableVertexAttribs();
									glEnable(GL_BLEND);
									glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
									glDrawArrays(GL_POINTS, 0, 1);
									glDisable(GL_BLEND);
									m_pointSprite->disableVertexAttribs();
Pierre Kraemer's avatar
Pierre Kraemer committed
200 201 202 203
									break;
								}
							}
						}
204 205 206
						break;
					}
					case FACE : {
207 208 209 210 211 212
						if (selector->getNbSelectedCells() > 0)
						{
							if (m_selectedFaces_dirty)
								updateSelectedCellsRendering();
							m_selectedFacesDrawer->callList();
						}
Pierre Kraemer's avatar
Pierre Kraemer committed
213

214
						if(m_selecting && m_selectingFace.valid())
Pierre Kraemer's avatar
Pierre Kraemer committed
215 216 217
						{
							switch(p.selectionMethod)
							{
218
								case NormalAngle :
Pierre Kraemer's avatar
Pierre Kraemer committed
219
								case SingleCell : {
Pierre Kraemer's avatar
Pierre Kraemer committed
220 221
									PFP2::MAP* m = static_cast<MapHandler<PFP2>*>(map)->getMap();
									m_selectingCellDrawer->newList(GL_COMPILE_AND_EXECUTE);
222
									m_selectingCellDrawer->lineWidth(6.0f);
Pierre Kraemer's avatar
Pierre Kraemer committed
223
									m_selectingCellDrawer->color3f(0.0f, 0.0f, 1.0f);
224 225 226 227 228 229 230
									m_selectingCellDrawer->begin(GL_LINE_LOOP);
									Dart d = m_selectingFace.dart;
									do
									{
										m_selectingCellDrawer->vertex(p.positionAttribute[d]);
										d = m->phi1(d);
									} while (d != m_selectingFace.dart);
Pierre Kraemer's avatar
Pierre Kraemer committed
231 232
									m_selectingCellDrawer->end();
									m_selectingCellDrawer->endList();
Pierre Kraemer's avatar
Pierre Kraemer committed
233 234 235
									break;
								}
								case WithinSphere : {
236
//									PFP2::MAP* m = static_cast<MapHandler<PFP2>*>(map)->getMap();
Sylvain Thery's avatar
Sylvain Thery committed
237

238
									std::vector<PFP2::VEC3> selectionPoint;
239
									selectionPoint.push_back(p.positionAttribute[m_selectingFace.dart]);
240
									m_selectionSphereVBO->updateData<3>(selectionPoint);
241 242 243 244

									m_pointSprite->setAttributePosition(m_selectionSphereVBO);
									m_pointSprite->setColor(CGoGN::Geom::Vec4f(0.0f, 0.0f, 1.0f, 0.5f));
									m_pointSprite->setLightPosition(CGoGN::Geom::Vec3f(0.0f, 0.0f, 1.0f));
245
									m_pointSprite->setSize(m_selectionRadiusBase * m_selectionRadiusCoeff);
246 247 248 249 250 251 252

									m_pointSprite->enableVertexAttribs();
									glEnable(GL_BLEND);
									glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
									glDrawArrays(GL_POINTS, 0, 1);
									glDisable(GL_BLEND);
									m_pointSprite->disableVertexAttribs();
Pierre Kraemer's avatar
Pierre Kraemer committed
253 254 255 256
									break;
								}
							}
						}
257 258
						break;
					}
259 260
				}
			}
261
		}
262
	}
263
	glDisable(GL_POLYGON_OFFSET_FILL);
264 265
}

266 267 268 269
void Surface_Selection_Plugin::keyPress(View* view, QKeyEvent* event)
{
	if(event->key() == Qt::Key_Shift)
	{
Sylvain Thery's avatar
Sylvain Thery committed
270 271 272 273
		view->setMouseTracking(true);
		m_selecting = true;

		// generate a false mouse move to update drawing on shift keypressed !
Sylvain Thery's avatar
Sylvain Thery committed
274
		QPoint p = m_schnapps->getSelectedView()->mapFromGlobal(QCursor::pos());
Sylvain Thery's avatar
Sylvain Thery committed
275
		QMouseEvent me = QMouseEvent(QEvent::MouseMove, p, Qt::NoButton, Qt::NoButton, Qt::ShiftModifier);
Sylvain Thery's avatar
Sylvain Thery committed
276 277
		mouseMove(view, &me);

278
		view->updateGL();
279 280 281 282 283 284 285 286 287
	}
}

void Surface_Selection_Plugin::keyRelease(View* view, QKeyEvent* event)
{
	if(event->key() == Qt::Key_Shift)
	{
		view->setMouseTracking(false);
		m_selecting = false;
288
		view->updateGL();
289 290 291
	}
}

292 293 294



295 296
void Surface_Selection_Plugin::mousePress(View* view, QMouseEvent* event)
{
297
	if(m_selecting && (event->button() == Qt::LeftButton || event->button() == Qt::RightButton))
298 299
	{
		MapHandlerGen* mh = m_schnapps->getSelectedMap();
300
		const MapParameters& p = h_parameterSet[mh];
301 302
		if(p.positionAttribute.isValid())
		{
303 304 305 306 307
			unsigned int orbit = m_schnapps->getCurrentOrbit();
			CellSelectorGen* selector = m_schnapps->getSelectedSelector(orbit);
			if(selector)
			{
				PFP2::MAP* map = static_cast<MapHandler<PFP2>*>(mh)->getMap();
308

309
				switch(orbit)
310
				{
311
					case VERTEX : {
312 313
						CellSelector<PFP2::MAP, VERTEX>* cs = static_cast<CellSelector<PFP2::MAP, VERTEX>*>(selector);
						if(m_selectingVertex.valid())
314
						{
315
							m_selectedVertices_dirty = true;
316 317 318 319
							switch(p.selectionMethod)
							{
								case SingleCell : {
									if(event->button() == Qt::LeftButton)
320
										cs->select(m_selectingVertex);
321
									else if(event->button() == Qt::RightButton)
322
										cs->unselect(m_selectingVertex);
323 324 325
									break;
								}
								case WithinSphere : {
326
									Algo::Surface::Selection::Collector_WithinSphere<PFP2> neigh(*map, p.positionAttribute, m_selectionRadiusBase * m_selectionRadiusCoeff);
Pierre Kraemer's avatar
Pierre Kraemer committed
327
									neigh.collectAll(m_selectingVertex);
328
									if(event->button() == Qt::LeftButton)
329
										cs->select(neigh.getInsideVertices());
330
									else if(event->button() == Qt::RightButton)
331
										cs->unselect(neigh.getInsideVertices());
332 333
									break;
								}
334 335 336
								case NormalAngle : {
									if(p.normalAttribute.isValid())
									{
Pierre Kraemer's avatar
Pierre Kraemer committed
337
										Algo::Surface::Selection::Collector_NormalAngle<PFP2> neigh(*map, p.normalAttribute, m_normalAngleThreshold);
338 339
										neigh.collectAll(m_selectingVertex);
										if(event->button() == Qt::LeftButton)
340
											cs->select(neigh.getInsideVertices());
341
										else if(event->button() == Qt::RightButton)
342
											cs->unselect(neigh.getInsideVertices());
343 344 345
									}
									break;
								}
346
							}
347
						}
348
						break;
349
					}
350
					case EDGE : {
351 352
						CellSelector<PFP2::MAP, EDGE>* cs = static_cast<CellSelector<PFP2::MAP, EDGE>*>(selector);
						if(m_selectingEdge.valid())
Pierre Kraemer's avatar
Pierre Kraemer committed
353
						{
354
							m_selectedEdges_dirty = true;
Pierre Kraemer's avatar
Pierre Kraemer committed
355 356 357 358
							switch(p.selectionMethod)
							{
								case SingleCell : {
									if(event->button() == Qt::LeftButton)
359
										cs->select(m_selectingEdge);
Pierre Kraemer's avatar
Pierre Kraemer committed
360
									else if(event->button() == Qt::RightButton)
361
										cs->unselect(m_selectingEdge);
Pierre Kraemer's avatar
Pierre Kraemer committed
362 363 364
									break;
								}
								case WithinSphere : {
365
									Algo::Surface::Selection::Collector_WithinSphere<PFP2> neigh(*map, p.positionAttribute, m_selectionRadiusBase * m_selectionRadiusCoeff);
366 367
									neigh.collectAll(m_selectingEdge);
									if(event->button() == Qt::LeftButton)
368
										cs->select(neigh.getInsideEdges());
369
									else if(event->button() == Qt::RightButton)
370
										cs->unselect(neigh.getInsideEdges());
Pierre Kraemer's avatar
Pierre Kraemer committed
371 372
									break;
								}
373 374 375
								case NormalAngle : {
									if(p.normalAttribute.isValid())
									{
Pierre Kraemer's avatar
Pierre Kraemer committed
376
										Algo::Surface::Selection::Collector_NormalAngle<PFP2> neigh(*map, p.normalAttribute, m_normalAngleThreshold);
377 378
										neigh.collectAll(m_selectingEdge);
										if(event->button() == Qt::LeftButton)
379
											cs->select(neigh.getInsideEdges());
380
										else if(event->button() == Qt::RightButton)
381
											cs->unselect(neigh.getInsideEdges());
382 383 384
									}
									break;
								}
Pierre Kraemer's avatar
Pierre Kraemer committed
385 386
							}
						}
387 388 389
						break;
					}
					case FACE : {
390 391
						CellSelector<PFP2::MAP, FACE>* cs = static_cast<CellSelector<PFP2::MAP, FACE>*>(selector);
						if(m_selectingFace.valid())
Pierre Kraemer's avatar
Pierre Kraemer committed
392
						{
393
							m_selectedFaces_dirty = true;
Pierre Kraemer's avatar
Pierre Kraemer committed
394 395 396 397
							switch(p.selectionMethod)
							{
								case SingleCell : {
									if(event->button() == Qt::LeftButton)
398
										cs->select(m_selectingFace);
Pierre Kraemer's avatar
Pierre Kraemer committed
399
									else if(event->button() == Qt::RightButton)
400
										cs->unselect(m_selectingFace);
Pierre Kraemer's avatar
Pierre Kraemer committed
401 402 403
									break;
								}
								case WithinSphere : {
404
									Algo::Surface::Selection::Collector_WithinSphere<PFP2> neigh(*map, p.positionAttribute, m_selectionRadiusBase * m_selectionRadiusCoeff);
405 406
									neigh.collectAll(m_selectingFace);
									if(event->button() == Qt::LeftButton)
407
										cs->select(neigh.getInsideFaces());
408
									else if(event->button() == Qt::RightButton)
409
										cs->unselect(neigh.getInsideFaces());
Pierre Kraemer's avatar
Pierre Kraemer committed
410 411
									break;
								}
412 413 414
								case NormalAngle : {
									if(p.normalAttribute.isValid())
									{
Pierre Kraemer's avatar
Pierre Kraemer committed
415
										Algo::Surface::Selection::Collector_NormalAngle<PFP2> neigh(*map, p.normalAttribute, m_normalAngleThreshold);
416 417
										neigh.collectAll(m_selectingFace);
										if(event->button() == Qt::LeftButton)
418
											cs->select(neigh.getInsideFaces());
419
										else if(event->button() == Qt::RightButton)
420
											cs->unselect(neigh.getInsideFaces());
421 422 423
									}
									break;
								}
Pierre Kraemer's avatar
Pierre Kraemer committed
424 425
							}
						}
426
						break;
427 428
					}
				}
429 430 431 432 433 434 435 436 437 438
			}
		}
	}
}

void Surface_Selection_Plugin::mouseMove(View* view, QMouseEvent* event)
{
	if(m_selecting)
	{
		MapHandlerGen* mh = m_schnapps->getSelectedMap();
439
		const MapParameters& p = h_parameterSet[mh];
440 441
		if(p.positionAttribute.isValid())
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
442 443 444 445 446 447 448 449 450
			unsigned int orbit = m_schnapps->getCurrentOrbit();
			CellSelectorGen* selector = m_schnapps->getSelectedSelector(orbit);
			if(selector)
			{
				QPoint pixel(event->x(), event->y());
				qglviewer::Vec orig;
				qglviewer::Vec dir;
				view->camera()->convertClickToLine(pixel, orig, dir);

Sylvain Thery's avatar
Sylvain Thery committed
451
				// compute coordinates of ray in map Frame
Pierre Kraemer's avatar
Pierre Kraemer committed
452 453
				qglviewer::Vec orig_inv = mh->getFrame()->coordinatesOf(orig);
				qglviewer::Vec dir_inv = mh->getFrame()->transformOf(dir);
Sylvain Thery's avatar
Sylvain Thery committed
454 455 456 457 458 459
				// apply inverse local map transfo
				glm::vec4 glmRayA = mh->getInverseTransfoMatrix()*glm::vec4(orig_inv.x, orig_inv.y, orig_inv.z, 1.0f);
				glm::vec4 glmAB = glm::transpose(mh->getInverseTransfoMatrix())*glm::vec4(dir_inv.x, dir_inv.y, dir_inv.z, 1.0f);
				// put in PFP::VEC3 format
				PFP2::VEC3 rayA(glmRayA.x, glmRayA.y, glmRayA.z);
				PFP2::VEC3 AB(glmAB.x, glmAB.y, glmAB.z);
Pierre Kraemer's avatar
Pierre Kraemer committed
460

Pierre Kraemer's avatar
Pierre Kraemer committed
461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477
				PFP2::MAP* map = static_cast<MapHandler<PFP2>*>(mh)->getMap();

				switch(orbit)
				{
					case VERTEX : {
						Algo::Selection::vertexRaySelection<PFP2>(*map, p.positionAttribute, rayA, AB, m_selectingVertex);
						break;
					}
					case EDGE : {
						Algo::Selection::edgeRaySelection<PFP2>(*map, p.positionAttribute, rayA, AB, m_selectingEdge);
						break;
					}
					case FACE : {
						Algo::Selection::faceRaySelection<PFP2>(*map, p.positionAttribute, rayA, AB, m_selectingFace);
						break;
					}
				}
478 479 480 481 482 483 484 485 486 487 488

				view->updateGL();
			}
		}
	}
}

void Surface_Selection_Plugin::wheelEvent(View* view, QWheelEvent* event)
{
	if(m_selecting)
	{
489 490 491
		MapHandlerGen* mh = m_schnapps->getSelectedMap();
		const MapParameters& p = h_parameterSet[mh];

492
		switch(p.selectionMethod)
493
		{
494 495 496 497 498
			case SingleCell : {
				break;
			}
			case WithinSphere : {
				if(event->delta() > 0)
499
					m_selectionRadiusCoeff *= 0.9f;
500
				else
501
					m_selectionRadiusCoeff *= 1.1f;
502
				view->updateGL();
Sylvain Thery's avatar
Sylvain Thery committed
503
				m_dockTab->spin_angle_radius->setValue(m_selectionRadiusBase * m_selectionRadiusCoeff);
504 505 506 507
				break;
			}
			case NormalAngle : {
				if(event->delta() > 0)
Sylvain Thery's avatar
Sylvain Thery committed
508
					m_normalAngleThreshold -= CGoGN::PFP_SCHNAPPS::REAL(M_PI / 180);
509
				else
Sylvain Thery's avatar
Sylvain Thery committed
510
					m_normalAngleThreshold += CGoGN::PFP_SCHNAPPS::REAL(M_PI / 180);
511
//				view->displayMessage(QString("Angle threshold : ") + m_normalAngleThreshold);
Sylvain Thery's avatar
Sylvain Thery committed
512
				m_dockTab->spin_angle_radius->setValue(m_normalAngleThreshold/M_PI*180);
513 514
				break;
			}
515
		}
516 517 518 519 520 521 522 523
	}
}



void Surface_Selection_Plugin::selectedMapChanged(MapHandlerGen *prev, MapHandlerGen *cur)
{
	m_dockTab->updateMapParameters();
Pierre Kraemer's avatar
Pierre Kraemer committed
524 525 526 527
	if(prev)
	{
		disconnect(prev, SIGNAL(attributeAdded(unsigned int, const QString&)), this, SLOT(selectedMapAttributeAdded(unsigned int, const QString&)));
		disconnect(prev, SIGNAL(attributeModified(unsigned int, const QString&)), this, SLOT(selectedMapAttributeModified(unsigned int, const QString&)));
528
		disconnect(prev, SIGNAL(connectivityModified()), this, SLOT(selectedMapConnectivityModified()));
529
		disconnect(prev, SIGNAL(boundingBoxModified()), this, SLOT(selectedMapBoundingBoxModified()));
530
		disconnect(prev, SIGNAL(cellSelectorRemoved(unsigned int, const QString&)), this, SLOT(updateRemovedSelector(unsigned int, const QString&)));
Pierre Kraemer's avatar
Pierre Kraemer committed
531
	}
532
	if(cur)
Pierre Kraemer's avatar
Pierre Kraemer committed
533 534 535
	{
		connect(cur, SIGNAL(attributeAdded(unsigned int, const QString&)), this, SLOT(selectedMapAttributeAdded(unsigned int, const QString&)));
		connect(cur, SIGNAL(attributeModified(unsigned int, const QString&)), this, SLOT(selectedMapAttributeModified(unsigned int, const QString&)));
536
		connect(cur, SIGNAL(connectivityModified()), this, SLOT(selectedMapConnectivityModified()));
537
		connect(cur, SIGNAL(boundingBoxModified()), this, SLOT(selectedMapBoundingBoxModified()));
538
		connect(cur, SIGNAL(cellSelectorRemoved(unsigned int, const QString&)), this, SLOT(updateRemovedSelector(unsigned int, const QString&)));
539
		m_selectionRadiusBase = cur->getBBdiagSize() / 50.0f;
Sylvain Thery's avatar
Sylvain Thery committed
540 541
		h_parameterSet[cur].basePSradius = cur->getBBdiagSize() / (std::sqrt(cur->getNbOrbits(EDGE)));
		h_parameterSet[cur].verticesScaleFactor = m_dockTab->slider_verticesScaleFactor->value() / 50.0f;
Pierre Kraemer's avatar
Pierre Kraemer committed
542
	}
543 544
}

Pierre Kraemer's avatar
Pierre Kraemer committed
545 546
void Surface_Selection_Plugin::updateSelectedCellsRendering()
{
Pierre Kraemer's avatar
Pierre Kraemer committed
547
	MapHandlerGen* map = m_schnapps->getSelectedMap();
548

Pierre Kraemer's avatar
Pierre Kraemer committed
549
	const MapParameters& p = h_parameterSet[map];
Pierre Kraemer's avatar
Pierre Kraemer committed
550 551 552 553
	if(p.positionAttribute.isValid())
	{
		unsigned int orbit = m_schnapps->getCurrentOrbit();
		CellSelectorGen* selector = m_schnapps->getSelectedSelector(orbit);
554
		if (selector != NULL)
Pierre Kraemer's avatar
Pierre Kraemer committed
555
		{
556 557 558 559 560 561 562 563
			switch(orbit)
			{
				case VERTEX : {
					CellSelector<PFP2::MAP, VERTEX>* cs = static_cast<CellSelector<PFP2::MAP, VERTEX>*>(selector);
					const std::vector<Vertex>& selectedCells = cs->getSelectedCells();
					std::vector<PFP2::VEC3> selectedPoints;
					for(std::vector<Vertex>::const_iterator v = selectedCells.begin(); v != selectedCells.end(); ++v)
						selectedPoints.push_back(p.positionAttribute[*v]);
564
					m_selectedVerticesVBO->updateData<3>(selectedPoints);
565 566
					m_selectedVertices_dirty = false;
					break;
Pierre Kraemer's avatar
Pierre Kraemer committed
567
				}
568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589
				case EDGE : {
					PFP2::MAP* m = static_cast<MapHandler<PFP2>*>(map)->getMap();

					CellSelector<PFP2::MAP, EDGE>* cs = static_cast<CellSelector<PFP2::MAP, EDGE>*>(selector);
					const std::vector<Edge>& selectedCells = cs->getSelectedCells();

					m_selectedEdgesDrawer->newList(GL_COMPILE);
					m_selectedEdgesDrawer->lineWidth(3.0f);
					m_selectedEdgesDrawer->color3f(p.color.redF(), p.color.greenF(), p.color.blueF());
					m_selectedEdgesDrawer->begin(GL_LINES);
					for(std::vector<Edge>::const_iterator e = selectedCells.begin(); e != selectedCells.end(); ++e)
					{
						m_selectedEdgesDrawer->vertex(p.positionAttribute[(*e).dart]);
						m_selectedEdgesDrawer->vertex(p.positionAttribute[m->phi1((*e).dart)]);
					}
					m_selectedEdgesDrawer->end();
					m_selectedEdgesDrawer->endList();
					m_selectedEdges_dirty = false;
					break;
				}
				case FACE : {
					PFP2::MAP* m = static_cast<MapHandler<PFP2>*>(map)->getMap();
Pierre Kraemer's avatar
Pierre Kraemer committed
590

591 592
					CellSelector<PFP2::MAP, FACE>* cs = static_cast<CellSelector<PFP2::MAP, FACE>*>(selector);
					const std::vector<Face>& selectedCells = cs->getSelectedCells();
593

594 595 596 597
					m_selectedFacesDrawer->newList(GL_COMPILE);
					m_selectedFacesDrawer->color3f(p.color.redF(), p.color.greenF(), p.color.blueF());
					m_selectedFacesDrawer->begin(GL_TRIANGLES);
					for(std::vector<Face>::const_iterator f = selectedCells.begin(); f != selectedCells.end(); ++f)
598
					{
599 600 601 602 603 604 605 606 607 608 609 610 611 612 613
						Dart d = m->phi1((*f).dart);
						Dart e = m->phi1(d);
						do
						{
							m_selectedFacesDrawer->vertex(p.positionAttribute[f->dart]);
							m_selectedFacesDrawer->vertex(p.positionAttribute[d]);
							m_selectedFacesDrawer->vertex(p.positionAttribute[e]);
							d = e;
							e = m->phi1(d);
						} while (e != f->dart);
					}
					m_selectedFacesDrawer->end();
					m_selectedFacesDrawer->endList();
					m_selectedFaces_dirty = false;
					break;
Pierre Kraemer's avatar
Pierre Kraemer committed
614
				}
Pierre Kraemer's avatar
Pierre Kraemer committed
615 616 617
			}
		}
	}
618 619 620 621 622
	const QList<View*>& lv = this->getLinkedViews();
	foreach(View* v, lv)
	{
			v->updateGL();
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
623 624
}

625 626 627 628 629 630 631 632 633 634 635 636 637
void Surface_Selection_Plugin::updateRemovedSelector(unsigned int orbit, const QString& name)
{
	updateSelectedCellsRendering();
	MapHandlerGen* m = m_schnapps->getSelectedMap();
	View* v = m_schnapps->getSelectedView();
	if (v && m)
	{
		if (v->isLinkedToMap(m))
			v->updateGL();
	}


}
638 639 640



Pierre Kraemer's avatar
Pierre Kraemer committed
641
void Surface_Selection_Plugin::selectedMapAttributeAdded(unsigned int orbit, const QString& name)
642
{
Pierre Kraemer's avatar
Pierre Kraemer committed
643
	if(orbit == VERTEX)
644 645 646
		m_dockTab->addVertexAttribute(name);
}

Pierre Kraemer's avatar
Pierre Kraemer committed
647 648 649 650 651 652 653 654 655 656 657
void Surface_Selection_Plugin::selectedMapAttributeModified(unsigned int orbit, const QString &name)
{
	if(orbit == VERTEX)
	{
		MapHandlerGen* map = static_cast<MapHandlerGen*>(QObject::sender());
		const MapParameters& p = h_parameterSet[map];
		if(p.positionAttribute.isValid() && QString::fromStdString(p.positionAttribute.name()) == name)
			updateSelectedCellsRendering();
	}
}

658 659 660 661 662 663 664 665
void Surface_Selection_Plugin::selectedMapConnectivityModified()
{
	MapHandlerGen* map = static_cast<MapHandlerGen*>(QObject::sender());
	const MapParameters& p = h_parameterSet[map];
	if(p.positionAttribute.isValid())
		updateSelectedCellsRendering();
}

666 667 668 669
void Surface_Selection_Plugin::selectedMapBoundingBoxModified()
{
	MapHandlerGen* map = static_cast<MapHandlerGen*>(QObject::sender());
	m_selectionRadiusBase = map->getBBdiagSize() / 50.0f;
670 671
	h_parameterSet[map].basePSradius = map->getBBdiagSize() / (std::sqrt(map->getNbOrbits(EDGE)));
	h_parameterSet[map].verticesScaleFactor = m_dockTab->slider_verticesScaleFactor->value() / 50.0f;
672 673
}

674 675 676 677




678
void Surface_Selection_Plugin::changePositionAttribute(const QString& map, const QString& name)
679 680
{
	MapHandlerGen* m = m_schnapps->getMap(map);
681
	if(m)
682
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
683 684
		MapHandler<PFP2>* mh = static_cast<MapHandler<PFP2>*>(m);
		h_parameterSet[m].positionAttribute = mh->getAttribute<PFP2::VEC3, VERTEX>(name);
685 686 687
		if(m->isSelectedMap())
			m_dockTab->updateMapParameters();
	}
688 689 690 691 692 693
	View* v = m_schnapps->getSelectedView();
	if (v)
	{
		if (v->isLinkedToMap(m))
			v->updateGL();
	}
694 695
}

696 697 698 699 700
void Surface_Selection_Plugin::changeNormalAttribute(const QString& map, const QString& name)
{
	MapHandlerGen* m = m_schnapps->getMap(map);
	if(m)
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
701 702
		MapHandler<PFP2>* mh = static_cast<MapHandler<PFP2>*>(m);
		h_parameterSet[m].normalAttribute = mh->getAttribute<PFP2::VEC3, VERTEX>(name);
703 704 705
		if(m->isSelectedMap())
			m_dockTab->updateMapParameters();
	}
706 707 708 709 710 711
	View* v = m_schnapps->getSelectedView();
	if (v)
	{
		if (v->isLinkedToMap(m))
			v->updateGL();
	}
712 713 714
}

void Surface_Selection_Plugin::changeSelectionMethod(const QString& map, unsigned int method)
715 716
{
	MapHandlerGen* m = m_schnapps->getMap(map);
717
	if(m)
718 719 720
	{
		h_parameterSet[m].selectionMethod = SelectionMethod(method);
		if(m->isSelectedMap())
721 722
			m_dockTab->updateMapParameters();
	}
723 724 725 726 727 728
	View* v = m_schnapps->getSelectedView();
	if (v)
	{
		if (v->isLinkedToMap(m))
			v->updateGL();
	}
729
}
Sylvain Thery's avatar
Sylvain Thery committed
730 731 732 733 734 735 736 737 738 739 740

void Surface_Selection_Plugin::changeVerticesScaleFactor(const QString& map, float f)
{
	DEBUG_SLOT();
	MapHandlerGen* m = m_schnapps->getMap(map);
	if (m)
	{
		h_parameterSet[m].verticesScaleFactor = f;
		if (m->isSelectedMap())
			m_dockTab->updateMapParameters();
	}
741

742 743 744 745 746 747
	View* v = m_schnapps->getSelectedView();
	if (v)
	{
		if (v->isLinkedToMap(m))
			v->updateGL();
	}
Sylvain Thery's avatar
Sylvain Thery committed
748 749 750 751 752 753 754 755 756
}

void Surface_Selection_Plugin::changeVerticesBaseSize(const QString& map, float f)
{
	DEBUG_SLOT();
	MapHandlerGen* m = m_schnapps->getMap(map);
	if (m)
	{
		h_parameterSet[m].basePSradius = f;
Sylvain Thery's avatar
Sylvain Thery committed
757 758 759
		if (m->isSelectedMap())
			m_dockTab->updateMapParameters();
	}
760

761 762 763 764 765 766
	View* v = m_schnapps->getSelectedView();
	if (v)
	{
		if (v->isLinkedToMap(m))
			v->updateGL();
	}
Sylvain Thery's avatar
Sylvain Thery committed
767 768 769 770 771 772 773 774 775 776 777 778
}


void Surface_Selection_Plugin::changeSelectedColor( const QString& map, const QString& col)
{
	MapHandlerGen* m = m_schnapps->getMap(map);
	if (m)
	{
		h_parameterSet[m].color = QColor(col);
		if (m->isSelectedMap())
			m_dockTab->updateMapParameters();

779 780 781 782 783 784
		View* v = m_schnapps->getSelectedView();
		if (v)
		{
			if (v->isLinkedToMap(m))
				v->updateGL();
		}
Sylvain Thery's avatar
Sylvain Thery committed
785 786 787
	}
}

788 789 790 791 792 793 794 795 796 797
void Surface_Selection_Plugin::clearSelection(const QString& map, unsigned int orbit, const QString& selectorName)
{
	MapHandlerGen* m = m_schnapps->getMap(map);
	if (m)
	{
		CellSelectorGen* selector = m->getCellSelector(orbit, selectorName);
		if (selector)
		{
			selector->clearAll();
		}
Sylvain Thery's avatar
Sylvain Thery committed
798

799 800 801 802 803 804 805 806
		View* v = m_schnapps->getSelectedView();
		if (v)
		{
			if (v->isLinkedToMap(m))
				v->updateGL();
		}
	}
}
Sylvain Thery's avatar
Sylvain Thery committed
807 808


Sylvain Thery's avatar
Sylvain Thery committed
809 810 811 812 813
#if CGOGN_QT_DESIRED_VERSION == 5
	Q_PLUGIN_METADATA(IID "CGoGN.SCHNapps.Plugin")
#else
	Q_EXPORT_PLUGIN2(Surface_Selection_Plugin, Surface_Selection_Plugin)
#endif
814 815 816 817 818


} // namespace SCHNApps

} // namespace CGoGN