cell.cpp 19.7 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
	bool Cell::CheckEdgeOrder() const
Kirill Terekhov's avatar
Kirill Terekhov committed
9
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
10
		assert(GetHandleElementType(GetHandle())==CELL);
Kirill Terekhov's avatar
Kirill Terekhov committed
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
		Mesh * m = GetMeshLink();
		if( Element::GetGeometricDimension(m->GetGeometricType(GetHandle())) == 2 )
		{
			if( !m->HideMarker() )
			{
				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
			{
				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
84
85
86
		return true;
	}
	
Kirill Terekhov's avatar
Kirill Terekhov committed
87
	bool Cell::FixEdgeOrder() const
Kirill Terekhov's avatar
Kirill Terekhov committed
88
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
89
		assert(GetHandleElementType(GetHandle())==CELL);
Kirill Terekhov's avatar
Kirill Terekhov committed
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
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
228
229
230
231
232
233
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
		Mesh * m = GetMeshLink();
		if( Element::GetGeometricDimension(m->GetGeometricType(GetHandle())) == 2 )
		{
			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;
			}
		}
Kirill Terekhov's avatar
Kirill Terekhov committed
286
287
288
		return false;
	}
	
Kirill Terekhov's avatar
Kirill Terekhov committed
289
	ElementArray<Node> Cell::getNodes() const
Kirill Terekhov's avatar
Kirill Terekhov committed
290
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
291
292
293
		assert(GetHandleElementType(GetHandle())==CELL);
		Mesh * m = GetMeshLink();
		if( !m->HideMarker() )
Kirill Terekhov's avatar
Kirill Terekhov committed
294
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
295
296
			adj_type const & hc = m->HighConn(GetHandle());
			return ElementArray<Node>(m,hc.data(),hc.data()+hc.size());
Kirill Terekhov's avatar
Kirill Terekhov committed
297
		}
Kirill Terekhov's avatar
Kirill Terekhov committed
298
299
		else
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
300
301
302
303
304
			MarkerType hm = m->HideMarker();
			ElementArray<Node> 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
305
306
307
			return aret;
		}
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
308
309


Kirill Terekhov's avatar
Kirill Terekhov committed
310
	ElementArray<Node> Cell::getNodes(MarkerType mask, bool invert) const
Kirill Terekhov's avatar
Kirill Terekhov committed
311
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
312
313
314
315
		assert(GetHandleElementType(GetHandle())==CELL);
		Mesh * m = GetMeshLink();
		ElementArray<Node> aret(m);
		if( !m->HideMarker() )
Kirill Terekhov's avatar
Kirill Terekhov committed
316
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
317
318
319
320
			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
321
322
323
		}
		else
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
324
325
326
327
328
			MarkerType hm = m->HideMarker();
			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
329
330
331
332
		}
		return aret;
	}

Kirill Terekhov's avatar
Kirill Terekhov committed
333
	ElementArray<Edge> Cell::getEdges() const
Kirill Terekhov's avatar
Kirill Terekhov committed
334
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
335
336
337
338
		assert(GetHandleElementType(GetHandle())==CELL);
		Mesh * m = GetMeshLink();
		ElementArray<Edge> aret(m);
		if( !m->HideMarker() )
Kirill Terekhov's avatar
Kirill Terekhov committed
339
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
340
			if( Element::GetGeometricDimension(m->GetGeometricType(GetHandle())) == 2 ) // This cell is 2d face
