attributeMultiVector.hpp 11 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
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/
Pierre Kraemer's avatar
Pierre Kraemer committed
24 25 26 27

namespace CGoGN
{

28
inline AttributeMultiVectorGen::AttributeMultiVectorGen(const std::string& strName, const std::string& strType):
29
	m_attrName(strName), m_typeName(strType), m_toProcess(true)
Pierre Kraemer's avatar
Pierre Kraemer committed
30 31
{}

32 33
inline AttributeMultiVectorGen::AttributeMultiVectorGen():
	m_toProcess(true)
Pierre Kraemer's avatar
Pierre Kraemer committed
34 35
{}

36
inline AttributeMultiVectorGen::~AttributeMultiVectorGen()
Pierre Kraemer's avatar
Pierre Kraemer committed
37 38
{}

39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
/**************************************
 *             ACCESSORS              *
 **************************************/

inline unsigned int AttributeMultiVectorGen::getOrbit() const
{
	return m_orbit;
}

inline void AttributeMultiVectorGen::setOrbit(unsigned int i)
{
	m_orbit = i ;
}

inline unsigned int AttributeMultiVectorGen::getIndex() const
{
	return m_index;
}

inline void AttributeMultiVectorGen::setIndex(unsigned int i)
{
	m_index = i ;
}

inline const std::string& AttributeMultiVectorGen::getName()
{
	return m_attrName;
}

inline void AttributeMultiVectorGen::setName(const std::string& n)
{
	m_attrName = n ;
}

inline const std::string& AttributeMultiVectorGen::getTypeName()
{
	return m_typeName;
}

inline void AttributeMultiVectorGen::setTypeName(const std::string& n)
{
	m_typeName = n ;
}

inline unsigned int AttributeMultiVectorGen::getBlockSize()
{
	return _BLOCKSIZE_ ;
}

Pierre Kraemer's avatar
Pierre Kraemer committed
88

89 90
/***************************************************************************************************/
/***************************************************************************************************/
Pierre Kraemer's avatar
Pierre Kraemer committed
91 92 93


template <typename T>
94
AttributeMultiVector<T>::AttributeMultiVector(const std::string& strName, const std::string& strType):
95
	AttributeMultiVectorGen(strName, strType)
Pierre Kraemer's avatar
Pierre Kraemer committed
96 97 98 99 100
{
	m_tableData.reserve(1024);
}

template <typename T>
101
AttributeMultiVector<T>::AttributeMultiVector()
Pierre Kraemer's avatar
Pierre Kraemer committed
102 103 104 105 106
{
	m_tableData.reserve(1024);
}

template <typename T>
107
AttributeMultiVector<T>::~AttributeMultiVector()
Pierre Kraemer's avatar
Pierre Kraemer committed
108 109 110 111 112 113
{
	for (typename std::vector< T* >::iterator it = m_tableData.begin(); it != m_tableData.end(); ++it)
		delete[] (*it);
}

template <typename T>
114
inline AttributeMultiVectorGen* AttributeMultiVector<T>::new_obj()
Pierre Kraemer's avatar
Pierre Kraemer committed
115
{
116 117 118
	AttributeMultiVectorGen* ptr = new AttributeMultiVector<T>;
	ptr->setTypeName(m_typeName);
	return ptr;
Pierre Kraemer's avatar
Pierre Kraemer committed
119 120
}

121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
/**************************************
 *       MULTI VECTOR MANAGEMENT      *
 **************************************/

template <typename T>
inline void AttributeMultiVector<T>::addBlock()
{
	T* ptr = new T[_BLOCKSIZE_];
	m_tableData.push_back(ptr);
	// init
//	T* endPtr = ptr + _BLOCKSIZE_;
//	while (ptr != endPtr)
//		*ptr++ = T(0);
}

template <typename T>
void AttributeMultiVector<T>::setNbBlocks(unsigned int nbb)
{
	if (nbb >= m_tableData.size())
	{
		for (unsigned int i= m_tableData.size(); i <nbb; ++i)
			addBlock();
	}
	else
	{
		for (unsigned int i = nbb; i < m_tableData.size(); ++i)
			delete[] m_tableData[i];
		m_tableData.resize(nbb);
	}
}

152 153 154 155 156 157
template <typename T>
unsigned int AttributeMultiVector<T>::getNbBlocks() const
{
	return m_tableData.size();
}

158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
template <typename T>
void AttributeMultiVector<T>::addBlocksBefore(unsigned int nbb)
{
	std::vector<T*> tempo;
	tempo.reserve(1024);

	for (unsigned int i = 0; i < nbb; ++i)
		addBlock();

	for (typename std::vector<T*>::iterator it = m_tableData.begin(); it != m_tableData.end(); ++it)
		tempo.push_back(*it);

	m_tableData.swap(tempo);
}

Pierre Kraemer's avatar
Pierre Kraemer committed
173
template <typename T>
174
bool AttributeMultiVector<T>::copy(const AttributeMultiVectorGen* atmvg)
Pierre Kraemer's avatar
Pierre Kraemer committed
175
{
176
	const AttributeMultiVector<T>* atmv = dynamic_cast<const AttributeMultiVector<T>*>(atmvg);
Pierre Kraemer's avatar
Pierre Kraemer committed
177 178 179

	if (atmv == NULL)
	{
180
		CGoGNerr << "trying to copy attributes of different type" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
181 182 183 184
		return false;
	}
	if (atmv->m_typeName != m_typeName)
	{
185
		CGoGNerr << "trying to swap attributes with different type names" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
186 187 188 189
		return false;
	}

	for (unsigned int i = 0; i < atmv->m_tableData.size(); ++i)
190 191
		std::memcpy(m_tableData[i], atmv->m_tableData[i], _BLOCKSIZE_ * sizeof(T));

Pierre Kraemer's avatar
Pierre Kraemer committed
192 193 194 195
	return true;
}

template <typename T>
196
bool AttributeMultiVector<T>::swap(AttributeMultiVectorGen* atmvg)
Pierre Kraemer's avatar
Pierre Kraemer committed
197
{
198
	AttributeMultiVector<T>* atmv = dynamic_cast<AttributeMultiVector<T>*>(atmvg);
Pierre Kraemer's avatar
Pierre Kraemer committed
199 200 201

	if (atmv == NULL)
	{
202
		CGoGNerr << "trying to swap attributes of different type" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
203 204
		return false;
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
205
	if (atmv->m_typeName != m_typeName)
Pierre Kraemer's avatar
Pierre Kraemer committed
206
	{
207
		CGoGNerr << "trying to swap attributes with different type names" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
208 209 210
		return false;
	}

Pierre Kraemer's avatar
Pierre Kraemer committed
211
	m_tableData.swap(atmv->m_tableData) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
212 213 214 215
	return true;
}

template <typename T>
216
bool AttributeMultiVector<T>::merge(const AttributeMultiVectorGen& att)
Pierre Kraemer's avatar
Pierre Kraemer committed
217
{
218
	const AttributeMultiVector<T>* attrib = dynamic_cast< const AttributeMultiVector<T>* >(&att);
Pierre Kraemer's avatar
Pierre Kraemer committed
219 220
	if (attrib==NULL)
	{
221
		CGoGNerr << "trying to merge attributes of different type" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
222 223
		return false;
	}
224

Pierre Kraemer's avatar
Pierre Kraemer committed
225 226
	if (attrib->m_typeName != m_typeName)
	{
227
		CGoGNerr << "trying to merge attributes with different type names" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
228 229 230
		return false;
	}

231
	for (typename std::vector<T*>::const_iterator it = attrib->m_tableData.begin(); it != attrib->m_tableData.end(); ++it)
Pierre Kraemer's avatar
Pierre Kraemer committed
232 233 234 235 236 237
		m_tableData.push_back(*it);

	return true;
}

template <typename T>
238
inline void AttributeMultiVector<T>::clear()
Pierre Kraemer's avatar
Pierre Kraemer committed
239
{
240 241 242
	for (typename std::vector< T* >::iterator it = m_tableData.begin(); it != m_tableData.end(); ++it)
		delete[] (*it);
	m_tableData.clear();
Pierre Kraemer's avatar
Pierre Kraemer committed
243
}
Pierre Kraemer's avatar
Pierre Kraemer committed
244

245 246 247
/**************************************
 *             DATA ACCESS            *
 **************************************/
Pierre Kraemer's avatar
Pierre Kraemer committed
248 249

template <typename T>
250
inline T& AttributeMultiVector<T>::operator[](unsigned int i)
Pierre Kraemer's avatar
Pierre Kraemer committed
251
{
252
	return m_tableData[i / _BLOCKSIZE_][i % _BLOCKSIZE_];
Pierre Kraemer's avatar
Pierre Kraemer committed
253 254 255
}

template <typename T>
256
inline const T& AttributeMultiVector<T>::operator[](unsigned int i) const
Pierre Kraemer's avatar
Pierre Kraemer committed
257
{
258
	return m_tableData[i / _BLOCKSIZE_][i % _BLOCKSIZE_];
Pierre Kraemer's avatar
Pierre Kraemer committed
259 260 261
}

template <typename T>
262
unsigned int AttributeMultiVector<T>::getBlocksPointers(std::vector<void*>& addr, unsigned int& byteBlockSize)
Pierre Kraemer's avatar
Pierre Kraemer committed
263
{
264 265 266 267 268 269 270 271 272
	byteBlockSize = _BLOCKSIZE_ * sizeof(T);

	addr.reserve(m_tableData.size());
	addr.clear();

	for (typename std::vector<T*>::iterator it = m_tableData.begin(); it != m_tableData.end(); ++it)
		addr.push_back(*it);

	return addr.size();
Pierre Kraemer's avatar
Pierre Kraemer committed
273 274
}

275 276 277 278
/**************************************
 *          LINES MANAGEMENT          *
 **************************************/

Pierre Kraemer's avatar
Pierre Kraemer committed
279
template <typename T>
Sylvain Thery's avatar
Sylvain Thery committed
280
inline void AttributeMultiVector<T>::initElt(unsigned int id)
Pierre Kraemer's avatar
Pierre Kraemer committed
281
{
282
	m_tableData[id / _BLOCKSIZE_][id % _BLOCKSIZE_] = T(0);
Pierre Kraemer's avatar
Pierre Kraemer committed
283 284 285
}

template <typename T>
Sylvain Thery's avatar
Sylvain Thery committed
286
inline void AttributeMultiVector<T>::copyElt(unsigned int dst, unsigned int src)
Pierre Kraemer's avatar
Pierre Kraemer committed
287
{
288
	m_tableData[dst / _BLOCKSIZE_][dst % _BLOCKSIZE_] = m_tableData[src / _BLOCKSIZE_][src % _BLOCKSIZE_];
Pierre Kraemer's avatar
Pierre Kraemer committed
289 290
}

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
291 292 293 294 295 296 297 298
template <typename T>
void AttributeMultiVector<T>::swapElt(unsigned int id1, unsigned int id2)
{
	T data = m_tableData[id1 / _BLOCKSIZE_][id1 % _BLOCKSIZE_] ;
	m_tableData[id1 / _BLOCKSIZE_][id1 % _BLOCKSIZE_] = m_tableData[id2 / _BLOCKSIZE_][id2 % _BLOCKSIZE_] ;
	m_tableData[id2 / _BLOCKSIZE_][id2 % _BLOCKSIZE_] = data ;
}

Pierre Kraemer's avatar
Pierre Kraemer committed
299
template <typename T>
300
void AttributeMultiVector<T>::overwrite(unsigned int src_b, unsigned int src_id, unsigned int dst_b, unsigned int dst_id)
Pierre Kraemer's avatar
Pierre Kraemer committed
301
{
302
	m_tableData[dst_b][dst_id] = m_tableData[src_b][src_id];
Pierre Kraemer's avatar
Pierre Kraemer committed
303 304
}

305 306 307 308 309

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

Pierre Kraemer's avatar
Pierre Kraemer committed
310
template <typename T>
311
void AttributeMultiVector<T>::saveBin(CGoGNostream& fs, unsigned int id)
Pierre Kraemer's avatar
Pierre Kraemer committed
312 313 314
{
	unsigned int nbs[3];
	nbs[0] = id;
315
	int len1 = m_attrName.size()+1;
Pierre Kraemer's avatar
Pierre Kraemer committed
316 317 318 319 320 321
	int len2 = m_typeName.size()+1;
	nbs[1] = len1;
	nbs[2] = len2;
	fs.write(reinterpret_cast<const char*>(nbs),3*sizeof(unsigned int));
	// store names
	char buffer[256];
322
	const char* s1 = m_attrName.c_str();
Pierre Kraemer's avatar
Pierre Kraemer committed
323 324 325 326 327 328 329 330 331 332
	memcpy(buffer,s1,len1);
	const char* s2 = m_typeName.c_str();
	memcpy(buffer+len1,s2,len2);
	fs.write(reinterpret_cast<const char*>(buffer),(len1+len2)*sizeof(char));

	nbs[0] = m_tableData.size();
	nbs[1] = nbs[0] * _BLOCKSIZE_* sizeof(T);
	fs.write(reinterpret_cast<const char*>(nbs),2*sizeof(unsigned int));

	// store data blocks
333
	for(unsigned int i=0; i<nbs[0]; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
334 335 336 337 338
	{
		fs.write(reinterpret_cast<const char*>(m_tableData[i]),_BLOCKSIZE_*sizeof(T));
	}
}

339
inline unsigned int AttributeMultiVectorGen::loadBinInfos(CGoGNistream& fs, std::string& name, std::string& type)
Pierre Kraemer's avatar
Pierre Kraemer committed
340 341 342 343 344 345 346 347 348 349 350 351
{
	unsigned int nbs[3];
	fs.read(reinterpret_cast<char*>(nbs), 3*sizeof(unsigned int));

	unsigned int id = nbs[0];
	unsigned int len1 = nbs[1];
	unsigned int len2 = nbs[2];

	char buffer[256];
	fs.read(buffer, (len1+len2)*sizeof(char));

	name = std::string(buffer);
352
	type = std::string(buffer + len1);
Pierre Kraemer's avatar
Pierre Kraemer committed
353 354 355 356 357

	return id;
}

template <typename T>
358
bool AttributeMultiVector<T>::loadBin(CGoGNistream& fs)
Pierre Kraemer's avatar
Pierre Kraemer committed
359 360 361 362 363 364 365 366
{
	unsigned int nbs[2];
	fs.read(reinterpret_cast<char*>(nbs), 2*sizeof(unsigned int));

	unsigned int nb = nbs[0];

	// load data blocks
	m_tableData.resize(nb);
367
	for(unsigned int i = 0; i < nb; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
368 369 370 371 372 373 374 375 376
	{
		T* ptr = new T[_BLOCKSIZE_];
		fs.read(reinterpret_cast<char*>(ptr),_BLOCKSIZE_*sizeof(T));
		m_tableData[i] = ptr;
	}

	return true;
}

377
inline bool AttributeMultiVectorGen::skipLoadBin(CGoGNistream& fs)
Pierre Kraemer's avatar
Pierre Kraemer committed
378 379 380 381 382 383 384 385
{
	unsigned int nbs[2];
	fs.read(reinterpret_cast<char*>(nbs), 2*sizeof(unsigned int));

	// get number of byte to skip
	unsigned int nbb = nbs[1];

	// check if nbb ok
386
	if (nbb % _BLOCKSIZE_ != 0)
Pierre Kraemer's avatar
Pierre Kraemer committed
387
	{
388
		CGoGNerr << "Error skipping wrong number of byte in attributes reading"<< CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
389 390 391 392 393
		return false;
	}

	// skip data (no seek because of pb with gzstream)
	char* ptr = new char[_BLOCKSIZE_];
394
	while (nbb != 0)
Pierre Kraemer's avatar
Pierre Kraemer committed
395 396 397 398 399 400 401 402 403 404
	{
		nbb -= _BLOCKSIZE_;
		fs.read(reinterpret_cast<char*>(ptr),_BLOCKSIZE_);
	}
	delete[] ptr;

	return true;
}

} // namespace CGoGN