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

25
#include "Topology/generic/dartmarker.h"
26 27
#include "Topology/generic/traversor/traversorCell.h"
#include "Topology/generic/traversor/traversorFactory.h"
28

Pierre Kraemer's avatar
Pierre Kraemer committed
29 30
namespace CGoGN
{
Sylvain Thery's avatar
Sylvain Thery committed
31 32 33 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 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
/****************************************
 *           BUFFERS MANAGEMENT           *
 ****************************************/

inline std::vector<Dart>* GenericMap::askDartBuffer(unsigned int thread)
{
	if (s_vdartsBuffers[thread].empty())
	{
		std::vector<Dart>* vd = new std::vector<Dart>;
		vd->reserve(128);
		return vd;
	}

	std::vector<Dart>* vd = s_vdartsBuffers[thread].back();
	s_vdartsBuffers[thread].pop_back();
	return vd;
}

inline void GenericMap::releaseDartBuffer(std::vector<Dart>* vd, unsigned int thread)
{
	if (vd->capacity()>1024)
	{
		std::vector<Dart> v;
		vd->swap(v);
		vd->reserve(128);
	}
	vd->clear();
	s_vdartsBuffers[thread].push_back(vd);
}


inline std::vector<unsigned int>* GenericMap::askUIntBuffer(unsigned int thread)
{
	if (s_vintsBuffers[thread].empty())
	{
		std::vector<unsigned int>* vui = new std::vector<unsigned int>;
		vui->reserve(128);
		return vui;
	}

	std::vector<unsigned int>* vui = s_vintsBuffers[thread].back();
	s_vintsBuffers[thread].pop_back();
	return vui;
}

inline void GenericMap::releaseUIntBuffer(std::vector<unsigned int>* vui, unsigned int thread)
{
	if (vui->capacity()>1024)
	{
		std::vector<unsigned int> v;
		vui->swap(v);
		vui->reserve(128);
	}
	vui->clear();
	s_vintsBuffers[thread].push_back(vui);
}


Pierre Kraemer's avatar
Pierre Kraemer committed
89

Pierre Kraemer's avatar
Pierre Kraemer committed
90 91 92 93 94 95
/****************************************
 *           DARTS MANAGEMENT           *
 ****************************************/

inline Dart GenericMap::newDart()
{
96
	unsigned int di = m_attribs[DART].insertLine();		// insert a new dart line
Pierre Kraemer's avatar
Pierre Kraemer committed
97
	for(unsigned int i = 0; i < NB_ORBITS; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
98
	{
99 100
		if (m_embeddings[i])							// set all its embeddings
			(*m_embeddings[i])[di] = EMBNULL ;			// to EMBNULL
Pierre Kraemer's avatar
Pierre Kraemer committed
101
	}
102

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

106 107 108 109
inline void GenericMap::deleteDartLine(unsigned int index)
{
	m_attribs[DART].removeLine(index) ;	// free the dart line

Pierre Kraemer's avatar
Pierre Kraemer committed
110 111
	for(unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit)
	{
112
		if (m_embeddings[orbit])									// for each embedded orbit
Pierre Kraemer's avatar
Pierre Kraemer committed
113
		{
114
			unsigned int emb = (*m_embeddings[orbit])[index] ;		// get the embedding of the dart
Pierre Kraemer's avatar
Pierre Kraemer committed
115
			if(emb != EMBNULL)
Sylvain Thery's avatar
Sylvain Thery committed
116
				m_attribs[orbit].unrefLine(emb);					// and unref the corresponding line
Pierre Kraemer's avatar
Pierre Kraemer committed
117 118
		}
	}
119
}
Pierre Kraemer's avatar
Pierre Kraemer committed
120

Pierre Kraemer's avatar
Pierre Kraemer committed
121
inline unsigned int GenericMap::copyDartLine(unsigned int index)
Pierre Kraemer's avatar
Pierre Kraemer committed
122
{
123 124
	unsigned int newindex = m_attribs[DART].insertLine() ;	// create a new dart line
	m_attribs[DART].copyLine(newindex, index) ;				// copy the given dart line
125 126
	for(unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit)
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
127 128 129 130 131 132
		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) ;
		}
133 134
	}
	return newindex ;
Pierre Kraemer's avatar
Pierre Kraemer committed
135 136
}

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

