explodeVolumeRender.hpp 23.3 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
inline ExplodeVolumeRender::ExplodeVolumeRender(bool withColorPerFace, bool withExplodeFace, bool withSmoothFaces):
		m_cpf(withColorPerFace),m_ef(withExplodeFace),m_smooth(withSmoothFaces),
48
        m_nbTris(0), m_nbLines(0), m_globalColor(0.9f,0.5f,0.0f)//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 96 97 98 99 100 101 102 103 104 105
//template<typename PFP>
//void ExplodeVolumeRender::computeFace(typename PFP::MAP& map, Dart d, const VertexAttribute<typename PFP::VEC3>& positions,
//                                     const typename PFP::VEC3& centerFace, const typename PFP::VEC3& centerNormalFace,
//									 std::vector<typename PFP::VEC3>& vertices, std::vector<typename PFP::VEC3>& normals)
//{
//    computeFaceGen<PFP, VertexAttribute<typename PFP::VEC3>, typename PFP::VEC3>(map,d,positions,centerFace, centerNormalFace, vertices, normals);
//}


template<typename PFP, typename EMBV>
void ExplodeVolumeRender::computeFace(typename PFP::MAP& map, Dart d, const EMBV& positions,
									  const typename PFP::VEC3& centerFace, const typename PFP::VEC3& /*centerNormalFace*/,
106
                                      std::vector<typename PFP::VEC3>& vertices, std::vector<typename PFP::VEC3>& normals)
107
{
108
    //typedef typename PFP::VEC3 VEC3;
109
	typedef typename EMBV::DATA_TYPE VEC3;
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
	typedef typename PFP::REAL REAL;

	normals.clear();
	vertices.clear();
	Dart a = d;
	do
	{
		VEC3 v1 = positions[a] - centerFace;
		v1.normalize();
		Dart e = map.phi1(a);
		VEC3 v2 = positions[e] - centerFace;
		v2.normalize();
		VEC3 N = v1^v2;
		normals.push_back(N);
		vertices.push_back(positions[a]);
		a = e;
	} while (a != d);
	
	unsigned int nb = normals.size();
	VEC3 Ntemp = normals[0];
	normals[0] += normals[nb-1];
	normals[0].normalize();
	for (unsigned int i=1; i!=nb ; ++i)
	{
		VEC3 Ntemp2 = normals[i];
		normals[i] += Ntemp;
		normals[i].normalize();
		Ntemp = Ntemp2;
	}
}


142 143 144 145 146
//template<typename PFP>
//void ExplodeVolumeRender::updateSmooth(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& positions, const VolumeAttribute<typename PFP::VEC3>& colorPerXXX)
//{
//    updateSmoothGen<PFP, VertexAttribute<typename PFP::VEC3>, typename PFP::VEC3>(map,positions,colorPerXXX);
//}
147

148

