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

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

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

45 46 47
// table of instancied maps for Dart/CellMarker release
std::vector<GenericMap*>  GenericMap::s_instances;

Sylvain Thery's avatar
Sylvain Thery committed
48
GenericMap::GenericMap()
Pierre Kraemer's avatar
Pierre Kraemer committed
49
{
50
	if(m_attributes_registry_map == NULL)
Pierre Kraemer's avatar
Pierre Kraemer committed
51
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
52
		m_attributes_registry_map = new std::map<std::string, RegisteredBaseAttribute*>;
53

Pierre Kraemer's avatar
Pierre Kraemer committed
54 55 56
		// register all known types
		registerAttribute<Dart>("Dart");
		registerAttribute<Mark>("Mark");
Pierre Kraemer's avatar
Pierre Kraemer committed
57

Pierre Kraemer's avatar
Pierre Kraemer committed
58
		registerAttribute<char>("char");
59 60 61
		registerAttribute<short>("short");
		registerAttribute<int>("int");
		registerAttribute<long>("long");
Pierre Kraemer's avatar
Pierre Kraemer committed
62

Pierre Kraemer's avatar
Pierre Kraemer committed
63
		registerAttribute<unsigned char>("unsigned char");
64 65 66 67 68 69
		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
70

Pierre Kraemer's avatar
Pierre Kraemer committed
71 72 73
		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
74

Pierre Kraemer's avatar
Pierre Kraemer committed
75 76 77
		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
78

Pierre Kraemer's avatar
Pierre Kraemer committed
79 80
		registerAttribute<Geom::Matrix33f>(Geom::Matrix33f::CGoGNnameOfType());
		registerAttribute<Geom::Matrix44f>(Geom::Matrix44f::CGoGNnameOfType());
Pierre Kraemer's avatar
Pierre Kraemer committed
81

Pierre Kraemer's avatar
Pierre Kraemer committed
82 83 84 85 86
		registerAttribute<Geom::Matrix33d>(Geom::Matrix33d::CGoGNnameOfType());
		registerAttribute<Geom::Matrix44d>(Geom::Matrix44d::CGoGNnameOfType());
	}

	m_nbInstances++;
87
	s_instances.push_back(this);
Pierre Kraemer's avatar
Pierre Kraemer committed
88

89
	for(unsigned int i = 0; i < NB_ORBITS; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
90
	{
91
		m_attribs[i].setOrbit(i) ;
92
		m_attribs[i].setRegistry(m_attributes_registry_map) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
93
	}
94

Pierre Kraemer's avatar
Pierre Kraemer committed
95 96
	init();

Sylvain Thery's avatar
Sylvain Thery committed
97 98
	// boundary markers dans init ou ici ?
	// voir avec load et copy from
Pierre Kraemer's avatar
Pierre Kraemer committed
99 100 101 102
}

GenericMap::~GenericMap()
{
103

Pierre Kraemer's avatar
Pierre Kraemer committed
104 105 106 107 108
	for(unsigned int i = 0; i < NB_ORBITS; ++i)
	{
		if(isOrbitEmbedded(i))
			m_attribs[i].clear(true) ;
	}
109 110 111 112 113

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

114 115 116

	// clean type registry if necessary
	m_nbInstances--;
Pierre Kraemer's avatar
Pierre Kraemer committed
117
	if (m_nbInstances <= 0)
118
	{
119 120 121
		for (std::map<std::string, RegisteredBaseAttribute*>::iterator it =  m_attributes_registry_map->begin(); it != m_attributes_registry_map->end(); ++it)
			delete it->second;

122
		delete m_attributes_registry_map;
123 124
		m_attributes_registry_map = NULL;
	}
125 126 127

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

Pierre Kraemer's avatar
Pierre Kraemer committed
130
void GenericMap::init()
131
{
Pierre Kraemer's avatar
Pierre Kraemer committed
132
	for(unsigned int i = 0; i < NB_ORBITS; ++i)
133
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
134 135 136 137 138
		m_attribs[i].clear(true) ;
		m_embeddings[i] = NULL ;
		m_quickTraversal[i] = NULL;

		for(unsigned int j = 0; j < NB_ORBITS; ++j)
139
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
140 141
			m_quickLocalIncidentTraversal[i][j] = NULL ;
			m_quickLocalAdjacentTraversal[i][j] = NULL ;
142
		}
Pierre Kraemer's avatar
Pierre Kraemer committed
143 144
	}

Sylvain Thery's avatar
Sylvain Thery committed
145 146
	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
147

Sylvain Thery's avatar
Sylvain Thery committed
148
	 for(std::multimap<AttributeMultiVectorGen*, AttributeHandlerGen*>::iterator it = attributeHandlers.begin(); it != attributeHandlers.end(); ++it)
Pierre Kraemer's avatar
Pierre Kraemer committed
149 150 151 152 153 154 155 156
		(*it).second->setInvalid() ;
	attributeHandlers.clear() ;
}

void GenericMap::clear(bool removeAttrib)
{
	if (removeAttrib)
		init();
Sylvain Thery's avatar
Sylvain Thery committed
157 158 159 160 161
	else
	{
		for(unsigned int i = 0; i < NB_ORBITS; ++i)
			m_attribs[i].clear(false) ;
	}
untereiner's avatar
untereiner committed
162 163
}

Pierre Kraemer's avatar
Pierre Kraemer committed
164 165 166 167
/****************************************
 *        ATTRIBUTES MANAGEMENT         *
 ****************************************/

untereiner's avatar
untereiner committed
168 169 170 171 172 173 174 175 176 177 178 179
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
180
	// NE MARCHE PLUS PAS POSSIBLE DE CHANGER LES CONTAINER
untereiner's avatar
untereiner committed
181

