bool Foam::octreeDataBoundBox::findTightest
(
    const label index,
    const point& sample,
    treeBoundBox& tightest
) const
{
    // Get furthest away vertex
    point myNear, myFar;
    allBb_[index].calcExtremities(sample, myNear, myFar);

    const point dist = myFar - sample;
    scalar myFarDist = mag(dist);

    point tightestNear, tightestFar;
    tightest.calcExtremities(sample, tightestNear, tightestFar);

    scalar tightestFarDist = mag(tightestFar - sample);

    if (tightestFarDist < myFarDist)
    {
        // Keep current tightest.
        return false;
    }
    else
    {
        // Construct bb around sample and myFar
        const point dist2(fabs(dist.x()), fabs(dist.y()), fabs(dist.z()));

        tightest.min() = sample - dist2;
        tightest.max() = sample + dist2;

        return true;
    }
}
bool Foam::treeLeaf<Foam::octreeDataPoint>::findNearest
(
    const octreeDataPoint& shapes,
    const point& sample,
    treeBoundBox& tightest,
    label& tightestI,
    scalar& tightestDist
) const
{
    // Some aliases
    const pointField& points = shapes.points();
    point& tMin = tightest.min();
    point& tMax = tightest.max();

    scalar minDist2 = sqr(tightestDist);

    label minIndex = -1;
    forAll(indices_, i)
    {
        label pointi = indices_[i];
        scalar dist = magSqr(points[pointi] - sample);

        if (dist < minDist2)
        {
            minDist2 = dist;
            minIndex = pointi;
        }
    }
예제 #3
0
bool Foam::treeLeaf<Foam::octreeDataTriSurface>::findNearest
(
    const octreeDataTriSurface& shapes,
    const point& sample,
    treeBoundBox& tightest,
    label& tightestI,
    scalar& tightestDist
) const
{
    // Some aliases
    const treeBoundBoxList& allBb = shapes.allBb();
    point& min = tightest.min();
    point& max = tightest.max();

    point nearest;

    bool changed = false;
    forAll(indices_, i)
    {
        label faceI = indices_[i];

        // Quick rejection test.
        if (tightest.overlaps(allBb[faceI]))
        {
            // Full calculation
            scalar dist = shapes.calcNearest(faceI, sample, nearest);

            if (dist < tightestDist)
            {
                // Update bb (centered around sample, span is dist)
                min.x() = sample.x() - dist;
                min.y() = sample.y() - dist;
                min.z() = sample.z() - dist;

                max.x() = sample.x() + dist;
                max.y() = sample.y() + dist;
                max.z() = sample.z() + dist;

                tightestI = faceI;
                tightestDist = dist;

                changed = true;
            }
        }
    }
예제 #4
0
void Foam::treeDataPoint::findNearestOp::operator()
(
    const labelUList& indices,
    const linePointRef& ln,

    treeBoundBox& tightest,
    label& minIndex,
    point& linePoint,
    point& nearestPoint
) const
{
    const treeDataPoint& shape = tree_.shapes();

    // Best so far
    scalar nearestDistSqr = GREAT;
    if (minIndex >= 0)
    {
        nearestDistSqr = magSqr(linePoint - nearestPoint);
    }

    forAll(indices, i)
    {
        const label index = indices[i];
        label pointi =
        (
            shape.useSubset()
          ? shape.pointLabels()[index]
          : index
        );

        const point& shapePt = shape.points()[pointi];

        if (tightest.contains(shapePt))
        {
            // Nearest point on line
            pointHit pHit = ln.nearestDist(shapePt);
            scalar distSqr = sqr(pHit.distance());

            if (distSqr < nearestDistSqr)
            {
                nearestDistSqr = distSqr;
                minIndex = index;
                linePoint = pHit.rawPoint();
                nearestPoint = shapePt;

                {
                    point& minPt = tightest.min();
                    minPt = min(ln.start(), ln.end());
                    minPt.x() -= pHit.distance();
                    minPt.y() -= pHit.distance();
                    minPt.z() -= pHit.distance();
                }
                {
                    point& maxPt = tightest.max();
                    maxPt = max(ln.start(), ln.end());
                    maxPt.x() += pHit.distance();
                    maxPt.y() += pHit.distance();
                    maxPt.z() += pHit.distance();
                }
            }
        }
    }
}
예제 #5
0
// 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::intersectBb
(
    const point& p0,
    const point& p1,
    const point& p2,
    const treeBoundBox& cubeBb
)
{
    const vector p10 = p1 - p0;
    const vector p20 = p2 - p0;

    // cubeBb points; counted as if cell with vertex0 at cubeBb.min().
    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  cube7(max.x(), max.y(), min.z());

    //
    // Intersect all 12 edges of cube with triangle
    //

    point pInter;
    pointField origin(4);
    // edges in x direction
    origin[0] = cube0;
    origin[1] = cube1;
    origin[2] = cube5;
    origin[3] = cube4;

    scalar maxSx = max.x() - min.x();

    if (intersectAxesBundle(p0, p10, p20, 0, origin, maxSx, pInter))
    {
        return true;
    }

    // edges in y direction
    origin[0] = cube0;
    origin[1] = cube1;
    origin[2] = cube2;
    origin[3] = cube3;

    scalar maxSy = max.y() - min.y();

    if (intersectAxesBundle(p0, p10, p20, 1, origin, maxSy, pInter))
    {
        return true;
    }

    // edges in z direction
    origin[0] = cube0;
    origin[1] = cube3;
    origin[2] = cube7;
    origin[3] = cube4;

    scalar maxSz = max.z() - min.z();

    if (intersectAxesBundle(p0, p10, p20, 2, origin, maxSz, pInter))
    {
        return true;
    }


    // Intersect triangle edges with bounding box
    if (cubeBb.intersects(p0, p1, pInter))
    {
        return true;
    }
    if (cubeBb.intersects(p1, p2, pInter))
    {
        return true;
    }
    if (cubeBb.intersects(p2, p0, pInter))
    {
        return true;
    }

    return false;
}