mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
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).
This commit is contained in:
@ -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;
|
||||
|
||||
Reference in New Issue
Block a user