face.cpp 23.2 KB
Newer Older
Kirill Terekhov's avatar
Kirill Terekhov committed
1
2
3
4
5
6
7
#include "inmost.h"
#if defined(USE_MESH)
namespace INMOST
{
	
	
	
Kirill Terekhov's avatar
Kirill Terekhov committed
8
	Cell Face::BackCell() const
Kirill Terekhov's avatar
Kirill Terekhov committed
9
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
10
11
		assert(GetHandleElementType(GetHandle())==FACE);
		Mesh * m = GetMeshLink();
Kirill Terekhov's avatar
Kirill Terekhov committed
12
13
		if( !GetMeshLink()->HideMarker() )
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
14
			adj_type const & hc = m->HighConn(GetHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
15
			if( hc.size() > 0 ) 
Kirill Terekhov's avatar
Kirill Terekhov committed
16
17
				return Cell(m,hc[0]); 
			return Cell(m,InvalidHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
18
19
20
		}
		else
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
21
			adj_type const & hc = m->HighConn(GetHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
22
			if( !hc.empty() )
Kirill Terekhov's avatar
Kirill Terekhov committed
23
			{
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
24
				enumerator i = ENUMUNDEF;
Kirill Terekhov's avatar
Kirill Terekhov committed
25
				MarkerType hm = m->HideMarker();
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
26
				i = m->getNext(hc.data(),static_cast<enumerator>(hc.size()),i,hm);
Kirill Terekhov's avatar
Kirill Terekhov committed
27
				if( i != hc.size() ) return Cell(m,hc[i]);
Kirill Terekhov's avatar
Kirill Terekhov committed
28
			}
Kirill Terekhov's avatar
Kirill Terekhov committed
29
			return Cell(m,InvalidHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
30
31
		}
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
32
	Cell Face::FrontCell() const
Kirill Terekhov's avatar
Kirill Terekhov committed
33
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
34
35
36
		assert(GetHandleElementType(GetHandle())==FACE);
		Mesh * m = GetMeshLink();
		if( !m->HideMarker() )
Kirill Terekhov's avatar
Kirill Terekhov committed
37
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
38
			adj_type const & hc = m->HighConn(GetHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
39
			if( hc.size() > 1 ) 
Kirill Terekhov's avatar
Kirill Terekhov committed
40
41
				return Cell(m,hc[1]); 
			return Cell(m,InvalidHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
42
43
44
		}
		else
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
45
			adj_type const & hc = m->HighConn(GetHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
46
			if( !hc.empty() )
Kirill Terekhov's avatar
Kirill Terekhov committed
47
			{
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
48
				enumerator i = ENUMUNDEF;
Kirill Terekhov's avatar
Kirill Terekhov committed
49
				MarkerType hm = m->HideMarker();
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
50
51
				i = m->getNext(hc.data(),static_cast<enumerator>(hc.size()),i,hm); //found first
				i = m->getNext(hc.data(),static_cast<enumerator>(hc.size()),i,hm); //found second
Kirill Terekhov's avatar
Kirill Terekhov committed
52
				if( i != hc.size() ) return Cell(m,hc[i]);
Kirill Terekhov's avatar
Kirill Terekhov committed
53
			}
Kirill Terekhov's avatar
Kirill Terekhov committed
54
			return Cell(m,InvalidHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
55
56
57
		}
	}

Kirill Terekhov's avatar
Kirill Terekhov committed
58
	Node Face::getBeg() const 
Kirill Terekhov's avatar
Kirill Terekhov committed
59
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
60
		assert(GetHandleElementType(GetHandle())==FACE);
Kirill Terekhov's avatar
Kirill Terekhov committed
61
		assert(GetElementDimension()==1);
Kirill Terekhov's avatar
Kirill Terekhov committed
62
63
		Mesh * m = GetMeshLink();
		if( !m->HideMarker() )
Kirill Terekhov's avatar
Kirill Terekhov committed
64
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
65
			adj_type const & lc = m->LowConn(GetHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
66
			if( lc.empty() )
Kirill Terekhov's avatar
Kirill Terekhov committed
67
68
				return Node(m,InvalidHandle());
			return Node(m,m->LowConn(lc.front()).front());
Kirill Terekhov's avatar
Kirill Terekhov committed
69
70
71
		}
		else
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
72
			adj_type const & lc = m->LowConn(GetHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
73
			if( !lc.empty() )
Kirill Terekhov's avatar
Kirill Terekhov committed
74
			{
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
75
				enumerator i = ENUMUNDEF;
Kirill Terekhov's avatar
Kirill Terekhov committed
76
				MarkerType hm = m->HideMarker();
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
77
78
				i = m->getNext(lc.data(),static_cast<enumerator>(lc.size()),i,hm);
				if( i != static_cast<enumerator>(lc.size()) ) 
Kirill Terekhov's avatar
Kirill Terekhov committed
79
				{
Kirill Terekhov's avatar
Kirill Terekhov committed
80
					adj_type const & llc = m->LowConn(lc[i]);
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
81
82
					enumerator j = ENUMUNDEF;
					j = m->getNext(llc.data(),static_cast<enumerator>(llc.size()),j,hm);
Kirill Terekhov's avatar
Kirill Terekhov committed
83
					if( j != llc.size() ) return Node(m,llc[j]);
Kirill Terekhov's avatar
Kirill Terekhov committed
84
85
				}
			}
Kirill Terekhov's avatar
Kirill Terekhov committed
86
			return Node(m,InvalidHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
87
88
		}
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
89
	Node Face::getEnd() const 
Kirill Terekhov's avatar
Kirill Terekhov committed
90
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
91
		assert(GetHandleElementType(GetHandle())==FACE);
Kirill Terekhov's avatar
Kirill Terekhov committed
92
		assert(GetElementDimension()==1);
Kirill Terekhov's avatar
Kirill Terekhov committed
93
94
		Mesh * m = GetMeshLink();
		if( !m->HideMarker() )
Kirill Terekhov's avatar
Kirill Terekhov committed
95
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
96
			adj_type const & lc = m->LowConn(GetHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
97
			if( lc.size() < 2 )
Kirill Terekhov's avatar
Kirill Terekhov committed
98
99
				return Node(m,InvalidHandle());
			return Node(m,m->LowConn(lc.back()).front());
Kirill Terekhov's avatar
Kirill Terekhov committed
100
101
102
		}
		else
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
103
			adj_type const & lc = m->LowConn(GetHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
104
			if( !lc.empty() )
Kirill Terekhov's avatar
Kirill Terekhov committed
105
			{
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
106
				enumerator i = ENUMUNDEF;
Kirill Terekhov's avatar
Kirill Terekhov committed
107
				MarkerType hm = m->HideMarker();
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
108
109
110
				i = m->getNext(lc.data(),static_cast<enumerator>(lc.size()),i,hm);
				i = m->getNext(lc.data(),static_cast<enumerator>(lc.size()),i,hm);
				if( i != static_cast<enumerator>(lc.size()) ) 
Kirill Terekhov's avatar
Kirill Terekhov committed
111
				{
Kirill Terekhov's avatar
Kirill Terekhov committed
112
					adj_type const & llc = m->LowConn(lc[i]);
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
113
114
115
					enumerator j = ENUMUNDEF;
					j = m->getNext(llc.data(),static_cast<enumerator>(llc.size()),j,hm);
					if( j != static_cast<enumerator>(llc.size()) ) return Node(m,llc[j]);
Kirill Terekhov's avatar
Kirill Terekhov committed
116
117
				}
			}
Kirill Terekhov's avatar
Kirill Terekhov committed
118
			return Node(m,InvalidHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
119
120
121
		}
	}
	
Kirill Terekhov's avatar
Kirill Terekhov committed
122
	bool Face::FaceOrientedOutside(Cell c) const
Kirill Terekhov's avatar
Kirill Terekhov committed
123
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
124
		assert(GetHandleElementType(GetHandle())==FACE);
Kirill Terekhov's avatar
Kirill Terekhov committed
125
126
127
128
129
		if( BackCell() == c ) 
			return true; 
		return false;
	}
	
Kirill Terekhov's avatar
Kirill Terekhov committed
130
	void Face::ReorderEdges() const
Kirill Terekhov's avatar
Kirill Terekhov committed
131
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
132
133
134
		assert(GetHandleElementType(GetHandle())==FACE);
		adj_type & lc = GetMeshLink()->LowConn(GetHandle());
		for(adj_type::size_type j = 0; j < lc.size()/2; j++) // reorder edges!
Kirill Terekhov's avatar
Kirill Terekhov committed
135
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
136
			HandleType t = lc[j];
Kirill Terekhov's avatar
Kirill Terekhov committed
137
138
			lc[j] = lc[lc.size()-1-j];
			lc[lc.size()-1-j] = t;
Kirill Terekhov's avatar
Kirill Terekhov committed
139
140
141
		}
	}
	
Kirill Terekhov's avatar
Kirill Terekhov committed
142
	bool Face::CheckEdgeOrder() const
Kirill Terekhov's avatar
Kirill Terekhov committed
143
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
144
		assert(GetHandleElementType(GetHandle())==FACE);
Kirill Terekhov's avatar
Kirill Terekhov committed
145
146
147
148
149
150
151
152
153
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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
		Mesh * m = GetMeshLink();
		if( !m->HideMarker() )
		{
			if( Element::GetGeometricDimension(m->GetGeometricType(GetHandle())) == 1 )
				return m->LowConn(GetHandle()).size() == 2; //it is 2d edge, check that there are 2 nodes
			else //check that edges form an ordered loop
			{
				HandleType last, first;
				adj_type const & lc = m->LowConn(GetHandle());
				if( lc.size() < 3 ) return false;
				HandleType q = lc[0]; //edge 0
				adj_type const & qlc = m->LowConn(q);
				first = qlc[0]; //node 0
				last = qlc[1]; //node 1
				HandleType r = lc[1]; //edge 1
				adj_type & rlc = m->LowConn(r);
				if( first == rlc[0] || first == rlc[1] )
				{
					HandleType temp = first;
					first = last;
					last = temp;
				}
				else if ( !(last == rlc[0] || last == rlc[1]) )
					return false;
				adj_type::size_type it = 1, iend = lc.size()-1;
				while(it < iend) //loop over edges
				{
					adj_type const & ilc = m->LowConn(lc[it]);
					if( last == ilc[0] ) last = ilc[1];
					else if( last == ilc[1] ) last = ilc[0];
					else return false;
					++it;
				}
			}
		}
		else
		{
			if( Element::GetGeometricDimension(m->GetGeometricType(GetHandle())) == 1 ) // This face is 2d edge
			{
				adj_type const & lc = m->LowConn(GetHandle());
				return m->Count(lc.data(),lc.size(),m->HideMarker()) == 2; //it is 2d edge, check that there are 2 nodes
			}
			else
			{
				MarkerType hm = m->HideMarker();
				HandleType first, last;
				enumerator i = ENUMUNDEF, k = ENUMUNDEF, k1 = ENUMUNDEF, k2;
				adj_type const & lc = m->LowConn(GetHandle());
				if( m->Count(lc.data(),lc.size(),hm) < 3 ) return false;
				i = m->getNext(lc.data(),static_cast<enumerator>(lc.size()),i,hm);
				HandleType q = lc[i]; //edge 0
				adj_type const & qlc = m->LowConn(q);
				k = m->getNext(qlc.data(),static_cast<enumerator>(qlc.size()),k,hm);
				first = qlc[k]; //node 0
				k = m->getNext(qlc.data(),static_cast<enumerator>(qlc.size()),k,hm);
				last = qlc[k]; //node 1
				i = m->getNext(lc.data(),static_cast<enumerator>(lc.size()),i,hm);
				HandleType r = lc[i]; //edge 1
				adj_type const & rlc = m->LowConn(r);
				k1 = m->getNext(rlc.data(),static_cast<enumerator>(rlc.size()),k1,hm);
				k2 = m->getNext(rlc.data(),static_cast<enumerator>(rlc.size()),k1,hm);
				if( first == rlc[k1] || first == rlc[k2] )
				{
					HandleType temp = first;
					first = last;
					last = temp;
				}
				else if ( !(last == rlc[k1] || last == rlc[k2]) )
					return false;
				adj_type::size_type it = 1, iend = lc.size()-1;
				while(it != iend) if( !m->GetMarker(lc[it],hm) ) //loop over edges
				{
					adj_type const & ilc = m->LowConn(lc[it]);
					k1 = ENUMUNDEF; 
					k1 = m->getNext(ilc.data(),static_cast<enumerator>(ilc.size()),k1,hm);
					k2 = m->getNext(ilc.data(),static_cast<enumerator>(ilc.size()),k1,hm);
					if( last == ilc[k1] ) last = ilc[k2];
					else if( last == ilc[k2] ) last = ilc[k1];
					else return false;
					++it;
				}
			}
		}
Kirill Terekhov's avatar
Kirill Terekhov committed
228
229
230
		return true;
	}
	
Kirill Terekhov's avatar
Kirill Terekhov committed
231
	bool Face::FixEdgeOrder() const
Kirill Terekhov's avatar
Kirill Terekhov committed
232
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
233
		assert(GetHandleElementType(GetHandle())==FACE);
Kirill Terekhov's avatar
Kirill Terekhov committed
234
235
236
237
238
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
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
		Mesh * m = GetMeshLink();
		if( Element::GetGeometricDimension(m->GetGeometricType(GetHandle())) == 1 )
		{
			adj_type const & lc = m->LowConn(GetHandle());
			if( m->HideMarker() ) return m->Count(lc.data(),lc.size(),m->HideMarker()) == 2;
			else return lc.size() == 2;
		}
		else
		{
			if( !m->HideMarker() )
			{
				HandleType last, first;
				adj_type & lc = m->LowConn(GetHandle());
				if( lc.size() < 3 ) return false;
				HandleType q = lc[0]; //edge 0
				adj_type const & qlc = m->LowConn(q);
				if( qlc.size() != 2 ) return false;
				first = qlc[0]; //node 0
				last = qlc[1]; //node 1
				HandleType r = lc[1]; //edge 1
				adj_type & rlc = m->LowConn(r);
				if( rlc.size() != 2 ) return false;
				if( first == rlc[0] || first == rlc[1] )
				{
					HandleType temp = first;
					first = last;
					last = temp;
				}
				else if ( !(last == rlc[0] || last == rlc[1]) )
				{
					adj_type::size_type jt = 2, jend = lc.size();
					while(jt < jend)
					{
						adj_type const & ilc = m->LowConn(lc[jt]);
						if( ilc.size() != 2 ) return false;
						if( first == ilc[0] || first == ilc[1] )
						{
							HandleType temp = lc[1];
							lc[1] = lc[jt];
							lc[jt] = lc[1];
							temp = first;
							first = last;
							last = temp;
							break;
						}
						else if( last == ilc[0] || last == ilc[1] )
						{
							HandleType temp = lc[1];
							lc[1] = lc[jt];
							lc[jt] = lc[1];
							break;
						}
						++jt;
					}
					if( jt == jend ) return false; //no matching edge
				}
				adj_type::size_type it = 1, iend = lc.size()-1;
				while(it < iend) //loop over edges
				{
					adj_type const & ilc = m->LowConn(lc[it]);
					if( ilc.size() != 2 ) return false;
					if( last == ilc[0] ) 
					{
						last = ilc[1];
						++it;
					}
					else if( last == ilc[1] ) 
					{
						last = ilc[0];
						++it;
					}
					else //search for the connected edge and swap with current
					{
						adj_type::size_type jt = it+1, jend = lc.size();
						while(jt < jend)
						{
							adj_type const & ilc = m->LowConn(lc[jt]);
							if( ilc.size() != 2 ) return false;
							if( last == ilc[0] || last == ilc[1] )
							{
								HandleType temp = lc[it];
								lc[it] = lc[jt];
								lc[jt] = temp;
								break;
							}
						}
						if( jt == jend ) return false; //no matching edge
					}
				}
				//check that the loop is closed
				adj_type const & ilc = m->LowConn(lc[iend]);
				if( ilc.size() != 2 ) return false;
				if( !( ilc[0] == last && ilc[1] == first || ilc[0] == first && ilc[1] == last ) )
					return false;
			}
			else
			{
				HandleType first, last;
				enumerator i = ENUMUNDEF, k = ENUMUNDEF, k1 = ENUMUNDEF, k2;
				MarkerType hm = m->HideMarker();
				adj_type & lc = m->LowConn(GetHandle());
				if( m->Count(lc.data(),lc.size(),hm) < 3 ) return false;
				i = m->getNext(lc.data(),static_cast<enumerator>(lc.size()),i,hm);
				HandleType q = lc[i]; //edge 0
				adj_type const & qlc = m->LowConn(q);
				if(m->Count(qlc.data(),qlc.size(),hm)!=2) return false;
				k = m->getNext(qlc.data(),static_cast<enumerator>(qlc.size()),k,hm);
				first = qlc[k]; //node 0
				k = m->getNext(qlc.data(),static_cast<enumerator>(qlc.size()),k,hm);
				last = qlc[k]; //node 1
				i = m->getNext(lc.data(),static_cast<enumerator>(lc.size()),i,hm);
				HandleType r = lc[i]; //edge 1
				adj_type const & rlc = m->LowConn(r);
				if(m->Count(rlc.data(),rlc.size(),hm)!=2) return false;
				k1 = m->getNext(rlc.data(),static_cast<enumerator>(rlc.size()),k1,hm);
				k2 = m->getNext(rlc.data(),static_cast<enumerator>(rlc.size()),k1,hm);
				if( first == rlc[k1] || first == rlc[k2] )
				{
					HandleType temp = first;
					first = last;
					last = temp;
				}
				else if( !(last == rlc[k1] || last == rlc[k2]) )
				{
					adj_type::size_type jt = i+1, jend = lc.size();
					while(jt < jend) if( !m->GetMarker(lc[jt],hm) ) //loop over edges
					{
						adj_type const & ilc = m->LowConn(lc[jt]);
						if( m->Count(ilc.data(),ilc.size(),hm) != 2 ) return false;
						k1 = ENUMUNDEF; 
						k1 = m->getNext(ilc.data(),static_cast<enumerator>(ilc.size()),k1,hm);
						k2 = m->getNext(ilc.data(),static_cast<enumerator>(ilc.size()),k1,hm);
						if( first == ilc[k1] || first == ilc[k2] )
						{
							HandleType temp = lc[i];
							lc[i] = lc[jt];
							lc[jt] = lc[i];
							temp = first;
							first = last;
							last = temp;
							break;
						}
						else if( last == ilc[k1] || last == ilc[k2] )
						{
							HandleType temp = lc[i];
							lc[i] = lc[jt];
							lc[jt] = lc[i];
							break;
						}
						++jt;
					}
					if( jt == jend ) return false; //no matching edge
				}
				adj_type::size_type it = i, iend = lc.size()-1;
				while(it != iend) if( !m->GetMarker(lc[it],hm) ) //loop over edges
				{
					adj_type const & ilc = m->LowConn(lc[it]);
					if(m->Count(ilc.data(),ilc.size(),hm)!=2) return false;
					k1 = ENUMUNDEF; 
					k1 = m->getNext(ilc.data(),static_cast<enumerator>(ilc.size()),k1,hm);
					k2 = m->getNext(ilc.data(),static_cast<enumerator>(ilc.size()),k1,hm);
					if( last == ilc[k1] ) 
					{
						last = ilc[k2];
						++it;
					}
					else if( last == ilc[k2] )
					{
						last = ilc[k1];
						++it;
					}
					else//search for the connected edge and swap with current
					{
						adj_type::size_type jt = it+1, jend = lc.size();
						while(jt < jend) if( !m->GetMarker(lc[jt],hm) ) //loop over edges
						{
							adj_type const & ilc = m->LowConn(lc[jt]);
							if(m->Count(ilc.data(),ilc.size(),hm)!=2) return false;
							k1 = ENUMUNDEF; 
							k1 = m->getNext(ilc.data(),static_cast<enumerator>(ilc.size()),k1,hm);
							k2 = m->getNext(ilc.data(),static_cast<enumerator>(ilc.size()),k1,hm);
							if( last == ilc[k1] || last == ilc[k2] )
							{
								HandleType temp = lc[it];
								lc[it] = lc[jt];
								lc[jt] = temp;
								break;
							}
						}
						if( jt == jend ) return false; //no matching edge
					}
				}
				//check that the loop is closed
				adj_type const & ilc = m->LowConn(lc[iend]);
				if(m->Count(ilc.data(),ilc.size(),hm)!=2) return false;
				k1 = ENUMUNDEF; 
				k1 = m->getNext(ilc.data(),static_cast<enumerator>(ilc.size()),k1,hm);
				k2 = m->getNext(ilc.data(),static_cast<enumerator>(ilc.size()),k1,hm);
				if( !( ilc[k1] == last && ilc[k2] == first || ilc[k1] == first && ilc[k2] == last ) )
					return false;
			}
		}
		return true;
Kirill Terekhov's avatar
Kirill Terekhov committed
437
438
439
	}
	
	
