attributeContainer.hpp 12.3 KB
Newer Older
Pierre Kraemer's avatar
Pierre Kraemer committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps  *
* version 0.1                                                                  *
* Copyright (C) 2009, IGG Team, LSIIT, University of Strasbourg                *
*                                                                              *
* 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.           *
*                                                                              *
* Web site: https://iggservis.u-strasbg.fr/CGoGN/                              *
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

#include <iostream>
Pierre Kraemer's avatar
Pierre Kraemer committed
26 27 28 29 30 31 32
#include <cassert>
#include "Container/registered.h"
#include "Utils/nameTypes.h"

namespace CGoGN
{

33 34 35 36
inline unsigned int AttributeContainer::getOrbit()
{
	return m_orbit ;
}
Pierre Kraemer's avatar
Pierre Kraemer committed
37

38 39 40 41 42 43 44 45 46 47 48
inline void AttributeContainer::setOrbit(unsigned int orbit)
{
	m_orbit = orbit ;
	for(unsigned int i = 0; i < m_tableAttribs.size(); ++i)
	{
		if (m_tableAttribs[i] != NULL)
			m_tableAttribs[i]->setOrbit(orbit);
	}
}

inline void AttributeContainer::setRegistry(std::map< std::string, RegisteredBaseAttribute* >* re)
Pierre Kraemer's avatar
Pierre Kraemer committed
49
{
50 51 52 53 54 55
	m_attributes_registry_map = re;
}

/**************************************
 *          BASIC FEATURES            *
 **************************************/
Pierre Kraemer's avatar
Pierre Kraemer committed
56

57 58 59
template <typename T>
AttributeMultiVector<T>* AttributeContainer::addAttribute(const std::string& attribName)
{
Pierre Kraemer's avatar
Pierre Kraemer committed
60
	// first check if attribute already exist
61
	unsigned int index ;
Pierre Kraemer's avatar
Pierre Kraemer committed
62 63
	if (attribName != "")
	{
64 65 66
		index = getAttributeIndex(attribName) ;
		if (index != UNKNOWN)
			return NULL ;
Pierre Kraemer's avatar
Pierre Kraemer committed
67 68
	}

69 70 71
	// create the new attribute
	std::string typeName = nameOfType(T()) ;
	AttributeMultiVector<T>* amv = new AttributeMultiVector<T>(attribName, typeName) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
72 73 74

	if(!m_freeIndices.empty())
	{
75
		index = m_freeIndices.back() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
76
		m_freeIndices.pop_back() ;
77
		m_tableAttribs[index] = amv ;
Pierre Kraemer's avatar
Pierre Kraemer committed
78 79 80
	}
	else
	{
81 82
		index = m_tableAttribs.size() ;
		m_tableAttribs.push_back(amv) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
83
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
84

85 86 87 88 89
	amv->setOrbit(m_orbit) ;
	amv->setIndex(index) ;

	// generate a name for the attribute if no one was given
	if (attribName == "")
Pierre Kraemer's avatar
Pierre Kraemer committed
90
	{
91 92 93
		std::stringstream ss ;
		ss << "unknown" << m_nbUnknown++ ;
		amv->setName(ss.str()) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
94 95
	}

96 97
	// update the memory cost of a line
	m_lineCost += sizeof(T) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
98

99 100 101 102
	// resize the new attribute so that it has the same size than others
	amv->setNbBlocks(m_holesBlocks.size()) ;

	m_nbAttributes++ ;
Pierre Kraemer's avatar
Pierre Kraemer committed
103

104
	return amv ;
Pierre Kraemer's avatar
Pierre Kraemer committed
105 106 107
}

template <typename T>
108
void AttributeContainer::addAttribute(const std::string& attribName, const std::string& nametype, unsigned int index)
Pierre Kraemer's avatar
Pierre Kraemer committed
109 110 111 112
{
	// first check if attribute already exist
	if (attribName != "")
	{
113 114 115
		unsigned int i = getAttributeIndex(attribName) ;
		if (i != UNKNOWN)
			return ;
Pierre Kraemer's avatar
Pierre Kraemer committed
116 117
	}

118
	// create the new attribute
Pierre Kraemer's avatar
Pierre Kraemer committed
119
	AttributeMultiVector<T>* amv = new AttributeMultiVector<T>(attribName, nametype);
120 121 122 123 124 125 126

	m_tableAttribs[index] = amv;
	amv->setOrbit(m_orbit) ;
	amv->setIndex(index) ;

	// generate a name for the attribute if no one was given
	if (attribName == "")
Pierre Kraemer's avatar
Pierre Kraemer committed
127 128 129 130 131
	{
		std::stringstream ss;
		ss << "unknown" << m_nbUnknown++;
		amv->setName(ss.str());
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
132

133 134
	// update the memory cost of a line
	m_lineCost += sizeof(T) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
135

136 137
	// resize the new attribute so that it has the same size than others
	amv->setNbBlocks(m_holesBlocks.size()) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
138 139 140 141

	m_nbAttributes++;
}

142 143 144 145 146
/**************************************
 *      INFO ABOUT THE CONTAINER      *
 **************************************/

inline unsigned int AttributeContainer::getNbAttributes() const
Pierre Kraemer's avatar
Pierre Kraemer committed
147
{
Pierre Kraemer's avatar
Pierre Kraemer committed
148
	return m_nbAttributes;
Pierre Kraemer's avatar
Pierre Kraemer committed
149 150
}

151 152 153 154
inline unsigned int AttributeContainer::size() const
{
	return m_size;
}
Pierre Kraemer's avatar
Pierre Kraemer committed
155

156
inline unsigned int AttributeContainer::capacity() const
Pierre Kraemer's avatar
Pierre Kraemer committed
157
{
158 159
	return m_holesBlocks.size() * _BLOCKSIZE_;
}
Pierre Kraemer's avatar
Pierre Kraemer committed
160

161 162 163 164
inline unsigned int AttributeContainer::memoryTotalSize() const
{
	return _BLOCKSIZE_ * (m_holesBlocks.size() * m_lineCost + 8);
}
Pierre Kraemer's avatar
Pierre Kraemer committed
165

166 167 168
inline bool AttributeContainer::used(unsigned int index) const
{
	return m_holesBlocks[index / _BLOCKSIZE_]->used(index % _BLOCKSIZE_);
Pierre Kraemer's avatar
Pierre Kraemer committed
169 170
}

171 172 173 174 175
/**************************************
 *         CONTAINER TRAVERSAL        *
 **************************************/

inline unsigned int AttributeContainer::begin() const
Pierre Kraemer's avatar
Pierre Kraemer committed
176
{
177 178 179 180 181
	unsigned int it = 0;
	while ((it < m_maxSize) && (!used(it)))
		++it;
	return it;
}
Pierre Kraemer's avatar
Pierre Kraemer committed
182

183 184 185 186
inline unsigned int AttributeContainer::end() const
{
	return m_maxSize;
}
Pierre Kraemer's avatar
Pierre Kraemer committed
187

188 189 190 191 192 193
inline void AttributeContainer::next(unsigned int &it) const
{
	do
	{
		++it;
	} while ((it < m_maxSize) && (!used(it)));
Pierre Kraemer's avatar
Pierre Kraemer committed
194 195
}

196 197 198 199 200
/**************************************
 *          LINES MANAGEMENT          *
 **************************************/

inline void AttributeContainer::initLine(unsigned int index)
Pierre Kraemer's avatar
Pierre Kraemer committed
201
{
202 203 204 205 206 207
	for(unsigned int i = 0; i < m_tableAttribs.size(); ++i)
	{
		if (m_tableAttribs[i] != NULL)
			m_tableAttribs[i]->initElt(index);
	}
}
Pierre Kraemer's avatar
Pierre Kraemer committed
208

209 210 211 212 213 214 215 216
inline void AttributeContainer::copyLine(unsigned int dstIndex, unsigned int srcIndex)
{
	for(unsigned int i = 0; i < m_tableAttribs.size(); ++i)
	{
		if (m_tableAttribs[i] != NULL)
			m_tableAttribs[i]->copyElt(dstIndex, srcIndex);
	}
}
Pierre Kraemer's avatar
Pierre Kraemer committed
217

218 219 220
inline void AttributeContainer::refLine(unsigned int index)
{
	m_holesBlocks[index / _BLOCKSIZE_]->ref(index % _BLOCKSIZE_);
Pierre Kraemer's avatar
Pierre Kraemer committed
221 222
}

223 224 225 226 227 228 229 230 231
inline bool AttributeContainer::unrefLine(unsigned int index)
{
	if (m_holesBlocks[index / _BLOCKSIZE_]->unref(index % _BLOCKSIZE_))
	{
		--m_size;
		return true;
	}
	return false;
}
Pierre Kraemer's avatar
Pierre Kraemer committed
232

233
inline unsigned int AttributeContainer::getNbRefs(unsigned int index)
Pierre Kraemer's avatar
Pierre Kraemer committed
234
{
235 236
	unsigned int bi = index / _BLOCKSIZE_;
	unsigned int j = index % _BLOCKSIZE_;
Pierre Kraemer's avatar
Pierre Kraemer committed
237

238
	return m_holesBlocks[bi]->nbRefs(j);
Pierre Kraemer's avatar
Pierre Kraemer committed
239 240
}

241
inline void AttributeContainer::setNbRefs(unsigned int index, unsigned int nb)
Pierre Kraemer's avatar
Pierre Kraemer committed
242
{
243 244
	m_holesBlocks[index / _BLOCKSIZE_]->setNbRefs(index % _BLOCKSIZE_, nb);
}
Pierre Kraemer's avatar
Pierre Kraemer committed
245

246 247 248
/**************************************
 *       ATTRIBUTES MANAGEMENT        *
 **************************************/
Pierre Kraemer's avatar
Pierre Kraemer committed
249

250 251 252 253
inline bool AttributeContainer::copyAttribute(unsigned int index_dst, unsigned int index_src)
{
	return m_tableAttribs[index_dst]->copy(m_tableAttribs[index_src]);
}
Pierre Kraemer's avatar
Pierre Kraemer committed
254

255 256 257
inline bool AttributeContainer::swapAttributes(unsigned int index1, unsigned int index2)
{
	return m_tableAttribs[index1]->swap(m_tableAttribs[index2]);
Pierre Kraemer's avatar
Pierre Kraemer committed
258 259
}

260 261 262
/**************************************
 *       ATTRIBUTES DATA ACCESS       *
 **************************************/
Pierre Kraemer's avatar
Pierre Kraemer committed
263 264

template <typename T>
265
AttributeMultiVector<T>& AttributeContainer::getDataVector(unsigned int attrIndex)
Pierre Kraemer's avatar
Pierre Kraemer committed
266
{
267 268 269 270 271 272
	assert(attrIndex < m_tableAttribs.size() || !"getDataVector: attribute index out of bounds");
	assert(m_tableAttribs[attrIndex] != NULL || !"getDataVector: attribute does not exist");

	AttributeMultiVector<T>* atm = dynamic_cast<AttributeMultiVector<T>*>(m_tableAttribs[attrIndex]);
	assert((atm != NULL) || !"getDataVector: wrong type");
	return *atm;
Pierre Kraemer's avatar
Pierre Kraemer committed
273 274
}

275 276 277 278
inline AttributeMultiVectorGen& AttributeContainer::getVirtualDataVector(unsigned int attrIndex)
{
	return *(m_tableAttribs[attrIndex]);
}
Pierre Kraemer's avatar
Pierre Kraemer committed
279

280 281
template <typename T>
AttributeMultiVector<T>& AttributeContainer::getDataVector(const std::string& attribName)
Pierre Kraemer's avatar
Pierre Kraemer committed
282
{
283 284 285 286 287 288 289
	unsigned int index = getAttributeIndex(attribName) ;

	assert(index != UNKNOWN) ;

	AttributeMultiVector<T>* atm = dynamic_cast<AttributeMultiVector<T>*>(m_tableAttribs[index]);
	assert((atm != NULL) || !"getDataVector: wrong type");
	return *atm;
Pierre Kraemer's avatar
Pierre Kraemer committed
290 291
}

292
inline AttributeMultiVectorGen& AttributeContainer::getVirtualDataVector(const std::string& attribName)
Pierre Kraemer's avatar
Pierre Kraemer committed
293
{
294 295 296
	unsigned int index = getAttributeIndex(attribName) ;
	assert(index != UNKNOWN) ;
	return *(m_tableAttribs[index]);
Pierre Kraemer's avatar
Pierre Kraemer committed
297 298
}

299 300
template <typename T>
inline T& AttributeContainer::getData(unsigned int attrIndex, unsigned int eltIndex)
Pierre Kraemer's avatar
Pierre Kraemer committed
301
{
302 303 304 305 306 307 308 309
	assert(eltIndex < m_maxSize || !"getData: element index out of bounds");
	assert(m_holesBlocks[eltIndex / _BLOCKSIZE_]->used(eltIndex % _BLOCKSIZE_) || !"getData: element does not exist");
	assert((m_tableAttribs[attrIndex] != NULL) || !"getData: attribute does not exist");

	AttributeMultiVector<T>* atm = dynamic_cast<AttributeMultiVector<T>*>(m_tableAttribs[attrIndex]);
	assert((atm != NULL) || !"getData: wrong type");

	return atm->operator[](eltIndex);
Pierre Kraemer's avatar
Pierre Kraemer committed
310 311
}

312 313
template <typename T>
inline const T& AttributeContainer::getData(unsigned int attrIndex, unsigned int eltIndex) const
Pierre Kraemer's avatar
Pierre Kraemer committed
314
{
315 316 317 318 319 320 321 322
	assert(eltIndex < m_maxSize || !"getData: element index out of bounds");
	assert(m_holesBlocks[eltIndex / _BLOCKSIZE_]->used(eltIndex % _BLOCKSIZE_) || !"getData: element does not exist");
	assert((m_tableAttribs[attrIndex] != NULL) || !"getData: attribute does not exist");

	AttributeMultiVector<T>* atm = dynamic_cast<AttributeMultiVector<T>*>(m_tableAttribs[attrIndex]);
	assert((atm != NULL) || !"getData: wrong type");

	return atm->operator[](eltIndex);
Pierre Kraemer's avatar
Pierre Kraemer committed
323 324
}

325 326
template <typename T>
inline void AttributeContainer::setData(unsigned int attrIndex, unsigned int eltIndex, const T& data)
Pierre Kraemer's avatar
Pierre Kraemer committed
327
{
328 329 330 331 332 333 334 335
	assert(eltIndex < m_maxSize || !"getData: element index out of bounds");
	assert(m_holesBlocks[eltIndex / _BLOCKSIZE_]->used(eltIndex % _BLOCKSIZE_) || !"getData: element does not exist");
	assert((m_tableAttribs[attrIndex] != NULL) || !"getData: attribute does not exist");

	AttributeMultiVector<T>* atm = dynamic_cast<AttributeMultiVector<T>*>(m_tableAttribs[attrIndex]);
	assert((atm != NULL) || !"getData: wrong type");

	atm->operator[](eltIndex) = data;
Pierre Kraemer's avatar
Pierre Kraemer committed
336 337
}

338 339 340 341 342
/**************************************
 *       ARITHMETIC OPERATIONS        *
 **************************************/

inline void AttributeContainer::toggleProcess(unsigned int index)
Pierre Kraemer's avatar
Pierre Kraemer committed
343
{
344 345 346
	assert(index < m_tableAttribs.size() || !"toggleProcess: attribute index out of bounds");
	assert(m_tableAttribs[index] != NULL || !"toggleProcess: attribute does not exist");
	m_tableAttribs[index]->toggleProcess();
Pierre Kraemer's avatar
Pierre Kraemer committed
347 348
}

349
inline void AttributeContainer::toggleNoProcess(unsigned int index)
Pierre Kraemer's avatar
Pierre Kraemer committed
350
{
351 352 353
	assert(index < m_tableAttribs.size() || !"toggleNoProcess: attribute index out of bounds");
	assert(m_tableAttribs[index] != NULL || !"toggleNoProcess: attribute does not exist");
	m_tableAttribs[index]->toggleNoProcess();
Pierre Kraemer's avatar
Pierre Kraemer committed
354 355
}

356
inline void AttributeContainer::affect(unsigned int i, unsigned int j)
Pierre Kraemer's avatar
Pierre Kraemer committed
357
{
358 359 360 361 362
	for (std::vector<AttributeMultiVectorGen*>::iterator it = m_tableAttribs.begin(); it!=  m_tableAttribs.end(); ++it)
	{
		if (*it != NULL)
			(*it)->affect(i, j);
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
363 364
}

365
inline void AttributeContainer::add(unsigned int i, unsigned int j)
Pierre Kraemer's avatar
Pierre Kraemer committed
366
{
367 368 369 370 371
	for (std::vector<AttributeMultiVectorGen*>::iterator it = m_tableAttribs.begin(); it!=  m_tableAttribs.end(); ++it)
	{
		if ((*it) != NULL)
			(*it)->add(i, j);
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
372 373
}

374
inline void AttributeContainer::sub(unsigned int i, unsigned int j)
Pierre Kraemer's avatar
Pierre Kraemer committed
375
{
376 377 378 379 380
	for (std::vector<AttributeMultiVectorGen*>::iterator it = m_tableAttribs.begin(); it!=  m_tableAttribs.end(); ++it)
	{
		if ((*it) != NULL)
			(*it)->sub(i, j);
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
381 382
}

383
inline void AttributeContainer::mult(unsigned int i, double alpha)
Pierre Kraemer's avatar
Pierre Kraemer committed
384
{
385
	for (std::vector<AttributeMultiVectorGen*>::iterator it = m_tableAttribs.begin(); it!=  m_tableAttribs.end(); ++it)
Pierre Kraemer's avatar
Pierre Kraemer committed
386
	{
387 388 389
		if ((*it) != NULL)
			(*it)->mult(i, alpha);
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
390 391
}

392
inline void AttributeContainer::div(unsigned int i, double alpha)
Pierre Kraemer's avatar
Pierre Kraemer committed
393
{
394 395 396 397 398
	for (std::vector<AttributeMultiVectorGen*>::iterator it = m_tableAttribs.begin(); it!=  m_tableAttribs.end(); ++it)
	{
		if ((*it) != NULL)
			(*it)->div(i, alpha);
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
399 400
}

401
inline void AttributeContainer::lerp(unsigned res, unsigned int i, unsigned int j, double alpha)
Pierre Kraemer's avatar
Pierre Kraemer committed
402
{
403 404 405 406 407
	for (std::vector<AttributeMultiVectorGen*>::iterator it = m_tableAttribs.begin(); it!=  m_tableAttribs.end(); ++it)
	{
		if ((*it) != NULL)
			(*it)->lerp(res, i, j, alpha);
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
408 409 410
}

} // namespace CGoGN