diff --git a/src/OpenFOAM/containers/Lists/UList/UList.C b/src/OpenFOAM/containers/Lists/UList/UList.C
index f3feb5b83526355c5a80105435866d10fad2c02e..f47969874420dee885258c2eaab74473ebc9d146 100644
--- a/src/OpenFOAM/containers/Lists/UList/UList.C
+++ b/src/OpenFOAM/containers/Lists/UList/UList.C
@@ -112,6 +112,7 @@ Foam::UList<T> Foam::UList<T>::operator[](const labelRange& range)
     return UList<T>(&(this->v_[slice.start()]), slice.size()); // SubList
 }
 
+
 template<class T>
 const Foam::UList<T> Foam::UList<T>::operator[](const labelRange& range) const
 {
@@ -132,6 +133,7 @@ Foam::UList<T> Foam::UList<T>::operator[]
     return UList<T>(&(this->v_[slice.start()]), slice.size()); // SubList
 }
 
+
 template<class T>
 const Foam::UList<T> Foam::UList<T>::operator[]
 (
diff --git a/src/OpenFOAM/meshes/meshShapes/edge/edge.H b/src/OpenFOAM/meshes/meshShapes/edge/edge.H
index 52bf97cb7cf65cfebbe2e30ca0a26881b808d3d7..aecb9a9c2e416c1acc4b055fcf1c4ff12e162b17 100644
--- a/src/OpenFOAM/meshes/meshShapes/edge/edge.H
+++ b/src/OpenFOAM/meshes/meshShapes/edge/edge.H
@@ -149,7 +149,11 @@ public:
 
         //- Return true if point label is found in edge.
         //  Always false for a negative label.
-        inline bool found(const label index) const;
+        inline bool found(const label pointLabel) const;
+
+        //- Return local index (0,1) of point label in edge -1 on failure
+        //  Always return -1 for a negative label.
+        inline label which(const label pointLabel) const;
 
         //- Do the edges share a common vertex index?
         //  Negative point labels never connect.
diff --git a/src/OpenFOAM/meshes/meshShapes/edge/edgeI.H b/src/OpenFOAM/meshes/meshShapes/edge/edgeI.H
index 75a5ba23655c5dd5fbe1d82cbf5a0ddb06a98bf9..e4ca81e9386f6abb51f0abc14ba2035222656268 100644
--- a/src/OpenFOAM/meshes/meshShapes/edge/edgeI.H
+++ b/src/OpenFOAM/meshes/meshShapes/edge/edgeI.H
@@ -206,10 +206,28 @@ inline Foam::label Foam::edge::maxVertex() const
 }
 
 
-inline bool Foam::edge::found(const label index) const
+inline bool Foam::edge::found(const label pointLabel) const
 {
     // -1: always false
-    return (index >= 0 && (index == start() || index == end()));
+    return (pointLabel >= 0 && (pointLabel == start() || pointLabel == end()));
+}
+
+
+inline Foam::label Foam::edge::which(const label pointLabel) const
+{
+    // -1: always false
+    if (pointLabel >= 0)
+    {
+        if (pointLabel == start())
+        {
+            return 0;
+        }
+        if (pointLabel == end())
+        {
+            return 1;
+        }
+    }
+    return -1;
 }
 
 
diff --git a/src/OpenFOAM/meshes/meshShapes/face/face.H b/src/OpenFOAM/meshes/meshShapes/face/face.H
index 2d83def92090a598a8b38213dc82f79a0c2b301e..822e3c4f9a6fc3f146480ee1ada390afb311497f 100644
--- a/src/OpenFOAM/meshes/meshShapes/face/face.H
+++ b/src/OpenFOAM/meshes/meshShapes/face/face.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -202,7 +202,10 @@ public:
 
         //- Navigation through face vertices
 
-            //- Which vertex on face (face index given a global index)
+            //- Return true if the global point label is found in face.
+            inline bool found(const label globalIndex) const;
+
+            //- Which local vertex on face given a global index.
             //  returns -1 if not found
             label which(const label globalIndex) const;
 
diff --git a/src/OpenFOAM/meshes/meshShapes/face/faceI.H b/src/OpenFOAM/meshes/meshShapes/face/faceI.H
index b45193f0e730b3d59ede32f0f443bf62b252046a..ce807528c6598dbbeae7b5489f3f187d6adbeafe 100644
--- a/src/OpenFOAM/meshes/meshShapes/face/faceI.H
+++ b/src/OpenFOAM/meshes/meshShapes/face/faceI.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -116,20 +116,24 @@ inline Foam::edge Foam::face::faceEdge(const label n) const
 }
 
 
-// Next vertex on face
+inline bool Foam::face::found(const label globalIndex) const
+{
+    return which(globalIndex) != -1;
+}
+
+
 inline Foam::label Foam::face::nextLabel(const label i) const
 {
     return operator[](fcIndex(i));
 }
 
 
-// Previous vertex on face
 inline Foam::label Foam::face::prevLabel(const label i) const
 {
     return operator[](rcIndex(i));
 }
 
-// Number of triangles directly known from number of vertices
+
 inline Foam::label Foam::face::nTriangles() const
 {
     return size() - 2;
diff --git a/src/surfMesh/MeshedSurface/MeshedSurfaceI.H b/src/OpenFOAM/meshes/meshShapes/traits/faceTraits.H
similarity index 51%
rename from src/surfMesh/MeshedSurface/MeshedSurfaceI.H
rename to src/OpenFOAM/meshes/meshShapes/traits/faceTraits.H
index a7415f7b4b69e8ef8a15731bdfc2e4598090c20b..523233a569957ab20c5e1c78cf35f5e4723646a6 100644
--- a/src/surfMesh/MeshedSurface/MeshedSurfaceI.H
+++ b/src/OpenFOAM/meshes/meshShapes/traits/faceTraits.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2017 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -21,83 +21,53 @@ License
     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::faceTraits
+
+Description
+    Traits class for faces
+
 \*---------------------------------------------------------------------------*/
 
+#ifndef faceTraits_H
+#define faceTraits_H
+
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 namespace Foam
 {
 
-// A triFace surface only handles triangulated faces
-template<>
-inline bool MeshedSurface<triFace>::isTri()
-{
-    return true;
-}
+// Forward declarations
+class triFace;
+class labelledTri;
 
+/*---------------------------------------------------------------------------*\
+                         Class faceTraits Declaration
+\*---------------------------------------------------------------------------*/
 
-// A labelledTri surface only handles triangulated faces
-template<>
-inline bool MeshedSurface<labelledTri>::isTri()
+template<class FaceType>
+class faceTraits
 {
-    return true;
-}
+public:
 
+    //- Face-type only handles triangles. Not true in general.
+    inline static bool isTri()  { return false; }
+};
 
-// Number of triangles for a triFace surface
-template<>
-inline label MeshedSurface<triFace>::nTriangles() const
-{
-    return ParentType::size();
-}
 
-// Number of triangles for a labelledTri surface
 template<>
-inline label MeshedSurface<labelledTri>::nTriangles() const
-{
-    return ParentType::size();
-}
+inline bool faceTraits<triFace>::isTri()        { return true; }
 
-
-// Inplace triangulation of triFace surface = no-op
 template<>
-inline label MeshedSurface<triFace>::triangulate()
-{
-    return 0;
-}
+inline bool faceTraits<labelledTri>::isTri()    { return true; }
 
-// Inplace triangulation of labelledTri surface = no-op
-template<>
-inline label MeshedSurface<labelledTri>::triangulate()
-{
-    return 0;
-}
 
-// Inplace triangulation of triFace surface (with face map) = no-op
-template<>
-inline label MeshedSurface<triFace>::triangulate(List<label>& faceMap)
-{
-    if (notNull(faceMap))
-    {
-        faceMap.clear();
-    }
-    return 0;
-}
-
-// Inplace triangulation of labelledTri surface (with face map) = no-op
-template<>
-inline label MeshedSurface<labelledTri>::triangulate(List<label>& faceMap)
-{
-    if (notNull(faceMap))
-    {
-        faceMap.clear();
-    }
-    return 0;
-}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
+} // End namespace Foam
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-} // End namespace Foam
+#endif
 
 // ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/meshShapes/triFace/triFace.H b/src/OpenFOAM/meshes/meshShapes/triFace/triFace.H