Kirill Terekhov's avatar
Kirill Terekhov committed
440
	ElementArray<Node> Face::getNodes() const
Kirill Terekhov's avatar
Kirill Terekhov committed
441
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
442
443
444
445
		assert(GetHandleElementType(GetHandle())==FACE);
		Mesh * m = GetMeshLink();
		ElementArray<Node> aret(m);
		if( !m->HideMarker() )
Kirill Terekhov's avatar
Kirill Terekhov committed
446
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
447
			if( Element::GetGeometricDimension(m->GetGeometricType(GetHandle())) == 1 ) // This face is 2d edge
Kirill Terekhov's avatar
Kirill Terekhov committed
448
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
449
				adj_type const & lc = m->LowConn(GetHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
450
				aret.reserve(lc.size());
Kirill Terekhov's avatar
Kirill Terekhov committed
451
452
				for(adj_type::size_type it = 0; it < lc.size(); it++) //iterate over edges that are of type Vertex
					aret.push_back(m->LowConn(lc[it]).front());
Kirill Terekhov's avatar
Kirill Terekhov committed
453
454
455
			}
			else
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
456
				adj_type const & lc = m->LowConn(GetHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
457
				assert(lc.size() > 2); // it should be at least triangle
Kirill Terekhov's avatar
Kirill Terekhov committed
458
				aret.reserve(lc.size());
Kirill Terekhov's avatar
Kirill Terekhov committed
459
460
				HandleType q = lc[0]; //edge 0
				adj_type const & qlc = m->LowConn(q);
Kirill Terekhov's avatar
Kirill Terekhov committed
461
				assert(qlc.size() == 2);
Kirill Terekhov's avatar
Kirill Terekhov committed
462
463
				aret.push_back(qlc[0]); //node 0
				aret.push_back(qlc[1]); //node 1
Kirill Terekhov's avatar
Kirill Terekhov committed
464
465
				HandleType r = lc[1]; //edge 1
				adj_type & rlc = m->LowConn(r);
Kirill Terekhov's avatar
Kirill Terekhov committed
466
				assert(rlc.size() == 2);
Kirill Terekhov's avatar
Kirill Terekhov committed
467
				if( aret.data()[0] == rlc[0] || aret.data()[0] == rlc[1] )
Kirill Terekhov's avatar
Kirill Terekhov committed
468
				{
Kirill Terekhov's avatar
Kirill Terekhov committed
469
					HandleType temp = aret.data()[0];
Kirill Terekhov's avatar
Kirill Terekhov committed
470
471
472
					aret.data()[0] = aret.data()[1];
					aret.data()[1] = temp;
				}
Kirill Terekhov's avatar
Kirill Terekhov committed
473
				adj_type::size_type it = 1, iend = lc.size()-1;
Kirill Terekhov's avatar
Kirill Terekhov committed
474
				while(it < iend) //loop over edges
Kirill Terekhov's avatar
Kirill Terekhov committed
475
				{
Kirill Terekhov's avatar
Kirill Terekhov committed
476
					adj_type const & ilc = m->LowConn(lc[it]);
Kirill Terekhov's avatar
Kirill Terekhov committed
477
					assert(ilc.size() == 2);
Kirill Terekhov's avatar
Kirill Terekhov committed
478
					if( aret.atback() == ilc[0] ) aret.push_back(ilc[1]);
Kirill Terekhov's avatar
Kirill Terekhov committed
479
					else aret.push_back(ilc[0]);
Kirill Terekhov's avatar
Kirill Terekhov committed
480
481
482
483
484
485
					++it;
				}
			}
		}
		else
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
486
487
			MarkerType hm = m->HideMarker();
			if( Element::GetGeometricDimension(m->GetGeometricType(GetHandle())) == 1 ) // This face is 2d edge
