mapRender.hpp 17 KB
Newer Older
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           *
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/                                           *
21 22 23
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/
24

25
#include "Topology/generic/attributeHandler.h"
26 27
#include "Topology/generic/dartmarker.h"
#include "Topology/generic/cellmarker.h"
28
#include "Topology/generic/traversor/traversorCell.h"
29

Thery Sylvain's avatar
Thery Sylvain committed
30
//#include "Utils/vbo.h"
31

32 33 34
#include "Geometry/intersection.h"
#include "Algo/Geometry/normal.h"

35 36 37 38 39 40 41 42 43
namespace CGoGN
{

namespace Algo
{

namespace Render
{

Sylvain Thery's avatar
Sylvain Thery committed
44
namespace GL2
45 46
{

47 48
inline bool MapRender::cmpVP(VertexPoly* lhs, VertexPoly* rhs)
{
Sylvain Thery's avatar
MAJ MC  
Sylvain Thery committed
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
//	 return lhs->value < rhs->value;

	if (fabs(lhs->value - rhs->value)<0.2f)
			return lhs->length < rhs->length;
	return lhs->value < rhs->value;
}

template<typename VEC3>
bool MapRender::inTriangle(const VEC3& P, const VEC3& normal, const VEC3& Ta,  const VEC3& Tb, const VEC3& Tc)
{
	typedef typename VEC3::DATA_TYPE T ;

	if (Geom::tripleProduct(P-Ta, (Tb-Ta), normal) >= T(0))
		return false;

	if (Geom::tripleProduct(P-Tb, (Tc-Tb), normal) >= T(0))
		return false;

	if (Geom::tripleProduct(P-Tc, (Ta-Tc), normal) >= T(0))
		return false;

	return true;
71 72
}

73
template<typename PFP>
74
void MapRender::recompute2Ears(const VertexAttribute<typename PFP::VEC3, typename PFP::MAP::IMPL>& position, VertexPoly* vp, const typename PFP::VEC3& normalPoly, VPMS& ears, bool convex)
75
{
76 77
	typedef typename PFP::VEC3 VEC3;

78 79 80
	VertexPoly* vprev = vp->prev;
	VertexPoly* vp2 = vp->next;
	VertexPoly* vnext = vp2->next;
81 82 83 84
	const VEC3& Ta = position[vp->id];
	const VEC3& Tb = position[vp2->id];
	const VEC3& Tc = position[vprev->id];
	const VEC3& Td = position[vnext->id];
85 86

	// compute angle
87 88 89
	VEC3 v1= Tb - Ta;
	VEC3 v2= Tc - Ta;
	VEC3 v3= Td - Tb;
90

91 92 93 94
	v1.normalize();
	v2.normalize();
	v3.normalize();

Sylvain Thery's avatar
MAJ MC  
Sylvain Thery committed
95 96 97 98 99
//	float dotpr1 = 1.0f - (v1*v2);
//	float dotpr2 = 1.0f + (v1*v3);
	float dotpr1 = acos(v1*v2) / (M_PI/2.0f);
	float dotpr2 = acos(-(v1*v3)) / (M_PI/2.0f);

100

101
	if (!convex)	// if convex no need to test if vertex is an ear (yes)
102
	{
103 104
		VEC3 nv1 = v1^v2;
		VEC3 nv2 = v1^v3;
105 106 107 108 109

		if (nv1*normalPoly < 0.0)
			dotpr1 = 10.0f - dotpr1;// not an ears  (concave)
		if (nv2*normalPoly < 0.0)
			dotpr2 = 10.0f - dotpr2;// not an ears  (concave)
110

Sylvain Thery's avatar
MAJ MC  
Sylvain Thery committed
111
		bool finished = (dotpr1>=5.0f) && (dotpr2>=5.0f);
112
		for (VPMS::reverse_iterator it = ears.rbegin(); (!finished)&&(it != ears.rend())&&((*it)->value > 5.0f); ++it)
113
		{
114
			int id = (*it)->id;
115
			const VEC3& P = position[id];
116

Sylvain Thery's avatar
MAJ MC  
Sylvain Thery committed
117
			if ((dotpr1 < 5.0f) && (id !=vprev->id))
118
				if (inTriangle<VEC3>(P, normalPoly,Tb,Tc,Ta))
119
					dotpr1 = 5.0f;// not an ears !
120

Sylvain Thery's avatar
MAJ MC  
Sylvain Thery committed
121
			if ((dotpr2 < 5.0f) && (id !=vnext->id) )
122
				if (inTriangle<VEC3>(P, normalPoly,Td,Ta,Tb))
123 124
					dotpr2 = 5.0f;// not an ears !

Sylvain Thery's avatar
MAJ MC  
Sylvain Thery committed
125
			finished = ((dotpr1 >= 5.0f)&&(dotpr2 >= 5.0f));
126 127
		}
	}
128 129

	vp->value  = dotpr1;
Sylvain Thery's avatar
MAJ MC  
Sylvain Thery committed
130
	vp->length = (Tb-Tc).norm2();
131
	vp->ear = ears.insert(vp);
132
	vp2->value = dotpr2;
Sylvain Thery's avatar
MAJ MC  
Sylvain Thery committed
133
	vp->length = (Td-Ta).norm2();
134
	vp2->ear = ears.insert(vp2);
135 136 137
}

template<typename PFP>
138
float MapRender::computeEarAngle(const typename PFP::VEC3& P1, const typename PFP::VEC3& P2,  const typename PFP::VEC3& P3, const typename PFP::VEC3& normalPoly)
139
{
140 141 142 143
	typedef typename PFP::VEC3 VEC3;

	VEC3 v1 = P1-P2;
	VEC3 v2 = P3-P2;
144 145
	v1.normalize();
	v2.normalize();
146

Sylvain Thery's avatar
MAJ MC  
Sylvain Thery committed
147 148
//	float dotpr = 1.0f - (v1*v2);
	float dotpr = acos(v1*v2) / (M_PI/2.0f);
149

150
	VEC3 vn = v1^v2;
151 152
	if (vn*normalPoly > 0.0f)
		dotpr = 10.0f - dotpr; 		// not an ears  (concave, store at the end for optimized use for intersections)
153 154 155 156 157

	return dotpr;
}

template<typename PFP>
158
bool MapRender::computeEarIntersection(const VertexAttribute<typename PFP::VEC3, typename PFP::MAP::IMPL>& position, VertexPoly* vp, const typename PFP::VEC3& normalPoly)
159
{
160
	typedef typename PFP::VEC3 VEC3;
Sylvain Thery's avatar
MAJ MC  
Sylvain Thery committed
161

162 163
	VertexPoly* endV = vp->prev;
	VertexPoly* curr = vp->next;
164 165 166
	const VEC3& Ta = position[vp->id];
	const VEC3& Tb = position[curr->id];
	const VEC3& Tc = position[endV->id];
167 168 169 170
	curr = curr->next;

	while (curr != endV)
	{
171
		if (inTriangle<VEC3>(position[curr->id], normalPoly,Tb,Tc,Ta))
172 173 174 175 176 177 178 179 180 181 182
		{
			vp->value = 5.0f;// not an ears !
			return false;
		}
		curr = curr->next;
	}

	return true;
}

template<typename PFP>
183
inline void MapRender::addEarTri(typename PFP::MAP& map, Dart d, std::vector<GLuint>& tableIndices, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP::IMPL>* pos)
184
{
185 186
	typedef typename PFP::VEC3 VEC3;

Sylvain Thery's avatar
MAJ MC  
Sylvain Thery committed
187 188
	bool(*fn_pt1)(VertexPoly*,VertexPoly*) = &(MapRender::cmpVP);
	VPMS ears(fn_pt1);
189

190
	const VertexAttribute<VEC3, typename PFP::MAP::IMPL>& position = *pos ;
191 192

	// compute normal to polygon
193
	VEC3 normalPoly = Algo::Surface::Geometry::newellNormal<PFP>(map, d, position);
194

195
	// first pass create polygon in chained list with angle computation
196 197
	VertexPoly* vpp = NULL;
	VertexPoly* prem = NULL;
198 199 200 201 202 203 204
	unsigned int nbv = 0;
	unsigned int nbe = 0;
	Dart a = d;
	Dart b = map.phi1(a);
	Dart c = map.phi1(b);
	do
	{
205 206 207
		VEC3 P1 = position[map.template getEmbedding<VERTEX>(a)];
		VEC3 P2 = position[map.template getEmbedding<VERTEX>(b)];
		VEC3 P3 = position[map.template getEmbedding<VERTEX>(c)];
208

209
		float val = computeEarAngle<PFP>(P1, P2, P3, normalPoly);
210
		VertexPoly* vp = new VertexPoly(map.template getEmbedding<VERTEX>(b), val, (P3-P1).norm2(), vpp);
Sylvain Thery's avatar
MAJ MC  
Sylvain Thery committed
211

212
		if (vp->value < 5.0f)
213
			nbe++;
214
		if (vpp == NULL)
215 216 217 218 219 220
			prem = vp;
		vpp = vp;
		a = b;
		b = c;
		c = map.phi1(c);
		nbv++;
221
	}while (a != d);
222

223
	VertexPoly::close(prem, vpp);
224

225
	bool convex = nbe == nbv;
226 227
	if (convex)
	{
228
		// second pass with no test of intersections with polygons
229 230 231
		vpp = prem;
		for (unsigned int i=0; i< nbv; ++i)
		{
232
			vpp->ear = ears.insert(vpp);
233 234 235 236 237
			vpp = vpp->next;
		}
	}
	else
	{
238
		// second pass test intersections with polygons
239 240 241 242
		vpp = prem;
		for (unsigned int i=0; i< nbv; ++i)
		{
			if (vpp->value <5.0f)
243
				computeEarIntersection<PFP>(position, vpp, normalPoly);
244
			vpp->ear = ears.insert(vpp);
245 246 247 248
			vpp = vpp->next;
		}
	}

249
	// NOW WE HAVE THE POLYGON AND EARS
250 251 252 253
	// LET'S REMOVE THEM
	while (nbv>3)
	{
		// take best (and valid!) ear
Sylvain Thery's avatar
MAJ MC  
Sylvain Thery committed
254
		VPMS::iterator be_it = ears.begin(); // best ear
255
		VertexPoly* be = *be_it;
256 257 258 259 260 261 262

		tableIndices.push_back(be->id);
		tableIndices.push_back(be->next->id);
		tableIndices.push_back(be->prev->id);
		nbv--;

		if (nbv>3)	// do not recompute if only one triangle left
Sylvain Thery's avatar
MAJ MC  
Sylvain Thery committed
263 264 265 266 267 268
		{
			//remove ears and two sided ears
			ears.erase(be_it);					// from map of ears
			ears.erase(be->next->ear);
			ears.erase(be->prev->ear);
			be = VertexPoly::erase(be); 	// and remove ear vertex from polygon
269
			recompute2Ears<PFP>(position,be,normalPoly,ears,convex);
Sylvain Thery's avatar
MAJ MC  
Sylvain Thery committed
270 271 272
			convex = (*(ears.rbegin()))->value < 5.0f;
		}
		else		// finish (no need to update ears)
273
		{
Sylvain Thery's avatar
MAJ MC  
Sylvain Thery committed
274 275 276
			// remove ear from polygon
			be = VertexPoly::erase(be);
			// last triangle
277
			tableIndices.push_back(be->id);
Sylvain Thery's avatar
MAJ MC  
Sylvain Thery committed
278
			tableIndices.push_back(be->next->id);
279
			tableIndices.push_back(be->prev->id);
280 281 282 283
			// release memory of last triangle in polygon
			delete be->next;
			delete be->prev;
			delete be;
284 285 286 287
		}
	}
}

288 289 290 291 292 293 294 295
template<typename PFP>
inline void MapRender::addTri(typename PFP::MAP& map, Dart d, std::vector<GLuint>& tableIndices)
{
	Dart a = d;
	Dart b = map.phi1(a);
	Dart c = map.phi1(b);

	// loop to cut a polygon in triangle on the fly (works only with convex faces)
296 297
	do
	{
298 299 300
		tableIndices.push_back(map.template getEmbedding<VERTEX>(d));
		tableIndices.push_back(map.template getEmbedding<VERTEX>(b));
		tableIndices.push_back(map.template getEmbedding<VERTEX>(c));
301 302 303
		b = c;
		c = map.phi1(b);
	} while (c != d);
304 305 306
}

template<typename PFP>
307
void MapRender::initTriangles(typename PFP::MAP& map, std::vector<GLuint>& tableIndices, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP::IMPL>* position, unsigned int thread)
308
{
Pierre Kraemer's avatar
Pierre Kraemer committed
309 310
	tableIndices.reserve(4 * map.getNbDarts() / 3);

311
//	TraversorF<typename PFP::MAP> trav(map, thread);
312 313 314

	if(position == NULL)
	{
315
//		for (Dart d = trav.begin(); d != trav.end(); d = trav.next())
316 317 318 319 320
//		foreachCellMT(VERTEX,d,typename PFP::MAP,map,thread)
		foreach_cell<VERTEX>(map, [&] (Vertex v)
		{
			addTri<PFP>(map, v, tableIndices);
		},false,thread);
321 322 323
	}
	else
	{
324
//		for (Dart d = trav.begin(); d != trav.end(); d = trav.next())
325
		foreach_cell<VERTEX>(map, [&] (Vertex v)
326
		{
327 328
			if(map.faceDegree(v) == 3)
				addTri<PFP>(map, v, tableIndices);
329
			else
330 331
				addEarTri<PFP>(map, v, tableIndices, position);
		},false,thread);
332
	}
333 334 335
}

template<typename PFP>
336
void MapRender::initTrianglesOptimized(typename PFP::MAP& map, std::vector<GLuint>& tableIndices, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP::IMPL>* position, unsigned int thread)
337 338
{
#define LIST_SIZE 20
Pierre Kraemer's avatar
Pierre Kraemer committed
339
	DartMarker<typename PFP::MAP> m(map, thread);
340 341 342
	// reserve memory for triangles ( nb indices == nb darts )
	// and a little bit more
	// if lots of polygonal faces, realloc is done by vector
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
343
	tableIndices.reserve(4 * map.getNbDarts() / 3);
344 345 346 347 348 349 350

	for (Dart dd = map.begin(); dd != map.end(); map.next(dd))
	{
		if (!m.isMarked(dd))
		{
			std::list<Dart> bound;

351
			if (!map.template isBoundaryMarked<PFP::MAP::DIMENSION>(dd))
352 353 354 355 356 357 358 359 360 361 362
			{
				if(position == NULL)
					addTri<PFP>(map, dd, tableIndices);
				else
				{
					if(map.faceDegree(dd) == 3)
						addTri<PFP>(map, dd, tableIndices);
					else
						addEarTri<PFP>(map, dd, tableIndices, position);
				}
			}
363
			m.template markOrbit<FACE>(dd);
364 365 366 367 368 369 370 371 372 373 374 375 376
			bound.push_back(dd);
			int nb = 1;
			do
			{
				Dart e = bound.back();
				Dart ee = e;
				do
				{
					Dart f = ee;
					do
					{
						if (!m.isMarked(f))
						{
377
							if ( !map.template isBoundaryMarked<PFP::MAP::DIMENSION>(f))
378 379 380 381 382 383 384 385 386 387 388
							{
								if(position == NULL)
									addTri<PFP>(map, f, tableIndices);
								else
								{
									if(map.faceDegree(f) == 3)
										addTri<PFP>(map, f, tableIndices);
									else
										addEarTri<PFP>(map, f, tableIndices, position);
								}
							}
389
							m.template markOrbit<FACE>(f);
390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411
							bound.push_back(map.phi1(f));
							++nb;
							if (nb > LIST_SIZE)
							{
								bound.pop_front();
								--nb;
							}
						}
						f = map.phi1(map.phi2(f));
					} while (f != ee);
					ee = map.phi1(ee);
				} while (ee != e);

				bound.pop_back();
				--nb;
			} while (!bound.empty());
		}
	}
#undef LIST_SIZE
}

template<typename PFP>
412
void MapRender::initLines(typename PFP::MAP& map, std::vector<GLuint>& tableIndices, unsigned int thread)
413 414 415
{
	tableIndices.reserve(map.getNbDarts());

416
//	TraversorE<typename PFP::MAP> trav(map, thread);
417
	foreach_cell<EDGE>(map, [&] (Edge e)
418
	{
419 420
		tableIndices.push_back(map.template getEmbedding<VERTEX>(e.dart));
		tableIndices.push_back(map.template getEmbedding<VERTEX>(map.phi1(e)));
421
	}
422
	,false,thread);
423 424 425
}

template<typename PFP>
426
void MapRender::initBoundaries(typename PFP::MAP& map, std::vector<GLuint>& tableIndices, unsigned int thread)
427 428 429
{
	tableIndices.reserve(map.getNbDarts()); //TODO optimisation ?

430 431
//	TraversorE<typename PFP::MAP> trav(map, thread);
//	for (Dart d = trav.begin(); d != trav.end(); d = trav.next())
432
	foreach_cell<EDGE>(map, [&] (Edge e)
433
	{
434
		if (map.isBoundaryEdge(e))
435
		{
436 437
			tableIndices.push_back(map.template getEmbedding<VERTEX>(e.dart));
			tableIndices.push_back(map.template getEmbedding<VERTEX>(map.phi1(e)));
438 439
		}
	}
440
	,false,thread);
441 442 443
}

template<typename PFP>
444
void MapRender::initLinesOptimized(typename PFP::MAP& map, std::vector<GLuint>& tableIndices, unsigned int thread)
445 446
{
#define LIST_SIZE 20
Pierre Kraemer's avatar
Pierre Kraemer committed
447
	DartMarker<typename PFP::MAP> m(map, thread);
448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467

	// reserve memory for edges indices ( nb indices == nb darts)
	tableIndices.reserve(map.getNbDarts());

	for (Dart dd = map.begin(); dd != map.end(); map.next(dd))
	{
		if (!m.isMarked(dd))
		{
			std::list<Dart> bound;
			bound.push_back(dd);
			int nb = 1;
			do
			{
				Dart e = bound.back();
				Dart ee = e;
				do
				{
					Dart f = map.phi2(ee);
					if (!m.isMarked(ee))
					{
468 469
						tableIndices.push_back(map.template getEmbedding<VERTEX>(ee));
						tableIndices.push_back(map.template getEmbedding<VERTEX>(map.phi1(ee)));
470
						m.template markOrbit<EDGE>(f);
471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490

						bound.push_back(f);
						++nb;
						if (nb > LIST_SIZE)
						{
							bound.pop_front();
							--nb;
						}
					}
					ee = map.phi1(f);
				} while (ee != e);
				bound.pop_back();
				--nb;
			} while (!bound.empty());
		}
	}
#undef LIST_SIZE
}

template<typename PFP>
491
void MapRender::initPoints(typename PFP::MAP& map, std::vector<GLuint>& tableIndices, unsigned int thread)
492
{
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
493
	tableIndices.reserve(map.getNbDarts() / 5);
494

495
//	TraversorV<typename PFP::MAP> trav(map, thread);
496 497 498 499 500
	foreach_cell<VERTEX>(map, [&] (Vertex v)
	{
		tableIndices.push_back(map.getEmbedding(v));
	}
	,false,thread);
501 502
}

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
503
template<typename PFP>
504
void MapRender::initPrimitives(typename PFP::MAP& map, int prim, bool optimized, unsigned int thread)
505
{
506
	initPrimitives<PFP>(map, prim, NULL, optimized, thread) ;
507 508 509
}

template <typename PFP>
510
void MapRender::initPrimitives(typename PFP::MAP& map, int prim, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP::IMPL>* position, bool optimized, unsigned int thread)
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
511 512
{
	std::vector<GLuint> tableIndices;
Sylvain Thery's avatar
Sylvain Thery committed
513

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
514 515 516
	switch(prim)
	{
		case POINTS:
517

518
			initPoints<PFP>(map, tableIndices, thread);
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
519 520 521
			break;
		case LINES:
			if(optimized)
522
				initLinesOptimized<PFP>(map, tableIndices, thread);
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
523
			else
524
				initLines<PFP>(map, tableIndices, thread) ;
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
525 526 527
			break;
		case TRIANGLES:
			if(optimized)
528
				initTrianglesOptimized<PFP>(map, tableIndices, position, thread);
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
529
			else
530
				initTriangles<PFP>(map, tableIndices, position, thread) ;
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
531 532 533
			break;
		case FLAT_TRIANGLES:
			break;
534
		case BOUNDARY:
535
			initBoundaries<PFP>(map, tableIndices, thread) ;
536
			break;
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
537 538 539 540
		default:
			CGoGNerr << "problem initializing VBO indices" << CGoGNendl;
			break;
	}
541 542 543

	m_nbIndices[prim] = tableIndices.size();
	m_indexBufferUpToDate[prim] = true;
Sylvain Thery's avatar
Sylvain Thery committed
544

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
545
	// setup du buffer d'indices
546 547
	glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffers[prim]);
	glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER, m_nbIndices[prim] * sizeof(GLuint), &(tableIndices[0]), GL_STREAM_DRAW);
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
548
}
Sylvain Thery's avatar
Sylvain Thery committed
549

550
template <typename PFP>
551
void MapRender::addPrimitives(typename PFP::MAP& map, int prim, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP::IMPL>* position, bool optimized, unsigned int thread)
552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 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
{
	std::vector<GLuint> tableIndices;

	switch(prim)
	{
		case POINTS:

			initPoints<PFP>(map, tableIndices, thread);
			break;
		case LINES:
			if(optimized)
				initLinesOptimized<PFP>(map, tableIndices, thread);
			else
				initLines<PFP>(map, tableIndices, thread) ;
			break;
		case TRIANGLES:
			if(optimized)
				initTrianglesOptimized<PFP>(map, tableIndices, position, thread);
			else
				initTriangles<PFP>(map, tableIndices, position, thread) ;
			break;
		case FLAT_TRIANGLES:
			break;
		case BOUNDARY:
			initBoundaries<PFP>(map, tableIndices, thread) ;
			break;
		default:
			CGoGNerr << "problem initializing VBO indices" << CGoGNendl;
			break;
	}

	m_indexBufferUpToDate[prim] = true;

	glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffers[prim]);
	GLint sz=0;
	glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &sz);
	GLuint* oldIndices =  reinterpret_cast<GLuint*>(glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_READ_WRITE));

	// allocate new buffer
	GLuint newBuffer;
	glGenBuffers(1,&newBuffer);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, newBuffer);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sz + tableIndices.size() * sizeof(GLuint),NULL, GL_STREAM_DRAW);

	//copy old indices
	glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sz, oldIndices);
	//and new ones
	glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, sz, m_nbIndices[prim] * sizeof(GLuint), &(tableIndices[0]) );

	glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffers[prim]);
	glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);

	glDeleteBuffers(1,&(m_indexBuffers[prim]));
	m_indexBuffers[prim] = newBuffer;

	m_nbIndices[prim] += tableIndices.size();
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
608
}
Sylvain Thery's avatar
Sylvain Thery committed
609 610

} // namespace GL2
611 612 613 614 615 616

} // namespace Render

} // namespace Algo

} // namespace CGoGN