Création d'un compte pour un collaborateur extérieur au laboratoire depuis l'intranet ICube : https://intranet.icube.unistra.fr/fr/labs/member/profile

topoRender.hpp 18.9 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"
Sylvain Thery's avatar
Sylvain Thery committed
39
#include "Utils/Shaders/shaderColorDarts.h"
40

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

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

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

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

53
54
template<typename MAP>
void TopoRender::overdrawDart(MAP& map, Dart d, float width, float r, float g, float b)
Pierre Kraemer's avatar
Pierre Kraemer committed
55
{
56
57
58
	if (d == NIL)
		return;

59
60
61
	DartAttribute<unsigned int, MAP> attIndex = map.template getAttribute<unsigned int, DART, MAP>(m_nameIndex);
	if (!attIndex.isValid())
		attIndex  = map.template addAttribute<unsigned int, DART, MAP>(m_nameIndex);
62

63
	unsigned int indexDart = attIndex[d];
Pierre Kraemer's avatar
Pierre Kraemer committed
64
65

	m_shader1->setColor(Geom::Vec4f(r,g,b,0.0f));
Sylvain Thery's avatar
Sylvain Thery committed
66
	m_shader1->setLineWidth(width);
Pierre Kraemer's avatar
Pierre Kraemer committed
67
68
	m_shader1->enableVertexAttribs();
	glDrawArrays(GL_LINES, indexDart, 2);
69
	m_shader1->disableVertexAttribs();
Pierre Kraemer's avatar
Pierre Kraemer committed
70
71
72
}


73
74
template<typename MAP>
void TopoRender::drawColoredDarts(MAP& map)
Pierre Kraemer's avatar
Pierre Kraemer committed
75
{
76
77
78
	DartAttribute<unsigned int, MAP> attIndex = map.template getAttribute<unsigned int, DART, MAP>(m_nameIndex);
	if (!attIndex.isValid())
		return;
Pierre Kraemer's avatar
Pierre Kraemer committed
79

80
81
82
83
	m_shader1->enableVertexAttribs();
	for (auto it=m_coloredDarts.begin(); it != m_coloredDarts.end(); ++it)
	{
		unsigned int indexDart = attIndex[it->d];
Pierre Kraemer's avatar
Pierre Kraemer committed
84

Sylvain Thery's avatar
Sylvain Thery committed
85
86
		m_shader1->directColor(Geom::Vec4f(it->r,it->g,it->b,0.0f));
//		m_shader1->bind(); // because of unbind, do a set color without bind/unbind
87
88
89
		glDrawArrays(GL_LINES, indexDart, 2);
	}
	m_shader1->disableVertexAttribs();
Pierre Kraemer's avatar
Pierre Kraemer committed
90
91
92
93
94
}



template<typename PFP>
95
void TopoRender::updateDataBoundary(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP>& positions)
Pierre Kraemer's avatar
Pierre Kraemer committed
96
{
97
	updateDataBoundary<PFP>(map,positions,m_ke,m_kf,m_ns);
Pierre Kraemer's avatar
Pierre Kraemer committed
98
99
100
101
}


template<typename PFP>
102
void TopoRender::updateDataBoundary(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP>& positions, float ke, float kf, float ns)
103
104
{
	m_normalShift = ns;
105
106
	SelectorDartBoundary<typename PFP::MAP> sdb(map);
	DartContainerBrowserSelector<typename PFP::MAP> browser(map, sdb);
107
	browser.enable();
108
	this->updateData<PFP>(map, positions, ke, kf, false,true); // false,true because we are drawing the boundary of a 3map
109
	browser.disable();
110
111
112
	m_normalShift = 0.0f;
}

113

114
115
116
117
118
template<typename PFP>
void TopoRender::updateData(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP>& positions, bool onlyBoundary)
{
	updateData<PFP>(map,positions,m_ke,m_kf,m_wb,onlyBoundary);
}
Pierre Kraemer's avatar
Pierre Kraemer committed
119

