edgeSelector.h 23.7 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 54 55 56 57 58 59 60
{
public:
	typedef typename PFP::MAP MAP ;
	typedef typename PFP::VEC3 VEC3 ;
	typedef typename PFP::REAL REAL ;

private:
	Dart cur ;

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

Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
73 74 75
} ;

template <typename PFP>
76
class EdgeSelector_Random : public Selector<PFP>
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
77 78 79 80 81 82 83 84 85 86 87 88
{
public:
	typedef typename PFP::MAP MAP ;
	typedef typename PFP::VEC3 VEC3 ;
	typedef typename PFP::REAL REAL ;

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

public:
89
	EdgeSelector_Random(MAP& m, VertexAttribute<typename PFP::VEC3>& pos, std::vector<ApproximatorGen<PFP>*>& approx) :
90
		Selector<PFP>(m, pos, approx),
91 92
		cur(0),
		allSkipped(false)
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
93 94 95 96 97
	{}
	~EdgeSelector_Random()
	{}
	SelectorType getType() { return S_Random ; }
	bool init() ;
98
	bool nextEdge(Dart& d) const ;
Sylvain Thery's avatar
Sylvain Thery committed
99
	void updateBeforeCollapse(Dart /*d2*/) {}
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
100
	void updateAfterCollapse(Dart d2, Dart dd2) ;
101
	void updateWithoutCollapse();
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
102 103 104
} ;

template <typename PFP>
105
class EdgeSelector_Length : public Selector<PFP>
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
106 107 108 109 110 111 112 113 114 115 116 117 118
{
public:
	typedef typename PFP::MAP MAP ;
	typedef typename PFP::VEC3 VEC3 ;
	typedef typename PFP::REAL REAL ;

private:
	typedef struct
	{
		typename std::multimap<float,Dart>::iterator it ;
		bool valid ;
		static std::string CGoGNnameOfType() { return "LengthEdgeInfo" ; }
	} LengthEdgeInfo ;
119
	typedef NoTypeNameAttribute<LengthEdgeInfo> EdgeInfo ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
120

121
	EdgeAttribute<EdgeInfo> edgeInfo ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
122 123 124 125 126 127 128 129 130

	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:
131
	EdgeSelector_Length(MAP& m, VertexAttribute<typename PFP::VEC3>& pos, std::vector<ApproximatorGen<PFP>*>& approx) :
132
		Selector<PFP>(m, pos, approx)
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
133
	{
134
		edgeInfo = m.template addAttribute<EdgeInfo, EDGE>("edgeInfo") ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
135 136 137 138 139 140 141
	}
	~EdgeSelector_Length()
	{
		this->m_map.removeAttribute(edgeInfo) ;
	}
	SelectorType getType() { return S_EdgeLength ; }
	bool init() ;
142
	bool nextEdge(Dart& d) const ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
143 144
	void updateBeforeCollapse(Dart d) ;
	void updateAfterCollapse(Dart d2, Dart dd2) ;
untereiner's avatar
untereiner committed
145

146
	void updateWithoutCollapse();
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
147

148
	void getEdgeErrors(EdgeAttribute<typename PFP::REAL> *errors) const
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
	{
		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()) ;

		TraversorE<typename PFP::MAP> travE(this->m_map) ;
		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
165 166 167
} ;

template <typename PFP>
168
class EdgeSelector_QEM : public Selector<PFP>
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
169 170 171 172 173 174 175 176 177 178 179 180 181
{
public:
	typedef typename PFP::MAP MAP ;
	typedef typename PFP::VEC3 VEC3 ;
	typedef typename PFP::REAL REAL ;

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

184
	EdgeAttribute<EdgeInfo> edgeInfo ;
185 186
	VertexAttribute<Utils::Quadric<REAL> > quadric ;
	Utils::Quadric<REAL> tmpQ ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
187 188 189 190

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

191
	Approximator<PFP, typename PFP::VEC3, EDGE>* m_positionApproximator ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
192 193 194 195 196 197

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

public:
198
	EdgeSelector_QEM(MAP& m, VertexAttribute<typename PFP::VEC3>& pos, std::vector<ApproximatorGen<PFP>*>& approx) :
199
		Selector<PFP>(m, pos, approx),
200
		m_positionApproximator(NULL)
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
201
	{
202
		edgeInfo = m.template addAttribute<EdgeInfo, EDGE>("edgeInfo") ;
203
		quadric = m.template addAttribute<Utils::Quadric<REAL>, VERTEX>("QEMquadric") ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
204 205 206 207 208 209 210 211
	}
	~EdgeSelector_QEM()
	{
		this->m_map.removeAttribute(quadric) ;
		this->m_map.removeAttribute(edgeInfo) ;
	}
	SelectorType getType() { return S_QEM ; }
	bool init() ;
212
	bool nextEdge(Dart& d) const ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
213 214
	void updateBeforeCollapse(Dart d) ;
	void updateAfterCollapse(Dart d2, Dart dd2) ;
untereiner's avatar
untereiner committed
215

216
	void updateWithoutCollapse();
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
217 218 219
} ;

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

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

