diff --git a/src/fileFormats/stl/STLReader.C b/src/fileFormats/stl/STLReader.C
index b7b91a0bb755574f216bb4d4f37a941286939610..ca7451d886a2ad7726a6b1f8d1a290a371414eaa 100644
--- a/src/fileFormats/stl/STLReader.C
+++ b/src/fileFormats/stl/STLReader.C
@@ -26,6 +26,7 @@ License
 #include "STLReader.H"
 #include "Map.H"
 #include "IFstream.H"
+#include "mergePoints.H"
 
 #undef DEBUG_STLBINARY
 
@@ -202,4 +203,38 @@ void Foam::fileFormats::STLReader::clear()
 }
 
 
+Foam::label Foam::fileFormats::STLReader::mergePointsMap
+(
+    labelList& pointMap
+) const
+{
+    // With the merge distance depending on the input format (ASCII | BINARY),
+    // but must be independent of WM_SP or WM_DP flag.
+    // - floatScalarSMALL  = 1e-6
+    // - doubleScalarSMALL = 1e-15
+
+    return mergePointsMap
+    (
+        (format_ == BINARY ? 10 : 100) * doubleScalarSMALL,
+        pointMap
+    );
+}
+
+
+Foam::label Foam::fileFormats::STLReader::mergePointsMap
+(
+    const scalar mergeTol,
+    labelList& pointMap
+) const
+{
+    return Foam::mergePoints
+    (
+        points_,
+        mergeTol,
+        false, // verbose
+        pointMap
+    );
+}
+
+
 // ************************************************************************* //
diff --git a/src/fileFormats/stl/STLReader.H b/src/fileFormats/stl/STLReader.H
index 9ed6838bc136feb7954060ad70bb93d7f0d2ba45..e9873aafe74bad823e3c4db840698f82efdfaf7a 100644
--- a/src/fileFormats/stl/STLReader.H
+++ b/src/fileFormats/stl/STLReader.H
@@ -61,7 +61,7 @@ class STLReader
         bool sorted_;
 
         //- The points supporting the facets
-        pointField points_;
+        List<STLpoint> points_;
 
         //- The zones associated with the faces
         List<label> zoneIds_;
@@ -117,6 +117,15 @@ public:
         //- Flush all values
         void clear();
 
+        //- Calculate merge points mapping, return old to new pointMap.
+        //  The merge tolerance based on ASCII or BINARY input format.
+        //  \return number of unique points
+        label mergePointsMap(labelList& pointMap) const;
+
+        //- Calculate merge points mapping, return old to new pointMap.
+        //  \return number of unique points
+        label mergePointsMap(const scalar mergeTol, labelList& pointMap) const;
+
         //- File read was already sorted?
         inline bool sorted() const
         {
@@ -124,7 +133,7 @@ public:
         }
 
         //- Return full access to the points
-        inline pointField& points()
+        inline List<STLpoint>& points()
         {
             return points_;
         }
diff --git a/src/fileFormats/stl/STLReaderASCII.L b/src/fileFormats/stl/STLReaderASCII.L
index 1e60c2a241ed79636f0a8c7340931f6b09e3210b..46c9ab1a853195dd9c28254f436a50b46f5eb478 100644
--- a/src/fileFormats/stl/STLReaderASCII.L
+++ b/src/fileFormats/stl/STLReaderASCII.L
@@ -77,7 +77,7 @@ class STLASCIILexer
         label lineNo_;
         word  startError_;
 
-        DynamicList<point> points_;
+        DynamicList<STLpoint> points_;
         DynamicList<label> facets_;
         DynamicList<word>  names_;
         DynamicList<label> sizes_;
@@ -105,7 +105,7 @@ public:
         }
 
         //- A list of unstitched triangle points
-        inline DynamicList<point>& points()
+        inline DynamicList<STLpoint>& points()
         {
             return points_;
         }
