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

#ifndef __CELL_MARKER__
#define __CELL_MARKER__

#include "Topology/generic/marker.h"
Sylvain Thery's avatar
Sylvain Thery committed
29
#include "Topology/generic/genericmap.h"
Sylvain Thery's avatar
Sylvain Thery committed
30
#include "Topology/generic/functor.h"
31 32
#include "Algo/Topo/embedding.h"

33
#include "Utils/static_assert.h"
Pierre Kraemer's avatar
Pierre Kraemer committed
34 35 36

namespace CGoGN
{
Sylvain Thery's avatar
Sylvain Thery committed
37 38 39 40
/**
 * @brief The CellMarkerGen class
 * @warning CellMarkerGen is no polymorphic version of CellMarker
 */
41
class CellMarkerGen
Pierre Kraemer's avatar
Pierre Kraemer committed
42
{
43 44
	friend class GenericMap ;

Pierre Kraemer's avatar
Pierre Kraemer committed
45
protected:
Sylvain Thery's avatar
Sylvain Thery committed
46
	AttributeMultiVector<MarkerBool>* m_markVector ;
47
	unsigned int m_cell ;
Pierre Kraemer's avatar
Pierre Kraemer committed
48

49
public:
50
	CellMarkerGen(unsigned int cell, unsigned int thread = 0) :
51
		m_cell(cell)
52 53
	{}

Pierre Kraemer's avatar
Pierre Kraemer committed
54
	virtual ~CellMarkerGen()
55 56
	{}

57 58
	unsigned int getCell() { return m_cell ; }

Sylvain Thery's avatar
Sylvain Thery committed
59
	void updateMarkVector(AttributeMultiVector<MarkerBool>* amv) { m_markVector = amv ; }
60

61 62 63 64 65
protected:
	// protected copy constructor to forbid its usage
	CellMarkerGen(const CellMarkerGen& /*cm*/)
	{}

66 67 68 69 70 71
};

/**
 * generic class that allows the marking of cells
 * \warning no default constructor
 */
72
template <typename MAP, unsigned int CELL>
73 74
class CellMarkerBase : public CellMarkerGen
{
75 76 77
protected:
	MAP& m_map ;

Pierre Kraemer's avatar
Pierre Kraemer committed
78 79 80
public:
	/**
	 * constructor
81
	 * @param map the map on which we work
Pierre Kraemer's avatar
Pierre Kraemer committed
82
	 */
83 84 85
	CellMarkerBase(MAP& map, unsigned int thread = 0) :
		CellMarkerGen(CELL, thread),
		m_map(map)
Pierre Kraemer's avatar
Pierre Kraemer committed
86
	{
87 88
		if(!m_map.template isOrbitEmbedded<CELL>())
			m_map.template addEmbedding<CELL>() ;
Sylvain Thery's avatar
Sylvain Thery committed
89
		m_markVector = m_map.template askMarkVector<CELL>();
Sylvain Thery's avatar
Sylvain Thery committed
90 91
	}

92 93 94
	CellMarkerBase(const MAP& map, unsigned int thread = 0) :
		CellMarkerGen(CELL, thread),
		m_map(const_cast<MAP&>(map))
Sylvain Thery's avatar
Sylvain Thery committed
95
	{
96 97
		if(!m_map.template isOrbitEmbedded<CELL>())
			m_map.template addEmbedding<CELL>() ;
Sylvain Thery's avatar
Sylvain Thery committed
98
		m_markVector = m_map.template askMarkVector<CELL>();
Sylvain Thery's avatar
Sylvain Thery committed
99 100
	}

Pierre Kraemer's avatar
Pierre Kraemer committed
101
	virtual ~CellMarkerBase()
Pierre Kraemer's avatar
Pierre Kraemer committed
102
	{
103
		if (GenericMap::alive(&m_map))
Sylvain Thery's avatar
Sylvain Thery committed
104
			m_map.template releaseMarkVector<CELL>(m_markVector);
Pierre Kraemer's avatar
Pierre Kraemer committed
105 106
	}

Sylvain Thery's avatar
Sylvain Thery committed
107 108 109 110 111 112 113 114
	void update()
	{
		if(!m_map.template isOrbitEmbedded<CELL>())
			m_map.template addEmbedding<CELL>() ;
		m_markVector = m_map.template askMarkVector<CELL>();
	}


Pierre Kraemer's avatar
Pierre Kraemer committed
115 116
protected:
	// protected copy constructor to forbid its usage
117 118 119
	CellMarkerBase(const CellMarkerBase<MAP, CELL>& cm) :
		m_map(cm.m_map),
		CellMarkerGen(CELL)
Pierre Kraemer's avatar
Pierre Kraemer committed
120 121 122 123 124 125
	{}

public:
	/**
	 * mark the cell of dart
	 */
126
	inline void mark(Cell<CELL> c)
Pierre Kraemer's avatar
Pierre Kraemer committed
127
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
128
		assert(m_markVector != NULL);
Sylvain Thery's avatar
Sylvain Thery committed
129

130
		unsigned int a = m_map.getEmbedding(c) ;
131

Sylvain Thery's avatar
Sylvain Thery committed
132
		if (a == EMBNULL)
133 134
			a = Algo::Topo::setOrbitEmbeddingOnNewCell(m_map, c) ;

Sylvain Thery's avatar
Sylvain Thery committed
135
		m_markVector->setTrue(a);
Pierre Kraemer's avatar
Pierre Kraemer committed
136 137 138 139 140
	}

