centroid.hpp 9.26 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
 * Contact information: cgogn@unistra.fr                                        *
 *                                                                              *
 *******************************************************************************/

#include "Topology/generic/cellmarker.h"
26 27 28 29
#include "Topology/generic/traversor/traversorCell.h"
#include "Topology/generic/traversor/traversor2.h"
#include "Topology/generic/traversor/traversorCell.h"
#include "Topology/generic/traversor/traversor3.h"
30

Pierre Kraemer's avatar
Pierre Kraemer committed
31 32 33 34 35 36
namespace CGoGN
{

namespace Algo
{

37 38 39
namespace Surface
{

Pierre Kraemer's avatar
Pierre Kraemer committed
40 41 42
namespace Geometry
{

43
template <typename PFP, typename V_ATT>
Sylvain Thery's avatar
Sylvain Thery committed
44
typename V_ATT::DATA_TYPE volumeCentroid(typename PFP::MAP& map, Vol d, const V_ATT& attributs)
Pierre Kraemer's avatar
Pierre Kraemer committed
45
{
46
	typename V_ATT::DATA_TYPE center(0.0);
47
	unsigned int count = 0 ;
48

49
	foreach_incident3<VERTEX>(map,d, [&] (Vertex v)
Pierre Kraemer's avatar
Pierre Kraemer committed
50
	{
51
		center += attributs[v];
Pierre Kraemer's avatar
Pierre Kraemer committed
52 53
		++count;
	}
Sylvain Thery's avatar
Sylvain Thery committed
54
	,false);
Pierre Kraemer's avatar
Pierre Kraemer committed
55 56 57 58 59

	center /= double(count) ;
	return center ;
}

60
template <typename PFP, typename V_ATT>
Sylvain Thery's avatar
Sylvain Thery committed
61
typename V_ATT::DATA_TYPE volumeCentroidELW(typename PFP::MAP& map, Vol d, const V_ATT& attributs)
62
{
63
	typedef typename V_ATT::DATA_TYPE EMB;
64
	EMB center(0.0);
65

66
	double count=0.0;
67

68
	foreach_incident3<EDGE>(map,d, [&] (Edge it)
69
	{
Sylvain Thery's avatar
Sylvain Thery committed
70
		EMB e1 = attributs[it.dart];
71 72 73 74
		EMB e2 = attributs[map.phi1(it)];
		double l = (e2-e1).norm();
		center += (e1+e2)*l;
		count += 2.0*l ;
Sylvain Thery's avatar
Sylvain Thery committed
75
	},false);
76 77 78 79
	center /= double(count);	
	return center ;
}

80
template <typename PFP, typename V_ATT>
81
typename V_ATT::DATA_TYPE faceCentroid(typename PFP::MAP& map, Face f, const V_ATT& attributs)
Pierre Kraemer's avatar
Pierre Kraemer committed
82
{
83
	typename V_ATT::DATA_TYPE center(0.0);
Pierre Kraemer's avatar
Pierre Kraemer committed
84
	unsigned int count = 0 ;
85

86
	foreach_incident2<VERTEX>(map, f, [&](Vertex it)
Pierre Kraemer's avatar
Pierre Kraemer committed
87 88 89
	{
		center += attributs[it];
		++count ;
90
	});
Pierre Kraemer's avatar
Pierre Kraemer committed
91 92 93 94
	center /= double(count);
	return center ;
}

95
template <typename PFP, typename V_ATT>
96
typename V_ATT::DATA_TYPE faceCentroidELW(typename PFP::MAP& map, Face f, const V_ATT& attributs)
97
{
98 99
	typedef typename V_ATT::DATA_TYPE EMB;

100
	EMB center(0.0);
101
	double count=0.0;
102

103
	foreach_incident2<EDGE>(map, f, [&](Edge it)
104
	{
Sylvain Thery's avatar
Sylvain Thery committed
105
		EMB e1 = attributs[it.dart];
106 107 108 109
		EMB e2 = attributs[map.phi1(it)];
		double l = (e2-e1).norm();
		center += (e1+e2)*l;
		count += 2.0*l ;
110
	});
111 112 113 114
	center /= double(count);
	return center ;
}

115
template <typename PFP, typename V_ATT>
116
typename V_ATT::DATA_TYPE vertexNeighborhoodCentroid(typename PFP::MAP& map, Vertex v, const V_ATT& attributs)
Pierre Kraemer's avatar
Pierre Kraemer committed
117
{
118 119
	typename V_ATT::DATA_TYPE center(0.0);

Pierre Kraemer's avatar
Pierre Kraemer committed
120
	unsigned int count = 0 ;
121
//	Traversor2VVaE<typename PFP::MAP> t(map, d) ;
122
	foreach_adjacent2<EDGE>(map, v, [&](Vertex it)
Pierre Kraemer's avatar
Pierre Kraemer committed
123
	{
124
		center += attributs[it];
Pierre Kraemer's avatar
Pierre Kraemer committed
125
		++count ;
126
	});
Pierre Kraemer's avatar
Pierre Kraemer committed
127 128 129 130
	center /= count ;
	return center ;
}

131
template <typename PFP, typename V_ATT, typename F_ATT>
Sylvain Thery's avatar
Sylvain Thery committed
132
void computeCentroidFaces(typename PFP::MAP& map, const V_ATT& position, F_ATT& face_centroid)
Pierre Kraemer's avatar
Pierre Kraemer committed
133
{
Sylvain Thery's avatar
Sylvain Thery committed
134
	if (CGoGN::Parallel::NumberOfThreads > 1)
Sylvain Thery's avatar
Sylvain Thery committed
135 136 137 138 139
	{
		Parallel::computeCentroidFaces<PFP,V_ATT,F_ATT>(map,position,face_centroid);
		return;
	}

140 141 142 143
	foreach_cell<FACE>(map, [&] (Face f)
	{
		face_centroid[f] = faceCentroid<PFP,V_ATT>(map, f, position) ;
	}
Sylvain Thery's avatar
Sylvain Thery committed
144
	,AUTO);
Pierre Kraemer's avatar
Pierre Kraemer committed
145 146
}

147
template <typename PFP, typename V_ATT, typename F_ATT>
Sylvain Thery's avatar
Sylvain Thery committed
148
void computeCentroidELWFaces(typename PFP::MAP& map, const V_ATT& position, F_ATT& face_centroid)
149
{
Sylvain Thery's avatar
Sylvain Thery committed
150
	if (CGoGN::Parallel::NumberOfThreads > 1)
Sylvain Thery's avatar
Sylvain Thery committed
151 152 153 154 155
	{
		Parallel::computeCentroidELWFaces<PFP,V_ATT,F_ATT>(map,position,face_centroid);
		return;
	}

156 157 158 159
	foreach_cell<FACE>(map, [&] (Face f)
	{
		face_centroid[f] = faceCentroidELW<PFP,V_ATT>(map, f, position) ;
	}
Sylvain Thery's avatar
Sylvain Thery committed
160
	,AUTO);
161 162
}

163
template <typename PFP, typename V_ATT>
Sylvain Thery's avatar
Sylvain Thery committed
164
void computeNeighborhoodCentroidVertices(typename PFP::MAP& map, const V_ATT& position, V_ATT& vertex_centroid)
Pierre Kraemer's avatar
Pierre Kraemer committed
165
{
Sylvain Thery's avatar
Sylvain Thery committed
166
	if (CGoGN::Parallel::NumberOfThreads > 1)
Sylvain Thery's avatar
Sylvain Thery committed
167 168 169 170 171
	{
		Parallel::computeNeighborhoodCentroidVertices<PFP,V_ATT>(map,position,vertex_centroid);
		return;
	}

172 173 174
	foreach_cell<VERTEX>(map, [&] (Vertex v)
	{
		vertex_centroid[v] = vertexNeighborhoodCentroid<PFP,V_ATT>(map, v, position) ;
Sylvain Thery's avatar
Sylvain Thery committed
175
	}, AUTO);
Pierre Kraemer's avatar
Pierre Kraemer committed
176 177
}

178 179 180 181

namespace Parallel
{

182
template <typename PFP, typename V_ATT, typename F_ATT>
Sylvain Thery's avatar
Sylvain Thery committed
183
void computeCentroidFaces(typename PFP::MAP& map, const V_ATT& position, F_ATT& face_centroid)
184
{
Pierre Kraemer's avatar
Pierre Kraemer committed
185
	CGoGN::Parallel::foreach_cell<FACE>(map,[&](Face f, unsigned int /*thr*/)
Sylvain Thery's avatar
Sylvain Thery committed
186 187
	{
		face_centroid[f] = faceCentroid<PFP>(map, f, position) ;
Sylvain Thery's avatar
Sylvain Thery committed
188
	});
189 190
}

191
template <typename PFP, typename V_ATT, typename F_ATT>
Sylvain Thery's avatar
Sylvain Thery committed
192
void computeCentroidELWFaces(typename PFP::MAP& map, const V_ATT& position, F_ATT& face_centroid)
193
{
Pierre Kraemer's avatar
Pierre Kraemer committed
194
	CGoGN::Parallel::foreach_cell<FACE>(map,[&](Face f, unsigned int /*thr*/)
Sylvain Thery's avatar
Sylvain Thery committed
195 196
	{
		face_centroid[f] = faceCentroidELW<PFP>(map, f, position) ;
Sylvain Thery's avatar
Sylvain Thery committed
197
	});
Sylvain Thery's avatar
Sylvain Thery committed
198

199 200
}

201
template <typename PFP, typename V_ATT>
202
void computeNeighborhoodCentroidVertices(typename PFP::MAP& map,
Sylvain Thery's avatar
Sylvain Thery committed
203
		const V_ATT& position, V_ATT& vertex_centroid)
204
{
Pierre Kraemer's avatar
Pierre Kraemer committed
205
	CGoGN::Parallel::foreach_cell<VERTEX>(map,[&](Vertex v, unsigned int /*thr*/)
Sylvain Thery's avatar
Sylvain Thery committed
206 207
	{
		vertex_centroid[v] = vertexNeighborhoodCentroid<PFP>(map, v, position) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
208
	}, FORCE_CELL_MARKING);
209 210
}

Pierre Kraemer's avatar
Pierre Kraemer committed
211 212 213 214
} // namespace Parallel



215
} // namespace Geometry
Pierre Kraemer's avatar
Pierre Kraemer committed
216

217
} // namespace Surface
218

219 220
namespace Volume
{
Pierre Kraemer's avatar
Pierre Kraemer committed
221

222
namespace Geometry
Lionel Untereiner's avatar
Lionel Untereiner committed
223
{
224

225
template <typename PFP, typename V_ATT>
Sylvain Thery's avatar
Sylvain Thery committed
226
typename V_ATT::DATA_TYPE vertexNeighborhoodCentroid(typename PFP::MAP& map, Vertex v, const V_ATT& attributs)
Lionel Untereiner's avatar
Lionel Untereiner committed
227
{
228
	typename V_ATT::DATA_TYPE  center(0.0);
Lionel Untereiner's avatar
Lionel Untereiner committed
229
	unsigned int count = 0 ;
Pierre Kraemer's avatar
Pierre Kraemer committed
230
	foreach_adjacent3<EDGE>(map, v, [&] (Vertex it)
Lionel Untereiner's avatar
Lionel Untereiner committed
231 232 233
	{
		center += attributs[it];
		++count ;
Sylvain Thery's avatar
Sylvain Thery committed
234
	}, false);
Lionel Untereiner's avatar
Lionel Untereiner committed
235 236 237
	center /= count ;
	return center ;
}
238

239
template <typename PFP, typename V_ATT, typename W_ATT>
Sylvain Thery's avatar
Sylvain Thery committed
240
void computeCentroidVolumes(typename PFP::MAP& map, const V_ATT& position, W_ATT& vol_centroid)
Lionel Untereiner's avatar
Lionel Untereiner committed
241
{
Sylvain Thery's avatar
Sylvain Thery committed
242
	if (CGoGN::Parallel::NumberOfThreads > 1)
Sylvain Thery's avatar
Sylvain Thery committed
243 244 245 246 247
	{
		Parallel::computeCentroidVolumes<PFP,V_ATT,W_ATT>(map,position,vol_centroid);
		return;
	}

248 249
	foreach_cell<VOLUME>(map, [&] (Vol v)
	{
Sylvain Thery's avatar
Sylvain Thery committed
250 251
		vol_centroid[v] = Surface::Geometry::volumeCentroid<PFP,V_ATT>(map, v, position) ;
	}, AUTO);
Lionel Untereiner's avatar
Lionel Untereiner committed
252
}
253

254
template <typename PFP, typename V_ATT, typename W_ATT>
Sylvain Thery's avatar
Sylvain Thery committed
255
void computeCentroidELWVolumes(typename PFP::MAP& map, const V_ATT& position, W_ATT& vol_centroid)
256
{
Sylvain Thery's avatar
Sylvain Thery committed
257
	if (CGoGN::Parallel::NumberOfThreads > 1)
Sylvain Thery's avatar
Sylvain Thery committed
258 259 260 261 262
	{
		Parallel::computeCentroidELWVolumes<PFP,V_ATT,W_ATT>(map,position,vol_centroid);
		return;
	}

263 264
	foreach_cell<VOLUME>(map, [&] (Vol v)
	{
Sylvain Thery's avatar
Sylvain Thery committed
265 266
		vol_centroid[v] = Surface::Geometry::volumeCentroidELW<PFP,V_ATT>(map, v, position) ;
	}, AUTO);
267 268
}

269
template <typename PFP, typename V_ATT>
Sylvain Thery's avatar
Sylvain Thery committed
270
void computeNeighborhoodCentroidVertices(typename PFP::MAP& map, const V_ATT& position, V_ATT& vertex_centroid)
Sylvain Thery's avatar
Sylvain Thery committed
271
{
Sylvain Thery's avatar
Sylvain Thery committed
272
	if (CGoGN::Parallel::NumberOfThreads > 1)
Sylvain Thery's avatar
Sylvain Thery committed
273 274 275 276 277
	{
		Parallel::computeNeighborhoodCentroidVertices<PFP,V_ATT>(map,position,vertex_centroid);
		return;
	}

278 279 280
	foreach_cell<VERTEX>(map, [&] (Vertex v)
	{
		vertex_centroid[v] = Volume::Geometry::vertexNeighborhoodCentroid<PFP,V_ATT>(map, v, position) ;
Sylvain Thery's avatar
Sylvain Thery committed
281
	}, AUTO);
Sylvain Thery's avatar
Sylvain Thery committed
282 283 284
}


285 286
namespace Parallel
{
Pierre Kraemer's avatar
Pierre Kraemer committed
287

288
template <typename PFP, typename V_ATT, typename W_ATT>
Sylvain Thery's avatar
Sylvain Thery committed
289
void computeCentroidVolumes(typename PFP::MAP& map, const V_ATT& position, W_ATT& vol_centroid)
290
{
Sylvain Thery's avatar
Sylvain Thery committed
291
	CGoGN::Parallel::foreach_cell<VOLUME>(map, [&] (Vol v, unsigned int /*thr*/)
292
	{
Sylvain Thery's avatar
Sylvain Thery committed
293
		vol_centroid[v] = Surface::Geometry::volumeCentroid<PFP,V_ATT>(map, v, position) ;
Sylvain Thery's avatar
Sylvain Thery committed
294
	});
Sylvain Thery's avatar
Sylvain Thery committed
295
}
296

297
template <typename PFP, typename V_ATT, typename W_ATT>
Sylvain Thery's avatar
Sylvain Thery committed
298
void computeCentroidELWVolumes(typename PFP::MAP& map, const V_ATT& position, W_ATT& vol_centroid)
299
{
Sylvain Thery's avatar
Sylvain Thery committed
300
	CGoGN::Parallel::foreach_cell<VOLUME>(map, [&] (Vol v, unsigned int /*thr*/)
Sylvain Thery's avatar
Sylvain Thery committed
301
	{
Sylvain Thery's avatar
Sylvain Thery committed
302
		vol_centroid[v] = Surface::Geometry::volumeCentroidELW<PFP,V_ATT>(map, v, position) ;
Sylvain Thery's avatar
Sylvain Thery committed
303
	});
304 305
}

306
template <typename PFP, typename V_ATT>
Sylvain Thery's avatar
Sylvain Thery committed
307
void computeNeighborhoodCentroidVertices(typename PFP::MAP& map, const V_ATT& position, V_ATT& vertex_centroid)
308
{
Sylvain Thery's avatar
Sylvain Thery committed
309
	CGoGN::Parallel::foreach_cell<VERTEX>(map, [&] (Vertex v, unsigned int /*thr*/)
Sylvain Thery's avatar
Sylvain Thery committed
310
	{
Sylvain Thery's avatar
Sylvain Thery committed
311
		vertex_centroid[v] = Volume::Geometry::vertexNeighborhoodCentroid<PFP,V_ATT>(map, v, position) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
312
	}, FORCE_CELL_MARKING);
313
}
314

untereiner's avatar
untereiner committed
315
} // namespace Parallel
Pierre Kraemer's avatar
Pierre Kraemer committed
316

317

Pierre Kraemer's avatar
Pierre Kraemer committed
318
} // namespace Geometry
319

Pierre Kraemer's avatar
Pierre Kraemer committed
320
} // namespace Volume
321

Pierre Kraemer's avatar
Pierre Kraemer committed
322 323 324
} // namespace Algo

} // namespace CGoGN