diff --git a/src/meshTools/searchableSurface/searchableBox.C b/src/meshTools/searchableSurface/searchableBox.C
index 7d639b99f8697205b13c4d6159a395b6630c65a9..5970e8257597703f908c667596a6a4ec8eecb8fc 100644
--- a/src/meshTools/searchableSurface/searchableBox.C
+++ b/src/meshTools/searchableSurface/searchableBox.C
@@ -249,6 +249,41 @@ Foam::tmp<Foam::pointField> Foam::searchableBox::coordinates() const
 }
 
 
+void Foam::searchableBox::boundingSpheres
+(
+    pointField& centres,
+    scalarField& radiusSqr
+) const
+{
+    centres.setSize(size());
+    radiusSqr.setSize(size());
+    radiusSqr = 0.0;
+
+    const pointField pts(treeBoundBox::points());
+    const faceList& fcs = treeBoundBox::faces;
+
+    forAll(fcs, i)
+    {
+        const face& f = fcs[i];
+
+        centres[i] = f.centre(pts);
+        forAll(f, fp)
+        {
+            const point& pt = pts[f[fp]];
+
+            radiusSqr[i] = Foam::max
+            (
+                radiusSqr[i],
+                Foam::magSqr(pt-centres[i])
+            );
+        }
+    }
+
+    // Add a bit to make sure all points are tested inside
+    radiusSqr += Foam::sqr(SMALL);
+}
+
+
 Foam::tmp<Foam::pointField> Foam::searchableBox::points() const
 {
     return treeBoundBox::points();
diff --git a/src/meshTools/searchableSurface/searchableBox.H b/src/meshTools/searchableSurface/searchableBox.H
index 40e5c5d7110ff3fe5a5c5a79cdd6b72c2c66e73e..d677c1b87de1f59b4c884d1b1fd74c8638095450 100644
--- a/src/meshTools/searchableSurface/searchableBox.H
+++ b/src/meshTools/searchableSurface/searchableBox.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2012 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -129,6 +129,14 @@ public:
         //  Usually the element centres (should be of length size()).
         virtual tmp<pointField> coordinates() const;
 
+        //- Get bounding spheres (centre and radius squared), one per element.
+        //  Any point on element is guaranteed to be inside.
+        virtual void boundingSpheres
+        (
+            pointField& centres,
+            scalarField& radiusSqr
+        ) const;
+
         //- Get the points that define the surface.
         virtual tmp<pointField> points() const;
 
diff --git a/src/meshTools/searchableSurface/searchableCylinder.C b/src/meshTools/searchableSurface/searchableCylinder.C
index 70d674d521b580acae0845f51890be762d07ce73..7657e883c98acb6c2163fde2ac20d664a94846da 100644
--- a/src/meshTools/searchableSurface/searchableCylinder.C
+++ b/src/meshTools/searchableSurface/searchableCylinder.C
@@ -47,6 +47,23 @@ Foam::tmp<Foam::pointField> Foam::searchableCylinder::coordinates() const
 }
 
 
