genericmap.hpp 20.3 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

32 33 34 35 36 37 38 39 40 41 42 43 44 45
/****************************************
 *           MULTIRES                   *
 ****************************************/

inline unsigned int GenericMap::getCurrentLevel()
{
	return m_mrCurrentLevel ;
}

inline void GenericMap::setCurrentLevel(unsigned int l)
{
	if(l < m_mrDarts.size())
		m_mrCurrentLevel = l ;
	else
Pierre Kraemer's avatar
Pierre Kraemer committed
46
		CGoGNout << "setCurrentLevel : try to access nonexistent resolution level" << CGoGNendl ;
47 48
}

Pierre Kraemer's avatar
Pierre Kraemer committed
49 50
inline void GenericMap::incCurrentLevel()
{
51
	if(m_mrCurrentLevel < m_mrDarts.size() - 1)
Pierre Kraemer's avatar
Pierre Kraemer committed
52 53 54 55 56 57 58 59 60 61 62 63 64
		++m_mrCurrentLevel ;
	else
		CGoGNout << "incCurrentLevel : already at maximum resolution level" << CGoGNendl ;
}

inline void GenericMap::decCurrentLevel()
{
	if(m_mrCurrentLevel > 0)
		--m_mrCurrentLevel ;
	else
		CGoGNout << "decCurrentLevel : already at minimum resolution level" << CGoGNendl ;
}

65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
inline void GenericMap::pushLevel()
{
	m_mrLevelStack.push_back(m_mrCurrentLevel) ;
}

inline void GenericMap::popLevel()
{
	m_mrCurrentLevel = m_mrLevelStack.back() ;
	m_mrLevelStack.pop_back() ;
}

inline unsigned int GenericMap::getMaxLevel()
{
	return m_mrDarts.size() - 1 ;
}

81

Pierre Kraemer's avatar
Pierre Kraemer committed
82 83 84 85 86 87
/****************************************
 *           DARTS MANAGEMENT           *
 ****************************************/