Pierre Kraemer's avatar
Pierre Kraemer committed
142 143 144 145
/****************************************
 *         EMBEDDING MANAGEMENT         *
 ****************************************/

146 147
template <unsigned int ORBIT>
inline bool GenericMap::isOrbitEmbedded() const
Pierre Kraemer's avatar
Pierre Kraemer committed
148
{
149
	return (ORBIT == DART) || (m_embeddings[ORBIT] != NULL) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
150 151
}

152
inline bool GenericMap::isOrbitEmbedded(unsigned int orbit) const
Pierre Kraemer's avatar
Pierre Kraemer committed
153
{
154
	return (orbit == DART) || (m_embeddings[orbit] != NULL) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
155 156
}

157 158
template <unsigned int ORBIT>
inline unsigned int GenericMap::newCell()
Pierre Kraemer's avatar
Pierre Kraemer committed
159
{
160
	assert(isOrbitEmbedded<ORBIT>() || !"Invalid parameter: orbit not embedded");
161
	return m_attribs[ORBIT].insertLine();
Pierre Kraemer's avatar
Pierre Kraemer committed
162 163
}

164 165
template <unsigned int ORBIT>
inline void GenericMap::copyCell(unsigned int i, unsigned int j)
Pierre Kraemer's avatar
Pierre Kraemer committed
166
{
167
	assert(isOrbitEmbedded<ORBIT>() || !"Invalid parameter: orbit not embedded");
168
	m_attribs[ORBIT].copyLine(i, j) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
169 170
}

171 172
template <unsigned int ORBIT>
inline void GenericMap::initCell(unsigned int i)
Pierre Kraemer's avatar
Pierre Kraemer committed
173
{
174
	assert(isOrbitEmbedded<ORBIT>() || !"Invalid parameter: orbit not embedded");
175
	m_attribs[ORBIT].initLine(i) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
176 177
}

Pierre Kraemer's avatar
Pierre Kraemer committed
178
/****************************************
179
 *   ATTRIBUTES CONTAINERS MANAGEMENT   *
Pierre Kraemer's avatar
Pierre Kraemer committed
180 181
 ****************************************/

182 183 184 185 186
inline unsigned int GenericMap::getNbCells(unsigned int orbit)
{
	return m_attribs[orbit].size() ;
}

187 188
template <unsigned int ORBIT>
inline AttributeContainer& GenericMap::getAttributeContainer()
Pierre Kraemer's avatar
Pierre Kraemer committed
189
{
190
	return m_attribs[ORBIT] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
191 192
}

Sylvain Thery's avatar
Sylvain Thery committed
193 194 195 196 197 198
template <unsigned int ORBIT>
inline const AttributeContainer& GenericMap::getAttributeContainer() const
{
	return m_attribs[ORBIT] ;
}

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

Sylvain Thery's avatar
Sylvain Thery committed
204 205 206 207 208
inline const AttributeContainer& GenericMap::getAttributeContainer(unsigned int orbit) const
{
	return m_attribs[orbit] ;
}

Pierre Kraemer's avatar
Pierre Kraemer committed
209 210 211 212 213
inline AttributeMultiVectorGen* GenericMap::getAttributeVectorGen(unsigned int orbit, const std::string& nameAttr)
{
	return m_attribs[orbit].getVirtualDataVector(nameAttr) ;
}

Sylvain Thery's avatar
Sylvain Thery committed
214 215

