ENH: meshSearch: use tet decomposition for cell searching
[OpenFOAM-2.0.x.git] / src / meshTools / indexedOctree / treeDataPolyMeshCell.C
blob9609197a2de68f20dcc5305116b805b5189278eb
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
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
13     the Free Software Foundation, either version 3 of the License, or
14     (at your 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, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "treeDataPolyMeshCell.H"
27 #include "indexedOctree.H"
28 #include "polyMesh.H"
30 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
32 defineTypeNameAndDebug(Foam::treeDataPolyMeshCell, 0);
35 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
37 Foam::treeBoundBox Foam::treeDataPolyMeshCell::calcCellBb(const label cellI) const
39     const cellList& cells = mesh_.cells();
40     const faceList& faces = mesh_.faces();
41     const pointField& points = mesh_.points();
43     treeBoundBox cellBb
44     (
45         vector(GREAT, GREAT, GREAT),
46         vector(-GREAT, -GREAT, -GREAT)
47     );
49     const cell& cFaces = cells[cellI];
51     forAll(cFaces, cFaceI)
52     {
53         const face& f = faces[cFaces[cFaceI]];
55         forAll(f, fp)
56         {
57             const point& p = points[f[fp]];
59             cellBb.min() = min(cellBb.min(), p);
60             cellBb.max() = max(cellBb.max(), p);
61         }
62     }
63     return cellBb;
67 void Foam::treeDataPolyMeshCell::update()
69     if (cacheBb_)
70     {
71         bbs_.setSize(cellLabels_.size());
73         forAll(cellLabels_, i)
74         {
75             bbs_[i] = calcCellBb(cellLabels_[i]);
76         }
77     }
81 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
83 Foam::treeDataPolyMeshCell::treeDataPolyMeshCell
85     const bool cacheBb,
86     const polyMesh& mesh,
87     const labelUList& cellLabels
90     mesh_(mesh),
91     cellLabels_(cellLabels),
92     cacheBb_(cacheBb)
94     update();
98 Foam::treeDataPolyMeshCell::treeDataPolyMeshCell
100     const bool cacheBb,
101     const polyMesh& mesh,
102     const Xfer<labelList>& cellLabels
105     mesh_(mesh),
106     cellLabels_(cellLabels),
107     cacheBb_(cacheBb)
109     update();
113 Foam::treeDataPolyMeshCell::treeDataPolyMeshCell
115     const bool cacheBb,
116     const polyMesh& mesh
119     mesh_(mesh),
120     cellLabels_(identity(mesh_.nCells())),
121     cacheBb_(cacheBb)
123     update();
127 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
129 Foam::pointField Foam::treeDataPolyMeshCell::shapePoints() const
131     pointField cc(cellLabels_.size());
133     forAll(cellLabels_, i)
134     {
135         cc[i] = mesh_.cellCentres()[cellLabels_[i]];
136     }
138     return cc;
142 bool Foam::treeDataPolyMeshCell::overlaps
144     const label index,
145     const treeBoundBox& cubeBb
146 ) const
148     if (cacheBb_)
149     {
150         return cubeBb.overlaps(bbs_[index]);
151     }
152     else
153     {
154         return cubeBb.overlaps(calcCellBb(cellLabels_[index]));
155     }
159 bool Foam::treeDataPolyMeshCell::contains
161     const label index,
162     const point& sample
163 ) const
165     //return mesh_.pointInCell(sample, cellLabels_[index]);
166     label tetFaceI, tetPtI;
167     mesh_.findTetFacePt(cellLabels_[index], sample, tetFaceI, tetPtI);
168     return tetFaceI != -1;
172 void Foam::treeDataPolyMeshCell::findNearest
174     const labelUList& indices,
175     const point& sample,
177     scalar& nearestDistSqr,
178     label& minIndex,
179     point& nearestPoint
180 ) const
182     forAll(indices, i)
183     {
184         label index = indices[i];
185         label cellI = cellLabels_[index];
186         scalar distSqr = magSqr(sample - mesh_.cellCentres()[cellI]);
188         if (distSqr < nearestDistSqr)
189         {
190             nearestDistSqr = distSqr;
191             minIndex = index;
192             nearestPoint = mesh_.cellCentres()[cellI];
193         }
194     }
198 bool Foam::treeDataPolyMeshCell::intersects
200     const label index,
201     const point& start,
202     const point& end,
203     point& intersectionPoint
204 ) const
206     // Do quick rejection test
207     if (cacheBb_)
208     {
209         const treeBoundBox& cellBb = bbs_[index];
211         if ((cellBb.posBits(start) & cellBb.posBits(end)) != 0)
212         {
213             // start and end in same block outside of cellBb.
214             return false;
215         }
216     }
217     else
218     {
219         const treeBoundBox cellBb = calcCellBb(cellLabels_[index]);
221         if ((cellBb.posBits(start) & cellBb.posBits(end)) != 0)
222         {
223             // start and end in same block outside of cellBb.
224             return false;
225         }
226     }
229     // Do intersection with all faces of cell
230     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
232     // Disable picking up intersections behind us.
233     scalar oldTol = intersection::setPlanarTol(0.0);
235     const cell& cFaces = mesh_.cells()[cellLabels_[index]];
237     const vector dir(end - start);
238     scalar minDistSqr = magSqr(dir);
239     bool hasMin = false;
241     forAll(cFaces, i)
242     {
243         const face& f = mesh_.faces()[cFaces[i]];
245         pointHit inter = f.ray
246         (
247             start,
248             dir,
249             mesh_.points(),
250             intersection::HALF_RAY
251         );
253         if (inter.hit() && sqr(inter.distance()) <= minDistSqr)
254         {
255             // Note: no extra test on whether intersection is in front of us
256             // since using half_ray AND zero tolerance. (note that tolerance
257             // is used to look behind us)
258             minDistSqr = sqr(inter.distance());
259             intersectionPoint = inter.hitPoint();
260             hasMin = true;
261         }
262     }
264     // Restore picking tolerance
265     intersection::setPlanarTol(oldTol);
267     return hasMin;
271 // ************************************************************************* //