	/**
	 * unmark the cell of dart
	 */
141
	inline void unmark(Cell<CELL> c)
Pierre Kraemer's avatar
Pierre Kraemer committed
142
	{
143
		assert(m_markVector != NULL);
Sylvain Thery's avatar
Sylvain Thery committed
144

145
		unsigned int a = m_map.getEmbedding(c) ;
146

Sylvain Thery's avatar
Sylvain Thery committed
147
		if (a == EMBNULL)
148 149
			a = Algo::Topo::setOrbitEmbeddingOnNewCell(m_map, c) ;

Sylvain Thery's avatar
Sylvain Thery committed
150
		m_markVector->setFalse(a);
Pierre Kraemer's avatar
Pierre Kraemer committed
151 152 153 154 155
	}

	/**
	 * test if cell of dart is marked
	 */
156
	inline bool isMarked(Cell<CELL> c) const
Pierre Kraemer's avatar
Pierre Kraemer committed
157
	{
158
		assert(m_markVector != NULL);
Sylvain Thery's avatar
Sylvain Thery committed
159

160
		unsigned int a = m_map.getEmbedding(c) ;
161

Sylvain Thery's avatar
Sylvain Thery committed
162 163
		if (a == EMBNULL)
			return false ;
164

Sylvain Thery's avatar
Sylvain Thery committed
165
		return m_markVector->operator[](a);
Pierre Kraemer's avatar
Pierre Kraemer committed
166 167 168 169 170
	}

	/**
	 * mark the cell
	 */
Sylvain Thery's avatar
Sylvain Thery committed
171
	inline void mark(unsigned int em)
Pierre Kraemer's avatar
Pierre Kraemer committed
172
	{
173
		assert(m_markVector != NULL);
Sylvain Thery's avatar
Sylvain Thery committed
174
		m_markVector->setTrue(em);
Pierre Kraemer's avatar
Pierre Kraemer committed
175 176 177 178 179
	}

	/**
	 * unmark the cell
	 */
Sylvain Thery's avatar
Sylvain Thery committed
180
	inline void unmark(unsigned int em)
Pierre Kraemer's avatar
Pierre Kraemer committed
181
	{
182
		assert(m_markVector != NULL);
Sylvain Thery's avatar
Sylvain Thery committed
183
		m_markVector->setFalse(em);
Pierre Kraemer's avatar
Pierre Kraemer committed
184 185 186 187 188
	}

	/**
	 * test if cell is marked
	 */
Sylvain Thery's avatar
Sylvain Thery committed
189
	inline bool isMarked(unsigned int em) const
Pierre Kraemer's avatar
Pierre Kraemer committed
190
	{
191
		assert(m_markVector != NULL);
Sylvain Thery's avatar
Sylvain Thery committed
192

Pierre Kraemer's avatar
Pierre Kraemer committed
193 194
		if (em == EMBNULL)
			return false ;
Sylvain Thery's avatar
Sylvain Thery committed
195
		return m_markVector->operator[](em);
Pierre Kraemer's avatar
Pierre Kraemer committed
196 197
	}

198 199 200
	/**
	 * mark all the cells
	 */
Sylvain Thery's avatar
Sylvain Thery committed
201
	inline void markAll()
Pierre Kraemer's avatar
Pierre Kraemer committed
202
	{
203
		assert(m_markVector != NULL);
Sylvain Thery's avatar
Sylvain Thery committed
204
		m_markVector->allFalse();
Pierre Kraemer's avatar
Pierre Kraemer committed
205 206
	}

Sylvain Thery's avatar
Sylvain Thery committed
207
	inline bool isAllUnmarked()
Pierre Kraemer's avatar
Pierre Kraemer committed
208
	{
209
		assert(m_markVector != NULL);
Sylvain Thery's avatar
Sylvain Thery committed
210

211
		AttributeContainer& cont = m_map.template getAttributeContainer<CELL>() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
212
		for (unsigned int i = cont.begin(); i != cont.end(); cont.next(i))
Sylvain Thery's avatar
Sylvain Thery committed
213
			if(m_markVector->operator[](i))
Pierre Kraemer's avatar
Pierre Kraemer committed
214 215 216
				return false ;
		return true ;
	}
217 218 219 220 221 222
};

