ENH: moved indexedOctree and treeBoundBox from meshTools to OpenFOAM

This commit is contained in:
andy
2011-02-24 16:06:51 +00:00
parent 06024cf988
commit c2851eaa9f
12 changed files with 15 additions and 34 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,647 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::indexedOctree
Description
Non-pointer based hierarchical recursive searching
SourceFiles
indexedOctree.C
\*---------------------------------------------------------------------------*/
#ifndef indexedOctree_H
#define indexedOctree_H
#include "treeBoundBox.H"
#include "pointIndexHit.H"
#include "FixedList.H"
#include "Ostream.H"
#include "HashSet.H"
#include "labelBits.H"
#include "PackedList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
template<class Type> class indexedOctree;
template<class Type> Ostream& operator<<(Ostream&, const indexedOctree<Type>&);
class Istream;
/*---------------------------------------------------------------------------*\
Class indexedOctreeName Declaration
\*---------------------------------------------------------------------------*/
TemplateName(indexedOctree);
/*---------------------------------------------------------------------------*\
Class indexedOctree Declaration
\*---------------------------------------------------------------------------*/
template <class Type>
class indexedOctree
:
public indexedOctreeName
{
public:
// Data types
//- volume types
enum volumeType
{
UNKNOWN = 0,
MIXED = 1,
INSIDE = 2,
OUTSIDE = 3
};
//- Tree node. Has up pointer and down pointers.
class node
{
public:
//- Bounding box of this node
treeBoundBox bb_;
//- parent node (index into nodes_ of tree)
label parent_;
//- IDs of the 8 nodes on all sides of the mid point
FixedList<labelBits, 8> subNodes_;
friend Ostream& operator<< (Ostream& os, const node& n)
{
return os << n.bb_ << token::SPACE
<< n.parent_ << token::SPACE << n.subNodes_;
}
friend Istream& operator>> (Istream& is, node& n)
{
return is >> n.bb_ >> n.parent_ >> n.subNodes_;
}
friend bool operator==(const node& a, const node& b)
{
return
a.bb_ == b.bb_
&& a.parent_ == b.parent_
&& a.subNodes_ == b.subNodes_;
}
friend bool operator!=(const node& a, const node& b)
{
return !(a == b);
}
};
private:
// Static data
//- Relative peturbation tolerance. Determines when point is
// considered to be close to face/edge of bb of node.
// The tolerance is relative to the bounding box of the smallest
// node.
static scalar perturbTol_;
// Private data
//- Underlying shapes for geometric queries.
const Type shapes_;
//- List of all nodes
List<node> nodes_;
//- List of all contents (referenced by those nodes that are contents)
labelListList contents_;
//- Per node per octant whether is fully inside/outside/mixed.
mutable PackedList<2> nodeTypes_;
// Private Member Functions
//- Helper: does bb intersect a sphere around sample? Or is any
// corner point of bb closer than nearestDistSqr to sample.
// (bb is implicitly provided as parent bb + octant)
static bool overlaps
(
const treeBoundBox& parentBb,
const direction octant,
const scalar nearestDistSqr,
const point& sample
);
// Construction
//- Split list of indices into 8 bins
// according to where they are in relation to mid.
void divide
(
const labelList& indices,
const treeBoundBox& bb,
labelListList& result
) const;
//- Subdivide the contents node at position contentI.
// Appends to contents.
node divide
(
const treeBoundBox& bb,
DynamicList<labelList>& contents,
const label contentI
) const;
//- Split any contents node with more than minSize elements.
void splitNodes
(
const label minSize,
DynamicList<node>& nodes,
DynamicList<labelList>& contents
) const;
static label compactContents
(
DynamicList<node>& nodes,
DynamicList<labelList>& contents,
const label compactLevel,
const label nodeI,
const label level,
List<labelList>& compactedContents,
label& compactI
);
//- Determine inside/outside per node (mixed if cannot be
// determined). Only valid for closed shapes.
volumeType calcVolumeType(const label nodeI) const;
//- Search cached volume type.
volumeType getVolumeType(const label nodeI, const point&) const;
// Query
//- Find nearest point to line.
void findNearest
(
const label nodeI,
const linePointRef& ln,
treeBoundBox& tightest,
label& nearestShapeI,
point& linePoint,
point& nearestPoint
) const;
//- Return bbox of octant
treeBoundBox subBbox
(
const label parentNodeI,
const direction octant
) const;
//- Helper: take a point on/close to face of bb and push it
// inside or outside of bb.
static point pushPoint
(
const treeBoundBox&,
const point&,
const bool pushInside
);
//- Helper: take a point on face of bb and push it
// inside or outside of bb.
static point pushPoint
(
const treeBoundBox&,
const direction,
const point&,
const bool pushInside
);
//- Helper: take point on face(s) of bb and push it away from
// edges of face.
static point pushPointIntoFace
(
const treeBoundBox& bb,
const vector& dir, // end-start
const point& pt
);
////- Push point on multiple faces away from any corner/edge.
//static void checkMultipleFaces
//(
// const treeBoundBox& bb,
// const vector& dir, // end-start
// pointIndexHit& faceHitInfo,
// direction& faceID
//);
//- Walk to parent of node+octant.
bool walkToParent
(
const label nodeI,
const direction octant,
label& parentNodeI,
label& parentOctant
) const;
//- Walk tree to neighbouring node. Return false if edge of tree
// hit.
bool walkToNeighbour
(
const point& facePoint,
const direction faceID, // direction to walk in
label& nodeI,
direction& octant
) const;
//- Debug: return verbose the bounding box faces
static word faceString(const direction faceID);
//- Traverse a node. If intersects a triangle return first
// intersection point.
// findAny=true : return any intersection
// findAny=false: return nearest (to start) intersection
void traverseNode
(
const bool findAny,
const point& treeStart,
const vector& treeVec,
const point& start,
const point& end,
const label nodeI,
const direction octantI,
pointIndexHit& hitInfo,
direction& faceID
) const;
//- Find any or nearest intersection
pointIndexHit findLine
(
const bool findAny,
const point& treeStart,
const point& treeEnd,
const label startNodeI,
const direction startOctantI,
const bool verbose = false
) const;
//- Find any or nearest intersection of line between start and end.
pointIndexHit findLine
(
const bool findAny,
const point& start,
const point& end
) const;
//- Find all elements intersecting box.
void findBox
(
const label nodeI,
const treeBoundBox& searchBox,
labelHashSet& elements
) const;
template <class CompareOp>
static void findNear
(
const scalar nearDist,
const bool okOrder,
const indexedOctree<Type>& tree1,
const labelBits index1,
const treeBoundBox& bb1,
const indexedOctree<Type>& tree2,
const labelBits index2,
const treeBoundBox& bb2,
CompareOp& cop
);
// Other
//- Count number of elements on this and sublevels
label countElements(const labelBits index) const;
//- Dump node+octant to an obj file
void writeOBJ(const label nodeI, const direction octant) const;
//- From index into contents_ to subNodes_ entry
static labelBits contentPlusOctant
(
const label i,
const direction octant
)
{
return labelBits(-i - 1, octant);
}
//- From index into nodes_ to subNodes_ entry
static labelBits nodePlusOctant
(
const label i,
const direction octant
)
{
return labelBits(i + 1, octant);
}
//- From empty to subNodes_ entry
static labelBits emptyPlusOctant
(
const direction octant
)
{
return labelBits(0, octant);
}
public:
//- Get the perturbation tolerance
static scalar& perturbTol();
// Constructors
//- Construct null
indexedOctree(const Type& shapes);
//- Construct from components
indexedOctree
(
const Type& shapes,
const List<node>& nodes,
const labelListList& contents
);
//- Construct from shapes
indexedOctree
(
const Type& shapes,
const treeBoundBox& bb,
const label maxLevels, // maximum number of levels
const scalar maxLeafRatio, // how many elements per leaf
const scalar maxDuplicity // in how many leaves is a shape on
// average
);
//- Construct from Istream
indexedOctree(const Type& shapes, Istream& is);
//- Clone
autoPtr<indexedOctree<Type> > clone() const
{
return autoPtr<indexedOctree<Type> >
(
new indexedOctree<Type>(*this)
);
}
// Member Functions
// Access
//- Reference to shape
const Type& shapes() const
{
return shapes_;
}
//- List of all nodes
const List<node>& nodes() const
{
return nodes_;
}
//- List of all contents (referenced by those nodes that are
// contents)
const labelListList& contents() const
{
return contents_;
}
//- Top bounding box
const treeBoundBox& bb() const
{
if (nodes_.empty())
{
FatalErrorIn("indexedOctree<Type>::bb() const")
<< "Tree is empty" << abort(FatalError);
}
return nodes_[0].bb_;
}
// Conversions for entries in subNodes_.
static bool isContent(const labelBits i)
{
return i.val() < 0;
}
static bool isEmpty(const labelBits i)
{
return i.val() == 0;
}
static bool isNode(const labelBits i)
{
return i.val() > 0;
}
static label getContent(const labelBits i)
{
if (!isContent(i))
{
FatalErrorIn("getContent(const label)")
<< abort(FatalError);
}
return -i.val()-1;
}
static label getNode(const labelBits i)
{
if (!isNode(i))
{
FatalErrorIn("getNode(const label)")
<< abort(FatalError);
}
return i.val() - 1;
}
static direction getOctant(const labelBits i)
{
return i.bits();
}
// Queries
//- Calculate nearest point on nearest shape.
// Returns
// - bool : any point found nearer than nearestDistSqr
// - label: index in shapes
// - point: actual nearest point found
pointIndexHit findNearest
(
const point& sample,
const scalar nearestDistSqr
) const;
//- Low level: calculate nearest starting from subnode.
void findNearest
(
const label nodeI,
const point&,
scalar& nearestDistSqr,
label& nearestShapeI,
point& nearestPoint
) const;
//- Find nearest to line.
// Returns
// - bool : any point found?
// - label: index in shapes
// - point: actual nearest point found
// sets:
// - linePoint : corresponding nearest point on line
pointIndexHit findNearest
(
const linePointRef& ln,
treeBoundBox& tightest,
point& linePoint
) const;
//- Find nearest intersection of line between start and end.
pointIndexHit findLine
(
const point& start,
const point& end
) const;
//- Find any intersection of line between start and end.
pointIndexHit findLineAny
(
const point& start,
const point& end
) const;
//- Find (in no particular order) indices of all shapes inside or
// overlapping bounding box (i.e. all shapes not outside box)
labelList findBox(const treeBoundBox& bb) const;
//- Find deepest node (as parent+octant) containing point. Starts
// off from starting index in nodes_ (use 0 to start from top)
// Use getNode and getOctant to extract info, or call findIndices.
labelBits findNode(const label nodeI, const point&) const;
//- Find shape containing point. Only implemented for certain
// shapes.
label findInside(const point&) const;
//- Find the shape indices that occupy the result of findNode
const labelList& findIndices(const point&) const;
//- Determine type (inside/outside/mixed) for point. unknown if
// cannot be determined (e.g. non-manifold surface)
volumeType getVolumeType(const point&) const;
//- Helper function to return the side. Returns outside if
// outsideNormal&vec >= 0, inside otherwise
static volumeType getSide
(
const vector& outsideNormal,
const vector& vec
);
//- Helper: does bb intersect a sphere around sample? Or is any
// corner point of bb closer than nearestDistSqr to sample.
static bool overlaps
(
const point& bbMin,
const point& bbMax,
const scalar nearestDistSqr,
const point& sample
);
//- Find near pairs and apply CompareOp to them.
// tree2 can be *this or different tree.
template <class CompareOp>
void findNear
(
const scalar nearDist,
const indexedOctree<Type>& tree2,
CompareOp& cop
) const;
// Write
//- Print tree. Either print all indices (printContent = true) or
// just size of contents nodes.
void print
(
prefixOSstream&,
const bool printContents,
const label
) const;
bool write(Ostream& os) const;
// IOstream Operators
friend Ostream& operator<< <Type>(Ostream&, const indexedOctree<Type>&);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "indexedOctree.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,32 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "indexedOctree.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(Foam::indexedOctreeName, 0);
// ************************************************************************* //

View File

@ -0,0 +1,153 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::labelBits
Description
A 29bits label and 3bits direction packed into single label
SourceFiles
\*---------------------------------------------------------------------------*/
#ifndef labelBits_H
#define labelBits_H
#include "label.H"
#include "uLabel.H"
#include "direction.H"
#include "error.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class labelBits Declaration
\*---------------------------------------------------------------------------*/
class labelBits
{
// Private data
label data_;
inline static label pack(const label val, const direction bits)
{
# ifdef FULLDEBUG
if (bits > 7 || (((val<<3)>>3) != val))
{
FatalErrorIn
(
"labelBits::pack(const label, const direction)"
) << "Direction " << bits << " outside range 0..7"
<< abort(FatalError);
}
# endif
return (val<<3) | bits;
}
public:
// Constructors
//- Construct null
inline labelBits()
{}
//- Construct from components
inline labelBits(const label val, const direction bits)
:
data_(pack(val, bits))
{}
//- Construct from Istream
inline labelBits(Istream& is)
{
is >> data_;
}
// Member Functions
inline label val() const
{
return data_ >> 3;
}
inline direction bits() const
{
return data_ & 7;
}
inline void setVal(const label val)
{
data_ = pack(val, bits());
}
inline void setBits(const direction bits)
{
data_ = pack(val(), bits);
}
// Member Operators
inline friend bool operator==(const labelBits& a, const labelBits& b)
{
return a.data_ == b.data_;
}
inline friend bool operator!=(const labelBits& a, const labelBits& b)
{
return !(a == b);
}
// IOstream Operators
inline friend Istream& operator>>(Istream& is, labelBits& lb)
{
return is >> lb.data_;
}
inline friend Ostream& operator<<(Ostream& os, const labelBits& lb)
{
return os << lb.data_;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,271 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "treeDataCell.H"
#include "indexedOctree.H"
#include "primitiveMesh.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(Foam::treeDataCell, 0);
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::treeBoundBox Foam::treeDataCell::calcCellBb(const label cellI) const
{
const cellList& cells = mesh_.cells();
const faceList& faces = mesh_.faces();
const pointField& points = mesh_.points();
treeBoundBox cellBb
(
vector(GREAT, GREAT, GREAT),
vector(-GREAT, -GREAT, -GREAT)
);
const cell& cFaces = cells[cellI];
forAll(cFaces, cFaceI)
{
const face& f = faces[cFaces[cFaceI]];
forAll(f, fp)
{
const point& p = points[f[fp]];
cellBb.min() = min(cellBb.min(), p);
cellBb.max() = max(cellBb.max(), p);
}
}
return cellBb;
}
void Foam::treeDataCell::update()
{
if (cacheBb_)
{
bbs_.setSize(cellLabels_.size());
forAll(cellLabels_, i)
{
bbs_[i] = calcCellBb(cellLabels_[i]);
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::treeDataCell::treeDataCell
(
const bool cacheBb,
const primitiveMesh& mesh,
const labelUList& cellLabels
)
:
mesh_(mesh),
cellLabels_(cellLabels),
cacheBb_(cacheBb)
{
update();
}
Foam::treeDataCell::treeDataCell
(
const bool cacheBb,
const primitiveMesh& mesh,
const Xfer<labelList>& cellLabels
)
:
mesh_(mesh),
cellLabels_(cellLabels),
cacheBb_(cacheBb)
{
update();
}
Foam::treeDataCell::treeDataCell
(
const bool cacheBb,
const primitiveMesh& mesh
)
:
mesh_(mesh),
cellLabels_(identity(mesh_.nCells())),
cacheBb_(cacheBb)
{
update();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::pointField Foam::treeDataCell::points() const
{
pointField cc(cellLabels_.size());
forAll(cellLabels_, i)
{
cc[i] = mesh_.cellCentres()[cellLabels_[i]];
}
return cc;
}
// Check if any point on shape is inside cubeBb.
bool Foam::treeDataCell::overlaps
(
const label index,
const treeBoundBox& cubeBb
) const
{
if (cacheBb_)
{
return cubeBb.overlaps(bbs_[index]);
}
else
{
return cubeBb.overlaps(calcCellBb(cellLabels_[index]));
}
}
bool Foam::treeDataCell::contains
(
const label index,
const point& sample
) const
{
return mesh_.pointInCell(sample, cellLabels_[index]);
}
// Calculate nearest point to sample. Updates (if any) nearestDistSqr, minIndex,
// nearestPoint.
void Foam::treeDataCell::findNearest
(
const labelUList& indices,
const point& sample,
scalar& nearestDistSqr,
label& minIndex,
point& nearestPoint
) const
{
forAll(indices, i)
{
label index = indices[i];
label cellI = cellLabels_[index];
scalar distSqr = magSqr(sample - mesh_.cellCentres()[cellI]);
if (distSqr < nearestDistSqr)
{
nearestDistSqr = distSqr;
minIndex = index;
nearestPoint = mesh_.cellCentres()[cellI];
}
}
}
bool Foam::treeDataCell::intersects
(
const label index,
const point& start,
const point& end,
point& intersectionPoint
) const
{
// Do quick rejection test
if (cacheBb_)
{
const treeBoundBox& cellBb = bbs_[index];
if ((cellBb.posBits(start) & cellBb.posBits(end)) != 0)
{
// start and end in same block outside of cellBb.
return false;
}
}
else
{
const treeBoundBox cellBb = calcCellBb(cellLabels_[index]);
if ((cellBb.posBits(start) & cellBb.posBits(end)) != 0)
{
// start and end in same block outside of cellBb.
return false;
}
}
// Do intersection with all faces of cell
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Disable picking up intersections behind us.
scalar oldTol = intersection::setPlanarTol(0.0);
const cell& cFaces = mesh_.cells()[cellLabels_[index]];
const vector dir(end - start);
scalar minDistSqr = magSqr(dir);
bool hasMin = false;
forAll(cFaces, i)
{
const face& f = mesh_.faces()[cFaces[i]];
pointHit inter = f.ray
(
start,
dir,
mesh_.points(),
intersection::HALF_RAY
);
if (inter.hit() && sqr(inter.distance()) <= minDistSqr)
{
// Note: no extra test on whether intersection is in front of us
// since using half_ray AND zero tolerance. (note that tolerance
// is used to look behind us)
minDistSqr = sqr(inter.distance());
intersectionPoint = inter.hitPoint();
hasMin = true;
}
}
// Restore picking tolerance
intersection::setPlanarTol(oldTol);
return hasMin;
}
// ************************************************************************* //

View File

@ -0,0 +1,217 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::treeDataCell
Description
Encapsulation of data needed to search in/for cells. Used to find the
cell containing a point (e.g. cell-cell mapping).
SourceFiles
treeDataCell.C
\*---------------------------------------------------------------------------*/
#ifndef treeDataCell_H
#define treeDataCell_H
#include "treeBoundBoxList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class primitiveMesh;
template<class Type> class indexedOctree;
/*---------------------------------------------------------------------------*\
Class treeDataCell Declaration
\*---------------------------------------------------------------------------*/
class treeDataCell
{
// Private data
const primitiveMesh& mesh_;
//- Subset of cells to work on
const labelList cellLabels_;
//- Whether to precalculate and store cell bounding box
const bool cacheBb_;
//- cell bounding boxes (valid only if cacheBb_)
treeBoundBoxList bbs_;
// Private Member Functions
//- Calculate cell bounding box
treeBoundBox calcCellBb(const label cellI) const;
//- Initialise all member data
void update();
public:
// Declare name of the class and its debug switch
ClassName("treeDataCell");
// Constructors
//- Construct from mesh and subset of cells.
treeDataCell
(
const bool cacheBb,
const primitiveMesh&,
const labelUList&
);
//- Construct from mesh and subset of cells, transferring contents
treeDataCell
(
const bool cacheBb,
const primitiveMesh&,
const Xfer<labelList>&
);
//- Construct from mesh. Uses all cells in mesh.
treeDataCell(const bool cacheBb, const primitiveMesh&);
// Member Functions
// Access
inline const labelList& cellLabels() const
{
return cellLabels_;
}
inline const primitiveMesh& mesh() const
{
return mesh_;
}
inline label size() const
{
return cellLabels_.size();
}
//- Get representative point cloud for all shapes inside
// (one point per shape)
pointField points() const;
// Search
//- Get type (inside,outside,mixed,unknown) of point w.r.t. surface.
// Only makes sense for closed surfaces.
label getVolumeType
(
const indexedOctree<treeDataCell>&,
const point&
) const
{
notImplemented
(
"treeDataCell::getVolumeType"
"(const indexedOctree<treeDataCell>&, const point&)"
);
return -1;
}
//- Does (bb of) shape at index overlap bb
bool overlaps
(
const label index,
const treeBoundBox& sampleBb
) const;
//- Does shape at index contain sample
bool contains
(
const label index,
const point& sample
) const;
//- Calculates nearest (to sample) point in shape.
// Returns actual point and distance (squared)
void findNearest
(
const labelUList& indices,
const point& sample,
scalar& nearestDistSqr,
label& nearestIndex,
point& nearestPoint
) const;
//- Calculates nearest (to line) point in shape.
// Returns point and distance (squared)
void findNearest
(
const labelUList& indices,
const linePointRef& ln,
treeBoundBox& tightest,
label& minIndex,
point& linePoint,
point& nearestPoint
) const
{
notImplemented
(
"treeDataCell::findNearest"
"(const labelUList&, const linePointRef&, ..)"
);
}
//- Calculate intersection of shape with ray. Sets result
// accordingly
bool intersects
(
const label index,
const point& start,
const point& end,
point& result
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //