map1.hpp 6.54 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
inline void Map1::init()
Pierre Kraemer's avatar
Pierre Kraemer committed
31 32 33 34 35
{
	m_phi1 = addRelation("phi1") ;
	m_phi_1 = addRelation("phi_1") ;
}

36 37 38 39 40
inline Map1::Map1() : AttribMap()
{
	init() ;
}

41
inline std::string Map1::mapTypeName() const
Pierre Kraemer's avatar
Pierre Kraemer committed
42
{
43
	return "Map1" ;
Pierre Kraemer's avatar
Pierre Kraemer committed
44 45
}

46
inline unsigned int Map1::dimension() const
Pierre Kraemer's avatar
Pierre Kraemer committed
47
{
48 49 50 51 52 53
	return 1 ;
}

inline void Map1::clear(bool removeAttrib)
{
	AttribMap::clear(removeAttrib) ;
Sylvain Thery's avatar
Sylvain Thery committed
54 55
	if (removeAttrib)
		init() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
56 57
}

Sylvain Thery's avatar
Sylvain Thery committed
58 59 60 61 62 63 64
inline void Map1::update_topo_shortcuts()
{
	GenericMap::update_topo_shortcuts();
	m_phi1 = getRelation("phi1");
	m_phi_1 = getRelation("phi_1");
}

Pierre Kraemer's avatar
Pierre Kraemer committed
65 66 67 68 69 70 71
/*! @name Basic Topological Operators
 * Access and Modification
 *************************************************************************/

inline Dart Map1::newDart()
{
	Dart d = GenericMap::newDart() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
72
	unsigned int d_index = dartIndex(d) ;
73 74
	(*m_phi1)[d_index] = d ;
	(*m_phi_1)[d_index] = d ;
Pierre Kraemer's avatar
Pierre Kraemer committed
75 76 77 78 79 80 81 82 83 84 85 86
	if(m_isMultiRes)
	{
		pushLevel() ;
		for(unsigned int i = m_mrCurrentLevel + 1;  i < m_mrDarts.size(); ++i)
		{
			setCurrentLevel(i) ;
			unsigned int d_index = dartIndex(d) ;
			(*m_phi1)[d_index] = d ;
			(*m_phi_1)[d_index] = d ;
		}
		popLevel() ;
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
87 88 89 90 91
	return d ;
}

inline Dart Map1::phi1(Dart d)
{
92 93
//	unsigned int d_index = dartIndex(d);
	return (*m_phi1)[dartIndex(d)] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
94 95 96 97
}

inline Dart Map1::phi_1(Dart d)
{
98 99
//	unsigned int d_index = dartIndex(d);
	return (*m_phi_1)[dartIndex(d)] ;
Pierre Kraemer's avatar
Pierre Kraemer committed
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
}

template <int N>
inline Dart Map1::phi(Dart d)
{
	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 ;
	}
}

inline Dart Map1::alpha1(Dart d)
{
	return phi1(d) ;
}

inline Dart Map1::alpha_1(Dart d)
{
	return phi_1(d) ;
}

inline void Map1::phi1sew(Dart d, Dart e)
{
133 134 135 136 137 138 139 140
	unsigned int d_index = dartIndex(d);
	unsigned int e_index = dartIndex(e);
	Dart f = (*m_phi1)[d_index] ;
	Dart g = (*m_phi1)[e_index] ;
	(*m_phi1)[d_index] = g ;
	(*m_phi1)[e_index] = f ;
	(*m_phi_1)[dartIndex(g)] = d ;
	(*m_phi_1)[dartIndex(f)] = e ;
Pierre Kraemer's avatar
Pierre Kraemer committed
141 142 143 144
}

inline void Map1::phi1unsew(Dart d)
{
145 146 147 148 149 150 151 152
	unsigned int d_index = dartIndex(d);
	Dart e = (*m_phi1)[d_index] ;
	unsigned int e_index = dartIndex(e);
	Dart f = (*m_phi1)[e_index] ;
	(*m_phi1)[d_index] = f ;
	(*m_phi1)[e_index] = e ;
	(*m_phi_1)[dartIndex(f)] = d ;
	(*m_phi_1)[e_index] = e ;
Pierre Kraemer's avatar
Pierre Kraemer committed
153 154 155 156 157 158
}

