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