inline Dart GenericMap::newDart()
{
88
	unsigned int di = m_attribs[DART].insertLine();		// insert a new dart line
Pierre Kraemer's avatar
Pierre Kraemer committed
89
	for(unsigned int i = 0; i < NB_ORBITS; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
90
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
91 92
		if (m_embeddings[i])								// set all its embeddings
			(*m_embeddings[i])[di] = EMBNULL ;				// to EMBNULL
Pierre Kraemer's avatar
Pierre Kraemer committed
93
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
94

Pierre Kraemer's avatar
Pierre Kraemer committed
95 96
	if (m_isMultiRes)
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
97 98
		unsigned int mrdi = m_mrattribs.insertLine() ;		// insert a new MRdart line
		(*m_mrLevels)[mrdi] = m_mrCurrentLevel ;			// set the introduction level of the dart
Pierre Kraemer's avatar
Pierre Kraemer committed
99
		m_mrNbDarts[m_mrCurrentLevel]++ ;
Pierre Kraemer's avatar
Pierre Kraemer committed
100

Pierre Kraemer's avatar
Pierre Kraemer committed
101
		for(unsigned int i = 0; i < m_mrCurrentLevel; ++i)	// for all previous levels
102
			(*m_mrDarts[i])[mrdi] = MRNULL ;					// this MRdart does not exist
Pierre Kraemer's avatar
Pierre Kraemer committed
103

untereiner's avatar
untereiner committed
104 105
		for(unsigned int i = m_mrCurrentLevel; i < m_mrDarts.size(); ++i)	// for all levels from current to max
  			(*m_mrDarts[i])[mrdi] = di ;									// make this MRdart point to the new dart line
106

Pierre Kraemer's avatar
Pierre Kraemer committed
107 108
		return Dart::create(mrdi) ;
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
109

Pierre Kraemer's avatar
Pierre Kraemer committed
110
	return Dart::create(di) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
111 112 113 114
}

inline void GenericMap::deleteDart(Dart d)
{
Pierre Kraemer's avatar
Pierre Kraemer committed
115 116
	if(m_isMultiRes)
	{
untereiner's avatar
untereiner committed
117
		unsigned int index = (*m_mrDarts[m_mrCurrentLevel])[d.index] ;
118

119
		if(getDartLevel(d) > m_mrCurrentLevel)
120
		{
121 122 123 124 125 126 127 128
			unsigned int di = (*m_mrDarts[m_mrCurrentLevel + 1])[d.index];
			// si le brin de niveau i pointe sur le meme brin que le niveau i-1
			if(di != index)
			{
				if(isDartValid(d))//index))
					deleteDartLine(index) ;
			}

untereiner's avatar
untereiner committed
129 130
			(*m_mrDarts[m_mrCurrentLevel])[d.index] = MRNULL ;
			return;
131
		}
untereiner's avatar
untereiner committed
132

133 134 135
		// a MRdart can only be deleted on its insertion level
		if(getDartLevel(d) == m_mrCurrentLevel)
		{
136 137
			if(isDartValid(d))
			{
138
				deleteDartLine(index) ;
139 140 141
				m_mrattribs.removeLine(d.index);
				m_mrNbDarts[m_mrCurrentLevel]--;
			}
142
		}
untereiner's avatar
untereiner committed
143 144
		else
		{
145
			unsigned int di = (*m_mrDarts[m_mrCurrentLevel - 1])[d.index];
146
			// si le brin de niveau i pointe sur le meme brin que le niveau i-1
untereiner's avatar
untereiner committed
147 148
			if(di != index)
			{
149
				if(isDartValid(d))//index))
untereiner's avatar
untereiner committed
150 151 152
					deleteDartLine(index) ;
			}

153 154 155 156 157
			for(unsigned int i = m_mrCurrentLevel; i <= getMaxLevel(); ++i) // for all levels from current to max
			{
				(*m_mrDarts[i])[d.index] = di ; //copy the index from previous level
			}
		}
Pierre Kraemer's avatar
Pierre Kraemer committed
158 159 160 161 162 163 164 165 166 167
	}
	else
		deleteDartLine(dartIndex(d)) ;
}

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
168
		(*m_markTables[DART][t])[index].clear() ;		// the removed dart
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
169

Pierre Kraemer's avatar
Pierre Kraemer committed
170 171
	for(unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit)
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
172
		if (m_embeddings[orbit])									// for each embedded orbit
Pierre Kraemer's avatar
Pierre Kraemer committed
173
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
174
			unsigned int emb = (*m_embeddings[orbit])[index] ;		// get the embedding of the dart
Pierre Kraemer's avatar
Pierre Kraemer committed
175
			if(emb != EMBNULL)
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
176
			{
Pierre Kraemer's avatar
Pierre Kraemer committed
177
				if(m_attribs[orbit].unrefLine(emb))					// unref the pointed embedding line
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
178
				{
Pierre Kraemer's avatar
Pierre Kraemer committed
179
					for (unsigned int t = 0; t < m_nbThreads; ++t)	// and clear its markers if it was
180
						(*m_markTables[orbit][t])[emb].clear() ;	// its last unref (and was thus freed)
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
181 182
				}
			}
Pierre Kraemer's avatar
Pierre Kraemer committed
183 184
		}
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
185
}
Pierre Kraemer's avatar
Pierre Kraemer committed
186

Pierre Kraemer's avatar
Pierre Kraemer committed
187
inline unsigned int GenericMap::copyDartLine(unsigned int index)
Pierre Kraemer's avatar
Pierre Kraemer committed
188
{
189 190
	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
191 192
	for(unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit)
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
193 194 195 196 197 198
		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
199 200
	}
	return newindex ;
Pierre Kraemer's avatar
Pierre Kraemer committed
201 202
}

Pierre Kraemer's avatar
Pierre Kraemer committed
203 204
inline void GenericMap::duplicateDart(Dart d)
{
205
	assert(getDartLevel(d) <= m_mrCurrentLevel || !"duplicateDart : called with a dart inserted after current level") ;
Pierre Kraemer's avatar
Pierre Kraemer committed
206

207
	if(getDartLevel(d) == m_mrCurrentLevel)	// no need to duplicate
Pierre Kraemer's avatar
Pierre Kraemer committed
208 209 210 211
		return ;								// a dart from its insertion level

	unsigned int oldindex = dartIndex(d) ;

212 213 214 215 216
	if(m_mrCurrentLevel > 0)
	{
		if((*m_mrDarts[m_mrCurrentLevel - 1])[d.index] != oldindex)	// no need to duplicate if the dart is already
			return ;												// duplicated with respect to previous level
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
217 218 219

	unsigned int newindex = copyDartLine(oldindex) ;

220
	for(unsigned int i = m_mrCurrentLevel; i <= getMaxLevel(); ++i) // for all levels from current to max
Pierre Kraemer's avatar
Pierre Kraemer committed
221 222 223 224 225 226
	{
		assert((*m_mrDarts[i])[d.index] == oldindex || !"duplicateDart : dart was already duplicated on a greater level") ;
		(*m_mrDarts[i])[d.index] = newindex ;						// make this MRdart points to the new dart line
	}
}

untereiner's avatar
untereiner committed
227
inline void GenericMap::duplicateDartAtOneLevel(Dart d, unsigned int level)
228
{
untereiner's avatar
untereiner committed
229
	(*m_mrDarts[level])[d.index] = copyDartLine(dartIndex(d)) ;
230 231
}

Sylvain Thery's avatar
Sylvain Thery committed
232
inline unsigned int GenericMap::dartIndex(Dart d) const
Pierre Kraemer's avatar
Pierre Kraemer committed
233
{
Pierre Kraemer's avatar
Pierre Kraemer committed
234 235 236 237 238
	if (m_isMultiRes)
		return (*m_mrDarts[m_mrCurrentLevel])[d.index] ;
	return d.index;
}

239
inline unsigned int GenericMap::getDartLevel(Dart d) const
Pierre Kraemer's avatar
Pierre Kraemer committed
240 241 242 243
{
	return (*m_mrLevels)[d.index] ;
}

244 245
inline void GenericMap::incDartLevel(Dart d) const
{
246
	++((*m_mrLevels)[d.index]) ;
247 248 249
}


Pierre Kraemer's avatar
Pierre Kraemer committed
250 251 252 253 254 255 256 257 258 259 260
inline unsigned int GenericMap::getNbInsertedDarts(unsigned int level)
{
	if(level < m_mrDarts.size())
		return m_mrNbDarts[level] ;
	else
		return 0 ;
}

inline unsigned int GenericMap::getNbDarts(unsigned int level)
{
	if(level < m_mrDarts.size())
Pierre Kraemer's avatar
Pierre Kraemer committed
261
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
262 263 264 265
		unsigned int nb = 0 ;
		for(unsigned int i = 0; i <= level; ++i)
			nb += m_mrNbDarts[i] ;
		return nb ;
Pierre Kraemer's avatar
Pierre Kraemer committed
266
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
267 268 269 270 271 272 273 274 275
	else
		return 0 ;
}

inline unsigned int GenericMap::getNbDarts()
{
	if(m_isMultiRes)
		return getNbDarts(m_mrCurrentLevel) ;

276
	return m_attribs[DART].size() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
277 278
}

Pierre Kraemer's avatar
Pierre Kraemer committed
279 280 281 282 283
inline bool GenericMap::isDartValid(Dart d)
{
	return !d.isNil() && m_attribs[DART].used(dartIndex(d)) ;
}

Pierre Kraemer's avatar
Pierre Kraemer committed
284 285 286 287
/****************************************
 *         EMBEDDING MANAGEMENT         *
 ****************************************/

288 289
template <unsigned int ORBIT>
inline bool GenericMap::isOrbitEmbedded() const
Pierre Kraemer's avatar
Pierre Kraemer committed
290
{
291
	return (ORBIT == DART) || (m_embeddings[ORBIT] != NULL) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
292 293
}

294
inline bool GenericMap::isOrbitEmbedded(unsigned int orbit) const
Pierre Kraemer's avatar
Pierre Kraemer committed
295
{
296
	return (orbit == DART) || (m_embeddings[orbit] != NULL) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
297 298
}

299 300
template <unsigned int ORBIT>
inline unsigned int GenericMap::getEmbedding(Dart d)
Pierre Kraemer's avatar
Pierre Kraemer committed
301
{
302
	assert(isOrbitEmbedded<ORBIT>() || !"Invalid parameter: orbit not embedded");
Pierre Kraemer's avatar
Pierre Kraemer committed
303

304 305
	unsigned int d_index = dartIndex(d);

306
	if (ORBIT == DART)
307
		return d_index;
Pierre Kraemer's avatar
Pierre Kraemer committed
308

309
	return (*m_embeddings[ORBIT])[d_index] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
310 311
}

312 313 314
template <unsigned int ORBIT>
void GenericMap::setDartEmbedding(Dart d, unsigned int emb)
{
315
	assert(isOrbitEmbedded<ORBIT>() || !"Invalid parameter: orbit not embedded");
316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333

	unsigned int old = getEmbedding<ORBIT>(d);

	if (old == emb)	// if same emb
		return;		// nothing to do

	if (old != EMBNULL)	// if different
	{
		if(m_attribs[ORBIT].unrefLine(old))	// then unref the old emb
		{
			for (unsigned int t = 0; t < m_nbThreads; ++t)	// clear the markers if it was the
				(*m_markTables[ORBIT][t])[old].clear();		// last unref of the line
		}
	}

	if (emb != EMBNULL)
		m_attribs[ORBIT].refLine(emb);	// ref the new emb

Pierre Kraemer's avatar
Pierre Kraemer committed
334
	(*m_embeddings[ORBIT])[dartIndex(d)] = emb ; // finally affect the embedding to the dart
335 336
}

337 338 339 340
template <unsigned int ORBIT>
void GenericMap::initDartEmbedding(Dart d, unsigned int emb)
{
	assert(isOrbitEmbedded<ORBIT>() || !"Invalid parameter: orbit not embedded");
Pierre Kraemer's avatar
Pierre Kraemer committed
341
	assert(getEmbedding<ORBIT>(d) == EMBNULL || !"initDartEmbedding called on already embedded dart");
342 343
	if(emb != EMBNULL)
		m_attribs[ORBIT].refLine(emb);	// ref the new emb
344 345 346
	(*m_embeddings[ORBIT])[dartIndex(d)] = emb ; // affect the embedding to the dart
}

347 348
template <unsigned int ORBIT>
inline void GenericMap::copyDartEmbedding(Dart dest, Dart src)
Pierre Kraemer's avatar
Pierre Kraemer committed
349
{
350
	assert(isOrbitEmbedded<ORBIT>() || !"Invalid parameter: orbit not embedded");
351
	setDartEmbedding<ORBIT>(dest, getEmbedding<ORBIT>(src));
Pierre Kraemer's avatar
Pierre Kraemer committed
352 353
}

354 355
template <unsigned int ORBIT>
inline unsigned int GenericMap::newCell()
Pierre Kraemer's avatar
Pierre Kraemer committed
356
{
357
	assert(isOrbitEmbedded<ORBIT>() || !"Invalid parameter: orbit not embedded");
358
	return m_attribs[ORBIT].insertLine();
Pierre Kraemer's avatar
Pierre Kraemer committed
359 360
}

361
template <unsigned int ORBIT>
362
inline void GenericMap::setOrbitEmbedding(Dart d, unsigned int em)
Pierre Kraemer's avatar
Pierre Kraemer committed
363
{
364
	assert(isOrbitEmbedded<ORBIT>() || !"Invalid parameter: orbit not embedded");
365 366
	FunctorSetEmb<GenericMap, ORBIT> fsetemb(*this, em);
	foreach_dart_of_orbit<ORBIT>(d, fsetemb);
Pierre Kraemer's avatar
Pierre Kraemer committed
367 368
}

369
template <unsigned int ORBIT>
370 371 372 373 374 375 376 377
inline void GenericMap::initOrbitEmbedding(Dart d, unsigned int em)
{
	assert(isOrbitEmbedded<ORBIT>() || !"Invalid parameter: orbit not embedded");
	FunctorInitEmb<GenericMap, ORBIT> fsetemb(*this, em);
	foreach_dart_of_orbit<ORBIT>(d, fsetemb);
}

template <unsigned int ORBIT>
378
inline unsigned int GenericMap::setOrbitEmbeddingOnNewCell(Dart d)
Pierre Kraemer's avatar
Pierre Kraemer committed
379
{
380
	assert(isOrbitEmbedded<ORBIT>() || !"Invalid parameter: orbit not embedded");
381
	unsigned int em = newCell<ORBIT>();
382 383 384 385 386 387 388 389 390 391
	setOrbitEmbedding<ORBIT>(d, em);
	return em;
}

template <unsigned int ORBIT>
inline unsigned int GenericMap::initOrbitEmbeddingNewCell(Dart d)
{
	assert(isOrbitEmbedded<ORBIT>() || !"Invalid parameter: orbit not embedded");
	unsigned int em = newCell<ORBIT>();
	initOrbitEmbedding<ORBIT>(d, em);
Pierre Kraemer's avatar
Pierre Kraemer committed
392 393 394
	return em;
}

395 396
template <unsigned int ORBIT>
inline void GenericMap::copyCell(Dart d, Dart e)
Pierre Kraemer's avatar
Pierre Kraemer committed
397
{
398
	assert(isOrbitEmbedded<ORBIT>() || !"Invalid parameter: orbit not embedded");
399 400
	unsigned int dE = getEmbedding<ORBIT>(d) ;
	unsigned int eE = getEmbedding<ORBIT>(e) ;
401 402 403 404
	if(eE != EMBNULL)	// if the source is NULL, nothing to copy
	{
		if(dE == EMBNULL)	// if the dest is NULL, create a new cell
			dE = setOrbitEmbeddingOnNewCell<ORBIT>(d) ;
405
		m_attribs[ORBIT].copyLine(dE, eE) ;	// copy the data
406
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
407 408
}

409 410
template <unsigned int ORBIT>
inline void GenericMap::copyCell(unsigned int i, unsigned int j)
Pierre Kraemer's avatar
Pierre Kraemer committed
411
{
412
	assert(isOrbitEmbedded<ORBIT>() || !"Invalid parameter: orbit not embedded");
413
	m_attribs[ORBIT].copyLine(i, j) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
414 415
}

416 417
template <unsigned int ORBIT>
inline void GenericMap::initCell(unsigned int i)
Pierre Kraemer's avatar
Pierre Kraemer committed
418
{
419
	assert(isOrbitEmbedded<ORBIT>() || !"Invalid parameter: orbit not embedded");
420
	m_attribs[ORBIT].initLine(i) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
421 422
}

423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439

template <unsigned int ORBIT>
void GenericMap::initAllOrbitsEmbedding(bool realloc)
{
	assert(isOrbitEmbedded<ORBIT>() || !"Invalid parameter: orbit not embedded") ;
	DartMarker mark(*this) ;
	for(Dart d = begin(); d != end(); next(d))
	{
		if(!mark.isMarked(d))
		{
			mark.markOrbit<ORBIT>(d) ;
			if(realloc || getEmbedding<ORBIT>(d) == EMBNULL)
				setOrbitEmbeddingOnNewCell<ORBIT>(d) ;
		}
	}
}

Pierre Kraemer's avatar
Pierre Kraemer committed
440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456
/****************************************
 *     QUICK TRAVERSAL MANAGEMENT       *
 ****************************************/

template <unsigned int ORBIT>
inline void GenericMap::enableQuickTraversal()
{
	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>
457
inline void GenericMap::updateQuickTraversal(const FunctorSelect& good)
Pierre Kraemer's avatar
Pierre Kraemer committed
458
{
Pierre Kraemer's avatar
Pierre Kraemer committed
459 460 461
	assert(m_quickTraversal[ORBIT] != NULL || !"updateQuickTraversal on a disabled orbit") ;

	CellMarker<ORBIT> cm(*this) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
462 463
	for(Dart d = begin(); d != end(); next(d))
	{
464
		if(good(d) && !cm.isMarked(d))
Pierre Kraemer's avatar
Pierre Kraemer committed
465 466
		{
			cm.mark(d) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
467
			(*m_quickTraversal[ORBIT])[getEmbedding<ORBIT>(d)] = d ;
Pierre Kraemer's avatar
Pierre Kraemer committed
468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487
		}
	}
}

template <unsigned int ORBIT>
inline AttributeMultiVector<Dart>* GenericMap::getQuickTraversal()
{
	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 ;
	}
}

Pierre Kraemer's avatar
Pierre Kraemer committed
488 489 490 491
/****************************************
 *        ATTRIBUTES MANAGEMENT         *
 ****************************************/

492 493
template <unsigned int ORBIT>
inline AttributeContainer& GenericMap::getAttributeContainer()
Pierre Kraemer's avatar
Pierre Kraemer committed
494
{
495
	return m_attribs[ORBIT] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
496 497
}

498 499
template <unsigned int ORBIT>
inline AttributeMultiVector<Mark>* GenericMap::getMarkVector(unsigned int thread)
Pierre Kraemer's avatar
Pierre Kraemer committed
500
{
501
	assert(isOrbitEmbedded<ORBIT>() || !"Invalid parameter: orbit not embedded") ;
502
	return m_markTables[ORBIT][thread] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
503 504
}

505 506
template <unsigned int ORBIT>
inline AttributeMultiVector<unsigned int>* GenericMap::getEmbeddingAttributeVector()
Pierre Kraemer's avatar
Pierre Kraemer committed
507
{
508
	return m_embeddings[ORBIT] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
509 510
}

511 512 513 514 515 516 517 518 519 520 521
inline AttributeContainer& GenericMap::getMRAttributeContainer()
{
	return m_mrattribs ;
}

inline AttributeMultiVector<unsigned int>* GenericMap::getMRDartAttributeVector(unsigned int level)
{
	assert(level <= getMaxLevel() || !"Invalid parameter: level does not exist");
	return m_mrDarts[level] ;
}

untereiner's avatar
untereiner committed
522 523 524 525 526
inline AttributeMultiVector<unsigned int>* GenericMap::getMRLevelAttributeVector()
{
	return m_mrLevels ;
}

527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542
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;
}

543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558
/****************************************
 *   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 ;

559 560 561
	// 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 ;
562 563
}

Pierre Kraemer's avatar
Pierre Kraemer committed
564 565 566 567
/****************************************
 *           DARTS TRAVERSALS           *
 ****************************************/

568
inline Dart GenericMap::begin() const
Pierre Kraemer's avatar
Pierre Kraemer committed
569
{
570 571 572
	if (m_isMultiRes)
	{
		unsigned int d = m_mrattribs.begin() ;
573 574 575 576 577
		if(d != m_mrattribs.end())
		{
			while (getDartLevel(d) > m_mrCurrentLevel)
				m_mrattribs.next(d) ;
		}
578 579 580 581
		return Dart::create(d) ;
	}

	return Dart::create(m_attribs[DART].begin()) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
582 583
}

584
inline Dart GenericMap::end() const
Pierre Kraemer's avatar
Pierre Kraemer committed
585
{
586 587 588
	if (m_isMultiRes)
		return Dart::create(m_mrattribs.end()) ;

589
	return Dart::create(m_attribs[DART].end()) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
590 591
}

592
inline void GenericMap::next(Dart& d) const
Pierre Kraemer's avatar
Pierre Kraemer committed
593
{
594 595
	if (m_isMultiRes)
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
596 597
		do
		{
598
			m_mrattribs.next(d.index) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
599
		} while (d.index != m_mrattribs.end() && getDartLevel(d) > m_mrCurrentLevel) ;
600 601 602
	}
	else
		m_attribs[DART].next(d.index) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
603 604
}