149 150
template<typename PFP, typename V_ATT, typename W_ATT>
void ExplodeVolumeRender::updateSmooth(typename PFP::MAP& map, const V_ATT& positions, const W_ATT& colorPerXXX)
151
{
152
	typedef typename V_ATT::DATA_TYPE VEC3;
153
	typedef typename W_ATT::DATA_TYPE COL3;
154
	typedef typename PFP::REAL REAL;
155
	typedef Geom::Vec3f VEC3F;
156

157
	VolumeAutoAttribute<VEC3> centerVolumes(map, "centerVolumes");
158
	Algo::Volume::Geometry::Parallel::computeCentroidELWVolumes<PFP>(map, positions, centerVolumes);
159

160
	std::vector<VEC3F> buffer;
161 162
	buffer.reserve(16384);

163
	std::vector<VEC3F> bufferColors;
164
	bufferColors.reserve(16384);
165
	std::vector<VEC3F> bufferNormals;
166
	bufferNormals.reserve(16384);
167
	
168
	std::vector<VEC3> normals;
169
	normals.reserve(20);
170
	std::vector<VEC3> vertices;
171
	vertices.reserve(20);
172

173
	
174
	TraversorCell<typename PFP::MAP, PFP::MAP::FACE_OF_PARENT> traFace(map);
175

Sylvain Thery's avatar
Sylvain Thery committed
176
	for (Dart d = traFace.begin(); d != traFace.end(); d = traFace.next())
177
	{
Sylvain Thery's avatar
Sylvain Thery committed
178
		// compute normals
179
		VEC3 centerFace = Algo::Surface::Geometry::faceCentroidELW<PFP>(map, d, positions);
180
		VEC3 centerNormalFace = Algo::Surface::Geometry::newellNormal<PFP>(map,d,positions);
181 182 183
		
		computeFace<PFP>(map,d,positions,centerFace,centerNormalFace,vertices,normals);
		
184
		VEC3F volCol = PFP::toVec3f(colorPerXXX[d]);
185 186 187 188 189

		unsigned int nbs = vertices.size();
		// just to have more easy algo further
		vertices.push_back(vertices.front());
		normals.push_back(normals.front());
190
		
191
		typename std::vector<VEC3>::iterator iv  = vertices.begin();
192
		typename std::vector<VEC3>::iterator in  = normals.begin();
193 194
		
		if (nbs == 3)
195
		{
196 197 198
			buffer.push_back(PFP::toVec3f(centerVolumes[d]));
			bufferColors.push_back(PFP::toVec3f(centerFace));
			bufferNormals.push_back(PFP::toVec3f(centerNormalFace)); // unsused just for fill
199
			
200 201
			buffer.push_back(PFP::toVec3f(*iv++));
			bufferNormals.push_back(PFP::toVec3f(*in++));
202 203
			bufferColors.push_back(volCol);
			
204 205
			buffer.push_back(PFP::toVec3f(*iv++));
			bufferNormals.push_back(PFP::toVec3f(*in++));
206 207
			bufferColors.push_back(volCol);

208 209
			buffer.push_back(PFP::toVec3f(*iv++));
			bufferNormals.push_back(PFP::toVec3f(*in++));
210
			bufferColors.push_back(volCol);
211
		}
212
		else
213
		{
214
			for (unsigned int i=0; i<nbs; ++i)
215
			{
216 217 218
				buffer.push_back(PFP::toVec3f(centerVolumes[d]));
				bufferColors.push_back(PFP::toVec3f(centerFace));
				bufferNormals.push_back(PFP::toVec3f(centerNormalFace)); // unsused just for fill
219

220
				buffer.push_back(PFP::toVec3f(centerFace));
221
				bufferColors.push_back(volCol);
222
				bufferNormals.push_back(PFP::toVec3f(centerNormalFace));
223
				
224 225
				buffer.push_back(PFP::toVec3f(*iv++));
				bufferNormals.push_back(PFP::toVec3f(*in++));
226 227
				bufferColors.push_back(volCol);
				
228 229
				buffer.push_back(PFP::toVec3f(*iv));
				bufferNormals.push_back(PFP::toVec3f(*in));
230
				bufferColors.push_back(volCol);
231
			}
232
		}
233
	}
Sylvain Thery's avatar
Sylvain Thery committed
234 235 236 237 238


	m_nbTris = buffer.size()/4;

	m_vboPos->allocate(buffer.size());
239 240
	VEC3F* ptrPos = reinterpret_cast<VEC3F*>(m_vboPos->lockPtr());
	memcpy(ptrPos,&buffer[0],buffer.size()*sizeof(VEC3F));
Sylvain Thery's avatar
Sylvain Thery committed
241 242 243 244
	m_vboPos->releasePtr();
	m_shaderS->setAttributePosition(m_vboPos);

	m_vboColors->allocate(bufferColors.size());
245 246
	VEC3F* ptrCol = reinterpret_cast<VEC3F*>(m_vboColors->lockPtr());
	memcpy(ptrCol,&bufferColors[0],bufferColors.size()*sizeof(VEC3F));
Sylvain Thery's avatar
Sylvain Thery committed
247 248 249 250
	m_vboColors->releasePtr();
	m_shaderS->setAttributeColor(m_vboColors);

	m_vboNormals->allocate(bufferNormals.size());
251 252
	VEC3F* ptrNorm = reinterpret_cast<VEC3F*>(m_vboNormals->lockPtr());
	memcpy(ptrNorm,&bufferNormals[0],bufferNormals.size()*sizeof(VEC3F));
Sylvain Thery's avatar
Sylvain Thery committed
253 254 255 256 257
	m_vboNormals->releasePtr();
	m_shaderS->setAttributeNormal(m_vboNormals);

	buffer.clear();

258
	TraversorCell<typename PFP::MAP, PFP::MAP::EDGE_OF_PARENT> traEdge(map);
Sylvain Thery's avatar
Sylvain Thery committed
259
	for (Dart d = traEdge.begin(); d != traEdge.end(); d = traEdge.next())
260
	{
261 262 263
			buffer.push_back(PFP::toVec3f(centerVolumes[d]));
			buffer.push_back(PFP::toVec3f(positions[d]));
			buffer.push_back(PFP::toVec3f(positions[map.phi1(d)]));
Sylvain Thery's avatar
Sylvain Thery committed
264 265 266 267 268 269
	}

	m_nbLines = buffer.size()/3;

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

270 271
	ptrPos = reinterpret_cast<VEC3F*>(m_vboPosLine->lockPtr());
	memcpy(ptrPos,&buffer[0],buffer.size()*sizeof(VEC3F));
Sylvain Thery's avatar
Sylvain Thery committed
272 273 274 275 276 277

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


278 279 280 281 282
//template<typename PFP>
//void ExplodeVolumeRender::updateSmooth(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& positions)
//{
//    updateSmoothGen<PFP, VertexAttribute<typename PFP::VEC3>, typename PFP::VEC3>(map, positions);
//}
283

284
template<typename PFP, typename EMBV>
285
void ExplodeVolumeRender::updateSmooth(typename PFP::MAP& map, const EMBV& positions)
Sylvain Thery's avatar
Sylvain Thery committed
286
{
287
	typedef typename EMBV::DATA_TYPE VEC3;
Sylvain Thery's avatar
Sylvain Thery committed
288
	typedef typename PFP::REAL REAL;
289
	typedef typename Geom::Vec3f VEC3F;
Sylvain Thery's avatar
Sylvain Thery committed
290 291

	VolumeAutoAttribute<VEC3> centerVolumes(map, "centerVolumes");
292
	Algo::Volume::Geometry::Parallel::computeCentroidELWVolumes<PFP>(map, positions, centerVolumes);
Sylvain Thery's avatar
Sylvain Thery committed
293

294
	std::vector<VEC3F> buffer;
Sylvain Thery's avatar
Sylvain Thery committed
295 296
	buffer.reserve(16384);

297
	std::vector<VEC3F> bufferColors;
Sylvain Thery's avatar
Sylvain Thery committed
298
	bufferColors.reserve(16384);
299
	std::vector<VEC3F> bufferNormals;
Sylvain Thery's avatar
Sylvain Thery committed
300
	bufferNormals.reserve(16384);
301
	
Sylvain Thery's avatar
Sylvain Thery committed
302 303
	std::vector<VEC3> normals;
	bufferNormals.reserve(20);
304 305
	std::vector<VEC3> vertices;
	bufferNormals.reserve(20);
Sylvain Thery's avatar
Sylvain Thery committed
306

307
	TraversorCell<typename PFP::MAP, PFP::MAP::FACE_OF_PARENT> traFace(map);
Sylvain Thery's avatar
Sylvain Thery committed
308 309 310 311

	for (Dart d = traFace.begin(); d != traFace.end(); d = traFace.next())
	{
		// compute normals
312
		VEC3 centerFace = Algo::Surface::Geometry::faceCentroidELW<PFP>(map, d, positions);
313
		VEC3 centerNormalFace = Algo::Surface::Geometry::newellNormal<PFP>(map, d, positions);
314

315 316
		computeFace<PFP>(map,d,positions,centerFace,centerNormalFace,vertices,normals);
		
317 318 319 320
		unsigned int nbs = vertices.size();
		// just to have more easy algo further
		vertices.push_back(vertices.front());
		normals.push_back(normals.front());
321
		
322
		typename std::vector<VEC3>::iterator iv  = vertices.begin();
323 324
		typename std::vector<VEC3>::iterator in  = normals.begin();
		
325
		if (nbs == 3)
326
		{
327 328 329
			buffer.push_back(PFP::toVec3f(centerVolumes[d]));
			bufferColors.push_back(PFP::toVec3f(centerFace));
			bufferNormals.push_back(PFP::toVec3f(centerNormalFace)); // unsused just for fill
330

331 332
			buffer.push_back(PFP::toVec3f(*iv++));
			bufferNormals.push_back(PFP::toVec3f(*in++));
Sylvain Thery's avatar
Sylvain Thery committed
333
			bufferColors.push_back(m_globalColor);
334
			
335 336
			buffer.push_back(PFP::toVec3f(*iv++));
			bufferNormals.push_back(PFP::toVec3f(*in++));
Sylvain Thery's avatar
Sylvain Thery committed
337 338
			bufferColors.push_back(m_globalColor);

339 340
			buffer.push_back(PFP::toVec3f(*iv++));
			bufferNormals.push_back(PFP::toVec3f(*in++));
341 342 343 344 345 346
			bufferColors.push_back(m_globalColor);
		}
		else
		{
			for (unsigned int i=0; i<nbs; ++i)
			{
347 348 349
				buffer.push_back(PFP::toVec3f(centerVolumes[d]));
				bufferColors.push_back(PFP::toVec3f(centerFace));
				bufferNormals.push_back(PFP::toVec3f(centerNormalFace)); // unsused just for fill
350

351
				buffer.push_back(PFP::toVec3f(centerFace));
352
				bufferColors.push_back(m_globalColor);
353
				bufferNormals.push_back(PFP::toVec3f(centerNormalFace));
354
				
355 356
				buffer.push_back(PFP::toVec3f(*iv++));
				bufferNormals.push_back(PFP::toVec3f(*in++));
357 358
				bufferColors.push_back(m_globalColor);
				
359 360
				buffer.push_back(PFP::toVec3f(*iv));
				bufferNormals.push_back(PFP::toVec3f(*in));
361 362 363
				bufferColors.push_back(m_globalColor);
			}
		}
364 365
	}
	
366 367 368
	m_nbTris = buffer.size()/4;

	m_vboPos->allocate(buffer.size());
369 370
	VEC3F* ptrPos = reinterpret_cast<VEC3F*>(m_vboPos->lockPtr());
	memcpy(ptrPos,&buffer[0],buffer.size()*sizeof(VEC3F));
371
	m_vboPos->releasePtr();
Sylvain Thery's avatar
Sylvain Thery committed
372
	m_shaderS->setAttributePosition(m_vboPos);
373

374
	m_vboColors->allocate(bufferColors.size());
375 376
	VEC3F* ptrCol = reinterpret_cast<VEC3F*>(m_vboColors->lockPtr());
	memcpy(ptrCol,&bufferColors[0],bufferColors.size()*sizeof(VEC3F));
377
	m_vboColors->releasePtr();
Sylvain Thery's avatar
Sylvain Thery committed
378 379 380
	m_shaderS->setAttributeColor(m_vboColors);

	m_vboNormals->allocate(bufferNormals.size());
381 382
	VEC3F* ptrNorm = reinterpret_cast<VEC3F*>(m_vboNormals->lockPtr());
	memcpy(ptrNorm,&bufferNormals[0],bufferNormals.size()*sizeof(VEC3F));
Sylvain Thery's avatar
Sylvain Thery committed
383 384
	m_vboNormals->releasePtr();
	m_shaderS->setAttributeNormal(m_vboNormals);
385

386 387
	buffer.clear();

388
	TraversorCell<typename PFP::MAP, PFP::MAP::EDGE_OF_PARENT> traEdge(map);
389
	for (Dart d = traEdge.begin(); d != traEdge.end(); d = traEdge.next())
390
	{
391 392 393
			buffer.push_back(PFP::toVec3f(centerVolumes[d]));
			buffer.push_back(PFP::toVec3f(positions[d]));
			buffer.push_back(PFP::toVec3f(positions[map.phi1(d)]));
394 395 396 397 398 399
	}

	m_nbLines = buffer.size()/3;

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

400 401
	ptrPos = reinterpret_cast<VEC3F*>(m_vboPosLine->lockPtr());
	memcpy(ptrPos,&buffer[0],buffer.size()*sizeof(VEC3F));
402 403 404 405

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

407

Sylvain Thery's avatar
Sylvain Thery committed
408

409 410 411 412 413
//template<typename PFP>
//void ExplodeVolumeRender::updateData(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& positions, const VolumeAttribute<typename PFP::VEC3>& colorPerXXX)
//{
//    updateDataGen<PFP,  const VertexAttribute<typename PFP::VEC3>, typename PFP::VEC3>(map, positions, colorPerXXX);
//}
414

415 416
template<typename PFP, typename V_ATT, typename W_ATT>
void ExplodeVolumeRender::updateData(typename PFP::MAP& map, const V_ATT& positions, const W_ATT& colorPerXXX)
417
{
Sylvain Thery's avatar
Sylvain Thery committed
418 419 420 421 422
	if (!m_cpf)
	{
		CGoGNerr<< "ExplodeVolumeRender: problem wrong update fonction use the other (without VolumeAttribute parameter)" << CGoGNendl;
		return;
	}
423 424

	if (m_smooth)
425
	{
426

427
		updateSmooth<PFP>(map,positions,colorPerXXX);
Sylvain Thery's avatar
Sylvain Thery committed
428
		return;
429 430
	}

431

432
    //typedef typename PFP::VEC3 VEC3;
433
	typedef typename V_ATT::DATA_TYPE VEC3;
434
	typedef typename PFP::REAL REAL;
435
	typedef Geom::Vec3f VEC3F;
436

437
	VolumeAutoAttribute<VEC3> centerVolumes(map, "centerVolumes");
438
	Algo::Volume::Geometry::Parallel::computeCentroidELWVolumes<PFP>(map, positions, centerVolumes);
439

440
	std::vector<VEC3F> buffer;
441 442
	buffer.reserve(16384);

443
	std::vector<VEC3F> bufferColors;
444

445
	bufferColors.reserve(16384);
446

447
	TraversorCell<typename PFP::MAP, PFP::MAP::FACE_OF_PARENT> traFace(map);
Sylvain Thery's avatar
Sylvain Thery committed
448 449

	for (Dart d = traFace.begin(); d != traFace.end(); d = traFace.next())
450
	{
451 452
		VEC3F centerFace = PFP::toVec3f(Algo::Surface::Geometry::faceCentroidELW<PFP>(map, d, positions));
		VEC3F volColor = PFP::toVec3f(colorPerXXX[d]);
453 454
		
		Dart b = d;
Sylvain Thery's avatar
Sylvain Thery committed
455
		Dart c = map.phi1(b);
456 457 458
		Dart a = map.phi1(c);
		
		if (map.phi1(a) == d)
459
		{
460
			buffer.push_back(PFP::toVec3f(centerVolumes[d]));
Sylvain Thery's avatar
Sylvain Thery committed
461
			bufferColors.push_back(centerFace);
462
			
463
			buffer.push_back(PFP::toVec3f(positions[b]));
464
			bufferColors.push_back(volColor);
465
			buffer.push_back(PFP::toVec3f(positions[c]));
466 467
			bufferColors.push_back(volColor);
			c = map.phi1(c);
468 469
			buffer.push_back(PFP::toVec3f(positions[c]));
			bufferColors.push_back(volColor);
470 471 472 473 474 475 476
		}
		else
		{
	
			// loop to cut a polygon in triangle on the fly (ceter point method)
			do
			{
477
				buffer.push_back(PFP::toVec3f(centerVolumes[d]));
478 479 480 481 482
				bufferColors.push_back(centerFace);
				
				buffer.push_back(centerFace);
				bufferColors.push_back(volColor);
				
483
				buffer.push_back(PFP::toVec3f(positions[b]));
484
				bufferColors.push_back(volColor);
485
				buffer.push_back(PFP::toVec3f(positions[c]));
486 487 488 489 490
				bufferColors.push_back(volColor);
				b = c;
				c = map.phi1(b);
			} while (b != d);
		}
491
	}
Sylvain Thery's avatar
Sylvain Thery committed
492 493 494 495

	m_nbTris = buffer.size()/4;

	m_vboPos->allocate(buffer.size());
496 497
	VEC3F* ptrPos = reinterpret_cast<VEC3F*>(m_vboPos->lockPtr());
	memcpy(ptrPos,&buffer[0],buffer.size()*sizeof(VEC3F));
Sylvain Thery's avatar
Sylvain Thery committed
498 499 500 501
	m_vboPos->releasePtr();
	m_shader->setAttributePosition(m_vboPos);

	m_vboColors->allocate(bufferColors.size());
502 503
	VEC3F* ptrCol = reinterpret_cast<VEC3F*>(m_vboColors->lockPtr());
	memcpy(ptrCol,&bufferColors[0],bufferColors.size()*sizeof(VEC3F));
Sylvain Thery's avatar
Sylvain Thery committed
504 505 506 507 508
	m_vboColors->releasePtr();
	m_shader->setAttributeColor(m_vboColors);

	buffer.clear();

509
	TraversorCell<typename PFP::MAP, PFP::MAP::EDGE_OF_PARENT> traEdge(map);
Sylvain Thery's avatar
Sylvain Thery committed
510 511
	for (Dart d = traEdge.begin(); d != traEdge.end(); d = traEdge.next())
	{
512 513 514
			buffer.push_back(PFP::toVec3f(centerVolumes[d]));
			buffer.push_back(PFP::toVec3f(positions[d]));
			buffer.push_back(PFP::toVec3f(positions[map.phi1(d)]));
Sylvain Thery's avatar
Sylvain Thery committed
515 516 517 518 519 520
	}

	m_nbLines = buffer.size()/3;

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

521 522
	ptrPos = reinterpret_cast<VEC3F*>(m_vboPosLine->lockPtr());
	memcpy(ptrPos,&buffer[0],buffer.size()*sizeof(VEC3F));
Sylvain Thery's avatar
Sylvain Thery committed
523 524 525 526 527

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

528 529 530 531 532
//template<typename PFP>
//void ExplodeVolumeRender::updateData(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& positions)
//{
//    updateDataGen<PFP, VertexAttribute<typename PFP::VEC3>, typename PFP::VEC3>(map, positions);
//}
533

534 535
template<typename PFP, typename EMBV>
void ExplodeVolumeRender::updateData(typename PFP::MAP& map, const EMBV& positions)
Sylvain Thery's avatar
Sylvain Thery committed
536 537 538
{
	if (m_smooth)
	{
539
		updateSmooth<PFP, EMBV>(map,positions);
Sylvain Thery's avatar
Sylvain Thery committed
540 541 542
		return;
	}

543
	typedef typename EMBV::DATA_TYPE VEC3;
Sylvain Thery's avatar
Sylvain Thery committed
544
	typedef typename PFP::REAL REAL;
545
	typedef Geom::Vec3f VEC3F;
Sylvain Thery's avatar
Sylvain Thery committed
546 547

	VolumeAutoAttribute<VEC3> centerVolumes(map, "centerVolumes");
548
	Algo::Volume::Geometry::Parallel::computeCentroidELWVolumes<PFP>(map, positions, centerVolumes);
Sylvain Thery's avatar
Sylvain Thery committed
549

550
	std::vector<VEC3F> buffer;
Sylvain Thery's avatar
Sylvain Thery committed
551 552
	buffer.reserve(16384);

553
	std::vector<VEC3F> bufferColors;
Sylvain Thery's avatar
Sylvain Thery committed
554 555
	bufferColors.reserve(16384);

556
	TraversorCell<typename PFP::MAP, PFP::MAP::FACE_OF_PARENT> traFace(map);
Sylvain Thery's avatar
Sylvain Thery committed
557 558

	for (Dart d = traFace.begin(); d != traFace.end(); d = traFace.next())
559
	{
560
		VEC3F centerFace = PFP::toVec3f(Algo::Surface::Geometry::faceCentroidELW<PFP>(map, d, positions));
Sylvain Thery's avatar
Sylvain Thery committed
561

562
		Dart b = d;
Sylvain Thery's avatar
Sylvain Thery committed
563
		Dart c = map.phi1(b);
564 565 566
		Dart a = map.phi1(c);
		
		if (map.phi1(a) == d)
567
		{
568
			buffer.push_back(PFP::toVec3f(centerVolumes[d]));
Sylvain Thery's avatar
Sylvain Thery committed
569
			bufferColors.push_back(centerFace);
570
			
571
			buffer.push_back(PFP::toVec3f(positions[b]));
Sylvain Thery's avatar
Sylvain Thery committed
572
			bufferColors.push_back(m_globalColor);
573
			buffer.push_back(PFP::toVec3f(positions[c]));
Sylvain Thery's avatar
Sylvain Thery committed
574
			bufferColors.push_back(m_globalColor);
575
			c = map.phi1(c);
576
			buffer.push_back(PFP::toVec3f(positions[c]));
577 578 579 580 581 582 583 584
			bufferColors.push_back(m_globalColor);	
		}
		else
		{
	
			// loop to cut a polygon in triangle on the fly (ceter point method)
			do
			{
585
				buffer.push_back(PFP::toVec3f(centerVolumes[d]));
586 587 588 589 590
				bufferColors.push_back(centerFace);
				
				buffer.push_back(centerFace);
				bufferColors.push_back(m_globalColor);
				
591
				buffer.push_back(PFP::toVec3f(positions[b]));
592
				bufferColors.push_back(m_globalColor);
593
				buffer.push_back(PFP::toVec3f(positions[c]));
594 595 596 597 598
				bufferColors.push_back(m_globalColor);
				b = c;
				c = map.phi1(b);
			} while (b != d);
		}
599 600
	}

601

602 603 604
	m_nbTris = buffer.size()/4;

	m_vboPos->allocate(buffer.size());
605 606
	VEC3F* ptrPos = reinterpret_cast<VEC3F*>(m_vboPos->lockPtr());
	memcpy(ptrPos,&buffer[0],buffer.size()*sizeof(VEC3F));
607 608 609
	m_vboPos->releasePtr();
	m_shader->setAttributePosition(m_vboPos);

610
	m_vboColors->allocate(bufferColors.size());
611 612
	VEC3F* ptrCol = reinterpret_cast<VEC3F*>(m_vboColors->lockPtr());
	memcpy(ptrCol,&bufferColors[0],bufferColors.size()*sizeof(VEC3F));
613 614
	m_vboColors->releasePtr();
	m_shader->setAttributeColor(m_vboColors);
615

616
	buffer.clear();
Sylvain Thery's avatar
Sylvain Thery committed
617

618
	TraversorCell<typename PFP::MAP, PFP::MAP::EDGE_OF_PARENT> traEdge(map);
619
	for (Dart d = traEdge.begin(); d != traEdge.end(); d = traEdge.next())
Pierre Kraemer's avatar
Pierre Kraemer committed
620
	{
621 622 623
			buffer.push_back(PFP::toVec3f(centerVolumes[d]));
			buffer.push_back(PFP::toVec3f(positions[d]));
			buffer.push_back(PFP::toVec3f(positions[map.phi1(d)]));
Pierre Kraemer's avatar
Pierre Kraemer committed
624 625
	}

626 627 628 629
	m_nbLines = buffer.size()/3;

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

630 631
	ptrPos = reinterpret_cast<VEC3F*>(m_vboPosLine->lockPtr());
	memcpy(ptrPos,&buffer[0],buffer.size()*sizeof(VEC3F));
632 633 634

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

Sylvain Thery's avatar
Sylvain Thery committed
637 638


639
inline void ExplodeVolumeRender::drawFaces()
Pierre Kraemer's avatar
Pierre Kraemer committed
640
{
Sylvain Thery's avatar
Sylvain Thery committed
641 642 643 644 645 646 647 648 649 650 651 652
	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();
	}
653
}
Pierre Kraemer's avatar
Pierre Kraemer committed
654

655 656
inline void ExplodeVolumeRender::drawEdges()
{
Pierre Kraemer's avatar
Pierre Kraemer committed
657

658 659 660
	m_shaderL->enableVertexAttribs();
	glDrawArrays(GL_TRIANGLES , 0 , m_nbLines*3 );
	m_shaderL->disableVertexAttribs();
Pierre Kraemer's avatar
Pierre Kraemer committed
661 662
}

Sylvain Thery's avatar
Sylvain Thery committed
663 664
inline void ExplodeVolumeRender::setExplodeVolumes(float explode)
{
665
	m_explodeV = explode;
Sylvain Thery's avatar
Sylvain Thery committed
666 667 668 669
	if (m_smooth)
		m_shaderS->setExplodeVolumes(explode);
	else
		m_shader->setExplodeVolumes(explode);
Sylvain Thery's avatar
Sylvain Thery committed
670 671 672
	m_shaderL->setExplodeVolumes(explode);
}

673 674
inline void ExplodeVolumeRender::setExplodeFaces(float explode)
{
Sylvain Thery's avatar
Sylvain Thery committed
675 676 677 678
	if (m_smooth)
		m_shaderS->setExplodeFaces(explode);
	else
		m_shader->setExplodeFaces(explode);
679 680
}

Sylvain Thery's avatar
Sylvain Thery committed
681 682
inline void ExplodeVolumeRender::setClippingPlane(const Geom::Vec4f& p)
{
683
	m_clipPlane = p;
Sylvain Thery's avatar
Sylvain Thery committed
684 685 686 687
	if (m_smooth)
		m_shaderS->setClippingPlane(p);
	else
		m_shader->setClippingPlane(p);
Sylvain Thery's avatar
Sylvain Thery committed
688 689 690 691 692
	m_shaderL->setClippingPlane(p);
}

inline void ExplodeVolumeRender::setNoClippingPlane()
{
693
	m_clipPlane = Geom::Vec4f(1.0f,1.0f,1.0f,-99999999.9f);
Sylvain Thery's avatar
Sylvain Thery committed
694
	if (m_smooth)
695
		m_shaderS->setClippingPlane(m_clipPlane);
Sylvain Thery's avatar
Sylvain Thery committed
696
	else
697 698
		m_shader->setClippingPlane(m_clipPlane);
	m_shaderL->setClippingPlane(m_clipPlane);
Sylvain Thery's avatar
Sylvain Thery committed
699 700 701 702
}

inline void ExplodeVolumeRender::setAmbiant(const Geom::Vec4f& ambiant)
{
Sylvain Thery's avatar
Sylvain Thery committed
703 704 705 706
	if (m_smooth)
		m_shaderS->setAmbiant(ambiant);
	else
		m_shader->setAmbiant(ambiant);
Sylvain Thery's avatar
Sylvain Thery committed
707 708
}

709
inline void ExplodeVolumeRender::setBackColor(const Geom::Vec4f& color)
Sylvain Thery's avatar
Sylvain Thery committed
710
{
711
	if (!m_smooth)
Sylvain Thery's avatar
Sylvain Thery committed
712
		m_shader->setBackColor(color);
Sylvain Thery's avatar
Sylvain Thery committed
713 714 715 716
}

inline void ExplodeVolumeRender::setLightPosition(const Geom::Vec3f& lp)
{
Sylvain Thery's avatar
Sylvain Thery committed
717 718 719 720
	if (m_smooth)
		m_shaderS->setLightPosition(lp);
	else
		m_shader->setLightPosition(lp);
Sylvain Thery's avatar
Sylvain Thery committed
721 722 723 724 725 726 727 728 729
}

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

inline Utils::GLSLShader* ExplodeVolumeRender::shaderFaces()
{
Sylvain Thery's avatar
Sylvain Thery committed
730 731
	if (m_smooth)
		return m_shaderS;
Sylvain Thery's avatar
Sylvain Thery committed
732 733 734 735 736 737 738
	return m_shader;
}

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

740
inline void ExplodeVolumeRender::svgoutEdges(const std::string& filename, const glm::mat4& model, const glm::mat4& proj,float af)
741 742
{
	Utils::SVG::SVGOut svg(filename,model,proj);
743
	svg.setAttenuationFactor(af);
744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763
	toSVG(svg);
	svg.write();
}

inline void ExplodeVolumeRender::toSVG(Utils::SVG::SVGOut& svg)
{

	Utils::SVG::SvgGroup* svg2 = new Utils::SVG::SvgGroup("alpha2", svg.m_model, svg.m_proj);

	Geom::Vec3f* ptr = reinterpret_cast<Geom::Vec3f*>(m_vboPosLine->lockPtr());
	svg2->setWidth(1.0f);
	svg2->beginLines();

	const Geom::Vec4f& col4 = m_shaderL->getColor();
	Geom::Vec3f col3(col4[0],col4[1],col4[2]);

	float XexplV = (1.0f-m_explodeV);
	for (unsigned int i=0; i<m_nbLines; ++i)
	{
		Geom::Vec3f C = ptr[3*i];
764 765 766 767 768 769 770
		Geom::Vec4f C4 = Geom::Vec4f(C[0],C[1],C[2],1.0f);
		if (m_clipPlane*C4 <=0.0f)
		{
			Geom::Vec3f P = XexplV*C + m_explodeV*ptr[3*i+1];
			Geom::Vec3f Q = XexplV*C + m_explodeV*ptr[3*i+2];
			svg2->addLine(P, Q, col3);
		}
771 772 773 774 775 776 777 778
	}
	svg2->endLines();
	m_vboPosLine->releasePtr();
	svg.addGroup(svg2);

}


Pierre Kraemer's avatar
Pierre Kraemer committed
779 780 781 782 783 784 785
}//end namespace VBO

}//end namespace Algo

}//end namespace Render

}//end namespace CGoGN