face.cpp 28.6 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
Kirill Terekhov committed
24
				enumerator i = ENUMUNDEF;
Kirill Terekhov's avatar
Kirill Terekhov committed
25
				MarkerType hm = m->HideMarker();
Kirill Terekhov's avatar
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
Kirill Terekhov committed
48
				enumerator i = ENUMUNDEF;
Kirill Terekhov's avatar
Kirill Terekhov committed
49
				MarkerType hm = m->HideMarker();
Kirill Terekhov's avatar
Kirill Terekhov committed
50
				i = m->getNext(hc.data(),static_cast<enumerator>(hc.size()),i,hm); //found first
51 52
				if( i != hc.size() )
					i = m->getNext(hc.data(),static_cast<enumerator>(hc.size()),i,hm); //found second
Kirill Terekhov's avatar
Kirill Terekhov committed
53
				if( i != hc.size() ) return Cell(m,hc[i]);
Kirill Terekhov's avatar
Kirill Terekhov committed
54
			}
Kirill Terekhov's avatar
Kirill Terekhov committed
55
			return Cell(m,InvalidHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
56 57 58
		}
	}

Kirill Terekhov's avatar
Kirill Terekhov committed
59
	Node Face::getBeg() const 
Kirill Terekhov's avatar
Kirill Terekhov committed
60
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
61
		assert(GetHandleElementType(GetHandle())==FACE);
Kirill Terekhov's avatar
Kirill Terekhov committed
62
		assert(GetElementDimension()==1);
Kirill Terekhov's avatar
Kirill Terekhov committed
63 64
		Mesh * m = GetMeshLink();
		if( !m->HideMarker() )
Kirill Terekhov's avatar
Kirill Terekhov committed
65
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
66
			adj_type const & lc = m->LowConn(GetHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
67
			if( lc.empty() )
Kirill Terekhov's avatar
Kirill Terekhov committed
68 69
				return Node(m,InvalidHandle());
			return Node(m,m->LowConn(lc.front()).front());
Kirill Terekhov's avatar
Kirill Terekhov committed
70 71 72
		}
		else
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
73
			adj_type const & lc = m->LowConn(GetHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
74
			if( !lc.empty() )
Kirill Terekhov's avatar
Kirill Terekhov committed
75
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
76
				enumerator i = ENUMUNDEF;
Kirill Terekhov's avatar
Kirill Terekhov committed
77
				MarkerType hm = m->HideMarker();
Kirill Terekhov's avatar
Kirill Terekhov committed
78 79
				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
80
				{
Kirill Terekhov's avatar
Kirill Terekhov committed
81
					adj_type const & llc = m->LowConn(lc[i]);
Kirill Terekhov's avatar
Kirill Terekhov committed
82 83
					enumerator j = ENUMUNDEF;
					j = m->getNext(llc.data(),static_cast<enumerator>(llc.size()),j,hm);
Kirill Terekhov's avatar
Kirill Terekhov committed
84
					if( j != llc.size() ) return Node(m,llc[j]);
Kirill Terekhov's avatar
Kirill Terekhov committed
85 86
				}
			}
Kirill Terekhov's avatar
Kirill Terekhov committed
87
			return Node(m,InvalidHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
88 89
		}
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
90
	Node Face::getEnd() const 
Kirill Terekhov's avatar
Kirill Terekhov committed
91
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
92
		assert(GetHandleElementType(GetHandle())==FACE);
Kirill Terekhov's avatar
Kirill Terekhov committed
93
		assert(GetElementDimension()==1);
Kirill Terekhov's avatar
Kirill Terekhov committed
94 95
		Mesh * m = GetMeshLink();
		if( !m->HideMarker() )
