explodeVolumeRender.hpp 23.8 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
	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;
	}
}

141 142 143 144 145
//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);
//}
146

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

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

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

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

172
//	TraversorCell<MAP, MAP::FACE_OF_PARENT> traFace(map);
173
	foreach_cell<MAP::FACE_OF_PARENT>(map, [&] (Cell<MAP::FACE_OF_PARENT> d)
174
	{
Sylvain Thery's avatar
Sylvain Thery committed
175
		// compute normals
176
		VEC3 centerFace = Algo::Surface::Geometry::faceCentroidELW<PFP>(map, d.dart, positions);
Pierre Kraemer's avatar
Pierre Kraemer committed
177
		VEC3 centerNormalFace = Algo::Surface::Geometry::newellNormal<PFP>(map, d.dart, positions);
178 179 180
		
		computeFace<PFP>(map,d,positions,centerFace,centerNormalFace,vertices,normals);
		
181
		VEC3F volCol = PFP::toVec3f(colorPerXXX[d.dart]);
182 183 184 185 186

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

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

217
				buffer.push_back(PFP::toVec3f(centerFace));
218
				bufferColors.push_back(volCol);
219
				bufferNormals.push_back(PFP::toVec3f(centerNormalFace));
220
				
221 222
				buffer.push_back(PFP::toVec3f(*iv++));
				bufferNormals.push_back(PFP::toVec3f(*in++));
223 224
				bufferColors.push_back(volCol);
				
225 226
				buffer.push_back(PFP::toVec3f(*iv));
				bufferNormals.push_back(PFP::toVec3f(*in));
227
				bufferColors.push_back(volCol);
228
			}
229
		}
230 231
	});
//	,false,thread); ????
Sylvain Thery's avatar
Sylvain Thery committed
232 233 234 235

	m_nbTris = buffer.size()/4;

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

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

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

	buffer.clear();

255
//	TraversorCell<typename PFP::MAP, PFP::MAP::EDGE_OF_PARENT> traEdge(map);
256
	foreach_cell<PFP::MAP::EDGE_OF_PARENT>(map, [&] (Cell<PFP::MAP::EDGE_OF_PARENT> c)
257
	{
258 259 260 261 262
			buffer.push_back(PFP::toVec3f(centerVolumes[c.dart]));
			buffer.push_back(PFP::toVec3f(positions[c.dart]));
			buffer.push_back(PFP::toVec3f(positions[map.phi1(c)]));
	});
	//	,false,thread); ????
Sylvain Thery's avatar
Sylvain Thery committed
263 264 265 266 267

	m_nbLines = buffer.size()/3;

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

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

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


276 277 278 279 280
//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);
//}
281

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

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

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

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

