genericmap.cpp 15.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 25
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

#include "Topology/generic/genericmap.h"
26
#include "Topology/generic/attributeHandler.h"
27
#include "Topology/generic/traversor/traversorCell.h"
Sylvain Thery's avatar
Sylvain Thery committed
28

Pierre Kraemer's avatar
Pierre Kraemer committed
29 30
#include "Geometry/vector_gen.h"
#include "Geometry/matrix.h"
31
#include "Container/registered.h"
Pierre Kraemer's avatar
Pierre Kraemer committed
32 33 34

namespace CGoGN
{
35

Pierre Kraemer's avatar
Pierre Kraemer committed
36
std::map<std::string, RegisteredBaseAttribute*>* GenericMap::m_attributes_registry_map = NULL;
37
int GenericMap::m_nbInstances = 0;
38

39
GenericMap::GenericMap() : m_nbThreads(1)
Pierre Kraemer's avatar
Pierre Kraemer committed
40
{
41
	if(m_attributes_registry_map == NULL)
Pierre Kraemer's avatar
Pierre Kraemer committed
42
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
43
		m_attributes_registry_map = new std::map<std::string, RegisteredBaseAttribute*>;
44

Pierre Kraemer's avatar
Pierre Kraemer committed
45 46 47
		// register all known types
		registerAttribute<Dart>("Dart");
		registerAttribute<Mark>("Mark");
Pierre Kraemer's avatar
Pierre Kraemer committed
48

Pierre Kraemer's avatar
Pierre Kraemer committed
49
		registerAttribute<char>("char");
50 51 52
		registerAttribute<short>("short");
		registerAttribute<int>("int");
		registerAttribute<long>("long");
Pierre Kraemer's avatar
Pierre Kraemer committed
53

Pierre Kraemer's avatar
Pierre Kraemer committed
54
		registerAttribute<unsigned char>("unsigned char");
55 56 57 58 59 60
		registerAttribute<unsigned short>("unsigned short");
		registerAttribute<unsigned int>("unsigned int");
		registerAttribute<unsigned long>("unsigned long");

		registerAttribute<float>("float");
		registerAttribute<double>("double");
Pierre Kraemer's avatar
Pierre Kraemer committed
61

Pierre Kraemer's avatar
Pierre Kraemer committed
62 63 64
		registerAttribute<Geom::Vec2f>(Geom::Vec2f::CGoGNnameOfType());
		registerAttribute<Geom::Vec3f>(Geom::Vec3f::CGoGNnameOfType());
		registerAttribute<Geom::Vec4f>(Geom::Vec4f::CGoGNnameOfType());
Pierre Kraemer's avatar
Pierre Kraemer committed
65

Pierre Kraemer's avatar
Pierre Kraemer committed
66 67 68
		registerAttribute<Geom::Vec2d>(Geom::Vec2d::CGoGNnameOfType());
		registerAttribute<Geom::Vec3d>(Geom::Vec3d::CGoGNnameOfType());
		registerAttribute<Geom::Vec4d>(Geom::Vec4d::CGoGNnameOfType());
Pierre Kraemer's avatar
Pierre Kraemer committed
69

Pierre Kraemer's avatar
Pierre Kraemer committed
70 71
		registerAttribute<Geom::Matrix33f>(Geom::Matrix33f::CGoGNnameOfType());
		registerAttribute<Geom::Matrix44f>(Geom::Matrix44f::CGoGNnameOfType());
Pierre Kraemer's avatar
Pierre Kraemer committed
72

Pierre Kraemer's avatar
Pierre Kraemer committed
73 74 75 76 77
		registerAttribute<Geom::Matrix33d>(Geom::Matrix33d::CGoGNnameOfType());
		registerAttribute<Geom::Matrix44d>(Geom::Matrix44d::CGoGNnameOfType());
	}

