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 = curHit.point().dist(p + curHit.distance()*n);
111 
112  if (missDist < nearestMissDist)
113  {
114  nearestMissDist = missDist;
115  nearest.setDistance(curHit.distance());
116  nearest.setPoint(curHit.point());
117  }
118  }
119  }
120  }
121 
122  if (nearest.hit())
123  {
124  nearest.setDistance(nearestHitDist);
125  }
126  else
127  {
128  // Haven't hit a single face triangle
129  nearest.setMiss(eligible);
130  }
131 
132  return nearest;
133 }
134 
135 
137 (
138  const point& p,
139  const vector& q,
140  const point& ctr,
141  const UList<point>& meshPoints,
142  const intersection::algorithm alg,
143  const scalar tol
144 ) const
145 {
146  // If the face is a triangle, do a direct calculation
147  if (size() == 3)
148  {
149  return triPointRef
150  (
151  meshPoints[operator[](0)],
152  meshPoints[operator[](1)],
153  meshPoints[operator[](2)]
154  ).intersection(p, q, alg, tol);
155  }
156 
157  scalar nearestHitDist = VGREAT;
158 
159  // Initialize to miss, distance = GREAT
160  pointHit nearest(p);
161 
162  const labelList& f = *this;
163 
164  forAll(f, pI)
165  {
166  // Note: for best accuracy, centre point always comes last
167  pointHit curHit = triPointRef
168  (
169  meshPoints[f[pI]],
170  meshPoints[f[fcIndex(pI)]],
171  ctr
172  ).intersection(p, q, alg, tol);
173 
174  if (curHit.hit())
175  {
176  if (Foam::mag(curHit.distance()) < Foam::mag(nearestHitDist))
177  {
178  nearestHitDist = curHit.distance();
179  nearest.hitPoint(curHit.point());
180  }
181  }
182  }
183 
184  if (nearest.hit())
185  {
186  nearest.setDistance(nearestHitDist);
187  }
188 
189  return nearest;
190 }
191 
192 
194 (
195  const point& p,
196  const UList<point>& meshPoints
197 ) const
198 {
199  // Dummy labels
200  label nearType = -1;
201  label nearLabel = -1;
202 
203  return nearestPointClassify(p, meshPoints, nearType, nearLabel);
204 }
205 
206 
208 (
209  const point& p,
210  const UList<point>& meshPoints,
211  label& nearType,
212  label& nearLabel
213 ) const
214 {
215  // If the face is a triangle, do a direct calculation
216  if (size() == 3)
217  {
218  return triPointRef
219  (
220  meshPoints[operator[](0)],
221  meshPoints[operator[](1)],
222  meshPoints[operator[](2)]
223  ).nearestPointClassify(p, nearType, nearLabel);
224  }
225 
226  const face& f = *this;
227  point ctr = centre(meshPoints);
228 
229  // Initialize to miss, distance=GREAT
230  pointHit nearest(p);
231 
232  nearType = -1;
233  nearLabel = -1;
234 
235  const label nPoints = f.size();
236 
237  point nextPoint = ctr;
238 
239  for (label pI = 0; pI < nPoints; pI++)
240  {
241  nextPoint = meshPoints[f[fcIndex(pI)]];
242 
243  label tmpNearType = -1;
244  label tmpNearLabel = -1;
245 
246  // Note: for best accuracy, centre point always comes last
247  triPointRef tri
248  (
249  meshPoints[f[pI]],
250  nextPoint,
251  ctr
252  );
253 
254  pointHit curHit = tri.nearestPointClassify
255  (
256  p,
257  tmpNearType,
258  tmpNearLabel
259  );
260 
261  if (Foam::mag(curHit.distance()) < Foam::mag(nearest.distance()))
262  {
263  nearest.setDistance(curHit.distance());
264 
265  // Assume at first that the near type is NONE on the
266  // triangle (i.e. on the face of the triangle) then it is
267  // therefore also for the face.
268 
269  nearType = NONE;
270 
271  if (tmpNearType == triPointRef::EDGE && tmpNearLabel == 0)
272  {
273  // If the triangle edge label is 0, then this is also
274  // an edge of the face, if not, it is on the face
275 
276  nearType = EDGE;
277 
278  nearLabel = pI;
279  }
280  else if (tmpNearType == triPointRef::POINT && tmpNearLabel < 2)
281  {
282  // If the triangle point label is 0 or 1, then this is
283  // also a point of the face, if not, it is on the face
284 
285  nearType = POINT;
286 
287  nearLabel = pI + tmpNearLabel;
288  }
289 
290  if (curHit.hit())
291  {
292  nearest.hitPoint(curHit.point());
293  }
294  else
295  {
296  // In nearest point, miss is always eligible
297  nearest.setMiss(true);
298  nearest.setPoint(curHit.point());
299  }
300  }
301  }
302 
303  return nearest;
304 }
305 
306 
308 (
309  const point& p,
310  const UList<point>& points,
311  const scalar tol
312 ) const
313 {
314  // Take three points [0, 1/3, 2/3] from the face
315  // - assumes the face is not severely warped
316 
317  return triPointRef
318  (
319  points[operator[](0)],
320  points[operator[](size()/3)],
321  points[operator[]((2*size())/3)]
322  ).sign(p, tol);
323 }
324 
325 
326 // ************************************************************************* //
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
dimensioned< Type > average(const DimensionedField< Type, GeoMesh > &f1)
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:421
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:97
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
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:105
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...
label size() const noexcept
The number of elements in the container.
Definition: UList.H:671
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 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