Pierre Kraemer's avatar
Pierre Kraemer committed
120
template<typename PFP>
121
void TopoRender::updateData(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP>& positions, float ke, float kf, bool withBoundary, bool onlyBoundary)
Pierre Kraemer's avatar
Pierre Kraemer committed
122
{
123
124
125
126
127
	typedef typename PFP::MAP MAP;
	typedef typename PFP::VEC3 VEC3;
	typedef typename PFP::REAL REAL;

	std::string name_index(this->m_nameIndex);
128
129
	if (onlyBoundary)
		name_index = std::string("dart_boundary_index2");
130

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

134
135
136
	DartAttribute<unsigned int, MAP> attIndex = map.template getAttribute<unsigned int, DART, MAP>(name_index);
	if (!attIndex.isValid())
		attIndex  = map.template addAttribute<unsigned int, DART, MAP>(name_index);
Sylvain Thery's avatar
Sylvain Thery committed
137

Pierre Kraemer's avatar
Pierre Kraemer committed
138

139
	for(Dart d = map.begin(); d != map.end(); map.next(d))
Pierre Kraemer's avatar
Pierre Kraemer committed
140
	{
141
		if (withBoundary || !map.template isBoundaryMarked<2>(d))
Pierre Kraemer's avatar
Pierre Kraemer committed
142
143
			vecDarts.push_back(d);
	}
144
	this->m_nbDarts = GLuint(vecDarts.size());
Pierre Kraemer's avatar
Pierre Kraemer committed
145
146

	// debut phi1
147
	DartAutoAttribute<VEC3, MAP> fv1(map);
Pierre Kraemer's avatar
Pierre Kraemer committed
148
	// fin phi1
149
	DartAutoAttribute<VEC3, MAP> fv11(map);
Pierre Kraemer's avatar
Pierre Kraemer committed
150
	// phi2
151
	DartAutoAttribute<VEC3, MAP> fv2(map);
152

Pierre Kraemer's avatar
Pierre Kraemer committed
153
154
155
156
	if (this->m_bufferDartPosition!=NULL)
		delete this->m_bufferDartPosition;
	this->m_bufferDartPosition = new Geom::Vec3f[2*this->m_nbDarts];
	Geom::Vec3f* positionDartBuf = reinterpret_cast<Geom::Vec3f*>(this->m_bufferDartPosition);
Pierre Kraemer's avatar
Pierre Kraemer committed
157

158
159
	std::vector<VEC3> vecPos;
	vecPos.reserve(16);
Pierre Kraemer's avatar
Pierre Kraemer committed
160

Pierre Kraemer's avatar
Pierre Kraemer committed
161
	unsigned int indexDC = 0;
162

163
	DartMarker<MAP> mf(map);
Pierre Kraemer's avatar
Pierre Kraemer committed
164
	for(std::vector<Dart>::iterator id = vecDarts.begin(); id != vecDarts.end(); id++)
Pierre Kraemer's avatar
Pierre Kraemer committed
165
166
167
168
	{
		Dart d = *id;
		if (!mf.isMarked(d))
		{
169
			vecPos.clear();
170
			if (!map.template isBoundaryMarked<2>(d))
Pierre Kraemer's avatar
Pierre Kraemer committed
171
			{
172
173
				//VEC3 center = Algo::Surface::Geometry::faceCentroidELW<PFP>(map,d,positions);
				VEC3 center = Algo::Surface::Geometry::faceCentroid<PFP>(map,d,positions);
174
175
176
177
178
				float k = 1.0f - kf;
				Dart dd = d;
				do
				{
					vecPos.push_back(center*k + positions[dd]*kf);
179
					dd = map.phi1(dd);
180
				} while (dd != d);
181

Pierre Kraemer's avatar
Pierre Kraemer committed
182
				if (this->m_normalShift > 0.0f)
183
				{
184
					VEC3 normal = Algo::Surface::Geometry::newellNormal<PFP>(map,d,positions);
185
186
					for (typename std::vector<VEC3>::iterator pit = vecPos.begin(); pit != vecPos.end(); ++pit)
					{
Pierre Kraemer's avatar
Pierre Kraemer committed
187
						*pit -= normal * this->m_normalShift;
188
					}
189
190
				}

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

194
195
196
197
198
199
200
				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;

201
					attIndex[d] = indexDC;
202
					indexDC+=2;
203
204
					*positionDartBuf++ = PFP::toVec3f(P);
					*positionDartBuf++ = PFP::toVec3f(Q);
205
206
207
208
209
210
					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;
211
					d = map.phi1(d);
212
				}
Pierre Kraemer's avatar
Pierre Kraemer committed
213
				mf.template markOrbit<FACE>(d);
214
215
			}
			else if (withBoundary)
Pierre Kraemer's avatar
Pierre Kraemer committed
216
			{
217
218
219
				Dart dd = d;
				do
				{
220
221
222
					Dart ee = map.phi2(dd);
					VEC3 normal = Algo::Surface::Geometry::newellNormal<PFP>(map,ee,positions);
					VEC3 vd = Algo::Surface::Geometry::vectorOutOfDart<PFP>(map,ee,positions);
223
224
					VEC3 v = vd ^ normal;
					v.normalize();
225
					VEC3 P = positions[map.phi1(ee)] + v* this->m_boundShift;
226
					vecPos.push_back(P);
227
228
229
					dd = map.phi1(dd);
					ee = map.phi2(dd);
					P = positions[map.phi1(ee)] + v* this->m_boundShift;
230
231
232
					vecPos.push_back(P);
				} while (dd != d);

233
				unsigned int nb = uint32(vecPos.size()/2);
234
235
236
237
238
239
240
				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;

241
					attIndex[d] = indexDC;
242
					indexDC+=2;
243
244
					*positionDartBuf++ = PFP::toVec3f(P);
					*positionDartBuf++ = PFP::toVec3f(Q);
245
246
247
248
249
250
					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;
251
					d = map.phi1(d);
252
				}
Pierre Kraemer's avatar
Pierre Kraemer committed
253
				mf.template markOrbit<FACE>(d);
Pierre Kraemer's avatar
Pierre Kraemer committed
254
255
256
257
			}
		}
	}

Pierre Kraemer's avatar
Pierre Kraemer committed
258
259
	this->m_vbo0->bind();
	glBufferData(GL_ARRAY_BUFFER, 2*this->m_nbDarts*sizeof(Geom::Vec3f), this->m_bufferDartPosition, GL_STREAM_DRAW);
Pierre Kraemer's avatar
Pierre Kraemer committed
260
261


Pierre Kraemer's avatar
Pierre Kraemer committed
262
263
	this->m_vbo1->bind();
	glBufferData(GL_ARRAY_BUFFER, 2*this->m_nbDarts*sizeof(Geom::Vec3f), 0, GL_STREAM_DRAW);
264
	GLvoid* PositionBuffer1 = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
Pierre Kraemer's avatar
Pierre Kraemer committed
265

Pierre Kraemer's avatar
Pierre Kraemer committed
266
267
	this->m_vbo2->bind();
	glBufferData(GL_ARRAY_BUFFER, 2*this->m_nbDarts*sizeof(Geom::Vec3f), 0, GL_STREAM_DRAW);
268
	GLvoid* PositionBuffer2 = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
Pierre Kraemer's avatar
Pierre Kraemer committed
269

Pierre Kraemer's avatar
Pierre Kraemer committed
270
271
	Geom::Vec3f* positionF1 = reinterpret_cast<Geom::Vec3f*>(PositionBuffer1);
	Geom::Vec3f* positionF2 = reinterpret_cast<Geom::Vec3f*>(PositionBuffer2);
Pierre Kraemer's avatar
Pierre Kraemer committed
272

Pierre Kraemer's avatar
Pierre Kraemer committed
273
	this->m_nbRel2 = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
274
275
276
277
	for(std::vector<Dart>::iterator id = vecDarts.begin(); id!= vecDarts.end(); id++)
	{
		Dart d = *id;

278
		Dart e = map.phi2(d);
279

Sylvain Thery's avatar
Sylvain Thery committed
280
//		if (good(e) && (e.index > d.index))
281
		if ( (withBoundary || !map.template isBoundaryMarked<2>(e)) && (e.index > d.index))
Pierre Kraemer's avatar
Pierre Kraemer committed
282
		{
283
284
			*positionF2++ = PFP::toVec3f(fv2[d]);
			*positionF2++ = PFP::toVec3f(fv2[e]);
Pierre Kraemer's avatar
Pierre Kraemer committed
285
			this->m_nbRel2++;
Pierre Kraemer's avatar
Pierre Kraemer committed
286
287
		}

288
		e = map.phi1(d);
289
290
		*positionF1++ = PFP::toVec3f(fv1[d]);
		*positionF1++ = PFP::toVec3f(fv11[e]);
Pierre Kraemer's avatar
Pierre Kraemer committed
291
	}
