initial commit for version 1.5.x patch release
[OpenFOAM-1.5.x.git] / src / meshTools / triSurface / booleanOps / surfaceIntersection / surfaceIntersectionFuncs.C
blobb3d0e8409bd3913d18fec741c40c6add61a44832
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
9     This file is part of OpenFOAM.
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 the
13     Free Software Foundation; either version 2 of the License, or (at your
14     option) any later version.
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.
21     You should have received a copy of the GNU General Public License
22     along with OpenFOAM; if not, write to the Free Software Foundation,
23     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 Description
27 \*---------------------------------------------------------------------------*/
29 #include "surfaceIntersection.H"
30 #include "triSurfaceSearch.H"
31 #include "labelPairLookup.H"
32 #include "OFstream.H"
33 #include "HashSet.H"
34 #include "labelHashSet.H"
35 #include "triSurface.H"
36 #include "pointIndexHit.H"
37 #include "octreeDataTriSurface.H"
38 #include "octree.H"
39 #include "meshTools.H"
41 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
44 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
46 void Foam::surfaceIntersection::writeOBJ(const point& pt, Ostream& os)
48     os << "v " << pt.x() << ' ' << pt.y() << ' ' << pt.z() << endl;
52 void Foam::surfaceIntersection::writeOBJ
54     const List<point>& pts,
55     const List<edge>& edges,
56     Ostream& os
59     forAll(pts, i)
60     {
61         writeOBJ(pts[i], os);
62     }
63     forAll(edges, i)
64     {
65         const edge& e = edges[i];
67         os << "l " << e.start()+1 << ' ' << e.end()+1 << endl;
68     }
72 // Get minimum length of all edges connected to point
73 Foam::scalar Foam::surfaceIntersection::minEdgeLen
75     const triSurface& surf,
76     const label pointI
79     const labelList& pEdges = surf.pointEdges()[pointI];
81     scalar minLen = GREAT;
83     forAll(pEdges, pEdgeI)
84     {
85         const edge& e = surf.edges()[pEdges[pEdgeI]];
87         minLen = min(minLen, e.mag(surf.localPoints()));
88     }
90     return minLen;
94 // Get edge between fp and fp+1 on faceI.
95 Foam::label Foam::surfaceIntersection::getEdge
97     const triSurface& surf,
98     const label faceI,
99     const label fp
102     const labelledTri& f = surf.localFaces()[faceI];
104     edge faceEdge(f[fp], f[(fp+1) % 3]);
106     const labelList& eLabels = surf.faceEdges()[faceI];
108     forAll(eLabels, eI)
109     {
110         const label edgeI = eLabels[eI];
112         if (surf.edges()[edgeI] == faceEdge)
113         {
114             return edgeI;
115         }
116     }
118     FatalErrorIn
119     (
120         "surfaceIntersection::getEdge(const triSurface&"
121         ", const label, const label"
122     )   << "Problem:: Cannot find edge with vertices " << faceEdge
123         << " in face " << faceI
124         << abort(FatalError);
126     return -1;
130 // Given a map remove all consecutive duplicate elements.
131 void Foam::surfaceIntersection::removeDuplicates
133     const labelList& map,
134     labelList& elems
137     bool hasDuplicate = false;
139     label prevVertI = -1;
141     forAll(elems, elemI)
142     {
143         label newVertI = map[elems[elemI]];
145         if (newVertI == prevVertI)
146         {
147             hasDuplicate = true;
149             break;
150         }
151         prevVertI = newVertI;
152     }
154     if (hasDuplicate)
155     {
156         // Create copy
157         labelList oldElems(elems);
159         label elemI = 0;
161         // Insert first
162         elems[elemI++] = map[oldElems[0]];
164         for(label vertI = 1; vertI < oldElems.size(); vertI++)
165         {
166             // Insert others only if they differ from one before
167             label newVertI = map[oldElems[vertI]];
169             if (newVertI != elems[elems.size()-1])
170             {
171                 elems[elemI++] = newVertI;
172             }
173         }
174         elems.setSize(elemI);
175     }
179 // Remap.
180 void Foam::surfaceIntersection::inlineRemap
182     const labelList& map,
183     labelList& elems
186     forAll(elems, elemI)
187     {
188         elems[elemI] = map[elems[elemI]];
189     }
193 // Remove all duplicate and degenerate elements. Return unique elements and
194 // map from old to new.
195 Foam::edgeList Foam::surfaceIntersection::filterEdges
197     const edgeList& edges,
198     labelList& map
201     HashSet<edge, Hash<edge> > uniqueEdges(10*edges.size());
203     edgeList newEdges(edges.size());
205     map.setSize(edges.size());
206     map = -1;
208     label newEdgeI = 0;
210     forAll(edges, edgeI)
211     {
212         const edge& e = edges[edgeI];
214         if
215         (
216             (e.start() != e.end())
217          && (uniqueEdges.find(e) == uniqueEdges.end())
218         )
219         {
220             // Edge is -non degenerate and -not yet seen.
221             uniqueEdges.insert(e);
223             map[edgeI] = newEdgeI;
225             newEdges[newEdgeI++] = e;
226         }
227     }
229     newEdges.setSize(newEdgeI);
231     return newEdges;
235 // Remove all duplicate elements.
236 Foam::labelList Foam::surfaceIntersection::filterLabels
238     const labelList& elems,
239     labelList& map
242     labelHashSet uniqueElems(10*elems.size());
244     labelList newElems(elems.size());
246     map.setSize(elems.size());
247     map = -1;
249     label newElemI = 0;
251     forAll(elems, elemI)
252     {
253         label elem = elems[elemI];
255         if (uniqueElems.find(elem) == uniqueElems.end())
256         {
257             // First time elem is seen
258             uniqueElems.insert(elem);
260             map[elemI] = newElemI;
262             newElems[newElemI++] = elem;
263         }
264     }
266     newElems.setSize(newElemI);
268     return newElems;
272 void Foam::surfaceIntersection::writeIntersectedEdges
274     const triSurface& surf,
275     const labelListList& edgeCutVerts,
276     Ostream& os
277 ) const
279     // Dump all points (surface followed by cutPoints)
280     const pointField& pts = surf.localPoints();
282     forAll(pts, pointI)
283     {
284         writeOBJ(pts[pointI], os);
285     }
286     forAll(cutPoints(), cutPointI)
287     {
288         writeOBJ(cutPoints()[cutPointI], os);
289     }
291     forAll(edgeCutVerts, edgeI)
292     {
293         const labelList& extraVerts = edgeCutVerts[edgeI];
295         if (extraVerts.size() != 0)
296         {
297             const edge& e = surf.edges()[edgeI];
299             // Start of original edge to first extra point
300             os  << "l " << e.start()+1 << ' '
301                 << extraVerts[0] + surf.nPoints() + 1 << endl;
303             for(label i = 1; i < extraVerts.size(); i++)
304             {
305                 os  << "l " << extraVerts[i-1] + surf.nPoints() + 1  << ' '
306                     << extraVerts[i] + surf.nPoints() + 1 << endl;
307             }
309             os  << "l " << extraVerts[extraVerts.size()-1] + surf.nPoints() + 1
310                 << ' ' << e.end()+1 << endl;
311         }
312     }
316 // Return 0 (p close to start), 1(close to end) or -1.
317 Foam::label Foam::surfaceIntersection::classify
319     const scalar startTol,
320     const scalar endTol,
321     const point& p,
322     const edge& e,
323     const pointField& points
326     if (mag(p - points[e.start()]) < startTol)
327     {
328         return 0;
329     }
330     else if (mag(p - points[e.end()]) < endTol)
331     {
332         return 1;
333     }
334     else
335     {
336         return -1;
337     }
341 // ************************************************************************* //