Blame | Last modification | View Log | RSS feed
#ifndef __IMESH_ATTRVEC_H__
#define __IMESH_ATTRVEC_H__
#include <string>
#include <vector>
#include "CGLA/Vec4f.h"
#include "CGLA/Vec3f.h"
#include "CGLA/Vec3i.h"
namespace IMesh
{
typedef std::vector<CGLA::Vec3i> FaceSet;
class AttrVecIf
{
const std::string name;
public:
AttrVecIf::AttrVecIf(const std::string& _name): name(_name) {}
virtual ~AttrVecIf() {}
const std::string& get_name() const {return name;}
virtual int size() const = 0;
virtual void resize(int n) = 0;
virtual AttrVecIf* clone() const = 0;
};
template<class ATTR>
class AttrVec: public AttrVecIf
{
std::vector<ATTR> attributes;
public:
AttrVec(const std::string& name): AttrVecIf(name) {}
ATTR& get(int i)
{
assert(i<attributes.size());
return attributes[i];
}
const ATTR& get(int i) const
{
assert(i<attributes.size());
return attributes[i];
}
void push_back(const ATTR& attr)
{
attributes.push_back(attr);
}
int size() const
{
return attributes.size();
}
void resize(int n)
{
attributes.resize(n);
}
virtual AttrVecIf* clone() const
{
AttrVec<ATTR>* twin = new AttrVec<ATTR>(get_name());
twin->attributes = attributes;
return twin;
}
};
template<class ATTR>
inline ATTR& attr(AttrVecIf& avec, int i)
{
//#ifdef NDEBUG
return static_cast<AttrVec<ATTR>&>(avec).get(i);
//#else
// return dynamic_cast<AttrVec<ATTR>&>(avec).get(i);
//#endif
}
template<class ATTR>
const ATTR& attr(const AttrVecIf& avec, int i)
{
//#ifdef NDEBUG
return static_cast<const AttrVec<ATTR>&>(avec).get(i);
//#else
// return dynamic_cast<const AttrVec<ATTR>&>(avec).get(i);
//#endif
}
template<class ATTR>
void push_back_attr(AttrVecIf& avec, const ATTR& attr)
{
//#ifdef NDEBUG
static_cast<AttrVec<ATTR>&>(avec).push_back(attr);
//#else
// dynamic_cast<AttrVec<ATTR>&>(avec).push_back(attr);
//#endif
}
class TriMeshData;
class TriMeshBuilder;
/** Attribute vector handle. This is simply an index into a vector
of attribute vectors. The only data in this struct is an integer
contain the index, but the class is a template, hence the handle
also carries the type information.
The idea of using a handle class which carries both the attribute
type and the index of the attribute vector was fostered because
VC 6.0 has a completely brain dead implementation of class member
template functions. It is necessary to let the template argument
be deduced from the normal function arguments, the template argument
cannot be supplied explicitly. However, this solution is actually
quite nice. */
template<class ATTR>
class AttrHandle
{
friend class TriMeshData;
friend class TriMeshBuilder;
int idx;
AttrHandle(int _idx): idx(_idx) {}
public:
AttrHandle(): idx(-1) {}
AttrHandle(const AttrHandle& a): idx(a.idx) {}
const AttrHandle& operator=(const AttrHandle& ah)
{
idx = ah.idx;
}
int get_idx() const {return idx;}
};
}
#endif