Kirill Terekhov's avatar
Kirill Terekhov committed
488
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
489
				adj_type const & lc = m->LowConn(GetHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
490
				aret.reserve(lc.size());
Kirill Terekhov's avatar
Kirill Terekhov committed
491
492
				for(adj_type::size_type it = 0; it < lc.size(); it++) //iterate over edges that are of type Vertex
					if( !m->GetMarker(lc[it],hm) ) 
Kirill Terekhov's avatar
Kirill Terekhov committed
493
					{
Kirill Terekhov's avatar
Kirill Terekhov committed
494
						adj_type const & ilc = m->LowConn(lc[it]);
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
495
496
497
						enumerator i = ENUMUNDEF;
						i = m->getNext(ilc.data(),static_cast<enumerator>(ilc.size()),i,hm);
						if( i < static_cast<enumerator>(ilc.size()) ) aret.push_back(ilc[i]);
Kirill Terekhov's avatar
Kirill Terekhov committed
498
					}
Kirill Terekhov's avatar
Kirill Terekhov committed
499
500
501
			}
			else
			{
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
502
				enumerator i = ENUMUNDEF, k = ENUMUNDEF, k1 = ENUMUNDEF, k2;
Kirill Terekhov's avatar
Kirill Terekhov committed
503
				adj_type const & lc = m->LowConn(GetHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
504
				aret.reserve(lc.size());
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
505
				i = m->getNext(lc.data(),static_cast<enumerator>(lc.size()),i,hm);
Kirill Terekhov's avatar
Kirill Terekhov committed
506
507
				HandleType q = lc[i]; //edge 0
				adj_type const & qlc = m->LowConn(q);
Kirill Terekhov's avatar
Kirill Terekhov committed
508
				assert(m->Count(qlc.data(),qlc.size(),hm)==2);
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
509
				k = m->getNext(qlc.data(),static_cast<enumerator>(qlc.size()),k,hm);
Kirill Terekhov's avatar
Kirill Terekhov committed
510
				aret.push_back(qlc[k]); //node 0
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
511
				k = m->getNext(qlc.data(),static_cast<enumerator>(qlc.size()),k,hm);
Kirill Terekhov's avatar
Kirill Terekhov committed
512
				aret.push_back(qlc[k]); //node 1
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
513
				i = m->getNext(lc.data(),static_cast<enumerator>(lc.size()),i,hm);
Kirill Terekhov's avatar
Kirill Terekhov committed
514
515
				HandleType r = lc[i]; //edge 1
				adj_type const & rlc = m->LowConn(r);
Kirill Terekhov's avatar
Kirill Terekhov committed
516
				assert(m->Count(rlc.data(),rlc.size(),hm)==2);
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
517
518
				k1 = m->getNext(rlc.data(),static_cast<enumerator>(rlc.size()),k1,hm);
				k2 = m->getNext(rlc.data(),static_cast<enumerator>(rlc.size()),k1,hm);
Kirill Terekhov's avatar
Kirill Terekhov committed
519
				if( aret.data()[0] == rlc[k1] || aret.data()[0] == rlc[k2] )
Kirill Terekhov's avatar
Kirill Terekhov committed
520
				{
Kirill Terekhov's avatar
Kirill Terekhov committed
521
					HandleType temp = aret.data()[0];
Kirill Terekhov's avatar
Kirill Terekhov committed
522
523
524
					aret.data()[0] = aret.data()[1];
					aret.data()[1] = temp;
				}
Kirill Terekhov's avatar
Kirill Terekhov committed
525
				adj_type::size_type it = i, iend = lc.size()-1;
Kirill Terekhov's avatar
Kirill Terekhov committed
526
				while(it != iend) if( !m->GetMarker(lc[it],hm) ) //loop over edges
Kirill Terekhov's avatar
Kirill Terekhov committed
527
				{
Kirill Terekhov's avatar
Kirill Terekhov committed
528
					adj_type const & ilc = m->LowConn(lc[it]);
Kirill Terekhov's avatar
Kirill Terekhov committed
529
					assert(m->Count(ilc.data(),ilc.size(),hm)==2);
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
530
531
532
					k1 = ENUMUNDEF; 
					k1 = m->getNext(ilc.data(),static_cast<enumerator>(ilc.size()),k1,hm);
					k2 = m->getNext(ilc.data(),static_cast<enumerator>(ilc.size()),k1,hm);
Kirill Terekhov's avatar
Kirill Terekhov committed
533
534
535
536
					if( aret.atback() == ilc[k1] ) 
						aret.push_back(ilc[k2]);
					else 
						aret.push_back(ilc[k1]);
Kirill Terekhov's avatar
Kirill Terekhov committed
537
538
539
540
541
542
543
					++it;
				}
			}

		}
		return aret;
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
544
545


