From 5f90964deefecb9aa3b03f28b40164dd3296a48c Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@esi-group.com>
Date: Wed, 8 Apr 2020 09:17:12 +0200
Subject: [PATCH] BUG: minor regression in surface reading of compressed files
 (#1600)

- as a side-effect of recent changes, command-line stripping of .gz
  extensions on input was lost. For example,

      OK:    surfaceTransformPoints file.stl ...
      Fail:  surfaceTransformPoints file.stl.gz ...

- restore the previous behaviour of silently stripping the '.gz'
  extension on input.

ENH: add triSurface::New selector entry point

- for symmetry with MeshedSurface
---
 src/surfMesh/Make/files                       |   1 +
 src/surfMesh/MeshedSurface/MeshedSurface.C    |  34 +---
 src/surfMesh/MeshedSurface/MeshedSurface.H    |   3 +
 src/surfMesh/MeshedSurface/MeshedSurfaceNew.C |  46 +++++-
 .../UnsortedMeshedSurface.C                   |  35 +---
 .../UnsortedMeshedSurface.H                   |   3 +
 .../UnsortedMeshedSurfaceNew.C                |  44 ++++-
 src/surfMesh/triSurface/triSurface.C          |  28 ++++
 src/surfMesh/triSurface/triSurface.H          |  33 ++--
 src/surfMesh/triSurface/triSurfaceIO.C        | 134 ++++-----------
 src/surfMesh/triSurface/triSurfaceNew.C       | 156 ++++++++++++++++++
 11 files changed, 335 insertions(+), 182 deletions(-)
 create mode 100644 src/surfMesh/triSurface/triSurfaceNew.C

diff --git a/src/surfMesh/Make/files b/src/surfMesh/Make/files
index 3bcf422ffab..0fe30852b3b 100644
--- a/src/surfMesh/Make/files
+++ b/src/surfMesh/Make/files
@@ -51,6 +51,7 @@ $(surfaceFormats)/x3d/X3DsurfaceFormatRunTime.C
 
 triSurface/triSurface.C
 triSurface/triSurfaceIO.C
+triSurface/triSurfaceNew.C
 triSurface/triSurfaceAddressing.C
 triSurface/triSurfaceStitch.C
 
diff --git a/src/surfMesh/MeshedSurface/MeshedSurface.C b/src/surfMesh/MeshedSurface/MeshedSurface.C
index 991664f2b5c..65c36de6287 100644
--- a/src/surfMesh/MeshedSurface/MeshedSurface.C
+++ b/src/surfMesh/MeshedSurface/MeshedSurface.C
@@ -1397,14 +1397,9 @@ void Foam::MeshedSurface<Face>::swapPoints(pointField& points)
 template<class Face>
 bool Foam::MeshedSurface<Face>::read(const fileName& name)
 {
-    const word ext(name.ext());
-    if (ext == "gz")
-    {
-        fileName unzipName = name.lessExt();
-        return read(unzipName, unzipName.ext());
-    }
-
-    return read(name, ext);
+    this->clear();
+    transfer(*New(name));
+    return true;
 }
 
 
@@ -1415,27 +1410,8 @@ bool Foam::MeshedSurface<Face>::read
     const word& fileType
 )
 {
-    if (fileType.empty())
-    {
-        // Handle empty/missing type
-
-        const word ext(name.ext());
-
-        if (ext.empty())
-        {
-            FatalErrorInFunction
-                << "Cannot determine format from filename" << nl
-                << "    " << name << nl
-                << exit(FatalError);
-        }
-
-        return read(name, ext);
-    }
-
-    clear();
-
-    // Read via selector mechanism
-    transfer(*(New(name, fileType)));
+    this->clear();
+    transfer(*New(name, fileType));
     return true;
 }
 
diff --git a/src/surfMesh/MeshedSurface/MeshedSurface.H b/src/surfMesh/MeshedSurface/MeshedSurface.H
index 0fbeb652e3d..c5df91f383b 100644
--- a/src/surfMesh/MeshedSurface/MeshedSurface.H
+++ b/src/surfMesh/MeshedSurface/MeshedSurface.H
@@ -338,6 +338,9 @@ public:
     // Selectors
 
         //- Read construct from filename with given file type
+        //
+        //  \note Use mandatory=false if support for the file type
+        //  is optional (the file still needs to exist!).
         static autoPtr<MeshedSurface> New
         (
             const fileName& name,
diff --git a/src/surfMesh/MeshedSurface/MeshedSurfaceNew.C b/src/surfMesh/MeshedSurface/MeshedSurfaceNew.C
index 5712c526a3a..d1dac5fa90e 100644
--- a/src/surfMesh/MeshedSurface/MeshedSurfaceNew.C
+++ b/src/surfMesh/MeshedSurface/MeshedSurfaceNew.C
@@ -30,7 +30,7 @@ License
 #include "UnsortedMeshedSurface.H"
 #include "ListOps.H"
 
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
 
 template<class Face>
 Foam::autoPtr<Foam::MeshedSurface<Face>>
@@ -41,6 +41,42 @@ Foam::MeshedSurface<Face>::New
     bool mandatory
 )
 {
+    const word ext(name.ext());
+
+    if (fileType.empty())
+    {
+        // Handle empty/missing type
+
+        if (ext.empty())
+        {
+            FatalErrorInFunction
+                << "Cannot determine format from filename" << nl
+                << "    " << name << nl
+                << exit(FatalError);
+        }
+
+        return New(name, ext, mandatory);
+    }
+    else if (fileType == "gz")
+    {
+        // Degenerate call
+        fileName unzipName(name.lessExt());
+        return New(unzipName, unzipName.ext(), mandatory);
+    }
+    else if (ext == "gz")
+    {
+        // Handle trailing "gz" on file name
+        return New(name.lessExt(), fileType, mandatory);
+    }
+
+    // if (check && !exists(name))
+    // {
+    //     FatalErrorInFunction
+    //         << "No such file " << name << nl
+    //         << exit(FatalError);
+    // }
+
+
     DebugInFunction
         << "Construct MeshedSurface (" << fileType << ")\n";
 
@@ -81,11 +117,15 @@ template<class Face>
 Foam::autoPtr<Foam::MeshedSurface<Face>>
 Foam::MeshedSurface<Face>::New(const fileName& name)
 {
-    word ext(name.ext());
+    const word ext(name.ext());
     if (ext == "gz")
     {
-        ext = name.lessExt().ext();
+        // Handle trailing "gz" on file name
+
+        fileName unzipName(name.lessExt());
+        return New(unzipName, unzipName.ext());
     }
+
     return New(name, ext);
 }
 
diff --git a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.C b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.C
index 42c8cc908b0..37b5216ccfc 100644
--- a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.C
+++ b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.C
@@ -732,6 +732,9 @@ void Foam::UnsortedMeshedSurface<Face>::transfer
 )
 {
     surfZoneList zoneInfo(surf.surfZones());
+
+    this->clear();
+
     MeshReference::transfer(surf);
 
     setZones(zoneInfo);
@@ -749,14 +752,9 @@ Foam::UnsortedMeshedSurface<Face>::releaseZoneIds()
 template<class Face>
 bool Foam::UnsortedMeshedSurface<Face>::read(const fileName& name)
 {
-    const word ext(name.ext());
-    if (ext == "gz")
-    {
-        fileName unzipName = name.lessExt();
-        return read(unzipName, unzipName.ext());
-    }
-
-    return read(name, ext);
+    this->clear();
+    transfer(*New(name));
+    return true;
 }
 
 
@@ -767,26 +765,7 @@ bool Foam::UnsortedMeshedSurface<Face>::read
     const word& fileType
 )
 {
-    if (fileType.empty())
-    {
-        // Handle empty/missing type
-
-        const word ext(name.ext());
-
-        if (ext.empty())
-        {
-            FatalErrorInFunction
-                << "Cannot determine format from filename" << nl
-                << "    " << name << nl
-                << exit(FatalError);
-        }
-
-        return read(name, ext);
-    }
-
-    clear();
-
-    // Read via selector mechanism
+    this->clear();
     transfer(*New(name, fileType));
     return true;
 }