	m_nbInstances++;
Pierre Kraemer's avatar
Pierre Kraemer committed
78

79
	for(unsigned int i = 0; i < NB_ORBITS; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
80
	{
81
		m_attribs[i].setOrbit(i) ;
82
		m_attribs[i].setRegistry(m_attributes_registry_map) ;
83 84 85
		for(unsigned int j = 0; j < NB_THREAD; ++j)
		{
			m_marksets[i][j].clear() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
86
			m_markTables[i][j] = NULL ;
87
		}
Pierre Kraemer's avatar
Pierre Kraemer committed
88
	}
89

Pierre Kraemer's avatar
Pierre Kraemer committed
90 91
	init();

92
	for (unsigned int i = 0; i < NB_THREAD; ++i)
93 94 95 96
	{
		dartMarkers[i].reserve(16) ;
		cellMarkers[i].reserve(16) ;
	}
97

98
	// get & lock marker for boundary
Pierre Kraemer's avatar
Pierre Kraemer committed
99 100
	m_boundaryMarkers[0] = m_marksets[DART][0].getNewMark();
	m_boundaryMarkers[1] = m_marksets[DART][0].getNewMark();
Pierre Kraemer's avatar
Pierre Kraemer committed
101 102 103 104
}

GenericMap::~GenericMap()
{
105
	// release marker for boundary
Thery Sylvain's avatar
Thery Sylvain committed
106 107
	m_marksets[DART][0].releaseMark(m_boundaryMarkers[0]);
	m_marksets[DART][0].releaseMark(m_boundaryMarkers[1]);
108

Pierre Kraemer's avatar
Pierre Kraemer committed
109 110 111 112 113
	for(unsigned int i = 0; i < NB_ORBITS; ++i)
	{
		if(isOrbitEmbedded(i))
			m_attribs[i].clear(true) ;
	}
114 115 116 117 118

	for(std::multimap<AttributeMultiVectorGen*, AttributeHandlerGen*>::iterator it = attributeHandlers.begin(); it != attributeHandlers.end(); ++it)
		(*it).second->setInvalid() ;
	attributeHandlers.clear() ;

119
	for (unsigned int i = 0; i < NB_THREAD; ++i)
120 121 122 123
	{
		for(std::vector<DartMarkerGen*>::iterator it = dartMarkers[i].begin(); it != dartMarkers[i].end(); ++it)
			(*it)->setReleaseOnDestruct(false) ;
		dartMarkers[i].clear() ;
124

125 126 127 128
		for(std::vector<CellMarkerGen*>::iterator it = cellMarkers[i].begin(); it != cellMarkers[i].end(); ++it)
			(*it)->setReleaseOnDestruct(false) ;
		cellMarkers[i].clear() ;
	}
129 130 131

	// clean type registry if necessary
	m_nbInstances--;
Pierre Kraemer's avatar
Pierre Kraemer committed
132
	if (m_nbInstances <= 0)
133
	{
134 135 136
		for (std::map<std::string, RegisteredBaseAttribute*>::iterator it =  m_attributes_registry_map->begin(); it != m_attributes_registry_map->end(); ++it)
			delete it->second;

137
		delete m_attributes_registry_map;
138 139
		m_attributes_registry_map = NULL;
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
140 141
}

Pierre Kraemer's avatar
Pierre Kraemer committed
142
void GenericMap::init()
143
{
Pierre Kraemer's avatar
Pierre Kraemer committed
144
	for(unsigned int i = 0; i < NB_ORBITS; ++i)
145
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
146 147 148 149 150
		m_attribs[i].clear(true) ;
		m_embeddings[i] = NULL ;
		m_quickTraversal[i] = NULL;

		for(unsigned int j = 0; j < NB_ORBITS; ++j)
151
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
152 153
			m_quickLocalIncidentTraversal[i][j] = NULL ;
			m_quickLocalAdjacentTraversal[i][j] = NULL ;
154
		}
Sylvain Thery's avatar
Sylvain Thery committed
155

Pierre Kraemer's avatar
Pierre Kraemer committed
156 157 158 159 160 161
		AttributeContainer& cont = m_attribs[i];
		for (unsigned int t = 0; t < m_nbThreads; ++t)
		{
			std::stringstream ss ;
			ss << "Mark_" << t ;
			AttributeMultiVector<Mark>* amvMark = cont.addAttribute<Mark>(ss.str()) ;
162 163
//			for(unsigned int idx = cont.begin(); idx < cont.end(); cont.next(idx))
//				amvMark->operator[](idx).clear() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
			m_markTables[i][t] = amvMark ;
		}
	}