+void Foam::searchableCylinder::boundingSpheres
+(
+    pointField& centres,
+    scalarField& radiusSqr
+) const
+{
+    centres.setSize(1);
+    centres[0] = 0.5*(point1_ + point2_);
+
+    radiusSqr.setSize(1);
+    radiusSqr[0] = Foam::magSqr(point1_-centres[0]) + Foam::sqr(radius_);
+
+    // Add a bit to make sure all points are tested inside
+    radiusSqr += Foam::sqr(SMALL);
+}
+
+
 Foam::tmp<Foam::pointField> Foam::searchableCylinder::points() const
 {
     tmp<pointField> tPts(new pointField(2));
diff --git a/src/meshTools/searchableSurface/searchableCylinder.H b/src/meshTools/searchableSurface/searchableCylinder.H
index 0bb570e4806b5ee41ae936bd12d05aa6381a39d7..ccf6850dc1be487f7be92f8e02dbb6a9ed1a62c5 100644
--- a/src/meshTools/searchableSurface/searchableCylinder.H
+++ b/src/meshTools/searchableSurface/searchableCylinder.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2012 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -154,6 +154,14 @@ public:
         //  Usually the element centres (should be of length size()).
         virtual tmp<pointField> coordinates() const;
 
+        //- Get bounding spheres (centre and radius squared), one per element.
+        //  Any point on element is guaranteed to be inside.
+        virtual void boundingSpheres
+        (
+            pointField& centres,
+            scalarField& radiusSqr
+        ) const;
+
         //- Get the points that define the surface.
         virtual tmp<pointField> points() const;
 
diff --git a/src/meshTools/searchableSurface/searchablePlane.C b/src/meshTools/searchableSurface/searchablePlane.C
index a76821d45740e53e4b571668977360b6bf229481..e6c9668b1f134558c972d7301a29afe64d648cab 100644
--- a/src/meshTools/searchableSurface/searchablePlane.C
+++ b/src/meshTools/searchableSurface/searchablePlane.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -134,6 +134,20 @@ const Foam::wordList& Foam::searchablePlane::regions() const
 }
 
 
+void Foam::searchablePlane::boundingSpheres
+(
+    pointField& centres,
+    scalarField& radiusSqr
+) const
+{
+    centres.setSize(1);
+    centres[0] = refPoint();
+
+    radiusSqr.setSize(1);
+    radiusSqr[0] = Foam::sqr(GREAT);
+}
+
+
 void Foam::searchablePlane::findNearest
 (
     const pointField& samples,
diff --git a/src/meshTools/searchableSurface/searchablePlane.H b/src/meshTools/searchableSurface/searchablePlane.H
index cc64844d0df9b9da1844ecae8e94057901dbde2c..a79f93f90292ae931e00d15fcb42c1c199a69733 100644
--- a/src/meshTools/searchableSurface/searchablePlane.H
+++ b/src/meshTools/searchableSurface/searchablePlane.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2012 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -130,6 +130,15 @@ public:
             return tCtrs;
         }
 
+        //- Get bounding spheres (centre and radius squared), one per element.
+        //  Any point on element is guaranteed to be inside.
+        //  Note: radius limited to sqr(GREAT)
+        virtual void boundingSpheres
+        (
+            pointField& centres,
+            scalarField& radiusSqr
+        ) const;
+
         //- Get the points that define the surface.
         virtual tmp<pointField> points() const
         {
diff --git a/src/meshTools/searchableSurface/searchablePlate.C b/src/meshTools/searchableSurface/searchablePlate.C
index 37404db05117444141a9a024425f66ad2816ac78..0ed10bd675c123ca4d77374a0d8546c85646d149 100644
--- a/src/meshTools/searchableSurface/searchablePlate.C
+++ b/src/meshTools/searchableSurface/searchablePlate.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2012 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -274,6 +274,71 @@ const Foam::wordList& Foam::searchablePlate::regions() const
 }
 
 
