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::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::octreeDataCell::overlaps ( const label index, const treeBoundBox& cubeBb ) const { return cubeBb.overlaps(bbs_[index]); }
bool Foam::octreeDataBoundBox::overlaps ( const label index, const treeBoundBox& sampleBb ) const { return sampleBb.overlaps(allBb_[index]); }
// Check if any point on shape is inside cubeBb. bool Foam::treeDataPoint::overlaps ( const label index, const treeBoundBox& cubeBb ) const { return cubeBb.contains(points_[index]); }
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; } } }
bool Foam::treeDataPoint::overlaps ( const label index, const treeBoundBox& cubeBb ) const { label pointi = (useSubset_ ? pointLabels_[index] : index); return cubeBb.contains(points_[pointi]); }
treeNode<Type>::treeNode(const treeBoundBox& bb) : treeElem<Type>(bb), treeNodeName(), mid_(bb.mid()), subNodeTypes_(0), volType_(0) { for(label octant=0; octant<8; octant++) { subNodes_[octant] = NULL; setVolType(octant, octree<Type>::UNKNOWN); } }
void dumpBox(const treeBoundBox& bb, const fileName& fName) { OFstream str(fName); Info<< "Dumping bounding box " << bb << " as lines to obj file " << str.name() << endl; pointField boxPoints(bb.points()); forAll(boxPoints, i) { meshTools::writeOBJ(str, boxPoints[i]); }
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(); } } } } }
const treeLeaf<Type>* treeNode<Type>::findLeafLineOctant ( const int level, const Type& shapes, const label octant, const vector& direction, point& start, const point& end ) const { static const char* functionName = "treeNode<Type>::findLeafLineOctant" "(const int, const Type&, const label, const vector&," " point&, const point&)"; if (debug & 2) { space(Pout, 2*level); Pout<< "findLeafLineOctant : bb:" << this->bb() << " start:" << start << " end:" << end << " mid:" << mid() << " Searching octant:" << octant << endl; } if (subNodes()[octant]) { if (isNode(octant)) { // Node: recurse into subnodes const treeNode<Type>* subNodePtr = getNodePtr(octant); if (subNodePtr->bb().contains(direction, start)) { // Search on lower level const treeLeaf<Type>* subLeafPtr = subNodePtr->findLeafLine ( level + 1, shapes, start, end ); if (debug & 2) { space(Pout, 2*level); Pout<< "findLeafLineOctant : bb:" << this->bb() << " returning from sub treeNode" << " with start:" << start << " subLeaf:" << long(subLeafPtr) << endl; } return subLeafPtr; } else { FatalErrorIn(functionName) << "Sub node " << subNodePtr->bb() << " at octant " << octant << " does not contain start " << start << abort(FatalError); } } else { // Leaf const treeLeaf<Type>* subLeafPtr = getLeafPtr(octant); if (subLeafPtr->bb().contains(direction, start)) { // Step to end of subleaf bb point tmp; if ( !subLeafPtr->bb().intersects ( end, start, tmp ) ) { FatalErrorIn(functionName) << "Sub leaf contains start " << start << " but line does not intersect its bb " << subLeafPtr->bb() << abort(FatalError); } start = tmp; if (debug & 2) { space(Pout, 2*level); Pout<< "findLeafLineOctant : returning from intersecting" << " treeLeaf " << subLeafPtr->bb() << " with start:" << start << " subLeaf:" << long(subLeafPtr) << endl; } return subLeafPtr; } else { FatalErrorIn(functionName) << "Sub leaf " << subLeafPtr->bb() << " at octant " << octant << " does not contain start " << start << abort(FatalError); } } } else { // Empty subNode. Transfer across. const treeBoundBox emptyBb = this->bb().subBbox(mid(), octant); if (emptyBb.contains(direction, start)) { if (debug & 2) { space(Pout, 2*level); Pout<< "findLeafLineOctant : Empty node. Octant:" << octant << " start:" << start << " bb:" << this->bb() << " emptyBb:" << emptyBb << endl; } // Update start by clipping to emptyBb point tmp; if ( !emptyBb.intersects ( end, start, tmp ) ) { FatalErrorIn(functionName) << "Empty node contains start " << start << " but line does not intersect its (calculated)" << " bb " << emptyBb << endl << "This might be due to truncation error" << abort(FatalError); } start = tmp; if (debug & 2) { space(Pout, 2*level); Pout<< "findLeafLineOctant : returning from intersecting with" << " empty " << emptyBb << " with start:" << start << " subLeaf:" << 0 << endl; } return NULL; } else { FatalErrorIn(functionName) << "Empty node " << emptyBb << " at octant " << octant << " does not contain start " << start << abort(FatalError); } } FatalErrorIn(functionName) << "Octant " << octant << " of cube " << this->bb() << " does not contain start " << start << abort(FatalError); return NULL; }
// 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; }
} // All the info for nearest. Construct to miss List<mappedPatchBase::nearInfo> nearest(this->size()); const polyPatch& pp = bm[patchi]; if (pp.size() > 0) { labelList bndFaces(pp.size()); forAll(bndFaces, i) { bndFaces[i] = pp.start() + i; } treeBoundBox overallBb(pp.points()); Random rndGen(123456); overallBb = overallBb.extend(rndGen, 1e-4); overallBb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); overallBb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); const indexedOctree<treeDataFace> boundaryTree ( treeDataFace // all information needed to search faces ( false, // do not cache bb mesh, bndFaces // patch faces only ), overallBb, // overall search domain 8, // maxLevel