cellmarker.h 11.8 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
#include "Utils/static_assert.h"
Pierre Kraemer's avatar
Pierre Kraemer committed
32
33
34
35

namespace CGoGN
{

36
class CellMarkerGen
Pierre Kraemer's avatar
Pierre Kraemer committed
37
{
38
39
	friend class GenericMap ;

Pierre Kraemer's avatar
Pierre Kraemer committed
40
protected:
Sylvain Thery's avatar
Sylvain Thery committed
41
	GenericMap& m_map ;
42
	Mark m_mark ;
43
	AttributeMultiVector<Mark>* m_markVector ;
Pierre Kraemer's avatar
Pierre Kraemer committed
44
	unsigned int m_thread ;
45
	unsigned int m_cell ;
46
	bool releaseOnDestruct ;
Pierre Kraemer's avatar
Pierre Kraemer committed
47

48
public:
49
50
51
52
53
	CellMarkerGen(GenericMap& map, unsigned int cell, unsigned int thread = 0) :
		m_map(map),
		m_thread(thread),
		m_cell(cell),
		releaseOnDestruct(true)
54
55
56
57
58
	{}

	virtual ~CellMarkerGen()
	{}

59
60
61
62
63
	unsigned int getThread() { return m_thread ; }
	unsigned int getCell() { return m_cell ; }

	void updateMarkVector(AttributeMultiVector<Mark>* amv) { m_markVector = amv ; }

64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
	/**
	 * set if the mark has to be release on destruction or not
	 */
	void setReleaseOnDestruct(bool b) { releaseOnDestruct = b ; }

	virtual void mark(Dart d) = 0 ;
	virtual void unmark(Dart d) = 0 ;
	virtual bool isMarked(Dart d) const = 0 ;
	virtual void mark(unsigned int em) = 0 ;
	virtual void unmark(unsigned int em) = 0 ;
	virtual bool isMarked(unsigned int em) const = 0 ;
	virtual void markAll() = 0 ;
	virtual void unmarkAll() = 0 ;
	virtual bool isAllUnmarked() = 0 ;
};

/**
 * generic class that allows the marking of cells
 * \warning no default constructor
 */
template <unsigned int CELL>
class CellMarkerBase : public CellMarkerGen
{
Pierre Kraemer's avatar
Pierre Kraemer committed
87
88
89
public:
	/**
	 * constructor
90
	 * @param map the map on which we work
Pierre Kraemer's avatar
Pierre Kraemer committed
91
	 */
92
	CellMarkerBase(GenericMap& map, unsigned int thread = 0) : CellMarkerGen(map, CELL, thread)
Pierre Kraemer's avatar
Pierre Kraemer committed
93
	{
94
95
		if(!map.isOrbitEmbedded<CELL>())
			map.addEmbedding<CELL>() ;
96
97
		m_mark = m_map.getMarkerSet<CELL>(m_thread).getNewMark() ;
		m_markVector = m_map.getMarkVector<CELL>(m_thread) ;
98
		m_map.cellMarkers[m_thread].push_back(this) ;
Sylvain Thery's avatar
Sylvain Thery committed
99
100
	}

101
	virtual ~CellMarkerBase()
Pierre Kraemer's avatar
Pierre Kraemer committed
102
	{
103
104
		if(releaseOnDestruct)
		{
105
			m_map.getMarkerSet<CELL>(m_thread).releaseMark(m_mark) ;
106
107
108

			std::vector<CellMarkerGen*>& cmg = m_map.cellMarkers[m_thread];
			for(std::vector<CellMarkerGen*>::iterator it = cmg.begin(); it != cmg.end(); ++it)
109
110
111
			{
				if(*it == this)
				{
112
113
					*it = cmg.back();
					cmg.pop_back();
114
115
116
117
					return;
				}
			}
		}
Pierre Kraemer's avatar
Pierre Kraemer committed
118
119
120
121
	}

protected:
	// protected copy constructor to forbid its usage
122
	CellMarkerBase(const CellMarkerGen& cm) : CellMarkerGen(cm.m_map, CELL)
Pierre Kraemer's avatar
Pierre Kraemer committed
123
124
125
126
127
128
129
130
	{}

public:
	/**
	 * mark the cell of dart
	 */
	virtual void mark(Dart d)
	{
131
		assert(m_map.getMarkerSet<CELL>(m_thread).testMark(m_mark));
Pierre Kraemer's avatar
Pierre Kraemer committed
132
		assert(m_markVector != NULL);
Sylvain Thery's avatar
Sylvain Thery committed
133

134
		unsigned int a = m_map.getEmbedding<CELL>(d) ;
Sylvain Thery's avatar
Sylvain Thery committed
135
136
		if (a == EMBNULL)
			a = m_map.setOrbitEmbeddingOnNewCell<CELL>(d) ;
137
		m_markVector->operator[](a).setMark(m_mark) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
138
139
140
141
142
143
144
	}

