stitchTriangles.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 | Copyright (C) 2011-2016 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 "triSurface.H"
27 #include "mergePoints.H"
28 #include "PackedBoolList.H"
29 
30 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
31 
32 bool Foam::triSurface::stitchTriangles
33 (
34  const scalar tol,
35  bool verbose
36 )
37 {
38  pointField& ps = storedPoints();
39 
40  // Merge points
41  labelList pointMap;
42  pointField newPoints;
43  bool hasMerged = mergePoints(ps, tol, verbose, pointMap, newPoints);
44 
45  if (hasMerged)
46  {
47  if (verbose)
48  {
49  Pout<< "stitchTriangles : Merged from " << ps.size()
50  << " points down to " << newPoints.size() << endl;
51  }
52 
53  // Set the coordinates to the merged ones
54  ps.transfer(newPoints);
55 
56  // Reset the triangle point labels to the unique points array
57  label newTriangleI = 0;
58  forAll(*this, i)
59  {
60  const labelledTri& tri = operator[](i);
61  labelledTri newTri
62  (
63  pointMap[tri[0]],
64  pointMap[tri[1]],
65  pointMap[tri[2]],
66  tri.region()
67  );
68 
69  if
70  (
71  (newTri[0] != newTri[1])
72  && (newTri[0] != newTri[2])
73  && (newTri[1] != newTri[2])
74  )
75  {
76  operator[](newTriangleI++) = newTri;
77  }
78  else if (verbose)
79  {
80  Pout<< "stitchTriangles : "
81  << "Removing triangle " << i
82  << " with non-unique vertices." << endl
83  << " vertices :" << newTri << endl
84  << " coordinates:" << newTri.points(ps)
85  << endl;
86  }
87  }
88 
89  if (newTriangleI != size())
90  {
91  if (verbose)
92  {
93  Pout<< "stitchTriangles : "
94  << "Removed " << size() - newTriangleI
95  << " triangles" << endl;
96  }
97  setSize(newTriangleI);
98 
99  // And possibly compact out any unused points (since used only
100  // by triangles that have just been deleted)
101  // Done in two passes to save memory (pointField)
102 
103  // 1. Detect only
104  PackedBoolList pointIsUsed(ps.size());
105 
106  label nPoints = 0;
107 
108  forAll(*this, i)
109  {
110  const triSurface::FaceType& f = operator[](i);
111 
112  forAll(f, fp)
113  {
114  label pointi = f[fp];
115  if (pointIsUsed.set(pointi, 1))
116  {
117  nPoints++;
118  }
119  }
120  }
121 
122  if (nPoints != ps.size())
123  {
124  // 2. Compact.
125  pointMap.setSize(ps.size());
126  label newPointi = 0;
127  forAll(pointIsUsed, pointi)
128  {
129  if (pointIsUsed[pointi])
130  {
131  ps[newPointi] = ps[pointi];
132  pointMap[pointi] = newPointi++;
133  }
134  }
135  ps.setSize(newPointi);
136 
137  newTriangleI = 0;
138  forAll(*this, i)
139  {
140  const labelledTri& tri = operator[](i);
141  operator[](newTriangleI++) = labelledTri
142  (
143  pointMap[tri[0]],
144  pointMap[tri[1]],
145  pointMap[tri[2]],
146  tri.region()
147  );
148  }
149  }
150  }
151  }
152 
153  return hasMerged;
154 }
155 
156 
157 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:428
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
T & operator[](const label)
Return element of UList.
Definition: UListI.H:167
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:253
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:42
List< label > labelList
A List of labels.
Definition: labelList.H:56
pointField & storedPoints()
Non-const access to global points.
Definition: triSurface.H:220
Merge points. See below.
void setSize(const label)
Reset size of List.
Definition: List.C:281
label newPointi
Definition: readKivaGrid.H:501
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
label mergePoints(const UList< Type > &points, const scalar mergeTol, const bool verbose, labelList &pointMap, const Type &origin=Type::zero)
Sorts and merges points. All points closer than/equal mergeTol get merged.
label size() const
Return the number of elements in the UList.
Definition: ListI.H:170