Kirill Terekhov's avatar
Kirill Terekhov committed
341
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
342
				adj_type const & lc = m->LowConn(GetHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
343
				aret.reserve(lc.size());
Kirill Terekhov's avatar
Kirill Terekhov committed
344
				if( lc.size() < 1 ) return aret;
Kirill Terekhov's avatar
Kirill Terekhov committed
345
346
				HandleType q = lc[0]; //edge 0
				adj_type const & qlc = m->LowConn(q);
Kirill Terekhov's avatar
Kirill Terekhov committed
347
348
349
				if( qlc.size() > 0 ) aret.push_back(qlc[0]); //node 0
				if( qlc.size() > 1 ) aret.push_back(qlc[1]); //node 1
				if( lc.size() < 2 ) return aret;
Kirill Terekhov's avatar
Kirill Terekhov committed
350
351
				HandleType r = lc[1]; //edge 1
				adj_type const & rlc = m->LowConn(r);
Kirill Terekhov's avatar
Kirill Terekhov committed
352
				if( aret.size() == 2 && rlc.size() == 2 )
Kirill Terekhov's avatar
Kirill Terekhov committed
353
				{
Kirill Terekhov's avatar
Kirill Terekhov committed
354
355
356
357
358
359
					if( aret.data()[0] == rlc[0] || aret.data()[0] == rlc[1] )
					{
						HandleType temp = aret.data()[0];
						aret.data()[0] = aret.data()[1];
						aret.data()[1] = temp;
					}
Kirill Terekhov's avatar
Kirill Terekhov committed
360
				}
Kirill Terekhov's avatar
Kirill Terekhov committed
361
				adj_type::size_type it = 1, iend = lc.size()-1;
Kirill Terekhov's avatar
Kirill Terekhov committed
362
363
				while(it < iend) //loop over edges
				{
Kirill Terekhov's avatar
Kirill Terekhov committed
364
365
366
367
368
					adj_type const & ilc = m->LowConn(lc[it]);
					if( aret.atback() == ilc[0] ) 
						aret.push_back(ilc[1]);
					else 
						aret.push_back(ilc[0]);
Kirill Terekhov's avatar
Kirill Terekhov committed
369
370
					++it;
				}
Kirill Terekhov's avatar
Kirill Terekhov committed
371
372
373
			}
			else
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
374
				MarkerType mrk = m->CreateMarker();
Kirill Terekhov's avatar
Kirill Terekhov committed
375
376
				adj_type const & lc = m->LowConn(GetHandle());
				for(adj_type::size_type it = 0; it < lc.size(); it++) //faces
Kirill Terekhov's avatar
Kirill Terekhov committed
377
				{
Kirill Terekhov's avatar
Kirill Terekhov committed
378
379
380
					adj_type const & ilc = m->LowConn(lc[it]);
					for(adj_type::size_type jt = 0; jt < ilc.size(); jt++) //edges
						if( !m->GetMarker(ilc[jt],mrk))
Kirill Terekhov's avatar
Kirill Terekhov committed
381
						{
Kirill Terekhov's avatar
Kirill Terekhov committed
382
							aret.push_back(ilc[jt]);
Kirill Terekhov's avatar
Kirill Terekhov committed
383
							m->SetMarker(ilc[jt],mrk);
Kirill Terekhov's avatar
Kirill Terekhov committed
384
						}
Kirill Terekhov's avatar
Kirill Terekhov committed
385
				}
Kirill Terekhov's avatar
Kirill Terekhov committed
386
387
				for(ElementArray<Edge>::size_type it = 0; it < aret.size(); it++)
					m->RemMarker(aret.at(it),mrk);
Kirill Terekhov's avatar
Kirill Terekhov committed
388
389
390
391
392
				m->ReleaseMarker(mrk);
			}
		}
		else
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
393
394
			MarkerType hm = m->HideMarker();
			if( Element::GetGeometricDimension(m->GetGeometricType(GetHandle())) == 2 ) // This cell is 2d face