Kirill Terekhov's avatar
Kirill Terekhov committed
96
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
97
			adj_type const & lc = m->LowConn(GetHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
98
			if( lc.size() < 2 )
Kirill Terekhov's avatar
Kirill Terekhov committed
99 100
				return Node(m,InvalidHandle());
			return Node(m,m->LowConn(lc.back()).front());
Kirill Terekhov's avatar
Kirill Terekhov committed
101 102 103
		}
		else
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
104
			adj_type const & lc = m->LowConn(GetHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
105
			if( !lc.empty() )
Kirill Terekhov's avatar
Kirill Terekhov committed
106
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
107
				enumerator i = ENUMUNDEF;
Kirill Terekhov's avatar
Kirill Terekhov committed
108
				MarkerType hm = m->HideMarker();
Kirill Terekhov's avatar
Kirill Terekhov committed
109
				i = m->getNext(lc.data(),static_cast<enumerator>(lc.size()),i,hm);
110
				if( i != static_cast<enumerator>(lc.size()) )
Kirill Terekhov's avatar
Kirill Terekhov committed
111
				{
112 113 114 115 116 117 118 119
					i = m->getNext(lc.data(),static_cast<enumerator>(lc.size()),i,hm);
					if( i != static_cast<enumerator>(lc.size()) )
					{
						adj_type const & llc = m->LowConn(lc[i]);
						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
120 121
				}
			}
Kirill Terekhov's avatar
Kirill Terekhov committed
122
			return Node(m,InvalidHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
123 124 125
		}
	}
	
Kirill Terekhov's avatar
Kirill Terekhov committed
126
	bool Face::FaceOrientedOutside(Cell c) const
Kirill Terekhov's avatar
Kirill Terekhov committed
127
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
128
		assert(GetHandleElementType(GetHandle())==FACE);
Kirill Terekhov's avatar
Kirill Terekhov committed
129 130 131 132 133
		if( BackCell() == c ) 
			return true; 
		return false;
	}
	
Kirill Terekhov's avatar
Kirill Terekhov committed
134
	void Face::ReorderEdges() const
Kirill Terekhov's avatar
Kirill Terekhov committed
135
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
136 137 138
		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
139
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
140
			HandleType t = lc[j];
Kirill Terekhov's avatar
Kirill Terekhov committed
141 142
			lc[j] = lc[lc.size()-1-j];
			lc[lc.size()-1-j] = t;
Kirill Terekhov's avatar
Kirill Terekhov committed
143 144 145
		}
	}
	
Kirill Terekhov's avatar
Kirill Terekhov committed
146
	bool Face::CheckEdgeOrder() const
Kirill Terekhov's avatar
Kirill Terekhov committed
147
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
148
		assert(GetHandleElementType(GetHandle())==FACE);
Kirill Terekhov's avatar
Kirill Terekhov committed
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
		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
232 233 234
		return true;
	}
	
Kirill Terekhov's avatar
Kirill Terekhov committed
235
	bool Face::FixEdgeOrder() const
Kirill Terekhov's avatar
Kirill Terekhov committed
236
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
237
		assert(GetHandleElementType(GetHandle())==FACE);
Kirill Terekhov's avatar
Kirill Terekhov committed
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
		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];
Kirill Terekhov's avatar
Kirill Terekhov committed
277
							lc[jt] = temp;
Kirill Terekhov's avatar
Kirill Terekhov committed
278 279 280 281 282 283 284 285 286
							temp = first;
							first = last;
							last = temp;
							break;
						}
						else if( last == ilc[0] || last == ilc[1] )
						{
							HandleType temp = lc[1];
							lc[1] = lc[jt];
Kirill Terekhov's avatar
Kirill Terekhov committed
287
							lc[jt] = temp;
Kirill Terekhov's avatar
Kirill Terekhov committed
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
							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;
							}
323
							++jt;
Kirill Terekhov's avatar
Kirill Terekhov committed
324 325 326 327 328 329 330
						}
						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;
Kirill Terekhov's avatar
Kirill Terekhov committed
331
				if( !( (ilc[0] == last && ilc[1] == first) || (ilc[0] == first && ilc[1] == last) ) )
