topo3Render.hpp 24.4 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 28 29 30 31 32
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

#include "Geometry/vector_gen.h"
#include "Topology/generic/autoAttributeHandler.h"
#include "Topology/generic/dartmarker.h"
#include "Topology/generic/cellmarker.h"

#include "Topology/map/map3.h"
#include "Topology/gmap/gmap3.h"

33 34 35
#include "Topology/generic/traversorCell.h"
#include "Algo/Geometry/centroid.h"

36 37
#include "Geometry/distances.h"

Pierre Kraemer's avatar
Pierre Kraemer committed
38 39 40 41 42 43 44 45 46
namespace CGoGN
{

namespace Algo
{

namespace Render
{

Sylvain Thery's avatar
Sylvain Thery committed
47
namespace GL2
Pierre Kraemer's avatar
Pierre Kraemer committed
48
{
49
template<typename PFP>
50
void Topo3Render::updateData(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& positions, float ke, float kf, float kv, const FunctorSelect& good)
51 52 53 54 55 56 57 58 59 60 61 62 63
{
	Map3* ptrMap3 = dynamic_cast<Map3*>(&map);
	if (ptrMap3 != NULL)
	{
		updateDataMap3<PFP>(map,positions,ke,kf,kv,good);
	}
	GMap3* ptrGMap3 = dynamic_cast<GMap3*>(&map);
	if (ptrGMap3 != NULL)
	{
		updateDataGMap3<PFP>(map,positions,ke,kf,kv,good);
	}
}

Pierre Kraemer's avatar
Pierre Kraemer committed
64
template<typename PFP>
65
void Topo3Render::updateDataMap3(typename PFP::MAP& mapx, const VertexAttribute<typename PFP::VEC3>& positions, float ke, float kf, float kv, const FunctorSelect& good)
Pierre Kraemer's avatar
Pierre Kraemer committed
66 67 68 69
{
	typedef typename PFP::VEC3 VEC3;
	typedef typename PFP::REAL REAL;

Sylvain Thery's avatar
Sylvain Thery committed
70
	m_attIndex  = mapx.template getAttribute<unsigned int, DART>("dart_index");
Sylvain Thery's avatar
Sylvain Thery committed
71 72

	if (!m_attIndex.isValid())
73
		m_attIndex  = mapx.template addAttribute<unsigned int, DART>("dart_index");
Pierre Kraemer's avatar
Pierre Kraemer committed
74 75

	m_nbDarts = 0;
Sylvain Thery's avatar
Sylvain Thery committed
76
	for (Dart d = mapx.begin(); d != mapx.end(); mapx.next(d))
Pierre Kraemer's avatar
Pierre Kraemer committed
77 78
	{
		if (good(d))
79 80 81 82
			m_nbDarts++;
	}

	// compute center of each volumes
Pierre Kraemer's avatar
Pierre Kraemer committed
83
	CellMarker<VOLUME> cmv(mapx);
84
	VolumeAutoAttribute<VEC3> centerVolumes(mapx, "centerVolumes");
Sylvain Thery's avatar
Sylvain Thery committed
85

86 87
	Algo::Geometry::Parallel::computeCentroidVolumes<PFP>(mapx, positions, centerVolumes, allDarts,3);

Pierre Kraemer's avatar
Pierre Kraemer committed
88 89

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

	// phi2
95 96
	DartAutoAttribute<VEC3> fv2(mapx);
	DartAutoAttribute<VEC3> fv2x(mapx);
Pierre Kraemer's avatar
Pierre Kraemer committed
97

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

103 104 105
	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);
Pierre Kraemer's avatar
Pierre Kraemer committed
106 107 108
	VEC3* positionDartBuf = reinterpret_cast<VEC3*>(PositionDartsBuffer);


109
	std::vector<Dart> vecDartFaces;
Sylvain Thery's avatar
Sylvain Thery committed
110
	vecDartFaces.reserve(m_nbDarts/3);
111
	unsigned int posDBI=0;
Pierre Kraemer's avatar
Pierre Kraemer committed
112

113
	// traverse each face of each volume
Pierre Kraemer's avatar
Pierre Kraemer committed
114
	TraversorCell<typename PFP::MAP, PFP::MAP::FACE_OF_PARENT> traFace(mapx, allDarts);
Pierre Kraemer's avatar
Pierre Kraemer committed
115
	for (Dart d = traFace.begin(); d != traFace.end(); d = traFace.next())
Pierre Kraemer's avatar
Pierre Kraemer committed
116
	{
117 118 119 120 121 122 123 124 125 126 127 128
		vecDartFaces.push_back(d);

		std::vector<VEC3> vecPos;
		vecPos.reserve(16);

		// store the face & center
		float okv = 1.0f - kv;

		VEC3 vc = centerVolumes[d];
		VEC3 centerFace(0, 0, 0);
		Dart dd = d;
		do
Pierre Kraemer's avatar
Pierre Kraemer committed
129
		{
130 131 132 133
			VEC3 P = positions[dd];
			P  = vc*okv + P*kv;
			vecPos.push_back(P);
			centerFace += P;
Sylvain Thery's avatar
Sylvain Thery committed
134
			dd = mapx.phi1(dd);
135 136
		} while (dd != d);
		centerFace /= REAL(vecPos.size());
Pierre Kraemer's avatar
Pierre Kraemer committed
137

138 139
		//shrink the face
		unsigned int nb = vecPos.size();
Pierre Kraemer's avatar
Pierre Kraemer committed
140

141
		float okf = 1.0f - kf;
Pierre Kraemer's avatar
Pierre Kraemer committed
142

143 144 145 146 147
		for (unsigned int i = 0; i < nb; ++i)
		{
			vecPos[i] = centerFace*okf + vecPos[i]*kf;
		}
		vecPos.push_back(vecPos.front()); // copy the first for easy computation on next loop
Pierre Kraemer's avatar
Pierre Kraemer committed
148

149 150 151 152
		// compute position of points to use for drawing topo
		float oke = 1.0f - ke;
		for (unsigned int i = 0; i < nb; ++i)
		{
153 154 155 156
			if (good(d))
			{
				VEC3 P = vecPos[i]*ke + vecPos[i+1]*oke;
				VEC3 Q = vecPos[i+1]*ke + vecPos[i]*oke;
157

158 159
				m_attIndex[d] = posDBI;
				posDBI+=2;
Pierre Kraemer's avatar
Pierre Kraemer committed
160

161 162 163 164
				*positionDartBuf++ = P;
				*positionDartBuf++ = Q;
				*colorDartBuf++ = m_dartsColor;
				*colorDartBuf++ = m_dartsColor;
Pierre Kraemer's avatar
Pierre Kraemer committed
165

166 167
				fv1[d] = P*0.1f + Q*0.9f;
				fv11[d] = P*0.9f + Q*0.1f;
Pierre Kraemer's avatar
Pierre Kraemer committed
168

169 170 171
				fv2[d] = P*0.52f + Q*0.48f;
				fv2x[d] = P*0.48f + Q*0.52f;
			}
Pierre Kraemer's avatar
Pierre Kraemer committed
172

Sylvain Thery's avatar
Sylvain Thery committed
173
			d = mapx.phi1(d);
Pierre Kraemer's avatar
Pierre Kraemer committed
174 175 176
		}
	}

177 178
	m_vbo0->bind();
	glUnmapBuffer(GL_ARRAY_BUFFER);
Pierre Kraemer's avatar
Pierre Kraemer committed
179

180 181 182
	m_vbo4->bind();
	glUnmapBuffer(GL_ARRAY_BUFFER);

Pierre Kraemer's avatar
Pierre Kraemer committed
183

184 185 186
	VEC3* positioniF1 = new VEC3[ 2*m_nbDarts];
	VEC3* positioniF2 = new VEC3[ 2*m_nbDarts];
	VEC3* positioniF3 = new VEC3[ 2*m_nbDarts];
Pierre Kraemer's avatar
Pierre Kraemer committed
187

188 189 190
	VEC3* positionF1 = positioniF1;
	VEC3* positionF2 = positioniF2;
	VEC3* positionF3 = positioniF3;
Pierre Kraemer's avatar
Pierre Kraemer committed
191

192
	m_nbRel1=0;
Pierre Kraemer's avatar
Pierre Kraemer committed
193 194 195 196 197 198 199 200
	m_nbRel2=0;
	m_nbRel3=0;

	for(std::vector<Dart>::iterator face = vecDartFaces.begin(); face != vecDartFaces.end(); ++face)
	{
		Dart d = *face;
		do
		{
Sylvain Thery's avatar
Sylvain Thery committed
201
			Dart e = mapx.phi2(d);
202
			if ((d < e) && good(d) && good(e))
Pierre Kraemer's avatar
Pierre Kraemer committed
203 204 205 206 207 208 209
			{
				*positionF2++ = fv2[d];
				*positionF2++ = fv2x[e];
				*positionF2++ = fv2[e];
				*positionF2++ = fv2x[d];
				m_nbRel2++;
			}
Sylvain Thery's avatar
Sylvain Thery committed
210
			e = mapx.phi3(d);
211
			if (!mapx.isBoundaryMarked(e) && (d < e) && good(d) && good(e))
Pierre Kraemer's avatar
Pierre Kraemer committed
212 213 214 215 216 217 218
			{
				*positionF3++ = fv2[d];
				*positionF3++ = fv2x[e];
				*positionF3++ = fv2[e];
				*positionF3++ = fv2x[d];
				m_nbRel3++;
			}
Sylvain Thery's avatar
Sylvain Thery committed
219
			e = mapx.phi1(d);
220 221 222 223 224 225
			if (good(d) && good(e))
			{
				*positionF1++ = fv1[d];
				*positionF1++ = fv11[e];
				m_nbRel1++;
			}
Sylvain Thery's avatar
Sylvain Thery committed
226
			d = mapx.phi1(d);
Pierre Kraemer's avatar
Pierre Kraemer committed
227 228 229
		} while (d != *face );
	}

230
	m_vbo3->bind();
231
	glBufferData(GL_ARRAY_BUFFER, 4*m_nbRel3*sizeof(typename PFP::VEC3), positioniF3, GL_STREAM_DRAW);
Pierre Kraemer's avatar
Pierre Kraemer committed
232

233
	m_vbo2->bind();
234
	glBufferData(GL_ARRAY_BUFFER, 4*m_nbRel2*sizeof(typename PFP::VEC3), positioniF2, GL_STREAM_DRAW);
Pierre Kraemer's avatar
Pierre Kraemer committed
235

236
	m_vbo1->bind();
237
	glBufferData(GL_ARRAY_BUFFER, 2*m_nbRel1*sizeof(typename PFP::VEC3), positioniF1, GL_STREAM_DRAW);
Pierre Kraemer's avatar
Pierre Kraemer committed
238

239 240 241
	delete[] positioniF1;
	delete[] positioniF2;
	delete[] positioniF3;
Pierre Kraemer's avatar
Pierre Kraemer committed
242
}
Sylvain Thery's avatar
Sylvain Thery committed
243

244
template<typename PFP>
245
void Topo3Render::setDartsIdColor(typename PFP::MAP& map, const FunctorSelect& good)
246
{
247 248
	m_vbo4->bind();
	float* colorBuffer =  reinterpret_cast<float*>(glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE));
249 250 251 252
	unsigned int nb=0;

