centroid.hpp 13.6 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
#include "Algo/Parallel/parallel_foreach.h"
Sylvain Thery's avatar
Sylvain Thery committed
31
#include "Topology/generic/cells_macros.h"
32

Pierre Kraemer's avatar
Pierre Kraemer committed
33
34
35
36
37
38
namespace CGoGN
{

namespace Algo
{

39
40
41
namespace Surface
{

Pierre Kraemer's avatar
Pierre Kraemer committed
42
43
44
namespace Geometry
{

45
template <typename PFP, typename V_ATT>
46
typename V_ATT::DATA_TYPE volumeCentroid(typename PFP::MAP& map, Vol d, const V_ATT& attributs, unsigned int thread)
Pierre Kraemer's avatar
Pierre Kraemer committed
47
{
48
	typename V_ATT::DATA_TYPE center(0.0);
49
	unsigned int count = 0 ;
50
51
52
53
54
55
56
57
//	Traversor3WV<typename PFP::MAP> tra(map,d,false,thread);
//	for (Dart d = tra.begin(); d != tra.end(); d = tra.next())
//	{
//		center += attributs[d];
//		++count;
//	}

	foreachIncident3MT(VOLUME,d,VERTEX,e,typename PFP::MAP,map,thread)
Pierre Kraemer's avatar
Pierre Kraemer committed
58
	{
59
		center += attributs[e];
Pierre Kraemer's avatar
Pierre Kraemer committed
60
61
62
63
64
65
66
		++count;
	}

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

67
template <typename PFP, typename V_ATT>
68
typename V_ATT::DATA_TYPE volumeCentroidELW(typename PFP::MAP& map, Vol d, const V_ATT& attributs, unsigned int thread)
69
{
70
	typedef typename V_ATT::DATA_TYPE EMB;
71
	EMB center(0.0);
72

73
	double count=0.0;
74
75
76
77
//	Traversor3WE<typename PFP::MAP> t(map, d,false,thread) ;
//	for(Dart it = t.begin(); it != t.end();it = t.next())

	foreachIncident3MT(VOLUME,d,EDGE,it,typename PFP::MAP,map,thread)
78
	{
Sylvain Thery's avatar
Sylvain Thery committed
79
		EMB e1 = attributs[it.dart];
80
81
82
83
84
85
86
87
88
		EMB e2 = attributs[map.phi1(it)];
		double l = (e2-e1).norm();
		center += (e1+e2)*l;
		count += 2.0*l ;
	}
	center /= double(count);	
	return center ;
}

89
template <typename PFP, typename V_ATT>
90
typename V_ATT::DATA_TYPE faceCentroid(typename PFP::MAP& map, Face d, const V_ATT& attributs)
Pierre Kraemer's avatar
Pierre Kraemer committed
91
{
92
	typename V_ATT::DATA_TYPE center(0.0);
Pierre Kraemer's avatar
Pierre Kraemer committed
93
	unsigned int count = 0 ;
94
95
96
97

//	Traversor2FV<typename PFP::MAP> t(map, d) ;
//	for(Dart it = t.begin(); it != t.end(); it = t.next())
	foreachIncident2(FACE,d,VERTEX,it,typename PFP::MAP,map)
Pierre Kraemer's avatar
Pierre Kraemer committed
98
99
100
	{
		center += attributs[it];
		++count ;
101
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
102
103
104
105
	center /= double(count);
	return center ;
}

106
template <typename PFP, typename V_ATT>
107
typename V_ATT::DATA_TYPE faceCentroidELW(typename PFP::MAP& map, Face d, const V_ATT& attributs)
108
{
109
110
	typedef typename V_ATT::DATA_TYPE EMB;

111
	EMB center(0.0);
112
	double count=0.0;
113
114
115
116

//	Traversor2FE<typename PFP::MAP> t(map, d) ;
//	for(Dart it = t.begin(); it != t.end(); it = t.next())
	foreachIncident2(FACE,d,EDGE,it,typename PFP::MAP,map)
117
	{
Sylvain Thery's avatar
Sylvain Thery committed
118
		EMB e1 = attributs[it.dart];
119
120
121
122
123
124
125
126
127
		EMB e2 = attributs[map.phi1(it)];
		double l = (e2-e1).norm();
		center += (e1+e2)*l;
		count += 2.0*l ;
	}
	center /= double(count);
	return center ;
}

128
template <typename PFP, typename V_ATT>
129
typename V_ATT::DATA_TYPE vertexNeighborhoodCentroid(typename PFP::MAP& map, Vertex d, const V_ATT& attributs)
Pierre Kraemer's avatar
Pierre Kraemer committed
130
{
131
132
	typename V_ATT::DATA_TYPE center(0.0);

Pierre Kraemer's avatar
Pierre Kraemer committed
133
	unsigned int count = 0 ;
134
135
136
//	Traversor2VVaE<typename PFP::MAP> t(map, d) ;
//	for(Dart it = t.begin(); it != t.end(); it = t.next())
	foreachAdjacent2(VERTEX,EDGE,d,it,typename PFP::MAP,map)
Pierre Kraemer's avatar
Pierre Kraemer committed
137
	{
138
		center += attributs[it];
Pierre Kraemer's avatar
Pierre Kraemer committed
139
		++count ;
140
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
141
142
143
144
	center /= count ;
	return center ;
}

145
146
template <typename PFP, typename V_ATT, typename F_ATT>
void computeCentroidFaces(typename PFP::MAP& map, const V_ATT& position, F_ATT& face_centroid, unsigned int thread)
Pierre Kraemer's avatar
Pierre Kraemer committed
147
{
148
149
150
//	TraversorF<typename PFP::MAP> t(map,thread) ;
//	for(Dart d = t.begin(); d != t.end(); d = t.next())
	foreachCellMT(FACE,d,typename PFP::MAP,map ,thread)
151
		face_centroid[d] = faceCentroid<PFP,V_ATT>(map, d, position) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
152
153
}

154
155
template <typename PFP, typename V_ATT, typename F_ATT>
void computeCentroidELWFaces(typename PFP::MAP& map, const V_ATT& position, F_ATT& face_centroid, unsigned int thread)
156
{
157
158
159
//	TraversorF<typename PFP::MAP> t(map,thread) ;
//	for(Dart d = t.begin(); d != t.end(); d = t.next())
	foreachCellMT(FACE,d,typename PFP::MAP,map ,thread)
160
		face_centroid[d] = faceCentroidELW<PFP,V_ATT>(map, d, position) ;
161
162
}

163
164
template <typename PFP, typename V_ATT>
void computeNeighborhoodCentroidVertices(typename PFP::MAP& map, const V_ATT& position, V_ATT& vertex_centroid, unsigned int thread)
Pierre Kraemer's avatar
Pierre Kraemer committed
165
{
166
167
168
//	TraversorV<typename PFP::MAP> t(map, thread) ;
//	for(Dart d = t.begin(); d != t.end(); d = t.next())
	foreachCellMT(VERTEX,d,typename PFP::MAP,map ,thread)
169
		vertex_centroid[d] = vertexNeighborhoodCentroid<PFP,V_ATT>(map, d, position) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
170
171
}

172
173
174
175

namespace Parallel
{

176
template <typename PFP, typename V_ATT, typename F_ATT>
Pierre Kraemer's avatar
Pierre Kraemer committed
177
class FunctorComputeCentroidFaces: public FunctorMapThreaded<typename PFP::MAP>
178
{
179
180
	 const V_ATT& m_position;
	 F_ATT& m_fcentroid;
Pierre Kraemer's avatar
Pierre Kraemer committed
181

182
public:
183
	 FunctorComputeCentroidFaces<PFP,V_ATT,F_ATT>( typename PFP::MAP& map, const V_ATT& position, F_ATT& fcentroid):
184
185
186
	 	 FunctorMapThreaded<typename PFP::MAP>(map), m_position(position), m_fcentroid(fcentroid)
	 { }

187
	void run(Dart d, unsigned int /*threadID*/)
188
189
190
191
192
	{
		m_fcentroid[d] = faceCentroid<PFP>(this->m_map, d, m_position) ;
	}
};

193
template <typename PFP, typename V_ATT, typename F_ATT>
Pierre Kraemer's avatar
Pierre Kraemer committed
194
class FunctorComputeCentroidELWFaces: public FunctorMapThreaded<typename PFP::MAP>
195
{
196
197
	const V_ATT& m_position;
	F_ATT& m_fcentroid;
Pierre Kraemer's avatar
Pierre Kraemer committed
198

199
public:
200
	 FunctorComputeCentroidELWFaces<PFP,V_ATT,F_ATT>( typename PFP::MAP& map, const V_ATT& position, F_ATT& fcentroid):
201
202
203
204
205
206
207
208
209
	 	 FunctorMapThreaded<typename PFP::MAP>(map), m_position(position), m_fcentroid(fcentroid)
	 { }

	void run(Dart d, unsigned int threadID)
	{
		m_fcentroid[d] = faceCentroidELW<PFP>(this->m_map, d, m_position) ;
	}
};

210
211
212
213
214
template <typename PFP, typename V_ATT>
class FunctorComputeNeighborhoodCentroidVertices: public FunctorMapThreaded<typename PFP::MAP >
{
	 const V_ATT& m_position;
	 V_ATT& m_vcentroid;
Pierre Kraemer's avatar
Pierre Kraemer committed
215

216
217
218
219
public:
	 FunctorComputeNeighborhoodCentroidVertices<PFP,V_ATT>( typename PFP::MAP& map, const V_ATT& position, V_ATT& vcentroid):
		 FunctorMapThreaded<typename PFP::MAP>(map), m_position(position), m_vcentroid(vcentroid)
	 { }
220

221
222
223
224
225
	void run(Dart d, unsigned int /*threadID*/)
	{
		m_vcentroid[d] = vertexNeighborhoodCentroid<PFP>(this->m_map, d, m_position) ;
	}
};
226

227
228
template <typename PFP, typename V_ATT, typename F_ATT>
void computeCentroidFaces(typename PFP::MAP& map, const V_ATT& position, F_ATT& face_centroid,
229
		unsigned int nbth, unsigned int current_thread)
230
{
231
	FunctorComputeCentroidFaces<PFP,V_ATT,F_ATT> funct(map,position,face_centroid);
232
	Algo::Parallel::foreach_cell<typename PFP::MAP,FACE>(map, funct, nbth, false, current_thread);
233
234
}

235
236
template <typename PFP, typename V_ATT, typename F_ATT>
void computeCentroidELWFaces(typename PFP::MAP& map, const V_ATT& position, F_ATT& face_centroid,
237
		unsigned int nbth, unsigned int current_thread)
238
{
239
	FunctorComputeCentroidELWFaces<PFP,V_ATT,F_ATT> funct(map,position,face_centroid);
240
	Algo::Parallel::foreach_cell<typename PFP::MAP,FACE>(map, funct, nbth, false, current_thread);
241
242
}

243
template <typename PFP, typename V_ATT>
244
void computeNeighborhoodCentroidVertices(typename PFP::MAP& map,
245
		const V_ATT& position, V_ATT& vertex_centroid,
246
		unsigned int nbth, unsigned int current_thread)
247
{
248
249
	FunctorComputeNeighborhoodCentroidVertices<PFP,V_ATT> funct(map,position,vertex_centroid);
	Algo::Parallel::foreach_cell<typename PFP::MAP,VERTEX>(map, funct, nbth, false);
250
251
}

Pierre Kraemer's avatar
Pierre Kraemer committed
252
253
254
255
} // namespace Parallel



256
} // namespace Geometry
Pierre Kraemer's avatar
Pierre Kraemer committed
257

258
} // namespace Surface
259

260
261
namespace Volume
{
Pierre Kraemer's avatar
Pierre Kraemer committed
262

263
namespace Geometry
Lionel Untereiner's avatar
Lionel Untereiner committed
264
{
265

266
template <typename PFP, typename V_ATT>
267
typename V_ATT::DATA_TYPE vertexNeighborhoodCentroid(typename PFP::MAP& map, Vertex d, const V_ATT& attributs, unsigned int thread)
Lionel Untereiner's avatar
Lionel Untereiner committed
268
{
269
	typename V_ATT::DATA_TYPE  center(0.0);
Lionel Untereiner's avatar
Lionel Untereiner committed
270
	unsigned int count = 0 ;
271
272
273
//	Traversor3VVaE<typename PFP::MAP> t(map, d) ;
//	for(Dart it = t.begin(); it != t.end(); it = t.next())
	foreachAdjacent3MT(VERTEX,EDGE,d,it,typename PFP::MAP,map,thread)
Lionel Untereiner's avatar
Lionel Untereiner committed
274
275
276
277
278
279
280
	{
		center += attributs[it];
		++count ;
	}
	center /= count ;
	return center ;
}
281

282
283
template <typename PFP, typename V_ATT, typename W_ATT>
void computeCentroidVolumes(typename PFP::MAP& map, const V_ATT& position, W_ATT& vol_centroid, unsigned int thread)
Lionel Untereiner's avatar
Lionel Untereiner committed
284
{
285
286
287
//	TraversorW<typename PFP::MAP> t(map, thread) ;
//	for(Dart d = t.begin(); d != t.end(); d = t.next())
	foreachCellMT(VOLUME,d,typename PFP::MAP,map ,thread)
288
		vol_centroid[d] = Surface::Geometry::volumeCentroid<PFP,V_ATT>(map, d, position,thread) ;
Lionel Untereiner's avatar
Lionel Untereiner committed
289
}
290

291
292
template <typename PFP, typename V_ATT, typename W_ATT>
void computeCentroidELWVolumes(typename PFP::MAP& map, const V_ATT& position, W_ATT& vol_centroid, unsigned int thread)
293
{
294
295
296
//	TraversorW<typename PFP::MAP> t(map,thread) ;
//	for(Dart d = t.begin(); d != t.end(); d = t.next())
	foreachCellMT(VOLUME,d,typename PFP::MAP,map ,thread)
297
		vol_centroid[d] = Surface::Geometry::volumeCentroidELW<PFP,V_ATT>(map, d, position,thread) ;
298
299
}

300
301
template <typename PFP, typename V_ATT>
void computeNeighborhoodCentroidVertices(typename PFP::MAP& map, const V_ATT& position, V_ATT& vertex_centroid, unsigned int thread)
Sylvain Thery's avatar
Sylvain Thery committed
302
{
303
304
305
//	TraversorV<typename PFP::MAP> t(map, thread) ;
//	for(Dart d = t.begin(); d != t.end(); d = t.next())
	foreachCellMT(VERTEX,d,typename PFP::MAP,map ,thread)
306
		vertex_centroid[d] = Volume::Geometry::vertexNeighborhoodCentroid<PFP,V_ATT>(map, d, position) ;
Sylvain Thery's avatar
Sylvain Thery committed
307
308
309
}


310
311
namespace Parallel
{
Pierre Kraemer's avatar
Pierre Kraemer committed
312

313
template <typename PFP, typename V_ATT, typename W_ATT>
314
315
class FunctorComputeCentroidVolumes: public FunctorMapThreaded<typename PFP::MAP >
{
316
317
	 const V_ATT& m_position;
	 W_ATT& m_vol_centroid;
Pierre Kraemer's avatar
Pierre Kraemer committed
318

319
public:
320
	 FunctorComputeCentroidVolumes<PFP,V_ATT,W_ATT>( typename PFP::MAP& map, const V_ATT& position, W_ATT& vol_centroid):
321
322
	 	 FunctorMapThreaded<typename PFP::MAP>(map), m_position(position), m_vol_centroid(vol_centroid)
	 { }
323

324
325
	void run(Dart d, unsigned int threadID)
	{
326
		m_vol_centroid[d] = Surface::Geometry::volumeCentroid<PFP,V_ATT,W_ATT>(this->m_map, d, m_position,threadID) ;
327
328
	}
};
329

330
331
template <typename PFP, typename V_ATT, typename W_ATT>
void computeCentroidVolumes(typename PFP::MAP& map, const V_ATT& position, W_ATT& vol_centroid,	unsigned int nbth)
332
{
333
	FunctorComputeCentroidVolumes<PFP,V_ATT,W_ATT> funct(map,position,vol_centroid);
334
	Algo::Parallel::foreach_cell<typename PFP::MAP,VOLUME>(map, funct, nbth, true);
Lionel Untereiner's avatar
Lionel Untereiner committed
335
}
336

337
338
template <typename PFP, typename V_ATT, typename W_ATT>
class FunctorComputeCentroidELWVolumes: public FunctorMapThreaded<typename PFP::MAP >
339
{
340
341
342
	 const V_ATT& m_position;
	 W_ATT& m_vol_centroid;
//	 VolumeAttribute<typename PFP::VEC3>& m_vol_centroid;
Pierre Kraemer's avatar
Pierre Kraemer committed
343

344
public:
345
	 FunctorComputeCentroidELWVolumes<PFP,V_ATT,W_ATT>( typename PFP::MAP& map, const V_ATT& position, W_ATT& vol_centroid):
346
347
348
349
350
		 FunctorMapThreaded<typename PFP::MAP>(map), m_position(position), m_vol_centroid(vol_centroid)
	 { }

	void run(Dart d, unsigned int threadID)
	{
351
		m_vol_centroid[d] = Surface::Geometry::volumeCentroidELW<PFP,V_ATT>(this->m_map, d, m_position, threadID) ;
352
353
354
	}
};

355
356
357
template <typename PFP, typename V_ATT, typename W_ATT>
void computeCentroidELWVolumes(typename PFP::MAP& map,
		const V_ATT& position, W_ATT& vol_centroid,
Thery Sylvain's avatar
Thery Sylvain committed
358
		unsigned int nbth)
359
{
360
	FunctorComputeCentroidELWVolumes<PFP,V_ATT,W_ATT> funct(map,position,vol_centroid);
361
362
363
	Algo::Parallel::foreach_cell<typename PFP::MAP,VOLUME>(map, funct, nbth, true);
}

364
template <typename PFP, typename V_ATT>
365
366
class FunctorComputeNeighborhoodCentroidVertices: public FunctorMapThreaded<typename PFP::MAP >
{
367
368
	 const V_ATT& m_position;
	 V_ATT& m_vcentroid;
Pierre Kraemer's avatar
Pierre Kraemer committed
369

370
public:
371
	 FunctorComputeNeighborhoodCentroidVertices<PFP,V_ATT>( typename PFP::MAP& map, const V_ATT& position, V_ATT& vcentroid):
372
373
	 	 FunctorMapThreaded<typename PFP::MAP>(map), m_position(position), m_vcentroid(vcentroid)
	 { }
374

375
	void run(Dart d, unsigned int /*threadID*/)
376
	{
377
		m_vcentroid[d] = vertexNeighborhoodCentroid<PFP,V_ATT>(this->m_map, d, m_position) ;
378
379
	}
};
380

381
382
383
template <typename PFP, typename V_ATT>
void computeNeighborhoodCentroidVertices(typename PFP::MAP& map, const V_ATT& position, V_ATT& vertex_centroid,
		unsigned int nbth)
384
{
385
386
	FunctorComputeNeighborhoodCentroidVertices<PFP,V_ATT> funct(map,position,vertex_centroid);
	Algo::Parallel::foreach_cell<typename PFP::MAP,VERTEX>(map, funct, nbth, false);
387
}
388

untereiner's avatar
untereiner committed
389
} // namespace Parallel
Pierre Kraemer's avatar
Pierre Kraemer committed
390

391

Pierre Kraemer's avatar
Pierre Kraemer committed
392
} // namespace Geometry
393

Pierre Kraemer's avatar
Pierre Kraemer committed
394
} // namespace Volume
395

Pierre Kraemer's avatar
Pierre Kraemer committed
396
397
398
} // namespace Algo

} // namespace CGoGN