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