Commit 0af1e0b7 authored by Mark OLESEN's avatar Mark OLESEN
Browse files

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).
parent bf88d4ec
......@@ -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
);
}
// ************************************************************************* //
......@@ -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_;
}
......
......@@ -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_;
}
......
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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
);
}
// ************************************************************************* //
......@@ -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_;
}
......
......@@ -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;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment