topoRender.hpp 14.2 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 "Geometry/distances.h"
34
#include "Algo/Geometry/centroid.h"
35
#include "Algo/Geometry/normal.h"
36

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

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

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

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

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

51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66

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;
	SelectorDartBoundary<typename PFP::MAP> sdb(map);
	MapBrowserSelector mbs(map,sdb);
	map.setBrowser(&mbs);

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

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


Pierre Kraemer's avatar
Pierre Kraemer committed
67
template<typename PFP>
68
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
69
{
70 71 72
	Map2* ptrMap2 = dynamic_cast<Map2*>(&map);
	if (ptrMap2 != NULL)
	{
73
		updateDataMap<PFP>(map, positions, ke, kf, withBoundary);
Pierre Kraemer's avatar
Pierre Kraemer committed
74
		return;
75 76 77 78
	}
	GMap2* ptrGMap2 = dynamic_cast<GMap2*>(&map);
	if (ptrGMap2 != NULL)
	{
79
		updateDataGMap<PFP>(map, positions, ke, kf, withBoundary);
Pierre Kraemer's avatar
Pierre Kraemer committed
80
		return;
81 82 83
	}
}

Pierre Kraemer's avatar
Pierre Kraemer committed
84
template<typename PFP>
85
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
86
{
87 88
	Map2& map = reinterpret_cast<Map2&>(mapx);

Pierre Kraemer's avatar
Pierre Kraemer committed
89 90 91 92
	typedef typename PFP::VEC3 VEC3;
	typedef typename PFP::REAL REAL;

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

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

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

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

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

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

115 116 117
	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
118 119
	VEC3* colorDartBuf = reinterpret_cast<VEC3*>(ColorDartsBuffer);

120 121 122 123 124 125 126 127 128
//	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
129

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

133 134
	unsigned int indexDC=0;

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

152 153 154 155 156 157 158 159 160 161

			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
162 163 164 165 166 167 168 169 170
			unsigned int nb = vecPos.size();
			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;

171 172
				m_attIndex[d] = indexDC;
				indexDC+=2;
Pierre Kraemer's avatar
Pierre Kraemer committed
173 174
				*positionDartBuf++ = P;
				*positionDartBuf++ = Q;
175
				*colorDartBuf++ = m_dartsColor;
176
				*colorDartBuf++ = m_dartsColor;
Pierre Kraemer's avatar
Pierre Kraemer committed
177 178 179 180 181 182 183 184
				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);
			}
Pierre Kraemer's avatar
Pierre Kraemer committed
185
			mf.markOrbit<FACE>(d);
Pierre Kraemer's avatar
Pierre Kraemer committed
186 187 188
		}
	}

189
	m_vbo0->bind();
190 191
	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
192

193 194
	m_vbo3->bind();
	glUnmapBuffer(GL_ARRAY_BUFFER);
Pierre Kraemer's avatar
Pierre Kraemer committed
195

196 197 198
	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
199

200 201 202
	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
203 204 205 206 207 208 209 210 211 212

	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);
213

Sylvain Thery's avatar
Sylvain Thery committed
214
//		if (good(e) && (e.index > d.index))
215
		if ( (withBoundary || !map.isBoundaryMarked2(e)) && (e.index > d.index))
Pierre Kraemer's avatar
Pierre Kraemer committed
216 217 218 219 220 221 222 223 224 225
		{
			*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
226
	m_nbRel1 = vecDarts.size();
Pierre Kraemer's avatar
Pierre Kraemer committed
227

228 229 230 231 232
	m_vbo1->bind();
	glUnmapBuffer(GL_ARRAY_BUFFER);

	m_vbo2->bind();
	glUnmapBuffer(GL_ARRAY_BUFFER);
Pierre Kraemer's avatar
Pierre Kraemer committed
233 234 235
}