diff --git a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.H b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.H
index 5637f835fdc..7834a4fb4fa 100644
--- a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.H
+++ b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.H
@@ -264,6 +264,9 @@ public:
     // Selectors
 
         //- Read construct from filename with given file type
+        //
+        //  \note Use mandatory=false if support for the file type
+        //  is optional (the file still needs to exist!).
         static autoPtr<UnsortedMeshedSurface> New
         (
             const fileName& name,
diff --git a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurfaceNew.C b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurfaceNew.C
index a2ff5b56ce3..d09be53b62b 100644
--- a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurfaceNew.C
+++ b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurfaceNew.C
@@ -29,7 +29,7 @@ License
 #include "UnsortedMeshedSurface.H"
 #include "ListOps.H"
 
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
 
 template<class Face>
 Foam::autoPtr<Foam::UnsortedMeshedSurface<Face>>
@@ -40,6 +40,41 @@ Foam::UnsortedMeshedSurface<Face>::New
     bool mandatory
 )
 {
+    const word ext(name.ext());
+
+    if (fileType.empty())
+    {
+        // Handle empty/missing type
+
+        if (ext.empty())
+        {
+            FatalErrorInFunction
+                << "Cannot determine format from filename" << nl
+                << "    " << name << nl
+                << exit(FatalError);
+        }
+
+        return New(name, ext, mandatory);
+    }
+    else if (fileType == "gz")
+    {
+        // Degenerate call
+        fileName unzipName(name.lessExt());
+        return New(unzipName, unzipName.ext(), mandatory);
+    }
+    else if (ext == "gz")
+    {
+        // Handle trailing "gz" on file name
+        return New(name.lessExt(), fileType, mandatory);
+    }
+
+    // if (check && !exists(name))
+    // {
+    //     FatalErrorInFunction
+    //         << "No such file " << name << nl
+    //         << exit(FatalError);
+    // }
+
     DebugInFunction
         << "Construct UnsortedMeshedSurface (" << fileType << ")\n";
 
@@ -80,10 +115,13 @@ template<class Face>
 Foam::autoPtr<Foam::UnsortedMeshedSurface<Face>>
 Foam::UnsortedMeshedSurface<Face>::New(const fileName& name)
 {
-    word ext(name.ext());
+    const word ext(name.ext());
     if (ext == "gz")
     {
-        ext = name.lessExt().ext();
+        // Handle trailing "gz" on file name
+
+        fileName unzipName(name.lessExt());
+        return New(unzipName, unzipName.ext());
     }
 
     return New(name, ext);
diff --git a/src/surfMesh/triSurface/triSurface.C b/src/surfMesh/triSurface/triSurface.C
index 9b126732c71..51e2b52e1b2 100644
--- a/src/surfMesh/triSurface/triSurface.C
+++ b/src/surfMesh/triSurface/triSurface.C
@@ -40,6 +40,34 @@ namespace Foam
 }
 
 
+// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Helper function to print triangle info
+static void printTriangle
+(
+    Ostream& os,
+    const string& pre,
+    const labelledTri& f,
+    const pointField& points
+)
+{
+    os
+        << pre.c_str() << "vertex numbers:"
+        << f[0] << ' ' << f[1] << ' ' << f[2] << nl
+
+        << pre.c_str() << "vertex coords :"
+        << points[f[0]] << ' ' << points[f[1]] << ' ' << points[f[2]]
+
+        << pre.c_str() << "region        :" << f.region() << nl
+        << endl;
+}
+
+} // End namespace Foam
+
+
 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
 
 Foam::fileName Foam::triSurface::triSurfInstance(const Time& d)