index e0e586673acd317ba968050ae2d270137d6f2dfd..301b845d112a82499420b4de2eeddd3daf6f4477 100644
--- a/src/OpenFOAM/meshes/meshShapes/triFace/triFace.H
+++ b/src/OpenFOAM/meshes/meshShapes/triFace/triFace.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -137,6 +137,13 @@ public:
         //  The starting points of the original and reverse face are identical.
         inline triFace reverseFace() const;
 
+        //- Return true if the global point label is found in face.
+        bool found(const label globalIndex) const;
+
+        //- Which local index (0,1,2) on face given a global index.
+        //  returns -1 if not found
+        label which(const label globalIndex) const;
+
         //- Return swept-volume from old-points to new-points
         inline scalar sweptVol
         (
diff --git a/src/OpenFOAM/meshes/meshShapes/triFace/triFaceI.H b/src/OpenFOAM/meshes/meshShapes/triFace/triFaceI.H
index 69d2a4033b8607c32d13a876b3670a9effb0763c..ae2545a7aa233e8542a9e4e644e1f098bd6b3c09 100644
--- a/src/OpenFOAM/meshes/meshShapes/triFace/triFaceI.H
+++ b/src/OpenFOAM/meshes/meshShapes/triFace/triFaceI.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -209,6 +209,21 @@ inline Foam::triFace Foam::triFace::reverseFace() const
 }
 
 
+inline bool Foam::triFace::found(const label globalIndex) const
+{
+    return which(globalIndex) != -1;
+}
+
+
+inline Foam::label Foam::triFace::which(const label globalIndex) const
+{
+    if (operator[](0) == globalIndex) return 0;
+    if (operator[](1) == globalIndex) return 1;
+    if (operator[](2) == globalIndex) return 2;
+    return -1;
+}
+
+
 inline Foam::scalar Foam::triFace::sweptVol
 (
     const UList<point>& opts,
diff --git a/src/OpenFOAM/meshes/primitiveShapes/line/line.H b/src/OpenFOAM/meshes/primitiveShapes/line/line.H
index 74bc680134eb0b4c2873ac4a9c14c0e81924634e..778a843ba75740616ef5922d017b94747f6a839a 100644
--- a/src/OpenFOAM/meshes/primitiveShapes/line/line.H
+++ b/src/OpenFOAM/meshes/primitiveShapes/line/line.H
@@ -98,10 +98,10 @@ public:
 
         // Access
 
-            //- Return first vertex
+            //- Return first point
             inline PointRef start() const;
 
-            //- Return second vertex
+            //- Return second point
             inline PointRef end() const;
 
 
@@ -113,9 +113,12 @@ public:
             //- Return scalar magnitude
             inline scalar mag() const;
 
-            //- Return start-end vector
+            //- Return start-to-end vector
             inline Point vec() const;
 
+            //- Return the unit vector (start-to-end)
+            inline Point unitVec() const;
+
             //- Return nearest distance to line from a given point
             //  If the nearest point is on the line, return a hit
             PointHit<Point> nearestDist(const Point& p) const;
diff --git a/src/OpenFOAM/meshes/primitiveShapes/line/lineI.H b/src/OpenFOAM/meshes/primitiveShapes/line/lineI.H
index 2dfca1e1c2c01c52405a410d9a6636a568016dd6..c4757716cfc9ad71d0fd17e3eaac235a55ee8cbe 100644
--- a/src/OpenFOAM/meshes/primitiveShapes/line/lineI.H
+++ b/src/OpenFOAM/meshes/primitiveShapes/line/lineI.H
@@ -90,6 +90,16 @@ inline Point Foam::line<Point, PointRef>::vec() const
 }
 
 
+template<class Point, class PointRef>
+inline Point Foam::line<Point, PointRef>::unitVec() const
+{
+    Point v = b_ - a_;
+    v /= ::Foam::mag(v) + VSMALL;
+
+    return v;
+}
+
+
 template<class Point, class PointRef>
 Foam::PointHit<Point> Foam::line<Point, PointRef>::nearestDist
 (
diff --git a/src/fileFormats/ensight/part/ensightCells.C b/src/fileFormats/ensight/part/ensightCells.C
index d08996ad85764bfda0c2616a51c0dbc2e2abc01f..3b1161ad984f075691af3a13957ead158889169e 100644
--- a/src/fileFormats/ensight/part/ensightCells.C
+++ b/src/fileFormats/ensight/part/ensightCells.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2016-2017 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -27,24 +27,13 @@ License
 #include "error.H"
 #include "polyMesh.H"
 #include "cellModeller.H"
-#include "demandDrivenData.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
 const Foam::label Foam::ensightCells::nTypes = 5;
 
-namespace Foam
-{
-    template<>
-    const char* Foam::NamedEnum
-    <
-        Foam::ensightCells::elemType,
-        5
-    >::names[] = { "tetra4", "pyramid5", "penta6", "hexa8", "nfaced" };
-}
-
-const Foam::NamedEnum<Foam::ensightCells::elemType, 5>
-    Foam::ensightCells::elemEnum;
+const char* Foam::ensightCells::elemNames[5] =
+    { "tetra4", "pyramid5", "penta6", "hexa8", "nfaced" };
 
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
@@ -63,9 +52,8 @@ void Foam::ensightCells::resizeAll()
     n = 0;
     forAll(sizes_, typei)
     {
-        deleteDemandDrivenData(lists_[typei]);
-
-        lists_[typei] = new SubList<label>(address_, sizes_[typei], n);
+        slices_[typei].setStart(n);
+        slices_[typei].setSize(sizes_[typei]);
 
         n += sizes_[typei];
     }
@@ -78,16 +66,10 @@ Foam::ensightCells::ensightCells(const label partIndex)
 :
     index_(partIndex),
     address_(),
-    sizes_(Zero),
-    lists_()
+    slices_(),
+    sizes_(Zero)
 {
-    // Ensure sub-lists are properly initialized to nullptr
-    forAll(lists_, typei)
-    {
-        lists_[typei] = nullptr;
-    }
-
-    resizeAll(); // adjust allocation
+    resizeAll(); // adjust allocation/sizing
 }
 
 
@@ -95,22 +77,16 @@ Foam::ensightCells::ensightCells(const ensightCells& obj)
 :
     index_(obj.index_),
     address_(obj.address_),
-    sizes_(),
-    lists_()
+    slices_(),
+    sizes_()
 {
-    // Ensure sub-lists are properly initialized to nullptr
-    forAll(lists_, typei)
-    {
-        lists_[typei] = nullptr;
-    }
-
-    // Total (reduced) sizes
+    // Save the total (reduced) sizes
     FixedList<label, 5> totSizes = obj.sizes_;
 
-    // Local sizes
+    // Need local sizes for the resize operation
     this->sizes_ = obj.sizes();
 
-    resizeAll(); // adjust allocation
+    resizeAll(); // adjust allocation/sizing
 
     // Restore total (reduced) sizes
     this->sizes_ = totSizes;
@@ -120,13 +96,7 @@ Foam::ensightCells::ensightCells(const ensightCells& obj)
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
 
 Foam::ensightCells::~ensightCells()
-{
-    forAll(lists_, typei)
-    {
-        deleteDemandDrivenData(lists_[typei]);
-    }
-    address_.clear();
-}
+{}
 
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
@@ -134,27 +104,15 @@ Foam::ensightCells::~ensightCells()
 Foam::FixedList<Foam::label, 5> Foam::ensightCells::sizes() const
 {
     FixedList<label, 5> count;
-    forAll(lists_, typei)
+    forAll(slices_, typei)
     {
-        count[typei] = lists_[typei]->size();
+        count[typei] = slices_[typei].size();
     }
 
     return count;
 }
 
 
-Foam::label Foam::ensightCells::offset(const enum elemType what) const
-{
-    label n = 0;
-    for (label typei = 0; typei < label(what); ++typei)
-    {
-        n += lists_[typei]->size();
-    }
-
-    return n;
-}
-
-
 Foam::label Foam::ensightCells::total() const
 {
     label n = 0;
@@ -175,9 +133,10 @@ void Foam::ensightCells::clear()
 
 void Foam::ensightCells::reduce()
 {
+    // No listCombineGather, listCombineScatter for FixedList
     forAll(sizes_, typei)
     {
-        sizes_[typei] = lists_[typei]->size();
+        sizes_[typei] = slices_[typei].size();
         Foam::reduce(sizes_[typei], sumOp<label>());
     }
 }
@@ -185,9 +144,13 @@ void Foam::ensightCells::reduce()
 
 void Foam::ensightCells::sort()
 {
-    forAll(lists_, typei)
+    forAll(slices_, typei)
     {
-        Foam::sort(*(lists_[typei]));
+        if (slices_[typei].size())
+        {
+            SubList<label> idLst(address_, slices_[typei]);
+            Foam::sort(idLst);
+        }
     }
 }
 
@@ -240,7 +203,7 @@ void Foam::ensightCells::classify
     }
 
     resizeAll();    // adjust allocation
-    sizes_ = Zero;  // reset sizes
+    sizes_ = Zero;  // reset sizes - use for local indexing here
 
     // Assign cell-id per shape type
     for (label listi = 0; listi < sz; ++listi)
@@ -267,7 +230,10 @@ void Foam::ensightCells::classify
         }
 
         // eg, the processor local cellId
-        lists_[what]->operator[](sizes_[what]++) = id;
+        UList<label> slice = address_[slices_[what]];
+
+        slice[sizes_[what]] = id;
+        sizes_[what]++;
     }
 }
 