Kirill Terekhov's avatar
Kirill Terekhov committed
395
			{
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
396
				enumerator i = ENUMUNDEF, k = ENUMUNDEF, k1 = ENUMUNDEF, k2;
Kirill Terekhov's avatar
Kirill Terekhov committed
397
				adj_type const & lc = m->LowConn(GetHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
398
				aret.reserve(lc.size());
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
399
				i = m->getNext(lc.data(),static_cast<enumerator>(lc.size()),i,hm);
Kirill Terekhov's avatar
Kirill Terekhov committed
400
				if( i == lc.size() ) return aret;
Kirill Terekhov's avatar
Kirill Terekhov committed
401
402
				HandleType q = lc[i]; //edge 0
				adj_type const & qlc = m->LowConn(q);
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
403
				k = m->getNext(qlc.data(),static_cast<enumerator>(qlc.size()),k,hm);
Kirill Terekhov's avatar
Kirill Terekhov committed
404
				if( k != qlc.size() ) aret.push_back(qlc[k]); //node 0
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
405
				k = m->getNext(qlc.data(),static_cast<enumerator>(qlc.size()),k,hm);
Kirill Terekhov's avatar
Kirill Terekhov committed
406
				if( k != qlc.size() ) aret.push_back(qlc[k]); //node 1
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
407
				i = m->getNext(lc.data(),static_cast<enumerator>(lc.size()),i,hm);
Kirill Terekhov's avatar
Kirill Terekhov committed
408
				if( i == lc.size() ) return aret;
Kirill Terekhov's avatar
Kirill Terekhov committed
409
410
				HandleType r = lc[i]; //edge 1
				adj_type const & rlc = m->LowConn(r);
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
411
412
				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
413
				if( k1 != rlc.size() && k2 != rlc.size() && aret.size() == 2 )
Kirill Terekhov's avatar
Kirill Terekhov committed
414
				{
Kirill Terekhov's avatar
Kirill Terekhov committed
415
416
417
418
419
420
					if( aret.data()[0] == rlc[k1] || aret.data()[0] == rlc[k2] )
					{
						HandleType temp = aret.data()[0];
						aret.data()[0] = aret.data()[1];
						aret.data()[1] = temp;
					}
Kirill Terekhov's avatar
Kirill Terekhov committed
421
				}
Kirill Terekhov's avatar
Kirill Terekhov committed
422
423
				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
424
				{
Kirill Terekhov's avatar
Kirill Terekhov committed
425
					adj_type const & ilc = m->LowConn(lc[it]);
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
426
427
428
					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
429
430
431
432
					if( aret.atback() == ilc[k1] ) 
						aret.push_back(ilc[k2]);
					else 
						aret.push_back(ilc[k1]);
Kirill Terekhov's avatar
Kirill Terekhov committed
433
434
435
436
437
					++it;
				}
			}
			else
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
438
				MarkerType mrk = m->CreateMarker();
Kirill Terekhov's avatar
Kirill Terekhov committed
439
440
				adj_type const & lc = m->LowConn(GetHandle());
				for(adj_type::size_type it = 0; it < lc.size(); it++) if( !m->GetMarker(lc[it],hm) ) //faces
Kirill Terekhov's avatar
Kirill Terekhov committed
441
				{
Kirill Terekhov's avatar
Kirill Terekhov committed
442
443
444
					adj_type const & ilc = m->LowConn(lc[it]);
					for(adj_type::size_type jt = 0; jt < ilc.size(); jt++) if( !m->GetMarker(ilc[jt],hm) )//edges
						if( !m->GetMarker(ilc[jt],mrk))
Kirill Terekhov's avatar
Kirill Terekhov committed
445
						{
Kirill Terekhov's avatar
Kirill Terekhov committed
446
							aret.push_back(ilc[jt]);
Kirill Terekhov's avatar
Kirill Terekhov committed
447
							m->SetMarker(ilc[jt],mrk);
Kirill Terekhov's avatar
Kirill Terekhov committed
448
						}
Kirill Terekhov's avatar
Kirill Terekhov committed
449
				}
Kirill Terekhov's avatar
Kirill Terekhov committed
450
451
				for(ElementArray<Edge>::size_type it = 0; it < aret.size(); it++)
					m->RemMarker(aret.at(it),mrk);
Kirill Terekhov's avatar
Kirill Terekhov committed
452
453
454
455
456
				m->ReleaseMarker(mrk);
			}
		}
		return aret;
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
457
458


Kirill Terekhov's avatar
Kirill Terekhov committed
459
	ElementArray<Edge> Cell::getEdges(MarkerType mask, bool invert) const
Kirill Terekhov's avatar
Kirill Terekhov committed
460
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
461
462
463
464
		assert(GetHandleElementType(GetHandle())==CELL);
		Mesh * m = GetMeshLink();
		ElementArray<Edge> aret(m);
		if( !m->HideMarker() )
Kirill Terekhov's avatar
Kirill Terekhov committed
465
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
466
			if( Element::GetGeometricDimension(m->GetGeometricType(GetHandle())) == 2 ) // This cell is 2d face
Kirill Terekhov's avatar
Kirill Terekhov committed
467
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
468
				adj_type const & lc = m->LowConn(GetHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
469
				aret.reserve(lc.size());
Kirill Terekhov's avatar
Kirill Terekhov committed
470
471
472
473
474
				HandleType last, first;
				HandleType q = lc[0]; //edge 0
				adj_type const & qlc = m->LowConn(q);
				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
Kirill Terekhov's avatar
Kirill Terekhov committed
475
476
				first = qlc[0];
				last  = qlc[1];
Kirill Terekhov's avatar
Kirill Terekhov committed
477
478
				HandleType r = lc[1]; //edge 1
				adj_type const & rlc = m->LowConn(r);
Kirill Terekhov's avatar
Kirill Terekhov committed
479
				if( first == rlc[0] || first == rlc[1] )
Kirill Terekhov's avatar
Kirill Terekhov committed
480
481
482
483
				{
					last = first;
					if( aret.size() > 1 )
					{
Kirill Terekhov's avatar
Kirill Terekhov committed
484
						HandleType temp = aret.data()[0];
Kirill Terekhov's avatar
Kirill Terekhov committed
485
486
487
488
						aret.data()[0] = aret.data()[1];
						aret.data()[1] = temp;
					}
				}
Kirill Terekhov's avatar
Kirill Terekhov committed
489
				adj_type::size_type it = 1, iend = lc.size()-1;
Kirill Terekhov's avatar
Kirill Terekhov committed
490
491
				while(it < iend) //loop over edges
				{
Kirill Terekhov's avatar
Kirill Terekhov committed
492
					adj_type const & ilc = m->LowConn(lc[it]);
Kirill Terekhov's avatar
Kirill Terekhov committed
493
494
					if( last == ilc[0] ) last = ilc[1];
					else last = ilc[0];
Kirill Terekhov's avatar
Kirill Terekhov committed
495
496
					if( invert ^ m->GetMarker(last,mask) ) 
						aret.push_back(last);
Kirill Terekhov's avatar
Kirill Terekhov committed
497
498
					++it;
				}
Kirill Terekhov's avatar
Kirill Terekhov committed
499
500
501
			}
			else
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
502
				MarkerType mrk = m->CreateMarker();