	/**
	 * unmark the cell of dart
	 */
	virtual void unmark(Dart d)
	{
145
146
		assert(m_map.getMarkerSet<CELL>(m_thread).testMark(m_mark));
		assert(m_markVector != NULL);
Sylvain Thery's avatar
Sylvain Thery committed
147

148
		unsigned int a = m_map.getEmbedding<CELL>(d) ;
Sylvain Thery's avatar
Sylvain Thery committed
149
150
		if (a == EMBNULL)
			a = m_map.setOrbitEmbeddingOnNewCell<CELL>(d) ;
151
		m_markVector->operator[](a).unsetMark(m_mark) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
152
153
154
155
156
	}

	/**
	 * test if cell of dart is marked
	 */
157
	virtual bool isMarked(Dart d) const
Pierre Kraemer's avatar
Pierre Kraemer committed
158
	{
159
160
		assert(m_map.getMarkerSet<CELL>(m_thread).testMark(m_mark));
		assert(m_markVector != NULL);
Sylvain Thery's avatar
Sylvain Thery committed
161

162
		unsigned int a = m_map.getEmbedding<CELL>(d) ;
Sylvain Thery's avatar
Sylvain Thery committed
163
164
		if (a == EMBNULL)
			return false ;
165
		return m_markVector->operator[](a).testMark(m_mark) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
166
167
168
169
170
171
172
	}

	/**
	 * mark the cell
	 */
	virtual void mark(unsigned int em)
	{
173
174
		assert(m_map.getMarkerSet<CELL>(m_thread).testMark(m_mark));
		assert(m_markVector != NULL);
Sylvain Thery's avatar
Sylvain Thery committed
175

176
		m_markVector->operator[](em).setMark(m_mark) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
177
178
179
180
181
182
183
	}

	/**
	 * unmark the cell
	 */
	virtual void unmark(unsigned int em)
	{
184
185
		assert(m_map.getMarkerSet<CELL>(m_thread).testMark(m_mark));
		assert(m_markVector != NULL);
Sylvain Thery's avatar
Sylvain Thery committed
186

187
		m_markVector->operator[](em).unsetMark(m_mark) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
188
189
190
191
192
	}

	/**
	 * test if cell is marked
	 */
193
	virtual bool isMarked(unsigned int em) const
Pierre Kraemer's avatar
Pierre Kraemer committed
194
	{
195
196
		assert(m_map.getMarkerSet<CELL>(m_thread).testMark(m_mark));
		assert(m_markVector != NULL);
Sylvain Thery's avatar
Sylvain Thery committed
197

198
		return m_markVector->operator[](em).testMark(m_mark) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
199
200
	}

201
202
203
	/**
	 * mark all the cells
	 */
Pierre Kraemer's avatar
Pierre Kraemer committed
204
205
	virtual void markAll()
	{
206
207
		assert(m_map.getMarkerSet<CELL>(m_thread).testMark(m_mark));
		assert(m_markVector != NULL);
Sylvain Thery's avatar
Sylvain Thery committed
208

209
		AttributeContainer& cont = m_map.getAttributeContainer<CELL>() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
210
		for (unsigned int i = cont.begin(); i != cont.end(); cont.next(i))
211
			m_markVector->operator[](i).setMark(m_mark) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
212
213
	}

214
	virtual bool isAllUnmarked()
Pierre Kraemer's avatar
Pierre Kraemer committed
215
	{
216
217
		assert(m_map.getMarkerSet<CELL>(m_thread).testMark(m_mark));
		assert(m_markVector != NULL);
Sylvain Thery's avatar
Sylvain Thery committed
218

219
		AttributeContainer& cont = m_map.getAttributeContainer<CELL>() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
220
		for (unsigned int i = cont.begin(); i != cont.end(); cont.next(i))
221
			if(m_markVector->operator[](i).testMark(m_mark))
Pierre Kraemer's avatar
Pierre Kraemer committed
222
223
224
				return false ;
		return true ;
	}
225
226
227
228
229
230
};

/**
 * class that allows the marking of cells
 * \warning no default constructor
 */
231
232
template <unsigned int CELL>
class CellMarker : public CellMarkerBase<CELL>
233
234
{
public:
235
	CellMarker(GenericMap& map, unsigned int thread = 0) : CellMarkerBase<CELL>(map, thread)
236
237
238
239
240
241
242
243
	{}

	virtual ~CellMarker()
	{
		unmarkAll() ;
	}

protected:
244
	CellMarker(const CellMarker& cm) : CellMarkerBase<CELL>(cm)
245
246
247
	{}

public:
Pierre Kraemer's avatar
Pierre Kraemer committed
248
249
	virtual void unmarkAll()
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
250
251
		assert(this->m_map.template getMarkerSet<CELL>(this->m_thread).testMark(this->m_mark));
		assert(this->m_markVector != NULL);
Sylvain Thery's avatar
Sylvain Thery committed
252

253
		AttributeContainer& cont = this->m_map.template getAttributeContainer<CELL>() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
254
		for (unsigned int i = cont.begin(); i != cont.end(); cont.next(i))
255
			this->m_markVector->operator[](i).unsetMark(this->m_mark) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
256
257
258
259
260
261
262
263
	}
};

