embeddedMap3.cpp 11.8 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 24 25 26 27 28 29
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

#include "Topology/map/embeddedMap3.h"

namespace CGoGN
{

Pierre Kraemer's avatar
Pierre Kraemer committed
30
Dart EmbeddedMap3::deleteVertex(Dart d)
31
{
untereiner's avatar
untereiner committed
32 33 34 35 36 37 38 39 40
	Dart v = Map3::deleteVertex(d) ;
	if(v != NIL)
	{
		if (isOrbitEmbedded(VOLUME))
		{
			embedOrbit(VOLUME, v, getEmbedding(VOLUME, v)) ;
		}
	}
	return v ;
41 42
}

David Cazier's avatar
David Cazier committed
43
Dart EmbeddedMap3::cutEdge(Dart d)
44
{
David Cazier's avatar
David Cazier committed
45
	Dart nd = Map3::cutEdge(d);
46 47 48

	if(isOrbitEmbedded(EDGE))
	{
untereiner's avatar
untereiner committed
49 50 51
		// embed the new darts created in the cut edge
		embedOrbit(EDGE, d, getEmbedding(EDGE, d)) ;
		// embed a new cell for the new edge and copy the attributes' line (c) Lionel
untereiner's avatar
untereiner committed
52 53
		embedNewCell(EDGE, nd) ;
		copyCell(EDGE, nd, d) ;
54 55
	}

56 57
//	if(isOrbitEmbedded(ORIENTED_FACE))
	if(isOrbitEmbedded(FACE2))
58 59 60 61
	{
		Dart f = d;
		do
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
62
			Dart f1 = phi1(f) ;
63 64
//			copyDartEmbedding(ORIENTED_FACE, f1, f);
			copyDartEmbedding(FACE2, f1, f);
Pierre Kraemer's avatar
Pierre Kraemer committed
65
			Dart e = phi3(f1);
66
//			copyDartEmbedding(ORIENTED_FACE, phi1(e), e);
67 68
//			copyDartEmbedding(FACE2, f1, f);
			copyDartEmbedding(FACE2, phi1(e), e);
untereiner's avatar
untereiner committed
69 70 71 72 73 74 75 76 77 78 79 80
			f = alpha2(f);
		} while(f != d);
	}

	if(isOrbitEmbedded(FACE))
	{
		Dart f = d;
		do
		{
			unsigned int fEmb = getEmbedding(FACE, f) ;
			setDartEmbedding(FACE, phi1(f), fEmb);
			setDartEmbedding(FACE, phi3(f), fEmb);
81 82 83 84 85 86 87 88 89
			f = alpha2(f);
		} while(f != d);
	}

	if(isOrbitEmbedded(VOLUME))
	{
		Dart f = d;
		do
		{
untereiner's avatar
untereiner committed
90 91 92
			unsigned int vEmb = getEmbedding(VOLUME, f) ;
			setDartEmbedding(VOLUME, phi1(f), vEmb);
			setDartEmbedding(VOLUME, phi2(f), vEmb);
93 94 95
			f = alpha2(f);
		} while(f != d);
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
96 97

	return nd ;
98 99
}

100
bool EmbeddedMap3::uncutEdge(Dart d)
101
{
102
	if(Map3::uncutEdge(d))
untereiner's avatar
untereiner committed
103
	{
104 105 106
		//embed all darts from the old two edges to one of the two edge embedding
		if(isOrbitEmbedded(EDGE))
		{
untereiner's avatar
untereiner committed
107
			embedOrbit(EDGE, d, getEmbedding(EDGE, d)) ;
108 109
		}
		return true ;
untereiner's avatar
untereiner committed
110
	}
111
	return false ;
112 113
}

untereiner's avatar
untereiner committed
114 115
Dart EmbeddedMap3::deleteEdge(Dart d)
{
116
	Dart v = Map3::deleteEdge(d) ;
untereiner's avatar
untereiner committed
117 118 119 120 121 122 123 124 125 126
	if(v != NIL)
	{
		if(isOrbitEmbedded(VOLUME))
		{
			embedOrbit(VOLUME, v, getEmbedding(VOLUME, v)) ;
		}
	}
	return v;
}

127 128 129 130 131
bool EmbeddedMap3::edgeCanCollapse(Dart d)
{
	//Criteres sur le bord
	if(isBoundaryEdge(d))
	{
132
		//fusion de deux bords
133 134 135

		//deconnection du bord
	}
136 137

	return false;
138 139
}

untereiner's avatar
untereiner committed
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
Dart EmbeddedMap3::collapseEdge(Dart d, bool delDegenerateVolumes)
{
	unsigned int vEmb = getEmbedding(VERTEX, d) ;

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

	if(resV != NIL)
	{
		if(isOrbitEmbedded(VERTEX))
		{
			embedOrbit(VERTEX,resV,vEmb);
		}
	}

	return resV;
}

157 158 159 160
//bool EmbeddedMap3::collapseDegeneratedFace(Dart d)
//{
//	return Map3::collapseDegeneratedFace(d);
//}
161

162 163
void EmbeddedMap3::splitFace(Dart d, Dart e)
{
untereiner's avatar
untereiner committed
164 165 166 167
	Dart dd = phi1(phi3(d));
	Dart ee = phi1(phi3(e));

	Map3::splitFace(d, e);
168 169 170

	if(isOrbitEmbedded(VERTEX))
	{
171 172 173 174 175 176
		unsigned int vEmb1 = getEmbedding(VERTEX, d) ;
		unsigned int vEmb2 = getEmbedding(VERTEX, e) ;
		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
177
	}
178

179
	if(isOrbitEmbedded(FACE2))
untereiner's avatar
untereiner committed
180
	{
181 182 183
		copyDartEmbedding(FACE2, phi_1(d), d) ;
		embedNewCell(FACE2, e) ;
		copyCell(FACE2, e, d) ;
184

185 186 187
		copyDartEmbedding(FACE2, phi_1(dd), dd) ;
		embedNewCell(FACE2, ee) ;
		copyCell(FACE2, ee, dd) ;
188 189 190 191
	}

	if(isOrbitEmbedded(FACE))
	{
untereiner's avatar
untereiner committed
192 193
		unsigned int fEmb = getEmbedding(FACE, d) ;
		setDartEmbedding(FACE, phi_1(d), fEmb) ;
194
		setDartEmbedding(FACE, phi_1(ee), fEmb) ;
untereiner's avatar
untereiner committed
195 196
		embedNewCell(FACE, e);
		copyCell(FACE, e, d);
197 198 199 200
	}

	if(isOrbitEmbedded(VOLUME))
	{
untereiner's avatar
untereiner committed
201 202 203
		unsigned int vEmb1 = getEmbedding(VOLUME, d) ;
		setDartEmbedding(VOLUME, phi_1(d),  vEmb1);
		setDartEmbedding(VOLUME, phi_1(e),  vEmb1);
204

untereiner's avatar
untereiner committed
205 206 207
		unsigned int vEmb2 = getEmbedding(VOLUME, dd) ;
		setDartEmbedding(VOLUME, phi_1(dd),  vEmb2);
		setDartEmbedding(VOLUME, phi_1(ee),  vEmb2);
208 209 210
	}
}

untereiner's avatar
untereiner committed
211
void EmbeddedMap3::sewVolumes(Dart d, Dart e, bool withBoundary)
212
{
213 214 215 216 217 218
	if (!withBoundary)
	{
		Map3::sewVolumes(d, e, false) ;
		return ;
	}

untereiner's avatar
untereiner committed
219
	Map3::sewVolumes(d, e, withBoundary);
220

221 222
	// embed the vertex orbits from the oriented face with dart e
	// with vertex orbits value from oriented face with dart d
223 224
	if (isOrbitEmbedded(VERTEX))
	{
225
		Dart it = d ;
untereiner's avatar
untereiner committed
226 227
		do
		{
228 229 230
			embedOrbit(VERTEX, it, getEmbedding(VERTEX, it)) ;
			it = phi1(it) ;
		} while(it != d) ;
231 232
	}

233 234
	// embed the new edge orbit with the old edge orbit value
	// for all the face
235 236
	if (isOrbitEmbedded(EDGE))
	{
237
		Dart it = d ;
untereiner's avatar
untereiner committed
238 239
		do
		{
240 241 242
			embedOrbit(EDGE, it, getEmbedding(EDGE, it)) ;
			it = phi1(it) ;
		} while(it != d) ;
243 244
	}

245
	// embed the face orbit from the volume sewn
246
	if (isOrbitEmbedded(FACE))
247
	{
untereiner's avatar
untereiner committed
248
		embedOrbit(FACE, e, getEmbedding(FACE, d)) ;
249
	}
250 251 252 253
}

void EmbeddedMap3::unsewVolumes(Dart d)
{
254 255
	Dart dd = alpha1(d);

untereiner's avatar
untereiner committed
256 257 258 259
	unsigned int fEmb = EMBNULL ;
	if(isOrbitEmbedded(FACE))
		fEmb = getEmbedding(FACE, d) ;

260 261
	Map3::unsewVolumes(d);

untereiner's avatar
untereiner committed
262 263 264 265 266
	Dart dit = d;
	do
	{
		// embed the unsewn vertex orbit with the vertex embedding if it is deconnected
		if(isOrbitEmbedded(VERTEX))
Thomas's avatar
Thomas committed
267
		{
untereiner's avatar
untereiner committed
268
			if(!sameVertex(dit, dd))
Thomas's avatar
Thomas committed
269
			{
270
				embedOrbit(VERTEX, dit, getEmbedding(VERTEX, dit)) ;
untereiner's avatar
untereiner committed
271 272
				embedNewCell(VERTEX, dd);
				copyCell(VERTEX, dd, dit);
273 274 275
			}
			else
			{
276
				embedOrbit(VERTEX, dit, getEmbedding(VERTEX, dit)) ;
Thomas's avatar
Thomas committed
277
			}
untereiner's avatar
untereiner committed
278
		}
Thomas's avatar
Thomas committed
279

untereiner's avatar
untereiner committed
280
		dd = phi_1(dd);
Thomas's avatar
Thomas committed
281

untereiner's avatar
untereiner committed
282 283 284 285
		// embed the unsewn edge with the edge embedding if it is deconnected
		if(isOrbitEmbedded(EDGE))
		{
			if(!sameEdge(dit, dd))
Thomas's avatar
Thomas committed
286
			{
untereiner's avatar
untereiner committed
287 288
				embedNewCell(EDGE, dd);
				copyCell(EDGE, dd, dit);
289 290 291 292 293 294 295
				copyDartEmbedding(EDGE, phi3(dit), dit) ;
			}
			else
			{
				unsigned int eEmb = getEmbedding(EDGE, dit) ;
				setDartEmbedding(EDGE, phi3(dit), eEmb) ;
				setDartEmbedding(EDGE, alpha_2(dit), eEmb) ;
Thomas's avatar
Thomas committed
296
			}
untereiner's avatar
untereiner committed
297
		}
Thomas's avatar
Thomas committed
298

untereiner's avatar
untereiner committed
299
		if(isOrbitEmbedded(FACE))
Thomas's avatar
Thomas committed
300
		{
untereiner's avatar
untereiner committed
301
			setDartEmbedding(FACE, phi3(dit), fEmb) ;
Thomas's avatar
Thomas committed
302
		}
untereiner's avatar
untereiner committed
303 304 305 306 307 308 309 310 311

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

	// embed the unsewn face with the face embedding
	if (isOrbitEmbedded(FACE))
	{
		embedNewCell(FACE, dd);
		copyCell(FACE, dd, d);
Thomas's avatar
Thomas committed
312
	}
313 314 315 316 317 318 319 320 321 322
}

bool EmbeddedMap3::mergeVolumes(Dart d)
{
	Dart d2 = phi2(d);

	if(Map3::mergeVolumes(d))
	{
		if (isOrbitEmbedded(VOLUME))
		{
untereiner's avatar
untereiner committed
323
			embedOrbit(VOLUME, d2, getEmbedding(VOLUME, d2)) ;
324 325 326 327 328 329
		}
		return true;
	}
	return false;
}

untereiner's avatar
untereiner committed
330 331 332 333
void EmbeddedMap3::splitVolume(std::vector<Dart>& vd)
{
	Map3::splitVolume(vd);

untereiner's avatar
untereiner committed
334
	// follow the edge path a second time to embed the vertex, edge and volume orbits
untereiner's avatar
untereiner committed
335 336 337
	for(std::vector<Dart>::iterator it = vd.begin() ; it != vd.end() ; ++it)
	{
		Dart dit = *it;
untereiner's avatar
untereiner committed
338
		Dart dit23 = alpha2(dit);
untereiner's avatar
untereiner committed
339

untereiner's avatar
untereiner committed
340
		// embed the vertex embedded from the origin volume to the new darts
untereiner's avatar
untereiner committed
341 342
		if(isOrbitEmbedded(VERTEX))
		{
untereiner's avatar
untereiner committed
343 344
			copyDartEmbedding(VERTEX, dit23, dit);
			copyDartEmbedding(VERTEX, phi2(dit), phi1(dit));
untereiner's avatar
untereiner committed
345 346
		}

untereiner's avatar
untereiner committed
347
		// embed the edge embedded from the origin volume to the new darts
untereiner's avatar
untereiner committed
348 349
		if(isOrbitEmbedded(EDGE))
		{
untereiner's avatar
untereiner committed
350 351 352
			unsigned int eEmb = getEmbedding(EDGE, dit) ;
			setDartEmbedding(EDGE, dit23, eEmb);
			setDartEmbedding(EDGE, phi2(dit), eEmb);
untereiner's avatar
untereiner committed
353 354
		}

untereiner's avatar
untereiner committed
355
		// embed the volume embedded from the origin volume to the new darts
untereiner's avatar
untereiner committed
356 357
		if(isOrbitEmbedded(VOLUME))
		{
untereiner's avatar
untereiner committed
358
			copyDartEmbedding(VOLUME, phi2(dit), dit);
untereiner's avatar
untereiner committed
359 360
		}
	}
untereiner's avatar
untereiner committed
361 362 363

	if(isOrbitEmbedded(VOLUME))
	{
364
		Dart v = vd.front() ;
untereiner's avatar
untereiner committed
365 366 367 368 369 370 371 372 373 374 375 376 377 378
		Dart v23 = alpha2(v) ;
		embedNewCell(VOLUME, v23) ;
		copyCell(VOLUME, v23, v) ;
	}
}

unsigned int EmbeddedMap3::closeHole(Dart d, bool forboundary)
{
	unsigned int nbF = Map3::closeHole(d, forboundary) ;

	DartMarkerStore mark(*this);	// Lock a marker

	std::vector<Dart> visitedFaces;	// Faces that are traversed
	visitedFaces.reserve(1024) ;
379
	visitedFaces.push_back(phi3(d));// Start with the face of d
380
	mark.markOrbit(FACE2, phi3(d)) ;
untereiner's avatar
untereiner committed
381 382

	// For every face added to the list
383
	for(unsigned int i = 0; i < visitedFaces.size(); ++i)
untereiner's avatar
untereiner committed
384
	{
385 386
		Dart it = visitedFaces[i] ;
		Dart f = it ;
387
		do
untereiner's avatar
untereiner committed
388
		{
389
			if(isOrbitEmbedded(VERTEX))
untereiner's avatar
untereiner committed
390
			{
391 392 393 394 395 396 397 398 399 400 401 402 403 404 405
				copyDartEmbedding(VERTEX, f, alpha1(f)) ;
			}
			if(isOrbitEmbedded(EDGE))
			{
				copyDartEmbedding(EDGE, f, phi3(f)) ;
			}
			if(isOrbitEmbedded(FACE))
			{
				copyDartEmbedding(FACE, f, phi3(f)) ;
			}

			Dart adj = phi2(f);	// Get adjacent face
			if (!mark.isMarked(adj))
			{
				visitedFaces.push_back(adj);	// Add it
406
				mark.markOrbit(FACE2, adj) ;
407 408 409
			}

			f = phi1(f) ;
410
		} while(f != it) ;
untereiner's avatar
untereiner committed
411 412 413
	}

	return nbF ;
untereiner's avatar
untereiner committed
414 415
}

416
bool EmbeddedMap3::check()
417
{
418 419 420
	bool topo = Map3::check() ;
	if (!topo)
		return false ;
421

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

424 425 426 427 428 429 430 431 432 433 434 435 436
    std::cout << "nb vertex orbits : " << getNbOrbits(VERTEX) << std::endl ;
    std::cout << "nb vertex cells : " << m_attribs[VERTEX].size() << std::endl ;

    std::cout << "nb edge orbits : " << getNbOrbits(EDGE) << std::endl ;
    std::cout << "nb edge cells : " << m_attribs[EDGE].size() << std::endl ;

    std::cout << "nb face orbits : " << getNbOrbits(FACE) << std::endl ;
    std::cout << "nb face cells : " << m_attribs[FACE].size() << std::endl ;

    std::cout << "nb volume orbits : " << getNbOrbits(VOLUME) << std::endl ;
    std::cout << "nb volume cells : " << m_attribs[VOLUME].size() << std::endl ;


437
	for(Dart d = begin(); d != end(); next(d))
438
	{
439
		if(isOrbitEmbedded(VERTEX))
440
		{
untereiner's avatar
untereiner committed
441 442
			if( getEmbedding(VERTEX, d) != getEmbedding(VERTEX, alpha1(d)) ||
					getEmbedding(VERTEX, d) != getEmbedding(VERTEX, alpha2(d)) )
443
			{
untereiner's avatar
untereiner committed
444 445 446 447 448 449 450 451 452 453 454 455 456 457 458
				std::cout << "Embedding Check : different embeddings on vertex" << std::endl ;
				return false ;
			}
		}

		if(isOrbitEmbedded(EDGE))
		{
			if( getEmbedding(EDGE, d) != getEmbedding(EDGE, phi2(d)) ||
					getEmbedding(EDGE, d) != getEmbedding(EDGE, phi3(d)) )
			{
				std::cout << "Embedding Check : different embeddings on edge" << std::endl ;
				return false ;
			}
		}

459
		if (isOrbitEmbedded(FACE2))
untereiner's avatar
untereiner committed
460
		{
461
			if (getEmbedding(FACE2, d) != getEmbedding(FACE2, phi1(d)))
untereiner's avatar
untereiner committed
462 463 464
			{
				CGoGNout << "Check: different embeddings on oriented face" << CGoGNendl ;
				return false ;
465
			}
466
		}
467

untereiner's avatar
untereiner committed
468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486
		if (isOrbitEmbedded(FACE))
		{
			if( getEmbedding(FACE, d) != getEmbedding(FACE, phi1(d)) ||
					getEmbedding(FACE, d) != getEmbedding(FACE, phi3(d)) )
			{
				CGoGNout << "Check: different embeddings on face" << CGoGNendl ;
				return false ;
			}
		}

		if (isOrbitEmbedded(VOLUME))
		{
			if( getEmbedding(VOLUME, d) != getEmbedding(VOLUME, phi1(d)) ||
					getEmbedding(VOLUME, d) != getEmbedding(VOLUME, phi2(d)) )
			{
				CGoGNout << "Check: different embeddings on volume" << CGoGNendl ;
				return false ;
			}
		}
487
	}
488

489
	std::cout << "Check: embedding ok" << std::endl ;
490

491
	return true ;
492 493 494
}

} // namespace CGoGN