embeddedMap3.cpp 17.2 KB
Newer Older
1 2 3
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps  *
* version 0.1                                                                  *
4
* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg           *
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
*                                                                              *
* This library is free software; you can redistribute it and/or modify it      *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your     *
* option) any later version.                                                   *
*                                                                              *
* This library is distributed in the hope that it will be useful, but WITHOUT  *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or        *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License  *
* for more details.                                                            *
*                                                                              *
* You should have received a copy of the GNU Lesser General Public License     *
* along with this library; if not, write to the Free Software Foundation,      *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.           *
*                                                                              *
20
* Web site: http://cgogn.unistra.fr/                                           *
21 22 23
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/
24

25 26
#include <vector>
#include <algorithm>
27
#include "Topology/map/embeddedMap3.h"
28
#include "Topology/generic/traversor/traversor3.h"
29 30 31 32

namespace CGoGN
{

untereiner's avatar
untereiner committed
33
//TODO
untereiner's avatar
untereiner committed
34
Dart EmbeddedMap3::splitVertex(std::vector<Dart>& vd)
35
{
Lionel Untereiner's avatar
Lionel Untereiner committed
36
	Dart d = vd.front();
untereiner's avatar
untereiner committed
37
	Dart d2 = phi1(phi2(d));
38

untereiner's avatar
untereiner committed
39
	Dart dres = Map3::splitVertex(vd);
40

41
	if(isOrbitEmbedded<VERTEX>())
42
	{
43 44 45
		Algo::Topo::setOrbitEmbeddingOnNewCell<VERTEX>(*this, d2);
		Algo::Topo::copyCellAttributes<VERTEX>(*this, d2, d);
		Algo::Topo::setOrbitEmbedding<VERTEX>(*this, d, getEmbedding<VERTEX>(d));
46 47
	}

48
	if(isOrbitEmbedded<EDGE>())
49
		Algo::Topo::initOrbitEmbeddingOnNewCell<EDGE>(*this, dres) ; // TODO : check if dres is a dart of the new edge
50

51
	if(isOrbitEmbedded<VOLUME>())
52
	{
Lionel Untereiner's avatar
Lionel Untereiner committed
53
		for(std::vector<Dart>::iterator it = vd.begin() ; it != vd.end() ; ++it)
54
			Algo::Topo::setOrbitEmbedding<VOLUME>(*this, *it, getEmbedding<VOLUME>(*it)) ;
55
	}
untereiner's avatar
untereiner committed
56 57

	return dres;
58 59
}

untereiner's avatar
untereiner committed
60
//TODO
61
Dart EmbeddedMap3::deleteVertex(Dart d)
62
{
untereiner's avatar
untereiner committed
63 64 65
	Dart v = Map3::deleteVertex(d) ;
	if(v != NIL)
	{
66
		if (isOrbitEmbedded<VOLUME>())
untereiner's avatar
untereiner committed
67
		{
68
			Algo::Topo::setOrbitEmbedding<VOLUME>(*this, v, getEmbedding<VOLUME>(v)) ;
untereiner's avatar
untereiner committed
69 70 71
		}
	}
	return v ;
72 73
}

David Cazier's avatar
David Cazier committed
74
Dart EmbeddedMap3::cutEdge(Dart d)
75
{
David Cazier's avatar
David Cazier committed
76
	Dart nd = Map3::cutEdge(d);
77

untereiner's avatar
untereiner committed
78 79 80 81
//	if(isOrbitEmbedded<VERTEX>())
//	{
//		initOrbitEmbeddingNewCell<VERTEX>(nd) ;
//	}
82

83
	if(isOrbitEmbedded<EDGE>())
84
	{
untereiner's avatar
untereiner committed
85
		// embed the new darts created in the cut edge
86
		Algo::Topo::setOrbitEmbedding<EDGE>(*this, d, getEmbedding<EDGE>(d)) ;
untereiner's avatar
untereiner committed
87
		// embed a new cell for the new edge and copy the attributes' line (c) Lionel
88 89
		Algo::Topo::setOrbitEmbeddingOnNewCell<EDGE>(*this, nd) ;
		Algo::Topo::copyCellAttributes<EDGE>(*this, nd, d) ;
90 91
	}

92
	if(isOrbitEmbedded<FACE2>())
93 94 95 96
	{
		Dart f = d;
		do
		{
97
			Dart f1 = phi1(f) ;
98

Pierre Kraemer's avatar
Pierre Kraemer committed
99
			copyDartEmbedding<FACE2>(f1, f);
100
			Dart e = phi3(f1);
Pierre Kraemer's avatar
Pierre Kraemer committed
101
			copyDartEmbedding<FACE2>(phi1(e), e);
untereiner's avatar
untereiner committed
102 103 104 105
			f = alpha2(f);
		} while(f != d);
	}

106
	if(isOrbitEmbedded<FACE>())
untereiner's avatar
untereiner committed
107 108 109 110
	{
		Dart f = d;
		do
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
111 112 113
			unsigned int fEmb = getEmbedding<FACE>(f) ;
			setDartEmbedding<FACE>(phi1(f), fEmb);
			setDartEmbedding<FACE>(phi3(f), fEmb);
114 115 116 117
			f = alpha2(f);
		} while(f != d);
	}

118
	if(isOrbitEmbedded<VOLUME>())
119 120 121 122
	{
		Dart f = d;
		do
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
123 124 125
			unsigned int vEmb = getEmbedding<VOLUME>(f) ;
			setDartEmbedding<VOLUME>(phi1(f), vEmb);
			setDartEmbedding<VOLUME>(phi2(f), vEmb);
126 127 128
			f = alpha2(f);
		} while(f != d);
	}