Kirill Terekhov's avatar
Kirill Terekhov committed
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
					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];
Kirill Terekhov's avatar
Kirill Terekhov committed
375
							lc[jt] = temp;
Kirill Terekhov's avatar
Kirill Terekhov committed
376 377 378 379 380 381 382 383 384
							temp = first;
							first = last;
							last = temp;
							break;
						}
						else if( last == ilc[k1] || last == ilc[k2] )
						{
							HandleType temp = lc[i];
							lc[i] = lc[jt];
Kirill Terekhov's avatar
Kirill Terekhov committed
385
							lc[jt] = temp;
Kirill Terekhov's avatar
Kirill Terekhov committed
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
							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;
							}
427
							++jt;
Kirill Terekhov's avatar
Kirill Terekhov committed
428 429 430 431 432 433 434 435 436 437
						}
						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);
Kirill Terekhov's avatar
Kirill Terekhov committed
438
				if( !( (ilc[k1] == last && ilc[k2] == first) || (ilc[k1] == first && ilc[k2] == last) ) )
Kirill Terekhov's avatar
Kirill Terekhov committed
439 440 441 442
					return false;
			}
		}
		return true;
Kirill Terekhov's avatar
Kirill Terekhov committed
443 444 445
	}
	
	
Kirill Terekhov's avatar
Kirill Terekhov committed
446
	ElementArray<Node> Face::getNodes() const
Kirill Terekhov's avatar
Kirill Terekhov committed
447
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
448 449 450 451
		assert(GetHandleElementType(GetHandle())==FACE);
		Mesh * m = GetMeshLink();
		ElementArray<Node> aret(m);
		if( !m->HideMarker() )
Kirill Terekhov's avatar
Kirill Terekhov committed
452
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
453
			if( Element::GetGeometricDimension(m->GetGeometricType(GetHandle())) == 1 ) // This face is 2d edge
Kirill Terekhov's avatar
Kirill Terekhov committed
454
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
455
				adj_type const & lc = m->LowConn(GetHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
456
				aret.reserve(lc.size());
Kirill Terekhov's avatar
Kirill Terekhov committed
457 458
				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
459 460 461
			}
			else
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
462
				adj_type const & lc = m->LowConn(GetHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
463
				assert(lc.size() > 2); // it should be at least triangle
Kirill Terekhov's avatar
Kirill Terekhov committed
464
				aret.reserve(lc.size());
Kirill Terekhov's avatar
Kirill Terekhov committed
465 466
				HandleType q = lc[0]; //edge 0
				adj_type const & qlc = m->LowConn(q);
Kirill Terekhov's avatar
Kirill Terekhov committed
467
				assert(qlc.size() == 2);
Kirill Terekhov's avatar
Kirill Terekhov committed
468 469
				aret.push_back(qlc[0]); //node 0
				aret.push_back(qlc[1]); //node 1
Kirill Terekhov's avatar
Kirill Terekhov committed
470 471
				HandleType r = lc[1]; //edge 1
				adj_type & rlc = m->LowConn(r);
Kirill Terekhov's avatar
Kirill Terekhov committed
472
				assert(rlc.size() == 2);
Kirill Terekhov's avatar
Kirill Terekhov committed
473
				if( aret.data()[0] == rlc[0] || aret.data()[0] == rlc[1] )
Kirill Terekhov's avatar
Kirill Terekhov committed
474
				{
Kirill Terekhov's avatar
Kirill Terekhov committed
475
					HandleType temp = aret.data()[0];
Kirill Terekhov's avatar
Kirill Terekhov committed
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
				while(it < iend) //loop over edges
Kirill Terekhov's avatar
Kirill Terekhov committed
481
				{
Kirill Terekhov's avatar
Kirill Terekhov committed
482
					adj_type const & ilc = m->LowConn(lc[it]);
Kirill Terekhov's avatar
Kirill Terekhov committed
483
					assert(ilc.size() == 2);
Kirill Terekhov's avatar
Kirill Terekhov committed
484
					if( aret.atback() == ilc[0] ) aret.push_back(ilc[1]);
Kirill Terekhov's avatar
Kirill Terekhov committed
485
					else aret.push_back(ilc[0]);
Kirill Terekhov's avatar
Kirill Terekhov committed
486 487 488 489 490 491
					++it;
				}
			}
		}
		else
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
492 493
			MarkerType hm = m->HideMarker();
			if( Element::GetGeometricDimension(m->GetGeometricType(GetHandle())) == 1 ) // This face is 2d edge
