mapRender.hpp 16.3 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

30
31
32
#include "Geometry/intersection.h"
#include "Algo/Geometry/normal.h"

33
34
35
36
37
38
39
40
41
namespace CGoGN
{

namespace Algo
{

namespace Render
{

Sylvain Thery's avatar
Sylvain Thery committed
42
namespace GL2
43
44
{

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

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

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

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

89
90
91
92
	v1.normalize();
	v2.normalize();
	v3.normalize();

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

98

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

		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)
108

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

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

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

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

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

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

	VEC3 v1 = P1-P2;
	VEC3 v2 = P3-P2;
142
143
	v1.normalize();
	v2.normalize();
144

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

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

	return dotpr;
}

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

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

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

	return true;
}

template<typename PFP>
181
inline void MapRender::addEarTri(typename PFP::MAP& map, Face f, std::vector<GLuint>& tableIndices, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP>* pos)
182
{
183
184
	typedef typename PFP::VEC3 VEC3;

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

188
	const VertexAttribute<VEC3, typename PFP::MAP>& position = *pos ;
189
190

	// compute normal to polygon
Pierre Kraemer's avatar
Pierre Kraemer committed
191
	VEC3 normalPoly = Algo::Surface::Geometry::newellNormal<PFP>(map, f, position);
192

193
	// first pass create polygon in chained list with angle computation
194
195
	VertexPoly* vpp = NULL;
	VertexPoly* prem = NULL;
196
197
	unsigned int nbv = 0;
	unsigned int nbe = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
198
199
200
	Vertex a = f.dart;
	Vertex b = map.phi1(a);
	Vertex c = map.phi1(b);
201
202
	do
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
203
204
205
		VEC3 P1 = position[map.getEmbedding(a)];
		VEC3 P2 = position[map.getEmbedding(b)];
		VEC3 P3 = position[map.getEmbedding(c)];
206

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

210
		if (vp->value < 5.0f)
211
			nbe++;
212
		if (vpp == NULL)
213
214
215
216
217
218
			prem = vp;
		vpp = vp;
		a = b;
		b = c;
		c = map.phi1(c);
		nbv++;
Pierre Kraemer's avatar
Pierre Kraemer committed
219
	} while (a.dart != f.dart);
220

221
	VertexPoly::close(prem, vpp);
222

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

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

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

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

286
template<typename PFP>
Pierre Kraemer's avatar
Pierre Kraemer committed
287
inline void MapRender::addTri(typename PFP::MAP& map, Face f, std::vector<GLuint>& tableIndices)
288
{
Pierre Kraemer's avatar
Pierre Kraemer committed
289
290
291
	Vertex a = f.dart;
	Vertex b = map.phi1(a);
	Vertex c = map.phi1(b);
292
293

	// loop to cut a polygon in triangle on the fly (works only with convex faces)
294
295
	do
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
296
297
298
		tableIndices.push_back(map.getEmbedding(a));
		tableIndices.push_back(map.getEmbedding(b));
		tableIndices.push_back(map.getEmbedding(c));
299
300
		b = c;
		c = map.phi1(b);
Pierre Kraemer's avatar
Pierre Kraemer committed
301
	} while (c.dart != a.dart);
302
303
304
}

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

309
310
	if(position == NULL)
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
311
		foreach_cell<FACE>(map, [&] (Face f)
312
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
313
			addTri<PFP>(map, f, tableIndices);
Sylvain Thery's avatar
Sylvain Thery committed
314
		}, AUTO);
315
316
317
	}
	else
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
318
		foreach_cell<FACE>(map, [&] (Face f)
319
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
320
321
			if(map.faceDegree(f) == 3)
				addTri<PFP>(map, f, tableIndices);
322
			else
Pierre Kraemer's avatar
Pierre Kraemer committed
323
				addEarTri<PFP>(map, f, tableIndices, position);
Sylvain Thery's avatar
Sylvain Thery committed
324
		}, AUTO);
325
	}
326
327
328
}

