genericmap.hpp 12 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
* 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
}

45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
inline void GenericMap::incCurrentLevel()
{
	if(m_mrCurrentLevel < m_mrDarts.size())
		++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();
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
		if (m_embeddings[i])
Pierre Kraemer's avatar
Pierre Kraemer committed
87 88
			(*m_embeddings[i])[di] = EMBNULL ;
	}
89

Pierre Kraemer's avatar
Pierre Kraemer committed
90 91 92
	if (m_isMultiRes)
	{
		unsigned int mrdi = m_mrattribs.insertLine() ;
93 94
		(*m_mrLevels)[mrdi] = m_mrCurrentLevel ;
		m_mrNbDarts[m_mrCurrentLevel]++ ;
Pierre Kraemer's avatar
Pierre Kraemer committed
95

Pierre Kraemer's avatar
Pierre Kraemer committed
96
		for(unsigned int i = 0; i < m_mrCurrentLevel; ++i)
97
			(*m_mrDarts[i])[mrdi] = MRNULL ;
Pierre Kraemer's avatar
Pierre Kraemer committed
98

99
		(*m_mrDarts[m_mrCurrentLevel])[mrdi] = di ;
Pierre Kraemer's avatar
Pierre Kraemer committed
100 101

		for(unsigned int i = m_mrCurrentLevel + 1; i < m_mrDarts.size(); ++i)
102 103
			(*m_mrDarts[i])[mrdi] = newCopyOfDartLine(di) ;

Pierre Kraemer's avatar
Pierre Kraemer committed
104 105
		return Dart::create(mrdi) ;
	}
106

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

inline void GenericMap::deleteDart(Dart d)
{
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
	// hypothese : lors d'une suppression de brin, les attributs du brin supprimé
	// sont identiques à tous les niveaux > au niveau où a lieu la suppression
	if(m_isMultiRes)
	{
		// if a dart is deleted on its insertion level
		// all the darts pointed in greater levels are deleted
		// and then the MRdart is deleted
		if((*m_mrLevels)[d.index] == m_mrCurrentLevel)
		{
			for(unsigned int i = m_mrCurrentLevel; i < m_mrDarts.size(); ++i)
				deleteDartLine((*m_mrDarts[i])[d.index]) ;
			m_mrattribs.removeLine(d.index) ;
			m_mrNbDarts[m_mrCurrentLevel]-- ;
		}
		// if a dart is deleted after its insertion level
		// the dart of previous level is copied in the greater levels
		else
		{
			unsigned int dprev = (*m_mrDarts[m_mrCurrentLevel - 1])[d.index] ;
			for(unsigned int i = m_mrCurrentLevel; i < m_mrDarts.size(); ++i)
				copyDartLine((*m_mrDarts[i])[d.index], dprev) ;
		}
	}
	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
Pierre Kraemer committed
145

Pierre Kraemer's avatar
Pierre Kraemer committed
146 147
	for(unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit)
	{
148
		if (m_embeddings[orbit])									// for each embedded orbit
Pierre Kraemer's avatar
Pierre Kraemer committed
149
		{
150
			unsigned int emb = (*m_embeddings[orbit])[index] ;		// get the embedding of the dart
Pierre Kraemer's avatar
Pierre Kraemer committed
151
			if(emb != EMBNULL)
Pierre Kraemer's avatar
Pierre Kraemer committed
152
			{
153
				if(m_attribs[orbit].unrefLine(emb))					// unref the pointed embedding line
Pierre Kraemer's avatar
Pierre Kraemer committed
154
				{
155 156
					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
Pierre Kraemer committed
157 158
				}
			}
Pierre Kraemer's avatar
Pierre Kraemer committed
159 160
		}
	}
161
}
Pierre Kraemer's avatar
Pierre Kraemer committed
162

