topoRender.hpp 15.5 KB
Newer Older
Pierre Kraemer's avatar
Pierre Kraemer committed
1
2
3
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps  *
* version 0.1                                                                  *
4
* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg           *
Pierre Kraemer's avatar
Pierre Kraemer committed
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
*                                                                              *
* This library is free software; you can redistribute it and/or modify it      *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your     *
* option) any later version.                                                   *
*                                                                              *
* This library is distributed in the hope that it will be useful, but WITHOUT  *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or        *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License  *
* for more details.                                                            *
*                                                                              *
* You should have received a copy of the GNU Lesser General Public License     *
* along with this library; if not, write to the Free Software Foundation,      *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.           *
*                                                                              *
20
* Web site: http://cgogn.unistra.fr/                                           *
Pierre Kraemer's avatar
Pierre Kraemer committed
21
22
23
24
25
26
27
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

#include "Geometry/vector_gen.h"
#include "Topology/generic/autoAttributeHandler.h"
#include "Topology/generic/dartmarker.h"
28
29
30
#include "Topology/generic/parameters.h"

#include "Topology/map/embeddedMap2.h"
31
#include "Topology/gmap/embeddedGMap2.h"
Pierre Kraemer's avatar
Pierre Kraemer committed
32

33
#include "Algo/Geometry/basic.h"
34
#include "Geometry/distances.h"
35
#include "Algo/Geometry/centroid.h"
36
#include "Algo/Geometry/normal.h"
37

38
#include "Topology/generic/mapBrowser.h"
39

