map2MR_PrimalRegular.hpp 9.75 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
/*******************************************************************************
* 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                                        *
*                                                                              *
*******************************************************************************/

25 26
#include "Algo/Import/importMRDAT.h"

Pierre Kraemer's avatar
Pierre Kraemer committed
27 28 29
namespace CGoGN
{

untereiner's avatar
untereiner committed
30 31 32
namespace Algo
{

33 34 35
namespace Surface
{

untereiner's avatar
untereiner committed
36 37 38 39 40 41 42 43 44 45 46 47
namespace MR
{

namespace Primal
{

namespace Regular
{

template <typename PFP>
Map2MR<PFP>::Map2MR(typename PFP::MAP& map) :
	m_map(map),
untereiner's avatar
untereiner committed
48
	shareVertexEmbeddings(true)
Pierre Kraemer's avatar
Pierre Kraemer committed
49
{
untereiner's avatar
untereiner committed
50

Pierre Kraemer's avatar
Pierre Kraemer committed
51 52
}

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

untereiner's avatar
untereiner committed
71 72 73
	m_map.addLevelBack() ;
	m_map.duplicateDarts(m_map.getMaxLevel());
	m_map.setCurrentLevel(m_map.getMaxLevel()) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
74 75

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

untereiner's avatar
untereiner committed
87
		m_map.cutEdge(d) ;
88
		travE.skip(d) ;
untereiner's avatar
untereiner committed
89
		travE.skip(m_map.phi1(d)) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
90

91 92 93 94
		//std::cout << "is EMB NULL : " << ( m_map.template getEmbedding<VERTEX>(m_map.phi1(d)) == EMBNULL ? "true" : "false" ) << std::endl;

		//if(embedNewVertices)
		//	m_map.template setOrbitEmbeddingOnNewCell<VERTEX>(m_map.phi1(d)) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
95 96 97
	}

	// split faces
untereiner's avatar
untereiner committed
98
	TraversorF<typename PFP::MAP> travF(m_map) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
99 100 101
	for (Dart d = travF.begin(); d != travF.end(); d = travF.next())
	{
		Dart old = d ;
untereiner's avatar
untereiner committed
102 103
		if(m_map.getDartLevel(old) == m_map.getMaxLevel())
			old = m_map.phi1(old) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
104

untereiner's avatar
untereiner committed
105 106 107
		m_map.decCurrentLevel() ;
		unsigned int degree = m_map.faceDegree(old) ;
		m_map.incCurrentLevel() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
108

109
		if(triQuad && (degree == 3))					// if subdividing a triangle
Pierre Kraemer's avatar
Pierre Kraemer committed
110
		{
untereiner's avatar
untereiner committed
111 112 113
			Dart dd = m_map.phi1(old) ;
			Dart e = m_map.phi1(m_map.phi1(dd)) ;
			m_map.splitFace(dd, e) ;
114
			travF.skip(dd) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
115 116

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

			dd = e ;
untereiner's avatar
untereiner committed
122 123
			e = m_map.phi1(m_map.phi1(dd)) ;
			m_map.splitFace(dd, e) ;
124
			travF.skip(dd) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
125

126
			travF.skip(e) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
127 128 129
		}
		else							// if subdividing a polygonal face
		{
untereiner's avatar
untereiner committed
130 131 132
			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
133

134
			Dart ne = m_map.phi2(m_map.phi_1(dd)) ;
untereiner's avatar
untereiner committed
135
			m_map.cutEdge(ne) ;				// cut the new edge to insert the central vertex
136
			travF.skip(dd) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
137

138 139 140
			//if(embedNewVertices)
			//		m_map.template setOrbitEmbeddingOnNewCell<VERTEX>(m_map.phi1(ne)) ;

untereiner's avatar
untereiner committed
141
			dd = m_map.phi1(m_map.phi1(next)) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
142 143
			while(dd != ne)				// turn around the face and insert new edges
			{							// linked to the central vertex
untereiner's avatar
untereiner committed
144 145
				Dart tmp = m_map.phi1(ne) ;
				m_map.splitFace(tmp, dd) ;
146
				travF.skip(tmp) ;
untereiner's avatar
untereiner committed
147
				dd = m_map.phi1(m_map.phi1(dd)) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
148
			}
149
			travF.skip(ne) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
150 151 152
		}
	}

untereiner's avatar
untereiner committed
153
	m_map.popLevel() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
154 155
}

156
template <typename PFP>
untereiner's avatar
untereiner committed
157
void Map2MR<PFP>::addNewLevelSqrt3()
158 159 160 161 162 163 164
{
	m_map.pushLevel() ;

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

165 166 167 168 169 170 171 172
	//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
173
			Dart df = m_map.findBoundaryEdgeOfFace(dit);
174
			//trisection of the boundary edge
175 176 177 178 179 180
			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)))) ;
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
		}
		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);

			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())
	{
211
		if(!m_map.isBoundaryEdge(dit) && m_map.getDartLevel(dit) < m_map.getCurrentLevel())
212 213 214 215 216 217 218
			m_map.flipEdge(dit);
	}

	m_map.popLevel() ;
}

