iterator.cpp 6.59 KB
Newer Older
Kirill Terekhov's avatar
Kirill Terekhov committed
1
2
3
4
5
6
7
8
9
10
#include "inmost.h"
#include <iostream>
#if defined(USE_MESH)





namespace INMOST
{
Kirill Terekhov's avatar
Kirill Terekhov committed
11
12

	ElementType GetNextType(ElementType current, ElementType types)
Kirill Terekhov's avatar
Kirill Terekhov committed
13
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
14
15
16
17
18
19
20
21
22
23
24
25
		ElementType ret = MESH << 1;
		for(ElementType i = current << 1; i <= MESH; i = i << 1)
			if( types & i )
			{
				ret = i;
				break;
			}
		if( ret > MESH ) ret = NONE;
		return ret;
	}

	ElementType GetPrevType(ElementType current, ElementType types)
Kirill Terekhov's avatar
Kirill Terekhov committed
26
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
27
28
29
		ElementType ret = MESH << 1;
		for(ElementType i = current >> 1; i > NONE; i = i >> 1)
			if( types & i )
Kirill Terekhov's avatar
Kirill Terekhov committed
30
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
31
32
				ret = i;
				break;
Kirill Terekhov's avatar
Kirill Terekhov committed
33
			}
Kirill Terekhov's avatar
Kirill Terekhov committed
34
		if( ret > MESH ) ret = NONE;
Kirill Terekhov's avatar
Kirill Terekhov committed
35
36
37
		return ret;
	}
	
Kirill Terekhov's avatar
Kirill Terekhov committed
38
	HandleType  Mesh::NextHandle(HandleType h) const 
Kirill Terekhov's avatar
Kirill Terekhov committed
39
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
40
41
42
		integer num = GetHandleElementNum(h), id = GetHandleID(h);
		++id;
		while( num < 5 )
Kirill Terekhov's avatar
Kirill Terekhov committed
43
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
44
			while(id < static_cast<integer>(links[num].size()) && links[num][id] == -1) ++id;
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
45
			if( id == static_cast<integer>(links[num].size()) ) 
Kirill Terekhov's avatar
Kirill Terekhov committed
46
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
47
48
				id = 0;
				++num;
Kirill Terekhov's avatar
Kirill Terekhov committed
49
			}
Kirill Terekhov's avatar
Kirill Terekhov committed
50
51
52
			else break;
		}
		if( num == 5 && id > 0 ) id = 1;
53
		return ComposeHandleNum(num,id);
Kirill Terekhov's avatar
Kirill Terekhov committed
54
55
56
57
58
59
60
61
62
63
	}

	HandleType  Mesh::PrevHandle(HandleType h) const 
	{
		integer num = GetHandleElementNum(h), id = GetHandleID(h);
		--id;
		if( num == 5 ) 
		{
			if( id < 0 )
				num = 4;
64
			else return ComposeHandleNum(ElementNum(MESH),0);
Kirill Terekhov's avatar
Kirill Terekhov committed
65
66
67
68
69
		}
		while( num >= 0 )
		{
			while(id >= 0 && links[num][id] == -1) --id;
			if( id == -1 ) 
Kirill Terekhov's avatar
Kirill Terekhov committed
70
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
71
72
				--num;
				if( num > 0 ) id = static_cast<integer>(links[num].size())-1;
Kirill Terekhov's avatar
Kirill Terekhov committed
73
			}
Kirill Terekhov's avatar
Kirill Terekhov committed
74
			else break;
Kirill Terekhov's avatar
Kirill Terekhov committed
75
		}
Kirill Terekhov's avatar
Kirill Terekhov committed
76
		if( num < 0 ) return InvalidHandle();
77
		return ComposeHandleNum(num,id);
Kirill Terekhov's avatar
Kirill Terekhov committed
78
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
79
80

	HandleType  Mesh::NextHandle(HandleType h, ElementType etype) const 
Kirill Terekhov's avatar
Kirill Terekhov committed
81
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
82
83
84
		integer num = GetHandleElementNum(h), id = GetHandleID(h);
		++id;
		while( num < 5 )
Kirill Terekhov's avatar
Kirill Terekhov committed
85
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
86
			while(id < static_cast<integer>(links[num].size()) && links[num][id] == -1) ++id;
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
87
			if( id == static_cast<integer>(links[num].size()) ) 
Kirill Terekhov's avatar
Kirill Terekhov committed
88
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
89
90
				bool stop = true;
				for(integer q = num+1; q < 5; q++)