/**
 * class that allows the marking of cells
 * \warning no default constructor
 */
223 224
template <typename MAP, unsigned int CELL>
class CellMarker : public CellMarkerBase<MAP, CELL>
225 226
{
public:
227
	CellMarker(MAP& map, unsigned int thread = 0) : CellMarkerBase<MAP, CELL>(map, thread)
228 229
	{}

230 231
	CellMarker(const MAP& map, unsigned int thread = 0) :
		CellMarkerBase<MAP, CELL>(map, thread)
Sylvain Thery's avatar
Sylvain Thery committed
232 233
	{}

Pierre Kraemer's avatar
Pierre Kraemer committed
234
	virtual ~CellMarker()
235 236 237 238 239
	{
		unmarkAll() ;
	}

protected:
240 241
	CellMarker(const CellMarker& cm) :
		CellMarkerBase<MAP, CELL>(cm)
242 243 244
	{}

public:
Sylvain Thery's avatar
Sylvain Thery committed
245
	inline void unmarkAll()
Pierre Kraemer's avatar
Pierre Kraemer committed
246
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
247
		assert(this->m_markVector != NULL);
Sylvain Thery's avatar
Sylvain Thery committed
248
		this->m_markVector->allFalse();
Pierre Kraemer's avatar
Pierre Kraemer committed
249 250 251 252 253 254 255 256
	}
};

/**
 * class that allows the marking of cells
 * the marked cells are stored to optimize the unmarking task at destruction
 * \warning no default constructor
 */
257 258
template <typename MAP, unsigned int CELL>
class CellMarkerStore: public CellMarkerBase<MAP, CELL>
Pierre Kraemer's avatar
Pierre Kraemer committed
259 260 261 262 263
{
protected:
	std::vector<unsigned int> m_markedCells ;

public:
264 265
	CellMarkerStore(MAP& map, unsigned int thread = 0) :
		CellMarkerBase<MAP, CELL>(map, thread)
266 267 268
	{
		m_markedCells.reserve(128);
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
269

270 271
	CellMarkerStore(const MAP& map, unsigned int thread = 0) :
		CellMarkerBase<MAP, CELL>(map, thread)
272 273 274
	{
		m_markedCells.reserve(128);
	}
Sylvain Thery's avatar
Sylvain Thery committed
275

Pierre Kraemer's avatar
Pierre Kraemer committed
276
	virtual ~CellMarkerStore()
277
	{
278
		unmarkAll() ;
279
//		assert(isAllUnmarked);
Pierre Kraemer's avatar
Pierre Kraemer committed
280
//		CGoGN_ASSERT(this->isAllUnmarked())
281 282
	}

Pierre Kraemer's avatar
Pierre Kraemer committed
283
protected:
284 285
	CellMarkerStore(const CellMarkerStore& cm) :
		CellMarkerBase<MAP, CELL>(cm)
Pierre Kraemer's avatar
Pierre Kraemer committed
286 287 288
	{}

public:
Pierre Kraemer's avatar
Pierre Kraemer committed
289
	inline void mark(Cell<CELL> d)
Pierre Kraemer's avatar
Pierre Kraemer committed
290
	{
291
		CellMarkerBase<MAP, CELL>::mark(d) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
292
		m_markedCells.push_back(this->m_map.template getEmbedding<CELL>(d)) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
293 294
	}

Sylvain Thery's avatar
Sylvain Thery committed
295
	inline void mark(unsigned int em)
Pierre Kraemer's avatar
Pierre Kraemer committed
296
	{
297
		CellMarkerBase<MAP, CELL>::mark(em) ;
298
		m_markedCells.push_back(em) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
299 300
	}

Sylvain Thery's avatar
Sylvain Thery committed
301
	inline void unmarkAll()
Pierre Kraemer's avatar
Pierre Kraemer committed
302
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
303
		assert(this->m_markVector != NULL);
Sylvain Thery's avatar
Sylvain Thery committed
304

Pierre Kraemer's avatar
Pierre Kraemer committed
305
		for (std::vector<unsigned int>::iterator it = m_markedCells.begin(); it != m_markedCells.end(); ++it)
Sylvain Thery's avatar
Sylvain Thery committed
306
			this->m_markVector->setFalse(*it);
Pierre Kraemer's avatar
Pierre Kraemer committed
307 308
	}
};
309

