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