From 1e420e02e78e558d1b809b96e52e4a9111619d18 Mon Sep 17 00:00:00 2001
From: laurence <laurence>
Date: Tue, 30 Jul 2013 11:03:19 +0100
Subject: [PATCH] ENH: foamyHexMesh: Move feature point conformation to
 separate class.

- Update point conversion routines
- Slightly more efficient point redistribution
---
 .../DelaunayMesh/DelaunayMesh.C               |   2 +-
 .../DelaunayMesh/DistributedDelaunayMesh.C    |  18 +-
 .../DelaunayMesh/DistributedDelaunayMesh.H    |   3 +-
 .../conformalVoronoiMesh/Make/files           |   5 +-
 .../backgroundMeshDecomposition.C             | 152 +---
 .../backgroundMeshDecomposition.H             |  11 +-
 .../backgroundMeshDecompositionTemplates.C    | 186 +++++
 .../cellShapeControlMesh.C                    |  20 +-
 .../controlMeshRefinement.C                   |   2 +-
 .../conformalVoronoiMesh.C                    |  53 +-
 .../conformalVoronoiMesh.H                    | 115 +--
 .../conformalVoronoiMeshFeaturePoints.C       | 692 +-----------------
 .../conformalVoronoiMeshI.H                   |   4 +-
 .../featurePointConformer.C                   | 598 +++++++++++++++
 .../featurePointConformer.H                   | 187 +++++
 .../featurePointConformerI.H                  |  32 +
 .../featurePointConformerSpecialisations.C}   |  59 +-
 .../pointFeatureEdgesTypes.C                  | 101 +++
 .../pointFeatureEdgesTypes.H                  |  64 +-
 .../conformalVoronoiMesh/pointConversion.H    |  29 +-
 .../foamyHexMesh/vectorTools/vectorTools.H    |   3 +-
 21 files changed, 1263 insertions(+), 1073 deletions(-)
 create mode 100644 applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecompositionTemplates.C
 create mode 100644 applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/featurePointConformer/featurePointConformer.C
 create mode 100644 applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/featurePointConformer/featurePointConformer.H
 create mode 100644 applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/featurePointConformer/featurePointConformerI.H
 rename applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/{conformalVoronoiMeshFeaturePointSpecialisations.C => featurePointConformer/featurePointConformerSpecialisations.C} (95%)
 create mode 100644 applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/featurePointConformer/pointFeatureEdgesTypes.C
 rename applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/{ => featurePointConformer}/pointFeatureEdgesTypes.H (70%)

diff --git a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/DelaunayMesh/DelaunayMesh.C b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/DelaunayMesh/DelaunayMesh.C
index 7eb8216b00f..4770a1748ab 100644
--- a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/DelaunayMesh/DelaunayMesh.C
+++ b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/DelaunayMesh/DelaunayMesh.C
@@ -117,7 +117,7 @@ Foam::DelaunayMesh<Triangulation>::DelaunayMesh
     {
         forAll(pts, ptI)
         {
-            Vertex_handle vh = this->insert(toPoint<Point>(pts[ptI]));
+            Vertex_handle vh = this->insert(toPoint(pts[ptI]));
 
             if (indices.headerOk())
             {
diff --git a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/DelaunayMesh/DistributedDelaunayMesh.C b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/DelaunayMesh/DistributedDelaunayMesh.C
index 809de99d8ae..152a82c7f29 100644
--- a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/DelaunayMesh/DistributedDelaunayMesh.C
+++ b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/DelaunayMesh/DistributedDelaunayMesh.C
@@ -814,7 +814,8 @@ template<class Triangulation>
 Foam::autoPtr<Foam::mapDistribute>
 Foam::DistributedDelaunayMesh<Triangulation>::distribute
 (
-    const backgroundMeshDecomposition& decomposition
+    const backgroundMeshDecomposition& decomposition,
+    List<Foam::point>& points
 )
 {
     if (!Pstream::parRun())
@@ -824,21 +825,6 @@ Foam::DistributedDelaunayMesh<Triangulation>::distribute
 
     distributeBoundBoxes(decomposition.procBounds());
 
-    DynamicList<point> points(Triangulation::number_of_vertices());
-
-    for
-    (
-        Finite_vertices_iterator vit = Triangulation::finite_vertices_begin();
-        vit != Triangulation::finite_vertices_end();
-        ++vit
-    )
-    {
-        if (vit->real())
-        {
-            points.append(topoint(vit->point()));
-        }
-    }
-
     autoPtr<mapDistribute> mapDist = decomposition.distributePoints(points);
 
     return mapDist;
diff --git a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/DelaunayMesh/DistributedDelaunayMesh.H b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/DelaunayMesh/DistributedDelaunayMesh.H
index abd68910c4b..1f5db3700f8 100644
--- a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/DelaunayMesh/DistributedDelaunayMesh.H
+++ b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/DelaunayMesh/DistributedDelaunayMesh.H
@@ -166,7 +166,8 @@ public:
 
         autoPtr<mapDistribute> distribute
         (
-            const backgroundMeshDecomposition& decomposition
+            const backgroundMeshDecomposition& decomposition,
+            List<Foam::point>& points
         );
 
         //- Refer vertices so that the processor interfaces are consistent
diff --git a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/Make/files b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/Make/files
index eec581bf102..e42c52451fc 100644
--- a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/Make/files
+++ b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/Make/files
@@ -10,7 +10,10 @@ conformalVoronoiMesh/conformalVoronoiMeshCalcDualMesh.C
 conformalVoronoiMesh/conformalVoronoiMeshConformToSurface.C
 conformalVoronoiMesh/conformalVoronoiMeshIO.C
 conformalVoronoiMesh/conformalVoronoiMeshFeaturePoints.C
-conformalVoronoiMesh/conformalVoronoiMeshFeaturePointSpecialisations.C
+
+conformalVoronoiMesh/featurePointConformer/pointFeatureEdgesTypes.C
+conformalVoronoiMesh/featurePointConformer/featurePointConformer.C
+conformalVoronoiMesh/featurePointConformer/featurePointConformerSpecialisations.C
 
 cvControls/cvControls.C
 
diff --git a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.C b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.C
index e14100cd003..51e113c81f3 100644
--- a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.C
+++ b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.C
@@ -29,6 +29,7 @@ License
 #include "zeroGradientFvPatchFields.H"
 #include "Time.H"
 #include "Random.H"
+#include "pointConversion.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -1043,22 +1044,6 @@ Foam::backgroundMeshDecomposition::distribute
 }
 
 
-Foam::autoPtr<Foam::mapDistribute>
-Foam::backgroundMeshDecomposition::distributePoints
-(
-    List<point>& points
-) const
-{
-    labelList toProc(processorPosition(points));
-
-    autoPtr<mapDistribute> map(buildMap(toProc));
-
-    map().distribute(points);
-
-    return map;
-}
-
-
 bool Foam::backgroundMeshDecomposition::positionOnThisProcessor
 (
     const point& pt
@@ -1128,141 +1113,6 @@ Foam::pointIndexHit Foam::backgroundMeshDecomposition::findLineAny
 }
 
 
-Foam::labelList Foam::backgroundMeshDecomposition::processorPosition
-(
-    const List<point>& pts
-) const
-{
-    DynamicList<label> toCandidateProc;
-    DynamicList<point> testPoints;
-    labelList ptBlockStart(pts.size(), -1);
-    labelList ptBlockSize(pts.size(), -1);
-
-    label nTotalCandidates = 0;
-
-    forAll(pts, pI)
-    {
-        const point& pt = pts[pI];
-
-        label nCandidates = 0;
-
-        forAll(allBackgroundMeshBounds_, procI)
-        {
-            if (allBackgroundMeshBounds_[procI].contains(pt))
-            {
-                toCandidateProc.append(procI);
-                testPoints.append(pt);
-
-                nCandidates++;
-            }
-        }
-
-        ptBlockStart[pI] = nTotalCandidates;
-        ptBlockSize[pI] = nCandidates;
-
-        nTotalCandidates += nCandidates;
-    }
-
-    // Needed for reverseDistribute
-    label preDistributionToCandidateProcSize = toCandidateProc.size();
-
-    autoPtr<mapDistribute> map(buildMap(toCandidateProc));
-
-    map().distribute(testPoints);
-
-    List<bool> pointOnCandidate(testPoints.size(), false);
-
-    // Test candidate points on candidate processors
-    forAll(testPoints, tPI)
-    {
-        pointOnCandidate[tPI] = positionOnThisProcessor(testPoints[tPI]);
-    }
-
-    map().reverseDistribute
-    (
-        preDistributionToCandidateProcSize,
-        pointOnCandidate
-    );
-
-    labelList ptProc(pts.size(), -1);
-
-    DynamicList<label> failedPointIndices;
-    DynamicList<point> failedPoints;
-
-    forAll(pts, pI)
-    {
-        // Extract the sub list of results for this point
-
-        SubList<bool> ptProcResults
-        (
-            pointOnCandidate,
-            ptBlockSize[pI],
-            ptBlockStart[pI]
-        );
-
-        forAll(ptProcResults, pPRI)
-        {
-            if (ptProcResults[pPRI])
-            {
-                ptProc[pI] = toCandidateProc[ptBlockStart[pI] + pPRI];
-
-                break;
-            }
-        }
-
-        if (ptProc[pI] < 0)
-        {
-            if (!globalBackgroundBounds_.contains(pts[pI]))
-            {
-                FatalErrorIn
-                (
-                    "Foam::labelList"
-                    "Foam::backgroundMeshDecomposition::processorPosition"
-                    "("
-                        "const List<point>&"
-                    ") const"
-                )
-                    << "The position " << pts[pI]
-                    << " is not in any part of the background mesh "
-                    << globalBackgroundBounds_ << endl
-                    << "A background mesh with a wider margin around "
-                    << "the geometry may help."
-                    << exit(FatalError);
-            }
-
-            if (debug)
-            {
-                WarningIn
-                (
-                    "Foam::labelList"
-                    "Foam::backgroundMeshDecomposition::processorPosition"
-                    "("
-                        "const List<point>&"
-                    ") const"
-                )   << "The position " << pts[pI]
-                    << " was not found in the background mesh "
-                    << globalBackgroundBounds_ << ", finding nearest."
-                    << endl;
-            }
-
-            failedPointIndices.append(pI);
-            failedPoints.append(pts[pI]);
-        }
-    }
-
-    labelList ptNearestProc(processorNearestPosition(failedPoints));
-
-    forAll(failedPoints, fPI)
-    {
-        label pI = failedPointIndices[fPI];
-
-        ptProc[pI] = ptNearestProc[fPI];
-    }
-
-    return ptProc;
-}
-
-
 Foam::labelList Foam::backgroundMeshDecomposition::processorNearestPosition
 (
     const List<point>& pts
diff --git a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.H b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.H
index 97b270a606d..94ad818c48a 100644
--- a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.H
+++ b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.H
@@ -72,6 +72,7 @@ SourceFiles
 #include "indexedOctree.H"
 #include "treeDataPrimitivePatch.H"
 #include "volumeType.H"
+#include "CGALTriangulation3Ddefs.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -224,7 +225,8 @@ public:
         );
 
         //- Distribute supplied the points to the appropriate processor
-        autoPtr<mapDistribute> distributePoints(List<point>& points) const;
+        template<typename PointType>
+        autoPtr<mapDistribute> distributePoints(List<PointType>& points) const;
 
         //- Is the given position inside the domain of this decomposition
         bool positionOnThisProcessor(const point& pt) const;
@@ -261,7 +263,8 @@ public:
         ) const;
 
         //- What processor is the given position on?
-        labelList processorPosition(const List<point>& pts) const;
+        template<typename PointType>
+        labelList processorPosition(const List<PointType>& pts) const;
 
         //- What is the nearest processor to the given position?
         labelList processorNearestPosition(const List<point>& pts) const;
@@ -334,6 +337,10 @@ public:
 
 #include "backgroundMeshDecompositionI.H"
 
+#ifdef NoRepository
+#   include "backgroundMeshDecompositionTemplates.C"
+#endif
+
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 #endif
diff --git a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecompositionTemplates.C b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecompositionTemplates.C
new file mode 100644
index 00000000000..148de2bafa0
--- /dev/null
+++ b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecompositionTemplates.C
@@ -0,0 +1,186 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2013 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "backgroundMeshDecomposition.H"
+#include "pointConversion.H"
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+template<typename PointType>
+Foam::autoPtr<Foam::mapDistribute>
+Foam::backgroundMeshDecomposition::distributePoints
+(
+    List<PointType>& points
+) const
+{
+    labelList toProc(processorPosition(points));
+
+    autoPtr<mapDistribute> map(buildMap(toProc));
+
+    map().distribute(points);
+
+    return map;
+}
+
+
+template<typename PointType>
+Foam::labelList Foam::backgroundMeshDecomposition::processorPosition
+(
+    const List<PointType>& pts
+) const
+{
+    DynamicList<label> toCandidateProc;
+    DynamicList<point> testPoints;
+    labelList ptBlockStart(pts.size(), -1);
+    labelList ptBlockSize(pts.size(), -1);
+
+    label nTotalCandidates = 0;
+
+    forAll(pts, pI)
+    {
+        const pointFromPoint pt = topoint(pts[pI]);
+
+        label nCandidates = 0;
+
+        forAll(allBackgroundMeshBounds_, procI)
+        {
+            if (allBackgroundMeshBounds_[procI].contains(pt))
+            {
+                toCandidateProc.append(procI);
+                testPoints.append(pt);
+
+                nCandidates++;
+            }
+        }
+
+        ptBlockStart[pI] = nTotalCandidates;
+        ptBlockSize[pI] = nCandidates;
+
+        nTotalCandidates += nCandidates;
+    }
+
+    // Needed for reverseDistribute
+    label preDistributionToCandidateProcSize = toCandidateProc.size();
+
+    autoPtr<mapDistribute> map(buildMap(toCandidateProc));
+
+    map().distribute(testPoints);
+
+    List<bool> pointOnCandidate(testPoints.size(), false);
+
+    // Test candidate points on candidate processors
+    forAll(testPoints, tPI)
+    {
+        pointOnCandidate[tPI] = positionOnThisProcessor(testPoints[tPI]);
+    }
+
+    map().reverseDistribute
+    (
+        preDistributionToCandidateProcSize,
+        pointOnCandidate
+    );
+
+    labelList ptProc(pts.size(), -1);
+
+    DynamicList<label> failedPointIndices;
+    DynamicList<point> failedPoints;
+
+    forAll(pts, pI)
+    {
+        // Extract the sub list of results for this point
+
+        SubList<bool> ptProcResults
+        (
+            pointOnCandidate,
+            ptBlockSize[pI],
+            ptBlockStart[pI]
+        );
+
+        forAll(ptProcResults, pPRI)
+        {
+            if (ptProcResults[pPRI])
+            {
+                ptProc[pI] = toCandidateProc[ptBlockStart[pI] + pPRI];
+
+                break;
+            }
+        }
+
+        if (ptProc[pI] < 0)
+        {
+            const pointFromPoint pt = topoint(pts[pI]);
+
+            if (!globalBackgroundBounds_.contains(pt))
+            {
+                FatalErrorIn
+                (
+                    "Foam::labelList"
+                    "Foam::backgroundMeshDecomposition::processorPosition"
+                    "("
+                        "const List<point>&"
+                    ") const"
+                )
+                    << "The position " << pt
+                    << " is not in any part of the background mesh "
+                    << globalBackgroundBounds_ << endl
+                    << "A background mesh with a wider margin around "
+                    << "the geometry may help."
+                    << exit(FatalError);
+            }
+
+            if (debug)
+            {
+                WarningIn
+                (
+                    "Foam::labelList"
+                    "Foam::backgroundMeshDecomposition::processorPosition"
+                    "("
+                        "const List<point>&"
+                    ") const"
+                )   << "The position " << pt
+                    << " was not found in the background mesh "
+                    << globalBackgroundBounds_ << ", finding nearest."
+                    << endl;
+            }
+
+            failedPointIndices.append(pI);
+            failedPoints.append(pt);
+        }
+    }
+
+    labelList ptNearestProc(processorNearestPosition(failedPoints));
+
+    forAll(failedPoints, fPI)
+    {
+        label pI = failedPointIndices[fPI];
+
+        ptProc[pI] = ptNearestProc[fPI];
+    }
+
+    return ptProc;
+}
+
+
+// ************************************************************************* //
diff --git a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/cellShapeControl/cellShapeControlMesh/cellShapeControlMesh.C b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/cellShapeControl/cellShapeControlMesh/cellShapeControlMesh.C
index 52d14633b43..53afd1868f6 100644
--- a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/cellShapeControl/cellShapeControlMesh/cellShapeControlMesh.C
+++ b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/cellShapeControl/cellShapeControlMesh/cellShapeControlMesh.C
@@ -619,7 +619,7 @@ void Foam::cellShapeControlMesh::barycentricCoords
 {
     // Use the previous cell handle as a hint on where to start searching
     // Giving a hint causes strange errors...
-    ch = locate(toPoint<Point>(pt));
+    ch = locate(toPoint(pt));
 
     if (dimension() > 2 && !is_infinite(ch))
     {
@@ -666,14 +666,6 @@ void Foam::cellShapeControlMesh::distribute
     const backgroundMeshDecomposition& decomposition
 )
 {
-    if (!Pstream::parRun())
-    {
-        return;
-    }
-
-    autoPtr<mapDistribute> mapDist =
-        DistributedDelaunayMesh<CellSizeDelaunay>::distribute(decomposition);
-
     DynamicList<Foam::point> points(number_of_vertices());
     DynamicList<scalar> sizes(number_of_vertices());
     DynamicList<tensor> alignments(number_of_vertices());
@@ -711,7 +703,13 @@ void Foam::cellShapeControlMesh::distribute
         }
     }
 
-    mapDist().distribute(points);
+    autoPtr<mapDistribute> mapDist =
+        DistributedDelaunayMesh<CellSizeDelaunay>::distribute
+        (
+            decomposition,
+            points
+        );
+
     mapDist().distribute(sizes);
     mapDist().distribute(alignments);
 
@@ -735,7 +733,7 @@ void Foam::cellShapeControlMesh::distribute
         (
             Vb
             (
-                toPoint<Point>(points[pI]),
+                toPoint(points[pI]),
                 -1,
                 Vb::vtInternal,
                 Pstream::myProcNo()
diff --git a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/cellShapeControl/controlMeshRefinement/controlMeshRefinement.C b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/cellShapeControl/controlMeshRefinement/controlMeshRefinement.C
index 5a4b0c785a8..f5d4d8526c9 100644
--- a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/cellShapeControl/controlMeshRefinement/controlMeshRefinement.C
+++ b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/cellShapeControl/controlMeshRefinement/controlMeshRefinement.C
@@ -763,7 +763,7 @@ Foam::label Foam::controlMeshRefinement::refineMesh
             (
                 Vb
                 (
-                    toPoint<cellShapeControlMesh::Point>(pt),
+                    toPoint(pt),
                     Vb::vtInternal
                 )
             );
diff --git a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C
index 562a5a800af..14d10427786 100644
--- a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C
+++ b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C
@@ -124,12 +124,13 @@ void Foam::conformalVoronoiMesh::insertInternalPoints
             decomposition_().distributePoints(transferPoints)
         );
 
+        transferPoints.clear();
+
         map().distribute(points);
     }
 
     label nVert = number_of_vertices();
 
-    // using the range insert (faster than inserting points one by one)
     insert(points.begin(), points.end());
 
     label nInserted(number_of_vertices() - nVert);
@@ -169,24 +170,7 @@ void Foam::conformalVoronoiMesh::insertPoints
 {
     if (Pstream::parRun() && distribute)
     {
-        const label preDistributionSize = vertices.size();
-
-        List<Foam::point> pts(preDistributionSize);
-
-        forAll(vertices, vI)
-        {
-            const Foam::point& pt = topoint(vertices[vI].point());
-
-            pts[vI] = pt;
-        }
-
-        // Distribute points to their appropriate processor
-        autoPtr<mapDistribute> map
-        (
-            decomposition_().distributePoints(pts)
-        );
-
-        map().distribute(vertices);
+        decomposition_().distributePoints(vertices);
 
         forAll(vertices, vI)
         {
@@ -196,12 +180,7 @@ void Foam::conformalVoronoiMesh::insertPoints
 
     label preReinsertionSize(number_of_vertices());
 
-    rangeInsertWithInfo
-    (
-        vertices.begin(),
-        vertices.end(),
-        false
-    );
+    this->DelaunayMesh<Delaunay>::insertPoints(vertices);
 
     const label nReinserted = returnReduce
     (
@@ -398,9 +377,6 @@ void Foam::conformalVoronoiMesh::distribute()
         return;
     }
 
-    autoPtr<mapDistribute> mapDist =
-        DistributedDelaunayMesh<Delaunay>::distribute(decomposition_());
-
     DynamicList<Foam::point> points(number_of_vertices());
     DynamicList<Foam::indexedVertexEnum::vertexType> types
     (
@@ -425,7 +401,9 @@ void Foam::conformalVoronoiMesh::distribute()
         }
     }
 
-    mapDist().distribute(points);
+    autoPtr<mapDistribute> mapDist =
+        DistributedDelaunayMesh<Delaunay>::distribute(decomposition_(), points);
+
     mapDist().distribute(types);
     mapDist().distribute(sizes);
     mapDist().distribute(alignments);
@@ -445,7 +423,7 @@ void Foam::conformalVoronoiMesh::distribute()
         (
             Vb
             (
-                toPoint<Point>(points[pI]),
+                toPoint(points[pI]),
                 -1,
                 types[pI],
                 Pstream::myProcNo()
@@ -862,8 +840,7 @@ Foam::conformalVoronoiMesh::conformalVoronoiMesh
         geometryToConformTo_
     ),
     limitBounds_(),
-    featureVertices_(),
-    featurePointLocations_(),
+    ftPtConformer_(*this),
     edgeLocationTreePtr_(),
     surfacePtLocationTreePtr_(),
     surfaceConformationVertices_(),
@@ -912,7 +889,7 @@ void Foam::conformalVoronoiMesh::initialiseForMotion()
 
     insertInitialPoints();
 
-    insertFeaturePoints();
+    insertFeaturePoints(true);
 
     setVertexSizeAndAlignment();
 
@@ -1160,7 +1137,7 @@ void Foam::conformalVoronoiMesh::move()
                     {
                         pointsToInsert.append
                         (
-                            toPoint<Point>(0.5*(dVA + dVB))
+                            toPoint(0.5*(dVA + dVB))
                         );
                     }
                 }
@@ -1297,7 +1274,7 @@ void Foam::conformalVoronoiMesh::move()
                             if (positionOnThisProc(newPt))
                             {
                                 // Prevent insertions spanning surfaces
-                                pointsToInsert.append(toPoint<Point>(newPt));
+                                pointsToInsert.append(toPoint(newPt));
                             }
                         }
                     }
@@ -1335,7 +1312,7 @@ void Foam::conformalVoronoiMesh::move()
                             {
                                 pointsToInsert.append
                                 (
-                                    toPoint<Point>(0.5*(dVA + dVB))
+                                    toPoint(0.5*(dVA + dVB))
                                 );
                             }
                         }
@@ -1454,7 +1431,7 @@ void Foam::conformalVoronoiMesh::move()
 
                 pointsToInsert.append
                 (
-                    toPoint<Point>
+                    toPoint
                     (
                         topoint(vit->point())
                       + displacementAccumulator[vit->index()]
@@ -1502,7 +1479,7 @@ void Foam::conformalVoronoiMesh::move()
 
     Info<< nl << "Inserting displaced tessellation" << endl;
 
-    reinsertFeaturePoints(true);
+    insertFeaturePoints(true);
 
     insertInternalPoints(pointsToInsert, true);
 
diff --git a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.H b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.H
index 5a8ed048148..6190b0418e4 100644
--- a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.H
+++ b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.H
@@ -74,9 +74,9 @@ SourceFiles
 #include "globalIndex.H"
 #include "pointFeatureEdgesTypes.H"
 #include "pointConversion.H"
-#include "Tuple2.H"
+#include "Pair.H"
 #include "DistributedDelaunayMesh.H"
-#include "tensorIOField.H"
+#include "featurePointConformer.H"
 
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -152,13 +152,8 @@ private:
         //- Limiting bound box before infinity begins
         treeBoundBox limitBounds_;
 
-        //- Store the feature constraining points to be reinserted after a
-        //  triangulation clear. Maintained with relative types and indices.
-        List<Vb> featureVertices_;
-
-        //- Storing the locations of all of the features to be conformed to.
-        //  Single pointField required by the featurePointTree.
-        pointField featurePointLocations_;
+        //-
+        featurePointConformer ftPtConformer_;
 
         //- Search tree for edge point locations
         mutable autoPtr<dynamicIndexedOctree<dynamicTreeDataPoint> >
@@ -235,7 +230,7 @@ private:
             const Foam::point& surfPt,
             const vector& n,
             DynamicList<Vb>& pts
-        );
+        ) const;
 
         inline Foam::point perturbPoint(const Foam::point& pt) const;
 
@@ -247,7 +242,7 @@ private:
             const Foam::point& surfPt,
             const vector& n,
             DynamicList<Vb>& pts
-        );
+        ) const;
 
         inline bool isPointPair
         (
@@ -272,20 +267,12 @@ private:
             const fileName fName = fileName::null
         );
 
-        //- Call the appropriate function to conform to an edge
-        void createEdgePointGroup
-        (
-            const extendedFeatureEdgeMesh& feMesh,
-            const pointIndexHit& edHit,
-            DynamicList<Vb>& pts
-        );
-
         void createEdgePointGroupByCirculating
         (
             const extendedFeatureEdgeMesh& feMesh,
             const pointIndexHit& edHit,
             DynamicList<Vb>& pts
-        );
+        ) const;
 
         bool meshableRegion
         (
@@ -308,7 +295,7 @@ private:
             const extendedFeatureEdgeMesh& feMesh,
             const pointIndexHit& edHit,
             DynamicList<Vb>& pts
-        );
+        ) const;
 
         //- Create points to conform to an internal edge
         void createInternalEdgePointGroup
@@ -316,7 +303,7 @@ private:
             const extendedFeatureEdgeMesh& feMesh,
             const pointIndexHit& edHit,
             DynamicList<Vb>& pts
-        );
+        ) const;
 
         //- Create points to conform to a flat edge
         void createFlatEdgePointGroup
@@ -324,7 +311,7 @@ private:
             const extendedFeatureEdgeMesh& feMesh,
             const pointIndexHit& edHit,
             DynamicList<Vb>& pts
-        );
+        ) const;
 
         //- Create points to conform to an open edge
         void createOpenEdgePointGroup
@@ -332,7 +319,7 @@ private:
             const extendedFeatureEdgeMesh& feMesh,
             const pointIndexHit& edHit,
             DynamicList<Vb>& pts
-        );
+        ) const;
 
         //- Create points to conform to multiply connected edge
         void createMultipleEdgePointGroup
@@ -340,85 +327,10 @@ private:
             const extendedFeatureEdgeMesh& feMesh,
             const pointIndexHit& edHit,
             DynamicList<Vb>& pts
-        );
-
-        //- Determine and insert point groups at the feature points
-        void insertFeaturePoints();
-
-        //- Create point groups at mixed feature points
-        void createMixedFeaturePoints(DynamicList<Vb>& pts);
-
-        void addMasterAndSlavePoints
-        (
-            const DynamicList<Foam::point>& masterPoints,
-            const DynamicList<indexedVertexEnum::vertexType>&masterPointsTypes,
-            const Map<DynamicList<autoPtr<plane> > >& masterPointReflections,
-            DynamicList<Vb>& pts,
-            const label ptI
         ) const;
 
-        label getSign(const extendedFeatureEdgeMesh::edgeStatus eStatus) const;
-
-        void createMasterAndSlavePoints
-        (
-            const extendedFeatureEdgeMesh& feMesh,
-            const label ptI,
-            DynamicList<Vb>& pts
-        ) const;
-
-        void createFeaturePoints(DynamicList<Vb>& pts);
-
-        vector sharedFaceNormal
-        (
-            const extendedFeatureEdgeMesh& feMesh,
-            const label edgeI,
-            const label nextEdgeI
-        ) const;
-
-        List<Foam::point> reflectPointInPlanes
-        (
-            const Foam::point p,
-            const DynamicList<autoPtr<plane> >& planes
-        ) const;
-
-        Foam::point reflectPointInPlane
-        (
-            const Foam::point p,
-            const plane& planeN
-        ) const;
-
-
-        //- Fill the pointFeatureEdgesType struct with the types of feature
-        //  edges that are attached to the point.
-        List<extendedFeatureEdgeMesh::edgeStatus> calcPointFeatureEdgesTypes
-        (
-            const extendedFeatureEdgeMesh& feMesh,
-            const labelList& pEds,
-            pointFeatureEdgesTypes& pFEdgeTypes
-        ) const;
-
-        //- Create feature point groups if a specialisation exists for the
-        //  structure
-        bool createSpecialisedFeaturePoint
-        (
-            const extendedFeatureEdgeMesh& feMesh,
-            const labelList& pEds,
-            const pointFeatureEdgesTypes& pFEdgeTypes,
-            const List<extendedFeatureEdgeMesh::edgeStatus>& allEdStat,
-            const label ptI,
-            DynamicList<Vb>& pts
-        );
-
-        //- Store the locations of all of the features to be conformed to
-        void constructFeaturePointLocations();
-
-        List<pointIndexHit> findSurfacePtLocationsNearFeaturePoint
-        (
-            const Foam::point& featurePoint
-        ) const;
-
-        //- Reinsert stored feature point defining points
-        void reinsertFeaturePoints(bool distribute = false);
+        //- Determine and insert point groups at the feature points
+        void insertFeaturePoints(bool distribute = false);
 
         //- Check if a location is in exclusion range around a feature point
         bool nearFeaturePt(const Foam::point& pt) const;
@@ -1012,6 +924,7 @@ public:
                 DynamicList<Vb>& pts
             ) const;
 
+
         // Write
 
             //- Write the elapsedCpuTime and memory usage, with an optional
diff --git a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshFeaturePoints.C b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshFeaturePoints.C
index 612709e1406..980064fb48c 100644
--- a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshFeaturePoints.C
+++ b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshFeaturePoints.C
@@ -39,7 +39,7 @@ void Foam::conformalVoronoiMesh::createEdgePointGroup
     const extendedFeatureEdgeMesh& feMesh,
     const pointIndexHit& edHit,
     DynamicList<Vb>& pts
-)
+) const
 {
     if (foamyHexMeshControls().circulateEdges())
     {
@@ -165,7 +165,7 @@ void Foam::conformalVoronoiMesh::createEdgePointGroupByCirculating
     const extendedFeatureEdgeMesh& feMesh,
     const pointIndexHit& edHit,
     DynamicList<Vb>& pts
-)
+)  const
 {
     typedef Foam::indexedVertexEnum::vertexType         vertexType;
     typedef extendedFeatureEdgeMesh::sideVolumeType     sideVolumeType;
@@ -414,6 +414,7 @@ void Foam::conformalVoronoiMesh::createEdgePointGroupByCirculating
 
                 // Remove the first reflection plane if we are no longer
                 // circulating
+
                 masterPointReflectionsPrev.erase(initialRegion);
                 masterPointReflectionsNext.erase(circ.nRotations());
             }
@@ -481,7 +482,7 @@ void Foam::conformalVoronoiMesh::createExternalEdgePointGroup
     const extendedFeatureEdgeMesh& feMesh,
     const pointIndexHit& edHit,
     DynamicList<Vb>& pts
-)
+) const
 {
     const Foam::point& edgePt = edHit.hitPoint();
 
@@ -582,7 +583,7 @@ void Foam::conformalVoronoiMesh::createInternalEdgePointGroup
     const extendedFeatureEdgeMesh& feMesh,
     const pointIndexHit& edHit,
     DynamicList<Vb>& pts
-)
+) const
 {
     const Foam::point& edgePt = edHit.hitPoint();
 
@@ -758,7 +759,7 @@ void Foam::conformalVoronoiMesh::createFlatEdgePointGroup
     const extendedFeatureEdgeMesh& feMesh,
     const pointIndexHit& edHit,
     DynamicList<Vb>& pts
-)
+) const
 {
     const Foam::point& edgePt = edHit.hitPoint();
 
@@ -790,7 +791,7 @@ void Foam::conformalVoronoiMesh::createOpenEdgePointGroup
     const extendedFeatureEdgeMesh& feMesh,
     const pointIndexHit& edHit,
     DynamicList<Vb>& pts
-)
+) const
 {
     // Assume it is a baffle and insert flat edge point pairs
     const Foam::point& edgePt = edHit.hitPoint();
@@ -837,7 +838,7 @@ void Foam::conformalVoronoiMesh::createMultipleEdgePointGroup
     const extendedFeatureEdgeMesh& feMesh,
     const pointIndexHit& edHit,
     DynamicList<Vb>& pts
-)
+) const
 {
 //    Info<< "NOT INSERTING MULTIPLE EDGE POINT GROUP, NOT IMPLEMENTED" << endl;
 
@@ -868,618 +869,27 @@ void Foam::conformalVoronoiMesh::createMultipleEdgePointGroup
 }
 
 
-void Foam::conformalVoronoiMesh::reinsertFeaturePoints(bool distribute)
+void Foam::conformalVoronoiMesh::insertFeaturePoints(bool distribute)
 {
-    Info<< nl << "Reinserting stored feature points" << endl;
-
-    insertPoints(featureVertices_, distribute);
-}
+    Info<< nl
+        << "Inserting feature points" << endl;
 
+    const label preFeaturePointSize(number_of_vertices());
 
