single precision changes; corrected intersection with tolerance

This commit is contained in:
mattijs
2009-04-09 13:05:32 +01:00
parent c203c3d6fd
commit 8ad04131f4
16 changed files with 1612 additions and 413 deletions

View File

@ -222,16 +222,16 @@ public:
) const; ) const;
//- Fast intersection with a ray. //- Fast intersection with a ray.
// For a hit, the pointHit.distance() is the line parameter t : // Does face-center decomposition and returns triangle intersection
// intersection=p+t*q. Only defined for FULL_RAY or // point closest to p. See triangle::intersection for details.
// HALF_RAY.
pointHit intersection pointHit intersection
( (
const point& p, const point& p,
const vector& q, const vector& q,
const point& ctr, const point& ctr,
const pointField& meshPoints, const pointField& meshPoints,
const intersection::algorithm alg const intersection::algorithm alg,
const scalar tol = 0.0
) const; ) const;
//- Return nearest point to face //- Return nearest point to face

View File

@ -136,7 +136,8 @@ Foam::pointHit Foam::face::intersection
const vector& q, const vector& q,
const point& ctr, const point& ctr,
const pointField& meshPoints, const pointField& meshPoints,
const intersection::algorithm alg const intersection::algorithm alg,
const scalar tol
) const ) const
{ {
scalar nearestHitDist = VGREAT; scalar nearestHitDist = VGREAT;
@ -154,7 +155,7 @@ Foam::pointHit Foam::face::intersection
meshPoints[f[pI]], meshPoints[f[pI]],
meshPoints[f[fcIndex(pI)]], meshPoints[f[fcIndex(pI)]],
ctr ctr
).intersection(p, q, alg); ).intersection(p, q, alg, tol);
if (curHit.hit()) if (curHit.hit())
{ {

View File

@ -153,7 +153,7 @@ public:
inline scalar sweptVol(const triangle& t) const; inline scalar sweptVol(const triangle& t) const;
//- Return point intersection with a ray. //- Return point intersection with a ray.
// For a hit, the distance is signed. Positive number // For a hit, the distance is signed. Positive number
// represents the point in front of triangle. // represents the point in front of triangle.
// In case of miss pointHit is set to nearest point // In case of miss pointHit is set to nearest point
// on triangle and its distance to the distance between // on triangle and its distance to the distance between
@ -166,12 +166,14 @@ public:
const intersection::direction dir = intersection::VECTOR const intersection::direction dir = intersection::VECTOR
) const; ) const;
//- Fast intersection with a ray. //- Fast intersection with a ray. Distance is normal distance
// For a hit, the pointHit.distance() is the line parameter t : // to the intersection.
// intersection=p+t*q. Only defined for VISIBLE, FULL_RAY or // For a hit, the distance is signed. Positive number
// represents the point in front of triangle. In case of miss
// pointHit position is undefined.
// Only defined for VISIBLE, FULL_RAY or
// HALF_RAY. tol increases the virtual size of the triangle // HALF_RAY. tol increases the virtual size of the triangle
// by a relative factor - can be used to compensate for // by a relative factor.
// limited precision.
inline pointHit intersection inline pointHit intersection
( (
const point& p, const point& p,

View File

@ -585,7 +585,7 @@ inline bool triangle<Point, PointRef>::classify
bool hit = false; bool hit = false;
if (Foam::mag(u1) < SMALL) if (Foam::mag(u1) < ROOTVSMALL)
{ {
beta = u0/u2; beta = u0/u2;

View File

@ -73,7 +73,7 @@ Foam::scalar Foam::ExactParticle<ParticleType>::trackToFace
const labelList& cFaces = mesh.cells()[this->celli_]; const labelList& cFaces = mesh.cells()[this->celli_];
point intersection(vector::zero); point intersection(vector::zero);
scalar trackFraction = VGREAT; scalar distanceSqr = VGREAT;
label hitFacei = -1; label hitFacei = -1;
const vector vec = endPosition-this->position_; const vector vec = endPosition-this->position_;
@ -93,32 +93,21 @@ Foam::scalar Foam::ExactParticle<ParticleType>::trackToFace
intersection::HALF_RAY intersection::HALF_RAY
); );
if (inter.hit() && inter.distance() < trackFraction) if (inter.hit())
{ {
trackFraction = inter.distance(); scalar s = magSqr(inter.hitPoint()-this->position_);
hitFacei = facei;
intersection = inter.hitPoint(); if (s < distanceSqr)
{
distanceSqr = s;
hitFacei = facei;
intersection = inter.hitPoint();
}
} }
} }
} }
if (hitFacei == -1)
if (hitFacei != -1)
{
if (trackFraction > 1.0)
{
// Nearest intersection beyond endPosition so we hit endPosition.
this->position_ = endPosition;
this->facei_ = -1;
return 1.0;
}
else
{
this->position_ = intersection;
this->facei_ = hitFacei;
}
}
else
{ {
// Did not find any intersection. Fall back to original approximate // Did not find any intersection. Fall back to original approximate
// algorithm // algorithm
@ -130,7 +119,24 @@ Foam::scalar Foam::ExactParticle<ParticleType>::trackToFace
} }
// Normal situation (trackFraction 0..1) scalar trackFraction = Foam::sqrt(distanceSqr/magSqr(vec));
if (trackFraction >= (1.0-SMALL))
{
// Nearest intersection beyond endPosition so we hit endPosition.
this->position_ = endPosition;
this->facei_ = -1;
return 1.0;
}
else
{
this->position_ = intersection;
this->facei_ = hitFacei;
}
// Normal situation (trackFraction 0..1). Straight copy
// of Particle::trackToFace.
bool internalFace = this->cloud().internalFace(this->facei_); bool internalFace = this->cloud().internalFace(this->facei_);

File diff suppressed because it is too large Load Diff

View File

@ -128,6 +128,15 @@ public:
private: 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 // Private data
//- Underlying shapes for geometric queries. //- Underlying shapes for geometric queries.
@ -144,8 +153,9 @@ private:
// Private Member Functions // Private Member Functions
//- Like above but now bb is implicitly provided as parent bb + mid //- Helper: does bb intersect a sphere around sample? Or is any
// + octant // corner point of bb closer than nearestDistSqr to sample.
// (bb is implicitly provided as parent bb + octant)
static bool overlaps static bool overlaps
( (
const treeBoundBox& parentBb, const treeBoundBox& parentBb,
@ -215,6 +225,60 @@ private:
point& nearestPoint point& nearestPoint
) const; ) 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 //- Walk tree to neighbouring node. Return false if edge of tree
// hit. // hit.
bool walkToNeighbour bool walkToNeighbour
@ -225,8 +289,8 @@ private:
direction& octant direction& octant
) const; ) const;
//- Categorize point on bounding box. //- Debug: return verbose the bounding box faces
static direction getFace(const treeBoundBox&, const point&); static word faceString(const direction faceID);
//- Traverse a node. If intersects a triangle return first //- Traverse a node. If intersects a triangle return first
// intersection point. // intersection point.
@ -235,9 +299,11 @@ private:
void traverseNode void traverseNode
( (
const bool findAny, const bool findAny,
const point& treeStart,
const vector& treeVec,
const point& start, const point& start,
const point& end, const point& end,
const vector& dir,
const label nodeI, const label nodeI,
const direction octantI, const direction octantI,
@ -252,7 +318,8 @@ private:
const point& treeStart, const point& treeStart,
const point& treeEnd, const point& treeEnd,
const label startNodeI, const label startNodeI,
const direction startOctantI const direction startOctantI,
const bool verbose = false
) const; ) const;
//- Find any or nearest intersection of line between start and end. //- Find any or nearest intersection of line between start and end.
@ -310,6 +377,10 @@ private:
public: public:
//- Get the perturbation tolerance
static scalar& perturbTol();
// Constructors // Constructors
//- Construct null //- Construct null
@ -505,6 +576,7 @@ public:
const point& sample const point& sample
); );
// Write // Write
//- Print tree. Either print all indices (printContent = true) or //- Print tree. Either print all indices (printContent = true) or

View File

