extractCloseness.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2018-2023 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "triSurfaceMesh.H"
27 #include "triSurfaceFields.H"
28 #include "meshTools.H"
29 #include "Time.H"
30 #include "unitConversion.H"
31 
32 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
33 
34 void Foam::triSurfaceMesh::drawHitProblem
35 (
36  const label fi,
37  const point& start,
38  const point& p,
39  const point& end,
40  const pointIndexHitList& hitInfo
41 ) const
42 {
43  if (debug)
44  {
45  const List<labelledTri>& tris = *this;
46  tmp<pointField> tpoints = points();
47  const pointField& points = tpoints();
48 
49  Info<< nl << "# findLineAll did not hit its own face."
50  << nl << "# fi " << fi
51  << nl << "# start " << start
52  << nl << "# point " << p
53  << nl << "# end " << end
54  << nl << "# hitInfo " << hitInfo
55  << endl;
56 
57  meshTools::writeOBJ(Info, start);
60 
61  Info<< "l 1 2 3" << endl;
62 
63  meshTools::writeOBJ(Info, points[tris[fi][0]]);
64  meshTools::writeOBJ(Info, points[tris[fi][1]]);
65  meshTools::writeOBJ(Info, points[tris[fi][2]]);
66 
67  Info<< "f 4 5 6" << endl;
68 
69  forAll(hitInfo, hi)
70  {
71  label hfi = hitInfo[hi].index();
72 
73  meshTools::writeOBJ(Info, points[tris[hfi][0]]);
74  meshTools::writeOBJ(Info, points[tris[hfi][1]]);
75  meshTools::writeOBJ(Info, points[tris[hfi][2]]);
76 
77  Info<< "f "
78  << 3*hi + 7 << " "
79  << 3*hi + 8 << " "
80  << 3*hi + 9
81  << endl;
82  }
83  }
84 }
85 
86 
87 void Foam::triSurfaceMesh::processHit
88 (
89  scalar& internalCloseness,
90  scalar& externalCloseness,
91  const scalar internalToleranceCosAngle,
92  const scalar externalToleranceCosAngle,
93  const label fi,
94  const point& start,
95  const point& p,
96  const point& end,
97  const vector& normal,
98  const vectorField& normals,
99  const pointIndexHitList& hitInfo
100 ) const
101 {
102  if (hitInfo.size() < 1)
103  {
104  drawHitProblem(fi, start, p, end, hitInfo);
105  }
106  else if (hitInfo.size() == 1)
107  {
108  if (!hitInfo[0].hit())
109  {
110  }
111  else if (hitInfo[0].index() != fi)
112  {
113  drawHitProblem(fi, start, p, end, hitInfo);
114  }
115  }
116  else
117  {
118  label ownHiti = -1;
119 
120  forAll(hitInfo, hI)
121  {
122  // Find the hit on the triangle that launched the ray
123 
124  if (hitInfo[hI].index() == fi)
125  {
126  ownHiti = hI;
127  break;
128  }
129  }
130 
131  if (ownHiti < 0)
132  {
133  drawHitProblem(fi, start, p, end, hitInfo);
134  }
135  else if (ownHiti == 0)
136  {
137  // There are no internal hits, the first hit is the
138  // closest external hit
139 
140  if
141  (
142  (normal & normals[hitInfo[ownHiti + 1].index()])
143  < externalToleranceCosAngle
144  )
145  {
146  externalCloseness = min
147  (
148  externalCloseness,
149  mag(p - hitInfo[ownHiti + 1].hitPoint())
150  );
151  }
152  }
153  else if (ownHiti == hitInfo.size() - 1)
154  {
155  // There are no external hits, the last but one hit is
156  // the closest internal hit
157 
158  if
159  (
160  (normal & normals[hitInfo[ownHiti - 1].index()])
161  < internalToleranceCosAngle
162  )
163  {
164  internalCloseness = min
165  (
166  internalCloseness,
167  mag(p - hitInfo[ownHiti - 1].hitPoint())
168  );
169  }
170  }
171  else
172  {
173  if
174  (
175  (normal & normals[hitInfo[ownHiti + 1].index()])
176  < externalToleranceCosAngle
177  )
178  {
179  externalCloseness = min
180  (
181  externalCloseness,
182  mag(p - hitInfo[ownHiti + 1].hitPoint())
183  );
184  }
185 
186  if
187  (
188  (normal & normals[hitInfo[ownHiti - 1].index()])
189  < internalToleranceCosAngle
190  )
191  {
192  internalCloseness = min
193  (
194  internalCloseness,
195  mag(p - hitInfo[ownHiti - 1].hitPoint())
196  );
197  }
198  }
199  }
200 }
201 
202 
205 (
206  const scalar internalAngleTolerance,
207  const scalar externalAngleTolerance
208 ) const
209 {
210  const scalar internalToleranceCosAngle
211  (
212  cos(degToRad(180 - internalAngleTolerance))
213  );
214 
215  const scalar externalToleranceCosAngle
216  (
217  cos(degToRad(180 - externalAngleTolerance))
218  );
219 
220  const Time& runTime = objectRegistry::time();
221 
222  // Prepare start and end points for intersection tests
223 
224  const vectorField& normals = faceNormals();
225 
226  const scalar span = bounds().mag();
227 
228  const pointField start(faceCentres() - span*normals);
229  const pointField end(faceCentres() + span*normals);
230  const pointField& faceCentres = this->faceCentres();
231 
232  List<List<pointIndexHit>> allHitinfo;
233 
234  // Find all intersections (in order)
235  findLineAll(start, end, allHitinfo);
236 
237  scalarField internalCloseness(start.size(), great);
238  scalarField externalCloseness(start.size(), great);
239 
240  forAll(allHitinfo, fi)
241  {
242  const List<pointIndexHit>& hitInfo = allHitinfo[fi];
243 
244  processHit
245  (
246  internalCloseness[fi],
247  externalCloseness[fi],
248  internalToleranceCosAngle,
249  externalToleranceCosAngle,
250  fi,
251  start[fi],
252  faceCentres[fi],
253  end[fi],
254  normals[fi],
255  normals,
256  hitInfo
257  );
258  }
259 
261  (
263  (
265  (
266  IOobject
267  (
268  objectRegistry::name() + ".internalCloseness",
269  runTime.constant(),
271  runTime
272  ),
273  *this,
274  dimLength,
275  internalCloseness
276  )
277  ),
278 
280  (
282  (
283  IOobject
284  (
285  objectRegistry::name() + ".externalCloseness",
286  runTime.constant(),
288  runTime
289  ),
290  *this,
291  dimLength,
292  externalCloseness
293  )
294  )
295  );
296 }
297 
298 
301 (
302  const scalar internalAngleTolerance,
303  const scalar externalAngleTolerance
304 ) const
305 {
306  const scalar internalToleranceCosAngle
307  (
308  cos(degToRad(180 - internalAngleTolerance))
309  );
310 
311  const scalar externalToleranceCosAngle
312  (
313  cos(degToRad(180 - externalAngleTolerance))
314  );
315 
316  const Time& runTime = objectRegistry::time();
317 
318  // Prepare start and end points for intersection tests
319 
320  tmp<pointField> tpoints = points();
321  const pointField& points = tpoints();
322  const labelList& meshPoints = this->meshPoints();
323  const pointField& faceCentres = this->faceCentres();
324  const vectorField& normals = this->faceNormals();
325  const labelListList& pointFaces = this->pointFaces();
326 
327  const scalar span = bounds().mag();
328 
329  label nPointFaces = 0;
330  forAll(pointFaces, pfi)
331  {
332  nPointFaces += pointFaces[pfi].size();
333  }
334 
335  pointField facePoints(nPointFaces);
336  pointField start(nPointFaces);
337  pointField end(nPointFaces);
338 
339  label i = 0;
340  forAll(points, pi)
341  {
342  forAll(pointFaces[pi], pfi)
343  {
344  const label fi = pointFaces[pi][pfi];
345 
346  facePoints[i] = (0.9*points[meshPoints[pi]] + 0.1*faceCentres[fi]);
347  const vector& n = normals[fi];
348 
349  start[i] = facePoints[i] - span*n;
350  end[i] = facePoints[i] + span*n;
351 
352  i++;
353  }
354  }
355 
356  List<pointIndexHitList> allHitinfo;
357 
358  // Find all intersections (in order)
359  findLineAll(start, end, allHitinfo);
360 
361  scalarField internalCloseness(points.size(), great);
362  scalarField externalCloseness(points.size(), great);
363 
364  i = 0;
365  forAll(points, pi)
366  {
367  forAll(pointFaces[pi], pfi)
368  {
369  const label fi = pointFaces[pi][pfi];
370  const pointIndexHitList& hitInfo = allHitinfo[i];
371 
372  processHit
373  (
374  internalCloseness[pi],
375  externalCloseness[pi],
376  internalToleranceCosAngle,
377  externalToleranceCosAngle,
378  fi,
379  start[i],
380  facePoints[i],
381  end[i],
382  normals[fi],
383  normals,
384  hitInfo
385  );
386 
387  i++;
388  }
389  }
390 
392  (
394  (
396  (
397  IOobject
398  (
399  objectRegistry::name() + ".internalPointCloseness",
400  runTime.constant(),
402  runTime
403  ),
404  *this,
405  dimLength,
406  internalCloseness
407  )
408  ),
409 
411  (
413  (
414  IOobject
415  (
416  objectRegistry::name() + ".externalPointCloseness",
417  runTime.constant(),
419  runTime
420  ),
421  *this,
422  dimLength,
423  externalCloseness
424  )
425  )
426  );
427 }
428 
429 
430 // ************************************************************************* //
label n
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
const word & name() const
Return name.
Definition: IOobject.H:310
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: List.H:91
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
An ordered pair of two objects of type <T> with first() and second() elements.
Definition: Pair.H:65
static const word & constant()
Return constant name.
Definition: TimePaths.H:122
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:76
const Time & time() const
Return time.
static const word & geometryDir()
Return the geometry directory name.
A class for managing temporary objects.
Definition: tmp.H:55
Pair< tmp< triSurfacePointScalarField > > extractPointCloseness(const scalar internalAngleTolerance=80, const scalar externalAngleTolerance=80) const
Return a pair of triSurfaceScalarPointFields representing the.
Pair< tmp< triSurfaceScalarField > > extractCloseness(const scalar internalAngleTolerance=80, const scalar externalAngleTolerance=80) const
Return a pair of triSurfaceScalarFields representing the.
virtual tmp< pointField > points() const
Get the points that define the surface.
const pointField & points
void writeOBJ(Ostream &os, const point &pt)
Write obj representation of point.
Definition: meshTools.C:203
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
messageStream Info
const dimensionSet dimLength
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:42
vector point
Point is a vector.
Definition: point.H:41
layerAndWeight min(const layerAndWeight &a, const layerAndWeight &b)
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:49
dimensioned< scalar > mag(const dimensioned< Type > &)
Field< vector > vectorField
Specialisation of Field<T> for vector.
List< pointIndexHit > pointIndexHitList
List of pointIndexHits and associated functions.
static const char nl
Definition: Ostream.H:260
dimensionedScalar cos(const dimensionedScalar &ds)
scalar degToRad(const scalar deg)
Conversion from degrees to radians.
volScalarField & p
static iteratorEnd end()
iteratorEnd set to beyond the end of any HashTable
Definition: HashTable.H:112
Fields for triSurface.
Unit conversion functions.