236
	EdgeAttribute<EdgeInfo> edgeInfo ;
237
	VertexAttribute<Utils::Quadric<REAL> > quadric ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
238 239 240 241

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

242
	Approximator<PFP, typename PFP::VEC3, EDGE>* m_positionApproximator ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
243 244 245 246 247 248 249

	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:
250
	EdgeSelector_QEMml(MAP& m, VertexAttribute<typename PFP::VEC3>& pos, std::vector<ApproximatorGen<PFP>*>& approx) :
251
		Selector<PFP>(m, pos, approx),
252
		m_positionApproximator(NULL)
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
253
	{
254
		edgeInfo = m.template addAttribute<EdgeInfo, EDGE>("edgeInfo") ;
255
		quadric = m.template addAttribute<Utils::Quadric<REAL>, VERTEX>("QEMquadric") ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
256 257 258 259 260 261 262 263
	}
	~EdgeSelector_QEMml()
	{
		this->m_map.removeAttribute(quadric) ;
		this->m_map.removeAttribute(edgeInfo) ;
	}
	SelectorType getType() { return S_QEMml ; }
	bool init() ;
264
	bool nextEdge(Dart& d) const ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
265 266
	void updateBeforeCollapse(Dart d) ;
	void updateAfterCollapse(Dart d2, Dart dd2) ;
untereiner's avatar
untereiner committed
267

268
	void updateWithoutCollapse();
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
269 270
} ;

271 272

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

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

	EdgeAttribute<EdgeInfo> edgeInfo ;
	EdgeAttribute<Geom::Matrix<3,3,REAL> > edgeMatrix ;

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

	Approximator<PFP, typename PFP::VEC3, EDGE>* m_positionApproximator ;

	void initEdgeInfo(Dart d) ;
	void updateEdgeInfo(Dart d) ;
	void computeEdgeInfo(Dart d, EdgeInfo& einfo) ;
300
	void computeEdgeMatrix(Dart d) ;
301 302 303
//	void recomputeQuadric(const Dart d, const bool recomputeNeighbors = false) ;

public:
304
	EdgeSelector_NormalArea(MAP& m, VertexAttribute<typename PFP::VEC3>& pos, std::vector<ApproximatorGen<PFP>*>& approx) :
305
		Selector<PFP>(m, pos, approx),
306 307 308 309 310 311 312 313 314 315 316 317
		m_positionApproximator(NULL)
	{
		edgeInfo = m.template addAttribute<EdgeInfo, EDGE>("edgeInfo") ;
		edgeMatrix = m.template addAttribute<Geom::Matrix<3,3,REAL>, EDGE>("NormalAreaMatrix") ;
	}
	~EdgeSelector_NormalArea()
	{
		this->m_map.removeAttribute(edgeMatrix) ;
		this->m_map.removeAttribute(edgeInfo) ;
	}
	SelectorType getType() { return S_NormalArea ; }
	bool init() ;
318
	bool nextEdge(Dart& d) const ;
319 320 321 322 323 324 325
	void updateBeforeCollapse(Dart d) ;
	void updateAfterCollapse(Dart d2, Dart dd2) ;

	void updateWithoutCollapse() { }
} ;


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

private:
	typedef	struct
	{
		typename std::multimap<float,Dart>::iterator it ;
		bool valid ;
		static std::string CGoGNnameOfType() { return "CurvatureEdgeInfo" ; }
	} CurvatureEdgeInfo ;
341
	typedef NoTypeNameAttribute<CurvatureEdgeInfo> EdgeInfo ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
342

343 344 345
	Geom::BoundingBox<VEC3> bb ;
	REAL radius ;

