triSurfaceStitch.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) 2022 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 "triSurface.H"
30 #include "mergePoints.H"
31 #include "bitSet.H"
32 
33 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
34 
35 bool Foam::triSurface::stitchTriangles
36 (
37  const scalar tol,
38  bool verbose
39 )
40 {
41  pointField& ps = this->storedPoints();
42 
43  // Merge points (inplace)
44  labelList pointMap;
45  label nChanged = Foam::inplaceMergePoints(ps, tol, verbose, pointMap);
46 
47  if (nChanged)
48  {
49  if (verbose)
50  {
51  Pout<< "stitchTriangles : Merged from " << pointMap.size()
52  << " points down to " << ps.size() << endl;
53  }
54 
55  // Reset the triangle point labels to the unique points array
56  label newTriangleI = 0;
57  forAll(*this, i)
58  {
59  const labelledTri& tri = operator[](i);
60  labelledTri newTri
61  (
62  pointMap[tri[0]],
63  pointMap[tri[1]],
64  pointMap[tri[2]],
65  tri.region()
66  );
67 
68  if (newTri.good())
69  {
70  operator[](newTriangleI++) = newTri;
71  }
72  else if (verbose)
73  {
74  Pout<< "stitchTriangles : "
75  << "Removing triangle " << i
76  << " with non-unique vertices." << nl
77  << " vertices :" << newTri << nl
78  << " coordinates:" << newTri.points(ps)
79  << endl;
80  }
81  }
82 
83  if (newTriangleI != size())
84  {
85  if (verbose)
86  {
87  Pout<< "stitchTriangles : "
88  << "Removed " << size() - newTriangleI
89  << " triangles" << endl;
90  }
91  setSize(newTriangleI);
92 
93  // And possibly compact out any unused points (since used only
94  // by triangles that have just been deleted)
95  // Done in two passes to save memory (pointField)
96 
97  // 1. Detect only
98  bitSet pointIsUsed(ps.size());
99 
100  label nPoints = 0;
101 
102  for (const labelledTri& f : *this)
103  {
104  for (const label pointi : f)
105  {
106  if (pointIsUsed.set(pointi))
107  {
108  ++nPoints;
109  }
110  }
111  }
112 
113  if (nPoints != ps.size())
114  {
115  // 2. Compact.
116  pointMap.setSize(ps.size());
117  label newPointi = 0;
118  forAll(pointIsUsed, pointi)
119  {
120  if (pointIsUsed[pointi])
121  {
122  ps[newPointi] = ps[pointi];
123  pointMap[pointi] = newPointi++;
124  }
125  }
126  ps.setSize(newPointi);
127 
128  newTriangleI = 0;
129  for (const labelledTri& f : *this)
130  {
131  operator[](newTriangleI++) = labelledTri
132  (
133  pointMap[f[0]],
134  pointMap[f[1]],
135  pointMap[f[2]],
136  f.region()
137  );
138  }
139  }
140  }
141  }
142 
143  return bool(nChanged);
144 }
145 
146 
147 // ************************************************************************* //
label nPoints() const
Number of points supporting patch faces.
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
T & operator[](const label i)
Return element of UList.
Definition: UListI.H:361
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:38
void setSize(const label n)
Alias for resize()
Definition: List.H:316
label inplaceMergePoints(PointList &points, const scalar mergeTol, const bool verbose, labelList &pointToUnique)
Inplace merge points, preserving the original point order. All points closer/equal mergeTol are to be...
pointField & storedPoints()
Non-const access to global points.
Definition: triSurface.H:230
label size() const noexcept
The number of elements in the container.
Definition: UList.H:671
Geometric merging of points. See below.
labelList f(nPoints)
label newPointi
Definition: readKivaGrid.H:496
List< label > labelList
A List of labels.
Definition: List.H:62
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.