-void Foam::conformalVoronoiMesh::createMixedFeaturePoints
-(
-    DynamicList<Vb>& pts
-)
-{
-    if (foamyHexMeshControls().mixedFeaturePointPPDistanceCoeff() < 0)
+    if (Pstream::parRun() && distribute)
     {
-        Info<< nl << "Skipping specialised handling for mixed feature points"
-            << endl;
-        return;
+        ftPtConformer_.distribute(decomposition());
     }
 
-    const PtrList<extendedFeatureEdgeMesh>& feMeshes
-    (
-        geometryToConformTo_.features()
-    );
-
-    forAll(feMeshes, i)
-    {
-        const extendedFeatureEdgeMesh& feMesh = feMeshes[i];
-        const labelListList& pointsEdges = feMesh.pointEdges();
-        const pointField& points = feMesh.points();
-
-        for
-        (
-            label ptI = feMesh.mixedStart();
-            ptI < feMesh.nonFeatureStart();
-            ptI++
-        )
-        {
-            const Foam::point& featPt = points[ptI];
-
-            if (!positionOnThisProc(featPt))
-            {
-                continue;
-            }
-
-            const labelList& pEds = pointsEdges[ptI];
-
-            pointFeatureEdgesTypes pFEdgeTypes(ptI);
-
-            const List<extendedFeatureEdgeMesh::edgeStatus> allEdStat
-                = calcPointFeatureEdgesTypes(feMesh, pEds, pFEdgeTypes);
-
-            bool specialisedSuccess = false;
-
-            if (foamyHexMeshControls().specialiseFeaturePoints())
-            {
-                specialisedSuccess = createSpecialisedFeaturePoint
-                (
-                    feMesh, pEds, pFEdgeTypes, allEdStat, ptI, pts
-                );
-            }
-
-            if (!specialisedSuccess && foamyHexMeshControls().edgeAiming())
-            {
-                // Specialisations available for some mixed feature points.  For
-                // non-specialised feature points, inserting mixed internal and
-                // external edge groups at feature point.
-
-                // Skipping unsupported mixed feature point types
-//                bool skipEdge = false;
-//
-//                forAll(pEds, e)
-//                {
-//                    const label edgeI = pEds[e];
-//
-//                    const extendedFeatureEdgeMesh::edgeStatus edStatus
-//                        = feMesh.getEdgeStatus(edgeI);
-//
-//                    if
-//                    (
-//                        edStatus == extendedFeatureEdgeMesh::OPEN
-//                     || edStatus == extendedFeatureEdgeMesh::MULTIPLE
-//                    )
-//                    {
-//                        Info<< "Edge type " << edStatus
-//                            << " found for mixed feature point " << ptI
-//                            << ". Not supported."
-//                            << endl;
-//
-//                        skipEdge = true;
-//                    }
-//                }
-//
-//                if (skipEdge)
-//                {
-//                    Info<< "Skipping point " << ptI << nl << endl;
-//
-//                    continue;
-//                }
-
-//                createFeaturePoints(feMesh, ptI, pts, types);
-
-                const Foam::point pt = points[ptI];
-
-                const scalar edgeGroupDistance = mixedFeaturePointDistance(pt);
+    const List<Vb>& ftPtVertices = ftPtConformer_.featurePointVertices();
 
-                forAll(pEds, e)
-                {
-                    const label edgeI = pEds[e];
-
-                    const Foam::point edgePt =
-                        pt + edgeGroupDistance*feMesh.edgeDirection(edgeI, ptI);
-
-                    const pointIndexHit edgeHit(true, edgePt, edgeI);
-
-                    createEdgePointGroup(feMesh, edgeHit, pts);
-                }
-            }
-        }
-    }
-}
-//
-//
-//void Foam::conformalVoronoiMesh::createFeaturePoints
-//(
-//    DynamicList<Foam::point>& pts,
-//    DynamicList<label>& indices,
-//    DynamicList<label>& types
-//)
-//{
-//    const PtrList<extendedFeatureEdgeMesh>& feMeshes
-//    (
-//        geometryToConformTo_.features()
-//    );
-//
-//    forAll(feMeshes, i)
-//    {
-//        const extendedFeatureEdgeMesh& feMesh(feMeshes[i]);
-//
-//        for
-//        (
-//            label ptI = feMesh.convexStart();
-//            ptI < feMesh.mixedStart();
-//            ++ptI
-//        )
-//        {
-//            const Foam::point& featPt = feMesh.points()[ptI];
-//
-//            if (!positionOnThisProc(featPt))
-//            {
-//                continue;
-//            }
-//
-//            const scalar searchRadiusSqr = 5.0*targetCellSize(featPt);
-//
-//            labelList indices = surfacePtLocationTreePtr_().findSphere
-//            (
-//                featPt,
-//                searchRadiusSqr
-//            );
-//
-//            pointField nearestSurfacePoints(indices.size());
-//
-//            forAll(indices, pI)
-//            {
-//                nearestSurfacePoints[pI] =
-//                    surfaceConformationVertices_[indices[pI]];
-//            }
-//
-//            forAll(feMesh.)
-//
-//            // Now find the nearest points within the edge cones.
-//
-//            // Calculate preliminary surface point locations
-//
-//
-//        }
-//    }
-//}
-
-
-void Foam::conformalVoronoiMesh::insertFeaturePoints()
-{
-    Info<< nl << "Conforming to feature points" << endl;
-
-    Info<< "    Circulating edges is: "
-        << foamyHexMeshControls().circulateEdges().asText() << nl
-        << "    Guarding feature points is: "
-        << foamyHexMeshControls().guardFeaturePoints().asText() << nl
-        << "    Snapping to feature points is: "
-        << foamyHexMeshControls().snapFeaturePoints().asText() << nl
-        << "    Specialising feature points is: "
-        << foamyHexMeshControls().specialiseFeaturePoints().asText() << endl;
-
-
-    DynamicList<Vb> pts;
-
-    const label preFeaturePointSize = number_of_vertices();
-
-    createFeaturePoints(pts);
-
-    createMixedFeaturePoints(pts);
-
-    // Points added using the createEdgePointGroup function will be labelled as
-    // internal/external feature edges. Relabel them as feature points,
-    // otherwise they are inserted as both feature points and surface points.
-    forAll(pts, pI)
-    {
-        Vb& pt = pts[pI];
-
-        //if (pt.featureEdgePoint())
-        {
-            if (pt.internalBoundaryPoint())
-            {
-                pt.type() = Vb::vtInternalFeaturePoint;
-            }
-            else if (pt.externalBoundaryPoint())
-            {
-                pt.type() = Vb::vtExternalFeaturePoint;
-            }
-        }
-    }
-
-    // Insert the created points, distributing to the appropriate processor
-    insertPoints(pts, true);
-
-    if (foamyHexMeshControls().objOutput())
-    {
-        writePoints("featureVertices.obj", pts);
-    }
+    // Insert the created points directly as already distributed.
+    this->DelaunayMesh<Delaunay>::insertPoints(ftPtVertices);
 
     label nFeatureVertices = number_of_vertices() - preFeaturePointSize;
     reduce(nFeatureVertices, sumOp<label>());
 
     Info<< "    Inserted " << nFeatureVertices << " feature vertices" << endl;
-
-    featureVertices_.clear();
-    featureVertices_.setSize(pts.size());
-
-    forAll(pts, pI)
-    {
-        featureVertices_[pI] = pts[pI];
-    }
-
-    constructFeaturePointLocations();
-}
-
-
-void Foam::conformalVoronoiMesh::constructFeaturePointLocations()
-{
-    DynamicList<Foam::point> ftPtLocs;
-
-    const PtrList<extendedFeatureEdgeMesh>& feMeshes
-    (
-        geometryToConformTo_.features()
-    );
-
-    forAll(feMeshes, i)
-    {
-        const extendedFeatureEdgeMesh& feMesh(feMeshes[i]);
-
-        if (foamyHexMeshControls().mixedFeaturePointPPDistanceCoeff() < 0)
-        {
-            // Ignoring mixed feature points
-            for
-            (
-                label ptI = feMesh.convexStart();
-                ptI < feMesh.mixedStart();
-                ptI++
-            )
-            {
-                ftPtLocs.append(feMesh.points()[ptI]);
-            }
-        }
-        else
-        {
-            for
-            (
-                label ptI = feMesh.convexStart();
-                ptI < feMesh.nonFeatureStart();
-                ptI++
-            )
-            {
-                ftPtLocs.append(feMesh.points()[ptI]);
-            }
-        }
-    }
-
-    featurePointLocations_.transfer(ftPtLocs);
-}
-
-
-Foam::List<Foam::pointIndexHit>
-Foam::conformalVoronoiMesh::findSurfacePtLocationsNearFeaturePoint
-(
-    const Foam::point& featurePoint
-) const
-{
-    DynamicList<pointIndexHit> dynPointList;
-
-    const scalar searchRadiusSqr = 3*targetCellSize(featurePoint);
-
-    labelList surfacePtList = surfacePtLocationTreePtr_().findSphere
-    (
-       featurePoint,
-       searchRadiusSqr
-    );
-
-    forAll(surfacePtList, elemI)
-    {
-       label index = surfacePtList[elemI];
-
-       const Foam::point& p
-           = surfacePtLocationTreePtr_().shapes().shapePoints()[index];
-
-       pointIndexHit nearHit(true, p, index);
-
-       dynPointList.append(nearHit);
-    }
-
-    return dynPointList.shrink();
-}
-
-
-void Foam::conformalVoronoiMesh::addMasterAndSlavePoints
-(
-    const DynamicList<Foam::point>& masterPoints,
-    const DynamicList<Foam::indexedVertexEnum::vertexType>& masterPointsTypes,
-    const Map<DynamicList<autoPtr<plane> > >& masterPointReflections,
-    DynamicList<Vb>& pts,
-    const label ptI
-) const
-{
-    typedef DynamicList<autoPtr<plane> >        planeDynList;
-    typedef Foam::indexedVertexEnum::vertexType vertexType;
-
-    forAll(masterPoints, pI)
-    {
-        // Append master to the list of points
-
-        const Foam::point& masterPt = masterPoints[pI];
-        const vertexType masterType = masterPointsTypes[pI];
-
-//        Info<< "    Master = " << masterPt << endl;
-
-        pts.append
-        (
-            Vb
-            (
-                masterPt,
-                vertexCount() + pts.size(),
-                masterType,
-                Pstream::myProcNo()
-            )
-        );
-
-//        const label masterIndex = pts[pts.size() - 1].index();
-
-        //meshTools::writeOBJ(strMasters, masterPt);
-
-        const planeDynList& masterPointPlanes = masterPointReflections[pI];
-
-        forAll(masterPointPlanes, planeI)
-        {
-            // Reflect master points in the planes and insert the slave points
-
-            const plane& reflPlane = masterPointPlanes[planeI]();
-
-            const Foam::point slavePt = reflPlane.mirror(masterPt);
-
-//            Info<< "        Slave " << planeI << " = " << slavePt << endl;
-
-            const vertexType slaveType =
-            (
-                masterType == Vb::vtInternalFeaturePoint
-              ? Vb::vtExternalFeaturePoint // true
-              : Vb::vtInternalFeaturePoint // false
-            );
-
-            pts.append
-            (
-                Vb
-                (
-                    slavePt,
-                    vertexCount() + pts.size(),
-                    slaveType,
-                    Pstream::myProcNo()
-                )
-            );
-
-
-            //meshTools::writeOBJ(strSlaves, slavePt);
-        }
-    }
-}
-
-
-Foam::label Foam::conformalVoronoiMesh::getSign
-(
-    const extendedFeatureEdgeMesh::edgeStatus eStatus
-) const
-{
-    if (eStatus == extendedFeatureEdgeMesh::EXTERNAL)
-    {
-        return -1;
-    }
-    else if (eStatus == extendedFeatureEdgeMesh::INTERNAL)
-    {
-        return 1;
-    }
-
-    return 0;
-}
-
-
-void Foam::conformalVoronoiMesh::createMasterAndSlavePoints
-(
-    const extendedFeatureEdgeMesh& feMesh,
-    const label ptI,
-    DynamicList<Vb>& pts
-) const
-{
-    typedef DynamicList<autoPtr<plane> >                planeDynList;
-    typedef Foam::indexedVertexEnum::vertexType         vertexType;
-    typedef Foam::extendedFeatureEdgeMesh::edgeStatus   edgeStatus;
-
-    const Foam::point& featPt = feMesh.points()[ptI];
-
-    if (!positionOnThisProc(featPt) || geometryToConformTo_.outside(featPt))
-    {
-        return;
-    }
-
-    const scalar ppDist = pointPairDistance(featPt);
-
-    // Maintain a list of master points and the planes to relect them in
-    DynamicList<Foam::point> masterPoints;
-    DynamicList<vertexType> masterPointsTypes;
-    Map<planeDynList> masterPointReflections;
-
-    const labelList& featPtEdges = feMesh.featurePointEdges()[ptI];
-
-    pointFeatureEdgesTypes pointEdgeTypes(ptI);
-
-    const List<extendedFeatureEdgeMesh::edgeStatus> allEdStat
-        = calcPointFeatureEdgesTypes(feMesh, featPtEdges, pointEdgeTypes);
-
-//    Info<< nl << featPt << "  " << pointEdgeTypes;
-
-    const_circulator<labelList> circ(featPtEdges);
-
-    // Loop around the edges of the feature point
-    if (circ.size()) do
-    {
-//        const edgeStatus eStatusPrev = feMesh.getEdgeStatus(circ.prev());
-        const edgeStatus eStatusCurr = feMesh.getEdgeStatus(circ());
-//        const edgeStatus eStatusNext = feMesh.getEdgeStatus(circ.next());
-
-//        Info<< "    Prev = "
-//            << extendedFeatureEdgeMesh::edgeStatusNames_[eStatusPrev]
-//            << " Curr = "
-//            << extendedFeatureEdgeMesh::edgeStatusNames_[eStatusCurr]
-////            << " Next = "
-////            << extendedFeatureEdgeMesh::edgeStatusNames_[eStatusNext]
-//            << endl;
-
-        // Get the direction in which to move the point in relation to the
-        // feature point
-        label sign = getSign(eStatusCurr);
-
-        const vector n = sharedFaceNormal(feMesh, circ(), circ.next());
-
-        const vector pointMotionDirection = sign*0.5*ppDist*n;
-
-//        Info<< "    Shared face normal      = " << n << endl;
-//        Info<< "    Direction to move point = " << pointMotionDirection
-//            << endl;
-
-        if (masterPoints.empty())
-        {
-            // Initialise with the first master point
-            Foam::point pt = featPt + pointMotionDirection;
-
-            planeDynList firstPlane;
-            firstPlane.append(autoPtr<plane>(new plane(featPt, n)));
-
-            masterPoints.append(pt);
-
-            masterPointsTypes.append
-            (
-                sign == 1
-              ? Vb::vtExternalFeaturePoint // true
-              : Vb::vtInternalFeaturePoint // false
-            );
-
-            //Info<< "    " << " " << firstPlane << endl;
-
-//            const Foam::point reflectedPoint = reflectPointInPlane
-//            (
-//                masterPoints.last(),
-//                firstPlane.last()()
-//            );
-
-            masterPointReflections.insert
-            (
-                masterPoints.size() - 1,
-                firstPlane
-            );
-        }
-//        else if
-//        (
-//            eStatusPrev == extendedFeatureEdgeMesh::INTERNAL
-//         && eStatusCurr == extendedFeatureEdgeMesh::EXTERNAL
-//        )
-//        {
-//            // Insert a new master point.
-//            Foam::point pt = featPt + pointMotionDirection;
-//
-//            planeDynList firstPlane;
-//            firstPlane.append(autoPtr<plane>(new plane(featPt, n)));
-//
-//            masterPoints.append(pt);
-//
-//            masterPointsTypes.append
-//            (
-//                sign == 1
-//              ? Vb::vtExternalFeaturePoint // true
-//              : Vb::vtInternalFeaturePoint // false
-//            );
-//
-//            masterPointReflections.insert
-//            (
-//                masterPoints.size() - 1,
-//                firstPlane
-//            );
-//        }
-//        else if
-//        (
-//            eStatusPrev == extendedFeatureEdgeMesh::EXTERNAL
-//         && eStatusCurr == extendedFeatureEdgeMesh::INTERNAL
-//        )
-//        {
-//
-//        }
-        else
-        {
-            // Just add this face contribution to the latest master point
-
-            masterPoints.last() += pointMotionDirection;
-
-            masterPointReflections[masterPoints.size() - 1].append
-            (
-                autoPtr<plane>(new plane(featPt, n))
-            );
-        }
-
-    } while (circ.circulate(CirculatorBase::CLOCKWISE));
-
-    addMasterAndSlavePoints
-    (
-        masterPoints,
-        masterPointsTypes,
-        masterPointReflections,
-        pts,
-        ptI
-    );
-}
-
-
-void Foam::conformalVoronoiMesh::createFeaturePoints(DynamicList<Vb>& pts)
-{
-    const PtrList<extendedFeatureEdgeMesh>& feMeshes
-    (
-        geometryToConformTo_.features()
-    );
-
-    forAll(feMeshes, i)
-    {
-        const extendedFeatureEdgeMesh& feMesh(feMeshes[i]);
-
-        for
-        (
-            label ptI = feMesh.convexStart();
-            ptI < feMesh.mixedStart();
-//            ptI < feMesh.nonFeatureStart();
-            ptI++
-        )
-        {
-            createMasterAndSlavePoints(feMesh, ptI, pts);
-        }
-
-        if (foamyHexMeshControls().guardFeaturePoints())
-        {
-            for
-            (
-                //label ptI = feMesh.convexStart();
-                label ptI = feMesh.mixedStart();
-                ptI < feMesh.nonFeatureStart();
-                ptI++
-            )
-            {
-                pts.append
-                (
-                    Vb
-                    (
-                        feMesh.points()[ptI],
-                        Vb::vtConstrained
-                    )
-                );
-            }
-        }
-    }
 }
 
 
