Coupure prévue mardi 3 Août au matin pour maintenance du serveur. Nous faisons au mieux pour que celle-ci soit la plus brève possible.

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
	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");
272
	return atm;
Pierre Kraemer's avatar
Pierre Kraemer committed
273
274
}

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

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

	AttributeMultiVector<T>* atm = dynamic_cast<AttributeMultiVector<T>*>(m_tableAttribs[index]);
	assert((atm != NULL) || !"getDataVector: wrong type");
289
	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
	unsigned int index = getAttributeIndex(attribName) ;
	assert(index != UNKNOWN) ;
296
	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