346
	VertexAttribute<VEC3> normal ;
347
	EdgeAttribute<EdgeInfo> edgeInfo ;
348 349 350 351 352 353
	EdgeAttribute<REAL> edgeangle ;
	VertexAttribute<REAL> kmax ;
	VertexAttribute<REAL> kmin ;
	VertexAttribute<VEC3> Kmax ;
	VertexAttribute<VEC3> Kmin ;
	VertexAttribute<VEC3> Knormal ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
354 355 356 357

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

358
	Approximator<PFP, VEC3,EDGE>* m_positionApproximator ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
359 360 361 362 363 364

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

public:
365
	EdgeSelector_Curvature(MAP& m, VertexAttribute<VEC3>& pos, std::vector<ApproximatorGen<PFP>*>& approx) :
366
		Selector<PFP>(m, pos, approx),
367
		m_positionApproximator(NULL)
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
368
	{
369 370 371
		bb = Algo::Geometry::computeBoundingBox<PFP>(m, pos) ;
		radius = bb.diagSize() * 0.003 ;

372
		normal = m.template getAttribute<VEC3, VERTEX>("normal") ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
373 374
		if(!normal.isValid())
		{
375
			normal = m.template addAttribute<VEC3, VERTEX>("normal") ;
376
			Algo::Surface::Geometry::computeNormalVertices<PFP>(m, pos, normal) ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
377 378
		}

379
		edgeangle = m.template getAttribute<REAL, EDGE>("edgeangle") ;
380 381
		if(!edgeangle.isValid())
		{
382
			edgeangle = m.template addAttribute<REAL, EDGE>("edgeangle") ;
383
			Algo::Surface::Geometry::computeAnglesBetweenNormalsOnEdges<PFP>(m, pos, edgeangle) ;
384 385
		}

386 387 388 389 390
		kmax = m.template getAttribute<REAL, VERTEX>("kmax") ;
		kmin = m.template getAttribute<REAL, VERTEX>("kmin") ;
		Kmax = m.template getAttribute<VEC3, VERTEX>("Kmax") ;
		Kmin = m.template getAttribute<VEC3, VERTEX>("Kmin") ;
		Knormal = m.template getAttribute<VEC3, VERTEX>("Knormal") ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
391 392
		// 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
393
		if(!kmax.isValid())
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
394
		{
395 396 397 398 399
			kmax = m.template addAttribute<REAL, VERTEX>("kmax") ;
			kmin = m.template addAttribute<REAL, VERTEX>("kmin") ;
			Kmax = m.template addAttribute<VEC3, VERTEX>("Kmax") ;
			Kmin = m.template addAttribute<VEC3, VERTEX>("Kmin") ;
			Knormal = m.template addAttribute<VEC3, VERTEX>("Knormal") ;
400
			Algo::Surface::Geometry::computeCurvatureVertices_NormalCycles<PFP>(m, radius, pos, normal, edgeangle, kmax, kmin, Kmax, Kmin, Knormal) ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
401 402
		}

403
		edgeInfo = m.template addAttribute<EdgeInfo, EDGE>("edgeInfo") ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
404 405 406
	}
	~EdgeSelector_Curvature()
	{
407 408 409 410 411 412
		this->m_map.removeAttribute(edgeangle) ;
		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
413 414 415 416
		this->m_map.removeAttribute(edgeInfo) ;
	}
	SelectorType getType() { return S_Curvature ; }
	bool init() ;
417
	bool nextEdge(Dart& d) const ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
418 419
	void updateBeforeCollapse(Dart d) ;
	void updateAfterCollapse(Dart d2, Dart dd2) ;
untereiner's avatar
untereiner committed
420

421
	void updateWithoutCollapse();
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
422 423
} ;

424 425