@@ -1655,71 +1065,3 @@ void Foam::conformalVoronoiMesh::createFeaturePoints(DynamicList<Vb>& pts)
 //        }
 //    }
 //}
-
-
-Foam::vector Foam::conformalVoronoiMesh::sharedFaceNormal
-(
-    const extendedFeatureEdgeMesh& feMesh,
-    const label edgeI,
-    const label nextEdgeI
-) const
-{
-    const labelList& edgeInormals = feMesh.edgeNormals()[edgeI];
-    const labelList& nextEdgeInormals = feMesh.edgeNormals()[nextEdgeI];
-
-    const vector& A1 = feMesh.normals()[edgeInormals[0]];
-    const vector& A2 = feMesh.normals()[edgeInormals[1]];
-
-    const vector& B1 = feMesh.normals()[nextEdgeInormals[0]];
-    const vector& B2 = feMesh.normals()[nextEdgeInormals[1]];
-
-//    Info<< "        A1 = " << A1 << endl;
-//    Info<< "        A2 = " << A2 << endl;
-//    Info<< "        B1 = " << B1 << endl;
-//    Info<< "        B2 = " << B2 << endl;
-
-    const scalar A1B1 = mag((A1 & B1) - 1.0);
-    const scalar A1B2 = mag((A1 & B2) - 1.0);
-    const scalar A2B1 = mag((A2 & B1) - 1.0);
-    const scalar A2B2 = mag((A2 & B2) - 1.0);
-
-//    Info<< "      A1B1 = " << A1B1 << endl;
-//    Info<< "      A1B2 = " << A1B2 << endl;
-//    Info<< "      A2B1 = " << A2B1 << endl;
-//    Info<< "      A2B2 = " << A2B2 << endl;
-
-    if (A1B1 < A1B2 && A1B1 < A2B1 && A1B1 < A2B2)
-    {
-        return 0.5*(A1 + B1);
-    }
-    else if (A1B2 < A1B1 && A1B2 < A2B1 && A1B2 < A2B2)
-    {
-        return 0.5*(A1 + B2);
-    }
-    else if (A2B1 < A1B1 && A2B1 < A1B2 && A2B1 < A2B2)
-    {
-        return 0.5*(A2 + B1);
-    }
-    else
-    {
-        return 0.5*(A2 + B2);
-    }
-}
-
-
-Foam::List<Foam::point> Foam::conformalVoronoiMesh::reflectPointInPlanes
-(
-    const Foam::point p,
-    const DynamicList<autoPtr<plane> >& planes
-) const
-{
-    List<Foam::point> reflectedPoints(planes.size());
-
-    forAll(planes, planeI)
-    {
-        reflectedPoints[planeI] = planes[planeI]().mirror(p);
-    }
-
-    return reflectedPoints;
-}
-
diff --git a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshI.H b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshI.H
index ff73cd79bd6..def7120d554 100644
--- a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshI.H
+++ b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshI.H
@@ -226,7 +226,7 @@ inline void Foam::conformalVoronoiMesh::createPointPair
     const Foam::point& surfPt,
     const vector& n,
     DynamicList<Vb>& pts