diff --git a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.C b/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.C
index f9e335c39eb8dd7cca3f629b277f68c197e86077..a746232d18aafdcb371dcb74c7ed7f42828d17e6 100644
--- a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.C
@@ -24,7 +24,6 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "STLsurfaceFormat.H"
-#include "labelledTri.H"
 #include "triPointRef.H"
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
@@ -126,13 +125,25 @@ bool Foam::fileFormats::STLsurfaceFormat<Face>::read
 {
     this->clear();
 
-    // read in the values
+    // Read in the values
     STLReader reader(filename);
 
-    // transfer points
-    this->storedPoints().transfer(reader.points());
+    // Get the map for stitched surface points, with merge tolerance depending
+    // on the input format
+    labelList pointMap;
+    const label nUniquePoints = reader.mergePointsMap(pointMap);
 
-    // retrieve the original zone information
+    const auto& readpts = reader.points();
+
+    // Assign points
+    pointField& pointLst = this->storedPoints();
+    pointLst.setSize(nUniquePoints);
+    forAll(readpts, pointi)
+    {
+        pointLst[pointMap[pointi]] = readpts[pointi];
+    }
+
+    // Retrieve the original zone information
     List<word>  names(reader.names().xfer());
     List<label> sizes(reader.sizes().xfer());
     List<label> zoneIds(reader.zoneIds().xfer());
@@ -142,16 +153,21 @@ bool Foam::fileFormats::STLsurfaceFormat<Face>::read
 
     if (reader.sorted())
     {
-        // already sorted - generate directly
+        // Already sorted - generate directly
         forAll(faceLst, facei)
         {
             const label startPt = 3*facei;
-            faceLst[facei] = Face{startPt, startPt+1, startPt+2};
+            faceLst[facei] = Face
+            {
+                pointMap[startPt],
+                pointMap[startPt+1],
+                pointMap[startPt+2]
+            };
         }
     }
     else
     {
-        // unsorted - determine the sorted order:
+        // Unsorted - determine the sorted order:
         // avoid SortableList since we discard the main list anyhow
         List<label> faceMap;
         sortedOrder(zoneIds, faceMap);
@@ -160,7 +176,12 @@ bool Foam::fileFormats::STLsurfaceFormat<Face>::read
         forAll(faceMap, facei)
         {
             const label startPt = 3*faceMap[facei];
-            faceLst[facei] = Face{startPt, startPt+1, startPt+2};
+            faceLst[facei] = Face
+            {
+                pointMap[startPt],
+                pointMap[startPt+1],
+                pointMap[startPt+2]
+            };
         }
     }
     zoneIds.clear();
@@ -177,7 +198,6 @@ bool Foam::fileFormats::STLsurfaceFormat<Face>::read
         this->addZones(sizes);
     }
     this->addZonesToFaces(); // for labelledTri
-    this->stitchFaces(SMALL);
 
     return true;
 }
diff --git a/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.C b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.C
index cb2aa80823b8b074fc90c665010a7236b245cd51..b36c5fd321d6c668069709f0b5493a47dc3ca15c 100644
--- a/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.C
@@ -78,13 +78,24 @@ bool Foam::fileFormats::TRIsurfaceFormat<Face>::read
 {
     this->clear();
 
-    // read in the values
+    // Read in the values
     TRIsurfaceFormatCore reader(filename);
 
-    // transfer points
-    this->storedPoints().transfer(reader.points());
+    // Get the map for stitched surface points
+    labelList pointMap;
+    const label nUniquePoints = reader.mergePointsMap(pointMap);
 
-    // retrieve the original zone information
+    const auto& readpts = reader.points();
+
+    // Assign points
+    pointField& pointLst = this->storedPoints();
+    pointLst.setSize(nUniquePoints);
+    forAll(readpts, pointi)
+    {
+        pointLst[pointMap[pointi]] = readpts[pointi];
+    }
+
+    // Retrieve the original zone information
     List<label> sizes(reader.sizes().xfer());
     List<label> zoneIds(reader.zoneIds().xfer());
 
@@ -93,16 +104,21 @@ bool Foam::fileFormats::TRIsurfaceFormat<Face>::read
 
     if (reader.sorted())
     {
-        // already sorted - generate directly
+        // Already sorted - generate directly
         forAll(faceLst, facei)
         {
             const label startPt = 3*facei;
-            faceLst[facei] = Face{startPt, startPt+1, startPt+2};
+            faceLst[facei] = Face
+            {
+                pointMap[startPt],
+                pointMap[startPt+1],
+                pointMap[startPt+2]
+            };
         }
     }
     else
     {
-        // unsorted - determine the sorted order:
+        // Unsorted - determine the sorted order:
         // avoid SortableList since we discard the main list anyhow
         List<label> faceMap;
         sortedOrder(zoneIds, faceMap);
@@ -111,7 +127,12 @@ bool Foam::fileFormats::TRIsurfaceFormat<Face>::read
         forAll(faceMap, facei)
         {
             const label startPt = 3*faceMap[facei];
-            faceLst[facei] = Face{startPt, startPt+1, startPt+2};
+            faceLst[facei] = Face
+            {
+                pointMap[startPt],
+                pointMap[startPt+1],
+                pointMap[startPt+2]
+            };
         }
     }
     zoneIds.clear();
@@ -121,7 +142,7 @@ bool Foam::fileFormats::TRIsurfaceFormat<Face>::read
 
     this->addZones(sizes);
     this->addZonesToFaces(); // for labelledTri
-    this->stitchFaces(SMALL);
+
     return true;
 }
 