pitiot's avatar
pitiot committed
310 311 312 313 314
/**
 * class that allows the marking of Darts
 * the marked Darts are stored to optimize the unmarking task at destruction
 * \warning no default constructor
 */
315 316
template <typename MAP, unsigned int CELL>
class CellMarkerMemo: public CellMarkerBase<MAP, CELL>
pitiot's avatar
pitiot committed
317 318 319 320 321
{
protected:
	std::vector<Dart> m_markedDarts ;

public:
322 323
	CellMarkerMemo(MAP& map, unsigned int thread = 0) :
		CellMarkerBase<MAP, CELL>(map, thread)
324 325 326
	{
		m_markedDarts.reserve(128);
	}
pitiot's avatar
pitiot committed
327

328 329
	CellMarkerMemo(const MAP& map, unsigned int thread = 0) :
		CellMarkerBase<MAP, CELL>(map, thread)
330 331 332
	{
		m_markedDarts.reserve(128);
	}
Sylvain Thery's avatar
Sylvain Thery committed
333

Pierre Kraemer's avatar
Pierre Kraemer committed
334
	virtual ~CellMarkerMemo()
pitiot's avatar
pitiot committed
335 336 337
	{
		unmarkAll() ;
//		assert(isAllUnmarked);
Pierre Kraemer's avatar
Pierre Kraemer committed
338
//		CGoGN_ASSERT(this->isAllUnmarked())
pitiot's avatar
pitiot committed
339 340 341
	}

protected:
342 343
	CellMarkerMemo(const CellMarkerMemo& cm) :
		CellMarkerBase<MAP, CELL>(cm)
pitiot's avatar
pitiot committed
344
	{}
Pierre Kraemer's avatar
Pierre Kraemer committed
345

pitiot's avatar
pitiot committed
346
public:
Pierre Kraemer's avatar
Pierre Kraemer committed
347
	inline void mark(Cell<CELL> c)
pitiot's avatar
pitiot committed
348
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
349
		if(!this->isMarked(c))
pitiot's avatar
pitiot committed
350
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
351 352
			CellMarkerBase<MAP, CELL>::mark(c) ;
			m_markedDarts.push_back(c.dart) ;
pitiot's avatar
pitiot committed
353 354 355
		}
	}

Sylvain Thery's avatar
Sylvain Thery committed
356
	inline void unmarkAll()
pitiot's avatar
pitiot committed
357 358 359
	{
		assert(this->m_markVector != NULL);
		for (std::vector<Dart>::iterator it = m_markedDarts.begin(); it != m_markedDarts.end(); ++it)
pitiot's avatar
pitiot committed
360 361 362
		{
			this->unmark(*it) ;
		}
363
		m_markedDarts.clear();
pitiot's avatar
pitiot committed
364

pitiot's avatar
pitiot committed
365
	}
Sylvain Thery's avatar
Sylvain Thery committed
366

367
	inline const std::vector<Dart>& get_markedCells()
pitiot's avatar
pitiot committed
368 369 370 371
	{
		return m_markedDarts;
	}
};
372

Pierre Kraemer's avatar
Pierre Kraemer committed
373 374 375 376 377
/**
 * class that allows the marking of cells
 * the markers are not unmarked at destruction
 * \warning no default constructor
 */