-)
+) const
 {
     vector ppDistn = ppDist*n;
 
@@ -297,7 +297,7 @@ inline void Foam::conformalVoronoiMesh::createBafflePointPair
     const Foam::point& surfPt,
     const vector& n,
     DynamicList<Vb>& pts
-)
+) const
 {
     vector ppDistn = ppDist*n;
 
diff --git a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/featurePointConformer/featurePointConformer.C b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/featurePointConformer/featurePointConformer.C
new file mode 100644
index 00000000000..9d88745ef8f
--- /dev/null
+++ b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/featurePointConformer/featurePointConformer.C
@@ -0,0 +1,598 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2013 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "featurePointConformer.H"
+#include "cvControls.H"
+#include "conformationSurfaces.H"
+#include "conformalVoronoiMesh.H"
+#include "cellShapeControl.H"
+#include "DelaunayMeshTools.H"
+#include "const_circulator.H"
+#include "backgroundMeshDecomposition.H"
+#include "autoPtr.H"
+#include "mapDistribute.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+defineTypeNameAndDebug(featurePointConformer, 0);
+}
+
+const Foam::scalar Foam::featurePointConformer::tolParallel = 1e-3;
+
+
+// * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * * //
+
+Foam::vector Foam::featurePointConformer::sharedFaceNormal
+(
+    const extendedFeatureEdgeMesh& feMesh,
+    const label edgeI,
+    const label nextEdgeI
+) const
+{
+    const labelList& edgeInormals = feMesh.edgeNormals()[edgeI];
+    const labelList& nextEdgeInormals = feMesh.edgeNormals()[nextEdgeI];
+
+    const vector& A1 = feMesh.normals()[edgeInormals[0]];
+    const vector& A2 = feMesh.normals()[edgeInormals[1]];
+
+    const vector& B1 = feMesh.normals()[nextEdgeInormals[0]];
+    const vector& B2 = feMesh.normals()[nextEdgeInormals[1]];
+
+//    Info<< "        A1 = " << A1 << endl;
+//    Info<< "        A2 = " << A2 << endl;
+//    Info<< "        B1 = " << B1 << endl;
+//    Info<< "        B2 = " << B2 << endl;
+
+    const scalar A1B1 = mag((A1 & B1) - 1.0);
+    const scalar A1B2 = mag((A1 & B2) - 1.0);
+    const scalar A2B1 = mag((A2 & B1) - 1.0);
+    const scalar A2B2 = mag((A2 & B2) - 1.0);
+
+//    Info<< "      A1B1 = " << A1B1 << endl;
+//    Info<< "      A1B2 = " << A1B2 << endl;
+//    Info<< "      A2B1 = " << A2B1 << endl;
+//    Info<< "      A2B2 = " << A2B2 << endl;
+
+    if (A1B1 < A1B2 && A1B1 < A2B1 && A1B1 < A2B2)
+    {
+        return 0.5*(A1 + B1);
+    }
+    else if (A1B2 < A1B1 && A1B2 < A2B1 && A1B2 < A2B2)
+    {
+        return 0.5*(A1 + B2);
+    }
+    else if (A2B1 < A1B1 && A2B1 < A1B2 && A2B1 < A2B2)
+    {
+        return 0.5*(A2 + B1);
+    }
+    else
+    {
+        return 0.5*(A2 + B2);
+    }
+}
+
+
+Foam::label Foam::featurePointConformer::getSign
+(
+    const extendedFeatureEdgeMesh::edgeStatus eStatus
+) const
+{
+    if (eStatus == extendedFeatureEdgeMesh::EXTERNAL)
+    {
+        return -1;
+    }
+    else if (eStatus == extendedFeatureEdgeMesh::INTERNAL)
+    {
+        return 1;
+    }
+
+    return 0;
+}
+
+
+void Foam::featurePointConformer::addMasterAndSlavePoints
+(
+    const DynamicList<Foam::point>& masterPoints,
+    const DynamicList<Foam::indexedVertexEnum::vertexType>& masterPointsTypes,
+    const Map<DynamicList<autoPtr<plane> > >& masterPointReflections,
+    DynamicList<Vb>& pts,
+    const label ptI
+) const
+{
+    typedef DynamicList<autoPtr<plane> >        planeDynList;
+    typedef Foam::indexedVertexEnum::vertexType vertexType;
+
+    forAll(masterPoints, pI)
+    {
+        // Append master to the list of points
+
+        const Foam::point& masterPt = masterPoints[pI];
+        const vertexType masterType = masterPointsTypes[pI];
+
+//        Info<< "    Master = " << masterPt << endl;
+
+        pts.append
+        (
+            Vb
+            (
+                masterPt,
+                foamyHexMesh_.vertexCount() + pts.size(),
+                masterType,
+                Pstream::myProcNo()
+            )
+        );
+
+//        const label masterIndex = pts[pts.size() - 1].index();
+
+        //meshTools::writeOBJ(strMasters, masterPt);
+
+        const planeDynList& masterPointPlanes = masterPointReflections[pI];
+
+        forAll(masterPointPlanes, planeI)
+        {
+            // Reflect master points in the planes and insert the slave points
+
+            const plane& reflPlane = masterPointPlanes[planeI]();
+
+            const Foam::point slavePt = reflPlane.mirror(masterPt);
+
+//            Info<< "        Slave " << planeI << " = " << slavePt << endl;
+
+            const vertexType slaveType =
+            (
+                masterType == Vb::vtInternalFeaturePoint
+              ? Vb::vtExternalFeaturePoint // true
+              : Vb::vtInternalFeaturePoint // false
+            );
+
+            pts.append
+            (
+                Vb
+                (
+                    slavePt,
+                    foamyHexMesh_.vertexCount() + pts.size(),
+                    slaveType,
+                    Pstream::myProcNo()
+                )
+            );
+
+
+            //meshTools::writeOBJ(strSlaves, slavePt);
+        }
+    }
+}
+
+
+void Foam::featurePointConformer::createMasterAndSlavePoints
+(
+    const extendedFeatureEdgeMesh& feMesh,
+    const label ptI,
+    DynamicList<Vb>& pts
+) const
+{
+    typedef DynamicList<autoPtr<plane> >          planeDynList;
+    typedef indexedVertexEnum::vertexType         vertexType;
+    typedef extendedFeatureEdgeMesh::edgeStatus   edgeStatus;
+
+    const Foam::point& featPt = feMesh.points()[ptI];
+
+    if
+    (
+        !foamyHexMesh_.positionOnThisProc(featPt)
+     || geometryToConformTo_.outside(featPt)
+    )
+    {
+        return;
+    }
+
+    const scalar ppDist = foamyHexMesh_.pointPairDistance(featPt);
+
+    // Maintain a list of master points and the planes to relect them in
+    DynamicList<Foam::point> masterPoints;
+    DynamicList<vertexType> masterPointsTypes;
+    Map<planeDynList> masterPointReflections;
+
+    const labelList& featPtEdges = feMesh.featurePointEdges()[ptI];
+
+    pointFeatureEdgesTypes pointEdgeTypes(feMesh, ptI);
+
+    const List<extendedFeatureEdgeMesh::edgeStatus> allEdStat =
+        pointEdgeTypes.calcPointFeatureEdgesTypes();
+
+//    Info<< nl << featPt << "  " << pointEdgeTypes;
+
+    const_circulator<labelList> circ(featPtEdges);
+
+    // Loop around the edges of the feature point
+    if (circ.size()) do
+    {
+//        const edgeStatus eStatusPrev = feMesh.getEdgeStatus(circ.prev());
+        const edgeStatus eStatusCurr = feMesh.getEdgeStatus(circ());
+//        const edgeStatus eStatusNext = feMesh.getEdgeStatus(circ.next());
+
+//        Info<< "    Prev = "
+//            << extendedFeatureEdgeMesh::edgeStatusNames_[eStatusPrev]
+//            << " Curr = "
+//            << extendedFeatureEdgeMesh::edgeStatusNames_[eStatusCurr]
+////            << " Next = "
+////            << extendedFeatureEdgeMesh::edgeStatusNames_[eStatusNext]
+//            << endl;
+
+        // Get the direction in which to move the point in relation to the
+        // feature point
+        label sign = getSign(eStatusCurr);
+
+        const vector n = sharedFaceNormal(feMesh, circ(), circ.next());
+
+        const vector pointMotionDirection = sign*0.5*ppDist*n;
+
+//        Info<< "    Shared face normal      = " << n << endl;
+//        Info<< "    Direction to move point = " << pointMotionDirection
+//            << endl;
+
+        if (masterPoints.empty())
+        {
+            // Initialise with the first master point
+            Foam::point pt = featPt + pointMotionDirection;
+
+            planeDynList firstPlane;
+            firstPlane.append(autoPtr<plane>(new plane(featPt, n)));
+
+            masterPoints.append(pt);
+
+            masterPointsTypes.append
+            (
+                sign == 1
+              ? Vb::vtExternalFeaturePoint // true
+              : Vb::vtInternalFeaturePoint // false
+            );
+
+            //Info<< "    " << " " << firstPlane << endl;
+
+//            const Foam::point reflectedPoint = reflectPointInPlane
+//            (
+//                masterPoints.last(),
+//                firstPlane.last()()
+//            );
+
+            masterPointReflections.insert
+            (
+                masterPoints.size() - 1,
+                firstPlane
+            );
+        }
+//        else if
+//        (
+//            eStatusPrev == extendedFeatureEdgeMesh::INTERNAL
+//         && eStatusCurr == extendedFeatureEdgeMesh::EXTERNAL
+//        )
+//        {
+//            // Insert a new master point.
+//            Foam::point pt = featPt + pointMotionDirection;
+//
+//            planeDynList firstPlane;
+//            firstPlane.append(autoPtr<plane>(new plane(featPt, n)));
+//
+//            masterPoints.append(pt);
+//
+//            masterPointsTypes.append
+//            (
+//                sign == 1
+//              ? Vb::vtExternalFeaturePoint // true
+//              : Vb::vtInternalFeaturePoint // false
+//            );
+//
+//            masterPointReflections.insert
+//            (
+//                masterPoints.size() - 1,
+//                firstPlane
+//            );
+//        }
+//        else if
+//        (
+//            eStatusPrev == extendedFeatureEdgeMesh::EXTERNAL
+//         && eStatusCurr == extendedFeatureEdgeMesh::INTERNAL
+//        )
+//        {
+//
+//        }
+        else
+        {
+            // Just add this face contribution to the latest master point
+
+            masterPoints.last() += pointMotionDirection;
+
+            masterPointReflections[masterPoints.size() - 1].append
+            (
+                autoPtr<plane>(new plane(featPt, n))
+            );
+        }
+
+    } while (circ.circulate(CirculatorBase::CLOCKWISE));
+
+    addMasterAndSlavePoints
+    (
+        masterPoints,
+        masterPointsTypes,
+        masterPointReflections,
+        pts,
+        ptI
+    );
+}
+
+
+void Foam::featurePointConformer::createMixedFeaturePoints
+(
+    DynamicList<Vb>& pts
+) const
+{
+    if (foamyHexMeshControls_.mixedFeaturePointPPDistanceCoeff() < 0)
+    {
+        Info<< nl
+            << "Skipping specialised handling for mixed feature points" << endl;
+
+        return;
+    }
+
+    const PtrList<extendedFeatureEdgeMesh>& feMeshes
+    (
+        geometryToConformTo_.features()
+    );
+
+    forAll(feMeshes, i)
+    {
+        const extendedFeatureEdgeMesh& feMesh = feMeshes[i];
+        const labelListList& pointsEdges = feMesh.pointEdges();
+        const pointField& points = feMesh.points();
+
+        for
+        (
+            label ptI = feMesh.mixedStart();
+            ptI < feMesh.nonFeatureStart();
+            ptI++
+        )
+        {
+            const Foam::point& featPt = points[ptI];
+
+            if (!foamyHexMesh_.positionOnThisProc(featPt))
+            {
+                continue;
+            }
+
+            const labelList& pEds = pointsEdges[ptI];
+
+            pointFeatureEdgesTypes pFEdgeTypes(feMesh, ptI);
+
+            const List<extendedFeatureEdgeMesh::edgeStatus> allEdStat =
+                pFEdgeTypes.calcPointFeatureEdgesTypes();
+
+            bool specialisedSuccess = false;
+
+            if (foamyHexMeshControls_.specialiseFeaturePoints())
+            {
+                specialisedSuccess =
+                    createSpecialisedFeaturePoint
+                    (
+                        feMesh, pEds, pFEdgeTypes, allEdStat, ptI, pts
+                    );
+            }
+
+            if (!specialisedSuccess && foamyHexMeshControls_.edgeAiming())
+            {
+                // Specialisations available for some mixed feature points.  For
+                // non-specialised feature points, inserting mixed internal and
+                // external edge groups at feature point.
+
+                // Skipping unsupported mixed feature point types
+//                bool skipEdge = false;
+//
+//                forAll(pEds, e)
+//                {
+//                    const label edgeI = pEds[e];
+//
+//                    const extendedFeatureEdgeMesh::edgeStatus edStatus
+//                        = feMesh.getEdgeStatus(edgeI);
+//
+//                    if
+//                    (
+//                        edStatus == extendedFeatureEdgeMesh::OPEN
+//                     || edStatus == extendedFeatureEdgeMesh::MULTIPLE
+//                    )
+//                    {
+//                        Info<< "Edge type " << edStatus
+//                            << " found for mixed feature point " << ptI
+//                            << ". Not supported."
+//                            << endl;
+//
+//                        skipEdge = true;
+//                    }
+//                }
+//
+//                if (skipEdge)
+//                {
+//                    Info<< "Skipping point " << ptI << nl << endl;
+//
+//                    continue;
+//                }
+
+//                createFeaturePoints(feMesh, ptI, pts, types);
+
+                const Foam::point& pt = points[ptI];
+
+                const scalar edgeGroupDistance =
+                    foamyHexMesh_.mixedFeaturePointDistance(pt);
+
+                forAll(pEds, e)
+                {
+                    const label edgeI = pEds[e];
+
+                    const Foam::point edgePt =
+                        pt + edgeGroupDistance*feMesh.edgeDirection(edgeI, ptI);
+
+                    const pointIndexHit edgeHit(true, edgePt, edgeI);
+
+                    foamyHexMesh_.createEdgePointGroup(feMesh, edgeHit, pts);
+                }
+            }
+        }
+    }
+}
+
+
+void Foam::featurePointConformer::createFeaturePoints(DynamicList<Vb>& pts)
+{
+    const PtrList<extendedFeatureEdgeMesh>& feMeshes
+    (
+        geometryToConformTo_.features()
+    );
+
+    forAll(feMeshes, i)
+    {
+        const extendedFeatureEdgeMesh& feMesh(feMeshes[i]);
+
+        for
+        (
+            label ptI = feMesh.convexStart();
+            ptI < feMesh.mixedStart();
+//            ptI < feMesh.nonFeatureStart();
+            ptI++
+        )
+        {
+            createMasterAndSlavePoints(feMesh, ptI, pts);
+        }
+
+        if (foamyHexMeshControls_.guardFeaturePoints())
+        {
+            for
+            (
+                //label ptI = feMesh.convexStart();
+                label ptI = feMesh.mixedStart();
+                ptI < feMesh.nonFeatureStart();
+                ptI++
+            )
+            {
+                pts.append
+                (
+                    Vb
+                    (
+                        feMesh.points()[ptI],
+                        Vb::vtConstrained
+                    )
+                );
+            }
+        }
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::featurePointConformer::featurePointConformer
+(
+    const conformalVoronoiMesh& foamyHexMesh
+)
+:
+    foamyHexMesh_(foamyHexMesh),
+    foamyHexMeshControls_(foamyHexMesh.foamyHexMeshControls()),
+    geometryToConformTo_(foamyHexMesh.geometryToConformTo()),
+    featurePointVertices_()
+{
+    Info<< nl
+        << "Conforming to feature points" << endl;
+
+    Info<< incrIndent
+        << indent << "Circulating edges is: "
+        << foamyHexMeshControls_.circulateEdges().asText() << nl
+        << indent << "Guarding feature points is: "
+        << foamyHexMeshControls_.guardFeaturePoints().asText() << nl
+        << indent << "Snapping to feature points is: "
+        << foamyHexMeshControls_.snapFeaturePoints().asText() << nl
+        << indent << "Specialising feature points is: "
+        << foamyHexMeshControls_.specialiseFeaturePoints().asText()
+        << decrIndent
+        << endl;
+
+    DynamicList<Vb> pts;
+
+    createFeaturePoints(pts);
+
+    createMixedFeaturePoints(pts);
+
+    // Points added using the createEdgePointGroup function will be labelled as
+    // internal/external feature edges. Relabel them as feature points,
+    // otherwise they are inserted as both feature points and surface points.
+    forAll(pts, pI)
+    {
+        Vb& pt = pts[pI];
+
+        //if (pt.featureEdgePoint())
+        {
+            if (pt.internalBoundaryPoint())
+            {
+                pt.type() = Vb::vtInternalFeaturePoint;
+            }
+            else if (pt.externalBoundaryPoint())
+            {
+                pt.type() = Vb::vtExternalFeaturePoint;
+            }
+        }
+    }
+
+    if (foamyHexMeshControls_.objOutput())
+    {
+        DelaunayMeshTools::writeOBJ("featureVertices.obj", pts);
+    }
+
+    featurePointVertices_.transfer(pts);
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::featurePointConformer::~featurePointConformer()
+{}
+
+
+// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
+
+void Foam::featurePointConformer::distribute
+(
+    const backgroundMeshDecomposition& decomposition
+)
+{
+    // Distribute points to their appropriate processor
+    decomposition.distributePoints(featurePointVertices_);
+
+    // Update the processor indices of the points to the new processor number
+    forAll(featurePointVertices_, vI)
+    {
+        featurePointVertices_[vI].procIndex() = Pstream::myProcNo();
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/featurePointConformer/featurePointConformer.H b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/featurePointConformer/featurePointConformer.H
new file mode 100644
index 00000000000..d4d52c1fff8
--- /dev/null
+++ b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/featurePointConformer/featurePointConformer.H
@@ -0,0 +1,187 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2013 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::featurePointConformer
+
+Description
+    The Delaunay vertices required to conform to a feature point can be
+    determined upon initialisation because the feature points are fixed and
+    do not change throughout the meshing process.
+
+SourceFiles
+    featurePointConformerI.H
+    featurePointConformer.C
+    featurePointConformerSpecialisations.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef featurePointConformer_H
+#define featurePointConformer_H
+
+#include "CGALTriangulation3Ddefs.H"
+#include "vector.H"
+#include "DynamicList.H"
+#include "List.H"
+#include "extendedFeatureEdgeMesh.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+class conformalVoronoiMesh;
+class cvControls;
+class conformationSurfaces;
+class pointFeatureEdgesTypes;
+class backgroundMeshDecomposition;
+
+/*---------------------------------------------------------------------------*\
+                   Class featurePointConformer Declaration
+\*---------------------------------------------------------------------------*/
+
+class featurePointConformer
+{
+    // Static data
+
+        //- Tolerance within which two lines are said to be parallel.
+        static const scalar tolParallel;
+
+
+    // Private data
+
+        //- Reference to the mesher.
+        const conformalVoronoiMesh& foamyHexMesh_;
+
+        //- Reference to the mesher controls.
+        const cvControls& foamyHexMeshControls_;
+
+        //- Reference to the conformation surfaces.
+        const conformationSurfaces& geometryToConformTo_;
+
+        //- Store the feature constraining points, to be reinserted after a
+        //  triangulation clear.
+        List<Vb> featurePointVertices_;
+
+
+    // Private Member Functions
+
+        //- Calculate the shared face normal between two edges geometrically.
+        vector sharedFaceNormal
+        (
+            const extendedFeatureEdgeMesh& feMesh,
+            const label edgeI,
+            const label nextEdgeI
+        ) const;
+
+        label getSign(const extendedFeatureEdgeMesh::edgeStatus eStatus) const;
+
+        bool createSpecialisedFeaturePoint
+        (
+            const extendedFeatureEdgeMesh& feMesh,
+            const labelList& pEds,
+            const pointFeatureEdgesTypes& pFEdgesTypes,
+            const List<extendedFeatureEdgeMesh::edgeStatus>& allEdStat,
+            const label ptI,
+            DynamicList<Vb>& pts
+        ) const;
+
+
+        void addMasterAndSlavePoints
+        (
+            const DynamicList<point>& masterPoints,
+            const DynamicList<indexedVertexEnum::vertexType>& masterPointsTypes,
+            const Map<DynamicList<autoPtr<plane> > >& masterPointReflections,
+            DynamicList<Vb>& pts,
+            const label ptI
+        ) const;
+
+        //- Helper function for conforming to feature points
+        void createMasterAndSlavePoints
+        (
+            const extendedFeatureEdgeMesh& feMesh,
+            const label ptI,
+            DynamicList<Vb>& pts
+        ) const;
+
+        void createMixedFeaturePoints(DynamicList<Vb>& pts) const;
+
+        //- Create the points that will conform to the feature
+        void createFeaturePoints(DynamicList<Vb>& pts);
+
+        //- Disallow default bitwise copy construct
+        featurePointConformer(const featurePointConformer&);
+
+        //- Disallow default bitwise assignment
+        void operator=(const featurePointConformer&);
+
+
+public:
+
+    //- Runtime type information
+    ClassName("featurePointConformer");
+
+
+    // Constructors
+
+        //- Construct from components
+        explicit featurePointConformer
+        (
+            const conformalVoronoiMesh& foamyHexMesh
+        );
+
+
+    //- Destructor
+    ~featurePointConformer();
+
+
+    // Member Functions
+
+        // Access
+
+            //- Return the feature point vertices for insertion into the
+            //  triangulation.
+            inline const List<Vb>& featurePointVertices() const;
+
+
+        // Edit
+
+            //- Distribute the feature point vertices according to the
+            //  supplied background mesh
+            void distribute(const backgroundMeshDecomposition& decomposition);
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#include "featurePointConformerI.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/featurePointConformer/featurePointConformerI.H b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/featurePointConformer/featurePointConformerI.H
new file mode 100644
index 00000000000..406ed3f0004
--- /dev/null
+++ b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/featurePointConformer/featurePointConformerI.H
@@ -0,0 +1,32 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2013 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+const Foam::List<Vb>& Foam::featurePointConformer::featurePointVertices() const
+{
+    return featurePointVertices_;
+}
+
+
+// ************************************************************************* //
diff --git a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshFeaturePointSpecialisations.C b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/featurePointConformer/featurePointConformerSpecialisations.C
similarity index 95%
rename from applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshFeaturePointSpecialisations.C
rename to applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/featurePointConformer/featurePointConformerSpecialisations.C
index f26c7a5b51d..a837fb5520a 100644
--- a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshFeaturePointSpecialisations.C
+++ b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/featurePointConformer/featurePointConformerSpecialisations.C
@@ -23,39 +23,17 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "conformalVoronoiMesh.H"
+#include "featurePointConformer.H"
 #include "vectorTools.H"
+#include "pointFeatureEdgesTypes.H"
+#include "conformalVoronoiMesh.H"
+#include "pointConversion.H"
 
 using namespace Foam::vectorTools;
 
 // * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * * //
 
-Foam::List<Foam::extendedFeatureEdgeMesh::edgeStatus>
-Foam::conformalVoronoiMesh::calcPointFeatureEdgesTypes
-(
-    const extendedFeatureEdgeMesh& feMesh,
-    const labelList& pEds,
-    pointFeatureEdgesTypes& pFEdgeTypes
-) const
-{
-    List<extendedFeatureEdgeMesh::edgeStatus> allEdStat(pEds.size());
-
-    forAll(pEds, i)
-    {
-        label edgeI = pEds[i];
-
-        extendedFeatureEdgeMesh::edgeStatus& eS = allEdStat[i];
-
-        eS = feMesh.getEdgeStatus(edgeI);
-
-        pFEdgeTypes(eS)++;
-    }
-
-    return allEdStat;
-}
-
-
-bool Foam::conformalVoronoiMesh::createSpecialisedFeaturePoint
+bool Foam::featurePointConformer::createSpecialisedFeaturePoint
 (
     const extendedFeatureEdgeMesh& feMesh,
     const labelList& pEds,
@@ -63,7 +41,7 @@ bool Foam::conformalVoronoiMesh::createSpecialisedFeaturePoint
     const List<extendedFeatureEdgeMesh::edgeStatus>& allEdStat,
     const label ptI,
     DynamicList<Vb>& pts
-)
+) const
 {
     if
     (
@@ -85,16 +63,16 @@ bool Foam::conformalVoronoiMesh::createSpecialisedFeaturePoint
 
         const Foam::point& featPt = feMesh.points()[ptI];
 
-        if (!positionOnThisProc(featPt))
+        if (!foamyHexMesh_.positionOnThisProc(featPt))
         {
             return false;
         }
 
-        label nVert = number_of_vertices();
+        label nVert = foamyHexMesh_.number_of_vertices();
 
         const label initialNumOfPoints = pts.size();
 
-        const scalar ppDist = pointPairDistance(featPt);
+        const scalar ppDist = foamyHexMesh_.pointPairDistance(featPt);
 
         const vectorField& normals = feMesh.normals();
 
@@ -204,8 +182,8 @@ bool Foam::conformalVoronoiMesh::createSpecialisedFeaturePoint
         Foam::point externalPtD;
         Foam::point externalPtE;
 
-        vector convexEdgePlaneCNormal(0,0,0);
-        vector convexEdgePlaneDNormal(0,0,0);
+        vector convexEdgePlaneCNormal(vector::zero);
+        vector convexEdgePlaneDNormal(vector::zero);
 
         const labelList& concaveEdgeNormals = edgeNormals[concaveEdgeI];
         const labelList& convexEdgeANormals = edgeNormals[convexEdgesI[0]];
@@ -349,7 +327,7 @@ bool Foam::conformalVoronoiMesh::createSpecialisedFeaturePoint
           + radAngleBetween(concaveEdgePlaneANormal, concaveEdgePlaneBNormal)
         );
 
-        if (totalAngle > foamyHexMeshControls().maxQuadAngle())
+        if (totalAngle > foamyHexMeshControls_.maxQuadAngle())
         {
             // Add additional mitreing points
             //scalar angleSign = 1.0;
@@ -424,16 +402,16 @@ bool Foam::conformalVoronoiMesh::createSpecialisedFeaturePoint
 
         const Foam::point& featPt = feMesh.points()[ptI];
 
-        if (!positionOnThisProc(featPt))
+        if (!foamyHexMesh_.positionOnThisProc(featPt))
         {
             return false;
         }
 
-        label nVert = number_of_vertices();
+        label nVert = foamyHexMesh_.number_of_vertices();
 
         const label initialNumOfPoints = pts.size();
 
-        const scalar ppDist = pointPairDistance(featPt);
+        const scalar ppDist = foamyHexMesh_.pointPairDistance(featPt);
 
         const vectorField& normals = feMesh.normals();
 
@@ -543,8 +521,8 @@ bool Foam::conformalVoronoiMesh::createSpecialisedFeaturePoint
         Foam::point externalPtD;
         Foam::point externalPtE;
 
-        vector concaveEdgePlaneCNormal(0,0,0);
-        vector concaveEdgePlaneDNormal(0,0,0);
+        vector concaveEdgePlaneCNormal(vector::zero);
+        vector concaveEdgePlaneDNormal(vector::zero);
 
         const labelList& convexEdgeNormals = edgeNormals[convexEdgeI];
         const labelList& concaveEdgeANormals = edgeNormals[concaveEdgesI[0]];
@@ -691,7 +669,7 @@ bool Foam::conformalVoronoiMesh::createSpecialisedFeaturePoint
           + radAngleBetween(convexEdgePlaneANormal, convexEdgePlaneBNormal)
         );
 
-        if (totalAngle > foamyHexMeshControls().maxQuadAngle())
+        if (totalAngle > foamyHexMeshControls_.maxQuadAngle())
         {
             // Add additional mitreing points
             //scalar angleSign = 1.0;
@@ -751,6 +729,7 @@ bool Foam::conformalVoronoiMesh::createSpecialisedFeaturePoint
                 Info<< "Point " << ptI << " "
                     << indexedVertexEnum::vertexTypeNames_[pts[ptI].type()]
                     << " : ";
+
                 meshTools::writeOBJ(Info, topoint(pts[ptI].point()));
             }
         }
diff --git a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/featurePointConformer/pointFeatureEdgesTypes.C b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/featurePointConformer/pointFeatureEdgesTypes.C
new file mode 100644
index 00000000000..795922cb4e7
--- /dev/null
+++ b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/featurePointConformer/pointFeatureEdgesTypes.C
@@ -0,0 +1,101 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2013 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "pointFeatureEdgesTypes.H"
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::pointFeatureEdgesTypes::pointFeatureEdgesTypes
+(
+    const extendedFeatureEdgeMesh& feMesh,
+    const label pointLabel
+)
+:
+    HashTable<label, extendedFeatureEdgeMesh::edgeStatus>(),
+    feMesh_(feMesh),
+    pointLabel_(pointLabel)
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::pointFeatureEdgesTypes::~pointFeatureEdgesTypes()
+{}
+
+
+// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
+
+Foam::List<Foam::extendedFeatureEdgeMesh::edgeStatus>
+Foam::pointFeatureEdgesTypes::calcPointFeatureEdgesTypes()
+{
+    const labelList& pEds = feMesh_.pointEdges()[pointLabel_];
+
+    List<extendedFeatureEdgeMesh::edgeStatus> allEdStat(pEds.size());
+
+    forAll(pEds, i)
+    {
+        label edgeI = pEds[i];
+
+        extendedFeatureEdgeMesh::edgeStatus& eS = allEdStat[i];
+
+        eS = feMesh_.getEdgeStatus(edgeI);
+
+        this->operator()(eS)++;
+    }
+
+    return allEdStat;
+}
+
+
+// * * * * * * * * * * * * * * Friend Functions  * * * * * * * * * * * * * * //
+
+Foam::Ostream& Foam::operator<<
+(
+    Ostream& os,
+    const pointFeatureEdgesTypes& p
+)
+{
+    os  << "Point = " << p.pointLabel_ << endl;
+
+    for
+    (
+        HashTable<label, extendedFeatureEdgeMesh::edgeStatus>
+            ::const_iterator iter = p.cbegin();
+        iter != p.cend();
+        ++iter
+    )
+    {
+        os  << "    "
+            << extendedFeatureEdgeMesh::edgeStatusNames_[iter.key()]
+            << " = "
+            << iter()
+            << endl;
+    }
+
+    return os;
+}
+
+
+// ************************************************************************* //
diff --git a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/pointFeatureEdgesTypes.H b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/featurePointConformer/pointFeatureEdgesTypes.H
similarity index 70%
rename from applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/pointFeatureEdgesTypes.H
rename to applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/featurePointConformer/pointFeatureEdgesTypes.H
index 4277f0d3b78..a7bfb723cab 100644
--- a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/pointFeatureEdgesTypes.H
+++ b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/featurePointConformer/pointFeatureEdgesTypes.H
@@ -27,11 +27,18 @@ Class
 Description
     Holds information on the types of feature edges attached to feature points.
 
+SourceFiles
+    pointFeatureEdgesTypes.C
+
 \*---------------------------------------------------------------------------*/
 
 #ifndef pointFeatureEdgesTypes_H
 #define pointFeatureEdgesTypes_H
 
+#include "HashTable.H"
+#include "extendedFeatureEdgeMesh.H"
+#include "List.H"
+
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 namespace Foam
@@ -46,38 +53,45 @@ class pointFeatureEdgesTypes
 :
     public HashTable<label, extendedFeatureEdgeMesh::edgeStatus>
 {
-    label pointLabel_;
+    // Private data
+
+        //- Reference to the feature edge mesh
+        const extendedFeatureEdgeMesh& feMesh_;
+
+        //- label of the point
+        label pointLabel_;
+
 
 public:
 
-    pointFeatureEdgesTypes(const label pointLabel)
-    :
-        HashTable<label, extendedFeatureEdgeMesh::edgeStatus>(),
-        pointLabel_(pointLabel)
-    {}
+    // Constructors
+
+        //- Construct from components
+        pointFeatureEdgesTypes
+        (
+            const extendedFeatureEdgeMesh& feMesh,
+            const label pointLabel
+        );
+
+
+    //- Destructor
+    ~pointFeatureEdgesTypes();
+
+
+    // Member Functions
+
+        //- Fill the pointFeatureEdgesType class with the types of feature
+        //  edges that are attached to the point.
+        List<extendedFeatureEdgeMesh::edgeStatus> calcPointFeatureEdgesTypes();
 
 
-    friend Ostream& operator<<(Ostream& os, const pointFeatureEdgesTypes& p)
-    {
-        os  << "Point = " << p.pointLabel_ << endl;
+    // Info
 
-        for
+        friend Ostream& operator<<
         (
-            HashTable<label, extendedFeatureEdgeMesh::edgeStatus>
-                ::const_iterator iter = p.cbegin();
-            iter != p.cend();
-            ++iter
-        )
-        {
-            os  << "    "
-                << extendedFeatureEdgeMesh::edgeStatusNames_[iter.key()]
-                << " = "
-                << iter()
-                << endl;
-        }
-
-        return os;
-    }
+            Ostream& os,
+            const pointFeatureEdgesTypes& p
+        );
 };
 
 
diff --git a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/pointConversion.H b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/pointConversion.H
index 7038fbdaef2..632270b5222 100644
--- a/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/pointConversion.H
+++ b/applications/utilities/mesh/generation/foamyHexMesh/conformalVoronoiMesh/conformalVoronoiMesh/pointConversion.H
@@ -25,8 +25,7 @@ Class
     pointConversion
 
 Description
-
-    Conversion functions between point (FOAM::) and Point (CGAL)
+    Conversion functions between point (Foam::) and Point (CGAL::)
 
 \*---------------------------------------------------------------------------*/
 
@@ -61,7 +60,6 @@ namespace Foam
         return reinterpret_cast<pointFromPoint>(P);
     }
 
-    template<typename Point>
     inline PointFrompoint toPoint(const Foam::point& p)
     {
         return reinterpret_cast<PointFrompoint>(p);
@@ -80,14 +78,33 @@ namespace Foam
         );
     }
 
-    template<typename Point>
-    inline Point toPoint(const Foam::point& p)
+    inline PointFrompoint toPoint(const Foam::point& p)
     {
-        return Point(p.x(), p.y(), p.z());
+        return PointFrompoint(p.x(), p.y(), p.z());
     }
 
 #endif
 
+    //- Specialisation for indexedVertex.
+    template<>
+    inline pointFromPoint topoint<CGAL::indexedVertex<K> >
+    (
+        const CGAL::indexedVertex<K>& P
+    )
+    {
+        return topoint(P.point());
+    }
+
+    //- Specialisation for Foam::point. Used only as a dummy.
+    template<>
+    inline pointFromPoint topoint<Foam::point>
+    (
+        const Foam::point& P
+    )
+    {
+        return P;
+    }
+
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 } // End namespace Foam
diff --git a/applications/utilities/mesh/generation/foamyHexMesh/vectorTools/vectorTools.H b/applications/utilities/mesh/generation/foamyHexMesh/vectorTools/vectorTools.H
index 106755153e7..a1b5d138162 100644
--- a/applications/utilities/mesh/generation/foamyHexMesh/vectorTools/vectorTools.H
+++ b/applications/utilities/mesh/generation/foamyHexMesh/vectorTools/vectorTools.H
@@ -27,8 +27,6 @@ Class
 Description
     Functions for analysing the relationships between vectors
 
-SourceFiles
-
 \*---------------------------------------------------------------------------*/
 
 #ifndef vectorTools_H
@@ -146,6 +144,7 @@ namespace vectorTools
 
 } // End namespace vectorTools
 
+
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 } // End namespace Foam
-- 
GitLab