attributeContainer.hpp 9.51 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 33 34 35 36 37
#include <cassert>
#include "Container/registered.h"
#include "Utils/nameTypes.h"

namespace CGoGN
{

///////////////////////////
// GESTION DES ATTRIBUTS
///////////////////////////

template <typename T>
38
unsigned int AttributeContainer::addAttribute(const std::string& attribName)
Pierre Kraemer's avatar
Pierre Kraemer committed
39 40 41 42 43 44 45 46 47 48 49 50
{
	std::string nametype = nameOfType(T());

	// first check if attribute already exist
	if (attribName != "")
	{
		MapNameId::iterator it = m_attribNameMap.find(attribName);
		if (it != m_attribNameMap.end())
			return UNKNOWN;
	}

	// new attribut
Pierre Kraemer's avatar
Pierre Kraemer committed
51 52 53 54 55 56 57 58 59 60 61 62 63 64
	AttributeMultiVector<T>* amv = new AttributeMultiVector<T>(attribName, nametype);

	unsigned int idxAttrib ;
	if(!m_freeIndices.empty())
	{
		idxAttrib = m_freeIndices.back() ;
		m_freeIndices.pop_back() ;
		m_tableAttribs[idxAttrib] = amv ;
	}
	else
	{
		idxAttrib = m_tableAttribs.size();
		m_tableAttribs.push_back(amv);
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
65 66 67 68 69

	// add it in the map 
	if (attribName == "") // if no name, generate a fake name
	{
		std::stringstream ss;
70
		ss << "unknown" << m_nbUnknown++;
Pierre Kraemer's avatar
Pierre Kraemer committed
71
		m_attribNameMap.insert(std::pair<std::string, unsigned int>(ss.str(), idxAttrib));
Pierre Kraemer's avatar
Pierre Kraemer committed
72
		amv->setName(ss.str());
Pierre Kraemer's avatar
Pierre Kraemer committed
73 74 75 76 77 78 79 80 81
	}
	else
		m_attribNameMap.insert(std::pair<std::string, unsigned int>(attribName, idxAttrib));

	// maj taille d'une ligne
	m_lineCost += sizeof(T);
	
	// resize the new attribute container to have same size than others
	int nbb = m_holesBlocks.size();
Pierre Kraemer's avatar
Pierre Kraemer committed
82
	amv->setNbBlocks(nbb);
Pierre Kraemer's avatar
Pierre Kraemer committed
83 84 85 86 87 88 89

	m_nbAttributes++;

	return idxAttrib;
}

template <typename T>
90
unsigned int AttributeContainer::addAttribute(const std::string& attribName, const std::string& nametype, unsigned int idxAttrib)
Pierre Kraemer's avatar
Pierre Kraemer committed
91 92 93 94 95 96 97 98 99 100
{
	// first check if attribute already exist
	if (attribName != "")
	{
		MapNameId::iterator it = m_attribNameMap.find(attribName);
		if (it != m_attribNameMap.end())
			return UNKNOWN;
	}

	// new attribut
Pierre Kraemer's avatar
Pierre Kraemer committed
101
	AttributeMultiVector<T>* amv = new AttributeMultiVector<T>(attribName, nametype);
Pierre Kraemer's avatar
Pierre Kraemer committed
102
	// add it to table of attribut_manager
Pierre Kraemer's avatar
Pierre Kraemer committed
103
	m_tableAttribs[idxAttrib] = amv;
Pierre Kraemer's avatar
Pierre Kraemer committed
104
	// add it in the map
Pierre Kraemer's avatar
Pierre Kraemer committed
105 106 107 108 109 110 111 112 113
	if (attribName == "") // if no name, generate a fake name
	{
		std::stringstream ss;
		ss << "unknown" << m_nbUnknown++;
		m_attribNameMap.insert(std::pair<std::string, unsigned int>(ss.str(), idxAttrib));
		amv->setName(ss.str());
	}
	else
		m_attribNameMap.insert(std::pair<std::string, unsigned int>(attribName, idxAttrib));
Pierre Kraemer's avatar
Pierre Kraemer committed
114 115 116 117 118 119

	// maj taille d'une ligne
	m_lineCost += sizeof(T);

	// resize the new attribute container to have same size than others
	int nbb = m_holesBlocks.size();
Pierre Kraemer's avatar
Pierre Kraemer committed
120
	amv->setNbBlocks(nbb);
Pierre Kraemer's avatar
Pierre Kraemer committed
121 122 123 124 125 126

	m_nbAttributes++;

	return idxAttrib;
}

127
inline unsigned int AttributeContainer::getNbAttributes()
Pierre Kraemer's avatar
Pierre Kraemer committed
128
{
Pierre Kraemer's avatar
Pierre Kraemer committed
129
	return m_nbAttributes;
Pierre Kraemer's avatar
Pierre Kraemer committed
130 131
}

Pierre Kraemer's avatar
Pierre Kraemer committed
132 133 134 135 136
///////////////////////////
// ACCES AUX DONNEES
///////////////////////////

template <typename T>
137
T& AttributeContainer::getData(unsigned int codeAttrib, unsigned int eltIdx)
Pierre Kraemer's avatar
Pierre Kraemer committed
138
{
Pierre Kraemer's avatar
Pierre Kraemer committed
139 140 141
	assert(eltIdx < m_maxSize || !"Attribut non existant (indice trop grand)");
	assert(m_holesBlocks[eltIdx/_BLOCKSIZE_]->used(eltIdx%_BLOCKSIZE_) || !"Attribut non existant");
	assert((m_tableAttribs[codeAttrib] != NULL) || !"Attribut detruit");
Pierre Kraemer's avatar
Pierre Kraemer committed
142

143
	AttributeMultiVector<T>* atm = dynamic_cast< AttributeMultiVector<T>* >(m_tableAttribs[codeAttrib]);
Pierre Kraemer's avatar
Pierre Kraemer committed
144
	assert((atm != NULL) || !"type attribut non concordant");
Pierre Kraemer's avatar
Pierre Kraemer committed
145 146 147 148 149

	return atm->operator[](eltIdx);
}

template <typename T>
150
const T& AttributeContainer::getData(unsigned int codeAttrib, unsigned int eltIdx) const
Pierre Kraemer's avatar
Pierre Kraemer committed
151
{
Pierre Kraemer's avatar
Pierre Kraemer committed
152 153 154
	assert(eltIdx < m_maxSize || !"Attribut non existant (indice trop grand)");
	assert(m_holesBlocks[eltIdx/_BLOCKSIZE_]->used(eltIdx%_BLOCKSIZE_) || !"Attribut non existant");
	assert((m_tableAttribs[codeAttrib] != NULL) || !"Attribut detruit");
Pierre Kraemer's avatar
Pierre Kraemer committed
155

156
	AttributeMultiVector<T>* atm = dynamic_cast< AttributeMultiVector<T>* >(m_tableAttribs[codeAttrib]);
Pierre Kraemer's avatar
Pierre Kraemer committed
157
	assert((atm != NULL) || !"type attribut non concordant");
Pierre Kraemer's avatar
Pierre Kraemer committed
158 159 160 161 162

	return atm->operator[](eltIdx);
}

template <typename T>
163
void AttributeContainer::setData(unsigned int codeAttrib, unsigned int eltIdx,  const T& data)
Pierre Kraemer's avatar
Pierre Kraemer committed
164
{
Pierre Kraemer's avatar
Pierre Kraemer committed
165 166 167
	assert(eltIdx < m_maxSize || !"Attribut non existant (indice trop grand)");
	assert(m_holesBlocks[eltIdx/_BLOCKSIZE_]->used(eltIdx%_BLOCKSIZE_) || !"Attribut non existant");
	assert((m_tableAttribs[codeAttrib] != NULL) || !"Attribut detruit");
Pierre Kraemer's avatar
Pierre Kraemer committed
168

169
	AttributeMultiVector<T>* atm = dynamic_cast< AttributeMultiVector<T>* >(m_tableAttribs[codeAttrib]);
Pierre Kraemer's avatar
Pierre Kraemer committed
170
	assert((atm != NULL) || !"type attribut non concordant");
Pierre Kraemer's avatar
Pierre Kraemer committed
171 172 173 174 175

	atm->operator[](eltIdx) = data;
}

//template <typename T>
176
//unsigned int AttributeContainer::insertLineWidthData(unsigned int codeAttrib,const T& data)
Pierre Kraemer's avatar
Pierre Kraemer committed
177 178 179 180 181 182 183
//{
//	unsigned int it =  insertLine();
//	setData<T>(codeAttrib, it, data);
//	return it;
//}

template<typename T>
184
AttributeMultiVector<T>& AttributeContainer::getDataVector(unsigned int codeAttrib)
Pierre Kraemer's avatar
Pierre Kraemer committed
185
{
Pierre Kraemer's avatar
Pierre Kraemer committed
186 187
	assert((codeAttrib < m_tableAttribs.size()) || !"Attribut inexistant");
	assert((m_tableAttribs[codeAttrib] != NULL) || !"Attribut detruit");
Pierre Kraemer's avatar
Pierre Kraemer committed
188

189
	AttributeMultiVector<T>* atm = dynamic_cast< AttributeMultiVector<T>* >(m_tableAttribs[codeAttrib]);
Pierre Kraemer's avatar
Pierre Kraemer committed
190
	assert((atm != NULL) || !"type attribut non concordant");
Pierre Kraemer's avatar
Pierre Kraemer committed
191 192 193
	return *atm;
}

Pierre Kraemer's avatar
Pierre Kraemer committed
194
template<typename T>
195
bool AttributeContainer::getAttributesVector(const std::string& attribName, AttributeMultiVector<T>** ptr)
Pierre Kraemer's avatar
Pierre Kraemer committed
196 197 198 199 200 201 202
{
	MapNameId::iterator it = m_attribNameMap.find(attribName);
	if (it == m_attribNameMap.end())
		return false;
	
	int codeAttrib = it->second;

Pierre Kraemer's avatar
Pierre Kraemer committed
203
	if (m_tableAttribs[codeAttrib] == NULL)
Pierre Kraemer's avatar
Pierre Kraemer committed
204 205
		return false;

206
	AttributeMultiVector<T>* atm = dynamic_cast< AttributeMultiVector<T>* >(m_tableAttribs[codeAttrib]);
Pierre Kraemer's avatar
Pierre Kraemer committed
207
	if (atm == NULL)
Pierre Kraemer's avatar
Pierre Kraemer committed
208 209 210 211 212 213 214 215 216 217 218
		return false;

	*ptr = atm;
	return true;
}

///////////////////////////
//  ADRESSES MEMOIRES
///////////////////////////

template <typename T>
219
unsigned int AttributeContainer::getAddresses(unsigned int attr, std::vector<T*>& vect_adr)
Pierre Kraemer's avatar
Pierre Kraemer committed
220
{
221
	AttributeMultiVector<T>* atm = dynamic_cast< AttributeMultiVector<T>* >(m_tableAttribs[attr]);
Pierre Kraemer's avatar
Pierre Kraemer committed
222
	assert((atm != NULL) || !"type attribut non concordant");
Pierre Kraemer's avatar
Pierre Kraemer committed
223 224 225 226 227 228 229 230
	return atm->getStartAddresses(vect_adr);
}

//////////////////////////////
//  Enregistrement attributs
//////////////////////////////

//// INLINED FUNCTIONS
231
inline bool AttributeContainer::used(unsigned int eltIdx) const
Pierre Kraemer's avatar
Pierre Kraemer committed
232 233 234 235
{
	return m_holesBlocks[ eltIdx / _BLOCKSIZE_ ]->used( eltIdx % _BLOCKSIZE_ );
}

236
inline void AttributeContainer::setRegistry(std::map< std::string, RegisteredBaseAttribute* >* re)
Pierre Kraemer's avatar
Pierre Kraemer committed
237 238 239 240
{
	m_attributes_registry_map = re;
}

241
inline bool AttributeContainer::copyAttribute(unsigned int index_dst, unsigned int index_src)
Pierre Kraemer's avatar
Pierre Kraemer committed
242 243 244 245
{
	return m_tableAttribs[index_dst]->copy(m_tableAttribs[index_src]);
}

246
inline bool AttributeContainer::swapAttributes(unsigned int index1, unsigned int index2)
Pierre Kraemer's avatar
Pierre Kraemer committed
247 248 249 250
{
	return m_tableAttribs[index1]->swap(m_tableAttribs[index2]);
}

251
inline void AttributeContainer::refLine(unsigned int eltIdx)
Pierre Kraemer's avatar
Pierre Kraemer committed
252 253 254 255
{
	m_holesBlocks[eltIdx / _BLOCKSIZE_]->ref(eltIdx % _BLOCKSIZE_);
}

256
inline bool AttributeContainer::unrefLine(unsigned int eltIdx)
Pierre Kraemer's avatar
Pierre Kraemer committed
257
{
258 259 260 261 262 263
	if (m_holesBlocks[eltIdx / _BLOCKSIZE_]->unref(eltIdx % _BLOCKSIZE_))
	{
		m_size--;
		return true;
	}
	return false;
Pierre Kraemer's avatar
Pierre Kraemer committed
264 265
}

266
inline void AttributeContainer::setRefLine(unsigned int eltIdx, unsigned int nb)
Pierre Kraemer's avatar
Pierre Kraemer committed
267 268 269 270
{
	m_holesBlocks[ eltIdx / _BLOCKSIZE_]->setNbRefs(eltIdx % _BLOCKSIZE_,nb);
}

271
inline AttributeMultiVectorGen& AttributeContainer::getVirtualDataVector(unsigned int codeAttrib)
Pierre Kraemer's avatar
Pierre Kraemer committed
272 273 274 275
{
	return *(m_tableAttribs[indexAttr(codeAttrib)]);
}

276
inline unsigned int AttributeContainer::end() const
Pierre Kraemer's avatar
Pierre Kraemer committed
277 278 279 280
{
	return m_maxSize;
}

281
inline unsigned int AttributeContainer::begin() const
Pierre Kraemer's avatar
Pierre Kraemer committed
282 283 284 285 286 287 288
{
	unsigned int it = 0;
	while ((it < m_maxSize) && (!used(it)))
		++it;
	return it;
}

289
inline void AttributeContainer::next(unsigned int &it) const
Pierre Kraemer's avatar
Pierre Kraemer committed
290 291 292 293 294 295 296
{
	do
	{
		++it;
	} while ((it < m_maxSize) && (!used(it)));
}

297
inline void AttributeContainer::toggleProcess(unsigned int id)
Pierre Kraemer's avatar
Pierre Kraemer committed
298 299 300 301
{
	m_tableAttribs[indexAttr(id)]->toggleProcess();
}

302
inline void AttributeContainer::toggleNoProcess(unsigned int id)
Pierre Kraemer's avatar
Pierre Kraemer committed
303 304 305 306 307
{
	m_tableAttribs[indexAttr(id)]->toggleNoProcess();
}

} // namespace CGoGN