163 164 165
inline void GenericMap::copyDartLine(unsigned int dest, unsigned int src)
{
	for(unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit)
Pierre Kraemer's avatar
Pierre Kraemer committed
166
	{
167
		if (m_embeddings[orbit])									// for each embedded orbit
Pierre Kraemer's avatar
Pierre Kraemer committed
168
		{
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
			unsigned int emb = (*m_embeddings[orbit])[dest] ;		// get the embedding of the destination dart
			if(emb != EMBNULL)
			{
				if(m_attribs[orbit].unrefLine(emb))					// unref the pointed embedding line
				{
					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)
				}
			}
		}
	}

	m_attribs[DART].copyLine(dest, src) ;

	for(unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit)
	{
		if (m_embeddings[orbit])									// for each embedded orbit
		{
			unsigned int emb = (*m_embeddings[orbit])[src] ;		// add a ref to the pointed attributes
			if(emb != EMBNULL)
				m_attribs[orbit].refLine(emb) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
190 191
		}
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
192 193
}

194
inline unsigned int GenericMap::newCopyOfDartLine(unsigned int index)
Pierre Kraemer's avatar
Pierre Kraemer committed
195
{
196 197 198 199 200 201 202 203 204 205 206 207
	unsigned int newindex = m_attribs[DART].insertLine() ;
	m_attribs[DART].copyLine(newindex, index) ;
	for(unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit)
	{
		if (m_embeddings[orbit])
		{
			unsigned int emb = (*m_embeddings[orbit])[newindex] ;	// add a ref to the pointed attributes
			if(emb != EMBNULL)
				m_attribs[orbit].refLine(emb) ;
		}
	}
	return newindex ;
Pierre Kraemer's avatar
Pierre Kraemer committed
208 209
}

210
inline unsigned int GenericMap::dartIndex(Dart d)
Pierre Kraemer's avatar
Pierre Kraemer committed
211
{
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232
	if (m_isMultiRes)
		return (*m_mrDarts[m_mrCurrentLevel])[d.index] ;
	return d.index;
}

inline unsigned int GenericMap::getDartLevel(Dart d)
{
	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
233
	{
234 235 236 237
		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
238
	}
239 240 241 242 243 244 245 246 247
	else
		return 0 ;
}

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

248
	return m_attribs[DART].size() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
249 250
}

251 252 253 254 255
inline bool GenericMap::isDartValid(Dart d)
{
	return !d.isNil() && m_attribs[DART].used(dartIndex(d)) ;
}

Pierre Kraemer's avatar
Pierre Kraemer committed
256 257 258 259 260 261
/****************************************
 *         EMBEDDING MANAGEMENT         *
 ****************************************/

inline bool GenericMap::isOrbitEmbedded(unsigned int orbit) const
{
262
	return (orbit == DART) || (m_embeddings[orbit] != NULL) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
263 264 265 266 267 268 269 270 271 272 273
}

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 ;
}

Pierre Kraemer's avatar
Pierre Kraemer committed
274
inline unsigned int GenericMap::getEmbedding(unsigned int orbit, Dart d)
Pierre Kraemer's avatar
Pierre Kraemer committed
275 276 277
{
	assert(isOrbitEmbedded(orbit) || !"Invalid parameter: orbit not embedded");

278 279
	unsigned int d_index = dartIndex(d);

280
	if (orbit == DART)
281
		return d_index;
Pierre Kraemer's avatar
Pierre Kraemer committed
282

283
	return (*m_embeddings[orbit])[d_index] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
284 285
}

286
inline void GenericMap::copyDartEmbedding(unsigned int orbit, Dart dest, Dart src)
Pierre Kraemer's avatar
Pierre Kraemer committed
287 288
{
	assert(isOrbitEmbedded(orbit) || !"Invalid parameter: orbit not embedded");
289
	setDartEmbedding(orbit, dest, getEmbedding(orbit, src));
Pierre Kraemer's avatar
Pierre Kraemer committed
290 291 292 293 294 295 296 297 298 299 300
}

inline unsigned int GenericMap::newCell(unsigned int orbit)
{
	assert(isOrbitEmbedded(orbit) || !"Invalid parameter: orbit not embedded");
	return m_attribs[orbit].insertLine();
}