@ -528,7 +528,7 @@ bool Foam::treeDataFace::intersects
intersection::HALF_RAY intersection::HALF_RAY
); );
if (inter.hit() && inter.distance() <= 1) if (inter.hit() && magSqr(inter.hitPoint()-start) <= magSqr(dir))
{ {
// Note: no extra test on whether intersection is in front of us // Note: no extra test on whether intersection is in front of us
// since using half_ray // since using half_ray

View File

@ -22,8 +22,6 @@ License
along with OpenFOAM; if not, write to the Free Software Foundation, along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "treeDataTriSurface.H" #include "treeDataTriSurface.H"
@ -226,7 +224,7 @@ Foam::label Foam::treeDataTriSurface::getVolumeType
if (!pHit.hit()) if (!pHit.hit())
{ {
FatalErrorIn("treeDataTriSurface::getVolumeType") FatalErrorIn("treeDataTriSurface::getVolumeType(..)")
<< "treeBb:" << treeBb << "treeBb:" << treeBb
<< " sample:" << sample << " sample:" << sample
<< " pHit:" << pHit << " pHit:" << pHit
@ -238,7 +236,8 @@ Foam::label Foam::treeDataTriSurface::getVolumeType
surface_, surface_,
sample, sample,
pHit.index(), pHit.index(),
pHit.hitPoint() pHit.hitPoint(),
indexedOctree<treeDataTriSurface>::perturbTol()
); );
if (t == triSurfaceTools::UNKNOWN) if (t == triSurfaceTools::UNKNOWN)
@ -255,12 +254,13 @@ Foam::label Foam::treeDataTriSurface::getVolumeType
} }
else else
{ {
FatalErrorIn("treeDataTriSurface::getVolumeType") FatalErrorIn("treeDataTriSurface::getVolumeType(..)")
<< "problem" << abort(FatalError); << "problem" << abort(FatalError);
return indexedOctree<treeDataTriSurface>::UNKNOWN; return indexedOctree<treeDataTriSurface>::UNKNOWN;
} }
} }
// Check if any point on triangle is inside cubeBb. // Check if any point on triangle is inside cubeBb.
bool Foam::treeDataTriSurface::overlaps bool Foam::treeDataTriSurface::overlaps
( (
@ -305,6 +305,7 @@ bool Foam::treeDataTriSurface::overlaps
// Now we have the difficult case: all points are outside but connecting // Now we have the difficult case: all points are outside but connecting
// edges might go through cube. Use fast intersection of bounding box. // edges might go through cube. Use fast intersection of bounding box.
//return triangleFuncs::intersectBbExact(p0, p1, p2, cubeBb);
return triangleFuncs::intersectBb(p0, p1, p2, cubeBb); return triangleFuncs::intersectBb(p0, p1, p2, cubeBb);
} }
@ -445,9 +446,17 @@ bool Foam::treeDataTriSurface::intersects
const vector dir(end - start); const vector dir(end - start);
pointHit inter = tri.intersection(start, dir, intersection::HALF_RAY); // Use relative tolerance (from octree) to determine intersection.
if (inter.hit() && inter.distance() <= 1) pointHit inter = tri.intersection
(
start,
dir,
intersection::HALF_RAY,
indexedOctree<treeDataTriSurface>::perturbTol()
);
if (inter.hit() && magSqr(inter.hitPoint()-start) <= magSqr(dir))
{ {
// Note: no extra test on whether intersection is in front of us // Note: no extra test on whether intersection is in front of us
// since using half_ray. // since using half_ray.
@ -459,6 +468,16 @@ bool Foam::treeDataTriSurface::intersects
{ {
return false; return false;
} }
//- Using exact intersections
//pointHit info = f.tri(points).intersectionExact(start, end);
//
//if (info.hit())
//{
// intersectionPoint = info.hitPoint();
//}
//return info.hit();
} }

View File