129 130

	return nd ;
131 132
}

133
bool EmbeddedMap3::uncutEdge(Dart d)
134
{
135
	if(Map3::uncutEdge(d))
untereiner's avatar
untereiner committed
136
	{
137
		//embed all darts from the old two edges to one of the two edge embedding
138
		if(isOrbitEmbedded<EDGE>())
139
		{
140
			Algo::Topo::setOrbitEmbedding<EDGE>(*this, d, getEmbedding<EDGE>(d)) ;
141 142
		}
		return true ;
untereiner's avatar
untereiner committed
143
	}
144
	return false ;
145 146
}

147 148
Dart EmbeddedMap3::deleteEdge(Dart d)
{
149
	Dart v = Map3::deleteEdge(d) ;
150 151
	if(v != NIL)
	{
152
		if(isOrbitEmbedded<VOLUME>())
153
		{
154
			Algo::Topo::setOrbitEmbedding<VOLUME>(*this, v, getEmbedding<VOLUME>(v)) ;
155 156 157 158 159
		}
	}
	return v;
}

160 161
bool EmbeddedMap3::edgeCanCollapse(Dart d)
{
162 163 164 165 166
//	if(isBoundaryVertex(d) || isBoundaryVertex(phi1(d)))
//		return false;
//
//	if(isBoundaryEdge(d))
//		return false;
167

Pierre Kraemer's avatar
Pierre Kraemer committed
168
	CellMarkerStore<EmbeddedMap3, VERTEX> mv(*this);
169 170 171

	Traversor3VVaE<TOPO_MAP> t3VVaE_v1(*this,d);
	for(Dart dit = t3VVaE_v1.begin() ; dit != t3VVaE_v1.end() ; dit = t3VVaE_v1.next())
172
	{
173
		mv.mark(dit);
174
	}
175

176 177
	Traversor3EW<TOPO_MAP> t3EW(*this,d);
	for(Dart dit = t3EW.begin() ; dit != t3EW.end() ; dit = t3EW.next())
178
	{
179 180
		mv.unmark(phi_1(dit));
		mv.unmark(phi_1(phi2(dit)));
181
	}
182

183 184
	Traversor3VVaE<TOPO_MAP> t3VVaE_v2(*this,phi2(d));
	for(Dart dit = t3VVaE_v2.begin() ; dit != t3VVaE_v2.end() ; dit = t3VVaE_v2.next())
185
	{
186 187 188 189 190
		if(mv.isMarked(dit))
			return false;
	}

	return true;
191 192
}