292
	this->m_nbRel1 = GLuint(vecDarts.size());
Pierre Kraemer's avatar
Pierre Kraemer committed
293

Pierre Kraemer's avatar
Pierre Kraemer committed
294
	this->m_vbo1->bind();
295
296
	glUnmapBuffer(GL_ARRAY_BUFFER);

Pierre Kraemer's avatar
Pierre Kraemer committed
297
	this->m_vbo2->bind();
298
	glUnmapBuffer(GL_ARRAY_BUFFER);
Pierre Kraemer's avatar
Pierre Kraemer committed
299
300
}

Pierre Kraemer's avatar
Pierre Kraemer committed
301

Pierre Kraemer's avatar
Pierre Kraemer committed
302
template<typename PFP>
303
void TopoRender::updateDataGMap(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP>& positions, bool onlyBoundary)
Pierre Kraemer's avatar
Pierre Kraemer committed
304
{
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
	updateDataGMap<PFP>(map,positions,m_ke,m_kf,m_wb,onlyBoundary);
}

template<typename PFP>
void TopoRender::updateDataGMap(typename PFP::MAP& dmap, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP>& positions, float ke, float kf, bool withBoundary, bool onlyBoundary)
{

	// compilation trick to bypass compilation problems

	struct GPFP:public PFP
	{
		typedef EmbeddedGMap2 MAP;
	};

	typedef typename GPFP::MAP MAP;
	typedef typename GPFP::VEC3 VEC3;
	typedef typename GPFP::REAL REAL;


	MAP& map = reinterpret_cast<MAP&>(dmap);
325

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

329
	std::string name_index(this->m_nameIndex);
330
331
332
333
	if (onlyBoundary)
		name_index = std::string("dart_boundary_index2");


334
335
336
	DartAttribute<unsigned int, MAP> attIndex = map.template getAttribute<unsigned int, DART, MAP>(name_index);
	if (!attIndex.isValid())
		attIndex  = map.template addAttribute<unsigned int, DART, MAP>(name_index);
Sylvain Thery's avatar
Sylvain Thery committed
337

Pierre Kraemer's avatar
Pierre Kraemer committed
338

Pierre Kraemer's avatar
Pierre Kraemer committed
339
	for(Dart d = map.begin(); d != map.end(); map.next(d))
Pierre Kraemer's avatar
Pierre Kraemer committed
340
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
341
		if (withBoundary || !map.template isBoundaryMarked<2>(d))
Pierre Kraemer's avatar
Pierre Kraemer committed
342
343
			vecDarts.push_back(d);
	}
344
	this->m_nbDarts = uint32(vecDarts.size());
Pierre Kraemer's avatar
Pierre Kraemer committed
345

346
	// debut phi1
347
	DartAutoAttribute<VEC3, MAP> fv1(map);
348
	// fin phi1
349
	DartAutoAttribute<VEC3, MAP> fv11(map);
350
	// phi2
351
	DartAutoAttribute<VEC3, MAP> fv2(map);
352

Pierre Kraemer's avatar
Pierre Kraemer committed
353
354
	this->m_vbo0->bind();
	glBufferData(GL_ARRAY_BUFFER, 4*this->m_nbDarts*sizeof(Geom::Vec3f), 0, GL_STREAM_DRAW);
355
	GLvoid* PositionDartsBuffer = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
356
	Geom::Vec3f* positionDartBuf = reinterpret_cast<Geom::Vec3f*>(PositionDartsBuffer);
357

358
359
	std::vector<VEC3> vecPos;
	vecPos.reserve(16);
Pierre Kraemer's avatar
Pierre Kraemer committed
360

Pierre Kraemer's avatar
Pierre Kraemer committed
361
	unsigned int indexDC = 0;
362

