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 \*---------------------------------------------------------------------------*/
29 #include "helperFunctionsTopologyManipulation.H"
31 #include "pointField.H"
38 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
43 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
45 template<class faceType1, class faceType2>
46 bool areFacesEqual(const faceType1& f1, const faceType2& f2)
48 //- their size mut be equal
49 if( f1.size() != f2.size() )
52 //- find the starting point the the second face
54 const label s = f2.size();
55 bool equalOrientation(false);
63 if( f1[1] == f2[(pI+1)%s] )
65 //- faces have the same orientation
66 equalOrientation = true;
68 else if( f1[1] != f2[(s-1+pI)%s] )
70 //- faces shall have opposite orientation, but do not match
79 if( equalOrientation )
81 //- same orientation, check if all points match
82 for(label pI=1;pI<s;++pI)
84 if( f1[pI] != f2[(pI+start)%s] )
90 //- faces with opposite orientation, check if all points match
91 for(label pI=1;pI<s;++pI)
93 if( f1[pI] != f2[(start+s-pI)%s] )
102 template<class T, class ListType >
103 label positionInList(const T& elmt, const ListType& l)
105 for(label i=0;i<l.size();++i)
112 template<class faceType>
113 faceType reverseFace(const faceType& f)
116 rf.setSize(f.size());
120 const label size = f.size();
121 for(label i=1;i<size;++i)
122 rf[f.size()-i] = f[i];
127 template<class faceType1, class faceType2>
128 inline face mergeTwoFaces(const faceType1& f1, const faceType2& f2)
130 DynList<bool> ce1, ce2;
131 ce1.setSize(f1.size());
133 ce2.setSize(f2.size());
138 const edge e1(f1[eI], f1[f1.fcIndex(eI)]);
142 const edge e2(f2[eJ], f2[f2.fcIndex(eJ)]);
153 DynList<edge> fEdges;
158 const edge e1(f1[eI], f1[f1.fcIndex(eI)]);
167 const edge e2(f2[eI], f2[f2.fcIndex(eI)]);
172 return face(sortEdgeChain(fEdges));
175 inline edgeList modifyFacesToShareOneEdge(face& f1, face& f2)
177 const edgeList edg1 = f1.edges();
178 const edgeList edg2 = f2.edges();
180 boolList she1(f1.size(), false);
181 boolList she2(f2.size(), false);
183 edgeList sharedEdges(edg1);
184 label nSharedEdges(0);
188 if( edg1[eI] == edg2[eJ] )
190 sharedEdges.newElmt(nSharedEdges++) = edg1[eI];
200 if( !(she1[pI] && she1[(pI-1+f1.size())%f1.size()]) )
209 if( !(she2[pI] && she2[(pI-1+f2.size())%f2.size()]) )
215 sharedEdges.setSize(nSharedEdges);
219 inline face createFaceFromRemovedPart(const face& fOrig, const face& fCut)
221 if( fCut.size() == 0 )
224 const edgeList eOrig = fOrig.edges();
225 const edgeList eCut = fCut.edges();
227 boolList usedEdge(eOrig.size(), false);
231 if( eOrig[eI] == eCut[eJ] )
241 if( !(usedEdge[pI] && usedEdge[(pI-1+fOrig.size())%fOrig.size()]) )
251 inline face removeEdgesFromFace
254 const DynList<edge>& removeEdges
257 boolList foundEdge(fOrig.size(), false);
259 forAll(removeEdges, reI)
261 if( removeEdges[reI] == fOrig.faceEdge(eI) )
263 foundEdge[eI] = true;
267 face newF(fOrig.size());
271 if( !(foundEdge[pI] && foundEdge[fOrig.rcIndex(pI)]) )
272 newF[i++] = fOrig[pI];
279 inline void findOpenEdges(const faceList& cellFaces, DynList<edge>& openEdges)
281 DynList<edge> cellEdges;
282 DynList<label> nAppearances;
284 forAll(cellFaces, fI)
286 const edgeList edges = cellFaces[fI].edges();
290 const label pos = cellEdges.containsAtPosition(edges[eI]);
294 cellEdges.append(edges[eI]);
295 nAppearances.append(1);
304 openEdges.setSize(12);
307 forAll(nAppearances, eI)
308 if( nAppearances[eI] == 1 )
310 openEdges.append(cellEdges[eI]);
312 else if( nAppearances[eI] > 2 )
316 "void findOpenEdges(const faceList& cellFaces,"
317 "DynList<edge>& openEdges)"
318 ) << "More than two faces in " << cellFaces
319 << " share edge " << cellEdges[eI] << abort(FatalError);
323 template<class faceType1, class faceType2>
324 inline bool shareAnEdge(const faceType1& f1, const faceType2& f2)
328 const edge e1(f1[eI], f1[f1.fcIndex(eI)]);
332 const edge e2(f2[eJ], f2[f2.fcIndex(eJ)]);
342 template<class faceType1, class faceType2>
343 inline edge sharedEdge(const faceType1& f1, const faceType2& f2)
347 const edge e1(f1[eI], f1[f1.fcIndex(eI)]);
351 const edge e2(f2[eJ], f2[f2.fcIndex(eJ)]);
361 template<class faceType>
362 inline label positionOfEdgeInFace(const edge& e, const faceType& f)
366 const edge fe(f[eI], f[f.fcIndex(eI)]);
375 template<class faceType1, class faceType2>
376 inline label sharedVertex(const faceType1& f1, const faceType2& f2)
380 if( f1[pI] == f2[pJ] )
386 template<class faceType1, class faceType2>
387 inline bool shareAVertex(const faceType1& f1, const faceType2& f2)
391 if( f1[pI] == f2[pJ] )
397 template<class faceListType>
398 inline label sharedVertex(const faceListType& fcs)
404 for(label i=1;i<fcs.size();++i)
408 if( fcs[0][pI] == fcs[i][pJ] )
425 template<class boolListType>
426 inline bool areElementsInChain(const boolListType& sel)
428 DynList<bool> selInChain(sel.size(), false);
434 selInChain[eI] = true;
439 forAll(selInChain, eJ)
441 !selInChain[eJ] && sel[eJ] &&
443 selInChain[sel.fcIndex(eJ)] ||
444 selInChain[sel.rcIndex(eJ)]
449 selInChain[eJ] = true;
459 if( sel[eI] && !selInChain[eI] )
466 inline void zipOpenChain(DynList<edge>& bEdges)
468 //- close the chain if open
469 DynList<label> chainVertices;
470 List<label> nAppearances;
473 const edge& e = bEdges[eI];
476 const label pos = chainVertices.containsAtPosition(e[pI]);
480 nAppearances[chainVertices.size()] = 1;
481 chainVertices.append(e[pI]);
491 DynList<label> openVertices(2);
492 forAll(chainVertices, pI)
493 if( nAppearances[pI] == 1 )
496 openVertices.append(chainVertices[pI]);
499 if( !closed && (openVertices.size() == 2) )
502 if( bEdges[eI].end() == openVertices[0] )
504 bEdges.append(edge(openVertices[0], openVertices[1]));
507 else if( bEdges[eI].end() == openVertices[1] )
509 bEdges.append(edge(openVertices[1], openVertices[0]));
517 "void dualMeshExtractor::decomposeCreatedPoly::"
518 "createMissingFaces(List<faceList>& cFaces)"
519 ) << "Chain has " << openVertices << " open vertices"
520 << abort(FatalError);
524 inline labelList sortEdgeChain(const DynList<edge>& bEdges)
526 boolList sorted(bEdges.size(), false);
528 DynList<edge> sortedEdges;
529 sortedEdges.append(bEdges[0]);
541 if( sortedEdges[i].end() == bEdges[eI].start() )
545 sortedEdges.append(bEdges[eI]);
548 else if( sortedEdges[i].end() == bEdges[eI].end() )
552 "labelList sortEdgeChain("
553 "const DynList<edge>& bEdges)"
554 ) << "Chain is not oriented correctly!"
555 << abort(FatalError);
558 } while( !finished );
560 labelList sortPoints(bEdges.size());
561 forAll(sortedEdges, eI)
562 sortPoints[eI] = sortedEdges[eI].start();
567 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
569 } // End namespace help
571 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
573 } // End namespace Foam
575 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //