1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright held by original author
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 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
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 \*---------------------------------------------------------------------------*/
27 #include "treeDataCell.H"
28 #include "indexedOctree.H"
29 #include "primitiveMesh.H"
31 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33 defineTypeNameAndDebug(Foam::treeDataCell, 0);
36 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
38 Foam::treeBoundBox Foam::treeDataCell::calcCellBb(const label cellI) const
40 const cellList& cells = mesh_.cells();
41 const faceList& faces = mesh_.faces();
42 const pointField& points = mesh_.points();
46 vector(GREAT, GREAT, GREAT),
47 vector(-GREAT, -GREAT, -GREAT)
50 const cell& cFaces = cells[cellI];
52 forAll(cFaces, cFaceI)
54 const face& f = faces[cFaces[cFaceI]];
58 const point& p = points[f[fp]];
60 cellBb.min() = min(cellBb.min(), p);
61 cellBb.max() = max(cellBb.max(), p);
68 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
70 // Construct from components
71 Foam::treeDataCell::treeDataCell
74 const primitiveMesh& mesh,
75 const labelList& cellLabels
79 cellLabels_(cellLabels),
84 bbs_.setSize(cellLabels_.size());
86 forAll(cellLabels_, i)
88 bbs_[i] = calcCellBb(cellLabels_[i]);
94 Foam::treeDataCell::treeDataCell
97 const primitiveMesh& mesh
101 cellLabels_(identity(mesh_.nCells())),
106 bbs_.setSize(cellLabels_.size());
108 forAll(cellLabels_, i)
110 bbs_[i] = calcCellBb(cellLabels_[i]);
116 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
118 Foam::pointField Foam::treeDataCell::points() const
120 pointField cc(cellLabels_.size());
122 forAll(cellLabels_, i)
124 cc[i] = mesh_.cellCentres()[cellLabels_[i]];
131 // Check if any point on shape is inside cubeBb.
132 bool Foam::treeDataCell::overlaps
135 const treeBoundBox& cubeBb
140 return cubeBb.overlaps(bbs_[index]);
144 return cubeBb.overlaps(calcCellBb(cellLabels_[index]));
149 // Calculate nearest point to sample. Updates (if any) nearestDistSqr, minIndex,
151 void Foam::treeDataCell::findNearest
153 const labelList& indices,
156 scalar& nearestDistSqr,
163 label index = indices[i];
164 label cellI = cellLabels_[index];
165 scalar distSqr = magSqr(sample - mesh_.cellCentres()[cellI]);
167 if (distSqr < nearestDistSqr)
169 nearestDistSqr = distSqr;
171 nearestPoint = mesh_.cellCentres()[cellI];
177 bool Foam::treeDataCell::intersects
182 point& intersectionPoint
185 // Do quick rejection test
188 const treeBoundBox& cellBb = bbs_[index];
190 if ((cellBb.posBits(start) & cellBb.posBits(end)) != 0)
192 // start and end in same block outside of cellBb.
198 const treeBoundBox cellBb = calcCellBb(cellLabels_[index]);
200 if ((cellBb.posBits(start) & cellBb.posBits(end)) != 0)
202 // start and end in same block outside of cellBb.
208 // Do intersection with all faces of cell
209 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
211 // Disable picking up intersections behind us.
212 scalar oldTol = intersection::setPlanarTol(0.0);
214 const cell& cFaces = mesh_.cells()[cellLabels_[index]];
216 const vector dir(end - start);
217 scalar minDistSqr = magSqr(dir);
222 const face& f = mesh_.faces()[cFaces[i]];
224 pointHit inter = f.ray
229 intersection::HALF_RAY
232 if (inter.hit() && sqr(inter.distance()) <= minDistSqr)
234 // Note: no extra test on whether intersection is in front of us
235 // since using half_ray AND zero tolerance. (note that tolerance
236 // is used to look behind us)
237 minDistSqr = sqr(inter.distance());
238 intersectionPoint = inter.hitPoint();
243 // Restore picking tolerance
244 intersection::setPlanarTol(oldTol);
250 // ************************************************************************* //