edgeIntersections.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) 2015 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 "edgeIntersections.H"
30 #include "triSurfaceSearch.H"
31 #include "OFstream.H"
32 #include "triSurface.H"
33 #include "pointIndexHit.H"
34 #include "treeDataTriSurface.H"
35 #include "indexedOctree.H"
36 #include "meshTools.H"
37 #include "plane.H"
38 #include "Random.H"
39 #include "unitConversion.H"
40 #include "treeBoundBox.H"
41 
42 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
43 
44 namespace Foam
45 {
46 defineTypeNameAndDebug(edgeIntersections, 0);
47 }
48 
50 
51 
52 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
53 
54 void Foam::edgeIntersections::checkEdges(const triSurface& surf)
55 {
56  const pointField& localPoints = surf.localPoints();
57  const edgeList& edges = surf.edges();
58 
59  treeBoundBox bb(localPoints);
60 
61  scalar minSize = SMALL * bb.minDim();
62 
63  forAll(edges, edgeI)
64  {
65  const edge& e = edges[edgeI];
66 
67  scalar eMag = e.mag(localPoints);
68 
69  if (eMag < minSize)
70  {
72  << "Edge " << edgeI << " vertices " << e
73  << " coords:" << localPoints[e[0]] << ' '
74  << localPoints[e[1]] << " is very small compared to bounding"
75  << " box dimensions " << bb << endl
76  << "This might lead to problems in intersection"
77  << endl;
78  }
79  }
80 }
81 
82 
83 // Update intersections for selected edges.
84 void Foam::edgeIntersections::intersectEdges
85 (
86  const triSurface& surf1,
87  const pointField& points1, // surf1 meshPoints (not localPoints!)
88  const triSurfaceSearch& querySurf2,
89  const scalarField& surf1PointTol, // surf1 tolerance per point
90  const labelList& edgeLabels
91 )
92 {
93  const triSurface& surf2 = querySurf2.surface();
94  const vectorField& normals2 = surf2.faceNormals();
95 
96  const labelList& meshPoints = surf1.meshPoints();
97 
98  if (debug)
99  {
100  Pout<< "Calculating intersection of " << edgeLabels.size() << " edges"
101  << " out of " << surf1.nEdges() << " with " << surf2.size()
102  << " triangles ..." << endl;
103  }
104 
105  pointField start(edgeLabels.size());
106  pointField end(edgeLabels.size());
107  vectorField edgeDirs(edgeLabels.size());
108 
109  // Go through all edges, calculate intersections
110  forAll(edgeLabels, i)
111  {
112  label edgeI = edgeLabels[i];
113 
114  if (debug)// && (i % 1000 == 0))
115  {
116  Pout<< "Intersecting edge " << edgeI << " with surface" << endl;
117  }
118 
119  const edge& e = surf1.edges()[edgeI];
120 
121  const point& pStart = points1[meshPoints[e.start()]];
122  const point& pEnd = points1[meshPoints[e.end()]];
123 
124  const vector n = normalised(pEnd - pStart);
125 
126  // Start tracking somewhat before pStart and up to somewhat after p1.
127  // Note that tolerances here are smaller than those used to classify
128  // hit below.
129  // This will cause this hit to be marked as degenerate and resolved
130  // later on.
131  start[i] = pStart - 0.5*surf1PointTol[e[0]]*n;
132  end[i] = pEnd + 0.5*surf1PointTol[e[1]]*n;
133 
134  edgeDirs[i] = n;
135  }
136 
137  List<List<pointIndexHit>> edgeIntersections;
138  querySurf2.findLineAll
139  (
140  start,
141  end,
142  edgeIntersections
143  );
144 
145  label nHits = 0;
146 
147  // Classify the hits
148  forAll(edgeLabels, i)
149  {
150  const label edgeI = edgeLabels[i];
151 
152  labelList& intersectionTypes = classification_[edgeI];
153  intersectionTypes.setSize(edgeIntersections[i].size(), -1);
154 
155  this->operator[](edgeI).transfer(edgeIntersections[i]);
156 
157  forAll(intersectionTypes, hitI)
158  {
159  const pointIndexHit& pHit = this->operator[](edgeI)[hitI];
160  label& hitType = intersectionTypes[hitI];
161 
162  if (!pHit.hit())
163  {
164  continue;
165  }
166 
167  const edge& e = surf1.edges()[edgeI];
168 
169  // Classify point on surface1 edge.
170  if (mag(pHit.hitPoint() - start[i]) < surf1PointTol[e[0]])
171  {
172  // Intersection is close to edge start
173  hitType = 0;
174  }
175  else if (mag(pHit.hitPoint() - end[i]) < surf1PointTol[e[1]])
176  {
177  // Intersection is close to edge end
178  hitType = 1;
179  }
180  else if (mag(edgeDirs[i] & normals2[pHit.index()]) < alignedCos_)
181  {
182  // Edge is almost coplanar with the face
183 
184  Pout<< "Flat angle edge:" << edgeI
185  << " face:" << pHit.index()
186  << " cos:" << mag(edgeDirs[i] & normals2[pHit.index()])
187  << endl;
188 
189  hitType = 2;
190  }
191 
192  if (debug)
193  {
194  Info<< " hit " << pHit << " classify = " << hitType << endl;
195  }
196 
197  nHits++;
198  }
199  }
200 
201  if (debug)
202  {
203  Pout<< "Found " << nHits << " intersections of edges with surface ..."
204  << endl;
205  }
206 }
207 
208 
209 // If edgeI intersections are close to endpoint of edge shift endpoints
210 // slightly along edge
211 // Updates
212 // - points1 with new endpoint position
213 // - affectedEdges with all edges affected by moving the point
214 // Returns true if changed anything.
215 bool Foam::edgeIntersections::inlinePerturb
216 (
217  const triSurface& surf1,
218  const scalarField& surf1PointTol, // surf1 tolerance per point
219  const label edgeI,
220  Random& rndGen,
221  pointField& points1,
222  boolList& affectedEdges
223 ) const
224 {
225  bool hasPerturbed = false;
226 
227  // Check if edge close to endpoint. Note that we only have to check
228  // the intersection closest to the edge endpoints (i.e. first and last in
229  // edgeEdgs)
230 
231  const labelList& edgeEnds = classification_[edgeI];
232 
233  if (edgeEnds.size())
234  {
235  bool perturbStart = false;
236  bool perturbEnd = false;
237 
238  // Check first intersection.
239  if (edgeEnds.first() == 0)
240  {
241  perturbStart = true;
242  }
243 
244  if (edgeEnds.last() == 1)
245  {
246  perturbEnd = true;
247  }
248 
249 
250  if (perturbStart || perturbEnd)
251  {
252  const edge& e = surf1.edges()[edgeI];
253 
254  label v0 = surf1.meshPoints()[e[0]];
255  label v1 = surf1.meshPoints()[e[1]];
256 
257  const vector n = normalised(points1[v1] - points1[v0]);
258 
259  if (perturbStart)
260  {
261  // Perturb with something (hopefully) larger than tolerance.
262  scalar t = 4.0*(rndGen.sample01<scalar>() - 0.5);
263  points1[v0] += t*surf1PointTol[e[0]]*n;
264 
265  const labelList& pEdges = surf1.pointEdges()[e[0]];
266 
267  forAll(pEdges, i)
268  {
269  affectedEdges[pEdges[i]] = true;
270  }
271  }
272  if (perturbEnd)
273  {
274  // Perturb with something larger than tolerance.
275  scalar t = 4.0*(rndGen.sample01<scalar>() - 0.5);
276  points1[v1] += t*surf1PointTol[e[1]]*n;
277 
278  const labelList& pEdges = surf1.pointEdges()[e[1]];
279 
280  forAll(pEdges, i)
281  {
282  affectedEdges[pEdges[i]] = true;
283  }
284  }
285  hasPerturbed = true;
286  }
287  }
288 
289  return hasPerturbed;
290 }
291 
292 
293 // Perturb single edge endpoint when perpendicular to face
294 bool Foam::edgeIntersections::rotatePerturb
295 (
296  const triSurface& surf1,
297  const scalarField& surf1PointTol, // surf1 tolerance per point
298  const label edgeI,
299 
300  Random& rndGen,
301  pointField& points1,
302  boolList& affectedEdges
303 ) const
304 {
305  const labelList& meshPoints = surf1.meshPoints();
306 
307  const labelList& edgeEnds = classification_[edgeI];
308 
309  bool hasPerturbed = false;
310 
311  forAll(edgeEnds, i)
312  {
313  if (edgeEnds[i] == 2)
314  {
315  const edge& e = surf1.edges()[edgeI];
316 
317  // Endpoint to modify. Choose either start or end.
318  label pointi = e[rndGen.bit()];
319  //label pointi = e[0];
320 
321  // Generate random vector slightly larger than tolerance.
322  vector rndVec = rndGen.sample01<vector>() - vector(0.5, 0.5, 0.5);
323 
324  // Make sure rndVec only perp to edge
325  vector n(points1[meshPoints[e[1]]] - points1[meshPoints[e[0]]]);
326  scalar magN = mag(n) + VSMALL;
327  n /= magN;
328 
329  rndVec -= n*(n & rndVec);
330  rndVec.normalise();
331 
332  // Scale to be moved by tolerance.
333  rndVec *= 0.01*magN;
334 
335  Pout<< "rotating: shifting endpoint " << meshPoints[pointi]
336  << " of edge:" << edgeI << " verts:"
337  << points1[meshPoints[e[0]]] << ' '
338  << points1[meshPoints[e[1]]]
339  << " by " << rndVec
340  << " tol:" << surf1PointTol[pointi] << endl;
341 
342  points1[meshPoints[pointi]] += rndVec;
343 
344  // Mark edges affected by change to point
345  const labelList& pEdges = surf1.pointEdges()[pointi];
346 
347  forAll(pEdges, i)
348  {
349  affectedEdges[pEdges[i]] = true;
350  }
351 
352  hasPerturbed = true;
353 
354  // Enough done for current edge; no need to test other intersections
355  // of this edge.
356  break;
357  }
358  }
359 
360  return hasPerturbed;
361 }
362 
363 
364 // Perturb edge when close to face
365 bool Foam::edgeIntersections::offsetPerturb
366 (
367  const triSurface& surf1,
368  const triSurface& surf2,
369  const label edgeI,
370 
371  Random& rndGen,
372  pointField& points1,
373  boolList& affectedEdges
374 ) const
375 {
376  const labelList& meshPoints = surf1.meshPoints();
377 
378  const edge& e = surf1.edges()[edgeI];
379 
380  const List<pointIndexHit>& hits = operator[](edgeI);
381 
382 
383  bool hasPerturbed = false;
384 
385  // For all hits on edge
386  forAll(hits, i)
387  {
388  const pointIndexHit& pHit = hits[i];
389 
390  // Classify point on face of surface2
391  label surf2Facei = pHit.index();
392 
393  const triSurface::FaceType& f2 = surf2.localFaces()[surf2Facei];
394  const pointField& surf2Pts = surf2.localPoints();
395 
396  const point ctr = f2.centre(surf2Pts);
397 
398  label nearType, nearLabel;
399 
400  f2.nearestPointClassify(pHit.hitPoint(), surf2Pts, nearType, nearLabel);
401 
402  if (nearType == triPointRef::POINT || nearType == triPointRef::EDGE)
403  {
404  // Shift edge towards tri centre
405  vector offset =
406  0.01*rndGen.sample01<scalar>()*(ctr - pHit.hitPoint());
407 
408  // shift e[0]
409  points1[meshPoints[e[0]]] += offset;
410 
411  // Mark edges affected by change to e0
412  const labelList& pEdges0 = surf1.pointEdges()[e[0]];
413 
414  forAll(pEdges0, i)
415  {
416  affectedEdges[pEdges0[i]] = true;
417  }
418 
419  // shift e[1]
420  points1[meshPoints[e[1]]] += offset;
421 
422  // Mark edges affected by change to e1
423  const labelList& pEdges1 = surf1.pointEdges()[e[1]];
424 
425  forAll(pEdges1, i)
426  {
427  affectedEdges[pEdges1[i]] = true;
428  }
429 
430  hasPerturbed = true;
431 
432  // No need to test any other hits on this edge
433  break;
434  }
435  }
436 
437  return hasPerturbed;
438 }
439 
440 
441 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
442 
443 // Construct null
445 :
446  List<List<pointIndexHit>>(),
447  classification_()
448 {}
449 
450 
452 (
453  const triSurface& surf1,
454  const triSurfaceSearch& query2,
455  const scalarField& surf1PointTol
456 )
457 :
459  classification_(surf1.nEdges())
460 {
461  checkEdges(surf1);
462 
463  // Current set of edges to test
464  labelList edgesToTest(identity(surf1.nEdges()));
465 
466  // Determine intersections for edgesToTest
467  intersectEdges
468  (
469  surf1,
470  surf1.points(), // surf1 meshPoints (not localPoints!)
471  query2,
472  surf1PointTol,
473  edgesToTest
474  );
475 }
476 
477 
478 // Construct from components
480 (
481  const List<List<pointIndexHit>>& intersections,
482  const labelListList& classification
483 )
484 :
485  List<List<pointIndexHit>>(intersections),
486  classification_(classification)
487 {}
488 
489 
490 // * * * * * * * * * * * * * * * Static Functions * * * * * * * * * * * * * //
491 
493 {
494  const pointField& localPoints = surf.localPoints();
495  const labelListList& pointEdges = surf.pointEdges();
496  const edgeList& edges = surf.edges();
497 
498  scalarField minLen(localPoints.size());
499 
500  forAll(minLen, pointi)
501  {
502  const labelList& pEdges = pointEdges[pointi];
503 
504  scalar minDist = GREAT;
505 
506  forAll(pEdges, i)
507  {
508  minDist = min(minDist, edges[pEdges[i]].mag(localPoints));
509  }
510 
511  minLen[pointi] = minDist;
512  }
513  return minLen;
514 }
515 
516 
517 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
518 
520 (
521  const label nIters,
522  const triSurface& surf1,
523  const triSurfaceSearch& query2,
524  const scalarField& surf1PointTol,
525  pointField& points1
526 )
527 {
528  const triSurface& surf2 = query2.surface();
529 
530  Random rndGen(356574);
531 
532  // Current set of edges to (re)test
533  labelList edgesToTest(surf1.nEdges());
534 
535  // Start off with all edges
536  forAll(edgesToTest, i)
537  {
538  edgesToTest[i] = i;
539  }
540 
541 
542  label iter = 0;
543 
544  for (; iter < nIters; iter++)
545  {
546  // Go through all edges to (re)test and perturb points if they are
547  // degenerate hits. Mark off edges that need to be recalculated.
548 
549  boolList affectedEdges(surf1.nEdges(), false);
550  label nShifted = 0;
551  label nRotated = 0;
552  label nOffset = 0;
553 
554  forAll(edgesToTest, i)
555  {
556  label edgeI = edgesToTest[i];
557 
558  // If edge not already marked for retesting
559  if (!affectedEdges[edgeI])
560  {
561  // 1. Check edges close to endpoint and perturb if necessary.
562 
563  bool shiftedEdgeEndPoints =
564  inlinePerturb
565  (
566  surf1,
567  surf1PointTol,
568  edgeI,
569  rndGen,
570  points1,
571  affectedEdges
572  );
573 
574  nShifted += (shiftedEdgeEndPoints ? 1 : 0);
575 
576  if (!shiftedEdgeEndPoints)
577  {
578  bool rotatedEdge =
579  rotatePerturb
580  (
581  surf1,
582  surf1PointTol,
583  edgeI,
584  rndGen,
585  points1,
586  affectedEdges
587  );
588 
589  nRotated += (rotatedEdge ? 1 : 0);
590 
591  if (!rotatedEdge)
592  {
593  // 2. we're sure now that the edge actually pierces the
594  // face. Now check the face for intersections close its
595  // points/edges
596 
597  bool offsetEdgePoints =
598  offsetPerturb
599  (
600  surf1,
601  surf2,
602  edgeI,
603  rndGen,
604  points1,
605  affectedEdges
606  );
607 
608  nOffset += (offsetEdgePoints ? 1 : 0);
609  }
610  }
611  }
612  }
613 
614  if (debug)
615  {
616  Pout<< "Edges to test : " << nl
617  << " total:" << edgesToTest.size() << nl
618  << " resolved by:" << nl
619  << " shifting : " << nShifted << nl
620  << " rotating : " << nRotated << nl
621  << " offsetting : " << nOffset << nl
622  << endl;
623  }
624 
625 
626  if (nShifted == 0 && nRotated == 0 && nOffset == 0)
627  {
628  // Nothing changed in current iteration. Current hit pattern is
629  // without any degenerates.
630  break;
631  }
632 
633  // Repack affected edges
634  labelList newEdgesToTest(surf1.nEdges());
635  label newEdgeI = 0;
636 
637  forAll(affectedEdges, edgeI)
638  {
639  if (affectedEdges[edgeI])
640  {
641  newEdgesToTest[newEdgeI++] = edgeI;
642  }
643  }
644  newEdgesToTest.setSize(newEdgeI);
645 
646  if (debug)
647  {
648  Pout<< "Edges to test:" << nl
649  << " was : " << edgesToTest.size() << nl
650  << " is : " << newEdgesToTest.size() << nl
651  << endl;
652  }
653 
654  // Transfer and test.
655  edgesToTest.transfer(newEdgesToTest);
656 
657  if (edgesToTest.empty())
658  {
659  FatalErrorInFunction << "oops" << abort(FatalError);
660  }
661 
662  // Re intersect moved edges.
663  intersectEdges
664  (
665  surf1,
666  points1, // surf1 meshPoints (not localPoints!)
667  query2,
668  surf1PointTol,
669  edgesToTest
670  );
671  }
672 
673  return iter;
674 }
675 
676 
678 (
679  const edgeIntersections& subInfo,
680  const labelList& edgeMap,
681  const labelList& faceMap,
682  const bool merge
683 )
684 {
685  forAll(subInfo, subI)
686  {
687  const List<pointIndexHit>& subHits = subInfo[subI];
688  const labelList& subClass = subInfo.classification()[subI];
689 
690  label edgeI = edgeMap[subI];
691  List<pointIndexHit>& intersections = operator[](edgeI);
692  labelList& intersectionTypes = classification_[edgeI];
693 
694  // Count unique hits. Assume edge can hit face only once
695  label sz = 0;
696  if (merge)
697  {
698  sz = intersections.size();
699  }
700 
701  label nNew = 0;
702  forAll(subHits, i)
703  {
704  const pointIndexHit& subHit = subHits[i];
705 
706  bool foundFace = false;
707  for (label interI = 0; interI < sz; interI++)
708  {
709  if (intersections[interI].index() == faceMap[subHit.index()])
710  {
711  foundFace = true;
712  break;
713  }
714  }
715  if (!foundFace)
716  {
717  nNew++;
718  }
719  }
720 
721 
722  intersections.setSize(sz+nNew);
723  intersectionTypes.setSize(sz+nNew);
724  nNew = sz;
725 
726  forAll(subHits, i)
727  {
728  const pointIndexHit& subHit = subHits[i];
729 
730  bool foundFace = false;
731  for (label interI = 0; interI < sz; interI++)
732  {
733  if (intersections[interI].index() == faceMap[subHit.index()])
734  {
735  foundFace = true;
736  break;
737  }
738  }
739 
740  if (!foundFace)
741  {
742  intersections[nNew] = pointIndexHit
743  (
744  subHit.hit(),
745  subHit.rawPoint(),
746  faceMap[subHit.index()]
747  );
748  intersectionTypes[nNew] = subClass[i];
749  nNew++;
750  }
751  }
752  }
753 }
754 
755 
756 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:74
Foam::pointField
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:44
Foam::edgeIntersections::classification
const labelListList & classification() const
For every intersection the classification status.
Definition: edgeIntersections.H:180
Foam::Random
Random number generator.
Definition: Random.H:59
Foam::scalarField
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Definition: primitiveFieldsFwd.H:52
meshTools.H
Foam::PointIndexHit::index
label index() const
Return index.
Definition: PointIndexHit.H:113
pointIndexHit.H
Foam::faceMap
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
Definition: blockMeshMergeFast.C:94
Foam::PrimitivePatch::points
const Field< PointType > & points() const
Return reference to global points.
Definition: PrimitivePatch.H:300
Foam::edgeList
List< edge > edgeList
A List of edges.
Definition: edgeList.H:63
edgeIntersections.H
Foam::PrimitivePatch::edges
const edgeList & edges() const
Return list of edges, address into LOCAL point list.
Definition: PrimitivePatch.C:238
Foam::PrimitivePatch::localPoints
const Field< PointType > & localPoints() const
Return pointField of points in patch.
Definition: PrimitivePatch.C:458
Foam::Random::sample01
Type sample01()
Return a sample whose components lie in the range [0,1].
Definition: RandomTemplates.C:36
Foam::PrimitivePatch::nEdges
label nEdges() const
Return number of edges in patch.
Definition: PrimitivePatch.H:317
indexedOctree.H
Foam::PointIndexHit::hit
bool hit() const
Is there a hit.
Definition: PointIndexHit.H:107
unitConversion.H
Unit conversion functions.
Foam::boolList
List< bool > boolList
A List of bools.
Definition: List.H:72
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:337
Foam::Pout
prefixOSstream Pout
An Ostream wrapper for parallel output to std::cout.
triSurface.H
Foam::triSurfaceSearch
Helper class to search on triSurface.
Definition: triSurfaceSearch.H:58
Foam::min
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
Foam::edgeIntersections::alignedCos_
static scalar alignedCos_
Cosine between edge and face normal when considered parallel.
Definition: edgeIntersections.H:144
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:290
OFstream.H
Foam::vectorField
Field< vector > vectorField
Specialisation of Field<T> for vector.
Definition: primitiveFieldsFwd.H:54
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::edgeIntersections::removeDegenerates
label removeDegenerates(const label nIters, const triSurface &surf1, const triSurfaceSearch &query2, const scalarField &surf1PointTol, pointField &points1)
Resolve ties. Shuffles points so all edge - face intersections.
Definition: edgeIntersections.C:520
Foam::PointIndexHit
This class describes the interaction of (usually) a face and a point. It carries the info of a succes...
Definition: PointIndexHit.H:55
Foam::PointIndexHit::rawPoint
const Point & rawPoint() const
Return point with no checking.
Definition: PointIndexHit.H:145
Foam::label
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:62
Foam::Field< scalar >
plane.H
Foam::triSurface
Triangulated surface description with patch information.
Definition: triSurface.H:70
treeBoundBox.H
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
Foam::PrimitivePatch::pointEdges
const labelListList & pointEdges() const
Return point-edge addressing.
Definition: PrimitivePatch.C:358
Foam::Vector::centre
const Vector< Cmpt > & centre(const Foam::List< Vector< Cmpt >> &) const
Return *this (used for point which is a typedef to Vector<scalar>.
Definition: VectorI.H:119
Foam::edgeIntersections::minEdgeLength
static scalarField minEdgeLength(const triSurface &surf)
Calculate min edge length for every surface point.
Definition: edgeIntersections.C:492
Foam::PrimitivePatch< labelledTri, ::Foam::List, pointField, point >::FaceType
labelledTri FaceType
Definition: PrimitivePatch.H:100
Foam::FatalError
error FatalError
stdFoam::end
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
Definition: stdFoam.H:115
Foam::triangle::POINT
Definition: triangle.H:100
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:137
Foam::vector
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:51
Foam::degToRad
constexpr scalar degToRad(const scalar deg) noexcept
Conversion from degrees to radians.
Definition: unitConversion.H:48
Random.H
treeDataTriSurface.H
Foam::normalised
VectorSpace< Form, Cmpt, Ncmpts > normalised(const VectorSpace< Form, Cmpt, Ncmpts > &vs)
Definition: VectorSpaceI.H:496
Foam::edgeIntersections::edgeIntersections
edgeIntersections()
Construct null.
Definition: edgeIntersections.C:444
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:355
Foam::pointIndexHit
PointIndexHit< point > pointIndexHit
Definition: pointIndexHit.H:45
Foam::triangle::EDGE
Definition: triangle.H:101
Foam::nl
constexpr char nl
Definition: Ostream.H:372
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:102
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Foam::start
label ListType::const_reference const label start
Definition: ListOps.H:408
Foam::triSurfaceSearch::surface
const triSurface & surface() const
Return reference to the surface.
Definition: triSurfaceSearch.H:129
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
Foam::identity
labelList identity(const label len, label start=0)
Create identity map of the given length with (map[i] == i)
Definition: labelList.C:38
triSurfaceSearch.H
rndGen
Random rndGen
Definition: createFields.H:23
Foam::edgeIntersections::merge
void merge(const edgeIntersections &, const labelList &edgeMap, const labelList &faceMap, const bool merge=true)
Merge (or override) edge intersection for a subset.
Definition: edgeIntersections.C:678
Foam::edgeIntersections
Holder of intersections of edges of a surface with another surface. Optionally shuffles around points...
Definition: edgeIntersections.H:62
Foam::point
vector point
Point is a vector.
Definition: point.H:43
Foam::List::setSize
void setSize(const label newSize)
Alias for resize(const label)
Definition: ListI.H:146
Foam::Random::bit
int bit()
Return a random bit.
Definition: RandomI.H:38
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:294
Foam::cos
dimensionedScalar cos(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:265