Subversion Repositories gelsvn

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
667 khor 1
/* ----------------------------------------------------------------------- *
2
 * This file is part of GEL, http://www.imm.dtu.dk/GEL
3
 * Copyright (C) the authors and DTU Informatics
4
 * For license and list of authors, see ../../doc/intro.pdf
5
 * ----------------------------------------------------------------------- */
6
 
7
/**
8
  @file AttributeVector.h
9
 Contains an abstract class template for attribute vectors for HMesh entities. 
10
 Also contains templates for attribute vectors for concrete entities.
11
 */
12
 
13
#ifndef __HMESH_ATTRIBUTEVECTOR_H__
14
#define __HMESH_ATTRIBUTEVECTOR_H__
15
 
16
#include <cassert>
17
#include <vector>
18
#include <map>
19
 
20
namespace HMesh 
21
{
22
    /** Abstract class for HMesh entity attribute vectors. This class is used for storing all attributes
23
     associated with any type of mesh entity - be it Vertex, HalfEdge, or Face. Also the position attribute
24
     is stored in an AttributeVector class.      
25
     */
26
    template<typename ITEM, typename ITEMID>
27
    class AttributeVector
28
    {
29
    public:
30
        /// Construct from optional size and item (size should be identical to number of entities in associated container
31
        AttributeVector(size_t _size = 0, ITEM item = ITEM());
32
 
33
        /// Add an item
34
       // ITEMID add(const ITEM& item);
35
 
36
        /// const reference to item given by ID
37
        const ITEM& get(ITEMID id) const;
38
 
39
        /// reference to item given by ID
40
        ITEM& get(ITEMID id);
41
 
42
        /// const reference to item given by ID
43
        const ITEM& operator [](ITEMID id) const;
44
 
45
        /// reference to item given by ID
46
        ITEM& operator [](ITEMID id);
47
 
48
        /// resize the vector (may be necessary if associated container size grows)
49
        void resize(size_t _size, ITEM item = ITEM());
50
 
51
        /// number of attribute items in vector
52
        size_t size() const;
53
 
54
        /// clear the vector
55
        void clear();
56
 
57
        /// clenup unused items from the vector, given by remap from associated container
58
        void cleanup(const std::map<ITEMID, ITEMID>& map);
59
 
60
    private:
61
        std::vector<ITEM> items;
62
    };
63
 
64
    template<typename ITEM>
65
    class VertexAttributeVector : public AttributeVector<ITEM, VertexID>
66
    {
67
    public:
68
        VertexAttributeVector(size_t _size = 0, ITEM item = ITEM());
69
    };
70
 
71
    template<typename ITEM>
72
    class FaceAttributeVector : public AttributeVector<ITEM, FaceID>
73
    {
74
    public:
75
        FaceAttributeVector(size_t _size = 0, ITEM item = ITEM());
76
    };
77
 
78
    template<typename ITEM>
79
    class HalfEdgeAttributeVector : public AttributeVector<ITEM, HalfEdgeID>
80
    {
81
    public:
82
        HalfEdgeAttributeVector(size_t _size = 0, ITEM item = ITEM());
83
    };
84
 
85
    template<typename ITEM>
86
    inline VertexAttributeVector<ITEM>::VertexAttributeVector(size_t _size, ITEM item) : AttributeVector<ITEM, VertexID>(_size, item){}
87
 
88
    template<typename ITEM>
89
    inline FaceAttributeVector<ITEM>::FaceAttributeVector(size_t _size, ITEM item) : AttributeVector<ITEM, FaceID>(_size, item){}
90
 
91
    template<typename ITEM>
92
    inline HalfEdgeAttributeVector<ITEM>::HalfEdgeAttributeVector(size_t _size, ITEM item) : AttributeVector<ITEM, HalfEdgeID>(_size, item){}
93
 
94
 
95
    template<typename ITEM, typename ITEMID>
96
    inline AttributeVector<ITEM, ITEMID>::AttributeVector(size_t _size, ITEM item) : items(_size, item){}
97
 
98
    template<typename ITEM, typename ITEMID>
99
    inline void AttributeVector<ITEM, ITEMID>::clear()
100
    { items.clear(); }
101
 
102
    template<typename ITEM, typename ITEMID>
103
    inline void AttributeVector<ITEM, ITEMID>::cleanup(const std::map<ITEMID, ITEMID>& remap)
104
    {
105
        std::vector<ITEM> new_items(remap.size());
106
        for(typename std::map<ITEMID, ITEMID>::const_iterator it = remap.begin(); it != remap.end(); ++it){
107
            assert(it->second.index < remap.size());
108
            new_items[it->second.index] = items[it->first.index];
109
        }
110
        std::swap(items, new_items);
111
    }
112
 
113
 
114
    template<typename ITEM, typename ITEMID>
115
    inline void AttributeVector<ITEM, ITEMID>::resize(size_t _size, ITEM item)
116
    { items.resize(_size, item); }
117
 
118
    template<typename ITEM, typename ITEMID>
119
    inline size_t AttributeVector<ITEM, ITEMID>::size() const
120
    { return items.size(); }
121
 
122
    // just returning should be ok; manifold and attribs should always be in sync.
123
    // const context means manifold and attribs should be const, hence in sync.
124
    template<typename ITEM, typename ITEMID>
125
    inline const ITEM& AttributeVector<ITEM, ITEMID>::get(ITEMID id) const
126
    { 
127
        assert(id.index < items.size());
128
        return items[id.index]; 
129
    }
130
 
131
    template<typename ITEM, typename ITEMID>
132
    inline ITEM& AttributeVector<ITEM, ITEMID>::get(ITEMID id)
133
    {
134
        if(id.index >= items.size())
135
            items.resize(id.index + 1);
136
        return items[id.index]; 
137
    }
138
 
139
    template<typename ITEM, typename ITEMID>
140
    inline const ITEM& AttributeVector<ITEM, ITEMID>::operator [](ITEMID id) const
141
    { 
142
        assert(id.index < items.size());
143
        return items[id.index]; 
144
    }
145
 
146
    template<typename ITEM, typename ITEMID>
147
    inline ITEM& AttributeVector<ITEM, ITEMID>::operator [](ITEMID id)
148
    {
149
        if(id.index >= items.size())
150
            items.resize(id.index + 1);
151
        return items[id.index]; 
152
    }
153
}
154
 
155
#endif