attributeMultiVector.hpp 11.7 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
/*******************************************************************************
* 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                                        *
*                                                                              *
*******************************************************************************/
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):
Pierre Kraemer's avatar
Pierre Kraemer committed
29
	m_attName(strName), m_typeName(strType), m_toProcess(true)
Pierre Kraemer's avatar
Pierre Kraemer committed
30
31
{}

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

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

38
inline void AttributeMultiVectorGen::toggleProcess()
Pierre Kraemer's avatar
Pierre Kraemer committed
39
40
41
42
{
	m_toProcess = true;
}

43
inline void AttributeMultiVectorGen::toggleNoProcess()
Pierre Kraemer's avatar
Pierre Kraemer committed
44
45
46
47
{
	m_toProcess = false;
}

48
inline bool AttributeMultiVectorGen::toProcess()
Pierre Kraemer's avatar
Pierre Kraemer committed
49
50
51
52
{
	return m_toProcess;
}

53
inline unsigned int AttributeMultiVectorGen::BlockSize()
Pierre Kraemer's avatar
Pierre Kraemer committed
54
55
56
57
58
59
60
61
62
63
{
	return _BLOCKSIZE_;
}






template <typename T>
64
65
AttributeMultiVector<T>::AttributeMultiVector(const std::string& strName, const std::string& strType):
AttributeMultiVectorGen(strName,strType)
Pierre Kraemer's avatar
Pierre Kraemer committed
66
67
68
69
70
{
	m_tableData.reserve(1024);
}

template <typename T>
71
AttributeMultiVector<T>::AttributeMultiVector()
Pierre Kraemer's avatar
Pierre Kraemer committed
72
73
74
75
76
{
	m_tableData.reserve(1024);
}

template <typename T>
77
AttributeMultiVector<T>::~AttributeMultiVector()
Pierre Kraemer's avatar
Pierre Kraemer committed
78
79
80
81
82
83
{
	for (typename std::vector< T* >::iterator it = m_tableData.begin(); it != m_tableData.end(); ++it)
		delete[] (*it);
}

template <typename T>
84
AttributeMultiVectorGen* AttributeMultiVector<T>::new_obj()
Pierre Kraemer's avatar
Pierre Kraemer committed
85
{
86
	return new AttributeMultiVector<T>;
Pierre Kraemer's avatar
Pierre Kraemer committed
87
88
89
}

template <typename T>
90
bool AttributeMultiVector<T>::copy(const AttributeMultiVectorGen* atmvg)
Pierre Kraemer's avatar
Pierre Kraemer committed
91
{
92
	const AttributeMultiVector<T>* atmv = dynamic_cast<const AttributeMultiVector<T>*>(atmvg);
Pierre Kraemer's avatar
Pierre Kraemer committed
93
94
95

	if (atmv == NULL)
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
96
97
98
99
100
101
		std::cerr << "trying to copy attributes of different type" << std::endl;
		return false;
	}
	if (atmv->m_typeName != m_typeName)
	{
		std::cerr << "trying to swap attributes with different type names" << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
102
103
104
105
106
107
108
109
110
111
112
		return false;
	}

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

template <typename T>
113
bool AttributeMultiVector<T>::swap(AttributeMultiVectorGen* atmvg)
Pierre Kraemer's avatar
Pierre Kraemer committed
114
{
115
	AttributeMultiVector<T>* atmv = dynamic_cast<AttributeMultiVector<T>*>(atmvg);
Pierre Kraemer's avatar
Pierre Kraemer committed
116
117
118

	if (atmv == NULL)
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
119
		std::cerr << "trying to swap attributes of different type" << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
120
121
		return false;
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
122
	if (atmv->m_typeName != m_typeName)
Pierre Kraemer's avatar
Pierre Kraemer committed
123
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
124
		std::cerr << "trying to swap attributes with different type names" << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
125
126
127
		return false;
	}

Pierre Kraemer's avatar
Pierre Kraemer committed
128
	m_tableData.swap(atmv->m_tableData) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
129
130
131
	return true;
}

Pierre Kraemer's avatar
Pierre Kraemer committed
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
//template <typename T>
//bool AttributeMultiVector<T>::swap(AttributeMultiVectorGen& att)
//{
//	AttributeMultiVector<T>* attrib = dynamic_cast<AttributeMultiVector<T>*>(&att);
//	if (attrib==NULL)
//	{
//		std::cerr << "Erreur, swap de container de types differents"<<std::endl;
//		return false;
//	}
//	if (attrib->m_typeName != m_typeName)
//	{
//		std::cerr << "Erreur, swap de container avec noms de type differents"<<std::endl;
//		return false;
//	}
//
//	m_tableData.swap(attrib->m_tableData);
//	m_typeName.swap(attrib->m_typeName);
//
//	return true;
//}