template <typename PFP>
426
class EdgeSelector_CurvatureTensor : public Selector<PFP>
427
{
Sauvage's avatar
Sauvage committed
428
	// TODO : this selector still needs to be tested
429 430 431 432 433 434 435 436 437 438 439 440
public:
	typedef typename PFP::MAP MAP ;
	typedef typename PFP::VEC3 VEC3 ;
	typedef typename PFP::REAL REAL ;

private:
	typedef	struct
	{
		typename std::multimap<float,Dart>::iterator it ;
		bool valid ;
		static std::string CGoGNnameOfType() { return "CurvatureTensorEdgeInfo" ; }
	} CurvatureTensorEdgeInfo ;
441
	typedef NoTypeNameAttribute<CurvatureTensorEdgeInfo> EdgeInfo ;
442 443 444 445 446 447 448 449 450 451

	EdgeAttribute<EdgeInfo> edgeInfo ;
	EdgeAttribute<REAL> edgeangle ;

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

	Approximator<PFP, VEC3,EDGE>* m_positionApproximator ;

	void initEdgeInfo(Dart d) ;
452
	void updateEdgeInfo(Dart d) ; // TODO : usually has a 2nd arg (, bool recompute) : why ??
453 454 455
	void computeEdgeInfo(Dart d, EdgeInfo& einfo) ;

public:
456
	EdgeSelector_CurvatureTensor(MAP& m, VertexAttribute<VEC3>& pos, std::vector<ApproximatorGen<PFP>*>& approx) :
457
		Selector<PFP>(m, pos, approx),
458 459 460 461 462 463
		m_positionApproximator(NULL)
	{
		edgeangle = m.template getAttribute<REAL, EDGE>("edgeangle") ;
		if(!edgeangle.isValid())
		{
			edgeangle = m.template addAttribute<REAL, EDGE>("edgeangle") ;
464
			Algo::Surface::Geometry::computeAnglesBetweenNormalsOnEdges<PFP>(m, pos, edgeangle) ;
465 466 467 468 469 470 471 472 473 474 475
		}

		edgeInfo = m.template addAttribute<EdgeInfo, EDGE>("edgeInfo") ;
	}
	~EdgeSelector_CurvatureTensor()
	{
		this->m_map.removeAttribute(edgeangle) ; // TODO : pas malin s'il existait avant
		this->m_map.removeAttribute(edgeInfo) ;
	}
	SelectorType getType() { return S_CurvatureTensor ; }
	bool init() ;
476
	bool nextEdge(Dart& d) const ;
477 478 479 480 481 482 483
	void updateBeforeCollapse(Dart d) ;
	void updateAfterCollapse(Dart d2, Dart dd2) ;

	void updateWithoutCollapse() {};
} ;


Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
484
template <typename PFP>
485
class EdgeSelector_MinDetail : public Selector<PFP>
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
486 487 488 489 490 491 492 493 494 495 496 497 498
{
public:
	typedef typename PFP::MAP MAP ;
	typedef typename PFP::VEC3 VEC3 ;
	typedef typename PFP::REAL REAL ;

private:
	typedef	struct
	{
		typename std::multimap<float,Dart>::iterator it ;
		bool valid ;
		static std::string CGoGNnameOfType() { return "MinDetailEdgeInfo" ; }
	} MinDetailEdgeInfo ;
499
	typedef NoTypeNameAttribute<MinDetailEdgeInfo> EdgeInfo ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
500

501
	EdgeAttribute<EdgeInfo> edgeInfo ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
502 503 504 505

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

506
	Approximator<PFP, typename PFP::VEC3, EDGE>* m_positionApproximator ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
507 508 509 510 511 512

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

public:
513
	EdgeSelector_MinDetail(MAP& m, VertexAttribute<typename PFP::VEC3>& pos, std::vector<ApproximatorGen<PFP>*>& approx) :
514
		Selector<PFP>(m, pos, approx),
515
		m_positionApproximator(NULL)
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
516
	{
517
		edgeInfo = m.template addAttribute<EdgeInfo, EDGE>("edgeInfo") ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
518 519 520 521 522 523 524
	}
	~EdgeSelector_MinDetail()
	{
		this->m_map.removeAttribute(edgeInfo) ;
	}
	SelectorType getType() { return S_MinDetail ; }
	bool init() ;
525
	bool nextEdge(Dart& d) const ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
526 527
	void updateBeforeCollapse(Dart d) ;
	void updateAfterCollapse(Dart d2, Dart dd2) ;
untereiner's avatar
untereiner committed
528

529
	void updateWithoutCollapse();
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
530 531
} ;

532
/*****************************************************************************************************************
533
 *                                      EDGE NAIVE COLOR METRIC (using QEMml)                                    *
534 535
 *****************************************************************************************************************/
