topoRender.hpp 13 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 35
#include "Algo/Geometry/centroid.h"

36

Pierre Kraemer's avatar
Pierre Kraemer committed
37 38
namespace CGoGN
{
39

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

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

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

template<typename PFP>
50
void TopoRender::updateData(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& positions, float ke, float kf, const FunctorSelect& good)
Pierre Kraemer's avatar
Pierre Kraemer committed
51
{
52 53 54
	Map2* ptrMap2 = dynamic_cast<Map2*>(&map);
	if (ptrMap2 != NULL)
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
55 56
		updateDataMap<PFP>(map, positions, ke, kf, good);
		return;
57 58 59 60
	}
	GMap2* ptrGMap2 = dynamic_cast<GMap2*>(&map);
	if (ptrGMap2 != NULL)
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
61 62
		updateDataGMap<PFP>(map, positions, ke, kf, good);
		return;
63 64 65
	}
}

Pierre Kraemer's avatar
Pierre Kraemer committed
66
template<typename PFP>
67
void TopoRender::updateDataMap(typename PFP::MAP& mapx, const VertexAttribute<typename PFP::VEC3>& positions, float ke, float kf, const FunctorSelect& good)
Pierre Kraemer's avatar
Pierre Kraemer committed
68
{
69 70
	Map2& map = reinterpret_cast<Map2&>(mapx);

Pierre Kraemer's avatar
Pierre Kraemer committed
71 72 73 74
	typedef typename PFP::VEC3 VEC3;
	typedef typename PFP::REAL REAL;

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

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

Sylvain Thery's avatar
Sylvain Thery committed
79
	if (!m_attIndex.isValid())
Pierre Kraemer's avatar
Pierre Kraemer committed
80
		m_attIndex  = map.template addAttribute<unsigned int, DART>("dart_index");
Pierre Kraemer's avatar
Pierre Kraemer committed
81 82 83 84 85 86 87 88 89

	for(Dart d = map.begin(); d!= map.end(); map.next(d))
	{
		if (good(d))
			vecDarts.push_back(d);
	}
	m_nbDarts = vecDarts.size();

	// debut phi1
90
	DartAutoAttribute<VEC3> fv1(map);
Pierre Kraemer's avatar
Pierre Kraemer committed
91
	// fin phi1
92
	DartAutoAttribute<VEC3> fv11(map);
Pierre Kraemer's avatar
Pierre Kraemer committed
93
	// phi2
94
	DartAutoAttribute<VEC3> fv2(map);
Pierre Kraemer's avatar
Pierre Kraemer committed
95

96 97 98
	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
99 100
	VEC3* colorDartBuf = reinterpret_cast<VEC3*>(ColorDartsBuffer);

101 102 103 104 105 106 107 108 109
//	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
110

111 112
	std::vector<VEC3> vecPos;
	vecPos.reserve(16);
Pierre Kraemer's avatar
Pierre Kraemer committed
113

114 115
	unsigned int indexDC=0;

Pierre Kraemer's avatar
Pierre Kraemer committed
116 117 118 119 120 121
	DartMarker mf(map);
	for(std::vector<Dart>::iterator id = vecDarts.begin(); id!= vecDarts.end(); id++)
	{
		Dart d = *id;
		if (!mf.isMarked(d))
		{
122
			vecPos.clear();
123 124 125
			VEC3 center = Algo::Surface::Geometry::faceCentroidELW<PFP>(mapx,d,positions);
			
			float k = 1.0f - kf;
Pierre Kraemer's avatar
Pierre Kraemer committed
126 127 128
			Dart dd = d;
			do
			{
129 130 131 132
				vecPos.push_back(center*k + positions[dd]*kf);
				dd = map.phi1(dd);
			} while (dd != d);

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

136

Pierre Kraemer's avatar
Pierre Kraemer committed
137 138 139 140 141 142
			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;

143 144
				m_attIndex[d] = indexDC;
				indexDC+=2;
Pierre Kraemer's avatar
Pierre Kraemer committed
145 146
				*positionDartBuf++ = P;
				*positionDartBuf++ = Q;
147
				*colorDartBuf++ = m_dartsColor;
148
				*colorDartBuf++ = m_dartsColor;
Pierre Kraemer's avatar
Pierre Kraemer committed
149 150 151 152 153 154 155 156
				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
157
			mf.markOrbit<FACE>(d);
Pierre Kraemer's avatar
Pierre Kraemer committed
158 159 160
		}
	}

161
	m_vbo0->bind();
162 163
	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
164

165 166
	m_vbo3->bind();
	glUnmapBuffer(GL_ARRAY_BUFFER);
Pierre Kraemer's avatar
Pierre Kraemer committed
167

168 169 170
	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
171

172 173 174
	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
175 176 177 178 179 180 181 182 183 184

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

Sylvain Thery's avatar
Sylvain Thery committed
186 187
//		if (good(e) && (e.index > d.index))
		if (good(e) && (d < e ))
Pierre Kraemer's avatar
Pierre Kraemer committed
188 189 190 191 192 193 194 195 196 197
		{
			*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
198
	m_nbRel1 = vecDarts.size();
Pierre Kraemer's avatar
Pierre Kraemer committed
199

200 201 202 203 204
	m_vbo1->bind();
	glUnmapBuffer(GL_ARRAY_BUFFER);

	m_vbo2->bind();
	glUnmapBuffer(GL_ARRAY_BUFFER);
Pierre Kraemer's avatar
Pierre Kraemer committed
205 206 207
}

template<typename PFP>
208
void TopoRender::updateDataGMap(typename PFP::MAP& mapx, const VertexAttribute<typename PFP::VEC3>& positions, float ke, float kf, const FunctorSelect& good)
Pierre Kraemer's avatar
Pierre Kraemer committed
209
{
Sylvain Thery's avatar
Sylvain Thery committed
210
	GMap2& map = dynamic_cast<GMap2&>(mapx);
211

Pierre Kraemer's avatar
Pierre Kraemer committed
212 213 214 215
	typedef typename PFP::VEC3 VEC3;
	typedef typename PFP::REAL REAL;

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

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

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

Pierre Kraemer's avatar
Pierre Kraemer committed
224 225 226 227 228 229 230 231

	for(Dart d = map.begin(); d!= map.end(); map.next(d))
	{
		if (good(d))
			vecDarts.push_back(d);
	}
	m_nbDarts = vecDarts.size();

232
	// debut phi1
233
	DartAutoAttribute<VEC3> fv1(map);
234
	// fin phi1
235
	DartAutoAttribute<VEC3> fv11(map);
236
	// phi2
237
	DartAutoAttribute<VEC3> fv2(map);
238 239 240 241

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

244 245 246
	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
247
	VEC3* positionDartBuf = reinterpret_cast<VEC3*>(PositionDartsBuffer);
248

249 250
	std::vector<VEC3> vecPos;
	vecPos.reserve(16);
Pierre Kraemer's avatar
Pierre Kraemer committed
251

252 253
	unsigned int indexDC=0;

Pierre Kraemer's avatar
Pierre Kraemer committed
254 255 256 257
	DartMarker mf(map);
	for(std::vector<Dart>::iterator id = vecDarts.begin(); id!= vecDarts.end(); id++)
	{
		Dart d = *id;
258

Pierre Kraemer's avatar
Pierre Kraemer committed
259 260
		if (!mf.isMarked(d))
		{
261
			vecPos.clear();
262 263 264
			VEC3 center = Algo::Surface::Geometry::faceCentroidELW<PFP>(mapx,d,positions);
			
			float k = 1.0f - kf;
Pierre Kraemer's avatar
Pierre Kraemer committed
265 266 267
			Dart dd = d;
			do
			{
268 269 270
				vecPos.push_back(center*k + positions[dd]*kf);
				dd = map.phi1(dd);
			} while (dd != d);
Pierre Kraemer's avatar
Pierre Kraemer committed
271 272 273 274 275 276 277 278 279 280 281 282

			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;
				VEC3 PP = REAL(0.52)*P + REAL(0.48)*Q;
				VEC3 QQ = REAL(0.52)*Q + REAL(0.48)*P;

283 284
				m_attIndex[d] = indexDC;
				indexDC+=2;
Pierre Kraemer's avatar
Pierre Kraemer committed
285
				*positionDartBuf++ = P;
286
				*colorDartBuf++ = m_dartsColor;
287
				*positionDartBuf++ = PP;
288
				*colorDartBuf++ = m_dartsColor;
Pierre Kraemer's avatar
Pierre Kraemer committed
289
				*positionDartBuf++ = Q;
290
				*colorDartBuf++ = m_dartsColor;
291
				*positionDartBuf++ = QQ;
292
				*colorDartBuf++ = m_dartsColor;
Pierre Kraemer's avatar
Pierre Kraemer committed
293

294
				VEC3 f = P*0.5f + PP*0.5f;
Pierre Kraemer's avatar
Pierre Kraemer committed
295
				fv2[d] = f;
296
				f = P*0.9f + PP*0.1f;
Pierre Kraemer's avatar
Pierre Kraemer committed
297 298
				fv1[d] = f;

299 300 301 302 303
				dd = map.beta0(d);
				f = Q*0.5f + QQ*0.5f;
				fv2[dd] = f;
				f = Q*0.9f + QQ*0.1f;
				fv1[dd] = f;
304 305 306
				m_attIndex[dd] = indexDC;
				indexDC+=2;

307

Pierre Kraemer's avatar
Pierre Kraemer committed
308 309
				d = map.phi1(d);
			}
Pierre Kraemer's avatar
Pierre Kraemer committed
310
			mf.markOrbit<FACE>(d);
Pierre Kraemer's avatar
Pierre Kraemer committed
311 312 313
		}
	}

314 315
	m_vbo0->bind();
	glUnmapBuffer(GL_ARRAY_BUFFER);
Pierre Kraemer's avatar
Pierre Kraemer committed
316

317 318
	m_vbo3->bind();
	glUnmapBuffer(GL_ARRAY_BUFFER);
Pierre Kraemer's avatar
Pierre Kraemer committed
319

320 321 322
	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
323

324 325 326
	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
327 328 329 330

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

331
	m_nbRel2 = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
332 333 334 335
	for(std::vector<Dart>::iterator id = vecDarts.begin(); id!= vecDarts.end(); id++)
	{
		Dart d = *id;
		Dart e = map.beta2(d);
Sylvain Thery's avatar
Sylvain Thery committed
336
		if (good(e) && (d < e ))
Pierre Kraemer's avatar
Pierre Kraemer committed
337 338 339 340 341 342 343 344 345 346
		{
			*positionF2++ = fv2[d];
			*positionF2++ = fv2[e];
			m_nbRel2++;
		}

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

349 350 351 352 353
	m_vbo1->bind();
	glUnmapBuffer(GL_ARRAY_BUFFER);

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

Sylvain Thery's avatar
Sylvain Thery committed
356 357 358 359
template<typename PFP>
void TopoRender::setDartsIdColor(typename PFP::MAP& map, const FunctorSelect& good)
{
	m_vbo3->bind();
Pierre Kraemer's avatar
Pierre Kraemer committed
360 361
	float* colorBuffer = reinterpret_cast<float*>(glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE));
	unsigned int nb = 0;
Sylvain Thery's avatar
Sylvain Thery committed
362

Pierre Kraemer's avatar
Pierre Kraemer committed
363
	m_attIndex = map.template getAttribute<unsigned int, DART>("dart_index");
Sylvain Thery's avatar
Sylvain Thery committed
364 365 366 367 368 369
	if (!m_attIndex.isValid())
	{
		CGoGNerr << "Error attribute_dartIndex does not exist during TopoRender::picking" << CGoGNendl;
		return;
	}

Sylvain Thery's avatar
Sylvain Thery committed
370 371
	for (Dart d = map.begin(); d != map.end(); map.next(d))
	{
372
		if (good(d))
Sylvain Thery's avatar
Sylvain Thery committed
373
		{
374
			if (nb < m_nbDarts)
Sylvain Thery's avatar
Sylvain Thery committed
375 376
			{
				float r,g,b;
377
				dartToCol(d, r,g,b);
Sylvain Thery's avatar
Sylvain Thery committed
378 379 380 381 382 383 384 385 386
				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++;
			}
387 388 389
			else
			{
				CGoGNerr << "Error buffer too small for color picking (change the good parameter ?)" << CGoGNendl;
390
				break;
391
			}
Sylvain Thery's avatar
Sylvain Thery committed
392 393 394 395 396 397
		}
	}
	glUnmapBuffer(GL_ARRAY_BUFFER);
}

template<typename PFP>
398
Dart TopoRender::picking(typename PFP::MAP& map,int x, int y, const FunctorSelect& good)
Sylvain Thery's avatar
Sylvain Thery committed
399 400 401 402 403 404 405 406 407
{
	pushColors();
	setDartsIdColor<PFP>(map,good);
	Dart d = pickColor(x,y);
	popColors();
	return d;

}

408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468


template<typename PFP>
Dart TopoRender::coneSelection(typename PFP::MAP& map, const Geom::Vec3f& rayA, const Geom::Vec3f& rayAB, float angle, const FunctorSelect& good)
{
	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>
Dart TopoRender::raySelection(typename PFP::MAP& map, const Geom::Vec3f& rayA, const Geom::Vec3f& rayAB, float dmax, const FunctorSelect& good)
{
	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
469
}//end namespace GL2
Pierre Kraemer's avatar
Pierre Kraemer committed
470 471 472 473 474 475

}//end namespace Algo

}//end namespace Render

}//end namespace CGoGN