genericmap.hpp 17.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-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
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

25 26
#include "Topology/generic/dartmarker.h"
#include "Topology/generic/traversorCell.h"
27
#include "Topology/generic/traversorFactory.h"
28

Pierre Kraemer's avatar
Pierre Kraemer committed
29 30
namespace CGoGN
{
Pierre Kraemer's avatar
Pierre Kraemer committed
31

Pierre Kraemer's avatar
Pierre Kraemer committed
32 33 34 35 36 37
/****************************************
 *           DARTS MANAGEMENT           *
 ****************************************/

inline Dart GenericMap::newDart()
{
38
	unsigned int di = m_attribs[DART].insertLine();		// insert a new dart line
Pierre Kraemer's avatar
Pierre Kraemer committed
39
	for(unsigned int i = 0; i < NB_ORBITS; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
40
	{
41 42
		if (m_embeddings[i])							// set all its embeddings
			(*m_embeddings[i])[di] = EMBNULL ;			// to EMBNULL
Pierre Kraemer's avatar
Pierre Kraemer committed
43
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
44

Pierre Kraemer's avatar
Pierre Kraemer committed
45
	return Dart::create(di) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
46 47
}

Pierre Kraemer's avatar
Pierre Kraemer committed
48 49 50 51 52
inline void GenericMap::deleteDartLine(unsigned int index)
{
	m_attribs[DART].removeLine(index) ;	// free the dart line

	for (unsigned int t = 0; t < m_nbThreads; ++t)	// clear markers of
53
		(*m_markTables[DART][t])[index].clear() ;	// the removed dart
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
54

Pierre Kraemer's avatar
Pierre Kraemer committed
55 56
	for(unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit)
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
57
		if (m_embeddings[orbit])									// for each embedded orbit
Pierre Kraemer's avatar
Pierre Kraemer committed
58
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
59
			unsigned int emb = (*m_embeddings[orbit])[index] ;		// get the embedding of the dart
Pierre Kraemer's avatar
Pierre Kraemer committed
60
			if(emb != EMBNULL)
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
61
			{
Pierre Kraemer's avatar
Pierre Kraemer committed
62
				if(m_attribs[orbit].unrefLine(emb))					// unref the pointed embedding line
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
63
				{
Pierre Kraemer's avatar
Pierre Kraemer committed
64
					for (unsigned int t = 0; t < m_nbThreads; ++t)	// and clear its markers if it was
65
						(*m_markTables[orbit][t])[emb].clear() ;	// its last unref (and was thus freed)
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
66 67
				}
			}
Pierre Kraemer's avatar
Pierre Kraemer committed
68 69
		}
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
70
}
Pierre Kraemer's avatar
Pierre Kraemer committed
71

Pierre Kraemer's avatar
Pierre Kraemer committed
72
inline unsigned int GenericMap::copyDartLine(unsigned int index)
Pierre Kraemer's avatar
Pierre Kraemer committed
73
{
74 75
	unsigned int newindex = m_attribs[DART].insertLine() ;	// create a new dart line
	m_attribs[DART].copyLine(newindex, index) ;				// copy the given dart line
Pierre Kraemer's avatar
Pierre Kraemer committed
76 77
	for(unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit)
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
78 79 80 81 82 83
		if (m_embeddings[orbit])
		{
			unsigned int emb = (*m_embeddings[orbit])[newindex] ;	// add a ref to the cells pointed
			if(emb != EMBNULL)										// by the new dart line
				m_attribs[orbit].refLine(emb) ;
		}
Pierre Kraemer's avatar
Pierre Kraemer committed
84 85
	}
	return newindex ;
Pierre Kraemer's avatar
Pierre Kraemer committed
86 87
}

Pierre Kraemer's avatar
Pierre Kraemer committed
88 89
inline unsigned int GenericMap::getNbDarts()
{
90
	return m_attribs[DART].size() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
91 92
}

93 94 95 96
//inline bool GenericMap::isDartValid(Dart d)
//{
//	return !d.isNil() && m_attribs[DART].used(dartIndex(d)) ;
//}
Pierre Kraemer's avatar
Pierre Kraemer committed
97

Pierre Kraemer's avatar
Pierre Kraemer committed
98 99 100 101
/****************************************
 *         EMBEDDING MANAGEMENT         *
 ****************************************/

102 103
template <unsigned int ORBIT>
inline bool GenericMap::isOrbitEmbedded() const
Pierre Kraemer's avatar
Pierre Kraemer committed
104
{
105
	return (ORBIT == DART) || (m_embeddings[ORBIT] != NULL) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
106 107
}

108
inline bool GenericMap::isOrbitEmbedded(unsigned int orbit) const
Pierre Kraemer's avatar
Pierre Kraemer committed
109
{
110
	return (orbit == DART) || (m_embeddings[orbit] != NULL) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
111 112
}

113 114
template <unsigned int ORBIT>
inline unsigned int GenericMap::newCell()
Pierre Kraemer's avatar
Pierre Kraemer committed
115
{
116
	assert(isOrbitEmbedded<ORBIT>() || !"Invalid parameter: orbit not embedded");
117
	return m_attribs[ORBIT].insertLine();
Pierre Kraemer's avatar
Pierre Kraemer committed
118 119
}

120 121
template <unsigned int ORBIT>
inline void GenericMap::copyCell(unsigned int i, unsigned int j)
Pierre Kraemer's avatar
Pierre Kraemer committed
122
{
123
	assert(isOrbitEmbedded<ORBIT>() || !"Invalid parameter: orbit not embedded");
124
	m_attribs[ORBIT].copyLine(i, j) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
125 126
}

127 128
template <unsigned int ORBIT>
inline void GenericMap::initCell(unsigned int i)
Pierre Kraemer's avatar
Pierre Kraemer committed
129
{
130
	assert(isOrbitEmbedded<ORBIT>() || !"Invalid parameter: orbit not embedded");
131
	m_attribs[ORBIT].initLine(i) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
132 133
}

Pierre Kraemer's avatar
Pierre Kraemer committed
134 135 136 137 138 139 140
/****************************************
 *     QUICK TRAVERSAL MANAGEMENT       *
 ****************************************/

template <unsigned int ORBIT>
inline void GenericMap::enableQuickTraversal()
{
Sylvain Thery's avatar
Sylvain Thery committed
141

Pierre Kraemer's avatar
Pierre Kraemer committed
142 143 144 145 146 147 148 149 150 151
	if(m_quickTraversal[ORBIT] == NULL)
	{
		if(!isOrbitEmbedded<ORBIT>())
			addEmbedding<ORBIT>() ;
		m_quickTraversal[ORBIT] = m_attribs[ORBIT].addAttribute<Dart>("quick_traversal") ;
	}
	updateQuickTraversal<ORBIT>() ;
}

template <unsigned int ORBIT>
152
inline void GenericMap::updateQuickTraversal()
Pierre Kraemer's avatar
Pierre Kraemer committed
153
{
Pierre Kraemer's avatar
Pierre Kraemer committed
154 155
	assert(m_quickTraversal[ORBIT] != NULL || !"updateQuickTraversal on a disabled orbit") ;

156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
//	CellMarker<ORBIT> cm(*this) ;
//	for(Dart d = begin(); d != end(); next(d))
//	{
//		if ((!cm.isMarked(d)) && (!isBoundaryMarkedCurrent(d)))
//		{
//			cm.mark(d) ;
//			(*m_quickTraversal[ORBIT])[getEmbedding<ORBIT>(d)] = d ;
//		}
//	}

	// ensure that we do not try to use quick traversal in Traversors
	AttributeMultiVector<Dart>* qt = m_quickTraversal[ORBIT];
	m_quickTraversal[ORBIT] = NULL;

	// fill the quick travsersal
	TraversorCell<GenericMap,VOLUME> trav(*this);
	for(Dart d = trav.begin(); d != trav.end(); d=trav.next())
Pierre Kraemer's avatar
Pierre Kraemer committed
173
	{
174
		(*qt)[getEmbedding<ORBIT>(d)] = d ;
Pierre Kraemer's avatar
Pierre Kraemer committed
175
	}
176 177 178 179

	// restore ptr
	m_quickTraversal[ORBIT] = qt;

Pierre Kraemer's avatar
Pierre Kraemer committed
180 181 182
}

template <unsigned int ORBIT>
Sylvain Thery's avatar
Sylvain Thery committed
183
inline const AttributeMultiVector<Dart>* GenericMap::getQuickTraversal() const
Pierre Kraemer's avatar
Pierre Kraemer committed
184 185 186 187 188 189 190 191 192 193 194 195 196 197
{
	return m_quickTraversal[ORBIT] ;
}

template <unsigned int ORBIT>
inline void GenericMap::disableQuickTraversal()
{
	if(m_quickTraversal[ORBIT] != NULL)
	{
		m_attribs[ORBIT].removeAttribute<Dart>(m_quickTraversal[ORBIT]->getIndex()) ;
		m_quickTraversal[ORBIT] = NULL ;
	}
}

Sylvain Thery's avatar
Sylvain Thery committed
198 199

template <typename MAP, unsigned int ORBIT, unsigned int INCI>
Sylvain Thery's avatar
Sylvain Thery committed
200
inline void GenericMap::enableQuickIncidentTraversal()
Sylvain Thery's avatar
Sylvain Thery committed
201 202 203 204 205 206 207 208 209
{
	if(m_quickLocalIncidentTraversal[ORBIT][INCI] == NULL)
	{
		if(!isOrbitEmbedded<ORBIT>())
			addEmbedding<ORBIT>() ;
		std::stringstream ss;
		ss << "quickLocalIncidentTraversal_" << INCI;
		m_quickLocalIncidentTraversal[ORBIT][INCI] = m_attribs[ORBIT].addAttribute<NoTypeNameAttribute<std::vector<Dart> > >(ss.str()) ;
	}
Sylvain Thery's avatar
Sylvain Thery committed
210
	updateQuickIncidentTraversal<MAP,ORBIT,INCI>() ;
Sylvain Thery's avatar
Sylvain Thery committed
211 212 213
}

template <typename MAP, unsigned int ORBIT, unsigned int INCI>
Sylvain Thery's avatar
Sylvain Thery committed
214
inline void GenericMap::updateQuickIncidentTraversal()
Sylvain Thery's avatar
Sylvain Thery committed
215 216 217 218 219 220 221 222 223
{
	assert(m_quickLocalIncidentTraversal[ORBIT][INCI] != NULL || !"updateQuickTraversal on a disabled orbit") ;

	AttributeMultiVector<NoTypeNameAttribute<std::vector<Dart> > >* ptrVD = m_quickLocalIncidentTraversal[ORBIT][INCI];
	m_quickLocalIncidentTraversal[ORBIT][INCI] = NULL;

	std::vector<Dart> buffer;
	buffer.reserve(100);

Sylvain Thery's avatar
Sylvain Thery committed
224 225
	MAP& map = static_cast<MAP&>(*this);

Sylvain Thery's avatar
Sylvain Thery committed
226 227 228 229
	TraversorCell<MAP,ORBIT> tra_glob(map);
	for (Dart d = tra_glob.begin(); d != tra_glob.end(); d = tra_glob.next())
	{
		buffer.clear();
Sylvain Thery's avatar
Sylvain Thery committed
230
		Traversor* tra_loc = TraversorFactory<MAP>::createIncident(map, d, map.dimension(), ORBIT, INCI);
Sylvain Thery's avatar
Sylvain Thery committed
231
		for (Dart e = tra_loc->begin(); e != tra_loc->end(); e = tra_loc->next())
Sylvain Thery's avatar
Sylvain Thery committed
232
			buffer.push_back(e);
Sylvain Thery's avatar
Sylvain Thery committed
233
		delete tra_loc;
Sylvain Thery's avatar
Sylvain Thery committed
234
		buffer.push_back(NIL);
235
		std::vector<Dart>& vd = (*ptrVD)[MAP::getEmbedding<ORBIT>(d)];
Sylvain Thery's avatar
Sylvain Thery committed
236 237 238 239 240 241 242
		vd.reserve(buffer.size());
		vd.assign(buffer.begin(),buffer.end());
	}
	m_quickLocalIncidentTraversal[ORBIT][INCI] = ptrVD;
}

template <unsigned int ORBIT, unsigned int INCI>
Sylvain Thery's avatar
Sylvain Thery committed
243
inline const AttributeMultiVector<NoTypeNameAttribute<std::vector<Dart> > >* GenericMap::getQuickIncidentTraversal() const
Sylvain Thery's avatar
Sylvain Thery committed
244 245 246 247 248
{
	return m_quickLocalIncidentTraversal[ORBIT][INCI] ;
}

template <unsigned int ORBIT, unsigned int INCI>
Sylvain Thery's avatar
Sylvain Thery committed
249
inline void GenericMap::disableQuickIncidentTraversal()
Sylvain Thery's avatar
Sylvain Thery committed
250 251 252 253 254 255 256 257 258
{
	if(m_quickLocalIncidentTraversal[ORBIT][INCI] != NULL)
	{
		m_attribs[ORBIT].removeAttribute<Dart>(m_quickLocalIncidentTraversal[ORBIT][INCI]->getIndex()) ;
		m_quickLocalIncidentTraversal[ORBIT][INCI] = NULL ;
	}
}

template <typename MAP, unsigned int ORBIT, unsigned int ADJ>
Sylvain Thery's avatar
Sylvain Thery committed
259
inline void GenericMap::enableQuickAdjacentTraversal()
Sylvain Thery's avatar
Sylvain Thery committed
260 261 262 263 264 265
{
	if(m_quickLocalAdjacentTraversal[ORBIT][ADJ] == NULL)
	{
		if(!isOrbitEmbedded<ORBIT>())
			addEmbedding<ORBIT>() ;
		std::stringstream ss;
Sylvain Thery's avatar
Sylvain Thery committed
266
		ss << "quickLocalAdjacentTraversal" << ADJ;
Sylvain Thery's avatar
Sylvain Thery committed
267 268
		m_quickLocalAdjacentTraversal[ORBIT][ADJ] = m_attribs[ORBIT].addAttribute<NoTypeNameAttribute<std::vector<Dart> > >(ss.str()) ;
	}
Sylvain Thery's avatar
Sylvain Thery committed
269
	updateQuickAdjacentTraversal<MAP,ORBIT,ADJ>() ;
Sylvain Thery's avatar
Sylvain Thery committed
270 271 272
}

template <typename MAP, unsigned int ORBIT, unsigned int ADJ>
Sylvain Thery's avatar
Sylvain Thery committed
273
inline void GenericMap::updateQuickAdjacentTraversal()
Sylvain Thery's avatar
Sylvain Thery committed
274 275 276 277 278 279
{
	assert(m_quickLocalAdjacentTraversal[ORBIT][ADJ] != NULL || !"updateQuickTraversal on a disabled orbit") ;

	AttributeMultiVector<NoTypeNameAttribute<std::vector<Dart> > >* ptrVD = m_quickLocalAdjacentTraversal[ORBIT][ADJ];
	m_quickLocalAdjacentTraversal[ORBIT][ADJ] = NULL;

Sylvain Thery's avatar
Sylvain Thery committed
280 281
	MAP& map = static_cast<MAP&>(*this);

Sylvain Thery's avatar
Sylvain Thery committed
282 283 284 285 286 287 288
	std::vector<Dart> buffer;
	buffer.reserve(100);

	TraversorCell<MAP,ORBIT> tra_glob(map);
	for (Dart d = tra_glob.begin(); d != tra_glob.end(); d = tra_glob.next())
	{
		buffer.clear();
Sylvain Thery's avatar
Sylvain Thery committed
289
		Traversor* tra_loc = TraversorFactory<MAP>::createAdjacent(map, d, map.dimension(), ORBIT, ADJ);
Sylvain Thery's avatar
Sylvain Thery committed
290
		for (Dart e = tra_loc->begin(); e != tra_loc->end(); e = tra_loc->next())
Sylvain Thery's avatar
Sylvain Thery committed
291 292
			buffer.push_back(e);
		buffer.push_back(NIL);
Sylvain Thery's avatar
Sylvain Thery committed
293
		delete tra_loc;
294
		std::vector<Dart>& vd = (*ptrVD)[MAP::getEmbedding<ORBIT>(d)];
Sylvain Thery's avatar
Sylvain Thery committed
295 296 297 298 299 300
		vd.reserve(buffer.size());
		vd.assign(buffer.begin(),buffer.end());
	}
	m_quickLocalAdjacentTraversal[ORBIT][ADJ] = ptrVD;
}

Sylvain Thery's avatar
Sylvain Thery committed
301
template <unsigned int ORBIT, unsigned int ADJ>
Sylvain Thery's avatar
Sylvain Thery committed
302
inline const AttributeMultiVector<NoTypeNameAttribute<std::vector<Dart> > >* GenericMap::getQuickAdjacentTraversal() const
Sylvain Thery's avatar
Sylvain Thery committed
303
{
Sylvain Thery's avatar
Sylvain Thery committed
304
	return m_quickLocalAdjacentTraversal[ORBIT][ADJ] ;
Sylvain Thery's avatar
Sylvain Thery committed
305 306 307
}

template <unsigned int ORBIT, unsigned int ADJ>
Sylvain Thery's avatar
Sylvain Thery committed
308
inline void GenericMap::disableQuickAdjacentTraversal()
Sylvain Thery's avatar
Sylvain Thery committed
309 310 311 312 313 314 315 316 317 318 319
{
	if(m_quickLocalAdjacentTraversal[ORBIT][ADJ] != NULL)
	{
		m_attribs[ORBIT].removeAttribute<Dart>(m_quickLocalAdjacentTraversal[ORBIT][ADJ]->getIndex()) ;
		m_quickLocalAdjacentTraversal[ORBIT][ADJ] = NULL ;
	}
}




Pierre Kraemer's avatar
Pierre Kraemer committed
320 321 322 323
/****************************************
 *        ATTRIBUTES MANAGEMENT         *
 ****************************************/

324 325 326 327 328
inline unsigned int GenericMap::getNbCells(unsigned int orbit)
{
	return m_attribs[orbit].size() ;
}

329 330
template <unsigned int ORBIT>
inline AttributeContainer& GenericMap::getAttributeContainer()
Pierre Kraemer's avatar
Pierre Kraemer committed
331
{
332
	return m_attribs[ORBIT] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
333 334
}

Sylvain Thery's avatar
Sylvain Thery committed
335 336 337 338 339 340
template <unsigned int ORBIT>
inline const AttributeContainer& GenericMap::getAttributeContainer() const
{
	return m_attribs[ORBIT] ;
}

Pierre Kraemer's avatar
Pierre Kraemer committed
341 342 343 344 345
inline AttributeContainer& GenericMap::getAttributeContainer(unsigned int orbit)
{
	return m_attribs[orbit] ;
}

Sylvain Thery's avatar
Sylvain Thery committed
346 347 348 349 350 351
inline const AttributeContainer& GenericMap::getAttributeContainer(unsigned int orbit) const
{
	return m_attribs[orbit] ;
}


352 353
template <unsigned int ORBIT>
inline AttributeMultiVector<Mark>* GenericMap::getMarkVector(unsigned int thread)
Pierre Kraemer's avatar
Pierre Kraemer committed
354
{
355
	assert(isOrbitEmbedded<ORBIT>() || !"Invalid parameter: orbit not embedded") ;
356
	return m_markTables[ORBIT][thread] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
357 358
}

359 360
template <unsigned int ORBIT>
inline AttributeMultiVector<unsigned int>* GenericMap::getEmbeddingAttributeVector()
Pierre Kraemer's avatar
Pierre Kraemer committed
361
{
362
	return m_embeddings[ORBIT] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
363 364
}

365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380
template <typename R>
bool GenericMap::registerAttribute(const std::string &nameType)
{
	RegisteredBaseAttribute* ra = new RegisteredAttribute<R>;
	if (ra == NULL)
	{
		CGoGNerr << "Erreur enregistrement attribut" << CGoGNendl;
		return false;
	}

	ra->setTypeName(nameType);

	m_attributes_registry_map->insert(std::pair<std::string, RegisteredBaseAttribute*>(nameType,ra));
	return true;
}

381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396
/****************************************
 *   EMBEDDING ATTRIBUTES MANAGEMENT    *
 ****************************************/

template <unsigned int ORBIT>
void GenericMap::addEmbedding()
{
	assert(!isOrbitEmbedded<ORBIT>() || !"Invalid parameter: orbit already embedded") ;

	std::ostringstream oss;
	oss << "EMB_" << ORBIT;

	AttributeContainer& dartCont = m_attribs[DART] ;
	AttributeMultiVector<unsigned int>* amv = dartCont.addAttribute<unsigned int>(oss.str()) ;
	m_embeddings[ORBIT] = amv ;

397 398 399
	// set new embedding to EMBNULL for all the darts of the map
	for(unsigned int i = dartCont.begin(); i < dartCont.end(); dartCont.next(i))
		(*amv)[i] = EMBNULL ;
400 401
}

Pierre Kraemer's avatar
Pierre Kraemer committed
402 403 404 405
/****************************************
 *           DARTS TRAVERSALS           *
 ****************************************/

406
template <unsigned int ORBIT>
Sylvain Thery's avatar
Sylvain Thery committed
407
bool GenericMap::foreach_dart_of_orbit(Dart d, FunctorType& f, unsigned int thread) const
408 409 410 411 412 413 414 415 416 417 418 419 420
{
	switch(ORBIT)
	{
		case DART:		return f(d);
		case VERTEX: 	return foreach_dart_of_vertex(d, f, thread);
		case EDGE: 		return foreach_dart_of_edge(d, f, thread);
		case FACE: 		return foreach_dart_of_face(d, f, thread);
		case VOLUME: 	return foreach_dart_of_volume(d, f, thread);
		case VERTEX1: 	return foreach_dart_of_vertex1(d, f, thread);
		case EDGE1: 	return foreach_dart_of_edge1(d, f, thread);
		case VERTEX2: 	return foreach_dart_of_vertex2(d, f, thread);
		case EDGE2:		return foreach_dart_of_edge2(d, f, thread);
		case FACE2:		return foreach_dart_of_face2(d, f, thread);
Pierre Kraemer's avatar
Pierre Kraemer committed
421
		default: 		assert(!"Cells of this dimension are not handled"); break;
422 423 424 425
	}
	return false;
}

426
template <typename MAP, unsigned int ORBIT>
Sylvain Thery's avatar
Sylvain Thery committed
427
bool GenericMap::foreach_orbit(FunctorType& fonct, unsigned int thread) const
428
{
429
	TraversorCell<MAP, ORBIT> trav(*reinterpret_cast<const MAP*>(this), true, thread);
430 431 432 433 434 435 436 437 438 439
	bool found = false;

	for (Dart d = trav.begin(); !found && d != trav.end(); d = trav.next())
	{
		if ((fonct)(d))
			found = true;
	}
	return found;
}

440
template <typename MAP, unsigned int ORBIT>
Sylvain Thery's avatar
Sylvain Thery committed
441
unsigned int GenericMap::getNbOrbits() const
442 443
{
	FunctorCount fcount;
444
	foreach_orbit<MAP, ORBIT>(fcount);
445 446 447
	return fcount.getNb();
}

448
template <typename MAP, unsigned int ORBIT, unsigned int INCIDENT>
Sylvain Thery's avatar
Sylvain Thery committed
449
unsigned int GenericMap::degree(Dart d) const
450
{
451
	assert(ORBIT != INCIDENT || !"degree does not manage adjacency counting") ;
Sylvain Thery's avatar
Sylvain Thery committed
452
	Traversor* t = TraversorFactory<MAP>::createIncident(*(reinterpret_cast<MAP*>(this)), d, dimension(), ORBIT, INCIDENT) ;
453 454
	FunctorCount fcount ;
	t->applyFunctor(fcount) ;
455
	delete t ;
456 457 458
	return fcount.getNb() ;
}

Sylvain Thery's avatar
Sylvain Thery committed
459 460 461 462 463 464 465 466 467 468 469
/****************************************
 *  TOPOLOGICAL ATTRIBUTES MANAGEMENT   *
 ****************************************/

inline AttributeMultiVector<Dart>* GenericMap::addRelation(const std::string& name)
{
	AttributeContainer& cont = m_attribs[DART] ;
	AttributeMultiVector<Dart>* amv = cont.addAttribute<Dart>(name) ;

	// set new relation to fix point for all the darts of the map
	for(unsigned int i = cont.begin(); i < cont.end(); cont.next(i))
Pierre Kraemer's avatar
Pierre Kraemer committed
470
		(*amv)[i] = i ;
Sylvain Thery's avatar
Sylvain Thery committed
471 472 473 474

	return amv ;
}

Sylvain Thery's avatar
Sylvain Thery committed
475 476 477 478 479 480 481
inline AttributeMultiVector<Dart>* GenericMap::getRelation(const std::string& name)
{
	AttributeContainer& cont = m_attribs[DART] ;
	AttributeMultiVector<Dart>* amv = cont.getDataVector<Dart>(cont.getAttributeIndex(name)) ;
	return amv ;
}

Sylvain Thery's avatar
Sylvain Thery committed
482 483 484 485 486

/**************************
 *  BOUNDARY MANAGEMENT   *
 **************************/

Thery Sylvain's avatar
Thery Sylvain committed
487
template <unsigned int D>
Sylvain Thery's avatar
Sylvain Thery committed
488 489
inline void GenericMap::boundaryMark(Dart d)
{
Thery Sylvain's avatar
Thery Sylvain committed
490
	m_markTables[DART][0]->operator[](dartIndex(d)).setMark(m_boundaryMarkers[D-2]);
Sylvain Thery's avatar
Sylvain Thery committed
491 492
}

Thery Sylvain's avatar
Thery Sylvain committed
493
template <unsigned int D>
Sylvain Thery's avatar
Sylvain Thery committed
494 495
inline void GenericMap::boundaryUnmark(Dart d)
{
Thery Sylvain's avatar
Thery Sylvain committed
496
	m_markTables[DART][0]->operator[](dartIndex(d)).unsetMark(m_boundaryMarkers[D-2]);
Sylvain Thery's avatar
Sylvain Thery committed
497 498
}

Thery Sylvain's avatar
Thery Sylvain committed
499
template <unsigned int D>
Sylvain Thery's avatar
Sylvain Thery committed
500 501
inline bool GenericMap::isBoundaryMarked(Dart d) const
{
Thery Sylvain's avatar
Thery Sylvain committed
502 503 504 505
	return m_markTables[DART][0]->operator[](dartIndex(d)).testMark(m_boundaryMarkers[D-2]);
}


506 507 508 509 510 511
inline bool GenericMap::isBoundaryMarkedCurrent(Dart d) const
{
	return m_markTables[DART][0]->operator[](dartIndex(d)).testMark(m_boundaryMarkers[this->dimension()-2]);
}


Thery Sylvain's avatar
Thery Sylvain committed
512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560
inline void GenericMap::boundaryMark2(Dart d)
{
	boundaryMark<2>(d);
}

inline void GenericMap::boundaryUnmark2(Dart d)
{
	boundaryUnmark<2>(d);
}

inline bool GenericMap::isBoundaryMarked2(Dart d) const
{
	return isBoundaryMarked<2>(d);
}

inline void GenericMap::boundaryMark3(Dart d)
{
	boundaryMark<3>(d);
}

inline void GenericMap::boundaryUnmark3(Dart d)
{
	boundaryUnmark<3>(d);
}

inline bool GenericMap::isBoundaryMarked3(Dart d) const
{
	return isBoundaryMarked<3>(d);
}

template <unsigned int ORBIT, unsigned int  DIM>
void GenericMap::boundaryMarkOrbit(Dart d)
{
	FunctorMark<GenericMap> fm(*this, m_boundaryMarkers[DIM-2], m_markTables[DART][0]) ;
	foreach_dart_of_orbit<ORBIT>(d, fm, 0) ;
}

template <unsigned int ORBIT, unsigned int DIM>
void GenericMap::boundaryUnmarkOrbit(Dart d)
{
	FunctorUnmark<GenericMap> fm(*this, m_boundaryMarkers[DIM-2], m_markTables[DART][0]) ;
	foreach_dart_of_orbit<ORBIT>(d, fm, 0) ;
}

template <unsigned int DIM>
void GenericMap::boundaryUnmarkAll()
{
	AttributeContainer& cont = getAttributeContainer<DART>() ;
	for (unsigned int i = cont.begin(); i != cont.end(); cont.next(i))
Thery Sylvain's avatar
Thery Sylvain committed
561
		m_markTables[DART][0]->operator[](i).unsetMark(m_boundaryMarkers[DIM-2]);
Sylvain Thery's avatar
Sylvain Thery committed
562 563
}

Thery Sylvain's avatar
Thery Sylvain committed
564

Pierre Kraemer's avatar
Pierre Kraemer committed
565
} //namespace CGoGN