faceIntersection.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2022 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "face.H"
30 #include "pointHit.H"
31 #include "triangle.H"
32 #include "line.H"
33 
34 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
35 
37 (
38  const point& p,
39  const vector& n,
40  const UList<point>& meshPoints,
41  const intersection::algorithm alg,
42  const intersection::direction dir
43 ) const
44 {
45  // Return potential intersection with face with a ray starting
46  // at p, direction n (does not need to be normalized)
47  // Does face-center decomposition and returns triangle intersection
48  // point closest to p.
49 
50  // In case of miss the point is the nearest point intersection of the
51  // face plane and the ray and the distance is the distance between the
52  // intersection point and the nearest point on the face
53 
54  // If the face is a triangle, do a direct calculation
55  if (size() == 3)
56  {
57  return triPointRef
58  (
59  meshPoints[operator[](0)],
60  meshPoints[operator[](1)],
61  meshPoints[operator[](2)]
62  ).ray(p, n, alg, dir);
63  }
64 
65  point ctr = Foam::average(points(meshPoints));
66 
67  scalar nearestHitDist = GREAT;
68  scalar nearestMissDist = GREAT;
69  bool eligible = false;
70 
71  // Initialize to miss, distance = GREAT
72  pointHit nearest(p);
73 
74  const labelList& f = *this;
75 
76  const label nPoints = size();
77 
78  point nextPoint = ctr;
79 
80  for (label pI = 0; pI < nPoints; pI++)
81  {
82  nextPoint = meshPoints[f[fcIndex(pI)]];
83 
84  // Note: for best accuracy, centre point always comes last
85  //
86  pointHit curHit = triPointRef
87  (
88  meshPoints[f[pI]],
89  nextPoint,
90  ctr
91  ).ray(p, n, alg, dir);
92 
93  if (curHit.hit())
94  {
95  if (Foam::mag(curHit.distance()) < Foam::mag(nearestHitDist))
96  {
97  nearestHitDist = curHit.distance();
98  nearest.hitPoint(curHit.point());
99  }
100  }
101  else if (!nearest.hit())
102  {
103  // Miss and no hit yet. Update miss statistics.
104  if (curHit.eligibleMiss())
105  {
106  eligible = true;
107 
108  // Miss distance is the distance between the plane intersection
109  // point and the nearest point of the triangle
110  scalar missDist =
111  Foam::mag
112  (
113  p + curHit.distance()*n
114  - curHit.point()
115  );
116 
117  if (missDist < nearestMissDist)
118  {
119  nearestMissDist = missDist;
120  nearest.setDistance(curHit.distance());
121  nearest.setPoint(curHit.point());
122  }
123  }
124  }
125  }
126 
127  if (nearest.hit())
128  {
129  nearest.setDistance(nearestHitDist);
130  }
131  else
132  {
133  // Haven't hit a single face triangle
134  nearest.setMiss(eligible);
135  }
136 
137  return nearest;
138 }
139 
140 
142 (
143  const point& p,
144  const vector& q,
145  const point& ctr,
146  const UList<point>& meshPoints,
147  const intersection::algorithm alg,
148  const scalar tol
149 ) const
150 {
151  // If the face is a triangle, do a direct calculation
152  if (size() == 3)
153  {
154  return triPointRef
155  (
156  meshPoints[operator[](0)],
157  meshPoints[operator[](1)],
158  meshPoints[operator[](2)]
159  ).intersection(p, q, alg, tol);
160  }
161 
162  scalar nearestHitDist = VGREAT;
163 
164  // Initialize to miss, distance = GREAT
165  pointHit nearest(p);
166 
167  const labelList& f = *this;
168 
169  forAll(f, pI)
170  {
171  // Note: for best accuracy, centre point always comes last
172  pointHit curHit = triPointRef
173  (
174  meshPoints[f[pI]],
175  meshPoints[f[fcIndex(pI)]],
176  ctr
177  ).intersection(p, q, alg, tol);
178 
179  if (curHit.hit())
180  {
181  if (Foam::mag(curHit.distance()) < Foam::mag(nearestHitDist))
182  {
183  nearestHitDist = curHit.distance();
184  nearest.hitPoint(curHit.point());
185  }
186  }
187  }
188 
189  if (nearest.hit())
190  {
191  nearest.setDistance(nearestHitDist);
192  }
193 
194  return nearest;
195 }
196 
197 
199 (
200  const point& p,
201  const UList<point>& meshPoints
202 ) const
203 {
204  // Dummy labels
205  label nearType = -1;
206  label nearLabel = -1;
207 
208  return nearestPointClassify(p, meshPoints, nearType, nearLabel);
209 }
210 
211 
213 (
214  const point& p,
215  const UList<point>& meshPoints,
216  label& nearType,
217  label& nearLabel
218 ) const
219 {
220  // If the face is a triangle, do a direct calculation
221  if (size() == 3)
222  {
223  return triPointRef
224  (
225  meshPoints[operator[](0)],
226  meshPoints[operator[](1)],
227  meshPoints[operator[](2)]
228  ).nearestPointClassify(p, nearType, nearLabel);
229  }
230 
231  const face& f = *this;
232  point ctr = centre(meshPoints);
233 
234  // Initialize to miss, distance=GREAT
235  pointHit nearest(p);
236 
237  nearType = -1;
238  nearLabel = -1;
239 
240  const label nPoints = f.size();
241 
242  point nextPoint = ctr;
243 
244  for (label pI = 0; pI < nPoints; pI++)
245  {
246  nextPoint = meshPoints[f[fcIndex(pI)]];
247 
248  label tmpNearType = -1;
249  label tmpNearLabel = -1;
250 
251  // Note: for best accuracy, centre point always comes last
252  triPointRef tri
253  (
254  meshPoints[f[pI]],
255  nextPoint,
256  ctr
257  );
258 
259  pointHit curHit = tri.nearestPointClassify
260  (
261  p,
262  tmpNearType,
263  tmpNearLabel
264  );
265 
266  if (Foam::mag(curHit.distance()) < Foam::mag(nearest.distance()))
267  {
268  nearest.setDistance(curHit.distance());
269 
270  // Assume at first that the near type is NONE on the
271  // triangle (i.e. on the face of the triangle) then it is
272  // therefore also for the face.
273 
274  nearType = NONE;
275 
276  if (tmpNearType == triPointRef::EDGE && tmpNearLabel == 0)
277  {
278  // If the triangle edge label is 0, then this is also
279  // an edge of the face, if not, it is on the face
280 
281  nearType = EDGE;
282 
283  nearLabel = pI;
284  }
285  else if (tmpNearType == triPointRef::POINT && tmpNearLabel < 2)
286  {
287  // If the triangle point label is 0 or 1, then this is
288  // also a point of the face, if not, it is on the face
289 
290  nearType = POINT;
291 
292  nearLabel = pI + tmpNearLabel;
293  }
294 
295  if (curHit.hit())
296  {
297  nearest.hitPoint(curHit.point());
298  }
299  else
300  {
301  // In nearest point, miss is always eligible
302  nearest.setMiss(true);
303  nearest.setPoint(curHit.point());
304  }
305  }
306  }
307 
308  return nearest;
309 }
310 
311 
313 (
314  const point& p,
315  const UList<point>& points,
316  const scalar tol
317 ) const
318 {
319  // Take three points [0, 1/3, 2/3] from the face
320  // - assumes the face is not severely warped
321 
322  return triPointRef
323  (
324  points[operator[](0)],
325  points[operator[](size()/3)],
326  points[operator[]((2*size())/3)]
327  ).sign(p, tol);
328 }
329 
330 
331 // ************************************************************************* //
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:118
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
void setPoint(const point_type &p)
Set the point.
Definition: pointHit.H:235
pointHit intersection(const point &p, const vector &q, const point &ctr, const UList< point > &meshPoints, const intersection::algorithm alg, const scalar tol=0.0) const
Fast intersection with a ray.
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:413
Close to point.
Definition: triangle.H:240
label fcIndex(const label i) const noexcept
The forward circular index. The next index in the list which returns to the first at the end of the l...
Definition: UListI.H:53
bool hit() const noexcept
Is there a hit.
Definition: pointHit.H:145
pointField points(const UList< point > &pts) const
Return the points corresponding to this face.
Definition: faceI.H:80
pointHit ray(const point &p, const vector &n, const UList< point > &meshPoints, const intersection::algorithm alg=intersection::FULL_RAY, const intersection::direction dir=intersection::VECTOR) const
Return potential intersection with face with a ray starting at p, direction n (does not need to be no...
int sign(const point &p, const UList< point > &points, const scalar tol=SMALL) const
The sign for the side of the face plane the point is on, using three evenly distributed face points f...
Close to edge.
Definition: triangle.H:241
const pointField & points
label nPoints
void setDistance(const scalar d) noexcept
Set the distance.
Definition: pointHit.H:243
Vector< scalar > vector
Definition: vector.H:57
dimensioned< Type > average(const DimensionedField< Type, GeoMesh > &df)
Describes the interaction of a object and a (templated) point. It carries the info of a successful hi...
Definition: pointHit.H:43
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:99
void setMiss(const bool eligible) noexcept
Set the hit status off and set the eligible miss status.
Definition: pointHit.H:226
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
pointHit nearestPointClassify(const point &p, const UList< point > &meshPoints, label &nearType, label &nearLabel) const
Return nearest point to face and classify it:
pointHit nearestPoint(const point &p, const UList< point > &meshPoints) const
Return nearest point to face.
labelList f(nPoints)
vector point
Point is a vector.
Definition: point.H:37
const point_type & hitPoint() const
Return the hit point. Fatal if not hit.
Definition: pointHit.H:177
scalar distance() const noexcept
Return distance to hit.
Definition: pointHit.H:169
triangle< point, const point & > triPointRef
A triangle using referred points.
Definition: triangleFwd.H:39
const point_type & point() const noexcept
Return the point, no checks.
Definition: pointHit.H:161
label size() const noexcept
The number of elements in the UList.
Definition: UListI.H:413
label n
bool eligibleMiss() const noexcept
Is this an eligible miss.
Definition: pointHit.H:153
List< label > labelList
A List of labels.
Definition: List.H:62
volScalarField & p
PointHit< point > pointHit
A PointHit with a 3D point.
Definition: pointHit.H:43