193 194
Dart EmbeddedMap3::collapseEdge(Dart d, bool delDegenerateVolumes)
{
195
	unsigned int vEmb = getEmbedding<VERTEX>(d) ;
196

197 198 199
	Dart d2 = phi2(phi_1(d)) ;
	Dart dd2 = phi2(phi_1(phi2(d))) ;

200 201 202 203
	Dart resV = Map3::collapseEdge(d, delDegenerateVolumes);

	if(resV != NIL)
	{
204
		if(isOrbitEmbedded<VERTEX>())
205
		{
206
			Algo::Topo::setOrbitEmbedding<VERTEX>(*this, resV, vEmb);
207
		}
208 209 210

		if(isOrbitEmbedded<EDGE>())
		{
211 212
			Algo::Topo::setOrbitEmbedding<EDGE>(*this, d2, getEmbedding<EDGE>(d2));
			Algo::Topo::setOrbitEmbedding<EDGE>(*this, dd2, getEmbedding<EDGE>(dd2));
213
		}
214 215 216 217 218
	}

	return resV;
}

219 220
void EmbeddedMap3::splitFace(Dart d, Dart e)
{
untereiner's avatar
untereiner committed
221 222 223 224
	Dart dd = phi1(phi3(d));
	Dart ee = phi1(phi3(e));

	Map3::splitFace(d, e);
225

226
	if(isOrbitEmbedded<VERTEX>())
227
	{
228 229
		unsigned int vEmb1 = getEmbedding<VERTEX>(d) ;
		unsigned int vEmb2 = getEmbedding<VERTEX>(e) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
230 231 232 233
		setDartEmbedding<VERTEX>(phi_1(e), vEmb1);
		setDartEmbedding<VERTEX>(phi_1(ee), vEmb1);
		setDartEmbedding<VERTEX>(phi_1(d), vEmb2);
		setDartEmbedding<VERTEX>(phi_1(dd), vEmb2);
untereiner's avatar
untereiner committed
234
	}
235

untereiner's avatar
untereiner committed
236 237 238 239
//	if(isOrbitEmbedded<EDGE>())
//	{
//		initOrbitEmbeddingNewCell<EDGE>(phi_1(d)) ;
//	}
240

241
	if(isOrbitEmbedded<FACE2>())
untereiner's avatar
untereiner committed
242
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
243
		copyDartEmbedding<FACE2>(phi_1(d), d) ;
244 245
		Algo::Topo::setOrbitEmbeddingOnNewCell<FACE2>(*this, e) ;
		Algo::Topo::copyCellAttributes<FACE2>(*this, e, d) ;
246

Pierre Kraemer's avatar
Pierre Kraemer committed
247
		copyDartEmbedding<FACE2>(phi_1(dd), dd) ;
248 249
		Algo::Topo::setOrbitEmbeddingOnNewCell<FACE2>(*this, ee) ;
		Algo::Topo::copyCellAttributes<FACE2>(*this, ee, dd) ;
250 251
	}

252
	if(isOrbitEmbedded<FACE>())
253
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
254 255 256
		unsigned int fEmb = getEmbedding<FACE>(d) ;
		setDartEmbedding<FACE>(phi_1(d), fEmb) ;
		setDartEmbedding<FACE>(phi_1(ee), fEmb) ;
257 258
		Algo::Topo::setOrbitEmbeddingOnNewCell<FACE>(*this, e);
		Algo::Topo::copyCellAttributes<FACE>(*this, e, d);
259 260
	}

261
	if(isOrbitEmbedded<VOLUME>())
262
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
263 264 265
		unsigned int vEmb1 = getEmbedding<VOLUME>(d) ;
		setDartEmbedding<VOLUME>(phi_1(d),  vEmb1);
		setDartEmbedding<VOLUME>(phi_1(e),  vEmb1);