Kirill Terekhov's avatar
Kirill Terekhov committed
546
	ElementArray<Node> Face::getNodes(MarkerType mask, bool invert) const
Kirill Terekhov's avatar
Kirill Terekhov committed
547
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
548
549
550
551
		assert(GetHandleElementType(GetHandle())==FACE);
		Mesh * m = GetMeshLink();
		ElementArray<Node> aret(m);
		if( !m->HideMarker() )
Kirill Terekhov's avatar
Kirill Terekhov committed
552
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
553
			if(  Element::GetGeometricDimension(m->GetGeometricType(GetHandle())) == 1 ) // This face is 2d edge
Kirill Terekhov's avatar
Kirill Terekhov committed
554
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
555
				adj_type const & lc = m->LowConn(GetHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
556
				aret.reserve(lc.size());
Kirill Terekhov's avatar
Kirill Terekhov committed
557
				for(adj_type::size_type it = 0; it < lc.size(); it++) //iterate over edges that are of type Vertex
Kirill Terekhov's avatar
Kirill Terekhov committed
558
				{
Kirill Terekhov's avatar
Kirill Terekhov committed
559
560
					HandleType e = m->LowConn(lc[it]).front();
					if( invert ^ m->GetMarker(e,mask) ) aret.push_back(e);
Kirill Terekhov's avatar
Kirill Terekhov committed
561
				}
Kirill Terekhov's avatar
Kirill Terekhov committed
562
563
564
			}
			else
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
565
				adj_type const & lc = m->LowConn(GetHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
566
				aret.reserve(lc.size());
Kirill Terekhov's avatar
Kirill Terekhov committed
567
568
569
570
571
572
573
				HandleType q = lc[0];
				adj_type const & qlc = m->LowConn(q);
				HandleType first = qlc[0], last = qlc[1]; //edge 0
				if( invert ^ m->GetMarker(qlc[0],mask) ) aret.push_back(qlc[0]); //node 0
				if( invert ^ m->GetMarker(qlc[1],mask) ) aret.push_back(qlc[1]); //node 1
				HandleType r = lc[1]; //edge 1
				adj_type const & rlc = m->LowConn(r);
Kirill Terekhov's avatar
Kirill Terekhov committed
574
				if( first == rlc[0] || first == rlc[1] ) 
Kirill Terekhov's avatar
Kirill Terekhov committed
575
576
577
578
				{
					last = first;
					if( aret.size() > 1 )
					{
Kirill Terekhov's avatar
Kirill Terekhov committed
579
						HandleType temp = aret.data()[0];
Kirill Terekhov's avatar
Kirill Terekhov committed
580
581
582
583
						aret.data()[0] = aret.data()[1];
						aret.data()[1] = temp;
					}
				}
Kirill Terekhov's avatar
Kirill Terekhov committed
584
				adj_type::size_type it = 1, iend = lc.size()-1;
Kirill Terekhov's avatar
Kirill Terekhov committed
585
				while(it < iend) //loop over edges
Kirill Terekhov's avatar
Kirill Terekhov committed
586
				{
Kirill Terekhov's avatar
Kirill Terekhov committed
587
					adj_type const & ilc = m->LowConn(lc[it]);
Kirill Terekhov's avatar
Kirill Terekhov committed
588
					if( last == ilc[0] ) 
Kirill Terekhov's avatar
Kirill Terekhov committed
589
					{
Kirill Terekhov's avatar
Kirill Terekhov committed
590
						if( invert ^ m->GetMarker(ilc[1],mask) ) 
Kirill Terekhov's avatar
Kirill Terekhov committed
591
592
							aret.push_back(ilc[1]);
						last = ilc[1];
Kirill Terekhov's avatar
Kirill Terekhov committed
593
594
595
					}
					else 
					{
Kirill Terekhov's avatar
Kirill Terekhov committed
596
						if( invert ^ m->GetMarker(ilc[0],mask) )
Kirill Terekhov's avatar
Kirill Terekhov committed
597
598
							aret.push_back(ilc[0]);
						last = ilc[0];
Kirill Terekhov's avatar
Kirill Terekhov committed
599
600
601
602
603
604
605
					}
					++it;
				}
			}
		}
		else
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
606
607
			MarkerType hm = m->HideMarker();
			if( Element::GetGeometricDimension(m->GetGeometricType(GetHandle())) == 1 ) // This face is 2d edge