Kirill Terekhov's avatar
Kirill Terekhov committed
494
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
495
				adj_type const & lc = m->LowConn(GetHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
496
				aret.reserve(lc.size());
Kirill Terekhov's avatar
Kirill Terekhov committed
497 498
				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
499
					{
Kirill Terekhov's avatar
Kirill Terekhov committed
500
						adj_type const & ilc = m->LowConn(lc[it]);
Kirill Terekhov's avatar
Kirill Terekhov committed
501 502 503
						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
504
					}
Kirill Terekhov's avatar
Kirill Terekhov committed
505 506 507
			}
			else
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
508
				enumerator i = ENUMUNDEF, k = ENUMUNDEF, k1 = ENUMUNDEF, k2;
Kirill Terekhov's avatar
Kirill Terekhov committed
509
				adj_type const & lc = m->LowConn(GetHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
510
				aret.reserve(lc.size());
Kirill Terekhov's avatar
Kirill Terekhov committed
511
				i = m->getNext(lc.data(),static_cast<enumerator>(lc.size()),i,hm);
Kirill Terekhov's avatar
Kirill Terekhov committed
512 513
				HandleType q = lc[i]; //edge 0
				adj_type const & qlc = m->LowConn(q);
Kirill Terekhov's avatar
Kirill Terekhov committed
514
				assert(m->Count(qlc.data(),qlc.size(),hm)==2);
Kirill Terekhov's avatar
Kirill Terekhov committed
515
				k = m->getNext(qlc.data(),static_cast<enumerator>(qlc.size()),k,hm);
Kirill Terekhov's avatar
Kirill Terekhov committed
516
				aret.push_back(qlc[k]); //node 0
Kirill Terekhov's avatar
Kirill Terekhov committed
517
				k = m->getNext(qlc.data(),static_cast<enumerator>(qlc.size()),k,hm);
Kirill Terekhov's avatar
Kirill Terekhov committed
518
				aret.push_back(qlc[k]); //node 1
Kirill Terekhov's avatar
Kirill Terekhov committed
519
				i = m->getNext(lc.data(),static_cast<enumerator>(lc.size()),i,hm);
Kirill Terekhov's avatar
Kirill Terekhov committed
520 521
				HandleType r = lc[i]; //edge 1
				adj_type const & rlc = m->LowConn(r);
Kirill Terekhov's avatar
Kirill Terekhov committed
522
				assert(m->Count(rlc.data(),rlc.size(),hm)==2);
Kirill Terekhov's avatar
Kirill Terekhov committed
523 524
				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
525
				if( aret.data()[0] == rlc[k1] || aret.data()[0] == rlc[k2] )
Kirill Terekhov's avatar
Kirill Terekhov committed
526
				{
Kirill Terekhov's avatar
Kirill Terekhov committed
527
					HandleType temp = aret.data()[0];
Kirill Terekhov's avatar
Kirill Terekhov committed
528 529 530
					aret.data()[0] = aret.data()[1];
					aret.data()[1] = temp;
				}
Kirill Terekhov's avatar
Kirill Terekhov committed
531
				adj_type::size_type it = i, iend = lc.size()-1;
532
				while(it != iend)
Kirill Terekhov's avatar
Kirill Terekhov committed
533
				{
534 535 536 537 538 539 540 541 542 543 544 545
					if( !m->GetMarker(lc[it],hm) ) //loop over edges
					{
						adj_type const & ilc = m->LowConn(lc[it]);
						assert(m->Count(ilc.data(),ilc.size(),hm)==2);
						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( aret.atback() == ilc[k1] )
							aret.push_back(ilc[k2]);
						else
							aret.push_back(ilc[k1]);
					}
Kirill Terekhov's avatar
Kirill Terekhov committed
546 547 548 549 550 551 552
					++it;
				}
			}

		}
		return aret;
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
553 554


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