266

Pierre Kraemer's avatar
Pierre Kraemer committed
267 268 269
		unsigned int vEmb2 = getEmbedding<VOLUME>(dd) ;
		setDartEmbedding<VOLUME>(phi_1(dd),  vEmb2);
		setDartEmbedding<VOLUME>(phi_1(ee),  vEmb2);
270 271 272
	}
}

Thomas's avatar
Thomas committed
273 274 275 276 277 278 279 280
bool EmbeddedMap3::mergeFaces(Dart d)
{
	Dart d1 = phi1(d);

	if(Map3::mergeFaces(d))
	{
		if(isOrbitEmbedded<FACE2>())
		{
281
			Algo::Topo::setOrbitEmbedding<FACE2>(*this, d1, getEmbedding<FACE2>(d1)) ;
Thomas's avatar
Thomas committed
282 283 284 285
		}

		if(isOrbitEmbedded<FACE>())
		{
286
			Algo::Topo::setOrbitEmbedding<FACE>(*this, d1, getEmbedding<FACE>(d1)) ;
Thomas's avatar
Thomas committed
287 288 289 290 291 292 293 294
		}

		return true;
	}

	return false;
}

295 296 297 298 299 300
//!
/*!
 *
 */
Dart EmbeddedMap3::collapseFace(Dart d, bool delDegenerateVolumes)
{
301
	unsigned int vEmb = getEmbedding<VERTEX>(d) ;
302 303 304 305 306

	Dart resV = Map3::collapseFace(d, delDegenerateVolumes);

	if(resV != NIL)
	{
307
		if(isOrbitEmbedded<VERTEX>())
308
		{
309
			Algo::Topo::setOrbitEmbedding<VERTEX>(*this, resV, vEmb);
310 311 312 313 314 315
		}
	}

	return resV;
}

untereiner's avatar
untereiner committed
316
void EmbeddedMap3::sewVolumes(Dart d, Dart e, bool withBoundary)
317
{
318 319 320 321 322 323
	if (!withBoundary)
	{
		Map3::sewVolumes(d, e, false) ;
		return ;
	}

untereiner's avatar
untereiner committed
324
	Map3::sewVolumes(d, e, withBoundary);
325

326 327
	// embed the vertex orbits from the oriented face with dart e
	// with vertex orbits value from oriented face with dart d
328
	if (isOrbitEmbedded<VERTEX>())
329
	{
330
		Dart it = d ;
untereiner's avatar
untereiner committed
331 332
		do
		{
333
			Algo::Topo::setOrbitEmbedding<VERTEX>(*this, it, getEmbedding<VERTEX>(it)) ;
334 335
			it = phi1(it) ;
		} while(it != d) ;
336 337
	}

338 339
	// embed the new edge orbit with the old edge orbit value
	// for all the face
340
	if (isOrbitEmbedded<EDGE>())
341
	{
342
		Dart it = d ;
untereiner's avatar
untereiner committed
343 344
		do
		{
345
			Algo::Topo::setOrbitEmbedding<EDGE>(*this, it, getEmbedding<EDGE>(it)) ;
346 347
			it = phi1(it) ;
		} while(it != d) ;
348 349
	}

350
	// embed the face orbit from the volume sewn
351
	if (isOrbitEmbedded<FACE>())
352
	{
353
		Algo::Topo::setOrbitEmbedding<FACE>(*this, e, getEmbedding<FACE>(d)) ;
354
	}
355 356
}

