attributeContainer.h 13.3 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
#ifndef __ATTRIBUTE_CONTAINER__
#define __ATTRIBUTE_CONTAINER__
Pierre Kraemer's avatar
Pierre Kraemer committed
27 28 29

#include "Container/sizeblock.h"
#include "Container/holeblockref.h"
30
#include "Container/attributeMultiVector.h"
Pierre Kraemer's avatar
Pierre Kraemer committed
31 32 33 34 35 36 37 38 39 40 41

#include <vector>
#include <map>
#include <libxml/encoding.h>
#include <libxml/xmlwriter.h>
#include <libxml/parser.h>

namespace CGoGN
{

class RegisteredBaseAttribute;
42 43 44 45 46 47 48 49 50 51 52 53
class AttributeContainer;


class ContainerBrowser
{
public:
	virtual unsigned int begin() const = 0;
	virtual unsigned int end() const = 0;
	virtual void next(unsigned int &it) const = 0;
	virtual void enable() = 0;
	virtual void disable() = 0;
};
Pierre Kraemer's avatar
Pierre Kraemer committed
54 55

/**
56 57 58 59
 * Container for AttributeMultiVectors
 * All the attributes always have the same size and
 * the management of holes is shared by all attributes
 */
60
class AttributeContainer
Pierre Kraemer's avatar
Pierre Kraemer committed
61
{
62
public:
Pierre Kraemer's avatar
Pierre Kraemer committed
63
	/**
64
	* constante d'attribut inconnu
Pierre Kraemer's avatar
Pierre Kraemer committed
65
	*/
66
	static const unsigned int UNKNOWN = 0xffffffff;
Pierre Kraemer's avatar
Pierre Kraemer committed
67 68

	/**
69
	* Taille du bloc
Pierre Kraemer's avatar
Pierre Kraemer committed
70
	*/
Sylvain Thery's avatar
Sylvain Thery committed
71
//	static const unsigned int BlockSize = _BLOCKSIZE_;
Pierre Kraemer's avatar
Pierre Kraemer committed
72

73
protected:
Pierre Kraemer's avatar
Pierre Kraemer committed
74
	/**
75
	* vector of pointers to AttributeMultiVectors
Pierre Kraemer's avatar
Pierre Kraemer committed
76
	*/
77
	std::vector<AttributeMultiVectorGen*> m_tableAttribs;
Pierre Kraemer's avatar
Pierre Kraemer committed
78

79 80 81
	/**
	 * vector of free indices in the vector of AttributeMultiVectors
	 */
Pierre Kraemer's avatar
Pierre Kraemer committed
82 83
	std::vector<unsigned int> m_freeIndices;

Pierre Kraemer's avatar
Pierre Kraemer committed
84
	/**
85
	* vector of pointers to HoleBlockRef -> structure that manages holes and refs
Pierre Kraemer's avatar
Pierre Kraemer committed
86
	*/
87
	std::vector<HoleBlockRef*> m_holesBlocks;
Pierre Kraemer's avatar
Pierre Kraemer committed
88

89 90 91 92 93 94 95 96 97
	/**
	* vector of indices of blocks that have free space
	*/
	std::vector<unsigned int> m_tableBlocksWithFree;

	/**
	* vector of indices of blocks that are empty
	*/
	std::vector<unsigned int> m_tableBlocksEmpty;
Pierre Kraemer's avatar
Pierre Kraemer committed
98

99 100
	ContainerBrowser* m_currentBrowser;

Pierre Kraemer's avatar
Pierre Kraemer committed
101
	/**
102 103 104 105 106 107
	 * orbit of the container
	 */
	unsigned int m_orbit;

	/**
	* number of attributes
Pierre Kraemer's avatar
Pierre Kraemer committed
108 109 110
	*/ 
	unsigned int m_nbAttributes;

111 112 113 114 115
	/**
	 * counter for attributes without name
	 */
	unsigned int m_nbUnknown;

Pierre Kraemer's avatar
Pierre Kraemer committed
116 117 118 119 120 121 122 123 124 125 126
	/**
	* size (number of elts) of the container
	*/
	unsigned int m_size;

	/**
	* size of the container with holes
	*/
	unsigned int m_maxSize;

	/**
127
	* memory cost of each line
Pierre Kraemer's avatar
Pierre Kraemer committed
128 129 130 131
	*/
	unsigned int m_lineCost;

	/**
132
	 * map pointer (shared for all container of the same map) for attribute registration
Pierre Kraemer's avatar
Pierre Kraemer committed
133
	 */
134
	std::map<std::string, RegisteredBaseAttribute*>* m_attributes_registry_map;
Pierre Kraemer's avatar
Pierre Kraemer committed
135

136 137
public:
	AttributeContainer();
Pierre Kraemer's avatar
Pierre Kraemer committed
138

139 140
	~AttributeContainer();

141 142
	unsigned int getOrbit() const;

143 144 145 146
	void setOrbit(unsigned int orbit);

	void setRegistry(std::map<std::string, RegisteredBaseAttribute*>* re);

147 148
	void setContainerBrowser(ContainerBrowser* bro) { m_currentBrowser = bro;}

149 150
	bool hasBrowser() { return m_currentBrowser != NULL; }

151 152 153
	/**************************************
	 *          BASIC FEATURES            *
	 **************************************/
Pierre Kraemer's avatar
Pierre Kraemer committed
154 155

	/**
156 157 158 159
	 * add a new attribute to the container
	 * @param T (template) type of the new attribute
	 * @param attribName name of the new attribute
	 * @return pointer to the new AttributeMultiVector
Pierre Kraemer's avatar
Pierre Kraemer committed
160
	 */
161 162
	template <typename T>
	AttributeMultiVector<T>* addAttribute(const std::string& attribName);
Pierre Kraemer's avatar
Pierre Kraemer committed
163

164
protected:
Pierre Kraemer's avatar
Pierre Kraemer committed
165
	/**
166 167 168 169 170
	 * add a new attribute with a given index (for load only)
	 * @param T (template) type of the new attribute
	 * @param attribName name of the new attribute
	 * @param typeName name of the new attribute's type
	 * @param index index of the new attribute
Pierre Kraemer's avatar
Pierre Kraemer committed
171
	 */
172 173
	template <typename T>
	void addAttribute(const std::string& attribName, const std::string& typeName, unsigned int index);
Pierre Kraemer's avatar
Pierre Kraemer committed
174 175 176

public:
	/**
177 178 179
	* Remove an attribute (destroys data)
	* @param attribName name of the attribute to remove
	* @return removed or not
Pierre Kraemer's avatar
Pierre Kraemer committed
180
	*/
181
	template <typename T>
182
	bool removeAttribute(const std::string& attribName);
Pierre Kraemer's avatar
Pierre Kraemer committed
183 184

	/**
185 186 187
	* Remove an attribute (destroys data)
	* @param index index of the attribute to remove
	* @return removed or not
Pierre Kraemer's avatar
Pierre Kraemer committed
188
	*/
189
	template <typename T>
190 191 192 193 194
	bool removeAttribute(unsigned int index);

	/**************************************
	 *      INFO ABOUT THE CONTAINER      *
	 **************************************/
Pierre Kraemer's avatar
Pierre Kraemer committed
195 196

	/**
197 198 199
	 * Number of attributes of the container
	 */
	unsigned int getNbAttributes() const;
Pierre Kraemer's avatar
Pierre Kraemer committed
200 201

	/**
202
	* Size of the container (number of lines)
Pierre Kraemer's avatar
Pierre Kraemer committed
203
	*/
204
	unsigned int size() const;
Pierre Kraemer's avatar
Pierre Kraemer committed
205 206

	/**
207
	* Capacity of the container (number of lines including holes)
Pierre Kraemer's avatar
Pierre Kraemer committed
208
	*/
209
	unsigned int capacity() const;
Pierre Kraemer's avatar
Pierre Kraemer committed
210 211

	/**
212 213 214
	* Total memory cost of container
	*/
	unsigned int memoryTotalSize() const;
Pierre Kraemer's avatar
Pierre Kraemer committed
215

216 217 218 219 220
	/**
	* Memory cost of every used line
	*/
	unsigned int memorySize() const;

Pierre Kraemer's avatar
Pierre Kraemer committed
221
	/**
222 223 224
	* is the line used in the container
	*/
	inline bool used(unsigned int index) const;
Pierre Kraemer's avatar
Pierre Kraemer committed
225

226 227 228 229 230
	/**
	 * @brief check if container contain marker attribute
	 */
	bool hasMarkerAttribute() const;

231 232 233
	/**************************************
	 *         CONTAINER TRAVERSAL        *
	 **************************************/
Pierre Kraemer's avatar
Pierre Kraemer committed
234 235

	/**
236
	 * return the index of the first line of the container
Pierre Kraemer's avatar
Pierre Kraemer committed
237
	 */
238
	unsigned int begin() const;
Pierre Kraemer's avatar
Pierre Kraemer committed
239 240

	/**
Sylvain Thery's avatar
Sylvain Thery committed
241
	 * return the index after the last line of the container
Pierre Kraemer's avatar
Pierre Kraemer committed
242
	 */
243
	unsigned int end() const;
Pierre Kraemer's avatar
Pierre Kraemer committed
244 245

	/**
246 247
	 * get the index of the line after it in the container
	 * MUST BE USED INSTEAD OF ++ !
Pierre Kraemer's avatar
Pierre Kraemer committed
248
	 */
249
	void next(unsigned int &it) const;
Pierre Kraemer's avatar
Pierre Kraemer committed
250

251 252 253 254 255 256 257 258


	/**
	 * return the index of the first line of the container
	 */
	unsigned int realBegin() const;

	/**
Sylvain Thery's avatar
Sylvain Thery committed
259
	 * return the index after the last line of the container
260 261 262 263 264 265 266 267 268 269
	 */
	unsigned int realEnd() const;

	/**
	 * get the index of the line after it in the container
	 * MUST BE USED INSTEAD OF ++ !
	 */
	void realNext(unsigned int &it) const;


Sylvain Thery's avatar
Sylvain Thery committed
270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285
	/**
	 * return the index of the last line of the container
	 */
	unsigned int realRBegin() const;

	/**
	 * return the index before the first line of the container
	 */
	unsigned int realREnd() const;

	/**
	 * get the index of the line before "it" in the container
	 * MUST BE USED INSTEAD OF ++ !
	 */
	void realRNext(unsigned int &it) const;

286 287 288
	/**************************************
	 *       INFO ABOUT ATTRIBUTES        *
	 **************************************/
Pierre Kraemer's avatar
Pierre Kraemer committed
289 290 291 292

	/**
	* recuperation du code d'un attribut
	* @param attribName nom de l'attribut
293
	* @return l'indice de l'attribut
Pierre Kraemer's avatar
Pierre Kraemer committed
294
	*/
295
	unsigned int getAttributeIndex(const std::string& attribName) const;
Pierre Kraemer's avatar
Pierre Kraemer committed
296 297 298 299

	/**
	 * get the name of an attribute, given its index in the container
	 */
300
	const std::string& getAttributeName(unsigned int attrIndex) const;
Pierre Kraemer's avatar
Pierre Kraemer committed
301

Pierre Kraemer's avatar
Pierre Kraemer committed
302
	/**
303 304 305 306 307
	 * fill a vector with pointers to the blocks of the given attribute
	 * @param attrIndex index of the attribute
	 * @param vect_addr (OUT) vector of pointers
	 * @param byteBlockSize (OUT) size in bytes of each block
	 * @return number of blocks
Pierre Kraemer's avatar
Pierre Kraemer committed
308
	 */
309 310
	template<typename T>
	unsigned int getAttributeBlocksPointers(unsigned int attrIndex, std::vector<T*>& vect_ptr, unsigned int& byteBlockSize);
Pierre Kraemer's avatar
Pierre Kraemer committed
311 312

	/**
Sylvain Thery's avatar
Sylvain Thery committed
313 314 315
	 * fill a vector with attributes names
	 * @param names vector of names
	 * @return number of attributes
Pierre Kraemer's avatar
Pierre Kraemer committed
316
	 */
317
	unsigned int getAttributesNames(std::vector<std::string>& names) const;
Pierre Kraemer's avatar
Pierre Kraemer committed
318

Sylvain Thery's avatar
Sylvain Thery committed
319 320 321 322 323 324 325
	/**
	 * fill a vector with attribute type names
	 * @param types vector of type names
	 * @return number of attributes
	 */
	unsigned int getAttributesTypes(std::vector<std::string>& types);

326 327 328
	/**************************************
	 *        CONTAINER MANAGEMENT        *
	 **************************************/
Pierre Kraemer's avatar
Pierre Kraemer committed
329 330

	/**
331
	 * swap two containers
Pierre Kraemer's avatar
Pierre Kraemer committed
332
	 */
333
	void swap(AttributeContainer& cont);
Pierre Kraemer's avatar
Pierre Kraemer committed
334 335

	/**
336 337 338 339
	 * clear the container
	 * @param removeAttrib remove the attributes (not only their data)
	 */
	void clear(bool clearAttrib = false);
Pierre Kraemer's avatar
Pierre Kraemer committed
340 341

	/**
342 343 344 345
	 * container compacting
	 * @param mapOldNew table that contains a map from old indices to new indices (holes -> 0xffffffff)
	 */
	void compact(std::vector<unsigned int>& mapOldNew);
Pierre Kraemer's avatar
Pierre Kraemer committed
346

Sylvain Thery's avatar
Sylvain Thery committed
347 348 349 350 351 352 353
	/**
	 * Test the fragmentation of container,
	 * in fact just size/max_size
	 * @return 1 if full filled - 0 is lots of holes
	 */
	inline float fragmentation();

354 355 356
	/**************************************
	 *          LINES MANAGEMENT          *
	 **************************************/
Pierre Kraemer's avatar
Pierre Kraemer committed
357 358

	/**
359 360
	* insert a line in the container
	* @return index of the line
Pierre Kraemer's avatar
Pierre Kraemer committed
361
	*/
362
	unsigned int insertLine();
Pierre Kraemer's avatar
Pierre Kraemer committed
363 364

	/**
365 366
	* remove a line in the container
	* @param index index of the line to remove
Pierre Kraemer's avatar
Pierre Kraemer committed
367
	*/
368
	void removeLine(unsigned int index);
Pierre Kraemer's avatar
Pierre Kraemer committed
369 370

	/**
371 372 373
	 * initialize a line of the container (an element of each attribute)
	 */
	void initLine(unsigned int index);
Pierre Kraemer's avatar
Pierre Kraemer committed
374 375

	/**
376 377 378
	 * copy the content of line src in line dst
	 */
	void copyLine(unsigned int dstIndex, unsigned int srcIndex);
Pierre Kraemer's avatar
Pierre Kraemer committed
379 380

	/**
381 382
	* increment the ref counter of the given line
	* @param index index of the line
Pierre Kraemer's avatar
Pierre Kraemer committed
383
	*/
384
	void refLine(unsigned int index);
Pierre Kraemer's avatar
Pierre Kraemer committed
385 386

	/**
387 388 389
	* decrement the ref counter of the given line
	* @param index index of the line
	* @return true if the line was removed
Pierre Kraemer's avatar
Pierre Kraemer committed
390
	*/
391
	bool unrefLine(unsigned int eltIdx);
Pierre Kraemer's avatar
Pierre Kraemer committed
392 393

	/**
394 395 396
	* get the number of refs of the given line
	* @param index index of the line
	* @return number of refs of the line
Pierre Kraemer's avatar
Pierre Kraemer committed
397
	*/
398
	unsigned int getNbRefs(unsigned int index) const;
Pierre Kraemer's avatar
Pierre Kraemer committed
399 400

	/**
401 402 403
	* set the number of refs of the given line
	* @param index index of the line
	* @param nb number of refs
Pierre Kraemer's avatar
Pierre Kraemer committed
404
	*/
405
	void setNbRefs(unsigned int eltIdx, unsigned int nb);
Pierre Kraemer's avatar
Pierre Kraemer committed
406

407 408 409
	/**************************************
	 *       ATTRIBUTES MANAGEMENT        *
	 **************************************/
Pierre Kraemer's avatar
Pierre Kraemer committed
410 411

	/**
412 413 414
	 * copy the data of attribute src in attribute dst (type has to be the same)
	 */
	bool copyAttribute(unsigned int dstIndex, unsigned int srcIndex);
Pierre Kraemer's avatar
Pierre Kraemer committed
415 416

	/**
417 418 419
	 * swap the data of attribute 1 with attribute 2 (type has to be the same)
	 */
	bool swapAttributes(unsigned int index1, unsigned int index2);
Pierre Kraemer's avatar
Pierre Kraemer committed
420

421 422 423
	/**************************************
	 *       ATTRIBUTES DATA ACCESS       *
	 **************************************/
Pierre Kraemer's avatar
Pierre Kraemer committed
424

425 426
	inline CGoGNCodeType getTypeCode(const std::string& attribName) const;

Pierre Kraemer's avatar
Pierre Kraemer committed
427
	/**
428 429
	* get an AttributeMultiVector
	* @param attrIndex index of the attribute
Pierre Kraemer's avatar
Pierre Kraemer committed
430 431
	*/
	template<typename T>
432
	AttributeMultiVector<T>* getDataVector(unsigned int attrIndex);
Pierre Kraemer's avatar
Pierre Kraemer committed
433

434
	AttributeMultiVectorGen* getVirtualDataVector(unsigned int attrIndex);
Pierre Kraemer's avatar
Pierre Kraemer committed
435 436

	/**
437 438
	* get an AttributeMultiVector
	* @param attribName name of the attribute
Pierre Kraemer's avatar
Pierre Kraemer committed
439
	*/
440
	template<typename T>
441
	AttributeMultiVector<T>* getDataVector(const std::string& attribName);
Pierre Kraemer's avatar
Pierre Kraemer committed
442

443
	AttributeMultiVectorGen* getVirtualDataVector(const std::string& attribName);
Pierre Kraemer's avatar
Pierre Kraemer committed
444 445

	/**
446 447 448 449 450
	* get a given element of a given attribute
	* @param T type of the attribute
	* @param attrIndex index of the attribute
	* @param eltIndex index of the element
	* @return a reference on the element
Pierre Kraemer's avatar
Pierre Kraemer committed
451
	*/
452 453
	template <typename T>
	T& getData(unsigned int attrIndex, unsigned int eltIndex);
Pierre Kraemer's avatar
Pierre Kraemer committed
454 455

	/**
456 457 458 459 460
	* get a given const element of a given attribute
	* @param T type of the attribute
	* @param attrIndex index of the attribute
	* @param eltIndex index of the element
	* @return a const reference on the element
Pierre Kraemer's avatar
Pierre Kraemer committed
461
	*/
462 463
	template <typename T>
	const T& getData(unsigned int attrIndex, unsigned int eltIndex) const;
Pierre Kraemer's avatar
Pierre Kraemer committed
464 465

	/**
466 467 468 469 470
	* set a given element of a given attribute
	* @param T type of the attribute
	* @param attrIndex index of the attribute
	* @param eltIndex index of the element
	* @param data data to insert
Pierre Kraemer's avatar
Pierre Kraemer committed
471
	*/
472 473
	template <typename T>
	void setData(unsigned int attrIndex, unsigned int eltIndex, const T& data);
Pierre Kraemer's avatar
Pierre Kraemer committed
474 475


476 477 478 479 480 481 482 483 484 485 486

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

public:
	/**
	* save binary file
	* @param fs a file stream
	* @param id the id to save
	*/
Sylvain Thery's avatar
Sylvain Thery committed
487
	void saveBin(CGoGNostream& fs, unsigned int id) const;
488 489 490 491 492 493 494 495 496 497 498 499 500 501

	/**
	* get id from file binary stream
	* @param fs file stream
	* @return the id of attribute container
	*/
	static unsigned int loadBinId(CGoGNistream& fs);

	/**
	* load from binary file
	* @param fs a file stream
	* @param id  ??
	*/
	bool loadBin(CGoGNistream& fs);
502 503 504 505 506 507 508

	/**
	 * copy container
	 * TODO a version that compact on the fly ?
	 */
	void copyFrom(const AttributeContainer& cont);

509 510 511 512 513 514 515 516
	/**
	 * dump the container in CSV format (; separated columns)
	 */
	void dumpCSV() const;

	void dumpByLines() const;


Pierre Kraemer's avatar
Pierre Kraemer committed
517 518 519 520
};

} // namespace CGoGN

521
#include "attributeContainer.hpp"
Pierre Kraemer's avatar
Pierre Kraemer committed
522 523

#endif