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


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

Kirill Terekhov's avatar
Kirill Terekhov committed
578
	ElementArray<Face> Cell::getFaces() const
Kirill Terekhov's avatar
Kirill Terekhov committed
579
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
580
581
582
		assert(GetHandleElementType(GetHandle())==CELL);
		Mesh * m = GetMeshLink();
		if( !m->HideMarker() )
Kirill Terekhov's avatar
Kirill Terekhov committed
583
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
584
585
			adj_type const & lc = m->LowConn(GetHandle());
			return ElementArray<Face>(m,lc.data(),lc.data()+lc.size());
Kirill Terekhov's avatar
Kirill Terekhov committed
586
		}
Kirill Terekhov's avatar
Kirill Terekhov committed
587
588
		else
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
589
590
591
592
593
			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
594
595
596
			return aret;
		}
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
597
598


Kirill Terekhov's avatar
Kirill Terekhov committed
599
	ElementArray<Face> Cell::getFaces(MarkerType mask, bool invert) const
Kirill Terekhov's avatar
Kirill Terekhov committed
600
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
601
602
603
604
		assert(GetHandleElementType(GetHandle())==CELL);
		Mesh * m = GetMeshLink();
		ElementArray<Face> aret(m);
		if( !m->HideMarker() )
Kirill Terekhov's avatar
Kirill Terekhov committed
605
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
606
607
608
			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
609
610
611
		}
		else
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
612
613
614
615
616
			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
617
618
619
		}
		return aret;
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
620
621
}
#endif