attributeHandler.h 10 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 26 27 28 29 30 31
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

#ifndef __ATTRIBUTE_HANDLER_H__
#define __ATTRIBUTE_HANDLER_H__

#include <vector>
#include <map>

#include "Topology/generic/genericmap.h"
Pierre Kraemer's avatar
Pierre Kraemer committed
32
#include "Container/attributeContainer.h"
33
#include "Container/fakeAttribute.h"
34
#include "Topology/generic/cells.h"
Pierre Kraemer's avatar
Pierre Kraemer committed
35

36 37 38
/// Macro that checks if ATTRIBUTEHANDLER type is an AttributeHandler
#define CHECK_ATTRIBUTEHANDLER(ATTRIBUTEHANDLER)\
	static_assert(std::is_base_of<AttributeHandlerGen, ATTRIBUTEHANDLER>::value, "Error not AttributeHandler");
39

40 41 42 43
/// Macro that checks if ATTRIBUTEHANDLER type is an AttributeHandler of orbit ORBITVALUE
#define CHECK_ATTRIBUTEHANDLER_ORBIT(ATTRIBUTEHANDLER, ORBITVALUE)\
	static_assert(std::is_base_of<AttributeHandlerGen, ATTRIBUTEHANDLER>::value, "Error not AttributeHandler");\
	static_assert(ATTRIBUTEHANDLER::ORBIT == ORBITVALUE, "Error wrong orbit of AttributeHandler");
44

Pierre Kraemer's avatar
Pierre Kraemer committed
45 46 47
namespace CGoGN
{

48 49 50
class AttributeHandlerGen
{
protected:
51
	friend class GenericMap ;
Pierre Kraemer's avatar
Pierre Kraemer committed
52
	template <typename MAP_IMPL> friend class MapCommon;
53 54 55

	// boolean that states the validity of the handler
	bool valid ;
56 57

public:
Pierre Kraemer's avatar
Pierre Kraemer committed
58
	AttributeHandlerGen(bool v) :
59
		valid(v)
60 61
	{}

62
	bool isValid() const { return valid ; }
63

64 65 66 67
	virtual int getSizeOfType() const = 0;

	virtual unsigned int getOrbit() const = 0;

68
	virtual const std::string& name() const = 0;
69 70 71
	virtual const std::string& typeName() const = 0;

	virtual AttributeMultiVectorGen* getDataVectorGen() const = 0;
72

73
protected:
74
	void setInvalid() { valid = false ; }
75
	void setValid() { valid = true ; }
76
} ;
77

78 79 80 81 82 83 84 85 86 87 88
template <unsigned int ORB>
class AttributeHandlerOrbit: public AttributeHandlerGen
{
public:
	AttributeHandlerOrbit(bool v) :
		AttributeHandlerGen(v)
	{}

	static const unsigned int ORBIT = ORB;
};

89 90 91 92 93 94 95

// forward declaration
template <typename T, unsigned int ORB, typename MAP>
class AttributeHandlerIter;



Pierre Kraemer's avatar
Pierre Kraemer committed
96 97
/**
 * Class that create an access-table to an existing attribute
Pierre Kraemer's avatar
Pierre Kraemer committed
98
 * Main available operations are:
Pierre Kraemer's avatar
Pierre Kraemer committed
99 100 101 102
 * - [ index ]
 * - [ dart ]
 * - begin / end / next to manage indexing
 */
103
template <typename T, unsigned int ORB, typename MAP>
104
class AttributeHandler : public AttributeHandlerOrbit<ORB>
Pierre Kraemer's avatar
Pierre Kraemer committed
105 106
{
protected:
Pierre Kraemer's avatar
Pierre Kraemer committed
107
	// the map that contains the linked attribute
108
	MAP* m_map;
109
	// the multi-vector that contains attribute data
110
	AttributeMultiVector<T>* m_attrib;
Pierre Kraemer's avatar
Pierre Kraemer committed
111

112 113 114
	void registerInMap() ;
	void unregisterFromMap() ;

115 116 117
public:
	typedef T DATA_TYPE ;

118 119 120 121 122 123
	/**
	 * Default constructor
	 * Constructs a non-valid AttributeHandler (i.e. not linked to any attribute)
	 */
	AttributeHandler() ;

Pierre Kraemer's avatar
Pierre Kraemer committed
124 125 126
	/**
	 * Constructor
	 * @param m the map which belong attribute
127
	 * @param amv a pointer to the AttributeMultiVector
Pierre Kraemer's avatar
Pierre Kraemer committed
128
	 */
129
	AttributeHandler(MAP* m, AttributeMultiVector<T>* amv) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
130 131 132 133 134

	/**
	 * Copy constructor
	 * @param ta the table attribute
	 */
135
	AttributeHandler(const AttributeHandler<T, ORB, MAP>& ta) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
136

untereiner's avatar
untereiner committed
137 138 139 140 141 142
	/**
	 * Transmute Constructor
	 * Construct an attribute of Orbit from Orbit2
	 * @param h the table attribute
	 */
	template <unsigned int ORBIT2>
143
	AttributeHandler(const AttributeHandler<T, ORBIT2, MAP>& h) ;
untereiner's avatar
untereiner committed
144

Pierre Kraemer's avatar
Pierre Kraemer committed
145 146 147 148
	/**
	 * affectation operator
	 * @param ta the table attribute to affect to this
	 */
149
	AttributeHandler<T, ORB, MAP>& operator=(const AttributeHandler<T, ORB, MAP>& ta) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
150

untereiner's avatar
untereiner committed
151 152 153 154 155
	/**
	 * transmuted affectation operator
	 * @param ta the table attribute to affect to this
	 */
	template <unsigned int ORBIT2>
156
	AttributeHandler<T, ORB, MAP>& operator=(const AttributeHandler<T, ORBIT2, MAP>& ta) ;
untereiner's avatar
untereiner committed
157

Pierre Kraemer's avatar
Pierre Kraemer committed
158 159 160 161 162
	/**
	 * Destructor (empty & virtual)
	 */
	virtual ~AttributeHandler() ;

Pierre Kraemer's avatar
Pierre Kraemer committed
163 164 165 166
	/**
	 * @brief map
	 * @return the map that contains the attribute
	 */
167
	MAP* map() const
Pierre Kraemer's avatar
Pierre Kraemer committed
168 169 170 171
	{
		return m_map ;
	}

Pierre Kraemer's avatar
Pierre Kraemer committed
172 173 174
	/**
	 * get attribute data vector
	 */
175
	AttributeMultiVector<T>* getDataVector() const ;
Pierre Kraemer's avatar
Pierre Kraemer committed
176

177 178 179 180 181 182 183 184 185 186
	/**
	 * get attribute data vector (generic MultiVector)
	 */
	virtual AttributeMultiVectorGen* getDataVectorGen() const ;

	/**
	 * get size of attribute type
	 */
	virtual int getSizeOfType() const ;

Pierre Kraemer's avatar
Pierre Kraemer committed
187
	/**
188
	 * get attribute orbit
Pierre Kraemer's avatar
Pierre Kraemer committed
189
	 */
190
	virtual unsigned int getOrbit() const ;
191 192 193 194 195

	/**
	 * get attribute index
	 */
	unsigned int getIndex() const ;
Pierre Kraemer's avatar
Pierre Kraemer committed
196 197 198 199

	/**
	 * get attribute name
	 */
200
	virtual const std::string& name() const ;
Pierre Kraemer's avatar
Pierre Kraemer committed
201

202 203 204 205
	/**
	 * get attribute type name
	 */
	virtual const std::string& typeName() const ;
206

207 208 209 210 211
	/**
	 * give the number of elements of the attribute container
	 */
	unsigned int nbElements() const;

Pierre Kraemer's avatar
Pierre Kraemer committed
212
	/**
213
	 * [] operator with cell parameter
Pierre Kraemer's avatar
Pierre Kraemer committed
214
	 */
215
	T& operator[](Cell<ORB> c) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
216 217

	/**
218
	 * const [] operator with cell parameter
Pierre Kraemer's avatar
Pierre Kraemer committed
219
	 */
220
	const T& operator[](Cell<ORB> c) const ;
Pierre Kraemer's avatar
Pierre Kraemer committed
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237

	/**
	 * at operator (same as [] but with index parameter)
	 */
	T& operator[](unsigned int a) ;

	/**
	 * const at operator (same as [] but with index parameter)
	 */
	const T& operator[](unsigned int a) const ;

	/**
	 * insert an element (warning we add here a complete line in container)
	 */
	unsigned int insert(const T& elt) ;

	/**
untereiner's avatar
ihm3  
untereiner committed
238
	 * insert an element with default value (warning we add here a complete line in container)
Pierre Kraemer's avatar
Pierre Kraemer committed
239 240 241
	 */
	unsigned int newElt() ;

242
	/**
243
	 * initialize all the lines of the attribute with the given value
244
	 */
245
	void setAllValues(const T& v) ;
246

Pierre Kraemer's avatar
Pierre Kraemer committed
247 248 249 250 251 252 253
	/**
	 * begin of table
	 * @return the iterator of the begin of container
	 */
	unsigned int begin() const;

	/**
254
	 * end of table
Pierre Kraemer's avatar
Pierre Kraemer committed
255 256 257 258 259
	 * @return the iterator of the end of container
	 */
	unsigned int end() const;

	/**
260
	 * Next on iterator (equivalent to stl ++)
Pierre Kraemer's avatar
Pierre Kraemer committed
261 262 263
	 * @param iter iterator to
	 */
	void next(unsigned int& iter) const;
264 265

	AttributeHandlerIter<T,ORB,MAP> iterable() const;
Pierre Kraemer's avatar
Pierre Kraemer committed
266 267
} ;

268 269


270
/**
271
 *  c++11 shortcut for Dart Attribute (Handler)
272
 */
273
template <typename T, typename MAP>
274
using DartAttribute = AttributeHandler<T, DART, MAP>;
275

276 277 278
typedef AttributeHandlerOrbit<DART> DartAttributeGen;


279
/**
280
 *  c++11 shortcut for Vertex Attribute (Handler)
281
 */
282
template <typename T, typename MAP>
283
using VertexAttribute = AttributeHandler<T, VERTEX, MAP>;
284

285 286 287
typedef AttributeHandlerOrbit<VERTEX> VertexAttributeGen;


288
/**
289
 *  c++11 shortcut for Edge Attribute (Handler)
290
 */
291
template <typename T, typename MAP>
292
using EdgeAttribute = AttributeHandler<T, EDGE, MAP>;
293

294 295
typedef AttributeHandlerOrbit<EDGE> EdgeAttributeGen;

296
/**
297
 *  c++11 shortcut for Face Attribute (Handler)
298
 */
299
template <typename T, typename MAP>
300
using FaceAttribute = AttributeHandler<T, FACE, MAP>;
301

302 303
typedef AttributeHandlerOrbit<FACE> FaceAttributeGen;

304
/**
305
 *  c++11 shortcut for Volume Attribute (Handler)
306
 */
307
template <typename T, typename MAP>
308 309
using VolumeAttribute = AttributeHandler<T, VOLUME, MAP>;

310
typedef AttributeHandlerOrbit<VOLUME> VolumeAttributeGen;
311

312

untereiner's avatar
untereiner committed
313

314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371

template <typename T, unsigned int ORB, typename MAP>
class AttributeHandlerIter : public AttributeHandler<T,ORB,MAP>
{
public:

	AttributeHandlerIter(const AttributeHandler<T, ORB, MAP>& ta):
		AttributeHandler<T,ORB,MAP>(ta)
	{
	}


	class iterator
	{
		AttributeHandlerIter<T,ORB,MAP>* m_ptr;
		unsigned int m_index;

	public:

		inline iterator(AttributeHandlerIter<T, ORB, MAP>* p, unsigned int i): m_ptr(p),m_index(i){}

		inline iterator& operator++()
		{
			m_ptr->next(m_index);
			return *this;
		}

		inline T& operator*()
		{
			T& v = m_ptr->operator[](m_index);
			return v;
		}

		inline bool operator!=(iterator it)
		{
			return m_index != it.m_index;
		}

	};

	inline iterator begin()
	{
		return iterator(this,AttributeHandler<T,ORB,MAP>::begin());
	}

	inline iterator end()
	{
		return iterator(this,AttributeHandler<T,ORB,MAP>::end());
	}

};







untereiner's avatar
untereiner committed
372 373 374 375
// turn_to<b>(A*</b> obj) changes class of the object
// that means it just replaces VTBL of the object by VTBL of another class.
// NOTE: these two classes has to be ABI compatible!
template <typename TO_T, typename FROM_T>
Pierre Kraemer's avatar
Pierre Kraemer committed
376 377 378 379 380
inline void turn_to(FROM_T* p)
{
assert(sizeof(FROM_T) == sizeof(TO_T));
::new(p) TO_T(); // use of placement new
}
untereiner's avatar
untereiner committed
381

Sylvain Thery's avatar
Sylvain Thery committed
382 383 384 385 386 387 388 389 390 391 392 393 394
/**
 * apply function on each element of attribute
 * Warning attr must also be captured by lambda funct
 */
template <typename ATTR, typename FUNC>
inline void foreach_attribute(ATTR& attr, FUNC func)
{
	for (unsigned int id=attr.begin(); id != attr.end(); attr.next(id))
		func(id);
}

namespace Parallel
{
395

Sylvain Thery's avatar
Sylvain Thery committed
396
template <typename ATTR, typename FUNC>
397 398
void foreach_attribute(ATTR& attribute, FUNC func, unsigned int nbth = NumberOfThreads);

Sylvain Thery's avatar
Sylvain Thery committed
399 400
}

401 402 403
template<unsigned int ORBIT>
inline bool checkAttributeHandlerOrbit(const AttributeHandlerGen& att)
{
Sylvain Thery's avatar
Sylvain Thery committed
404
	return dynamic_cast<const AttributeHandlerOrbit<ORBIT>*>(&att) != NULL;
405 406
}

Pierre Kraemer's avatar
Pierre Kraemer committed
407 408 409 410 411
} // namespace CGoGN

#include "Topology/generic/attributeHandler.hpp"

#endif