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

namespace CGoGN
{
Pierre Kraemer's avatar
Pierre Kraemer committed
27

28 29 30 31 32 33 34 35 36 37 38 39 40 41
/****************************************
 *           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
42
		CGoGNout << "setCurrentLevel : try to access nonexistent resolution level" << CGoGNendl ;
43 44
}

Pierre Kraemer's avatar
Pierre Kraemer committed
45 46
inline void GenericMap::incCurrentLevel()
{
47
	if(m_mrCurrentLevel < m_mrDarts.size() - 1)
Pierre Kraemer's avatar
Pierre Kraemer committed
48 49 50 51 52 53 54 55 56 57 58 59 60
		++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 ;
}

61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
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 ;
}

Pierre Kraemer's avatar
Pierre Kraemer committed
77 78 79 80 81 82
/****************************************
 *           DARTS MANAGEMENT           *
 ****************************************/

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

Pierre Kraemer's avatar
Pierre Kraemer committed
90 91
	if (m_isMultiRes)
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
92 93
		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
94
		m_mrNbDarts[m_mrCurrentLevel]++ ;
Pierre Kraemer's avatar
Pierre Kraemer committed
95

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

99 100 101 102 103 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

		(*m_mrDarts[m_mrCurrentLevel])[mrdi] = di ;		// for the current level, this MRdart points to the new dart line

		for(unsigned int i = m_mrCurrentLevel + 1; i < m_mrDarts.size(); ++i)	// for all levels from current + 1 to max
			(*m_mrDarts[i])[mrdi] = copyDartLine(di) ;							// make this MRdart point to a copy of the new dart line
Pierre Kraemer's avatar
Pierre Kraemer committed
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)
	{
117 118 119 120
		// a MRdart can only be deleted on its insertion level
		assert(getDartLevel(d) == m_mrCurrentLevel || !"deleteDart : try to delete a dart on a level greater than its insertion level") ;

		for(unsigned int i = m_mrCurrentLevel; i < m_mrDarts.size(); ++i)
121 122 123 124 125
		{
			unsigned int index = (*m_mrDarts[i])[d.index] ;
			if(isDartValid(index))
				deleteDartLine(index) ;
		}
126 127
		m_mrattribs.removeLine(d.index) ;
		m_mrNbDarts[m_mrCurrentLevel]-- ;
Pierre Kraemer's avatar
Pierre Kraemer committed
128 129 130 131 132 133 134 135 136 137 138
	}
	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
		(*m_markTables[DART][t])[index].clear() ;	// the removed dart
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
139

Pierre Kraemer's avatar
Pierre Kraemer committed
140 141
	for(unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit)
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
142
		if (m_embeddings[orbit])									// for each embedded orbit
Pierre Kraemer's avatar
Pierre Kraemer committed
143
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
144
			unsigned int emb = (*m_embeddings[orbit])[index] ;		// get the embedding of the dart
Pierre Kraemer's avatar
Pierre Kraemer committed
145
			if(emb != EMBNULL)
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
146
			{
Pierre Kraemer's avatar
Pierre Kraemer committed
147
				if(m_attribs[orbit].unrefLine(emb))					// unref the pointed embedding line
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
148
				{
Pierre Kraemer's avatar
Pierre Kraemer committed
149 150
					for (unsigned int t = 0; t < m_nbThreads; ++t)	// and clear its markers if it was
						(*m_markTables[orbit][t])[emb].clear() ;	// its last unref (and was thus freed)
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
151 152
				}
			}
Pierre Kraemer's avatar
Pierre Kraemer committed
153 154
		}
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
155
}
Pierre Kraemer's avatar
Pierre Kraemer committed
156

Pierre Kraemer's avatar
Pierre Kraemer committed
157
inline unsigned int GenericMap::copyDartLine(unsigned int index)
Pierre Kraemer's avatar
Pierre Kraemer committed
158
{
159 160
	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
161 162
	for(unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit)
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
163 164 165 166 167 168
		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
169 170
	}
	return newindex ;
Pierre Kraemer's avatar
Pierre Kraemer committed
171 172
}

