diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C
index 7ca688a113a88106a744bf3f75c67793cc80669f..e8cedc49c2cbd5e05256b513c4be1250f8140e4f 100644
--- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C
+++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C
@@ -426,8 +426,6 @@ void Foam::conformalVoronoiMesh::insertPoints
         indices,
         types
     );
-
-    Pout<< pts.size() << " " << indices.size() << " " << types.size() << endl;
 }
 
 
@@ -524,43 +522,20 @@ void Foam::conformalVoronoiMesh::insertEdgePointGroups
 }
 
 
-const Foam::indexedOctree<Foam::treeDataPoint>&
-Foam::conformalVoronoiMesh::featurePointTree() const
-{
-    if (featurePointTreePtr_.empty())
-    {
-        treeBoundBox overallBb
-        (
-            geometryToConformTo_.globalBounds().extend(rndGen_, 1e-4)
-        );
-
-        overallBb.min() -= Foam::point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
-        overallBb.max() += Foam::point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
-
-        featurePointTreePtr_.reset
-        (
-            new indexedOctree<treeDataPoint>
-            (
-                treeDataPoint(featurePointLocations_),
-                overallBb,  // overall search domain
-                10,         // max levels
-                10.0,       // maximum ratio of cubes v.s. cells
-                100.0       // max. duplicity; n/a since no bounding boxes.
-            )
-        );
-    }
-
-    return featurePointTreePtr_();
-}
-
-
 bool Foam::conformalVoronoiMesh::nearFeaturePt(const Foam::point& pt) const
 {
-    const indexedOctree<treeDataPoint>& tree = featurePointTree();
-
     scalar exclusionRangeSqr = featurePointExclusionDistanceSqr(pt);
 
-    pointIndexHit info = tree.findNearest(pt, exclusionRangeSqr);
+    pointIndexHit info;
+    label featureHit;
+
+    geometryToConformTo_.findFeaturePointNearest
+    (
+        pt,
+        exclusionRangeSqr,
+        info,
+        featureHit
+    );
 
     return info.hit();
 }
@@ -1209,7 +1184,6 @@ Foam::conformalVoronoiMesh::conformalVoronoiMesh
     limitBounds_(),
     featureVertices_(),
     featurePointLocations_(),
-    featurePointTreePtr_(),
     edgeLocationTreePtr_(),
     surfacePtLocationTreePtr_(),
     sizeAndAlignmentLocations_(),
diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.H b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.H
index d29cf85295d2925d3a18566d2fc9c735e0b737f5..7a68f98b035e3447e55e0c8a2516fa212da398a1 100644
--- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.H
+++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.H
@@ -169,9 +169,6 @@ private:
         //  Single pointField required by the featurePointTree.
         pointField featurePointLocations_;
 
-        //- Search tree for feature point locations
-        mutable autoPtr<indexedOctree<treeDataPoint> > featurePointTreePtr_;
-
         //- Search tree for edge point locations
         mutable autoPtr<dynamicIndexedOctree<dynamicTreeDataPoint> >
         edgeLocationTreePtr_;
@@ -487,9 +484,6 @@ private:
         //- Reinsert stored feature point defining points
         void reinsertFeaturePoints(bool distribute = false);
 
-        //- Demand driven construction of octree for feature points
-        const indexedOctree<treeDataPoint>& featurePointTree() const;
-
         //- Check if a location is in exclusion range around a feature point
         bool nearFeaturePt(const Foam::point& pt) const;
 
diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshCalcDualMesh.C b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshCalcDualMesh.C
index 0a79cd620d13ed3b5efead94e80bb5e8e0c20f01..04ef2af045d22226200bce8d1943ec4ed9438696 100644
--- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshCalcDualMesh.C
+++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshCalcDualMesh.C
@@ -79,9 +79,7 @@ void Foam::conformalVoronoiMesh::calcDualMesh
         }
     }
 
