collector.h 17.7 KB
Newer Older
Pierre Kraemer's avatar
Pierre Kraemer committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps  *
* version 0.1                                                                  *
* Copyright (C) 2009, IGG Team, LSIIT, University of Strasbourg                *
*                                                                              *
* This library is free software; you can redistribute it and/or modify it      *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your     *
* option) any later version.                                                   *
*                                                                              *
* This library is distributed in the hope that it will be useful, but WITHOUT  *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or        *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License  *
* for more details.                                                            *
*                                                                              *
* You should have received a copy of the GNU Lesser General Public License     *
* along with this library; if not, write to the Free Software Foundation,      *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.           *
*                                                                              *
20
* Web site: http://cgogn.unistra.fr/                                  *
Pierre Kraemer's avatar
Pierre Kraemer committed
21 22 23 24 25 26 27
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

#ifndef __COLLECTOR_H__
#define __COLLECTOR_H__

Sylvain Thery's avatar
Sylvain Thery committed
28
#include "Container/fakeAttribute.h"
Sylvain Thery's avatar
Sylvain Thery committed
29
#include "Geometry/basic.h"
Sylvain Thery's avatar
Sylvain Thery committed
30

31 32
#include "Topology/generic/traversor/traversor2.h"

Pierre Kraemer's avatar
Pierre Kraemer committed
33 34 35 36 37 38 39 40 41 42
/*****************************************
 * Class hierarchy :
 * Collector (virtual)
 * - Collector_WithinSphere
 * - Collector_OneRing
 ****************************************/

namespace CGoGN
{

43 44 45
namespace Algo
{

Thery Sylvain's avatar
Thery Sylvain committed
46 47 48
namespace Surface
{

Pierre Kraemer's avatar
Pierre Kraemer committed
49 50 51 52
namespace Selection
{

/*********************************************************
53
 * Generic Collector
Pierre Kraemer's avatar
Pierre Kraemer committed
54
 *********************************************************/
55

Pierre Kraemer's avatar
Pierre Kraemer committed
56 57 58
template <typename PFP>
class Collector
{
Pierre Kraemer's avatar
Pierre Kraemer committed
59
	typedef typename PFP::MAP MAP ;
Pierre Kraemer's avatar
Pierre Kraemer committed
60 61 62
	typedef typename PFP::VEC3 VEC3;
	typedef typename PFP::REAL REAL;

Pierre Kraemer's avatar
Pierre Kraemer committed
63 64
protected:
	MAP& map;
Pierre Kraemer's avatar
Pierre Kraemer committed
65 66 67

