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