ihm.hpp 11.7 KB
Newer Older
Pierre Kraemer's avatar
Pierre Kraemer committed
1
2
3
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps  *
* version 0.1                                                                  *
4
* Copyright (C) 2009-2011, IGG Team, LSIIT, University of Strasbourg           *
Pierre Kraemer's avatar
Pierre Kraemer committed
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.u-strasbg.fr/                                         *
Pierre Kraemer's avatar
Pierre Kraemer committed
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

namespace CGoGN
{

namespace Algo
{

namespace IHM
{

/***************************************************
 *             ATTRIBUTES MANAGEMENT               *
 ***************************************************/

template <typename T>
AttributeHandler_IHM<T> ImplicitHierarchicalMap::addAttribute(unsigned int orbit, const std::string& nameAttr)
{
	bool addNextLevelCell = false ;
	if(!isOrbitEmbedded(orbit))
		addNextLevelCell = true ;

	AttributeHandler<T> h = Map2::addAttribute<T>(orbit, nameAttr) ;

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

56
	return AttributeHandler_IHM<T>(this, h.getDataVector()) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
57
58
}

Pierre Kraemer's avatar
Pierre Kraemer committed
59
60
61
62
template <typename T>
AttributeHandler_IHM<T> ImplicitHierarchicalMap::getAttribute(unsigned int orbit, const std::string& nameAttr)
{
	AttributeHandler<T> h = Map2::getAttribute<T>(orbit, nameAttr) ;
63
	return AttributeHandler_IHM<T>(this, h.getDataVector()) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
64
65
}

Pierre Kraemer's avatar
Pierre Kraemer committed
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/***************************************************
 *                 MAP TRAVERSAL                   *
 ***************************************************/

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

inline Dart ImplicitHierarchicalMap::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 ;
	do
	{
		it = Map2::phi1(it) ;
		if(m_dartLevel[it] <= m_curLevel)
			finished = true ;
		else
		{
			while(m_edgeId[it] != edgeId)
				it = Map2::alpha_1(it) ;
		}
	} while(!finished) ;
	return it ;
}

inline Dart ImplicitHierarchicalMap::phi_1(Dart d)
{
	assert(m_dartLevel[d] <= m_curLevel || !"Access to a dart introduced after current level") ;
	bool finished = false ;
	Dart it = Map2::phi_1(d) ;
	unsigned int edgeId = m_edgeId[it] ;
	do
	{
		if(m_dartLevel[it] <= m_curLevel)
			finished = true ;
		else
		{
			it = Map2::phi_1(it) ;
			while(m_edgeId[it] != edgeId)
				it = Map2::phi_1(Map2::phi2(it)) ;
		}
	} while(!finished) ;
	return it ;
}

inline Dart ImplicitHierarchicalMap::phi2(Dart d)
{
	assert(m_dartLevel[d] <= m_curLevel || !"Access to a dart introduced after current level") ;
	if(Map2::phi2(d) == d)
		return d ;
	return Map2::alpha1(phi1(d)) ;
}

inline Dart ImplicitHierarchicalMap::alpha0(Dart d)
{
	return phi2(d) ;
}

inline Dart ImplicitHierarchicalMap::alpha1(Dart d)
{
	return Map2::alpha1(d) ;
}

inline Dart ImplicitHierarchicalMap::alpha_1(Dart d)
{
	return Map2::alpha_1(d) ;
}

inline Dart ImplicitHierarchicalMap::begin()
{
	Dart d = Map2::begin() ;
	while(m_dartLevel[d] > m_curLevel)
		Map2::next(d) ;
	return d ;
}

inline Dart ImplicitHierarchicalMap::end()
{
	return Map2::end() ;
}

inline void ImplicitHierarchicalMap::next(Dart& d)
{
	do
	{
		Map2::next(d) ;
160
	} while(d != Map2::end() && m_dartLevel[d] > m_curLevel) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
161
162
}

163
inline bool ImplicitHierarchicalMap::foreach_dart_of_vertex(Dart d, FunctorType& f, unsigned int thread)
Pierre Kraemer's avatar
Pierre Kraemer committed
164
165
166
167
168
169
170
171
172
173
174
{
	Dart dNext = d;
	do
	{
		if (f(dNext))
			return true;
		dNext = alpha1(dNext);
 	} while (dNext != d);
 	return false;
}

175
inline bool ImplicitHierarchicalMap::foreach_dart_of_edge(Dart d, FunctorType& f, unsigned int thread)
Pierre Kraemer's avatar
Pierre Kraemer committed
176
177
178
179
180
181
182
183
184
185
186
{
	if (f(d))
		return true;

	Dart d2 = phi2(d);
	if (d2 != d)
		return f(d2);
	else
		return false;
}

187
inline bool ImplicitHierarchicalMap::foreach_dart_of_oriented_face(Dart d, FunctorType& f, unsigned int thread)
Pierre Kraemer's avatar
Pierre Kraemer committed
188
189
190
191
192
193
194
195
196
197
198
{
	Dart dNext = d ;
	do
	{
		if (f(dNext))
			return true ;
		dNext = phi1(dNext) ;
	} while (dNext != d) ;
	return false ;
}

199
inline bool ImplicitHierarchicalMap::foreach_dart_of_face(Dart d, FunctorType& f, unsigned int thread)
Pierre Kraemer's avatar
Pierre Kraemer committed
200
201
202
203
{
	return foreach_dart_of_oriented_face(d, f) ;
}

204
inline bool ImplicitHierarchicalMap::foreach_dart_of_oriented_volume(Dart d, FunctorType& f, unsigned int thread)
Pierre Kraemer's avatar
Pierre Kraemer committed
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
{
	DartMarkerStore mark(*this);	// Lock a marker
	bool found = false;				// Last functor return value

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

	// For every face added to the list
	for (face = visitedFaces.begin(); !found && face != visitedFaces.end(); ++face)
	{
		if (!mark.isMarked(*face))		// Face has not been visited yet
		{
			// Apply functor to the darts of the face
			found = foreach_dart_of_oriented_face(*face, 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 dNext = *face ;
				do
				{
					mark.mark(dNext);					// Mark
					Dart adj = phi2(dNext);				// Get adjacent face
					if (adj != dNext && !mark.isMarked(adj))
						visitedFaces.push_back(adj);	// Add it
					dNext = phi1(dNext);
				} while(dNext != *face);
			}
		}
	}
	return found;
}

240
inline bool ImplicitHierarchicalMap::foreach_dart_of_volume(Dart d, FunctorType& f, unsigned int thread)
Pierre Kraemer's avatar
Pierre Kraemer committed
241
242
243
244
{
	return foreach_dart_of_oriented_volume(d, f) ;
}

245
inline bool ImplicitHierarchicalMap::foreach_dart_of_cc(Dart d, FunctorType& f, unsigned int thread)
Pierre Kraemer's avatar
Pierre Kraemer committed
246
247
248
249
{
	return foreach_dart_of_oriented_volume(d, f) ;
}

250
251
252
253
254
255
/***************************************************
 *               MAP MANIPULATION                  *
 ***************************************************/

inline void ImplicitHierarchicalMap::splitFace(Dart d, Dart e)
{
256
	EmbeddedMap2::splitFace(d, e) ;
257
	if(isOrbitEmbedded(FACE))
258
259
260
	{
		unsigned int cur = m_curLevel ;
		m_curLevel = m_maxLevel ;
261
262
		this->embedOrbit(FACE, d, this->getEmbedding(FACE, d)) ;
		this->embedOrbit(FACE, e, this->getEmbedding(FACE, e)) ;
263
264
		m_curLevel = cur ;
	}
265
266
}

Pierre Kraemer's avatar
Pierre Kraemer committed
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
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
326
327
328
329
330
331
332
333
334
/***************************************************
 *              LEVELS MANAGEMENT                  *
 ***************************************************/

inline unsigned int ImplicitHierarchicalMap::getCurrentLevel()
{
	return m_curLevel ;
}

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

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

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

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

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

inline unsigned int ImplicitHierarchicalMap::getNewEdgeId()
{
	return m_idCount++ ;
}

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

inline void ImplicitHierarchicalMap::setEdgeId(Dart d, unsigned int i)
{
	m_edgeId[d] = i ;
}

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

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

inline unsigned int ImplicitHierarchicalMap::edgeLevel(Dart d)
{
	assert(m_dartLevel[d] <= m_curLevel || !"Access to a dart introduced after current level") ;
	unsigned int ld = m_dartLevel[d] ;
//	unsigned int ldd = m_dartLevel[phi2(d)] ;	// the level of an edge is the maximum of the
	unsigned int ldd = m_dartLevel[phi1(d)] ;
	return ld < ldd ? ldd : ld ;				// insertion levels of its two darts
}

335
336
337
338
/***************************************************
 *               ATTRIBUTE HANDLER                 *
 ***************************************************/

Pierre Kraemer's avatar
Pierre Kraemer committed
339
340
341
342
343
344
345
template <typename T>
T& AttributeHandler_IHM<T>::operator[](Dart d)
{
	ImplicitHierarchicalMap* m = reinterpret_cast<ImplicitHierarchicalMap*>(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") ;

346
	unsigned int orbit = this->getOrbit() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
347
	unsigned int nbSteps = m->m_curLevel - m->vertexInsertionLevel(d) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
348
	unsigned int index = m->getEmbedding(orbit, d) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
349

350
	if(index == EMBNULL)
Pierre Kraemer's avatar
Pierre Kraemer committed
351
352
353
354
355
	{
		index = m->embedNewCell(orbit, d) ;
		m->m_nextLevelCell[orbit]->operator[](index) = EMBNULL ;
	}

356
	AttributeContainer& cont = m->getAttributeContainer(orbit) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
	unsigned int step = 0 ;
	while(step < nbSteps)
	{
		step++ ;
		unsigned int nextIdx = m->m_nextLevelCell[orbit]->operator[](index) ;
		if (nextIdx == EMBNULL)
		{
			nextIdx = m->newCell(orbit) ;
			m->copyCell(orbit, nextIdx, index) ;
			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);
}

template <typename T>
const T& AttributeHandler_IHM<T>::operator[](Dart d) const
{
	ImplicitHierarchicalMap* m = reinterpret_cast<ImplicitHierarchicalMap*>(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") ;

382
	unsigned int orbit = this->getOrbit() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
383
	unsigned int nbSteps = m->m_curLevel - m->vertexInsertionLevel(d) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
384
	unsigned int index = m->getEmbedding(orbit, d) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401

	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);
}

} //namespace IHM

} //namespace Algo

} //namespace CGoGN