edgeSelector.h 22.5 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-2012, IGG Team, LSIIT, 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"
29
#include "Algo/Geometry/boundingbox.h"
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
30

31 32 33 34
#include "Container/fakeAttribute.h"
#include "Utils/qem.h"
#include "Utils/quadricRGBfunctions.h"
#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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
namespace CGoGN
{

namespace Algo
{

namespace Decimation
{

template <typename PFP>
class EdgeSelector_MapOrder : public EdgeSelector<PFP>
{
public:
	typedef typename PFP::MAP MAP ;
	typedef typename PFP::VEC3 VEC3 ;
	typedef typename PFP::REAL REAL ;

private:
	Dart cur ;

public:
58
	EdgeSelector_MapOrder(MAP& m, VertexAttribute<typename PFP::VEC3>& pos, std::vector<ApproximatorGen<PFP>*>& approx, const FunctorSelect& select) :
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
59 60 61 62 63 64 65 66 67 68
		EdgeSelector<PFP>(m, pos, approx, select)
	{}
	~EdgeSelector_MapOrder()
	{}
	SelectorType getType() { return S_MapOrder ; }
	bool init() ;
	bool nextEdge(Dart& d) ;
	void updateBeforeCollapse(Dart d)
	{}
	void updateAfterCollapse(Dart d2, Dart dd2) ;
untereiner's avatar
untereiner committed
69

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

Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
} ;

template <typename PFP>
class EdgeSelector_Random : public EdgeSelector<PFP>
{
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:
88
	EdgeSelector_Random(MAP& m, VertexAttribute<typename PFP::VEC3>& pos, std::vector<ApproximatorGen<PFP>*>& approx, const FunctorSelect& select) :
89 90 91
		EdgeSelector<PFP>(m, pos, approx, select),
		cur(0),
		allSkipped(false)
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
92 93 94 95 96 97 98 99 100
	{}
	~EdgeSelector_Random()
	{}
	SelectorType getType() { return S_Random ; }
	bool init() ;
	bool nextEdge(Dart& d) ;
	void updateBeforeCollapse(Dart d2)
	{}
	void updateAfterCollapse(Dart d2, Dart dd2) ;
untereiner's avatar
untereiner committed
101

102
	void updateWithoutCollapse();
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
} ;

template <typename PFP>
class EdgeSelector_Length : public EdgeSelector<PFP>
{
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 ;
	typedef NoMathIOAttribute<LengthEdgeInfo> EdgeInfo ;

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

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

147
	void updateWithoutCollapse();
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165

	void getEdgeErrors(EdgeAttribute<typename PFP::REAL> *errors)
	{
		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
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
} ;

template <typename PFP>
class EdgeSelector_QEM : public EdgeSelector<PFP>
{
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 ;
	typedef NoMathIOAttribute<QEMedgeInfo> EdgeInfo ;

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

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

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

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

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

217
	void updateWithoutCollapse();
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236
} ;

template <typename PFP>
class EdgeSelector_QEMml : public EdgeSelector<PFP>
{
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 ;
	typedef NoMathIOAttribute<QEMedgeInfo> EdgeInfo ;

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

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

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

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

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

272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300

template <typename PFP>
class EdgeSelector_NormalArea : public EdgeSelector<PFP>
{
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 ;
	typedef NoMathIOAttribute<NormalAreaEdgeInfo> EdgeInfo ;

	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) ;
301
	void computeEdgeMatrix(Dart d) ;
302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
//	void recomputeQuadric(const Dart d, const bool recomputeNeighbors = false) ;

public:
	EdgeSelector_NormalArea(MAP& m, VertexAttribute<typename PFP::VEC3>& pos, std::vector<ApproximatorGen<PFP>*>& approx, const FunctorSelect& select) :
		EdgeSelector<PFP>(m, pos, approx, select),
		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() ;
	bool nextEdge(Dart& d) ;
	void updateBeforeCollapse(Dart d) ;
	void updateAfterCollapse(Dart d2, Dart dd2) ;

