diff --git a/src/meshTools/indexedOctree/treeDataEdge.C b/src/meshTools/indexedOctree/treeDataEdge.C
index 4d0b9b4d813624bb635424c125b1f61e7e3f0d07..ffd0969e8f5612ab5d838bf0a7b851c137e1761b 100644
--- a/src/meshTools/indexedOctree/treeDataEdge.C
+++ b/src/meshTools/indexedOctree/treeDataEdge.C
@@ -105,6 +105,17 @@ Foam::treeDataEdge::findNearestOp::findNearestOp
 {}
 
 
+Foam::treeDataEdge::findNearestOpSubset::findNearestOpSubset
+(
+    const indexedOctree<treeDataEdge>& tree,
+    DynamicList<label>& shapeMask
+)
+:
+    tree_(tree),
+    shapeMask_(shapeMask)
+{}
+
+
 Foam::treeDataEdge::findIntersectOp::findIntersectOp
 (
     const indexedOctree<treeDataEdge>& tree
@@ -270,6 +281,105 @@ void Foam::treeDataEdge::findNearestOp::operator()
 }
 
 
+void Foam::treeDataEdge::findNearestOpSubset::operator()
+(
+    const labelUList& indices,
+    const point& sample,
+
+    scalar& nearestDistSqr,
+    label& minIndex,
+    point& nearestPoint
+) const
+{
+    const treeDataEdge& shape = tree_.shapes();
+
+    forAll(indices, i)
+    {
+        const label index = indices[i];
+        const label edgeIndex = shape.edgeLabels()[index];
+
+        if (!shapeMask_.empty() && findIndex(shapeMask_, edgeIndex) != -1)
+        {
+            continue;
+        }
+
+        const edge& e = shape.edges()[edgeIndex];
+
+        pointHit nearHit = e.line(shape.points()).nearestDist(sample);
+
+        scalar distSqr = sqr(nearHit.distance());
+
+        if (distSqr < nearestDistSqr)
+        {
+            nearestDistSqr = distSqr;
+            minIndex = index;
+            nearestPoint = nearHit.rawPoint();
+        }
+    }
+}
+
+
+void Foam::treeDataEdge::findNearestOpSubset::operator()
+(
+    const labelUList& indices,
+    const linePointRef& ln,
+
+    treeBoundBox& tightest,
+    label& minIndex,
+    point& linePoint,
+    point& nearestPoint
+) const
+{
+    const treeDataEdge& shape = tree_.shapes();
+
+    // Best so far
+    scalar nearestDistSqr = magSqr(linePoint - nearestPoint);
+
+    forAll(indices, i)
+    {
+        const label index = indices[i];
+        const label edgeIndex = shape.edgeLabels()[index];
+
+        if (!shapeMask_.empty() && findIndex(shapeMask_, edgeIndex) != -1)
+        {
+            continue;
+        }
+
+        const edge& e = shape.edges()[edgeIndex];
+
+        // Note: could do bb test ? Worthwhile?
+
+        // Nearest point on line
+        point ePoint, lnPt;
+        scalar dist = e.line(shape.points()).nearestDist(ln, ePoint, lnPt);
+        scalar distSqr = sqr(dist);
+
+        if (distSqr < nearestDistSqr)
+        {
+            nearestDistSqr = distSqr;
+            minIndex = index;
+            linePoint = lnPt;
+            nearestPoint = ePoint;
+
+            {
+                point& minPt = tightest.min();
+                minPt = min(ln.start(), ln.end());
+                minPt.x() -= dist;
+                minPt.y() -= dist;
+                minPt.z() -= dist;
+            }
+            {
+                point& maxPt = tightest.max();
+                maxPt = max(ln.start(), ln.end());
+                maxPt.x() += dist;
+                maxPt.y() += dist;
+                maxPt.z() += dist;
+            }
+        }
+    }
+}
+
+
 bool Foam::treeDataEdge::findIntersectOp::operator()
 (
     const label index,
diff --git a/src/meshTools/indexedOctree/treeDataEdge.H b/src/meshTools/indexedOctree/treeDataEdge.H
index 12fd0d6aa10ba98c5db55977549b4775d58ca4d7..5a804d5f8e337228785fa3dc55920d9400409f2c 100644
--- a/src/meshTools/indexedOctree/treeDataEdge.H
+++ b/src/meshTools/indexedOctree/treeDataEdge.H
@@ -118,6 +118,43 @@ public:
         ) const;
     };
 
+    class findNearestOpSubset
+    {
+        const indexedOctree<treeDataEdge>& tree_;
+
+        DynamicList<label>& shapeMask_;
+
+    public:
+
+        findNearestOpSubset
+        (
+            const indexedOctree<treeDataEdge>& tree,
+            DynamicList<label>& shapeMask
+        );
+
+        void operator()
+        (
+            const labelUList& indices,
+            const point& sample,
+
+            scalar& nearestDistSqr,
+            label& minIndex,
+            point& nearestPoint
+        ) const;
+
+        //- Calculates nearest (to line) point in shape.
+        //  Returns point and distance (squared)
+        void operator()
+        (
+            const labelUList& indices,
+            const linePointRef& ln,
+
+            treeBoundBox& tightest,
+            label& minIndex,
+            point& linePoint,
+            point& nearestPoint
+        ) const;
+    };
 
     class findIntersectOp
     {