Pierre Kraemer's avatar
Pierre Kraemer committed
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
inline void GenericMap::duplicateDart(Dart d)
{
	assert(getDartLevel(d) <= getCurrentLevel() || !"duplicateDart : called with a dart inserted after current level") ;

	if(getDartLevel(d) == getCurrentLevel())	// no need to duplicate
		return ;								// a dart from its insertion level

	unsigned int oldindex = dartIndex(d) ;

	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

	unsigned int newindex = copyDartLine(oldindex) ;

	for(unsigned int i = getCurrentLevel(); i <= getMaxLevel(); ++i) // for all levels from current to max
	{
		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
	}
}

Sylvain Thery's avatar
Sylvain Thery committed
194
inline unsigned int GenericMap::dartIndex(Dart d) const
Pierre Kraemer's avatar
Pierre Kraemer committed
195
{
Pierre Kraemer's avatar
Pierre Kraemer committed
196 197 198 199 200
	if (m_isMultiRes)
		return (*m_mrDarts[m_mrCurrentLevel])[d.index] ;
	return d.index;
}

201
inline unsigned int GenericMap::getDartLevel(Dart d) const
Pierre Kraemer's avatar
Pierre Kraemer committed
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
{
	return (*m_mrLevels)[d.index] ;
}

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
217
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
218 219 220 221
		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
222
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
223 224 225 226 227 228 229 230 231
	else
		return 0 ;
}

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

232
	return m_attribs[DART].size() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
233 234
}

Pierre Kraemer's avatar
Pierre Kraemer committed
235 236 237 238 239
inline bool GenericMap::isDartValid(Dart d)
{
	return !d.isNil() && m_attribs[DART].used(dartIndex(d)) ;
}

Pierre Kraemer's avatar
Pierre Kraemer committed
240 241 242 243 244 245
/****************************************
 *         EMBEDDING MANAGEMENT         *
 ****************************************/

inline bool GenericMap::isOrbitEmbedded(unsigned int orbit) const
{
246
	return (orbit == DART) || (m_embeddings[orbit] != NULL) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
247 248 249 250 251 252 253 254 255 256 257
}

inline unsigned int GenericMap::nbEmbeddings() const
{
	unsigned int nb = 0;
	for(unsigned int i = 0; i < NB_ORBITS; ++i)
		if (isOrbitEmbedded(i))
			++nb;
	return nb ;
}

258 259
template <unsigned int ORBIT>
inline unsigned int GenericMap::getEmbedding(Dart d)
Pierre Kraemer's avatar
Pierre Kraemer committed
260
{
261
	assert(isOrbitEmbedded(ORBIT) || !"Invalid parameter: orbit not embedded");
Pierre Kraemer's avatar
Pierre Kraemer committed
262

263 264
	unsigned int d_index = dartIndex(d);

265
	if (ORBIT == DART)
266
		return d_index;
Pierre Kraemer's avatar
Pierre Kraemer committed
267

268
	return (*m_embeddings[ORBIT])[d_index] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
269 270
}

271 272
template <unsigned int ORBIT>
inline void GenericMap::copyDartEmbedding(Dart dest, Dart src)
Pierre Kraemer's avatar
Pierre Kraemer committed
273
{
274 275
	assert(isOrbitEmbedded(ORBIT) || !"Invalid parameter: orbit not embedded");
	setDartEmbedding<ORBIT>(dest, getEmbedding<ORBIT>(src));
Pierre Kraemer's avatar
Pierre Kraemer committed
276 277
}

278 279
template <unsigned int ORBIT>
inline unsigned int GenericMap::newCell()
Pierre Kraemer's avatar
Pierre Kraemer committed
280
{
281 282
	assert(isOrbitEmbedded(ORBIT) || !"Invalid parameter: orbit not embedded");
	return m_attribs[ORBIT].insertLine();
Pierre Kraemer's avatar
Pierre Kraemer committed
283 284
}

285 286
template <unsigned int ORBIT>
inline void GenericMap::embedOrbit(Dart d, unsigned int em)
Pierre Kraemer's avatar
Pierre Kraemer committed
287
{
288 289 290
	assert(isOrbitEmbedded(ORBIT) || !"Invalid parameter: orbit not embedded");
	FunctorSetEmb<GenericMap, ORBIT> fsetemb(*this, em);
	foreach_dart_of_orbit<ORBIT>(d, fsetemb);
Pierre Kraemer's avatar
Pierre Kraemer committed
291 292
}