357
void EmbeddedMap3::unsewVolumes(Dart d, bool withBoundary)
358
{
359 360 361 362 363 364
	if (!withBoundary)
	{
		Map3::unsewVolumes(d, false) ;
		return ;
	}

365 366
	Dart dd = alpha1(d);

untereiner's avatar
untereiner committed
367
	unsigned int fEmb = EMBNULL ;
368
	if(isOrbitEmbedded<FACE>())
Pierre Kraemer's avatar
Pierre Kraemer committed
369
		fEmb = getEmbedding<FACE>(d) ;
untereiner's avatar
untereiner committed
370

371 372
	Map3::unsewVolumes(d);

untereiner's avatar
untereiner committed
373 374 375 376
	Dart dit = d;
	do
	{
		// embed the unsewn vertex orbit with the vertex embedding if it is deconnected
377
		if(isOrbitEmbedded<VERTEX>())
Thomas's avatar
Thomas committed
378
		{
untereiner's avatar
untereiner committed
379
			if(!sameVertex(dit, dd))
Thomas's avatar
Thomas committed
380
			{
381 382 383
				Algo::Topo::setOrbitEmbedding<VERTEX>(*this, dit, getEmbedding<VERTEX>(dit)) ;
				Algo::Topo::setOrbitEmbeddingOnNewCell<VERTEX>(*this, dd);
				Algo::Topo::copyCellAttributes<VERTEX>(*this, dd, dit);
384 385 386
			}
			else
			{
387
				Algo::Topo::setOrbitEmbedding<VERTEX>(*this, dit, getEmbedding<VERTEX>(dit)) ;
Thomas's avatar
Thomas committed
388
			}
untereiner's avatar
untereiner committed
389
		}
Thomas's avatar
Thomas committed
390

untereiner's avatar
untereiner committed
391
		dd = phi_1(dd);
Thomas's avatar
Thomas committed
392

untereiner's avatar
untereiner committed
393
		// embed the unsewn edge with the edge embedding if it is deconnected
394
		if(isOrbitEmbedded<EDGE>())
untereiner's avatar
untereiner committed
395 396
		{
			if(!sameEdge(dit, dd))
Thomas's avatar
Thomas committed
397
			{
398 399
				Algo::Topo::setOrbitEmbeddingOnNewCell<EDGE>(*this, dd);
				Algo::Topo::copyCellAttributes<EDGE>(*this, dd, dit);
Pierre Kraemer's avatar
Pierre Kraemer committed
400
				copyDartEmbedding<EDGE>(phi3(dit), dit) ;
401 402 403
			}
			else
			{
Pierre Kraemer's avatar
Pierre Kraemer committed
404 405 406
				unsigned int eEmb = getEmbedding<EDGE>(dit) ;
				setDartEmbedding<EDGE>(phi3(dit), eEmb) ;
				setDartEmbedding<EDGE>(alpha_2(dit), eEmb) ;
Thomas's avatar
Thomas committed
407
			}
untereiner's avatar
untereiner committed
408
		}
Thomas's avatar
Thomas committed
409

410
		if(isOrbitEmbedded<FACE>())
Thomas's avatar
Thomas committed
411
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
412
			setDartEmbedding<FACE>(phi3(dit), fEmb) ;
Thomas's avatar
Thomas committed
413
		}
untereiner's avatar
untereiner committed
414 415 416 417 418

		dit = phi1(dit);
	} while(dit != d);

	// embed the unsewn face with the face embedding
419
	if (isOrbitEmbedded<FACE>())
untereiner's avatar
untereiner committed
420
	{
421 422
		Algo::Topo::setOrbitEmbeddingOnNewCell<FACE>(*this, dd);
		Algo::Topo::copyCellAttributes<FACE>(*this, dd, d);
Thomas's avatar
Thomas committed
423
	}
424 425
}

426
bool EmbeddedMap3::mergeVolumes(Dart d, bool deleteFace)
427 428 429
{
	Dart d2 = phi2(d);

430
	if(Map3::mergeVolumes(d, deleteFace))
431
	{
432
		if (isOrbitEmbedded<VOLUME>())
433
		{
434
			Algo::Topo::setOrbitEmbedding<VOLUME>(*this, d2, getEmbedding<VOLUME>(d2)) ;
435 436 437 438 439 440
		}
		return true;
	}
	return false;
}

