Subversion Repositories gelsvn

Rev

Rev 67 | Blame | Compare with Previous | 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;

                /** \brief 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