293 294
template <unsigned int ORBIT>
inline unsigned int GenericMap::embedNewCell(Dart d)
Pierre Kraemer's avatar
Pierre Kraemer committed
295
{
296 297 298
	assert(isOrbitEmbedded(ORBIT) || !"Invalid parameter: orbit not embedded");
	unsigned int em = newCell<ORBIT>();
	embedOrbit<ORBIT>(d, em);
Pierre Kraemer's avatar
Pierre Kraemer committed
299 300 301
	return em;
}

302 303
template <unsigned int ORBIT>
inline void GenericMap::copyCell(Dart d, Dart e)
Pierre Kraemer's avatar
Pierre Kraemer committed
304
{
305 306 307
	assert(isOrbitEmbedded(ORBIT) || !"Invalid parameter: orbit not embedded");
	unsigned int dE = getEmbedding<ORBIT>(d) ;
	unsigned int eE = getEmbedding<ORBIT>(e) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
308 309 310
	if(eE != EMBNULL)	// if the source is NULL, nothing to copy
	{
		if(dE == EMBNULL)	// if the dest is NULL, create a new cell
311 312
			dE = embedNewCell<ORBIT>(d) ;
		m_attribs[ORBIT].copyLine(dE, eE) ;	// copy the data
Pierre Kraemer's avatar
Pierre Kraemer committed
313 314 315
	}
}

316 317
template <unsigned int ORBIT>
inline void GenericMap::copyCell(unsigned int i, unsigned int j)
Pierre Kraemer's avatar
Pierre Kraemer committed
318
{
319 320
	assert(isOrbitEmbedded(ORBIT) || !"Invalid parameter: orbit not embedded");
	m_attribs[ORBIT].copyLine(i, j) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
321 322
}

323 324
template <unsigned int ORBIT>
inline void GenericMap::initCell(unsigned int i)
Pierre Kraemer's avatar
Pierre Kraemer committed
325
{
326 327
	assert(isOrbitEmbedded(ORBIT) || !"Invalid parameter: orbit not embedded");
	m_attribs[ORBIT].initLine(i) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
328 329 330 331 332 333
}

/****************************************
 *        ATTRIBUTES MANAGEMENT         *
 ****************************************/

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

340 341
template <unsigned int ORBIT>
inline AttributeMultiVector<Mark>* GenericMap::getMarkVector(unsigned int thread)
Pierre Kraemer's avatar
Pierre Kraemer committed
342
{
343 344
	assert(isOrbitEmbedded(ORBIT) || !"Invalid parameter: orbit not embedded") ;
	return m_markTables[ORBIT][thread] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
345 346
}

347 348
template <unsigned int ORBIT>
inline AttributeMultiVector<unsigned int>* GenericMap::getEmbeddingAttributeVector()
Pierre Kraemer's avatar
Pierre Kraemer committed
349
{
350
	return m_embeddings[ORBIT] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
351 352 353 354 355 356
}

/****************************************
 *           DARTS TRAVERSALS           *
 ****************************************/

357
inline Dart GenericMap::begin() const
Pierre Kraemer's avatar
Pierre Kraemer committed
358
{
359 360 361 362 363 364 365 366 367
	if (m_isMultiRes)
	{
		unsigned int d = m_mrattribs.begin() ;
		while (getDartLevel(d) > m_mrCurrentLevel)
			m_mrattribs.next(d) ;
		return Dart::create(d) ;
	}

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

370
inline Dart GenericMap::end() const
Pierre Kraemer's avatar
Pierre Kraemer committed
371
{
372 373 374
	if (m_isMultiRes)
		return Dart::create(m_mrattribs.end()) ;

375
	return Dart::create(m_attribs[DART].end()) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
376 377
}

378
inline void GenericMap::next(Dart& d) const
Pierre Kraemer's avatar
Pierre Kraemer committed
379
{
380 381
	if (m_isMultiRes)
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
382 383
		do
		{
384
			m_mrattribs.next(d.index) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
385
		} while (d.index != m_mrattribs.end() && getDartLevel(d) > m_mrCurrentLevel) ;
386 387 388
	}
	else
		m_attribs[DART].next(d.index) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
389 390
}

Sylvain Thery's avatar
Sylvain Thery committed
391 392 393 394 395 396 397 398 399 400 401
/****************************************
 *  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
402
		(*amv)[i] = i ;
Sylvain Thery's avatar
Sylvain Thery committed
403 404 405 406

	return amv ;
}

Sylvain Thery's avatar
Sylvain Thery committed
407 408 409 410 411 412 413
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
414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434

/**************************
 *  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
435
} //namespace CGoGN