untereiner's avatar
untereiner committed
441 442 443 444
void EmbeddedMap3::splitVolume(std::vector<Dart>& vd)
{
	Map3::splitVolume(vd);

445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460
	// follow the edge path a second time to embed the vertex, edge and volume orbits
	for(std::vector<Dart>::iterator it = vd.begin() ; it != vd.end() ; ++it)
	{
		Dart dit = *it;
		Dart dit23 = phi3(phi2(dit));

		// embed the vertex embedded from the origin volume to the new darts
		if(isOrbitEmbedded<VERTEX>())
		{
			copyDartEmbedding<VERTEX>(dit23, dit);
			copyDartEmbedding<VERTEX>(phi2(dit), phi1(dit));
		}

		// embed the edge embedded from the origin volume to the new darts
		if(isOrbitEmbedded<EDGE2>())
		{
461 462
			Algo::Topo::setOrbitEmbeddingOnNewCell<EDGE2>(*this, dit23) ;
			Algo::Topo::copyCellAttributes<EDGE2>(*this, dit23, dit) ;
463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485

			copyDartEmbedding<EDGE2>(phi2(dit), dit);
		}

		// embed the edge embedded from the origin volume to the new darts
		if(isOrbitEmbedded<EDGE>())
		{
			unsigned int eEmb = getEmbedding<EDGE>(dit) ;
			setDartEmbedding<EDGE>(dit23, eEmb);
			setDartEmbedding<EDGE>(phi2(dit), eEmb);
		}

		// embed the volume embedded from the origin volume to the new darts
		if(isOrbitEmbedded<VOLUME>())
		{
			copyDartEmbedding<VOLUME>(phi2(dit), dit);
		}
	}

	if(isOrbitEmbedded<VOLUME>())
	{
		Dart v = vd.front() ;
		Dart v23 = phi3(phi2(v));
486 487
		Algo::Topo::setOrbitEmbeddingOnNewCell<VOLUME>(*this, v23) ;
		Algo::Topo::copyCellAttributes<VOLUME>(*this, v23, v) ;
488 489 490 491 492 493 494 495
	}
}

//! Split a volume into two volumes along a edge path and add the given face between
void EmbeddedMap3::splitVolumeWithFace(std::vector<Dart>& vd, Dart d)
{
	Map3::splitVolumeWithFace(vd,d);

untereiner's avatar
untereiner committed
496
	// follow the edge path a second time to embed the vertex, edge and volume orbits
untereiner's avatar
untereiner committed
497 498 499
	for(std::vector<Dart>::iterator it = vd.begin() ; it != vd.end() ; ++it)
	{
		Dart dit = *it;
500
		Dart dit23 = phi3(phi2(dit));
untereiner's avatar
untereiner committed
501

untereiner's avatar
untereiner committed
502
		// embed the vertex embedded from the origin volume to the new darts
503
		if(isOrbitEmbedded<VERTEX>())
untereiner's avatar
untereiner committed
504
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
505 506
			copyDartEmbedding<VERTEX>(dit23, dit);
			copyDartEmbedding<VERTEX>(phi2(dit), phi1(dit));
untereiner's avatar
untereiner committed
507 508
		}

509 510 511
		// embed the edge embedded from the origin volume to the new darts
		if(isOrbitEmbedded<EDGE2>())
		{
512 513
			Algo::Topo::setOrbitEmbeddingOnNewCell<EDGE2>(*this, dit23) ;
			Algo::Topo::copyCellAttributes<EDGE2>(*this, dit23, dit) ;
514 515 516 517

			copyDartEmbedding<EDGE2>(phi2(dit), dit);
		}

untereiner's avatar
untereiner committed
518
		// embed the edge embedded from the origin volume to the new darts
519
		if(isOrbitEmbedded<EDGE>())
untereiner's avatar
untereiner committed
520
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
521 522 523
			unsigned int eEmb = getEmbedding<EDGE>(dit) ;
			setDartEmbedding<EDGE>(dit23, eEmb);
			setDartEmbedding<EDGE>(phi2(dit), eEmb);
untereiner's avatar
untereiner committed
524 525
		}

