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
This commit is contained in:
Mark Olesen
2020-04-08 09:17:12 +02:00
parent 0eed8fa829
commit 5f90964dee
11 changed files with 336 additions and 183 deletions

View File

@ -51,6 +51,7 @@ $(surfaceFormats)/x3d/X3DsurfaceFormatRunTime.C
triSurface/triSurface.C
triSurface/triSurfaceIO.C
triSurface/triSurfaceNew.C
triSurface/triSurfaceAddressing.C
triSurface/triSurfaceStitch.C

View File

@ -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;
}

View File

@ -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,

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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,

View File

@ -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);

View File

@ -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)

View File

@ -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);
};

View File

@ -162,25 +162,7 @@ Foam::fileName Foam::triSurface::findFile
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::triSurface::printTriangle
(
Ostream& os,
const string& pre,
const labelledTri& f,
const pointField& points
)
{
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;
}
bool Foam::triSurface::read(Istream& is)
bool Foam::triSurface::readNative(Istream& is)
{
// Read triangles, points from Istream
is >> patches_ >> storedPoints() >> storedFaces();
@ -189,6 +171,18 @@ bool Foam::triSurface::read(Istream& is)
}
void Foam::triSurface::writeNative(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);
}
bool Foam::triSurface::read
(
const fileName& name,
@ -199,80 +193,14 @@ 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)));
this->clear();
transfer(*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;
}
void Foam::triSurface::write
@ -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;
}

View File

@ -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);
}
// ************************************************************************* //