diff --git a/src/fileFormats/ensight/part/ensightCells.H b/src/fileFormats/ensight/part/ensightCells.H
index 33bc98a2f4710835ee61e5dba40f3b9107e46f4f..cef7c4b2edd8c7aa3bc482fd661fa32391dfd0f6 100644
--- a/src/fileFormats/ensight/part/ensightCells.H
+++ b/src/fileFormats/ensight/part/ensightCells.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2016-2017 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -35,8 +35,6 @@ Description
 
 #include "labelList.H"
 #include "FixedList.H"
-#include "SubList.H"
-#include "NamedEnum.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -58,18 +56,18 @@ public:
         //- Addressable ensight element types
         enum elemType
         {
-            TETRA4,
-            PYRAMID5,
-            PENTA6,
-            HEXA8,
-            NFACED
+            TETRA4,     //!< "tetra4"
+            PYRAMID5,   //!< "pyramid5"
+            PENTA6,     //!< "penta6"
+            HEXA8,      //!< "hexa8"
+            NFACED      //!< "nfaced"
         };
 
         //- Number of element types (5)
         static const label nTypes;
 
-        //- The Ensight names for each element type
-        static const NamedEnum<elemType, 5> elemEnum;
+        //- The ensight element type names
+        static const char* elemNames[5];
 
 
     // Static Member Functions
@@ -86,17 +84,16 @@ private:
         //  The ensight part number is typically this value +1.
         label index_;
 
-        //- Linear list of ids, sub-sectioned per element type via SubLists
+        //- Linear list of ids, sub-sectioned per element type by sub-lists
         labelList address_;
 
+        //- Slices (sub-lists) of the address ids for each element type.
+        FixedList<labelRange, 5> slices_;
+
         //- List of global sizes for each element type.
         //  Used temporarily for local sizes when building the element lists.
         FixedList<label, 5> sizes_;
 
-        //- List of ids for each element type.
-        //  Managed via pointers, since a SubList cannot be relocated/resized.
-        FixedList<SubList<label>*, 5> lists_;
-
 
     // Private Member Functions
 
@@ -115,7 +112,7 @@ public:
         ensightCells(label partIndex = 0);
 
         //- Copy constructor. Needed for lists etc.
-        ensightCells(const ensightCells&);
+        ensightCells(const ensightCells& obj);
 
 
     //- Destructor
@@ -135,6 +132,9 @@ public:
         //- The processor local size of all elements.
         inline label size() const;
 
+        //- The processor local size of the specified element type.
+        inline label size(const enum elemType) const;
+
         //- The global number of the specified element type.
         //  This value is only meaningful after a reduce operation.
         inline label total(const enum elemType) const;
@@ -151,23 +151,23 @@ public:
         FixedList<label, 5> sizes() const;
 
         //- Processor local starting offset of element type.
-        label offset(const enum elemType what) const;
+        inline label offset(const enum elemType what) const;
 
         //- Return the (local) cell ids of the specified element type
-        inline const labelUList& cellIds(const enum elemType) const;
+        inline const labelUList cellIds(const enum elemType) const;
 
         //- Return the cell ids of all elements
         inline const labelUList& cellIds() const;
 
 
-    // Edit
+      // Edit
 
         //- Classify cell types and set the element lists.
         //  The optional indirect addressing can be used when classifying
         //  groups of cells (eg, from a cellZone etc).
         void classify
         (
-            const polyMesh&,
+            const polyMesh& mesh,
             const labelUList& addressing = labelUList::null()
         );
 
diff --git a/src/fileFormats/ensight/part/ensightCellsI.H b/src/fileFormats/ensight/part/ensightCellsI.H
index 88e016832220ff94ee17033a2da7d06be4adc51e..ff03b8fdfdedcee3f43c89c669ce46c019696701 100644
--- a/src/fileFormats/ensight/part/ensightCellsI.H
+++ b/src/fileFormats/ensight/part/ensightCellsI.H
@@ -29,7 +29,7 @@ License
 
 inline const char* Foam::ensightCells::key(const enum elemType what)
 {
-    return elemEnum[what];
+    return elemNames[what];
 }
 
 
@@ -63,20 +63,24 @@ inline Foam::label Foam::ensightCells::total(const enum elemType what) const
 }
 
 
-inline const Foam::labelUList& Foam::ensightCells::cellIds
+inline Foam::label Foam::ensightCells::size(const enum elemType what) const
+{
+    return slices_[what].size();
+}
+
+
+inline Foam::label Foam::ensightCells::offset(const enum elemType what) const
+{
+    return slices_[what].start();
+}
+
+
+inline const Foam::labelUList Foam::ensightCells::cellIds
 (
     const enum elemType what
 ) const
 {
-    if (!lists_[what])
-    {
-        FatalErrorInFunction
-            << "Accessing unallocated sublist for elem-type: "
-            << elemEnum[what]
-            << exit(FatalError);
-    }
-
-    return *(lists_[what]);
+    return address_[slices_[what]];
 }
 
 
diff --git a/src/fileFormats/ensight/part/ensightFaces.C b/src/fileFormats/ensight/part/ensightFaces.C
index 65117d3cd60d56a36de7ed381f49d654778f50cc..db64d85adbc32e5701c9270eaf2948e950069d29 100644
--- a/src/fileFormats/ensight/part/ensightFaces.C
+++ b/src/fileFormats/ensight/part/ensightFaces.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2016-2017 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -27,24 +27,13 @@ License
 #include "error.H"
 #include "polyMesh.H"
 #include "ListOps.H"
-#include "demandDrivenData.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
 const Foam::label Foam::ensightFaces::nTypes = 3;
 
-namespace Foam
-{
-    template<>
-    const char* Foam::NamedEnum
-    <
-        Foam::ensightFaces::elemType,
-        3
-    >::names[] = { "tria3", "quad4", "nsided" };
-}
-
-const Foam::NamedEnum<Foam::ensightFaces::elemType, 3>
-    Foam::ensightFaces::elemEnum;
+const char* Foam::ensightFaces::elemNames[3] =
+    { "tria3", "quad4", "nsided" };
 
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
@@ -99,9 +88,8 @@ void Foam::ensightFaces::resizeAll()
     n = 0;
     forAll(sizes_, typei)
     {
-        deleteDemandDrivenData(lists_[typei]);
-
-        lists_[typei] = new SubList<label>(address_, sizes_[typei], n);
+        slices_[typei].setStart(n);
+        slices_[typei].setSize(sizes_[typei]);
 
         n += sizes_[typei];
     }
@@ -118,16 +106,10 @@ Foam::ensightFaces::ensightFaces(label partIndex)
     index_(partIndex),
     address_(),
     flipMap_(),
-    sizes_(Zero),
-    lists_()
+    slices_(),
+    sizes_(Zero)
 {
-    // Ensure sub-lists are properly initialized to nullptr
-    forAll(lists_, typei)
-    {
-        lists_[typei] = nullptr;
-    }
-
-    resizeAll(); // adjust allocation
+    resizeAll(); // adjust allocation/sizing
 }
 
 
@@ -136,22 +118,16 @@ Foam::ensightFaces::ensightFaces(const ensightFaces& obj)
     index_(obj.index_),
     address_(obj.address_),
     flipMap_(obj.flipMap_),