	for (unsigned int j = 0; j < NB_THREAD; ++j)
	{
		std::vector<CellMarkerGen*>& cmg = cellMarkers[j];
		for(unsigned int i = 0; i < cmg.size(); ++i)
		{
			CellMarkerGen* cm = cmg[i] ;
			cm->updateMarkVector(m_markTables[cm->getCell()][cm->getThread()]) ;
		}

		std::vector<DartMarkerGen*>& dmg = dartMarkers[j];
		for(unsigned int i = 0; i < dmg.size(); ++i)
		{
			DartMarkerGen* dm = dmg[i] ;
			dm->updateMarkVector(m_markTables[DART][dm->getThread()]) ;
		}
183
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
184 185 186 187 188 189 190 191 192 193

	for(std::multimap<AttributeMultiVectorGen*, AttributeHandlerGen*>::iterator it = attributeHandlers.begin(); it != attributeHandlers.end(); ++it)
		(*it).second->setInvalid() ;
	attributeHandlers.clear() ;
}

void GenericMap::clear(bool removeAttrib)
{
	if (removeAttrib)
		init();
Sylvain Thery's avatar
Sylvain Thery committed
194 195 196 197 198
	else
	{
		for(unsigned int i = 0; i < NB_ORBITS; ++i)
			m_attribs[i].clear(false) ;
	}
untereiner's avatar
untereiner committed
199 200
}

Pierre Kraemer's avatar
Pierre Kraemer committed
201 202 203 204
/****************************************
 *        ATTRIBUTES MANAGEMENT         *
 ****************************************/

untereiner's avatar
untereiner committed
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
void GenericMap::swapEmbeddingContainers(unsigned int orbit1, unsigned int orbit2)
{
	assert(orbit1 != orbit2 || !"Cannot swap a container with itself") ;
	assert((orbit1 != DART && orbit2 != DART) || !"Cannot swap the darts container") ;

	m_attribs[orbit1].swap(m_attribs[orbit2]) ;
	m_attribs[orbit1].setOrbit(orbit1) ;	// to update the orbit information
	m_attribs[orbit2].setOrbit(orbit2) ;	// in the contained AttributeMultiVectors

	m_embeddings[orbit1]->swap(m_embeddings[orbit2]) ;

	for(unsigned int t = 0; t < m_nbThreads; ++t)
	{
		AttributeMultiVector<Mark>* m = m_markTables[orbit1][t] ;
		m_markTables[orbit1][t] = m_markTables[orbit2][t] ;
		m_markTables[orbit2][t] = m ;

		MarkSet ms = m_marksets[orbit1][t] ;
		m_marksets[orbit1][t] = m_marksets[orbit2][t] ;
		m_marksets[orbit2][t] = ms ;
	}

227
	for (unsigned int i = 0; i < NB_THREAD; ++i)
untereiner's avatar
untereiner committed
228 229 230 231 232 233 234 235 236 237
	{
		for(std::vector<CellMarkerGen*>::iterator it = cellMarkers[i].begin(); it != cellMarkers[i].end(); ++it)
		{
			if((*it)->m_cell == orbit1)
				(*it)->m_cell = orbit2 ;
			else if((*it)->m_cell == orbit2)
				(*it)->m_cell = orbit1 ;
		}
	}
}
Pierre Kraemer's avatar
Pierre Kraemer committed
238

239 240 241 242 243 244 245 246 247 248 249 250
void GenericMap::viewAttributesTables()
{
	std::cout << "======================="<< std::endl ;
	for (unsigned int i = 0; i < NB_ORBITS; ++i)
	{
		std::cout << "ATTRIBUTE_CONTAINER " << i << std::endl ;
		AttributeContainer& cont = m_attribs[i] ;

		// get the list of attributes
		std::vector<std::string> listeNames ;
		cont.getAttributesNames(listeNames) ;
		for (std::vector<std::string>::iterator it = listeNames.begin(); it != listeNames.end(); ++it)
251 252 253 254 255
		{
			unsigned int id = cont.getAttributeIndex(*it);
			std::cout << "    " << *it << " ("<<id<<")"<<std::endl ;
		}

256 257 258 259 260 261 262 263 264 265 266 267 268
		std::cout << "-------------------------" << std::endl ;
	}
	std::cout << "m_embeddings: " << std::hex ;
	for (unsigned int i = 0; i < NB_ORBITS; ++i)
		std::cout << (long)(m_embeddings[i]) << " / " ;
	std::cout << std::endl << "-------------------------" << std::endl ;

	std::cout << "m_markTables: " ;
	for (unsigned int i = 0; i < NB_ORBITS; ++i)
		std::cout << (long)(m_markTables[i][0]) << " / " ;
	std::cout << std::endl << "-------------------------" << std::endl << std::dec ;
}

269 270 271 272 273 274 275
void GenericMap::printDartsTable()
{
	std::cout << "======================="<< std::endl ;

	//m_attribs[DART]
}

276 277 278 279 280 281 282 283 284 285 286 287 288 289 290
/****************************************
 *          THREAD MANAGEMENT           *
 ****************************************/

void GenericMap::addThreadMarker(unsigned int nb)
{
	unsigned int th ;

	for (unsigned int j = 0; j < nb; ++j)
	{
		th = m_nbThreads ;
		m_nbThreads++ ;

		for (unsigned int i = 0; i < NB_ORBITS; ++i)
		{
291 292 293 294 295
			std::stringstream ss ;
			ss << "Mark_"<< th ;
			AttributeContainer& cellCont = m_attribs[i] ;
			AttributeMultiVector<Mark>* amvMark = cellCont.addAttribute<Mark>(ss.str()) ;
			m_markTables[i][th] = amvMark ;
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313
		}
	}
}

unsigned int GenericMap::getNbThreadMarkers()
{
	return m_nbThreads;
}

void GenericMap::removeThreadMarker(unsigned int nb)
{
	unsigned int th = 0;
	while ((m_nbThreads > 1) && (nb > 0))
	{
		th = --m_nbThreads ;
		--nb;
		for (unsigned int i = 0; i < NB_ORBITS; ++i)
		{
314 315 316 317 318
			std::stringstream ss ;
			ss << "Mark_"<< th ;
			AttributeContainer& cellCont = m_attribs[i] ;
			cellCont.removeAttribute<Mark>(ss.str()) ;
			m_markTables[i][th] = NULL ;
319 320 321
		}
	}
}
Pierre Kraemer's avatar
Pierre Kraemer committed
322 323 324 325 326

/****************************************
 *             SAVE & LOAD              *
 ****************************************/

Pierre Kraemer's avatar
Pierre Kraemer committed
327
void GenericMap::restore_shortcuts()
Sylvain Thery's avatar
Sylvain Thery committed
328
{
329 330 331 332 333 334 335 336 337 338 339
	// NB THREADS

	std::vector<std::string> typeMark;
	unsigned int nbatt0 = m_attribs[0].getAttributesTypes(typeMark);
	m_nbThreads = 0;
	for (unsigned int i = 0; i < nbatt0; ++i)
	{
		if (typeMark[i] == "Mark")
			++m_nbThreads;
	}

Pierre Kraemer's avatar
Pierre Kraemer committed
340 341
	// EMBEDDING

Sylvain Thery's avatar
Sylvain Thery committed
342 343 344 345 346 347 348 349 350 351
	// get container of dart orbit
	AttributeContainer& cont = m_attribs[DART] ;

	// get the list of attributes
	std::vector<std::string> listeNames;
	cont.getAttributesNames(listeNames);

	// check if there are EMB_X attributes
	for (unsigned int i = 0;  i < listeNames.size(); ++i)
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
352
		std::string sub = listeNames[i].substr(0, listeNames[i].size() - 1);
Sylvain Thery's avatar
Sylvain Thery committed
353 354 355 356 357 358 359 360
		if (sub == "EMB_")
		{
			unsigned int orb = listeNames[i][4]-'0'; // easy atoi computation for one char;
			AttributeMultiVector<unsigned int>* amv = cont.getDataVector<unsigned int>(i);
			m_embeddings[orb] = amv ;
		}
	}

Pierre Kraemer's avatar
Pierre Kraemer committed
361 362
	// MARKERS & QUICK TRAVERSAL

Sylvain Thery's avatar
Sylvain Thery committed
363 364 365 366
	for(unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit)
	{
		AttributeContainer& cont = m_attribs[orbit];

Pierre Kraemer's avatar
Pierre Kraemer committed
367 368 369 370 371 372 373 374 375
		// QUICK TRAVERSAL

		m_quickTraversal[orbit] = cont.getDataVector<Dart>("quick_traversal") ;
		for(unsigned int j = 0; j < NB_ORBITS; ++j)
		{
			std::stringstream ss;
			ss << "quickLocalIncidentTraversal_" << j;
			m_quickLocalIncidentTraversal[orbit][j] = cont.getDataVector< NoTypeNameAttribute<std::vector<Dart> > >(ss.str()) ;
			std::stringstream ss2;
Pierre Kraemer's avatar
Pierre Kraemer committed
376
			ss2 << "quickLocalAdjacentTraversal_" << j;
Pierre Kraemer's avatar
Pierre Kraemer committed
377 378 379 380 381
			m_quickLocalAdjacentTraversal[orbit][j] = cont.getDataVector< NoTypeNameAttribute<std::vector<Dart> > >(ss2.str()) ;
		}

		// MARKERS

Sylvain Thery's avatar
Sylvain Thery committed
382 383 384 385 386
		std::vector<std::string> listeNames;
		cont.getAttributesNames(listeNames);

		for (unsigned int i = 0;  i < listeNames.size(); ++i)
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
387
			std::string sub = listeNames[i].substr(0, 5);
Sylvain Thery's avatar
Sylvain Thery committed
388 389 390
			if (sub == "Mark_")
			{
				// get thread number
Pierre Kraemer's avatar
Pierre Kraemer committed
391
				unsigned int thread = listeNames[i][5] - '0';
Pierre Kraemer's avatar
Pierre Kraemer committed
392
				if (listeNames[i].size() > 6) 					// thread number is >9
Pierre Kraemer's avatar
Pierre Kraemer committed
393
					thread = 10 * thread + (listeNames[i][6] - '0');
Sylvain Thery's avatar
Sylvain Thery committed
394 395 396 397

				AttributeMultiVector<Mark>* amvMark = cont.getDataVector<Mark>(i);
				m_markTables[orbit][thread] = amvMark ;

398 399
				if ((orbit == DART) && (thread == 0))	// for Dart Marker of thread O
				{										// clear all marks expect boundary marks
Pierre Kraemer's avatar
Pierre Kraemer committed
400
					Mark m(m_boundaryMarkers[0] + m_boundaryMarkers[1]);
Sylvain Thery's avatar
Sylvain Thery committed
401
					m.invert();
Pierre Kraemer's avatar
Pierre Kraemer committed
402
					for (unsigned int i = cont.begin(); i != cont.end(); cont.next(i))
Sylvain Thery's avatar
Sylvain Thery committed
403 404
						amvMark->operator[](i).unsetMark(m);
				}
405
				else									// for others clear all
Sylvain Thery's avatar
Sylvain Thery committed
406
				{
Pierre Kraemer's avatar
Pierre Kraemer committed
407
					for (unsigned int i = cont.begin(); i != cont.end(); cont.next(i))
Sylvain Thery's avatar
Sylvain Thery committed
408 409 410 411 412
						amvMark->operator[](i).clear();
				}
			}
		}
	}
413

414
	// restore mark vectors in Dart & Cell Markers
415 416 417 418
	for (unsigned int j = 0; j < NB_THREAD; ++j)
	{
		for (std::vector<DartMarkerGen*>::iterator it = dartMarkers[j].begin(); it != dartMarkers[j].end(); ++it)
			(*it)->updateMarkVector(m_markTables[DART][(*it)->getThread()]);
419

420 421 422
		for (std::vector<CellMarkerGen*>::iterator it = cellMarkers[j].begin(); it != cellMarkers[j].end(); ++it)
			(*it)->updateMarkVector(m_markTables[(*it)->getCell()][(*it)->getThread()]);
	}
423

424 425 426 427
	// set Attribute handlers invalid
	for(std::multimap<AttributeMultiVectorGen*, AttributeHandlerGen*>::iterator it = attributeHandlers.begin(); it != attributeHandlers.end(); ++it)
		(*it).second->setInvalid() ;
	attributeHandlers.clear() ;
Sylvain Thery's avatar
Sylvain Thery committed
428 429 430 431
}

void GenericMap::dumpAttributesAndMarkers()
{
Pierre Kraemer's avatar
Pierre Kraemer committed
432
	for (unsigned int i = 0; i < NB_ORBITS; ++i)
Sylvain Thery's avatar
Sylvain Thery committed
433 434
	{
		std::vector<std::string> names;
Pierre Kraemer's avatar
Pierre Kraemer committed
435
		names.reserve(32); 				//just to limit reallocation
Sylvain Thery's avatar
Sylvain Thery committed
436 437
		m_attribs[i].getAttributesNames(names);
		unsigned int nb = names.size();
Pierre Kraemer's avatar
Pierre Kraemer committed
438
		if (nb > 0)
Sylvain Thery's avatar
Sylvain Thery committed
439
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
440
			CGoGNout << "ORBIT "<< i << CGoGNendl;
Sylvain Thery's avatar
Sylvain Thery committed
441 442 443
			std::vector<std::string> types;
			types.reserve(nb);
			m_attribs[i].getAttributesTypes(types);
Pierre Kraemer's avatar
Pierre Kraemer committed
444 445
			for (unsigned int j = 0; j < nb; ++j)
				CGoGNout << "    " << j << " : " << types[j] << " " << names[j] << CGoGNendl;
Sylvain Thery's avatar
Sylvain Thery committed
446 447 448
		}
	}
	CGoGNout << "RESERVED MARKERS "<< CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
449
	for (unsigned int i = 0; i < NB_ORBITS; ++i)
Sylvain Thery's avatar
Sylvain Thery committed
450
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
451
		for (unsigned int j = 0; j < NB_THREAD; ++j)
Sylvain Thery's avatar
Sylvain Thery committed
452 453 454 455
		{
			MarkSet ms = m_marksets[i][j];
			if (!ms.isClear())
			{
Pierre Kraemer's avatar
Pierre Kraemer committed
456
				CGoGNout << "Orbit " << i << "  thread " << j << " : ";
Sylvain Thery's avatar
Sylvain Thery committed
457
				Mark m(1);
Pierre Kraemer's avatar
Pierre Kraemer committed
458
				for (unsigned i = 0; i < Mark::getNbMarks(); ++i)
Sylvain Thery's avatar
Sylvain Thery committed
459 460
				{
					if (ms.testMark(m))
Pierre Kraemer's avatar
Pierre Kraemer committed
461
						CGoGNout << m.getMarkVal() << ", ";
Sylvain Thery's avatar
Sylvain Thery committed
462 463 464 465 466 467 468 469
					m.setMarkVal(m.getMarkVal()<<1);
				}
				CGoGNout << CGoGNendl;
			}
		}
	}
}

470 471
void GenericMap::compact()
{
472 473 474
	// compact embedding attribs
	std::vector< std::vector<unsigned int>* > oldnews;
	oldnews.resize(NB_ORBITS);
475 476 477 478
	for (unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit)
	{
		if ((orbit != DART) && (isOrbitEmbedded(orbit)))
		{
479 480 481 482
			oldnews[orbit] = new std::vector<unsigned int>;
			m_attribs[orbit].compact(*(oldnews[orbit]));
		}
	}
483

484 485 486 487 488 489
	// update embedding indices of topo
	for (unsigned int i = m_attribs[DART].begin(); i != m_attribs[DART].end(); m_attribs[DART].next(i))
	{
		for (unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit)
		{
			if ((orbit != DART) && (isOrbitEmbedded(orbit)))
490
			{
491 492
				unsigned int& idx = m_embeddings[orbit]->operator[](i);
				unsigned int jdx = oldnews[orbit]->operator[](idx);
Pierre Kraemer's avatar
Pierre Kraemer committed
493
				if ((jdx != 0xffffffff) && (jdx != idx))
494 495 496 497
					idx = jdx;
			}
		}
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
498

499 500 501 502 503
	// delete allocated vectors
	for (unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit)
		if ((orbit != DART) && (isOrbitEmbedded(orbit)))
			delete[] oldnews[orbit];

504 505
	// compact topo (depends on map implementation)
	compactTopo();
506 507
}

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