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-2024 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 
31 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
32 
33 void Foam::triSurfaceMesh::drawHitProblem
34 (
35  const label fi,
36  const point& start,
37  const point& p,
38  const point& end,
39  const pointIndexHitList& hitInfo
40 ) const
41 {
42  if (debug)
43  {
44  const List<labelledTri>& tris = *this;
45  tmp<pointField> tpoints = points();
46  const pointField& points = tpoints();
47 
48  Info<< nl << "# findLineAll did not hit its own face."
49  << nl << "# fi " << fi
50  << nl << "# start " << start
51  << nl << "# point " << p
52  << nl << "# end " << end
53  << nl << "# hitInfo " << hitInfo
54  << endl;
55 
56  meshTools::writeOBJ(Info, start);
59 
60  Info<< "l 1 2 3" << endl;
61 
62  meshTools::writeOBJ(Info, points[tris[fi][0]]);
63  meshTools::writeOBJ(Info, points[tris[fi][1]]);
64  meshTools::writeOBJ(Info, points[tris[fi][2]]);
65 
66  Info<< "f 4 5 6" << endl;
67 
68  forAll(hitInfo, hi)
69  {
70  label hfi = hitInfo[hi].index();
71 
72  meshTools::writeOBJ(Info, points[tris[hfi][0]]);
73  meshTools::writeOBJ(Info, points[tris[hfi][1]]);
74  meshTools::writeOBJ(Info, points[tris[hfi][2]]);
75 
76  Info<< "f "
77  << 3*hi + 7 << " "
78  << 3*hi + 8 << " "
79  << 3*hi + 9
80  << endl;
81  }
82  }
83 }
84 
85 
86 void Foam::triSurfaceMesh::processHit
87 (
88  scalar& internalCloseness,
89  scalar& externalCloseness,
90  const scalar internalToleranceCosAngle,
91  const scalar externalToleranceCosAngle,
92  const label fi,
93  const point& start,
94  const point& p,
95  const point& end,
96  const vector& normal,
97  const vectorField& normals,
98  const pointIndexHitList& hitInfo
99 ) const
100 {
101  if (hitInfo.size() < 1)
102  {
103  drawHitProblem(fi, start, p, end, hitInfo);
104  }
105  else if (hitInfo.size() == 1)
106  {
107  if (!hitInfo[0].hit())
108  {
109  }
110  else if (hitInfo[0].index() != fi)
111  {
112  drawHitProblem(fi, start, p, end, hitInfo);
113  }
114  }
115  else
116  {
117  label ownHiti = -1;
118 
119  forAll(hitInfo, hI)
120  {
121  // Find the hit on the triangle that launched the ray
122 
123  if (hitInfo[hI].index() == fi)
124  {
125  ownHiti = hI;
126  break;
127  }
128  }
129 
130  if (ownHiti < 0)
131  {
132  drawHitProblem(fi, start, p, end, hitInfo);
133  }
134  else if (ownHiti == 0)
135  {
136  // There are no internal hits, the first hit is the
137  // closest external hit
138 
139  if
140  (
141  (normal & normals[hitInfo[ownHiti + 1].index()])
142  < externalToleranceCosAngle
143  )
144  {
145  externalCloseness = min
146  (
147  externalCloseness,
148  mag(p - hitInfo[ownHiti + 1].hitPoint())
149  );
150  }
151  }
152  else if (ownHiti == hitInfo.size() - 1)
153  {
154  // There are no external hits, the last but one hit is
155  // the closest internal hit
156 
157  if
158  (
159  (normal & normals[hitInfo[ownHiti - 1].index()])
160  < internalToleranceCosAngle
161  )
162  {
163  internalCloseness = min
164  (
165  internalCloseness,
166  mag(p - hitInfo[ownHiti - 1].hitPoint())
167  );
168  }
169  }
170  else
171  {
172  if
173  (
174  (normal & normals[hitInfo[ownHiti + 1].index()])
175  < externalToleranceCosAngle
176  )
177  {
178  externalCloseness = min
179  (
180  externalCloseness,
181  mag(p - hitInfo[ownHiti + 1].hitPoint())
182  );
183  }
184 
185  if
186  (
187  (normal & normals[hitInfo[ownHiti - 1].index()])
188  < internalToleranceCosAngle
189  )
190  {
191  internalCloseness = min
192  (
193  internalCloseness,
194  mag(p - hitInfo[ownHiti - 1].hitPoint())
195  );
196  }
197  }
198  }
199 }
200 
201 
204 (
205  const scalar internalAngleTolerance,
206  const scalar externalAngleTolerance
207 ) const
208 {
209  const scalar internalToleranceCosAngle
210  (
211  cos(degToRad(180) - internalAngleTolerance)
212  );
213 
214  const scalar externalToleranceCosAngle
215  (
216  cos(degToRad(180) - externalAngleTolerance)
217  );
218 
219  const Time& runTime = objectRegistry::time();
220 
221  // Prepare start and end points for intersection tests
222 
223  const vectorField& normals = faceNormals();
224 
225  const scalar span = bounds().mag();
226 
227  const pointField start(faceCentres() - span*normals);
228  const pointField end(faceCentres() + span*normals);
229  const pointField& faceCentres = this->faceCentres();
230 
231  List<List<pointIndexHit>> allHitinfo;
232 
233  // Find all intersections (in order)
234  findLineAll(start, end, allHitinfo);
235 
236  scalarField internalCloseness(start.size(), great);
237  scalarField externalCloseness(start.size(), great);
238 
239  forAll(allHitinfo, fi)
240  {
241  const List<pointIndexHit>& hitInfo = allHitinfo[fi];
242 
243  processHit
244  (
245  internalCloseness[fi],
246  externalCloseness[fi],
247  internalToleranceCosAngle,
248  externalToleranceCosAngle,
249  fi,
250  start[fi],
251  faceCentres[fi],
252  end[fi],
253  normals[fi],
254  normals,
255  hitInfo
256  );
257  }
258 
260  (
262  (
264  (
265  IOobject
266  (
267  objectRegistry::name() + ".internalCloseness",
268  runTime.constant(),
270  runTime
271  ),
272  *this,
273  dimLength,
274  internalCloseness
275  )
276  ),
277 
279  (
281  (
282  IOobject
283  (
284  objectRegistry::name() + ".externalCloseness",
285  runTime.constant(),
287  runTime
288  ),
289  *this,
290  dimLength,
291  externalCloseness
292  )
293  )
294  );
295 }
296 
297 
300 (
301  const scalar internalAngleTolerance,
302  const scalar externalAngleTolerance
303 ) const
304 {
305  const scalar internalToleranceCosAngle
306  (
307  cos(degToRad(180) - internalAngleTolerance)
308  );
309 
310  const scalar externalToleranceCosAngle
311  (
312  cos(degToRad(180) - externalAngleTolerance)
313  );
314 
315  const Time& runTime = objectRegistry::time();
316 
317  // Prepare start and end points for intersection tests
318 
319  tmp<pointField> tpoints = points();
320  const pointField& points = tpoints();
321  const labelList& meshPoints = this->meshPoints();
322  const pointField& faceCentres = this->faceCentres();
323  const vectorField& normals = this->faceNormals();
324  const labelListList& pointFaces = this->pointFaces();
325 
326  const scalar span = bounds().mag();
327 
328  label nPointFaces = 0;
329  forAll(pointFaces, pfi)
330  {
331  nPointFaces += pointFaces[pfi].size();
332  }
333 
334  pointField facePoints(nPointFaces);
335  pointField start(nPointFaces);
336  pointField end(nPointFaces);
337 
338  label i = 0;
339  forAll(points, pi)
340  {
341  forAll(pointFaces[pi], pfi)
342  {
343  const label fi = pointFaces[pi][pfi];
344 
345  facePoints[i] = (0.9*points[meshPoints[pi]] + 0.1*faceCentres[fi]);
346  const vector& n = normals[fi];
347 
348  start[i] = facePoints[i] - span*n;
349  end[i] = facePoints[i] + span*n;
350 
351  i++;
352  }
353  }
354 
355  List<pointIndexHitList> allHitinfo;
356 
357  // Find all intersections (in order)
358  findLineAll(start, end, allHitinfo);
359 
360  scalarField internalCloseness(points.size(), great);
361  scalarField externalCloseness(points.size(), great);
362 
363  i = 0;
364  forAll(points, pi)
365  {
366  forAll(pointFaces[pi], pfi)
367  {
368  const label fi = pointFaces[pi][pfi];
369  const pointIndexHitList& hitInfo = allHitinfo[i];
370 
371  processHit
372  (
373  internalCloseness[pi],
374  externalCloseness[pi],
375  internalToleranceCosAngle,
376  externalToleranceCosAngle,
377  fi,
378  start[i],
379  facePoints[i],
380  end[i],
381  normals[fi],
382  normals,
383  hitInfo
384  );
385 
386  i++;
387  }
388  }
389 
391  (
393  (
395  (
396  IOobject
397  (
398  objectRegistry::name() + ".internalPointCloseness",
399  runTime.constant(),
401  runTime
402  ),
403  *this,
404  dimLength,
405  internalCloseness
406  )
407  ),
408 
410  (
412  (
413  IOobject
414  (
415  objectRegistry::name() + ".externalPointCloseness",
416  runTime.constant(),
418  runTime
419  ),
420  *this,
421  dimLength,
422  externalCloseness
423  )
424  )
425  );
426 }
427 
428 
429 // ************************************************************************* //
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< triSurfaceScalarField > > extractCloseness(const scalar internalAngleTolerance=degToRad(80), const scalar externalAngleTolerance=degToRad(80)) const
Return a pair of triSurfaceScalarFields representing the.
Pair< tmp< triSurfacePointScalarField > > extractPointCloseness(const scalar internalAngleTolerance=degToRad(80), const scalar externalAngleTolerance=degToRad(80)) const
Return a pair of triSurfaceScalarPointFields 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
scalar degToRad(const scalar deg)
Convert degrees to radians.
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:257
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:266
dimensionedScalar cos(const dimensionedScalar &ds)
volScalarField & p
static iteratorEnd end()
iteratorEnd set to beyond the end of any HashTable
Definition: HashTable.H:112
Fields for triSurface.