Kirill Terekhov's avatar
Kirill Terekhov committed
684 685 686 687
			}
		}
		else
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
688
			if( !m->HideMarker() )
Kirill Terekhov's avatar
Kirill Terekhov committed
689
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722
				if(  Element::GetGeometricDimension(m->GetGeometricType(GetHandle())) == 1 ) // This face is 2d edge
				{
					adj_type const & lc = m->LowConn(GetHandle());
					aret.reserve(lc.size());
					for(adj_type::size_type it = 0; it < lc.size(); it++) //iterate over edges that are of type Vertex
					{
						HandleType e = m->LowConn(lc[it]).front();
						if( invert ^ m->GetMarker(e,mask) ) aret.push_back(e);
					}
				}
				else
				{
					adj_type const & lc = m->LowConn(GetHandle());
					aret.reserve(lc.size());
					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);
					if( first == rlc[0] || first == rlc[1] ) 
					{
						last = first;
						if( aret.size() > 1 )
						{
							HandleType temp = aret.data()[0];
							aret.data()[0] = aret.data()[1];
							aret.data()[1] = temp;
						}
					}
					adj_type::size_type it = 1, iend = lc.size()-1;
					while(it < iend) //loop over edges
Kirill Terekhov's avatar
Kirill Terekhov committed
723
					{
Kirill Terekhov's avatar
Kirill Terekhov committed
724
						adj_type const & ilc = m->LowConn(lc[it]);
Kirill Terekhov's avatar
Kirill Terekhov committed
725 726 727 728 729 730 731 732 733 734 735 736 737
						if( last == ilc[0] ) 
						{
							if( invert ^ m->GetMarker(ilc[1],mask) ) 
								aret.push_back(ilc[1]);
							last = ilc[1];
						}
						else 
						{
							if( invert ^ m->GetMarker(ilc[0],mask) )
								aret.push_back(ilc[0]);
							last = ilc[0];
						}
						++it;
Kirill Terekhov's avatar
Kirill Terekhov committed
738
					}
Kirill Terekhov's avatar
Kirill Terekhov committed
739
				}
Kirill Terekhov's avatar
Kirill Terekhov committed
740 741 742
			}
			else
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
743 744
				MarkerType hm = m->HideMarker();
				if( Element::GetGeometricDimension(m->GetGeometricType(GetHandle())) == 1 ) // This face is 2d edge
Kirill Terekhov's avatar
Kirill Terekhov committed
745
				{
Kirill Terekhov's avatar
Kirill Terekhov committed
746 747 748 749 750 751 752 753 754 755 756
					adj_type const & lc = m->LowConn(GetHandle());
					aret.reserve(lc.size());
					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) ) 
						{
							adj_type const & ilc = m->LowConn(lc[it]);
							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)) ) 
								aret.push_back(ilc[i]);
						}
Kirill Terekhov's avatar
Kirill Terekhov committed
757
				}
Kirill Terekhov's avatar
Kirill Terekhov committed
758
				else