Kirill Terekhov's avatar
Kirill Terekhov committed
91
				{
Kirill Terekhov's avatar
Kirill Terekhov committed
92
					if( etype & (1 << q) )
Kirill Terekhov's avatar
Kirill Terekhov committed
93
					{
Kirill Terekhov's avatar
Kirill Terekhov committed
94
95
96
						id = 0;
						num = q;
						stop = false;
Kirill Terekhov's avatar
Kirill Terekhov committed
97
98
99
						break;
					}
				}
Kirill Terekhov's avatar
Kirill Terekhov committed
100
				if( stop ) break;
Kirill Terekhov's avatar
Kirill Terekhov committed
101
			}
Kirill Terekhov's avatar
Kirill Terekhov committed
102
103
104
			else break;
		}
		if( num == 5 && id > 0 ) id = 1;
105
		return ComposeHandleNum(num,id);
Kirill Terekhov's avatar
Kirill Terekhov committed
106
107
108
109
110
111
112
113
114
	}

	HandleType  Mesh::PrevHandle(HandleType h, ElementType etype) const 
	{
		integer num = GetHandleElementNum(h), id = GetHandleID(h);
		--id;
		if( num == 5 ) 
		{
			if( id < 0 )
Kirill Terekhov's avatar
Kirill Terekhov committed
115
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
116
117
				bool stop = true;
				for(integer q = 4; q >= 0; q--)
Kirill Terekhov's avatar
Kirill Terekhov committed
118
				{
Kirill Terekhov's avatar
Kirill Terekhov committed
119
					if( etype & (1 << q) )
Kirill Terekhov's avatar
Kirill Terekhov committed
120
					{
Kirill Terekhov's avatar
Kirill Terekhov committed
121
122
123
124
125
						
						num = q;
						id = static_cast<integer>(links[num].size())-1;
						stop = false;
						break;
Kirill Terekhov's avatar
Kirill Terekhov committed
126
127
					}
				}
Kirill Terekhov's avatar
Kirill Terekhov committed
128
				if( stop ) return InvalidHandle();
Kirill Terekhov's avatar
Kirill Terekhov committed
129
			}
130
			else return ComposeHandleNum(ElementNum(MESH),0);
Kirill Terekhov's avatar
Kirill Terekhov committed
131
132
133
134
135
		}
		while( num >= 0 )
		{
			while(id >= 0 && links[num][id] == -1) --id;
			if( id == -1 ) 
Kirill Terekhov's avatar
Kirill Terekhov committed
136
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
137
138
				bool stop = true;
				for(integer q = num-1; q >= 0; q--)
Kirill Terekhov's avatar
Kirill Terekhov committed
139
				{
Kirill Terekhov's avatar
Kirill Terekhov committed
140
					if( etype & (1 << q) )
Kirill Terekhov's avatar
Kirill Terekhov committed
141
					{
Kirill Terekhov's avatar
Kirill Terekhov committed
142
143
144
145
						num = q;
						id = static_cast<integer>(links[num].size())-1;
						stop = false;
						break;
Kirill Terekhov's avatar
Kirill Terekhov committed
146
147
					}
				}
Kirill Terekhov's avatar
Kirill Terekhov committed
148
				if( stop ) return InvalidHandle();
Kirill Terekhov's avatar
Kirill Terekhov committed
149
			}
Kirill Terekhov's avatar
Kirill Terekhov committed
150
151
152
			else break;
		}
		if( num < 0 ) return InvalidHandle();
153
		return ComposeHandleNum(num,id);
Kirill Terekhov's avatar
Kirill Terekhov committed
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
	}

	Storage::integer  Mesh::FirstLocalID(ElementType etype) const 
	{
		assert(OneType(etype)); 
		integer ret = 0, n = ElementNum(etype); 
		if(n == 5) return 0; 
		while(ret < static_cast<integer>(links[n].size()) && links[n][ret] == -1) ++ret; 
		return ret;
	}

	Storage::integer Mesh::NumberOf(ElementType t) const
	{
		integer ret = 0;
		for(int m = 0; m < 5; m++) if( (1 << m) & t )
			ret += static_cast<integer>(links[m].size() - empty_links[m].size());
		if( t & MESH ) ret++;
		return ret;
	}
	
	template<typename EType>
	Mesh::base_iterator<EType> & Mesh::base_iterator<EType>::operator ++()
	{
		while( etype != NONE ) 
		{
			lid = m->NextLocalID(etype,lid);
			if( lid == m->LastLocalID(etype) )
Kirill Terekhov's avatar
Kirill Terekhov committed
181
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
182
				etype = GetNextType(etype,types);
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
183
184
				lid = -1;
				if( !etype ) break;
Kirill Terekhov's avatar
Kirill Terekhov committed
185
			}
Kirill Terekhov's avatar
Kirill Terekhov committed
186
187
188
189
190
191
192
193
194
195
196
197
			else break;
		}
		return *this;
	}

	template<typename EType>
	Mesh::base_iterator<EType> & Mesh::base_iterator<EType>::operator --()
	{
		while( etype != NONE ) 
		{
			lid = m->PrevLocalID(etype,lid);
			if( lid == -1 )
Kirill Terekhov's avatar
Kirill Terekhov committed
198
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
199
200
201
202
				etype = GetPrevType(etype,types);
				if( etype ) 
					lid = m->LastLocalID(etype);
				else
Kirill Terekhov's avatar
Kirill Terekhov committed
203
				{
Kirill Terekhov's avatar
Kirill Terekhov committed
204
205
					lid = -1;
					break;
Kirill Terekhov's avatar
Kirill Terekhov committed
206
207
				}
			}
Kirill Terekhov's avatar
Kirill Terekhov committed
208
			else break;
Kirill Terekhov's avatar
Kirill Terekhov committed
209
210
211
212
		}
		return *this;
	}
	