605 606 607 608 609 610 611 612 613 614 615 616 617 618 619
template <unsigned int ORBIT>
bool GenericMap::foreach_dart_of_orbit(Dart d, FunctorType& f, unsigned int thread)
{
	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
620
		default: 		assert(!"Cells of this dimension are not handled"); break;
621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646
	}
	return false;
}

template <unsigned int ORBIT>
bool GenericMap::foreach_orbit(FunctorType& fonct, const FunctorSelect& good, unsigned int thread)
{
	TraversorCell<GenericMap, ORBIT> trav(*this, good, true, thread);
	bool found = false;

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

template <unsigned int ORBIT>
unsigned int GenericMap::getNbOrbits(const FunctorSelect& good)
{
	FunctorCount fcount;
	foreach_orbit<ORBIT>(fcount, good);
	return fcount.getNb();
}

647
template <typename MAP, unsigned int ORBIT, unsigned int INCIDENT>
648 649
unsigned int GenericMap::degree(Dart d)
{
650
	assert(ORBIT != INCIDENT || !"degree does not manage adjacency counting") ;
Pierre Kraemer's avatar
Pierre Kraemer committed
651
	Traversor<MAP>* t = TraversorFactory<MAP>::createIncident(*(reinterpret_cast<MAP*>(this)), d, dimension(), ORBIT, INCIDENT) ;
652 653
	FunctorCount fcount ;
	t->applyFunctor(fcount) ;
654
	delete t ;
655 656 657
	return fcount.getNb() ;
}

658 659 660 661 662 663 664 665 666 667 668 669 670 671
template <unsigned int ORBIT>
void GenericMap::boundaryMarkOrbit(Dart d)
{
	FunctorMark<GenericMap> fm(*this, m_boundaryMarker, m_markTables[DART][0]) ;
	foreach_dart_of_orbit<ORBIT>(d, fm, 0) ;
}

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

Sylvain Thery's avatar
Sylvain Thery committed
672 673 674 675 676 677 678 679 680 681 682
/****************************************
 *  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
683
		(*amv)[i] = i ;
Sylvain Thery's avatar
Sylvain Thery committed
684 685 686 687

	return amv ;
}

Sylvain Thery's avatar
Sylvain Thery committed
688 689 690 691 692 693 694
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
695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714

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

inline void GenericMap::boundaryMark(Dart d)
{
	m_markTables[DART][0]->operator[](dartIndex(d)).setMark(m_boundaryMarker);
}

inline void GenericMap::boundaryUnmark(Dart d)
{
	m_markTables[DART][0]->operator[](dartIndex(d)).unsetMark(m_boundaryMarker);
}

inline bool GenericMap::isBoundaryMarked(Dart d) const
{
	return m_markTables[DART][0]->operator[](dartIndex(d)).testMark(m_boundaryMarker);
}

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