306 307
//	TraversorCell<MAP, MAP::FACE_OF_PARENT> traFace(map);
//	for (Dart d = traFace.begin(); d != traFace.end(); d = traFace.next())
308
	foreach_cell<MAP::FACE_OF_PARENT>(map, [&] (Cell<MAP::FACE_OF_PARENT> d)
Sylvain Thery's avatar
Sylvain Thery committed
309 310
	{
		// compute normals
311
		VEC3 centerFace = Algo::Surface::Geometry::faceCentroidELW<PFP>(map, d, positions);
312
		VEC3 centerNormalFace = Algo::Surface::Geometry::newellNormal<PFP>(map, d, positions);
313

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

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

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

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

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

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

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

385 386
	buffer.clear();

387 388
//	TraversorCell<typename PFP::MAP, PFP::MAP::EDGE_OF_PARENT> traEdge(map);
//	for (Dart d = traEdge.begin(); d != traEdge.end(); d = traEdge.next())
389
	foreach_cell<MAP::EDGE_OF_PARENT>(map, [&] (Cell<MAP::EDGE_OF_PARENT> c)
390
	{
391 392 393 394
			buffer.push_back(PFP::toVec3f(centerVolumes[c.dart]));
			buffer.push_back(PFP::toVec3f(positions[c.dart]));
			buffer.push_back(PFP::toVec3f(positions[map.phi1(c.dart)]));
	});
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
		updateSmooth<PFP>(map,positions,colorPerXXX);
Sylvain Thery's avatar
Sylvain Thery committed
427
		return;
428 429
	}

430
    //typedef typename PFP::VEC3 VEC3;
431
	typedef typename V_ATT::DATA_TYPE VEC3;
Pierre Kraemer's avatar
Pierre Kraemer committed
432
	typedef typename PFP::MAP MAP;
433
	typedef typename PFP::REAL REAL;
434
	typedef Geom::Vec3f VEC3F;
435

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

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

442
	std::vector<VEC3F> bufferColors;
443

444
	bufferColors.reserve(16384);
445

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

	m_nbTris = buffer.size()/4;

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

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

	buffer.clear();

507 508
//	TraversorCell<typename PFP::MAP, PFP::MAP::EDGE_OF_PARENT> traEdge(map);
//	for (Dart d = traEdge.begin(); d != traEdge.end(); d = traEdge.next())
509 510 511 512 513
	foreach_cell<MAP::EDGE_OF_PARENT>(map, [&] (Cell<MAP::EDGE_OF_PARENT> c)
	{			buffer.push_back(PFP::toVec3f(centerVolumes[c.dart]));
			buffer.push_back(PFP::toVec3f(positions[c.dart]));
			buffer.push_back(PFP::toVec3f(positions[map.phi1(c)]));
	}); // false,thread ???
Sylvain Thery's avatar
Sylvain Thery committed
514 515 516 517 518

	m_nbLines = buffer.size()/3;

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

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

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

526 527 528 529 530
//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);
//}
531

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

541
	typedef typename EMBV::DATA_TYPE VEC3;
Pierre Kraemer's avatar
Pierre Kraemer committed
542
	typedef typename PFP::MAP MAP;
Sylvain Thery's avatar
Sylvain Thery committed
543
	typedef typename PFP::REAL REAL;
544
	typedef Geom::Vec3f VEC3F;
Sylvain Thery's avatar
Sylvain Thery committed
545

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

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

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

555
//	TraversorCell<MAP, MAP::FACE_OF_PARENT> traFace(map);
556
	foreach_cell<MAP::FACE_OF_PARENT>(map, [&] (Cell<MAP::FACE_OF_PARENT> d)
557
	{
558
		VEC3F centerFace = PFP::toVec3f(Algo::Surface::Geometry::faceCentroidELW<PFP>(map, d, positions));
Sylvain Thery's avatar
Sylvain Thery committed
559

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

599

600 601 602
	m_nbTris = buffer.size()/4;

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

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

614
	buffer.clear();
Sylvain Thery's avatar
Sylvain Thery committed
615

616
//	TraversorCell<typename PFP::MAP, PFP::MAP::EDGE_OF_PARENT> traEdge(map);
617
	foreach_cell<MAP::EDGE_OF_PARENT>(map, [&] (Cell<MAP::EDGE_OF_PARENT> c)
Pierre Kraemer's avatar
Pierre Kraemer committed
618
	{
619 620 621 622
			buffer.push_back(PFP::toVec3f(centerVolumes[c.dart]));
			buffer.push_back(PFP::toVec3f(positions[c.dart]));
			buffer.push_back(PFP::toVec3f(positions[map.phi1(c)]));
	});
Pierre Kraemer's avatar
Pierre Kraemer committed
623

624 625 626 627
	m_nbLines = buffer.size()/3;

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

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

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

Sylvain Thery's avatar
Sylvain Thery committed
635 636


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

653 654
inline void ExplodeVolumeRender::drawEdges()
{
Pierre Kraemer's avatar
Pierre Kraemer committed
655

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

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

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

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

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

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

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

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

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

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

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

738
inline void ExplodeVolumeRender::svgoutEdges(const std::string& filename, const glm::mat4& model, const glm::mat4& proj,float af)
739 740
{
	Utils::SVG::SVGOut svg(filename,model,proj);
741
	svg.setAttenuationFactor(af);
742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761
	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];
762 763 764 765 766 767 768
		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);
		}
769 770 771 772 773 774 775 776
	}
	svg2->endLines();
	m_vboPosLine->releasePtr();
	svg.addGroup(svg2);

}


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

}//end namespace Algo

}//end namespace Render

}//end namespace CGoGN