Go to the documentation of this file.
11 #ifndef ATTRIBUTES_HPP
12 #define ATTRIBUTES_HPP
22 #include <QTextStream>
30 #include <tbb/concurrent_unordered_map.h>
37 #if __cplusplus >= 201103L && !__GNUC_LESS(5, 0)
38 #include <type_traits>
39 #define is_trivially_copyable std::is_trivially_copyable
41 #include <tr1/type_traits>
42 #define is_trivially_copyable std::tr1::has_trivial_copy
48 #define STD_MAP tbb::concurrent_unordered_map
50 template<
bool,
typename _Tp =
void>
53 template<
typename _Tp>
59 #define IS_POD(T) typename enable_if<is_trivially_copyable<T>::value, T>::type
77 bool readPOD(
IS_POD(T) &data,
const QByteArray &ba,
size_t &pos)
79 if(qint64(pos +
sizeof(T)) > ba.size()) {
83 memcpy(&data, ba.data() + pos,
sizeof(T));
90 bool readPODVector(
IS_POD(T) &data,
size_t n,
const QByteArray &ba,
size_t &pos)
92 if(qint64(pos +
sizeof(T) *
n) > ba.size()) {
96 memcpy(&data, ba.data() + pos,
sizeof(T) *
n);
101 inline bool readChar(
void *data,
uint sz,
const QByteArray &ba,
size_t &pos)
103 if(qint64(pos + sz) > ba.size()) {
107 memcpy(data, ba.data() + pos, sz);
114 bool writePOD(
const IS_POD(T) &data, QByteArray &ba)
116 QByteArray qba(
sizeof(T), 0);
117 memcpy(qba.data(), &data,
sizeof(T));
123 bool writePODVector(
const IS_POD(T) &data,
size_t n, QByteArray &ba)
125 QByteArray qba(
sizeof(T) *
n, 0);
126 memcpy(qba.data(), &data,
sizeof(T) *
n);
132 inline bool writeChar(
const void *data,
size_t sz, QByteArray &ba)
134 QByteArray qba(sz, 0);
135 memcpy(qba.data(), data, sz);
143 template <
typename T>
144 bool writeFile(QIODevice &file,
const T &data)
146 size_t qty = file.write((
char*)&data,
sizeof(T));
148 throw QString(
"Attributes::write:Error on write");
153 template <
typename T>
154 bool writeFile(QIODevice &file,
const std::vector<T> &data)
156 size_t sz = data.size();
158 for(
size_t i = 0; i < sz; i++)
159 writeFile(file, data[i]);
164 inline bool writeFile(QIODevice &file,
char *data,
size_t size)
166 size_t qty = file.write(data, size);
168 throw QString(
"Attributes::write:Error on write");
173 inline bool writeFileQString(QIODevice &file,
const QString &s)
175 QByteArray ba = s.toUtf8();
177 return writeFile(file, sz)
178 and writeFile(file, ba.data(), sz);
182 inline bool writeFile(QIODevice &file,
const QString &s)
184 return writeFileQString(file, s);
188 template <
typename T>
189 bool readFile(QIODevice &file, T &data)
191 size_t count = file.read((
char*)&data,
sizeof(T));
192 if(count !=
sizeof(T))
199 template <
typename T>
200 bool readFile(QIODevice &file, std::vector<T> &data)
203 bool result = readFile(file, sz);
204 data.reserve(data.size() + sz);
205 for(
size_t i = 0; i < sz; i++) {
207 result &= readFile(file, value);
208 data.push_back(value);
214 inline bool readFileQString(QIODevice &file, QString &s)
217 if(!readFile(file, sz))
219 QByteArray ba(sz, 0);
220 if(file.read(ba.data(), sz) != sz)
222 s = QString::fromUtf8(ba);
227 inline bool readFile(QIODevice &file, QString &s)
229 return readFileQString(file, s);
244 bool readAttr(T &data,
const QByteArray &ba,
size_t &pos)
246 return readPOD<T>(data, ba, pos);
249 template<
size_t n,
size_t m,
typename T>
252 for(
size_t i = 0; i <
n; ++i)
253 if(!readPODVector<T>(data[i][0], m, ba, pos))
258 template<
size_t n,
typename T>
261 return readPODVector<T>(data[0],
n, ba, pos);
267 for(
size_t i = 0; i <
n; ++i)
268 if(!readChar(&data[i][0],
sizeof(
Colorb), ba, pos))
273 template<
typename T,
typename U>
274 bool readAttr(std::pair<T,U> &data,
const QByteArray &ba,
size_t &pos)
276 bool ok =
readAttr(data.first,ba,pos);
277 if(ok) ok =
readAttr(data.second,ba,pos);
284 return readPODVector<float>(data.
ev1()[0], 9, ba, pos);
293 if(!readPOD<uint>(vId, ba, pos))
297 IntVtxMap::iterator it =
vMap->find(vId);
298 if(it !=
vMap->end())
310 uint v1Id = 0, v2Id = 0;
311 if(!readPOD<uint>(v1Id, ba, pos))
313 if(!readPOD<uint>(v2Id, ba, pos))
316 IntVtxMap::iterator it =
vMap->find(v1Id);
317 if(it !=
vMap->end())
318 pr.first = it->second;
323 it =
vMap->find(v2Id);
324 if(it !=
vMap->end())
325 pr.second = it->second;
338 uint v1Id = 0, v2Id = 0, v3Id = 0;
339 if(!readPOD<uint>(v1Id, ba, pos))
341 if(!readPOD<uint>(v2Id, ba, pos))
343 if(!readPOD<uint>(v3Id, ba, pos))
345 vertex v1(0), v2(0), v3(0);
347 IntVtxMap::iterator it =
vMap->find(v1Id);
348 if(it !=
vMap->end())
351 Information::out <<
"Vertex 1 not found reading triangle attribute" << endl;
352 it =
vMap->find(v2Id);
353 if(it !=
vMap->end())
356 Information::out <<
"Vertex 2 not found reading triangle attribute" << endl;
357 it =
vMap->find(v3Id);
358 if(it !=
vMap->end())
361 Information::out <<
"Vertex 3 not found reading triangle attribute" << endl;
369 bool inline readAttr(
cell &c,
const QByteArray &ba,
size_t &pos)
372 if(!readPOD<uint>(cId, ba, pos))
376 IntCellMap::iterator it =
cMap->find(cId);
377 if(it !=
cMap->end())
389 uint c1Id = 0, c2Id = 0;
390 if(!readPOD<uint>(c1Id, ba, pos))
392 if(!readPOD<uint>(c2Id, ba, pos))
397 IntCellMap::iterator it =
cMap->find(c1Id);
398 if(it !=
cMap->end())
399 pr.first = it->second;
402 it =
cMap->find(c2Id);
403 if(it !=
cMap->end())
404 pr.second = it->second;
413 inline bool readAttr(QString &data,
const QByteArray &ba,
size_t &pos)
419 if(!readPOD<uint>(sz, ba, pos))
423 QByteArray qba(sz, 0);
424 readChar(qba.data(), sz, ba, pos);
425 data = QString::fromUtf8(qba);
431 inline bool readAttr(QStringList &data,
const QByteArray &ba,
size_t &pos)
435 if(!readPOD<uint>(sz, ba, pos))
438 for(
uint i = 0; i < sz; i++){
446 inline bool readAttr(QByteArray &qba,
const QByteArray &ba,
size_t &pos)
450 if(!readPOD<uint>(sz, ba, pos))
455 readChar(qba.data(), sz, ba, pos);
464 if(!readChar(&color[0],
sizeof(
Colorb), ba, pos))
470 template <
typename T>
471 inline bool readAttr(std::vector<T> &data,
const QByteArray &ba,
size_t &pos)
475 if(!readPOD<uint>(
n, ba, pos))
479 for(
size_t i = 0; i <
n; ++i)
486 template <
typename KeyT,
typename ValueT>
487 inline bool readAttr(std::map<KeyT, ValueT> &data,
const QByteArray &ba,
size_t &pos)
491 if(!readPOD<uint>(
n, ba, pos))
494 for(
size_t i = 0; i <
n; ++i) {
512 return writePOD<T>(data, ba);
515 template<
size_t n,
size_t m,
typename T>
518 for(
size_t i = 0; i <
n; ++i)
519 if(!writePODVector<T>(data[i][0], m, ba))
524 template<
size_t n,
typename T>
527 return writePODVector<T>(data[0],
n, ba);
533 for(
size_t i = 0; i <
n; ++i)
534 if(!writeChar(&data[i][0],
sizeof(
Colorb), ba))
539 template<
typename T,
typename U>
540 bool writeAttr(
const std::pair<T,U> &data, QByteArray &ba)
550 return writePODVector<float>(data.
ev1()[0], 9, ba);
562 return writePOD<uint>(v->saveId, ba);
576 return writePOD<uint>(t.
v[0]->saveId, ba)
577 and writePOD<uint>(t.
v[1]->saveId, ba)
578 and writePOD<uint>(t.
v[2]->saveId, ba);
590 return writePOD<uint>(c->saveId, ba);
604 QByteArray qba = s.toUtf8();
605 uint sz = qba.size();
606 return writeChar((
char *)&sz,
sizeof(
uint), ba)
607 and writeChar((
char *)qba.data(), sz, ba);
612 inline bool writeAttr(
const QStringList &s, QByteArray &ba)
615 for(
int i = 0; i < s.size(); i++){
623 inline bool writeAttr(
const QByteArray &qba, QByteArray &ba)
625 uint sz = qba.size();
626 return writeChar((
char *)&sz,
sizeof(
uint), ba)
627 and writeChar((
char *)qba.data(), sz, ba);
634 if(!writeChar(&color[0],
sizeof(
Colorb), ba))
640 template <
typename T>
641 bool writeAttr(
const std::vector<T> &data, QByteArray &ba)
643 uint n = data.size();
647 for(
size_t i = 0; i <
n; ++i)
654 template <
typename KeyT,
typename ValueT>
655 bool writeAttr(
const std::map<KeyT, ValueT> &data, QByteArray &ba)
657 uint n = data.size();
661 for(
typename std::map<KeyT, ValueT>::const_iterator i = data.begin(); i != data.end(); ++i) {
685 template<
typename KeyT,
typename ValueT>
689 typedef std::pair<KeyT, ValueT>
pair;
690 typedef typename STD_MAP<KeyT, ValueT>::iterator
iterator;
696 omp_init_lock(&_lock);
700 omp_init_lock(&_lock);
704 template<
typename IterT>
707 _map.insert(first, last);
708 omp_init_lock(&_lock);
714 omp_init_lock(&_lock);
721 _defaultVal = a._defaultVal;
759 const ValueT &
at(
const KeyT &key)
const
802 size_t size()
const {
return _map.size(); }
803 bool empty()
const {
return _map.empty(); }
804 size_t count (
const KeyT &key)
const {
return _map.count(key); }
814 size_t erase(
const KeyT &key) {
return _map.unsafe_erase(key); }
818 template<
typename IterT>
819 void insert(IterT first, IterT last) { _map.insert(first, last); }
822 STD_MAP<KeyT, ValueT, std::hash<KeyT> > _map;
931 AttributeBase(
const QString &name) : _name(name)
939 virtual ~AttributeBase()
947 const QString &name() {
return _name; }
952 virtual bool write(QByteArray &) {
return true; }
957 virtual void clear() {}
962 virtual size_t size() = 0;
976 template <
typename KeyT,
typename ValueT>
977 class Attribute :
public AttributeBase
984 Attribute(
const QString &name,
const ValueT &defaultVal = ValueT())
985 : AttributeBase(name), _map(defaultVal) {}
1002 bool write(QByteArray &ba)
1009 if(i->second == _map.defaultVal())
1020 if(i->second == _map.defaultVal())
1044 bool read(QByteArray &ba)
1054 #pragma GCC diagnostic push
1055 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
1057 for(
size_t i = 0; i < count; ++i) {
1069 _map.defaultVal() = value;
1070 #pragma GCC diagnostic pop
1086 virtual size_t size() {
return _map.size(); }
1098 Attributes() : _attributes(0), _saveRequired(true), _vMapAttr(0), _cMapAttr(0)
1100 omp_init_lock(&_lock);
1115 template <
typename KeyT,
typename ValueT>
1118 Attribute<KeyT, ValueT> *a =
dynamic_cast<Attribute<KeyT, ValueT> *
>(_attributes[name]);
1122 if(_attributes[name]) {
1123 Information::out <<
"Warning, changing type for attribute: " << name << endl;
1124 delete _attributes[name];
1126 a =
new Attribute<KeyT, ValueT>(name);
1127 _attributes[name] = a;
1130 if(_ba[name].size() > 0) {
1134 if(!a->read(_ba[name])) {
1136 Information::out <<
"Read error for attribute: " << name <<
", clearing" << endl;
1138 Information::out <<
"Loaded attribute: " << name <<
", Size:" << a->map().size() << endl;
1142 _saveRequired[name] =
true;
1150 template <
typename KeyT,
typename ValueT>
1153 const AttributeBase *attrbase = _attributes[name];
1154 const Attribute<KeyT, ValueT> *a =
dynamic_cast<const Attribute<KeyT, ValueT> *
>(attrbase);
1167 return _saveRequired[name];
1171 return _saveRequired[name] = saveReq;
1180 AttributeBase *a = _attributes[name];
1183 _attributes.erase(name);
1194 for(STD_MAP<QString, AttributeBase*>::iterator
1195 a = _attributes.begin(); a != _attributes.end(); ) {
1200 if(saveIt != _saveRequired.
end())
1201 _saveRequired.erase(saveIt);
1203 if(baIt != _ba.
end())
1207 _attributes.erase(a++);
1226 typedef std::pair<QString, bool> QStringBoolPair;
1228 forall(
const QStringBoolPair &i, _attributes)
1229 if(_saveRequired[i.first])
1231 writeFile(file, count);
1234 qint64 attrPos = file.pos();
1235 file.seek(attrPos + (count + 1) *
sizeof(
size_t));
1240 typedef std::pair<QString, AttributeBase*> QStringAttrBasePr;
1241 forall(
const QStringAttrBasePr &i, _attributes) {
1242 QString name = i.first;
1243 if(!_saveRequired[name])
1247 qint64 currentPos = file.pos();
1249 writeFile(file,
size_t(currentPos));
1250 attrPos = file.pos();
1251 file.seek(currentPos);
1253 AttributeBase* ab = i.second;
1258 writeFile(file, name);
1261 if(_ba[name].size() == 0) {
1264 file.write((
char *)ba.data(),ba.size());
1267 file.write((
char *)_ba[name].data(),_ba[name].size());
1274 qint64 currentPos = file.pos();
1276 writeFile(file,
size_t(currentPos));
1277 file.seek(currentPos);
1287 bool read(QIODevice &file,
bool clearAttr =
true)
1295 readFile(file, count);
1298 std::vector<size_t> attrPos;
1299 for(
size_t i = 0; i <= count; ++i) {
1301 readFile(file, pos);
1302 attrPos.push_back(pos);
1308 for(
size_t i = 0; i < count; ++i) {
1310 file.seek(attrPos[i]);
1314 readFile(file, name);
1319 if(_attributes[name]) {
1320 delete _attributes[name];
1321 _attributes[name] = 0;
1325 size_t sz = attrPos[i+1] - attrPos[i];
1326 QByteArray ba(sz, 0);
1327 file.read(ba.data(), sz);
1329 _saveRequired[name] =
true;
1330 if(qint64(sz) != _ba[name].size())
1332 "Warning, chars read (%1) doesn't match file size (%2) for attribute: %3")
1333 .arg(_ba[name].size()).arg(sz).arg(name) << endl;
1339 file.seek(attrPos[count]);
1352 if(!read(file, clearAttr))
1354 saveVtxCellMaps(
vMap,
cMap, clearAttr);
1368 if(
vMap and _vMapAttr and clearAttr) {
1372 if(
cMap and _cMapAttr and clearAttr) {
1376 if(
vMap and !_vMapAttr)
1378 if(
cMap and !_cMapAttr)
1392 if(_name.size() != 0 and _attributes.find(_name) != _attributes.end()){
1393 if(_attributes[_name] != 0)
1394 return _attributes[_name]->size();
1404 QStringList attrList;
1409 if(_ba.find(i->first) != _ba.end())
1410 attrList << i->first;
1420 QStringList attrList;
1424 if(_ba.find(i->first) != _ba.end() and _attributes.find(i->first) != _attributes.end()){
1425 if(_ba[i->first].size() == 0 and _attributes[i->first]->size() > 0)
1426 attrList <<i->first;
1447 template<
typename KeyT,
typename ValueT>
1452 template<
typename KeyT,
typename ValueT>
1459 template<
typename ValueT>
1464 template<
typename ValueT>
1470 template<
typename ValueT>
1475 template<
typename ValueT>
QStringList clearNotparsedAttrList() const
Return a list of unparsed attribute names.
AttrMap< edge, float > EdgeFloatAttr
AttrMap< wall, Point2f > WallPoint2fAttr
AttrMap< vertex, Vec3Colorb > VtxVec3ColorbAttr
std::pair< KeyT, ValueT > pair
const ValueT & operator[](const KeyT &key) const
const Accessor
vvGraph::vertex_t vertex
Type of a vertex.
AttrMap< QString, SymmetricTensor > QStringSymTensorAttr
AttrMap(const ValueT &defaultVal)
Holds a set of attributes.
AttrMap< IntIntPair, Point3f > IntIntPoint3fAttr
AttrMap< wall, QString > WallQStringAttr
AttrMap< edge, Vec2Colorb > EdgeVec2ColorbAttr
identity_t target() const
Returns the identifier of the target of the edge.
ValueT & defaulVal()
The default value.
AttrMap< cell, Matrix3f > CellMatrix3fAttr
AttrMap< vertex, float > VtxFloatAttr
size_t erase(const KeyT &key)
bool saveRequired(const QString &name) const
Get a reference to the attribute's save status, it will be created if it doesn't exist.
identity_t source() const
Returns the identifier of the source of the edge.
void progressSetMsg(const std::string &msg)
Vector< 3, Colorb > Vec3Colorb
AttrMap< QString, Vec3Colorb > QStringVec3ColorbAttr
ValueT & operator->*(const KeyT &key, AttrMap< KeyT, ValueT > &map)
void insert(IterT first, IterT last)
#define IS_POD(T)
Determines if template arguments are plain old data (POD) types.
AttrMap< vertex, Point3f > VtxPoint3fAttr
AttrMap & operator=(const AttrMap &a)
void erase(iterator first, iterator last)
AttrMap< edge, Vec3Colorb > EdgeVec3ColorbAttr
AttrMap< IntIntPair, float > IntIntFloatAttr
AttrMap< edge, QString > EdgeQStringAttr
AttrMap< Triangle, SymmetricTensor > TriSymTensorAttr
AttrMap< cell, int > CellIntAttr
Vector< 2, Colorb > Vec2Colorb
AttrMap< cell, SymmetricTensor > CellSymTensorAttr
AttrMap< Triangle, Point3f > TriPoint3fAttr
AttrMap< cell, Colorb > CellColorbAttr
AttrMap< edge, Matrix3f > EdgeMatrix3fAttr
AttrMap< vertex, QString > VtxQStringAttr
const_iterator begin() const
std::unordered_map< int, vertex > IntVtxMap
Int to vertex map.
std::pair< vertex, vertex > VtxVtxPair
AttrMap(const AttrMap &a)
bool write(QIODevice &file)
Write the attributes to a file.
STD_MAP< KeyT, ValueT >::const_iterator const_iterator
AttrMap< int, int > IntIntAttr
AttrMap< int, Vec2Colorb > IntVec2ColorbAttr
bool read(QIODevice &file, bool clearAttr=true)
Read the attributes from a file.
bool isNull() const
Test if a vertex is a null vertex.
AttrMap< vertex, Vec2Colorb > VtxVec2ColorbAttr
AttrMap< vertex, Colorb > VtxColorbAttr
AttrMap< cell, bool > CellBoolAttr
Distributed matrix library.
AttrMap< QString, Matrix3f > QStringMatrix3fAttr
AttrMap< Triangle, QString > TriQStringAttr
AttrMap< cell, float > CellFloatAttr
AttrMap< edge, Point3f > EdgePoint3fAttr
AttrMap< edge, Colorb > EdgeColorbAttr
AttrMap< vertex, Point2f > VtxPoint2fAttr
std::pair< cell, cell > CellCellPair
const ValueT & at(const KeyT &key) const
Counterpart to map::at(), which returns reference to default value if key is not found.
AttrMap< wall, SymmetricTensor > WallSymTensorAttr
const AttrMap< KeyT, ValueT > * getAttrMap(const QString &name) const
Try to get a constant pointer to an attribute.
mgx_EXPORT IntVtxMap * vMap
Maps for saveId for vertices and cells, created when file is read Globals required for overloads of r...
AttrMap< wall, Vec3Colorb > WallVec3ColorbAttr
AttrMap< vertex, int > VtxIntAttr
mgx_EXPORT IntCellMap * cMap
AttrMap< Triangle, Vec3Colorb > TriVec3ColorbAttr
AttrMap< Triangle, Vec2Colorb > TriVec2ColorbAttr
AttrMap< wall, Matrix3f > WallMatrix3fAttr
AttrMap< cell, Point3f > CellPoint3fAttr
iterator find(const KeyT &key)
bool saveVtxCellMaps(IntVtxMap *vMap, IntCellMap *cMap, bool clearAttr)
Set the saveId-vertex map for loading vertex and Index attributes Since the readAttr and writeAttr ar...
AttrMap< vertex, bool > VtxBoolAttr
AttrMap< edge, Point2f > EdgePoint2fAttr
T CU_HOST_DEVICE max(const T a, const T b)
virtual ~Attributes()
Destructor.
AttrMap< cell, QString > CellQStringAttr
AttrMap< QString, Point3f > QStringPoint3fAttr
AttrMap< Triangle, bool > TriBoolAttr
AttrMap< KeyT, ValueT > & attrMap(const QString &name, bool saveRequired=true)
Get the attribute, if it does not exist create it and add to the set If it exists,...
AttrMap< wall, bool > WallBoolAttr
AttrMap< cell, Point2f > CellPoint2fAttr
AttrMap< QString, QString > QStringQStringAttr
AttrMap< int, QString > IntQStringAttr
AttrMap< QString, Colorb > QStringColorbAttr
virtual size_t size(QString _name)
AttrMap< edge, bool > EdgeBoolAttr
AttrMap< vertex, Matrix3f > VtxMatrix3fAttr
class Triangle Triangle.hpp <Triangle.hpp>
void clear()
Clear the attributes.
AttrMap< wall, float > WallFloatAttr
const ValueT & defaultVal() const
Get a reference to the default value.
cellGraph::vertex_t cell
Type of a vertex.
AttrMap< int, Matrix3f > IntMatrix3fAttr
AttrMap< QString, Vec2Colorb > QStringVec2ColorbAttr
AttrMap< QString, int > QStringIntAttr
ValueT & operator[](const KeyT &key)
Accessor.
QStringList getAttrList() const
Return a list of attribute names.
AttrMap< int, SymmetricTensor > IntSymTensorAttr
Namespace containing all the utility classes.
AttrMap< Triangle, int > TriIntAttr
AttrMap< wall, Point3f > WallPoint3fAttr
const_iterator find(const KeyT &key) const
bool read(QIODevice &file, IntVtxMap *vMap, IntCellMap *cMap, bool clearAttr=true)
Read the attributes from a file.
AttrMap< wall, Colorb > WallColorbAttr
AttrMap< edge, int > EdgeIntAttr
AttrMap< wall, int > WallIntAttr
AttrMap< Triangle, Matrix3f > TriMatrix3fAttr
std::unordered_map< int, cell > IntCellMap
Int to cell map.
AttrMap< int, float > IntFloatAttr
A utility class to encapsulate color data.
bool writeAttr(const T &data, QByteArray &ba)
Write the attribute value from a QByteArray.
bool setSaveRequired(const QString &name, bool saveReq)
STD_MAP< KeyT, ValueT >::iterator iterator
const_iterator end() const
const ValueT & defaulVal() const
void erase(const QString &name)
Erase an attribute.
AttrMap< QString, float > QStringFloatAttr
AttrMap< wall, Vec2Colorb > WallVec2ColorbAttr
AttrMap< edge, SymmetricTensor > EdgeSymTensorAttr
AttrMap< Triangle, Point2f > TriPoint2fAttr
AttrMap< int, Vec3Colorb > IntVec3ColorbAttr
bool readAttr(T &data, const QByteArray &ba, size_t &pos)
Read the attribute value from a QByteArray.
AttrMap< int, Point3f > IntPoint3fAttr
AttrMap< Triangle, float > TriFloatAttr
size_t count(const KeyT &key) const
AttrMap< cell, Vec2Colorb > CellVec2ColorbAttr
AttrMap< cell, Vec3Colorb > CellVec3ColorbAttr
AttrMap< int, Colorb > IntColorbAttr
AttrMap(IterT first, IterT last, const ValueT &defaultVal=ValueT())
Attribute map wraps std::map.
AttrMap< Triangle, Colorb > TriColorbAttr
AttrMap< vertex, SymmetricTensor > VtxSymTensorAttr
CU_HOST_DEVICE Vector< dim, T > map(const T &(*fct)(const T1 &), const Vector< dim, T1 > &v)