-// REMOVED BECAUSE THIS CODE STOPS ALL FACES NEAR ANY BOUNDARY (PROC OR REAL)
-// FROM BEING FILTERED.
-//
+    // THIS CODE STOPS ALL FACES NEAR ANY PROCESSOR BOUNDARY BEING FILTERED.
     for
     (
         Delaunay::Finite_vertices_iterator vit = finite_vertices_begin();
@@ -104,19 +102,12 @@ void Foam::conformalVoronoiMesh::calcDualMesh
             // Allow filtering if any vertices are far points. Otherwise faces
             // with boundary points attached to a cell with a far point will
             // not be filtered.
-//            if
-//            (
-//                (!(*cit)->vertex(0)->real() && !(*cit)->vertex(0)->farPoint())
-//             || (!(*cit)->vertex(1)->real() && !(*cit)->vertex(1)->farPoint())
-//             || (!(*cit)->vertex(2)->real() && !(*cit)->vertex(2)->farPoint())
-//             || (!(*cit)->vertex(3)->real() && !(*cit)->vertex(3)->farPoint())
-//            )
             if
             (
-                (!(*cit)->vertex(0)->real())
-             || (!(*cit)->vertex(1)->real())
-             || (!(*cit)->vertex(2)->real())
-             || (!(*cit)->vertex(3)->real())
+                (!(*cit)->vertex(0)->real() && !(*cit)->vertex(0)->farPoint())
+             || (!(*cit)->vertex(1)->real() && !(*cit)->vertex(1)->farPoint())
+             || (!(*cit)->vertex(2)->real() && !(*cit)->vertex(2)->farPoint())
+             || (!(*cit)->vertex(3)->real() && !(*cit)->vertex(3)->farPoint())
             )
             {
                 hasProcPt = true;
diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshConformToSurface.C b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshConformToSurface.C
index cf77b5e14a57d7ce88cb99c876242b463f379981..847974a2f4ed3c01bdc652fe52baafafcb8bc96c 100644
--- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshConformToSurface.C
+++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshConformToSurface.C
@@ -175,7 +175,43 @@ void Foam::conformalVoronoiMesh::buildSurfaceConformation
     //   \    .    /
     //     ---x----
 
+    label countNearBoundaryVertices = 0;
 
+    for
+    (
+        Delaunay::Finite_vertices_iterator vit = finite_vertices_begin();
+        vit != finite_vertices_end();
+        vit++
+    )
+    {
+        if (vit->internalPoint() && !vit->nearBoundary())
+        {
+            const Foam::point& pt = topoint(vit->point());
+            const scalar range = sqr(2.0*targetCellSize(pt));
+
+            pointIndexHit pHit;
+            label hitSurface;
+
+            geometryToConformTo_.findSurfaceNearest
+            (
+                pt,
+                range,
+                pHit,
+                hitSurface
+            );
+
+            if (pHit.hit())
+            {
+                vit->setNearBoundary();
+                countNearBoundaryVertices++;
+            }
+        }
+    }
+
+    Info<< "    Vertices marked as being near a boundary: "
+        << countNearBoundaryVertices << " (estimated)" << endl;
+
+    timeCheck("After set near boundary");
 
     // Initial surface protrusion conformation - nearest surface point
     {
@@ -198,7 +234,7 @@ void Foam::conformalVoronoiMesh::buildSurfaceConformation
             vit++
         )
         {
-            if (vit->internalPoint())
+            if (vit->internalPoint() && vit->nearBoundary())
             {
                 const Foam::point vert = topoint(vit->point());
 
@@ -220,11 +256,6 @@ void Foam::conformalVoronoiMesh::buildSurfaceConformation
                     )
                 )
                 {
-                    // This used to be just before this if statement.
-                    // Moved because a point is only near the boundary if
-                    // the dual cell intersects the surface.
-                    vit->setNearBoundary();
-
                     // meshTools::writeOBJ(Pout, vert);
                     // meshTools::writeOBJ(Pout, surfHit.hitPoint());
                     // Pout<< "l cr0 cr1" << endl;
@@ -246,9 +277,18 @@ void Foam::conformalVoronoiMesh::buildSurfaceConformation
                         existingSurfacePtLocations
                     );
                 }
+                else
+                {
+                    vit->setInternal();
+                    countNearBoundaryVertices--;
+                }
             }
         }
 