Kirill Terekhov's avatar
Kirill Terekhov committed
503
504
				adj_type const & lc = m->LowConn(GetHandle());
				for(adj_type::size_type it = 0; it < lc.size(); it++) //faces
Kirill Terekhov's avatar
Kirill Terekhov committed
505
				{
Kirill Terekhov's avatar
Kirill Terekhov committed
506
507
508
					adj_type const & ilc = m->LowConn(lc[it]);
					for(adj_type::size_type jt = 0; jt != ilc.size(); jt++) //edges
						if( (invert ^ m->GetMarker(ilc[jt],mask)) && !m->GetMarker(ilc[jt],mrk))
Kirill Terekhov's avatar
Kirill Terekhov committed
509
						{
Kirill Terekhov's avatar
Kirill Terekhov committed
510
							aret.push_back(ilc[jt]);
Kirill Terekhov's avatar
Kirill Terekhov committed
511
							m->SetMarker(ilc[jt],mrk);
Kirill Terekhov's avatar
Kirill Terekhov committed
512
						}
Kirill Terekhov's avatar
Kirill Terekhov committed
513
				}
Kirill Terekhov's avatar
Kirill Terekhov committed
514
515
				for(ElementArray<Edge>::size_type it = 0; it != aret.size(); it++)
					m->RemMarker(aret.at(it),mrk);
Kirill Terekhov's avatar
Kirill Terekhov committed
516
517
518
519
520
				m->ReleaseMarker(mrk);
			}
		}
		else
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
521
			MarkerType hm = GetMeshLink()->HideMarker();
Kirill Terekhov's avatar
Kirill Terekhov committed
522
			if( Element::GetGeometricDimension(m->GetGeometricType(GetHandle())) == 2 ) // This cell is 2d face