Kirill Terekhov's avatar
Kirill Terekhov committed
608
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
609
				adj_type const & lc = m->LowConn(GetHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
610
				aret.reserve(lc.size());
Kirill Terekhov's avatar
Kirill Terekhov committed
611
612
				for(adj_type::size_type it = 0; it < lc.size(); it++) //iterate over edges that are of type Vertex
					if( !m->GetMarker(lc[it],hm) ) 
Kirill Terekhov's avatar
Kirill Terekhov committed
613
					{
Kirill Terekhov's avatar
Kirill Terekhov committed
614
						adj_type const & ilc = m->LowConn(lc[it]);
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
615
616
617
						enumerator i = ENUMUNDEF;
						i = m->getNext(ilc.data(),static_cast<enumerator>(ilc.size()),i,hm);
						if( i < static_cast<enumerator>(ilc.size()) && (invert ^ m->GetMarker(ilc[i],mask)) ) 
Kirill Terekhov's avatar
Kirill Terekhov committed
618
							aret.push_back(ilc[i]);
Kirill Terekhov's avatar
Kirill Terekhov committed
619
620
621
622
					}
			}
			else
			{
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
623
				enumerator i = ENUMUNDEF, k = ENUMUNDEF, k1 = ENUMUNDEF, k2;
Kirill Terekhov's avatar
Kirill Terekhov committed
624
				adj_type const & lc = m->LowConn(GetHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
625
				aret.reserve(lc.size());
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
626
				i = m->getNext(lc.data(),static_cast<enumerator>(lc.size()),i,hm);
Kirill Terekhov's avatar
Kirill Terekhov committed
627
628
				HandleType q = lc[i], first, last; //edge 0
				adj_type const & qlc = m->LowConn(q);
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
629
				k = m->getNext(qlc.data(),static_cast<enumerator>(qlc.size()),k,hm);
Kirill Terekhov's avatar
Kirill Terekhov committed
630
				if( invert ^ m->GetMarker(qlc[k],mask) ) aret.push_back(qlc[k]); //node 0
Kirill Terekhov's avatar
Kirill Terekhov committed
631
				first = qlc[k];
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
632
				k = m->getNext(qlc.data(),static_cast<enumerator>(qlc.size()),k,hm);
Kirill Terekhov's avatar
Kirill Terekhov committed
633
				if( invert ^ m->GetMarker(qlc[k],mask) ) aret.push_back(qlc[k]); //node 1
Kirill Terekhov's avatar
Kirill Terekhov committed
634
				last = qlc[k];
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
635
				i = m->getNext(lc.data(),static_cast<enumerator>(lc.size()),i,hm);
Kirill Terekhov's avatar
Kirill Terekhov committed
636
637
				HandleType r = lc[i]; //edge 1
				adj_type const & rlc = m->LowConn(r);
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
638
639
				k1 = m->getNext(rlc.data(),static_cast<enumerator>(rlc.size()),k1,hm);
				k2 = m->getNext(rlc.data(),static_cast<enumerator>(rlc.size()),k1,hm);
Kirill Terekhov's avatar
Kirill Terekhov committed
640
				if( first == rlc[k1] || first == rlc[k2] )
Kirill Terekhov's avatar
Kirill Terekhov committed
641
642
643
644
				{
					last = first;
					if( aret.size() > 1 )
					{
Kirill Terekhov's avatar
Kirill Terekhov committed
645
						HandleType temp = aret.data()[0];
Kirill Terekhov's avatar
Kirill Terekhov committed
646
647
648
649
						aret.data()[0] = aret.data()[1];
						aret.data()[1] = temp;
					}
				}
Kirill Terekhov's avatar
Kirill Terekhov committed
650
651
				adj_type::size_type it = 1, iend = lc.size()-1;
				while(it < iend) if( !m->GetMarker(lc[it],hm) ) //loop over edges
Kirill Terekhov's avatar
Kirill Terekhov committed
652
				{
Kirill Terekhov's avatar
Kirill Terekhov committed
653
					adj_type const & ilc = m->LowConn(lc[it]);
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
654
655
656
					k1 = ENUMUNDEF; 
					k1 = m->getNext(ilc.data(),static_cast<enumerator>(ilc.size()),k1,hm);
					k2 = m->getNext(ilc.data(),static_cast<enumerator>(ilc.size()),k1,hm);
Kirill Terekhov's avatar
Kirill Terekhov committed
657
					if( last == ilc[k1] ) 
Kirill Terekhov's avatar
Kirill Terekhov committed
658
					{
Kirill Terekhov's avatar
Kirill Terekhov committed
659
660
						if( invert ^ m->GetMarker(ilc[k2],mask) ) 
							aret.push_back(ilc[k2]);
Kirill Terekhov's avatar
Kirill Terekhov committed
661
						last = ilc[k2];
Kirill Terekhov's avatar
Kirill Terekhov committed
662
663
664
					}
					else 
					{
Kirill Terekhov's avatar
Kirill Terekhov committed
665
666
						if( invert ^ m->GetMarker(ilc[k1],mask) ) 
							aret.push_back(ilc[k1]);
Kirill Terekhov's avatar
Kirill Terekhov committed
667
						last = ilc[k1];
Kirill Terekhov's avatar
Kirill Terekhov committed
668
669
670
671
672
673
674
675
676
					}
					++it;
				}
			}

		}
		return aret;
	}