Pierre Kraemer's avatar
Pierre Kraemer committed
153
template <typename T>
154
bool AttributeMultiVector<T>::merge(const AttributeMultiVectorGen& att)
Pierre Kraemer's avatar
Pierre Kraemer committed
155
{
156
	const AttributeMultiVector<T>* attrib = dynamic_cast< const AttributeMultiVector<T>* >(&att);
Pierre Kraemer's avatar
Pierre Kraemer committed
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
	if (attrib==NULL)
	{
		std::cerr << "Erreur, merge de container de types differents"<<std::endl;
		return false;
	}
	if (attrib->m_typeName != m_typeName)
	{
		std::cerr << "Erreur, merge de container avec noms de type differents"<<std::endl;
		return false;
	}

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

	return true;
}

template <typename T>
Pierre Kraemer's avatar
Pierre Kraemer committed
175
176
177
178
T& AttributeMultiVector<T>::operator[](unsigned int i)
{
	return m_tableData[i/_BLOCKSIZE_][i%_BLOCKSIZE_];
}
Pierre Kraemer's avatar
Pierre Kraemer committed
179
180

template <typename T>
Pierre Kraemer's avatar
Pierre Kraemer committed
181
182
183
184
const T& AttributeMultiVector<T>::operator[](unsigned int i) const
{
	return m_tableData[i/_BLOCKSIZE_][i%_BLOCKSIZE_];
}
Pierre Kraemer's avatar
Pierre Kraemer committed
185
186

template <typename T>
187
std::string AttributeMultiVector<T>::output(unsigned int i)
Pierre Kraemer's avatar
Pierre Kraemer committed
188
189
190
191
192
193
194
{
	std::stringstream ss;
	ss << m_tableData[i/_BLOCKSIZE_][i%_BLOCKSIZE_];
	return ss.str();
}

template <typename T>
195
void AttributeMultiVector<T>::input(unsigned int i,const std::string& st)
Pierre Kraemer's avatar
Pierre Kraemer committed
196
197
198
199
200
201
{
	std::stringstream ss(st);
	ss >> m_tableData[i/_BLOCKSIZE_][i%_BLOCKSIZE_];
}

template <typename T>
202
void AttributeMultiVector<T>::addBlock()
Pierre Kraemer's avatar
Pierre Kraemer committed
203
204
205
206
207
208
209
210
211
212
{
	T* ptr = new T[_BLOCKSIZE_];
	m_tableData.push_back( ptr );
	// init
//	T* endPtr = ptr + _BLOCKSIZE_;
//	while (ptr != endPtr)
//		*ptr++ = T(0);
}

template <typename T>
213
void AttributeMultiVector<T>::initElt(unsigned int id)
Pierre Kraemer's avatar
Pierre Kraemer committed
214
{
215
	m_tableData[id/_BLOCKSIZE_][id%_BLOCKSIZE_] = T(0);
Pierre Kraemer's avatar
Pierre Kraemer committed
216
217
218
}

template <typename T>
219
void AttributeMultiVector<T>::copyElt(unsigned int dst, unsigned int src)
Pierre Kraemer's avatar
Pierre Kraemer committed
220
{
221
	m_tableData[dst/_BLOCKSIZE_][dst%_BLOCKSIZE_] = m_tableData[src/_BLOCKSIZE_][src%_BLOCKSIZE_];
Pierre Kraemer's avatar
Pierre Kraemer committed
222
223
224
}

template <typename T>
225
void AttributeMultiVector<T>::setNbBlocks(unsigned int nbb)
Pierre Kraemer's avatar
Pierre Kraemer committed
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
{
	if (nbb >=m_tableData.size())
	{
		for (unsigned int i= m_tableData.size(); i <nbb; ++i)
		{
//			T* ptr = new T[_BLOCKSIZE_];
//			m_tableData.push_back( ptr );
			addBlock();
		}
	}
	else
	{
		for (unsigned int i= nbb; i <m_tableData.size(); ++i)
		{
			delete[] m_tableData[i];
		}
		m_tableData.resize(nbb);
	}
}

