explodeVolumeRender.hpp 20.5 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
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/
#include <cmath>

#include "Geometry/vector_gen.h"
#include "Topology/generic/dartmarker.h"
#include "Topology/generic/cellmarker.h"
29
#include "Algo/Geometry/centroid.h"
30
#include "Topology/generic/autoAttributeHandler.h"
31
#include "Algo/Geometry/normal.h"
Sylvain Thery's avatar
Sylvain Thery committed
32 33
#include "Algo/Geometry/basic.h"

Pierre Kraemer's avatar
Pierre Kraemer committed
34 35 36 37 38 39 40 41 42
namespace CGoGN
{

namespace Algo
{

namespace Render
{

Sylvain Thery's avatar
Sylvain Thery committed
43
namespace GL2
Pierre Kraemer's avatar
Pierre Kraemer committed
44 45
{

46 47 48
inline ExplodeVolumeRender::ExplodeVolumeRender(bool withColorPerFace, bool withExplodeFace, bool withSmoothFaces):
		m_cpf(withColorPerFace),m_ef(withExplodeFace),m_smooth(withSmoothFaces),
		m_nbTris(0), m_nbLines(0),m_globalColor(0.7f,0.7f,0.7f)
Pierre Kraemer's avatar
Pierre Kraemer committed
49
{
50 51 52
	m_vboPos = new Utils::VBO();
	m_vboPos->setDataSize(3);

53 54 55
	m_vboColors = new Utils::VBO();
	m_vboColors->setDataSize(3);

56 57 58
	m_vboPosLine = new Utils::VBO();
	m_vboPosLine->setDataSize(3);

59 60 61 62
	if (m_smooth)
	{
		m_shaderS = new Utils::ShaderExplodeSmoothVolumes(withColorPerFace,withExplodeFace);
		m_shader = NULL;
Sylvain Thery's avatar
Sylvain Thery committed
63 64
		m_vboNormals = new Utils::VBO();
		m_vboNormals->setDataSize(3);
65 66 67 68 69
	}
	else
	{
		m_shader = new Utils::ShaderExplodeVolumes(withColorPerFace,withExplodeFace);
		m_shaderS = NULL;
Sylvain Thery's avatar
Sylvain Thery committed
70
		m_vboNormals = NULL;
71
	}
72

73
	m_shaderL = new Utils::ShaderExplodeVolumesLines();
untereiner's avatar
untereiner committed
74
	m_shaderL->setColor(Geom::Vec4f(1.0f,1.0f,1.0f,0.0f));
75 76

}
Pierre Kraemer's avatar
Pierre Kraemer committed
77

78
inline ExplodeVolumeRender::~ExplodeVolumeRender()
Pierre Kraemer's avatar
Pierre Kraemer committed
79
{
80
	delete m_vboPos;
81
	delete m_vboColors;
82
	delete m_vboPosLine;
Sylvain Thery's avatar
Sylvain Thery committed
83 84 85

	if (m_vboNormals != NULL)
		delete m_vboNormals;
86 87 88 89
	if (m_shader != NULL)
		delete m_shader;
	if (m_shaderS != NULL)
		delete m_shaderS;
90
	delete m_shaderL;
Pierre Kraemer's avatar
Pierre Kraemer committed
91 92
}

93 94


95
template<typename PFP>
96
void ExplodeVolumeRender::updateSmooth(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& positions, const VolumeAttribute<typename PFP::VEC3>& colorPerXXX, const FunctorSelect& good)
97 98 99 100
{
	typedef typename PFP::VEC3 VEC3;
	typedef typename PFP::REAL REAL;

101
	VolumeAutoAttribute<VEC3> centerVolumes(map, "centerVolumes");
102
	Algo::Volume::Geometry::computeCentroidELWVolumes<PFP>(map, positions, centerVolumes, good);
103 104 105 106

	std::vector<VEC3> buffer;
	buffer.reserve(16384);

107 108 109 110
	std::vector<VEC3> bufferColors;
	bufferColors.reserve(16384);
	std::vector<VEC3> bufferNormals;
	bufferNormals.reserve(16384);
111
	
112 113
	std::vector<VEC3> normals;
	bufferNormals.reserve(20);
114 115
	std::vector<VEC3> vertices;
	bufferNormals.reserve(20);
116

117
	
Pierre Kraemer's avatar
Pierre Kraemer committed
118
	TraversorCell<typename PFP::MAP, PFP::MAP::FACE_OF_PARENT> traFace(map, good);
119

120

Sylvain Thery's avatar
Sylvain Thery committed
121
	for (Dart d = traFace.begin(); d != traFace.end(); d = traFace.next())
122
	{
Sylvain Thery's avatar
Sylvain Thery committed
123 124
		// compute normals
		normals.clear();
125 126 127 128
		vertices.clear();
		VEC3 centerFace = Algo::Surface::Geometry::faceCentroid<PFP>(map, d, positions);
		VEC3 centerNormalFace = Algo::Surface::Geometry::newellNormal<PFP>(map,d,positions);

Sylvain Thery's avatar
Sylvain Thery committed
129 130 131
		Dart a = d;
		do
		{
132 133
			VEC3 v1 = positions[a] - centerFace;
			v1.normalize();
Sylvain Thery's avatar
Sylvain Thery committed
134
			Dart e = map.phi1(a);
135 136
			VEC3 v2 = positions[map.phi1(e)] - centerFace;
			v2.normalize();
Sylvain Thery's avatar
Sylvain Thery committed
137
			VEC3 N = v1^v2;
138
			
139
			double l = N.norm();
140 141
			if (l<0.01)
				N = centerNormalFace;
142 143
			else
			{
144 145 146
				N /= l;
				if (N*centerNormalFace < 0.707)
					N = centerNormalFace;
147 148
			}
			
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
			normals.push_back(N);
			vertices.push_back(positions[e]);
			
// 			VEC3 v1 = Algo::Surface::Geometry::vectorOutOfDart<PFP>(map,a,positions);
// 			Dart e = map.phi1(a);
// 			VEC3 v2 = Algo::Surface::Geometry::vectorOutOfDart<PFP>(map,e,positions);
// 			v1.normalize();
// 			v2.normalize();
// 			VEC3 N = v1^v2;
//  			double l = N.norm();
// 			double ll = fabs(N*centerNormalFace());
// 			if ((l<0.2) && l<0
			
// 			if (l<0.3)
//  			{
// 				N = centerNormalFace;
// 			}
// 			else
// 			{
// 				if (N*centerNormalFace < 0.0)
// 					N /= -l;
// 				else
// 					N /= l;
// 			}
// 			if ((l < 0.5) || (N*centerNormalFace < 0.0))
// 			{
// 				N = centerNormalFace;
// 			}
			

			
			
			
// 				if (N*centerNormalFace < 0.0)
// 				{
// 					std::cout << "INVERTED" <<std::endl;
// 					N =-N;
// 				}
// 				N.normalize();
// 				normals.push_back(N);
// 			}
// 			normals.push_back(N);
// 			vertices.push_back(positions[e]);

		//centerFace += positions[e];
			
195
			a = e;
Sylvain Thery's avatar
Sylvain Thery committed
196 197
		} while (a != d);

198 199
//		centerFace /= float(vertices.size());
//		centerNormalFace.normalize();
200
		
201 202 203 204 205 206
		VEC3 volCol = colorPerXXX[d];

		unsigned int nbs = vertices.size();
		// just to have more easy algo further
		vertices.push_back(vertices.front());
		normals.push_back(normals.front());
207
		
208
		typename std::vector<VEC3>::iterator iv  = vertices.begin();
209
		typename std::vector<VEC3>::iterator in  = normals.begin();
210 211
		
		if (nbs == 3)
212
		{
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227
			buffer.push_back(centerVolumes[d]);
			bufferColors.push_back(centerFace);
			bufferNormals.push_back(centerNormalFace); // unsused just for fill
			
			buffer.push_back(*iv++);
			bufferNormals.push_back(*in++);
			bufferColors.push_back(volCol);
			
			buffer.push_back(*iv++);
			bufferNormals.push_back(*in++);
			bufferColors.push_back(volCol);

			buffer.push_back(*iv++);
			bufferNormals.push_back(*in++);
			bufferColors.push_back(volCol);
228
		}
229
		else
230
		{
231
			for (unsigned int i=0; i<nbs; ++i)
232
			{
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247
				buffer.push_back(centerVolumes[d]);
				bufferColors.push_back(centerFace);
				bufferNormals.push_back(centerNormalFace); // unsused just for fill

				buffer.push_back(centerFace);
				bufferColors.push_back(volCol);
				bufferNormals.push_back(centerNormalFace);
				
				buffer.push_back(*iv++);
				bufferNormals.push_back(*in++);
				bufferColors.push_back(volCol);
				
				buffer.push_back(*iv);
				bufferNormals.push_back(*in);
				bufferColors.push_back(volCol);
248
			}
249
		}
250
	}
Sylvain Thery's avatar
Sylvain Thery committed
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276


	m_nbTris = buffer.size()/4;

	m_vboPos->allocate(buffer.size());
	VEC3* ptrPos = reinterpret_cast<VEC3*>(m_vboPos->lockPtr());
	memcpy(ptrPos,&buffer[0],buffer.size()*sizeof(VEC3));
	m_vboPos->releasePtr();
	m_shaderS->setAttributePosition(m_vboPos);

	m_vboColors->allocate(bufferColors.size());
	VEC3* ptrCol = reinterpret_cast<VEC3*>(m_vboColors->lockPtr());
	memcpy(ptrCol,&bufferColors[0],bufferColors.size()*sizeof(VEC3));
	m_vboColors->releasePtr();
	m_shaderS->setAttributeColor(m_vboColors);

	m_vboNormals->allocate(bufferNormals.size());
	VEC3* ptrNorm = reinterpret_cast<VEC3*>(m_vboNormals->lockPtr());
	memcpy(ptrNorm,&bufferNormals[0],bufferNormals.size()*sizeof(VEC3));
	m_vboNormals->releasePtr();
	m_shaderS->setAttributeNormal(m_vboNormals);

	buffer.clear();

	TraversorCell<typename PFP::MAP, PFP::MAP::EDGE_OF_PARENT> traEdge(map, good);
	for (Dart d = traEdge.begin(); d != traEdge.end(); d = traEdge.next())
277
	{
Sylvain Thery's avatar
Sylvain Thery committed
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
			buffer.push_back(centerVolumes[d]);
			buffer.push_back(positions[d]);
			buffer.push_back(positions[map.phi1(d)]);
	}

	m_nbLines = buffer.size()/3;

	m_vboPosLine->allocate(buffer.size());

	ptrPos = reinterpret_cast<VEC3*>(m_vboPosLine->lockPtr());
	memcpy(ptrPos,&buffer[0],buffer.size()*sizeof(VEC3));

	m_vboPosLine->releasePtr();
	m_shaderL->setAttributePosition(m_vboPosLine);
}


template<typename PFP>
void ExplodeVolumeRender::updateSmooth(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& positions, const FunctorSelect& good)
{
	typedef typename PFP::VEC3 VEC3;
	typedef typename PFP::REAL REAL;

	VolumeAutoAttribute<VEC3> centerVolumes(map, "centerVolumes");
302
	Algo::Volume::Geometry::computeCentroidELWVolumes<PFP>(map, positions, centerVolumes, good);
Sylvain Thery's avatar
Sylvain Thery committed
303 304 305 306 307 308 309 310

	std::vector<VEC3> buffer;
	buffer.reserve(16384);

	std::vector<VEC3> bufferColors;
	bufferColors.reserve(16384);
	std::vector<VEC3> bufferNormals;
	bufferNormals.reserve(16384);
311
	
Sylvain Thery's avatar
Sylvain Thery committed
312 313
	std::vector<VEC3> normals;
	bufferNormals.reserve(20);
314 315
	std::vector<VEC3> vertices;
	bufferNormals.reserve(20);
Sylvain Thery's avatar
Sylvain Thery committed
316 317 318 319 320 321 322

	TraversorCell<typename PFP::MAP, PFP::MAP::FACE_OF_PARENT> traFace(map, good);

	for (Dart d = traFace.begin(); d != traFace.end(); d = traFace.next())
	{
		// compute normals
		normals.clear();
323
		vertices.clear();
Sylvain Thery's avatar
Sylvain Thery committed
324
		VEC3 centerFace(0);
325 326
		VEC3 centerNormalFace(0);

Sylvain Thery's avatar
Sylvain Thery committed
327 328 329 330 331 332 333
		Dart a = d;
		do
		{
			VEC3 v1 = Algo::Surface::Geometry::vectorOutOfDart<PFP>(map,a,positions);
			Dart e = map.phi1(a);
			VEC3 v2 = Algo::Surface::Geometry::vectorOutOfDart<PFP>(map,e,positions);
			VEC3 N = v1^v2;
334 335 336 337 338 339 340 341 342
			double l = N.norm();
			if (l>0.000001)
			{
				N /= l;
				normals.push_back(N);
				centerNormalFace += N;
				vertices.push_back(positions[e]);
				centerFace += positions[e];
			}
Sylvain Thery's avatar
Sylvain Thery committed
343 344 345
			a = e;
		} while (a != d);

346 347 348 349 350 351 352
		centerFace /= float(vertices.size());
		centerNormalFace.normalize();

		unsigned int nbs = vertices.size();
		// just to have more easy algo further
		vertices.push_back(vertices.front());
		normals.push_back(normals.front());
353
		
354
		typename std::vector<VEC3>::iterator iv  = vertices.begin();
355 356
		typename std::vector<VEC3>::iterator in  = normals.begin();
		
357
		if (nbs == 3)
358
		{
Sylvain Thery's avatar
Sylvain Thery committed
359 360
			buffer.push_back(centerVolumes[d]);
			bufferColors.push_back(centerFace);
361 362 363 364
			bufferNormals.push_back(centerNormalFace); // unsused just for fill

			buffer.push_back(*iv++);
			bufferNormals.push_back(*in++);
Sylvain Thery's avatar
Sylvain Thery committed
365
			bufferColors.push_back(m_globalColor);
366 367
			
			buffer.push_back(*iv++);
Sylvain Thery's avatar
Sylvain Thery committed
368 369 370
			bufferNormals.push_back(*in++);
			bufferColors.push_back(m_globalColor);

371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395
			buffer.push_back(*iv++);
			bufferNormals.push_back(*in++);
			bufferColors.push_back(m_globalColor);
		}
		else
		{
			for (unsigned int i=0; i<nbs; ++i)
			{
				buffer.push_back(centerVolumes[d]);
				bufferColors.push_back(centerFace);
				bufferNormals.push_back(centerNormalFace); // unsused just for fill

				buffer.push_back(centerFace);
				bufferColors.push_back(m_globalColor);
				bufferNormals.push_back(centerNormalFace);
				
				buffer.push_back(*iv++);
				bufferNormals.push_back(*in++);
				bufferColors.push_back(m_globalColor);
				
				buffer.push_back(*iv);
				bufferNormals.push_back(*in);
				bufferColors.push_back(m_globalColor);
			}
		}
396 397
	}
	
398 399 400 401 402 403
	m_nbTris = buffer.size()/4;

	m_vboPos->allocate(buffer.size());
	VEC3* ptrPos = reinterpret_cast<VEC3*>(m_vboPos->lockPtr());
	memcpy(ptrPos,&buffer[0],buffer.size()*sizeof(VEC3));
	m_vboPos->releasePtr();
Sylvain Thery's avatar
Sylvain Thery committed
404
	m_shaderS->setAttributePosition(m_vboPos);
405

406 407 408 409
	m_vboColors->allocate(bufferColors.size());
	VEC3* ptrCol = reinterpret_cast<VEC3*>(m_vboColors->lockPtr());
	memcpy(ptrCol,&bufferColors[0],bufferColors.size()*sizeof(VEC3));
	m_vboColors->releasePtr();
Sylvain Thery's avatar
Sylvain Thery committed
410 411 412 413 414 415 416
	m_shaderS->setAttributeColor(m_vboColors);

	m_vboNormals->allocate(bufferNormals.size());
	VEC3* ptrNorm = reinterpret_cast<VEC3*>(m_vboNormals->lockPtr());
	memcpy(ptrNorm,&bufferNormals[0],bufferNormals.size()*sizeof(VEC3));
	m_vboNormals->releasePtr();
	m_shaderS->setAttributeNormal(m_vboNormals);
417

418 419
	buffer.clear();

Pierre Kraemer's avatar
Pierre Kraemer committed
420
	TraversorCell<typename PFP::MAP, PFP::MAP::EDGE_OF_PARENT> traEdge(map, good);
421
	for (Dart d = traEdge.begin(); d != traEdge.end(); d = traEdge.next())
422
	{
423 424 425
			buffer.push_back(centerVolumes[d]);
			buffer.push_back(positions[d]);
			buffer.push_back(positions[map.phi1(d)]);
426 427 428 429 430 431 432 433 434 435 436 437
	}

	m_nbLines = buffer.size()/3;

	m_vboPosLine->allocate(buffer.size());

	ptrPos = reinterpret_cast<VEC3*>(m_vboPosLine->lockPtr());
	memcpy(ptrPos,&buffer[0],buffer.size()*sizeof(VEC3));

	m_vboPosLine->releasePtr();
	m_shaderL->setAttributePosition(m_vboPosLine);
}
438

439

Sylvain Thery's avatar
Sylvain Thery committed
440

441
template<typename PFP>
442
void ExplodeVolumeRender::updateData(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& positions, const VolumeAttribute<typename PFP::VEC3>& colorPerXXX, const FunctorSelect& good)
443
{
Sylvain Thery's avatar
Sylvain Thery committed
444 445 446 447 448
	if (!m_cpf)
	{
		CGoGNerr<< "ExplodeVolumeRender: problem wrong update fonction use the other (without VolumeAttribute parameter)" << CGoGNendl;
		return;
	}
449 450

	if (m_smooth)
451
	{
452

Sylvain Thery's avatar
Sylvain Thery committed
453 454
		updateSmooth<PFP>(map,positions,colorPerXXX,good);
		return;
455 456
	}

457

458 459 460
	typedef typename PFP::VEC3 VEC3;
	typedef typename PFP::REAL REAL;

461
	VolumeAutoAttribute<VEC3> centerVolumes(map, "centerVolumes");
462
	Algo::Volume::Geometry::computeCentroidELWVolumes<PFP>(map, positions, centerVolumes, good);
463 464 465 466

	std::vector<VEC3> buffer;
	buffer.reserve(16384);

467 468
	std::vector<VEC3> bufferColors;

469
	bufferColors.reserve(16384);
470

Pierre Kraemer's avatar
Pierre Kraemer committed
471
	TraversorCell<typename PFP::MAP, PFP::MAP::FACE_OF_PARENT> traFace(map, good);
Sylvain Thery's avatar
Sylvain Thery committed
472 473

	for (Dart d = traFace.begin(); d != traFace.end(); d = traFace.next())
474
	{
475 476 477 478
		VEC3 centerFace = Algo::Surface::Geometry::faceCentroidELW<PFP>(map, d, positions);
		VEC3 volColor = colorPerXXX[d];
		
		Dart b = d;
Sylvain Thery's avatar
Sylvain Thery committed
479
		Dart c = map.phi1(b);
480 481 482
		Dart a = map.phi1(c);
		
		if (map.phi1(a) == d)
483
		{
Sylvain Thery's avatar
Sylvain Thery committed
484 485
			buffer.push_back(centerVolumes[d]);
			bufferColors.push_back(centerFace);
486
			
Sylvain Thery's avatar
Sylvain Thery committed
487
			buffer.push_back(positions[b]);
488 489 490 491
			bufferColors.push_back(volColor);
			buffer.push_back(positions[c]);
			bufferColors.push_back(volColor);
			c = map.phi1(c);
Sylvain Thery's avatar
Sylvain Thery committed
492
			buffer.push_back(positions[c]);
493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514
			bufferColors.push_back(volColor);	
		}
		else
		{
	
			// loop to cut a polygon in triangle on the fly (ceter point method)
			do
			{
				buffer.push_back(centerVolumes[d]);
				bufferColors.push_back(centerFace);
				
				buffer.push_back(centerFace);
				bufferColors.push_back(volColor);
				
				buffer.push_back(positions[b]);
				bufferColors.push_back(volColor);
				buffer.push_back(positions[c]);
				bufferColors.push_back(volColor);
				b = c;
				c = map.phi1(b);
			} while (b != d);
		}
515
	}
Sylvain Thery's avatar
Sylvain Thery committed
516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571

	m_nbTris = buffer.size()/4;

	m_vboPos->allocate(buffer.size());
	VEC3* ptrPos = reinterpret_cast<VEC3*>(m_vboPos->lockPtr());
	memcpy(ptrPos,&buffer[0],buffer.size()*sizeof(VEC3));
	m_vboPos->releasePtr();
	m_shader->setAttributePosition(m_vboPos);

	m_vboColors->allocate(bufferColors.size());
	VEC3* ptrCol = reinterpret_cast<VEC3*>(m_vboColors->lockPtr());
	memcpy(ptrCol,&bufferColors[0],bufferColors.size()*sizeof(VEC3));
	m_vboColors->releasePtr();
	m_shader->setAttributeColor(m_vboColors);

	buffer.clear();

	TraversorCell<typename PFP::MAP, PFP::MAP::EDGE_OF_PARENT> traEdge(map, good);
	for (Dart d = traEdge.begin(); d != traEdge.end(); d = traEdge.next())
	{
			buffer.push_back(centerVolumes[d]);
			buffer.push_back(positions[d]);
			buffer.push_back(positions[map.phi1(d)]);
	}

	m_nbLines = buffer.size()/3;

	m_vboPosLine->allocate(buffer.size());

	ptrPos = reinterpret_cast<VEC3*>(m_vboPosLine->lockPtr());
	memcpy(ptrPos,&buffer[0],buffer.size()*sizeof(VEC3));

	m_vboPosLine->releasePtr();
	m_shaderL->setAttributePosition(m_vboPosLine);
}

template<typename PFP>
void ExplodeVolumeRender::updateData(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& positions, const FunctorSelect& good)
{
	if (m_cpf)
	{
		CGoGNerr<< "ExplodeVolumeRender: problem wrong update fonction use the other (without VolumeAttribute parameter)" << CGoGNendl;
		return;
	}

	if (m_smooth)
	{
		updateSmooth<PFP>(map,positions,good);
		return;
	}


	typedef typename PFP::VEC3 VEC3;
	typedef typename PFP::REAL REAL;

	VolumeAutoAttribute<VEC3> centerVolumes(map, "centerVolumes");
572
	Algo::Volume::Geometry::computeCentroidELWVolumes<PFP>(map, positions, centerVolumes, good);
Sylvain Thery's avatar
Sylvain Thery committed
573 574 575 576 577 578 579 580 581 582 583

	std::vector<VEC3> buffer;
	buffer.reserve(16384);

	std::vector<VEC3> bufferColors;

	bufferColors.reserve(16384);

	TraversorCell<typename PFP::MAP, PFP::MAP::FACE_OF_PARENT> traFace(map, good);

	for (Dart d = traFace.begin(); d != traFace.end(); d = traFace.next())
584
	{
585
		VEC3 centerFace = Algo::Surface::Geometry::faceCentroidELW<PFP>(map, d, positions);
Sylvain Thery's avatar
Sylvain Thery committed
586

587
		Dart b = d;
Sylvain Thery's avatar
Sylvain Thery committed
588
		Dart c = map.phi1(b);
589 590 591
		Dart a = map.phi1(c);
		
		if (map.phi1(a) == d)
592
		{
Sylvain Thery's avatar
Sylvain Thery committed
593 594
			buffer.push_back(centerVolumes[d]);
			bufferColors.push_back(centerFace);
595
			
Sylvain Thery's avatar
Sylvain Thery committed
596 597 598 599
			buffer.push_back(positions[b]);
			bufferColors.push_back(m_globalColor);
			buffer.push_back(positions[c]);
			bufferColors.push_back(m_globalColor);
600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623
			c = map.phi1(c);
			buffer.push_back(positions[c]);
			bufferColors.push_back(m_globalColor);	
		}
		else
		{
	
			// loop to cut a polygon in triangle on the fly (ceter point method)
			do
			{
				buffer.push_back(centerVolumes[d]);
				bufferColors.push_back(centerFace);
				
				buffer.push_back(centerFace);
				bufferColors.push_back(m_globalColor);
				
				buffer.push_back(positions[b]);
				bufferColors.push_back(m_globalColor);
				buffer.push_back(positions[c]);
				bufferColors.push_back(m_globalColor);
				b = c;
				c = map.phi1(b);
			} while (b != d);
		}
624 625
	}

626

627 628 629 630 631 632 633 634
	m_nbTris = buffer.size()/4;

	m_vboPos->allocate(buffer.size());
	VEC3* ptrPos = reinterpret_cast<VEC3*>(m_vboPos->lockPtr());
	memcpy(ptrPos,&buffer[0],buffer.size()*sizeof(VEC3));
	m_vboPos->releasePtr();
	m_shader->setAttributePosition(m_vboPos);

635 636 637 638 639
	m_vboColors->allocate(bufferColors.size());
	VEC3* ptrCol = reinterpret_cast<VEC3*>(m_vboColors->lockPtr());
	memcpy(ptrCol,&bufferColors[0],bufferColors.size()*sizeof(VEC3));
	m_vboColors->releasePtr();
	m_shader->setAttributeColor(m_vboColors);
640

641
	buffer.clear();
Sylvain Thery's avatar
Sylvain Thery committed
642

Pierre Kraemer's avatar
Pierre Kraemer committed
643
	TraversorCell<typename PFP::MAP, PFP::MAP::EDGE_OF_PARENT> traEdge(map, good);
644
	for (Dart d = traEdge.begin(); d != traEdge.end(); d = traEdge.next())
Pierre Kraemer's avatar
Pierre Kraemer committed
645
	{
646 647
			buffer.push_back(centerVolumes[d]);
			buffer.push_back(positions[d]);
648
			buffer.push_back(positions[map.phi1(d)]);
Pierre Kraemer's avatar
Pierre Kraemer committed
649 650
	}

651 652 653 654 655 656 657 658 659
	m_nbLines = buffer.size()/3;

	m_vboPosLine->allocate(buffer.size());

	ptrPos = reinterpret_cast<VEC3*>(m_vboPosLine->lockPtr());
	memcpy(ptrPos,&buffer[0],buffer.size()*sizeof(VEC3));

	m_vboPosLine->releasePtr();
	m_shaderL->setAttributePosition(m_vboPosLine);
Pierre Kraemer's avatar
Pierre Kraemer committed
660 661
}

Sylvain Thery's avatar
Sylvain Thery committed
662 663


664
inline void ExplodeVolumeRender::drawFaces()
Pierre Kraemer's avatar
Pierre Kraemer committed
665
{
Sylvain Thery's avatar
Sylvain Thery committed
666 667 668 669 670 671 672 673 674 675 676 677
	if (m_smooth)
	{
		m_shaderS->enableVertexAttribs();
		glDrawArrays(GL_LINES_ADJACENCY_EXT , 0 , m_nbTris*4 );
		m_shaderS->disableVertexAttribs();
	}
	else
	{
		m_shader->enableVertexAttribs();
		glDrawArrays(GL_LINES_ADJACENCY_EXT , 0 , m_nbTris*4 );
		m_shader->disableVertexAttribs();
	}
678
}
Pierre Kraemer's avatar
Pierre Kraemer committed
679

680 681
inline void ExplodeVolumeRender::drawEdges()
{
Pierre Kraemer's avatar
Pierre Kraemer committed
682

683 684 685
	m_shaderL->enableVertexAttribs();
	glDrawArrays(GL_TRIANGLES , 0 , m_nbLines*3 );
	m_shaderL->disableVertexAttribs();
Pierre Kraemer's avatar
Pierre Kraemer committed
686 687
}

Sylvain Thery's avatar
Sylvain Thery committed
688 689
inline void ExplodeVolumeRender::setExplodeVolumes(float explode)
{
Sylvain Thery's avatar
Sylvain Thery committed
690 691 692 693
	if (m_smooth)
		m_shaderS->setExplodeVolumes(explode);
	else
		m_shader->setExplodeVolumes(explode);
Sylvain Thery's avatar
Sylvain Thery committed
694 695 696
	m_shaderL->setExplodeVolumes(explode);
}

697 698
inline void ExplodeVolumeRender::setExplodeFaces(float explode)
{
Sylvain Thery's avatar
Sylvain Thery committed
699 700 701 702
	if (m_smooth)
		m_shaderS->setExplodeFaces(explode);
	else
		m_shader->setExplodeFaces(explode);
703 704
}

Sylvain Thery's avatar
Sylvain Thery committed
705 706
inline void ExplodeVolumeRender::setClippingPlane(const Geom::Vec4f& p)
{
Sylvain Thery's avatar
Sylvain Thery committed
707 708 709 710
	if (m_smooth)
		m_shaderS->setClippingPlane(p);
	else
		m_shader->setClippingPlane(p);
Sylvain Thery's avatar
Sylvain Thery committed
711 712 713 714 715 716
	m_shaderL->setClippingPlane(p);
}

inline void ExplodeVolumeRender::setNoClippingPlane()
{
	Geom::Vec4f p(1.0f,1.0f,1.0f,-99999999.9f);
Sylvain Thery's avatar
Sylvain Thery committed
717 718 719 720
	if (m_smooth)
		m_shaderS->setClippingPlane(p);
	else
		m_shader->setClippingPlane(p);
Sylvain Thery's avatar
Sylvain Thery committed
721 722 723 724 725
	m_shaderL->setClippingPlane(p);
}

inline void ExplodeVolumeRender::setAmbiant(const Geom::Vec4f& ambiant)
{
Sylvain Thery's avatar
Sylvain Thery committed
726 727 728 729
	if (m_smooth)
		m_shaderS->setAmbiant(ambiant);
	else
		m_shader->setAmbiant(ambiant);
Sylvain Thery's avatar
Sylvain Thery committed
730 731
}

732
inline void ExplodeVolumeRender::setBackColor(const Geom::Vec4f& color)
Sylvain Thery's avatar
Sylvain Thery committed
733
{
734
	if (!m_smooth)
Sylvain Thery's avatar
Sylvain Thery committed
735
		m_shader->setBackColor(color);
Sylvain Thery's avatar
Sylvain Thery committed
736 737 738 739
}

inline void ExplodeVolumeRender::setLightPosition(const Geom::Vec3f& lp)
{
Sylvain Thery's avatar
Sylvain Thery committed
740 741 742 743
	if (m_smooth)
		m_shaderS->setLightPosition(lp);
	else
		m_shader->setLightPosition(lp);
Sylvain Thery's avatar
Sylvain Thery committed
744 745 746 747 748 749 750 751 752
}

inline void ExplodeVolumeRender::setColorLine(const Geom::Vec4f& col)
{
	m_shaderL->setColor(col);
}

inline Utils::GLSLShader* ExplodeVolumeRender::shaderFaces()
{
Sylvain Thery's avatar
Sylvain Thery committed
753 754
	if (m_smooth)
		return m_shaderS;
Sylvain Thery's avatar
Sylvain Thery committed
755 756 757 758 759 760 761
	return m_shader;
}

inline Utils::GLSLShader* ExplodeVolumeRender::shaderLines()
{
	return m_shaderL;
}
762

Pierre Kraemer's avatar
Pierre Kraemer committed
763 764 765 766 767 768 769
}//end namespace VBO

}//end namespace Algo

}//end namespace Render

}//end namespace CGoGN