genericmap.hpp 9.49 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 41 42 43 44 45 46 47 48
/****************************************
 *           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
49
		CGoGNout << "setCurrentLevel : try to access nonexistent resolution level" << CGoGNendl ;
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
}

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

inline unsigned int GenericMap::getDartLevel(Dart d)
{
70
	return m_mrLevels->operator[](d.index) ;
71 72
}

Pierre Kraemer's avatar
Pierre Kraemer committed
73 74 75 76 77 78
/****************************************
 *           DARTS MANAGEMENT           *
 ****************************************/

inline Dart GenericMap::newDart()
{
Pierre Kraemer's avatar
Pierre Kraemer committed
79
	unsigned int di = m_attribs[DART].insertLine();
Pierre Kraemer's avatar
Pierre Kraemer committed
80
	for(unsigned int i = 0; i < NB_ORBITS; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
81
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
82
		if (m_embeddings[i])
Pierre Kraemer's avatar
Pierre Kraemer committed
83 84 85 86 87
			(*m_embeddings[i])[di] = EMBNULL ;
	}
	if (m_isMultiRes)
	{
		unsigned int mrdi = m_mrattribs.insertLine() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
88
		m_mrLevels->operator[](mrdi) = m_mrCurrentLevel ;
Pierre Kraemer's avatar
Pierre Kraemer committed
89

Pierre Kraemer's avatar
Pierre Kraemer committed
90
		for(unsigned int i = 0; i < m_mrCurrentLevel; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
91
			m_mrDarts[i]->operator[](mrdi) = MRNULL ;
Pierre Kraemer's avatar
Pierre Kraemer committed
92 93 94 95 96 97 98 99 100 101 102 103 104

		m_mrDarts[m_mrCurrentLevel]->operator[](mrdi) = di ;

		for(unsigned int i = m_mrCurrentLevel + 1; i < m_mrDarts.size(); ++i)
		{
			unsigned int dj = m_attribs[DART].insertLine();
			for(unsigned int o = 0; o < NB_ORBITS; ++o)
			{
				if (m_embeddings[o])
					(*m_embeddings[o])[dj] = EMBNULL ;
			}
			m_mrDarts[i]->operator[](mrdi) = dj ;
		}
Pierre Kraemer's avatar
Pierre Kraemer committed
105 106 107
		return Dart::create(mrdi) ;
	}
	return Dart::create(di) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
108 109 110 111
}

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

Pierre Kraemer's avatar
Pierre Kraemer committed
117 118 119 120
	for(unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit)
	{
		if (m_embeddings[orbit])
		{
121
			unsigned int emb = (*m_embeddings[orbit])[d_index] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
122
			if(emb != EMBNULL)
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
123 124 125 126
			{
				if(m_attribs[orbit].unrefLine(emb))
				{
					for (unsigned int t = 0; t < m_nbThreads; ++t)
Pierre Kraemer's avatar
Pierre Kraemer committed
127
						m_markTables[orbit][t]->operator[](emb).clear() ;
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
128 129
				}
			}
Pierre Kraemer's avatar
Pierre Kraemer committed
130 131
		}
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
132 133 134 135 136 137 138 139

	// 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
140
			unsigned int di = m_mrDarts[m_mrCurrentLevel - 1]->operator[](d.index) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
141
			for(unsigned int i = m_mrCurrentLevel; i < m_mrDarts.size(); ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
142
				m_mrDarts[i]->operator[](d.index) = di ;
Pierre Kraemer's avatar
Pierre Kraemer committed
143 144
		}
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
145 146 147 148
}

inline bool GenericMap::isDartValid(Dart d)
{
Pierre Kraemer's avatar
Pierre Kraemer committed
149
	return !d.isNil() && m_attribs[DART].used(dartIndex(d)) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
150 151 152 153
}

inline unsigned int GenericMap::getNbDarts()
{
Pierre Kraemer's avatar
Pierre Kraemer committed
154 155 156 157 158 159 160 161
	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 ;
	}
162
	return m_attribs[DART].size() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
163 164 165 166 167 168 169 170
}

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

inline bool GenericMap::isOrbitEmbedded(unsigned int orbit) const
{
171
	return (orbit == DART) || (m_embeddings[orbit] != NULL) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
172 173 174 175 176 177 178 179 180 181 182
}

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

187 188
	unsigned int d_index = dartIndex(d);

189
	if (orbit == DART)
190
		return d_index;
Pierre Kraemer's avatar
Pierre Kraemer committed
191

192
	return (*m_embeddings[orbit])[d_index] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
193 194 195 196 197
}

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
198
	setDartEmbedding(orbit, d, getEmbedding(orbit, e));
Pierre Kraemer's avatar
Pierre Kraemer committed
199 200 201 202 203 204 205 206 207 208 209
}

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
210
	FunctorSetEmb<GenericMap> fsetemb(*this, orbit, em);
Pierre Kraemer's avatar
Pierre Kraemer committed
211 212 213 214 215 216 217 218 219 220 221 222 223 224
	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
225 226
	unsigned int dE = getEmbedding(orbit, d) ;
	unsigned int eE = getEmbedding(orbit, e) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
227 228 229 230 231 232 233 234 235 236 237
	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
238
	m_attribs[orbit].copyLine(i, j) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
239 240 241 242 243 244 245 246 247 248 249 250
}

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

251
inline AttributeContainer& GenericMap::getAttributeContainer(unsigned int orbit)
Pierre Kraemer's avatar
Pierre Kraemer committed
252
{
253
	return m_attribs[orbit] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
254 255
}

Pierre Kraemer's avatar
Pierre Kraemer committed
256
inline AttributeMultiVector<Mark>* GenericMap::getMarkVector(unsigned int orbit, unsigned int thread)
Pierre Kraemer's avatar
Pierre Kraemer committed
257
{
258
	assert(isOrbitEmbedded(orbit) || !"Invalid parameter: orbit not embedded") ;
Pierre Kraemer's avatar
Pierre Kraemer committed
259
	return m_markTables[orbit][thread] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
260 261
}

262
inline AttributeMultiVector<unsigned int>* GenericMap::getEmbeddingAttributeVector(unsigned int orbit)
Pierre Kraemer's avatar
Pierre Kraemer committed
263
{
264
	return m_embeddings[orbit] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
265 266 267 268 269 270 271 272
}

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

inline Dart GenericMap::begin()
{
273 274 275 276 277 278 279 280 281
	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
282 283 284 285
}

inline Dart GenericMap::end()
{
286 287 288
	if (m_isMultiRes)
		return Dart::create(m_mrattribs.end()) ;

289
	return Dart::create(m_attribs[DART].end()) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
290 291 292 293
}

inline void GenericMap::next(Dart& d)
{
294 295
	if (m_isMultiRes)
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
296 297
		do
		{
298
			m_mrattribs.next(d.index) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
299
		} while (d.index != m_mrattribs.end() && getDartLevel(d) > m_mrCurrentLevel) ;
300 301 302
	}
	else
		m_attribs[DART].next(d.index) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
303 304
}

Sylvain Thery's avatar
Sylvain Thery committed
305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320
/****************************************
 *  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
321 322 323 324 325 326 327
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
328
} //namespace CGoGN