template <unsigned int ORBIT>
Sylvain Thery's avatar
Sylvain Thery committed
216
AttributeMultiVector<MarkerBool>* GenericMap::askMarkVector(unsigned int thread)
Sylvain Thery's avatar
Sylvain Thery committed
217 218 219
{
	assert(isOrbitEmbedded<ORBIT>() || !"Invalid parameter: orbit not embedded") ;

Sylvain Thery's avatar
Sylvain Thery committed
220
	if (!m_markVectors_free[ORBIT][thread].empty())
Sylvain Thery's avatar
Sylvain Thery committed
221
	{
Sylvain Thery's avatar
Sylvain Thery committed
222 223 224 225 226 227
		AttributeMultiVector<MarkerBool>* amv = m_markVectors_free[ORBIT][thread].back();
		m_markVectors_free[ORBIT][thread].pop_back();
		return amv;
	}
	else
	{
Sylvain Thery's avatar
Sylvain Thery committed
228
		std::lock_guard<std::mutex> lockMV(m_MarkerStorageMutex[ORBIT]);
229 230 231 232 233 234 235 236 237 238

		unsigned int x=m_nextMarkerId++;
		std::string number("___");
		number[2]= '0'+x%10;
		x = x/10;
		number[1]= '0'+x%10;
		x = x/10;
		number[0]= '0'+x%10;

		AttributeMultiVector<MarkerBool>* amv = m_attribs[ORBIT].addAttribute<MarkerBool>("marker_" + orbitName(ORBIT) + number);
Sylvain Thery's avatar
Sylvain Thery committed
239 240 241 242 243
		return amv;
	}
}


244
template <unsigned int ORBIT>
Sylvain Thery's avatar
Sylvain Thery committed
245
inline void GenericMap::releaseMarkVector(AttributeMultiVector<MarkerBool>* amv, unsigned int thread)
Pierre Kraemer's avatar
Pierre Kraemer committed
246
{
247
	assert(isOrbitEmbedded<ORBIT>() || !"Invalid parameter: orbit not embedded") ;
Sylvain Thery's avatar
Sylvain Thery committed
248

Sylvain Thery's avatar
Sylvain Thery committed
249
	m_markVectors_free[ORBIT][thread].push_back(amv);
Pierre Kraemer's avatar
Pierre Kraemer committed
250 251
}

Sylvain Thery's avatar
Sylvain Thery committed
252 253


254 255
template <unsigned int ORBIT>
inline AttributeMultiVector<unsigned int>* GenericMap::getEmbeddingAttributeVector()
Pierre Kraemer's avatar
Pierre Kraemer committed
256
{
257
	return m_embeddings[ORBIT] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
258 259
}

260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275
template <typename R>
bool GenericMap::registerAttribute(const std::string &nameType)
{
	RegisteredBaseAttribute* ra = new RegisteredAttribute<R>;
	if (ra == NULL)
	{
		CGoGNerr << "Erreur enregistrement attribut" << CGoGNendl;
		return false;
	}

	ra->setTypeName(nameType);

	m_attributes_registry_map->insert(std::pair<std::string, RegisteredBaseAttribute*>(nameType,ra));
	return true;
}

276 277 278 279 280 281 282
/****************************************
 *   EMBEDDING ATTRIBUTES MANAGEMENT    *
 ****************************************/

template <unsigned int ORBIT>
void GenericMap::addEmbedding()
{
283 284 285 286
	if (!isOrbitEmbedded<ORBIT>())
	{
		std::ostringstream oss;
		oss << "EMB_" << ORBIT;
287

288 289 290
		AttributeContainer& dartCont = m_attribs[DART] ;
		AttributeMultiVector<unsigned int>* amv = dartCont.addAttribute<unsigned int>(oss.str()) ;
		m_embeddings[ORBIT] = amv ;
291

292 293 294 295
		// set new embedding to EMBNULL for all the darts of the map
		for(unsigned int i = dartCont.begin(); i < dartCont.end(); dartCont.next(i))
			(*amv)[i] = EMBNULL ;
	}
296 297
}

Pierre Kraemer's avatar
Pierre Kraemer committed
298
/****************************************
299
 *          ORBITS TRAVERSALS           *
Pierre Kraemer's avatar
Pierre Kraemer committed
300 301
 ****************************************/

Sylvain Thery's avatar
Sylvain Thery committed
302 303 304 305 306 307 308 309 310 311 312
/****************************************
 *  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))
313
		(*amv)[i] = Dart(i) ;
Sylvain Thery's avatar
Sylvain Thery committed
314 315 316 317

	return amv ;
}

Sylvain Thery's avatar
Sylvain Thery committed
318 319 320 321 322 323 324
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 ;
}

325 326 327 328 329 330 331
inline float GenericMap::fragmentation(unsigned int orbit)
{
	if (isOrbitEmbedded(orbit))
		return m_attribs[orbit].fragmentation();
	return 1.0f;
}

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