From 0af1e0b7228cf6a5e160ea4f519861f6867300d7 Mon Sep 17 00:00:00 2001 From: Mark Olesen <Mark.Olesen@esi-group.com> Date: Mon, 12 Jun 2017 15:47:01 +0200 Subject: [PATCH] BUG: minor regression. STL reading in double, not float (issue #491) - By definition, binary STL uses float (not double) when reading. The ascii STL should be the same. This reduces memory overhead when loading files. The older triSurface reader had float, the surfMesh reader had double, but now has float. - Inconsistency in the STL merge-tolerances between triSurface reader, surfMesh reader and WM_SP vs WM_DP. Now use consistent tolerances conrresponding to 10,100 * doubleSMALL. - Similar float/double code adjustments for TRI format since this is very similar to the STL reader and had a similar inconsistency between the triSurface and surfMesh version. The AC3D reader still uses double when reading, but this can be revisited in the future (and can then remove the stichTriangles method too). --- src/fileFormats/stl/STLReader.C | 35 +++++++++++++ src/fileFormats/stl/STLReader.H | 13 ++++- src/fileFormats/stl/STLReaderASCII.L | 4 +- .../surfaceFormats/stl/STLsurfaceFormat.C | 40 +++++++++++---- .../surfaceFormats/tri/TRIsurfaceFormat.C | 39 +++++++++++---- .../surfaceFormats/tri/TRIsurfaceFormatCore.C | 50 +++++++++++++++++-- .../surfaceFormats/tri/TRIsurfaceFormatCore.H | 38 +++++++------- .../triSurface/interfaces/STL/readSTL.C | 28 +++-------- 8 files changed, 182 insertions(+), 65 deletions(-) diff --git a/src/fileFormats/stl/STLReader.C b/src/fileFormats/stl/STLReader.C index b7b91a0bb75..ca7451d886a 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 9ed6838bc13..e9873aafe74 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 1e60c2a241e..46c9ab1a853 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 f9e335c39eb..a746232d18a 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 cb2aa80823b..b36c5fd321d 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 87cc04d20ec..8f473d11203 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 12ce08e3725..5d4b76fd6e0 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 43c9453a524..70b1e9f4445 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; -- GitLab