genericmap.hpp 9.24 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 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
/****************************************
 *           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
		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 ;
}

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

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
		for(unsigned int i = 0; i < m_mrCurrentLevel; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
90
			m_mrDarts[i]->operator[](mrdi) = MRNULL ;
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[](mrdi) = di ;
Pierre Kraemer's avatar
Pierre Kraemer committed
93 94 95
		return Dart::create(mrdi) ;
	}
	return Dart::create(di) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
96 97 98 99
}

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

Pierre Kraemer's avatar
Pierre Kraemer committed
105 106 107 108
	for(unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit)
	{
		if (m_embeddings[orbit])
		{
109
			unsigned int emb = (*m_embeddings[orbit])[d_index] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
110
			if(emb != EMBNULL)
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
111 112 113 114
			{
				if(m_attribs[orbit].unrefLine(emb))
				{
					for (unsigned int t = 0; t < m_nbThreads; ++t)
Pierre Kraemer's avatar
Pierre Kraemer committed
115
						m_markTables[orbit][t]->operator[](emb).clear() ;
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
116 117
				}
			}
Pierre Kraemer's avatar
Pierre Kraemer committed
118 119
		}
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
120 121 122 123 124 125 126 127

	// 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
128
			unsigned int di = m_mrDarts[m_mrCurrentLevel - 1]->operator[](d.index) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
129
			for(unsigned int i = m_mrCurrentLevel; i < m_mrDarts.size(); ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
130
				m_mrDarts[i]->operator[](d.index) = di ;
Pierre Kraemer's avatar
Pierre Kraemer committed
131 132
		}
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
133 134 135 136
}

inline bool GenericMap::isDartValid(Dart d)
{
Pierre Kraemer's avatar
Pierre Kraemer committed
137
	return !d.isNil() && m_attribs[DART].used(dartIndex(d)) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
138 139 140 141
}

inline unsigned int GenericMap::getNbDarts()
{
Pierre Kraemer's avatar
Pierre Kraemer committed
142 143 144 145 146 147 148 149
	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 ;
	}
150
	return m_attribs[DART].size() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
151 152 153 154 155 156 157 158
}

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

inline bool GenericMap::isOrbitEmbedded(unsigned int orbit) const
{
159
	return (orbit == DART) || (m_embeddings[orbit] != NULL) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
160 161 162 163 164 165 166 167 168 169 170
}

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

175 176
	unsigned int d_index = dartIndex(d);

177
	if (orbit == DART)
178
		return d_index;
Pierre Kraemer's avatar
Pierre Kraemer committed
179

180
	return (*m_embeddings[orbit])[d_index] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
181 182 183 184 185
}

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
186
	setDartEmbedding(orbit, d, getEmbedding(orbit, e));
Pierre Kraemer's avatar
Pierre Kraemer committed
187 188 189 190 191 192 193 194 195 196 197
}

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
198
	FunctorSetEmb<GenericMap> fsetemb(*this, orbit, em);
Pierre Kraemer's avatar
Pierre Kraemer committed
199 200 201 202 203 204 205 206 207 208 209 210 211 212
	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
213 214
	unsigned int dE = getEmbedding(orbit, d) ;
	unsigned int eE = getEmbedding(orbit, e) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
215 216 217 218 219 220 221 222 223 224 225
	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
226
	m_attribs[orbit].copyLine(i, j) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
227 228 229 230 231 232 233 234 235 236 237 238
}

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

239
inline AttributeContainer& GenericMap::getAttributeContainer(unsigned int orbit)
Pierre Kraemer's avatar
Pierre Kraemer committed
240
{
241
	return m_attribs[orbit] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
242 243
}

Pierre Kraemer's avatar
Pierre Kraemer committed
244
inline AttributeMultiVector<Mark>* GenericMap::getMarkVector(unsigned int orbit, unsigned int thread)
Pierre Kraemer's avatar
Pierre Kraemer committed
245
{
246
	assert(isOrbitEmbedded(orbit) || !"Invalid parameter: orbit not embedded") ;
Pierre Kraemer's avatar
Pierre Kraemer committed
247
	return m_markTables[orbit][thread] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
248 249
}

250
inline AttributeMultiVector<unsigned int>* GenericMap::getEmbeddingAttributeVector(unsigned int orbit)
Pierre Kraemer's avatar
Pierre Kraemer committed
251
{
252
	return m_embeddings[orbit] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
253 254 255 256 257 258 259 260
}

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

inline Dart GenericMap::begin()
{
261 262 263 264 265 266 267 268 269
	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
270 271 272 273
}

inline Dart GenericMap::end()
{
274 275 276
	if (m_isMultiRes)
		return Dart::create(m_mrattribs.end()) ;

277
	return Dart::create(m_attribs[DART].end()) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
278 279 280 281
}

inline void GenericMap::next(Dart& d)
{
282 283 284 285 286 287 288
	if (m_isMultiRes)
	{
		while ((d.index != m_mrattribs.end() ) && (getDartLevel(d.index) > m_mrCurrentLevel))
			m_mrattribs.next(d.index) ;
	}
	else
		m_attribs[DART].next(d.index) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
289 290
}

Sylvain Thery's avatar
Sylvain Thery committed
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306
/****************************************
 *  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
307 308 309 310 311 312 313
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
314
} //namespace CGoGN