mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: keep element ids when reading/writing meshed surfaces (#1600)
This commit is contained in:
@ -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;
|
||||
}
|
||||
|
||||
@ -96,6 +96,7 @@ public:
|
||||
const pointField& unmergedPoints,
|
||||
const faceList& unmergedFaces,
|
||||
const labelList& origZoneIds,
|
||||
const labelList& origFaceIds,
|
||||
const scalar mergeDim
|
||||
);
|
||||
|
||||
@ -133,6 +134,12 @@ public:
|
||||
return zoneIds_;
|
||||
}
|
||||
|
||||
//- Per-face identifier (eg, element Id)
|
||||
virtual const labelList& faceIds() const
|
||||
{
|
||||
return faceIds_;
|
||||
}
|
||||
|
||||
//- Map for reordered points (old-to-new)
|
||||
const labelList& pointsMap() const
|
||||
{
|
||||
@ -166,6 +173,7 @@ public:
|
||||
const pointField& unmergedPoints,
|
||||
const faceList& unmergedFaces,
|
||||
const labelList& origZoneIds,
|
||||
const labelList& origFaceIds,
|
||||
const scalar mergeDim
|
||||
);
|
||||
|
||||
|
||||
@ -79,6 +79,12 @@ public:
|
||||
{
|
||||
return labelList::null();
|
||||
}
|
||||
|
||||
//- Per-face identifier (eg, element Id)
|
||||
virtual const labelList& faceIds() const
|
||||
{
|
||||
return labelList::null();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -53,6 +53,7 @@ class meshedSurfRef
|
||||
std::reference_wrapper<const pointField> points_;
|
||||
std::reference_wrapper<const faceList> faces_;
|
||||
std::reference_wrapper<const labelList> zoneIds_;
|
||||
std::reference_wrapper<const labelList> faceIds_;
|
||||
|
||||
|
||||
public:
|
||||
@ -64,7 +65,8 @@ public:
|
||||
:
|
||||
points_(std::cref<pointField>(pointField::null())),
|
||||
faces_(std::cref<faceList>(faceList::null())),
|
||||
zoneIds_(std::cref<labelList>(labelList::null()))
|
||||
zoneIds_(std::cref<labelList>(labelList::null())),
|
||||
faceIds_(std::cref<labelList>(labelList::null()))
|
||||
{}
|
||||
|
||||
|
||||
@ -73,12 +75,14 @@ public:
|
||||
(
|
||||
const pointField& pointLst,
|
||||
const faceList& faceLst,
|
||||
const labelList& zoneIdLst = labelList::null()
|
||||
const labelList& zoneIdLst = labelList::null(),
|
||||
const labelList& faceIdLst = labelList::null()
|
||||
)
|
||||
:
|
||||
points_(std::cref<pointField>(pointLst)),
|
||||
faces_(std::cref<faceList>(faceLst)),
|
||||
zoneIds_(std::cref<labelList>(zoneIdLst))
|
||||
zoneIds_(std::cref<labelList>(zoneIdLst)),
|
||||
faceIds_(std::cref<labelList>(faceIdLst))
|
||||
{}
|
||||
|
||||
|
||||
@ -106,12 +110,19 @@ public:
|
||||
return zoneIds_.get();
|
||||
}
|
||||
|
||||
//- Per-face identifier (eg, element Id)
|
||||
virtual const labelList& faceIds() const
|
||||
{
|
||||
return faceIds_.get();
|
||||
}
|
||||
|
||||
//- Remove all references by redirecting to null objects
|
||||
void clear()
|
||||
{
|
||||
points_ = std::cref<pointField>(pointField::null());
|
||||
faces_ = std::cref<faceList>(faceList::null());
|
||||
zoneIds_ = std::cref<labelList>(labelList::null());
|
||||
faceIds_ = std::cref<labelList>(labelList::null());
|
||||
}
|
||||
|
||||
//- Reset components
|
||||
@ -119,12 +130,14 @@ public:
|
||||
(
|
||||
const pointField& pointLst,
|
||||
const faceList& faceLst,
|
||||
const labelList& zoneIdLst = labelList::null()
|
||||
const labelList& zoneIdLst = labelList::null(),
|
||||
const labelList& faceIdLst = labelList::null()
|
||||
)
|
||||
{
|
||||
points_ = std::cref<pointField>(pointLst);
|
||||
faces_ = std::cref<faceList>(faceLst);
|
||||
zoneIds_ = std::cref<labelList>(zoneIdLst);
|
||||
faceIds_ = std::cref<labelList>(faceIdLst);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -117,6 +117,8 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
|
||||
|
||||
DynamicList<label> pointId; // Nastran point id (1-based)
|
||||
DynamicList<point> dynPoints;
|
||||
|
||||
DynamicList<label> dynElemId; // Nastran element id (1-based)
|
||||
DynamicList<Face> dynFaces;
|
||||
DynamicList<label> dynZones;
|
||||
DynamicList<label> dynSizes;
|
||||
@ -127,6 +129,9 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
|
||||
label zoneId = 0;
|
||||
bool sorted = true;
|
||||
|
||||
// Element id gets trashed with decompose into a triangle!
|
||||
bool ignoreElemId = false;
|
||||
|
||||
// Name for face group
|
||||
Map<word> nameLookup;
|
||||
|
||||
@ -222,7 +227,7 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
|
||||
|
||||
if (cmd == "CTRIA3")
|
||||
{
|
||||
(void) nextNasField(line, linei, 8); // 8-16
|
||||
label elemId = readLabel(nextNasField(line, linei, 8)); // 8-16
|
||||
label groupId = readLabel(nextNasField(line, linei, 8)); // 16-24
|
||||
const auto a = readLabel(nextNasField(line, linei, 8)); // 24-32
|
||||
const auto b = readLabel(nextNasField(line, linei, 8)); // 32-40
|
||||
@ -247,13 +252,15 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
|
||||
// Info<< "zone" << zoneId << " => group " << groupId <<nl;
|
||||
}
|
||||
|
||||
--elemId; // Convert 1-based -> 0-based
|
||||
dynElemId.append(elemId);
|
||||
dynFaces.append(Face{a, b, c});
|
||||
dynZones.append(zoneId);
|
||||
dynSizes[zoneId]++;
|
||||
}
|
||||
else if (cmd == "CQUAD4")
|
||||
{
|
||||
(void) nextNasField(line, linei, 8); // 8-16
|
||||
label elemId = readLabel(nextNasField(line, linei, 8)); // 8-16
|
||||
label groupId = readLabel(nextNasField(line, linei, 8)); // 16-24
|
||||
const auto a = readLabel(nextNasField(line, linei, 8)); // 24-32
|
||||
const auto b = readLabel(nextNasField(line, linei, 8)); // 32-40
|
||||
@ -281,6 +288,9 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
|
||||
|
||||
if (faceTraits<Face>::isTri())
|
||||
{
|
||||
ignoreElemId = true;
|
||||
dynElemId.clear();
|
||||
|
||||
dynFaces.append(Face{a, b, c});
|
||||
dynFaces.append(Face{c, d, a});
|
||||
dynZones.append(zoneId);
|
||||
@ -289,6 +299,9 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
|
||||
}
|
||||
else
|
||||
{
|
||||
--elemId; // Convert 1-based -> 0-based
|
||||
|
||||
dynElemId.append(elemId);
|
||||
dynFaces.append(Face{a,b,c,d});
|
||||
dynZones.append(zoneId);
|
||||
dynSizes[zoneId]++;
|
||||
@ -358,6 +371,10 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
|
||||
// << " points:" << dynPoints.size()
|
||||
// << endl;
|
||||
|
||||
if (ignoreElemId)
|
||||
{
|
||||
dynElemId.clear();
|
||||
}
|
||||
|
||||
// Transfer to normal lists
|
||||
this->storedPoints().transfer(dynPoints);
|
||||
@ -403,7 +420,7 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
|
||||
}
|
||||
}
|
||||
|
||||
this->sortFacesAndStore(dynFaces, dynZones, sorted);
|
||||
this->sortFacesAndStore(dynFaces, dynZones, dynElemId, sorted);
|
||||
|
||||
// Add zones (retaining empty ones)
|
||||
this->addZones(dynSizes, names);
|
||||
@ -428,6 +445,7 @@ void Foam::fileFormats::NASsurfaceFormat<Face>::write
|
||||
const UList<point>& pointLst = surf.points();
|
||||
const UList<Face>& faceLst = surf.surfFaces();
|
||||
const UList<label>& faceMap = surf.faceMap();
|
||||
const UList<label>& elemIds = surf.faceIds();
|
||||
|
||||
// for no zones, suppress the group name
|
||||
const surfZoneList zones =
|
||||
@ -439,6 +457,25 @@ void Foam::fileFormats::NASsurfaceFormat<Face>::write
|
||||
|
||||
const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1);
|
||||
|
||||
// Possible to use faceIds?
|
||||
bool useOrigFaceIds =
|
||||
(!useFaceMap && elemIds.size() == faceLst.size());
|
||||
|
||||
if (useOrigFaceIds)
|
||||
{
|
||||
// Not possible with on-the-fly face decomposition
|
||||
|
||||
for (const auto& f : faceLst)
|
||||
{
|
||||
if (f.size() > 4)
|
||||
{
|
||||
useOrigFaceIds = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
OFstream os(filename, streamOpt);
|
||||
if (!os.good())
|
||||
{
|
||||
@ -489,6 +526,11 @@ void Foam::fileFormats::NASsurfaceFormat<Face>::write
|
||||
|
||||
const Face& f = faceLst[facei];
|
||||
|
||||
if (useOrigFaceIds)
|
||||
{
|
||||
elemId = elemIds[facei];
|
||||
}
|
||||
|
||||
elemId = writeShell(os, f, elemId, zoneIndex);
|
||||
}
|
||||
|
||||
|
||||
@ -71,6 +71,8 @@ bool Foam::fileFormats::OBJsurfaceFormat<Face>::read
|
||||
|
||||
DynamicList<point> dynPoints;
|
||||
DynamicList<label> dynVerts;
|
||||
|
||||
DynamicList<label> dynElemId; // unused
|
||||
DynamicList<Face> dynFaces;
|
||||
|
||||
DynamicList<word> dynNames;
|
||||
@ -207,7 +209,7 @@ bool Foam::fileFormats::OBJsurfaceFormat<Face>::read
|
||||
// Transfer to normal lists
|
||||
this->storedPoints().transfer(dynPoints);
|
||||
|
||||
this->sortFacesAndStore(dynFaces, dynZones, sorted);
|
||||
this->sortFacesAndStore(dynFaces, dynZones, dynElemId, sorted);
|
||||
|
||||
// Add zones (retaining empty ones)
|
||||
this->addZones(dynSizes, dynNames);
|
||||
|
||||
@ -127,7 +127,9 @@ bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
|
||||
|
||||
readHeader(is, STARCDCore::HEADER_CEL);
|
||||
|
||||
DynamicList<label> dynElemId; // STARCD element id (1-based)
|
||||
DynamicList<Face> dynFaces;
|
||||
|
||||
DynamicList<label> dynZones;
|
||||
DynamicList<word> dynNames;
|
||||
DynamicList<label> dynSizes;
|
||||
@ -137,6 +139,9 @@ bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
|
||||
bool sorted = true;
|
||||
label zoneId = 0;
|
||||
|
||||
// Element id gets trashed with decompose into a triangle!
|
||||
bool ignoreElemId = false;
|
||||
|
||||
label ignoredLabel, shapeId, nLabels, cellTableId, typeId;
|
||||
DynamicList<label> vertexLabels(64);
|
||||
|
||||
@ -144,7 +149,9 @@ bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
|
||||
|
||||
while (is.read(tok).good() && tok.isLabel())
|
||||
{
|
||||
// const label starCellId = tok.labelToken();
|
||||
// First token is the element id (1-based)
|
||||
label elemId = tok.labelToken();
|
||||
|
||||
is >> shapeId
|
||||
>> nLabels
|
||||
>> cellTableId
|
||||
@ -203,6 +210,8 @@ bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
|
||||
if (faceTraits<Face>::isTri() && nLabels > 3)
|
||||
{
|
||||
// The face needs triangulation
|
||||
ignoreElemId = true;
|
||||
dynElemId.clear();
|
||||
|
||||
face f(vertices);
|
||||
|
||||
@ -220,6 +229,9 @@ bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
|
||||
}
|
||||
else if (nLabels >= 3)
|
||||
{
|
||||
--elemId; // Convert 1-based -> 0-based
|
||||
dynElemId.append(elemId);
|
||||
|
||||
dynFaces.append(Face(vertices));
|
||||
dynZones.append(zoneId);
|
||||
dynSizes[zoneId]++;
|
||||
@ -228,7 +240,14 @@ bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
|
||||
}
|
||||
mapPointId.clear();
|
||||
|
||||
this->sortFacesAndStore(dynFaces, dynZones, sorted);
|
||||
|
||||
if (ignoreElemId)
|
||||
{
|
||||
dynElemId.clear();
|
||||
}
|
||||
|
||||
|
||||
this->sortFacesAndStore(dynFaces, dynZones, dynElemId, sorted);
|
||||
|
||||
// Add zones (retaining empty ones)
|
||||
this->addZones(dynSizes, dynNames);
|
||||
@ -253,6 +272,7 @@ void Foam::fileFormats::STARCDsurfaceFormat<Face>::write
|
||||
const UList<point>& pointLst = surf.points();
|
||||
const UList<Face>& faceLst = surf.surfFaces();
|
||||
const UList<label>& faceMap = surf.faceMap();
|
||||
const UList<label>& elemIds = surf.faceIds();
|
||||
|
||||
const surfZoneList zones =
|
||||
(
|
||||
@ -263,6 +283,15 @@ void Foam::fileFormats::STARCDsurfaceFormat<Face>::write
|
||||
|
||||
const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1);
|
||||
|
||||
// Possible to use faceIds?
|
||||
const bool useOrigFaceIds =
|
||||
(
|
||||
!useFaceMap
|
||||
&& surf.useFaceIds()
|
||||
&& elemIds.size() == faceLst.size()
|
||||
);
|
||||
|
||||
|
||||
fileName baseName = filename.lessExt();
|
||||
|
||||
// The .vrt file
|
||||
@ -287,6 +316,11 @@ void Foam::fileFormats::STARCDsurfaceFormat<Face>::write
|
||||
|
||||
const Face& f = faceLst[facei];
|
||||
|
||||
if (useOrigFaceIds)
|
||||
{
|
||||
elemId = elemIds[facei];
|
||||
}
|
||||
|
||||
writeShell(os, f, elemId, zoneIndex);
|
||||
++elemId;
|
||||
}
|
||||
|
||||
@ -175,6 +175,8 @@ bool Foam::fileFormats::VTKsurfaceFormat<Face>::read
|
||||
}
|
||||
}
|
||||
|
||||
DynamicList<label> dynElemId; // unused
|
||||
|
||||
if (nTri > faces.size())
|
||||
{
|
||||
// We are here if the target surface needs triangles and
|
||||
@ -203,7 +205,7 @@ bool Foam::fileFormats::VTKsurfaceFormat<Face>::read
|
||||
zoneSizes[zonei]++;
|
||||
}
|
||||
|
||||
this->sortFacesAndStore(dynFaces, dynZones, sorted);
|
||||
this->sortFacesAndStore(dynFaces, dynZones, dynElemId, sorted);
|
||||
|
||||
// Add zones (retaining empty ones)
|
||||
this->addZones(zoneSizes, zoneNames);
|
||||
@ -225,7 +227,7 @@ bool Foam::fileFormats::VTKsurfaceFormat<Face>::read
|
||||
zoneSizes[zonei]++;
|
||||
}
|
||||
|
||||
this->sortFacesAndStore(dynFaces, dynZones, sorted);
|
||||
this->sortFacesAndStore(dynFaces, dynZones, dynElemId, sorted);
|
||||
|
||||
// Add zones (retaining empty ones)
|
||||
this->addZones(zoneSizes, zoneNames);
|
||||
|
||||
@ -211,6 +211,24 @@ void Foam::surfaceWriters::nastranWriter::writeGeometry
|
||||
const pointField& points = surf.points();
|
||||
const faceList& faces = surf.faces();
|
||||
const labelList& zones = surf.zoneIds();
|
||||
const labelList& elemIds = surf.faceIds();
|
||||
|
||||
// Possible to use faceIds?
|
||||
bool useOrigFaceIds = (elemIds.size() == faces.size());
|
||||
|
||||
if (useOrigFaceIds)
|
||||
{
|
||||
// Not possible with on-the-fly face decomposition
|
||||
for (const auto& f : faces)
|
||||
{
|
||||
if (f.size() > 4)
|
||||
{
|
||||
useOrigFaceIds = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Write points
|
||||
|
||||
@ -238,6 +256,12 @@ void Foam::surfaceWriters::nastranWriter::writeGeometry
|
||||
{
|
||||
const face& f = faces[facei];
|
||||
|
||||
if (useOrigFaceIds)
|
||||
{
|
||||
// When available and not decomposed
|
||||
elemId = elemIds[facei];
|
||||
}
|
||||
|
||||
// 1-offset for PID
|
||||
const label propId = 1 + (facei < zones.size() ? zones[facei] : 0);
|
||||
|
||||
|
||||
@ -247,6 +247,16 @@ Foam::fileName Foam::surfaceWriters::nastranWriter::writeTemplate
|
||||
|
||||
// Regular (undecomposed) faces
|
||||
const faceList& faces = surf.faces();
|
||||
const labelList& elemIds = surf.faceIds();
|
||||
|
||||
// Possible to use faceIds?
|
||||
// Not possible with on-the-fly face decomposition
|
||||
const bool useOrigFaceIds =
|
||||
(
|
||||
elemIds.size() == faces.size()
|
||||
&& decompFaces.empty()
|
||||
);
|
||||
|
||||
|
||||
label elemId = 0;
|
||||
|
||||
@ -254,6 +264,12 @@ Foam::fileName Foam::surfaceWriters::nastranWriter::writeTemplate
|
||||
{
|
||||
forAll(faces, facei)
|
||||
{
|
||||
if (useOrigFaceIds)
|
||||
{
|
||||
// When available and not decomposed
|
||||
elemId = elemIds[facei];
|
||||
}
|
||||
|
||||
const label beginElemId = elemId;
|
||||
|
||||
// Any face decomposition
|
||||
@ -299,6 +315,12 @@ Foam::fileName Foam::surfaceWriters::nastranWriter::writeTemplate
|
||||
|
||||
forAll(faces, facei)
|
||||
{
|
||||
if (useOrigFaceIds)
|
||||
{
|
||||
// When available and not decomposed
|
||||
elemId = elemIds[facei];
|
||||
}
|
||||
|
||||
const Type v(varScale * *valIter);
|
||||
++valIter;
|
||||
|
||||
|
||||
@ -145,7 +145,14 @@ Foam::fileName Foam::surfaceWriters::starcdWriter::write()
|
||||
mkDir(outputFile.path());
|
||||
}
|
||||
|
||||
MeshedSurfaceProxy<face>(surf.points(), surf.faces()).write
|
||||
MeshedSurfaceProxy<face>
|
||||
(
|
||||
surf.points(),
|
||||
surf.faces(),
|
||||
UList<surfZone>::null(), // one zone
|
||||
labelUList::null(), // no faceMap
|
||||
surf.faceIds() // with face ids (if possible)
|
||||
).write
|
||||
(
|
||||
outputFile,
|
||||
"starcd", // Canonical selection name
|
||||
|
||||
Reference in New Issue
Block a user