+        Info<< "    Vertices marked as being near a boundary: "
+            << countNearBoundaryVertices
+            << " (after dual surface intersection)" << endl;
+
         label nVerts = number_of_vertices();
         label nSurfHits = surfaceHits.size();
         label nFeatEdHits = featureEdgeHits.size();
@@ -1179,6 +1219,8 @@ void Foam::conformalVoronoiMesh::buildParallelInterfaceInfluence
         cIOuter++;
     }
 
+    timeCheck("End of testing cell influence");
+
     // Increasing the circumspheres to increase the overlaps and compensate for
     // floating point errors missing some referrals
     labelListList circumsphereOverlaps
@@ -1186,6 +1228,8 @@ void Foam::conformalVoronoiMesh::buildParallelInterfaceInfluence
         overlapsProc(circumcentre, sqr(1.01)*circumradiusSqr)
     );
 
+    timeCheck("End of increasing overlaps");
+
     // Reset counters
     cIOuter = 0;
 
@@ -2144,7 +2188,7 @@ void Foam::conformalVoronoiMesh::buildSizeAndAlignmentTree() const
             treeDataPoint(sizeAndAlignmentLocations_),
             overallBb,  // overall search domain
             10,         // max levels
-            10.0,       // maximum ratio of cubes v.s. cells
+            20.0,       // maximum ratio of cubes v.s. cells
             100.0       // max. duplicity; n/a since no bounding boxes.
         )
     );
@@ -2168,13 +2212,13 @@ void Foam::conformalVoronoiMesh::addSurfaceAndEdgeHits
     DynamicList<Foam::point>& existingSurfacePtLocations
 ) const
 {
-    bool keepSurfacePoint = true;
-
     const scalar cellSize = targetCellSize(vert);
     const scalar cellSizeSqr = sqr(cellSize);
 
     forAll(surfHit, sI)
     {
+        bool keepSurfacePoint = true;
+
         pointIndexHit surfHitI = surfHit[sI];
         label hitSurfaceI = hitSurface[sI];
 
diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformationSurfaces/conformationSurfaces.C b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformationSurfaces/conformationSurfaces.C
index b91d40121d48f23d8a1ff077c9ce679983ed6218..8212688165a69d1cf9b84262b584c87da868b8ba 100644
--- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformationSurfaces/conformationSurfaces.C
+++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformationSurfaces/conformationSurfaces.C
@@ -619,6 +619,37 @@ void Foam::conformationSurfaces::findSurfaceNearest
 }
 
 
+void Foam::conformationSurfaces::findFeaturePointNearest
+(
+    const point& sample,
+    scalar nearestDistSqr,
+    pointIndexHit& fpHit,
+    label& featureHit
+) const
+{
+    // Work arrays
+    scalar minDistSqr = nearestDistSqr;
+    pointIndexHit hitInfo;
+
+    forAll(features_, testI)
+    {
+        features_[testI].nearestFeaturePoint
+        (
+            sample,
+            minDistSqr,
+            hitInfo
+        );
+
+        if (hitInfo.hit())
+        {
+            minDistSqr = magSqr(hitInfo.hitPoint()- sample);
+            fpHit = hitInfo;
+            featureHit = testI;
+        }
+    }
+}
+
+
 void Foam::conformationSurfaces::findEdgeNearest
 (
     const point& sample,
diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformationSurfaces/conformationSurfaces.H b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformationSurfaces/conformationSurfaces.H
index fe883fbaa5cae003313dc9a381ea16a5734a535b..bb78cde3e4edb1a48d29118c67e7614a22fa6e6a 100644
--- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformationSurfaces/conformationSurfaces.H
+++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformationSurfaces/conformationSurfaces.H
@@ -246,6 +246,14 @@ public:
                 labelList& hitSurfaces
             ) const;
 
+            //- Find the nearest point on any feature edge
+            void findFeaturePointNearest
+            (
+                const point& sample,
+                scalar nearestDistSqr,
+                pointIndexHit& fpHit,
+                label& featureHit
+            ) const;
 
             //- Find the nearest point on any feature edge
             void findEdgeNearest
diff --git a/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processor/processorPolyPatch.C b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processor/processorPolyPatch.C
index ac8e28a81cbc82ef86de18dec320ae7ba81ed0ee..7ee72d6142ba2ae90d37b8f164387a25e64ecef9 100644
--- a/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processor/processorPolyPatch.C
+++ b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processor/processorPolyPatch.C
@@ -369,6 +369,24 @@ void Foam::processorPolyPatch::updateMesh(PstreamBuffers& pBufs)
                 >> nbrPointIndex
                 >> nbrEdgeFace
                 >> nbrEdgeIndex;
+
+            if
+            (
+                nbrPointIndex.size() != nPoints()
+             || nbrEdgeIndex.size() != nEdges()
+            )
+            {
+                FatalErrorIn
+                (
+                    "processorPolyPatch::updateMesh(PstreamBuffers&)"
+                )   << "Size of data from processor " << neighbProcNo()
+                    << " does not match size of data on processor "
+                    << Pstream::myProcNo() << "." << nl
+                    << "    Neighbour has " << nbrPointFace.size()
+                    << " points and " << nbrEdgeFace.size() << " edges." << nl
+                    << "    This proc has " << nPoints() << " points and "
+                    << nEdges() << " edges." << exit(FatalError);
+            }
         }
 
         // Convert neighbour faces and indices into face back into