Kirill Terekhov's avatar
Kirill Terekhov committed
677
	ElementArray<Edge> Face::getEdges() const
Kirill Terekhov's avatar
Kirill Terekhov committed
678
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
679
680
681
		assert(GetHandleElementType(GetHandle())==FACE);
		Mesh * m = GetMeshLink();
		if( !m->HideMarker() )
Kirill Terekhov's avatar
Kirill Terekhov committed
682
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
683
684
			adj_type const & lc = m->LowConn(GetHandle());
			return ElementArray<Edge>(m,lc.data(),lc.data()+lc.size());
Kirill Terekhov's avatar
Kirill Terekhov committed
685
		}
Kirill Terekhov's avatar
Kirill Terekhov committed
686
687
		else
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
688
689
690
691
692
693
			MarkerType hm = m->HideMarker();
			ElementArray<Edge> aret(m);
			adj_type const & lc = m->LowConn(GetHandle());
			for(adj_type::size_type it = 0; it < lc.size(); ++it)
				if( !m->GetMarker(lc[it],hm) ) 
					aret.push_back(lc[it]);
Kirill Terekhov's avatar
Kirill Terekhov committed
694
695
696
			return aret;
		}
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
697

Kirill Terekhov's avatar
Kirill Terekhov committed
698
	ElementArray<Edge> Face::getEdges(MarkerType mask, bool invert) const