+Foam::tmp<Foam::pointField> Foam::searchablePlate::coordinates() const
+{
+    return tmp<pointField>(new pointField(1, origin_ + 0.5*span_));
+}
+
+
+void Foam::searchablePlate::boundingSpheres
+(
+    pointField& centres,
+    scalarField& radiusSqr
+) const
+{
+    centres.setSize(1);
+    centres[0] = origin_ + 0.5*span_;
+
+    radiusSqr.setSize(1);
+    radiusSqr[0] = Foam::magSqr(0.5*span_);
+
+    // Add a bit to make sure all points are tested inside
+    radiusSqr += Foam::sqr(SMALL);
+}
+
+
+Foam::tmp<Foam::pointField> Foam::searchablePlate::points() const
+{
+    tmp<pointField> tPts(new pointField(4));
+    pointField& pts = tPts();
+
+    pts[0] = origin_;
+    pts[2] = origin_ + span_;
+
+    if (span_.x() < span_.y() && span_.x() < span_.z())
+    {
+        pts[1] = origin_ + point(0, span_.y(), 0);
+        pts[3] = origin_ + point(0, 0, span_.z());
+    }
+    else if (span_.y() < span_.z())
+    {
+        pts[1] = origin_ + point(span_.x(), 0, 0);
+        pts[3] = origin_ + point(0, 0, span_.z());
+    }
+    else
+    {
+        pts[1] = origin_ + point(span_.x(), 0, 0);
+        pts[3] = origin_ + point(0, span_.y(), 0);
+    }
+
+    return tPts;
+}
+
+
+bool Foam::searchablePlate::overlaps(const boundBox& bb) const
+{
+    return
+    (
+        (origin_.x() + span_.x()) >= bb.min().x()
+     && origin_.x() <= bb.max().x()
+     && (origin_.y() + span_.y()) >= bb.min().y()
+     && origin_.y() <= bb.max().y()
+     && (origin_.z() + span_.z()) >= bb.min().z()
+     && origin_.z() <= bb.max().z()
+    );
+}
+
+
 void Foam::searchablePlate::findNearest
 (
     const pointField& samples,
diff --git a/src/meshTools/searchableSurface/searchablePlate.H b/src/meshTools/searchableSurface/searchablePlate.H
index 86b0785077370effb75ecb83c13091d2506c6fcf..af2d732ff635ecbc0aaa4f1ce3272138568e08aa 100644
--- a/src/meshTools/searchableSurface/searchablePlate.H
+++ b/src/meshTools/searchableSurface/searchablePlate.H
@@ -145,53 +145,21 @@ public:
 
         //- Get representative set of element coordinates
         //  Usually the element centres (should be of length size()).
-        virtual tmp<pointField> coordinates() const
-        {
-            tmp<pointField> tCtrs(new pointField(1, origin_ + 0.5*span_));
-            return tCtrs;
-        }
-
-        //- Get the points that define the surface.
-        virtual tmp<pointField> points() const
-        {
-            tmp<pointField> tPts(new pointField(4));
-            pointField& pts = tPts();
+        virtual tmp<pointField> coordinates() const;
 
-            pts[0] = origin_;
-            pts[2] = origin_ + span_;
-
-            if (span_.x() < span_.y() && span_.x() < span_.z())
-            {
-                pts[1] = origin_ + point(0, span_.y(), 0);
-                pts[3] = origin_ + point(0, 0, span_.z());
-            }
-            else if (span_.y() < span_.z())
-            {
-                pts[1] = origin_ + point(span_.x(), 0, 0);
-                pts[3] = origin_ + point(0, 0, span_.z());
-            }
-            else
-            {
-                pts[1] = origin_ + point(span_.x(), 0, 0);
-                pts[3] = origin_ + point(0, span_.y(), 0);
-            }
+        //- Get bounding spheres (centre and radius squared), one per element.
+        //  Any point on element is guaranteed to be inside.
+        virtual void boundingSpheres
+        (
+            pointField& centres,
+            scalarField& radiusSqr
+        ) const;
 
-            return tPts;
-        }
+        //- Get the points that define the surface.
+        virtual tmp<pointField> points() const;
 
         //- Does any part of the surface overlap the supplied bound box?
-        virtual bool overlaps(const boundBox& bb) const
-        {
-            return
-            (
-                (origin_.x() + span_.x()) >= bb.min().x()
-             && origin_.x() <= bb.max().x()
-             && (origin_.y() + span_.y()) >= bb.min().y()
-             && origin_.y() <= bb.max().y()
-             && (origin_.z() + span_.z()) >= bb.min().z()
-             && origin_.z() <= bb.max().z()
-            );
-        }
+        virtual bool overlaps(const boundBox& bb) const;
 
 
         // Multiple point queries.
diff --git a/src/meshTools/searchableSurface/searchableSphere.C b/src/meshTools/searchableSurface/searchableSphere.C
index c367c6281babd1d176a5845146cdce897d6b6c93..e4eae4ab27452e40e4dcb1977754ebc5b13d9f1f 100644
--- a/src/meshTools/searchableSurface/searchableSphere.C
+++ b/src/meshTools/searchableSurface/searchableSphere.C
@@ -185,6 +185,23 @@ const Foam::wordList& Foam::searchableSphere::regions() const
 
 
 
+void Foam::searchableSphere::boundingSpheres
+(
+    pointField& centres,
+    scalarField& radiusSqr
+) const
+{
+    centres.setSize(1);
+    centres[0] = centre_;
+
+    radiusSqr.setSize(1);
+    radiusSqr[0] = Foam::sqr(radius_);
+
+    // Add a bit to make sure all points are tested inside
+    radiusSqr += Foam::sqr(SMALL);
+}
+
+
 void Foam::searchableSphere::findNearest
 (
     const pointField& samples,
diff --git a/src/meshTools/searchableSurface/searchableSphere.H b/src/meshTools/searchableSurface/searchableSphere.H
index 5d46f8ad4b5128e3d6748e2a8d3009042a6d8ab0..50900f936185c9a884fca3ef3d338452d2be1aee 100644
--- a/src/meshTools/searchableSurface/searchableSphere.H
+++ b/src/meshTools/searchableSurface/searchableSphere.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2012 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -60,7 +60,7 @@ private:
         //- Centre point
         const point centre_;
 
-        //- Radius squared
+        //- Radius
         const scalar radius_;
 
         //- Names of regions
@@ -139,6 +139,14 @@ public:
             return tCtrs;
         }
 
+        //- Get bounding spheres (centre and radius squared), one per element.
+        //  Any point on element is guaranteed to be inside.
+        virtual void boundingSpheres
+        (
+            pointField& centres,
+            scalarField& radiusSqr
+        ) const;
+
         //- Get the points that define the surface.
         virtual tmp<pointField> points() const
         {
diff --git a/src/meshTools/searchableSurface/searchableSurface.H b/src/meshTools/searchableSurface/searchableSurface.H
index 90224ae9ce54c517b3cdf589467b3533607d930e..6a2adcc9466561b1366d6b642a15c5e6ee56cf28 100644
--- a/src/meshTools/searchableSurface/searchableSurface.H
+++ b/src/meshTools/searchableSurface/searchableSurface.H
@@ -190,6 +190,14 @@ public:
         //  Usually the element centres (should be of length size()).
         virtual tmp<pointField> coordinates() const = 0;
 
+        //- Get bounding spheres (centre and radius squared), one per element.
+        //  Any point on element is guaranteed to be inside.
+        virtual void boundingSpheres
+        (
+            pointField& centres,
+            scalarField& radiusSqr
+        ) const = 0;
+
         //- Get the points that define the surface.
         virtual tmp<pointField> points() const = 0;
 
diff --git a/src/meshTools/searchableSurface/searchableSurfaceCollection.C b/src/meshTools/searchableSurface/searchableSurfaceCollection.C
index 3a02066afae137a1d251eaf982bd5db3cf3a82da..3aad85f72d7bfd552b681aa6cb1f359bd25e89f7 100644
--- a/src/meshTools/searchableSurface/searchableSurfaceCollection.C
+++ b/src/meshTools/searchableSurface/searchableSurfaceCollection.C
@@ -354,6 +354,42 @@ Foam::searchableSurfaceCollection::coordinates() const
 }
 
 
+void Foam::searchableSurfaceCollection::boundingSpheres
+(
+    pointField& centres,
+    scalarField& radiusSqr
+) const
+{
+    centres.setSize(size());
+    radiusSqr.setSize(centres.size());
+
+    // Append individual coordinates
+    label coordI = 0;
+
+    forAll(subGeom_, surfI)
+    {
+        scalar maxScale = cmptMax(scale_[surfI]);
+
+        pointField subCentres;
+        scalarField subRadiusSqr;
+        subGeom_[surfI].boundingSpheres(subCentres, subRadiusSqr);
+
+        forAll(subCentres, i)
+        {
+            centres[coordI++] = transform_[surfI].globalPosition
+            (
+                cmptMultiply
+                (
+                    subCentres[i],
+                    scale_[surfI]
+                )
+            );
+            radiusSqr[coordI++] = maxScale*subRadiusSqr[i];
+        }
+    }
+}
+
+
 Foam::tmp<Foam::pointField>
 Foam::searchableSurfaceCollection::points() const
 {
diff --git a/src/meshTools/searchableSurface/searchableSurfaceCollection.H b/src/meshTools/searchableSurface/searchableSurfaceCollection.H
index 53e677eaa656ce4adcf6b5b8c8119bd55f0f441d..dd8a21664b9823f4f27d52dd24ea8866c96e438d 100644
--- a/src/meshTools/searchableSurface/searchableSurfaceCollection.H
+++ b/src/meshTools/searchableSurface/searchableSurfaceCollection.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2012 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -176,6 +176,14 @@ public:
         //  Usually the element centres (should be of length size()).
         virtual tmp<pointField> coordinates() const;
 
+        //- Get bounding spheres (centre and radius squared), one per element.
+        //  Any point on element is guaranteed to be inside.
+        virtual void boundingSpheres
+        (
+            pointField& centres,
+            scalarField& radiusSqr
+        ) const;
+
         //- Get the points that define the surface.
         virtual tmp<pointField> points() const;
 
diff --git a/src/meshTools/searchableSurface/searchableSurfaceWithGaps.H b/src/meshTools/searchableSurface/searchableSurfaceWithGaps.H
index 1344cda2d9ed5fc4da35dcea0e3ca7a57e1284e2..d07d331c8a56a442c5b1b9c435205aebf98f90a6 100644
--- a/src/meshTools/searchableSurface/searchableSurfaceWithGaps.H
+++ b/src/meshTools/searchableSurface/searchableSurfaceWithGaps.H
@@ -156,6 +156,17 @@ public:
             return surface().coordinates();
         }
 
+        //- Get bounding spheres (centre and radius squared), one per element.
+        //  Any point on element is guaranteed to be inside.
+        virtual void boundingSpheres
+        (
+            pointField& centres,
+            scalarField& radiusSqr
+        ) const
+        {
+            surface().boundingSpheres(centres, radiusSqr);
+        }
+
         //- Get the points that define the surface.
         virtual tmp<pointField> points() const
         {
diff --git a/src/meshTools/searchableSurface/triSurfaceMesh.C b/src/meshTools/searchableSurface/triSurfaceMesh.C
index 125450603b06524ee9b9509224cffe2cc2cf1fa9..7b6b8ad6ad9785eb428197e4a10b2062993e74d5 100644
--- a/src/meshTools/searchableSurface/triSurfaceMesh.C
+++ b/src/meshTools/searchableSurface/triSurfaceMesh.C
@@ -145,10 +145,12 @@ bool Foam::triSurfaceMesh::addFaceToEdge
 
 bool Foam::triSurfaceMesh::isSurfaceClosed() const
 {
+    const pointField& pts = triSurface::points();
+
     // Construct pointFaces. Let's hope surface has compact point
     // numbering ...
     labelListList pointFaces;
-    invertManyToMany(points()().size(), *this, pointFaces);
+    invertManyToMany(pts.size(), *this, pointFaces);
 
     // Loop over all faces surrounding point. Count edges emanating from point.
     // Every edge should be used by two faces exactly.
@@ -241,7 +243,9 @@ Foam::triSurfaceMesh::triSurfaceMesh(const IOobject& io, const triSurface& s)
     minQuality_(-1),
     surfaceClosed_(-1)
 {
-    bounds() = boundBox(points());
+    const pointField& pts = triSurface::points();
+
+    bounds() = boundBox(pts);
 }
 
 
@@ -287,7 +291,9 @@ Foam::triSurfaceMesh::triSurfaceMesh(const IOobject& io)
     minQuality_(-1),
     surfaceClosed_(-1)
 {
-    bounds() = boundBox(points());
+    const pointField& pts = triSurface::points();
+
+    bounds() = boundBox(pts);
 }
 
 
@@ -347,7 +353,9 @@ Foam::triSurfaceMesh::triSurfaceMesh
         triSurface::scalePoints(scaleFactor);
     }
 
-    bounds() = boundBox(points());
+    const pointField& pts = triSurface::points();
+
+    bounds() = boundBox(pts);
 
     // Have optional minimum quality for normal calculation
     if (dict.readIfPresent("minQuality", minQuality_) && minQuality_ > 0)
@@ -393,6 +401,34 @@ Foam::tmp<Foam::pointField> Foam::triSurfaceMesh::coordinates() const
 }
 
 
+void Foam::triSurfaceMesh::boundingSpheres
+(
+    pointField& centres,
+    scalarField& radiusSqr
+) const
+{
+    centres = coordinates();
+    radiusSqr.setSize(size());
+    radiusSqr = 0.0;
+
+    const pointField& pts = triSurface::points();
+
+    forAll(*this, faceI)
+    {
+        const labelledTri& f = triSurface::operator[](faceI);
+        const point& fc = centres[faceI];
+        forAll(f, fp)
+        {
+            const point& pt = pts[f[fp]];
+            radiusSqr[faceI] = max(radiusSqr[faceI], Foam::magSqr(fc-pt));
+        }
+    }
+
+    // Add a bit to make sure all points are tested inside
+    radiusSqr += Foam::sqr(SMALL);
+}
+
+
 Foam::tmp<Foam::pointField> Foam::triSurfaceMesh::points() const
 {
     return triSurface::points();
@@ -606,6 +642,7 @@ void Foam::triSurfaceMesh::getNormal
 ) const
 {
     const triSurface& s = static_cast<const triSurface&>(*this);
+    const pointField& pts = s.points();
 
     normal.setSize(info.size());
 
@@ -621,9 +658,9 @@ void Foam::triSurfaceMesh::getNormal
             if (info[i].hit())
             {
                 label faceI = info[i].index();
-                normal[i] = s[faceI].normal(points());
+                normal[i] = s[faceI].normal(pts);
 
-                scalar qual = s[faceI].tri(points()).quality();
+                scalar qual = s[faceI].tri(pts).quality();
 
                 if (qual < minQuality_)
                 {
@@ -633,11 +670,11 @@ void Foam::triSurfaceMesh::getNormal
                     forAll(fFaces, j)
                     {
                         label nbrI = fFaces[j];
-                        scalar nbrQual = s[nbrI].tri(points()).quality();
+                        scalar nbrQual = s[nbrI].tri(pts).quality();
                         if (nbrQual > qual)
                         {
                             qual = nbrQual;
-                            normal[i] = s[nbrI].normal(points());
+                            normal[i] = s[nbrI].normal(pts);
                         }
                     }
                 }
@@ -662,7 +699,7 @@ void Foam::triSurfaceMesh::getNormal
                 //normal[i] = faceNormals()[faceI];
 
                 //- Uncached
-                normal[i] = s[faceI].normal(points());
+                normal[i] = s[faceI].normal(pts);
                 normal[i] /= mag(normal[i]) + VSMALL;
             }
             else
diff --git a/src/meshTools/searchableSurface/triSurfaceMesh.H b/src/meshTools/searchableSurface/triSurfaceMesh.H
index fa7e9e511c769a0d37b7eb6d9b9a885ecaa367cd..e6ecd39594aa03cb67c7e97be15ab93203cdf9a4 100644
--- a/src/meshTools/searchableSurface/triSurfaceMesh.H
+++ b/src/meshTools/searchableSurface/triSurfaceMesh.H
@@ -187,6 +187,14 @@ public:
             //  Usually the element centres (should be of length size()).
             virtual tmp<pointField> coordinates() const;
 
+            //- Get bounding spheres (centre and radius squared). Any point
+            //  on surface is guaranteed to be inside.
+            virtual void boundingSpheres
+            (
+                pointField& centres,
+                scalarField& radiusSqr
+            ) const;
+
             //- Get the points that define the surface.
             virtual tmp<pointField> points() const;