Création d'un compte pour un collaborateur extérieur au laboratoire depuis l'intranet ICube : https://intranet.icube.unistra.fr/fr/labs/member/profile

raySelector.h 9.89 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-2011, 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.u-strasbg.fr/                                         *
Pierre Kraemer's avatar
Pierre Kraemer committed
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

#ifndef RAYSELECTOR_H_
#define RAYSELECTOR_H_

#include <algorithm>
#include <vector>
#include "Algo/Selection/raySelectFunctor.hpp"

namespace CGoGN
{

namespace Algo
{

namespace Selection
{
40

Pierre Kraemer's avatar
Pierre Kraemer committed
41
42
43
44
/**
 * Function that does the selection of faces, returned darts are sorted from closest to farthest
 * @param map the map we want to test
 * @param good a dart selector
45
46
47
 * @param rayA first point of ray (user side)
 * @param rayAB direction of ray (directed to the scene)
 * @param vecFaces (out) vector to store the darts of intersected faces
Pierre Kraemer's avatar
Pierre Kraemer committed
48
49
50
51
 */
template<typename PFP>
void facesRaySelection(typename PFP::MAP& map, const typename PFP::TVEC3& position, const FunctorSelect& good, const typename PFP::VEC3& rayA, const typename PFP::VEC3& rayAB, std::vector<Dart>& vecFaces)
{
52
	std::vector<typename PFP::VEC3> iPoints;
Pierre Kraemer's avatar
Pierre Kraemer committed
53
54
55
56

	// get back intersected faces
	vecFaces.clear();
	Algo::Selection::FuncFaceInter<PFP> ffi(map, position, vecFaces, iPoints, rayA, rayAB);
57
	map.foreach_orbit(FACE, ffi, good);
Pierre Kraemer's avatar
Pierre Kraemer committed
58

59
	// compute all distances to observer for each intersected face
Pierre Kraemer's avatar
Pierre Kraemer committed
60
61
62
63
64
65
	// and put them in a vector for sorting
	typedef std::pair<typename PFP::REAL, Dart> DartDist;
	std::vector<DartDist> distndart;

	unsigned int nbi = vecFaces.size();
	distndart.resize(nbi);
66
	for (unsigned int i = 0; i < nbi; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
67
68
69
	{
		distndart[i].second = vecFaces[i];
		typename PFP::VEC3 V = iPoints[i] - rayA;
70
		distndart[i].first = V.norm2();
Pierre Kraemer's avatar
Pierre Kraemer committed
71
72
73
74
75
76
	}

	// sort the vector of pair dist/dart
	std::sort(distndart.begin(), distndart.end(), distndartOrdering<PFP>);

	// store sorted darts in returned vector
77
	for (unsigned int i = 0; i < nbi; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
78
79
80
81
82
83
84
85
86
		vecFaces[i] = distndart[i].second;
}

/**
 * Function that does the selection of edges, returned darts are sorted from closest to farthest
 * @param map the map we want to test
 * @param rayA first point of  ray (user side)
 * @param rayAB vector of ray (directed ot the scene)
 * @param vecEdges (out) vector to store dart of intersected edges
87
 * @param dist radius of the cylinder of selection
Pierre Kraemer's avatar
Pierre Kraemer committed
88
89
90
91
 */
template<typename PFP>
void edgesRaySelection(typename PFP::MAP& map, const typename PFP::TVEC3& position, const FunctorSelect& good, const typename PFP::VEC3& rayA, const typename PFP::VEC3& rayAB, std::vector<Dart>& vecEdges, float dist)
{
92
93
	typename PFP::REAL dist2 = dist * dist;
	typename PFP::REAL AB2 = rayAB * rayAB;
Pierre Kraemer's avatar
Pierre Kraemer committed
94
95
96
97

	// recuperation des aretes intersectees
	vecEdges.clear();
	Algo::Selection::FuncEdgeInter<PFP> ffi(map, position, vecEdges, rayA, rayAB, AB2, dist2);
98
	map.foreach_orbit(EDGE, ffi, good);
Pierre Kraemer's avatar
Pierre Kraemer committed
99
100
101
102
103
104
105

	typedef std::pair<typename PFP::REAL, Dart> DartDist;
	std::vector<DartDist> distndart;

	unsigned int nbi = vecEdges.size();
	distndart.resize(nbi);

106
	// compute all distances to observer for each middle of intersected edge
Pierre Kraemer's avatar
Pierre Kraemer committed
107
108
109
110
111
	// and put them in a vector for sorting
	for (unsigned int i = 0; i < nbi; ++i)
	{
		Dart d = vecEdges[i];
		distndart[i].second = d;
112
		typename PFP::VEC3 V = (position[d] + position[map.phi1(d)]) / typename PFP::REAL(2);
Pierre Kraemer's avatar
Pierre Kraemer committed
113
		V -= rayA;
114
		distndart[i].first = V.norm2();
Pierre Kraemer's avatar
Pierre Kraemer committed
115
116
117
118
119
120
	}

	// sort the vector of pair dist/dart
	std::sort(distndart.begin(), distndart.end(), distndartOrdering<PFP>);

	// store sorted darts in returned vector
121
	for (unsigned int i = 0; i < nbi; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
122
123
124
125
126
127
128
129
		vecEdges[i] = distndart[i].second;
}

/**
 * Function that does the selection of vertices, returned darts are sorted from closest to farthest
 * @param map the map we want to test
 * @param rayA first point of  ray (user side)
 * @param rayAB vector of ray (directed ot the scene)
130
131
 * @param vecVertices (out) vector to store dart of intersected vertices
 * @param dist radius of the cylinder of selection
Pierre Kraemer's avatar
Pierre Kraemer committed
132
133
134
135
 */
template<typename PFP>
void verticesRaySelection(typename PFP::MAP& map, const typename PFP::TVEC3& position, const typename PFP::VEC3& rayA, const typename PFP::VEC3& rayAB, std::vector<Dart>& vecVertices, float dist, const FunctorSelect& good= SelectorTrue())
{
136
137
138
	typename PFP::REAL dist2 = dist * dist;
	typename PFP::REAL AB2 = rayAB * rayAB;

Pierre Kraemer's avatar
Pierre Kraemer committed
139
140
141
	// recuperation des sommets intersectes
	vecVertices.clear();
	Algo::Selection::FuncVertexInter<PFP> ffi(map, position, vecVertices, rayA, rayAB, AB2, dist2);
142
	map.foreach_orbit(VERTEX, ffi, good);
Pierre Kraemer's avatar
Pierre Kraemer committed
143
144
145
146
147
148
149

	typedef std::pair<typename PFP::REAL, Dart> DartDist;
	std::vector<DartDist> distndart;

	unsigned int nbi = vecVertices.size();
	distndart.resize(nbi);

150
	// compute all distances to observer for each intersected vertex
Pierre Kraemer's avatar
Pierre Kraemer committed
151
152
153
154
155
156
	// and put them in a vector for sorting
	for (unsigned int i = 0; i < nbi; ++i)
	{
		Dart d = vecVertices[i];
		distndart[i].second = d;
		typename PFP::VEC3 V = position[d] - rayA;
157
		distndart[i].first = V.norm2();
Pierre Kraemer's avatar
Pierre Kraemer committed
158
159
160
161
162
163
	}

	// sort the vector of pair dist/dart
	std::sort(distndart.begin(), distndart.end(), distndartOrdering<PFP>);

	// store sorted darts in returned vector
164
	for (unsigned int i = 0; i < nbi; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
165
166
167
168
169
170
171
172
		vecVertices[i] = distndart[i].second;
}

/**
 * Function that does the selection of one vertex
 * @param map the map we want to test
 * @param rayA first point of  ray (user side)
 * @param rayAB vector of ray (directed ot the scene)
Pierre Kraemer's avatar
Pierre Kraemer committed
173
 * @param vertex (out) dart of selected vertex (set to NIL if no vertex selected)
Pierre Kraemer's avatar
Pierre Kraemer committed
174
175
176
177
 */
template<typename PFP>
void vertexRaySelection(typename PFP::MAP& map, const typename PFP::TVEC3& position, const typename PFP::VEC3& rayA, const typename PFP::VEC3& rayAB, Dart& vertex, const FunctorSelect& good = SelectorTrue())
{
178
179
180
	std::vector<Dart> vecFaces;
	std::vector<typename PFP::VEC3> iPoints;

Pierre Kraemer's avatar
Pierre Kraemer committed
181
	// recuperation des faces intersectes
182
183
184
	Algo::Selection::FuncFaceInter<PFP> ffi(map, position, vecFaces, iPoints, rayA, rayAB);
	map.foreach_orbit(FACE, ffi, good);

Pierre Kraemer's avatar
Pierre Kraemer committed
185
186
187
188
189
190
191
192
193
	if(vecFaces.size() > 0)
	{
		typedef std::pair<typename PFP::REAL, unsigned int> IndexedDist;
		std::vector<IndexedDist> distnint;

		unsigned int nbi = vecFaces.size();
		distnint.resize(nbi);
		for (unsigned int i = 0; i < nbi; ++i)
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
194
			distnint[i].first = (iPoints[i] - rayA).norm2();
Pierre Kraemer's avatar
Pierre Kraemer committed
195
196
197
198
199
200
			distnint[i].second = i;
		}

		// sort the vector of pair dist/dart
		std::sort(distnint.begin(), distnint.end(), distnintOrdering<PFP>);

201
		// recuperation du point d'intersection sur la face la plus proche
Pierre Kraemer's avatar
Pierre Kraemer committed
202
		unsigned int first = distnint[0].second;
203
204
		typename PFP::VEC3 ip = iPoints[first];

Pierre Kraemer's avatar
Pierre Kraemer committed
205
		// recuperation du sommet le plus proche du point d'intersection
206
207
208
		Dart d = vecFaces[first];
		Dart it = d;
		typename PFP::REAL minDist = (ip - position[it]).norm2();
Pierre Kraemer's avatar
Pierre Kraemer committed
209
		vertex = it;
210
211
		it = map.phi1(it);
		while(it != d)
Pierre Kraemer's avatar
Pierre Kraemer committed
212
		{
213
			typename PFP::REAL dist = (ip - position[it]).norm2();
Pierre Kraemer's avatar
Pierre Kraemer committed
214
215
			if(dist < minDist)
			{
216
217
				minDist = dist;
				vertex = it;
Pierre Kraemer's avatar
Pierre Kraemer committed
218
			}
219
220
			it = map.phi1(it);
		}
Pierre Kraemer's avatar
Pierre Kraemer committed
221
222
	}
	else
Pierre Kraemer's avatar
Pierre Kraemer committed
223
		vertex = NIL;
Pierre Kraemer's avatar
Pierre Kraemer committed
224
225
226
}

/**
227
228
 * Fonction that do the selection of darts, returned darts are sorted from closest to farthest
 * Dart is here considered as a triangle formed by the 2 end vertices of the edge and the face centroid
Pierre Kraemer's avatar
Pierre Kraemer committed
229
230
231
232
233
234
235
236
237
238
239
 * @param map the map we want to test
 * @param rayA first point of  ray (user side)
 * @param rayAB vector of ray (directed ot the scene)
 * @param vecDarts (out) vector to store dart of intersected darts
 */
template<typename PFP>
void dartsRaySelection(typename PFP::MAP& map, const typename PFP::TVEC3& position, const typename PFP::VEC3& rayA, const typename PFP::VEC3& rayAB, std::vector<Dart>& vecDarts, const FunctorSelect& good = SelectorTrue())
{
	// recuperation des brins intersectes
	vecDarts.clear();
	Algo::Selection::FuncDartMapD2Inter<PFP> ffi(map, position, vecDarts, rayA, rayAB);
240
	map.foreach_orbit(FACE, ffi, good);
Pierre Kraemer's avatar
Pierre Kraemer committed
241
242
243
244
245
246
247
248
249
250
251
252
253

	typedef std::pair<typename PFP::REAL, Dart> DartDist;
	std::vector<DartDist> distndart;

	unsigned int nbi = vecDarts.size();
	distndart.resize(nbi);

	// compute all distances to observer for each dart of middle of edge
	// and put them in a vector for sorting
	for (unsigned int i = 0; i < nbi; ++i)
	{
		Dart d = vecDarts[i];
		distndart[i].second = d;
254
		typename PFP::VEC3 V = (position[d] + position[map.phi1(d)]) / typename PFP::REAL(2);
Pierre Kraemer's avatar
Pierre Kraemer committed
255
		V -= rayA;
256
		distndart[i].first = V.norm2();
Pierre Kraemer's avatar
Pierre Kraemer committed
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
	}

	// sort the vector of pair dist/dart
	std::sort(distndart.begin(), distndart.end(), distndartOrdering<PFP>);

	// store sorted darts in returned vector
	for (unsigned int i=0; i< nbi; ++i)
		vecDarts[i] = distndart[i].second;

}

} //namespace Selection

} //namespace Algo

} //namespace CGoGN

#endif /* RAYSELECTOR_H_ */