	void updateWithoutCollapse() { }
} ;


Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343
template <typename PFP>
class EdgeSelector_Curvature : public EdgeSelector<PFP>
{
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 ;
	typedef NoMathIOAttribute<CurvatureEdgeInfo> EdgeInfo ;

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

347
	VertexAttribute<VEC3> normal ;
348
	EdgeAttribute<EdgeInfo> edgeInfo ;
349 350 351 352 353 354
	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
355 356 357 358

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

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

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

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

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

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

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

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

422
	void updateWithoutCollapse();
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441
} ;

template <typename PFP>
class EdgeSelector_MinDetail : public EdgeSelector<PFP>
{
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 ;
	typedef NoMathIOAttribute<MinDetailEdgeInfo> EdgeInfo ;

442
	EdgeAttribute<EdgeInfo> edgeInfo ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
443 444 445 446

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

447
	Approximator<PFP, typename PFP::VEC3, EDGE>* m_positionApproximator ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
448 449 450 451 452 453

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

public:
454
	EdgeSelector_MinDetail(MAP& m, VertexAttribute<typename PFP::VEC3>& pos, std::vector<ApproximatorGen<PFP>*>& approx, const FunctorSelect& select) :
455 456
		EdgeSelector<PFP>(m, pos, approx, select),
		m_positionApproximator(NULL)
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
457
	{
458
		edgeInfo = m.template addAttribute<EdgeInfo, EDGE>("edgeInfo") ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
459 460 461 462 463 464 465 466 467 468
	}
	~EdgeSelector_MinDetail()
	{
		this->m_map.removeAttribute(edgeInfo) ;
	}
	SelectorType getType() { return S_MinDetail ; }
	bool init() ;
	bool nextEdge(Dart& d) ;
	void updateBeforeCollapse(Dart d) ;
	void updateAfterCollapse(Dart d2, Dart dd2) ;
untereiner's avatar
untereiner committed
469

470
	void updateWithoutCollapse();
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
471 472
} ;

473
/*****************************************************************************************************************
474
 *                                      EDGE NAIVE COLOR METRIC (using QEMml)                                    *
475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493
 *****************************************************************************************************************/
template <typename PFP>
class EdgeSelector_ColorNaive : public EdgeSelector<PFP>
{
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 ;
	typedef NoMathIOAttribute<ColorNaiveedgeInfo> EdgeInfo ;

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

496 497 498 499
	VertexAttribute<VEC3> m_pos, m_color ;
	int m_approxindex_pos, m_attrindex_pos ;
	int m_approxindex_color, m_attrindex_color ;

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

502 503 504 505 506 507 508 509 510 511 512
	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:
	EdgeSelector_ColorNaive(MAP& m, VertexAttribute<typename PFP::VEC3>& pos, std::vector<ApproximatorGen<PFP>*>& approx, const FunctorSelect& select = allDarts) :
		EdgeSelector<PFP>(m, pos, approx, select),
513 514 515 516
		m_approxindex_pos(-1),
		m_attrindex_pos(-1),
		m_approxindex_color(-1),
		m_attrindex_color(-1)
517 518
	{
		edgeInfo = m.template addAttribute<EdgeInfo, EDGE>("edgeInfo") ;
519
		m_quadric = m.template addAttribute<Utils::Quadric<REAL>, VERTEX>("QEMquadric") ;
520 521 522 523 524 525 526 527 528 529 530
	}
	~EdgeSelector_ColorNaive()
	{
		this->m_map.removeAttribute(edgeInfo) ;
		this->m_map.removeAttribute(m_quadric) ;
	}
	SelectorType getType() { return S_ColorNaive ; }
	bool init() ;
	bool nextEdge(Dart& d) ;
	void updateBeforeCollapse(Dart d) ;
	void updateAfterCollapse(Dart d2, Dart dd2) ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
531 532

	void updateWithoutCollapse() { }
533 534
} ;

535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556
/*****************************************************************************************************************
 *                                 QEM extended to color metric                                                  *
 *****************************************************************************************************************/
template <typename PFP>
class EdgeSelector_QEMextColor : public EdgeSelector<PFP>
{
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 ;
	typedef NoMathIOAttribute<QEMextColorEdgeInfo> EdgeInfo ;

