cellmarker.h 10.2 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-2011, 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.u-strasbg.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 36

namespace CGoGN
{

/**
37
 * generic class that allows the marking of cells
Pierre Kraemer's avatar
Pierre Kraemer committed
38 39
 * \warning no default constructor
 */
40
class CellMarkerGen
Pierre Kraemer's avatar
Pierre Kraemer committed
41
{
42 43
	friend class GenericMap ;

Pierre Kraemer's avatar
Pierre Kraemer committed
44
protected:
Sylvain Thery's avatar
Sylvain Thery committed
45
	GenericMap& m_map ;
46
	Mark m_mark ;
Pierre Kraemer's avatar
Pierre Kraemer committed
47 48
	unsigned int m_cell ;
	unsigned int m_thread ;
49
	bool releaseOnDestruct ;
Pierre Kraemer's avatar
Pierre Kraemer committed
50 51 52 53

public:
	/**
	 * constructor
54
	 * @param map the map on which we work
55
	 * @param cell the type of cell we want to mark VERTEX, EDGE,...
Pierre Kraemer's avatar
Pierre Kraemer committed
56
	 */
57
	CellMarkerGen(GenericMap& map, unsigned int cell, unsigned int thread = 0) : m_map(map), m_cell(cell), m_thread(thread), releaseOnDestruct(true)
Pierre Kraemer's avatar
Pierre Kraemer committed
58
	{
59 60
		if(!map.isOrbitEmbedded(cell))
			map.addEmbedding(cell) ;
61 62
		m_mark = m_map.getMarkerSet(m_cell, m_thread).getNewMark() ;
		m_map.cellMarkers.push_back(this) ;
Sylvain Thery's avatar
Sylvain Thery committed
63 64
	}

65
	virtual ~CellMarkerGen()
Pierre Kraemer's avatar
Pierre Kraemer committed
66
	{
67 68 69 70 71 72 73 74 75 76 77 78 79
		if(releaseOnDestruct)
		{
			m_map.getMarkerSet(m_cell, m_thread).releaseMark(m_mark) ;
			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
80 81 82 83
	}

protected:
	// protected copy constructor to forbid its usage
84
	CellMarkerGen(const CellMarkerGen& cm) : m_map(cm.m_map)
Pierre Kraemer's avatar
Pierre Kraemer committed
85 86
	{}

87 88 89 90 91
	/**
	 * set if the mark has to be release on destruction or not
	 */
	void setReleaseOnDestruct(bool b) { releaseOnDestruct = b ; }

Pierre Kraemer's avatar
Pierre Kraemer committed
92 93 94 95 96 97
public:
	/**
	 * mark the cell of dart
	 */
	virtual void mark(Dart d)
	{
98
		assert(m_map.getMarkerSet(m_cell, m_thread).testMark(m_mark));
Sylvain Thery's avatar
Sylvain Thery committed
99 100
		assert(m_map.getMarkVector(m_cell, m_thread) != NULL);

Pierre Kraemer's avatar
Pierre Kraemer committed
101
		unsigned int a = m_map.getEmbedding(m_cell, d) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
102
		if (a == EMBNULL)
Pierre Kraemer's avatar
Pierre Kraemer committed
103
			a = m_map.embedNewCell(m_cell, d) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
104

Pierre Kraemer's avatar
Pierre Kraemer committed
105
		m_map.getMarkVector(m_cell, m_thread)->operator[](a).setMark(m_mark) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
106 107 108 109 110 111 112
	}

	/**
	 * unmark the cell of dart
	 */
	virtual void unmark(Dart d)
	{
113
		assert(m_map.getMarkerSet(m_cell, m_thread).testMark(m_mark));
Sylvain Thery's avatar
Sylvain Thery committed
114 115
		assert(m_map.getMarkVector(m_cell, m_thread) != NULL);

Pierre Kraemer's avatar
Pierre Kraemer committed
116
		unsigned int a = m_map.getEmbedding(m_cell, d) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
117
		if (a == EMBNULL)
Pierre Kraemer's avatar
Pierre Kraemer committed
118
			a = m_map.embedNewCell(m_cell, d) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
119

Pierre Kraemer's avatar
Pierre Kraemer committed
120
		m_map.getMarkVector(m_cell, m_thread)->operator[](a).unsetMark(m_mark) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
121 122 123 124 125
	}

	/**
	 * test if cell of dart is marked
	 */
126
	virtual bool isMarked(Dart d) const
Pierre Kraemer's avatar
Pierre Kraemer committed
127
	{
128
		assert(m_map.getMarkerSet(m_cell, m_thread).testMark(m_mark));
Sylvain Thery's avatar
Sylvain Thery committed
129 130
		assert(m_map.getMarkVector(m_cell, m_thread) != NULL);

Pierre Kraemer's avatar
Pierre Kraemer committed
131
		unsigned int a = m_map.getEmbedding(m_cell, d) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
132
		if (a == EMBNULL)
Pierre Kraemer's avatar
Pierre Kraemer committed
133
			return false ;
Pierre Kraemer's avatar
Pierre Kraemer committed
134

Pierre Kraemer's avatar
Pierre Kraemer committed
135
		return m_map.getMarkVector(m_cell, m_thread)->operator[](a).testMark(m_mark) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
136 137 138 139 140 141 142
	}

	/**
	 * mark the cell
	 */
	virtual void mark(unsigned int em)
	{
143
		assert(m_map.getMarkerSet(m_cell, m_thread).testMark(m_mark));
Sylvain Thery's avatar
Sylvain Thery committed
144 145
		assert(m_map.getMarkVector(m_cell, m_thread) != NULL);

Pierre Kraemer's avatar
Pierre Kraemer committed
146
		m_map.getMarkVector(m_cell, m_thread)->operator[](em).setMark(m_mark) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
147 148 149 150 151 152 153
	}

	/**
	 * unmark the cell
	 */
	virtual void unmark(unsigned int em)
	{
154
		assert(m_map.getMarkerSet(m_cell, m_thread).testMark(m_mark));
Sylvain Thery's avatar
Sylvain Thery committed
155 156
		assert(m_map.getMarkVector(m_cell, m_thread) != NULL);

Pierre Kraemer's avatar
Pierre Kraemer committed
157
		m_map.getMarkVector(m_cell, m_thread)->operator[](em).unsetMark(m_mark) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
158 159 160 161 162
	}

	/**
	 * test if cell is marked
	 */
163
	virtual bool isMarked(unsigned int em) const
Pierre Kraemer's avatar
Pierre Kraemer committed
164
	{
165
		assert(m_map.getMarkerSet(m_cell, m_thread).testMark(m_mark));
Sylvain Thery's avatar
Sylvain Thery committed
166 167
		assert(m_map.getMarkVector(m_cell, m_thread) != NULL);

Pierre Kraemer's avatar
Pierre Kraemer committed
168
		return m_map.getMarkVector(m_cell, m_thread)->operator[](em).testMark(m_mark) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
169 170
	}

171 172 173
	/**
	 * mark all the cells
	 */
Pierre Kraemer's avatar
Pierre Kraemer committed
174 175
	virtual void markAll()
	{
176
		assert(m_map.getMarkerSet(m_cell, m_thread).testMark(m_mark));
Sylvain Thery's avatar
Sylvain Thery committed
177 178 179
		AttributeMultiVector<Mark>* mark_vect = m_map.getMarkVector(m_cell, m_thread);
		assert(mark_vect != NULL);

Pierre Kraemer's avatar
Pierre Kraemer committed
180
		AttributeContainer& cont = m_map.getAttributeContainer(m_cell) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
181
		for (unsigned int i = cont.begin(); i != cont.end(); cont.next(i))
Sylvain Thery's avatar
Sylvain Thery committed
182
			mark_vect->operator[](i).setMark(m_mark) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
183 184
	}

185 186 187 188
	/**
	 * unmark all the cells
	 */
	virtual void unmarkAll() = 0 ;
Pierre Kraemer's avatar
Pierre Kraemer committed
189 190 191

	bool isAllUnmarked()
	{
192
		assert(m_map.getMarkerSet(m_cell, m_thread).testMark(m_mark));
Sylvain Thery's avatar
Sylvain Thery committed
193 194 195 196

		AttributeMultiVector<Mark>* mark_vect = m_map.getMarkVector(m_cell, m_thread);
		assert(mark_vect != NULL);

Pierre Kraemer's avatar
Pierre Kraemer committed
197 198
		AttributeContainer& cont = m_map.getAttributeContainer(m_cell) ;
		for (unsigned int i = cont.begin(); i != cont.end(); cont.next(i))
Sylvain Thery's avatar
Sylvain Thery committed
199
			if(mark_vect->operator[](i).testMark(m_mark))
Pierre Kraemer's avatar
Pierre Kraemer committed
200 201 202
				return false ;
		return true ;
	}
203 204 205 206 207 208 209 210 211
};

/**
 * class that allows the marking of cells
 * \warning no default constructor
 */
class CellMarker : public CellMarkerGen
{
public:
Sylvain Thery's avatar
Sylvain Thery committed
212
	CellMarker(GenericMap& map, unsigned int cell, unsigned int thread = 0) : CellMarkerGen(map, cell, thread)
213 214 215 216 217 218 219 220 221 222 223 224
	{}

	virtual ~CellMarker()
	{
		unmarkAll() ;
	}

protected:
	CellMarker(const CellMarker& cm) : CellMarkerGen(cm)
	{}

public:
Pierre Kraemer's avatar
Pierre Kraemer committed
225 226
	virtual void unmarkAll()
	{
227
		assert(m_map.getMarkerSet(m_cell, m_thread).testMark(m_mark));
Sylvain Thery's avatar
Sylvain Thery committed
228 229 230
		AttributeMultiVector<Mark>* mark_vect = m_map.getMarkVector(m_cell, m_thread);
		assert(mark_vect != NULL);

Pierre Kraemer's avatar
Pierre Kraemer committed
231
		AttributeContainer& cont = m_map.getAttributeContainer(m_cell) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
232
		for (unsigned int i = cont.begin(); i != cont.end(); cont.next(i))
Sylvain Thery's avatar
Sylvain Thery committed
233
			mark_vect->operator[](i).unsetMark(m_mark) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
234 235 236 237 238 239 240 241
	}
};

/**
 * class that allows the marking of cells
 * the marked cells are stored to optimize the unmarking task at destruction
 * \warning no default constructor
 */
242
class CellMarkerStore: public CellMarkerGen
Pierre Kraemer's avatar
Pierre Kraemer committed
243 244 245 246 247
{
protected:
	std::vector<unsigned int> m_markedCells ;

public:
Sylvain Thery's avatar
Sylvain Thery committed
248
	CellMarkerStore(GenericMap& map, unsigned int cell, unsigned int thread = 0) : CellMarkerGen(map, cell, thread)
Pierre Kraemer's avatar
Pierre Kraemer committed
249 250
	{}

251

Pierre Kraemer's avatar
Pierre Kraemer committed
252
	virtual ~CellMarkerStore()
253
	{
254
		unmarkAll() ;
255 256
//		assert(isAllUnmarked);
		CGoGN_ASSERT(isAllUnmarked())
257 258
	}

Pierre Kraemer's avatar
Pierre Kraemer committed
259
protected:
260
	CellMarkerStore(const CellMarkerStore& cm) : CellMarkerGen(cm)
Pierre Kraemer's avatar
Pierre Kraemer committed
261 262 263 264 265
	{}

public:
	void mark(Dart d)
	{
266
		CellMarkerGen::mark(d) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
267
		m_markedCells.push_back(m_map.getEmbedding(m_cell, d)) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
268 269 270 271
	}

	void mark(unsigned int em)
	{
272 273
		CellMarkerGen::mark(em) ;
		m_markedCells.push_back(em) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
274 275 276 277
	}

	void unmarkAll()
	{
278
		assert(m_map.getMarkerSet(m_cell, m_thread).testMark(m_mark));
Sylvain Thery's avatar
Sylvain Thery committed
279 280 281
		AttributeMultiVector<Mark>* mark_vect = m_map.getMarkVector(m_cell, m_thread);
		assert(mark_vect != NULL);

Pierre Kraemer's avatar
Pierre Kraemer committed
282
		for (std::vector<unsigned int>::iterator it = m_markedCells.begin(); it != m_markedCells.end(); ++it)
Sylvain Thery's avatar
Sylvain Thery committed
283
			mark_vect->operator[](*it).unsetMark(m_mark) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
284 285 286 287 288 289 290 291
	}
};

/**
 * class that allows the marking of cells
 * the markers are not unmarked at destruction
 * \warning no default constructor
 */
292
class CellMarkerNoUnmark: public CellMarkerGen
Pierre Kraemer's avatar
Pierre Kraemer committed
293 294
{
public:
Sylvain Thery's avatar
Sylvain Thery committed
295
	CellMarkerNoUnmark(GenericMap& map, unsigned int cell, unsigned int thread = 0) : CellMarkerGen(map, cell, thread)
Pierre Kraemer's avatar
Pierre Kraemer committed
296
	{}
Sylvain Thery's avatar
Sylvain Thery committed
297

Pierre Kraemer's avatar
Pierre Kraemer committed
298 299
	virtual ~CellMarkerNoUnmark()
	{
300 301
//		assert(isAllUnmarked()) ;
		CGoGN_ASSERT(isAllUnmarked())
Pierre Kraemer's avatar
Pierre Kraemer committed
302
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
303 304

protected:
305
	CellMarkerNoUnmark(const CellMarkerNoUnmark& cm) : CellMarkerGen(cm)
Pierre Kraemer's avatar
Pierre Kraemer committed
306
	{}
307 308 309 310

public:
	void unmarkAll()
	{
311
		assert(m_map.getMarkerSet(m_cell, m_thread).testMark(m_mark));
Sylvain Thery's avatar
Sylvain Thery committed
312 313 314
		AttributeMultiVector<Mark>* mark_vect = m_map.getMarkVector(m_cell, m_thread);
		assert(mark_vect != NULL);

Pierre Kraemer's avatar
Pierre Kraemer committed
315
		AttributeContainer& cont = m_map.getAttributeContainer(m_cell) ;
316
		for (unsigned int i = cont.begin(); i != cont.end(); cont.next(i))
Sylvain Thery's avatar
Sylvain Thery committed
317
			mark_vect->operator[](i).unsetMark(m_mark) ;
318
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
319 320
};

Sylvain Thery's avatar
Sylvain Thery committed
321 322

/**
323
 * selector that say if a dart has its cell marked
Sylvain Thery's avatar
Sylvain Thery committed
324
 */
325
class SelectorCellMarked : public FunctorSelect
Sylvain Thery's avatar
Sylvain Thery committed
326 327
{
protected:
328
	const CellMarkerGen& m_cmarker ;
Sylvain Thery's avatar
Sylvain Thery committed
329
public:
330
	SelectorCellMarked(const CellMarkerGen& cm) : m_cmarker(cm) {}
Sylvain Thery's avatar
Sylvain Thery committed
331 332 333
	bool operator()(Dart d) const
	{
		if (m_cmarker.isMarked(d))
334 335
			return true ;
		return false ;
Sylvain Thery's avatar
Sylvain Thery committed
336
	}
337
	FunctorSelect* copy() const { return new SelectorCellMarked(m_cmarker);}
Sylvain Thery's avatar
Sylvain Thery committed
338 339
};

340
class SelectorCellUnmarked : public FunctorSelect
341 342
{
protected:
343
	const CellMarkerGen& m_cmarker ;
344
public:
345
	SelectorCellUnmarked(const CellMarkerGen& cm) : m_cmarker(cm) {}
346 347 348
	bool operator()(Dart d) const
	{
		if (!m_cmarker.isMarked(d))
349 350
			return true ;
		return false ;
351
	}
352
	FunctorSelect* copy() const { return new SelectorCellUnmarked(m_cmarker);}
353
};
Sylvain Thery's avatar
Sylvain Thery committed
354

Thomas's avatar
Thomas committed
355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380
// Functor version (needed for use with foreach_xxx)

class FunctorCellIsMarked : public FunctorType
{
protected:
	CellMarkerGen& m_marker;
public:
	FunctorCellIsMarked(CellMarkerGen& cm) : m_marker(cm) {}
	bool operator()(Dart d)
	{
		return m_marker.isMarked(d);
	}
};

class FunctorCellIsUnmarked : public FunctorType
{
protected:
	CellMarkerGen& m_marker;
public:
	FunctorCellIsUnmarked(CellMarkerGen& cm) : m_marker(cm) {}
	bool operator()(Dart d)
	{
		return !m_marker.isMarked(d);
	}
};

Pierre Kraemer's avatar
Pierre Kraemer committed
381 382 383
} // namespace CGoGN

#endif