FacePatchIntersection.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) 2023-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 "FacePatchIntersection.H"
27 #include "cpuTime.H"
28 #include "primitiveTriPatch.H"
29 #include "polygonTriangulate.H"
30 #include "TriPatchIntersection.H"
31 #include "vtkWritePolyData.H"
32 
33 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
34 
35 namespace Foam
36 {
37 
38 template<class T, class ListType>
39 void inplaceRemove(ListType& lst, const T& value)
40 {
41  if (lst.size())
42  {
43  inplaceRemove(lst, value, lst[0]);
44  }
45 }
46 
47 template<class T, class NotT, class ListType>
48 void inplaceRemove(ListType& lst, const T& value, const NotT&)
49 {
50  forAll(lst, i)
51  {
52  if (lst[i].size())
53  {
54  inplaceRemove(lst[i], value, lst[i][0]);
55  }
56  }
57 }
58 
59 template<class T, class ListType>
60 void inplaceRemove(ListType& lst, const T& value, const T&)
61 {
62  label iNew = 0;
63  forAll(lst, iOld)
64  {
65  if (lst[iOld] != value)
66  {
67  lst[iNew] = lst[iOld];
68  ++ iNew;
69  }
70  }
71  lst.resize(iNew);
72 }
73 
74 template<class ListType>
75 ListType reorder
76 (
77  const label size,
78  const typename ListType::value_type& defaultValue,
79  const labelUList& oldToNew,
80  const ListType& lst
81 )
82 {
83  ListType newLst(size, defaultValue);
84 
85  forAll(lst, elemI)
86  {
87  if (oldToNew[elemI] >= 0)
88  {
89  newLst[oldToNew[elemI]] = lst[elemI];
90  }
91  }
92 
93  return newLst;
94 }
95 
96 }
97 
98 
99 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
100 
101 template<class SrcPatchType, class TgtPatchType>
103 (
104  const SrcPatchType& srcPatch,
105  const TgtPatchType& tgtPatch,
106  const scalar snapTol
107 )
108 :
109  FacePatchIntersection(srcPatch, srcPatch.pointNormals(), tgtPatch, snapTol)
110 {}
111 
112 
113 template<class SrcPatchType, class TgtPatchType>
115 (
116  const SrcPatchType& srcPatch,
117  const vectorField& srcPointNormals,
118  const TgtPatchType& tgtPatch,
119  const scalar snapTol
120 )
121 :
122  PatchIntersection<SrcPatchType, TgtPatchType>(srcPatch, tgtPatch)
123 {
124  cpuTime time;
125 
126  Info<< type() << ": Intersecting "
127  << this->srcPatch_.size() << " source faces and "
128  << this->tgtPatch_.size() << " target faces" << incrIndent << endl;
129 
130  if (this->debug)
131  {
132  Info<< indent << "Writing patches" << incrIndent << endl;
133  const fileName srcFileName = type() + "_srcPatch.vtk";
134  Info<< indent << "Writing patch to " << srcFileName << endl;
136  (
137  srcFileName,
138  "source",
139  false,
140  this->srcPatch_.localPoints(),
141  labelList(),
142  labelListList(),
143  this->srcPatch_.localFaces(),
144  "normals",
145  true,
146  srcPointNormals
147  );
148  const fileName tgtFileName = type() + "_tgtPatch.vtk";
149  Info<< indent << "Writing patch to " << tgtFileName << endl;
151  (
152  tgtFileName,
153  "target",
154  false,
155  this->tgtPatch_.localPoints(),
156  labelList(),
157  labelListList(),
158  this->tgtPatch_.localFaces()
159  );
160  Info<< decrIndent;
161  }
162 
163  // Step 1: Triangulate the source and target patches and create addressing
164  DynamicList<triFace> srcTris, tgtTris;
165  DynamicList<label> srcTriSrcFaces, tgtTriTgtFaces;
166  DynamicList<FixedList<label, 3>> srcTriSrcEdges, tgtTriTgtEdges;
167  polygonTriangulate triEngine;
168  forAll(this->srcPatch_, srcFacei)
169  {
170  const face& srcFacePoints = this->srcPatch_[srcFacei];
171  const labelList& srcFaceEdges = this->srcPatch_.faceEdges()[srcFacei];
172  triEngine.triangulate
173  (
174  UIndirectList<point>(this->srcPatch_.points(), srcFacePoints)
175  );
176  srcTris.append(triEngine.triPoints(srcFacePoints));
177  srcTriSrcFaces.resize(srcTris.size(), srcFacei);
178  srcTriSrcEdges.append(triEngine.triEdges(srcFaceEdges));
179  }
180  forAll(this->tgtPatch_, tgtFacei)
181  {
182  const face tgtFacePoints = this->tgtPatch_[tgtFacei].reverseFace();
183  const labelList tgtFaceEdges =
184  reverseList(this->tgtPatch_.faceEdges()[tgtFacei]);
185  triEngine.triangulate
186  (
187  UIndirectList<point>(this->tgtPatch_.points(), tgtFacePoints)
188  );
189  tgtTris.append(triEngine.triPoints(tgtFacePoints));
190  tgtTriTgtFaces.resize(tgtTris.size(), tgtFacei);
191  tgtTriTgtEdges.append(triEngine.triEdges(tgtFaceEdges));
192  const label n = triEngine.triPoints().size();
193  for (label i = 0; i < n; ++ i)
194  {
195  tgtTris[tgtTris.size() - n + i] =
196  tgtTris[tgtTris.size() - n + i].reverseFace();
197  tgtTriTgtEdges[tgtTris.size() - n + i] =
198  reverseList(tgtTriTgtEdges[tgtTris.size() - n + i]);
199  }
200  }
201  const primitiveTriPatch srcTriPatch
202  (
203  SubList<triFace>(srcTris, srcTris.size()),
204  this->srcPatch_.points()
205  );
206  const primitiveTriPatch tgtTriPatch
207  (
208  SubList<triFace>(tgtTris, tgtTris.size()),
209  this->tgtPatch_.points()
210  );
211 
212  labelList srcTriPatchPointSrcPatchPoints(srcTriPatch.nPoints());
213  labelList tgtTriPatchPointTgtPatchPoints(tgtTriPatch.nPoints());
214  {
215  labelList map
216  (
217  max(max(srcPatch.meshPoints()), max(tgtPatch.meshPoints())) + 1,
218  -1
219  );
220 
221  UIndirectList<label>(map, srcPatch.meshPoints()) =
222  identityMap(srcPatch.nPoints());
223 
224  srcTriPatchPointSrcPatchPoints =
225  renumber(map, srcTriPatch.meshPoints());
226 
227  UIndirectList<label>(map, srcPatch.meshPoints()) = -1;
228 
229  UIndirectList<label>(map, tgtPatch.meshPoints()) =
230  identityMap(tgtPatch.nPoints());
231 
232  tgtTriPatchPointTgtPatchPoints =
233  renumber(map, tgtTriPatch.meshPoints());
234 
235  UIndirectList<label>(map, tgtPatch.meshPoints()) = -1;
236  }
237 
238  labelList srcTriPatchEdgeSrcPatchEdges(srcTriPatch.nEdges());
239  labelList tgtTriPatchEdgeTgtPatchEdges(tgtTriPatch.nEdges());
240  forAll(srcTriPatch, srcTrii)
241  {
242  forAll(srcTriPatch[srcTrii], srcTriEdgei)
243  {
244  const label srcTriPatchEdgei =
245  srcTriPatch.faceEdges()[srcTrii][srcTriEdgei];
246  const label srcPatchEdgei = srcTriSrcEdges[srcTrii][srcTriEdgei];
247  srcTriPatchEdgeSrcPatchEdges[srcTriPatchEdgei] = srcPatchEdgei;
248  }
249  }
250  forAll(tgtTriPatch, tgtTrii)
251  {
252  forAll(tgtTriPatch[tgtTrii], tgtTriEdgei)
253  {
254  const label tgtTriPatchEdgei =
255  tgtTriPatch.faceEdges()[tgtTrii][tgtTriEdgei];
256  const label tgtPatchEdgei = tgtTriTgtEdges[tgtTrii][tgtTriEdgei];
257  tgtTriPatchEdgeTgtPatchEdges[tgtTriPatchEdgei] = tgtPatchEdgei;
258  }
259  }
260 
261  // Step 2: Do the tri-patch intersection
263  (
264  srcTriPatch,
265  vectorField(srcPointNormals, srcTriPatchPointSrcPatchPoints),
266  tgtTriPatch,
267  snapTol
268  );
269 
270  // Step 3: Map points and point associations back into the class data
271  {
272  this->points_ = tpi.points();
273 
274  // Point-point connectivity
275  this->srcPointPoints_ =
276  reorder
277  (
278  this->srcPatch().nPoints(),
279  -1,
280  srcTriPatchPointSrcPatchPoints,
281  tpi.srcPointPoints()
282  );
283  this->tgtPointPoints_ =
284  reorder
285  (
286  this->tgtPatch().nPoints(),
287  -1,
288  tgtTriPatchPointTgtPatchPoints,
289  tpi.tgtPointPoints()
290  );
291  this->pointSrcPoints_ = tpi.pointSrcPoints();
292  inplaceRenumber(srcTriPatchPointSrcPatchPoints, this->pointSrcPoints_);
293  this->pointTgtPoints_ = tpi.pointTgtPoints();
294  inplaceRenumber(tgtTriPatchPointTgtPatchPoints, this->pointTgtPoints_);
295 
296  // Point-edge connectivity
297  this->srcEdgePoints_ =
298  reorder
299  (
300  this->srcPatch_.nEdges(),
302  srcTriPatchEdgeSrcPatchEdges,
303  tpi.srcEdgePoints()
304  );
305  this->srcEdgePoints_.resize(this->srcPatch_.nEdges());
306  this->tgtEdgePoints_ =
307  reorder
308  (
309  this->tgtPatch_.nEdges(),
311  tgtTriPatchEdgeTgtPatchEdges,
312  tpi.tgtEdgePoints()
313  );
314  this->tgtEdgePoints_.resize(this->tgtPatch_.nEdges());
315  this->pointSrcEdges_ = tpi.pointSrcEdges();
316  inplaceRenumber(srcTriPatchEdgeSrcPatchEdges, this->pointSrcEdges_);
317  this->pointTgtEdges_ = tpi.pointTgtEdges();
318  inplaceRenumber(tgtTriPatchEdgeTgtPatchEdges, this->pointTgtEdges_);
319 
320  // Point-tri connectivity
321  this->pointSrcFaces_ = tpi.pointSrcFaces();
322  inplaceRenumber(srcTriSrcFaces, this->pointSrcFaces_);
323  this->pointTgtFaces_ = tpi.pointTgtFaces();
324  inplaceRenumber(tgtTriTgtFaces, this->pointTgtFaces_);
325 
326  // Point-face-diagonal connectivity
327  auto setFaceDiagonalPoints = []
328  (
329  const List<DynamicList<label>>& edgePoints,
330  const labelListList& edgeTris,
331  const labelUList& triFaces,
332  DynamicList<label>& pointFaces
333  )
334  {
335  forAll(edgePoints, edgei)
336  {
337  const labelList& triis = edgeTris[edgei];
338 
339  if (triis.size() != 2)
340  {
341  continue;
342  }
343 
344  const label facei0 = triFaces[triis[0]];
345  const label facei1 = triFaces[triis[1]];
346 
347  if (facei0 != facei1)
348  {
349  continue;
350  }
351 
352  const label facei = facei0;
353 
354  for
355  (
356  label edgePointi = 1;
357  edgePointi < edgePoints[edgei].size() - 1;
358  ++ edgePointi
359  )
360  {
361  const label pointi = edgePoints[edgei][edgePointi];
362 
363  pointFaces[pointi] = facei;
364  }
365  }
366  };
367  setFaceDiagonalPoints
368  (
369  tpi.srcEdgePoints(),
370  srcTriPatch.edgeFaces(),
371  srcTriSrcFaces,
372  this->pointSrcFaces_
373  );
374  setFaceDiagonalPoints
375  (
376  tpi.tgtEdgePoints(),
377  tgtTriPatch.edgeFaces(),
378  tgtTriTgtFaces,
379  this->pointTgtFaces_
380  );
381  }
382 
383  // Step 4: Construct faces and face associations by merging the faces that
384  // result from the tri-patch intersection
385  {
386  // Loop the tri intersection faces, initialising a star at each one,
387  // and propagating out to include everything connected with the same
388  // source and target face. This is then part of the face intersection.
389  boolList tpiFaceCombined(tpi.faces().size(), false);
390  star tpiStar;
391  forAll(tpi.faces(), tpiFacei)
392  {
393  // If this face has been done then skip to the next
394  if (tpiFaceCombined[tpiFacei]) continue;
395 
396  // Get the source and target faces
397  const label srcFacei =
398  tpi.faceSrcFaces()[tpiFacei] != -1
399  ? srcTriSrcFaces[tpi.faceSrcFaces()[tpiFacei]]
400  : -1;
401  const label tgtFacei =
402  tpi.faceTgtFaces()[tpiFacei] != -1
403  ? tgtTriTgtFaces[tpi.faceTgtFaces()[tpiFacei]]
404  : -1;
405 
406  // Get the relevant set of face-edge and edge-face addressing
407  const UList<labelList>& tpiFaceEdges = tpi.faceEdges();
408  const UList<labelPair>& tpiEdgeFaces =
409  srcFacei != -1 && tgtFacei != -1
410  ? tpi.intersectEdgeFaces()
411  : tpi.nonIntersectEdgeFaces();
412 
413  // Fill the star with all connected faces with the same source and
414  // target face associations
415  star::context tpiStarContext = tpiStar.populate
416  (
417  tpiFacei,
418  true,
419  [&](const label tpiEdgei, const label tpiFacei)
420  {
421  const label tpiSrcFacei = tpi.faceSrcFaces()[tpiFacei];
422  const label tpiTgtFacei = tpi.faceTgtFaces()[tpiFacei];
423  return
424  (
425  tpiSrcFacei != -1
426  ? srcTriSrcFaces[tpiSrcFacei] == srcFacei
427  : srcFacei == -1
428  )
429  && (
430  tpiTgtFacei != -1
431  ? tgtTriTgtFaces[tpiTgtFacei] == tgtFacei
432  : tgtFacei == -1
433  );
434  },
435  tpiFaceEdges,
436  tpiEdgeFaces
437  );
438 
439  // Mark everything that has been visited
440  forAllStarFaces(tpiStar, starFacei, tpiFacei)
441  {
442  tpiFaceCombined[tpiFacei] = true;
443  }
444 
445  // Create the new face
446  const label facei = this->faces_.size();
447  this->faces_.append(face(tpiStar.starEdgeEdges().size()));
448  if (srcFacei != -1)
449  {
450  this->srcFaceFaces_[srcFacei].append(facei);
451  }
452  if (tgtFacei != -1)
453  {
454  this->tgtFaceFaces_[tgtFacei].append(facei);
455  }
456  this->faceSrcFaces_.append(srcFacei);
457  this->faceTgtFaces_.append(tgtFacei);
458  forAllStarEdges(tpiStar, i, starEdgei, tpiEdgei)
459  {
460  const label tpiEdgeFacei =
461  tpiEdgeFaces[tpiEdgei][0] == -1
462  || tpiStar.faceStarFaces()[tpiEdgeFaces[tpiEdgei][0]] == -1;
463 
464  const label tpiFacei = tpiEdgeFaces[tpiEdgei][tpiEdgeFacei];
465  const label tpiFaceEdgei =
466  findIndex(tpiFaceEdges[tpiFacei], tpiEdgei);
467 
468  this->faces_.last()[i] =
469  tpi.faces()[tpiFacei].faceEdge(tpiFaceEdgei).start();
470  }
471  }
472  }
473 
474  // Step 5: Filter out points that aren't used
475  {
476  // Determine how many faces each point is a part of
477  labelList pointNFaces(this->points_.size(), 0);
478  forAll(this->faces_, facei)
479  {
480  const face& f = this->faces_[facei];
481  forAll(f, fPointi)
482  {
483  ++ pointNFaces[f[fPointi]];
484  }
485  }
486 
487  // Remove points that are referenced by two faces or fewer, and which
488  // do not correspond to original geometry or an intersection
489  labelList oldPointNewPoints(this->points_.size(), -1);
490  label pointi = 0;
491  forAll(this->points_, pointj)
492  {
493  if
494  (
495  pointNFaces[pointj] > 2
496  || (
497  pointNFaces[pointj] > 0
498  && (
499  this->pointSrcPoints_[pointj] != -1
500  || this->pointTgtPoints_[pointj] != -1
501  || (
502  this->pointSrcEdges_[pointj] != -1
503  && this->pointTgtEdges_[pointj] != -1
504  )
505  )
506  )
507  )
508  {
509  oldPointNewPoints[pointj] = pointi;
510  this->points_[pointi] = this->points_[pointj];
511  this->pointSrcPoints_[pointi] = this->pointSrcPoints_[pointj];
512  this->pointTgtPoints_[pointi] = this->pointTgtPoints_[pointj];
513  this->pointSrcEdges_[pointi] = this->pointSrcEdges_[pointj];
514  this->pointTgtEdges_[pointi] = this->pointTgtEdges_[pointj];
515  this->pointSrcFaces_[pointi] = this->pointSrcFaces_[pointj];
516  this->pointTgtFaces_[pointi] = this->pointTgtFaces_[pointj];
517  ++ pointi;
518  }
519  }
520  this->points_.resize(pointi);
521  this->pointSrcPoints_.resize(pointi);
522  this->pointTgtPoints_.resize(pointi);
523  this->pointSrcEdges_.resize(pointi);
524  this->pointTgtEdges_.resize(pointi);
525  this->pointSrcFaces_.resize(pointi);
526  this->pointTgtFaces_.resize(pointi);
527 
528  // Map
529  inplaceRenumber(oldPointNewPoints, this->faces_);
530  inplaceRenumber(oldPointNewPoints, this->srcPointPoints_);
531  inplaceRenumber(oldPointNewPoints, this->tgtPointPoints_);
532  inplaceRenumber(oldPointNewPoints, this->srcEdgePoints_);
533  inplaceRenumber(oldPointNewPoints, this->tgtEdgePoints_);
534 
535  // Remove deleted points
536  inplaceRemove(this->faces_, label(-1));
537  inplaceRemove(this->srcEdgePoints_, label(-1));
538  inplaceRemove(this->tgtEdgePoints_, label(-1));
539  }
540 
541  // Step 6: Reporting
542  this->report();
543 
544  Info<< indent << this->faces_.size() << " couplings generated in "
545  << time.cpuTimeIncrement() << 's' << endl;
546 
547  Info<< decrIndent;
548 }
549 
550 
551 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
552 
553 template<class SrcPatchType, class TgtPatchType>
556 {}
557 
558 
559 // ************************************************************************* //
label n
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:78
void resize(const label)
Alter the addressed list size.
Definition: DynamicListI.H:216
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Definition: DynamicListI.H:296
Patch intersection based on polygonal faces. This triangulates the supplied patches and passes them t...
FacePatchIntersection(const SrcPatchType &srcPatch, const TgtPatchType &tgtPatch, const scalar snapTol)
Construct from a source and a target patch.
virtual ~FacePatchIntersection()
Destructor.
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
Base class for patch intersections. Provides storage and access to the intersection points and faces ...
const SrcPatchType & srcPatch() const
The source patch.
const SrcPatchType & srcPatch_
Reference to the source patch.
const TgtPatchType & tgtPatch() const
The target patch.
const TgtPatchType & tgtPatch_
Reference to the target patch.
A list of faces which address into the list of points.
label nEdges() const
Return number of edges in patch.
label nPoints() const
Return number of points supporting patch faces.
const labelList & meshPoints() const
Return labelList of mesh points in patch. They are constructed.
const labelListList & edgeFaces() const
Return edge-face addressing.
const labelListList & faceEdges() const
Return face-edge addressing.
A List obtained as a section of another List.
Definition: SubList.H:56
Patch intersection based on triangular faces. Intersects and combines two triangulated patches increm...
const DynamicList< labelPair > & intersectEdgeFaces() const
...
const DynamicList< labelList > & faceEdges() const
...
const DynamicList< labelPair > & nonIntersectEdgeFaces() const
...
A List with indirect addressing.
Definition: UIndirectList.H:60
Starts timing CPU usage and return elapsed time from start.
Definition: cpuTime.H:55
double cpuTimeIncrement() const
Return CPU time (in seconds) since last call to cpuTimeIncrement()
Definition: cpuTime.C:60
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:76
A class for handling file names.
Definition: fileName.H:82
const DynamicList< label > & pointSrcFaces() const
The intersection points' source faces, or -1 if the point.
DynamicList< label > pointTgtFaces_
The intersection points' target faces, or -1 if the point.
List< DynamicList< label > > tgtFaceFaces_
The target faces' intersection faces.
const DynamicList< label > & pointSrcPoints() const
The intersection points' corresponding source points, or -1.
const DynamicList< label > & faceSrcFaces() const
The intersection faces' corresponding source faces, or -1.
const List< DynamicList< label > > & tgtEdgePoints() const
The target edges' intersection points. Ordered along the edge.
DynamicField< point > points_
The intersection points.
const faceList & faces() const
The intersection faces.
DynamicList< label > pointTgtPoints_
The intersection points' corresponding target points, or -1.
List< DynamicList< label > > tgtEdgePoints_
The target edges' intersection points. Ordered along the edge.
void report(const word &writeSuffix=word::null)
Report properties of the intersection process.
DynamicList< label > pointSrcPoints_
The intersection points' corresponding source points, or -1.
const labelList & srcPointPoints() const
The source points' corresponding intersection points.
const DynamicList< label > & pointSrcEdges() const
The intersection points' source edges, or -1 if the point.
const DynamicList< label > & faceTgtFaces() const
The intersection faces' corresponding target faces, or -1.
const DynamicList< label > & pointTgtFaces() const
The intersection points' target faces, or -1 if the point.
List< DynamicList< label > > srcEdgePoints_
The source edges' intersection points. Ordered along the edge.
labelList srcPointPoints_
The source points' corresponding intersection points.
DynamicList< label > pointSrcFaces_
The intersection points' source faces, or -1 if the point.
DynamicList< label > pointSrcEdges_
The intersection points' source edges, or -1 if the point.
const DynamicList< label > & pointTgtEdges() const
The intersection points' target edges, or -1 if the point.
DynamicList< face > faces_
The intersection faces.
DynamicList< label > faceTgtFaces_
The intersection faces' corresponding target faces, or -1.
const labelList & tgtPointPoints() const
The target points' corresponding intersection points.
const pointField & points() const
The intersection points.
const List< DynamicList< label > > & srcEdgePoints() const
The source edges' intersection points. Ordered along the edge.
const DynamicList< label > & pointTgtPoints() const
The intersection points' corresponding target points, or -1.
labelList tgtPointPoints_
The target points' corresponding intersection points.
List< DynamicList< label > > srcFaceFaces_
The source faces' intersection faces.
DynamicList< label > faceSrcFaces_
The intersection faces' corresponding source faces, or -1.
DynamicList< label > pointTgtEdges_
The intersection points' target edges, or -1 if the point.
Triangulation of three-dimensional polygons.
const UList< FixedList< label, 3 > > & triEdges() const
Get the triangles' edges.
const UList< triFace > & triPoints() const
Get the triangles' points.
Context class. Returned by populate and resets the star when it.
Definition: star.H:66
Engine for constructing a star-shaped domain by walking.
Definition: star.H:50
const DynamicList< edgeLink > & starEdgeEdges() const
Access the star-edge-edges.
Definition: star.H:157
const DynamicList< label > & faceStarFaces() const
Access the face-star-faces.
Definition: star.H:151
context populate(const label faceOrEdgei, const bool isFace, CanCross canCross, const UList< FaceEdges > &faceEdges, const UList< labelPair > &edgeFaces, const label maxIterations=labelMax)
Populate the star given a seed face or edge, a function.
label nPoints
void write(const fileName &file, const word &title, const bool binary, const PointField &points, const VertexList &vertices, const LineList &lines, const FaceList &faces, const wordList &fieldNames, const boolList &fieldIsPointValues, const UPtrList< const Field< label >> &fieldLabelValues #define FieldTypeValuesConstArg(Type, nullArg))
Write VTK polygonal data to a file. Takes a PtrList of fields of labels and.
Namespace for OpenFOAM.
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
Definition: Ostream.H:241
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
void inplaceRemove(ListType &lst, const T &value)
ListType reverseList(const ListType &list)
Reverse a list. First element becomes last element etc.
ListType renumber(const labelUList &oldToNew, const ListType &)
Renumber the values (not the indices) of a list.
messageStream Info
Ostream & incrIndent(Ostream &os)
Increment the indent level.
Definition: Ostream.H:234
ListType reorder(const label size, const typename ListType::value_type &defaultValue, const labelUList &oldToNew, const ListType &lst)
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:57
void inplaceRenumber(const labelUList &oldToNew, ListType &)
Inplace renumber the values of a list.
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
Field< vector > vectorField
Specialisation of Field<T> for vector.
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurrence of given element and return index,.
labelList identityMap(const label len)
Create identity map (map[i] == i) of given length.
Definition: ListOps.C:104
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:227
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
labelList f(nPoints)
#define forAllStarFaces(star, starFacei, facei)
Definition: star.H:219
#define forAllStarEdges(star, i, starEdgei, edgei)
Definition: star.H:240