-    sizes_(),
-    lists_()
+    slices_(),
+    sizes_()
 {
-    // Ensure sub-lists are properly initialized to nullptr
-    forAll(lists_, typei)
-    {
-        lists_[typei] = nullptr;
-    }
-
-    // Total (reduced) sizes
+    // Save the total (reduced) sizes
     FixedList<label, 3> totSizes = obj.sizes_;
 
-    // Local sizes
+    // Need local sizes for the resize operation
     this->sizes_ = obj.sizes();
 
-    resizeAll(); // adjust allocation
+    resizeAll(); // adjust allocation/sizing
 
     // Restore total (reduced) sizes
     this->sizes_ = totSizes;
@@ -161,14 +137,7 @@ Foam::ensightFaces::ensightFaces(const ensightFaces& obj)
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
 
 Foam::ensightFaces::~ensightFaces()
-{
-    forAll(lists_, typei)
-    {
-        deleteDemandDrivenData(lists_[typei]);
-    }
-    address_.clear();
-    flipMap_.clear();
-}
+{}
 
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
@@ -176,27 +145,15 @@ Foam::ensightFaces::~ensightFaces()
 Foam::FixedList<Foam::label, 3> Foam::ensightFaces::sizes() const
 {
     FixedList<label, 3> count;
-    forAll(lists_, typei)
+    forAll(slices_, typei)
     {
-        count[typei] = lists_[typei]->size();
+        count[typei] = slices_[typei].size();
     }
 
     return count;
 }
 
 
-Foam::label Foam::ensightFaces::offset(const enum elemType what) const
-{
-    label n = 0;
-    for (label typei = 0; typei < label(what); ++typei)
-    {
-        n += lists_[typei]->size();
-    }
-
-    return n;
-}
-
-
 Foam::label Foam::ensightFaces::total() const
 {
     label n = 0;
@@ -217,9 +174,10 @@ void Foam::ensightFaces::clear()
 
 void Foam::ensightFaces::reduce()
 {
+    // No listCombineGather, listCombineScatter for FixedList
     forAll(sizes_, typei)
     {
-        sizes_[typei] = lists_[typei]->size();
+        sizes_[typei] = slices_[typei].size();
         Foam::reduce(sizes_[typei], sumOp<label>());
     }
 }
@@ -229,20 +187,15 @@ void Foam::ensightFaces::sort()
 {
     if (flipMap_.size() == address_.size())
     {
-        // sort flip map too
-
+        // Must sort flip map as well
         labelList order;
-        label start = 0;
 
-        forAll(lists_, typei)
+        forAll(slices_, typei)
         {
-            SubList<label>& idLst = *(lists_[typei]);
-            const label sz = idLst.size();
-
-            if (sz)
+            if (slices_[typei].size())
             {
-                SubList<bool> flip(flipMap_, sz, start);
-                start += sz; // for next sub-list
+                SubList<label> idLst(address_, slices_[typei]);
+                SubList<bool>  flip(flipMap_, slices_[typei]);
 
                 Foam::sortedOrder(idLst, order);
 
@@ -254,11 +207,16 @@ void Foam::ensightFaces::sort()
     else
     {
         // no flip-maps, simpler to sort
-        forAll(lists_, typei)
+        forAll(slices_, typei)
         {
-            Foam::sort(*(lists_[typei]));
+            if (slices_[typei].size())
+            {
+                SubList<label> idLst(address_, slices_[typei]);
+                Foam::sort(idLst);
+            }
         }
-        flipMap_.clear();  // for safety
+
+        flipMap_.clear();  // for extra safety
     }
 }
 
@@ -278,7 +236,7 @@ void Foam::ensightFaces::classify(const faceList& faces)
     }
 
     resizeAll();    // adjust allocation
-    sizes_ = Zero;  // reset sizes
+    sizes_ = Zero;  // reset sizes - use for local indexing here
 
     // Assign face-id per shape type
     for (label listi = 0; listi < sz; ++listi)
@@ -318,7 +276,7 @@ void Foam::ensightFaces::classify
     }
 
     resizeAll();    // adjust allocation
-    sizes_ = Zero;  // reset sizes
+    sizes_ = Zero;  // reset sizes - use for local indexing here
 
     if (useFlip)
     {
@@ -330,11 +288,11 @@ void Foam::ensightFaces::classify
     for (label listi = 0; listi < sz; ++listi)
     {
         const label faceId = addressing[listi];
-        const bool flip = useFlip && flipMap[listi];
+        const bool  doFlip = useFlip && flipMap[listi];
 
         if (!exclude[faceId])
         {
-            add(faces[faceId], faceId, flip);
+            add(faces[faceId], faceId, doFlip);
         }
     }
 }
diff --git a/src/fileFormats/ensight/part/ensightFaces.H b/src/fileFormats/ensight/part/ensightFaces.H
index 844a03e9b357f874cb297c0f893958d69bac5c5d..bd7b3e8c40eb8add2d619abba7c6ff05b3db6b27 100644
--- a/src/fileFormats/ensight/part/ensightFaces.H
+++ b/src/fileFormats/ensight/part/ensightFaces.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2016-2017 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -37,7 +37,6 @@ Description
 #include "faceList.H"
 #include "FixedList.H"
 #include "PackedBoolList.H"
-#include "NamedEnum.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -57,16 +56,16 @@ public:
         //- Addressable ensight element types
         enum elemType
         {
-            TRIA3,
-            QUAD4,
-            NSIDED
+            TRIA3,      //!< "tria3"
+            QUAD4,      //!< "quad4"
+            NSIDED      //!< "nsided"
         };
 
         //- Number of element types (3)
         static const label nTypes;
 
-        //- The Ensight names for each element type
-        static const NamedEnum<elemType, 3> elemEnum;
+        //- The ensight element type names
+        static const char* elemNames[3];
 
 
     // Static Member Functions
@@ -83,28 +82,27 @@ private:
         //  The ensight part number is typically this value +1.
         label index_;
 
-        //- Linear list of ids, sub-sectioned per element type via SubLists
+        //- Linear list of ids, sub-sectioned per element type by sub-lists
         labelList address_;
 
         //- Linear list of face-flips
         boolList flipMap_;
 
+        //- Slices (sub-lists) of the address and flips for each element type.
+        FixedList<labelRange, 3> slices_;
+
         //- List of global sizes for each element type.
         //  Used temporarily for local sizes when building the element lists.
         FixedList<label, 3> sizes_;
 
-        //- SubLists of ids for each element type.
-        //  Managed via pointers, since a SubList cannot be relocated/resized.
-        FixedList<SubList<label>*, 3> lists_;
-
 
     // Private Member Functions
 
         //- Simple classifier
-        inline static elemType whatType(const face&);
+        inline static elemType whatType(const face& f);
 
         //- Low-level internal addition routine
-        inline void add(const face&, const label id, const bool flip = false);
+        inline void add(const face& f, const label id, const bool flip = false);
 
         //- Use temporarily stored sizes to redimension the element lists
         void resizeAll();
@@ -121,7 +119,7 @@ public:
         ensightFaces(label partIndex = 0);
 
         //- Copy constructor. Needed for lists etc.
-        ensightFaces(const ensightFaces&);
+        ensightFaces(const ensightFaces& obj);
 
 
     //- Destructor
@@ -141,14 +139,17 @@ public:
         //- The processor local size of all elements.
         inline label size() const;
 
-        //- The global number of the specified element type.
-        //  This value is only meaningful after a reduce operation.
-        inline label total(const enum elemType) const;
+        //- The processor local size of the specified element type.
+        inline label size(const enum elemType) const;
 
         //- The global number of all element types.
         //  This value is only meaningful after a reduce operation.
         label total() const;
 
+        //- The global number of the specified element type.
+        //  This value is only meaningful after a reduce operation.
+        inline label total(const enum elemType) const;
+
         //- The global numbers per element type.
         //  This value is only meaningful after a reduce operation.
         inline const FixedList<label, 3>& totals() const;
@@ -157,10 +158,10 @@ public:
         FixedList<label, 3> sizes() const;
 
         //- Processor local starting offset of element type.
-        label offset(const enum elemType what) const;
+        inline label offset(const enum elemType what) const;
 
         //- Return the (local) face ids of the specified element type
-        inline const labelUList& faceIds(const enum elemType) const;
+        inline const labelUList faceIds(const enum elemType) const;
 
         //- Return the processor local face ids of all elements
         inline const labelUList& faceIds() const;
diff --git a/src/fileFormats/ensight/part/ensightFacesI.H b/src/fileFormats/ensight/part/ensightFacesI.H
index 4b32a373dbe23082fde720b58a3c6568396fca68..78048c1c90b26e7b37b71c06e2f6138b5cca282d 100644
--- a/src/fileFormats/ensight/part/ensightFacesI.H
+++ b/src/fileFormats/ensight/part/ensightFacesI.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2016-2017 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -29,7 +29,7 @@ License
 
 inline const char* Foam::ensightFaces::key(const enum elemType what)
 {
-    return elemEnum[what];
+    return elemNames[what];
 }
 
 
@@ -63,20 +63,24 @@ inline Foam::label Foam::ensightFaces::total(const enum elemType what) const
 }
 
 
-inline const Foam::labelUList& Foam::ensightFaces::faceIds
+inline Foam::label Foam::ensightFaces::size(const enum elemType what) const
+{
+    return slices_[what].size();
+}
+
+
+inline Foam::label Foam::ensightFaces::offset(const enum elemType what) const
+{
+    return slices_[what].start();
+}
+
+
+inline const Foam::labelUList Foam::ensightFaces::faceIds
 (
     const enum elemType what
 ) const
 {
-    if (!lists_[what])
-    {
-        FatalErrorInFunction
-            << "Accessing unallocated sublist for elem-type: "
-            << elemEnum[what]
-            << exit(FatalError);
-    }
-
-    return *(lists_[what]);
+    return address_[slices_[what]];
 }
 
 
diff --git a/src/surfMesh/MeshedSurface/MeshedSurface.C b/src/surfMesh/MeshedSurface/MeshedSurface.C
index 0606860e64a4da677e4b4c6eeb72c36c9ed5f0dd..41d0418a3b7d38a1935d59c9f87fe3f69a5d2fa4 100644
--- a/src/surfMesh/MeshedSurface/MeshedSurface.C
+++ b/src/surfMesh/MeshedSurface/MeshedSurface.C
@@ -33,24 +33,17 @@ License
 #include "polyMesh.H"
 #include "surfMesh.H"
 #include "primitivePatch.H"
+#include "faceTraits.H"
 #include "addToRunTimeSelectionTable.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
-template<class Face>
-inline bool Foam::MeshedSurface<Face>::isTri()
-{
-    return false;
-}
-
-
 template<class Face>
 Foam::wordHashSet Foam::MeshedSurface<Face>::readTypes()
 {
     return wordHashSet(*fileExtensionConstructorTablePtr_);
 }
 
-
 template<class Face>
 Foam::wordHashSet Foam::MeshedSurface<Face>::writeTypes()
 {
@@ -116,25 +109,34 @@ void Foam::MeshedSurface<Face>::write
     const fileName& name,
     const MeshedSurface<Face>& surf
 )
+{
+    write(name, name.ext(), surf);
+}
+
+
+template<class Face>
+void Foam::MeshedSurface<Face>::write
+(
+    const fileName& name,
+    const word& ext,
+    const MeshedSurface<Face>& surf
+)
 {
     if (debug)
     {
         InfoInFunction << "Writing to " << name << endl;
     }
 
-    const word ext = name.ext();
-
-    typename writefileExtensionMemberFunctionTable::iterator mfIter =
-        writefileExtensionMemberFunctionTablePtr_->find(ext);
+    auto mfIter = writefileExtensionMemberFunctionTablePtr_->find(ext);
 
-    if (mfIter == writefileExtensionMemberFunctionTablePtr_->end())
+    if (!mfIter.found())
     {
         // No direct writer, delegate to proxy if possible
         const wordHashSet& delegate = ProxyType::writeTypes();
 
         if (delegate.found(ext))
         {
-            MeshedSurfaceProxy<Face>(surf).write(name);
+            MeshedSurfaceProxy<Face>(surf).write(name, ext);
         }
         else
         {
@@ -850,6 +852,11 @@ bool Foam::MeshedSurface<Face>::checkFaces
 template<class Face>
 Foam::label Foam::MeshedSurface<Face>::nTriangles() const
 {
+    if (faceTraits<Face>::isTri())
+    {
+        return ParentType::size();
+    }
+
     return nTriangles
     (
         const_cast<List<label>&>(List<label>::null())
@@ -905,10 +912,18 @@ Foam::label Foam::MeshedSurface<Face>::nTriangles
 template<class Face>
 Foam::label Foam::MeshedSurface<Face>::triangulate()
 {
-    return triangulate
-    (
-        const_cast<List<label>&>(List<label>::null())
-    );
+    if (faceTraits<Face>::isTri())
+    {
+        // Inplace triangulation of triFace/labelledTri surface = no-op
+        return 0;
+    }
+    else
+    {
+        return triangulate
+        (
+            const_cast<List<label>&>(List<label>::null())
+        );
+    }
 }
 
 
@@ -918,6 +933,17 @@ Foam::label Foam::MeshedSurface<Face>::triangulate
     List<label>& faceMapOut
 )
 {
+    if (faceTraits<Face>::isTri())
+    {
+        // Inplace triangulation of triFace/labelledTri surface = no-op
+        if (notNull(faceMapOut))
+        {
+            faceMapOut.clear();
+        }
+
+        return 0;
+    }
+
     label nTri = 0;
     label maxTri = 0;  // the maximum number of triangles for any single face
     List<Face>& faceLst = this->storedFaces();
@@ -966,7 +992,7 @@ Foam::label Foam::MeshedSurface<Face>::triangulate
             {
                 label fp1 = f.fcIndex(fp);
 
-                newFaces[nTri] = triFace(f[0], f[fp], f[fp1]);
+                newFaces[nTri] = Face{f[0], f[fp], f[fp1]};
                 faceMap[nTri] = facei;
                 nTri++;
             }
diff --git a/src/surfMesh/MeshedSurface/MeshedSurface.H b/src/surfMesh/MeshedSurface/MeshedSurface.H
index 513a813597ca1fe5de1a174ff751db4680bc4ff5..aca6e18647f2e65174f915ea80dee8e77a5e66c9 100644
--- a/src/surfMesh/MeshedSurface/MeshedSurface.H
+++ b/src/surfMesh/MeshedSurface/MeshedSurface.H
@@ -186,9 +186,6 @@ public:
 
     // Static
 
-        //- Face storage only handles triangulated faces
-        inline static bool isTri();
-
         //- Can we read this file format?
         static bool canRead(const fileName&, const bool verbose=false);
 
@@ -210,36 +207,36 @@ public:
         //- Construct by transferring components (points, faces, zones).
         MeshedSurface
         (
-            const Xfer<pointField>&,
-            const Xfer<List<Face>>&,
-            const Xfer<surfZoneList>&
+            const Xfer<pointField>& pointLst,
+            const Xfer<List<Face>>& faceLst,
+            const Xfer<surfZoneList>& zoneLst
         );
 
         //- Construct by transferring components (points, faces).
         //  Use zone information if available
         MeshedSurface
         (
-            const Xfer<pointField>&,
-            const Xfer<List<Face>>&,
+            const Xfer<pointField>& pointLst,
+            const Xfer<List<Face>>& faceLst,
             const labelUList& zoneSizes = labelUList(),
             const UList<word>& zoneNames = UList<word>()
         );
 
         //- Construct as copy
-        MeshedSurface(const MeshedSurface&);
+        MeshedSurface(const MeshedSurface& surf);
 
         //- Construct from a UnsortedMeshedSurface
-        MeshedSurface(const UnsortedMeshedSurface<Face>&);
+        MeshedSurface(const UnsortedMeshedSurface<Face>& surf);
 
         //- Construct from a boundary mesh with local points/faces
         MeshedSurface
         (
-            const polyBoundaryMesh&,
+            const polyBoundaryMesh& bMesh,
             const bool globalPoints=false
         );
 
         //- Construct from a surfMesh
-        MeshedSurface(const surfMesh&);
+        MeshedSurface(const surfMesh& mesh);
 
         //- Construct by transferring the contents from a UnsortedMeshedSurface
         MeshedSurface(const Xfer<UnsortedMeshedSurface<Face>>&);
@@ -248,18 +245,18 @@ public:
         MeshedSurface(const Xfer<MeshedSurface<Face>>&);
 
         //- Construct from file name (uses extension to determine type)
-        MeshedSurface(const fileName&);
+        MeshedSurface(const fileName& name);
 
         //- Construct from file name (uses extension to determine type)
-        MeshedSurface(const fileName&, const word& ext);
+        MeshedSurface(const fileName& name, const word& ext);
 
         //- Construct from Istream
-        MeshedSurface(Istream&);
+        MeshedSurface(Istream& is);
 
         //- Construct from database
         MeshedSurface
         (
-            const Time&,
+            const Time& t,
             const word& surfName = word::null
         );
 
@@ -283,7 +280,7 @@ public:
         //- Select constructed from filename (explicit extension)
         static autoPtr<MeshedSurface> New
         (
-            const fileName&,
+            const fileName& name,
             const word& ext
         );
 
@@ -310,11 +307,19 @@ public:
             (name, surf)
         );
 
-        //- Write to file
+        //- Write to file, selecting writer based on its extension
         static void write
         (
-            const fileName&,
-            const MeshedSurface<Face>&
+            const fileName& name,
+            const MeshedSurface<Face>& surf
+        );
+
+        //- Write to file, selecting writer based on the given extension
+        static void write
+        (
+            const fileName& name,
+            const word& ext,
+            const MeshedSurface<Face>& surf
         );
 
 
@@ -563,8 +568,6 @@ bool MeshedSurface<labelledTri>::addZonesToFaces();
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-#include "MeshedSurfaceI.H"
-
 #ifdef NoRepository
     #include "MeshedSurface.C"
 #endif
diff --git a/src/surfMesh/MeshedSurface/MeshedSurfaceCore.C b/src/surfMesh/MeshedSurface/MeshedSurfaceCore.C
index 8640b6e5aeb0aa571943318c1bc20f016a7b2321..4a9bb6cac1994038b69a1792a8e9599cb8f3fa57 100644
--- a/src/surfMesh/MeshedSurface/MeshedSurfaceCore.C
+++ b/src/surfMesh/MeshedSurface/MeshedSurfaceCore.C
@@ -50,7 +50,7 @@ namespace Foam
     )
     {
         // First triangulate
-        // - slightly wasteful for space, but manages adjusts the zones too!
+        // - slightly wasteful for space, but adjusts the zones too!
         surf.triangulate();
         this->storedPoints().transfer(surf.storedPoints());
         this->storedZones().transfer(surf.storedZones());
@@ -81,12 +81,12 @@ namespace Foam
     )
     {
         // First triangulate
-        // - slightly wasteful for space, but manages adjusts the zones too!
+        // - slightly wasteful for space, but adjusts the zones too!
         surf.triangulate();
         this->storedPoints().transfer(surf.storedPoints());
         this->storedZones().transfer(surf.storedZones());
 
-        // transcribe from face -> triFace
+        // transcribe from face -> labelledTri (via triFace)
         const List<face>& origFaces = surf.surfFaces();
         List<labelledTri> newFaces(origFaces.size());
         forAll(origFaces, facei)
diff --git a/src/surfMesh/MeshedSurface/MeshedSurfaceIO.C b/src/surfMesh/MeshedSurface/MeshedSurfaceIO.C
index 9d8c5dd0912b8c9259657d5a936a5d9b225c3330..a8c8e4c7a3291292151ac3b68cc24b644a9cc4f0 100644
--- a/src/surfMesh/MeshedSurface/MeshedSurfaceIO.C
+++ b/src/surfMesh/MeshedSurface/MeshedSurfaceIO.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016-2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -25,6 +25,7 @@ License
 
 #include "MeshedSurface.H"
 #include "boundBox.H"
+#include "faceTraits.H"
 #include "Istream.H"
 #include "Ostream.H"
 
@@ -58,7 +59,7 @@ template<class Face>
 void Foam::MeshedSurface<Face>::writeStats(Ostream& os) const
 {
     os  << "points      : " << this->points().size() << nl;
-    if (MeshedSurface<Face>::isTri())
+    if (faceTraits<Face>::isTri())
     {
         os << "triangles   : " << this->size() << nl;
     }
@@ -82,7 +83,7 @@ void Foam::MeshedSurface<Face>::writeStats(Ostream& os) const
 
         os  << "faces       : " << this->size()
             << "  (tri:" << nTri << " quad:" << nQuad
-            << " poly:" << (this->size() - nTri - nQuad ) << ")" << nl;
+            << " poly:" << (this->size() - nTri - nQuad) << ")" << nl;
     }
 
     os  << "boundingBox : " << boundBox(this->points()) << endl;
diff --git a/src/surfMesh/MeshedSurface/MeshedSurfaceNew.C b/src/surfMesh/MeshedSurface/MeshedSurfaceNew.C
index a8280451ee8c6e95c383f74bc9128b0dec957fb0..7d345191ff8539fe5590cdb8cd39ee0e28618b6d 100644
--- a/src/surfMesh/MeshedSurface/MeshedSurfaceNew.C
+++ b/src/surfMesh/MeshedSurface/MeshedSurfaceNew.C
@@ -38,10 +38,9 @@ Foam::MeshedSurface<Face>::New(const fileName& name, const word& ext)
         InfoInFunction << "Constructing MeshedSurface" << endl;
     }
 
-    typename fileExtensionConstructorTable::iterator cstrIter =
-        fileExtensionConstructorTablePtr_->find(ext);
+    auto cstrIter = fileExtensionConstructorTablePtr_->find(ext);
 
-    if (cstrIter == fileExtensionConstructorTablePtr_->end())
+    if (!cstrIter.found())
     {
         // No direct reader, delegate to friend if possible
         const wordHashSet& delegate = FriendType::readTypes();
diff --git a/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxy.C b/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxy.C
index 168155a59716e9fc1e00ec7da637a4fb62384b15..b5dbdb6c99d3a23dda30fbe7177723c4350898c0 100644
--- a/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxy.C
+++ b/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxy.C
@@ -29,6 +29,7 @@ License
 #include "ListOps.H"
 #include "surfMesh.H"
 #include "OFstream.H"
+#include "faceTraits.H"
 
 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
 
@@ -59,18 +60,27 @@ void Foam::MeshedSurfaceProxy<Face>::write
     const fileName& name,
     const MeshedSurfaceProxy& surf
 )
+{
+    write(name, name.ext(), surf);
+}
+
+
+template<class Face>
+void Foam::MeshedSurfaceProxy<Face>::write
+(
+    const fileName& name,
+    const word& ext,
+    const MeshedSurfaceProxy& surf
+)
 {
     if (debug)
     {
         InfoInFunction << "Writing to " << name << endl;
     }
 
-    const word ext = name.ext();
+    auto mfIter = writefileExtensionMemberFunctionTablePtr_->find(ext);
 
-    typename writefileExtensionMemberFunctionTable::iterator mfIter =
-        writefileExtensionMemberFunctionTablePtr_->find(ext);
-
-    if (mfIter == writefileExtensionMemberFunctionTablePtr_->end())
+    if (!mfIter.found())
     {
         FatalErrorInFunction
             << "Unknown file extension " << ext << nl << nl
@@ -237,38 +247,24 @@ Foam::MeshedSurfaceProxy<Face>::~MeshedSurfaceProxy()
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-
-namespace Foam
-{
-
-// Number of triangles for a triFace surface
-template<>
-inline label MeshedSurfaceProxy<triFace>::nTriangles() const
-{
-    return this->size();
-}
-
-// Number of triangles for a labelledTri surface
-template<>
-inline label MeshedSurfaceProxy<labelledTri>::nTriangles() const
-{
-    return this->size();
-}
-
-}
-
-
 template<class Face>
 inline Foam::label Foam::MeshedSurfaceProxy<Face>::nTriangles() const
 {
-    label nTri = 0;
-    const List<Face>& faceLst = this->surfFaces();
-    forAll(faceLst, facei)
+    if (faceTraits<Face>::isTri())
     {
-        nTri += faceLst[facei].nTriangles();
+        return this->size();
     }
+    else
+    {
+        label nTri = 0;
+        const List<Face>& faceLst = this->surfFaces();
+        forAll(faceLst, facei)
+        {
+            nTri += faceLst[facei].nTriangles();
+        }
 
-    return nTri;
+        return nTri;
+    }
 }
 
 
diff --git a/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxy.H b/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxy.H
index 3bedc3f0767f90fea6c792158c60676764be8469..6c0f3582e577fa2ac8bcbfae373f606f95a16148 100644
--- a/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxy.H
+++ b/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxy.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016-2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -100,9 +100,9 @@ public:
         //- Construct from component references
         MeshedSurfaceProxy
         (
-            const pointField&,
-            const List<Face>&,
-            const List<surfZone>& = List<surfZone>(),
+            const pointField& pointLst,
+            const List<Face>& faceLst,
+            const List<surfZone>& zoneLst = List<surfZone>(),
             const List<label>& faceMap = List<label>()
         );
 
@@ -126,11 +126,19 @@ public:
             (name, surf)
         );
 
-        //- Write to file
+        //- Write to file, selected based on its extension
         static void write
         (
-            const fileName&,
-            const MeshedSurfaceProxy<Face>&
+            const fileName& name,
+            const MeshedSurfaceProxy& surf
+        );
+
+        //- Write to file, selected based on given extension
+        static void write
+        (
+            const fileName& name,
+            const word& ext,
+            const MeshedSurfaceProxy& surf
         );
 
 
@@ -188,10 +196,16 @@ public:
                 write(name, *this);
             }
 
+            //- Generic write routine. Chooses writer based on extension.
+            virtual void write(const fileName& name, const word& ext) const
+            {
+                write(name, ext, *this);
+            }
+
             //- Write to database
             virtual void write
             (
-                const Time&,
+                const Time& t,
                 const word& surfName = word::null
             ) const;
 };
diff --git a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.C b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.C
index 42a7d1d9fe1ecc8e4d36466c10f430d536cf7862..7ac9a3e598c536a08433fe787aff92370aaeb6af 100644
--- a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.C
+++ b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.C
@@ -113,17 +113,16 @@ void Foam::UnsortedMeshedSurface<Face>::write
 
     const word ext = name.ext();
 
-    typename writefileExtensionMemberFunctionTable::iterator mfIter =
-        writefileExtensionMemberFunctionTablePtr_->find(ext);
+    auto mfIter = writefileExtensionMemberFunctionTablePtr_->find(ext);
 
-    if (mfIter == writefileExtensionMemberFunctionTablePtr_->end())
+    if (!mfIter.found())
     {
         // No direct writer, delegate to proxy if possible
         const wordHashSet& delegate = ProxyType::writeTypes();
 
         if (delegate.found(ext))
         {
-            MeshedSurfaceProxy<Face>(surf).write(name);
+            MeshedSurfaceProxy<Face>(surf).write(name, ext);
         }
         else
         {
diff --git a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurfaceNew.C b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurfaceNew.C
index f6f1431a8353b3eb01814acf26034b6bae87eeb1..6f50b238975201c096eff579cb5da7c54b0340d9 100644
--- a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurfaceNew.C
+++ b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurfaceNew.C
@@ -37,10 +37,9 @@ Foam::UnsortedMeshedSurface<Face>::New(const fileName& name, const word& ext)
         InfoInFunction << "Constructing UnsortedMeshedSurface" << endl;
     }
 
-    typename fileExtensionConstructorTable::iterator cstrIter =
-        fileExtensionConstructorTablePtr_->find(ext);
+    auto cstrIter = fileExtensionConstructorTablePtr_->find(ext);
 
-    if (cstrIter == fileExtensionConstructorTablePtr_->end())
+    if (!cstrIter.found())
     {
         // No direct reader, delegate to parent if possible
         const wordHashSet& delegate = ParentType::readTypes();
diff --git a/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.C b/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.C
index 0c60b22ede22db7b1b71739a0b67cc76bcbd21fc..daa0e2c1f8acca4b085751892e3b475a68285e8c 100644
--- a/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016-2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -26,6 +26,7 @@ License
 #include "AC3DsurfaceFormat.H"
 #include "IStringStream.H"
 #include "PrimitivePatch.H"
+#include "faceTraits.H"
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
@@ -194,9 +195,9 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
                         verts[vertI] = parse<int>(line) + vertexOffset;
                     }
 
-                    labelUList& f = static_cast<labelUList&>(verts);
+                    const labelUList& f = static_cast<const labelUList&>(verts);
 
-                    if (MeshedSurface<Face>::isTri() && f.size() > 3)
+                    if (faceTraits<Face>::isTri() && f.size() > 3)
                     {
                         // simple face triangulation about f[0]
                         // points may be incomplete
@@ -204,7 +205,7 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
                         {
                             label fp2 = f.fcIndex(fp1);
 
-                            dynFaces.append(triFace(f[0], f[fp1], f[fp2]));
+                            dynFaces.append(Face{f[0], f[fp1], f[fp2]});
                             sizes[zoneI]++;
                         }
                     }
diff --git a/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormat.C b/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormat.C
index 731b2e1b96aa397c06aeeecfb80073ea37721161..f2aa5b22ee3eaf1b1f7fa0d4fb11a20140e5c04b 100644
--- a/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormat.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016-2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -28,8 +28,8 @@ License
 #include "clock.H"
 #include "IFstream.H"
 #include "IStringStream.H"
-#include "Ostream.H"
 #include "OFstream.H"
+#include "faceTraits.H"
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
@@ -187,7 +187,7 @@ bool Foam::fileFormats::GTSsurfaceFormat<Face>::read
                 << exit(FatalError);
         }
 
-        faceLst[facei] = triFace(e0Far, common01, e1Far);
+        faceLst[facei] = Face{e0Far, common01, e1Far};
         zoneIds[facei] = zoneI;
     }
 
@@ -229,7 +229,7 @@ void Foam::fileFormats::GTSsurfaceFormat<Face>::write
     // check if output triangulation would be required
     // It is too annoying to triangulate on-the-fly
     // just issue a warning and get out
-    if (!MeshedSurface<Face>::isTri())
+    if (!faceTraits<Face>::isTri())
     {
         label nNonTris = 0;
         forAll(faceLst, facei)
@@ -249,7 +249,6 @@ void Foam::fileFormats::GTSsurfaceFormat<Face>::write
         }
     }
 
-
     OFstream os(filename);
     if (!os.good())
     {
@@ -331,7 +330,7 @@ void Foam::fileFormats::GTSsurfaceFormat<Face>::write
     // check if output triangulation would be required
     // It is too annoying to triangulate on-the-fly
     // just issue a warning and get out
-    if (!MeshedSurface<Face>::isTri())
+    if (!faceTraits<Face>::isTri())
     {
         label nNonTris = 0;
         forAll(faceLst, facei)
@@ -351,7 +350,6 @@ void Foam::fileFormats::GTSsurfaceFormat<Face>::write
         }
     }
 
-
     OFstream os(filename);
     if (!os.good())
     {
diff --git a/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.C b/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.C
index d7b932ec485de4fba41ca5b3efbb1ae4996bc325..55f941bf43fc63bb21060761959e620141c7e72e 100644
--- a/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2015 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -26,6 +26,7 @@ License
 #include "NASsurfaceFormat.H"
 #include "IFstream.H"
 #include "IStringStream.H"
+#include "faceTraits.H"
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
@@ -191,12 +192,10 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
 
         if (cmd == "CTRIA3")
         {
-            triFace fTri;
-
             label groupId = readLabel(IStringStream(line.substr(16,8))());
-            fTri[0] = readLabel(IStringStream(line.substr(24,8))());
-            fTri[1] = readLabel(IStringStream(line.substr(32,8))());
-            fTri[2] = readLabel(IStringStream(line.substr(40,8))());
+            label a = readLabel(IStringStream(line.substr(24,8))());
+            label b = readLabel(IStringStream(line.substr(32,8))());
+            label c = readLabel(IStringStream(line.substr(40,8))());
 
             // Convert groupID into zoneId
             Map<label>::const_iterator fnd = lookup.find(groupId);
@@ -217,20 +216,17 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
                 // Info<< "zone" << zoneI << " => group " << groupId <<endl;
             }
 
-            dynFaces.append(fTri);
+            dynFaces.append(Face{a, b, c});
             dynZones.append(zoneI);
             dynSizes[zoneI]++;
         }
         else if (cmd == "CQUAD4")
         {
-            face fQuad(4);
-            labelUList& f = static_cast<labelUList&>(fQuad);
-
             label groupId = readLabel(IStringStream(line.substr(16,8))());
-            fQuad[0] = readLabel(IStringStream(line.substr(24,8))());
-            fQuad[1] = readLabel(IStringStream(line.substr(32,8))());
-            fQuad[2] = readLabel(IStringStream(line.substr(40,8))());
-            fQuad[3] = readLabel(IStringStream(line.substr(48,8))());
+            label a = readLabel(IStringStream(line.substr(24,8))());
+            label b = readLabel(IStringStream(line.substr(32,8))());
+            label c = readLabel(IStringStream(line.substr(40,8))());
+            label d = readLabel(IStringStream(line.substr(48,8))());
 
             // Convert groupID into zoneId
             Map<label>::const_iterator fnd = lookup.find(groupId);
@@ -251,18 +247,17 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
                 // Info<< "zone" << zoneI << " => group " << groupId <<endl;
             }
 
-
-            if (MeshedSurface<Face>::isTri())
+            if (faceTraits<Face>::isTri())
             {
-                dynFaces.append(triFace(f[0], f[1], f[2]));
-                dynFaces.append(triFace(f[0], f[2], f[3]));
+                dynFaces.append(Face{a, b, c});
+                dynFaces.append(Face{c, d, a});
                 dynZones.append(zoneI);
                 dynZones.append(zoneI);
                 dynSizes[zoneI] += 2;
             }
             else
             {
-                dynFaces.append(Face(f));
+                dynFaces.append(Face{a,b,c,d});
                 dynZones.append(zoneI);
                 dynSizes[zoneI]++;
             }
diff --git a/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormat.C b/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormat.C
index 395e2bacb73f18c19564946eb17cda5bbf9eb625..db2036aa888e5204251393612833f53273b32bfe 100644
--- a/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormat.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016-2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -27,9 +27,9 @@ License
 #include "clock.H"
 #include "IFstream.H"
 #include "IStringStream.H"
-#include "Ostream.H"
 #include "OFstream.H"
 #include "ListOps.H"
+#include "faceTraits.H"
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
@@ -172,7 +172,7 @@ bool Foam::fileFormats::OBJsurfaceFormat<Face>::read
 
             labelUList& f = static_cast<labelUList&>(dynVertices);
 
-            if (MeshedSurface<Face>::isTri() && f.size() > 3)
+            if (faceTraits<Face>::isTri() && f.size() > 3)
             {
                 // simple face triangulation about f[0]
                 // points may be incomplete
@@ -180,7 +180,7 @@ bool Foam::fileFormats::OBJsurfaceFormat<Face>::read
                 {
                     label fp2 = f.fcIndex(fp1);
 
-                    dynFaces.append(triFace(f[0], f[fp1], f[fp2]));
+                    dynFaces.append(Face{f[0], f[fp1], f[fp2]});
                     dynZones.append(zoneI);
                     dynSizes[zoneI]++;
                 }
diff --git a/src/surfMesh/surfaceFormats/off/OFFsurfaceFormat.C b/src/surfMesh/surfaceFormats/off/OFFsurfaceFormat.C
index fd869a0c5086db67467529aa42bac8d9f282f080..3146f01b990b6f9fcfbbe537433c0ca51f6e736d 100644
--- a/src/surfMesh/surfaceFormats/off/OFFsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/off/OFFsurfaceFormat.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016-2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -27,7 +27,7 @@ License
 #include "clock.H"
 #include "IFstream.H"
 #include "IStringStream.H"
-#include "Ostream.H"
+#include "faceTraits.H"
 #include "OFstream.H"
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
@@ -113,9 +113,9 @@ bool Foam::fileFormats::OFFsurfaceFormat<Face>::read
                 lineStream >> verts[vertI];
             }
 
-            labelUList& f = static_cast<labelUList&>(verts);
+            const labelUList& f = static_cast<const labelUList&>(verts);
 
-            if (MeshedSurface<Face>::isTri() && f.size() > 3)
+            if (faceTraits<Face>::isTri() && f.size() > 3)
             {
                 // simple face triangulation about f[0]
                 // cannot use face::triangulation (points may be incomplete)
@@ -123,7 +123,7 @@ bool Foam::fileFormats::OFFsurfaceFormat<Face>::read
                 {
                     label fp2 = f.fcIndex(fp1);
 
-                    dynFaces.append(triFace(f[0], f[fp1], f[fp2]));
+                    dynFaces.append(Face{f[0], f[fp1], f[fp2]});
                 }
             }
             else
diff --git a/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormat.C b/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormat.C
index 7240ee78245a01aad1371e18d01ccdf1b7233dfe..36e3f2b0a0bc6abe4831c5a4df54aa3f4cb8e7d5 100644
--- a/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormat.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016-2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -25,6 +25,7 @@ License
 
 #include "STARCDsurfaceFormat.H"
 #include "ListOps.H"
+#include "faceTraits.H"
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
@@ -193,7 +194,7 @@ bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
             }
 
             SubList<label> vertices(vertexLabels, vertexLabels.size());
-            if (MeshedSurface<Face>::isTri() && nLabels > 3)
+            if (faceTraits<Face>::isTri() && nLabels > 3)
             {
                 // face needs triangulation
                 face f(vertices);
diff --git a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.C b/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.C
index ee598a5228e87c559a0d8c32669eb63f7fba65ec..f9e335c39eb8dd7cca3f629b277f68c197e86077 100644
--- a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.C
@@ -146,7 +146,7 @@ bool Foam::fileFormats::STLsurfaceFormat<Face>::read
         forAll(faceLst, facei)
         {
             const label startPt = 3*facei;
-            faceLst[facei] = triFace(startPt, startPt+1, startPt+2);
+            faceLst[facei] = Face{startPt, startPt+1, startPt+2};
         }
     }
     else
@@ -160,7 +160,7 @@ bool Foam::fileFormats::STLsurfaceFormat<Face>::read
         forAll(faceMap, facei)
         {
             const label startPt = 3*faceMap[facei];
-            faceLst[facei] = triFace(startPt, startPt+1, startPt+2);
+            faceLst[facei] = Face{startPt, startPt+1, startPt+2};
         }
     }
     zoneIds.clear();