diff --git a/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormatCore.C b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormatCore.C
index 87cc04d20ec49afcef7da2ff05adef49922aaae6..8f473d11203f5553a5b6907b45814ec375eae1d2 100644
--- a/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormatCore.C
+++ b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormatCore.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.
@@ -27,6 +27,7 @@ License
 #include "IFstream.H"
 #include "IOmanip.H"
 #include "IStringStream.H"
+#include "mergePoints.H"
 #include "Map.H"
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
@@ -71,7 +72,7 @@ bool Foam::fileFormats::TRIsurfaceFormatCore::read
 
     // uses similar structure as STL, just some points
     // the rest of the reader resembles the STL binary reader
-    DynamicList<point> dynPoints;
+    DynamicList<STLpoint> dynPoints;
     DynamicList<label> dynZones;
     DynamicList<label> dynSizes;
     HashTable<label>   lookup;
@@ -94,7 +95,7 @@ bool Foam::fileFormats::TRIsurfaceFormatCore::read
 
         IStringStream lineStream(line);
 
-        point p
+        STLpoint p
         (
             readScalar(lineStream),
             readScalar(lineStream),
@@ -106,7 +107,7 @@ bool Foam::fileFormats::TRIsurfaceFormatCore::read
         dynPoints.append(p);
         dynPoints.append
         (
-            point
+            STLpoint
             (
                 readScalar(lineStream),
                 readScalar(lineStream),
@@ -115,7 +116,7 @@ bool Foam::fileFormats::TRIsurfaceFormatCore::read
         );
         dynPoints.append
         (
-            point
+            STLpoint
             (
                 readScalar(lineStream),
                 readScalar(lineStream),
@@ -179,4 +180,43 @@ bool Foam::fileFormats::TRIsurfaceFormatCore::read
 }
 
 
+void Foam::fileFormats::TRIsurfaceFormatCore::clear()
+{
+    sorted_ = true;
+    points_.clear();
+    zoneIds_.clear();
+    sizes_.clear();
+}
+
+
+Foam::label Foam::fileFormats::TRIsurfaceFormatCore::mergePointsMap
+(
+    labelList& pointMap
+) const
+{
+    // Use merge tolerance as per STL ascii
+    return mergePointsMap
+    (
+        100 * doubleScalarSMALL,
+        pointMap
+    );
+}
+
+
+Foam::label Foam::fileFormats::TRIsurfaceFormatCore::mergePointsMap
+(
+    const scalar mergeTol,
+    labelList& pointMap
+) const
+{
+    return Foam::mergePoints
+    (
+        points_,
+        mergeTol,
+        false, // verbose
+        pointMap
+    );
+}
+
+
 // ************************************************************************* //
diff --git a/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormatCore.H b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormatCore.H
index 12ce08e3725fdc72d03e1f4b96313f7879baa186..5d4b76fd6e0d122fb238e2433fca22430043a90f 100644
--- a/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormatCore.H
+++ b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormatCore.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.
@@ -36,7 +36,7 @@ SourceFiles
 #define TRIsurfaceFormatCore_H
 
 #include "surfaceFormatsCore.H"
-#include "triFace.H"
+#include "STLpoint.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -58,7 +58,7 @@ class TRIsurfaceFormatCore
         bool sorted_;
 
         //- The points supporting the facets
-        pointField points_;
+        List<STLpoint> points_;
 
         //- The zones associated with the faces
         List<label> zoneIds_;
@@ -83,7 +83,7 @@ public:
     // Constructors
 
         //- Read from file, filling in the information
-        TRIsurfaceFormatCore(const fileName&);
+        TRIsurfaceFormatCore(const fileName& filename);
 
 
     //- Destructor
@@ -92,35 +92,39 @@ public:
 
     // Member Functions
 
+        //- Flush all values
+        void clear();
+
+        //- Calculate merge points mapping, return old to new pointMap.
+        //  Use merge tolerance as per STL ascii
+        //  \return number of unique points
+        label mergePointsMap(labelList& pointMap) const;
+
+        //- Calculate merge points mapping, return old to new pointMap.
+        //  \return number of unique points
+        label mergePointsMap(const scalar mergeTol, labelList& pointMap) const;
+
+
         //- File read was already sorted
-        bool sorted() const
+        inline bool sorted() const
         {
             return sorted_;
         }
 
-        //- Flush all values
-        void clear()
-        {
-            sorted_ = true;
-            points_.clear();
-            zoneIds_.clear();
-            sizes_.clear();
-        }
-
         //- Return full access to the points
-        pointField& points()
+        inline List<STLpoint>& points()
         {
             return points_;
         }
 
         //- Return full access to the zones
-        List<label>& zoneIds()
+        inline List<label>& zoneIds()
         {
             return zoneIds_;
         }
 
         //- The list of zone sizes in the order of their first appearance
-        List<label>& sizes()
+        inline List<label>& sizes()
         {
             return sizes_;
         }
diff --git a/src/surfMesh/triSurface/interfaces/STL/readSTL.C b/src/surfMesh/triSurface/interfaces/STL/readSTL.C
index 43c9453a524e045805b69c0561a878d819b626a9..70b1e9f44454d172af6031f59e0127d865efb751 100644
--- a/src/surfMesh/triSurface/interfaces/STL/readSTL.C
+++ b/src/surfMesh/triSurface/interfaces/STL/readSTL.C
@@ -24,7 +24,6 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "STLReader.H"
-#include "mergePoints.H"
 #include "triSurface.H"
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
@@ -42,22 +41,13 @@ bool Foam::triSurface::readSTL(const fileName& STLfileName, bool forceBinary)
         )
     );
 
-    // Stitch points
+    // Get the map for stitched surface points, with merge tolerance depending
+    // on the input format
     labelList pointMap;
-    label nUniquePoints = mergePoints
-    (
-        reader.points(),
-        (
-            // With the merge distance depending on the input format
-            (reader.stlFormat() == fileFormats::STLCore::BINARY ? 10 : 100)
-          * SMALL
-        ),
-        false,                  // verbose
-        pointMap                // old to new point map
-    );
+    const label nUniquePoints = reader.mergePointsMap(pointMap);
 
-    const pointField& readpts = reader.points();
-    const labelList&  zoneIds = reader.zoneIds();
+    const auto& readpts = reader.points();
+    const labelList& zoneIds = reader.zoneIds();
 
     pointField& pointLst = storedPoints();
     List<Face>& faceLst  = storedFaces();
@@ -84,18 +74,16 @@ bool Foam::triSurface::readSTL(const fileName& STLfileName, bool forceBinary)
         f.region() = zoneIds[i];
     }
 
-    // Set patch names (and sizes)
-    // - there is likely a more efficient means of doing this
+    // Set patch name/index.
     if (reader.stlFormat() == fileFormats::STLCore::ASCII)
     {
         const List<word>& names = reader.names();
 
         patches_.setSize(names.size());
-        forAll(names, namei)
+        forAll(patches_, patchi)
         {
-            patches_[namei].name() = names[namei];
+            patches_[patchi] = geometricSurfacePatch(names[patchi], patchi);
         }
-        setDefaultPatches();
     }
 
     return true;