Kirill Terekhov's avatar
Kirill Terekhov committed
213
214
	template<typename EType>
	Mesh::base_iterator<EType>::base_iterator(ElementType T, Mesh * _m, bool last)
Kirill Terekhov's avatar
Kirill Terekhov committed
215
216
217
	{
		m = _m;
		types = T;
Kirill Terekhov's avatar
Kirill Terekhov committed
218
219
		etype = NONE;
		lid = -1;
Kirill Terekhov's avatar
Kirill Terekhov committed
220
221
		if( last )
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
222
223
			for(ElementType i = MESH; i >= NODE; i = i >> 1) if( types & i ) {etype = i; break;}
			lid = m->LastLocalID(etype);
Kirill Terekhov's avatar
Kirill Terekhov committed
224
225
226
227
			operator--();
		}
		else
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
228
229
			for(ElementType i = NODE; i <= MESH; i = i << 1) if( types & i ) {etype = i; break;}
			lid = -1;
Kirill Terekhov's avatar
Kirill Terekhov committed
230
231
232
			operator++();
		}
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
233
234
	template<typename EType>
	void Mesh::base_iterator<EType>::Print()
Kirill Terekhov's avatar
Kirill Terekhov committed
235
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
236
		printf("Number: %10d CurrentType %x types %x\n",lid,etype,types);
Kirill Terekhov's avatar
Kirill Terekhov committed
237
238
	}

Kirill Terekhov's avatar
Kirill Terekhov committed
239
240
	Mesh::iteratorStorage Mesh::Begin(ElementType Types)        {return base_iterator<Storage>(Types,this,false);}
	Mesh::iteratorStorage Mesh::End()                           {return base_iterator<Storage>(this);}
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
241
	Mesh::iteratorElement Mesh::BeginElement(ElementType Types) {return base_iterator<Element>(Types & (NODE | EDGE | FACE | CELL | ESET),this,false);}
Kirill Terekhov's avatar
Kirill Terekhov committed
242
243
244
245
246
247
248
249
250
251
252
253
254
255
	Mesh::iteratorElement Mesh::EndElement()                    {return base_iterator<Element>(this);}
	Mesh::iteratorSet     Mesh::BeginSet()                      {return base_iterator<ElementSet>(ESET,this,false);}
	Mesh::iteratorSet     Mesh::EndSet()                        {return base_iterator<ElementSet>(this);}
	Mesh::iteratorCell    Mesh::BeginCell()                     {return base_iterator<Cell>(CELL,this,false);}
	Mesh::iteratorCell    Mesh::EndCell()                       {return base_iterator<Cell>(this);}
	Mesh::iteratorFace    Mesh::BeginFace()                     {return base_iterator<Face>(FACE,this,false);}
	Mesh::iteratorFace    Mesh::EndFace()                       {return base_iterator<Face>(this);}
	Mesh::iteratorEdge    Mesh::BeginEdge()                     {return base_iterator<Edge>(EDGE,this,false);}
	Mesh::iteratorEdge    Mesh::EndEdge()                       {return base_iterator<Edge>(this);}
	Mesh::iteratorNode    Mesh::BeginNode()                     {return base_iterator<Node>(NODE,this,false);}
	Mesh::iteratorNode    Mesh::EndNode()                       {return base_iterator<Node>(this);}

	//all possible templates
	template class Mesh::base_iterator<Element>;
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
256
	template class Mesh::base_iterator<ElementSet>;
Kirill Terekhov's avatar
Kirill Terekhov committed
257
258
259
260
261
	template class Mesh::base_iterator<Node>;
	template class Mesh::base_iterator<Edge>;
	template class Mesh::base_iterator<Face>;
	template class Mesh::base_iterator<Cell>;
	template class Mesh::base_iterator<Storage>;
Kirill Terekhov's avatar
Kirill Terekhov committed
262
263
}
#endif