1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
7 -------------------------------------------------------------------------------
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
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 "treeDataCell.H"
27 #include "indexedOctree.H"
28 #include "primitiveMesh.H"
30 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
32 defineTypeNameAndDebug(Foam::treeDataCell, 0);
35 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
37 Foam::treeBoundBox Foam::treeDataCell::calcCellBb(const label cellI) const
39 const cellList& cells = mesh_.cells();
40 const faceList& faces = mesh_.faces();
41 const pointField& points = mesh_.points();
45 vector(GREAT, GREAT, GREAT),
46 vector(-GREAT, -GREAT, -GREAT)
49 const cell& cFaces = cells[cellI];
51 forAll(cFaces, cFaceI)
53 const face& f = faces[cFaces[cFaceI]];
57 const point& p = points[f[fp]];
59 cellBb.min() = min(cellBb.min(), p);
60 cellBb.max() = max(cellBb.max(), p);
67 void Foam::treeDataCell::update()
71 bbs_.setSize(cellLabels_.size());
73 forAll(cellLabels_, i)
75 bbs_[i] = calcCellBb(cellLabels_[i]);
81 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
83 Foam::treeDataCell::treeDataCell
86 const primitiveMesh& mesh,
87 const labelUList& cellLabels
91 cellLabels_(cellLabels),
98 Foam::treeDataCell::treeDataCell
101 const primitiveMesh& mesh,
102 const Xfer<labelList>& cellLabels
106 cellLabels_(cellLabels),
113 Foam::treeDataCell::treeDataCell
116 const primitiveMesh& mesh
120 cellLabels_(identity(mesh_.nCells())),
127 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
129 Foam::pointField Foam::treeDataCell::shapePoints() const
131 pointField cc(cellLabels_.size());
133 forAll(cellLabels_, i)
135 cc[i] = mesh_.cellCentres()[cellLabels_[i]];
142 bool Foam::treeDataCell::overlaps
145 const treeBoundBox& cubeBb
150 return cubeBb.overlaps(bbs_[index]);
154 return cubeBb.overlaps(calcCellBb(cellLabels_[index]));
159 bool Foam::treeDataCell::contains
165 return mesh_.pointInCell(sample, cellLabels_[index]);
169 void Foam::treeDataCell::findNearest
171 const labelUList& indices,
174 scalar& nearestDistSqr,
181 label index = indices[i];
182 label cellI = cellLabels_[index];
183 scalar distSqr = magSqr(sample - mesh_.cellCentres()[cellI]);
185 if (distSqr < nearestDistSqr)
187 nearestDistSqr = distSqr;
189 nearestPoint = mesh_.cellCentres()[cellI];
195 bool Foam::treeDataCell::intersects
200 point& intersectionPoint
203 // Do quick rejection test
206 const treeBoundBox& cellBb = bbs_[index];
208 if ((cellBb.posBits(start) & cellBb.posBits(end)) != 0)
210 // start and end in same block outside of cellBb.
216 const treeBoundBox cellBb = calcCellBb(cellLabels_[index]);
218 if ((cellBb.posBits(start) & cellBb.posBits(end)) != 0)
220 // start and end in same block outside of cellBb.
226 // Do intersection with all faces of cell
227 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
229 // Disable picking up intersections behind us.
230 scalar oldTol = intersection::setPlanarTol(0.0);
232 const cell& cFaces = mesh_.cells()[cellLabels_[index]];
234 const vector dir(end - start);
235 scalar minDistSqr = magSqr(dir);
240 const face& f = mesh_.faces()[cFaces[i]];
242 pointHit inter = f.ray
247 intersection::HALF_RAY
250 if (inter.hit() && sqr(inter.distance()) <= minDistSqr)
252 // Note: no extra test on whether intersection is in front of us
253 // since using half_ray AND zero tolerance. (note that tolerance
254 // is used to look behind us)
255 minDistSqr = sqr(inter.distance());
256 intersectionPoint = inter.hitPoint();
261 // Restore picking tolerance
262 intersection::setPlanarTol(oldTol);
268 // ************************************************************************* //