diff --git a/src/surfMesh/triSurface/triSurface.H b/src/surfMesh/triSurface/triSurface.H
index d75ab32c836..c87a3525a0d 100644
--- a/src/surfMesh/triSurface/triSurface.H
+++ b/src/surfMesh/triSurface/triSurface.H
@@ -127,7 +127,10 @@ class triSurface
         );
 
         //- Read in OpenFOAM format
-        bool read(Istream& is);
+        bool readNative(Istream& is);
+
+        //- Write in OpenFOAM format
+        void writeNative(Ostream& os) const;
 
         //- Read in STL format
         bool readSTL(const fileName& filename, bool forceBinary=false);
@@ -168,15 +171,6 @@ class triSurface
             const label defaultRegion = 0
         );
 
-        //- Helper function to print triangle info
-        static void printTriangle
-        (
-            Ostream& os,
-            const string& pre,
-            const labelledTri& f,
-            const pointField& points
-        );
-
         //- Return a new surface using specified pointMap and faceMap
         //
         //  \param[in] pointMap from subsetMeshMap
@@ -373,6 +367,19 @@ public:
         );
 
 
+    // Selectors
+
+        //- Read construct from filename with given file type
+        static autoPtr<triSurface> New
+        (
+            const fileName& name,
+            const word& fileType
+        );
+
+        //- Read construct from filename (file type implicit from extension)
+        static autoPtr<triSurface> New(const fileName& name);
+
+
     //- Destructor
     virtual ~triSurface();
 
@@ -563,7 +570,7 @@ public:
 
     // Write
 
-        //- Write to Ostream in simple FOAM format
+        //- Write to Ostream in simple OpenFOAM format
         void write(Ostream& os) const;
 
         //- Generic write routine (uses extension to determine type).
@@ -601,8 +608,8 @@ public:
 
     // IOstream Operators
 
-        friend Istream& operator>>(Istream&, triSurface&);
-        friend Ostream& operator<<(Ostream&, const triSurface&);
+        friend Istream& operator>>(Istream& is, triSurface& s);
+        friend Ostream& operator<<(Ostream& os, const triSurface& s);
 };
 
 
diff --git a/src/surfMesh/triSurface/triSurfaceIO.C b/src/surfMesh/triSurface/triSurfaceIO.C
index 47e77b9f877..f3158231954 100644
--- a/src/surfMesh/triSurface/triSurfaceIO.C
+++ b/src/surfMesh/triSurface/triSurfaceIO.C
@@ -162,30 +162,24 @@ Foam::fileName Foam::triSurface::findFile
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-void Foam::triSurface::printTriangle
-(
-    Ostream& os,
-    const string& pre,
-    const labelledTri& f,
-    const pointField& points
-)
+bool Foam::triSurface::readNative(Istream& is)
 {
-    os
-        << pre.c_str() << "vertex numbers:"
-        << f[0] << ' ' << f[1] << ' ' << f[2] << endl
-        << pre.c_str() << "vertex coords :"
-        << points[f[0]] << ' ' << points[f[1]] << ' ' << points[f[2]]
-        << pre.c_str() << "region        :" << f.region() << endl
-        << endl;
+    // Read triangles, points from Istream
+    is  >> patches_ >> storedPoints() >> storedFaces();
+
+    return true;
 }
 
 
-bool Foam::triSurface::read(Istream& is)
+void Foam::triSurface::writeNative(Ostream& os) const
 {
-    // Read triangles, points from Istream
-    is  >> patches_ >> storedPoints() >> storedFaces();
+    os  << patches() << nl;
 
-    return true;
+    //Note: Write with global point numbering
+    os  << points() << nl
+        << static_cast<const List<labelledTri>&>(*this) << nl;
+
+    os.check(FUNCTION_NAME);
 }
 
 
