topoRender.hpp 15.7 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 "Container/containerBrowser.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
//	SelectorDartBoundary<typename PFP::MAP> sdb(map);
//	MapBrowserSelector mbs(map,sdb);
59
60
61
62
63
64
65
//	MapBrowserSelector mbs(map,SelectorDartBoundary<typename PFP::MAP>(map));
//	map.setBrowser(&mbs);

	SelectorDartBoundary<typename PFP::MAP> sdb(map);
	DartContainerBrowserSelector browser(map,sdb);
	browser.enable();

66
67
68

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

69
70
	browser.disable();
//	map.setBrowser(NULL);
71
72
73
74
	m_normalShift = 0.0f;
}


Pierre Kraemer's avatar
Pierre Kraemer committed
75
template<typename PFP>
76
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
77
{
78
79
80
	Map2* ptrMap2 = dynamic_cast<Map2*>(&map);
	if (ptrMap2 != NULL)
	{
81
		updateDataMap<PFP>(map, positions, ke, kf, withBoundary);
Pierre Kraemer's avatar
Pierre Kraemer committed
82
		return;
83
84
85
86
	}
	GMap2* ptrGMap2 = dynamic_cast<GMap2*>(&map);
	if (ptrGMap2 != NULL)
	{
87
		updateDataGMap<PFP>(map, positions, ke, kf, withBoundary);
Pierre Kraemer's avatar
Pierre Kraemer committed
88
		return;
89
90
91
	}
}

Pierre Kraemer's avatar
Pierre Kraemer committed
92
template<typename PFP>
93
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
94
{
untereiner's avatar
untereiner committed
95
	//Map2& map = reinterpret_cast<Map2&>(mapx);
96

Pierre Kraemer's avatar
Pierre Kraemer committed
97
98
99
100
	typedef typename PFP::VEC3 VEC3;
	typedef typename PFP::REAL REAL;

	std::vector<Dart> vecDarts;
untereiner's avatar
untereiner committed
101
	vecDarts.reserve(mapx.getNbDarts());  // no problem dart is int: no problem of memory
Pierre Kraemer's avatar
Pierre Kraemer committed
102

untereiner's avatar
untereiner committed
103
	m_attIndex = mapx.template getAttribute<unsigned int, DART>("dart_index");
Sylvain Thery's avatar
Sylvain Thery committed
104

Sylvain Thery's avatar
Sylvain Thery committed
105
	if (!m_attIndex.isValid())
untereiner's avatar
untereiner committed
106
		m_attIndex  = mapx.template addAttribute<unsigned int, DART>("dart_index");
Pierre Kraemer's avatar
Pierre Kraemer committed
107

untereiner's avatar
untereiner committed
108
	for(Dart d = mapx.begin(); d!= mapx.end(); mapx.next(d))
Pierre Kraemer's avatar
Pierre Kraemer committed
109
	{
untereiner's avatar
untereiner committed
110
		if (withBoundary || !mapx.isBoundaryMarked2(d))
Pierre Kraemer's avatar
Pierre Kraemer committed
111
			vecDarts.push_back(d);
112

Pierre Kraemer's avatar
Pierre Kraemer committed
113
114
115
116
	}
	m_nbDarts = vecDarts.size();

	// debut phi1
untereiner's avatar
untereiner committed
117
	DartAutoAttribute<VEC3> fv1(mapx);
Pierre Kraemer's avatar
Pierre Kraemer committed
118
	// fin phi1
untereiner's avatar
untereiner committed
119
	DartAutoAttribute<VEC3> fv11(mapx);
Pierre Kraemer's avatar
Pierre Kraemer committed
120
	// phi2
untereiner's avatar
untereiner committed
121
	DartAutoAttribute<VEC3> fv2(mapx);
Pierre Kraemer's avatar
Pierre Kraemer committed
122

123
124
125
	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
126
127
	VEC3* colorDartBuf = reinterpret_cast<VEC3*>(ColorDartsBuffer);

128
129
130
131
132
133
134
135
136
//	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
137

138
139
	std::vector<VEC3> vecPos;
	vecPos.reserve(16);
Pierre Kraemer's avatar
Pierre Kraemer committed
140

141
142
	unsigned int indexDC=0;

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

162

163
				if (m_normalShift > 0.0f)
164
				{
165
166
167
168
169
					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;
					}
170
171
				}

172
173
				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
174

175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
				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;
untereiner's avatar
untereiner committed
194
					d = mapx.phi1(d);
195
196
197
198
				}
				mf.markOrbit<FACE>(d);
			}
			else if (withBoundary)