diff --git a/src/edgeMesh/extendedFeatureEdgeMesh/extendedFeatureEdgeMesh.C b/src/edgeMesh/extendedFeatureEdgeMesh/extendedFeatureEdgeMesh.C
index 9f621b24ee64fd5fc9e6034496eb0c3fdc4d177d..0ebb7b58ab6d0e54c7bc91092e02a51df9fadaa8 100644
--- a/src/edgeMesh/extendedFeatureEdgeMesh/extendedFeatureEdgeMesh.C
+++ b/src/edgeMesh/extendedFeatureEdgeMesh/extendedFeatureEdgeMesh.C
@@ -72,6 +72,7 @@ Foam::extendedFeatureEdgeMesh::extendedFeatureEdgeMesh(const IOobject& io)
     edgeNormals_(0),
     featurePointNormals_(0),
     regionEdges_(0),
+    pointTree_(),
     edgeTree_(),
     edgeTreesByType_()
 {
@@ -159,6 +160,7 @@ Foam::extendedFeatureEdgeMesh::extendedFeatureEdgeMesh
     edgeNormals_(fem.edgeNormals()),
     featurePointNormals_(fem.featurePointNormals()),
     regionEdges_(fem.regionEdges()),
+    pointTree_(),
     edgeTree_(),
     edgeTreesByType_()
 {}
@@ -185,6 +187,7 @@ Foam::extendedFeatureEdgeMesh::extendedFeatureEdgeMesh
     edgeNormals_(0),
     featurePointNormals_(0),
     regionEdges_(0),
+    pointTree_(),
     edgeTree_(),
     edgeTreesByType_()
 {}
@@ -222,6 +225,7 @@ Foam::extendedFeatureEdgeMesh::extendedFeatureEdgeMesh
     edgeNormals_(0),
     featurePointNormals_(0),
     regionEdges_(0),
+    pointTree_(),
     edgeTree_(),
     edgeTreesByType_()
 {
@@ -578,6 +582,7 @@ Foam::extendedFeatureEdgeMesh::extendedFeatureEdgeMesh
     edgeNormals_(edgeNormals),
     featurePointNormals_(featurePointNormals),
     regionEdges_(regionEdges),
+    pointTree_(),
     edgeTree_(),
     edgeTreesByType_()
 {}
@@ -684,6 +689,21 @@ Foam::extendedFeatureEdgeMesh::classifyEdge
 
 // * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
 
+void Foam::extendedFeatureEdgeMesh::nearestFeaturePoint
+(
+    const point& sample,
+    scalar searchDistSqr,
+    pointIndexHit& info
+) const
+{
+    info = pointTree().findNearest
+    (
+        sample,
+        searchDistSqr
+    );
+}
+
+
 void Foam::extendedFeatureEdgeMesh::nearestFeatureEdge
 (
     const point& sample,
@@ -816,6 +836,46 @@ void Foam::extendedFeatureEdgeMesh::allNearestFeatureEdges
 }
 
 
+const Foam::indexedOctree<Foam::treeDataPoint>&
+Foam::extendedFeatureEdgeMesh::pointTree() const
+{
+    if (pointTree_.empty())
+    {
+        Random rndGen(17301893);
+
+        // Slightly extended bb. Slightly off-centred just so on symmetric
+        // geometry there are less face/edge aligned items.
+        treeBoundBox bb
+        (
+            treeBoundBox(points()).extend(rndGen, 1E-4)
+        );
+
+        bb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
+        bb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
+
+        const labelList featurePointLabels = identity(nonFeatureStart_);
+
+        pointTree_.reset
+        (
+            new indexedOctree<treeDataPoint>
+            (
+                treeDataPoint
+                (
+                    points(),
+                    featurePointLabels
+                ),
+                bb,     // bb
+                8,      // maxLevel
+                10,     // leafsize
+                3.0     // duplicity
+            )
+        );
+    }
+
+    return pointTree_();
+}
+
+
 const Foam::indexedOctree<Foam::treeDataEdge>&
 Foam::extendedFeatureEdgeMesh::edgeTree() const
 {
diff --git a/src/edgeMesh/extendedFeatureEdgeMesh/extendedFeatureEdgeMesh.H b/src/edgeMesh/extendedFeatureEdgeMesh/extendedFeatureEdgeMesh.H
index 3268e719c5f7c00da82db4cc2bfee23cb1dadbb9..52de62552ca67e78ae9f56a649297cf34b3c976a 100644
--- a/src/edgeMesh/extendedFeatureEdgeMesh/extendedFeatureEdgeMesh.H
+++ b/src/edgeMesh/extendedFeatureEdgeMesh/extendedFeatureEdgeMesh.H
@@ -61,6 +61,7 @@ SourceFiles
 #include "IOdictionary.H"
 #include "indexedOctree.H"
 #include "treeDataEdge.H"
+#include "treeDataPoint.H"
 #include "pointIndexHit.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -155,6 +156,9 @@ private:
         //- Feature edges which are on the boundary between regions
         labelList regionEdges_;
 
+        //- Search tree for all feature points
+        mutable autoPtr<indexedOctree<treeDataPoint> > pointTree_;
+
         //- Search tree for all edges
         mutable autoPtr<indexedOctree<treeDataEdge> > edgeTree_;
 
@@ -247,6 +251,14 @@ public:
 
         // Find
 
+            //- Find nearest surface edge for the sample point.
+            void nearestFeaturePoint
+            (
+                const point& sample,
+                scalar searchDistSqr,
+                pointIndexHit& info
+            ) const;
+
             //- Find nearest surface edge for the sample point.
             void nearestFeatureEdge
             (
@@ -349,6 +361,9 @@ public:
             //- Return the edgeStatus of a specified edge
             inline edgeStatus getEdgeStatus(label edgeI) const;
 
+            //- Demand driven construction of octree for feature points
+            const indexedOctree<treeDataPoint>& pointTree() const;
+
             //- Demand driven construction of octree for boundary edges
             const indexedOctree<treeDataEdge>& edgeTree() const;