Sylvain Thery's avatar
Sylvain Thery committed
182 183 184 185 186 187 188 189 190 191
//	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
192
}
Pierre Kraemer's avatar
Pierre Kraemer committed
193

Pierre Kraemer's avatar
Pierre Kraemer committed
194 195 196 197 198 199 200 201 202 203 204 205
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)
206 207 208 209 210
		{
			unsigned int id = cont.getAttributeIndex(*it);
			std::cout << "    " << *it << " ("<<id<<")"<<std::endl ;
		}

Pierre Kraemer's avatar
Pierre Kraemer committed
211 212 213 214 215 216 217
		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
218 219 220 221
//	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
222 223
}

224 225 226 227 228 229 230
void GenericMap::printDartsTable()
{
	std::cout << "======================="<< std::endl ;

	//m_attribs[DART]
}

231 232 233 234
/****************************************
 *          THREAD MANAGEMENT           *
 ****************************************/

Sylvain Thery's avatar
Sylvain Thery committed
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276
//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
277 278 279 280 281

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

Pierre Kraemer's avatar
Pierre Kraemer committed
282
void GenericMap::restore_shortcuts()
Sylvain Thery's avatar
Sylvain Thery committed
283
{
Pierre Kraemer's avatar
Pierre Kraemer committed
284 285
	// EMBEDDING

Sylvain Thery's avatar
Sylvain Thery committed
286 287 288 289 290 291 292 293 294 295
	// 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
296
		std::string sub = listeNames[i].substr(0, listeNames[i].size() - 1);
Sylvain Thery's avatar
Sylvain Thery committed
297 298 299 300 301 302 303 304
		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
305 306
	// MARKERS
	m_attribs[DART].getAttributesNames(listeNames);
Pierre Kraemer's avatar
Pierre Kraemer committed
307

Sylvain Thery's avatar
Sylvain Thery committed
308
	for (unsigned int i = 0;  i < listeNames.size(); ++i)
Sylvain Thery's avatar
Sylvain Thery committed
309
	{
Sylvain Thery's avatar
Sylvain Thery committed
310 311 312 313 314 315
		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
316

Sylvain Thery's avatar
Sylvain Thery committed
317
	// QUICK TRAVERSAL
Pierre Kraemer's avatar
Pierre Kraemer committed
318

Sylvain Thery's avatar
Sylvain Thery committed
319 320 321
	for(unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit)
	{
		AttributeContainer& cont = m_attribs[orbit];
Pierre Kraemer's avatar
Pierre Kraemer committed
322 323 324 325 326 327 328
		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
329
			ss2 << "quickLocalAdjacentTraversal_" << j;
Pierre Kraemer's avatar
Pierre Kraemer committed
330 331
			m_quickLocalAdjacentTraversal[orbit][j] = cont.getDataVector< NoTypeNameAttribute<std::vector<Dart> > >(ss2.str()) ;
		}
332
	}
333

334 335 336 337
	// 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
338 339 340 341
}

void GenericMap::dumpAttributesAndMarkers()
{
Pierre Kraemer's avatar
merges  
Pierre Kraemer committed
342
	for (unsigned int i = 0; i < NB_ORBITS; ++i)
Sylvain Thery's avatar
Sylvain Thery committed
343 344
	{
		std::vector<std::string> names;
Pierre Kraemer's avatar
merges  
Pierre Kraemer committed
345
		names.reserve(32); 				//just to limit reallocation
Sylvain Thery's avatar
Sylvain Thery committed
346 347
		m_attribs[i].getAttributesNames(names);
		unsigned int nb = names.size();
Pierre Kraemer's avatar
merges  
Pierre Kraemer committed
348
		if (nb > 0)
Sylvain Thery's avatar
Sylvain Thery committed
349
		{
Pierre Kraemer's avatar
merges  
Pierre Kraemer committed
350
			CGoGNout << "ORBIT "<< i << CGoGNendl;
Sylvain Thery's avatar
Sylvain Thery committed
351 352 353
			std::vector<std::string> types;
			types.reserve(nb);
			m_attribs[i].getAttributesTypes(types);
Pierre Kraemer's avatar
merges  
Pierre Kraemer committed
354 355
			for (unsigned int j = 0; j < nb; ++j)
				CGoGNout << "    " << j << " : " << types[j] << " " << names[j] << CGoGNendl;
Sylvain Thery's avatar
Sylvain Thery committed
356 357
		}
	}
Sylvain Thery's avatar
Sylvain Thery committed
358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377
//	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
378 379
}

380 381
void GenericMap::compact()
{
382 383 384
	// compact embedding attribs
	std::vector< std::vector<unsigned int>* > oldnews;
	oldnews.resize(NB_ORBITS);
385 386 387 388
	for (unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit)
	{
		if ((orbit != DART) && (isOrbitEmbedded(orbit)))
		{
389 390 391 392
			oldnews[orbit] = new std::vector<unsigned int>;
			m_attribs[orbit].compact(*(oldnews[orbit]));
		}
	}
393

394 395 396 397 398 399
	// 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)))
400
			{
401 402
				unsigned int& idx = m_embeddings[orbit]->operator[](i);
				unsigned int jdx = oldnews[orbit]->operator[](idx);
Pierre Kraemer's avatar
merges  
Pierre Kraemer committed
403
				if ((jdx != 0xffffffff) && (jdx != idx))
404 405 406 407
					idx = jdx;
			}
		}
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
408

409 410 411 412 413
	// delete allocated vectors
	for (unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit)
		if ((orbit != DART) && (isOrbitEmbedded(orbit)))
			delete[] oldnews[orbit];

414 415
	// compact topo (depends on map implementation)
	compactTopo();
416 417
}

418 419 420 421 422 423 424 425 426
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
427
} // namespace CGoGN