template <typename T>
247
void AttributeMultiVector<T>::addBlocksBefore(unsigned int nbb)
Pierre Kraemer's avatar
Pierre Kraemer committed
248
249
250
251
{
	std::vector< T* > tempo;
	tempo.reserve(1024);

252
	for (unsigned int i= 0; i <nbb; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
253
254
255
256
257
258
259
260
261
262
263
264
265
	{
		T* ptr = new T[_BLOCKSIZE_];
		tempo.push_back( ptr );
	}

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

template <typename T>
266
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
267
268
269
270
271
{
	m_tableData[dst_b][dst_id] = m_tableData[src_b][src_id];
}

template <typename T>
272
void AttributeMultiVector<T>::free()
Pierre Kraemer's avatar
Pierre Kraemer committed
273
274
275
276
277
278
279
{
	for (typename std::vector< T* >::iterator it = m_tableData.begin(); it != m_tableData.end(); ++it)
		delete[] (*it);
	m_tableData.clear();
}

template <typename T>
280
unsigned int AttributeMultiVector<T>::getStartAddresses(std::vector<void*>& addr, unsigned int& byteTableSize)
Pierre Kraemer's avatar
Pierre Kraemer committed
281
282
283
284
285
286
287
288
289
290
291
292
293
294
{
	byteTableSize = _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();
}

template <typename T>
295
void AttributeMultiVector<T>::saveBin(CGoGNostream& fs, unsigned int id)
Pierre Kraemer's avatar
Pierre Kraemer committed
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
{
	unsigned int nbs[3];
	nbs[0] = id;
	int len1 = m_attName.size()+1;
	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];
	const char* s1 = m_attName.c_str();
	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
318
	for(unsigned int i=0; i<nbs[0]; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
319
320
321
322
323
	{
		fs.write(reinterpret_cast<const char*>(m_tableData[i]),_BLOCKSIZE_*sizeof(T));
	}
}

324
inline unsigned int AttributeMultiVectorGen::loadBinInfos(CGoGNistream& fs, std::string& name, std::string& type)
Pierre Kraemer's avatar
Pierre Kraemer committed
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
{
	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);
	type = std::string(buffer+len1);

	return id;
}

template <typename T>
343
bool AttributeMultiVector<T>::loadBin(CGoGNistream& fs)
Pierre Kraemer's avatar
Pierre Kraemer committed
344
345
346
347
348
349
350
351
{
	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);
352
	for(unsigned int i=0; i<nb; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
353
354
355
356
357
358
359
360
361
	{
		T* ptr = new T[_BLOCKSIZE_];
		fs.read(reinterpret_cast<char*>(ptr),_BLOCKSIZE_*sizeof(T));
		m_tableData[i] = ptr;
	}

	return true;
}

362
inline bool AttributeMultiVectorGen::skipLoadBin(CGoGNistream& fs)
Pierre Kraemer's avatar
Pierre Kraemer committed
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
{
	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
	if (nbb%_BLOCKSIZE_ != 0)
	{
		std::cerr << "Error skipping wrong number of byte in attributes reading"<< std::endl;
		return false;
	}

	// skip data (no seek because of pb with gzstream)
	char* ptr = new char[_BLOCKSIZE_];
	while (nbb!=0)
	{
		nbb -= _BLOCKSIZE_;
		fs.read(reinterpret_cast<char*>(ptr),_BLOCKSIZE_);
	}
	delete[] ptr;

	return true;
}

template <typename T>
390
void AttributeMultiVector<T>::affect(unsigned int i, unsigned int j)
Pierre Kraemer's avatar
Pierre Kraemer committed
391
392
393
394
395
396
{
	if (m_toProcess)
		m_tableData[i/_BLOCKSIZE_][i%_BLOCKSIZE_] = m_tableData[j/_BLOCKSIZE_][j%_BLOCKSIZE_];
}

template <typename T>
397
void AttributeMultiVector<T>::add(unsigned int i, unsigned int j)
Pierre Kraemer's avatar
Pierre Kraemer committed
398
399
400
401
402
403
{
	if (m_toProcess)
		m_tableData[i/_BLOCKSIZE_][i%_BLOCKSIZE_] += m_tableData[j/_BLOCKSIZE_][j%_BLOCKSIZE_];
}

template <typename T>
404
void AttributeMultiVector<T>::sub(unsigned int i, unsigned int j)
Pierre Kraemer's avatar
Pierre Kraemer committed
405
406
407
408
409
410
{
	if (m_toProcess)
		m_tableData[i/_BLOCKSIZE_][i%_BLOCKSIZE_] -= m_tableData[j/_BLOCKSIZE_][j%_BLOCKSIZE_];
}

template <typename T>
411
void AttributeMultiVector<T>::mult(unsigned int i, double alpha)
Pierre Kraemer's avatar
Pierre Kraemer committed
412
413
414
415
416
417
{
	if (m_toProcess)
		m_tableData[i/_BLOCKSIZE_][i%_BLOCKSIZE_] *= alpha;
}

template <typename T>
418
void AttributeMultiVector<T>::div(unsigned int i, double alpha)
Pierre Kraemer's avatar
Pierre Kraemer committed
419
420
421
422
423
424
{
	if (m_toProcess)
		m_tableData[i/_BLOCKSIZE_][i%_BLOCKSIZE_] /= alpha;
}

template <typename T>
425
void AttributeMultiVector<T>::lerp(unsigned res, unsigned int i, unsigned int j, double alpha)
Pierre Kraemer's avatar
Pierre Kraemer committed
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
{
	if (m_toProcess)
	{
		T v1 = m_tableData[i/_BLOCKSIZE_][i%_BLOCKSIZE_];
		T v2 = m_tableData[j/_BLOCKSIZE_][j%_BLOCKSIZE_];

		v1 *= alpha;
		v2 *= 1.0-alpha;
		v1+=v2;
		m_tableData[res/_BLOCKSIZE_][res%_BLOCKSIZE_] = v1;

		std::cout << "LERP "<< m_tableData[i/_BLOCKSIZE_][i%_BLOCKSIZE_]<< " & " << m_tableData[j/_BLOCKSIZE_][j%_BLOCKSIZE_];
		std::cout << " = "<< m_tableData[res/_BLOCKSIZE_][res%_BLOCKSIZE_]<< std::endl;
	}
}

} // namespace CGoGN