/**
 * class that allows the marking of cells
 * the marked cells are stored to optimize the unmarking task at destruction
 * \warning no default constructor
 */
264
265
template <unsigned int CELL>
class CellMarkerStore: public CellMarkerBase<CELL>
Pierre Kraemer's avatar
Pierre Kraemer committed
266
267
268
269
270
{
protected:
	std::vector<unsigned int> m_markedCells ;

public:
271
	CellMarkerStore(GenericMap& map, unsigned int thread = 0) : CellMarkerBase<CELL>(map, thread)
Pierre Kraemer's avatar
Pierre Kraemer committed
272
273
	{}

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

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

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

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

	void unmarkAll()
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
300
301
		assert(this->m_map.template getMarkerSet<CELL>(this->m_thread).testMark(this->m_mark));
		assert(this->m_markVector != NULL);
Sylvain Thery's avatar
Sylvain Thery committed
302

Pierre Kraemer's avatar
Pierre Kraemer committed
303
		for (std::vector<unsigned int>::iterator it = m_markedCells.begin(); it != m_markedCells.end(); ++it)
304
			this->m_markVector->operator[](*it).unsetMark(this->m_mark) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
305
306
	}
};
pitiot's avatar
pitiot committed
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
/**
 * class that allows the marking of Darts
 * the marked Darts are stored to optimize the unmarking task at destruction
 * \warning no default constructor
 */
template <unsigned int CELL>
class CellMarkerMemo: public CellMarkerBase<CELL>
{
protected:
	std::vector<Dart> m_markedDarts ;

public:
	CellMarkerMemo(GenericMap& map, unsigned int thread = 0) : CellMarkerBase<CELL>(map, thread)
	{}

	virtual ~CellMarkerMemo()
	{
		unmarkAll() ;
//		assert(isAllUnmarked);
		CGoGN_ASSERT(this->isAllUnmarked())
	}

protected:
	CellMarkerMemo(const CellMarkerMemo& cm) : CellMarkerBase<CELL>(cm)
	{}
Pierre Kraemer's avatar
Pierre Kraemer committed
332

pitiot's avatar
pitiot committed
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
public:
	void mark(Dart d)
	{
		if(!this->isMarked(d))
		{
			CellMarkerBase<CELL>::mark(d) ;
			m_markedDarts.push_back(d) ;
		}
	}

	void unmarkAll()
	{
		assert(this->m_map.template getMarkerSet<CELL>(this->m_thread).testMark(this->m_mark));
		assert(this->m_markVector != NULL);

		for (std::vector<Dart>::iterator it = m_markedDarts.begin(); it != m_markedDarts.end(); ++it)
			this->m_markVector->operator[](this->m_map.template getEmbedding<CELL>(*it)).unsetMark(this->m_mark) ;
	}
	std::vector<Dart> get_markedCells()
	{
		return m_markedDarts;
	}
};
Pierre Kraemer's avatar
Pierre Kraemer committed
356
357
358
359
360
/**
 * class that allows the marking of cells
 * the markers are not unmarked at destruction
 * \warning no default constructor
 */