Pierre Kraemer's avatar
Pierre Kraemer committed
363
	DartMarker<MAP> mf(map);
Pierre Kraemer's avatar
Pierre Kraemer committed
364
365
366
	for(std::vector<Dart>::iterator id = vecDarts.begin(); id!= vecDarts.end(); id++)
	{
		Dart d = *id;
367

Pierre Kraemer's avatar
Pierre Kraemer committed
368
369
		if (!mf.isMarked(d))
		{
370
			vecPos.clear();
371
			VEC3 center = Algo::Surface::Geometry::faceCentroidELW<GPFP>(map, d, positions);
372
373
			
			float k = 1.0f - kf;
Pierre Kraemer's avatar
Pierre Kraemer committed
374
375
376
			Dart dd = d;
			do
			{
377
378
379
				vecPos.push_back(center*k + positions[dd]*kf);
				dd = map.phi1(dd);
			} while (dd != d);
Pierre Kraemer's avatar
Pierre Kraemer committed
380

381

Pierre Kraemer's avatar
Pierre Kraemer committed
382
			if (this->m_normalShift > 0.0f)
383
			{
384
				VEC3 normal = Algo::Surface::Geometry::newellNormal<GPFP>(map, d, positions);
385
386
				for (typename std::vector<VEC3>::iterator pit = vecPos.begin(); pit != vecPos.end(); ++pit)
				{
Pierre Kraemer's avatar
Pierre Kraemer committed
387
					*pit -= normal * this->m_normalShift;
388
389
				}
			}
390
			unsigned int nb = uint32(vecPos.size());
Pierre Kraemer's avatar
Pierre Kraemer committed
391
392
393
394
395
396
397
398
399
400
			vecPos.push_back(vecPos.front()); // copy the first for easy computation on next loop

			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;

401
				attIndex[d] = indexDC;
402
				indexDC+=2;
403
404
405
406
				*positionDartBuf++ = GPFP::toVec3f(P);
				*positionDartBuf++ = GPFP::toVec3f(PP);
				*positionDartBuf++ = GPFP::toVec3f(Q);
				*positionDartBuf++ = GPFP::toVec3f(QQ);
407
				VEC3 f = P*0.5f + PP*0.5f;
Pierre Kraemer's avatar
Pierre Kraemer committed
408
				fv2[d] = f;
409
				f = P*0.9f + PP*0.1f;
Pierre Kraemer's avatar
Pierre Kraemer committed
410
411
				fv1[d] = f;

412
413
414
415
416
				dd = map.beta0(d);
				f = Q*0.5f + QQ*0.5f;
				fv2[dd] = f;
				f = Q*0.9f + QQ*0.1f;
				fv1[dd] = f;
417
				attIndex[dd] = indexDC;
418
419
				indexDC+=2;

Pierre Kraemer's avatar
Pierre Kraemer committed
420
421
				d = map.phi1(d);
			}
Pierre Kraemer's avatar
Pierre Kraemer committed
422
			mf.template markOrbit<FACE>(d);
Pierre Kraemer's avatar
Pierre Kraemer committed
423
424
425
		}
	}

Pierre Kraemer's avatar
Pierre Kraemer committed
426
	this->m_vbo0->bind();
427
	glUnmapBuffer(GL_ARRAY_BUFFER);
Pierre Kraemer's avatar
Pierre Kraemer committed
428

Pierre Kraemer's avatar
Pierre Kraemer committed
429
430
	this->m_vbo1->bind();
	glBufferData(GL_ARRAY_BUFFER, 2*this->m_nbDarts*sizeof(Geom::Vec3f), 0, GL_STREAM_DRAW);
431
	GLvoid* PositionBuffer1 = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
Pierre Kraemer's avatar
Pierre Kraemer committed
432

Pierre Kraemer's avatar
Pierre Kraemer committed
433
434
	this->m_vbo2->bind();
	glBufferData(GL_ARRAY_BUFFER, 2*this->m_nbDarts*sizeof(Geom::Vec3f), 0, GL_STREAM_DRAW);
435
	GLvoid* PositionBuffer2 = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
Pierre Kraemer's avatar
Pierre Kraemer committed
436