template <typename PFP>
536
class EdgeSelector_ColorNaive : public Selector<PFP>
537 538 539 540 541 542 543 544 545 546 547 548 549
{
public:
	typedef typename PFP::MAP MAP ;
	typedef typename PFP::VEC3 VEC3 ;
	typedef typename PFP::REAL REAL ;

private:
	typedef	struct
	{
		typename std::multimap<float,Dart>::iterator it ;
		bool valid ;
		static std::string CGoGNnameOfType() { return "ColorNaiveEdgeInfo" ; }
	} ColorNaiveedgeInfo ;
550
	typedef NoTypeNameAttribute<ColorNaiveedgeInfo> EdgeInfo ;
551 552

	EdgeAttribute<EdgeInfo> edgeInfo ;
553
	VertexAttribute<Utils::Quadric<REAL> > m_quadric ;
554

555 556 557 558
	VertexAttribute<VEC3> m_pos, m_color ;
	int m_approxindex_pos, m_attrindex_pos ;
	int m_approxindex_color, m_attrindex_color ;

559
	std::vector<Approximator<PFP, typename PFP::VEC3, EDGE>* > m_approx ;
560

561 562 563 564 565 566 567 568 569
	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:
570
	EdgeSelector_ColorNaive(MAP& m, VertexAttribute<typename PFP::VEC3>& pos, std::vector<ApproximatorGen<PFP>*>& approx) :
571
		Selector<PFP>(m, pos, approx),
572 573 574 575
		m_approxindex_pos(-1),
		m_attrindex_pos(-1),
		m_approxindex_color(-1),
		m_attrindex_color(-1)
576 577
	{
		edgeInfo = m.template addAttribute<EdgeInfo, EDGE>("edgeInfo") ;
578
		m_quadric = m.template addAttribute<Utils::Quadric<REAL>, VERTEX>("QEMquadric") ;
579 580 581 582 583 584 585 586
	}
	~EdgeSelector_ColorNaive()
	{
		this->m_map.removeAttribute(edgeInfo) ;
		this->m_map.removeAttribute(m_quadric) ;
	}
	SelectorType getType() { return S_ColorNaive ; }
	bool init() ;
587
	bool nextEdge(Dart& d) const ;
588 589
	void updateBeforeCollapse(Dart d) ;
	void updateAfterCollapse(Dart d2, Dart dd2) ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
590 591

	void updateWithoutCollapse() { }
592 593
} ;

594 595 596 597
/*****************************************************************************************************************
 *                                  EDGE GEOMETRY+COLOR METRIC (using QEMml and Gradient norm)                   *
 *****************************************************************************************************************/
template <typename PFP>
598
class EdgeSelector_GeomColOptGradient : public Selector<PFP>
599 600 601 602 603 604 605 606 607 608 609 610 611
{
public:
	typedef typename PFP::MAP MAP ;
	typedef typename PFP::VEC3 VEC3 ;
	typedef typename PFP::REAL REAL ;

private:
	typedef	struct
	{
		typename std::multimap<float,Dart>::iterator it ;
		bool valid ;
		static std::string CGoGNnameOfType() { return "GeomColOptGradEdgeInfo" ; }
	} ColorNaiveedgeInfo ;
612
	typedef NoTypeNameAttribute<ColorNaiveedgeInfo> EdgeInfo ;
613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629

	EdgeAttribute<EdgeInfo> edgeInfo ;
	VertexAttribute<Utils::Quadric<REAL> > m_quadric ;

	VertexAttribute<VEC3> m_pos, m_color ;
	int m_approxindex_pos, m_attrindex_pos ;
	int m_approxindex_color, m_attrindex_color ;

	std::vector<Approximator<PFP, typename PFP::VEC3, EDGE>* > m_approx ;

	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
630
	VEC3 computeEdgeGradientColorError(const Dart& v0, const VEC3& p, const VEC3& c) ;
631 632 633

public:
	EdgeSelector_GeomColOptGradient(MAP& m, VertexAttribute<typename PFP::VEC3>& pos, std::vector<ApproximatorGen<PFP>*>& approx) :
634
		Selector<PFP>(m, pos, approx),
635 636 637 638 639 640 641 642 643 644 645 646 647 648 649
		m_approxindex_pos(-1),
		m_attrindex_pos(-1),
		m_approxindex_color(-1),
		m_attrindex_color(-1)
	{
		edgeInfo = m.template addAttribute<EdgeInfo, EDGE>("edgeInfo") ;
		m_quadric = m.template addAttribute<Utils::Quadric<REAL>, VERTEX>("QEMquadric") ;
	}
	~EdgeSelector_GeomColOptGradient()
	{
		this->m_map.removeAttribute(edgeInfo) ;
		this->m_map.removeAttribute(m_quadric) ;
	}
	SelectorType getType() { return S_GeomColOptGrad ; }
	bool init() ;
650
	bool nextEdge(Dart& d) const ;
651 652 653 654 655
	void updateBeforeCollapse(Dart d) ;
	void updateAfterCollapse(Dart d2, Dart dd2) ;

	void updateWithoutCollapse() { }

656
	void getEdgeErrors(EdgeAttribute<typename PFP::REAL> *errors) const
657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674
	{
		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()) ;

		TraversorE<typename PFP::MAP> travE(this->m_map) ;
		for(Dart d = travE.begin() ; d != travE.end() ; d = travE.next())
		{
			(*errors)[d] = -1 ;
			if (edgeInfo[d].valid)
			{
				(*errors)[d] = edgeInfo[d].it->first ;
			}
		}
	}
} ;