Kirill Terekhov's avatar
Kirill Terekhov committed
699
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
700
701
702
703
		assert(GetHandleElementType(GetHandle())==FACE);
		Mesh * m = GetMeshLink();
		ElementArray<Edge> aret(m);
		if( !m->HideMarker() )
Kirill Terekhov's avatar
Kirill Terekhov committed
704
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
705
706
707
708
			adj_type const & lc = m->LowConn(GetHandle());
			for(adj_type::size_type it = 0; it < lc.size(); ++it)
				if( invert ^ m->GetMarker(lc[it],mask) ) 
					aret.push_back(lc[it]);
Kirill Terekhov's avatar
Kirill Terekhov committed
709
710
711
		}
		else
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
712
713
714
715
716
			MarkerType hm = m->HideMarker();
			adj_type const & lc = m->LowConn(GetHandle());
			for(adj_type::size_type it = 0; it < lc.size(); ++it)
				if( (invert ^ m->GetMarker(lc[it],mask)) && !m->GetMarker(lc[it],hm) ) 
					aret.push_back(lc[it]);
Kirill Terekhov's avatar
Kirill Terekhov committed
717
718
719
720
		}
		return aret;
	}

Kirill Terekhov's avatar
Kirill Terekhov committed
721
	ElementArray<Cell> Face::getCells() const
