surface_selection.cpp 25.6 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),
27
	m_normalAngleThreshold(10)
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 43
	m_selectedFacesDrawer = new Utils::Drawer();

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

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

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

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

Pierre Kraemer's avatar
Pierre Kraemer committed
56 57 58 59 60
	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&)));
61
		connect(cur, SIGNAL(connectivityModified()), this, SLOT(selectedMapConnectivityModified()));
62
		connect(cur, SIGNAL(boundingBoxModified()), this, SLOT(selectedMapBoundingBoxModified()));
63 64
		connect(cur, SIGNAL(cellSelectorRemoved(unsigned int, const QString&)), this, SLOT(updateRemovedSelector(unsigned int, const QString&)));

65
		m_selectionRadiusBase = cur->getBBdiagSize() / 50.0f;
Sylvain Thery's avatar
Sylvain Thery committed
66 67
		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
68
	}
69 70 71 72 73 74 75 76

	m_dockTab->updateMapParameters();

	return true;
}

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

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

	delete m_selectedEdgesDrawer;
	delete m_selectedFacesDrawer;
	delete m_selectingCellDrawer;

89
	delete m_selectionSphereVBO;
90

Pierre Kraemer's avatar
Pierre Kraemer committed
91
	disconnect(m_schnapps, SIGNAL(selectedViewChanged(View*, View*)), this, SLOT(selectedViewChanged(View*, View*)));
92
	disconnect(m_schnapps, SIGNAL(mapRemoved(MapHandlerGen*)), this, SLOT(mapRemoved(MapHandlerGen*)));
93 94
}

95 96
void Surface_Selection_Plugin::drawMap(View* view, MapHandlerGen* map)
{
97
	if(map->isSelectedMap())
98
	{
99 100 101
		glEnable(GL_POLYGON_OFFSET_FILL);
		glPolygonOffset(-1.0f, -1.0f);

102
		const MapParameters& p = h_parameterSet[map];
103 104 105 106 107 108
		if(p.positionAttribute.isValid())
		{
			unsigned int orbit = m_schnapps->getCurrentOrbit();
			CellSelectorGen* selector = m_schnapps->getSelectedSelector(orbit);
			if(selector)
			{
Pierre Kraemer's avatar
Pierre Kraemer committed
109
				unsigned int nbCells = map->getGenericMap()->getNbCells(orbit);
110
				switch(orbit)
111
				{
112
					case VERTEX : {
113 114 115 116
						if (selector->getNbSelectedCells() > 0)
						{
							if (m_selectedVertices_dirty)
								updateSelectedCellsRendering();
117

118
							m_pointSprite->setAttributePosition(m_selectedVerticesVBO);
Sylvain Thery's avatar
Sylvain Thery committed
119 120
							const QColor& col = p.color;
							m_pointSprite->setColor(Geom::Vec4f(col.redF(), col.greenF(), col.blueF(), 0.0f));
121
							m_pointSprite->setLightPosition(CGoGN::Geom::Vec3f(0.0f, 0.0f, 1.0f));
Sylvain Thery's avatar
Sylvain Thery committed
122
							m_pointSprite->setSize(p.basePSradius*p.verticesScaleFactor);
123 124 125 126 127

							m_pointSprite->enableVertexAttribs();
							glDrawArrays(GL_POINTS, 0, selector->getNbSelectedCells());
							m_pointSprite->disableVertexAttribs();
						}
128

129
						if(m_selecting && m_selectingVertex.valid())
130 131
						{
							std::vector<PFP2::VEC3> selectionPoint;
Pierre Kraemer's avatar
Pierre Kraemer committed
132
							selectionPoint.push_back(p.positionAttribute[m_selectingVertex]);
133 134 135 136 137 138 139 140
							m_selectionSphereVBO->updateData(selectionPoint);

							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 159
									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 : {
160 161 162 163 164 165
						if (selector->getNbSelectedCells() > 0)
						{
							if (m_selectedEdges_dirty)
								updateSelectedCellsRendering();
							m_selectedEdgesDrawer->callList();
						}
Pierre Kraemer's avatar
Pierre Kraemer committed
166

167
						if(m_selecting && m_selectingEdge.valid())
Pierre Kraemer's avatar
Pierre Kraemer committed
168 169 170
						{
							switch(p.selectionMethod)
							{
171
								case NormalAngle :
Pierre Kraemer's avatar
Pierre Kraemer committed
172
								case SingleCell : {
Pierre Kraemer's avatar
Pierre Kraemer committed
173 174 175 176 177
									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);
178 179
									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
180 181
									m_selectingCellDrawer->end();
									m_selectingCellDrawer->endList();
Pierre Kraemer's avatar
Pierre Kraemer committed
182 183 184
									break;
								}
								case WithinSphere : {
185
//									PFP2::MAP* m = static_cast<MapHandler<PFP2>*>(map)->getMap();
186
									std::vector<PFP2::VEC3> selectionPoint;
187
									selectionPoint.push_back(p.positionAttribute[m_selectingEdge.dart]);
188 189 190 191 192
									m_selectionSphereVBO->updateData(selectionPoint);

									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));
193
									m_pointSprite->setSize(m_selectionRadiusBase * m_selectionRadiusCoeff);
194 195 196 197 198 199 200

									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
201 202 203 204
									break;
								}
							}
						}
205 206 207
						break;
					}
					case FACE : {
208 209 210 211 212 213
						if (selector->getNbSelectedCells() > 0)
						{
							if (m_selectedFaces_dirty)
								updateSelectedCellsRendering();
							m_selectedFacesDrawer->callList();
						}
Pierre Kraemer's avatar
Pierre Kraemer committed
214

215
						if(m_selecting && m_selectingFace.valid())
Pierre Kraemer's avatar
Pierre Kraemer committed
216 217 218
						{
							switch(p.selectionMethod)
							{
219
								case NormalAngle :
Pierre Kraemer's avatar
Pierre Kraemer committed
220
								case SingleCell : {
Pierre Kraemer's avatar
Pierre Kraemer committed
221 222
									PFP2::MAP* m = static_cast<MapHandler<PFP2>*>(map)->getMap();
									m_selectingCellDrawer->newList(GL_COMPILE_AND_EXECUTE);
223
									m_selectingCellDrawer->lineWidth(6.0f);
Pierre Kraemer's avatar
Pierre Kraemer committed
224
									m_selectingCellDrawer->color3f(0.0f, 0.0f, 1.0f);
225 226 227 228 229 230 231
									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
232 233
									m_selectingCellDrawer->end();
									m_selectingCellDrawer->endList();
Pierre Kraemer's avatar
Pierre Kraemer committed
234 235 236
									break;
								}
								case WithinSphere : {
237
//									PFP2::MAP* m = static_cast<MapHandler<PFP2>*>(map)->getMap();
Sylvain Thery's avatar
Sylvain Thery committed
238

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

									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));
246
									m_pointSprite->setSize(m_selectionRadiusBase * m_selectionRadiusCoeff);
247 248 249 250 251 252 253

									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
254 255 256 257
									break;
								}
							}
						}
258 259
						break;
					}
260 261
				}
			}
