Création d'un compte pour un collaborateur extérieur au laboratoire depuis l'intranet ICube : https://intranet.icube.unistra.fr/fr/labs/member/profile

map2MR_PrimalRegular.hpp 8.05 KB
Newer Older
Pierre Kraemer's avatar
Pierre Kraemer committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps  *
* version 0.1                                                                  *
* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg           *
*                                                                              *
* 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.           *
*                                                                              *
* Web site: http://cgogn.unistra.fr/                                           *
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

namespace CGoGN
{

untereiner's avatar
untereiner committed
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
namespace Algo
{

namespace MR
{

namespace Primal
{

namespace Regular
{

template <typename PFP>
Map2MR<PFP>::Map2MR(typename PFP::MAP& map) :
	m_map(map),
untereiner's avatar
untereiner committed
43
44
	shareVertexEmbeddings(true),
	filter(F_None)
Pierre Kraemer's avatar
Pierre Kraemer committed
45
{
untereiner's avatar
untereiner committed
46

Pierre Kraemer's avatar
Pierre Kraemer committed
47
48
}

49
50
51
52
53
54
55
56
57
58
59
60
61
template <typename PFP>
Map2MR<PFP>::~Map2MR()
{
	unsigned int level = m_map.getCurrentLevel();
	unsigned int maxL = m_map.getMaxLevel();

	for(unsigned int i = maxL ; i > level ; --i)
		m_map.removeLevelBack();

	for(unsigned int i = 0 ; i < level ; ++i)
		m_map.removeLevelFront();
}

untereiner's avatar
untereiner committed
62
template <typename PFP>
untereiner's avatar
untereiner committed
63
void Map2MR<PFP>::addNewLevel(bool triQuad, bool embedNewVertices)
Pierre Kraemer's avatar
Pierre Kraemer committed
64
{
untereiner's avatar
untereiner committed
65
	m_map.pushLevel() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
66

untereiner's avatar
untereiner committed
67
68
69
	m_map.addLevelBack() ;
	m_map.duplicateDarts(m_map.getMaxLevel());
	m_map.setCurrentLevel(m_map.getMaxLevel()) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
70
71

	// cut edges
untereiner's avatar
untereiner committed
72
	TraversorE<typename PFP::MAP> travE(m_map) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
73
74
	for (Dart d = travE.begin(); d != travE.end(); d = travE.next())
	{
75
		if(!shareVertexEmbeddings && embedNewVertices)
Pierre Kraemer's avatar
Pierre Kraemer committed
76
		{
untereiner's avatar
untereiner committed
77
			if(m_map.template getEmbedding<VERTEX>(d) == EMBNULL)
78
				m_map.template setOrbitEmbeddingOnNewCell<VERTEX>(d) ;
untereiner's avatar
untereiner committed
79
			if(m_map.template getEmbedding<VERTEX>(m_map.phi1(d)) == EMBNULL)
80
				m_map.template setOrbitEmbeddingOnNewCell<VERTEX>(d) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
81
82
		}

untereiner's avatar
untereiner committed
83
		m_map.cutEdge(d) ;
84
		travE.skip(d) ;
untereiner's avatar
untereiner committed
85
		travE.skip(m_map.phi1(d)) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
86
87

		if(embedNewVertices)
88
			m_map.template setOrbitEmbeddingOnNewCell<VERTEX>(m_map.phi1(d)) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
89
90
91
	}

	// split faces
untereiner's avatar
untereiner committed
92
	TraversorF<typename PFP::MAP> travF(m_map) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
93
94
95
	for (Dart d = travF.begin(); d != travF.end(); d = travF.next())
	{
		Dart old = d ;
untereiner's avatar
untereiner committed
96
97
		if(m_map.getDartLevel(old) == m_map.getMaxLevel())
			old = m_map.phi1(old) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
98

untereiner's avatar
untereiner committed
99
100
101
		m_map.decCurrentLevel() ;
		unsigned int degree = m_map.faceDegree(old) ;
		m_map.incCurrentLevel() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
102

103
		if(triQuad && (degree == 3))					// if subdividing a triangle
Pierre Kraemer's avatar
Pierre Kraemer committed
104
		{
untereiner's avatar
untereiner committed
105
106
107
			Dart dd = m_map.phi1(old) ;
			Dart e = m_map.phi1(m_map.phi1(dd)) ;
			m_map.splitFace(dd, e) ;
108
			travF.skip(dd) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
109
110

			dd = e ;
untereiner's avatar
untereiner committed
111
112
			e = m_map.phi1(m_map.phi1(dd)) ;
			m_map.splitFace(dd, e) ;
113
			travF.skip(dd) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
114
115

			dd = e ;
untereiner's avatar
untereiner committed
116
117
			e = m_map.phi1(m_map.phi1(dd)) ;
			m_map.splitFace(dd, e) ;
118
			travF.skip(dd) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
119

120
			travF.skip(e) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
121
122
123
		}
		else							// if subdividing a polygonal face
		{
untereiner's avatar
untereiner committed
124
125
126
			Dart dd = m_map.phi1(old) ;
			Dart next = m_map.phi1(m_map.phi1(dd)) ;
			m_map.splitFace(dd, next) ;		// insert a first edge
Pierre Kraemer's avatar
Pierre Kraemer committed
127

untereiner's avatar
untereiner committed
128
129
			Dart ne = m_map.alpha1(dd) ;
			m_map.cutEdge(ne) ;				// cut the new edge to insert the central vertex
130
			travF.skip(dd) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
131
132

			if(embedNewVertices)
133
				m_map.template setOrbitEmbeddingOnNewCell<VERTEX>(m_map.phi1(ne)) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
134

untereiner's avatar
untereiner committed
135
			dd = m_map.phi1(m_map.phi1(next)) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
136
137
			while(dd != ne)				// turn around the face and insert new edges
			{							// linked to the central vertex
untereiner's avatar
untereiner committed
138
139
				Dart tmp = m_map.phi1(ne) ;
				m_map.splitFace(tmp, dd) ;
140
				travF.skip(tmp) ;
untereiner's avatar
untereiner committed
141
				dd = m_map.phi1(m_map.phi1(dd)) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
142
			}
143
			travF.skip(ne) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
144
145
146
		}
	}

untereiner's avatar
untereiner committed
147
	m_map.popLevel() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
148
149
}

150
151
152
153
154
155
156
157
158
template <typename PFP>
void Map2MR<PFP>::addNewLevelSqrt3(bool embedNewVertices)
{
	m_map.pushLevel() ;

	m_map.addLevelBack() ;
	m_map.duplicateDarts(m_map.getMaxLevel());
	m_map.setCurrentLevel(m_map.getMaxLevel()) ;

159
160
161
162
163
164
165
166
	//split faces
	TraversorF<typename PFP::MAP> t(m_map) ;
	for (Dart dit = t.begin(); dit != t.end(); dit = t.next())
	{
		//if it is an even level (triadic refinement) and a boundary face
		if((m_map.getCurrentLevel()%2 == 0) && m_map.isBoundaryFace(dit))
		{
			//find the boundary edge
167
			Dart df = m_map.findBoundaryEdgeOfFace(dit);
168
			//trisection of the boundary edge
169
170
171
172
173
174
			m_map.cutEdge(df) ;
			m_map.splitFace(m_map.phi2(df), m_map.phi1(m_map.phi1(m_map.phi2(df)))) ;

			df = m_map.phi1(df);
			m_map.cutEdge(df) ;
			m_map.splitFace(m_map.phi2(df), m_map.phi1(m_map.phi1(m_map.phi2(df)))) ;
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
		}
		else
		{
			Dart d1 = m_map.phi1(dit);
			m_map.splitFace(dit, d1) ;
			m_map.cutEdge(m_map.phi_1(dit)) ;
			Dart x = m_map.phi2(m_map.phi_1(dit)) ;
			Dart dd = m_map.phi1(m_map.phi1(m_map.phi1((x))));
			while(dd != x)
			{
				Dart next = m_map.phi1(dd) ;
				m_map.splitFace(dd, m_map.phi1(x)) ;
				dd = next ;
			}

			Dart cd = m_map.phi2(x);

			if(embedNewVertices)
				m_map.template embedNewCell<VERTEX>(cd) ;

			Dart fit = cd ;
			do
			{
				t.skip(fit);
				fit = m_map.phi2(m_map.phi_1(fit));
			} while(fit != cd);
		}
	}

	//swap edges
	TraversorE<typename PFP::MAP> te(m_map) ;
	for (Dart dit = te.begin(); dit != te.end(); dit = te.next())
	{
208
		if(!m_map.isBoundaryEdge(dit) && m_map.getDartLevel(dit) < m_map.getCurrentLevel())
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
			m_map.flipEdge(dit);
	}

	m_map.popLevel() ;
}

template <typename PFP>
void Map2MR<PFP>::addNewLevelSqrt2(bool embedNewVertices)
{
	m_map.pushLevel() ;

	m_map.addLevelBack() ;
	m_map.duplicateDarts(m_map.getMaxLevel());
	m_map.setCurrentLevel(m_map.getMaxLevel()) ;

224
	//split faces
untereiner's avatar
untereiner committed
225
	TraversorF<typename PFP::MAP> t(m_map) ;
226
227
228
	for (Dart dit = t.begin(); dit != t.end(); dit = t.next())
	{
		Dart d1 = m_map.phi1(dit);
untereiner's avatar
untereiner committed
229
230
		m_map.splitFace(dit, d1) ;
		m_map.cutEdge(m_map.phi_1(dit)) ;
231
		Dart x = m_map.phi2(m_map.phi_1(dit)) ;
untereiner's avatar
untereiner committed
232
		Dart dd = m_map.phi1(m_map.phi1(m_map.phi1((x))));
233
234
235
		while(dd != x)
		{
			Dart next = m_map.phi1(dd) ;
untereiner's avatar
untereiner committed
236
			m_map.splitFace(dd, m_map.phi1(x)) ;
237
238
239
240
241
242
			dd = next ;
		}

		Dart cd = m_map.phi2(x);

		if(embedNewVertices)
243
			m_map.template setOrbitEmbeddingOnNewCell<VERTEX>(cd) ;
244
245
246
247
248

		Dart fit = cd ;
		do
		{
			t.skip(fit);
untereiner's avatar
untereiner committed
249
			fit = m_map.phi2(m_map.phi_1(fit));
250
251
252
253
254
255
		} while(fit != cd);
	}

	m_map.popLevel() ;
}

untereiner's avatar
untereiner committed
256
257
template <typename PFP>
void Map2MR<PFP>::analysis()
Pierre Kraemer's avatar
Pierre Kraemer committed
258
{
untereiner's avatar
untereiner committed
259
	assert(m_map.getCurrentLevel() > 0 || !"analysis : called on level 0") ;
Pierre Kraemer's avatar
Pierre Kraemer committed
260

untereiner's avatar
untereiner committed
261
	m_map.decCurrentLevel() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
262
263
264
265
266

	for(unsigned int i = 0; i < analysisFilters.size(); ++i)
		(*analysisFilters[i])() ;
}

untereiner's avatar
untereiner committed
267
268
template <typename PFP>
void Map2MR<PFP>::synthesis()
Pierre Kraemer's avatar
Pierre Kraemer committed
269
{
untereiner's avatar
untereiner committed
270
	assert(m_map.getCurrentLevel() < m_map.getMaxLevel() || !"synthesis : called on max level") ;
Pierre Kraemer's avatar
Pierre Kraemer committed
271
272
273
274

	for(unsigned int i = 0; i < synthesisFilters.size(); ++i)
		(*synthesisFilters[i])() ;

untereiner's avatar
untereiner committed
275
276
277
278
279
280
281
282
283
284
//	for(unsigned int i = 0; i < synthesisFilters.size(); ++i)
//	{
//		if((filter == F_LowPass && m_map.getCurrentLevel() <= thresholdHigh) ||
//		(filter == F_HighPass && m_map.getCurrentLevel() >= thresholdLow) ||
//		(filter == F_BandPass && (thresholdLow >= m_map.getCurrentLevel() &&  m_map.getCurrentLevel() <= thresholdHigh)))
//			(*synthesisFilters[i])(true) ;
//		else
//			(*synthesisFilters[i])(false) ;
//	}

untereiner's avatar
untereiner committed
285
	m_map.incCurrentLevel() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
286
287
}

untereiner's avatar
untereiner committed
288
289
290
291
292
293
294
295
296

} // namespace Regular

} // namespace Primal

} // namespace MR

} // namespace Algo

Pierre Kraemer's avatar
Pierre Kraemer committed
297
} // namespace CGoGN