	for (Dart d = map.begin(); d != map.end(); map.next(d))
	{
253
		if (good(d))
254
		{
255
			if (nb < m_nbDarts)
256
			{
Sylvain Thery's avatar
Sylvain Thery committed
257
				float r,g,b;
258
				dartToCol(d, r,g,b);
259
				
Sylvain Thery's avatar
Sylvain Thery committed
260 261 262 263 264 265 266
				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;
267 268 269

				nb++;
			}
270 271
			else
			{
272 273 274 275 276 277 278 279 280
				CGoGNerr << "Error buffer too small for color picking (change the selector parameter ?)" << CGoGNendl;
				break;
			}
		}
	}
	glUnmapBuffer(GL_ARRAY_BUFFER);
}

template<typename PFP>
281
void Topo3Render::updateColors(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& colors, const FunctorSelect& good)
282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298
{
	m_vbo4->bind();
	Geom::Vec3f* colorBuffer =  reinterpret_cast<Geom::Vec3f*>(glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE));
	unsigned int nb=0;

	for (Dart d = map.begin(); d != map.end(); map.next(d))
	{
		if (good(d))
		{
			if (nb < m_nbDarts)
			{
				colorBuffer[m_attIndex[d]] = colors[d];
				nb++;
			}
			else
			{
				CGoGNerr << "Error buffer too small for color picking (change the selector parameter ?)" << CGoGNendl;
299
				break;
300
			}
301 302
		}
	}
303
	glUnmapBuffer(GL_ARRAY_BUFFER);
304 305
}

Sylvain Thery's avatar
Sylvain Thery committed
306
template<typename PFP>
307
Dart Topo3Render::picking(typename PFP::MAP& map, int x, int y, const FunctorSelect& good)
Sylvain Thery's avatar
Sylvain Thery committed
308 309 310 311 312 313 314 315
{
	pushColors();
	setDartsIdColor<PFP>(map,good);
	Dart d = pickColor(x,y);
	popColors();
	return d;
}

Thomas's avatar
Thomas committed
316
template<typename PFP>
317
void Topo3Render::updateDataGMap3(typename PFP::MAP& mapx, const VertexAttribute<typename PFP::VEC3>& positions, float ke, float kf, float kv, const FunctorSelect& good)
Thomas's avatar
Thomas committed
318
{
319 320 321
	typedef typename PFP::VEC3 VEC3;
	typedef typename PFP::REAL REAL;

322
	GMap3& map = dynamic_cast<GMap3&>(mapx);	// TODO reflechir comment virer ce warning quand on compile avec PFP::MAP=Map3
323

Thomas's avatar
Thomas committed
324 325 326
	typedef typename PFP::VEC3 VEC3;
	typedef typename PFP::REAL REAL;

Sylvain Thery's avatar
Sylvain Thery committed
327
	if (m_attIndex.map() != &mapx)
328
		m_attIndex  = mapx.template getAttribute<unsigned int, DART>("dart_index");
Sylvain Thery's avatar
Sylvain Thery committed
329
	if (!m_attIndex.isValid())
330
		m_attIndex  = mapx.template addAttribute<unsigned int, DART>("dart_index");
Thomas's avatar
Thomas committed
331 332

	m_nbDarts = 0;
Sylvain Thery's avatar
Sylvain Thery committed
333
	for (Dart d = mapx.begin(); d != mapx.end(); mapx.next(d))
Thomas's avatar
Thomas committed
334
	{
335
		if (good(d))
336 337 338 339
			m_nbDarts++;
	}

	// compute center of each volumes
340
	VolumeAutoAttribute<VEC3> centerVolumes(mapx, "centerVolumes");
341
	Algo::Geometry::Parallel::computeCentroidVolumes<PFP>(mapx, positions, centerVolumes, good);
342 343

	// beta1
344
	DartAutoAttribute<VEC3> fv1(mapx);
345
	// beta2/3
346 347
	DartAutoAttribute<VEC3> fv2(mapx);
	DartAutoAttribute<VEC3> fv2x(mapx);
348 349 350 351 352 353

	m_vbo4->bind();
	glBufferData(GL_ARRAY_BUFFER, 2*m_nbDarts*sizeof(VEC3), 0, GL_STREAM_DRAW);
	GLvoid* ColorDartsBuffer = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
	VEC3* colorDartBuf = reinterpret_cast<VEC3*>(ColorDartsBuffer);

354 355 356 357 358 359 360 361 362 363

	if (m_bufferDartPosition!=NULL)
		delete m_bufferDartPosition;
	m_bufferDartPosition = new Geom::Vec3f[2*m_nbDarts];
	VEC3* positionDartBuf = reinterpret_cast<VEC3*>(m_bufferDartPosition);

//	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);
364

365
	std::vector<Dart> vecDartFaces;
Sylvain Thery's avatar
Sylvain Thery committed
366
	vecDartFaces.reserve(m_nbDarts/6);
367 368 369
	unsigned int posDBI=0;

	//traverse each face of each volume
Pierre Kraemer's avatar
Pierre Kraemer committed
370
	TraversorCell<typename PFP::MAP, PFP::MAP::FACE_OF_PARENT> traFace(mapx, good);
Pierre Kraemer's avatar
Pierre Kraemer committed
371
	for (Dart d = traFace.begin(); d != traFace.end(); d = traFace.next())
372
	{
373 374 375 376 377 378 379 380 381 382 383 384
		vecDartFaces.push_back(d);

		std::vector<VEC3> vecPos;
		vecPos.reserve(16);

		// store the face & center
		float okv = 1.0f - kv;

		VEC3 vc = centerVolumes[d];
		VEC3 centerFace(0, 0, 0);
		Dart dd = d;
		do
385
		{
386 387 388 389
			VEC3 P = positions[dd];
			P  = vc*okv + P*kv;
			vecPos.push_back(P);
			centerFace += P;
Sylvain Thery's avatar
Sylvain Thery committed
390
			dd = mapx.phi1(dd);
391 392
		} while (dd != d);
		centerFace /= REAL(vecPos.size());
393

394 395
		//shrink the face
		unsigned int nb = vecPos.size();
396

397
		float okf = 1.0f - kf;
398

399 400 401 402 403
		for (unsigned int i = 0; i < nb; ++i)
		{
			vecPos[i] = centerFace*okf + vecPos[i]*kf;
		}
		vecPos.push_back(vecPos.front()); // copy the first for easy computation on next loop
404

405 406 407 408 409 410
		// compute position of points to use for drawing topo
		float oke = 1.0f - ke;
		for (unsigned int i = 0; i < nb; ++i)
		{
			VEC3 P = vecPos[i]*ke + vecPos[i+1]*oke;
			VEC3 Q = vecPos[i+1]*ke + vecPos[i]*oke;
411

412 413
			VEC3 PP = 0.52f*P + 0.48f*Q;
			VEC3 QQ = 0.52f*Q + 0.48f*P;
414

415 416 417 418
			*positionDartBuf++ = P;
			*positionDartBuf++ = PP;
			*positionDartBuf++ = Q;
			*positionDartBuf++ = QQ;
419 420 421 422
			*colorDartBuf++ = m_dartsColor;
			*colorDartBuf++ = m_dartsColor;
			*colorDartBuf++ = m_dartsColor;
			*colorDartBuf++ = m_dartsColor;
423

424 425
			m_attIndex[d] = posDBI;
			posDBI+=2;
426 427


428 429 430 431 432 433 434
			fv1[d] = P*0.9f + PP*0.1f;
			fv2x[d] = P*0.52f + PP*0.48f;
			fv2[d] = P*0.48f + PP*0.52f;
			Dart dx = map.beta0(d);
			fv1[dx] = Q*0.9f + QQ*0.1f;
			fv2[dx] = Q*0.52f + QQ*0.48f;
			fv2x[dx] = Q*0.48f + QQ*0.52f;
435

436 437
			m_attIndex[dx] = posDBI;
			posDBI+=2;
438

439 440
			d = mapx.phi1(d);
		}
441 442 443
	}

	m_vbo0->bind();
444 445 446
	glBufferData(GL_ARRAY_BUFFER, 2*m_nbDarts*sizeof(VEC3), m_bufferDartPosition, GL_STREAM_DRAW);
//	m_vbo0->bind();
//	glUnmapBuffer(GL_ARRAY_BUFFER);
447

448 449 450 451
	m_vbo4->bind();
	glUnmapBuffer(GL_ARRAY_BUFFER);

	// beta3
452
	m_vbo1->bind();
453
	glBufferData(GL_ARRAY_BUFFER, 2*m_nbDarts*sizeof(typename PFP::VEC3), 0, GL_STREAM_DRAW);
454 455
	GLvoid* PositionBuffer1 = glMapBufferARB(GL_ARRAY_BUFFER, GL_READ_WRITE);

456
	// beta3
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 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506
	m_vbo2->bind();
	glBufferData(GL_ARRAY_BUFFER, 2*m_nbDarts*sizeof(typename PFP::VEC3), 0, GL_STREAM_DRAW);
	GLvoid* PositionBuffer2 = glMapBufferARB(GL_ARRAY_BUFFER, GL_READ_WRITE);

	// beta3
	m_vbo3->bind();
	glBufferData(GL_ARRAY_BUFFER, 2*m_nbDarts*sizeof(typename PFP::VEC3), 0, GL_STREAM_DRAW);
	GLvoid* PositionBuffer3 = glMapBufferARB(GL_ARRAY_BUFFER, GL_READ_WRITE);

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

	m_nbRel2=0;
	m_nbRel3=0;

	for(std::vector<Dart>::iterator face = vecDartFaces.begin(); face != vecDartFaces.end(); ++face)
	{
		Dart d = *face;
		do
		{
			Dart e = map.beta2(d);
			if (d < e)
			{
				*positionF2++ = fv2[d];
				*positionF2++ = fv2x[e];
				*positionF2++ = fv2[e];
				*positionF2++ = fv2x[d];
				m_nbRel2++;
			}
			e = map.beta3(d);
			if (!map.isBoundaryMarked(e) && (d < e))
			{
				*positionF3++ = fv2[d];
				*positionF3++ = fv2x[e];
				*positionF3++ = fv2[e];
				*positionF3++ = fv2x[d];
				m_nbRel3++;
			}
			d = map.beta0(d);
			e = map.beta2(d);
			if (d < e)
			{
				*positionF2++ = fv2[d];
				*positionF2++ = fv2x[e];
				*positionF2++ = fv2[e];
				*positionF2++ = fv2x[d];
				m_nbRel2++;
			}
			e = map.beta3(d);
507
			if (!map.isBoundaryMarked(e) && (d < e))
508 509 510 511 512 513 514 515 516 517
			{
				*positionF3++ = fv2[d];
				*positionF3++ = fv2x[e];
				*positionF3++ = fv2[e];
				*positionF3++ = fv2x[d];
				m_nbRel3++;
			}
			*positionF1++ = fv1[d];
			d = map.beta1(d);
			*positionF1++ = fv1[d];
518
			m_nbRel1++;
519 520 521 522 523 524 525 526 527 528 529 530 531 532 533
		} while (d != *face );
	}

	m_vbo3->bind();
	glUnmapBufferARB(GL_ARRAY_BUFFER);

	m_vbo2->bind();
	glUnmapBufferARB(GL_ARRAY_BUFFER);

	m_vbo1->bind();
	glUnmapBuffer(GL_ARRAY_BUFFER);

	m_vbo4->bind();
	glUnmapBuffer(GL_ARRAY_BUFFER);
}
Sylvain Thery's avatar
Sylvain Thery committed
534

Pierre Kraemer's avatar
Pierre Kraemer committed
535
template<typename PFP>
536
void Topo3Render::computeDartMiddlePositions(typename PFP::MAP& map, DartAttribute<typename PFP::VEC3>& posExpl, const FunctorSelect& good)
Pierre Kraemer's avatar
Pierre Kraemer committed
537 538 539 540 541 542 543 544 545 546 547 548 549 550 551
{
	m_vbo0->bind();
	typename PFP::VEC3* positionsPtr = reinterpret_cast<typename PFP::VEC3*>(glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY));

