iterator.cpp 7.58 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
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
		}
		while( num >= 0 )
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
68
			while(id >= 0 && (links[num][id] == -1)) --id;
Kirill Terekhov's avatar
Kirill Terekhov committed
69
			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
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
		}
		while( num >= 0 )
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
134
			while(id >= 0 && (links[num][id] == -1)) --id;
Kirill Terekhov's avatar
Kirill Terekhov committed
135
			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
	}

	Storage::integer  Mesh::FirstLocalID(ElementType etype) const 
	{
		assert(OneType(etype)); 
		integer ret = 0, n = ElementNum(etype); 
		if(n == 5) return 0; 
Kirill Terekhov's avatar
Kirill Terekhov committed
161
		while(ret < static_cast<integer>(links[n].size()) && (links[n][ret] == -1)) ++ret; 
Kirill Terekhov's avatar
Kirill Terekhov committed
162 163 164 165 166 167 168
		return ret;
	}

	Storage::integer Mesh::NumberOf(ElementType t) const
	{
		integer ret = 0;
		for(int m = 0; m < 5; m++) if( (1 << m) & t )
Kirill Terekhov's avatar
Kirill Terekhov committed
169
			ret += static_cast<integer>(links[m].size() - empty_links[m].size()) - hidden_count[m];
Kirill Terekhov's avatar
Kirill Terekhov committed
170 171 172 173 174 175 176 177 178
		if( t & MESH ) ret++;
		return ret;
	}
	
	template<typename EType>
	Mesh::base_iterator<EType> & Mesh::base_iterator<EType>::operator ++()
	{
		while( etype != NONE ) 
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
179
			lid = m->NextLocalIDIter(etype,lid);
Kirill Terekhov's avatar
Kirill Terekhov committed
180
			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
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
			else break;
		}
		return *this;
	}

	template<typename EType>
	Mesh::base_iterator<EType> & Mesh::base_iterator<EType>::operator --()
	{
		while( etype != NONE ) 
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
196
			lid = m->PrevLocalIDIter(etype,lid);
Kirill Terekhov's avatar
Kirill Terekhov committed
197
			if( lid == -1 )
Kirill Terekhov's avatar
Kirill Terekhov committed
198
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
199 200
				etype = GetPrevType(etype,types);
				if( etype ) 
Kirill Terekhov's avatar
Kirill Terekhov committed
201
					lid = m->LastLocalIDIter(etype);
Kirill Terekhov's avatar
Kirill Terekhov committed
202
				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 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268
	Storage::integer Mesh::NextLocalIDIter(ElementType etype, integer lid) const 
	{
		integer q = ElementNum(etype); 
		++lid; 
		while(lid < static_cast<integer>(links[q].size()) && (links[q][lid] == -1|| Hidden(ComposeHandleNum(q,lid)))) ++lid; 
		return lid;
	}

	Storage::integer Mesh::PrevLocalIDIter(ElementType etype, integer lid) const 
	{
		integer q = ElementNum(etype); 
		--lid; 
		while(lid > 0 && (links[q][lid] == -1 || Hidden(ComposeHandleNum(q,lid)))) --lid; 
		return lid;
	}
	Storage::integer Mesh::FirstLocalIDIter(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|| Hidden(ComposeHandleNum(n,ret)))) ++ret; 
		return ret;
	}
	Storage::integer Mesh::LastLocalIDIter(ElementType etype) const 
	{
		assert(OneType(etype)); 
		int ret = LastLocalIDNum(ElementNum(etype));
		return PrevLocalIDIter(etype,ret);
	}

Kirill Terekhov's avatar
Kirill Terekhov committed
269 270
	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
Kirill Terekhov committed
271
	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
272 273 274 275 276 277 278 279 280 281 282 283 284 285
	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
Kirill Terekhov committed
286
	template class Mesh::base_iterator<ElementSet>;
Kirill Terekhov's avatar
Kirill Terekhov committed
287 288 289 290 291
	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
292 293
}
#endif