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
 * @file ItemVector.h
8
 * @brief Contains the vector type used for the mesh entities.
9
 */
10
 
11
#ifndef __HMESH_ITEMVECTOR_H__
12
#define __HMESH_ITEMVECTOR_H__
13
 
14
#include <cassert>
15
#include <vector>
16
#include "ItemID.h"
17
 
18
namespace HMesh
19
{
20
    /** The ItemVector is a vector of mesh entities.
21
        An ItemVector is a layer on top of the regular vector class which keeps
22
        track of the unused elements in a vector. This allows for garbage collection.
23
        ItemVector is used for storing vectors of Face, HalfEdge, and Vertex type.
24
     */
25
    template<typename ITEM>
26
    class ItemVector
27
    {
28
    public:
29
        typedef ItemID<ITEM> IDType;
30
 
31
 
32
        /// default constructor
33
        ItemVector(size_t _size = 0, ITEM i = ITEM()); 
34
 
35
        /// Get a reference to item i from kernel
36
        ITEM& get(IDType i);
37
        /// Get a const reference to item i from kernel
38
        const ITEM& get(IDType i) const;
39
        /// Get a reference to item i from kernel
40
        ITEM& operator[](IDType i);
41
        /// Get a const reference to item i from kernel
42
        const ITEM& operator[](IDType i) const;
43
 
44
        /// Add an entity to the kernel
45
        IDType add(const ITEM& i);
46
 
47
        /// remove an entity from kernel - entity is NOT erased!
48
        void remove(IDType i);
49
 
50
        /// erase unused entities from the kernel
51
        void cleanup();
52
 
53
        /// active size of vector
54
        size_t size() const;
55
 
56
        /// total size of vector
57
        size_t allocated_size() const;
58
 
59
        /// Resize the kernel NOTE: Sets all active flags to true
60
        void resize(size_t _size, ITEM i = ITEM());
61
        /// Request size change in kernel
62
        void reserve(size_t i);
63
 
64
        /// Clear the kernel
65
        void clear();
66
 
67
        /// Check if entity i is used
68
        bool in_use(IDType i) const;
69
 
70
        /// get starting index (default: skip to first active index)
71
        IDType index_begin(bool skip = true) const;
72
 
73
        /// get one past the end index of vector
74
        IDType index_end() const;
75
 
76
        /// get the next index (default: skip to first active index)
77
        IDType index_next(IDType index, bool skip = true) const;
78
 
79
        /// get the previous index (default: skip to first active index)
80
        IDType index_prev(IDType index, bool skip = true) const;
81
 
82
    private:
83
 
84
        size_t size_active;
85
        std::vector<ITEM> items;
86
 
87
        /// Memory consideration - objects flagged as unused should be remembered for future use (unless purged)
88
        std::vector<bool> active_items;
89
    };
90
 
91
    template<typename ITEM>
92
    inline ItemVector<ITEM>::ItemVector(size_t _size, ITEM i) 
93
        :   size_active(_size), 
94
            items(_size, i), 
95
            active_items(_size, true){}
96
 
97
    template<typename ITEM>
98
    inline ITEM& ItemVector<ITEM>::get(IDType id)
99
    {
100
        assert(id.index < items.size());
101
        return items[id.index];
102
    }
103
 
104
    template<typename ITEM>
105
    inline const ITEM& ItemVector<ITEM>::get(IDType id) const
106
    {
107
        assert(id.index < items.size());
108
        return items[id.index];
109
    }
110
 
111
    template<typename ITEM>
112
    inline ITEM& ItemVector<ITEM>::operator [](IDType id)
113
    {
114
        assert(id.index < items.size());
115
        return items[id.index];
116
    } 
117
 
118
    template<typename ITEM>
119
    inline const ITEM& ItemVector<ITEM>::operator [](IDType id) const
120
    {
121
        assert(id.index < items.size());
122
        return items[id.index];
123
    }
124
 
125
    template<typename ITEM>
126
    inline typename ItemVector<ITEM>::IDType ItemVector<ITEM>::add(const ITEM& item)
127
    {
128
        items.push_back(item);
129
        active_items.push_back(true);
130
        ++size_active;
131
        return IDType(items.size() - 1);
132
    }
133
 
134
    template<typename ITEM>
135
    inline void ItemVector<ITEM>::remove(typename ItemVector<ITEM>::IDType id)
136
    {
137
        if(active_items[id.index]){
138
            --size_active;
139
            active_items[id.index] = false;
140
        }
141
    }
142
 
143
    template<typename ITEM>
144
    inline void ItemVector<ITEM>::cleanup()
145
    {
146
        std::vector<ITEM> new_items;
147
        for(size_t i = 0; i < items.size(); ++i){
148
            if(active_items[i]) 
149
                new_items.push_back(items[i]);          
150
        }
151
        std::swap(items, new_items);
152
        active_items = std::vector<bool>(items.size(), true);
153
        size_active = items.size();
154
    }
155
 
156
    template<typename ITEM>
157
    inline size_t ItemVector<ITEM>::size() const
158
    { return size_active; }
159
 
160
    template<typename ITEM>
161
    inline size_t ItemVector<ITEM>::allocated_size() const
162
    { return items.size(); }
163
 
164
    template<typename ITEM>
165
    inline void ItemVector<ITEM>::resize(size_t _size, ITEM i)
166
    {
167
        items.resize(_size, i);
168
        active_items.resize(_size, true);
169
        size_active = _size;
170
    }
171
 
172
    template<typename ITEM>
173
    inline void ItemVector<ITEM>::reserve(size_t i)
174
    {
175
        items.reserve(i);
176
        active_items.reserve(i);
177
    }
178
 
179
    template<typename ITEM>
180
    inline void ItemVector<ITEM>::clear()
181
    {
182
        items.clear();
183
        active_items.clear();
184
        size_active = 0;
185
    }
186
 
187
    template<typename ITEM>
188
    inline bool ItemVector<ITEM>::in_use(typename ItemVector<ITEM>::IDType id) const
189
    {
190
        if(id.index < active_items.size())
191
			return active_items[id.index];
192
		return false;
193
    }
194
 
195
    template<typename ITEM>
196
    inline typename ItemVector<ITEM>::IDType ItemVector<ITEM>::index_begin(bool skip) const
197
    {
198
        size_t i = 0;
199
 
200
        if(!skip)
201
            return IDType(i);
202
 
203
        while(i < active_items.size() && !active_items[i])
204
            ++i;
205
 
206
 
207
        return IDType(i);
208
    }
209
 
210
    template<typename ITEM>
211
    inline typename ItemVector<ITEM>::IDType ItemVector<ITEM>::index_end() const
212
    { return IDType(items.size()); }
213
 
214
    template<typename ITEM>
215
    inline typename ItemVector<ITEM>::IDType ItemVector<ITEM>::index_next(typename ItemVector<ITEM>::IDType id, bool skip) const
216
    {
217
        if(id.index < items.size())
218
            ++id.index;
219
 
220
        if(!skip)
221
            return IDType(id);
222
 
223
        while(id.index < items.size() && !active_items[id.index])
224
           ++id.index;
225
 
226
        return id;
227
    }
228
 
229
    template<typename ITEM>
230
    inline typename ItemVector<ITEM>::IDType ItemVector<ITEM>::index_prev(typename ItemVector<ITEM>::IDType id, bool skip) const
231
    {
232
        if(id.index > 0)
233
            --id.index;
234
 
235
        if(!skip)
236
            return id;
237
 
238
        while(!active_items[id.index] && id.index > 0)
239
            --id.index;
240
 
241
        return id;
242
    }
243
 
244
}
245
 
246
#endif