map2MR_PrimalRegular.hpp 7.34 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),
Pierre Kraemer's avatar
Pierre Kraemer committed
43 44
	shareVertexEmbeddings(true)
{
untereiner's avatar
untereiner committed
45

Pierre Kraemer's avatar
Pierre Kraemer committed
46 47
}

48 49 50 51 52 53 54 55 56 57 58 59 60
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
61
template <typename PFP>
untereiner's avatar
untereiner committed
62
void Map2MR<PFP>::addNewLevel(bool triQuad, bool embedNewVertices)
Pierre Kraemer's avatar
Pierre Kraemer committed
63
{
untereiner's avatar
untereiner committed
64
	m_map.pushLevel() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
65

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

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

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

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

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

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

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

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

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

119
			travF.skip(e) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
120 121 122
		}
		else							// if subdividing a polygonal face
		{
untereiner's avatar
untereiner committed
123 124 125
			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
126

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

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

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

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

149 150 151 152 153 154 155 156 157
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()) ;

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 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
	//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
			//Dart df = m_map.findBoundaryEdgeOfFace(dit);

			//trisection of the boundary edge
		}
		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())
	{
		if(m_map.getDartLevel(dit) < m_map.getCurrentLevel() && !m_map.isBoundaryEdge(dit))
			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()) ;

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

		Dart cd = m_map.phi2(x);

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

		Dart fit = cd ;
		do
		{
			t.skip(fit);
untereiner's avatar
untereiner committed
243
			fit = m_map.phi2(m_map.phi_1(fit));
244 245 246 247 248 249
		} while(fit != cd);
	}

	m_map.popLevel() ;
}

untereiner's avatar
untereiner committed
250 251
template <typename PFP>
void Map2MR<PFP>::analysis()
Pierre Kraemer's avatar
Pierre Kraemer committed
252
{
untereiner's avatar
untereiner committed
253
	assert(m_map.getCurrentLevel() > 0 || !"analysis : called on level 0") ;
Pierre Kraemer's avatar
Pierre Kraemer committed
254

untereiner's avatar
untereiner committed
255
	m_map.decCurrentLevel() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
256 257 258 259 260

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

untereiner's avatar
untereiner committed
261 262
template <typename PFP>
void Map2MR<PFP>::synthesis()
Pierre Kraemer's avatar
Pierre Kraemer committed
263
{
untereiner's avatar
untereiner committed
264
	assert(m_map.getCurrentLevel() < m_map.getMaxLevel() || !"synthesis : called on max level") ;
Pierre Kraemer's avatar
Pierre Kraemer committed
265 266 267 268

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

untereiner's avatar
untereiner committed
269
	m_map.incCurrentLevel() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
270 271
}

untereiner's avatar
untereiner committed
272 273 274 275 276 277 278 279 280

} // namespace Regular

} // namespace Primal

} // namespace MR

} // namespace Algo

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