ihm3.hpp 17.3 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
30
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

namespace CGoGN
{

namespace Algo
{

31
32
33
namespace Volume
{

untereiner's avatar
untereiner committed
34
namespace IHM
35
36
{

37
/***************************************************
38
 *  	   ATTRIBUTES MANAGEMENT    	           	 *
39
40
 ***************************************************/

Pierre Kraemer's avatar
Pierre Kraemer committed
41
42
template <typename T, unsigned int ORBIT>
AttributeHandler_IHM<T, ORBIT> ImplicitHierarchicalMap3::addAttribute(const std::string& nameAttr)
43
44
{
	bool addNextLevelCell = false ;
45
	if(!isOrbitEmbedded<ORBIT>())
46
47
		addNextLevelCell = true ;

Pierre Kraemer's avatar
Pierre Kraemer committed
48
	AttributeHandler<T, ORBIT> h = Map3::addAttribute<T, ORBIT>(nameAttr) ;
49
50
51

	if(addNextLevelCell)
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
52
		AttributeContainer& cellCont = m_attribs[ORBIT] ;
53
		AttributeMultiVector<unsigned int>* amv = cellCont.addAttribute<unsigned int>("nextLevelCell") ;
Pierre Kraemer's avatar
Pierre Kraemer committed
54
		m_nextLevelCell[ORBIT] = amv ;
55
56
57
58
		for(unsigned int i = cellCont.begin(); i < cellCont.end(); cellCont.next(i))
			amv->operator[](i) = EMBNULL ;
	}

Pierre Kraemer's avatar
Pierre Kraemer committed
59
	return AttributeHandler_IHM<T, ORBIT>(this, h.getDataVector()) ;
60
61
}

Pierre Kraemer's avatar
Pierre Kraemer committed
62
63
template <typename T, unsigned int ORBIT>
AttributeHandler_IHM<T, ORBIT> ImplicitHierarchicalMap3::getAttribute(const std::string& nameAttr)
64
{
Pierre Kraemer's avatar
Pierre Kraemer committed
65
66
	AttributeHandler<T, ORBIT> h = Map3::getAttribute<T, ORBIT>(nameAttr) ;
	return AttributeHandler_IHM<T, ORBIT>(this, h.getDataVector()) ;
67
}
untereiner's avatar
untereiner committed
68

69
70
71
72

inline void ImplicitHierarchicalMap3::update_topo_shortcuts()
{
	Map3::update_topo_shortcuts();
Pierre Kraemer's avatar
Pierre Kraemer committed
73
74
75
	m_dartLevel = Map3::getAttribute<unsigned int, DART>("dartLevel") ;
	m_faceId = Map3::getAttribute<unsigned int, DART>("faceId") ;
	m_edgeId = Map3::getAttribute<unsigned int, DART>("edgeId") ;
76
77
78

	//AttributeContainer& cont = m_attribs[DART] ;
	//m_nextLevelCell = cont.getDataVector<unsigned int>(cont.getAttributeIndex("nextLevelCell")) ;
79
80
81
}


82
/***************************************************
untereiner's avatar
untereiner committed
83
 *          			 	    MAP TRAVERSAL         		  		         *
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
 ***************************************************/

inline Dart ImplicitHierarchicalMap3::newDart()
{
	Dart d = Map3::newDart() ;
	m_dartLevel[d] = m_curLevel ;
	if(m_curLevel > m_maxLevel)			// update max level
		m_maxLevel = m_curLevel ;		// if needed
	return d ;
}

inline Dart ImplicitHierarchicalMap3::phi1(Dart d)
{
	assert(m_dartLevel[d] <= m_curLevel || !"Access to a dart introduced after current level") ;
	bool finished = false ;

	unsigned int edgeId = m_edgeId[d] ;
	Dart it = d ;
untereiner's avatar
untereiner committed
102

103
104
	do
	{
untereiner's avatar
untereiner committed
105

106
107
108
109
110
		it = Map3::phi1(it) ;
		if(m_dartLevel[it] <= m_curLevel)
			finished = true ;
		else
		{
111
			while(m_edgeId[it] != edgeId)
112
				it = Map3::phi1(phi2bis(it));
untereiner's avatar
untereiner committed
113

114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
		}
	} while(!finished) ;

	return it ;
}

inline Dart ImplicitHierarchicalMap3::phi_1(Dart d)
{
	assert(m_dartLevel[d] <= m_curLevel || !"Access to a dart introduced after current level") ;
	bool finished = false ;

	Dart it = Map3::phi_1(d) ;
	unsigned int edgeId = m_edgeId[it] ;
	do
	{
		if(m_dartLevel[it] <= m_curLevel)
			finished = true ;
		else
		{
			it = Map3::phi_1(it) ;
134
			while(m_edgeId[it] != edgeId)
untereiner's avatar
untereiner committed
135
				it = Map3::phi_1(phi2bis(it));
136
137
138
139
140
141
142
143
144
145
146
147
		}
	} while(!finished) ;

	return it ;
}

inline Dart ImplicitHierarchicalMap3::phi2bis(Dart d)
{
	unsigned int faceId = m_faceId[d];
	Dart it = d;

	it = Map3::phi2(it) ;
untereiner's avatar
untereiner committed
148

149
150
151
152
	if(m_faceId[it] == faceId)
		return it;
	else
	{
untereiner's avatar
untereiner committed
153
154
		do
		{
155
			it = Map3::phi2(Map3::phi3(it));
untereiner's avatar
untereiner committed
156
157
		}
		while(m_faceId[it] != faceId);
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

		return it;
	}
}

inline Dart ImplicitHierarchicalMap3::phi2(Dart d)
{
	assert(m_dartLevel[d] <= m_curLevel || !"Access to a dart introduced after current level") ;

	return Map3::phi2(Map3::phi_1(phi1(d))) ;
}

inline Dart ImplicitHierarchicalMap3::phi3(Dart d)
{
	assert(m_dartLevel[d] <= m_curLevel || !"Access to a dart introduced after current level") ;

	if(Map3::phi3(d) == d)
		return d;

	return Map3::phi3(Map3::phi_1(phi1(d)));
}

inline Dart ImplicitHierarchicalMap3::alpha0(Dart d)
{
	return phi3(d) ;
}

inline Dart ImplicitHierarchicalMap3::alpha1(Dart d)
{
187
	//assert(m_dartLevel[d] <= m_curLevel || !"Access to a dart introduced after current level") ;
188

189
	return phi3(phi_1(d)) ;
190
191
192
193
}

inline Dart ImplicitHierarchicalMap3::alpha2(Dart d)
{
untereiner's avatar
untereiner committed
194
195
	assert(m_dartLevel[d] <= m_curLevel || !"Access to a dart introduced after current level") ;

196
	return phi3(phi2(d));
197
198
199
200
}

inline Dart ImplicitHierarchicalMap3::alpha_2(Dart d)
{
untereiner's avatar
untereiner committed
201
202
	assert(m_dartLevel[d] <= m_curLevel || !"Access to a dart introduced after current level") ;

203
	return phi2(phi3(d));
204
205
}

206
inline Dart ImplicitHierarchicalMap3::begin() const
207
208
209
210
211
212
213
{
	Dart d = Map3::begin() ;
	while(m_dartLevel[d] > m_curLevel)
		Map3::next(d) ;
	return d ;
}

214
inline Dart ImplicitHierarchicalMap3::end() const
215
216
217
218
{
	return Map3::end() ;
}

219
inline void ImplicitHierarchicalMap3::next(Dart& d) const
220
221
222
223
{
	do
	{
		Map3::next(d) ;
224
	} while(d != Map3::end() && m_dartLevel[d] > m_curLevel) ;
225
226
}

227
inline bool ImplicitHierarchicalMap3::foreach_dart_of_vertex(Dart d, FunctorType& f, unsigned int thread)
228
{
untereiner's avatar
untereiner committed
229
	DartMarkerStore mv(*this, thread);	// Lock a marker
230
231
	bool found = false;					// Last functor return value

untereiner's avatar
untereiner committed
232
233
234
	std::vector<Dart> darts;	// Darts that are traversed
	darts.reserve(256);
	darts.push_back(d);			// Start with the dart d
235
236
	mv.mark(d);

237
	for(unsigned int i = 0; !found && i < darts.size(); ++i)
238
	{
untereiner's avatar
untereiner committed
239
240
241
242
		// add phi21 and phi23 successor if they are not marked yet
		Dart d2 = phi2(darts[i]);
		Dart d21 = phi1(d2); // turn in volume
		Dart d23 = phi3(d2); // change volume
243

untereiner's avatar
untereiner committed
244
		if(!mv.isMarked(d21))
245
		{
untereiner's avatar
untereiner committed
246
247
248
249
250
251
252
			darts.push_back(d21);
			mv.mark(d21);
		}
		if(!mv.isMarked(d23))
		{
			darts.push_back(d23);
			mv.mark(d23);
253
254
		}

untereiner's avatar
untereiner committed
255
		found = f(darts[i]);
256
257
258
259
	}
	return found;
}

260
inline bool ImplicitHierarchicalMap3::foreach_dart_of_edge(Dart d, FunctorType& f, unsigned int thread)
261
262
263
{
	Dart dNext = d;
	do {
untereiner's avatar
untereiner committed
264
		if (foreach_dart_of_edge2(dNext, f, thread))
265
			return true;
266
267
268
269
270
		dNext = alpha2(dNext);
	} while (dNext != d);
	return false;
}

271
inline bool ImplicitHierarchicalMap3::foreach_dart_of_oriented_face(Dart d, FunctorType& f, unsigned int thread)
272
273
274
275
276
277
278
279
280
281
282
{
	Dart dNext = d ;
	do
	{
		if (f(dNext))
			return true ;
		dNext = phi1(dNext) ;
	} while (dNext != d) ;
	return false ;
}

283
inline bool ImplicitHierarchicalMap3::foreach_dart_of_face(Dart d, FunctorType& f, unsigned int thread)
284
{
untereiner's avatar
untereiner committed
285
	return foreach_dart_of_oriented_face(d, f, thread) || foreach_dart_of_oriented_face(phi3(d), f, thread);
286
287
}

untereiner's avatar
untereiner 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
323
324
325
inline bool ImplicitHierarchicalMap3::foreach_dart_of_oriented_volume(Dart d, FunctorType& f, unsigned int thread)
{
	DartMarkerStore mark(*this, thread);	// Lock a marker
	bool found = false;				// Last functor return value

	std::vector<Dart> visitedFaces;	// Faces that are traversed
	visitedFaces.reserve(1024) ;
	visitedFaces.push_back(d);		// Start with the face of d

	// For every face added to the list
	for(unsigned int i = 0; !found && i < visitedFaces.size(); ++i)
	{
		if (!mark.isMarked(visitedFaces[i]))	// Face has not been visited yet
		{
			// Apply functor to the darts of the face
			found = foreach_dart_of_oriented_face(visitedFaces[i], f);

			// If functor returns false then mark visited darts (current face)
			// and add non visited adjacent faces to the list of face
			if (!found)
			{
				Dart e = visitedFaces[i] ;
				do
				{
					mark.mark(e);				// Mark
					Dart adj = phi2(e);			// Get adjacent face
					if (!mark.isMarked(adj))
						visitedFaces.push_back(adj);	// Add it
					e = phi1(e);
				} while(e != visitedFaces[i]);
			}
		}
	}
	return found;
}

inline bool ImplicitHierarchicalMap3::foreach_dart_of_volume(Dart d, FunctorType& f, unsigned int thread)
{
326
	return foreach_dart_of_oriented_volume(d, f, thread) ;
untereiner's avatar
untereiner committed
327
}
untereiner's avatar
untereiner committed
328
329

inline bool ImplicitHierarchicalMap3::foreach_dart_of_cc(Dart d, FunctorType& f, unsigned int thread)
330
{
untereiner's avatar
untereiner committed
331
	DartMarkerStore mark(*this, thread);	// Lock a marker
332
333
	bool found = false;				// Last functor return value

334
	std::vector<Dart> visitedFaces;	// Faces that are traversed
untereiner's avatar
untereiner committed
335
	visitedFaces.reserve(1024) ;
336
337
338
	visitedFaces.push_back(d);		// Start with the face of d

	// For every face added to the list
339
	for(unsigned int i = 0; !found && i < visitedFaces.size(); ++i)
340
	{
untereiner's avatar
untereiner committed
341
		if (!mark.isMarked(visitedFaces[i]))	// Face has not been visited yet
342
343
		{
			// Apply functor to the darts of the face
untereiner's avatar
untereiner committed
344
			found = foreach_dart_of_face(visitedFaces[i], f);
345
346
347
348
349

			// If functor returns false then mark visited darts (current face)
			// and add non visited adjacent faces to the list of face
			if (!found)
			{
untereiner's avatar
untereiner committed
350
				Dart e = visitedFaces[i] ;
351
352
				do
				{
untereiner's avatar
untereiner committed
353
354
355
					mark.mark(e);				// Mark
					Dart adj = phi2(e);			// Get adjacent face
					if (!mark.isMarked(adj))
356
						visitedFaces.push_back(adj);	// Add it
untereiner's avatar
untereiner committed
357
358
					e = phi1(e);
				} while(e != visitedFaces[i]);
359
360
361
362
363
			}
		}
	}
	return found;

untereiner's avatar
untereiner committed
364

untereiner's avatar
untereiner committed
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
//	//return foreach_dart_of_oriented_volume(d, f) ;
//	DartMarkerStore mv(*this,thread);	// Lock a marker
//	bool found = false;					// Last functor return value
//
//	std::vector<Dart> darts;	// Darts that are traversed
//	darts.reserve(1024);
//	darts.push_back(d);			// Start with the dart d
//	mv.mark(d);
//
//	for(unsigned int i = 0; !found && i < darts.size(); ++i)
//	{
//		// add all successors if they are not marked yet
//		Dart d2 = phi1(darts[i]); // turn in face
//		Dart d3 = phi2(darts[i]); // change face
//		Dart d4 = phi3(darts[i]); // change volume
//
//		if (!mv.isMarked(d2))
//		{
//			darts.push_back(d2);
//			mv.mark(d2);
//		}
//		if (!mv.isMarked(d3))
//		{
//			darts.push_back(d2);
//			mv.mark(d2);
//		}
//		if (!mv.isMarked(d4))
//		{
//			darts.push_back(d4);
//			mv.mark(d4);
//		}
//
//		found = f(darts[i]);
//	}
//	return found;
400
401
}

untereiner's avatar
untereiner committed
402

untereiner's avatar
untereiner committed
403
404
405
406
407
408
409
410
411
412
inline bool ImplicitHierarchicalMap3::foreach_dart_of_vertex2(Dart d, FunctorType& f, unsigned int thread)
{
	Dart dNext = d;
	do
	{
		if (f(dNext))
			return true;
		dNext = phi2(phi_1(dNext));
 	} while (dNext != d);
 	return false;
413
414
}

untereiner's avatar
untereiner committed
415
416
417
418
419
420
421
422
423
424
425
inline bool ImplicitHierarchicalMap3::foreach_dart_of_edge2(Dart d, FunctorType& f, unsigned int thread)
{
	if (f(d))
		return true;
	return f(phi2(d));
}

inline bool ImplicitHierarchicalMap3::foreach_dart_of_face2(Dart d, FunctorType& f, unsigned int thread)
{
	return foreach_dart_of_oriented_face(d,f,thread);
}
untereiner's avatar
untereiner committed
426

427
428
429
430
/***************************************************
 *              LEVELS MANAGEMENT                  *
 ***************************************************/

untereiner's avatar
untereiner committed
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
inline void ImplicitHierarchicalMap3::incCurrentLevel()
{
	if(m_curLevel < m_maxLevel)
		++m_curLevel ;
	else
		CGoGNout << "incCurrentLevel : already at maximum resolution level" << CGoGNendl ;
}

inline void ImplicitHierarchicalMap3::decCurrentLevel()
{
	if(m_curLevel > 0)
		--m_curLevel ;
	else
		CGoGNout << "decCurrentLevel : already at minimum resolution level" << CGoGNendl ;
}



449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
inline unsigned int ImplicitHierarchicalMap3::getCurrentLevel()
{
	return m_curLevel ;
}

inline void ImplicitHierarchicalMap3::setCurrentLevel(unsigned int l)
{
	assert(l >= 0 || !"Trying to set current level to a negative value") ;
	m_curLevel = l ;
}

inline unsigned int ImplicitHierarchicalMap3::getMaxLevel()
{
	return m_maxLevel ;
}

inline unsigned int ImplicitHierarchicalMap3::getDartLevel(Dart d)
{
	return m_dartLevel[d] ;
}

inline void ImplicitHierarchicalMap3::setDartLevel(Dart d, unsigned int l)
{
	m_dartLevel[d] = l ;
}

/***************************************************
 *             EDGE ID MANAGEMENT                  *
 ***************************************************/

inline unsigned int ImplicitHierarchicalMap3::getNewEdgeId()
{
	return m_edgeIdCount++ ;
}


inline unsigned int ImplicitHierarchicalMap3::getEdgeId(Dart d)
{
	return m_edgeId[d] ;
}

inline void ImplicitHierarchicalMap3::setEdgeId(Dart d, unsigned int i, unsigned int orbit)
{
492
	if(orbit == EDGE)
493
494
495
496
497
498
499
500
501
502
503
	{
		Dart e = d;

		do
		{
			m_edgeId[e] = i;
			m_edgeId[Map3::phi2(e)] = i;

			e = Map3::alpha2(e);
		} while(e != d);
	}
504
	else if(orbit == DART)
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
	{
		m_edgeId[d] = i;
	}
}

/***************************************************
 *             FACE ID MANAGEMENT                  *
 ***************************************************/

inline unsigned int ImplicitHierarchicalMap3::getNewFaceId()
{
	return m_faceIdCount++;
}

inline unsigned int ImplicitHierarchicalMap3::getFaceId(Dart d)
{
	return m_faceId[d] ;
}

524
inline void ImplicitHierarchicalMap3::setFaceId(unsigned int orbit, Dart d)
525
526
{
	//Mise a jour de l'id de face pour les brins autour d'une arete
527
	if(orbit == EDGE)
528
529
530
531
532
	{
		Dart e = d;

		do
		{
533
			m_faceId[Map3::phi1(e)] = m_faceId[e];
534
535
536
537
538

			e = Map3::alpha2(e);
		}while(e != d);

	}
539
540
541
542
543
}

inline void ImplicitHierarchicalMap3::setFaceId(Dart d, unsigned int i, unsigned int orbit)
{

544
	//Mise a jour de l'id de face pour les brins autour de la face
545
	if(orbit == FACE)
546
547
548
549
550
551
552
553
554
555
556
557
558
559
	{
		Dart e = d;

		do
		{
			m_faceId[e] = i;

			Dart e3 = Map3::phi3(e);
			if(e3 != e)
				m_faceId[e3] = i;

			e = Map3::phi1(e);
		} while(e != d);
	}
560
	else if(orbit == DART)
561
562
	{
		m_faceId[d] = i;
563
564
565

		if(Map3::phi3(d) != d)
			m_faceId[Map3::phi3(d)] = i;
566
567
568
569
570
571
572
573
574
575
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
	}
}

/***************************************************
 *               CELLS INFORMATION                 *
 ***************************************************/

//TODO
inline unsigned int ImplicitHierarchicalMap3::vertexInsertionLevel(Dart d)
{
	assert(m_dartLevel[d] <= m_curLevel || !"Access to a dart introduced after current level") ;
	return m_dartLevel[d] ;
}

inline unsigned int ImplicitHierarchicalMap3::edgeLevel(Dart d)
{
	assert(m_dartLevel[d] <= m_curLevel || !"Access to a dart introduced after current level") ;

	// the level of an edge is the maximum of the
	// insertion levels of its darts

	unsigned int r = 0;

	Dart e = d;
	do
	{
		unsigned int ld = m_dartLevel[e] ;
		unsigned int ldd = m_dartLevel[phi2(e)] ;
		unsigned int temp = ld < ldd ? ldd : ld;

		r =  r < temp ? temp : r ;

		e = alpha2(e);
	} while(e != d);

	return r;
}

604

605
606
607
608
/***************************************************
 *               ATTRIBUTE HANDLER                 *
 ***************************************************/

Pierre Kraemer's avatar
Pierre Kraemer committed
609
610
template <typename T, unsigned int ORBIT>
T& AttributeHandler_IHM<T, ORBIT>::operator[](Dart d)
611
612
613
614
615
616
617
{
	ImplicitHierarchicalMap3* m = reinterpret_cast<ImplicitHierarchicalMap3*>(this->m_map) ;
	assert(m->m_dartLevel[d] <= m->m_curLevel || !"Access to a dart introduced after current level") ;
	assert(m->vertexInsertionLevel(d) <= m->m_curLevel || !"Access to the embedding of a vertex inserted after current level") ;

	unsigned int orbit = this->getOrbit() ;
	unsigned int nbSteps = m->m_curLevel - m->vertexInsertionLevel(d) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
618
	unsigned int index = m->getEmbedding<ORBIT>(d) ;
619
620
621

	if(index == EMBNULL)
	{
622
		index = m->setOrbitEmbeddingOnNewCell<ORBIT>(d) ;
623
624
625
		m->m_nextLevelCell[orbit]->operator[](index) = EMBNULL ;
	}

Pierre Kraemer's avatar
Pierre Kraemer committed
626
	AttributeContainer& cont = m->getAttributeContainer<ORBIT>() ;
627
628
629
630
631
632
633
	unsigned int step = 0 ;
	while(step < nbSteps)
	{
		step++ ;
		unsigned int nextIdx = m->m_nextLevelCell[orbit]->operator[](index) ;
		if (nextIdx == EMBNULL)
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
634
635
			nextIdx = m->newCell<ORBIT>() ;
			m->copyCell<ORBIT>(nextIdx, index) ;
636
637
638
639
640
641
642
643
644
			m->m_nextLevelCell[orbit]->operator[](index) = nextIdx ;
			m->m_nextLevelCell[orbit]->operator[](nextIdx) = EMBNULL ;
			cont.refLine(index) ;
		}
		index = nextIdx ;
	}
	return this->m_attrib->operator[](index);
}

Pierre Kraemer's avatar
Pierre Kraemer committed
645
646
template <typename T, unsigned int ORBIT>
const T& AttributeHandler_IHM<T, ORBIT>::operator[](Dart d) const
647
648
649
650
651
652
653
{
	ImplicitHierarchicalMap3* m = reinterpret_cast<ImplicitHierarchicalMap3*>(this->m_map) ;
	assert(m->m_dartLevel[d] <= m->m_curLevel || !"Access to a dart introduced after current level") ;
	assert(m->vertexInsertionLevel(d) <= m->m_curLevel || !"Access to the embedding of a vertex inserted after current level") ;

	unsigned int orbit = this->getOrbit() ;
	unsigned int nbSteps = m->m_curLevel - m->vertexInsertionLevel(d) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
654
	unsigned int index = m->getEmbedding<ORBIT>(d) ;
655
656
657
658
659
660
661
662
663
664
665

	unsigned int step = 0 ;
	while(step < nbSteps)
	{
		step++ ;
		unsigned int next = m->m_nextLevelCell[orbit]->operator[](index) ;
		if(next != EMBNULL) index = next ;
		else break ;
	}
	return this->m_attrib->operator[](index);
}
666
667

} //namespace IHM
668
} // Volume
669
670
} //namespace Algo
} //namespace CGoGN