1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | cfMesh: A library for mesh generation
5 \\ / A nd | Author: Franjo Juretic (franjo.juretic@c-fields.com)
6 \\/ M anipulation | Copyright (C) Creative Fields, Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of cfMesh.
11 cfMesh is free software; you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation; either version 3 of the License, or (at your
14 option) any later version.
16 cfMesh 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
21 You should have received a copy of the GNU General Public License
22 along with cfMesh. If not, see <http://www.gnu.org/licenses/>.
26 \*---------------------------------------------------------------------------*/
28 #include "triSurfaceCleanupDuplicates.H"
29 #include "triSurfModifier.H"
30 #include "meshOctree.H"
31 #include "demandDrivenData.H"
38 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
43 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
45 bool triSurfaceCleanupDuplicates::checkDuplicateTriangles()
47 labelLongList newTriangleLabel(surf_.size(), -1);
49 const VRWGraph& pointTriangles = surf_.pointFacets();
51 //- check if there exist duplicate triangles
56 if( newTriangleLabel[triI] != -1 )
59 newTriangleLabel[triI] = counter;
62 const labelledTri& tri = surf_[triI];
64 forAll(pointTriangles[tri[0]], ptI)
66 const label triJ = pointTriangles(tri[0], ptI);
71 const labelledTri& otherTri = surf_[triJ];
74 newTriangleLabel[triJ] = newTriangleLabel[triI];
78 Info << "Found " << (newTriangleLabel.size()-counter)
79 << " duplicate triangles" << endl;
81 //- return if there exist no duplicate triangles
82 if( counter == newTriangleLabel.size() )
85 Info << "Current number of triangles" << surf_.size() << endl;
86 Info << "New number of triangles " << counter << endl;
88 //- create new list of triangles and store it in the surface mesh
89 LongList<labelledTri> newTriangles(counter);
91 forAll(newTriangleLabel, triI)
93 newTriangles[newTriangleLabel[triI]] = surf_[triI];
96 updateTriangleLabels(newTriangleLabel);
98 triSurfModifier(surf_).facetsAccess().transfer(newTriangles);
99 surf_.updateFacetsSubsets(newTriangleLabel);
104 bool triSurfaceCleanupDuplicates::mergeDuplicatePoints()
106 pointField& pts = const_cast<pointField&>(surf_.points());
107 labelLongList newPointLabel(surf_.nPoints());
108 bool foundDuplicates(false);
111 # pragma omp parallel
117 forAll(newPointLabel, pI)
118 newPointLabel[pI] = pI;
123 //- check if there exist any vertices closer
124 //- than the prescribed tolerance
126 # pragma omp for schedule(dynamic, 20)
128 for(label leafI=0;leafI<octree_.numberOfLeaves();++leafI)
131 octree_.containedTriangles(leafI, ct);
133 std::set<label> points;
137 const label triI = newTriangleLabel_[ct[ctI]];
142 const labelledTri& tri = surf_[triI];
145 points.insert(tri[i]);
150 std::set<label>::const_iterator it=points.begin();
154 const label pointI = *it;
158 std::set<label>::const_iterator nIt=++it;
162 if( magSqr(pts[pointI] - pts[*nIt]) < sqr(tolerance_) )
164 foundDuplicates = true;
166 # pragma omp critical
168 newPointLabel[*nIt] = pointI;
174 //- find if there exist no duplicate points
175 if( !foundDuplicates )
178 //- remove vertices and update node labels
181 if( newPointLabel[pI] == pI )
183 newPointLabel[pI] = counter;
185 pts[counter] = pts[pI];
190 const label origI = newPointLabel[pI];
191 newPointLabel[pI] = newPointLabel[origI];
194 Info << "Found " << (pts.size() - counter) << "duplicate points" << endl;
196 pts.setSize(counter);
198 //- remove triangles containing duplicate points
199 LongList<labelledTri> newTriangles(surf_.facets());
200 labelLongList newTriangleLabel(surf_.size(), -1);
205 const labelledTri& tri = surf_[triI];
206 const labelledTri newTri
208 newPointLabel[tri[0]],
209 newPointLabel[tri[1]],
210 newPointLabel[tri[2]],
215 for(label i=0;i<2;++i)
216 for(label j=i+1;j<3;++j)
217 if( newTri[i] == newTri[j] )
225 newTriangles[counter] = newTri;
226 newTriangleLabel[triI] = counter;
231 newTriangles.setSize(counter);
233 //- update the surface
234 triSurfModifier(surf_).facetsAccess().transfer(newTriangles);
235 surf_.updateFacetsSubsets(newTriangleLabel);
240 void triSurfaceCleanupDuplicates::updateTriangleLabels
242 const labelLongList& newTriangleLabel
245 //- update addressing between the original triangles and the cleaned mesh
246 forAll(newTriangleLabel_, triI)
248 const label origI = newTriangleLabel_[triI];
251 newTriangleLabel_[triI] = newTriangleLabel[origI];
255 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
257 } // End namespace Foam
259 // ************************************************************************* //