Kirill Terekhov's avatar
Kirill Terekhov committed
722
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
723
724
		assert(GetHandleElementType(GetHandle())==FACE);
		Mesh * m = GetMeshLink();
Kirill Terekhov's avatar
Kirill Terekhov committed
725
		if( !GetMeshLink()->HideMarker() )
Kirill Terekhov's avatar
Kirill Terekhov committed
726
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
727
728
			adj_type const & hc = m->HighConn(GetHandle());
			return ElementArray<Cell>(m,hc.data(),hc.data()+hc.size());
Kirill Terekhov's avatar
Kirill Terekhov committed
729
		}
Kirill Terekhov's avatar
Kirill Terekhov committed
730
731
		else
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
732
733
734
735
736
737
			MarkerType hm = m->HideMarker();
			ElementArray<Cell> aret(m);
			adj_type const & hc = m->HighConn(GetHandle());
			for(adj_type::size_type it = 0; it < hc.size(); ++it)
				if( !m->GetMarker(hc[it],hm) ) 
					aret.push_back(hc[it]);
Kirill Terekhov's avatar
Kirill Terekhov committed
738
739
740
			return aret;
		}
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
741

Kirill Terekhov's avatar
Kirill Terekhov committed
742
	ElementArray<Cell> Face::getCells(MarkerType mask, bool invert) const
Kirill Terekhov's avatar
Kirill Terekhov committed
743
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
744
745
746
747
		assert(GetHandleElementType(GetHandle())==FACE);
		Mesh * m = GetMeshLink();
		ElementArray<Cell> aret(m);
		if( !m->HideMarker() )
Kirill Terekhov's avatar
Kirill Terekhov committed
748
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
749
750
751
752
			adj_type const & hc = m->HighConn(GetHandle());
			for(adj_type::size_type it = 0; it < hc.size(); ++it)
				if( invert ^ m->GetMarker(hc[it],mask)) 
					aret.push_back(hc[it]);
Kirill Terekhov's avatar
Kirill Terekhov committed
753
754
755
		}
		else
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
756
			MarkerType hm = GetMeshLink()->HideMarker();
Kirill Terekhov's avatar
Kirill Terekhov committed
757
758
759
760
			adj_type const & hc = m->HighConn(GetHandle());
			for(adj_type::size_type it = 0; it < hc.size(); ++it)
				if( (invert ^ m->GetMarker(hc[it],mask)) && !m->GetMarker(hc[it],hm) ) 
					aret.push_back(hc[it]);
Kirill Terekhov's avatar
Kirill Terekhov committed
761
762
763
764
		}
		return aret;
	}

Kirill Terekhov's avatar
Kirill Terekhov committed
765
	
Kirill Terekhov's avatar
Kirill Terekhov committed
766
767
}
#endif