Subversion Repositories gelsvn

Rev

Rev 512 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
511 s042372 1
/*
2
* Written by Christian Thode Larsen 2009-2010
3
* Contact: thode2d@gmail.com
4
* Based on original work by J. Andreas Baerentzen
5
* Inspired by OpenMesh (www.openmesh.org)
6
*/
7
 
8
#ifndef __HMESH_ITEMVECTOR_H__
9
#define __HMESH_ITEMVECTOR_H__
10
 
11
#include <vector>
12
 
13
#include "ItemID.h"
14
 
15
namespace HMesh
16
{
17
	template<typename ITEM>
18
	class ItemVector
19
	{
20
	public:
21
		/// default constructor
22
		ItemVector();
23
		ItemVector(IndexType _size, ITEM i = ITEM()); 
24
 
25
		/// Get a reference to entity i from kernel
26
		ITEM& get(IndexType i);
27
		/// Get a const reference to entity i from kernel
28
		const ITEM& get(IndexType i) const;
29
 
30
		ITEM& operator[](IndexType i);
31
		const ITEM& operator[](IndexType i) const;
32
 
33
		/// Add an entity to the kernel
34
		IndexType add(const ITEM& i);
35
 
36
		/// remove an entity from kernel - entity is NOT erased!
37
		void remove(IndexType i);
38
 
39
		/// erase unused entities from the kernel
40
		void cleanup();
41
 
42
		/// size of vector (default: only active items)
43
		IndexType size(bool active = true) const;
44
 
45
		/// Resize the kernel NOTE: Sets all active flags to true
46
		void resize(IndexType _size, ITEM i = ITEM());
47
		/// Request size change in kernel
48
		void reserve(IndexType i);
49
 
50
		/// Clear the kernel
51
		void clear();
52
 
53
		/// Check if entity i is used
54
		bool in_use(IndexType i) const;
55
 
56
		/// get starting index (default: skip to first active index)
57
		IndexType index_begin(bool skip = true) const;
58
 
59
		/// get ending index
60
		IndexType index_end() const;
61
 
62
		/// get the next index (default: skip to first active index)
63
		IndexType index_next(IndexType index, bool skip = true) const;
64
 
65
		/// get the previous index (default: skip to first active index)
66
		IndexType index_prev(IndexType index, bool skip = true) const;
67
 
68
	private:
69
 
70
		IndexType size_active;
71
		std::vector<ITEM> items;
72
 
73
		/// Memory consideration - objects flagged as unused should be remembered for future use (unless purged)
74
		std::vector<bool> active_items;
75
	};
76
 
77
	template<typename ITEM>
78
	inline ItemVector<ITEM>::ItemVector() : size_active(0) {}
79
 
80
	template<typename ITEM>
81
	inline ItemVector<ITEM>::ItemVector(IndexType _size, ITEM i = ITEM()) : size_active(_size), items(_size, i){}
82
 
83
	template<typename ITEM>
84
	ITEM& ItemVector<ITEM>::get(IndexType i)
85
	{
86
		assert(i < items.size());
87
		return items[i];
88
	}
89
 
90
	template<typename ITEM>
91
	const ITEM& ItemVector<ITEM>::get(IndexType i) const
92
	{
93
		assert(i < items.size());
94
		return items[i];
95
	}
96
 
97
	template<typename ITEM>
98
	ITEM& ItemVector<ITEM>::operator [](IndexType i)
99
	{
100
		assert(i < items.size());
101
		return items[i];
102
	} 
103
 
104
	template<typename ITEM>
105
	const ITEM& ItemVector<ITEM>::operator [](IndexType i) const
106
	{
107
		assert(i < items.size());
108
		return items[i];
109
	}
110
 
111
	template<typename ITEM>
112
	IndexType ItemVector<ITEM>::add(const ITEM& i)
113
	{
114
		items.push_back(i);
115
		active_items.push_back(true);
116
		++size_active;
117
		return items.size() - 1;
118
	}
119
 
120
	template<typename ITEM>
121
	void ItemVector<ITEM>::remove(IndexType i)
122
	{
123
		if(active_items[i]) 
124
			--size_active;
125
		active_items[i] = false;
126
	}
127
 
128
	template<typename ITEM>
129
	void ItemVector<ITEM>::cleanup()
130
	{
131
		std::vector<ITEM> new_items;
132
		for(IndexType i = 0; i < items.size(); ++i){
133
			if(active_items[i]) 
134
				new_items.push_back(items[i]);          
135
		}
136
		items = new_items;
137
		active_items = std::vector<bool>(items.size(), true);
138
		size_active = items.size();
139
	}
140
 
141
	template<typename ITEM>
142
	IndexType ItemVector<ITEM>::size(bool active = true) const
143
	{ return active ? size_active : items.size(); }
144
 
145
	template<typename ITEM>
146
	void ItemVector<ITEM>::resize(IndexType _size, ITEM i = ITEM())
147
	{
148
		items.resize(_size, i);
149
		active_items.resize(_size, true);
150
		size_active = _size;
151
	}
152
 
153
	template<typename ITEM>
154
	void ItemVector<ITEM>::reserve(IndexType i)
155
	{
156
		items.reserve(i);
157
		active_items.reserve(i);
158
	}
159
 
160
	template<typename ITEM>
161
	void ItemVector<ITEM>::clear()
162
	{
163
		items.clear();
164
		active_items.clear();
165
		size_active = 0;
166
	}
167
 
168
	template<typename ITEM>
169
	bool ItemVector<ITEM>::in_use(IndexType i) const
170
	{
171
		assert(i < active_items.size());
172
		return active_items[i];
173
	}
174
 
175
	template<typename ITEM>
176
	IndexType ItemVector<ITEM>::index_begin(bool skip = true) const
177
	{
178
		if(!skip)
179
			return 0;
180
		IndexType i = 0;
181
		while(!active_items[i])
182
			++i;
183
		return i;
184
	}
185
 
186
	template<typename ITEM>
187
	IndexType ItemVector<ITEM>::index_end() const
188
	{ return items.size(); }
189
 
190
	template<typename ITEM>
191
	IndexType ItemVector<ITEM>::index_next(IndexType index, bool skip = true) const
192
	{
193
		if(index != items.size())
194
			++index;
195
 
196
		if(skip){
197
			while(!in_use(index) && index < items.size()){
198
				++index;
199
			}
200
		}
201
		return index;
202
	}
203
 
204
	template<typename ITEM>
205
	IndexType ItemVector<ITEM>::index_prev(IndexType index, bool skip = true) const
206
	{
207
		if(index > 0)
208
			--index;
209
 
210
		if(skip){
211
			while(!in_use(index) && index > 0){
212
				--index;
213
			}
214
		}
215
		return index;
216
	}
217
 
218
}
219
 
220
#endif