Kirill Terekhov's avatar
Kirill Terekhov committed
759
				{
Kirill Terekhov's avatar
Kirill Terekhov committed
760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777
					enumerator i = ENUMUNDEF, k = ENUMUNDEF, k1 = ENUMUNDEF, k2;
					adj_type const & lc = m->LowConn(GetHandle());
					aret.reserve(lc.size());
					i = m->getNext(lc.data(),static_cast<enumerator>(lc.size()),i,hm);
					HandleType q = lc[i], first, last; //edge 0
					adj_type const & qlc = m->LowConn(q);
					k = m->getNext(qlc.data(),static_cast<enumerator>(qlc.size()),k,hm);
					if( invert ^ m->GetMarker(qlc[k],mask) ) aret.push_back(qlc[k]); //node 0
					first = qlc[k];
					k = m->getNext(qlc.data(),static_cast<enumerator>(qlc.size()),k,hm);
					if( invert ^ m->GetMarker(qlc[k],mask) ) aret.push_back(qlc[k]); //node 1
					last = qlc[k];
					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] )
Kirill Terekhov's avatar
Kirill Terekhov committed
778
					{
Kirill Terekhov's avatar
Kirill Terekhov committed
779 780 781 782 783 784 785
						last = first;
						if( aret.size() > 1 )
						{
							HandleType temp = aret.data()[0];
							aret.data()[0] = aret.data()[1];
							aret.data()[1] = temp;
						}
Kirill Terekhov's avatar
Kirill Terekhov committed
786
					}
Kirill Terekhov's avatar
Kirill Terekhov committed
787
					adj_type::size_type it = 1, iend = lc.size()-1;
Kirill Terekhov's avatar
Kirill Terekhov committed
788 789
					while (m->GetMarker(lc[iend],hm) && iend > 0) iend--;
					while(it < iend)
Kirill Terekhov's avatar
Kirill Terekhov committed
790
					{
Kirill Terekhov's avatar
Kirill Terekhov committed
791
						if( !m->GetMarker(lc[it],hm) ) //loop over edges
Kirill Terekhov's avatar
Kirill Terekhov committed
792
						{
Kirill Terekhov's avatar
Kirill Terekhov committed
793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808
							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] )
							{
								if( invert ^ m->GetMarker(ilc[k2],mask) )
									aret.push_back(ilc[k2]);
								last = ilc[k2];
							}
							else
							{
								if( invert ^ m->GetMarker(ilc[k1],mask) )
									aret.push_back(ilc[k1]);
								last = ilc[k1];
							}
Kirill Terekhov's avatar
Kirill Terekhov committed
809 810
						}
						++it;
Kirill Terekhov's avatar
Kirill Terekhov committed
811 812 813
					}
				}

Kirill Terekhov's avatar
Kirill Terekhov committed
814
			}
Kirill Terekhov's avatar
Kirill Terekhov committed
815 816 817 818
		}
		return aret;
	}

Kirill Terekhov's avatar
Kirill Terekhov committed
819
	ElementArray<Edge> Face::getEdges() const
Kirill Terekhov's avatar
Kirill Terekhov committed
820
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
821 822 823
		assert(GetHandleElementType(GetHandle())==FACE);
		Mesh * m = GetMeshLink();
		if( !m->HideMarker() )
Kirill Terekhov's avatar
Kirill Terekhov committed
824
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
825 826
			adj_type const & lc = m->LowConn(GetHandle());
			return ElementArray<Edge>(m,lc.data(),lc.data()+lc.size());
Kirill Terekhov's avatar
Kirill Terekhov committed
827
		}
Kirill Terekhov's avatar
Kirill Terekhov committed
828 829
		else
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
830 831 832 833 834 835
			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
836 837 838
			return aret;
		}
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
839

Kirill Terekhov's avatar
Kirill Terekhov committed
840
	ElementArray<Edge> Face::getEdges(MarkerType mask, bool invert) const
Kirill Terekhov's avatar
Kirill Terekhov committed
841
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
842 843 844 845
		assert(GetHandleElementType(GetHandle())==FACE);
		Mesh * m = GetMeshLink();
		ElementArray<Edge> aret(m);
		if( !m->HideMarker() )