/*! @name Topological Operators
 *  Topological operations on 1-maps
 *************************************************************************/

David Cazier's avatar
David Cazier committed
159
inline Dart Map1::cutEdge(Dart d)
Pierre Kraemer's avatar
Pierre Kraemer committed
160 161
{
	Dart e = newDart() ;	// Create a new dart
Pierre Kraemer's avatar
Pierre Kraemer committed
162
	phi1sew(d, e) ;			// Insert dart e between d and phi1(d)
Sylvain Thery's avatar
Sylvain Thery committed
163 164 165

	if (isBoundaryMarked(d))
		boundaryMark(e);
Pierre Kraemer's avatar
Pierre Kraemer committed
166 167

	return e ;
Pierre Kraemer's avatar
Pierre Kraemer committed
168 169
}

Pierre Kraemer's avatar
Pierre Kraemer committed
170 171 172 173 174 175 176
inline void Map1::uncutEdge(Dart d)
{
	Dart d1 = phi1(d) ;
	phi1unsew(d) ;		// Dart d is linked to the successor of its successor
	deleteDart(d1) ;	// Dart d1 is erased
}

Pierre Kraemer's avatar
Pierre Kraemer committed
177 178 179 180 181 182
inline void Map1::collapseEdge(Dart d)
{
	phi1unsew(phi_1(d)) ;	// Dart before d is linked to its successor
	deleteDart(d) ;			// Dart d is erased
}

183
inline void Map1::splitCycle(Dart d, Dart e)
Pierre Kraemer's avatar
Pierre Kraemer committed
184
{
185 186
	assert(d != e && sameCycle(d, e)) ;
	phi1sew(phi_1(d), phi_1(e)) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
187 188
}

189
inline void Map1::mergeCycles(Dart d, Dart e)
Thomas's avatar
Thomas committed
190
{
191 192
	assert(!sameCycle(d, e)) ;
	phi1sew(phi_1(d), phi_1(e)) ;
Thomas's avatar
Thomas committed
193 194
}

195
inline void Map1::linkCycles(Dart d, Dart e)
Pierre Kraemer's avatar
Pierre Kraemer committed
196
{
197 198 199 200
	assert(d != e && !sameCycle(d, e)) ;
	Map1::cutEdge(phi_1(d));		// cut the edge before d (insert a new dart before d)
	Map1::cutEdge(phi_1(e));		// cut the edge before e (insert a new dart before e)
	phi1sew(phi_1(d), phi_1(e)) ;	// phi1sew between the 2 new inserted darts
Pierre Kraemer's avatar
Pierre Kraemer committed
201 202 203 204 205 206
}

/*! @name Topological Queries
 *  Return or set various topological information
 *************************************************************************/

207
inline bool Map1::sameCycle(Dart d, Dart e)
Pierre Kraemer's avatar
Pierre Kraemer committed
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
	Dart it = d ;
	do
	{
		if(it == e)
			return true ;
		it = phi1(it) ;
	} while(it != d) ;
	return false ;
}

inline unsigned int Map1::cycleDegree(Dart d)
{
	unsigned int count = 0 ;
	Dart it = d ;
	do
	{
		++count ;
		it = phi1(it) ;
	} while (it != d) ;
	return count ;
}

inline bool Map1::isCycleTriangle(Dart d)
{
	return (phi1(d) != d) && (phi1(phi1(phi1(d))) == d) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
234 235 236 237 238 239
}

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

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

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

250
inline bool Map1::foreach_dart_of_cc(Dart d, FunctorType& f, unsigned int thread)
251 252 253 254 255 256 257 258 259 260 261
{
	Dart it = d ;
	do
	{
		if (f(it))
			return true ;
		it = phi1(it) ;
	} while (it != d) ;
	return false ;
}

Pierre Kraemer's avatar
Pierre Kraemer committed
262 263

} // namespace CGoGN