edgeSelector.h 24.8 KB
Newer Older
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
1 2 3
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps  *
* version 0.1                                                                  *
4
* Copyright (C) 2009-2013, IGG Team, ICube, University of Strasbourg           *
Kenneth Vanhoey's avatar
Kenneth Vanhoey 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/                                           *
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
21 22 23 24 25 26 27 28
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

#ifndef __EDGESELECTOR_H__
#define __EDGESELECTOR_H__

#include "Algo/Decimation/selector.h"
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
29
#include "Algo/Decimation/approximator.h"
30
#include "Algo/Geometry/boundingbox.h"
31
#include "Utils/qem.h"
32 33
#include "Algo/Geometry/normal.h"
#include "Algo/Selection/collector.h"
34
#include "Algo/Geometry/curvature.h"
35
#include "Algo/Geometry/area.h"
36

Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
37 38 39 40 41 42
namespace CGoGN
{

namespace Algo
{

43 44 45
namespace Surface
{

Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
46 47 48 49
namespace Decimation
{

template <typename PFP>
50
class EdgeSelector_MapOrder : public Selector<PFP>
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
51
{
52 53
public:
	typedef typename PFP::MAP MAP;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
54 55 56 57 58

private:
	Dart cur ;

public:
59 60
	EdgeSelector_MapOrder(MAP& m) :
		Selector<PFP>(m)
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
61 62 63 64 65
	{}
	~EdgeSelector_MapOrder()
	{}
	SelectorType getType() { return S_MapOrder ; }
	bool init() ;
66
	bool nextEdge(Dart& d) const ;
Sylvain Thery's avatar
Sylvain Thery committed
67
	void updateBeforeCollapse(Dart /*d*/) {}
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
68
	void updateAfterCollapse(Dart d2, Dart dd2) ;
Sylvain Thery's avatar
Sylvain Thery committed
69
	void updateWithoutCollapse() {}
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
70 71 72
} ;

template <typename PFP>
73
class EdgeSelector_Random : public Selector<PFP>
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
74
{
75 76
public:
	typedef typename PFP::MAP MAP;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
77 78 79 80 81 82 83

private:
	std::vector<Dart> darts ;
	unsigned int cur ;
	bool allSkipped ;

public:
84 85
	EdgeSelector_Random(MAP& m) :
		Selector<PFP>(m),
86 87
		cur(0),
		allSkipped(false)
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
88 89 90 91 92
	{}
	~EdgeSelector_Random()
	{}
	SelectorType getType() { return S_Random ; }
	bool init() ;
93
	bool nextEdge(Dart& d) const ;
Sylvain Thery's avatar
Sylvain Thery committed
94
	void updateBeforeCollapse(Dart /*d2*/) {}
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
95
	void updateAfterCollapse(Dart d2, Dart dd2) ;
96
	void updateWithoutCollapse();
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
97 98 99
} ;

template <typename PFP>
100
class EdgeSelector_Length : public Selector<PFP>
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
101 102 103 104 105 106 107
{
public:
	typedef typename PFP::MAP MAP ;
	typedef typename PFP::VEC3 VEC3 ;
	typedef typename PFP::REAL REAL ;

private:
108 109
	const VertexAttribute<VEC3, MAP>& position ;

Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
110 111 112 113 114 115
	typedef struct
	{
		typename std::multimap<float,Dart>::iterator it ;
		bool valid ;
		static std::string CGoGNnameOfType() { return "LengthEdgeInfo" ; }
	} LengthEdgeInfo ;
116
	typedef NoTypeNameAttribute<LengthEdgeInfo> EdgeInfo ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
117

118
	EdgeAttribute<EdgeInfo, MAP> edgeInfo ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
119 120 121 122 123 124 125 126 127

	std::multimap<float,Dart> edges ;
	typename std::multimap<float,Dart>::iterator cur ;

	void initEdgeInfo(Dart d) ;
	void updateEdgeInfo(Dart d, bool recompute) ;
	void computeEdgeInfo(Dart d, EdgeInfo& einfo) ;

public:
128 129 130
	EdgeSelector_Length(MAP& m, const VertexAttribute<VEC3, MAP>& pos) :
		Selector<PFP>(m),
		position(pos)
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
131
	{
Sylvain Thery's avatar
Sylvain Thery committed
132
		edgeInfo = m.template addAttribute<EdgeInfo, EDGE, MAP>("edgeInfo") ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
133 134 135 136 137 138 139
	}
	~EdgeSelector_Length()
	{
		this->m_map.removeAttribute(edgeInfo) ;
	}
	SelectorType getType() { return S_EdgeLength ; }
	bool init() ;
140
	bool nextEdge(Dart& d) const ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
141 142
	void updateBeforeCollapse(Dart d) ;
	void updateAfterCollapse(Dart d2, Dart dd2) ;
untereiner's avatar
untereiner committed
143

144
	void updateWithoutCollapse();
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
145

146
	void getEdgeErrors(EdgeAttribute<REAL, MAP> *errors) const
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
147 148 149 150 151 152
	{
		assert(errors != NULL || !"EdgeSelector::setColorMap requires non null vertexattribute argument") ;
		if (!errors->isValid())
			std::cerr << "EdgeSelector::setColorMap requires valid edgeattribute argument" << std::endl ;
		assert(edgeInfo.isValid()) ;

Pierre Kraemer's avatar
Pierre Kraemer committed
153
		TraversorE<MAP> travE(this->m_map) ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
154 155 156 157 158 159 160 161 162
		for(Dart d = travE.begin() ; d != travE.end() ; d = travE.next())
		{
			(*errors)[d] = -1 ;
			if (edgeInfo[d].valid)
			{
				(*errors)[d] = edgeInfo[d].it->first ;
			}
		}
	}
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
163 164 165
} ;

template <typename PFP>
166
class EdgeSelector_QEM : public Selector<PFP>
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
167 168 169 170 171 172 173
{
public:
	typedef typename PFP::MAP MAP ;
	typedef typename PFP::VEC3 VEC3 ;
	typedef typename PFP::REAL REAL ;

private:
174 175 176
	const VertexAttribute<VEC3, MAP>& m_position ;
	Approximator<PFP, VEC3, EDGE>& m_positionApproximator ;

Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
177 178 179 180 181 182
	typedef	struct
	{
		typename std::multimap<float,Dart>::iterator it ;
		bool valid ;
		static std::string CGoGNnameOfType() { return "QEMedgeInfo" ; }
	} QEMedgeInfo ;
183
	typedef NoTypeNameAttribute<QEMedgeInfo> EdgeInfo ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
184

185 186
	EdgeAttribute<EdgeInfo, MAP> edgeInfo ;
	VertexAttribute<Utils::Quadric<REAL>, MAP> quadric ;
187
	Utils::Quadric<REAL> tmpQ ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
188 189 190 191 192 193 194 195 196

	std::multimap<float,Dart> edges ;
	typename std::multimap<float,Dart>::iterator cur ;

	void initEdgeInfo(Dart d) ;
	void updateEdgeInfo(Dart d, bool recompute) ;
	void computeEdgeInfo(Dart d, EdgeInfo& einfo) ;

public:
197 198 199 200
	EdgeSelector_QEM(MAP& m, const VertexAttribute<VEC3, MAP>& pos, Approximator<PFP, VEC3, EDGE>& posApprox) :
		Selector<PFP>(m),
		m_position(pos),
		m_positionApproximator(posApprox)
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
201
	{
Sylvain Thery's avatar
Sylvain Thery committed
202
		edgeInfo = m.template addAttribute<EdgeInfo, EDGE, MAP>("edgeInfo") ;
203
		std::string attrName = m_position.name();
Pierre Kraemer's avatar
Pierre Kraemer committed
204
		attrName += "_QEM";
205
		quadric = m.template addAttribute<Utils::Quadric<REAL>, VERTEX, MAP>(attrName) ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
206 207 208 209
	}
	~EdgeSelector_QEM()
	{
		this->m_map.removeAttribute(edgeInfo) ;
210
		this->m_map.removeAttribute(quadric) ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
211 212 213
	}
	SelectorType getType() { return S_QEM ; }
	bool init() ;
214
	bool nextEdge(Dart& d) const ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
215 216
	void updateBeforeCollapse(Dart d) ;
	void updateAfterCollapse(Dart d2, Dart dd2) ;
untereiner's avatar
untereiner committed
217

218
	void updateWithoutCollapse();
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
219 220 221
} ;

template <typename PFP>
222
class EdgeSelector_QEMml : public Selector<PFP>
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
223 224 225 226 227 228 229
{
public:
	typedef typename PFP::MAP MAP ;
	typedef typename PFP::VEC3 VEC3 ;
	typedef typename PFP::REAL REAL ;

private:
230 231 232
	const VertexAttribute<VEC3, MAP>& m_position ;
	Approximator<PFP, VEC3, EDGE>& m_positionApproximator ;

Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
233 234 235 236 237 238
	typedef	struct
	{
		typename std::multimap<float,Dart>::iterator it ;
		bool valid ;
		static std::string CGoGNnameOfType() { return "QEMedgeInfo" ; }
	} QEMedgeInfo ;
239
	typedef NoTypeNameAttribute<QEMedgeInfo> EdgeInfo ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
240

241 242
	EdgeAttribute<EdgeInfo, MAP> edgeInfo ;
	VertexAttribute<Utils::Quadric<REAL>, MAP> quadric ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
243 244 245 246 247 248 249 250 251 252

	std::multimap<float,Dart> edges ;
	typename std::multimap<float,Dart>::iterator cur ;

	void initEdgeInfo(Dart d) ;
	void updateEdgeInfo(Dart d, bool recompute) ;
	void computeEdgeInfo(Dart d, EdgeInfo& einfo) ;
	void recomputeQuadric(const Dart d, const bool recomputeNeighbors = false) ;

public:
253 254 255 256
	EdgeSelector_QEMml(MAP& m, VertexAttribute<VEC3, MAP>& pos, Approximator<PFP, VEC3, EDGE>& posApprox) :
		Selector<PFP>(m),
		m_position(pos),
		m_positionApproximator(posApprox)
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
257
	{
Sylvain Thery's avatar
Sylvain Thery committed
258
		edgeInfo = m.template addAttribute<EdgeInfo, EDGE, MAP>("edgeInfo") ;
259
		std::string attrName = m_position.name();
Pierre Kraemer's avatar
Pierre Kraemer committed
260
		attrName += "_QEM";
261
		quadric = m.template addAttribute<Utils::Quadric<REAL>, VERTEX, MAP>(attrName) ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
262 263 264 265
	}
	~EdgeSelector_QEMml()
	{
		this->m_map.removeAttribute(edgeInfo) ;
266
		this->m_map.removeAttribute(quadric) ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
267 268 269
	}
	SelectorType getType() { return S_QEMml ; }
	bool init() ;
270
	bool nextEdge(Dart& d) const ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
271 272
	void updateBeforeCollapse(Dart d) ;
	void updateAfterCollapse(Dart d2, Dart dd2) ;
untereiner's avatar
untereiner committed
273

274
	void updateWithoutCollapse();
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
275 276
} ;

277
template <typename PFP>
278
class EdgeSelector_NormalArea : public Selector<PFP>
279 280 281 282 283 284 285
{
public:
	typedef typename PFP::MAP MAP ;
	typedef typename PFP::VEC3 VEC3 ;
	typedef typename PFP::REAL REAL ;

private:
286 287 288
	const VertexAttribute<VEC3, MAP>& m_position ;
	Approximator<PFP, VEC3, EDGE>& m_positionApproximator ;

289 290 291 292 293 294
	typedef	struct
	{
		typename std::multimap<float,Dart>::iterator it ;
		bool valid ;
		static std::string CGoGNnameOfType() { return "NormalAreaEdgeInfo" ; }
	} NormalAreaEdgeInfo ;
295
	typedef NoTypeNameAttribute<NormalAreaEdgeInfo> EdgeInfo ;
296

297 298
	EdgeAttribute<EdgeInfo, MAP> edgeInfo ;
	EdgeAttribute<Geom::Matrix<3,3,REAL>, MAP> edgeMatrix ;
299 300 301 302 303 304 305

	std::multimap<float,Dart> edges ;
	typename std::multimap<float,Dart>::iterator cur ;

	void initEdgeInfo(Dart d) ;
	void updateEdgeInfo(Dart d) ;
	void computeEdgeInfo(Dart d, EdgeInfo& einfo) ;
306
	void computeEdgeMatrix(Dart d) ;
307 308

public:
309 310 311 312
	EdgeSelector_NormalArea(MAP& m, VertexAttribute<VEC3, MAP>& pos, Approximator<PFP, VEC3, EDGE>& posApprox) :
		Selector<PFP>(m),
		m_position(pos),
		m_positionApproximator(posApprox)
313
	{
Sylvain Thery's avatar
Sylvain Thery committed
314 315
		edgeInfo = m.template addAttribute<EdgeInfo, EDGE, MAP>("edgeInfo") ;
		edgeMatrix = m.template addAttribute<Geom::Matrix<3,3,REAL>, EDGE, MAP>("NormalAreaMatrix") ;
316 317 318 319
	}
	~EdgeSelector_NormalArea()
	{
		this->m_map.removeAttribute(edgeInfo) ;
320
		this->m_map.removeAttribute(edgeMatrix) ;
321 322 323
	}
	SelectorType getType() { return S_NormalArea ; }
	bool init() ;
324
	bool nextEdge(Dart& d) const ;
325 326 327 328 329 330
	void updateBeforeCollapse(Dart d) ;
	void updateAfterCollapse(Dart d2, Dart dd2) ;

	void updateWithoutCollapse() { }
} ;

Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
331
template <typename PFP>
332
class EdgeSelector_Curvature : public Selector<PFP>
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
333 334 335 336 337 338 339
{
public:
	typedef typename PFP::MAP MAP ;
	typedef typename PFP::VEC3 VEC3 ;
	typedef typename PFP::REAL REAL ;

private:
340 341 342
	VertexAttribute<VEC3, MAP>& m_position ;
	Approximator<PFP, VEC3, EDGE>& m_positionApproximator ;

Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
343 344 345 346 347 348
	typedef	struct
	{
		typename std::multimap<float,Dart>::iterator it ;
		bool valid ;
		static std::string CGoGNnameOfType() { return "CurvatureEdgeInfo" ; }
	} CurvatureEdgeInfo ;
349
	typedef NoTypeNameAttribute<CurvatureEdgeInfo> EdgeInfo ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
350

351 352 353
	Geom::BoundingBox<VEC3> bb ;
	REAL radius ;

354 355 356
	VertexAttribute<VEC3, MAP> normal ;
	EdgeAttribute<EdgeInfo, MAP> edgeInfo ;
	EdgeAttribute<REAL, MAP> edgeangle ;
357
	EdgeAttribute<REAL, MAP> edgearea ;
358 359 360 361 362
	VertexAttribute<REAL, MAP> kmax ;
	VertexAttribute<REAL, MAP> kmin ;
	VertexAttribute<VEC3, MAP> Kmax ;
	VertexAttribute<VEC3, MAP> Kmin ;
	VertexAttribute<VEC3, MAP> Knormal ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
363 364 365 366 367 368 369 370 371

	std::multimap<float,Dart> edges ;
	typename std::multimap<float,Dart>::iterator cur ;

	void initEdgeInfo(Dart d) ;
	void updateEdgeInfo(Dart d, bool recompute) ;
	void computeEdgeInfo(Dart d, EdgeInfo& einfo) ;

public:
372 373 374 375
	EdgeSelector_Curvature(MAP& m, VertexAttribute<VEC3, MAP>& pos, Approximator<PFP, VEC3, EDGE>& posApprox) :
		Selector<PFP>(m),
		m_position(pos),
		m_positionApproximator(posApprox)
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
376
	{
377 378 379
		bb = Algo::Geometry::computeBoundingBox<PFP>(m, pos) ;
		radius = bb.diagSize() * 0.003 ;

Sylvain Thery's avatar
Sylvain Thery committed
380
		normal = m.template getAttribute<VEC3, VERTEX, MAP>("normal") ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
381 382
		if(!normal.isValid())
		{
Sylvain Thery's avatar
Sylvain Thery committed
383
			normal = m.template addAttribute<VEC3, VERTEX, MAP>("normal") ;
384
			Algo::Surface::Geometry::computeNormalVertices<PFP>(m, pos, normal) ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
385 386
		}

Sylvain Thery's avatar
Sylvain Thery committed
387
		edgeangle = m.template getAttribute<REAL, EDGE, MAP>("edgeangle") ;
388 389
		if(!edgeangle.isValid())
		{
Sylvain Thery's avatar
Sylvain Thery committed
390
			edgeangle = m.template addAttribute<REAL, EDGE, MAP>("edgeangle") ;
391
			Algo::Surface::Geometry::computeAnglesBetweenNormalsOnEdges<PFP>(m, pos, edgeangle) ;
392 393
		}

394 395 396 397 398 399 400
		edgearea = m.template getAttribute<REAL, EDGE, MAP>("edgearea") ;
		if(!edgearea.isValid())
		{
			edgearea = m.template addAttribute<REAL, EDGE, MAP>("edgearea") ;
			Algo::Surface::Geometry::computeAreaEdges<PFP>(m, pos, edgearea) ;
		}

Sylvain Thery's avatar
Sylvain Thery committed
401 402 403 404 405
		kmax = m.template getAttribute<REAL, VERTEX, MAP>("kmax") ;
		kmin = m.template getAttribute<REAL, VERTEX, MAP>("kmin") ;
		Kmax = m.template getAttribute<VEC3, VERTEX, MAP>("Kmax") ;
		Kmin = m.template getAttribute<VEC3, VERTEX, MAP>("Kmin") ;
		Knormal = m.template getAttribute<VEC3, VERTEX, MAP>("Knormal") ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
406 407
		// as all these attributes are computed simultaneously by computeCurvatureVertices
		// one can assume that if one of them is not valid, the others must be created too
408
		if(!kmax.isValid())
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
409
		{
Sylvain Thery's avatar
Sylvain Thery committed
410 411 412 413 414
			kmax = m.template addAttribute<REAL, VERTEX, MAP>("kmax") ;
			kmin = m.template addAttribute<REAL, VERTEX, MAP>("kmin") ;
			Kmax = m.template addAttribute<VEC3, VERTEX, MAP>("Kmax") ;
			Kmin = m.template addAttribute<VEC3, VERTEX, MAP>("Kmin") ;
			Knormal = m.template addAttribute<VEC3, VERTEX, MAP>("Knormal") ;
415
			Algo::Surface::Geometry::computeCurvatureVertices_NormalCycles<PFP>(m, radius, pos, normal, edgeangle, edgearea, kmax, kmin, Kmax, Kmin, Knormal) ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
416 417
		}

Sylvain Thery's avatar
Sylvain Thery committed
418
		edgeInfo = m.template addAttribute<EdgeInfo, EDGE, MAP>("edgeInfo") ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
419 420 421
	}
	~EdgeSelector_Curvature()
	{
422
//		this->m_map.removeAttribute(edgeangle) ;
423
//		this->m_map.removeAttribute(edgearea) ;
424 425 426 427 428
//		this->m_map.removeAttribute(kmax) ;
//		this->m_map.removeAttribute(kmin) ;
//		this->m_map.removeAttribute(Kmax) ;
//		this->m_map.removeAttribute(Kmin) ;
//		this->m_map.removeAttribute(Knormal) ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
429 430 431 432
		this->m_map.removeAttribute(edgeInfo) ;
	}
	SelectorType getType() { return S_Curvature ; }
	bool init() ;
433
	bool nextEdge(Dart& d) const ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
434 435
	void updateBeforeCollapse(Dart d) ;
	void updateAfterCollapse(Dart d2, Dart dd2) ;
untereiner's avatar
untereiner committed
436

437
	void updateWithoutCollapse();
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
438 439
} ;

440 441

template <typename PFP>
442
class EdgeSelector_CurvatureTensor : public Selector<PFP>
443
{
Sauvage's avatar
Sauvage committed
444
	// TODO : this selector still needs to be tested
445 446 447 448 449 450
public:
	typedef typename PFP::MAP MAP ;
	typedef typename PFP::VEC3 VEC3 ;
	typedef typename PFP::REAL REAL ;

private:
451 452 453
	VertexAttribute<VEC3, MAP>& m_position ;
	Approximator<PFP, VEC3, EDGE>& m_positionApproximator ;

454 455 456 457 458 459
	typedef	struct
	{
		typename std::multimap<float,Dart>::iterator it ;
		bool valid ;
		static std::string CGoGNnameOfType() { return "CurvatureTensorEdgeInfo" ; }
	} CurvatureTensorEdgeInfo ;
460
	typedef NoTypeNameAttribute<CurvatureTensorEdgeInfo> EdgeInfo ;
461

462 463
	EdgeAttribute<EdgeInfo, MAP> edgeInfo ;
	EdgeAttribute<REAL, MAP> edgeangle ;
464
	EdgeAttribute<REAL, MAP> edgearea ;
465 466 467 468 469

	std::multimap<float,Dart> edges ;
	typename std::multimap<float,Dart>::iterator cur ;

	void initEdgeInfo(Dart d) ;
470
	void updateEdgeInfo(Dart d) ; // TODO : usually has a 2nd arg (, bool recompute) : why ??
471 472 473
	void computeEdgeInfo(Dart d, EdgeInfo& einfo) ;

public:
474 475 476 477
	EdgeSelector_CurvatureTensor(MAP& m, VertexAttribute<VEC3, MAP>& pos, Approximator<PFP, VEC3, EDGE>& posApprox) :
		Selector<PFP>(m),
		m_position(pos),
		m_positionApproximator(posApprox)
478
	{
Sylvain Thery's avatar
Sylvain Thery committed
479
		edgeangle = m.template getAttribute<REAL, EDGE, MAP>("edgeangle") ;
480 481
		if(!edgeangle.isValid())
		{
Sylvain Thery's avatar
Sylvain Thery committed
482
			edgeangle = m.template addAttribute<REAL, EDGE, MAP>("edgeangle") ;
483
			Algo::Surface::Geometry::computeAnglesBetweenNormalsOnEdges<PFP>(m, pos, edgeangle) ;
484 485
		}

486 487 488 489 490 491 492
		edgearea = m.template getAttribute<REAL, EDGE, MAP>("edgearea") ;
		if(!edgearea.isValid())
		{
			edgearea = m.template addAttribute<REAL, EDGE, MAP>("edgearea") ;
			Algo::Surface::Geometry::computeAreaEdges<PFP>(m, pos, edgearea) ;
		}

Sylvain Thery's avatar
Sylvain Thery committed
493
		edgeInfo = m.template addAttribute<EdgeInfo, EDGE, MAP>("edgeInfo") ;
494 495 496
	}
	~EdgeSelector_CurvatureTensor()
	{
497
//		this->m_map.removeAttribute(edgeangle) ;
498
//		this->m_map.removeAttribute(edgearea) ;
499 500 501 502
		this->m_map.removeAttribute(edgeInfo) ;
	}
	SelectorType getType() { return S_CurvatureTensor ; }
	bool init() ;
503
	bool nextEdge(Dart& d) const ;
504 505 506 507 508 509
	void updateBeforeCollapse(Dart d) ;
	void updateAfterCollapse(Dart d2, Dart dd2) ;

	void updateWithoutCollapse() {};
} ;

Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
510
template <typename PFP>
511
class EdgeSelector_MinDetail : public Selector<PFP>
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
512 513 514 515 516 517 518
{
public:
	typedef typename PFP::MAP MAP ;
	typedef typename PFP::VEC3 VEC3 ;
	typedef typename PFP::REAL REAL ;

private:
519 520 521
	const VertexAttribute<VEC3, MAP>& m_position ;
	Approximator<PFP, VEC3, EDGE>& m_positionApproximator ;

Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
522 523 524 525 526 527
	typedef	struct
	{
		typename std::multimap<float,Dart>::iterator it ;
		bool valid ;
		static std::string CGoGNnameOfType() { return "MinDetailEdgeInfo" ; }
	} MinDetailEdgeInfo ;
528
	typedef NoTypeNameAttribute<MinDetailEdgeInfo> EdgeInfo ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
529

530
	EdgeAttribute<EdgeInfo, MAP> edgeInfo ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
531 532 533 534 535 536 537 538 539

	std::multimap<float,Dart> edges ;
	typename std::multimap<float,Dart>::iterator cur ;

	void initEdgeInfo(Dart d) ;
	void updateEdgeInfo(Dart d, bool recompute) ;
	void computeEdgeInfo(Dart d, EdgeInfo& einfo) ;

public:
540 541 542 543
	EdgeSelector_MinDetail(MAP& m, VertexAttribute<VEC3, MAP>& pos, Approximator<PFP, VEC3, EDGE>& posApprox) :
		Selector<PFP>(m),
		m_position(pos),
		m_positionApproximator(posApprox)
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
544
	{
Sylvain Thery's avatar
Sylvain Thery committed
545
		edgeInfo = m.template addAttribute<EdgeInfo, EDGE, MAP>("edgeInfo") ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
546 547 548 549 550 551 552
	}
	~EdgeSelector_MinDetail()
	{
		this->m_map.removeAttribute(edgeInfo) ;
	}
	SelectorType getType() { return S_MinDetail ; }
	bool init() ;
553
	bool nextEdge(Dart& d) const ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
554 555
	void updateBeforeCollapse(Dart d) ;
	void updateAfterCollapse(Dart d2, Dart dd2) ;
untereiner's avatar
untereiner committed
556

557
	void updateWithoutCollapse();
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
558 559
} ;

560
/*****************************************************************************************************************
561
 *                                      EDGE NAIVE COLOR METRIC (using QEMml)                                    *
562
 *****************************************************************************************************************/
Pierre Kraemer's avatar
Pierre Kraemer committed
563

564
template <typename PFP>
565
class EdgeSelector_ColorNaive : public Selector<PFP>
566 567 568 569 570 571 572
{
public:
	typedef typename PFP::MAP MAP ;
	typedef typename PFP::VEC3 VEC3 ;
	typedef typename PFP::REAL REAL ;

private:
573 574 575 576 577
	const VertexAttribute<VEC3, MAP>& m_position ;
	const VertexAttribute<VEC3, MAP>& m_color ;
	Approximator<PFP, VEC3, EDGE>& m_positionApproximator;
	Approximator<PFP, VEC3, EDGE>& m_colorApproximator;

578 579 580 581 582 583
	typedef	struct
	{
		typename std::multimap<float,Dart>::iterator it ;
		bool valid ;
		static std::string CGoGNnameOfType() { return "ColorNaiveEdgeInfo" ; }
	} ColorNaiveedgeInfo ;
584
	typedef NoTypeNameAttribute<ColorNaiveedgeInfo> EdgeInfo ;
585

586 587
	EdgeAttribute<EdgeInfo, MAP> edgeInfo ;
	VertexAttribute<Utils::Quadric<REAL>, MAP> m_quadric ;
588 589 590 591 592 593 594 595 596 597

	std::multimap<float,Dart> edges ;
	typename std::multimap<float,Dart>::iterator cur ;

	void initEdgeInfo(Dart d) ;
	void updateEdgeInfo(Dart d, bool recompute) ;
	void computeEdgeInfo(Dart d,EdgeInfo& einfo) ;
	void recomputeQuadric(const Dart d, const bool recomputeNeighbors = false) ;

public:
598 599 600 601 602 603 604 605 606 607 608 609
	EdgeSelector_ColorNaive(
		MAP& m,
		VertexAttribute<VEC3, MAP>& pos,
		VertexAttribute<VEC3, MAP>& col,
		Approximator<PFP, VEC3, EDGE>& posApprox,
		Approximator<PFP, VEC3, EDGE>& colApprox
	) :
		Selector<PFP>(m),
		m_position(pos),
		m_color(col),
		m_positionApproximator(posApprox),
		m_colorApproximator(colApprox)
610
	{
Sylvain Thery's avatar
Sylvain Thery committed
611 612
		edgeInfo = m.template addAttribute<EdgeInfo, EDGE, MAP>("edgeInfo") ;
		m_quadric = m.template addAttribute<Utils::Quadric<REAL>, VERTEX, MAP>("QEMquadric") ;
613 614 615 616 617 618 619 620
	}
	~EdgeSelector_ColorNaive()
	{
		this->m_map.removeAttribute(edgeInfo) ;
		this->m_map.removeAttribute(m_quadric) ;
	}
	SelectorType getType() { return S_ColorNaive ; }
	bool init() ;
621
	bool nextEdge(Dart& d) const ;
622 623
	void updateBeforeCollapse(Dart d) ;
	void updateAfterCollapse(Dart d2, Dart dd2) ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
624 625

	void updateWithoutCollapse() { }
626 627
} ;

628 629 630
/*****************************************************************************************************************
 *                                  EDGE GEOMETRY+COLOR METRIC (using QEMml and Gradient norm)                   *
 *****************************************************************************************************************/
Pierre Kraemer's avatar
Pierre Kraemer committed
631

632
template <typename PFP>
633
class EdgeSelector_GeomColOptGradient : public Selector<PFP>
634 635 636 637 638 639 640
{
public:
	typedef typename PFP::MAP MAP ;
	typedef typename PFP::VEC3 VEC3 ;
	typedef typename PFP::REAL REAL ;

private:
641 642 643 644 645
	const VertexAttribute<VEC3, MAP>& m_position ;
	const VertexAttribute<VEC3, MAP>& m_color ;
	Approximator<PFP, VEC3, EDGE>& m_positionApproximator;
	Approximator<PFP, VEC3, EDGE>& m_colorApproximator;

646 647 648 649 650 651
	typedef	struct
	{
		typename std::multimap<float,Dart>::iterator it ;
		bool valid ;
		static std::string CGoGNnameOfType() { return "GeomColOptGradEdgeInfo" ; }
	} ColorNaiveedgeInfo ;
652
	typedef NoTypeNameAttribute<ColorNaiveedgeInfo> EdgeInfo ;
653

654 655
	EdgeAttribute<EdgeInfo, MAP> edgeInfo ;
	VertexAttribute<Utils::Quadric<REAL>, MAP> m_quadric ;
656 657 658 659 660 661 662 663

	std::multimap<float,Dart> edges ;
	typename std::multimap<float,Dart>::iterator cur ;

	void initEdgeInfo(Dart d) ;
	void updateEdgeInfo(Dart d) ;
	void computeEdgeInfo(Dart d,EdgeInfo& einfo) ;
	void recomputeQuadric(const Dart d, const bool recomputeNeighbors = false) ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
664
	VEC3 computeEdgeGradientColorError(const Dart& v0, const VEC3& p, const VEC3& c) ;
665 666

public:
667 668 669 670 671 672 673 674 675 676 677 678
	EdgeSelector_GeomColOptGradient(
			MAP& m,
			VertexAttribute<VEC3, MAP>& pos,
			VertexAttribute<VEC3, MAP>& col,
			Approximator<PFP, VEC3, EDGE>& posApprox,
			Approximator<PFP, VEC3, EDGE>& colApprox
		) :
			Selector<PFP>(m),
			m_position(pos),
			m_color(col),
			m_positionApproximator(posApprox),
			m_colorApproximator(colApprox)
679
	{
Sylvain Thery's avatar
Sylvain Thery committed
680
		edgeInfo = m.template addAttribute<EdgeInfo, EDGE, MAP>("edgeInfo") ;
681
		std::string attrName = m_position.name();
Pierre Kraemer's avatar
Pierre Kraemer committed
682
		attrName += "_QEM";
683
		m_quadric = m.template addAttribute<Utils::Quadric<REAL>, VERTEX, MAP>(attrName) ;
684 685 686 687 688 689 690 691
	}
	~EdgeSelector_GeomColOptGradient()
	{
		this->m_map.removeAttribute(edgeInfo) ;
		this->m_map.removeAttribute(m_quadric) ;
	}
	SelectorType getType() { return S_GeomColOptGrad ; }
	bool init() ;
692
	bool nextEdge(Dart& d) const ;
693 694 695 696 697
	void updateBeforeCollapse(Dart d) ;
	void updateAfterCollapse(Dart d2, Dart dd2) ;

	void updateWithoutCollapse() { }

698
	void getEdgeErrors(EdgeAttribute<REAL, MAP> *errors) const
699 700 701 702 703 704
	{
		assert(errors != NULL || !"EdgeSelector::setColorMap requires non null vertexattribute argument") ;
		if (!errors->isValid())
			std::cerr << "EdgeSelector::setColorMap requires valid edgeattribute argument" << std::endl ;
		assert(edgeInfo.isValid()) ;

Pierre Kraemer's avatar
Pierre Kraemer committed
705
		TraversorE<MAP> travE(this->m_map) ;
706 707 708 709 710 711 712 713 714 715 716
		for(Dart d = travE.begin() ; d != travE.end() ; d = travE.next())
		{
			(*errors)[d] = -1 ;
			if (edgeInfo[d].valid)
			{
				(*errors)[d] = edgeInfo[d].it->first ;
			}
		}
	}
} ;

717 718 719
/*****************************************************************************************************************
 *                                 QEM extended to color metric                                                  *
 *****************************************************************************************************************/
Pierre Kraemer's avatar
Pierre Kraemer committed
720

721
template <typename PFP>
722
class EdgeSelector_QEMextColor : public Selector<PFP>
723 724 725 726 727 728 729 730
{
public:
	typedef typename PFP::MAP MAP ;
	typedef typename PFP::REAL REAL ;
	typedef typename PFP::VEC3 VEC3 ;
	typedef typename Geom::Vector<6,REAL> VEC6 ;

private:
731 732 733 734 735
	const VertexAttribute<VEC3, MAP>& m_position ;
	const VertexAttribute<VEC3, MAP>& m_color ;
	Approximator<PFP, VEC3, EDGE>& m_positionApproximator;
	Approximator<PFP, VEC3, EDGE>& m_colorApproximator;

736 737 738 739 740 741
	typedef	struct
	{
		typename std::multimap<float,Dart>::iterator it ;
		bool valid ;
		static std::string CGoGNnameOfType() { return "QEMextColorEdgeInfo" ; }
	} QEMextColorEdgeInfo ;
742
	typedef NoTypeNameAttribute<QEMextColorEdgeInfo> EdgeInfo ;
743

744 745
	EdgeAttribute<EdgeInfo, MAP> edgeInfo ;
	VertexAttribute<Utils::QuadricNd<REAL,6>, MAP> m_quadric ;
746 747 748 749 750 751

	std::multimap<float,Dart> edges ;
	typename std::multimap<float,Dart>::iterator cur ;

	void initEdgeInfo(Dart d) ;
	void updateEdgeInfo(Dart d, bool recompute) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
752
	void computeEdgeInfo(Dart d, EdgeInfo& einfo) ;
753 754 755
	void recomputeQuadric(const Dart d, const bool recomputeNeighbors = false) ;

public:
756 757 758 759 760 761 762 763 764 765 766 767
	EdgeSelector_QEMextColor(
			MAP& m,
			VertexAttribute<VEC3, MAP>& pos,
			VertexAttribute<VEC3, MAP>& col,
			Approximator<PFP, VEC3, EDGE>& posApprox,
			Approximator<PFP, VEC3, EDGE>& colApprox
		) :
			Selector<PFP>(m),
			m_position(pos),
			m_color(col),
			m_positionApproximator(posApprox),
			m_colorApproximator(colApprox)
768
	{
Sylvain Thery's avatar
Sylvain Thery committed
769 770
		edgeInfo = m.template addAttribute<EdgeInfo, EDGE, MAP>("edgeInfo") ;
		m_quadric = m.template addAttribute<Utils::QuadricNd<REAL,6>, VERTEX, MAP>("QEMext-quadric") ;
771 772 773 774 775 776 777 778
	}
	~EdgeSelector_QEMextColor()
	{
		this->m_map.removeAttribute(edgeInfo) ;
		this->m_map.removeAttribute(m_quadric) ;
	}
	SelectorType getType() { return S_QEMextColor ; }
	bool init() ;
779
	bool nextEdge(Dart& d) const ;
780 781
	void updateBeforeCollapse(Dart d) ;
	void updateAfterCollapse(Dart d2, Dart dd2) ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
782 783

	void updateWithoutCollapse() { }
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
784

785
	void getEdgeErrors(EdgeAttribute<REAL, MAP> *errors) const
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
786 787 788 789 790 791
	{
		assert(errors != NULL || !"EdgeSelector::setColorMap requires non null vertexattribute argument") ;
		if (!errors->isValid())
			std::cerr << "EdgeSelector::setColorMap requires valid edgeattribute argument" << std::endl ;
		assert(edgeInfo.isValid()) ;

Pierre Kraemer's avatar
Pierre Kraemer committed
792
		TraversorE<MAP> travE(this->m_map) ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
793 794 795 796 797 798 799 800 801
		for(Dart d = travE.begin() ; d != travE.end() ; d = travE.next())
		{
			(*errors)[d] = -1 ;
			if (edgeInfo[d].valid)
			{
				(*errors)[d] = edgeInfo[d].it->first ;
			}
		}
	}
802
} ;
803

Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
804 805
} // namespace Decimation

806
} // namespace Surface
807

Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
808 809 810 811 812 813 814
} // namespace Algo

} // namespace CGoGN

#include "Algo/Decimation/edgeSelector.hpp"

#endif