Kirill Terekhov's avatar
Kirill Terekhov committed
846
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
847
			adj_type const & lc = m->LowConn(GetHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
848 849 850 851 852 853 854 855 856 857 858 859
			if( isPrivate(mask) )
			{
				for(adj_type::size_type it = 0; it < lc.size(); ++it)
					if( invert ^ m->GetPrivateMarker(lc[it],mask) ) 
						aret.push_back(lc[it]);
			}
			else
			{
				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
860 861 862
		}
		else
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
863 864
			MarkerType hm = m->HideMarker();
			adj_type const & lc = m->LowConn(GetHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
865 866 867 868 869 870 871 872 873 874 875 876
			if( isPrivate(mask) )
			{
				for(adj_type::size_type it = 0; it < lc.size(); ++it)
					if( (invert ^ m->GetPrivateMarker(lc[it],mask)) && !m->GetMarker(lc[it],hm) ) 
						aret.push_back(lc[it]);
			}
			else
			{
				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
877 878 879 880
		}
		return aret;
	}

Kirill Terekhov's avatar
Kirill Terekhov committed
881
	ElementArray<Cell> Face::getCells() const
Kirill Terekhov's avatar
Kirill Terekhov committed
882
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
883 884
		assert(GetHandleElementType(GetHandle())==FACE);
		Mesh * m = GetMeshLink();
Kirill Terekhov's avatar
Kirill Terekhov committed
885
		if( !GetMeshLink()->HideMarker() )
Kirill Terekhov's avatar
Kirill Terekhov committed
886
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
887 888
			adj_type const & hc = m->HighConn(GetHandle());
			return ElementArray<Cell>(m,hc.data(),hc.data()+hc.size());
Kirill Terekhov's avatar
Kirill Terekhov committed
889
		}
Kirill Terekhov's avatar
Kirill Terekhov committed
890 891
		else
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
892 893 894 895 896 897
			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
898 899 900
			return aret;
		}
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
901

Kirill Terekhov's avatar
Kirill Terekhov committed
902
	ElementArray<Cell> Face::getCells(MarkerType mask, bool invert) const
Kirill Terekhov's avatar
Kirill Terekhov committed
903
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
904 905 906 907
		assert(GetHandleElementType(GetHandle())==FACE);
		Mesh * m = GetMeshLink();
		ElementArray<Cell> aret(m);
		if( !m->HideMarker() )
Kirill Terekhov's avatar
Kirill Terekhov committed
908
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
909
			adj_type const & hc = m->HighConn(GetHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
910 911 912 913 914 915 916 917 918 919 920 921
			if( isPrivate(mask) )
			{
				for(adj_type::size_type it = 0; it < hc.size(); ++it)
					if( invert ^ m->GetPrivateMarker(hc[it],mask)) 
						aret.push_back(hc[it]);
			}
			else
			{
				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
922 923 924
		}
		else
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
925
			MarkerType hm = GetMeshLink()->HideMarker();
Kirill Terekhov's avatar
Kirill Terekhov committed
926
			adj_type const & hc = m->HighConn(GetHandle());
Kirill Terekhov's avatar
Kirill Terekhov committed
927 928 929 930 931 932 933 934 935 936 937 938
			if( isPrivate(mask) )
			{
				for(adj_type::size_type it = 0; it < hc.size(); ++it)
					if( (invert ^ m->GetPrivateMarker(hc[it],mask)) && !m->GetMarker(hc[it],hm) ) 
						aret.push_back(hc[it]);
			}
			else
			{
				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
939 940 941 942
		}
		return aret;
	}

Kirill Terekhov's avatar
Kirill Terekhov committed
943
	
Kirill Terekhov's avatar
Kirill Terekhov committed
944 945
}
#endif