Pierre Kraemer's avatar
Pierre Kraemer committed
199
			{
200
201
202
203
204
205
206
207
208

				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();
untereiner's avatar
untereiner committed
209
					VEC3 P = positions[mapx.phi1(ee)] + v* m_boundShift;
210
					vecPos.push_back(P);
untereiner's avatar
untereiner committed
211
					dd = mapx.phi1(dd);
212
					ee = mapx.phi2(dd);
untereiner's avatar
untereiner committed
213
					P = positions[mapx.phi1(ee)] + v* m_boundShift;
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
					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;
untereiner's avatar
untereiner committed
237
					d = mapx.phi1(d);
238
239
				}
				mf.markOrbit<FACE>(d);
Pierre Kraemer's avatar
Pierre Kraemer committed
240
241
242
243
			}
		}
	}

244
	m_vbo0->bind();
245
246
	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
247

248
249
	m_vbo3->bind();
	glUnmapBuffer(GL_ARRAY_BUFFER);
Pierre Kraemer's avatar
Pierre Kraemer committed
250

251
252
253
	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
254

255
256
257
	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
258
259
260
261
262
263
264
265
266

	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;

untereiner's avatar
untereiner committed
267
		Dart e = mapx.phi2(d);
268

Sylvain Thery's avatar
Sylvain Thery committed
269
//		if (good(e) && (e.index > d.index))
untereiner's avatar
untereiner committed
270
		if ( (withBoundary || !mapx.isBoundaryMarked2(e)) && (e.index > d.index))
Pierre Kraemer's avatar
Pierre Kraemer committed
271
272
273
274
275
276
		{
			*positionF2++ = fv2[d];
			*positionF2++ = fv2[e];
			m_nbRel2++;
		}

untereiner's avatar
untereiner committed
277
		e = mapx.phi1(d);
Pierre Kraemer's avatar
Pierre Kraemer committed
278
279
280
		*positionF1++ = fv1[d];
		*positionF1++ = fv11[e];
	}
Sylvain Thery's avatar
Sylvain Thery committed
281
	m_nbRel1 = vecDarts.size();
Pierre Kraemer's avatar
Pierre Kraemer committed
282

283
284
285
286
287
	m_vbo1->bind();
	glUnmapBuffer(GL_ARRAY_BUFFER);

	m_vbo2->bind();
	glUnmapBuffer(GL_ARRAY_BUFFER);
Pierre Kraemer's avatar
Pierre Kraemer committed
288
289
290
}

template<typename PFP>
291
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
292
{
Sylvain Thery's avatar
Sylvain Thery committed
293
	GMap2& map = dynamic_cast<GMap2&>(mapx);
294

Pierre Kraemer's avatar
Pierre Kraemer committed
295
296
297
298
	typedef typename PFP::VEC3 VEC3;
	typedef typename PFP::REAL REAL;

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

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

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

Pierre Kraemer's avatar
Pierre Kraemer committed
307
308
309

	for(Dart d = map.begin(); d!= map.end(); map.next(d))
	{
310
		if (withBoundary || !map.isBoundaryMarked2(d))
Pierre Kraemer's avatar
Pierre Kraemer committed
311
312
313
314
			vecDarts.push_back(d);
	}
	m_nbDarts = vecDarts.size();

315
	// debut phi1
316
	DartAutoAttribute<VEC3> fv1(map);
317
	// fin phi1
318
	DartAutoAttribute<VEC3> fv11(map);
319
	// phi2
320
	DartAutoAttribute<VEC3> fv2(map);
321
322
323
324

	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
325
326
	VEC3* colorDartBuf = reinterpret_cast<VEC3*>(ColorDartsBuffer);

327
328
329
	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
330
	VEC3* positionDartBuf = reinterpret_cast<VEC3*>(PositionDartsBuffer);
331

332
333
	std::vector<VEC3> vecPos;
	vecPos.reserve(16);
Pierre Kraemer's avatar
Pierre Kraemer committed
334

335
336
	unsigned int indexDC=0;

Pierre Kraemer's avatar
Pierre Kraemer committed
337
338
339
340
	DartMarker mf(map);
	for(std::vector<Dart>::iterator id = vecDarts.begin(); id!= vecDarts.end(); id++)
	{
		Dart d = *id;
341

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

355
356
357
358
359
360
361
362
363

			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
364
365
366
			unsigned int nb = vecPos.size();
			vecPos.push_back(vecPos.front()); // copy the first for easy computation on next loop

367

Pierre Kraemer's avatar
Pierre Kraemer committed
368
369
370
371
372
373
374
375
			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;

376
377
				m_attIndex[d] = indexDC;
				indexDC+=2;
Pierre Kraemer's avatar
Pierre Kraemer committed
378
				*positionDartBuf++ = P;
379
				*colorDartBuf++ = m_dartsColor;
380
				*positionDartBuf++ = PP;
381
				*colorDartBuf++ = m_dartsColor;
Pierre Kraemer's avatar
Pierre Kraemer committed
382
				*positionDartBuf++ = Q;
383
				*colorDartBuf++ = m_dartsColor;
384
				*positionDartBuf++ = QQ;
385
				*colorDartBuf++ = m_dartsColor;
Pierre Kraemer's avatar
Pierre Kraemer committed
386

387
				VEC3 f = P*0.5f + PP*0.5f;
Pierre Kraemer's avatar
Pierre Kraemer committed
388
				fv2[d] = f;
389
				f = P*0.9f + PP*0.1f;
Pierre Kraemer's avatar
Pierre Kraemer committed
390
391
				fv1[d] = f;

392
393
394
395
396
				dd = map.beta0(d);
				f = Q*0.5f + QQ*0.5f;
				fv2[dd] = f;
				f = Q*0.9f + QQ*0.1f;
				fv1[dd] = f;
397
398
399
				m_attIndex[dd] = indexDC;
				indexDC+=2;

400

Pierre Kraemer's avatar
Pierre Kraemer committed
401
402
				d = map.phi1(d);
			}
Pierre Kraemer's avatar
Pierre Kraemer committed
403
			mf.markOrbit<FACE>(d);
Pierre Kraemer's avatar
Pierre Kraemer committed
404
405
406
		}
	}

