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 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "face.H"
29 #include "pointHit.H"
30 #include "triPointRef.H"
31 #include "line.H"
32 
33 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
34 
36 (
37  const point& p,
38  const vector& n,
39  const UList<point>& meshPoints,
40  const intersection::algorithm alg,
41  const intersection::direction dir
42 ) const
43 {
44  // Return potential intersection with face with a ray starting
45  // at p, direction n (does not need to be normalized)
46  // Does face-center decomposition and returns triangle intersection
47  // point closest to p.
48 
49  // In case of miss the point is the nearest point intersection of the
50  // face plane and the ray and the distance is the distance between the
51  // intersection point and the nearest point on the face
52 
53  // If the face is a triangle, do a direct calculation
54  if (size() == 3)
55  {
56  return triPointRef
57  (
58  meshPoints[operator[](0)],
59  meshPoints[operator[](1)],
60  meshPoints[operator[](2)]
61  ).ray(p, n, alg, dir);
62  }
63 
64  point ctr = Foam::average(points(meshPoints));
65 
66  scalar nearestHitDist = GREAT;
67  scalar nearestMissDist = GREAT;
68  bool eligible = false;
69 
70  // Initialize to miss, distance = GREAT
71  pointHit nearest(p);
72 
73  const labelList& f = *this;
74 
75  const label nPoints = size();
76 
77  point nextPoint = ctr;
78 
79  for (label pI = 0; pI < nPoints; pI++)
80  {
81  nextPoint = meshPoints[f[fcIndex(pI)]];
82 
83  // Note: for best accuracy, centre point always comes last
84  //
85  pointHit curHit = triPointRef
86  (
87  meshPoints[f[pI]],
88  nextPoint,
89  ctr
90  ).ray(p, n, alg, dir);
91 
92  if (curHit.hit())
93  {
94  if (Foam::mag(curHit.distance()) < Foam::mag(nearestHitDist))
95  {
96  nearestHitDist = curHit.distance();
97  nearest.setHit();
98  nearest.setPoint(curHit.hitPoint());
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.missPoint()
115  );
116 
117  if (missDist < nearestMissDist)
118  {
119  nearestMissDist = missDist;
120  nearest.setDistance(curHit.distance());
121  nearest.setPoint(curHit.missPoint());
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.setHit();
185  nearest.setPoint(curHit.hitPoint());
186  }
187  }
188  }
189 
190  if (nearest.hit())
191  {
192  nearest.setDistance(nearestHitDist);
193  }
194 
195  return nearest;
196 }
197 
198 
200 (
201  const point& p,
202  const UList<point>& meshPoints
203 ) const
204 {
205  // Dummy labels
206  label nearType = -1;
207  label nearLabel = -1;
208 
209  return nearestPointClassify(p, meshPoints, nearType, nearLabel);
210 }
211 
212 
214 (
215  const point& p,
216  const UList<point>& meshPoints,
217  label& nearType,
218  label& nearLabel
219 ) const
220 {
221  // If the face is a triangle, do a direct calculation
222  if (size() == 3)
223  {
224  return triPointRef
225  (
226  meshPoints[operator[](0)],
227  meshPoints[operator[](1)],
228  meshPoints[operator[](2)]
229  ).nearestPointClassify(p, nearType, nearLabel);
230  }
231 
232  const face& f = *this;
233  point ctr = centre(meshPoints);
234 
235  // Initialize to miss, distance=GREAT
236  pointHit nearest(p);
237 
238  nearType = -1;
239  nearLabel = -1;
240 
241  const label nPoints = f.size();
242 
243  point nextPoint = ctr;
244 
245  for (label pI = 0; pI < nPoints; pI++)
246  {
247  nextPoint = meshPoints[f[fcIndex(pI)]];
248 
249  label tmpNearType = -1;
250  label tmpNearLabel = -1;
251 
252  // Note: for best accuracy, centre point always comes last
253  triPointRef tri
254  (
255  meshPoints[f[pI]],
256  nextPoint,
257  ctr
258  );
259 
260  pointHit curHit = tri.nearestPointClassify
261  (
262  p,
263  tmpNearType,
264  tmpNearLabel
265  );
266 
267  if (Foam::mag(curHit.distance()) < Foam::mag(nearest.distance()))
268  {
269  nearest.setDistance(curHit.distance());
270 
271  // Assume at first that the near type is NONE on the
272  // triangle (i.e. on the face of the triangle) then it is
273  // therefore also for the face.
274 
275  nearType = NONE;
276 
277  if (tmpNearType == triPointRef::EDGE && tmpNearLabel == 0)
278  {
279  // If the triangle edge label is 0, then this is also
280  // an edge of the face, if not, it is on the face
281 
282  nearType = EDGE;
283 
284  nearLabel = pI;
285  }
286  else if (tmpNearType == triPointRef::POINT && tmpNearLabel < 2)
287  {
288  // If the triangle point label is 0 or 1, then this is
289  // also a point of the face, if not, it is on the face
290 
291  nearType = POINT;
292 
293  nearLabel = pI + tmpNearLabel;
294  }
295 
296  if (curHit.hit())
297  {
298  nearest.setHit();
299  nearest.setPoint(curHit.hitPoint());
300  }
301  else
302  {
303  // In nearest point, miss is always eligible
304  nearest.setMiss(true);
305  nearest.setPoint(curHit.missPoint());
306  }
307  }
308  }
309 
310  return nearest;
311 }
312 
313 
315 (
316  const point& p,
317  const UList<point>& points,
318  const scalar tol
319 ) const
320 {
321  // Take three points [0, 1/3, 2/3] from the face
322  // - assumes the face is not severely warped
323 
324  return triPointRef
325  (
326  points[operator[](0)],
327  points[operator[](size()/3)],
328  points[operator[]((2*size())/3)]
329  ).sign(p, tol);
330 }
331 
332 
333 // ************************************************************************* //
Foam::intersection::direction
direction
Definition: intersection.H:66
Foam::PointHit::setHit
void setHit() noexcept
Set the hit status on.
Definition: PointHit.H:181
Foam::PointHit::setMiss
void setMiss(const bool eligible) noexcept
Set the hit status off and set the eligible miss status.
Definition: PointHit.H:188
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::face::nearestPoint
pointHit nearestPoint(const point &p, const UList< point > &meshPoints) const
Return nearest point to face.
Definition: faceIntersection.C:200
Foam::PointHit::setDistance
void setDistance(const scalar d) noexcept
Set the distance.
Definition: PointHit.H:201
Foam::PointHit
Describes the interaction of a face and a point. It carries the info of a successful hit and (if succ...
Definition: PointHit.H:53
face.H
Foam::PointHit::distance
scalar distance() const noexcept
Return distance to hit.
Definition: PointHit.H:139
Foam::PointHit::hitPoint
const point_type & hitPoint() const
Return the hit point. Fatal if not hit.
Definition: PointHit.H:145
line.H
triPointRef.H
pointHit.H
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
nPoints
label nPoints
Definition: gmvOutputHeader.H:2
Foam::triangle
A triangle primitive used to calculate face normals and swept volumes.
Definition: triangle.H:59
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::PointHit::eligibleMiss
bool eligibleMiss() const noexcept
Is this an eligible miss.
Definition: PointHit.H:127
Foam::PointHit::missPoint
const point_type & missPoint() const
Return the miss point. Fatal if hit.
Definition: PointHit.H:158
Foam::intersection::algorithm
algorithm
Definition: intersection.H:72
Foam::face::ray
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
Definition: faceIntersection.C:36
Foam::face::intersection
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.
Definition: faceIntersection.C:142
Foam::PointHit::setPoint
void setPoint(const point_type &p)
Set the point.
Definition: PointHit.H:195
Foam::triangle::nearestPointClassify
pointHit nearestPointClassify(const point &p, label &nearType, label &nearLabel) const
Find the nearest point to p on the triangle and classify it:
Definition: triangleI.H:522
f
labelList f(nPoints)
Foam::Vector< scalar >
Foam::List< label >
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Foam::UList
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:103
points
const pointField & points
Definition: gmvOutputHeader.H:1
Foam::face::sign
int sign(const point &p, const UList< point > &points, const scalar tol=SMALL) const
Definition: faceIntersection.C:315
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:72
Foam::face::nearestPointClassify
pointHit nearestPointClassify(const point &p, const UList< point > &meshPoints, label &nearType, label &nearLabel) const
Return nearest point to face and classify it:
Definition: faceIntersection.C:214
Foam::PointHit::hit
bool hit() const noexcept
Is there a hit.
Definition: PointHit.H:121
Foam::average
dimensioned< Type > average(const DimensionedField< Type, GeoMesh > &df)
Definition: DimensionedFieldFunctions.C:328
Foam::triPointRef
triangle< point, const point & > triPointRef
A triangle using referred points.
Definition: triangle.H:71