@@ -199,79 +193,13 @@ bool Foam::triSurface::read
     if (check && !exists(name))
     {
         FatalErrorInFunction
-            << "Cannnot read " << name << nl
+            << "No such file " << name << nl
             << exit(FatalError);
     }
 
-    if (fileType.empty())
-    {
-        // Handle empty/missing type
-
-        const word ext(name.ext());
-
-        if (ext.empty())
-        {
-            FatalErrorInFunction
-                << "Cannot determine format from filename" << nl
-                << "    " << name << nl
-                << exit(FatalError);
-        }
-
-        return read(name, ext, false);
-    }
-
-
-    if (fileType == "gz")
-    {
-        fileName unzipName = name.lessExt();
-
-        // Do not check for existence. Let IFstream do the unzipping.
-        return read(unzipName, unzipName.ext(), false);
-    }
-
-    // Hard-coded readers
-    if (fileType == "ftr")
-    {
-        return read(IFstream(name)());
-    }
-    else if (fileType == "stl")
-    {
-        return readSTL(name);  // ASCII
-    }
-    else if (fileType == "stlb")
-    {
-        return readSTL(name, true); // Force BINARY
-    }
-
-    // UnsortedMeshedSurface
-    {
-        using proxyType = UnsortedMeshedSurface<labelledTri>;
-        if (proxyType::readTypes().found(fileType))
-        {
-            transfer(*(proxyType::New(name, fileType)));
-            return true;
-        }
-    }
-
-    // MeshedSurface
-    {
-        using proxyType = MeshedSurface<labelledTri>;
-        if (proxyType::readTypes().found(fileType))
-        {
-            transfer(*(proxyType::New(name, fileType)));
-            return true;
-        }
-    }
-
-
-    FatalErrorInFunction
-        << "Unknown surface format " << fileType
-        << " for reading file " << name << nl
-        << "Valid types:" << nl
-        << "    " << flatOutput(readTypes().sortedToc()) << nl
-        << exit(FatalError);
-
-    return false;
+    this->clear();
+    transfer(*New(name, fileType));
+    return true;
 }
 
 
@@ -301,12 +229,12 @@ void Foam::triSurface::write
     }
 
 
-    // Hard-coded readers
+    // Hard-coded writers
 
     if (fileType == "ftr")
     {
         OFstream os(name);
-        write(os);
+        writeNative(os);
     }
     else if (fileType == "stl")
     {
@@ -353,7 +281,7 @@ Foam::triSurface::triSurface(Istream& is)
 :
     triSurface()
 {
-    read(is);
+    readNative(is);
 
     setDefaultPatches();
 }
@@ -368,7 +296,7 @@ Foam::triSurface::triSurface(const Time& d)
         d.path()/triSurfInstance(d)/typeName/(d.caseName() + ".ftr")
     );
 
-    read(is);
+    readNative(is);
 
     setDefaultPatches();
 }
@@ -407,13 +335,7 @@ void Foam::triSurface::write
 
 void Foam::triSurface::write(Ostream& os) const
 {
-    os  << patches() << nl;
-
-    //Note: Write with global point numbering
-    os  << points() << nl
-        << static_cast<const List<labelledTri>&>(*this) << nl;
-
-    os.check(FUNCTION_NAME);
+    writeNative(os);
 }
 
 
@@ -424,7 +346,7 @@ void Foam::triSurface::write(const Time& d) const
         d.path()/triSurfInstance(d)/typeName/(d.caseName() + ".ftr")
     );
 
-    write(os);
+    writeNative(os);
 }
 
 
@@ -460,18 +382,18 @@ void Foam::triSurface::writeStats(Ostream& os) const
 
 // * * * * * * * * * * * * * * * IOstream Operators  * * * * * * * * * * * * //
 
-Foam::Istream& Foam::operator>>(Istream& is, triSurface& sm)
+Foam::Istream& Foam::operator>>(Istream& is, triSurface& s)
 {
-    sm.clearOut();
-    sm.read(is);
-    sm.setDefaultPatches();
+    s.clearOut();
+    s.readNative(is);
+    s.setDefaultPatches();
     return is;
 }
 
 