diff --git a/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.C b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.C
index 5b0aba1f8808a1a6885bd5925f2fe08ef9e42c7d..cb2aa80823b8b074fc90c665010a7236b245cd51 100644
--- a/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016-2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -97,7 +97,7 @@ bool Foam::fileFormats::TRIsurfaceFormat<Face>::read
         forAll(faceLst, facei)
         {
             const label startPt = 3*facei;
-            faceLst[facei] = triFace(startPt, startPt+1, startPt+2);
+            faceLst[facei] = Face{startPt, startPt+1, startPt+2};
         }
     }
     else
@@ -111,7 +111,7 @@ bool Foam::fileFormats::TRIsurfaceFormat<Face>::read
         forAll(faceMap, facei)
         {
             const label startPt = 3*faceMap[facei];
-            faceLst[facei] = triFace(startPt, startPt+1, startPt+2);
+            faceLst[facei] = Face{startPt, startPt+1, startPt+2};
         }
     }
     zoneIds.clear();
diff --git a/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.C b/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.C
index aedd18d6c853b42e048bfd75f514f62b4d8e85aa..b0a5d2711498e694299a1d41c2504fdd83eb5fd6 100644
--- a/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016-2107 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -26,6 +26,7 @@ License
 #include "VTKsurfaceFormat.H"
 #include "vtkUnstructuredReader.H"
 #include "scalarIOField.H"
+#include "faceTraits.H"
 #include "OFstream.H"
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
@@ -150,7 +151,7 @@ bool Foam::fileFormats::VTKsurfaceFormat<Face>::read
 
     // Check if it needs triangulation
     label nTri = 0;
-    if (MeshedSurface<Face>::isTri())
+    if (faceTraits<Face>::isTri())
     {
         forAll(faces, facei)
         {
@@ -172,7 +173,7 @@ bool Foam::fileFormats::VTKsurfaceFormat<Face>::read
             {
                 label fp2 = f.fcIndex(fp1);
 
-                dynFaces.append(triFace(f[0], f[fp1], f[fp2]));
+                dynFaces.append(Face{f[0], f[fp1], f[fp2]});
                 dynZones.append(zones[facei]);
             }
         }