template<typename PFP>
Sylvain Thery's avatar
Sylvain Thery committed
329
void MapRender::initTrianglesOptimized(typename PFP::MAP& map, std::vector<GLuint>& tableIndices, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP>* position)
330
331
{
#define LIST_SIZE 20
Sylvain Thery's avatar
Sylvain Thery committed
332
	DartMarker<typename PFP::MAP> m(map);
333
334
335
	// 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
336
	tableIndices.reserve(4 * map.getNbDarts() / 3);
337
338
339
340
341
342
343

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

344
			if (!map.template isBoundaryMarked<PFP::MAP::DIMENSION>(dd))
345
346
347
348
349
350
351
352
353
354
355
			{
				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);
				}
			}
356
			m.template markOrbit<FACE>(dd);
357
358
359
360
361
362
363
364
365
366
367
368
369
			bound.push_back(dd);
			int nb = 1;
			do
			{
				Dart e = bound.back();
				Dart ee = e;
				do
				{
					Dart f = ee;
					do
					{
						if (!m.isMarked(f))
						{
370
							if ( !map.template isBoundaryMarked<PFP::MAP::DIMENSION>(f))
371
372
373
374
375
376
377
378
379
380
381
							{
								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);
								}
							}
382
							m.template markOrbit<FACE>(f);
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
							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>
Sylvain Thery's avatar
Sylvain Thery committed
405
void MapRender::initLines(typename PFP::MAP& map, std::vector<GLuint>& tableIndices)
406
407
408
{
	tableIndices.reserve(map.getNbDarts());

Sylvain Thery's avatar
Sylvain Thery committed
409
//	TraversorE<typename PFP::MAP> trav(map);
410
	foreach_cell<EDGE>(map, [&] (Edge e)
411
	{
412
413
		tableIndices.push_back(map.template getEmbedding<VERTEX>(e.dart));
		tableIndices.push_back(map.template getEmbedding<VERTEX>(map.phi1(e)));
414
	}
Sylvain Thery's avatar
Sylvain Thery committed
415
	,AUTO);
416
417
418
}

template<typename PFP>
Sylvain Thery's avatar
Sylvain Thery committed
419
void MapRender::initBoundaries(typename PFP::MAP& map, std::vector<GLuint>& tableIndices)
420
421
422
{
	tableIndices.reserve(map.getNbDarts()); //TODO optimisation ?

Sylvain Thery's avatar
Sylvain Thery committed
423
//	TraversorE<typename PFP::MAP> trav(map);
424
//	for (Dart d = trav.begin(); d != trav.end(); d = trav.next())
425
	foreach_cell<EDGE>(map, [&] (Edge e)
426
	{
427
		if (map.isBoundaryEdge(e))
428
		{
429
430
			tableIndices.push_back(map.template getEmbedding<VERTEX>(e.dart));
			tableIndices.push_back(map.template getEmbedding<VERTEX>(map.phi1(e)));
431
432
		}
	}
Sylvain Thery's avatar
Sylvain Thery committed
433
	,AUTO);
434
435
436
}

template<typename PFP>
Sylvain Thery's avatar
Sylvain Thery committed
437
void MapRender::initLinesOptimized(typename PFP::MAP& map, std::vector<GLuint>& tableIndices)
438
439
{
#define LIST_SIZE 20
Sylvain Thery's avatar
Sylvain Thery committed
440
	DartMarker<typename PFP::MAP> m(map);
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460

	// 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))
					{
461
462
						tableIndices.push_back(map.template getEmbedding<VERTEX>(ee));
						tableIndices.push_back(map.template getEmbedding<VERTEX>(map.phi1(ee)));
463
						m.template markOrbit<EDGE>(f);
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483

						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>
Sylvain Thery's avatar
Sylvain Thery committed
484
void MapRender::initPoints(typename PFP::MAP& map, std::vector<GLuint>& tableIndices)
485
{
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
486
	tableIndices.reserve(map.getNbDarts() / 5);
487

Sylvain Thery's avatar
Sylvain Thery committed
488
//	TraversorV<typename PFP::MAP> trav(map);
489
490
491
492
	foreach_cell<VERTEX>(map, [&] (Vertex v)
	{
		tableIndices.push_back(map.getEmbedding(v));
	}
Sylvain Thery's avatar
Sylvain Thery committed
493
	,FORCE_CELL_MARKING); //
494
495
}

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
496
template<typename PFP>
Sylvain Thery's avatar
Sylvain Thery committed
497
void MapRender::initPrimitives(typename PFP::MAP& map, int prim, bool optimized)
498
{
Sylvain Thery's avatar
Sylvain Thery committed
499
	initPrimitives<PFP>(map, prim, NULL, optimized) ;
500
501
502
}

template <typename PFP>
Sylvain Thery's avatar
Sylvain Thery committed
503
void MapRender::initPrimitives(typename PFP::MAP& map, int prim, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP>* position, bool optimized)
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
504
505
{
	std::vector<GLuint> tableIndices;
Sylvain Thery's avatar
Sylvain Thery committed
506

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
507
508
509
	switch(prim)
	{
		case POINTS:
510

Sylvain Thery's avatar
Sylvain Thery committed
511
			initPoints<PFP>(map, tableIndices);
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
512
513
514
			break;
		case LINES:
			if(optimized)
Sylvain Thery's avatar
Sylvain Thery committed
515
				initLinesOptimized<PFP>(map, tableIndices);
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
516
			else
Sylvain Thery's avatar
Sylvain Thery committed
517
				initLines<PFP>(map, tableIndices) ;
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
518
519
520
			break;
		case TRIANGLES:
			if(optimized)
Sylvain Thery's avatar
Sylvain Thery committed
521
				initTrianglesOptimized<PFP>(map, tableIndices, position);
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
522
			else
Sylvain Thery's avatar
Sylvain Thery committed
523
				initTriangles<PFP>(map, tableIndices, position) ;
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
524
525
526
			break;
		case FLAT_TRIANGLES:
			break;
527
		case BOUNDARY:
Sylvain Thery's avatar
Sylvain Thery committed
528
			initBoundaries<PFP>(map, tableIndices) ;
529
			break;
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
530
531
532
533
		default:
			CGoGNerr << "problem initializing VBO indices" << CGoGNendl;
			break;
	}
534

535
	m_nbIndices[prim] = GLuint(tableIndices.size());
536
	m_indexBufferUpToDate[prim] = true;
Sylvain Thery's avatar
Sylvain Thery committed
537

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
538
	// setup du buffer d'indices
Sylvain Thery's avatar
Sylvain Thery committed
539
540
541
542
543
	if (m_nbIndices[prim] > 0)
	{
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffers[prim]);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_nbIndices[prim] * sizeof(GLuint), &(tableIndices[0]), GL_STREAM_DRAW);
	}
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
544
}
Sylvain Thery's avatar
Sylvain Thery committed
545

546
template <typename PFP>
Sylvain Thery's avatar
Sylvain Thery committed
547
void MapRender::addPrimitives(typename PFP::MAP& map, int prim, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP>* position, bool optimized)
548
549
550
551
552
553
554
{
	std::vector<GLuint> tableIndices;

	switch(prim)
	{
		case POINTS:

Sylvain Thery's avatar
Sylvain Thery committed
555
			initPoints<PFP>(map, tableIndices);
556
557
558
			break;
		case LINES:
			if(optimized)
Sylvain Thery's avatar
Sylvain Thery committed
559
				initLinesOptimized<PFP>(map, tableIndices);
560
			else
Sylvain Thery's avatar
Sylvain Thery committed
561
				initLines<PFP>(map, tableIndices) ;
562
563
564
			break;
		case TRIANGLES:
			if(optimized)
Sylvain Thery's avatar
Sylvain Thery committed
565
				initTrianglesOptimized<PFP>(map, tableIndices, position);
566
			else
Sylvain Thery's avatar
Sylvain Thery committed
567
				initTriangles<PFP>(map, tableIndices, position) ;
568
569
570
571
			break;
		case FLAT_TRIANGLES:
			break;
		case BOUNDARY:
Sylvain Thery's avatar
Sylvain Thery committed
572
			initBoundaries<PFP>(map, tableIndices) ;
573
574
575
576
577
578
579
580
			break;
		default:
			CGoGNerr << "problem initializing VBO indices" << CGoGNendl;
			break;
	}

	m_indexBufferUpToDate[prim] = true;

581
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffers[prim]);
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
	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]) );

597
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffers[prim]);
598
599
600
601
602
603
	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
604
}
Sylvain Thery's avatar
Sylvain Thery committed
605
606

} // namespace GL2
607
608
609
610
611
612

} // namespace Render

} // namespace Algo

} // namespace CGoGN