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

This commit is contained in:
Mark Olesen
2020-02-26 00:12:14 +01:00
parent 560c053bc8
commit cfd8873012
22 changed files with 345 additions and 68 deletions

View File

@ -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();

View File

@ -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

View File

@ -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)

View File

@ -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"
);
}

View File

@ -69,7 +69,7 @@ Description
}
surfaces
(
{
f0surf
{
type meshedSurface;
@ -88,7 +88,7 @@ Description
// Optional: registry storage
store true
}
);
}
}
\endverbatim

View File

@ -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()
);
}

View File

@ -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

View File

@ -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());

View File

@ -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]];
}
}

View File

@ -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)
{}

View File

@ -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;

View File

@ -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;
}

View File

@ -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
);

View File

@ -79,6 +79,12 @@ public:
{
return labelList::null();
}
//- Per-face identifier (eg, element Id)
virtual const labelList& faceIds() const
{
return labelList::null();
}
};

View File

@ -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);
}
};

View File

@ -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);
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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