genericmap.hpp 11.6 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 26
#include "Topology/generic/dartmarker.h"

Pierre Kraemer's avatar
Pierre Kraemer committed
27 28
namespace CGoGN
{
29

Sylvain Thery's avatar
Sylvain Thery committed
30
/****************************************
Sylvain Thery's avatar
Sylvain Thery committed
31
 *         THREAD ID MANAGEMENT         *
Sylvain Thery's avatar
Sylvain Thery committed
32
 ****************************************/
33

Sylvain Thery's avatar
Sylvain Thery committed
34 35 36
inline unsigned int GenericMap::getCurrentThreadIndex() const
{
	std::thread::id id = std::this_thread::get_id();
37 38 39 40 41 42 43 44 45 46 47 48
	for (unsigned int i = 0; i < m_thread_ids.size(); ++i)
	{
		if (id == m_thread_ids[i])
			return i;
	}
	assert(m_thread_ids.size() < NB_THREADS + 1);
	if (m_authorizeExternalThreads)
	{
		m_thread_ids.push_back(id);
		return m_thread_ids.size() - 1;
	}
	else
Sylvain Thery's avatar
Sylvain Thery committed
49
	{
50
		return -1;
Sylvain Thery's avatar
Sylvain Thery committed
51 52 53
	}
}

54
//inline void GenericMap::addThreadId(const std::thread::id id)
Sylvain Thery's avatar
Sylvain Thery committed
55
//{
56 57 58 59 60 61 62 63
//	for (unsigned int i = 0; i < m_thread_ids.size(); ++i)
//	{
//		if (m_thread_ids[i] == id)
//			return;
//	}
//	assert(m_thread_ids.size() < NB_THREADS + 1);
//	if (m_authorizeExternalThreads)
//		m_thread_ids.push_back(id);
Sylvain Thery's avatar
Sylvain Thery committed
64 65
//}

66 67 68 69 70 71 72 73 74 75 76 77 78 79
inline void GenericMap::removeThreadId(const std::thread::id id)
{
	for (unsigned int i = 0; i < m_thread_ids.size(); ++i)
	{
		if (m_thread_ids[i] == id)
		{
			m_thread_ids[i] = m_thread_ids.back();
			m_thread_ids.pop_back();
			break;
		}
	}
}

inline std::thread::id& GenericMap::addEmptyThreadId()
Sylvain Thery's avatar
Sylvain Thery committed
80
{
81 82 83 84
	assert(m_thread_ids.size() < NB_THREADS + 1);
	unsigned int size = uint32(m_thread_ids.size());
	m_thread_ids.resize(size + 1);
	return m_thread_ids.back();
Sylvain Thery's avatar
Sylvain Thery committed
85 86
}

87
inline std::thread::id GenericMap::getThreadId(unsigned int index) const
Sylvain Thery's avatar
Sylvain Thery committed
88
{
89 90
	assert(index < m_thread_ids.size());
	return m_thread_ids[index];
Sylvain Thery's avatar
Sylvain Thery committed
91
}
Sylvain Thery's avatar
Sylvain Thery committed
92

93
inline void GenericMap::setExternalThreadsAuthorization(bool b)
Sylvain Thery's avatar
Sylvain Thery committed
94
{
95 96 97 98 99 100 101
	m_authorizeExternalThreads = b;
	if (!m_authorizeExternalThreads)
	{
		// keep only the thread that created the map
		while (m_thread_ids.size() > 1)
			m_thread_ids.pop_back();
	}
Sylvain Thery's avatar
Sylvain Thery committed
102 103
}

Sylvain Thery's avatar
Sylvain Thery committed
104 105 106 107 108 109

/****************************************
 *         BUFFERS MANAGEMENT           *
 ****************************************/

inline std::vector<Dart>* GenericMap::askDartBuffer() const
Sylvain Thery's avatar
Sylvain Thery committed
110
{
Sylvain Thery's avatar
Sylvain Thery committed
111 112
	unsigned int thread = getCurrentThreadIndex();

Sylvain Thery's avatar
Sylvain Thery committed
113 114 115 116 117 118 119 120 121 122 123 124
	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;
}

Sylvain Thery's avatar
Sylvain Thery committed
125
inline void GenericMap::releaseDartBuffer(std::vector<Dart>* vd) const
Sylvain Thery's avatar
Sylvain Thery committed
126
{
Sylvain Thery's avatar
Sylvain Thery committed
127 128
	unsigned int thread = getCurrentThreadIndex();

129
	if (vd->capacity() > 1024)
Sylvain Thery's avatar
Sylvain Thery committed
130 131 132 133 134 135 136 137 138
	{
		std::vector<Dart> v;
		vd->swap(v);
		vd->reserve(128);
	}
	vd->clear();
	s_vdartsBuffers[thread].push_back(vd);
}

Sylvain Thery's avatar
Sylvain Thery committed
139
inline std::vector<unsigned int>* GenericMap::askUIntBuffer() const
Sylvain Thery's avatar
Sylvain Thery committed
140
{
Sylvain Thery's avatar
Sylvain Thery committed
141 142
	unsigned int thread = getCurrentThreadIndex();

Sylvain Thery's avatar
Sylvain Thery committed
143 144 145 146 147 148 149 150 151 152 153 154
	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;
}

Sylvain Thery's avatar
Sylvain Thery committed
155
inline void GenericMap::releaseUIntBuffer(std::vector<unsigned int>* vui) const
Sylvain Thery's avatar
Sylvain Thery committed
156
{
Sylvain Thery's avatar
Sylvain Thery committed
157 158
	unsigned int thread = getCurrentThreadIndex();

159
	if (vui->capacity() > 1024)
Sylvain Thery's avatar
Sylvain Thery committed
160 161 162 163 164 165 166 167 168 169
	{
		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
170 171 172 173 174 175
/****************************************
 *           DARTS MANAGEMENT           *
 ****************************************/

inline Dart GenericMap::newDart()
{
176
	unsigned int di = m_attribs[DART].insertLine();		// insert a new dart line
177
	m_attribs[DART].initMarkersOfLine(di);
Pierre Kraemer's avatar
Pierre Kraemer committed
178
	for(unsigned int i = 0; i < NB_ORBITS; ++i)
179
	{
180 181
		if (m_embeddings[i])							// set all its embeddings
			(*m_embeddings[i])[di] = EMBNULL ;			// to EMBNULL
182
	}
183

184
	return Dart::create(di) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
185 186
}

187 188 189 190
inline void GenericMap::deleteDartLine(unsigned int index)
{
	m_attribs[DART].removeLine(index) ;	// free the dart line

Pierre Kraemer's avatar
Pierre Kraemer committed
191 192
	for(unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit)
	{
193
		if (m_embeddings[orbit])									// for each embedded orbit
Pierre Kraemer's avatar
Pierre Kraemer committed
194
		{
195
			unsigned int emb = (*m_embeddings[orbit])[index] ;		// get the embedding of the dart
Pierre Kraemer's avatar
Pierre Kraemer committed
196
			if(emb != EMBNULL)
Sylvain Thery's avatar
Sylvain Thery committed
197
				m_attribs[orbit].unrefLine(emb);					// and unref the corresponding line
Pierre Kraemer's avatar
Pierre Kraemer committed
198 199
		}
	}
200
}
201

202
inline unsigned int GenericMap::copyDartLine(unsigned int index)
Pierre Kraemer's avatar
Pierre Kraemer committed
203
{
204 205
	unsigned int newindex = m_attribs[DART].insertLine() ;	// create a new dart line
	m_attribs[DART].copyLine(newindex, index) ;				// copy the given dart line
206 207
	for(unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit)
	{
208 209 210 211 212 213
		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) ;
		}
214 215
	}
	return newindex ;
Pierre Kraemer's avatar
Pierre Kraemer committed
216 217
}

218 219 220 221
//inline bool GenericMap::isDartValid(Dart d)
//{
//	return !d.isNil() && m_attribs[DART].used(dartIndex(d)) ;
//}
222

Pierre Kraemer's avatar
Pierre Kraemer committed
223 224 225 226
/****************************************
 *         EMBEDDING MANAGEMENT         *
 ****************************************/

227 228
template <unsigned int ORBIT>
inline bool GenericMap::isOrbitEmbedded() const
Pierre Kraemer's avatar
Pierre Kraemer committed
229
{
230
	return (ORBIT == DART) || (m_embeddings[ORBIT] != NULL) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
231 232
}

233
inline bool GenericMap::isOrbitEmbedded(unsigned int orbit) const
Pierre Kraemer's avatar
Pierre Kraemer committed
234
{
235
	return (orbit == DART) || (m_embeddings[orbit] != NULL) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
236 237
}

238 239
template <unsigned int ORBIT>
inline unsigned int GenericMap::newCell()
Pierre Kraemer's avatar
Pierre Kraemer committed
240
{
241
	assert(isOrbitEmbedded<ORBIT>() || !"Invalid parameter: orbit not embedded");
242 243 244 245

	unsigned int c = m_attribs[ORBIT].insertLine();
	m_attribs[ORBIT].initMarkersOfLine(c);
	return c;
Pierre Kraemer's avatar
Pierre Kraemer committed
246 247
}

248 249
template <unsigned int ORBIT>
inline void GenericMap::copyCell(unsigned int i, unsigned int j)
Pierre Kraemer's avatar
Pierre Kraemer committed
250
{
251
	assert(isOrbitEmbedded<ORBIT>() || !"Invalid parameter: orbit not embedded");
252
	m_attribs[ORBIT].copyLine(i, j) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
253 254
}

255 256
template <unsigned int ORBIT>
inline void GenericMap::initCell(unsigned int i)
Pierre Kraemer's avatar
Pierre Kraemer committed
257
{
258
	assert(isOrbitEmbedded<ORBIT>() || !"Invalid parameter: orbit not embedded");
259
	m_attribs[ORBIT].initLine(i) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
260 261
}

Pierre Kraemer's avatar
Pierre Kraemer committed
262
/****************************************
263
 *   ATTRIBUTES CONTAINERS MANAGEMENT   *
Pierre Kraemer's avatar
Pierre Kraemer committed
264 265
 ****************************************/

266 267 268 269 270
inline unsigned int GenericMap::getNbCells(unsigned int orbit)
{
	return m_attribs[orbit].size() ;
}

271 272
template <unsigned int ORBIT>
inline AttributeContainer& GenericMap::getAttributeContainer()
Pierre Kraemer's avatar
Pierre Kraemer committed
273
{
274
	return m_attribs[ORBIT] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
275 276
}

Sylvain Thery's avatar
Sylvain Thery committed
277 278 279 280 281 282
template <unsigned int ORBIT>
inline const AttributeContainer& GenericMap::getAttributeContainer() const
{
	return m_attribs[ORBIT] ;
}

Pierre Kraemer's avatar
Pierre Kraemer committed
283 284 285 286 287
inline AttributeContainer& GenericMap::getAttributeContainer(unsigned int orbit)
{
	return m_attribs[orbit] ;
}

Sylvain Thery's avatar
Sylvain Thery committed
288 289 290 291 292
inline const AttributeContainer& GenericMap::getAttributeContainer(unsigned int orbit) const
{
	return m_attribs[orbit] ;
}

293 294 295 296 297
inline AttributeMultiVectorGen* GenericMap::getAttributeVectorGen(unsigned int orbit, const std::string& nameAttr)
{
	return m_attribs[orbit].getVirtualDataVector(nameAttr) ;
}

Sylvain Thery's avatar
Sylvain Thery committed
298 299

template <unsigned int ORBIT>
Sylvain Thery's avatar
Sylvain Thery committed
300
AttributeMultiVector<MarkerBool>* GenericMap::askMarkVector()
Sylvain Thery's avatar
Sylvain Thery committed
301 302 303
{
	assert(isOrbitEmbedded<ORBIT>() || !"Invalid parameter: orbit not embedded") ;

Sylvain Thery's avatar
Sylvain Thery committed
304 305 306
	// get current thread index for table of markers
	unsigned int thread = getCurrentThreadIndex();

307
	if (!m_markVectors_free[ORBIT][thread].empty())
Sylvain Thery's avatar
Sylvain Thery committed
308
	{
309 310 311 312 313 314
		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
315
		std::lock_guard<std::mutex> lockMV(m_MarkerStorageMutex[ORBIT]);
316

317
		unsigned int x = m_nextMarkerId++;
318
		std::string number("___");
319
		number[2] = '0'+x%10;
320
		x = x/10;
321
		number[1] = '0'+x%10;
322
		x = x/10;
323
		number[0] = '0'+x%10;
324

325
		AttributeMultiVector<MarkerBool>* amv = m_attribs[ORBIT].addMarkerAttribute("marker_" + orbitName(ORBIT) + number);
Sylvain Thery's avatar
Sylvain Thery committed
326 327 328 329
		return amv;
	}
}

330
template <unsigned int ORBIT>
Sylvain Thery's avatar
Sylvain Thery committed
331
inline void GenericMap::releaseMarkVector(AttributeMultiVector<MarkerBool>* amv)
Pierre Kraemer's avatar
Pierre Kraemer committed
332
{
333
	assert(isOrbitEmbedded<ORBIT>() || !"Invalid parameter: orbit not embedded") ;
Sylvain Thery's avatar
Sylvain Thery committed
334

Sylvain Thery's avatar
Sylvain Thery committed
335
	unsigned int thread = getCurrentThreadIndex();
336
	m_markVectors_free[ORBIT][thread].push_back(amv);
Pierre Kraemer's avatar
Pierre Kraemer committed
337 338
}

Sylvain Thery's avatar
Sylvain Thery committed
339 340


341 342
template <unsigned int ORBIT>
inline AttributeMultiVector<unsigned int>* GenericMap::getEmbeddingAttributeVector()
Pierre Kraemer's avatar
Pierre Kraemer committed
343
{
344
	return m_embeddings[ORBIT] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
345 346
}

347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362
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;
}

363 364 365 366 367 368 369
/****************************************
 *   EMBEDDING ATTRIBUTES MANAGEMENT    *
 ****************************************/

template <unsigned int ORBIT>
void GenericMap::addEmbedding()
{
370 371 372 373
	if (!isOrbitEmbedded<ORBIT>())
	{
		std::ostringstream oss;
		oss << "EMB_" << ORBIT;
374

375 376 377
		AttributeContainer& dartCont = m_attribs[DART] ;
		AttributeMultiVector<unsigned int>* amv = dartCont.addAttribute<unsigned int>(oss.str()) ;
		m_embeddings[ORBIT] = amv ;
378

379 380 381 382
		// 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 ;
	}
383 384
}

Pierre Kraemer's avatar
Pierre Kraemer committed
385
/****************************************
386
 *          ORBITS TRAVERSALS           *
Pierre Kraemer's avatar
Pierre Kraemer committed
387 388
 ****************************************/

389 390 391 392 393 394 395 396 397 398 399
/****************************************
 *  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))
400
		(*amv)[i] = Dart(i) ;
401 402 403 404

	return amv ;
}

405 406 407 408 409 410 411
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 ;
}

412 413 414 415 416 417 418
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
419
} //namespace CGoGN