inline void GenericMap::embedOrbit(unsigned int orbit, Dart d, unsigned int em)
{
	assert(isOrbitEmbedded(orbit) || !"Invalid parameter: orbit not embedded");
Pierre Kraemer's avatar
Pierre Kraemer committed
301
	FunctorSetEmb<GenericMap> fsetemb(*this, orbit, em);
Pierre Kraemer's avatar
Pierre Kraemer committed
302 303 304 305 306 307 308 309 310 311 312 313 314 315
	foreach_dart_of_orbit(orbit, d, fsetemb);
}

inline unsigned int GenericMap::embedNewCell(unsigned int orbit, Dart d)
{
	assert(isOrbitEmbedded(orbit) || !"Invalid parameter: orbit not embedded");
	unsigned int em = newCell(orbit);
	embedOrbit(orbit, d, em);
	return em;
}

inline void GenericMap::copyCell(unsigned int orbit, Dart d, Dart e)
{
	assert(isOrbitEmbedded(orbit) || !"Invalid parameter: orbit not embedded");
Pierre Kraemer's avatar
Pierre Kraemer committed
316 317
	unsigned int dE = getEmbedding(orbit, d) ;
	unsigned int eE = getEmbedding(orbit, e) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
318 319 320 321 322 323 324 325 326 327 328
	if(eE != EMBNULL)	// if the source is NULL, nothing to copy
	{
		if(dE == EMBNULL)	// if the dest is NULL, create a new cell
			dE = embedNewCell(orbit, d) ;
		m_attribs[orbit].copyLine(dE, eE) ;	// copy the data
	}
}

inline void GenericMap::copyCell(unsigned int orbit, unsigned int i, unsigned int j)
{
	assert(isOrbitEmbedded(orbit) || !"Invalid parameter: orbit not embedded");
Pierre Kraemer's avatar
Pierre Kraemer committed
329
	m_attribs[orbit].copyLine(i, j) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
330 331 332 333 334 335 336 337 338 339 340 341
}

inline void GenericMap::initCell(unsigned int orbit, unsigned int i)
{
	assert(isOrbitEmbedded(orbit) || !"Invalid parameter: orbit not embedded");
	m_attribs[orbit].initLine(i) ;
}

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

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

Pierre Kraemer's avatar
Pierre Kraemer committed
347
inline AttributeMultiVector<Mark>* GenericMap::getMarkVector(unsigned int orbit, unsigned int thread)
Pierre Kraemer's avatar
Pierre Kraemer committed
348
{
349
	assert(isOrbitEmbedded(orbit) || !"Invalid parameter: orbit not embedded") ;
Pierre Kraemer's avatar
Pierre Kraemer committed
350
	return m_markTables[orbit][thread] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
351 352
}

353
inline AttributeMultiVector<unsigned int>* GenericMap::getEmbeddingAttributeVector(unsigned int orbit)
Pierre Kraemer's avatar
Pierre Kraemer committed
354
{
355
	return m_embeddings[orbit] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
356 357 358 359 360 361 362 363
}

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

inline Dart GenericMap::begin()
{
364 365 366 367 368 369 370 371 372
	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
373 374 375 376
}

inline Dart GenericMap::end()
{
377 378 379
	if (m_isMultiRes)
		return Dart::create(m_mrattribs.end()) ;

380
	return Dart::create(m_attribs[DART].end()) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
381 382 383 384
}

inline void GenericMap::next(Dart& d)
{
385 386
	if (m_isMultiRes)
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
387 388
		do
		{
389
			m_mrattribs.next(d.index) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
390
		} while (d.index != m_mrattribs.end() && getDartLevel(d) > m_mrCurrentLevel) ;
391 392 393
	}
	else
		m_attribs[DART].next(d.index) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
394 395
}

Sylvain Thery's avatar
Sylvain Thery committed
396 397 398 399 400 401 402 403 404 405 406
/****************************************
 *  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))
407
		(*amv)[i] = i ;
Sylvain Thery's avatar
Sylvain Thery committed
408 409 410 411

	return amv ;
}

Sylvain Thery's avatar
Sylvain Thery committed
412 413 414 415 416 417 418
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 ;
}

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