genericmap.hpp 8.85 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
inline unsigned int GenericMap::dartIndex(Dart d)
{
	if (m_isMultiRes)
Pierre Kraemer's avatar
Pierre Kraemer committed
31
		return m_mrDarts[m_mrCurrentLevel]->operator[](d.index) ;
32 33
	return d.index;
}
Pierre Kraemer's avatar
Pierre Kraemer committed
34 35 36 37 38 39 40

/****************************************
 *           DARTS MANAGEMENT           *
 ****************************************/

inline Dart GenericMap::newDart()
{
Pierre Kraemer's avatar
Pierre Kraemer committed
41
	unsigned int di = m_attribs[DART].insertLine();
Pierre Kraemer's avatar
Pierre Kraemer committed
42
	for(unsigned int i = 0; i < NB_ORBITS; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
43
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
44
		if (m_embeddings[i])
Pierre Kraemer's avatar
Pierre Kraemer committed
45 46 47 48 49
			(*m_embeddings[i])[di] = EMBNULL ;
	}
	if (m_isMultiRes)
	{
		unsigned int mrdi = m_mrattribs.insertLine() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
50
		m_mrLevels->operator[](mrdi) = m_mrCurrentLevel ;
Pierre Kraemer's avatar
Pierre Kraemer committed
51
		for(unsigned int i = 0; i < m_mrCurrentLevel; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
52
			m_mrDarts[i]->operator[](mrdi) = MRNULL ;
Pierre Kraemer's avatar
Pierre Kraemer committed
53
		for(unsigned int i = m_mrCurrentLevel; i < m_mrDarts.size(); ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
54
			m_mrDarts[i]->operator[](mrdi) = di ;
Pierre Kraemer's avatar
Pierre Kraemer committed
55 56 57
		return Dart::create(mrdi) ;
	}
	return Dart::create(di) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
58 59 60 61
}

inline void GenericMap::deleteDart(Dart d)
{
62 63
	unsigned int d_index = dartIndex(d);
	m_attribs[DART].removeLine(d_index) ;
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
64
	for (unsigned int t = 0; t < m_nbThreads; ++t)
65
		m_markTables[DART][t]->operator[](d_index).clear() ;
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
66

Pierre Kraemer's avatar
Pierre Kraemer committed
67 68 69 70
	for(unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit)
	{
		if (m_embeddings[orbit])
		{
71
			unsigned int emb = (*m_embeddings[orbit])[d_index] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
72
			if(emb != EMBNULL)
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
73 74 75 76
			{
				if(m_attribs[orbit].unrefLine(emb))
				{
					for (unsigned int t = 0; t < m_nbThreads; ++t)
Pierre Kraemer's avatar
Pierre Kraemer committed
77
						m_markTables[orbit][t]->operator[](emb).clear() ;
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
78 79
				}
			}
Pierre Kraemer's avatar
Pierre Kraemer committed
80 81
		}
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
82 83 84 85 86 87 88 89

	// hypothese : le brin MR pointe vers le même brin pour tous les niveaux >= au courant
	if(m_isMultiRes)
	{
		if(m_mrCurrentLevel == 0)
			m_mrattribs.removeLine(d.index) ;
		else
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
90
			unsigned int di = m_mrDarts[m_mrCurrentLevel - 1]->operator[](d.index) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
91
			for(unsigned int i = m_mrCurrentLevel; i < m_mrDarts.size(); ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
92
				m_mrDarts[i]->operator[](d.index) = di ;
Pierre Kraemer's avatar
Pierre Kraemer committed
93 94
		}
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
95 96 97 98
}

inline bool GenericMap::isDartValid(Dart d)
{
Pierre Kraemer's avatar
Pierre Kraemer committed
99
	return !d.isNil() && m_attribs[DART].used(dartIndex(d)) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
100 101 102 103
}

inline unsigned int GenericMap::getNbDarts()
{
Pierre Kraemer's avatar
Pierre Kraemer committed
104 105 106 107 108 109 110 111
	if(m_isMultiRes)
	{
		unsigned int nbDarts = 0 ;
		for(unsigned int i = m_mrattribs.begin(); i != m_mrattribs.end(); m_mrattribs.next(i))
			if(m_mrLevels->operator[](i) <= m_mrCurrentLevel)
				++nbDarts ;
		return nbDarts ;
	}
112
	return m_attribs[DART].size() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
113 114 115 116 117 118 119 120
}

/****************************************
 *         EMBEDDING MANAGEMENT         *
 ****************************************/

inline bool GenericMap::isOrbitEmbedded(unsigned int orbit) const
{
121
	return (orbit == DART) || (m_embeddings[orbit] != NULL) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
122 123 124 125 126 127 128 129 130 131 132
}

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
133
inline unsigned int GenericMap::getEmbedding(unsigned int orbit, Dart d)
Pierre Kraemer's avatar
Pierre Kraemer committed
134 135 136
{
	assert(isOrbitEmbedded(orbit) || !"Invalid parameter: orbit not embedded");

137 138
	unsigned int d_index = dartIndex(d);

139
	if (orbit == DART)
140
		return d_index;
Pierre Kraemer's avatar
Pierre Kraemer committed
141

142
	return (*m_embeddings[orbit])[d_index] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
143 144 145 146 147
}

inline void GenericMap::copyDartEmbedding(unsigned int orbit, Dart d, Dart e)
{
	assert(isOrbitEmbedded(orbit) || !"Invalid parameter: orbit not embedded");
Pierre Kraemer's avatar
Pierre Kraemer committed
148
	setDartEmbedding(orbit, d, getEmbedding(orbit, e));
Pierre Kraemer's avatar
Pierre Kraemer committed
149 150 151 152 153 154 155 156 157 158 159
}

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
merge..  
Pierre Kraemer committed
160
	FunctorSetEmb<GenericMap> fsetemb(*this, orbit, em);
Pierre Kraemer's avatar
Pierre Kraemer committed
161 162 163 164 165 166 167 168 169 170 171 172 173 174
	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
175 176
	unsigned int dE = getEmbedding(orbit, d) ;
	unsigned int eE = getEmbedding(orbit, e) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
177 178 179 180 181 182 183 184 185 186 187
	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
188
	m_attribs[orbit].copyLine(i, j) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
189 190 191 192 193 194 195 196 197 198 199 200
}

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         *
 ****************************************/

201
inline AttributeContainer& GenericMap::getAttributeContainer(unsigned int orbit)
Pierre Kraemer's avatar
Pierre Kraemer committed
202
{
203
	return m_attribs[orbit] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
204 205
}

Pierre Kraemer's avatar
Pierre Kraemer committed
206
inline AttributeMultiVector<Mark>* GenericMap::getMarkVector(unsigned int orbit, unsigned int thread)
Pierre Kraemer's avatar
Pierre Kraemer committed
207
{
208
	assert(isOrbitEmbedded(orbit) || !"Invalid parameter: orbit not embedded") ;
Pierre Kraemer's avatar
Pierre Kraemer committed
209
	return m_markTables[orbit][thread] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
210 211
}

212
inline AttributeMultiVector<unsigned int>* GenericMap::getEmbeddingAttributeVector(unsigned int orbit)
Pierre Kraemer's avatar
Pierre Kraemer committed
213
{
214
	return m_embeddings[orbit] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
215 216 217 218 219 220 221 222
}

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

inline Dart GenericMap::begin()
{
223
	return Dart::create(m_attribs[DART].begin());
Pierre Kraemer's avatar
Pierre Kraemer committed
224 225 226 227
}

inline Dart GenericMap::end()
{
228
	return Dart::create(m_attribs[DART].end()) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
229 230 231 232
}

inline void GenericMap::next(Dart& d)
{
233 234 235 236
	unsigned int d_index = dartIndex(d);
	m_attribs[DART].next(d_index) ;

	d = Dart::create(d_index);
Pierre Kraemer's avatar
Pierre Kraemer committed
237 238
}

Sylvain Thery's avatar
Sylvain Thery committed
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
/****************************************
 *  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))
		amv->operator[](i) = i ;

	return amv ;
}

Sylvain Thery's avatar
Sylvain Thery committed
255 256 257 258 259 260 261
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 ;
}

262 263 264 265 266

/******************************************
 *  TOPOLOGICAL MULTIRESOLUTION MANAGEMENT*
 ******************************************/

267
inline unsigned int GenericMap::getCurrentLevel()
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299
{
	return m_mrCurrentLevel ;
}


inline void GenericMap::setCurrentLevel(unsigned int l)
{
	if (l < m_mrDarts.size())
		m_mrCurrentLevel = l ;
	else
		CGoGNout << "try to access inexisting resolution level" << CGoGNendl ;
}

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