378 379
template <typename MAP, unsigned int CELL>
class CellMarkerNoUnmark: public CellMarkerBase<MAP, CELL>
Pierre Kraemer's avatar
Pierre Kraemer committed
380 381
{
public:
382 383
	CellMarkerNoUnmark(MAP& map, unsigned int thread = 0) :
		CellMarkerBase<MAP, CELL>(map, thread)
Pierre Kraemer's avatar
Pierre Kraemer committed
384
	{}
Sylvain Thery's avatar
Sylvain Thery committed
385

386 387
	CellMarkerNoUnmark(const MAP& map, unsigned int thread = 0) :
		CellMarkerBase<MAP, CELL>(map, thread)
Sylvain Thery's avatar
Sylvain Thery committed
388 389
	{}

Pierre Kraemer's avatar
Pierre Kraemer committed
390
	virtual ~CellMarkerNoUnmark()
Pierre Kraemer's avatar
Pierre Kraemer committed
391
	{
392
//		assert(isAllUnmarked()) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
393
//		CGoGN_ASSERT(this->isAllUnmarked())
Pierre Kraemer's avatar
Pierre Kraemer committed
394
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
395 396

protected:
397 398
	CellMarkerNoUnmark(const CellMarkerNoUnmark& cm) :
		CellMarkerBase<MAP, CELL>(cm)
Pierre Kraemer's avatar
Pierre Kraemer committed
399
	{}
400 401

public:
Sylvain Thery's avatar
Sylvain Thery committed
402
	inline void unmarkAll()
403
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
404
		assert(this->m_markVector != NULL);
Sylvain Thery's avatar
Sylvain Thery committed
405
		this->m_markVector->allFalse();
406
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
407 408
};

409 410
// Selector and count functors testing for marker existence
/********************************************************/
Sylvain Thery's avatar
Sylvain Thery committed
411 412

/**
413
 * selector that say if a dart has its cell marked
Sylvain Thery's avatar
Sylvain Thery committed
414
 */
415
template <typename MAP, unsigned int CELL>
416
class SelectorCellMarked : public FunctorSelect
Sylvain Thery's avatar
Sylvain Thery committed
417 418
{
protected:
419 420
	const CellMarkerBase<MAP, CELL>& m_cmarker ;

Sylvain Thery's avatar
Sylvain Thery committed
421
public:
422 423 424
	SelectorCellMarked(const CellMarkerBase<MAP, CELL>& cm) :
		m_cmarker(cm)
	{}
Sylvain Thery's avatar
Sylvain Thery committed
425

Pierre Kraemer's avatar
Pierre Kraemer committed
426
	inline bool operator()(Cell<CELL> d) const
Sylvain Thery's avatar
Sylvain Thery committed
427 428
	{
		if (m_cmarker.isMarked(d))
429 430
			return true ;
		return false ;
Sylvain Thery's avatar
Sylvain Thery committed
431
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
432

Sylvain Thery's avatar
Sylvain Thery committed
433
	inline FunctorSelect* copy() const { return new SelectorCellMarked(m_cmarker); }
Sylvain Thery's avatar
Sylvain Thery committed
434 435
};

436
template <typename MAP, unsigned int CELL>
437
class SelectorCellUnmarked : public FunctorSelect
438 439
{
protected:
440 441
	const CellMarkerBase<MAP, CELL>& m_cmarker ;

442
public:
443 444 445 446
	SelectorCellUnmarked(const CellMarkerBase<MAP, CELL>& cm) :
		m_cmarker(cm)
	{}

Pierre Kraemer's avatar
Pierre Kraemer committed
447
	inline bool operator()(Cell<CELL> d) const
448 449
	{
		if (!m_cmarker.isMarked(d))
450 451
			return true ;
		return false ;
452
	}
453 454 455 456 457

	inline FunctorSelect* copy() const
	{
		return new SelectorCellUnmarked(m_cmarker);
	}
458
};
Sylvain Thery's avatar
Sylvain Thery committed
459

Thomas's avatar
Thomas committed
460 461
// Functor version (needed for use with foreach_xxx)

462
template <typename MAP, unsigned int CELL>
Thomas's avatar
Thomas committed
463 464 465
class FunctorCellIsMarked : public FunctorType
{
protected:
466 467
	CellMarkerBase<MAP, CELL>& m_marker;

Thomas's avatar
Thomas committed
468
public:
469 470 471 472
	FunctorCellIsMarked(CellMarkerBase<MAP, CELL>& cm) :
		m_marker(cm)
	{}

Pierre Kraemer's avatar
Pierre Kraemer committed
473
	inline bool operator()(Cell<CELL> d)
Thomas's avatar
Thomas committed
474 475 476 477 478
	{
		return m_marker.isMarked(d);
	}
};

479
template <typename MAP, unsigned int CELL>
Thomas's avatar
Thomas committed
480 481 482
class FunctorCellIsUnmarked : public FunctorType
{
protected:
483
	CellMarkerBase<MAP, CELL>& m_marker;
Thomas's avatar
Thomas committed
484
public:
485 486 487 488
	FunctorCellIsUnmarked(CellMarkerBase<MAP, CELL>& cm) :
		m_marker(cm)
	{}

Pierre Kraemer's avatar
Pierre Kraemer committed
489
	inline bool operator()(Cell<CELL> d)
Thomas's avatar
Thomas committed
490 491 492 493 494
	{
		return !m_marker.isMarked(d);
	}
};

Pierre Kraemer's avatar
Pierre Kraemer committed
495 496 497
} // namespace CGoGN

#endif