	EdgeAttribute<EdgeInfo> edgeInfo ;
557
	VertexAttribute<Utils::QuadricNd<REAL,6> > m_quadric ;
558

559 560 561 562
	VertexAttribute<VEC3> m_pos, m_color ;
	int m_approxindex_pos, m_attrindex_pos ;
	int m_approxindex_color, m_attrindex_color ;

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

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

	void updateWithoutCollapse() { }
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613

	void getEdgeErrors(EdgeAttribute<typename PFP::REAL> *errors)
	{
		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 ;
			}
		}
	}
614
} ;
615

616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633
/*****************************************************************************************************************
 *                                 LIGHTFIELD QUADRIC ERROR METRIC                                               *
 *****************************************************************************************************************/
template <typename PFP>
class EdgeSelector_Lightfield : public EdgeSelector<PFP>
{
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" ; }
634 635
	} LightfieldEdgeInfo ;
	typedef NoMathIOAttribute<LightfieldEdgeInfo> EdgeInfo ;
636 637 638 639

	EdgeAttribute<EdgeInfo> edgeInfo ;

	VertexAttribute<VEC3> m_pos, m_frameT, m_frameB, m_frameN ;
640
	std::vector<VertexAttribute<VEC3> > m_HF ;
641 642
	int m_approxindex_pos, m_attrindex_pos ;
	int m_approxindex_FN, m_attrindex_FN ;
643 644
	std::vector<unsigned int> m_approxindex_HF, m_attrindex_HF ;
	unsigned int m_K ;
645

646 647
	VertexAttribute<Utils::Quadric<REAL> > m_quadricGeom ;
	EdgeAttribute<Utils::QuadricHF<REAL> > m_quadricHF ;
648

649
	std::vector<Approximator<PFP, typename PFP::VEC3, EDGE>* > m_approx ;
650 651 652 653 654 655 656 657 658 659 660 661 662 663 664

	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:
	EdgeSelector_Lightfield(MAP& m, VertexAttribute<typename PFP::VEC3>& pos, std::vector<ApproximatorGen<PFP>*>& approx, const FunctorSelect& select = allDarts) :
		EdgeSelector<PFP>(m, pos, approx, select),
		m_approxindex_pos(-1),
		m_attrindex_pos(-1),
		m_approxindex_FN(-1),
665 666
		m_attrindex_FN(-1),
		m_K(0)
667 668
	{
		edgeInfo = m.template addAttribute<EdgeInfo, EDGE>("edgeInfo") ;
669 670
		m_quadricGeom = m.template addAttribute<Utils::Quadric<REAL>, VERTEX>("QEMquadric") ;
		m_quadricHF = m.template getAttribute<Utils::QuadricHF<REAL>, EDGE>("HFquadric") ;
671 672 673 674 675 676 677 678 679 680 681
	}
	~EdgeSelector_Lightfield()
	{
		this->m_map.removeAttribute(edgeInfo) ;
		this->m_map.removeAttribute(m_quadricGeom) ;
	}
	SelectorType getType() { return S_Lightfield ; }
	bool init() ;
	bool nextEdge(Dart& d) ;
	void updateBeforeCollapse(Dart d) ;
	void updateAfterCollapse(Dart d2, Dart dd2) ;
Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
682 683

	void updateWithoutCollapse() { }
684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702

	void getEdgeErrors(EdgeAttribute<typename PFP::REAL> *errors)
	{
		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())
		{
			if (edgeInfo[d].valid)
			{
				(*errors)[d] = edgeInfo[d].it->first ;
			}
			else
				(*errors)[d] = -1 ;
		}
	}
703 704
} ;

Kenneth Vanhoey's avatar
Kenneth Vanhoey committed
705 706 707 708 709 710 711 712 713
} // namespace Decimation

} // namespace Algo

} // namespace CGoGN

#include "Algo/Decimation/edgeSelector.hpp"

#endif