map1.hpp 7.81 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-2012, 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.unistra.fr/                                           *
Pierre Kraemer's avatar
Pierre Kraemer committed
21 22 23 24 25 26 27 28 29
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

namespace CGoGN
{

/// INLINE FUNCTIONS

30 31
template <class MAP>
inline void Map1<MAP>::init()
Pierre Kraemer's avatar
Pierre Kraemer committed
32
{
33
	MAP::addPermutation() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
34 35
}

36 37
template <class MAP>
inline Map1<MAP>::Map1() : MAP()
38 39 40 41
{
	init() ;
}

42 43
template <class MAP>
inline std::string Map1<MAP>::mapTypeName() const
Pierre Kraemer's avatar
Pierre Kraemer committed
44
{
45
	return "Map1" ;
Pierre Kraemer's avatar
Pierre Kraemer committed
46 47
}

48 49
template <class MAP>
inline unsigned int Map1<MAP>::dimension() const
Pierre Kraemer's avatar
Pierre Kraemer committed
50
{
51 52 53
	return 1 ;
}

54 55
template <class MAP>
inline void Map1<MAP>::clear(bool removeAttrib)
56
{
57
	MAP::clear(removeAttrib) ;
Sylvain Thery's avatar
Sylvain Thery committed
58 59
	if (removeAttrib)
		init() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
60 61
}

62 63
template <class MAP>
inline void Map1<MAP>::update_topo_shortcuts()
Sylvain Thery's avatar
Sylvain Thery committed
64
{
65
	MAP::update_topo_shortcuts();
66 67
//	m_phi1 = MAP::getRelation("phi1");
//	m_phi_1 = MAP::getRelation("phi_1");
Sylvain Thery's avatar
Sylvain Thery committed
68 69
}

Pierre Kraemer's avatar
Pierre Kraemer committed
70 71 72 73
/*! @name Basic Topological Operators
 * Access and Modification
 *************************************************************************/

74 75
template <class MAP>
inline Dart Map1<MAP>::phi1(Dart d) const
Pierre Kraemer's avatar
Pierre Kraemer committed
76
{
77
	return MAP::getPermutation<0>(d);
Pierre Kraemer's avatar
Pierre Kraemer committed
78 79
}

80 81
template <class MAP>
inline Dart Map1<MAP>::phi_1(Dart d) const
Pierre Kraemer's avatar
Pierre Kraemer committed
82
{
83
	return MAP::getPermutationInv<0>(d);
Pierre Kraemer's avatar
Pierre Kraemer committed
84 85
}

86
template <class MAP>
Pierre Kraemer's avatar
Pierre Kraemer committed
87
template <int N>
88
inline Dart Map1<MAP>::phi(Dart d) const
Pierre Kraemer's avatar
Pierre Kraemer committed
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
{
	assert((N > 0) || !"negative parameters not allowed in template multi-phi");
	if (N < 10)
	{
		switch(N)
		{
			case 1 : return phi1(d) ;
			default : assert(!"Wrong multi-phi relation value") ; return d ;
		}
	}
	switch(N%10)
	{
		case 1 : return phi1(phi<N/10>(d)) ;
		default : assert(!"Wrong multi-phi relation value") ; return d ;
	}
}

106 107
template <class MAP>
inline Dart Map1<MAP>::alpha1(Dart d) const
Pierre Kraemer's avatar
Pierre Kraemer committed
108 109 110 111
{
	return phi1(d) ;
}

112 113
template <class MAP>
inline Dart Map1<MAP>::alpha_1(Dart d) const
Pierre Kraemer's avatar
Pierre Kraemer committed
114 115 116 117
{
	return phi_1(d) ;
}

118 119
template <class MAP>
inline void Map1<MAP>::phi1sew(Dart d, Dart e)
Pierre Kraemer's avatar
Pierre Kraemer committed
120
{
121
	MAP::permutationSew<0>(d,e);
Pierre Kraemer's avatar
Pierre Kraemer committed
122 123
}

124 125
template <class MAP>
inline void Map1<MAP>::phi1unsew(Dart d)
Pierre Kraemer's avatar
Pierre Kraemer committed
126
{
127
	MAP::permutationUnsew<0>(d);
Pierre Kraemer's avatar
Pierre Kraemer committed
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
/*! @name Generator and Deletor
 *  To generate or delete faces in a 1-map
 *************************************************************************/

template <class MAP>
Dart Map1<MAP>::newCycle(unsigned int nbEdges)
{
	assert(nbEdges > 0 || !"Cannot create a face with no edge") ;
	Dart d = this->newDart() ;	// Create the first edge
	for (unsigned int i = 1 ; i < nbEdges ; ++i)
		Map1<MAP>::cutEdge(d) ;		// Subdivide nbEdges-1 times this edge
	return d ;
}

template <class MAP>
void Map1<MAP>::deleteCycle(Dart d)
{
	Dart e = phi1(d) ;
	while (e != d)
	{
		Dart f = phi1(e) ;
		this->deleteDart(e) ;
		e = f ;
	}
	this->deleteDart(d) ;
}

Pierre Kraemer's avatar
Pierre Kraemer committed
157 158 159 160
/*! @name Topological Operators
 *  Topological operations on 1-maps
 *************************************************************************/

161 162
template <class MAP>
inline Dart Map1<MAP>::cutEdge(Dart d)
Pierre Kraemer's avatar
Pierre Kraemer committed
163
{
164
	Dart e = this->newDart() ;	// Create a new dart
165
	phi1sew(d, e) ;				// Insert dart e between d and phi1(d)
Sylvain Thery's avatar
Sylvain Thery committed
166

167
	if (this->isBoundaryMarked2(d))
168
		this->boundaryMark2(e);
Pierre Kraemer's avatar
Pierre Kraemer committed
169

170 171
	if (this->isBoundaryMarked3(d))
		this->boundaryMark3(e);
172

Pierre Kraemer's avatar
Pierre Kraemer committed
173
	return e ;
Pierre Kraemer's avatar
Pierre Kraemer committed
174 175
}

176 177
template <class MAP>
inline void Map1<MAP>::uncutEdge(Dart d)
Pierre Kraemer's avatar
Pierre Kraemer committed
178 179
{
	Dart d1 = phi1(d) ;
180
	phi1unsew(d) ;			// Dart d is linked to the successor of its successor
181
	this->deleteDart(d1) ;	// Dart d1 is erased
Pierre Kraemer's avatar
Pierre Kraemer committed
182 183
}

184 185
template <class MAP>
inline void Map1<MAP>::collapseEdge(Dart d)
Pierre Kraemer's avatar
Pierre Kraemer committed
186 187
{
	phi1unsew(phi_1(d)) ;	// Dart before d is linked to its successor
188
	this->deleteDart(d) ;	// Dart d is erased
Pierre Kraemer's avatar
Pierre Kraemer committed
189 190
}

191 192
template <class MAP>
inline void Map1<MAP>::splitCycle(Dart d, Dart e)
Pierre Kraemer's avatar
Pierre Kraemer committed
193
{
194 195
	assert(d != e && sameCycle(d, e)) ;
	phi1sew(phi_1(d), phi_1(e)) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
196 197
}

198 199
template <class MAP>
inline void Map1<MAP>::mergeCycles(Dart d, Dart e)
Thomas's avatar
Thomas committed
200
{
201 202
	assert(!sameCycle(d, e)) ;
	phi1sew(phi_1(d), phi_1(e)) ;
Thomas's avatar
Thomas committed
203 204
}

205 206
template <class MAP>
inline void Map1<MAP>::linkCycles(Dart d, Dart e)
Pierre Kraemer's avatar
Pierre Kraemer committed
207
{
208
	assert(d != e && !sameCycle(d, e)) ;
209 210
	Map1<MAP>::cutEdge(phi_1(d));		// cut the edge before d (insert a new dart before d)
	Map1<MAP>::cutEdge(phi_1(e));		// cut the edge before e (insert a new dart before e)
211
	phi1sew(phi_1(d), phi_1(e)) ;	// phi1sew between the 2 new inserted darts
Pierre Kraemer's avatar
Pierre Kraemer committed
212 213
}

214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232
template <class MAP>
void Map1<MAP>::reverseCycle(Dart d)
{
	Dart e = phi1(d) ;			// Dart e is the first edge of the new face
	if (e == d) return ;		// Only one edge: nothing to do
	if (phi1(e) == d) return ;	// Only two edges: nothing to do

	phi1unsew(d) ;				// Detach e from the face of d

	Dart dNext = phi1(d) ;		// While the face of d contains more than two edges
	while (dNext != d)
	{
		phi1unsew(d) ;			// Unsew the edge after d
		phi1sew(e, dNext) ;		// Sew it after e (thus in reverse order)
		dNext = phi1(d) ;
	}
	phi1sew(e, d) ;				// Sew the last edge
}

Pierre Kraemer's avatar
Pierre Kraemer committed
233 234 235 236
/*! @name Topological Queries
 *  Return or set various topological information
 *************************************************************************/

237 238
template <class MAP>
inline bool Map1<MAP>::sameCycle(Dart d, Dart e) const
Pierre Kraemer's avatar
Pierre Kraemer committed
239
{
240 241 242 243 244 245 246 247 248 249
	Dart it = d ;
	do
	{
		if(it == e)
			return true ;
		it = phi1(it) ;
	} while(it != d) ;
	return false ;
}

250 251
template <class MAP>
inline unsigned int Map1<MAP>::cycleDegree(Dart d) const
252 253 254 255
{
	unsigned int count = 0 ;
	Dart it = d ;
	do
256
    {
257 258 259 260 261 262
		++count ;
		it = phi1(it) ;
	} while (it != d) ;
	return count ;
}

263 264
template <class MAP>
inline int Map1<MAP>::checkCycleDegree(Dart d, unsigned int degree) const
265 266 267 268 269 270 271 272 273 274 275 276
{
	unsigned int count = 0 ;
	Dart it = d ;
	do
	{
		++count ;
		it = phi1(it) ;
	} while ((count<=degree) && (it != d)) ;

	return count-degree;
}

277 278
template <class MAP>
inline bool Map1<MAP>::isCycleTriangle(Dart d) const
279 280
{
	return (phi1(d) != d) && (phi1(phi1(phi1(d))) == d) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
281 282 283 284 285 286
}

/*! @name Cell Functors
 *  Apply functors to all darts of a cell
 *************************************************************************/

287 288
template <class MAP>
inline bool Map1<MAP>::foreach_dart_of_vertex(Dart d, FunctorType& f, unsigned int /*thread*/) const
Pierre Kraemer's avatar
Pierre Kraemer committed
289 290 291 292
{
	return f(d) ;
}

293 294
template <class MAP>
inline bool Map1<MAP>::foreach_dart_of_edge(Dart d, FunctorType& f, unsigned int /*thread*/) const
Pierre Kraemer's avatar
Pierre Kraemer committed
295 296 297 298
{
	return f(d) ;
}

299 300
template <class MAP>
inline bool Map1<MAP>::foreach_dart_of_cc(Dart d, FunctorType& f, unsigned int /*thread*/) const
301 302 303 304 305 306 307 308 309 310 311
{
	Dart it = d ;
	do
	{
		if (f(it))
			return true ;
		it = phi1(it) ;
	} while (it != d) ;
	return false ;
}

Pierre Kraemer's avatar
Pierre Kraemer committed
312 313

} // namespace CGoGN