Pierre Kraemer's avatar
Pierre Kraemer committed
40
41
namespace CGoGN
{
42

Pierre Kraemer's avatar
Pierre Kraemer committed
43
44
namespace Algo
{
45

Pierre Kraemer's avatar
Pierre Kraemer committed
46
47
namespace Render
{
48

Sylvain Thery's avatar
Sylvain Thery committed
49
namespace GL2
Pierre Kraemer's avatar
Pierre Kraemer committed
50
51
{

52
53
54
55
56

template<typename PFP>
void TopoRender::updateDataBoundary(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& positions, float ke, float kf,float ns)
{
	m_normalShift = ns;
Sylvain Thery's avatar
Sylvain Thery committed
57
58
59
//	SelectorDartBoundary<typename PFP::MAP> sdb(map);
//	MapBrowserSelector mbs(map,sdb);
	MapBrowserSelector mbs(map,SelectorDartBoundary<typename PFP::MAP>(map));
60
61
62
63
64
65
66
67
68
	map.setBrowser(&mbs);

	updateData<PFP>(map,positions, ke, kf,true);

	map.setBrowser(NULL);
	m_normalShift = 0.0f;
}


Pierre Kraemer's avatar
Pierre Kraemer committed
69
template<typename PFP>
70
void TopoRender::updateData(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& positions, float ke, float kf, bool withBoundary)
Pierre Kraemer's avatar
Pierre Kraemer committed
71
{
72
73
74
	Map2* ptrMap2 = dynamic_cast<Map2*>(&map);
	if (ptrMap2 != NULL)
	{
75
		updateDataMap<PFP>(map, positions, ke, kf, withBoundary);
Pierre Kraemer's avatar
Pierre Kraemer committed
76
		return;
77
78
79
80
	}
	GMap2* ptrGMap2 = dynamic_cast<GMap2*>(&map);
	if (ptrGMap2 != NULL)
	{
81
		updateDataGMap<PFP>(map, positions, ke, kf, withBoundary);
Pierre Kraemer's avatar
Pierre Kraemer committed
82
		return;
83
84
85
	}
}

Pierre Kraemer's avatar
Pierre Kraemer committed
86
template<typename PFP>
87
void TopoRender::updateDataMap(typename PFP::MAP& mapx, const VertexAttribute<typename PFP::VEC3>& positions, float ke, float kf, bool withBoundary)
Pierre Kraemer's avatar
Pierre Kraemer committed
88
{
89
90
	Map2& map = reinterpret_cast<Map2&>(mapx);

Pierre Kraemer's avatar
Pierre Kraemer committed
91
92
93
94
	typedef typename PFP::VEC3 VEC3;
	typedef typename PFP::REAL REAL;

	std::vector<Dart> vecDarts;
95
	vecDarts.reserve(map.getNbDarts());  // no problem dart is int: no problem of memory
Pierre Kraemer's avatar
Pierre Kraemer committed
96

Sylvain Thery's avatar
Sylvain Thery committed
97
98
	m_attIndex = map.template getAttribute<unsigned int, DART>("dart_index");

Sylvain Thery's avatar
Sylvain Thery committed
99
	if (!m_attIndex.isValid())
Pierre Kraemer's avatar
Pierre Kraemer committed
100
		m_attIndex  = map.template addAttribute<unsigned int, DART>("dart_index");
Pierre Kraemer's avatar
Pierre Kraemer committed
101
102
103

	for(Dart d = map.begin(); d!= map.end(); map.next(d))
	{
104
		if (withBoundary || !map.isBoundaryMarked2(d))
Pierre Kraemer's avatar
Pierre Kraemer committed
105
			vecDarts.push_back(d);
106

Pierre Kraemer's avatar
Pierre Kraemer committed
107
108
109
110
	}
	m_nbDarts = vecDarts.size();

	// debut phi1
111
	DartAutoAttribute<VEC3> fv1(map);
Pierre Kraemer's avatar
Pierre Kraemer committed
112
	// fin phi1
113
	DartAutoAttribute<VEC3> fv11(map);
Pierre Kraemer's avatar
Pierre Kraemer committed
114
	// phi2
115
	DartAutoAttribute<VEC3> fv2(map);
Pierre Kraemer's avatar
Pierre Kraemer committed
116

117
118
119
	m_vbo3->bind();
	glBufferData(GL_ARRAY_BUFFER, 2*m_nbDarts*sizeof(VEC3), 0, GL_STREAM_DRAW);
	GLvoid* ColorDartsBuffer = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
Pierre Kraemer's avatar
Pierre Kraemer committed
120
121
	VEC3* colorDartBuf = reinterpret_cast<VEC3*>(ColorDartsBuffer);

122
123
124
125
126
127
128
129
130
//	m_vbo0->bind();
//	glBufferData(GL_ARRAY_BUFFER, 2*m_nbDarts*sizeof(VEC3), 0, GL_STREAM_DRAW);
//	GLvoid* PositionDartsBuffer = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
//	VEC3* positionDartBuf = reinterpret_cast<VEC3*>(PositionDartsBuffer);

	if (m_bufferDartPosition!=NULL)
		delete m_bufferDartPosition;
	m_bufferDartPosition = new Geom::Vec3f[2*m_nbDarts];
	VEC3* positionDartBuf = reinterpret_cast<VEC3*>(m_bufferDartPosition);
Pierre Kraemer's avatar
Pierre Kraemer committed
131

132
133
	std::vector<VEC3> vecPos;
	vecPos.reserve(16);
Pierre Kraemer's avatar
Pierre Kraemer committed
134

135
136
	unsigned int indexDC=0;

Pierre Kraemer's avatar
Pierre Kraemer committed
137
138
139
140
141
142
	DartMarker mf(map);
	for(std::vector<Dart>::iterator id = vecDarts.begin(); id!= vecDarts.end(); id++)
	{
		Dart d = *id;
		if (!mf.isMarked(d))
		{
143
			vecPos.clear();
144
			if (!map.isBoundaryMarked2(d))
Pierre Kraemer's avatar
Pierre Kraemer committed
145
			{
146
147
148
149
150
151
152
153
				VEC3 center = Algo::Surface::Geometry::faceCentroidELW<PFP>(mapx,d,positions);
				float k = 1.0f - kf;
				Dart dd = d;
				do
				{
					vecPos.push_back(center*k + positions[dd]*kf);
					dd = map.phi1(dd);
				} while (dd != d);
154

155

156
				if (m_normalShift > 0.0f)
157
				{
158
159
160
161
162
					VEC3 normal = Algo::Surface::Geometry::newellNormal<PFP>(mapx,d,positions);
					for (typename std::vector<VEC3>::iterator pit = vecPos.begin(); pit != vecPos.end(); ++pit)
					{
						*pit -= normal*m_normalShift;
					}
163
164
				}

165
166
				unsigned int nb = vecPos.size();
				vecPos.push_back(vecPos.front()); // copy the first for easy computation on next loop
Pierre Kraemer's avatar
Pierre Kraemer committed
167

168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
				k = 1.0f - ke;
				for (unsigned int i = 0; i < nb; ++i)
				{

					VEC3 P = vecPos[i]*ke + vecPos[i+1]*k;
					VEC3 Q = vecPos[i+1]*ke + vecPos[i]*k;

					m_attIndex[d] = indexDC;
					indexDC+=2;
					*positionDartBuf++ = P;
					*positionDartBuf++ = Q;
					*colorDartBuf++ = m_dartsColor;
					*colorDartBuf++ = m_dartsColor;
					VEC3 f = P*0.5f + Q*0.5f;
					fv2[d] = f;
					f = P*0.1f + Q*0.9f;
					fv1[d] = f;
					f = P*0.9f + Q*0.1f;
					fv11[d] = f;
					d = map.phi1(d);
				}
				mf.markOrbit<FACE>(d);
			}
			else if (withBoundary)
Pierre Kraemer's avatar
Pierre Kraemer committed
192
			{
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232

				Dart dd = d;
				do
				{
					Dart ee = mapx.phi2(dd);
					VEC3 normal = Algo::Surface::Geometry::newellNormal<PFP>(mapx,ee,positions);
					VEC3 vd = Algo::Surface::Geometry::vectorOutOfDart<PFP>(mapx,ee,positions);
					VEC3 v = vd ^ normal;
					v.normalize();
					VEC3 P = positions[map.phi1(ee)] + v* m_boundShift;
					vecPos.push_back(P);
					dd = map.phi1(dd);
					ee = mapx.phi2(dd);
					P = positions[map.phi1(ee)] + v* m_boundShift;
					vecPos.push_back(P);
				} while (dd != d);

				unsigned int nb = vecPos.size()/2;
				float k = 1.0f - ke;
				for (unsigned int i = 0; i < nb; ++i)
				{

					VEC3 P = vecPos[2*i]*ke + vecPos[2*i+1]*k;
					VEC3 Q = vecPos[2*i+1]*ke + vecPos[2*i]*k;

					m_attIndex[d] = indexDC;
					indexDC+=2;
					*positionDartBuf++ = P;
					*positionDartBuf++ = Q;
					*colorDartBuf++ = m_dartsBoundaryColor;
					*colorDartBuf++ = m_dartsBoundaryColor;
					VEC3 f = P*0.5f + Q*0.5f;
					fv2[d] = f;
					f = P*0.1f + Q*0.9f;
					fv1[d] = f;
					f = P*0.9f + Q*0.1f;
					fv11[d] = f;
					d = map.phi1(d);
				}
				mf.markOrbit<FACE>(d);
Pierre Kraemer's avatar
Pierre Kraemer committed
233
234
235
236
			}
		}
	}

237
	m_vbo0->bind();
238
239
	glBufferData(GL_ARRAY_BUFFER, 2*m_nbDarts*sizeof(VEC3), m_bufferDartPosition, GL_STREAM_DRAW);
//	glUnmapBuffer(GL_ARRAY_BUFFER);
Pierre Kraemer's avatar
Pierre Kraemer committed
240

241
242
	m_vbo3->bind();
	glUnmapBuffer(GL_ARRAY_BUFFER);
Pierre Kraemer's avatar
Pierre Kraemer committed
243

244
245
246
	m_vbo1->bind();
	glBufferData(GL_ARRAY_BUFFER, 2*m_nbDarts*sizeof(typename PFP::VEC3), 0, GL_STREAM_DRAW);
	GLvoid* PositionBuffer1 = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
Pierre Kraemer's avatar
Pierre Kraemer committed
247

248
249
250
	m_vbo2->bind();
	glBufferData(GL_ARRAY_BUFFER, 2*m_nbDarts*sizeof(typename PFP::VEC3), 0, GL_STREAM_DRAW);
	GLvoid* PositionBuffer2 = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
Pierre Kraemer's avatar
Pierre Kraemer committed
251
252
253
254
255
256
257
258
259
260

	VEC3* positionF1 = reinterpret_cast<VEC3*>(PositionBuffer1);
	VEC3* positionF2 = reinterpret_cast<VEC3*>(PositionBuffer2);

	m_nbRel2 =0;
	for(std::vector<Dart>::iterator id = vecDarts.begin(); id!= vecDarts.end(); id++)
	{
		Dart d = *id;

		Dart e = map.phi2(d);
261

Sylvain Thery's avatar
Sylvain Thery committed
262
//		if (good(e) && (e.index > d.index))
263
		if ( (withBoundary || !map.isBoundaryMarked2(e)) && (e.index > d.index))
Pierre Kraemer's avatar
Pierre Kraemer committed
264
265
266
267
268
269
270
271
272
273
		{
			*positionF2++ = fv2[d];
			*positionF2++ = fv2[e];
			m_nbRel2++;
		}

		e = map.phi1(d);
		*positionF1++ = fv1[d];
		*positionF1++ = fv11[e];
	}
Sylvain Thery's avatar
Sylvain Thery committed
274
	m_nbRel1 = vecDarts.size();
Pierre Kraemer's avatar
Pierre Kraemer committed
275

276
277
278
279
280
	m_vbo1->bind();
	glUnmapBuffer(GL_ARRAY_BUFFER);

	m_vbo2->bind();
	glUnmapBuffer(GL_ARRAY_BUFFER);
Pierre Kraemer's avatar
Pierre Kraemer committed
281
282
283
}

template<typename PFP>
284
void TopoRender::updateDataGMap(typename PFP::MAP& mapx, const VertexAttribute<typename PFP::VEC3>& positions, float ke, float kf, bool withBoundary)
Pierre Kraemer's avatar
Pierre Kraemer committed
285
{
Sylvain Thery's avatar
Sylvain Thery committed
286
	GMap2& map = dynamic_cast<GMap2&>(mapx);
287

Pierre Kraemer's avatar
Pierre Kraemer committed
288
289
290
291
	typedef typename PFP::VEC3 VEC3;
	typedef typename PFP::REAL REAL;

	std::vector<Dart> vecDarts;
292
	vecDarts.reserve(map.getNbDarts()); // no problem dart is int: no problem of memory
Pierre Kraemer's avatar
Pierre Kraemer committed
293

Sylvain Thery's avatar
Sylvain Thery committed
294
	if (m_attIndex.map() != &map)
Pierre Kraemer's avatar
Pierre Kraemer committed
295
		m_attIndex  = map.template getAttribute<unsigned int, DART>("dart_index");
Sylvain Thery's avatar
Sylvain Thery committed
296

Sylvain Thery's avatar
Sylvain Thery committed
297
	if (!m_attIndex.isValid())
Pierre Kraemer's avatar
Pierre Kraemer committed
298
		m_attIndex  = map.template addAttribute<unsigned int, DART>("dart_index");
Sylvain Thery's avatar
Sylvain Thery committed
299

Pierre Kraemer's avatar
Pierre Kraemer committed
300
301
302

	for(Dart d = map.begin(); d!= map.end(); map.next(d))
	{
303
		if (withBoundary || !map.isBoundaryMarked2(d))
Pierre Kraemer's avatar
Pierre Kraemer committed
304
305
306
307
			vecDarts.push_back(d);
	}
	m_nbDarts = vecDarts.size();

308
	// debut phi1
309
	DartAutoAttribute<VEC3> fv1(map);
310
	// fin phi1
311
	DartAutoAttribute<VEC3> fv11(map);
312
	// phi2
313
	DartAutoAttribute<VEC3> fv2(map);
314
315
316
317

	m_vbo3->bind();
	glBufferData(GL_ARRAY_BUFFER, 4*m_nbDarts*sizeof(VEC3), 0, GL_STREAM_DRAW);
	GLvoid* ColorDartsBuffer = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
Pierre Kraemer's avatar
Pierre Kraemer committed
318
319
	VEC3* colorDartBuf = reinterpret_cast<VEC3*>(ColorDartsBuffer);

320
321
322
	m_vbo0->bind();
	glBufferData(GL_ARRAY_BUFFER, 4*m_nbDarts*sizeof(VEC3), 0, GL_STREAM_DRAW);
	GLvoid* PositionDartsBuffer = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
Pierre Kraemer's avatar
Pierre Kraemer committed
323
	VEC3* positionDartBuf = reinterpret_cast<VEC3*>(PositionDartsBuffer);
324

325
326
	std::vector<VEC3> vecPos;
	vecPos.reserve(16);
Pierre Kraemer's avatar
Pierre Kraemer committed
327

328
329
	unsigned int indexDC=0;

Pierre Kraemer's avatar
Pierre Kraemer committed
330
331
332
333
	DartMarker mf(map);
	for(std::vector<Dart>::iterator id = vecDarts.begin(); id!= vecDarts.end(); id++)
	{
		Dart d = *id;
334

Pierre Kraemer's avatar
Pierre Kraemer committed
335
336
		if (!mf.isMarked(d))
		{
337
			vecPos.clear();
338
339
340
			VEC3 center = Algo::Surface::Geometry::faceCentroidELW<PFP>(mapx,d,positions);
			
			float k = 1.0f - kf;
Pierre Kraemer's avatar
Pierre Kraemer committed
341
342
343
			Dart dd = d;
			do
			{
344
345
346
				vecPos.push_back(center*k + positions[dd]*kf);
				dd = map.phi1(dd);
			} while (dd != d);
Pierre Kraemer's avatar
Pierre Kraemer committed
347

348
349
350
351
352
353
354
355
356

			if (m_normalShift > 0.0f)
			{
				VEC3 normal = Algo::Surface::Geometry::newellNormal<PFP>(mapx,d,positions);
				for (typename std::vector<VEC3>::iterator pit = vecPos.begin(); pit != vecPos.end(); ++pit)
				{
					*pit -= normal*m_normalShift;
				}
			}
Pierre Kraemer's avatar
Pierre Kraemer committed
357
358
359
			unsigned int nb = vecPos.size();
			vecPos.push_back(vecPos.front()); // copy the first for easy computation on next loop

360

Pierre Kraemer's avatar
Pierre Kraemer committed
361
362
363
364
365
366
367
368
			k = 1.0f - ke;
			for (unsigned int i = 0; i < nb; ++i)
			{
				VEC3 P = vecPos[i]*ke + vecPos[i+1]*k;
				VEC3 Q = vecPos[i+1]*ke + vecPos[i]*k;
				VEC3 PP = REAL(0.52)*P + REAL(0.48)*Q;
				VEC3 QQ = REAL(0.52)*Q + REAL(0.48)*P;

369
370
				m_attIndex[d] = indexDC;
				indexDC+=2;
Pierre Kraemer's avatar
Pierre Kraemer committed
371
				*positionDartBuf++ = P;
372
				*colorDartBuf++ = m_dartsColor;
373
				*positionDartBuf++ = PP;
374
				*colorDartBuf++ = m_dartsColor;
Pierre Kraemer's avatar
Pierre Kraemer committed
375
				*positionDartBuf++ = Q;
376
				*colorDartBuf++ = m_dartsColor;
377
				*positionDartBuf++ = QQ;
378
				*colorDartBuf++ = m_dartsColor;
Pierre Kraemer's avatar
Pierre Kraemer committed
379

380
				VEC3 f = P*0.5f + PP*0.5f;
Pierre Kraemer's avatar
Pierre Kraemer committed
381
				fv2[d] = f;
382
				f = P*0.9f + PP*0.1f;
Pierre Kraemer's avatar
Pierre Kraemer committed
383
384
				fv1[d] = f;

385
386
387
388
389
				dd = map.beta0(d);
				f = Q*0.5f + QQ*0.5f;
				fv2[dd] = f;
				f = Q*0.9f + QQ*0.1f;
				fv1[dd] = f;
390
391
392
				m_attIndex[dd] = indexDC;
				indexDC+=2;

393

Pierre Kraemer's avatar
Pierre Kraemer committed
394
395
				d = map.phi1(d);
			}
Pierre Kraemer's avatar
Pierre Kraemer committed
396
			mf.markOrbit<FACE>(d);
Pierre Kraemer's avatar
Pierre Kraemer committed
397
398
399
		}
	}

400
401
	m_vbo0->bind();
	glUnmapBuffer(GL_ARRAY_BUFFER);
Pierre Kraemer's avatar
Pierre Kraemer committed
402

403
404
	m_vbo3->bind();
	glUnmapBuffer(GL_ARRAY_BUFFER);
Pierre Kraemer's avatar
Pierre Kraemer committed
405

406
407
408
	m_vbo1->bind();
	glBufferData(GL_ARRAY_BUFFER, 2*m_nbDarts*sizeof(typename PFP::VEC3), 0, GL_STREAM_DRAW);
	GLvoid* PositionBuffer1 = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
Pierre Kraemer's avatar
Pierre Kraemer committed
409

410
411
412
	m_vbo2->bind();
	glBufferData(GL_ARRAY_BUFFER, 2*m_nbDarts*sizeof(typename PFP::VEC3), 0, GL_STREAM_DRAW);
	GLvoid* PositionBuffer2 = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
Pierre Kraemer's avatar
Pierre Kraemer committed
413
414
415
416

	VEC3* positionF1 = reinterpret_cast<VEC3*>(PositionBuffer1);
	VEC3* positionF2 = reinterpret_cast<VEC3*>(PositionBuffer2);

417
	m_nbRel2 = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
418
419
420
421
	for(std::vector<Dart>::iterator id = vecDarts.begin(); id!= vecDarts.end(); id++)
	{
		Dart d = *id;
		Dart e = map.beta2(d);
422
423
//		if (d < e )
		if ( (withBoundary || !map.isBoundaryMarked2(e)) && (d < e ))
Pierre Kraemer's avatar
Pierre Kraemer committed
424
425
426
427
428
429
430
431
432
433
		{
			*positionF2++ = fv2[d];
			*positionF2++ = fv2[e];
			m_nbRel2++;
		}

		e = map.beta1(d);
		*positionF1++ = fv1[d];
		*positionF1++ = fv1[e];
	}
434
	m_nbRel1 = vecDarts.size()/2;
Pierre Kraemer's avatar
Pierre Kraemer committed
435

436
437
438
439
440
	m_vbo1->bind();
	glUnmapBuffer(GL_ARRAY_BUFFER);

	m_vbo2->bind();
	glUnmapBuffer(GL_ARRAY_BUFFER);
Pierre Kraemer's avatar
Pierre Kraemer committed
441
442
}

Sylvain Thery's avatar
Sylvain Thery committed
443
template<typename PFP>
444
void TopoRender::setDartsIdColor(typename PFP::MAP& map, bool withBoundary)
Sylvain Thery's avatar
Sylvain Thery committed
445
446
{
	m_vbo3->bind();
Pierre Kraemer's avatar
Pierre Kraemer committed
447
448
	float* colorBuffer = reinterpret_cast<float*>(glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE));
	unsigned int nb = 0;
Sylvain Thery's avatar
Sylvain Thery committed
449

Pierre Kraemer's avatar
Pierre Kraemer committed
450
	m_attIndex = map.template getAttribute<unsigned int, DART>("dart_index");
Sylvain Thery's avatar
Sylvain Thery committed
451
452
453
454
455
456
	if (!m_attIndex.isValid())
	{
		CGoGNerr << "Error attribute_dartIndex does not exist during TopoRender::picking" << CGoGNendl;
		return;
	}

Sylvain Thery's avatar
Sylvain Thery committed
457
458
	for (Dart d = map.begin(); d != map.end(); map.next(d))
	{
459
		if (withBoundary || !map.isBoundaryMarked2(d))
460
		{
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480

			if (nb < m_nbDarts)
			{
				float r,g,b;
				dartToCol(d, r,g,b);
				float* local = colorBuffer+3*m_attIndex[d]; // get the right position in VBO
				*local++ = r;
				*local++ = g;
				*local++ = b;
				*local++ = r;
				*local++ = g;
				*local++ = b;
				nb++;
			}
			else
			{
				CGoGNerr << "Error buffer too small for color picking (change the good parameter ?)" << CGoGNendl;
				CGoGNerr << "NB = " << nb << "   NBDARTs = "<< m_nbDarts<<CGoGNendl;
				break;
			}
Sylvain Thery's avatar
Sylvain Thery committed
481
482
483
484
485
486
		}
	}
	glUnmapBuffer(GL_ARRAY_BUFFER);
}

template<typename PFP>
487
Dart TopoRender::picking(typename PFP::MAP& map,int x, int y, bool withBoundary)
Sylvain Thery's avatar
Sylvain Thery committed
488
489
{
	pushColors();
490
	setDartsIdColor<PFP>(map,withBoundary);
Sylvain Thery's avatar
Sylvain Thery committed
491
492
493
494
495
496
	Dart d = pickColor(x,y);
	popColors();
	return d;

}

497
498
499


template<typename PFP>
500
Dart TopoRender::coneSelection(typename PFP::MAP& map, const Geom::Vec3f& rayA, const Geom::Vec3f& rayAB, float angle)
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
{
	float AB2 = rayAB*rayAB;
	Dart dFinal;
	double sin2 = sin(M_PI/180.0 * angle);
	sin2 = sin2*sin2;
	double dist2 = std::numeric_limits<double>::max();

	for(Dart d = map.begin(); d!=map.end(); map.next(d))
	{
		// get back position of segment PQ
		const Geom::Vec3f& P = m_bufferDartPosition[m_attIndex[d]];
		const Geom::Vec3f& Q =m_bufferDartPosition[m_attIndex[d]+1];
		float ld2 = Geom::squaredDistanceLine2Seg(rayA, rayAB, AB2, P, Q);
		Geom::Vec3f V = (P+Q)/2.0f - rayA;
		double d2 = double(V*V);
		double s2 = double(ld2) / d2;
		if (s2 < sin2)
		{
			if (d2<dist2)
			{
				dist2 = d2;
				dFinal = d;
			}
		}
	}
	return dFinal;
}

template<typename PFP>
530
Dart TopoRender::raySelection(typename PFP::MAP& map, const Geom::Vec3f& rayA, const Geom::Vec3f& rayAB, float dmax)
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
{
	float AB2 = rayAB*rayAB;
	Dart dFinal;
	float dm2 = dmax*dmax;
	double dist2 = std::numeric_limits<double>::max();

	for(Dart d = map.begin(); d!=map.end(); map.next(d))
	{
		// get back position of segment PQ
		const Geom::Vec3f& P = m_bufferDartPosition[m_attIndex[d]];
		const Geom::Vec3f& Q =m_bufferDartPosition[m_attIndex[d]+1];
		float ld2 = Geom::squaredDistanceLine2Seg(rayA, rayAB, AB2, P, Q);
		if (ld2<dm2)
		{
			Geom::Vec3f V = (P+Q)/2.0f - rayA;
			double d2 = double(V*V);
			if (d2<dist2)
			{
				dist2 = d2;
				dFinal = d;
			}
		}
	}
	return dFinal;
}


Sylvain Thery's avatar
Sylvain Thery committed
558
}//end namespace GL2
Pierre Kraemer's avatar
Pierre Kraemer committed
559
560
561
562
563
564

}//end namespace Algo

}//end namespace Render

}//end namespace CGoGN