template<typename PFP>
236
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
237
{
Sylvain Thery's avatar
Sylvain Thery committed
238
	GMap2& map = dynamic_cast<GMap2&>(mapx);
239

Pierre Kraemer's avatar
Pierre Kraemer committed
240 241 242 243
	typedef typename PFP::VEC3 VEC3;
	typedef typename PFP::REAL REAL;

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

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

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

Pierre Kraemer's avatar
Pierre Kraemer committed
252 253 254

	for(Dart d = map.begin(); d!= map.end(); map.next(d))
	{
255
		if (withBoundary || !map.isBoundaryMarked2(d))
Pierre Kraemer's avatar
Pierre Kraemer committed
256 257 258 259
			vecDarts.push_back(d);
	}
	m_nbDarts = vecDarts.size();

260
	// debut phi1
261
	DartAutoAttribute<VEC3> fv1(map);
262
	// fin phi1
263
	DartAutoAttribute<VEC3> fv11(map);
264
	// phi2
265
	DartAutoAttribute<VEC3> fv2(map);
266 267 268 269

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

272 273 274
	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
275
	VEC3* positionDartBuf = reinterpret_cast<VEC3*>(PositionDartsBuffer);
276

277 278
	std::vector<VEC3> vecPos;
	vecPos.reserve(16);
Pierre Kraemer's avatar
Pierre Kraemer committed
279

280 281
	unsigned int indexDC=0;

Pierre Kraemer's avatar
Pierre Kraemer committed
282 283 284 285
	DartMarker mf(map);
	for(std::vector<Dart>::iterator id = vecDarts.begin(); id!= vecDarts.end(); id++)
	{
		Dart d = *id;
286

Pierre Kraemer's avatar
Pierre Kraemer committed
287 288
		if (!mf.isMarked(d))
		{
289
			vecPos.clear();
290 291 292
			VEC3 center = Algo::Surface::Geometry::faceCentroidELW<PFP>(mapx,d,positions);
			
			float k = 1.0f - kf;
Pierre Kraemer's avatar
Pierre Kraemer committed
293 294 295
			Dart dd = d;
			do
			{
296 297 298
				vecPos.push_back(center*k + positions[dd]*kf);
				dd = map.phi1(dd);
			} while (dd != d);
Pierre Kraemer's avatar
Pierre Kraemer committed
299

300 301 302 303 304 305 306 307 308

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

312

Pierre Kraemer's avatar
Pierre Kraemer committed
313 314 315 316 317 318 319 320
			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;

321 322
				m_attIndex[d] = indexDC;
				indexDC+=2;
Pierre Kraemer's avatar
Pierre Kraemer committed
323
				*positionDartBuf++ = P;
324
				*colorDartBuf++ = m_dartsColor;
325
				*positionDartBuf++ = PP;
326
				*colorDartBuf++ = m_dartsColor;
Pierre Kraemer's avatar
Pierre Kraemer committed
327
				*positionDartBuf++ = Q;
328
				*colorDartBuf++ = m_dartsColor;
329
				*positionDartBuf++ = QQ;
330
				*colorDartBuf++ = m_dartsColor;
Pierre Kraemer's avatar
Pierre Kraemer committed
331

332
				VEC3 f = P*0.5f + PP*0.5f;
Pierre Kraemer's avatar
Pierre Kraemer committed
333
				fv2[d] = f;
334
				f = P*0.9f + PP*0.1f;
Pierre Kraemer's avatar
Pierre Kraemer committed
335 336
				fv1[d] = f;

337 338 339 340 341
				dd = map.beta0(d);
				f = Q*0.5f + QQ*0.5f;
				fv2[dd] = f;
				f = Q*0.9f + QQ*0.1f;
				fv1[dd] = f;
342 343 344
				m_attIndex[dd] = indexDC;
				indexDC+=2;

345

Pierre Kraemer's avatar
Pierre Kraemer committed
346 347
				d = map.phi1(d);
			}
Pierre Kraemer's avatar
Pierre Kraemer committed
348
			mf.markOrbit<FACE>(d);
Pierre Kraemer's avatar
Pierre Kraemer committed
349 350 351
		}
	}

352 353
	m_vbo0->bind();
	glUnmapBuffer(GL_ARRAY_BUFFER);
Pierre Kraemer's avatar
Pierre Kraemer committed
354

355 356
	m_vbo3->bind();
	glUnmapBuffer(GL_ARRAY_BUFFER);
Pierre Kraemer's avatar
Pierre Kraemer committed
357

358 359 360
	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
361

362 363 364
	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
365 366 367 368

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

369
	m_nbRel2 = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
370 371 372 373
	for(std::vector<Dart>::iterator id = vecDarts.begin(); id!= vecDarts.end(); id++)
	{
		Dart d = *id;
		Dart e = map.beta2(d);
374 375
//		if (d < e )
		if ( (withBoundary || !map.isBoundaryMarked2(e)) && (d < e ))
Pierre Kraemer's avatar
Pierre Kraemer committed
376 377 378 379 380 381 382 383 384 385
		{
			*positionF2++ = fv2[d];
			*positionF2++ = fv2[e];
			m_nbRel2++;
		}

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

388 389 390 391 392
	m_vbo1->bind();
	glUnmapBuffer(GL_ARRAY_BUFFER);

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

Sylvain Thery's avatar
Sylvain Thery committed
395
template<typename PFP>
396
void TopoRender::setDartsIdColor(typename PFP::MAP& map, bool withBoundary)
Sylvain Thery's avatar
Sylvain Thery committed
397 398
{
	m_vbo3->bind();
Pierre Kraemer's avatar
Pierre Kraemer committed
399 400
	float* colorBuffer = reinterpret_cast<float*>(glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE));
	unsigned int nb = 0;
Sylvain Thery's avatar
Sylvain Thery committed
401

Pierre Kraemer's avatar
Pierre Kraemer committed
402
	m_attIndex = map.template getAttribute<unsigned int, DART>("dart_index");
Sylvain Thery's avatar
Sylvain Thery committed
403 404 405 406 407 408
	if (!m_attIndex.isValid())
	{
		CGoGNerr << "Error attribute_dartIndex does not exist during TopoRender::picking" << CGoGNendl;
		return;
	}

Sylvain Thery's avatar
Sylvain Thery committed
409 410
	for (Dart d = map.begin(); d != map.end(); map.next(d))
	{
411
		if (withBoundary || !map.isBoundaryMarked2(d))
412
		{
413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432

			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
433 434 435 436 437 438
		}
	}
	glUnmapBuffer(GL_ARRAY_BUFFER);
}

template<typename PFP>
439
Dart TopoRender::picking(typename PFP::MAP& map,int x, int y, bool withBoundary)
Sylvain Thery's avatar
Sylvain Thery committed
440 441
{
	pushColors();
442
	setDartsIdColor<PFP>(map,withBoundary);
Sylvain Thery's avatar
Sylvain Thery committed
443 444 445 446 447 448
	Dart d = pickColor(x,y);
	popColors();
	return d;

}

449 450 451


template<typename PFP>
452
Dart TopoRender::coneSelection(typename PFP::MAP& map, const Geom::Vec3f& rayA, const Geom::Vec3f& rayAB, float angle)
453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481
{
	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>
482
Dart TopoRender::raySelection(typename PFP::MAP& map, const Geom::Vec3f& rayA, const Geom::Vec3f& rayAB, float dmax)
483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509
{
	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
510
}//end namespace GL2
Pierre Kraemer's avatar
Pierre Kraemer committed
511 512 513 514 515 516

}//end namespace Algo

}//end namespace Render

}//end namespace CGoGN