262
		}
263
	}
264
	glDisable(GL_POLYGON_OFFSET_FILL);
265 266
}

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

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

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

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

293 294 295



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

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

void Surface_Selection_Plugin::mouseMove(View* view, QMouseEvent* event)
{
	if(m_selecting)
	{
		MapHandlerGen* mh = m_schnapps->getSelectedMap();
440
		const MapParameters& p = h_parameterSet[mh];
441 442
		if(p.positionAttribute.isValid())
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
443 444 445 446 447 448 449 450 451
			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
452
				// compute coordinates of ray in map Frame
Pierre Kraemer's avatar
Pierre Kraemer committed
453 454
				qglviewer::Vec orig_inv = mh->getFrame()->coordinatesOf(orig);
				qglviewer::Vec dir_inv = mh->getFrame()->transformOf(dir);
Sylvain Thery's avatar
Sylvain Thery committed
455 456 457 458 459 460
				// 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
461

Pierre Kraemer's avatar
Pierre Kraemer committed
462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478
				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;
					}
				}
479 480 481 482 483 484 485 486 487 488 489

				view->updateGL();
			}
		}
	}
}

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

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



void Surface_Selection_Plugin::selectedMapChanged(MapHandlerGen *prev, MapHandlerGen *cur)
{
	m_dockTab->updateMapParameters();
Pierre Kraemer's avatar
Pierre Kraemer committed
523 524 525 526
	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&)));
527
		disconnect(prev, SIGNAL(connectivityModified()), this, SLOT(selectedMapConnectivityModified()));
528
		disconnect(prev, SIGNAL(boundingBoxModified()), this, SLOT(selectedMapBoundingBoxModified()));
529
		disconnect(prev, SIGNAL(cellSelectorRemoved(unsigned int, const QString&)), this, SLOT(updateRemovedSelector(unsigned int, const QString&)));
Pierre Kraemer's avatar
Pierre Kraemer committed
530
	}
531
	if(cur)
Pierre Kraemer's avatar
Pierre Kraemer committed
532 533 534
	{
		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&)));
535
		connect(cur, SIGNAL(connectivityModified()), this, SLOT(selectedMapConnectivityModified()));
536
		connect(cur, SIGNAL(boundingBoxModified()), this, SLOT(selectedMapBoundingBoxModified()));
537
		connect(cur, SIGNAL(cellSelectorRemoved(unsigned int, const QString&)), this, SLOT(updateRemovedSelector(unsigned int, const QString&)));
538
		m_selectionRadiusBase = cur->getBBdiagSize() / 50.0f;
Sylvain Thery's avatar
Sylvain Thery committed
539 540
		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
541
	}
542 543
}

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

Pierre Kraemer's avatar
Pierre Kraemer committed
548
	const MapParameters& p = h_parameterSet[map];
Pierre Kraemer's avatar
Pierre Kraemer committed
549 550 551 552
	if(p.positionAttribute.isValid())
	{
		unsigned int orbit = m_schnapps->getCurrentOrbit();
		CellSelectorGen* selector = m_schnapps->getSelectedSelector(orbit);
553
		if (selector != NULL)
Pierre Kraemer's avatar
Pierre Kraemer committed
554
		{
555 556 557 558 559 560 561 562 563 564 565
			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]);
					m_selectedVerticesVBO->updateData(selectedPoints);
					m_selectedVertices_dirty = false;
					break;
Pierre Kraemer's avatar
Pierre Kraemer committed
566
				}
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(1.0f, 0.0f, 0.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