-Foam::Ostream& Foam::operator<<(Ostream& os, const triSurface& sm)
+Foam::Ostream& Foam::operator<<(Ostream& os, const triSurface& s)
 {
-    sm.write(os);
+    s.writeNative(os);
     return os;
 }
 
diff --git a/src/surfMesh/triSurface/triSurfaceNew.C b/src/surfMesh/triSurface/triSurfaceNew.C
new file mode 100644
index 00000000000..ffb7f94fb82
--- /dev/null
+++ b/src/surfMesh/triSurface/triSurfaceNew.C
@@ -0,0 +1,156 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2020 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+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 "triSurface.H"
+#include "Fstream.H"
+#include "MeshedSurface.H"
+#include "UnsortedMeshedSurface.H"
+
+// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
+
+Foam::autoPtr<Foam::triSurface>
+Foam::triSurface::New
+(
+    const fileName& name,
+    const word& fileType
+)
+{
+    const word ext(name.ext());
+
+    if (fileType.empty())
+    {
+        // Handle empty/missing type
+
+        if (ext.empty())
+        {
+            FatalErrorInFunction
+                << "Cannot determine format from filename" << nl
+                << "    " << name << nl
+                << exit(FatalError);
+        }
+
+        return New(name, ext);
+    }
+    else if (fileType == "gz")
+    {
+        // Degenerate call
+        fileName unzipName(name.lessExt());
+        return New(unzipName, unzipName.ext());
+    }
+    else if (ext == "gz")
+    {
+        // Handle trailing "gz" on file name
+        return New(name.lessExt(), fileType);
+    }
+
+    // if (check && !exists(name))
+    // {
+    //     FatalErrorInFunction
+    //         << "No such file " << name << nl
+    //         << exit(FatalError);
+    // }
+
+
+    // Hard-coded readers
+    if (fileType == "ftr")
+    {
+        auto surf = autoPtr<triSurface>::New();
+
+        IFstream is(name);
+        surf->readNative(is);
+        return surf;
+    }
+    else if (fileType == "stl")
+    {
+        auto surf = autoPtr<triSurface>::New();
+
+        surf->readSTL(name);  // ASCII
+        return surf;
+    }
+    else if (fileType == "stlb")
+    {
+        auto surf = autoPtr<triSurface>::New();
+
+        surf->readSTL(name, true); // Force BINARY
+        return surf;
+    }
+
+    {
+        // UnsortedMeshedSurface
+        using proxyType = UnsortedMeshedSurface<labelledTri>;
+        if (proxyType::readTypes().found(fileType))
+        {
+            auto surf = autoPtr<triSurface>::New();
+
+            surf->transfer(*proxyType::New(name, fileType));
+            return surf;
+        }
+    }
+
+    // MeshedSurface
+    {
+        using proxyType = MeshedSurface<labelledTri>;
+        if (proxyType::readTypes().found(fileType))
+        {
+            auto surf = autoPtr<triSurface>::New();
+
+            surf->transfer(*proxyType::New(name, fileType));
+            return surf;
+        }
+    }
+
+    {
+        FatalErrorInFunction
+            << "Unknown surface format " << fileType
+            << " for reading file " << name << nl
+            << "Valid types:" << nl
+            << "    " << flatOutput(readTypes().sortedToc()) << nl
+            << exit(FatalError);
+    }
+
+    // Failed
+    return nullptr;
+}
+
+
+Foam::autoPtr<Foam::triSurface>
+Foam::triSurface::New(const fileName& name)
+{
+    const word ext(name.ext());
+    if (ext == "gz")
+    {
+        // Handle trailing "gz" on file name
+
+        fileName unzipName(name.lessExt());
+        return New(unzipName, unzipName.ext());
+    }
+
+    return New(name, ext);
+}
+
+
+// ************************************************************************* //
-- 
GitLab