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 "faceDecomposition.H"
29 #include "pointField.H"
31 #include "helperFunctions.H"
33 // #define DEBUG_faceDecomposition
35 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
40 label faceDecomposition::concaveVertex() const
42 vector n = f_.normal(points_);
45 const edgeList edges = f_.edges();
51 vector ev = edges[eI].vec(points_);
54 const short next = (eI+1) % f_.size();
55 vector evn = edges[next].vec(points_);
58 const vector prod = (ev ^ evn);
60 if( (prod & n) < -SMALL )
62 if( concaveVrt != -1 )
66 "label faceDecomposition::concaveVertex(const label faceI) const"
67 ) << "Face " << f_ << " has more than one concave vertex."
68 << " Cannot continue ..." << exit(FatalError);
71 label vrtIndex = edges[eI].commonVertex(edges[next]);
74 pointTriIndex_[vrtIndex] &&
75 pointTriIndex_[vrtIndex]->size() > 1
78 concaveVrt = vrtIndex;
85 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
87 faceDecomposition::faceDecomposition
99 faceDecomposition::~faceDecomposition()
103 bool faceDecomposition::isFaceConvex() const
105 if( concaveVertex() == -1 )
111 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
113 bool faceDecomposition::isFacePlanar(const scalar tol) const
115 vector nref = f_.normal(points_);
119 if( mag((points_[f_[pI]] - points_[f_[0]]) & nref) > tol )
121 # ifdef DEBUG_faceDecomposition
122 Info << "Face is not planar " << endl;
130 bool faceDecomposition::isFacePlanar() const
134 const point c = f_.centre(points_);
136 tol = Foam::max(tol, Foam::mag(c - points_[f_[pI]]));
140 return isFacePlanar(tol);
143 faceList faceDecomposition::decomposeFace() const
145 faceList ff = decomposeFaceIntoTriangles();
149 //- face is decomposed into 2 or 3 triangles. I am happy with that.
153 boolList mergedFaces(ff.size(), false);
155 face rf = ff[ff.size()-1];
157 direction il(1), ir(ff.size()-2);
163 //- merge on the side of lower labels
164 face fl = help::mergeTwoFaces(ff[il], lf);
165 if( faceDecomposition(fl, points_).isFaceConvex() )
169 storage.newElmt(fI++) = lf;
173 storage.newElmt(fI++) = lf;
176 storage.newElmt(fI++) = lf;
179 //- merge from the side of higher labels
180 face fr = help::mergeTwoFaces(rf, ff[ir]);
181 if( faceDecomposition(fr, points_).isFaceConvex() )
185 storage.newElmt(fI++) = rf;
189 storage.newElmt(fI++) = rf;
192 storage.newElmt(fI++) = rf;
198 //- this happens if the face has odd number of edges
201 fl = help::mergeTwoFaces(ff[il], lf);
202 fr = help::mergeTwoFaces(rf, ff[ir]);
203 if( faceDecomposition(fl, points_).isFaceConvex() )
205 storage.newElmt(fI++) = fl;
206 storage.newElmt(fI++) = rf;
208 else if( faceDecomposition(fr, points_).isFaceConvex() )
210 storage.newElmt(fI++) = fr;
211 storage.newElmt(fI++) = lf;
215 storage.newElmt(fI++) = lf;
216 storage.newElmt(fI++) = ff[il];
217 storage.newElmt(fI++) = rf;
222 if( storage.size() > 2 )
225 # ifdef DEBUG_faceDecomposition
226 Info << "Original face " << f_ << endl;
227 Info << "Triangles " << ff << endl;
228 Info << "Concave vertex " << concaveVertex(f_) << endl;
229 Info << "Storage " << storage << endl;
235 faceList faceDecomposition::decomposeFaceIntoTriangles(const label cv) const
250 const edgeList edg = f_.edges();
252 for(short eI=1;eI<edg.size()-1;eI++)
254 const short i = (eI+start) % f_.size();
257 add[1] = edg[i].start();
258 add[2] = edg[i].end();
260 fcs.newElmt(fI++) = add;
265 # ifdef DEBUG_faceDecomposition
266 Info << "face " << faceNo << " " << f_
267 << " is decomposed into " << fcs << endl;
278 faceList faceDecomposition::decomposeFaceIntoTriangles() const
280 const label cv = concaveVertex();
281 return decomposeFaceIntoTriangles(cv);
284 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
286 } // End namespace Foam
288 // ************************************************************************* //