	for (Dart d = map.begin(); d != map.end(); map.next(d))
	{
		if (good(d))
		{
			posExpl[d] = (positionsPtr[m_attIndex[d]] + positionsPtr[m_attIndex[d]+1])*0.5f;
		}
	}

	m_vbo0->bind();
	glUnmapBuffer(GL_ARRAY_BUFFER);
}
552

untereiner's avatar
untereiner committed
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 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627
//template<typename PFP>
//void Topo3Render::updateDataMap3OldFashioned(typename PFP::MAP& mapx, const typename PFP::TVEC3& positions, float ke, float kf, float kv, const FunctorSelect& good)
//{
//	Map3& map = reinterpret_cast<Map3&>(mapx);
//
//	typedef typename PFP::VEC3 VEC3;
//	typedef typename PFP::REAL REAL;
//
//
//	if (m_attIndex.map() != &map)
//	{
//		m_attIndex  = map.template getAttribute<unsigned int>(DART, "dart_index");
//		if (!m_attIndex.isValid())
//			m_attIndex  = map.template addAttribute<unsigned int>(DART, "dart_index");
//	}
//
//	m_nbDarts = 0;
//
//	// table of center of volume
//	std::vector<VEC3> vecCenters;
//	vecCenters.reserve(1000);
//	// table of nbfaces per volume
//	std::vector<unsigned int> vecNbFaces;
//	vecNbFaces.reserve(1000);
//	// table of face (one dart of each)
//	std::vector<Dart> vecDartFaces;
//	vecDartFaces.reserve(map.getNbDarts()/4);
//
//	unsigned int posDBI=0;
//
//	DartMarker mark(map);					// marker for darts
//	for (Dart d = map.begin(); d != map.end(); map.next(d))
//	{
//		if (good(d))
//		{
//			CellMarkerStore markVert(map, VERTEX);		//marker for vertices
//			VEC3 center(0, 0, 0);
//			unsigned int nbv = 0;
//			unsigned int nbf = 0;
//			std::list<Dart> visitedFaces;	// Faces that are traversed
//			visitedFaces.push_back(d);		// Start with the face of d
//
//			// For every face added to the list
//			for (std::list<Dart>::iterator face = visitedFaces.begin(); face != visitedFaces.end(); ++face)
//			{
//				if (!mark.isMarked(*face))		// Face has not been visited yet
//				{
//					// store a dart of face
//					vecDartFaces.push_back(*face);
//					nbf++;
//					Dart dNext = *face ;
//					do
//					{
//						if (!markVert.isMarked(dNext))
//						{
//							markVert.mark(dNext);
//							center += positions[dNext];
//							nbv++;
//						}
//						mark.mark(dNext);					// Mark
//						m_nbDarts++;
//						Dart adj = map.phi2(dNext);				// Get adjacent face
//						if (adj != dNext && !mark.isMarked(adj))
//							visitedFaces.push_back(adj);	// Add it
//						dNext = map.phi1(dNext);
//					} while(dNext != *face);
//				}
//			}
//			center /= typename PFP::REAL(nbv);
//			vecCenters.push_back(center);
//			vecNbFaces.push_back(nbf);
//		}
//	}
//
//	// debut phi1
628
//	DartAutoAttribute<VEC3> fv1(map);
untereiner's avatar
untereiner committed
629
//	// fin phi1
630
//	DartAutoAttribute<VEC3> fv11(map);
untereiner's avatar
untereiner committed
631 632
//
//	// phi2
633 634
//	DartAutoAttribute<VEC3> fv2(map);
//	DartAutoAttribute<VEC3> fv2x(map);
untereiner's avatar
untereiner committed
635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775
//
//	m_vbo4->bind();
//	glBufferData(GL_ARRAY_BUFFER, 2*m_nbDarts*sizeof(VEC3), 0, GL_STREAM_DRAW);
//	GLvoid* ColorDartsBuffer = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
//	VEC3* colorDartBuf = reinterpret_cast<VEC3*>(ColorDartsBuffer);
//
//	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);
//
//
//
//	std::vector<Dart>::iterator face = vecDartFaces.begin();
//	for (unsigned int iVol=0; iVol<vecNbFaces.size(); ++iVol)
//	{
//		for (unsigned int iFace = 0; iFace < vecNbFaces[iVol]; ++iFace)
//		{
//			Dart d = *face++;
//
//			std::vector<VEC3> vecPos;
//			vecPos.reserve(16);
//
//			// store the face & center
//			VEC3 center(0, 0, 0);
//			Dart dd = d;
//			do
//			{
//				const VEC3& P = positions[d];
//				vecPos.push_back(P);
//				center += P;
//				d = map.phi1(d);
//			} while (d != dd);
//			center /= REAL(vecPos.size());
//
//			//shrink the face
//			unsigned int nb = vecPos.size();
//			float okf = 1.0f - kf;
//			float okv = 1.0f - kv;
//			for (unsigned int i = 0; i < nb; ++i)
//			{
//				vecPos[i] = vecCenters[iVol]*okv + vecPos[i]*kv;
//				vecPos[i] = center*okf + vecPos[i]*kf;
//			}
//			vecPos.push_back(vecPos.front()); // copy the first for easy computation on next loop
//
//			// compute position of points to use for drawing topo
//			float oke = 1.0f - ke;
//			for (unsigned int i = 0; i < nb; ++i)
//			{
//				VEC3 P = vecPos[i]*ke + vecPos[i+1]*oke;
//				VEC3 Q = vecPos[i+1]*ke + vecPos[i]*oke;
//
//				m_attIndex[d] = posDBI;
//				posDBI+=2;
//
//				*positionDartBuf++ = P;
//				*positionDartBuf++ = Q;
//				*colorDartBuf++ = VEC3(1.,1.,1.0);
//				*colorDartBuf++ = VEC3(1.,1.,1.0);
//
//				fv1[d] = P*0.1f + Q*0.9f;
//				fv11[d] = P*0.9f + Q*0.1f;
//
//				fv2[d] = P*0.52f + Q*0.48f;
//				fv2x[d] = P*0.48f + Q*0.52f;
//
//				d = map.phi1(d);
//			}
//
//		}
//	}
//
//	m_vbo0->bind();
//	glUnmapBuffer(GL_ARRAY_BUFFER);
//
//	// phi1
//	m_vbo1->bind();
//	glBufferData(GL_ARRAY_BUFFER, 2*m_nbDarts*sizeof(typename PFP::VEC3), 0, GL_STREAM_DRAW);
//	GLvoid* PositionBuffer1 = glMapBufferARB(GL_ARRAY_BUFFER, GL_READ_WRITE);
//
//	//phi2
//	m_vbo2->bind();
//	glBufferData(GL_ARRAY_BUFFER, 2*m_nbDarts*sizeof(typename PFP::VEC3), 0, GL_STREAM_DRAW);
//	GLvoid* PositionBuffer2 = glMapBufferARB(GL_ARRAY_BUFFER, GL_READ_WRITE);
//
//	//phi3
//	m_vbo3->bind();
//	glBufferData(GL_ARRAY_BUFFER, 2*m_nbDarts*sizeof(typename PFP::VEC3), 0, GL_STREAM_DRAW);
//	GLvoid* PositionBuffer3 = glMapBufferARB(GL_ARRAY_BUFFER, GL_READ_WRITE);
//
//	VEC3* positionF1 = reinterpret_cast<VEC3*>(PositionBuffer1);
//	VEC3* positionF2 = reinterpret_cast<VEC3*>(PositionBuffer2);
//	VEC3* positionF3 = reinterpret_cast<VEC3*>(PositionBuffer3);
//
//	m_nbRel2=0;
//	m_nbRel3=0;
//
//	for(std::vector<Dart>::iterator face = vecDartFaces.begin(); face != vecDartFaces.end(); ++face)
//	{
//		Dart d = *face;
//		do
//		{
//			Dart e = map.phi2(d);
//			if (d < e)
//			{
//				*positionF2++ = fv2[d];
//				*positionF2++ = fv2x[e];
//				*positionF2++ = fv2[e];
//				*positionF2++ = fv2x[d];
//				m_nbRel2++;
//			}
//			e = map.phi3(d);
//			if (!map.isBoundaryMarked(e) && (d < e))
//			{
//				*positionF3++ = fv2[d];
//				*positionF3++ = fv2x[e];
//				*positionF3++ = fv2[e];
//				*positionF3++ = fv2x[d];
//				m_nbRel3++;
//			}
//			e = map.phi1(d);
//			*positionF1++ = fv1[d];
//			*positionF1++ = fv11[e];
//
//			d = map.phi1(d);
//		} while (d != *face );
//	}
//
//	m_vbo3->bind();
//	glUnmapBufferARB(GL_ARRAY_BUFFER);
//
//	m_vbo2->bind();
//	glUnmapBufferARB(GL_ARRAY_BUFFER);
//
//	m_vbo1->bind();
//	glUnmapBuffer(GL_ARRAY_BUFFER);
//
//	m_vbo4->bind();
//	glUnmapBuffer(GL_ARRAY_BUFFER);
//}
776

777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893

template<typename PFP>
Dart Topo3Render::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 Topo3Render::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;
}

// DART RAY SELECTION
//template<typename PFP>
//void edgesConeSelection(, const VertexAttribute<typename PFP::VEC3>& position, const typename PFP::VEC3& rayA, const typename PFP::VEC3& rayAB, float angle, std::vector<Dart>& vecEdges, const FunctorSelect& good)
//{
//	typename PFP::REAL AB2 = rayAB * rayAB;
//
//	double sin2 = sin(M_PI/180.0 * angle);
//	sin2 = sin2*sin2;
//
//	// recuperation des aretes intersectees
//	vecEdges.reserve(256);
//	vecEdges.clear();
//
//	TraversorE<typename PFP::MAP> trav(map);
//	for(Dart d = trav.begin(); d!=trav.end(); d = trav.next())
//	{
//		// get back position of segment PQ
//		const typename PFP::VEC3& P = position[d];
//		const typename PFP::VEC3& Q = position[map.phi1(d)];
//		// the three distance to P, Q and (PQ) not used here
//		float ld2 = Geom::squaredDistanceLine2Seg(rayA, rayAB, AB2, P, Q);
//		typename PFP::VEC3 V = P - rayA;
//		double s2 = double(ld2) / double(V*V);
//		if (s2 < sin2)
//			vecEdges.push_back(d);
//	}
//
//	typedef std::pair<typename PFP::REAL, Dart> DartDist;
//	std::vector<DartDist> distndart;
//
//	unsigned int nbi = vecEdges.size();
//	distndart.resize(nbi);
//
//	// compute all distances to observer for each middle of intersected edge
//	// and put them in a vector for sorting
//	for (unsigned int i = 0; i < nbi; ++i)
//	{
//		Dart d = vecEdges[i];
//		distndart[i].second = d;
//		typename PFP::VEC3 V = (position[d] + position[map.phi1(d)]) / typename PFP::REAL(2);
//		V -= rayA;
//		distndart[i].first = V.norm2();
//	}
//
//	// sort the vector of pair dist/dart
//	std::sort(distndart.begin(), distndart.end(), distndartOrdering<PFP>);
//
//	// store sorted darts in returned vector
//	for (unsigned int i = 0; i < nbi; ++i)
//		vecEdges[i] = distndart[i].second;
//}







894
} //end namespace GL2
895

896
} //end namespace Render
Pierre Kraemer's avatar
Pierre Kraemer committed
897

898
} //end namespace Algo
Pierre Kraemer's avatar
Pierre Kraemer committed
899

900
} //end namespace CGoGN