675 676 677 678
/*****************************************************************************************************************
 *                                 QEM extended to color metric                                                  *
 *****************************************************************************************************************/
template <typename PFP>
679
class EdgeSelector_QEMextColor : public Selector<PFP>
680 681 682 683 684 685 686 687 688 689 690 691 692 693
{
public:
	typedef typename PFP::MAP MAP ;
	typedef typename PFP::REAL REAL ;
	typedef typename PFP::VEC3 VEC3 ;
	typedef typename Geom::Vector<6,REAL> VEC6 ;

private:
	typedef	struct
	{
		typename std::multimap<float,Dart>::iterator it ;
		bool valid ;
		static std::string CGoGNnameOfType() { return "QEMextColorEdgeInfo" ; }
	} QEMextColorEdgeInfo ;
694
	typedef NoTypeNameAttribute<QEMextColorEdgeInfo> EdgeInfo ;
695 696

	EdgeAttribute<EdgeInfo> edgeInfo ;
697
	VertexAttribute<Utils::QuadricNd<REAL,6> > m_quadric ;
698

699 700 701 702
	VertexAttribute<VEC3> m_pos, m_color ;
	int m_approxindex_pos, m_attrindex_pos ;
	int m_approxindex_color, m_attrindex_color ;

703
	std::vector<Approximator<PFP, typename PFP::VEC3, EDGE>* > m_approx ;
704

705 706 707 708 709 710 711 712 713
	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:
714
	EdgeSelector_QEMextColor(MAP& m, VertexAttribute<typename PFP::VEC3>& pos, std::vector<ApproximatorGen<PFP>*>& approx) :
715
		Selector<PFP>(m, pos, approx),
716 717 718 719
		m_approxindex_pos(-1),
		m_attrindex_pos(-1),
		m_approxindex_color(-1),
		m_attrindex_color(-1)
720 721
	{
		edgeInfo = m.template addAttribute<EdgeInfo, EDGE>("edgeInfo") ;
722
		m_quadric = m.template addAttribute<Utils::QuadricNd<REAL,6>, VERTEX>("QEMext-quadric") ;
723 724 725 726 727 728 729 730
	}
	~EdgeSelector_QEMextColor()
	{
		this->m_map.removeAttribute(edgeInfo) ;
		this->m_map.removeAttribute(m_quadric) ;
	}
	SelectorType getType() { return S_QEMextColor ; }
	bool init() ;
731
	bool nextEdge(Dart& d) const ;
732 733
	void updateBeforeCollapse(Dart d) ;
	void updateAfterCollapse(Dart d2, Dart dd2) ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
734 735

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

737
	void getEdgeErrors(EdgeAttribute<typename PFP::REAL> *errors) const
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753
	{
		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()) ;

		TraversorE<typename PFP::MAP> travE(this->m_map) ;
		for(Dart d = travE.begin() ; d != travE.end() ; d = travE.next())
		{
			(*errors)[d] = -1 ;
			if (edgeInfo[d].valid)
			{
				(*errors)[d] = edgeInfo[d].it->first ;
			}
		}
	}
754
} ;
755

Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
756 757
} // namespace Decimation

758
} // namespace Surface
759

Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
760 761 762 763 764 765 766
} // namespace Algo

} // namespace CGoGN

#include "Algo/Decimation/edgeSelector.hpp"

#endif