361
362
template <unsigned int CELL>
class CellMarkerNoUnmark: public CellMarkerBase<CELL>
Pierre Kraemer's avatar
Pierre Kraemer committed
363
364
{
public:
365
	CellMarkerNoUnmark(GenericMap& map, unsigned int thread = 0) : CellMarkerBase<CELL>(map, thread)
Pierre Kraemer's avatar
Pierre Kraemer committed
366
	{}
Sylvain Thery's avatar
Sylvain Thery committed
367

Pierre Kraemer's avatar
Pierre Kraemer committed
368
369
	virtual ~CellMarkerNoUnmark()
	{
370
//		assert(isAllUnmarked()) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
371
		CGoGN_ASSERT(this->isAllUnmarked())
Pierre Kraemer's avatar
Pierre Kraemer committed
372
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
373
374

protected:
375
	CellMarkerNoUnmark(const CellMarkerNoUnmark& cm) : CellMarkerBase<CELL>(cm)
Pierre Kraemer's avatar
Pierre Kraemer committed
376
	{}
377
378
379
380

public:
	void unmarkAll()
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
381
382
		assert(this->m_map.template getMarkerSet<CELL>(this->m_thread).testMark(this->m_mark));
		assert(this->m_markVector != NULL);
Sylvain Thery's avatar
Sylvain Thery committed
383

384
		AttributeContainer& cont = this->m_map.template getAttributeContainer<CELL>() ;
385
		for (unsigned int i = cont.begin(); i != cont.end(); cont.next(i))
386
			this->m_markVector->operator[](i).unsetMark(this->m_mark) ;
387
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
388
389
};

Sylvain Thery's avatar
Sylvain Thery committed
390
391

/**
392
 * selector that say if a dart has its cell marked
Sylvain Thery's avatar
Sylvain Thery committed
393
 */
394
template <unsigned int CELL>
395
class SelectorCellMarked : public FunctorSelect
Sylvain Thery's avatar
Sylvain Thery committed
396
397
{
protected:
398
	const CellMarkerBase<CELL>& m_cmarker ;
Sylvain Thery's avatar
Sylvain Thery committed
399
public:
400
	SelectorCellMarked(const CellMarkerBase<CELL>& cm) : m_cmarker(cm) {}
Sylvain Thery's avatar
Sylvain Thery committed
401
402
403
	bool operator()(Dart d) const
	{
		if (m_cmarker.isMarked(d))
404
405
			return true ;
		return false ;
Sylvain Thery's avatar
Sylvain Thery committed
406
	}
407
	FunctorSelect* copy() const { return new SelectorCellMarked(m_cmarker); }
Sylvain Thery's avatar
Sylvain Thery committed
408
409
};

410
template <unsigned int CELL>
411
class SelectorCellUnmarked : public FunctorSelect
412
413
{
protected:
414
	const CellMarkerBase<CELL>& m_cmarker ;
415
public:
416
	SelectorCellUnmarked(const CellMarkerBase<CELL>& cm) : m_cmarker(cm) {}
417
418
419
	bool operator()(Dart d) const
	{
		if (!m_cmarker.isMarked(d))
420
421
			return true ;
		return false ;
422
	}
423
	FunctorSelect* copy() const { return new SelectorCellUnmarked(m_cmarker); }
424
};
Sylvain Thery's avatar
Sylvain Thery committed
425

Thomas's avatar
Thomas committed
426
427
// Functor version (needed for use with foreach_xxx)

428
template <unsigned int CELL>
Thomas's avatar
Thomas committed
429
430
431
class FunctorCellIsMarked : public FunctorType
{
protected:
432
	CellMarkerBase<CELL>& m_marker;
Thomas's avatar
Thomas committed
433
public:
434
	FunctorCellIsMarked(CellMarkerBase<CELL>& cm) : m_marker(cm) {}
Thomas's avatar
Thomas committed
435
436
437
438
439
440
	bool operator()(Dart d)
	{
		return m_marker.isMarked(d);
	}
};

441
template <unsigned int CELL>
Thomas's avatar
Thomas committed
442
443
444
class FunctorCellIsUnmarked : public FunctorType
{
protected:
445
	CellMarkerBase<CELL>& m_marker;
Thomas's avatar
Thomas committed
446
public:
447
	FunctorCellIsUnmarked(CellMarkerBase<CELL>& cm) : m_marker(cm) {}
Thomas's avatar
Thomas committed
448
449
450
451
452
453
	bool operator()(Dart d)
	{
		return !m_marker.isMarked(d);
	}
};

Pierre Kraemer's avatar
Pierre Kraemer committed
454
455
456
} // namespace CGoGN

#endif