cellmarker.h 10.7 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.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
109
110
111
112
113
114
115
			for(std::vector<CellMarkerGen*>::iterator it = m_map.cellMarkers.begin(); it != m_map.cellMarkers.end(); ++it)
			{
				if(*it == this)
				{
					*it = m_map.cellMarkers.back();
					m_map.cellMarkers.pop_back();
					return;
				}
			}
		}
Pierre Kraemer's avatar
Pierre Kraemer committed
116
117
118
119
	}

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

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

132
		unsigned int a = m_map.getEmbedding<CELL>(d) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
133
		if (a == EMBNULL)
134
			a = m_map.embedNewCell<CELL>(d) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
135

136
		m_markVector->operator[](a).setMark(m_mark) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
137
138
139
140
141
142
143
	}

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

147
		unsigned int a = m_map.getEmbedding<CELL>(d) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
148
		if (a == EMBNULL)
149
			a = m_map.embedNewCell<CELL>(d) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
150

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) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
163
		if (a == EMBNULL)
Pierre Kraemer's avatar
Pierre Kraemer committed
164
			return false ;
Pierre Kraemer's avatar
Pierre Kraemer committed
165

166
		return m_markVector->operator[](a).testMark(m_mark) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
167
168
169
170
171
172
173
	}

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

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

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

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

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

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

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

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

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

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

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

	virtual ~CellMarker()
	{
		unmarkAll() ;
	}

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

public:
Pierre Kraemer's avatar
Pierre Kraemer committed
249
250
	virtual void unmarkAll()
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
251
252
		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
253

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

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

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

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

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

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

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

	void unmarkAll()
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
301
302
		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
303

Pierre Kraemer's avatar
Pierre Kraemer committed
304
		for (std::vector<unsigned int>::iterator it = m_markedCells.begin(); it != m_markedCells.end(); ++it)
305
			this->m_markVector->operator[](*it).unsetMark(this->m_mark) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
306
307
308
309
310
311
312
313
	}
};

/**
 * class that allows the marking of cells
 * the markers are not unmarked at destruction
 * \warning no default constructor
 */
314
315
template <unsigned int CELL>
class CellMarkerNoUnmark: public CellMarkerBase<CELL>
Pierre Kraemer's avatar
Pierre Kraemer committed
316
317
{
public:
318
	CellMarkerNoUnmark(GenericMap& map, unsigned int thread = 0) : CellMarkerBase<CELL>(map, thread)
Pierre Kraemer's avatar
Pierre Kraemer committed
319
	{}
Sylvain Thery's avatar
Sylvain Thery committed
320

Pierre Kraemer's avatar
Pierre Kraemer committed
321
322
	virtual ~CellMarkerNoUnmark()
	{
323
//		assert(isAllUnmarked()) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
324
		CGoGN_ASSERT(this->isAllUnmarked())
Pierre Kraemer's avatar
Pierre Kraemer committed
325
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
326
327

protected:
328
	CellMarkerNoUnmark(const CellMarkerNoUnmark& cm) : CellMarkerBase<CELL>(cm)
Pierre Kraemer's avatar
Pierre Kraemer committed
329
	{}
330
331
332
333

public:
	void unmarkAll()
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
334
335
		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
336

337
		AttributeContainer& cont = this->m_map.template getAttributeContainer<CELL>() ;
338
		for (unsigned int i = cont.begin(); i != cont.end(); cont.next(i))
339
			this->m_markVector->operator[](i).unsetMark(this->m_mark) ;
340
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
341
342
};

Sylvain Thery's avatar
Sylvain Thery committed
343
344

/**
345
 * selector that say if a dart has its cell marked
Sylvain Thery's avatar
Sylvain Thery committed
346
 */
347
template <unsigned int CELL>
348
class SelectorCellMarked : public FunctorSelect
Sylvain Thery's avatar
Sylvain Thery committed
349
350
{
protected:
351
	const CellMarkerBase<CELL>& m_cmarker ;
Sylvain Thery's avatar
Sylvain Thery committed
352
public:
353
	SelectorCellMarked(const CellMarkerBase<CELL>& cm) : m_cmarker(cm) {}
Sylvain Thery's avatar
Sylvain Thery committed
354
355
356
	bool operator()(Dart d) const
	{
		if (m_cmarker.isMarked(d))
357
358
			return true ;
		return false ;
Sylvain Thery's avatar
Sylvain Thery committed
359
	}
360
	FunctorSelect* copy() const { return new SelectorCellMarked(m_cmarker); }
Sylvain Thery's avatar
Sylvain Thery committed
361
362
};

363
template <unsigned int CELL>
364
class SelectorCellUnmarked : public FunctorSelect
365
366
{
protected:
367
	const CellMarkerBase<CELL>& m_cmarker ;
368
public:
369
	SelectorCellUnmarked(const CellMarkerBase<CELL>& cm) : m_cmarker(cm) {}
370
371
372
	bool operator()(Dart d) const
	{
		if (!m_cmarker.isMarked(d))
373
374
			return true ;
		return false ;
375
	}
376
	FunctorSelect* copy() const { return new SelectorCellUnmarked(m_cmarker); }
377
};
Sylvain Thery's avatar
Sylvain Thery committed
378

Thomas's avatar
Thomas committed
379
380
// Functor version (needed for use with foreach_xxx)

381
template <unsigned int CELL>
Thomas's avatar
Thomas committed
382
383
384
class FunctorCellIsMarked : public FunctorType
{
protected:
385
	CellMarkerBase<CELL>& m_marker;
Thomas's avatar
Thomas committed
386
public:
387
	FunctorCellIsMarked(CellMarkerBase<CELL>& cm) : m_marker(cm) {}
Thomas's avatar
Thomas committed
388
389
390
391
392
393
	bool operator()(Dart d)
	{
		return m_marker.isMarked(d);
	}
};

394
template <unsigned int CELL>
Thomas's avatar
Thomas committed
395
396
397
class FunctorCellIsUnmarked : public FunctorType
{
protected:
398
	CellMarkerBase<CELL>& m_marker;
Thomas's avatar
Thomas committed
399
public:
400
	FunctorCellIsUnmarked(CellMarkerBase<CELL>& cm) : m_marker(cm) {}
Thomas's avatar
Thomas committed
401
402
403
404
405
406
	bool operator()(Dart d)
	{
		return !m_marker.isMarked(d);
	}
};

Pierre Kraemer's avatar
Pierre Kraemer committed
407
408
409
} // namespace CGoGN

#endif