407
408
	m_vbo0->bind();
	glUnmapBuffer(GL_ARRAY_BUFFER);
Pierre Kraemer's avatar
Pierre Kraemer committed
409

410
411
	m_vbo3->bind();
	glUnmapBuffer(GL_ARRAY_BUFFER);
Pierre Kraemer's avatar
Pierre Kraemer committed
412

413
414
415
	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
416

417
418
419
	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
420
421
422
423

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

424
	m_nbRel2 = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
425
426
427
428
	for(std::vector<Dart>::iterator id = vecDarts.begin(); id!= vecDarts.end(); id++)
	{
		Dart d = *id;
		Dart e = map.beta2(d);
429
430
//		if (d < e )
		if ( (withBoundary || !map.isBoundaryMarked2(e)) && (d < e ))
Pierre Kraemer's avatar
Pierre Kraemer committed
431
432
433
434
435
436
437
438
439
440
		{
			*positionF2++ = fv2[d];
			*positionF2++ = fv2[e];
			m_nbRel2++;
		}

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

443
444
445
446
447
	m_vbo1->bind();
	glUnmapBuffer(GL_ARRAY_BUFFER);

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

Sylvain Thery's avatar
Sylvain Thery committed
450
template<typename PFP>
451
void TopoRender::setDartsIdColor(typename PFP::MAP& map, bool withBoundary)
Sylvain Thery's avatar
Sylvain Thery committed
452
453
{
	m_vbo3->bind();
Pierre Kraemer's avatar
Pierre Kraemer committed
454
455
	float* colorBuffer = reinterpret_cast<float*>(glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE));
	unsigned int nb = 0;
Sylvain Thery's avatar
Sylvain Thery committed
456

Pierre Kraemer's avatar
Pierre Kraemer committed
457
	m_attIndex = map.template getAttribute<unsigned int, DART>("dart_index");
Sylvain Thery's avatar
Sylvain Thery committed
458
459
460
461
462
463
	if (!m_attIndex.isValid())
	{
		CGoGNerr << "Error attribute_dartIndex does not exist during TopoRender::picking" << CGoGNendl;
		return;
	}

Sylvain Thery's avatar
Sylvain Thery committed
464
465
	for (Dart d = map.begin(); d != map.end(); map.next(d))
	{
466
		if (withBoundary || !map.isBoundaryMarked2(d))
467
		{
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487

			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
488
489
490
491
492
493
		}
	}
	glUnmapBuffer(GL_ARRAY_BUFFER);
}

template<typename PFP>
494
Dart TopoRender::picking(typename PFP::MAP& map,int x, int y, bool withBoundary)
Sylvain Thery's avatar
Sylvain Thery committed
495
496
{
	pushColors();
497
	setDartsIdColor<PFP>(map,withBoundary);
Sylvain Thery's avatar
Sylvain Thery committed
498
499
500
501
502
503
	Dart d = pickColor(x,y);
	popColors();
	return d;

}

504
505
506


template<typename PFP>
507
Dart TopoRender::coneSelection(typename PFP::MAP& map, const Geom::Vec3f& rayA, const Geom::Vec3f& rayAB, float angle)
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
{
	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>
537
Dart TopoRender::raySelection(typename PFP::MAP& map, const Geom::Vec3f& rayA, const Geom::Vec3f& rayAB, float dmax)
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
{
	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
565
}//end namespace GL2
Pierre Kraemer's avatar
Pierre Kraemer committed
566
567
568
569
570
571

}//end namespace Algo

}//end namespace Render

}//end namespace CGoGN