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; } }
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; } } }
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(); } } } } }
// 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; }