template <typename PFP>
untereiner's avatar
untereiner committed
219
void Map2MR<PFP>::addNewLevelSqrt2()
220 221 222 223 224 225 226
{
	m_map.pushLevel() ;

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

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

		Dart cd = m_map.phi2(x);

		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

	for(unsigned int i = 0; i < analysisFilters.size(); ++i)
untereiner's avatar
untereiner committed
264
		(*analysisFilters[i])() ;
untereiner's avatar
untereiner committed
265

Pierre Kraemer's avatar
Pierre Kraemer committed
266 267
}

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

untereiner's avatar
untereiner committed
273
	for(unsigned int i = 0; i < synthesisFilters.size(); ++i)
untereiner's avatar
untereiner committed
274
		(*synthesisFilters[i])() ;
untereiner's avatar
untereiner committed
275

untereiner's avatar
untereiner committed
276
	m_map.incCurrentLevel() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
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 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353
template <typename PFP>
void Map2MR<PFP>::addLevelFront()
{
	DartMarker md(m_map);

	m_map.addLevelFront() ;
	m_map.duplicateDarts(0);
	m_map.setCurrentLevel(0);

	std::vector<Dart> visitedVertices;
	visitedVertices.reserve(1024);

	//look for an irregular vertex

	TraversorV<typename PFP::MAP> tv(m_map);
	bool found = false;
	for(Dart d = tv.begin() ; !found && d != tv.end() ; d = tv.next())
	{
		if(m_map.vertexDegree(d) != 6)
		{
			found = true;
			visitedVertices.push_back(d);
		}
	}

	std::cout << "d = " << visitedVertices[0] << std::endl;

	for(unsigned int i = 0 ; i < visitedVertices.size() ; ++i)
	{
		Dart d = visitedVertices[i];

			Dart fit1 = m_map.phi2(m_map.phi1(d));
			//m_map.mergeFaces(fit1) ;


//		Traversor2VE<typename PFP::MAP> tve(m_map, d);
//		for(Dart eit = tve.begin() ; eit != tve.end() ; eit = tve.next())
//		{
//			//coarse all faces around the vertex
//			if(!md.isMarked(eit))
//			{
//				unsigned int degree = m_map.faceDegree(eit);

//				if(degree == 3)
//				{
//					Dart fit1 = m_map.phi2(m_map.phi1(eit));
//					//Dart fit2 = m_map.phi1(fit1);
//					//Dart fit3 = m_map.phi1(fit2);

//					m_map.mergeFaces(fit1) ;
//					//m_map.mergeFaces(fit2) ;
//					//m_map.mergeFaces(fit3) ;
//				}
//				else
//				{

//				}

//				//visitedVertices.push_back(m_map.phi1(m_map.phi1(eit)));
//				//visitedVertices.push_back(m_map.phi_1(m_map.phi_1(eit)));
//			}
//		}

//		for(Dart eit = tve.begin() ; eit != tve.end() ; eit = tve.next())
//		{
//			if(!md.isMarked(eit))
//			{
//				//coarse all edges around the vertex
//				m_map.uncutEdge(eit) ;
//				md.markOrbit<EDGE>(eit);
//			}
//		}
	}
}

354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371
template <typename PFP>
void Map2MR<PFP>::import(Algo::Surface::Import::QuadTree& qt)
{
	std::cout << "  Create finer resolution levels.." << std::flush ;

	for(unsigned int i = 0; i < qt.depth; ++i)
		addNewLevel(true, false) ;

	std::cout << "..done" << std::endl ;
	std::cout << "  Embed finer resolution levels.." << std::flush ;

	m_map.setCurrentLevel(0) ;
	qt.embed<PFP>(m_map) ;
	m_map.setCurrentLevel(m_map.getMaxLevel()) ;

	std::cout << "..done" << std::endl ;
}

untereiner's avatar
untereiner committed
372 373 374 375 376 377 378

} // namespace Regular

} // namespace Primal

} // namespace MR

379 380
} // namespace Surface

untereiner's avatar
untereiner committed
381 382
} // namespace Algo

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