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
|