genericmap.cpp 13.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

Sylvain Thery's avatar
Sylvain Thery committed
33 34
#include <algorithm>

Pierre Kraemer's avatar
Pierre Kraemer committed
35 36
namespace CGoGN
{
37

Sylvain Thery's avatar
Sylvain Thery committed
38 39 40 41 42 43
namespace Parallel
{
//int NumberOfThreads=1;
int NumberOfThreads = getSystemNumberOfCores();
}

Pierre Kraemer's avatar
Pierre Kraemer committed
44
std::map<std::string, RegisteredBaseAttribute*>* GenericMap::m_attributes_registry_map = NULL;
45
int GenericMap::m_nbInstances = 0;
46

Sylvain Thery's avatar
Sylvain Thery committed
47 48 49 50 51

std::vector< std::vector<Dart>* > GenericMap::s_vdartsBuffers[NB_ORBITS];

std::vector< std::vector<unsigned int>* > GenericMap::s_vintsBuffers[NB_ORBITS];

52 53 54
// table of instancied maps for Dart/CellMarker release
std::vector<GenericMap*>  GenericMap::s_instances;

Sylvain Thery's avatar
Sylvain Thery committed
55
GenericMap::GenericMap()
Pierre Kraemer's avatar
Pierre Kraemer committed
56
{
57
	if(m_attributes_registry_map == NULL)
Pierre Kraemer's avatar
Pierre Kraemer committed
58
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
59
		m_attributes_registry_map = new std::map<std::string, RegisteredBaseAttribute*>;
60

Pierre Kraemer's avatar
Pierre Kraemer committed
61 62 63
		// register all known types
		registerAttribute<Dart>("Dart");
		registerAttribute<Mark>("Mark");
Pierre Kraemer's avatar
Pierre Kraemer committed
64

Pierre Kraemer's avatar
Pierre Kraemer committed
65
		registerAttribute<char>("char");
66 67 68
		registerAttribute<short>("short");
		registerAttribute<int>("int");
		registerAttribute<long>("long");
Pierre Kraemer's avatar
Pierre Kraemer committed
69

Pierre Kraemer's avatar
Pierre Kraemer committed
70
		registerAttribute<unsigned char>("unsigned char");
71 72 73 74 75 76
		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
77

Pierre Kraemer's avatar
Pierre Kraemer committed
78 79 80
		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
81

Pierre Kraemer's avatar
Pierre Kraemer committed
82 83 84
		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
85

Pierre Kraemer's avatar
Pierre Kraemer committed
86 87
		registerAttribute<Geom::Matrix33f>(Geom::Matrix33f::CGoGNnameOfType());
		registerAttribute<Geom::Matrix44f>(Geom::Matrix44f::CGoGNnameOfType());
Pierre Kraemer's avatar
Pierre Kraemer committed
88

Pierre Kraemer's avatar
Pierre Kraemer committed
89 90 91 92
		registerAttribute<Geom::Matrix33d>(Geom::Matrix33d::CGoGNnameOfType());
		registerAttribute<Geom::Matrix44d>(Geom::Matrix44d::CGoGNnameOfType());
	}

Sylvain Thery's avatar
Sylvain Thery committed
93 94


Pierre Kraemer's avatar
Pierre Kraemer committed
95
	m_nbInstances++;
96
	s_instances.push_back(this);
Pierre Kraemer's avatar
Pierre Kraemer committed
97

98
	for(unsigned int i = 0; i < NB_ORBITS; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
99
	{
100
		m_attribs[i].setOrbit(i) ;
101
		m_attribs[i].setRegistry(m_attributes_registry_map) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
102
	}
103

Sylvain Thery's avatar
Sylvain Thery committed
104 105 106 107 108 109 110 111 112
	for(unsigned int i = 0; i < NB_THREAD; ++i)
	{
		if (s_vdartsBuffers[i].capacity()<8)
		{
			s_vdartsBuffers[i].reserve(8);
			s_vintsBuffers[i].reserve(8);
			// prealloc ?
		}
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
113
	init();
Pierre Kraemer's avatar
Pierre Kraemer committed
114 115 116 117
}

GenericMap::~GenericMap()
{
118

Pierre Kraemer's avatar
Pierre Kraemer committed
119 120 121 122 123
	for(unsigned int i = 0; i < NB_ORBITS; ++i)
	{
		if(isOrbitEmbedded(i))
			m_attribs[i].clear(true) ;
	}
124 125 126 127 128

	for(std::multimap<AttributeMultiVectorGen*, AttributeHandlerGen*>::iterator it = attributeHandlers.begin(); it != attributeHandlers.end(); ++it)
		(*it).second->setInvalid() ;
	attributeHandlers.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
		m_attributes_registry_map = NULL;
Sylvain Thery's avatar
Sylvain Thery committed
139 140 141 142 143 144 145 146 147 148

		for(unsigned int i = 0; i < NB_THREAD; ++i)
		{
			for (auto it =s_vdartsBuffers[i].begin(); it != s_vdartsBuffers[i].end(); ++it)
				delete *it;
			for (auto it =s_vintsBuffers[i].begin(); it != s_vintsBuffers[i].end(); ++it)
				delete *it;
		}


149
	}
150 151 152

	// remove instance for table
	std::remove (s_instances.begin(), s_instances.end(), this); 
Pierre Kraemer's avatar
Pierre Kraemer committed
153 154
}

Pierre Kraemer's avatar
Pierre Kraemer committed
155
void GenericMap::init()
156
{
Pierre Kraemer's avatar
Pierre Kraemer committed
157
	for(unsigned int i = 0; i < NB_ORBITS; ++i)
158
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
159 160 161 162 163
		m_attribs[i].clear(true) ;
		m_embeddings[i] = NULL ;
		m_quickTraversal[i] = NULL;

		for(unsigned int j = 0; j < NB_ORBITS; ++j)
164
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
165 166
			m_quickLocalIncidentTraversal[i][j] = NULL ;
			m_quickLocalAdjacentTraversal[i][j] = NULL ;
167
		}
Pierre Kraemer's avatar
Pierre Kraemer committed
168 169
	}

Sylvain Thery's avatar
Sylvain Thery committed
170 171
	m_boundaryMarkers[0] = m_attribs[DART].addAttribute<MarkerBool>("BoundaryMark0") ;
	m_boundaryMarkers[1] = m_attribs[DART].addAttribute<MarkerBool>("BoundaryMark1") ;
Pierre Kraemer's avatar
Pierre Kraemer committed
172

Sylvain Thery's avatar
Sylvain Thery committed
173
	 for(std::multimap<AttributeMultiVectorGen*, AttributeHandlerGen*>::iterator it = attributeHandlers.begin(); it != attributeHandlers.end(); ++it)
Pierre Kraemer's avatar
Pierre Kraemer committed
174 175 176 177 178 179 180 181
		(*it).second->setInvalid() ;
	attributeHandlers.clear() ;
}

void GenericMap::clear(bool removeAttrib)
{
	if (removeAttrib)
		init();
Sylvain Thery's avatar
Sylvain Thery committed
182 183 184 185 186
	else
	{
		for(unsigned int i = 0; i < NB_ORBITS; ++i)
			m_attribs[i].clear(false) ;
	}
untereiner's avatar
untereiner committed
187 188
}

Pierre Kraemer's avatar
Pierre Kraemer committed
189 190 191 192
/****************************************
 *        ATTRIBUTES MANAGEMENT         *
 ****************************************/

untereiner's avatar
untereiner committed
193 194 195 196 197 198 199 200 201 202 203 204
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]) ;


Sylvain Thery's avatar
Sylvain Thery committed
205
	// NE MARCHE PLUS PAS POSSIBLE DE CHANGER LES CONTAINER
untereiner's avatar
untereiner committed
206

Sylvain Thery's avatar
Sylvain Thery committed
207 208 209 210 211 212 213 214 215 216
//	for (unsigned int i = 0; i < NB_THREAD; ++i)
//	{
//		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 ;
//		}
//	}
untereiner's avatar
untereiner committed
217
}
Pierre Kraemer's avatar
Pierre Kraemer committed
218

Pierre Kraemer's avatar
Pierre Kraemer committed
219 220 221 222 223 224 225 226 227 228 229 230
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)
231 232 233 234 235
		{
			unsigned int id = cont.getAttributeIndex(*it);
			std::cout << "    " << *it << " ("<<id<<")"<<std::endl ;
		}

Pierre Kraemer's avatar
Pierre Kraemer committed
236 237 238 239 240 241 242
		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 ;

Sylvain Thery's avatar
Sylvain Thery committed
243 244 245 246
//	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 ;
Pierre Kraemer's avatar
Pierre Kraemer committed
247 248
}

249 250 251 252 253 254 255
void GenericMap::printDartsTable()
{
	std::cout << "======================="<< std::endl ;

	//m_attribs[DART]
}

256 257 258 259
/****************************************
 *          THREAD MANAGEMENT           *
 ****************************************/

Sylvain Thery's avatar
Sylvain Thery committed
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
//void GenericMap::addThreadMarker(unsigned int nb)
//{
//	unsigned int th ;

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

//		for (unsigned int i = 0; i < NB_ORBITS; ++i)
//		{
//			std::stringstream ss ;
//			ss << "Mark_"<< th ;
//			AttributeContainer& cellCont = m_attribs[i] ;
//			AttributeMultiVector<Mark>* amvMark = cellCont.addAttribute<Mark>(ss.str()) ;
//			m_markTables[i][th] = amvMark ;
//		}
//	}
//}

//unsigned int GenericMap::getNbThreadMarkers() const
//{
//	return m_nbThreadMarkers;
//}

//void GenericMap::removeThreadMarker(unsigned int nb)
//{
//	unsigned int th = 0;
//	while ((m_nbThreadMarkers > 1) && (nb > 0))
//	{
//		th = --m_nbThreadMarkers ;
//		--nb;
//		for (unsigned int i = 0; i < NB_ORBITS; ++i)
//		{
//			std::stringstream ss ;
//			ss << "Mark_"<< th ;
//			AttributeContainer& cellCont = m_attribs[i] ;
//			cellCont.removeAttribute<Mark>(ss.str()) ;
//			m_markTables[i][th] = NULL ;
//		}
//	}
//}
Pierre Kraemer's avatar
Pierre Kraemer committed
302 303 304 305 306

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

Pierre Kraemer's avatar
Pierre Kraemer committed
307
void GenericMap::restore_shortcuts()
Sylvain Thery's avatar
Sylvain Thery committed
308
{
Pierre Kraemer's avatar
Pierre Kraemer committed
309 310
	// EMBEDDING

Sylvain Thery's avatar
Sylvain Thery committed
311 312 313 314 315 316 317 318 319 320
	// 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
merges  
Pierre Kraemer committed
321
		std::string sub = listeNames[i].substr(0, listeNames[i].size() - 1);
Sylvain Thery's avatar
Sylvain Thery committed
322 323 324 325 326 327 328 329
		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 ;
		}
	}

Sylvain Thery's avatar
Sylvain Thery committed
330 331
	// MARKERS
	m_attribs[DART].getAttributesNames(listeNames);
Pierre Kraemer's avatar
Pierre Kraemer committed
332

Sylvain Thery's avatar
Sylvain Thery committed
333
	for (unsigned int i = 0;  i < listeNames.size(); ++i)
Sylvain Thery's avatar
Sylvain Thery committed
334
	{
Sylvain Thery's avatar
Sylvain Thery committed
335 336 337 338 339 340
		if (listeNames[i] == "BoundaryMark0")
			m_boundaryMarkers[0] = cont.getDataVector<MarkerBool>(i);

		if (listeNames[i] == "BoundaryMark1")
			m_boundaryMarkers[1] = cont.getDataVector<MarkerBool>(i);
	}
Sylvain Thery's avatar
Sylvain Thery committed
341

Sylvain Thery's avatar
Sylvain Thery committed
342
	// QUICK TRAVERSAL
Pierre Kraemer's avatar
Pierre Kraemer committed
343

Sylvain Thery's avatar
Sylvain Thery committed
344 345 346
	for(unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit)
	{
		AttributeContainer& cont = m_attribs[orbit];
Pierre Kraemer's avatar
Pierre Kraemer committed
347 348 349 350 351 352 353
		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
354
			ss2 << "quickLocalAdjacentTraversal_" << j;
Pierre Kraemer's avatar
Pierre Kraemer committed
355 356
			m_quickLocalAdjacentTraversal[orbit][j] = cont.getDataVector< NoTypeNameAttribute<std::vector<Dart> > >(ss2.str()) ;
		}