	Dart centerDart;

68 69
	bool isInsideCollected;

Pierre Kraemer's avatar
Pierre Kraemer committed
70 71 72
	std::vector<Vertex> insideVertices;
	std::vector<Edge> insideEdges;
	std::vector<Face> insideFaces;
Pierre Kraemer's avatar
Pierre Kraemer committed
73 74 75
	std::vector<Dart> border;

public:
Sylvain Thery's avatar
Sylvain Thery committed
76
	Collector(MAP& m);
Pierre Kraemer's avatar
Pierre Kraemer committed
77

Pierre Kraemer's avatar
Pierre Kraemer committed
78 79 80
	inline void init(Dart d)
	{
		centerDart = d;
81
		isInsideCollected = false;
Pierre Kraemer's avatar
Pierre Kraemer committed
82 83 84 85 86
		insideVertices.clear();
		insideEdges.clear();
		insideFaces.clear();
		border.clear();
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
87

Pierre Kraemer's avatar
Pierre Kraemer committed
88 89
	virtual void collectAll(Dart d) = 0;
	virtual void collectBorder(Dart d) = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
90

91
	template <typename FUNC>
92
	void applyOnInsideVertices(FUNC& func);
93
	template <typename FUNC>
94
	void applyOnInsideEdges(FUNC& func);
95
	template <typename FUNC>
96
	void applyOnInsideFaces(FUNC& func);
97
	template <typename FUNC>
98
	void applyOnBorder(FUNC& func);
99

Pierre Kraemer's avatar
Pierre Kraemer committed
100
	inline void sort()
Pierre Kraemer's avatar
Pierre Kraemer committed
101 102 103 104 105 106 107
	{
		std::sort(insideVertices.begin(), insideVertices.end());
		std::sort(insideEdges.begin(), insideEdges.end());
		std::sort(insideFaces.begin(), insideFaces.end());
		std::sort(border.begin(), border.end());
	}

Pierre Kraemer's avatar
Pierre Kraemer committed
108
	inline MAP& getMap() { return map; }
Pierre Kraemer's avatar
Pierre Kraemer committed
109

Pierre Kraemer's avatar
Pierre Kraemer committed
110
	inline Dart getCenterDart() const { return centerDart; }
Pierre Kraemer's avatar
Pierre Kraemer committed
111

Pierre Kraemer's avatar
Pierre Kraemer committed
112 113 114
	inline const std::vector<Vertex>& getInsideVertices() const { assert(isInsideCollected || !"getInsideVertices: inside cells have not been collected.") ; return insideVertices; }
	inline const std::vector<Edge>& getInsideEdges() const { assert(isInsideCollected || !"getInsideEdges: inside cells have not been collected.") ; return insideEdges; }
	inline const std::vector<Face>& getInsideFaces() const { assert(isInsideCollected || !"getInsideFaces: inside cells have not been collected.") ; return insideFaces; }
Pierre Kraemer's avatar
Pierre Kraemer committed
115
	inline const std::vector<Dart>& getBorder() const { return border; }
Pierre Kraemer's avatar
Pierre Kraemer committed
116

117 118 119
	inline unsigned int getNbInsideVertices() const { assert(isInsideCollected || !"getNbInsideVertices: inside cells have not been collected.") ; return insideVertices.size(); }
	inline unsigned int getNbInsideEdges() const { assert(isInsideCollected || !"getNbInsideEdges: inside cells have not been collected.") ; return insideEdges.size(); }
	inline unsigned int getNbInsideFaces() const { assert(isInsideCollected || !"getNbInsideFaces: inside cells have not been collected.") ; return insideFaces.size(); }
Pierre Kraemer's avatar
Pierre Kraemer committed
120
	inline unsigned int getNbBorder() const { return border.size(); }
Pierre Kraemer's avatar
Pierre Kraemer committed
121 122 123

	template <typename PPFP>
	friend std::ostream& operator<<(std::ostream &out, const Collector<PPFP>& c);
124

125
	virtual REAL computeArea(const VertexAttribute<VEC3, MAP>& /*pos*/)
Pierre Kraemer's avatar
Pierre Kraemer committed
126
	{
127 128 129
		assert(!"Warning: Collector<PFP>::computeArea() should be overloaded in non-virtual derived classes");
		return 0.0;
	}
130 131 132 133 134 135 136 137

	virtual REAL computeArea(const VertexAttribute<VEC3, MAP>& /*pos*/, const EdgeAttribute<REAL, MAP>& /*edgearea*/)
	{
		assert(!"Warning: Collector<PFP>::computeArea() should be overloaded in non-virtual derived classes");
		return 0.0;
	}

	virtual REAL borderEdgeRatio(Dart /*d*/, const VertexAttribute<VEC3, MAP>& /*pos*/)
Pierre Kraemer's avatar
Pierre Kraemer committed
138
	{
139 140
		assert(!"Warning: Collector<PFP>::borderEdgeRatio() should be overloaded in non-virtual derived classes");
		return 1.0;
Pierre Kraemer's avatar
Pierre Kraemer committed
141
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
142 143 144 145 146 147 148 149 150 151
};

/*********************************************************
 * Collector One Ring
 *********************************************************/

/*
 * insideVertices = centerDart
 * insideEdges = star (edges incident to centerDart)
 * insideFaces = triangles incident to centerDart
152
 * border = vertices of 1-ring -> link (set of adjacent vertices)
Pierre Kraemer's avatar
Pierre Kraemer committed
153 154 155 156 157
 *        = edges of 1-ring
 */
template <typename PFP>
class Collector_OneRing : public Collector<PFP>
{
Pierre Kraemer's avatar
Pierre Kraemer committed
158
	typedef typename PFP::MAP MAP ;
159 160 161
	typedef typename PFP::VEC3 VEC3 ;
	typedef typename PFP::REAL REAL ;

Pierre Kraemer's avatar
Pierre Kraemer committed
162
public:
Sylvain Thery's avatar
Sylvain Thery committed
163 164
	Collector_OneRing(MAP& m) :
		Collector<PFP>(m)
Pierre Kraemer's avatar
Pierre Kraemer committed
165
	{}
Pierre Kraemer's avatar
Pierre Kraemer committed
166 167
	void collectAll(Dart d);
	void collectBorder(Dart d);
168

169
	REAL computeArea(const VertexAttribute<VEC3, MAP>& pos);
170
	REAL computeArea(const VertexAttribute<VEC3, MAP>& pos, const EdgeAttribute<REAL, MAP>& edgearea);
171
	REAL borderEdgeRatio(Dart d, const VertexAttribute<VEC3, MAP>& pos);
Pierre Kraemer's avatar
Pierre Kraemer committed
172 173
};

174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
/*********************************************************
 * Collector One Ring around edge
 *********************************************************/

/*
 * insideVertices = 2 ends of center edge (centerDart)
 * insideEdges = center egde + edges adjacent by a vertex
 *             = union of stars of 1-rings of the 2 ends
 * insideFaces = triangles incident to the 2 ends
 * border = vertices of 1-ring -> link (set of adjacent vertices)
 *        = edges of 1-ring
 */

template <typename PFP>
class Collector_OneRing_AroundEdge : public Collector<PFP>
{
Pierre Kraemer's avatar
Pierre Kraemer committed
190
	typedef typename PFP::MAP MAP ;
191 192 193 194
	typedef typename PFP::VEC3 VEC3 ;
	typedef typename PFP::REAL REAL ;

public:
Sylvain Thery's avatar
Sylvain Thery committed
195 196
	Collector_OneRing_AroundEdge(MAP& m) :
		Collector<PFP>(m)
Pierre Kraemer's avatar
Pierre Kraemer committed
197
	{}
198 199 200
	void collectAll(Dart d);
	void collectBorder(Dart d);

201
	REAL computeArea(const VertexAttribute<VEC3, MAP>& pos);
202
	REAL computeArea(const VertexAttribute<VEC3, MAP>& pos, const EdgeAttribute<REAL, MAP>& edgearea);
203
	REAL borderEdgeRatio(Dart d, const VertexAttribute<VEC3, MAP>& pos);
Pierre Kraemer's avatar
Pierre Kraemer committed
204 205 206 207 208 209 210 211 212 213
};

/*********************************************************
 * Collector Within Sphere
 *********************************************************/

/*
 * collect all primitives of the connected component containing "centerDart"
 * within the sphere of radius "radius" and center "position[centerDart]"
 * (hopefully) it defines a 2-manifold (if inserting border-vertices along the border-edges)
Basile Sauvage's avatar
Basile Sauvage committed
214
 * NB : is equivalent to Collector_Vertices with CollectorCriterion_VertexWithinSphere
Pierre Kraemer's avatar
Pierre Kraemer committed
215 216 217 218
 */
template <typename PFP>
class Collector_WithinSphere : public Collector<PFP>
{
Pierre Kraemer's avatar
Pierre Kraemer committed
219
	typedef typename PFP::MAP MAP ;
220 221 222
	typedef typename PFP::VEC3 VEC3 ;
	typedef typename PFP::REAL REAL ;

Pierre Kraemer's avatar
Pierre Kraemer committed
223
protected:
224
	const VertexAttribute<VEC3, MAP>& position;
225
	REAL radius;
226

Pierre Kraemer's avatar
Pierre Kraemer committed
227
public:
Sylvain Thery's avatar
Sylvain Thery committed
228 229
	Collector_WithinSphere(MAP& m, const VertexAttribute<VEC3, MAP>& p, REAL r = 0) :
		Collector<PFP>(m),
Pierre Kraemer's avatar
Pierre Kraemer committed
230
		position(p),
231
		radius(r)
Pierre Kraemer's avatar
Pierre Kraemer committed
232
	{}
233 234
	inline void setRadius(REAL r) { radius = r; }
	inline REAL getRadius() const { return radius; }
235
	inline const VertexAttribute<VEC3, MAP>& getPosition() const { return position; }
Pierre Kraemer's avatar
Pierre Kraemer committed
236 237 238 239

	void collectAll(Dart d);
	void collectBorder(Dart d);

240
	REAL computeArea(const VertexAttribute<VEC3, MAP>& pos);
241
	REAL computeArea(const VertexAttribute<VEC3, MAP>& pos, const EdgeAttribute<REAL, MAP>& edgearea);
242
	REAL borderEdgeRatio(Dart d, const VertexAttribute<VEC3, MAP>& pos);
Pierre Kraemer's avatar
Pierre Kraemer committed
243 244
};

245
/*********************************************************
246
 * Collector Normal Angle (Vertices)
247 248 249 250 251 252
 *********************************************************/

/*
 * collect all primitives of the connected component containing "centerDart"
 * the angle between the included vertices normal vectors and the central normal vector
 * stays under a given threshold
Basile Sauvage's avatar
Basile Sauvage committed
253
 * NB : is equivalent to Collector_Vertices with CollectorCriterion_VertexNormalAngle
254 255 256 257
 */
template <typename PFP>
class Collector_NormalAngle : public Collector<PFP>
{
Pierre Kraemer's avatar
Pierre Kraemer committed
258 259 260 261
	typedef typename PFP::MAP MAP ;
	typedef typename PFP::VEC3 VEC3 ;
	typedef typename PFP::REAL REAL ;

262
protected:
263
	const VertexAttribute<VEC3, MAP>& normal ;
Pierre Kraemer's avatar
Pierre Kraemer committed
264
	REAL angleThreshold ;
265 266 267

public:
	Collector_NormalAngle(
Pierre Kraemer's avatar
Pierre Kraemer committed
268
		MAP& m,
269
		const VertexAttribute<VEC3, MAP>& n,
Sylvain Thery's avatar
Sylvain Thery committed
270 271
		REAL a
	) :	Collector<PFP>(m), normal(n), angleThreshold(a)
272
	{}
Pierre Kraemer's avatar
Pierre Kraemer committed
273 274
	inline void setAngleThreshold(REAL a) { angleThreshold = a; }
	inline REAL getAngleThreshold() const { return angleThreshold; }
275
	inline const VertexAttribute<VEC3, MAP>& getNormal() const { return normal ; }
276 277 278 279 280

	void collectAll(Dart d) ;
	void collectBorder(Dart d) ;
};

281 282 283 284 285 286 287 288 289 290 291 292 293
/*********************************************************
 * Collector Normal Angle (Triangles)
 *********************************************************/

/*
 * collect all primitives of the connected component containing "centerDart"
 * the angle between the included triangles normal vectors and the central normal vector
 * stays under a given threshold
 * NB : is equivalent to Collector_Triangles with CollectorCriterion_TriangleNormalAngle
 */
template <typename PFP>
class Collector_NormalAngle_Triangles : public Collector<PFP>
{
Pierre Kraemer's avatar
Pierre Kraemer committed
294 295 296 297
	typedef typename PFP::MAP MAP ;
	typedef typename PFP::VEC3 VEC3 ;
	typedef typename PFP::REAL REAL ;

298
protected:
299
	const FaceAttribute<VEC3, MAP>& normal ;
Pierre Kraemer's avatar
Pierre Kraemer committed
300
	REAL angleThreshold ;
301 302 303

public:
	Collector_NormalAngle_Triangles(
Pierre Kraemer's avatar
Pierre Kraemer committed
304
		MAP& m,
305
		const FaceAttribute<VEC3, MAP>& n,
Sylvain Thery's avatar
Sylvain Thery committed
306 307
		REAL a
	) :	Collector<PFP>(m), normal(n), angleThreshold(a)
308
	{}
Pierre Kraemer's avatar
Pierre Kraemer committed
309 310
	inline void setAngleThreshold(REAL a) { angleThreshold = a; }
	inline REAL getAngleThreshold() const { return angleThreshold; }
311
	inline const VertexAttribute<VEC3, MAP>& getNormal() const { return normal ; }
312 313 314 315 316

	void collectAll(Dart d) ;
	void collectBorder(Dart d) ;
};

Basile Sauvage's avatar
Basile Sauvage committed
317
/*********************************************************
Basile Sauvage's avatar
Basile Sauvage committed
318
 * Collector Criterions
Basile Sauvage's avatar
Basile Sauvage committed
319
 *********************************************************/
320

Basile Sauvage's avatar
Basile Sauvage committed
321 322
class CollectorCriterion
{
323
public:
324 325
	CollectorCriterion() {}
	virtual ~CollectorCriterion() {}
Basile Sauvage's avatar
Basile Sauvage committed
326 327 328 329
	virtual void init(Dart center) = 0;
	virtual bool isInside(Dart d) = 0;
};

Pierre Kraemer's avatar
Pierre Kraemer committed
330
// tests if the angle between vertex normals is below some threshold
Basile Sauvage's avatar
Basile Sauvage committed
331 332
template <typename PFP>
class CollectorCriterion_VertexNormalAngle : public CollectorCriterion
Pierre Kraemer's avatar
Pierre Kraemer committed
333 334
{
	typedef typename PFP::MAP MAP ;
Basile Sauvage's avatar
Basile Sauvage committed
335 336 337
	typedef typename PFP::VEC3 VEC3;
	typedef typename PFP::REAL REAL;

338
private:
339
	const VertexAttribute<VEC3, MAP>& vertexNormals;
Basile Sauvage's avatar
Basile Sauvage committed
340 341
	REAL threshold;
	VEC3 centerNormal;
Pierre Kraemer's avatar
Pierre Kraemer committed
342

343
public:
344
	CollectorCriterion_VertexNormalAngle(const VertexAttribute<VEC3, MAP>& n, REAL th) :
Pierre Kraemer's avatar
Pierre Kraemer committed
345 346
		vertexNormals(n), threshold(th), centerNormal(0)
	{}
Basile Sauvage's avatar
Basile Sauvage committed
347

Pierre Kraemer's avatar
Pierre Kraemer committed
348
	void init (Dart center) { centerNormal = vertexNormals[center]; }
349 350
	bool isInside (Dart d)
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
351
		return ( Geom::angle(centerNormal, vertexNormals[d]) < threshold );
Basile Sauvage's avatar
Basile Sauvage committed
352 353 354
	}
};

Pierre Kraemer's avatar
Pierre Kraemer committed
355
// tests if the angle between triangle normals is below some threshold
Basile Sauvage's avatar
Basile Sauvage committed
356 357
template <typename PFP>
class CollectorCriterion_TriangleNormalAngle : public CollectorCriterion
Pierre Kraemer's avatar
Pierre Kraemer committed
358 359
{
	typedef typename PFP::MAP MAP ;
Basile Sauvage's avatar
Basile Sauvage committed
360 361 362
	typedef typename PFP::VEC3 VEC3;
	typedef typename PFP::REAL REAL;

363
private:
364
	const FaceAttribute<VEC3, MAP>& faceNormals;
Basile Sauvage's avatar
Basile Sauvage committed
365 366
	REAL threshold;
	VEC3 centerNormal;
Pierre Kraemer's avatar
Pierre Kraemer committed
367

368
public:
369
	CollectorCriterion_TriangleNormalAngle(const FaceAttribute<VEC3, MAP>& n, REAL th) :
Pierre Kraemer's avatar
Pierre Kraemer committed
370 371
		faceNormals(n), threshold(th), centerNormal(0)
	{}
Basile Sauvage's avatar
Basile Sauvage committed
372

Pierre Kraemer's avatar
Pierre Kraemer committed
373
	void init (Dart center) { centerNormal = faceNormals[center]; }
374 375
	bool isInside (Dart d)
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
376
		return ( Geom::angle(centerNormal, faceNormals[d]) < threshold );
Basile Sauvage's avatar
Basile Sauvage committed
377 378 379
	}
};

Pierre Kraemer's avatar
Pierre Kraemer committed
380
// tests if the distance between vertices is below some threshold
Basile Sauvage's avatar
Basile Sauvage committed
381 382
template <typename PFP>
class CollectorCriterion_VertexWithinSphere : public CollectorCriterion
Pierre Kraemer's avatar
Pierre Kraemer committed
383 384
{
	typedef typename PFP::MAP MAP ;
Basile Sauvage's avatar
Basile Sauvage committed
385 386 387
	typedef typename PFP::VEC3 VEC3;
	typedef typename PFP::REAL REAL;

388
private:
389
	const VertexAttribute<VEC3, MAP>& vertexPositions;
Basile Sauvage's avatar
Basile Sauvage committed
390 391
	REAL threshold;
	VEC3 centerPosition;
Pierre Kraemer's avatar
Pierre Kraemer committed
392

393
public:
394
	CollectorCriterion_VertexWithinSphere(const VertexAttribute<VEC3, MAP>& p, REAL th) :
Pierre Kraemer's avatar
Pierre Kraemer committed
395 396
		vertexPositions(p), threshold(th), centerPosition(0)
	{}
Basile Sauvage's avatar
Basile Sauvage committed
397

Pierre Kraemer's avatar
Pierre Kraemer committed
398
	void init (Dart center) { centerPosition = vertexPositions[center]; }
399 400
	bool isInside (Dart d)
	{
Basile Sauvage's avatar
Basile Sauvage committed
401 402 403 404
		return (vertexPositions[d] - centerPosition).norm() < threshold ;
	}
};

Basile Sauvage's avatar
Basile Sauvage committed
405 406 407 408 409 410
/*********************************************************
 * Collector Vertices
 *********************************************************/

/*
 * collect all vertices of the connected component containing "centerDart"
411
 * that satisfy the CollectorCriterion
Basile Sauvage's avatar
Basile Sauvage committed
412 413 414 415 416
 * (hopefully) it defines a 2-manifold (if inserting border-vertices along the border-edges)
 */
template <typename PFP>
class Collector_Vertices : public Collector<PFP>
{
Pierre Kraemer's avatar
Pierre Kraemer committed
417 418 419 420
	typedef typename PFP::MAP MAP ;
	typedef typename PFP::VEC3 VEC3;
	typedef typename PFP::REAL REAL;

Basile Sauvage's avatar
Basile Sauvage committed
421 422 423 424
protected:
	CollectorCriterion & crit;

public:
Sylvain Thery's avatar
Sylvain Thery committed
425 426
	Collector_Vertices(typename PFP::MAP& m, CollectorCriterion& c) :
		Collector<PFP>(m),
Basile Sauvage's avatar
Basile Sauvage committed
427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443
		crit(c)
	{}
	void collectAll(Dart d);
	void collectBorder(Dart d);
};

/*********************************************************
 * Collector Triangles
 *********************************************************/

/*
 * collect all triangles of the connected component containing "centerDart"
 * within a distance to centerDart defined by the CollectorCriterion
 */
template <typename PFP>
class Collector_Triangles : public Collector<PFP>
{
Pierre Kraemer's avatar
Pierre Kraemer committed
444 445 446 447
	typedef typename PFP::MAP MAP ;
	typedef typename PFP::VEC3 VEC3;
	typedef typename PFP::REAL REAL;

Basile Sauvage's avatar
Basile Sauvage committed
448 449 450 451
protected:
	CollectorCriterion & crit;

public:
Sylvain Thery's avatar
Sylvain Thery committed
452 453
	Collector_Triangles(typename PFP::MAP& m, CollectorCriterion& c) :
		Collector<PFP>(m), crit(c)
Basile Sauvage's avatar
Basile Sauvage committed
454 455 456 457 458
	{}
	void collectAll(Dart d) ;
	void collectBorder(Dart d) ;
};

Basile Sauvage's avatar
Basile Sauvage committed
459
/*********************************************************
460
 * Collector Dijkstra_Vertices
Basile Sauvage's avatar
Basile Sauvage committed
461 462 463 464 465
 *********************************************************/

/*
 * collect all primitives of the connected component containing "centerDart"
 * within a distance < maxDist (the shortest path follows edges)
466
 * the edge length is specified in edge_cost attribute
Basile Sauvage's avatar
Basile Sauvage committed
467
 */
468

Basile Sauvage's avatar
Basile Sauvage committed
469
template <typename PFP>
470
class Collector_Dijkstra_Vertices : public Collector<PFP>
Basile Sauvage's avatar
Basile Sauvage committed
471
{
Pierre Kraemer's avatar
Pierre Kraemer committed
472 473 474 475
	typedef typename PFP::MAP MAP ;
	typedef typename PFP::VEC3 VEC3;
	typedef typename PFP::REAL REAL;

Basile Sauvage's avatar
Basile Sauvage committed
476
protected:
477
	const EdgeAttribute<REAL, MAP>& edge_cost;
Pierre Kraemer's avatar
Pierre Kraemer committed
478
	REAL maxDist;
Basile Sauvage's avatar
Basile Sauvage committed
479 480 481 482 483 484 485

	typedef struct
	{
		typename std::multimap<float,Dart>::iterator it ;
		bool valid ;
		static std::string CGoGNnameOfType() { return "DijkstraVertexInfo" ; }
	} DijkstraVertexInfo ;
486
	typedef NoTypeNameAttribute<DijkstraVertexInfo> VertexInfo ;
Basile Sauvage's avatar
Basile Sauvage committed
487

488
	VertexAttribute<VertexInfo, MAP> vertexInfo ;
Basile Sauvage's avatar
Basile Sauvage committed
489

Pierre Kraemer's avatar
Pierre Kraemer committed
490
	std::multimap<float, Dart> front ;
Basile Sauvage's avatar
Basile Sauvage committed
491 492

public:
Sylvain Thery's avatar
Sylvain Thery committed
493 494
	Collector_Dijkstra_Vertices(MAP& m, const EdgeAttribute<REAL, MAP>& c, REAL d = 0) :
		Collector<PFP>(m),
495
		edge_cost(c),
Basile Sauvage's avatar
Basile Sauvage committed
496 497
		maxDist(d)
	{
498
		vertexInfo = m.template addAttribute<VertexInfo, VERTEX, typename PFP::MAP>("vertexInfo");
Basile Sauvage's avatar
Basile Sauvage committed
499
	}
500 501
	~Collector_Dijkstra_Vertices()
	{
Basile Sauvage's avatar
Basile Sauvage committed
502 503
		this->map.removeAttribute(vertexInfo);
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
504 505 506
	inline void init (Dart d) { Collector<PFP>::init(d); front.clear(); }
	inline void setMaxDistance(REAL d) { maxDist = d; }
	inline REAL getMaxDist() const { return maxDist; }
Basile Sauvage's avatar
Basile Sauvage committed
507 508 509 510

	void collectAll(Dart d);
	void collectBorder(Dart d);
};
511

Basile Sauvage's avatar
Basile Sauvage committed
512
/*********************************************************
513
 * Collector Dijkstra
Basile Sauvage's avatar
Basile Sauvage committed
514 515 516 517 518 519 520
 *********************************************************/

/*
 * collect all primitives of the connected component containing "centerDart"
 * within a distance < maxDist (the shortest path follows edges)
 */
template <typename PFP>
521
class Collector_Dijkstra : public Collector<PFP>
Basile Sauvage's avatar
Basile Sauvage committed
522
{
Pierre Kraemer's avatar
Pierre Kraemer committed
523 524 525 526
	typedef typename PFP::MAP MAP ;
	typedef typename PFP::VEC3 VEC3;
	typedef typename PFP::REAL REAL;

Basile Sauvage's avatar
Basile Sauvage committed
527
protected:
528
	const VertexAttribute<VEC3, MAP>& position;
Pierre Kraemer's avatar
Pierre Kraemer committed
529
	REAL maxDist;
Basile Sauvage's avatar
Basile Sauvage committed
530 531 532

	typedef struct
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
533
		typename std::multimap<float, Dart>::iterator it ;
Basile Sauvage's avatar
Basile Sauvage committed
534 535 536
		bool valid ;
		static std::string CGoGNnameOfType() { return "DijkstraVertexInfo" ; }
	} DijkstraVertexInfo ;
537
	typedef NoTypeNameAttribute<DijkstraVertexInfo> VertexInfo ;
Basile Sauvage's avatar
Basile Sauvage committed
538

539
	VertexAttribute<VertexInfo, MAP> vertexInfo ;
Basile Sauvage's avatar
Basile Sauvage committed
540

Pierre Kraemer's avatar
Pierre Kraemer committed
541
	std::multimap<float, Dart> front ;
Basile Sauvage's avatar
Basile Sauvage committed
542 543

public:
Sylvain Thery's avatar
Sylvain Thery committed
544 545
	Collector_Dijkstra(MAP& m, const VertexAttribute<VEC3, MAP>& p, REAL d = 0) :
		Collector<PFP>(m),
546
		position(p),
Basile Sauvage's avatar
Basile Sauvage committed
547 548 549 550
		maxDist(d)
	{
		vertexInfo = m.template addAttribute<VertexInfo, VERTEX>("vertexInfo");
	}
551 552
	~Collector_Dijkstra()
	{
Basile Sauvage's avatar
Basile Sauvage committed
553 554
		this->map.removeAttribute(vertexInfo);
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
555 556 557
	inline void init (Dart d) { Collector<PFP>::init(d); front.clear(); }
	inline void setMaxDistance(REAL d) { maxDist = d; }
	inline REAL getMaxDist() const { return maxDist; }
558
	inline const VertexAttribute<VEC3, MAP>& getPosition() const { return position; }
Basile Sauvage's avatar
Basile Sauvage committed
559 560 561

	void collectAll(Dart d);
	void collectBorder(Dart d);
562

563 564 565
private :
	inline float edgeLength (Dart d);
//	inline Dart oppositeVertex (Dart d);
Basile Sauvage's avatar
Basile Sauvage committed
566 567
};

Pierre Kraemer's avatar
Pierre Kraemer committed
568
} // namespace Selection
Basile Sauvage's avatar
Basile Sauvage committed
569

Pierre Kraemer's avatar
Pierre Kraemer committed
570
} // namespace Surface
571

572
} // namespace Algo
Pierre Kraemer's avatar
Pierre Kraemer committed
573

Pierre Kraemer's avatar
Pierre Kraemer committed
574 575 576 577 578
} // namespace CGoGN

#include "Algo/Selection/collector.hpp"

#endif