@ -309,12 +309,14 @@ bool Foam::treeBoundBox::overlaps
// This makes sure that posBits tests 'inside' // This makes sure that posBits tests 'inside'
bool Foam::treeBoundBox::intersects bool Foam::treeBoundBox::intersects
( (
const point& overallStart,
const vector& overallVec,
const point& start, const point& start,
const point& end, const point& end,
point& pt point& pt,
direction& ptOnFaces
) const ) const
{ {
const vector vec(end - start);
const direction endBits = posBits(end); const direction endBits = posBits(end);
pt = start; pt = start;
@ -325,80 +327,106 @@ bool Foam::treeBoundBox::intersects
if (ptBits == 0) if (ptBits == 0)
{ {
// pt inside bb // pt inside bb
ptOnFaces = faceBits(pt);
return true; return true;
} }
if ((ptBits & endBits) != 0) if ((ptBits & endBits) != 0)
{ {
// pt and end in same block outside of bb // pt and end in same block outside of bb
ptOnFaces = faceBits(pt);
return false; return false;
} }
if (ptBits & LEFTBIT) if (ptBits & LEFTBIT)
{ {
// Intersect with plane V=min, n=-1,0,0 // Intersect with plane V=min, n=-1,0,0
if (Foam::mag(vec.x()) > VSMALL) if (Foam::mag(overallVec.x()) > VSMALL)
{ {
scalar s = (min().x() - pt.x())/vec.x(); scalar s = (min().x() - overallStart.x())/overallVec.x();
pt.x() = min().x();
pt.y() = overallStart.y() + overallVec.y()*s;
pt.z() = overallStart.z() + overallVec.z()*s;
}
else
{
// Vector not in x-direction. But still intersecting bb planes.
// So must be close - just snap to bb.
pt.x() = min().x(); pt.x() = min().x();
pt.y() = pt.y() + vec.y()*s;
pt.z() = pt.z() + vec.z()*s;
} }
} }
if (ptBits & RIGHTBIT) else if (ptBits & RIGHTBIT)
{ {
// Intersect with plane V=max, n=1,0,0 // Intersect with plane V=max, n=1,0,0
if (Foam::mag(vec.x()) > VSMALL) if (Foam::mag(overallVec.x()) > VSMALL)
{
scalar s = (max().x() - overallStart.x())/overallVec.x();
pt.x() = max().x();
pt.y() = overallStart.y() + overallVec.y()*s;
pt.z() = overallStart.z() + overallVec.z()*s;
}
else
{ {
scalar s = (max().x() - pt.x())/vec.x();
pt.x() = max().x(); pt.x() = max().x();
pt.y() = pt.y() + vec.y()*s;
pt.z() = pt.z() + vec.z()*s;
} }
} }
else if (ptBits & BOTTOMBIT)
if (ptBits & BOTTOMBIT)
{ {
// Intersect with plane V=min, n=0,-1,0 // Intersect with plane V=min, n=0,-1,0
if (Foam::mag(vec.y()) > VSMALL) if (Foam::mag(overallVec.y()) > VSMALL)
{ {
scalar s = (min().y() - pt.y())/vec.y(); scalar s = (min().y() - overallStart.y())/overallVec.y();
pt.x() = pt.x() + vec.x()*s; pt.x() = overallStart.x() + overallVec.x()*s;
pt.y() = min().y(); pt.y() = min().y();
pt.z() = pt.z() + vec.z()*s; pt.z() = overallStart.z() + overallVec.z()*s;
}
else
{
pt.x() = min().y();
} }
} }
if (ptBits & TOPBIT) else if (ptBits & TOPBIT)
{ {
// Intersect with plane V=max, n=0,1,0 // Intersect with plane V=max, n=0,1,0
if (Foam::mag(vec.y()) > VSMALL) if (Foam::mag(overallVec.y()) > VSMALL)
{
scalar s = (max().y() - overallStart.y())/overallVec.y();
pt.x() = overallStart.x() + overallVec.x()*s;
pt.y() = max().y();
pt.z() = overallStart.z() + overallVec.z()*s;
}
else
{ {
scalar s = (max().y() - pt.y())/vec.y();
pt.x() = pt.x() + vec.x()*s;
pt.y() = max().y(); pt.y() = max().y();
pt.z() = pt.z() + vec.z()*s;
} }
} }
else if (ptBits & BACKBIT)
if (ptBits & BACKBIT)
{ {
// Intersect with plane V=min, n=0,0,-1 // Intersect with plane V=min, n=0,0,-1
if (Foam::mag(vec.z()) > VSMALL) if (Foam::mag(overallVec.z()) > VSMALL)
{
scalar s = (min().z() - overallStart.z())/overallVec.z();
pt.x() = overallStart.x() + overallVec.x()*s;
pt.y() = overallStart.y() + overallVec.y()*s;
pt.z() = min().z();
}
else
{ {
scalar s = (min().z() - pt.z())/vec.z();
pt.x() = pt.x() + vec.x()*s;
pt.y() = pt.y() + vec.y()*s;
pt.z() = min().z(); pt.z() = min().z();
} }
} }
if (ptBits & FRONTBIT) else if (ptBits & FRONTBIT)
{ {
// Intersect with plane V=max, n=0,0,1 // Intersect with plane V=max, n=0,0,1
if (Foam::mag(vec.z()) > VSMALL) if (Foam::mag(overallVec.z()) > VSMALL)
{
scalar s = (max().z() - overallStart.z())/overallVec.z();
pt.x() = overallStart.x() + overallVec.x()*s;
pt.y() = overallStart.y() + overallVec.y()*s;
pt.z() = max().z();
}
else
{ {
scalar s = (max().z() - pt.z())/vec.z();
pt.x() = pt.x() + vec.x()*s;
pt.y() = pt.y() + vec.y()*s;
pt.z() = max().z(); pt.z() = max().z();
} }
} }
@ -406,6 +434,18 @@ bool Foam::treeBoundBox::intersects
} }
bool Foam::treeBoundBox::intersects
(
const point& start,
const point& end,
point& pt
) const
{
direction ptBits;
return intersects(start, end-start, start, end, pt, ptBits);
}
// this.bb fully contains bb // this.bb fully contains bb
bool Foam::treeBoundBox::contains(const treeBoundBox& bb) const bool Foam::treeBoundBox::contains(const treeBoundBox& bb) const
{ {
@ -452,6 +492,40 @@ bool Foam::treeBoundBox::contains(const vector& dir, const point& pt) const
} }
// Code position of pt on bounding box faces
Foam::direction Foam::treeBoundBox::faceBits(const point& pt) const
{
direction faceBits = 0;
if (pt.x() == min().x())
{
faceBits |= LEFTBIT;
}
else if (pt.x() == max().x())
{
faceBits |= RIGHTBIT;
}
if (pt.y() == min().y())
{
faceBits |= BOTTOMBIT;
}
else if (pt.y() == max().y())
{
faceBits |= TOPBIT;
}
if (pt.z() == min().z())
{
faceBits |= BACKBIT;
}
else if (pt.z() == max().z())
{
faceBits |= FRONTBIT;
}
return faceBits;
}
// Code position of point relative to box // Code position of point relative to box
Foam::direction Foam::treeBoundBox::posBits(const point& pt) const Foam::direction Foam::treeBoundBox::posBits(const point& pt) const
{ {
@ -461,7 +535,7 @@ Foam::direction Foam::treeBoundBox::posBits(const point& pt) const
{ {
posBits |= LEFTBIT; posBits |= LEFTBIT;
} }
if (pt.x() > max().x()) else if (pt.x() > max().x())
{ {
posBits |= RIGHTBIT; posBits |= RIGHTBIT;
} }
@ -470,7 +544,7 @@ Foam::direction Foam::treeBoundBox::posBits(const point& pt) const
{ {
posBits |= BOTTOMBIT; posBits |= BOTTOMBIT;
} }
if (pt.y() > max().y()) else if (pt.y() > max().y())
{ {
posBits |= TOPBIT; posBits |= TOPBIT;
} }
@ -479,7 +553,7 @@ Foam::direction Foam::treeBoundBox::posBits(const point& pt) const
{ {
posBits |= BACKBIT; posBits |= BACKBIT;
} }
if (pt.z() > max().z()) else if (pt.z() > max().z())
{ {
posBits |= FRONTBIT; posBits |= FRONTBIT;
} }

View File

@ -120,12 +120,12 @@ public:
enum faceBit enum faceBit
{ {
NOFACE = 0, NOFACE = 0,
LEFTBIT = 0x1 << LEFT, LEFTBIT = 0x1 << LEFT, //1
RIGHTBIT = 0x1 << RIGHT, RIGHTBIT = 0x1 << RIGHT, //2
BOTTOMBIT = 0x1 << BOTTOM, BOTTOMBIT = 0x1 << BOTTOM, //4
TOPBIT = 0x1 << TOP, TOPBIT = 0x1 << TOP, //8
BACKBIT = 0x1 << BACK, BACKBIT = 0x1 << BACK, //16
FRONTBIT = 0x1 << FRONT, FRONTBIT = 0x1 << FRONT, //32
}; };
//- Edges codes. //- Edges codes.
@ -265,9 +265,25 @@ public:
//- Overlaps boundingSphere (centre + sqr(radius))? //- Overlaps boundingSphere (centre + sqr(radius))?
bool overlaps(const point&, const scalar radiusSqr) const; bool overlaps(const point&, const scalar radiusSqr) const;
//- Intersects segment; set point to intersection position, //- Intersects segment; set point to intersection position and face,
// return true if intersection found. // return true if intersection found.
// (intPt argument used during calculation even if not intersecting) // (pt argument used during calculation even if not intersecting).
// Calculates intersections from outside supplied vector
// (overallStart, overallVec). This is so when
// e.g. tracking through lots of consecutive boxes
// (typical octree) we're not accumulating truncation errors. Set
// to start, (end-start) if not used.
bool intersects
(
const point& overallStart,
const vector& overallVec,
const point& start,
const point& end,
point& pt,
direction& ptBits
) const;
//- Like above but does not return faces point is on
bool intersects bool intersects
( (
const point& start, const point& start,
@ -285,6 +301,9 @@ public:
// dir would cause it to go inside. // dir would cause it to go inside.
bool contains(const vector& dir, const point&) const; bool contains(const vector& dir, const point&) const;
//- Code position of pt on bounding box faces
direction faceBits(const point& pt) const;
//- Position of point relative to bounding box //- Position of point relative to bounding box
direction posBits(const point&) const; direction posBits(const point&) const;

View File

@ -238,7 +238,8 @@ void Foam::orientedSurface::propagateOrientation
s, s,
samplePoint, samplePoint,
nearestFaceI, nearestFaceI,
nearestPt nearestPt,
10*SMALL
); );
if (side == triSurfaceTools::UNKNOWN) if (side == triSurfaceTools::UNKNOWN)

View File

@ -2203,7 +2203,8 @@ Foam::triSurfaceTools::sideType Foam::triSurfaceTools::surfaceSide
const triSurface& surf, const triSurface& surf,
const point& sample, const point& sample,
const label nearestFaceI, // nearest face const label nearestFaceI, // nearest face
const point& nearestPoint // nearest point on nearest face const point& nearestPoint, // nearest point on nearest face
const scalar tol
) )
{ {
const labelledTri& f = surf[nearestFaceI]; const labelledTri& f = surf[nearestFaceI];
@ -2217,7 +2218,7 @@ Foam::triSurfaceTools::sideType Foam::triSurfaceTools::surfaceSide
points[f[0]], points[f[0]],
points[f[1]], points[f[1]],
points[f[2]] points[f[2]]
).classify(nearestPoint, 1E-6, nearType, nearLabel); ).classify(nearestPoint, tol, nearType, nearLabel);
if (nearType == triPointRef::NONE) if (nearType == triPointRef::NONE)
{ {

View File

@ -454,13 +454,14 @@ public:
//- Given nearest point (to sample) on surface determines which side //- Given nearest point (to sample) on surface determines which side
// sample is. Uses either face normal, edge normal or point normal // sample is. Uses either face normal, edge normal or point normal
// (non-trivial). Feed in output of e.g. triangle::classify. // (non-trivial). Uses triangle::classify.
static sideType surfaceSide static sideType surfaceSide
( (
const triSurface& surf, const triSurface& surf,
const point& sample, const point& sample,
const label nearestFaceI, // nearest face const label nearestFaceI, // nearest face
const point& nearestPt // nearest point on nearest face const point& nearestPt, // nearest point on nearest face
const scalar tol // tolerance for nearness test.
); );
// Triangulation of faces // Triangulation of faces

View File

@ -22,8 +22,6 @@ License
along with OpenFOAM; if not, write to the Free Software Foundation, along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "triangleFuncs.H" #include "triangleFuncs.H"
@ -31,8 +29,6 @@ Description
#include "treeBoundBox.H" #include "treeBoundBox.H"
#include "SortableList.H" #include "SortableList.H"
#include "boolList.H" #include "boolList.H"
#include "scalar.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@ -170,7 +166,6 @@ bool Foam::triangleFuncs::intersectAxesBundle
} }
// Intersect triangle with bounding box. Return true if // Intersect triangle with bounding box. Return true if
// any of the faces of bb intersect triangle. // any of the faces of bb intersect triangle.
// Note: so returns false if triangle inside bb. // Note: so returns false if triangle inside bb.
@ -262,6 +257,272 @@ bool Foam::triangleFuncs::intersectBb
} }
//// Intersect triangle with bounding box. Return true if
//// any of the faces of bb intersect triangle.
//// Note: so returns false if triangle inside bb.
//bool Foam::triangleFuncs::intersectBbExact
//(
// const point& p0,
// const point& p1,
// const point& p2,
// const treeBoundBox& cubeBb
//)
//{
// const point& min = cubeBb.min();
// const point& max = cubeBb.max();
//
// const point& cube0 = min;
// const point cube1(min.x(), min.y(), max.z());
// const point cube2(max.x(), min.y(), max.z());
// const point cube3(max.x(), min.y(), min.z());
//
// const point cube4(min.x(), max.y(), min.z());
// const point cube5(min.x(), max.y(), max.z());
// const point& cube6 = max;
// const point cube7(max.x(), max.y(), min.z());
//
// // Test intersection of triangle with twelve edges of box.
// {
// triPointRef tri(p0, p1, p2);
// if (tri.intersectionExact(cube0, cube1).hit())
// {
// return true;
// }
// if (tri.intersectionExact(cube1, cube2).hit())
// {
// return true;
// }
// if (tri.intersectionExact(cube2, cube3).hit())
// {
// return true;
// }
// if (tri.intersectionExact(cube3, cube0).hit())
// {
// return true;
// }
//
// if (tri.intersectionExact(cube4, cube5).hit())
// {
// return true;
// }
// if (tri.intersectionExact(cube5, cube6).hit())
// {
// return true;
// }
// if (tri.intersectionExact(cube6, cube7).hit())
// {
// return true;
// }
// if (tri.intersectionExact(cube7, cube4).hit())
// {
// return true;
// }
//
// if (tri.intersectionExact(cube0, cube4).hit())
// {
// return true;
// }
// if (tri.intersectionExact(cube1, cube5).hit())
// {
// return true;
// }
// if (tri.intersectionExact(cube2, cube6).hit())
// {
// return true;
// }
// if (tri.intersectionExact(cube3, cube7).hit())
// {
// return true;
// }
// }
// // Test intersection of triangle edges with bounding box
// {
// triPointRef tri(cube0, cube1, cube2);
// if (tri.intersectionExact(p0, p1).hit())
// {
// return true;
// }
// if (tri.intersectionExact(p1, p2).hit())
// {
// return true;
// }
// if (tri.intersectionExact(p2, p0).hit())
// {
// return true;
// }
// }
// {
// triPointRef tri(cube2, cube3, cube0);
// if (tri.intersectionExact(p0, p1).hit())
// {
// return true;
// }
// if (tri.intersectionExact(p1, p2).hit())
// {
// return true;
// }
// if (tri.intersectionExact(p2, p0).hit())
// {
// return true;
// }
// }
// {
// triPointRef tri(cube4, cube5, cube6);
// if (tri.intersectionExact(p0, p1).hit())
// {
// return true;
// }
// if (tri.intersectionExact(p1, p2).hit())
// {
// return true;
// }
// if (tri.intersectionExact(p2, p0).hit())
// {
// return true;
// }
// }
// {
// triPointRef tri(cube6, cube7, cube4);
// if (tri.intersectionExact(p0, p1).hit())
// {
// return true;
// }
// if (tri.intersectionExact(p1, p2).hit())
// {
// return true;
// }
// if (tri.intersectionExact(p2, p0).hit())
// {
// return true;
// }
// }
//
//
// {
// triPointRef tri(cube4, cube5, cube1);
// if (tri.intersectionExact(p0, p1).hit())
// {
// return true;
// }
// if (tri.intersectionExact(p1, p2).hit())
// {
// return true;
// }
// if (tri.intersectionExact(p2, p0).hit())
// {
// return true;
// }
// }
// {
// triPointRef tri(cube1, cube0, cube4);
// if (tri.intersectionExact(p0, p1).hit())
// {
// return true;
// }
// if (tri.intersectionExact(p1, p2).hit())
// {
// return true;
// }
// if (tri.intersectionExact(p2, p0).hit())
// {
// return true;
// }
// }
// {
// triPointRef tri(cube7, cube6, cube2);
// if (tri.intersectionExact(p0, p1).hit())
// {
// return true;
// }
// if (tri.intersectionExact(p1, p2).hit())
// {
// return true;
// }
// if (tri.intersectionExact(p2, p0).hit())
// {
// return true;
// }
// }
// {
// triPointRef tri(cube2, cube3, cube7);
// if (tri.intersectionExact(p0, p1).hit())
// {
// return true;
// }
// if (tri.intersectionExact(p1, p2).hit())
// {
// return true;
// }
// if (tri.intersectionExact(p2, p0).hit())
// {
// return true;
// }
// }
//
// {
// triPointRef tri(cube0, cube4, cube7);
// if (tri.intersectionExact(p0, p1).hit())
// {
// return true;
// }
// if (tri.intersectionExact(p1, p2).hit())
// {
// return true;
// }
// if (tri.intersectionExact(p2, p0).hit())
// {
// return true;
// }
// }
// {
// triPointRef tri(cube7, cube3, cube0);
// if (tri.intersectionExact(p0, p1).hit())
// {
// return true;
// }
// if (tri.intersectionExact(p1, p2).hit())
// {
// return true;
// }
// if (tri.intersectionExact(p2, p0).hit())
// {
// return true;
// }
// }
// {
// triPointRef tri(cube1, cube5, cube6);
// if (tri.intersectionExact(p0, p1).hit())
// {
// return true;
// }
// if (tri.intersectionExact(p1, p2).hit())
// {
// return true;
// }
// if (tri.intersectionExact(p2, p0).hit())
// {
// return true;
// }
// }
// {
// triPointRef tri(cube6, cube2, cube1);
// if (tri.intersectionExact(p0, p1).hit())
// {
// return true;
// }
// if (tri.intersectionExact(p1, p2).hit())
// {
// return true;
// }
// if (tri.intersectionExact(p2, p0).hit())
// {
// return true;
// }
// }
// return false;
//}
bool Foam::triangleFuncs::intersect bool Foam::triangleFuncs::intersect
( (
const point& va0, const point& va0,
@ -470,145 +731,4 @@ bool Foam::triangleFuncs::intersect
} }
bool Foam::triangleFuncs::classify
(
const point& baseVertex,
const vector& E0,
const vector& E1,
const vector& n,
const point& pInter,
const scalar tol,
label& nearType,
label& nearLabel
)
{
// Get largest component of normal
scalar magX = Foam::mag(n.x());
scalar magY = Foam::mag(n.y());
scalar magZ = Foam::mag(n.z());
label i0 = -1;
if ((magX >= magY) && (magX >= magZ))
{
i0 = 0;
}
else if ((magY >= magX) && (magY >= magZ))
{
i0 = 1;
}
else
{
i0 = 2;
}
// Get other components
label i1 = (i0 + 1) % 3;
label i2 = (i1 + 1) % 3;
scalar u1 = E0[i1];
scalar v1 = E0[i2];
scalar u2 = E1[i1];
scalar v2 = E1[i2];
scalar det = v2*u1 - u2*v1;
scalar u0 = pInter[i1] - baseVertex[i1];
scalar v0 = pInter[i2] - baseVertex[i2];
scalar alpha = 0;
scalar beta = 0;
bool hit = false;
if (Foam::mag(u1) < ROOTVSMALL)
{
beta = u0/u2;
alpha = (v0 - beta*v2)/v1;
hit = ((alpha >= 0) && ((alpha + beta) <= 1));
}
else
{
beta = (v0*u1 - u0*v1)/det;
alpha = (u0 - beta*u2)/u1;
hit = ((alpha >= 0) && ((alpha + beta) <= 1));
}
//
// Now alpha, beta are the coordinates in the triangle local coordinate
// system E0, E1
//
nearType = NONE;
nearLabel = -1;
if (mag(alpha+beta-1) < tol)
{
// On edge between vert 1-2 (=edge 1)
if (mag(alpha) < tol)
{
nearType = POINT;
nearLabel = 2;
}
else if (mag(beta) < tol)
{
nearType = POINT;
nearLabel = 1;
}
else if ((alpha >= 0) && (alpha <= 1) && (beta >= 0) && (beta <= 1))
{
nearType = EDGE;
nearLabel = 1;
}
}
else if (mag(alpha) < tol)
{
// On edge between vert 2-0 (=edge 2)
if (mag(beta) < tol)
{
nearType = POINT;
nearLabel = 0;
}
else if (mag(beta-1) < tol)
{
nearType = POINT;
nearLabel = 2;
}
else if ((beta >= 0) && (beta <= 1))
{
nearType = EDGE;
nearLabel = 2;
}
}
else if (mag(beta) < tol)
{
// On edge between vert 0-1 (= edge 0)
if (mag(alpha) < tol)
{
nearType = POINT;
nearLabel = 0;
}
else if (mag(alpha-1) < tol)
{
nearType = POINT;
nearLabel = 1;
}
else if ((alpha >= 0) && (alpha <= 1))
{
nearType = EDGE;
nearLabel = 0;
}
}
return hit;
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -147,25 +147,6 @@ public:
point& pInter0, point& pInter0,
point& pInter1 point& pInter1
); );
//- Classify point on triangle plane w.r.t. triangle edges.
// - inside/outside (returned)
// - near point (0, 1, 2)
// - near edge (0, 1, 2). Note: edges are counted from starting vertex
// so e.g. edge 2 is from f[2] to f[0]
static bool classify
(
const point& baseVertex,
const vector& E0,
const vector& E1,
const vector& n,
const point& pInter,
const scalar tol,
label& nearType,
label& nearLabel
);
}; };