357
	}
358

359 360 361 362
	// 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
363 364 365 366
}

void GenericMap::dumpAttributesAndMarkers()
{
Pierre Kraemer's avatar
merges  
Pierre Kraemer committed
367
	for (unsigned int i = 0; i < NB_ORBITS; ++i)
Sylvain Thery's avatar
Sylvain Thery committed
368 369
	{
		std::vector<std::string> names;
Pierre Kraemer's avatar
merges  
Pierre Kraemer committed
370
		names.reserve(32); 				//just to limit reallocation
Sylvain Thery's avatar
Sylvain Thery committed
371 372
		m_attribs[i].getAttributesNames(names);
		unsigned int nb = names.size();
Pierre Kraemer's avatar
merges  
Pierre Kraemer committed
373
		if (nb > 0)
Sylvain Thery's avatar
Sylvain Thery committed
374
		{
Pierre Kraemer's avatar
merges  
Pierre Kraemer committed
375
			CGoGNout << "ORBIT "<< i << CGoGNendl;
Sylvain Thery's avatar
Sylvain Thery committed
376 377 378
			std::vector<std::string> types;
			types.reserve(nb);
			m_attribs[i].getAttributesTypes(types);
Pierre Kraemer's avatar
merges  
Pierre Kraemer committed
379 380
			for (unsigned int j = 0; j < nb; ++j)
				CGoGNout << "    " << j << " : " << types[j] << " " << names[j] << CGoGNendl;
Sylvain Thery's avatar
Sylvain Thery committed
381 382
		}
	}
Sylvain Thery's avatar
Sylvain Thery committed
383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402
//	CGoGNout << "RESERVED MARKERS "<< CGoGNendl;
//	for (unsigned int i = 0; i < NB_ORBITS; ++i)
//	{
//		for (unsigned int j = 0; j < NB_THREAD; ++j)
//		{
//			MarkSet ms = m_marksets[i][j];
//			if (!ms.isClear())
//			{
//				CGoGNout << "Orbit " << i << "  thread " << j << " : ";
//				Mark m(1);
//				for (unsigned i = 0; i < Mark::getNbMarks(); ++i)
//				{
//					if (ms.testMark(m))
//						CGoGNout << m.getMarkVal() << ", ";
//					m.setMarkVal(m.getMarkVal()<<1);
//				}
//				CGoGNout << CGoGNendl;
//			}
//		}
//	}
Sylvain Thery's avatar
Sylvain Thery committed
403 404
}

405 406
void GenericMap::compact()
{
407 408 409
	// compact embedding attribs
	std::vector< std::vector<unsigned int>* > oldnews;
	oldnews.resize(NB_ORBITS);
410 411 412 413
	for (unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit)
	{
		if ((orbit != DART) && (isOrbitEmbedded(orbit)))
		{
414 415 416 417
			oldnews[orbit] = new std::vector<unsigned int>;
			m_attribs[orbit].compact(*(oldnews[orbit]));
		}
	}
418

419 420 421 422 423 424
	// 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)))
425
			{
426 427
				unsigned int& idx = m_embeddings[orbit]->operator[](i);
				unsigned int jdx = oldnews[orbit]->operator[](idx);
Pierre Kraemer's avatar
merges  
Pierre Kraemer committed
428
				if ((jdx != 0xffffffff) && (jdx != idx))
429 430 431 432
					idx = jdx;
			}
		}
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
433

434 435 436 437 438
	// delete allocated vectors
	for (unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit)
		if ((orbit != DART) && (isOrbitEmbedded(orbit)))
			delete[] oldnews[orbit];

439 440
	// compact topo (depends on map implementation)
	compactTopo();
441 442
}

443 444 445 446 447 448 449 450 451
void GenericMap::dumpCSV() const
{
	for (unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit)
	{
		m_attribs[orbit].dumpCSV();
	}
	CGoGNout << CGoGNendl;
}

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