Kirill Terekhov's avatar
Kirill Terekhov committed
523
			{
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
524
				enumerator i = ENUMUNDEF, k = ENUMUNDEF, k1 = ENUMUNDEF, k2;
Kirill Terekhov's avatar
Kirill Terekhov committed
525
526
				HandleType last, first;
				adj_type const & lc = m->LowConn(GetHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
527
				aret.reserve(lc.size());
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
528
				i = m->getNext(lc.data(),static_cast<enumerator>(lc.size()),i,hm);
Kirill Terekhov's avatar
Kirill Terekhov committed
529
530
				HandleType q = lc[i]; //edge 0
				adj_type const & qlc = m->LowConn(q);
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
531
				k = m->getNext(qlc.data(),static_cast<enumerator>(qlc.size()),k,hm);
Kirill Terekhov's avatar
Kirill Terekhov committed
532
				if( invert ^ m->GetMarker(qlc[k],mask) ) aret.push_back(qlc[k]); //node 0
Kirill Terekhov's avatar
Kirill Terekhov committed
533
				first = qlc[k];
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
534
				k = m->getNext(qlc.data(),static_cast<enumerator>(qlc.size()),k,hm);
Kirill Terekhov's avatar
Kirill Terekhov committed
535
				if( invert ^ m->GetMarker(qlc[k],mask) ) aret.push_back(qlc[k]); //node 1
Kirill Terekhov's avatar
Kirill Terekhov committed
536
				last = qlc[k];
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
537
				i = m->getNext(lc.data(),static_cast<enumerator>(lc.size()),i,hm);
Kirill Terekhov's avatar
Kirill Terekhov committed
538
539
				HandleType r = lc[i]; //edge 1
				adj_type const & rlc = m->LowConn(r);
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
540
541
				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
542
				if( first == rlc[k1] || first == rlc[k2] )
Kirill Terekhov's avatar
Kirill Terekhov committed
543
544
545
546
				{
					last = first;
					if( aret.size() > 1 )
					{
Kirill Terekhov's avatar
Kirill Terekhov committed
547
						HandleType temp = aret.data()[0];
Kirill Terekhov's avatar
Kirill Terekhov committed
548
549
550
551
						aret.data()[0] = aret.data()[1];
						aret.data()[1] = temp;
					}
				}
Kirill Terekhov's avatar
Kirill Terekhov committed
552
553
				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
554
				{
Kirill Terekhov's avatar
Kirill Terekhov committed
555
					adj_type const & ilc = m->LowConn(lc[it]);
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
556
557
558
					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
559
560
					if( last == ilc[k1] ) 
						last = ilc[k2];
Kirill Terekhov's avatar
Kirill Terekhov committed
561
					else last = ilc[k1];
Kirill Terekhov's avatar
Kirill Terekhov committed
562
					if( invert ^ m->GetMarker(last,mask) ) aret.push_back(last);
Kirill Terekhov's avatar
Kirill Terekhov committed
563
564
565
566
567
					++it;
				}
			}
			else
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
568
				MarkerType mrk = m->CreateMarker();
Kirill Terekhov's avatar
Kirill Terekhov committed
569
570
				adj_type const & lc = m->LowConn(GetHandle());
				for(adj_type::size_type it = 0; it < lc.size(); it++) if( !m->GetMarker(lc[it],hm) ) //faces
Kirill Terekhov's avatar
Kirill Terekhov committed
571
				{
Kirill Terekhov's avatar
Kirill Terekhov committed
572
573
574
					adj_type const & ilc = m->LowConn(lc[it]);
					for(adj_type::size_type jt = 0; jt < ilc.size(); jt++) if( !m->GetMarker(ilc[jt],hm) )//edges
						if( (invert ^ m->GetMarker(ilc[jt],mask)) && !m->GetMarker(ilc[jt],mrk))
Kirill Terekhov's avatar
Kirill Terekhov committed
575
						{
Kirill Terekhov's avatar
Kirill Terekhov committed
576
							aret.push_back(ilc[jt]);
Kirill Terekhov's avatar
Kirill Terekhov committed
577
							m->SetMarker(ilc[jt],mrk);
Kirill Terekhov's avatar
Kirill Terekhov committed
578
						}
Kirill Terekhov's avatar
Kirill Terekhov committed
579
				}
Kirill Terekhov's avatar
Kirill Terekhov committed
580
581
				for(ElementArray<Edge>::size_type it = 0; it < aret.size(); it++) 
					m->RemMarker(aret.at(it),mrk);
Kirill Terekhov's avatar
Kirill Terekhov committed
582
583
584
585
586
587
				m->ReleaseMarker(mrk);
			}
		}
		return aret;
	}

Kirill Terekhov's avatar
Kirill Terekhov committed
588
	ElementArray<Face> Cell::getFaces() const
Kirill Terekhov's avatar
Kirill Terekhov committed
589
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
590
591
592
		assert(GetHandleElementType(GetHandle())==CELL);
		Mesh * m = GetMeshLink();
		if( !m->HideMarker() )
Kirill Terekhov's avatar
Kirill Terekhov committed
593
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
594
595
			adj_type const & lc = m->LowConn(GetHandle());
			return ElementArray<Face>(m,lc.data(),lc.data()+lc.size());
Kirill Terekhov's avatar
Kirill Terekhov committed
596
		}
Kirill Terekhov's avatar
Kirill Terekhov committed
597
598
		else
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
599
600
601
602
603
			MarkerType hm = m->HideMarker();
			ElementArray<Face> aret(m);
			adj_type & 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
604
605
606
			return aret;
		}
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
607
608


Kirill Terekhov's avatar
Kirill Terekhov committed
609
	ElementArray<Face> Cell::getFaces(MarkerType mask, bool invert) const
Kirill Terekhov's avatar
Kirill Terekhov committed
610
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
611
612
613
614
		assert(GetHandleElementType(GetHandle())==CELL);
		Mesh * m = GetMeshLink();
		ElementArray<Face> aret(m);
		if( !m->HideMarker() )
Kirill Terekhov's avatar
Kirill Terekhov committed
615
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
616
617
618
			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
619
620
621
		}
		else
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
622
623
624
625
626
			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
627
628
629
		}
		return aret;
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
630
631
}
#endif