Commit cfd88730 authored by Mark Olesen's avatar Mark Olesen
Browse files

ENH: keep element ids when reading/writing meshed surfaces (#1600)

parent 560c053b
......@@ -118,7 +118,7 @@ inline static IOobject selectReadIO(const word& name, const Time& runTime)
void Foam::sampledMeshedSurface::setZoneMap()
{
// Ensure zoneIds_ are correctly populated
// Populate zoneIds_ based on surfZone information
const meshedSurface& s = static_cast<const meshedSurface&>(*this);
......@@ -279,19 +279,10 @@ bool Foam::sampledMeshedSurface::update(const meshSearch& meshSearcher)
s = surface_.subsetMesh(facesToSubset, pointMap, faceMap);
// Ensure zoneIds_ are indeed correct
setZoneMap();
// This is currently only partially useful
if (keepIds_)
{
originalIds_ = faceMap;
}
else
{
originalIds_.clear();
}
// Subset cellOrFaceLabels (for compact faces)
cellOrFaceLabels = labelUIndList(cellOrFaceLabels, faceMap)();
......@@ -492,8 +483,7 @@ Foam::sampledMeshedSurface::sampledMeshedSurface
),
sampleSource_(sampleSource),
needsUpdate_(true),
keepIds_(false),
originalIds_(),
keepIds_(true),
zoneIds_(),
sampleElements_(),
samplePoints_()
......@@ -524,8 +514,7 @@ Foam::sampledMeshedSurface::sampledMeshedSurface
),
sampleSource_(samplingSourceNames_.get("source", dict)),
needsUpdate_(true),
keepIds_(dict.lookupOrDefault("keepIds", false)),
originalIds_(),
keepIds_(dict.getOrDefault("keepIds", true)),
zoneIds_(),
sampleElements_(),
samplePoints_()
......@@ -610,7 +599,6 @@ bool Foam::sampledMeshedSurface::expire()
MeshStorage::clear();
zoneIds_.clear();
originalIds_.clear();
sampleElements_.clear();
samplePoints_.clear();
......
......@@ -86,7 +86,7 @@ Usage
surface | surface name in triSurface/ | yes |
patches | Limit to named surface regions (wordRes) | no |
source | cells/insideCells/boundaryFaces | yes |
keepIds | pass through id numbering | no | false
keepIds | pass through id numbering | no | true
file | Alternative file name | no |
fileType | The surface format | no | (extension)
scale | Surface scaling factor | no | 0
......@@ -156,10 +156,6 @@ private:
//- Retain element ids/order of original surface
bool keepIds_;
//- List of element ids/order of the original surface,
//- when keepIds is active.
labelList originalIds_;
//- For compatibility with the meshSurf interface
labelList zoneIds_;
......@@ -258,6 +254,12 @@ public:
return zoneIds_;
}
//- Per-face identifier (eg, element Id)
virtual const labelList& faceIds() const
{
return MeshStorage::faceIds();
}
//- Face area vectors
virtual const vectorField& Sf() const
{
......@@ -279,14 +281,7 @@ public:
//- If element ids/order of the original surface are kept
virtual bool hasFaceIds() const
{
return keepIds_;
}
//- List of element ids/order of the original surface,
// when keepIds is active.
virtual const labelList& originalIds() const
{
return originalIds_;
return keepIds_ && !MeshStorage::faceIds().empty();
}
//- Sampling boundary values instead of cell values
......
......@@ -340,13 +340,6 @@ public:
return false;
}
//- List of element ids/order of the original surface,
//- when hasFaceIds is true.
virtual const labelList& originalIds() const
{
return labelList::null();
}
// General registry storage (optional)
......
......@@ -558,10 +558,15 @@ bool Foam::sampledSurfaces::performAction(unsigned request)
// Write original ids
if (s.hasFaceIds() && !s.interpolate())
{
// This is still quite horrible.
Field<label> ids(s.faceIds());
ids += label(1); // From 0-based to 1-based
writeSurface
(
outWriter,
Field<label>(s.originalIds()),
ids,
"Ids"
);
}
......
......@@ -69,7 +69,7 @@ Description
}
surfaces
(
{
f0surf
{
type meshedSurface;
......@@ -88,7 +88,7 @@ Description
// Optional: registry storage
store true
}
);
}
}
\endverbatim
......
......@@ -183,6 +183,7 @@ template<class Face>
Foam::MeshedSurface<Face>::MeshedSurface()
:
MeshReference(List<Face>(), pointField()),
faceIds_(),
zones_()
{}
......@@ -194,6 +195,7 @@ Foam::MeshedSurface<Face>::MeshedSurface
)
:
MeshReference(surf.surfFaces(), surf.points()),
faceIds_(surf.faceIds_),
zones_(surf.zones_)
{}
......@@ -204,20 +206,40 @@ Foam::MeshedSurface<Face>::MeshedSurface
const UnsortedMeshedSurface<Face>& surf
)
:
MeshReference(List<Face>(), surf.points()) // Copy points only
MeshReference(List<Face>(), surf.points()), // Copy points only
faceIds_(),
zones_()
{
labelList faceMap;
this->storedZones() = surf.sortedZones(faceMap);
// Faces, in the sorted order
const List<Face>& origFaces = surf;
List<Face> newFaces(origFaces.size());
forAll(newFaces, facei)
{
newFaces[faceMap[facei]] = origFaces[facei];
List<Face> newFaces(origFaces.size());
forAll(newFaces, facei)
{
newFaces[faceMap[facei]] = origFaces[facei];
}
this->storedFaces().transfer(newFaces);
}
this->storedFaces().transfer(newFaces);
// FaceIds, in the sorted order
const labelList& origIds = surf.faceIds();
if (origIds.size() == origFaces.size())
{
labelList newFaceIds(origIds.size());
forAll(newFaceIds, facei)
{
newFaceIds[faceMap[facei]] = origIds[facei];
}
this->storedFaceIds().transfer(newFaceIds);
}
}
......@@ -254,6 +276,7 @@ Foam::MeshedSurface<Face>::MeshedSurface
)
:
MeshReference(faceLst, pointLst), // Copy construct
faceIds_(),
zones_(zoneLst)
{}
......@@ -267,6 +290,7 @@ Foam::MeshedSurface<Face>::MeshedSurface
)
:
MeshReference(faceLst, pointLst, true), // Move construct
faceIds_(),
zones_(zoneLst)
{}
......@@ -281,6 +305,7 @@ Foam::MeshedSurface<Face>::MeshedSurface
)
:
MeshReference(faceLst, pointLst), // Copy construct
faceIds_(),
zones_()
{
if (zoneSizes.size())
......@@ -307,6 +332,7 @@ Foam::MeshedSurface<Face>::MeshedSurface
)
:
MeshReference(faceLst, pointLst, true), // Move construct
faceIds_(),
zones_()
{
if (zoneSizes.size())
......@@ -571,6 +597,7 @@ void Foam::MeshedSurface<Face>::clear()
storedPoints().clear();
storedFaces().clear();
storedFaceIds().clear();
storedZones().clear();
}
......@@ -690,6 +717,17 @@ bool Foam::MeshedSurface<Face>::stitchFaces
faceMap.resize(newFacei);
faceLst.resize(newFacei);
// The faceMap is a newToOld mapping and only removes elements
if (faceIds_.size())
{
forAll(faceMap, facei)
{
faceIds_[facei] = faceIds_[faceMap[facei]];
}
faceIds_.resize(newFacei);
}
remapFaces(faceMap);
}
faceMap.clear();
......@@ -849,6 +887,17 @@ bool Foam::MeshedSurface<Face>::checkFaces
faceMap.resize(newFacei);
faceLst.resize(newFacei);
// The faceMap is a newToOld mapping and only removes elements
if (faceIds_.size())
{
forAll(faceMap, facei)
{
faceIds_[facei] = faceIds_[faceMap[facei]];
}
faceIds_.resize(newFacei);
}
remapFaces(faceMap);
}
faceMap.clear();
......@@ -979,6 +1028,8 @@ Foam::label Foam::MeshedSurface<Face>::triangulate
return 0;
}
this->storedFaceIds().clear(); // Invalid or misleading
List<Face> newFaces(nTri);
List<label> faceMap;
......@@ -1118,11 +1169,20 @@ Foam::MeshedSurface<Face>::subsetMeshImpl
zone.size() = newFacei - zone.start();
}
// Subset of faceIds. Can be empty.
labelList newFaceIds;
if (faceIds_.size())
{
newFaceIds = labelUIndList(faceIds_, faceMap);
}
// Construct the sub-surface
MeshedSurface<Face> newSurf;
newSurf.storedFaces().transfer(newFaces);
newSurf.storedPoints().transfer(newPoints);
newSurf.storedZones().transfer(newZones);
newSurf.storedFaceIds().transfer(newFaceIds);
return newSurf;
}
......@@ -1224,6 +1284,7 @@ void Foam::MeshedSurface<Face>::swap
this->storedPoints().swap(surf.storedPoints());
this->storedFaces().swap(surf.storedFaces());
this->storedZones().swap(surf.storedZones());
this->storedFaceIds().swap(surf.storedFaceIds());
}
......@@ -1239,6 +1300,7 @@ void Foam::MeshedSurface<Face>::transfer
this->storedPoints().transfer(pointLst);
this->storedFaces().transfer(faceLst);
this->storedZones().clear();
this->storedFaceIds().clear(); // Likely to be invalid
}
......@@ -1258,6 +1320,7 @@ void Foam::MeshedSurface<Face>::transfer
this->storedPoints().transfer(surf.storedPoints());
this->storedFaces().transfer(surf.storedFaces());
this->storedZones().transfer(surf.storedZones());
this->storedFaceIds().transfer(surf.storedFaceIds());
surf.clear();
}
......@@ -1316,6 +1379,8 @@ void Foam::MeshedSurface<Face>::swapFaces(List<Face>& faces)
{
MeshReference::clearOut(); // Topology changes
this->storedFaceIds().clear(); // Likely to be invalid
this->storedFaces().swap(faces);
}
......@@ -1401,6 +1466,7 @@ void Foam::MeshedSurface<Face>::operator=(const MeshedSurface<Face>& surf)
this->storedPoints() = surf.points();
this->storedFaces() = surf.surfFaces();
this->storedFaceIds() = surf.faceIds();
this->storedZones() = surf.surfZones();
}
......@@ -1419,7 +1485,9 @@ Foam::MeshedSurface<Face>::operator Foam::MeshedSurfaceProxy<Face>() const
(
this->points(),
this->surfFaces(),
this->surfZones()
this->surfZones(),
labelUList::null(), // faceMap = none
this->faceIds()
);
}
......
......@@ -115,6 +115,11 @@ private:
// Private Data
//- Face ids.
// If these exist, they are typically arise from reading a mesh
// format from another CAE software (eg, NASTRAN, STARCD, ...)
labelList faceIds_;
//- Zone information
// (face ordering nFaces/startFace only used during reading/writing)
surfZoneList zones_;
......@@ -164,6 +169,12 @@ protected:
return static_cast<List<Face>&>(*this);
}
//- Non-const access to face ids
labelList& storedFaceIds()
{
return faceIds_;
}
//- Non-const access to the zones
surfZoneList& storedZones()
{
......@@ -175,6 +186,7 @@ protected:
(
DynamicList<Face>& unsortedFaces,
DynamicList<label>& zoneIds,
DynamicList<label>& elemIds,
bool sorted
);
......@@ -394,6 +406,14 @@ public:
return static_cast<const List<Face>&>(*this);
}
//- Return const access to faces ids
// If these exist, they are typically arise from reading a mesh
// format from another CAE software (eg, NASTRAN, STARCD, ...)
const labelList& faceIds() const
{
return faceIds_;
}
//- Const access to the surface zones.
// If zones are defined, they must be contiguous and cover the
// entire surface
......
......@@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016 OpenCFD Ltd.
Copyright (C) 2016-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -52,9 +52,11 @@ namespace Foam
MeshedSurface<face>& surf
)
{
// First triangulate
// - slightly wasteful for space, but adjusts the zones too!
// First triangulate.
// Potentially wasteful of space, but adjusts zones and
// invalidates the faceIds
surf.triangulate();
this->storedPoints().transfer(surf.storedPoints());
this->storedZones().transfer(surf.storedZones());
......@@ -83,9 +85,11 @@ namespace Foam
MeshedSurface<face>& surf
)
{
// First triangulate
// - slightly wasteful for space, but adjusts the zones too!
// First triangulate.
// Potentially wasteful of space, but adjusts zones and
// invalidates the faceIds
surf.triangulate();
this->storedPoints().transfer(surf.storedPoints());
this->storedZones().transfer(surf.storedZones());
......
......@@ -71,6 +71,7 @@ void Foam::MeshedSurface<Face>::sortFacesAndStore
(
DynamicList<Face>& unsortedFaces,
DynamicList<label>& zoneIds,
DynamicList<label>& elemIds,
bool sorted
)
{
......@@ -84,10 +85,16 @@ void Foam::MeshedSurface<Face>::sortFacesAndStore
sorted = true;
}
if (elemIds.size() != nInputFaces)
{
elemIds.clear();
}
if (sorted)
{
// No additional sorting required
this->storedFaces().transfer(unsortedFaces);
this->storedFaceIds().transfer(elemIds);
return;
}
......@@ -106,6 +113,15 @@ void Foam::MeshedSurface<Face>::sortFacesAndStore
// Can use transfer, faceMap is unique
newFaces[facei].transfer(unsortedFaces[faceMap[facei]]);
}
auto& newFaceIds = this->storedFaceIds();
newFaceIds.resize(elemIds.size());
// Element ids in sorted order
forAll(newFaceIds, facei)
{
newFaceIds[facei] = elemIds[faceMap[facei]];
}
}
......
......@@ -238,13 +238,15 @@ Foam::MeshedSurfaceProxy<Face>::MeshedSurfaceProxy
const pointField& pointLst,
const UList<Face>& faceLst,
const UList<surfZone>& zoneLst,
const labelUList& faceMap
const labelUList& faceMap,
const labelUList& faceIdsLst
)
:
points_(pointLst),
faces_(faceLst),
zones_(zoneLst),
faceMap_(faceMap)
faceMap_(faceMap),
faceIds_(faceIdsLst)
{}
......
......@@ -31,6 +31,9 @@ Description
A proxy for writing MeshedSurface, UnsortedMeshedSurface and surfMesh
to various file formats.
The constructor interface is fat and ugly, but is largely encapsulated
by conversion operators in other classes.
SourceFiles
MeshedSurfaceProxy.C
MeshedSurfaceProxys.C
......@@ -73,6 +76,9 @@ class MeshedSurfaceProxy
const UList<label>& faceMap_;
const UList<label>& faceIds_;
public:
// Public Typedefs
......@@ -104,8 +110,9 @@ public:
(
const pointField& pointLst,
const UList<Face>& faceLst,
const UList<surfZone>& zoneLst = List<surfZone>(),
const labelUList& faceMap = labelUList::null()
const UList<surfZone>& zoneLst = UList<surfZone>::null(),
const labelUList& faceMap = labelUList::null(),
const labelUList& faceIdLst = labelUList::null()
);
......@@ -187,12 +194,24 @@ public:
return faceMap_;
}
//- Const access to the faceIds, zero-sized when unused
const labelUList& faceIds() const
{
return faceIds_;
}
//- Can/should use faceMap?
bool useFaceMap() const
{
return faceMap_.size() == faces_.size();
}
//- Possible to use faceIds?
bool useFaceIds() const
{
return faceIds_.size() == faces_.size();
}
//- Count number of triangles.
inline label nTriangles() const;
......
......@@ -61,6 +61,7 @@ Foam::mergedSurf::mergedSurf
const pointField& unmergedPoints,
const faceList& unmergedFaces,
const labelList& origZoneIds,
const labelList& origFaceIds,
const scalar mergeDim
)
:
......@@ -71,6 +72,7 @@ Foam::mergedSurf::mergedSurf
unmergedPoints,
unmergedFaces,
origZoneIds,
origFaceIds,
mergeDim
);
}
......@@ -91,6 +93,7 @@ void Foam::mergedSurf::clear()
pointsMap_.clear();
zoneIds_.clear();
faceIds_.clear();
}
......@@ -106,6 +109,7 @@ bool Foam::mergedSurf::merge
unmergedSurface.points(),
unmergedSurface.faces(),
unmergedSurface.zoneIds(),
unmergedSurface.faceIds(),
mergeDim
);
}
......@@ -124,6 +128,7 @@ bool Foam::mergedSurf::merge
unmergedPoints,
unmergedFaces,
labelList(),
labelList(),
mergeDim
);
}
......@@ -134,6 +139,7 @@ bool Foam::mergedSurf::merge
const pointField& unmergedPoints,
const faceList& unmergedFaces,
const labelList& origZoneIds,
const labelList& origFaceIds,
const scalar mergeDim
)
{
......@@ -160,6 +166,7 @@ bool Foam::mergedSurf::merge
// Now handle per-face information
globalIndex::gatherOp(origZoneIds, zoneIds_);
globalIndex::gatherOp(origFaceIds, faceIds_);
return true;