Pierre Kraemer's avatar
Pierre Kraemer committed
437
438
	Geom::Vec3f* positionF1 = reinterpret_cast<Geom::Vec3f*>(PositionBuffer1);
	Geom::Vec3f* positionF2 = reinterpret_cast<Geom::Vec3f*>(PositionBuffer2);
Pierre Kraemer's avatar
Pierre Kraemer committed
439

Pierre Kraemer's avatar
Pierre Kraemer committed
440
	this->m_nbRel2 = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
441
442
443
444
	for(std::vector<Dart>::iterator id = vecDarts.begin(); id!= vecDarts.end(); id++)
	{
		Dart d = *id;
		Dart e = map.beta2(d);
445
//		if (d < e )
Pierre Kraemer's avatar
Pierre Kraemer committed
446
		if ( (withBoundary || !map.template isBoundaryMarked<2>(e)) && (d < e ))
Pierre Kraemer's avatar
Pierre Kraemer committed
447
		{
448
449
			*positionF2++ = GPFP::toVec3f(fv2[d]);
			*positionF2++ = GPFP::toVec3f(fv2[e]);
Pierre Kraemer's avatar
Pierre Kraemer committed
450
			this->m_nbRel2++;
Pierre Kraemer's avatar
Pierre Kraemer committed
451
452
453
		}

		e = map.beta1(d);
454
455
		*positionF1++ = GPFP::toVec3f(fv1[d]);
		*positionF1++ = GPFP::toVec3f(fv1[e]);
Pierre Kraemer's avatar
Pierre Kraemer committed
456
	}
457
	this->m_nbRel1 = uint32(vecDarts.size()/2);
Pierre Kraemer's avatar
Pierre Kraemer committed
458

Pierre Kraemer's avatar
Pierre Kraemer committed
459
	this->m_vbo1->bind();
460
461
	glUnmapBuffer(GL_ARRAY_BUFFER);

Pierre Kraemer's avatar
Pierre Kraemer committed
462
	this->m_vbo2->bind();
463
	glUnmapBuffer(GL_ARRAY_BUFFER);
Pierre Kraemer's avatar
Pierre Kraemer committed
464
465
}

466
467
468
469


template<typename MAP>
Dart TopoRender::picking(MAP& map,int x, int y, bool withBoundary)
Sylvain Thery's avatar
Sylvain Thery committed
470
{
471
472
473
474
475
476

	Utils::VBO vboCol;
	vboCol.setDataSize(3);

	vboCol.bind();
	glBufferData(GL_ARRAY_BUFFER, 2*this->m_nbDarts*sizeof(Geom::Vec3f), NULL, GL_STREAM_DRAW);
Pierre Kraemer's avatar
Pierre Kraemer committed
477
478
	float* colorBuffer = reinterpret_cast<float*>(glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE));
	unsigned int nb = 0;
Sylvain Thery's avatar
Sylvain Thery committed
479

480
481
	DartAttribute<unsigned int, MAP> attIndex = map.template getAttribute<unsigned int, DART, MAP>(m_nameIndex);
	if (!attIndex.isValid())
Sylvain Thery's avatar
Sylvain Thery committed
482
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
483
		CGoGNerr << "Error attribute_dartIndex does not exist during TopoRender<PFP>::picking" << CGoGNendl;
484
		return NIL;
Sylvain Thery's avatar
Sylvain Thery committed
485
486
	}

Sylvain Thery's avatar
Sylvain Thery committed
487
488
	for (Dart d = map.begin(); d != map.end(); map.next(d))
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
489
		if (withBoundary || !map.template isBoundaryMarked<2>(d))
490
		{
491
492
493
494
495

			if (nb < m_nbDarts)
			{
				float r,g,b;
				dartToCol(d, r,g,b);
496
				float* local = colorBuffer+3*attIndex[d]; // get the right position in VBO
497
498
499
500
501
502
503
504
505
506
507
508
509
510
				*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
511
512
513
514
		}
	}
	glUnmapBuffer(GL_ARRAY_BUFFER);

Sylvain Thery's avatar
Sylvain Thery committed
515
	Utils::ShaderColorDarts shaderCol;
516
517
518
519
520
521
522
523
	shaderCol.setAttributePosition(m_vbo0);
	shaderCol.setAttributeColor(&vboCol);
	shaderCol.updateMatrices(m_shader1);

	// save clear color and set to zero
	float cc[4];
	glGetFloatv(GL_COLOR_CLEAR_VALUE,cc);

Sylvain Thery's avatar
Sylvain Thery committed
524
525
526
527
	bool multi = glIsEnabled(GL_MULTISAMPLE);
	if (multi)
		glDisable(GL_MULTISAMPLE);

528
529
530
	glClearColor(0.0f,0.0f,0.0f,0.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

Sylvain Thery's avatar
Sylvain Thery committed
531
	shaderCol.setLineWidth(m_topo_dart_width + 2);
532
533
534
535
536
537
538
539
540
	shaderCol.enableVertexAttribs();
	glDrawArrays(GL_LINES, 0, m_nbDarts*2);
	shaderCol.disableVertexAttribs();

	// read the pixel under the mouse in back buffer
	glReadBuffer(GL_BACK);
	float color[3];
	glReadPixels(x,y,1,1,GL_RGB,GL_FLOAT,color);

Sylvain Thery's avatar
Sylvain Thery committed
541
542
543
	if (multi)
		glEnable(GL_MULTISAMPLE);

544
545
546
	glClearColor(cc[0], cc[1], cc[2], cc[3]);

	Dart d = colToDart(color);
Sylvain Thery's avatar
Sylvain Thery committed
547
	return d;
548

Sylvain Thery's avatar
Sylvain Thery committed
549
550
}

551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578

























//template<typename PFP>
template<typename MAP>
Dart TopoRender::coneSelection(MAP& map, const Geom::Vec3f& rayA, const Geom::Vec3f& rayAB, float angle)
579
{
580
581
582
583
	DartAttribute<unsigned int, MAP> attIndex = map.template getAttribute<unsigned int, DART, MAP>(m_nameIndex);
	if (!attIndex.isValid())
		attIndex  = map.template addAttribute<unsigned int, DART, MAP>(m_nameIndex);

584
585
586
587
588
589
590
591
592
	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
593
594
		const Geom::Vec3f& P = m_bufferDartPosition[attIndex[d]];
		const Geom::Vec3f& Q =m_bufferDartPosition[attIndex[d]+1];
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
		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;
}

611
612
613
//template<typename PFP>
template<typename MAP>
Dart TopoRender::raySelection(MAP& map, const Geom::Vec3f& rayA, const Geom::Vec3f& rayAB, float dmax)
614
{
615
616
617
618
	DartAttribute<unsigned int, MAP> attIndex = map.template getAttribute<unsigned int, DART, MAP>(m_nameIndex);
	if (!attIndex.isValid())
		attIndex  = map.template addAttribute<unsigned int, DART, MAP>(m_nameIndex);

619
620
621
622
623
624
625
626
	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
627
628
		const Geom::Vec3f& P = m_bufferDartPosition[attIndex[d]];
		const Geom::Vec3f& Q =m_bufferDartPosition[attIndex[d]+1];
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
		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;
}

644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
template <typename PFP>
void TopoRender::computeDartMiddlePositions( typename PFP::MAP& map, DartAttribute< typename PFP::VEC3, typename PFP::MAP>& posExpl)
{
	DartAttribute<unsigned int, typename PFP::MAP> attIndex = map.template getAttribute<unsigned int, DART, typename PFP::MAP>(m_nameIndex);
	if (!attIndex.isValid())
		attIndex  = map.template addAttribute<unsigned int, DART, typename PFP::MAP>(m_nameIndex);


	for (Dart d = map.begin(); d != map.end(); map.next(d))
	{
		const Geom::Vec3f& P = m_bufferDartPosition[attIndex[d]];
		const Geom::Vec3f& Q = m_bufferDartPosition[attIndex[d]+1];
		posExpl[d] = (P + Q)*0.5f;
	}
}


661
} // namespace GL2
662

663
} // namespace Algo
Pierre Kraemer's avatar
Pierre Kraemer committed
664

665
} // namespace Render
Pierre Kraemer's avatar
Pierre Kraemer committed
666

667
} // namespace CGoGN