untereiner's avatar
untereiner committed
526
		// embed the volume embedded from the origin volume to the new darts
527
		if(isOrbitEmbedded<VOLUME>())
untereiner's avatar
untereiner committed
528
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
529
			copyDartEmbedding<VOLUME>(phi2(dit), dit);
untereiner's avatar
untereiner committed
530 531
		}
	}
untereiner's avatar
untereiner committed
532

533
	if(isOrbitEmbedded<VOLUME>())
untereiner's avatar
untereiner committed
534
	{
535
		Dart v = vd.front() ;
536
		Dart v23 = phi3(phi2(v));
537 538
		Algo::Topo::setOrbitEmbeddingOnNewCell<VOLUME>(*this, v23) ;
		Algo::Topo::copyCellAttributes<VOLUME>(*this, v23, v) ;
untereiner's avatar
untereiner committed
539 540 541
	}
}

542 543
Dart EmbeddedMap3::collapseVolume(Dart d, bool delDegenerateVolumes)
{
544
	unsigned int vEmb = getEmbedding<VERTEX>(d) ;
545 546 547 548 549

	Dart resV = Map3::collapseVolume(d, delDegenerateVolumes);

	if(resV != NIL)
	{
550
		if(isOrbitEmbedded<VERTEX>())
551
		{
552
			Algo::Topo::setOrbitEmbedding<VERTEX>(*this, resV, vEmb);
553 554 555 556 557 558
		}
	}

	return resV;
}

559
unsigned int EmbeddedMap3::closeHole(Dart d)
untereiner's avatar
untereiner committed
560
{
561
	unsigned int nbF = Map3::closeHole(d) ;
untereiner's avatar
untereiner committed
562

Pierre Kraemer's avatar
Pierre Kraemer committed
563
	DartMarkerStore<EmbeddedMap3> mark(*this);	// Lock a marker
untereiner's avatar
untereiner committed
564 565 566

	std::vector<Dart> visitedFaces;	// Faces that are traversed
	visitedFaces.reserve(1024) ;
567
	visitedFaces.push_back(phi3(d));// Start with the face of d
Pierre Kraemer's avatar
Pierre Kraemer committed
568
	mark.markOrbit<FACE2>(phi3(d)) ;
untereiner's avatar
untereiner committed
569 570

	// For every face added to the list
571
	for(unsigned int i = 0; i < visitedFaces.size(); ++i)
untereiner's avatar
untereiner committed
572
	{
573 574
		Dart it = visitedFaces[i] ;
		Dart f = it ;
575
		do
untereiner's avatar
untereiner committed
576
		{
577
			if(isOrbitEmbedded<VERTEX>())
untereiner's avatar
untereiner committed
578
			{
Pierre Kraemer's avatar
Pierre Kraemer committed
579
				copyDartEmbedding<VERTEX>(f, alpha1(f)) ;
580
			}
581
			if(isOrbitEmbedded<EDGE>())
582
			{
Pierre Kraemer's avatar
Pierre Kraemer committed
583
				copyDartEmbedding<EDGE>(f, phi3(f)) ;
584
			}
585
			if(isOrbitEmbedded<FACE>())
586
			{
Pierre Kraemer's avatar
Pierre Kraemer committed
587
				copyDartEmbedding<FACE>(f, phi3(f)) ;
588 589 590 591 592 593
			}

			Dart adj = phi2(f);	// Get adjacent face
			if (!mark.isMarked(adj))
			{
				visitedFaces.push_back(adj);	// Add it
Pierre Kraemer's avatar
Pierre Kraemer committed
594
				mark.markOrbit<FACE2>(adj) ;
595 596 597
			}

			f = phi1(f) ;
598
		} while(f != it) ;
untereiner's avatar
untereiner committed
599 600 601
	}

	return nbF ;
untereiner's avatar
untereiner committed
602 603
}

604
bool EmbeddedMap3::check()
605
{
606
	std::cout << "nb vertex orbits : " << Algo::Topo::getNbOrbits<VERTEX>(*this) << std::endl ;
607 608
    std::cout << "nb vertex cells : " << m_attribs[VERTEX].size() << std::endl ;

609
	std::cout << "nb edge orbits : " << Algo::Topo::getNbOrbits<EDGE>(*this) << std::endl ;
610 611
    std::cout << "nb edge cells : " << m_attribs[EDGE].size() << std::endl ;

612
	std::cout << "nb face orbits : " << Algo::Topo::getNbOrbits<FACE>(*this) << std::endl ;
613 614
    std::cout << "nb face cells : " << m_attribs[FACE].size() << std::endl ;

615
	std::cout << "nb volume orbits : " << Algo::Topo::getNbOrbits<VOLUME>(*this) << std::endl ;
616 617
    std::cout << "nb volume cells : " << m_attribs[VOLUME].size() << std::endl ;

untereiner's avatar
untereiner committed
618 619 620 621 622 623
	bool topo = Map3::check() ;
	if (!topo)
		return false ;

	std::cout << "Check: embedding begin" << std::endl ;

624
	for(Dart d = begin(); d != end(); next(d))
625
	{
626
		if(isOrbitEmbedded<VERTEX>())
627
		{
628
			if( getEmbedding<VERTEX>(d) != getEmbedding<VERTEX>(alpha1(d)))
629 630 631 632
			{
				std::cout << "Embedding Check : different embeddings on vertex (alpha1(d) != d)" << std::endl ;
				return false ;
			}
633
			if(getEmbedding<VERTEX>(d) != getEmbedding<VERTEX>(alpha2(d)) )
634
			{
635
				std::cout << "Embedding Check : different embeddings on vertex (alpha2(d) != d)" << std::endl ;
untereiner's avatar
untereiner committed
636 637 638 639
				return false ;
			}
		}

640
		if(isOrbitEmbedded<EDGE>())
untereiner's avatar
untereiner committed
641
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
642 643
			if( getEmbedding<EDGE>(d) != getEmbedding<EDGE>(phi2(d)) ||
					getEmbedding<EDGE>(d) != getEmbedding<EDGE>(phi3(d)) )
untereiner's avatar
untereiner committed
644 645 646 647 648 649
			{
				std::cout << "Embedding Check : different embeddings on edge" << std::endl ;
				return false ;
			}
		}

650
		if (isOrbitEmbedded<FACE2>())
untereiner's avatar
untereiner committed
651
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
652
			if (getEmbedding<FACE2>(d) != getEmbedding<FACE2>(phi1(d)))
untereiner's avatar
untereiner committed
653 654 655
			{
				CGoGNout << "Check: different embeddings on oriented face" << CGoGNendl ;
				return false ;
656
			}
657
		}
658

659
		if (isOrbitEmbedded<FACE>())
untereiner's avatar
untereiner committed
660
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
661 662
			if( getEmbedding<FACE>(d) != getEmbedding<FACE>(phi1(d)) ||
					getEmbedding<FACE>(d) != getEmbedding<FACE>(phi3(d)) )
untereiner's avatar
untereiner committed
663 664 665 666 667 668
			{
				CGoGNout << "Check: different embeddings on face" << CGoGNendl ;
				return false ;
			}
		}

669
		if (isOrbitEmbedded<VOLUME>())
untereiner's avatar
untereiner committed
670
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
671 672
			if( getEmbedding<VOLUME>(d) != getEmbedding<VOLUME>(phi1(d)) ||
					getEmbedding<VOLUME>(d) != getEmbedding<VOLUME>(phi2(d)) )
untereiner's avatar
untereiner committed
673 674 675 676 677
			{
				CGoGNout << "Check: different embeddings on volume" << CGoGNendl ;
				return false ;
			}
		}
678
	}
679

680
	std::cout << "Check: embedding ok" << std::endl ;
681

682
	return true ;
683 684 685
}

} // namespace CGoGN