surfMesh streamlining

- all formats except ftr and gts are now read as MeshedSurface (thus sorted
   immediately). Avoid unnecessary sorting during construction though.
 - moved cleanup routines completely into PrimitiveMeshedSurface
This commit is contained in:
Mark Olesen
2008-11-21 01:38:56 +01:00
parent 7bbe6c9d10
commit fa69fd6690
40 changed files with 1124 additions and 1536 deletions

View File

@ -99,14 +99,14 @@ bool Foam::MeshedSurface<Face>::canWriteType
template<class Face> template<class Face>
bool Foam::MeshedSurface<Face>::canRead bool Foam::MeshedSurface<Face>::canRead
( (
const fileName& fName, const fileName& name,
const bool verbose const bool verbose
) )
{ {
word ext = fName.ext(); word ext = name.ext();
if (ext == "gz") if (ext == "gz")
{ {
ext = fName.lessExt().ext(); ext = name.lessExt().ext();
} }
return canReadType(ext, verbose); return canReadType(ext, verbose);
} }
@ -115,7 +115,7 @@ bool Foam::MeshedSurface<Face>::canRead
template<class Face> template<class Face>
void Foam::MeshedSurface<Face>::write void Foam::MeshedSurface<Face>::write
( (
const fileName& fName, const fileName& name,
const MeshedSurface& surf const MeshedSurface& surf
) )
{ {
@ -123,16 +123,16 @@ void Foam::MeshedSurface<Face>::write
{ {
Info<< "MeshedSurface::write" Info<< "MeshedSurface::write"
"(const fileName&, const MeshedSurface&) : " "(const fileName&, const MeshedSurface&) : "
"writing to " << fName "writing to " << name
<< endl; << endl;
} }
word ext = fName.ext(); word ext = name.ext();
// handle 'native' format directly // handle 'native' format directly
if (isNative(ext)) if (isNative(ext))
{ {
surf.write(OFstream(fName)()); surf.write(OFstream(name)());
return; return;
} }
@ -150,7 +150,7 @@ void Foam::MeshedSurface<Face>::write
<< exit(FatalError); << exit(FatalError);
} }
mfIter()(fName, surf); mfIter()(name, surf);
} }
@ -180,100 +180,25 @@ Foam::MeshedSurface<Face>::MeshedSurface
const xfer<pointField>& pointLst, const xfer<pointField>& pointLst,
const xfer<List<Face> >& faceLst, const xfer<List<Face> >& faceLst,
const UList<label>& patchSizes, const UList<label>& patchSizes,
const UList<word>& patchNames, const UList<word>& patchNames
const UList<word>& patchTypes
) )
: :
ParentType(pointLst, faceLst) ParentType(pointLst, faceLst)
{ {
surfGroupList newPatches(patchSizes.size()); if (&patchSizes)
label start = 0;
forAll(newPatches, patchI)
{ {
newPatches[patchI] = surfGroup if (&patchNames)
(
patchNames[patchI],
patchSizes[patchI],
start,
patchI
);
start += patchSizes[patchI];
}
patches_.transfer(newPatches);
}
template<class Face>
Foam::MeshedSurface<Face>::MeshedSurface
(
const xfer<pointField>& pointLst,
const xfer<List<Face> >& faceLst,
const UList<label>& regionIds,
const Map<word>& regionNames
)
:
ParentType(pointLst, faceLst)
{
if (&regionIds && regionIds.size() && regionIds.size() != size())
{
FatalErrorIn
(
"MeshedSurface::MeshedSurface(\n"
"(\n"
" const xfer<pointField>&,\n"
" const xfer<List<Face> >&,\n"
" const UList<label>& regionIds,\n"
" const Map<word>& regionNames\n"
" )\n"
)
<< "size mismatch : region and face sizes"
<< exit(FatalError);
}
else
{
sortFacesByRegion(regionIds, regionNames);
}
}
template<class Face>
Foam::MeshedSurface<Face>::MeshedSurface
(
const xfer<pointField>& pointLst,
const xfer<List<Face> >& faceLst,
const UList<label>& regionIds,
const HashTable<label>& nameToRegionMapping
)
:
ParentType(pointLst, faceLst)
{
if (&regionIds && regionIds.size() && regionIds.size() != size())
{
FatalErrorIn
(
"MeshedSurface::MeshedSurface(\n"
"(\n"
" const xfer<pointField>&,\n"
" const xfer<List<Face> >&,\n"
" const UList<label>& regionIds,\n"
" const HashTable<label>& nameToRegionMapping\n"
" )\n"
)
<< "size mismatch : region and face sizes"
<< exit(FatalError);
}
else
{
Map<word> regionNames;
forAllConstIter(HashTable<label>, nameToRegionMapping, iter)
{ {
regionNames.insert(iter(), iter.key()); addPatches(patchSizes, patchNames);
} }
else
sortFacesByRegion(regionIds, regionNames); {
addPatches(patchSizes);
}
}
else
{
onePatch();
} }
} }
@ -430,18 +355,18 @@ Foam::MeshedSurface<Face>::MeshedSurface
template<class Face> template<class Face>
Foam::MeshedSurface<Face>::MeshedSurface Foam::MeshedSurface<Face>::MeshedSurface
( (
const fileName& fName, const fileName& name,
const word& ext const word& ext
) )
{ {
read(fName, ext); read(name, ext);
} }
template<class Face> template<class Face>
Foam::MeshedSurface<Face>::MeshedSurface(const fileName& fName) Foam::MeshedSurface<Face>::MeshedSurface(const fileName& name)
{ {
read(fName); read(name);
} }
@ -456,7 +381,6 @@ template<class Face>
Foam::MeshedSurface<Face>::MeshedSurface(const Time& d) Foam::MeshedSurface<Face>::MeshedSurface(const Time& d)
{ {
read(IFstream(findMeshName(d))()); read(IFstream(findMeshName(d))());
// setDefaultPatches();
} }
@ -567,39 +491,40 @@ void Foam::MeshedSurface<Face>::checkPatches()
template<class Face> template<class Face>
void Foam::MeshedSurface<Face>::sortFacesByRegion void Foam::MeshedSurface<Face>::sortFacesAndStore
( (
const UList<label>& regionIds, const xfer<List<Face> >& unsortedFaces,
const Map<word>& regionNames const xfer<List<label> >& regionIds,
const bool sorted
) )
{ {
const List<Face>& unsortedFaces = this->faces(); List<Face> oldFaces(unsortedFaces);
List<label> regions(regionIds);
if (!&regionNames || !&regionIds || regionIds.size() == 0) if (sorted)
{ {
onePatch(); // already sorted - simply transfer faces
this->storedFaces().transfer(oldFaces);
} }
else if (regionIds.size() == unsortedFaces.size()) else
{ {
labelList faceMap; // unsorted - determine the sorted order:
surfGroupList newPatches = UnsortedMeshedSurface<Face>::sortedRegions // avoid SortableList since we discard the main list anyhow
( List<label> faceMap;
regionIds, sortedOrder(regions, faceMap);
regionNames, regions.clear();
faceMap
);
patches_.transfer(newPatches);
// this is somewhat like ListOps reorder and/or IndirectList // sorted faces
List<Face> newFaces(unsortedFaces.size()); List<Face> newFaces(faceMap.size());
forAll(newFaces, faceI) forAll(faceMap, faceI)
{ {
newFaces[faceI] = unsortedFaces[faceMap[faceI]]; // use transfer to recover memory if possible
newFaces[faceI].transfer(oldFaces[faceMap[faceI]]);
} }
faceMap.clear();
this->storedFaces().transfer(newFaces); this->storedFaces().transfer(newFaces);
} }
regions.clear();
} }
@ -634,8 +559,8 @@ void Foam::MeshedSurface<Face>::remapRegions(List<label>& faceMap)
// adjust patch size // adjust patch size
p.size() = newFaceI - p.start(); p.size() = newFaceI - p.start();
} }
faceMap.clear();
} }
faceMap.clear();
} }
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
@ -662,6 +587,7 @@ Foam::MeshedSurface<Face> Foam::MeshedSurface<Face>::subsetMesh
const pointField& locPoints = this->localPoints(); const pointField& locPoints = this->localPoints();
const List<Face>& locFaces = this->localFaces(); const List<Face>& locFaces = this->localFaces();
// Fill pointMap, faceMap // Fill pointMap, faceMap
this->subsetMap(include, pointMap, faceMap); this->subsetMap(include, pointMap, faceMap);
@ -751,58 +677,83 @@ Foam::MeshedSurface<Face> Foam::MeshedSurface<Face>::subsetMesh
template<class Face> template<class Face>
void Foam::MeshedSurface<Face>::addPatches void Foam::MeshedSurface<Face>::addPatches
( (
const UList<surfGroup>& patchLst const UList<surfGroup>& patches,
const bool cullEmpty
) )
{ {
patches_ = patchLst; label nPatch = 0;
patches_.setSize(patches.size());
forAll(patches_, patchI)
{
if (patches[patchI].size() || !cullEmpty)
{
patches_[nPatch] = surfGroup(patches[patchI], nPatch);
nPatch++;
}
}
patches_.setSize(nPatch);
} }
template<class Face> template<class Face>
void Foam::MeshedSurface<Face>::addPatches void Foam::MeshedSurface<Face>::addPatches
( (
const UList<label>& sizes,
const UList<word>& names, const UList<word>& names,
const UList<label>& sizes const bool cullEmpty
) )
{ {
patches_.setSize(sizes.size()); label start = 0;
label nPatch = 0;
label start = 0; patches_.setSize(sizes.size());
forAll(patches_, patchI) forAll(patches_, patchI)
{ {
patches_[patchI] = surfGroup if (sizes[patchI] || !cullEmpty)
( {
names[patchI], patches_[nPatch] = surfGroup
sizes[patchI], (
start, names[patchI],
patchI sizes[patchI],
); start,
nPatch
start += sizes[patchI]; );
start += sizes[patchI];
nPatch++;
}
} }
patches_.setSize(nPatch);
} }
template<class Face> template<class Face>
void Foam::MeshedSurface<Face>::addPatches void Foam::MeshedSurface<Face>::addPatches
( (
const UList<label>& sizes const UList<label>& sizes,
const bool cullEmpty
) )
{ {
patches_.setSize(sizes.size()); label start = 0;
label nPatch = 0;
label start = 0; patches_.setSize(sizes.size());
forAll(patches_, patchI) forAll(patches_, patchI)
{ {
patches_[patchI] = surfGroup if (sizes[patchI] || !cullEmpty)
( {
word("patch") + ::Foam::name(patchI), patches_[nPatch] = surfGroup
sizes[patchI], (
start, word("patch") + ::Foam::name(nPatch),
patchI sizes[patchI],
); start,
nPatch
start += sizes[patchI]; );
start += sizes[patchI];
nPatch++;
}
} }
patches_.setSize(nPatch);
} }
@ -829,39 +780,35 @@ void Foam::MeshedSurface<Face>::transfer
labelList faceMap; labelList faceMap;
surfGroupList patchLst = surf.sortedRegions(faceMap); surfGroupList patchLst = surf.sortedRegions(faceMap);
List<Face>& oldFaces = surf.storedFaces();
const List<Face>& oldFaces = surf.faces(); List<Face> newFaces(faceMap.size());
List<Face> newFaces(oldFaces.size()); forAll(faceMap, faceI)
// this is somewhat like ListOps reorder and/or IndirectList
forAll(newFaces, faceI)
{ {
newFaces[faceI] = oldFaces[faceMap[faceI]]; newFaces[faceI].transfer(oldFaces[faceMap[faceI]]);
} }
faceMap.clear(); faceMap.clear();
reset(xferMove(surf.storedPoints()), xferMove(newFaces)); reset(xferMove(surf.storedPoints()), xferMove(newFaces));
patches_.transfer(patchLst); patches_.transfer(patchLst);
surf.regions_.clear();
surf.patches_.clear();
surf.clear(); surf.clear();
} }
// Read from file, determine format from extension // Read from file, determine format from extension
template<class Face> template<class Face>
bool Foam::MeshedSurface<Face>::read(const fileName& fName) bool Foam::MeshedSurface<Face>::read(const fileName& name)
{ {
word ext = fName.ext(); word ext = name.ext();
if (ext == "gz") if (ext == "gz")
{ {
fileName unzipName = fName.lessExt(); fileName unzipName = name.lessExt();
return read(unzipName, unzipName.ext()); return read(unzipName, unzipName.ext());
} }
else else
{ {
return read(fName, ext); return read(name, ext);
} }
} }
@ -870,19 +817,19 @@ bool Foam::MeshedSurface<Face>::read(const fileName& fName)
template<class Face> template<class Face>
bool Foam::MeshedSurface<Face>::read bool Foam::MeshedSurface<Face>::read
( (
const fileName& fName, const fileName& name,
const word& ext const word& ext
) )
{ {
// handle 'native' format directly // handle 'native' format directly
if (isNative(ext)) if (isNative(ext))
{ {
return read(IFstream(fName)()); return read(IFstream(name)());
} }
else else
{ {
// use selector mechanism // use selector mechanism
transfer(New(fName, ext)()); transfer(New(name, ext)());
return true; return true;
} }
} }
@ -912,7 +859,6 @@ void Foam::MeshedSurface<Face>::operator=(const MeshedSurface& surf)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "MeshedSurfaceCleanup.C"
#include "MeshedSurfaceIO.C" #include "MeshedSurfaceIO.C"
#include "MeshedSurfaceNew.C" #include "MeshedSurfaceNew.C"

View File

@ -28,7 +28,7 @@ Class
Description Description
A surface geometry mesh with patch information, not to be confused A surface geometry mesh with patch information, not to be confused
with a similarily named surfaceMesh, which actually refers to with a similarily named surfaceMesh, which actually refers to
the cell faces of a volume mesh! the cell faces of a volume mesh.
The MeshedSurface is intended to surfaces from a variety of sources. The MeshedSurface is intended to surfaces from a variety of sources.
- A set of points and faces without any patch information. - A set of points and faces without any patch information.
@ -94,12 +94,6 @@ private:
// Private member functions // Private member functions
//- Sort faces by regionIds and set patches
void sortFacesByRegion(const UList<label>&, const Map<word>&);
//- Set new regions from faceMap
void remapRegions(List<label>& faceMap);
//- Read OpenFOAM Surface format //- Read OpenFOAM Surface format
bool read(Istream&); bool read(Istream&);
@ -107,12 +101,20 @@ protected:
// Protected Member functions // Protected Member functions
//- set a single patch
void onePatch();
//- basic sanity check on patches //- basic sanity check on patches
void checkPatches(); void checkPatches();
//- sort faces by regions and store sorted faces
void sortFacesAndStore
(
const xfer<List<Face> >& unsortedFaces,
const xfer<List<label> >& regionIds,
const bool sorted
);
//- Set new regions from faceMap
virtual void remapRegions(List<label>& faceMap);
public: public:
//- Runtime type information //- Runtime type information
@ -137,8 +139,7 @@ public:
//- Construct null //- Construct null
MeshedSurface(); MeshedSurface();
//- Construct by transferring components //- Construct by transferring components (points, faces, patches).
// (points, faces and patches).
MeshedSurface MeshedSurface
( (
const xfer<pointField>&, const xfer<pointField>&,
@ -146,35 +147,14 @@ public:
const xfer<surfGroupList>& const xfer<surfGroupList>&
); );
//- Construct from points, faces, and patch information
MeshedSurface
(
const xfer<pointField>&,
const xfer<List<Face> >&,
const UList<label>& patchSizes,
const UList<word>& patchNames,
const UList<word>& patchTypes
);
//- Construct by transferring points, faces. //- Construct by transferring points, faces.
// Sort faces according to regionIds with the names of the regions, // Use patch information, or set single default patch.
// or jsut set a single default patch.
MeshedSurface MeshedSurface
( (
const xfer<pointField>&, const xfer<pointField>&,
const xfer<List<Face> >&, const xfer<List<Face> >&,
const UList<label>& regionIds = UList<label>::null(), const UList<label>& patchSizes = UList<label>::null(),
const Map<word>& regionNames = Map<word>::null() const UList<word>& patchNames = UList<word>::null()
);
//- Construct by transferring points, faces.
// Sort faces according to regionIds with patch-names from hash
MeshedSurface
(
const xfer<pointField>&,
const xfer<List<Face> >&,
const UList<label>& regionIds,
const HashTable<label>& nameToRegionMapping
); );
//- Construct from a boundary mesh with local points/faces //- Construct from a boundary mesh with local points/faces
@ -219,9 +199,9 @@ public:
MeshedSurface, MeshedSurface,
fileExtension, fileExtension,
( (
const fileName& fName const fileName& name
), ),
(fName) (name)
); );
// Selectors // Selectors
@ -250,10 +230,10 @@ public:
write, write,
fileExtension, fileExtension,
( (
const fileName& fName, const fileName& name,
const MeshedSurface<Face>& surf const MeshedSurface<Face>& surf
), ),
(fName, surf) (name, surf)
); );
//- Write to file //- Write to file
@ -275,35 +255,36 @@ public:
return patches_; return patches_;
} }
void addPatches(const UList<surfGroup>&); //- set a single patch
void onePatch();
void addPatches(const UList<word>& names, const UList<label>& sizes);
void addPatches(const UList<label>& sizes);
//- add patches
void addPatches
(
const UList<surfGroup>&,
const bool cullEmpty=false
);
//- add patches
void addPatches
(
const UList<label>& sizes,
const UList<word>& names,
const bool cullEmpty=false
);
//- add patches
void addPatches
(
const UList<label>& sizes,
const bool cullEmpty=false
);
// Edit // Edit
//- Clear all storage //- Clear all storage
virtual void clear(); virtual void clear();
//- Remove invalid faces
void cleanup(const bool verbose);
//- Check/fix duplicate/degenerate faces
virtual bool checkFaces(const bool verbose);
//- Join the faces by removing duplicate points.
// Returns true if any points merged
virtual bool stitchFaces
(
const scalar tol=SMALL,
const bool verbose=false
);
//- Triangulate the surface, return the number of added faces.
// The patch list will be adjusted accordingly.
virtual label triangulate();
//- Return new surface. //- Return new surface.
// Returns return pointMap, faceMap from subsetMeshMap // Returns return pointMap, faceMap from subsetMeshMap
MeshedSurface subsetMesh MeshedSurface subsetMesh
@ -341,9 +322,9 @@ public:
virtual void write(Ostream&) const; virtual void write(Ostream&) const;
//- Generic write routine. Chooses writer based on extension. //- Generic write routine. Chooses writer based on extension.
virtual void write(const fileName& fName) const virtual void write(const fileName& name) const
{ {
write(fName, *this); write(name, *this);
} }
//- Write to database //- Write to database
@ -365,15 +346,6 @@ public:
}; };
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Specialization for holding triangulated information
template<>
inline label MeshedSurface<triFace>::triangulate()
{
return 0;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam } // End namespace Foam

View File

@ -1,82 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "MeshedSurface.H"
#include "mergePoints.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// Remove badly degenerate faces, double faces.
template<class Face>
void Foam::MeshedSurface<Face>::cleanup(const bool verbose)
{
// merge points (already done for STL, TRI)
stitchFaces(SMALL, verbose);
checkFaces(verbose);
ParentType::checkEdges(verbose);
}
template<class Face>
bool Foam::MeshedSurface<Face>::stitchFaces
(
const scalar tol,
const bool verbose
)
{
List<label> faceMap;
bool hasMerged = ParentType::stitchFaces(faceMap, tol, verbose);
remapRegions(faceMap);
return hasMerged;
}
// Remove badly degenerate faces and double faces.
template<class Face>
bool Foam::MeshedSurface<Face>::checkFaces(const bool verbose)
{
List<label> faceMap;
bool changed = ParentType::checkFaces(faceMap, verbose);
remapRegions(faceMap);
return changed;
}
template<class Face>
Foam::label Foam::MeshedSurface<Face>::triangulate()
{
List<label> faceMap;
label nTri = ParentType::triangulate(this->storedFaces(), faceMap);
remapRegions(faceMap);
return nTri;
}
// ************************************************************************* //

View File

@ -29,14 +29,10 @@ License
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// all input is indirect via UnsortedMeshedSurface
template<class Face> template<class Face>
Foam::autoPtr<Foam::MeshedSurface<Face> > Foam::autoPtr<Foam::MeshedSurface<Face> >
Foam::MeshedSurface<Face>::New Foam::MeshedSurface<Face>::New(const fileName& name, const word& ext)
(
const fileName& fName,
const word& ext
)
{ {
if (debug) if (debug)
{ {
@ -56,7 +52,7 @@ Foam::MeshedSurface<Face>::New
{ {
// create indirectly // create indirectly
autoPtr<MeshedSurface<Face> > surf(new MeshedSurface<Face>); autoPtr<MeshedSurface<Face> > surf(new MeshedSurface<Face>);
surf().transfer(SiblingType::New(fName, ext)()); surf().transfer(SiblingType::New(name, ext)());
return surf; return surf;
} }
@ -67,8 +63,7 @@ Foam::MeshedSurface<Face>::New
FatalErrorIn FatalErrorIn
( (
"MeshedSurface<Face>::New" "MeshedSurface<Face>::New(const fileName&, const word&) : "
"(const fileName&, const word&) : "
"constructing MeshedSurface" "constructing MeshedSurface"
) << "Unknown file extension " << ext << nl << nl ) << "Unknown file extension " << ext << nl << nl
<< "Valid types are :" << nl << "Valid types are :" << nl
@ -76,23 +71,20 @@ Foam::MeshedSurface<Face>::New
<< exit(FatalError); << exit(FatalError);
} }
return autoPtr<MeshedSurface<Face> >(cstrIter()(fName)); return autoPtr<MeshedSurface<Face> >(cstrIter()(name));
} }
template<class Face> template<class Face>
Foam::autoPtr<Foam::MeshedSurface<Face> > Foam::autoPtr<Foam::MeshedSurface<Face> >
Foam::MeshedSurface<Face>::New Foam::MeshedSurface<Face>::New(const fileName& name)
(
const fileName& fName
)
{ {
word ext = fName.ext(); word ext = name.ext();
if (ext == "gz") if (ext == "gz")
{ {
ext = fName.lessExt().ext(); ext = name.lessExt().ext();
} }
return New(fName, ext); return New(name, ext);
} }
// ************************************************************************* // // ************************************************************************* //

View File

@ -36,75 +36,6 @@ inline bool Foam::PrimitiveMeshedSurface<Face>::isTri()
} }
template<class Face>
Foam::label Foam::PrimitiveMeshedSurface<Face>::triangulate
(
List<Face>& faceLst,
List<label>& faceMap
)
{
label nTri = 0;
// determine how many triangles are needed
forAll(faceLst, faceI)
{
nTri += faceLst[faceI].size() - 2;
}
// nothing to do
if (nTri <= faceLst.size())
{
if (&faceMap)
{
faceMap.clear();
}
return 0;
}
List<Face> newFaces(nTri);
List<label> fMap(nTri);
// remember the number of *additional* faces
nTri -= faceLst.size();
label newFaceI = 0;
forAll(faceLst, faceI)
{
const Face& f = faceLst[faceI];
triFace fTri;
// Do simple face triangulation around f[0].
// we could also use face::triangulation, but that requires points
// and doesn't currently template nicely
fTri[0] = f[0];
for (label fp = 1; fp < f.size() - 1; ++fp)
{
label fp1 = (fp + 1) % f.size();
fTri[1] = f[fp];
fTri[2] = f[fp1];
newFaces[newFaceI] = fTri;
fMap[newFaceI] = faceI;
newFaceI++;
}
}
faceLst.transfer(newFaces);
if (&faceMap)
{
faceMap.transfer(fMap);
}
else
{
fMap.clear();
}
return nTri;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Face> template<class Face>
@ -200,10 +131,21 @@ void Foam::PrimitiveMeshedSurface<Face>::reset
} }
// Remove badly degenerate faces, double faces.
template<class Face>
void Foam::PrimitiveMeshedSurface<Face>::cleanup(const bool verbose)
{
// merge points (already done for STL, TRI)
stitchFaces(SMALL, verbose);
checkFaces(verbose);
this->checkEdges(verbose);
}
template<class Face> template<class Face>
bool Foam::PrimitiveMeshedSurface<Face>::stitchFaces bool Foam::PrimitiveMeshedSurface<Face>::stitchFaces
( (
List<label>& faceMap,
const scalar tol, const scalar tol,
const bool verbose const bool verbose
) )
@ -218,10 +160,6 @@ bool Foam::PrimitiveMeshedSurface<Face>::stitchFaces
if (!hasMerged) if (!hasMerged)
{ {
if (&faceMap)
{
faceMap.clear();
}
return false; return false;
} }
@ -236,13 +174,7 @@ bool Foam::PrimitiveMeshedSurface<Face>::stitchFaces
List<Face>& faceLst = this->storedFaces(); List<Face>& faceLst = this->storedFaces();
// local copy List<label> faceMap(faceLst.size());
List<label> fMap;
if (&faceMap)
{
fMap.transfer(faceMap);
}
fMap.setSize(faceLst.size());
// Reset the point labels to the unique points array // Reset the point labels to the unique points array
label newFaceI = 0; label newFaceI = 0;
@ -261,7 +193,7 @@ bool Foam::PrimitiveMeshedSurface<Face>::stitchFaces
{ {
faceLst[newFaceI] = f; faceLst[newFaceI] = f;
} }
fMap[newFaceI] = faceI; faceMap[newFaceI] = faceI;
newFaceI++; newFaceI++;
} }
else if (verbose) else if (verbose)
@ -282,18 +214,12 @@ bool Foam::PrimitiveMeshedSurface<Face>::stitchFaces
<< " faces" << endl; << " faces" << endl;
} }
faceLst.setSize(newFaceI); faceLst.setSize(newFaceI);
if (&faceMap) remapRegions(faceMap);
{
faceMap.transfer(fMap);
faceMap.setSize(newFaceI);
}
} }
fMap.clear(); faceMap.clear();
// Merging points might have changed geometric factors // Merging points might have changed geometric factors
ParentType::clearOut(); ParentType::clearOut();
return true; return true;
} }
@ -302,20 +228,13 @@ bool Foam::PrimitiveMeshedSurface<Face>::stitchFaces
template<class Face> template<class Face>
bool Foam::PrimitiveMeshedSurface<Face>::checkFaces bool Foam::PrimitiveMeshedSurface<Face>::checkFaces
( (
List<label>& faceMap,
const bool verbose const bool verbose
) )
{ {
bool changed = false; bool changed = false;
List<Face>& faceLst = this->storedFaces(); List<Face>& faceLst = this->storedFaces();
// local copy List<label> faceMap(faceLst.size());
List<label> fMap;
if (&faceMap)
{
fMap.transfer(faceMap);
}
fMap.setSize(faceLst.size());
label newFaceI = 0; label newFaceI = 0;
// Detect badly labelled faces and mark degenerate faces // Detect badly labelled faces and mark degenerate faces
@ -339,13 +258,13 @@ bool Foam::PrimitiveMeshedSurface<Face>::checkFaces
} }
} }
fMap[faceI] = faceI; faceMap[faceI] = faceI;
newFaceI++; newFaceI++;
} }
else else
{ {
// mark as bad face // mark as bad face
fMap[faceI] = -1; faceMap[faceI] = -1;
changed = true; changed = true;
if (verbose) if (verbose)
@ -366,7 +285,7 @@ bool Foam::PrimitiveMeshedSurface<Face>::checkFaces
forAll(faceLst, faceI) forAll(faceLst, faceI)
{ {
// skip already collapsed faces: // skip already collapsed faces:
if (fMap[faceI] < 0) if (faceMap[faceI] < 0)
{ {
continue; continue;
} }
@ -383,7 +302,7 @@ bool Foam::PrimitiveMeshedSurface<Face>::checkFaces
{ {
const label neiFaceI = neighbours[neighI]; const label neiFaceI = neighbours[neighI];
if (neiFaceI <= faceI || fMap[neiFaceI] < 0) if (neiFaceI <= faceI || faceMap[neiFaceI] < 0)
{ {
// lower numbered faces already checked // lower numbered faces already checked
// skip neighbours that are themselves collapsed // skip neighbours that are themselves collapsed
@ -414,12 +333,12 @@ bool Foam::PrimitiveMeshedSurface<Face>::checkFaces
if (okay) if (okay)
{ {
fMap[faceI] = faceI; faceMap[faceI] = faceI;
newFaceI++; newFaceI++;
} }
else else
{ {
fMap[faceI] = -1; faceMap[faceI] = -1;
} }
} }
@ -443,33 +362,94 @@ bool Foam::PrimitiveMeshedSurface<Face>::checkFaces
newFaceI = 0; newFaceI = 0;
forAll(faceLst, faceI) forAll(faceLst, faceI)
{ {
if (fMap[faceI] >= 0) if (faceMap[faceI] >= 0)
{ {
if (newFaceI != faceI) if (newFaceI != faceI)
{ {
faceLst[newFaceI] = faceLst[faceI]; faceLst[newFaceI] = faceLst[faceI];
} }
fMap[newFaceI] = faceI; faceMap[newFaceI] = faceI;
newFaceI++; newFaceI++;
} }
} }
faceLst.setSize(newFaceI); faceLst.setSize(newFaceI);
if (&faceMap) remapRegions(faceMap);
{
faceMap.transfer(fMap);
faceMap.setSize(newFaceI);
}
} }
fMap.clear(); faceMap.clear();
// Topology can change because of renumbering // Topology can change because of renumbering
ParentType::clearOut(); ParentType::clearOut();
return changed; return changed;
} }
template<class Face>
Foam::label Foam::PrimitiveMeshedSurface<Face>::triangulate()
{
label nTri = 0;
List<Face>& faceLst = this->storedFaces();
// determine how many triangles are needed
forAll(faceLst, faceI)
{
nTri += faceLst[faceI].size() - 2;
}
// nothing to do
if (nTri <= faceLst.size())
{
return 0;
}
List<Face> newFaces(nTri);
List<label> faceMap(nTri);
// remember the number of *additional* faces
nTri -= faceLst.size();
label newFaceI = 0;
forAll(faceLst, faceI)
{
const Face& f = faceLst[faceI];
triFace fTri;
// Do simple face triangulation around f[0].
// we could also use face::triangulation, but that requires points
// and doesn't currently template nicely
fTri[0] = f[0];
for (label fp = 1; fp < f.size() - 1; ++fp)
{
label fp1 = (fp + 1) % f.size();
fTri[1] = f[fp];
fTri[2] = f[fp1];
newFaces[newFaceI] = fTri;
faceMap[newFaceI] = faceI;
newFaceI++;
}
}
faceLst.transfer(newFaces);
remapRegions(faceMap);
faceMap.clear();
// Topology can change because of renumbering
ParentType::clearOut();
return nTri;
}
// dummy implementation to avoid a pure virtual class
template<class Face>
void Foam::PrimitiveMeshedSurface<Face>::remapRegions(List<label>& faceMap)
{
faceMap.clear();
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * // // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //

View File

@ -84,6 +84,9 @@ protected:
return static_cast<List<Face> &>(*this); return static_cast<List<Face> &>(*this);
} }
//- Set new regions/patches from faceMap
virtual void remapRegions(List<label>& faceMap);
public: public:
// Static // Static
@ -91,15 +94,6 @@ public:
//- Face storage only handles triangulated faces //- Face storage only handles triangulated faces
inline static bool isTri(); inline static bool isTri();
//- Triangulate faceLst in-place
// Returning the number of triangles added and a map to the
// the original face Ids
static label triangulate
(
List<Face>& faceLst,
List<label>& faceMap=const_cast<List<label>&>(List<label>::null())
);
// Constructors // Constructors
//- Construct null //- Construct null
@ -144,19 +138,24 @@ public:
const xfer<List<Face> >& const xfer<List<Face> >&
); );
//- Remove invalid faces
virtual void cleanup(const bool verbose);
virtual bool stitchFaces virtual bool stitchFaces
( (
List<label>& faceMap=const_cast<List<label>&>(List<label>::null()),
const scalar tol=SMALL, const scalar tol=SMALL,
const bool verbose=false const bool verbose=false
); );
virtual bool checkFaces virtual bool checkFaces
( (
List<label>& faceMap=const_cast<List<label>&>(List<label>::null()),
const bool verbose=false const bool verbose=false
); );
//- Triangulate in-place
// Returning the number of triangles added
virtual label triangulate();
}; };
@ -169,6 +168,13 @@ inline bool PrimitiveMeshedSurface<triFace>::isTri()
return true; return true;
} }
//- Specialization for holding triangulated information
template<>
inline label PrimitiveMeshedSurface<triFace>::triangulate()
{
return 0;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam } // End namespace Foam

View File

@ -95,14 +95,14 @@ bool Foam::UnsortedMeshedSurface<Face>::canWriteType
template<class Face> template<class Face>
bool Foam::UnsortedMeshedSurface<Face>::canRead bool Foam::UnsortedMeshedSurface<Face>::canRead
( (
const fileName& fName, const fileName& name,
const bool verbose const bool verbose
) )
{ {
word ext = fName.ext(); word ext = name.ext();
if (ext == "gz") if (ext == "gz")
{ {
ext = fName.lessExt().ext(); ext = name.lessExt().ext();
} }
return canReadType(ext, verbose); return canReadType(ext, verbose);
} }
@ -111,7 +111,7 @@ bool Foam::UnsortedMeshedSurface<Face>::canRead
template<class Face> template<class Face>
void Foam::UnsortedMeshedSurface<Face>::write void Foam::UnsortedMeshedSurface<Face>::write
( (
const fileName& fName, const fileName& name,
const UnsortedMeshedSurface<Face>& surf const UnsortedMeshedSurface<Face>& surf
) )
{ {
@ -119,16 +119,16 @@ void Foam::UnsortedMeshedSurface<Face>::write
{ {
Info<< "UnsortedMeshedSurface::write" Info<< "UnsortedMeshedSurface::write"
"(const fileName&, const UnsortedMeshedSurface&) : " "(const fileName&, const UnsortedMeshedSurface&) : "
"writing to " << fName "writing to " << name
<< endl; << endl;
} }
const word ext = fName.ext(); const word ext = name.ext();
// handle 'native' format directly // handle 'native' format directly
if (isNative(ext)) if (isNative(ext))
{ {
surf.write(OFstream(fName)()); surf.write(OFstream(name)());
return; return;
} }
@ -147,7 +147,7 @@ void Foam::UnsortedMeshedSurface<Face>::write
<< exit(FatalError); << exit(FatalError);
} }
mfIter()(fName, surf); mfIter()(name, surf);
} }
@ -178,53 +178,27 @@ Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
( (
const xfer<pointField>& pointLst, const xfer<pointField>& pointLst,
const xfer<List<Face> >& faceLst, const xfer<List<Face> >& faceLst,
const xfer<List<label> >& regionIds, const UList<label>& patchSizes,
const Map<word>& regionNames const UList<word>& patchNames
)
:
ParentType(pointLst, faceLst),
regions_(regionIds)
{
if (&regionNames)
{
// set patch names from (id => name) mapping
setPatches(regionNames);
}
else
{
// find highest region ID and set patch names automatically
setPatches();
}
}
template<class Face>
Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
(
const xfer<pointField>& pointLst,
const xfer<List<Face> >& faceLst,
const xfer<List<label> >& regionIds,
const HashTable<label>& labelToRegion
)
:
ParentType(pointLst, faceLst),
regions_(regionIds)
{
// set patch names from (name => id) mapping
setPatches(labelToRegion);
}
template<class Face>
Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
(
const xfer<pointField>& pointLst,
const xfer<List<Face> >& faceLst
) )
: :
ParentType(pointLst, faceLst) ParentType(pointLst, faceLst)
{ {
onePatch(); if (&patchSizes)
{
if (&patchNames)
{
setPatches(patchSizes, patchNames);
}
else
{
setPatches(patchSizes);
}
}
else
{
onePatch();
}
} }
@ -249,39 +223,25 @@ Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
: :
ParentType(xferCopy(surf.points()), xferCopy(surf.faces())) ParentType(xferCopy(surf.points()), xferCopy(surf.faces()))
{ {
const surfGroupList& patchLst = surf.patches(); setPatches(surf.patches());
regions_.setSize(size());
patches_.setSize(patchLst.size());
label faceI = 0;
forAll(patchLst, patchI)
{
patches_[patchI] = patchLst[patchI];
forAll(patchLst[patchI], patchFaceI)
{
regions_[faceI++] = patchI;
}
}
} }
template<class Face> template<class Face>
Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
( (
const fileName& fName, const fileName& name,
const word& ext const word& ext
) )
{ {
read(fName, ext); read(name, ext);
} }
template<class Face> template<class Face>
Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface(const fileName& fName) Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface(const fileName& name)
{ {
read(fName); read(name);
} }
@ -348,92 +308,27 @@ void Foam::UnsortedMeshedSurface<Face>::onePatch()
// set single default patch // set single default patch
patches_.setSize(1); patches_.setSize(1);
patches_[0] = PatchRegionType("patch0", 0); patches_[0] = surfPatchIdentifier("patch0", 0);
}
template<class Face>
void Foam::UnsortedMeshedSurface<Face>::setPatches(const label maxPatch)
{
patches_.setSize(maxPatch+1);
forAll(patches_, patchI)
{
patches_[patchI] = PatchRegionType
(
"patch" + ::Foam::name(patchI),
patchI
);
}
}
template<class Face>
void Foam::UnsortedMeshedSurface<Face>::setPatches()
{
label maxPatch = 0;
// find the max region that occurs
forAll(regions_, faceI)
{
const label regId = regions_[faceI];
if (maxPatch < regId)
{
maxPatch = regId;
}
}
setPatches(maxPatch);
} }
template<class Face> template<class Face>
void Foam::UnsortedMeshedSurface<Face>::setPatches void Foam::UnsortedMeshedSurface<Face>::setPatches
( (
const Map<word>& regionNames, const surfGroupList& patches
const label maxPatchHint
) )
{ {
label maxPatch = maxPatchHint; regions_.setSize(size());
patches_.setSize(patches.size());
// determine max patch ID if required forAll(patches, patchI)
if (maxPatchHint < 0)
{ {
maxPatch = 0; const surfGroup& p = patches[patchI];
forAllConstIter(Map<word>, regionNames, iter)
{
if (maxPatch < iter.key())
{
maxPatch = iter.key();
}
}
}
patches_[patchI] = p;
// Info<< "setPatches with maxPatch: " << maxPatch << endl; SubList<label> subRegion(regions_, p.size(), p.start());
subRegion = patchI;
patches_.setSize(maxPatch+1);
forAll(patches_, patchI)
{
Map<word>::const_iterator findPatch = regionNames.find(patchI);
word patchName;
if (findPatch != regionNames.end())
{
patchName = findPatch();
}
else
{
patchName = "patch" + ::Foam::name(patchI);
}
patches_[patchI] = PatchRegionType
(
patchName,
patchI
);
} }
} }
@ -441,23 +336,49 @@ void Foam::UnsortedMeshedSurface<Face>::setPatches
template<class Face> template<class Face>
void Foam::UnsortedMeshedSurface<Face>::setPatches void Foam::UnsortedMeshedSurface<Face>::setPatches
( (
const HashTable<label>& groupToPatch const UList<label>& sizes,
const UList<word>& names
) )
{ {
// determine max patch Id regions_.setSize(size());
label maxPatch = 0; patches_.setSize(sizes.size());
Map<word> regionNames;
forAllConstIter(HashTable<label>, groupToPatch, iter) label start = 0;
forAll(patches_, patchI)
{ {
regionNames.insert(iter(), iter.key()); patches_[patchI] = surfPatchIdentifier(names[patchI], patchI);
if (maxPatch < iter())
{
maxPatch = iter();
}
}
setPatches(regionNames, maxPatch); SubList<label> subRegion(regions_, sizes[patchI], start);
subRegion = patchI;
start += sizes[patchI];
}
}
template<class Face>
void Foam::UnsortedMeshedSurface<Face>::setPatches
(
const UList<label>& sizes
)
{
regions_.setSize(size());
patches_.setSize(sizes.size());
label start = 0;
forAll(patches_, patchI)
{
patches_[patchI] = surfPatchIdentifier
(
word("patch") + ::Foam::name(patchI),
patchI
);
SubList<label> subRegion(regions_, sizes[patchI], start);
subRegion = patchI;
start += sizes[patchI];
}
} }
@ -473,10 +394,10 @@ void Foam::UnsortedMeshedSurface<Face>::remapRegions(List<label>& faceMap)
} }
regions_.transfer(faceMap); regions_.transfer(faceMap);
} }
faceMap.clear();
} }
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Face> template<class Face>
@ -620,43 +541,25 @@ void Foam::UnsortedMeshedSurface<Face>::transfer
MeshedSurface<Face>& surf MeshedSurface<Face>& surf
) )
{ {
surfGroupList& patchLst = surf.patches_;
reset(xferMove(surf.storedPoints()), xferMove(surf.storedFaces())); reset(xferMove(surf.storedPoints()), xferMove(surf.storedFaces()));
setPatches(surf.patches());
regions_.setSize(size());
patches_.setSize(patchLst.size());
label faceIndex = 0;
forAll(patchLst, patchI)
{
// copy info
patches_[patchI] = patchLst[patchI];
forAll(patchLst[patchI], patchFaceI)
{
regions_[faceIndex++] = patchI;
}
}
patchLst.clear();
surf.clear(); surf.clear();
} }
// Read from file, determine format from extension // Read from file, determine format from extension
template<class Face> template<class Face>
bool Foam::UnsortedMeshedSurface<Face>::read(const fileName& fName) bool Foam::UnsortedMeshedSurface<Face>::read(const fileName& name)
{ {
word ext = fName.ext(); word ext = name.ext();
if (ext == "gz") if (ext == "gz")
{ {
fileName unzipName = fName.lessExt(); fileName unzipName = name.lessExt();
return read(unzipName, unzipName.ext()); return read(unzipName, unzipName.ext());
} }
else else
{ {
return read(fName, ext); return read(name, ext);
} }
} }
@ -665,19 +568,19 @@ bool Foam::UnsortedMeshedSurface<Face>::read(const fileName& fName)
template<class Face> template<class Face>
bool Foam::UnsortedMeshedSurface<Face>::read bool Foam::UnsortedMeshedSurface<Face>::read
( (
const fileName& fName, const fileName& name,
const word& ext const word& ext
) )
{ {
// handle 'native' format directly // handle 'native' format directly
if (isNative(ext)) if (isNative(ext))
{ {
return read(IFstream(fName)()); return read(IFstream(name)());
} }
else else
{ {
// use selector mechanism // use selector mechanism
transfer(New(fName, ext)()); transfer(New(name, ext)());
return true; return true;
} }
} }
@ -713,7 +616,6 @@ void Foam::UnsortedMeshedSurface<Face>::operator=
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "UnsortedMeshedSurfaceCleanup.C"
#include "UnsortedMeshedSurfaceIO.C" #include "UnsortedMeshedSurfaceIO.C"
#include "UnsortedMeshedSurfaceNew.C" #include "UnsortedMeshedSurfaceNew.C"

View File

@ -91,9 +91,6 @@ private:
typedef PrimitiveMeshedSurface<Face> ParentType; typedef PrimitiveMeshedSurface<Face> ParentType;
typedef MeshedSurface<Face> SiblingType; typedef MeshedSurface<Face> SiblingType;
//- Typedef for type holding the region (patch) informationm
typedef surfPatchIdentifier PatchRegionType;
// Private Member Data // Private Member Data
//- The regions associated with the faces //- The regions associated with the faces
@ -101,7 +98,7 @@ private:
//- Patch information (face ordering nFaces/startFace only used //- Patch information (face ordering nFaces/startFace only used
// during reading and writing) // during reading and writing)
List<PatchRegionType> patches_; List<surfPatchIdentifier> patches_;
// Private member functions // Private member functions
@ -111,38 +108,25 @@ private:
//- Read OpenFOAM Surface format //- Read OpenFOAM Surface format
bool read(Istream&); bool read(Istream&);
//- Set new regions from faceMap
void remapRegions(List<label>& faceMap);
protected: protected:
// Protected Member functions // Protected Member functions
//- Set a single patch
void onePatch();
//- Sets default patch names based on the maximum patch number
void setPatches(const label maxPatch);
//- Finds maximum patch number and sets default patch names
void setPatches();
//- Sets patch names from hashed values (id -> name)
void setPatches
(
const Map<word>& regionNames,
const label maxPatch = -1
);
//- Sets patch names from hashed values (name -> id)
void setPatches(const HashTable<label>& groupToPatch);
//- Return non-const access to the faces //- Return non-const access to the faces
List<label>& storedRegions() List<label>& storedRegions()
{ {
return regions_; return regions_;
} }
//- Return non-const access to the patches
List<surfPatchIdentifier>& storedPatches()
{
return patches_;
}
//- Set new regions from faceMap
virtual void remapRegions(List<label>& faceMap);
public: public:
//- Runtime type information //- Runtime type information
@ -177,32 +161,14 @@ public:
const xfer<surfPatchIdentifierList>& const xfer<surfPatchIdentifierList>&
); );
//- Construct by transferring points, faces and regionIds
// with region names per map or set to default.
UnsortedMeshedSurface
(
const xfer<pointField>&,
const xfer<List<Face> >&,
const xfer<List<label> >& regionIds,
const Map<word>& regionNames = Map<word>::null()
);
//- Construct by transferring points, faces and regionIds
// with patch-names from hash
UnsortedMeshedSurface
(
const xfer<pointField>&,
const xfer<List<Face> >&,
const xfer<List<label> >& regionIds,
const HashTable<label>& labelToRegion
);
//- Construct by transferring points, faces. //- Construct by transferring points, faces.
// Set single default patch. // Use patch information, or set single default patch
UnsortedMeshedSurface UnsortedMeshedSurface
( (
const xfer<pointField>&, const xfer<pointField>&,
const xfer<List<Face> >& const xfer<List<Face> >&,
const UList<label>& patchSizes = UList<label>::null(),
const UList<word>& patchNames = UList<word>::null()
); );
//- Construct from a boundary mesh with local points/faces //- Construct from a boundary mesh with local points/faces
@ -244,9 +210,9 @@ public:
UnsortedMeshedSurface, UnsortedMeshedSurface,
fileExtension, fileExtension,
( (
const fileName& fName const fileName& name
), ),
(fName) (name)
); );
// Selectors // Selectors
@ -275,10 +241,10 @@ public:
write, write,
fileExtension, fileExtension,
( (
const fileName& fName, const fileName& name,
const UnsortedMeshedSurface<Face>& surf const UnsortedMeshedSurface<Face>& surf
), ),
(fName, surf) (name, surf)
); );
//- Write to file //- Write to file
@ -314,29 +280,24 @@ public:
// Returns patch list and sets faceMap to index within faces() // Returns patch list and sets faceMap to index within faces()
List<surfGroup> sortedRegions(labelList& faceMap) const; List<surfGroup> sortedRegions(labelList& faceMap) const;
//- Set regions to 0 and set a single patch
void onePatch();
//- Set regions and patches
void setPatches(const surfGroupList&);
//- Set regions and patches
void setPatches(const UList<label>& sizes, const UList<word>& names);
//- Set regions and patches with default names
void setPatches(const UList<label>& sizes);
// Edit // Edit
//- Clear all storage //- Clear all storage
virtual void clear(); virtual void clear();
//- Remove invalid faces
void cleanup(const bool verbose);
//- Check/fix duplicate/degenerate faces
virtual bool checkFaces(const bool verbose);
//- Join the faces by removing duplicate points.
// Returns true if any points merged
virtual bool stitchFaces
(
const scalar tol=SMALL,
const bool verbose=false
);
//- Triangulate the surface, return the number of added faces.
virtual label triangulate();
//- Return new surface. //- Return new surface.
// Returns return pointMap, faceMap from subsetMeshMap // Returns return pointMap, faceMap from subsetMeshMap
UnsortedMeshedSurface subsetMesh UnsortedMeshedSurface subsetMesh
@ -382,9 +343,9 @@ public:
virtual void write(Ostream&) const; virtual void write(Ostream&) const;
//- Generic write routine. Chooses writer based on extension. //- Generic write routine. Chooses writer based on extension.
virtual void write(const fileName& fName) const virtual void write(const fileName& name) const
{ {
write(fName, *this); write(name, *this);
} }
//- Write to database //- Write to database
@ -408,15 +369,6 @@ public:
}; };
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Specialization for holding triangulated information
template<>
inline label UnsortedMeshedSurface<triFace>::triangulate()
{
return 0;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam } // End namespace Foam

View File

@ -1,81 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "UnsortedMeshedSurface.H"
#include "mergePoints.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// Remove badly degenerate faces, double faces.
template<class Face>
void Foam::UnsortedMeshedSurface<Face>::cleanup(const bool verbose)
{
// merge points (already done for STL, TRI)
stitchFaces(SMALL, verbose);
checkFaces(verbose);
ParentType::checkEdges(verbose);
}
template<class Face>
bool Foam::UnsortedMeshedSurface<Face>::stitchFaces
(
const scalar tol,
const bool verbose
)
{
List<label> faceMap;
bool hasMerged = ParentType::stitchFaces(faceMap, tol, verbose);
remapRegions(faceMap);
return hasMerged;
}
// Remove badly degenerate faces and double faces.
template<class Face>
bool Foam::UnsortedMeshedSurface<Face>::checkFaces(const bool verbose)
{
List<label> faceMap;
bool changed = ParentType::checkFaces(faceMap, verbose);
remapRegions(faceMap);
return changed;
}
template<class Face>
Foam::label Foam::UnsortedMeshedSurface<Face>::triangulate()
{
List<label> faceMap;
label nTri = ParentType::triangulate(this->storedFaces(), faceMap);
remapRegions(faceMap);
return nTri;
}
// ************************************************************************* //

View File

@ -31,16 +31,11 @@ License
template<class Face> template<class Face>
Foam::autoPtr<Foam::UnsortedMeshedSurface<Face> > Foam::autoPtr<Foam::UnsortedMeshedSurface<Face> >
Foam::UnsortedMeshedSurface<Face>::New Foam::UnsortedMeshedSurface<Face>::New(const fileName& name, const word& ext)
(
const fileName& fName,
const word& ext
)
{ {
if (debug) if (debug)
{ {
Info<< "UnsortedMeshedSurface<Face>::New" Info<< "UnsortedMeshedSurface::New(const fileName&, const word&) : "
"(const fileName&, const word&) : "
"constructing UnsortedMeshedSurface" "constructing UnsortedMeshedSurface"
<< endl; << endl;
} }
@ -59,7 +54,7 @@ Foam::UnsortedMeshedSurface<Face>::New
( (
new UnsortedMeshedSurface<Face> new UnsortedMeshedSurface<Face>
); );
surf().transfer(SiblingType::New(fName, ext)()); surf().transfer(SiblingType::New(name, ext)());
return surf; return surf;
} }
@ -79,24 +74,21 @@ Foam::UnsortedMeshedSurface<Face>::New
<< exit(FatalError); << exit(FatalError);
} }
return autoPtr<UnsortedMeshedSurface<Face> >(cstrIter()(fName)); return autoPtr<UnsortedMeshedSurface<Face> >(cstrIter()(name));
} }
template<class Face> template<class Face>
Foam::autoPtr<Foam::UnsortedMeshedSurface<Face> > Foam::autoPtr<Foam::UnsortedMeshedSurface<Face> >
Foam::UnsortedMeshedSurface<Face>::New Foam::UnsortedMeshedSurface<Face>::New(const fileName& name)
(
const fileName& fName
)
{ {
word ext = fName.ext(); word ext = name.ext();
if (ext == "gz") if (ext == "gz")
{ {
ext = fName.lessExt().ext(); ext = name.lessExt().ext();
} }
return New(fName, ext); return New(name, ext);
} }
// ************************************************************************* // // ************************************************************************* //

View File

@ -41,10 +41,10 @@ License
template<class Face> template<class Face>
Foam::fileFormats::AC3DsurfaceFormat<Face>::AC3DsurfaceFormat Foam::fileFormats::AC3DsurfaceFormat<Face>::AC3DsurfaceFormat
( (
const fileName& fName const fileName& filename
) )
{ {
read(fName); read(filename);
} }
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
@ -52,20 +52,20 @@ Foam::fileFormats::AC3DsurfaceFormat<Face>::AC3DsurfaceFormat
template<class Face> template<class Face>
bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
( (
const fileName& fName const fileName& filename
) )
{ {
const bool mustTriangulate = this->isTri(); const bool mustTriangulate = this->isTri();
this->clear(); this->clear();
IFstream is(fName); IFstream is(filename);
if (!is.good()) if (!is.good())
{ {
FatalErrorIn FatalErrorIn
( (
"fileFormats::AC3DsurfaceFormat::read(const fileName&)" "fileFormats::AC3DsurfaceFormat::read(const fileName&)"
) )
<< "Cannot read file " << fName << "Cannot read file " << filename
<< exit(FatalError); << exit(FatalError);
} }
@ -81,7 +81,7 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
( (
"fileFormats::AC3DsurfaceFormat::read(const fileName&)" "fileFormats::AC3DsurfaceFormat::read(const fileName&)"
) )
<< "When reading AC3D file " << fName << "When reading AC3D file " << filename
<< " read header " << line << " with version " << " read header " << line << " with version "
<< version << endl << version << endl
<< "Only tested reading with version 'b'." << "Only tested reading with version 'b'."
@ -95,7 +95,7 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
( (
"fileFormats::AC3DsurfaceFormat::read(const fileName&)" "fileFormats::AC3DsurfaceFormat::read(const fileName&)"
) )
<< "Cannot find \"OBJECT world\" in file " << fName << "Cannot find \"OBJECT world\" in file " << filename
<< exit(FatalError); << exit(FatalError);
} }
@ -108,13 +108,14 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
DynamicList<point> dynPoints; DynamicList<point> dynPoints;
DynamicList<Face> dynFaces; DynamicList<Face> dynFaces;
List<label> sizes(nPatches, 0); List<word> names(nPatches);
List<label> sizes(nPatches, 0);
for (label patchI = 0; patchI < nPatches; ++patchI) for (label patchI = 0; patchI < nPatches; ++patchI)
{ {
word patchName = word("patch") + Foam::name(patchI); names[patchI] = word("patch") + Foam::name(patchI);
args = cueToOrDie(is, "OBJECT", "while reading " + patchName); args = cueToOrDie(is, "OBJECT", "while reading " + names[patchI]);
// number of vertices for this patch // number of vertices for this patch
label nPatchPoints = 0; label nPatchPoints = 0;
@ -133,7 +134,7 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
"fileFormats::AC3DsurfaceFormat::read(const fileName&)" "fileFormats::AC3DsurfaceFormat::read(const fileName&)"
) )
<< "Did not read up to \"kids 0\" while reading patch " << "Did not read up to \"kids 0\" while reading patch "
<< patchI << " from file " << fName << patchI << " from file " << filename
<< exit(FatalError); << exit(FatalError);
} }
@ -143,7 +144,7 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
string str = parse<string>(args); string str = parse<string>(args);
string::stripInvalid<word>(str); string::stripInvalid<word>(str);
patchName = str; names[patchI] = str;
} }
else if (cmd == "rot") else if (cmd == "rot")
{ {
@ -203,7 +204,7 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
string(" while reading face ") string(" while reading face ")
+ Foam::name(faceI) + " on patch " + Foam::name(faceI) + " on patch "
+ Foam::name(patchI) + Foam::name(patchI)
+ " from file " + fName; + " from file " + filename;
cueToOrDie(is, "SURF", errorMsg); cueToOrDie(is, "SURF", errorMsg);
cueToOrDie(is, "mat", errorMsg); cueToOrDie(is, "mat", errorMsg);
@ -277,7 +278,8 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
this->storedPoints().transfer(dynPoints); this->storedPoints().transfer(dynPoints);
this->storedFaces().transfer(dynFaces); this->storedFaces().transfer(dynFaces);
this->addPatches(sizes); // add patches, culling empty groups
this->addPatches(sizes, names, true);
this->stitchFaces(SMALL); this->stitchFaces(SMALL);
return true; return true;
} }

View File

@ -83,14 +83,11 @@ public:
// Selectors // Selectors
//- Read file and return surface //- Read file and return surface
static autoPtr<MeshedSurface<Face> > New static autoPtr<MeshedSurface<Face> > New(const fileName& name)
(
const fileName& fName
)
{ {
return autoPtr<MeshedSurface<Face> > return autoPtr<MeshedSurface<Face> >
( (
new AC3DsurfaceFormat<Face>(fName) new AC3DsurfaceFormat<Face>(name)
); );
} }
@ -115,11 +112,11 @@ public:
//- Write MeshedSurface //- Write MeshedSurface
static void write static void write
( (
const fileName& fName, const fileName& name,
const MeshedSurface<Face>& surf const MeshedSurface<Face>& surf
) )
{ {
write(OFstream(fName)(), surf); write(OFstream(name)(), surf);
} }
//- Write UnsortedMeshedSurface //- Write UnsortedMeshedSurface
@ -134,11 +131,11 @@ public:
// The output is always sorted by regions. // The output is always sorted by regions.
static void write static void write
( (
const fileName& fName, const fileName& name,
const UnsortedMeshedSurface<Face>& surf const UnsortedMeshedSurface<Face>& surf
) )
{ {
write(OFstream(fName)(), surf); write(OFstream(name)(), surf);
} }
//- Write object //- Write object

View File

@ -35,10 +35,10 @@ License
template<class Face> template<class Face>
Foam::fileFormats::FTRsurfaceFormat<Face>::FTRsurfaceFormat Foam::fileFormats::FTRsurfaceFormat<Face>::FTRsurfaceFormat
( (
const fileName& fName const fileName& filename
) )
{ {
read(fName); read(filename);
} }
@ -47,19 +47,19 @@ Foam::fileFormats::FTRsurfaceFormat<Face>::FTRsurfaceFormat
template<class Face> template<class Face>
bool Foam::fileFormats::FTRsurfaceFormat<Face>::read bool Foam::fileFormats::FTRsurfaceFormat<Face>::read
( (
const fileName& fName const fileName& filename
) )
{ {
this->clear(); this->clear();
IFstream is(fName); IFstream is(filename);
if (!is.good()) if (!is.good())
{ {
FatalErrorIn FatalErrorIn
( (
"fileFormats::FTRsurfaceFormat::read(const fileName&)" "fileFormats::FTRsurfaceFormat::read(const fileName&)"
) )
<< "Cannot read file " << fName << "Cannot read file " << filename
<< exit(FatalError); << exit(FatalError);
} }
@ -85,13 +85,18 @@ bool Foam::fileFormats::FTRsurfaceFormat<Face>::read
this->storedFaces().transfer(faceLst); this->storedFaces().transfer(faceLst);
this->storedRegions().transfer(regionLst); this->storedRegions().transfer(regionLst);
Map<word> regionNames; // cast ftrPatch into new form
forAll(readPatches, patchI) List<surfPatchIdentifier> newPatches(readPatches.size());
forAll(newPatches, patchI)
{ {
regionNames.insert(patchI, readPatches[patchI].name()); newPatches[patchI] = surfPatchIdentifier
(
readPatches[patchI].name(),
patchI
);
} }
this->setPatches(regionNames, readPatches.size() - 1); this->storedPatches().transfer(newPatches);
return true; return true;
} }

View File

@ -99,14 +99,11 @@ public:
// Selectors // Selectors
//- Read file and return surface //- Read file and return surface
static autoPtr<UnsortedMeshedSurface<Face> > New static autoPtr<UnsortedMeshedSurface<Face> > New(const fileName& name)
(
const fileName& fName
)
{ {
return autoPtr<UnsortedMeshedSurface<Face> > return autoPtr<UnsortedMeshedSurface<Face> >
( (
new FTRsurfaceFormat<Face>(fName) new FTRsurfaceFormat<Face>(name)
); );
} }

View File

@ -38,10 +38,10 @@ License
template<class Face> template<class Face>
Foam::fileFormats::GTSsurfaceFormat<Face>::GTSsurfaceFormat Foam::fileFormats::GTSsurfaceFormat<Face>::GTSsurfaceFormat
( (
const fileName& fName const fileName& filename
) )
{ {
read(fName); read(filename);
} }
@ -50,19 +50,19 @@ Foam::fileFormats::GTSsurfaceFormat<Face>::GTSsurfaceFormat
template<class Face> template<class Face>
bool Foam::fileFormats::GTSsurfaceFormat<Face>::read bool Foam::fileFormats::GTSsurfaceFormat<Face>::read
( (
const fileName& fName const fileName& filename
) )
{ {
this->clear(); this->clear();
IFstream is(fName); IFstream is(filename);
if (!is.good()) if (!is.good())
{ {
FatalErrorIn FatalErrorIn
( (
"fileFormats::GTSsurfaceFormat::read(const fileName&)" "fileFormats::GTSsurfaceFormat::read(const fileName&)"
) )
<< "Cannot read file " << fName << "Cannot read file " << filename
<< exit(FatalError); << exit(FatalError);
} }
@ -205,111 +205,22 @@ bool Foam::fileFormats::GTSsurfaceFormat<Face>::read
regionLst[faceI] = regionI; regionLst[faceI] = regionI;
} }
this->setPatches(maxPatch);
// this->stitchFaces(SMALL); List<surfPatchIdentifier> newPatches(maxPatch+1);
forAll(newPatches, patchI)
{
newPatches[patchI] = surfPatchIdentifier
(
"patch" + ::Foam::name(patchI),
patchI
);
}
this->storedPatches().transfer(newPatches);
return true; return true;
} }
template<class Face>
void Foam::fileFormats::GTSsurfaceFormat<Face>::write
(
Ostream& os,
const UnsortedMeshedSurface<Face>& surf
)
{
const pointField& pointLst = surf.points();
const List<Face>& faceLst = surf.faces();
// check if output triangulation would be required
// It is too annoying to triangulate on-the-fly
// just issue a warning and get out
if (!surf.isTri())
{
label nNonTris = 0;
forAll(faceLst, faceI)
{
if (faceLst[faceI].size() != 3)
{
++nNonTris;
}
}
if (nNonTris)
{
FatalErrorIn
(
"fileFormats::GTSsurfaceFormat::write"
"(Ostream&, const UnsortedMeshedSurfaces<Face>&)"
)
<< "Surface has " << nNonTris << "/" << faceLst.size()
<< " non-triangulated faces - not writing!" << endl;
return;
}
}
labelList faceMap;
List<surfGroup> patchLst = surf.sortedRegions(faceMap);
// Write header, print patch names as comment
os << "# GTS file" << nl
<< "# Regions:" << nl;
forAll(patchLst, patchI)
{
os << "# " << patchI << " "
<< patchLst[patchI].name() << nl;
}
os << "#" << endl;
os << "# nPoints nEdges nTriangles" << nl
<< pointLst.size() << ' ' << surf.nEdges() << ' '
<< surf.size() << endl;
// Write vertex coords
forAll(pointLst, pointI)
{
os << pointLst[pointI].x() << ' '
<< pointLst[pointI].y() << ' '
<< pointLst[pointI].z() << endl;
}
// Write edges.
// Note: edges are in local point labels so convert
const edgeList& es = surf.edges();
const labelList& meshPts = surf.meshPoints();
forAll(es, edgeI)
{
os << meshPts[es[edgeI].start()] + 1 << ' '
<< meshPts[es[edgeI].end()] + 1 << endl;
}
// Write faces in terms of edges.
const labelListList& faceEs = surf.faceEdges();
label faceIndex = 0;
forAll(patchLst, patchI)
{
forAll(patchLst[patchI], patchFaceI)
{
const labelList& fEdges = faceEs[faceMap[faceIndex++]];
os << fEdges[0] + 1 << ' '
<< fEdges[1] + 1 << ' '
<< fEdges[2] + 1 << ' '
<< patchI << endl;
}
}
}
template<class Face> template<class Face>
void Foam::fileFormats::GTSsurfaceFormat<Face>::write void Foam::fileFormats::GTSsurfaceFormat<Face>::write
( (
@ -406,4 +317,101 @@ void Foam::fileFormats::GTSsurfaceFormat<Face>::write
} }
} }
template<class Face>
void Foam::fileFormats::GTSsurfaceFormat<Face>::write
(
Ostream& os,
const UnsortedMeshedSurface<Face>& surf
)
{
const pointField& pointLst = surf.points();
const List<Face>& faceLst = surf.faces();
const List<label>& regionLst = surf.regions();
const List<surfPatchIdentifier>& patchInfo = surf.patches();
// check if output triangulation would be required
// It is too annoying to triangulate on-the-fly
// just issue a warning and get out
if (!surf.isTri())
{
label nNonTris = 0;
forAll(faceLst, faceI)
{
if (faceLst[faceI].size() != 3)
{
++nNonTris;
}
}
if (nNonTris)
{
FatalErrorIn
(
"fileFormats::GTSsurfaceFormat::write"
"(Ostream&, const UnsortedMeshedSurfaces<Face>&)"
)
<< "Surface has " << nNonTris << "/" << faceLst.size()
<< " non-triangulated faces - not writing!" << endl;
return;
}
}
labelList faceMap;
List<surfGroup> patchLst = surf.sortedRegions(faceMap);
// Write header, print patch names as comment
os << "# GTS file" << nl
<< "# Regions:" << nl;
forAll(patchInfo, patchI)
{
os << "# " << patchI << " "
<< patchInfo[patchI].name() << nl;
}
os << "#" << endl;
os << "# nPoints nEdges nTriangles" << nl
<< pointLst.size() << ' ' << surf.nEdges() << ' '
<< surf.size() << endl;
// Write vertex coords
forAll(pointLst, pointI)
{
os << pointLst[pointI].x() << ' '
<< pointLst[pointI].y() << ' '
<< pointLst[pointI].z() << endl;
}
// Write edges.
// Note: edges are in local point labels so convert
const edgeList& es = surf.edges();
const labelList& meshPts = surf.meshPoints();
forAll(es, edgeI)
{
os << meshPts[es[edgeI].start()] + 1 << ' '
<< meshPts[es[edgeI].end()] + 1 << endl;
}
// Write faces in terms of edges.
const labelListList& faceEs = surf.faceEdges();
forAll(faceLst, faceI)
{
const labelList& fEdges = faceEs[faceI];
os << fEdges[0] + 1 << ' '
<< fEdges[1] + 1 << ' '
<< fEdges[2] + 1 << ' '
<< regionLst[faceI] << endl;
}
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -27,6 +27,7 @@ Class
Description Description
Provide a means of reading/writing GTS format. Provide a means of reading/writing GTS format.
The output is never sorted by patch.
SourceFiles SourceFiles
GTSsurfaceFormat.C GTSsurfaceFormat.C
@ -75,14 +76,11 @@ public:
// Selectors // Selectors
//- Read file and return surface //- Read file and return surface
static autoPtr<UnsortedMeshedSurface<Face> > New static autoPtr<UnsortedMeshedSurface<Face> > New(const fileName& name)
(
const fileName& fName
)
{ {
return autoPtr<UnsortedMeshedSurface<Face> > return autoPtr<UnsortedMeshedSurface<Face> >
( (
new GTSsurfaceFormat<Face>(fName) new GTSsurfaceFormat<Face>(name)
); );
} }
@ -105,15 +103,15 @@ public:
//- Write MeshedSurface //- Write MeshedSurface
static void write static void write
( (
const fileName& fName, const fileName& name,
const MeshedSurface<Face>& surf const MeshedSurface<Face>& surf
) )
{ {
write(OFstream(fName)(), surf); write(OFstream(name)(), surf);
} }
//- Write UnsortedMeshedSurface //- Write UnsortedMeshedSurface
// The output is sorted by regions // The output remains unsorted
static void write static void write
( (
Ostream&, Ostream&,
@ -121,14 +119,14 @@ public:
); );
//- Write UnsortedMeshedSurface //- Write UnsortedMeshedSurface
// The output is sorted by regions // The output remains unsorted
static void write static void write
( (
const fileName& fName, const fileName& name,
const UnsortedMeshedSurface<Face>& surf const UnsortedMeshedSurface<Face>& surf
) )
{ {
write(OFstream(fName)(), surf); write(OFstream(name)(), surf);
} }
//- Write object //- Write object

View File

@ -38,10 +38,10 @@ License
template<class Face> template<class Face>
Foam::fileFormats::NASsurfaceFormat<Face>::NASsurfaceFormat Foam::fileFormats::NASsurfaceFormat<Face>::NASsurfaceFormat
( (
const fileName& fName const fileName& filename
) )
{ {
read(fName); read(filename);
} }
@ -50,43 +50,44 @@ Foam::fileFormats::NASsurfaceFormat<Face>::NASsurfaceFormat
template<class Face> template<class Face>
bool Foam::fileFormats::NASsurfaceFormat<Face>::read bool Foam::fileFormats::NASsurfaceFormat<Face>::read
( (
const fileName& fName const fileName& filename
) )
{ {
const bool mustTriangulate = this->isTri(); const bool mustTriangulate = this->isTri();
this->clear(); this->clear();
IFstream is(fName); IFstream is(filename);
if (!is.good()) if (!is.good())
{ {
FatalErrorIn FatalErrorIn
( (
"fileFormats::NASsurfaceFormat::read(const fileName&)" "fileFormats::NASsurfaceFormat::read(const fileName&)"
) )
<< "Cannot read file " << fName << "Cannot read file " << filename
<< exit(FatalError); << exit(FatalError);
} }
DynamicList<point> pointLst;
// Nastran index of points // Nastran index of points
DynamicList<label> pointId; DynamicList<label> pointId;
DynamicList<Face> faceLst; DynamicList<point> dynPoints;
DynamicList<label> regionLst; DynamicList<Face> dynFaces;
HashTable<label> groupToPatch; DynamicList<label> dynRegions;
DynamicList<label> dynSizes;
Map<label> lookup;
// From face groupId to patchId // assume the types are not intermixed
Map<label> groupIdToPatchId; bool sorted = true;
label nPatches = 0; label regionI = 0;
// Name for face group // Name for face group
Map<word> groupIdToName; Map<word> nameLookup;
// Ansa tags. Denoted by $ANSA_NAME. These will appear just before the // Ansa tags. Denoted by $ANSA_NAME.
// first use of a type. We read them and store the pshell types which // These will appear just before the first use of a type.
// are used to name the patches. // We read them and store the PSHELL types which are used to name
// the patches.
label ansaId = -1; label ansaId = -1;
word ansaType; word ansaType, ansaName;
word ansaName;
// leave faces that didn't have a group in 0 // leave faces that didn't have a group in 0
// label groupID = 0; // label groupID = 0;
@ -134,7 +135,7 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
string::stripInvalid<word>(rawName); string::stripInvalid<word>(rawName);
ansaName = rawName; ansaName = rawName;
// Info<< "ANSA tag for NastranID:" << ansaID // Info<< "ANSA tag for NastranID:" << ansaId
// << " of type " << ansaType // << " of type " << ansaType
// << " name " << ansaName << endl; // << " name " << ansaName << endl;
} }
@ -161,9 +162,9 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
string::stripInvalid<word>(rawName); string::stripInvalid<word>(rawName);
word groupName(rawName); word groupName(rawName);
groupIdToName.insert(groupId, groupName); nameLookup.insert(groupId, groupName);
Info<< "group " << groupId << " => " << groupName << endl; // Info<< "group " << groupId << " => " << groupName << endl;
} }
@ -173,7 +174,6 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
continue; continue;
} }
// Check if character 72 is continuation // Check if character 72 is continuation
if (line.size() > 72 && line[72] == '+') if (line.size() > 72 && line[72] == '+')
{ {
@ -212,22 +212,27 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
fTri[2] = readLabel(IStringStream(line.substr(40,8))()); fTri[2] = readLabel(IStringStream(line.substr(40,8))());
// Convert groupID into patchID // Convert groupID into patchID
Map<label>::const_iterator iter = groupIdToPatchId.find(groupId); Map<label>::const_iterator fnd = lookup.find(groupId);
if (fnd != lookup.end())
label patchI;
if (iter == groupIdToPatchId.end())
{ {
patchI = nPatches++; if (regionI != fnd())
groupIdToPatchId.insert(groupId, patchI); {
Info<< "patch " << patchI << " => group " << groupId << endl; // pshell types are intermixed
sorted = false;
}
regionI = fnd();
} }
else else
{ {
patchI = iter(); regionI = dynSizes.size();
lookup.insert(groupId, regionI);
dynSizes.append(0);
// Info<< "patch" << regionI << " => group " << groupId <<endl;
} }
faceLst.append(fTri); dynFaces.append(fTri);
regionLst.append(patchI); dynRegions.append(regionI);
dynSizes[regionI]++;
} }
else if (cmd == "CQUAD4") else if (cmd == "CQUAD4")
{ {
@ -240,43 +245,39 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
fQuad[2] = readLabel(IStringStream(line.substr(40,8))()); fQuad[2] = readLabel(IStringStream(line.substr(40,8))());
fQuad[3] = readLabel(IStringStream(line.substr(48,8))()); fQuad[3] = readLabel(IStringStream(line.substr(48,8))());
// Convert group into patch // Convert groupID into patchID
Map<label>::const_iterator iter = groupIdToPatchId.find(groupId); Map<label>::const_iterator fnd = lookup.find(groupId);
if (fnd != lookup.end())
label patchI;
if (iter == groupIdToPatchId.end())
{ {
patchI = nPatches++; if (regionI != fnd())
groupIdToPatchId.insert(groupId, patchI); {
Info<< "patch " << patchI << " => group " << groupId << endl; // pshell types are intermixed
sorted = false;
}
regionI = fnd();
} }
else else
{ {
patchI = iter(); regionI = dynSizes.size();
lookup.insert(groupId, regionI);
dynSizes.append(0);
// Info<< "patch" << regionI << " => group " << groupId <<endl;
} }
if (mustTriangulate) if (mustTriangulate)
{ {
faceLst.append(triFace(f[0], f[1], f[2])); dynFaces.append(triFace(f[0], f[1], f[2]));
faceLst.append(triFace(f[0], f[2], f[3])); dynFaces.append(triFace(f[0], f[2], f[3]));
regionLst.append(patchI); dynRegions.append(regionI);
regionLst.append(patchI); dynRegions.append(regionI);
dynSizes[regionI] += 2;
} }
else else
{ {
faceLst.append(Face(f)); dynFaces.append(Face(f));
regionLst.append(patchI); dynRegions.append(regionI);
} dynSizes[regionI]++;
}
else if (cmd == "PSHELL")
{
// Read shell type since group gives patchnames.
label groupId = readLabel(IStringStream(line.substr(8,8))());
if (groupId == ansaId && ansaType == "PSHELL")
{
groupIdToName.insert(groupId, ansaName);
Info<< "group " << groupId << " => " << ansaName << endl;
} }
} }
else if (cmd == "GRID") else if (cmd == "GRID")
@ -287,7 +288,7 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
scalar z = parseNASCoord(line.substr(40, 8)); scalar z = parseNASCoord(line.substr(40, 8));
pointId.append(index); pointId.append(index);
pointLst.append(point(x, y, z)); dynPoints.append(point(x, y, z));
} }
else if (cmd == "GRID*") else if (cmd == "GRID*")
{ {
@ -309,76 +310,95 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
"fileFormats::NASsurfaceFormat::read(const fileName&)" "fileFormats::NASsurfaceFormat::read(const fileName&)"
) )
<< "Expected continuation symbol '*' when reading GRID*" << "Expected continuation symbol '*' when reading GRID*"
<< " (double precision coordinate) output" << nl << " (double precision coordinate) format" << nl
<< "Read:" << line << nl << "Read:" << line << nl
<< "File:" << is.name() << "File:" << is.name() << " line:" << is.lineNumber()
<< " line:" << is.lineNumber()
<< exit(FatalError); << exit(FatalError);
} }
scalar z = parseNASCoord(line.substr(8, 16)); scalar z = parseNASCoord(line.substr(8, 16));
pointId.append(index); pointId.append(index);
pointLst.append(point(x, y, z)); dynPoints.append(point(x, y, z));
}
else if (cmd == "PSHELL")
{
// pshell type for patch names with the Ansa extension
label groupId = readLabel(IStringStream(line.substr(8,8))());
if (groupId == ansaId && ansaType == "PSHELL")
{
nameLookup.insert(ansaId, ansaName);
// Info<< "group " << groupId << " => " << ansaName << endl;
}
} }
else if (unhandledCmd.insert(cmd)) else if (unhandledCmd.insert(cmd))
{ {
Info<< "Unhandled Nastran command " << line << nl Info<< "Unhandled Nastran command " << line << nl
<< "File:" << is.name() << "File:" << is.name() << " line:" << is.lineNumber()
<< " line:" << is.lineNumber()
<< endl; << endl;
} }
} }
Info<< "Read faces:" << faceLst.size() // Info<< "Read faces:" << dynFaces.size()
<< " points:" << pointLst.size() // << " points:" << dynPoints.size()
<< endl; // << endl;
// transfer to normal lists // transfer to normal lists
this->storedPoints().transfer(pointLst); this->storedPoints().transfer(dynPoints);
this->storedRegions().transfer(regionLst);
pointId.shrink(); pointId.shrink();
faceLst.shrink(); dynFaces.shrink();
// Build inverse mapping (NASTRAN pointId -> index)
Map<label> mapPointId(2*pointId.size());
forAll(pointId, i)
{ {
// Build inverse mapping (index to point) mapPointId.insert(pointId[i], i);
Map<label> nasToFoamPoint(2*pointId.size()); }
forAll(pointId, i)
// Relabel faces
// ~~~~~~~~~~~~~
forAll(dynFaces, i)
{
Face& f = dynFaces[i];
forAll(f, fp)
{ {
nasToFoamPoint.insert(pointId[i], i); f[fp] = mapPointId[f[fp]];
} }
pointId.clearStorage(); }
pointId.clearStorage();
mapPointId.clear();
// Relabel faces // create default patch names, or from ANSA/Hypermesh information
forAll(faceLst, i) List<word> names(dynSizes.size());
forAllConstIter(Map<label>, lookup, iter)
{
const label patchI = iter();
const label groupI = iter.key();
Map<word>::const_iterator fnd = nameLookup.find(groupI);
if (fnd != nameLookup.end())
{ {
Face& f = faceLst[i]; names[patchI] = fnd();
forAll(f, fp) }
{ else
f[fp] = nasToFoamPoint[f[fp]]; {
} names[patchI] = word("patch") + ::Foam::name(patchI);
} }
} }
// convert Nastran groupId => name to patchId => name sortFacesAndStore
Map<word> regionNames; (
forAllConstIter(Map<word>, groupIdToName, iter) xferMoveTo<List<Face> >(dynFaces),
{ xferMoveTo<List<label> >(dynRegions),
Map<label>::const_iterator iter2 = groupIdToPatchId.find(iter.key()); sorted
);
if (iter2 != groupIdToPatchId.end()) // add patches, culling empty groups
{ this->addPatches(dynSizes, names, true);
regionNames.insert(iter2.key(), iter());
}
}
// transfer to normal lists
this->storedFaces().transfer(faceLst);
this->setPatches(regionNames);
return true; return true;
} }

View File

@ -58,13 +58,13 @@ namespace fileFormats
{ {
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class NASsurfaceFormat Declaration Class NASsurfaceFormat Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
template<class Face> template<class Face>
class NASsurfaceFormat class NASsurfaceFormat
: :
public UnsortedMeshedSurface<Face>, public MeshedSurface<Face>,
public NASsurfaceFormatCore public NASsurfaceFormatCore
{ {
// Private Member Functions // Private Member Functions
@ -85,14 +85,11 @@ public:
// Selectors // Selectors
//- Read file and return surface //- Read file and return surface
static autoPtr<UnsortedMeshedSurface<Face> > New static autoPtr<MeshedSurface<Face> > New(const fileName& name)
(
const fileName& fName
)
{ {
return autoPtr<UnsortedMeshedSurface<Face> > return autoPtr<MeshedSurface<Face> >
( (
new NASsurfaceFormat<Face>(fName) new NASsurfaceFormat<Face>(name)
); );
} }

View File

@ -37,9 +37,10 @@ namespace fileFormats
{ {
// .bdf (Bulk Data Format) // .bdf (Bulk Data Format)
// .nas (Nastran)
addNamedTemplatedToRunTimeSelectionTable addNamedTemplatedToRunTimeSelectionTable
( (
UnsortedMeshedSurface, MeshedSurface,
NASsurfaceFormat, NASsurfaceFormat,
face, face,
fileExtension, fileExtension,
@ -47,25 +48,24 @@ addNamedTemplatedToRunTimeSelectionTable
); );
addNamedTemplatedToRunTimeSelectionTable addNamedTemplatedToRunTimeSelectionTable
( (
UnsortedMeshedSurface, MeshedSurface,
NASsurfaceFormat,
triFace,
fileExtension,
bdf
);
// .nas (Nastran)
addNamedTemplatedToRunTimeSelectionTable
(
UnsortedMeshedSurface,
NASsurfaceFormat, NASsurfaceFormat,
face, face,
fileExtension, fileExtension,
nas nas
); );
addNamedTemplatedToRunTimeSelectionTable addNamedTemplatedToRunTimeSelectionTable
( (
UnsortedMeshedSurface, MeshedSurface,
NASsurfaceFormat,
triFace,
fileExtension,
bdf
);
addNamedTemplatedToRunTimeSelectionTable
(
MeshedSurface,
NASsurfaceFormat, NASsurfaceFormat,
triFace, triFace,
fileExtension, fileExtension,

View File

@ -27,6 +27,7 @@ License
#include "OBJsurfaceFormat.H" #include "OBJsurfaceFormat.H"
#include "IFstream.H" #include "IFstream.H"
#include "IStringStream.H" #include "IStringStream.H"
#include "ListOps.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@ -35,10 +36,10 @@ License
template<class Face> template<class Face>
Foam::fileFormats::OBJsurfaceFormat<Face>::OBJsurfaceFormat Foam::fileFormats::OBJsurfaceFormat<Face>::OBJsurfaceFormat
( (
const fileName& fName const fileName& filename
) )
{ {
read(fName); read(filename);
} }
@ -47,31 +48,38 @@ Foam::fileFormats::OBJsurfaceFormat<Face>::OBJsurfaceFormat
template<class Face> template<class Face>
bool Foam::fileFormats::OBJsurfaceFormat<Face>::read bool Foam::fileFormats::OBJsurfaceFormat<Face>::read
( (
const fileName& fName const fileName& filename
) )
{ {
const bool mustTriangulate = this->isTri(); const bool mustTriangulate = this->isTri();
this->clear(); this->clear();
IFstream is(fName); IFstream is(filename);
if (!is.good()) if (!is.good())
{ {
FatalErrorIn FatalErrorIn
( (
"fileFormats::OBJsurfaceFormat::read(const fileName&)" "fileFormats::OBJsurfaceFormat::read(const fileName&)"
) )
<< "Cannot read file " << fName << "Cannot read file " << filename
<< exit(FatalError); << exit(FatalError);
} }
DynamicList<point> pointLst; // assume that the groups are not intermixed
DynamicList<Face> faceLst; bool sorted = true;
DynamicList<label> regionLst;
HashTable<label> groupToPatch;
// leave faces that didn't have a group in 0 DynamicList<point> dynPoints;
label groupID = 0; DynamicList<Face> dynFaces;
label maxGroupID = -1; DynamicList<label> dynRegions;
DynamicList<word> dynNames;
DynamicList<label> dynSizes;
HashTable<label> lookup;
// place faces without a group in patch0
label regionI = 0;
lookup.insert("patch0", regionI);
dynNames.append("patch0");
dynSizes.append(0);
while (is.good()) while (is.good())
{ {
@ -93,30 +101,29 @@ bool Foam::fileFormats::OBJsurfaceFormat<Face>::read
{ {
scalar x, y, z; scalar x, y, z;
lineStream >> x >> y >> z; lineStream >> x >> y >> z;
pointLst.append(point(x, y, z)); dynPoints.append(point(x, y, z));
} }
else if (cmd == "g") else if (cmd == "g")
{ {
word groupName; word name;
lineStream >> groupName; lineStream >> name;
HashTable<label>::const_iterator findGroup = HashTable<label>::const_iterator fnd = lookup.find(name);
groupToPatch.find(groupName); if (fnd != lookup.end())
if (findGroup != groupToPatch.end())
{ {
groupID = findGroup(); if (regionI != fnd())
{
// group appeared out of order
sorted = false;
}
regionI = fnd();
} }
else else
{ {
// special treatment if any initial faces were not in a group regionI = dynSizes.size();
if (maxGroupID == -1 && faceLst.size()) lookup.insert(name, regionI);
{ dynNames.append(name);
groupToPatch.insert("patch0", 0); dynSizes.append(0);
maxGroupID = 0;
}
groupID = ++maxGroupID;
groupToPatch.insert(groupName, groupID);
} }
} }
else if (cmd == "f") else if (cmd == "f")
@ -183,28 +190,72 @@ bool Foam::fileFormats::OBJsurfaceFormat<Face>::read
fTri[1] = f[fp1]; fTri[1] = f[fp1];
fTri[2] = f[fp2]; fTri[2] = f[fp2];
faceLst.append(fTri); dynFaces.append(fTri);
regionLst.append(groupID); dynRegions.append(regionI);
dynSizes[regionI]++;
} }
} }
else else
{ {
faceLst.append(Face(f)); dynFaces.append(Face(f));
regionLst.append(groupID); dynRegions.append(regionI);
dynSizes[regionI]++;
} }
} }
} }
// transfer to normal lists
this->storedPoints().transfer(pointLst);
this->storedFaces().transfer(faceLst);
this->storedRegions().transfer(regionLst);
this->setPatches(groupToPatch); // transfer to normal lists
this->storedPoints().transfer(dynPoints);
sortFacesAndStore
(
xferMoveTo<List<Face> >(dynFaces),
xferMoveTo<List<label> >(dynRegions),
sorted
);
// add patches, culling empty groups
this->addPatches(dynSizes, dynNames, true);
return true; return true;
} }
template<class Face>
void Foam::fileFormats::OBJsurfaceFormat<Face>::write
(
Ostream& os,
const MeshedSurface<Face>& surf
)
{
const List<Face>& faceLst = surf.faces();
const List<surfGroup>& patchLst = surf.patches();
writeHeader(os, surf.points(), faceLst.size(), patchLst);
label faceIndex = 0;
forAll(patchLst, patchI)
{
const surfGroup& patch = patchLst[patchI];
os << "g " << patch.name() << endl;
forAll(patch, patchFaceI)
{
const Face& f = faceLst[faceIndex++];
os << 'f';
forAll(f, fp)
{
os << ' ' << f[fp] + 1;
}
os << endl;
}
}
os << "# </faces>" << endl;
}
template<class Face> template<class Face>
void Foam::fileFormats::OBJsurfaceFormat<Face>::write void Foam::fileFormats::OBJsurfaceFormat<Face>::write
( (
@ -243,39 +294,4 @@ void Foam::fileFormats::OBJsurfaceFormat<Face>::write
os << "# </faces>" << endl; os << "# </faces>" << endl;
} }
template<class Face>
void Foam::fileFormats::OBJsurfaceFormat<Face>::write
(
Ostream& os,
const MeshedSurface<Face>& surf
)
{
const List<Face>& faceLst = surf.faces();
const List<surfGroup>& patchLst = surf.patches();
writeHeader(os, surf.points(), faceLst.size(), patchLst);
label faceIndex = 0;
forAll(patchLst, patchI)
{
const surfGroup& patch = patchLst[patchI];
os << "g " << patch.name() << endl;
forAll(patch, patchFaceI)
{
const Face& f = faceLst[faceIndex++];
os << 'f';
forAll(f, fp)
{
os << ' ' << f[fp] + 1;
}
os << endl;
}
}
os << "# </faces>" << endl;
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -58,7 +58,7 @@ namespace fileFormats
template<class Face> template<class Face>
class OBJsurfaceFormat class OBJsurfaceFormat
: :
public UnsortedMeshedSurface<Face>, public MeshedSurface<Face>,
public OBJsurfaceFormatCore public OBJsurfaceFormatCore
{ {
// Private Member Functions // Private Member Functions
@ -87,14 +87,11 @@ public:
// Selectors // Selectors
//- Read file and return surface //- Read file and return surface
static autoPtr<UnsortedMeshedSurface<Face> > New static autoPtr<MeshedSurface<Face> > New(const fileName& name)
(
const fileName& fName
)
{ {
return autoPtr<UnsortedMeshedSurface<Face> > return autoPtr<MeshedSurface<Face> >
( (
new OBJsurfaceFormat<Face>(fName) new OBJsurfaceFormat<Face>(name)
); );
} }
@ -119,11 +116,11 @@ public:
//- Write MeshedSurface //- Write MeshedSurface
static void write static void write
( (
const fileName& fName, const fileName& name,
const MeshedSurface<Face>& surf const MeshedSurface<Face>& surf
) )
{ {
write(OFstream(fName)(), surf); write(OFstream(name)(), surf);
} }
//- Write UnsortedMeshedSurface //- Write UnsortedMeshedSurface
@ -138,11 +135,11 @@ public:
// The output is sorted by regions // The output is sorted by regions
static void write static void write
( (
const fileName& fName, const fileName& name,
const UnsortedMeshedSurface<Face>& surf const UnsortedMeshedSurface<Face>& surf
) )
{ {
write(OFstream(fName)(), surf); write(OFstream(name)(), surf);
} }
//- Write object //- Write object

View File

@ -38,7 +38,7 @@ namespace fileFormats
addNamedTemplatedToRunTimeSelectionTable addNamedTemplatedToRunTimeSelectionTable
( (
UnsortedMeshedSurface, MeshedSurface,
OBJsurfaceFormat, OBJsurfaceFormat,
face, face,
fileExtension, fileExtension,
@ -46,7 +46,7 @@ addNamedTemplatedToRunTimeSelectionTable
); );
addNamedTemplatedToRunTimeSelectionTable addNamedTemplatedToRunTimeSelectionTable
( (
UnsortedMeshedSurface, MeshedSurface,
OBJsurfaceFormat, OBJsurfaceFormat,
triFace, triFace,
fileExtension, fileExtension,

View File

@ -37,10 +37,10 @@ License
template<class Face> template<class Face>
Foam::fileFormats::OFFsurfaceFormat<Face>::OFFsurfaceFormat Foam::fileFormats::OFFsurfaceFormat<Face>::OFFsurfaceFormat
( (
const fileName& fName const fileName& filename
) )
{ {
read(fName); read(filename);
} }
@ -49,20 +49,20 @@ Foam::fileFormats::OFFsurfaceFormat<Face>::OFFsurfaceFormat
template<class Face> template<class Face>
bool Foam::fileFormats::OFFsurfaceFormat<Face>::read bool Foam::fileFormats::OFFsurfaceFormat<Face>::read
( (
const fileName& fName const fileName& filename
) )
{ {
const bool mustTriangulate = this->isTri(); const bool mustTriangulate = this->isTri();
this->clear(); this->clear();
IFstream is(fName); IFstream is(filename);
if (!is.good()) if (!is.good())
{ {
FatalErrorIn FatalErrorIn
( (
"fileFormats::OFFsurfaceFormat<Face>::read(const fileName&)" "fileFormats::OFFsurfaceFormat<Face>::read(const fileName&)"
) )
<< "Cannot read file " << fName << "Cannot read file " << filename
<< exit(FatalError); << exit(FatalError);
} }
@ -74,7 +74,7 @@ bool Foam::fileFormats::OFFsurfaceFormat<Face>::read
( (
"fileFormats::OFFsurfaceFormat<Face>::read(const fileName&)" "fileFormats::OFFsurfaceFormat<Face>::read(const fileName&)"
) )
<< "OFF file " << fName << " does not start with 'OFF'" << "OFF file " << filename << " does not start with 'OFF'"
<< exit(FatalError); << exit(FatalError);
} }
@ -103,7 +103,7 @@ bool Foam::fileFormats::OFFsurfaceFormat<Face>::read
// Read faces - ignore optional region information // Read faces - ignore optional region information
// use a DynamicList for possible on-the-fly triangulation // use a DynamicList for possible on-the-fly triangulation
DynamicList<Face> faceLst(nElems); DynamicList<Face> dynFaces(nElems);
for (label faceI = 0; faceI < nElems; ++faceI) for (label faceI = 0; faceI < nElems; ++faceI)
{ {
@ -137,12 +137,12 @@ bool Foam::fileFormats::OFFsurfaceFormat<Face>::read
fTri[1] = f[fp1]; fTri[1] = f[fp1];
fTri[2] = f[fp2]; fTri[2] = f[fp2];
faceLst.append(fTri); dynFaces.append(fTri);
} }
} }
else else
{ {
faceLst.append(Face(f)); dynFaces.append(Face(f));
} }
} }
} }
@ -151,7 +151,7 @@ bool Foam::fileFormats::OFFsurfaceFormat<Face>::read
reset reset
( (
xferMove(pointLst), xferMove(pointLst),
xferMoveTo<List<Face> >(faceLst) xferMoveTo<List<Face> >(dynFaces)
); );
// no region information // no region information

View File

@ -95,14 +95,11 @@ public:
// Selectors // Selectors
//- Read file and return surface //- Read file and return surface
static autoPtr<MeshedSurface<Face> > New static autoPtr<MeshedSurface<Face> > New(const fileName& name)
(
const fileName& fName
)
{ {
return autoPtr<MeshedSurface<Face> > return autoPtr<MeshedSurface<Face> >
( (
new OFFsurfaceFormat(fName) new OFFsurfaceFormat(name)
); );
} }
@ -125,11 +122,11 @@ public:
//- Write MeshedSurface //- Write MeshedSurface
static void write static void write
( (
const fileName& fName, const fileName& name,
const MeshedSurface<Face>& surf const MeshedSurface<Face>& surf
) )
{ {
write(OFstream(fName)(), surf); write(OFstream(name)(), surf);
} }
//- Write UnsortedMeshedSurface //- Write UnsortedMeshedSurface
@ -144,11 +141,11 @@ public:
// The output is sorted by region. // The output is sorted by region.
static void write static void write
( (
const fileName& fName, const fileName& name,
const UnsortedMeshedSurface<Face>& surf const UnsortedMeshedSurface<Face>& surf
) )
{ {
write(OFstream(fName)(), surf); write(OFstream(name)(), surf);
} }
//- Write object //- Write object

View File

@ -38,6 +38,38 @@ Foam::fileFormats::SMESHsurfaceFormat<Face>::SMESHsurfaceFormat()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Face>
void Foam::fileFormats::SMESHsurfaceFormat<Face>::write
(
Ostream& os,
const MeshedSurface<Face>& surf
)
{
const List<Face>& faceLst = surf.faces();
const List<surfGroup>& patchLst = surf.patches();
writeHeader(os, surf.points(), faceLst.size());
label faceIndex = 0;
forAll(patchLst, patchI)
{
forAll(patchLst[patchI], patchFaceI)
{
const Face& f = faceLst[faceIndex++];
os << f.size();
forAll(f, fp)
{
os << ' ' << f[fp];
}
os << ' ' << patchI << endl;
}
}
writeTail(os);
}
template<class Face> template<class Face>
void Foam::fileFormats::SMESHsurfaceFormat<Face>::write void Foam::fileFormats::SMESHsurfaceFormat<Face>::write
( (
@ -72,35 +104,4 @@ void Foam::fileFormats::SMESHsurfaceFormat<Face>::write
} }
template<class Face>
void Foam::fileFormats::SMESHsurfaceFormat<Face>::write
(
Ostream& os,
const MeshedSurface<Face>& surf
)
{
const List<Face>& faceLst = surf.faces();
const List<surfGroup>& patchLst = surf.patches();
writeHeader(os, surf.points(), faceLst.size());
label faceIndex = 0;
forAll(patchLst, patchI)
{
forAll(patchLst[patchI], patchFaceI)
{
const Face& f = faceLst[faceIndex++];
os << f.size();
forAll(f, fp)
{
os << ' ' << f[fp];
}
os << ' ' << patchI << endl;
}
}
writeTail(os);
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -63,7 +63,7 @@ namespace fileFormats
template<class Face> template<class Face>
class SMESHsurfaceFormat class SMESHsurfaceFormat
: :
public UnsortedMeshedSurface<Face>, public MeshedSurface<Face>,
public SMESHsurfaceFormatCore public SMESHsurfaceFormatCore
{ {
// Private Member Functions // Private Member Functions
@ -101,11 +101,11 @@ public:
//- Write MeshedSurface //- Write MeshedSurface
static void write static void write
( (
const fileName& fName, const fileName& name,
const MeshedSurface<Face>& surf const MeshedSurface<Face>& surf
) )
{ {
write(OFstream(fName)(), surf); write(OFstream(name)(), surf);
} }
//- Write UnsortedMeshedSurface //- Write UnsortedMeshedSurface
@ -120,11 +120,11 @@ public:
// The output is sorted by region. // The output is sorted by region.
static void write static void write
( (
const fileName& fName, const fileName& name,
const UnsortedMeshedSurface<Face>& surf const UnsortedMeshedSurface<Face>& surf
) )
{ {
write(OFstream(fName)(), surf); write(OFstream(name)(), surf);
} }
//- Write object //- Write object

View File

@ -25,6 +25,7 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "STARCDsurfaceFormat.H" #include "STARCDsurfaceFormat.H"
#include "ListOps.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -69,10 +70,10 @@ inline void Foam::fileFormats::STARCDsurfaceFormat<Face>::writeShell
template<class Face> template<class Face>
Foam::fileFormats::STARCDsurfaceFormat<Face>::STARCDsurfaceFormat Foam::fileFormats::STARCDsurfaceFormat<Face>::STARCDsurfaceFormat
( (
const fileName& fName const fileName& filename
) )
{ {
read(fName); read(filename);
} }
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
@ -80,93 +81,65 @@ Foam::fileFormats::STARCDsurfaceFormat<Face>::STARCDsurfaceFormat
template<class Face> template<class Face>
bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
( (
const fileName& fName const fileName& filename
) )
{ {
const bool mustTriangulate = this->isTri(); const bool mustTriangulate = this->isTri();
this->clear(); this->clear();
fileName baseName = fName.lessExt(); fileName baseName = filename.lessExt();
autoPtr<IFstream> isPtr;
DynamicList<point> pointLst;
// STAR-CD index of points // STAR-CD index of points
DynamicList<label> pointId; List<label> pointId;
// // read points from .vrt file
// read .vrt file readPoints
// ~~~~~~~~~~~~~~ (
isPtr.reset(new IFstream(baseName + ".vrt")); IFstream(baseName + ".vrt")(),
this->storedPoints(),
pointId
);
if (!isPtr().good()) // Build inverse mapping (STAR-CD pointId -> index)
{ Map<label> mapPointId(2*pointId.size());
FatalErrorIn
(
"fileFormats::STARCDsurfaceFormat::read(const fileName&)"
)
<< "Cannot read file " << (baseName + ".vrt")
<< exit(FatalError);
}
readHeader(isPtr(), "PROSTAR_VERTEX");
label lineLabel;
while ((isPtr() >> lineLabel).good())
{
pointId.append(lineLabel);
scalar x, y, z;
isPtr() >> x >> y >> z;
pointLst.append(point(x, y, z));
}
// transfer to normal lists
this->storedPoints().transfer(pointLst);
// Build inverse mapping (index to point)
pointId.shrink();
Map<label> mapToFoamPointId(2*pointId.size());
forAll(pointId, i) forAll(pointId, i)
{ {
mapToFoamPointId.insert(pointId[i], i); mapPointId.insert(pointId[i], i);
} }
pointId.clear(); pointId.clear();
DynamicList<Face> faceLst;
DynamicList<label> regionLst;
// From face cellTableId to patchId
Map<label> cellTableToPatchId;
label nPatches = 0;
// //
// read .cel file // read .cel file
// ~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~
isPtr.reset(new IFstream(baseName + ".cel")); IFstream is(baseName + ".cel");
if (!is.good())
if (!isPtr().good())
{ {
FatalErrorIn FatalErrorIn
( (
"fileFormats::STARCDsurfaceFormat::read(const fileName&)" "fileFormats::STARCDsurfaceFormat::read(const fileName&)"
) )
<< "Cannot read file " << (baseName + ".cel") << "Cannot read file " << is.name()
<< exit(FatalError); << exit(FatalError);
} }
readHeader(isPtr(), "PROSTAR_CELL"); readHeader(is, "PROSTAR_CELL");
label shapeId, nLabels, cellTableId, typeId; DynamicList<Face> dynFaces;
DynamicList<label> dynRegions;
DynamicList<word> dynNames;
DynamicList<label> dynSizes;
Map<label> lookup;
// assume the cellTableIds are not intermixed
bool sorted = true;
label regionI = 0;
label lineLabel, shapeId, nLabels, cellTableId, typeId;
labelList starLabels(64); labelList starLabels(64);
while ((isPtr() >> lineLabel).good()) while ((is >> lineLabel).good())
{ {
isPtr() >> shapeId >> nLabels >> cellTableId >> typeId; is >> shapeId >> nLabels >> cellTableId >> typeId;
if (nLabels > starLabels.size()) if (nLabels > starLabels.size())
{ {
@ -179,42 +152,43 @@ bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
{ {
if ((i % 8) == 0) if ((i % 8) == 0)
{ {
isPtr() >> lineLabel; is >> lineLabel;
} }
isPtr() >> starLabels[i]; is >> starLabels[i];
} }
if (typeId == starcdShellType_) if (typeId == starcdShellType_)
{ {
// Convert groupID into patchID // Convert groupID into patchID
Map<label>::const_iterator iter = Map<label>::const_iterator fnd = lookup.find(cellTableId);
cellTableToPatchId.find(cellTableId); if (fnd != lookup.end())
label patchI;
if (iter == cellTableToPatchId.end())
{ {
patchI = nPatches++; if (regionI != fnd())
{
cellTableToPatchId.insert(cellTableId, patchI); // cellTableIds are intermixed
sorted = false;
}
regionI = fnd();
} }
else else
{ {
patchI = iter(); regionI = dynSizes.size();
lookup.insert(cellTableId, regionI);
dynNames.append(word("cellTable_") + ::Foam::name(regionI));
dynSizes.append(0);
} }
SubList<label> vertices(starLabels, nLabels);
// convert orig vertex id to point label // convert orig vertex id to point label
for (label i=0; i < nLabels; ++i) forAll(vertices, i)
{ {
starLabels[i] = mapToFoamPointId[starLabels[i]]; vertices[i] = mapPointId[vertices[i]];
} }
if (mustTriangulate && nLabels > 3) if (mustTriangulate && nLabels > 3)
{ {
face f face f(vertices);
(
SubList<label>(starLabels, nLabels)
);
faceList triFaces(f.nTriangles(this->points())); faceList triFaces(f.nTriangles(this->points()));
label nTri = 0; label nTri = 0;
@ -222,47 +196,37 @@ bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
forAll(triFaces, faceI) forAll(triFaces, faceI)
{ {
// a triangle, but not yet a triFace // a triangular face, but not yet a triFace
faceLst.append dynFaces.append
( (
triFace triFace
( (
static_cast<UList<label>&>(triFaces[faceI]) static_cast<UList<label>&>(triFaces[faceI])
) )
); );
regionLst.append(patchI); dynRegions.append(regionI);
dynSizes[regionI]++;
} }
} }
else else
{ {
faceLst.append dynFaces.append(Face(vertices));
( dynRegions.append(regionI);
Face(SubList<label>(starLabels, nLabels)) dynSizes[regionI]++;
);
regionLst.append(patchI);
} }
} }
} }
mapPointId.clear();
mapToFoamPointId.clear(); sortFacesAndStore
(
// convert cellTable_N patchId => name xferMoveTo<List<Face> >(dynFaces),
Map<word> regionNames; xferMoveTo<List<label> >(dynRegions),
forAllConstIter(Map<label>, cellTableToPatchId, iter) sorted
{ );
regionNames.insert
(
iter(),
"cellTable_" + Foam::name(iter.key())
);
}
// transfer to normal lists
this->storedFaces().transfer(faceLst);
this->storedRegions().transfer(regionLst);
this->setPatches(regionNames);
// add patches, culling empty groups
this->addPatches(dynSizes, dynNames, true);
return true; return true;
} }
@ -270,51 +234,11 @@ bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
template<class Face> template<class Face>
void Foam::fileFormats::STARCDsurfaceFormat<Face>::write void Foam::fileFormats::STARCDsurfaceFormat<Face>::write
( (
const fileName& fName, const fileName& filename,
const UnsortedMeshedSurface<Face>& surf
)
{
fileName baseName = fName.lessExt();
writePoints(OFstream(baseName + ".vrt")(), surf.points());
OFstream os(baseName + ".cel");
writeHeader(os, "CELL");
const List<Face>& faceLst = surf.faces();
labelList faceMap;
List<surfGroup> patchLst = surf.sortedRegions(faceMap);
label faceIndex = 0;
forAll(patchLst, patchI)
{
const surfGroup& patch = patchLst[patchI];
forAll(patch, patchFaceI)
{
const Face& f = faceLst[faceMap[faceIndex++]];
writeShell(os, f, faceIndex, patchI + 1);
}
}
// write simple .inp file
writeCase
(
OFstream(baseName + ".inp")(),
surf.points(),
surf.size(),
patchLst
);
}
template<class Face>
void Foam::fileFormats::STARCDsurfaceFormat<Face>::write
(
const fileName& fName,
const MeshedSurface<Face>& surf const MeshedSurface<Face>& surf
) )
{ {
fileName baseName = fName.lessExt(); fileName baseName = filename.lessExt();
writePoints(OFstream(baseName + ".vrt")(), surf.points()); writePoints(OFstream(baseName + ".vrt")(), surf.points());
OFstream os(baseName + ".cel"); OFstream os(baseName + ".cel");
@ -345,4 +269,45 @@ void Foam::fileFormats::STARCDsurfaceFormat<Face>::write
); );
} }
template<class Face>
void Foam::fileFormats::STARCDsurfaceFormat<Face>::write
(
const fileName& filename,
const UnsortedMeshedSurface<Face>& surf
)
{
fileName baseName = filename.lessExt();
writePoints(OFstream(baseName + ".vrt")(), surf.points());
OFstream os(baseName + ".cel");
writeHeader(os, "CELL");
const List<Face>& faceLst = surf.faces();
labelList faceMap;
List<surfGroup> patchLst = surf.sortedRegions(faceMap);
label faceIndex = 0;
forAll(patchLst, patchI)
{
const surfGroup& patch = patchLst[patchI];
forAll(patch, patchFaceI)
{
const Face& f = faceLst[faceMap[faceIndex++]];
writeShell(os, f, faceIndex, patchI + 1);
}
}
// write simple .inp file
writeCase
(
OFstream(baseName + ".inp")(),
surf.points(),
surf.size(),
patchLst
);
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -62,7 +62,7 @@ namespace fileFormats
template<class Face> template<class Face>
class STARCDsurfaceFormat class STARCDsurfaceFormat
: :
public UnsortedMeshedSurface<Face>, public MeshedSurface<Face>,
public STARCDsurfaceFormatCore public STARCDsurfaceFormatCore
{ {
// Private Data // Private Data
@ -97,15 +97,12 @@ public:
// Selectors // Selectors
//- Read file and return keyedSurface //- Read file and return surface
static autoPtr<UnsortedMeshedSurface<Face> > New static autoPtr<MeshedSurface<Face> > New(const fileName& name)
(
const fileName& fName
)
{ {
return autoPtr<UnsortedMeshedSurface<Face> > return autoPtr<MeshedSurface<Face> >
( (
new STARCDsurfaceFormat<Face>(fName) new STARCDsurfaceFormat<Face>(name)
); );
} }

View File

@ -89,6 +89,52 @@ void Foam::fileFormats::STARCDsurfaceFormatCore::writeHeader
} }
bool Foam::fileFormats::STARCDsurfaceFormatCore::readPoints
(
IFstream& is,
pointField& points,
labelList& ids
)
{
//
// read .vrt file
// ~~~~~~~~~~~~~~
if (!is.good())
{
FatalErrorIn
(
"fileFormats::STARCDsurfaceFormatCore::readPoints(const fileName&)"
)
<< "Cannot read file " << is.name()
<< exit(FatalError);
}
readHeader(is, "PROSTAR_VERTEX");
DynamicList<point> dynPoints;
// STAR-CD index of points
DynamicList<label> dynPointId;
label lineLabel;
while ((is >> lineLabel).good())
{
scalar x, y, z;
is >> x >> y >> z;
dynPoints.append(point(x, y, z));
dynPointId.append(lineLabel);
}
points.transfer(dynPoints);
ids.transfer(dynPointId);
return true;
}
void Foam::fileFormats::STARCDsurfaceFormatCore::writePoints void Foam::fileFormats::STARCDsurfaceFormatCore::writePoints
( (
Ostream& os, Ostream& os,

View File

@ -61,6 +61,8 @@ protected:
static void writeHeader(Ostream&, const char* filetype); static void writeHeader(Ostream&, const char* filetype);
static bool readPoints(IFstream&, pointField&, labelList& ids);
static void writePoints(Ostream&, const pointField&); static void writePoints(Ostream&, const pointField&);
static void writeCase static void writeCase

View File

@ -38,7 +38,7 @@ namespace fileFormats
addNamedTemplatedToRunTimeSelectionTable addNamedTemplatedToRunTimeSelectionTable
( (
UnsortedMeshedSurface, MeshedSurface,
STARCDsurfaceFormat, STARCDsurfaceFormat,
face, face,
fileExtension, fileExtension,
@ -46,7 +46,7 @@ addNamedTemplatedToRunTimeSelectionTable
); );
addNamedTemplatedToRunTimeSelectionTable addNamedTemplatedToRunTimeSelectionTable
( (
UnsortedMeshedSurface, MeshedSurface,
STARCDsurfaceFormat, STARCDsurfaceFormat,
triFace, triFace,
fileExtension, fileExtension,

View File

@ -269,10 +269,10 @@ void Foam::fileFormats::STLsurfaceFormat<Face>::writeBINARY
template<class Face> template<class Face>
Foam::fileFormats::STLsurfaceFormat<Face>::STLsurfaceFormat Foam::fileFormats::STLsurfaceFormat<Face>::STLsurfaceFormat
( (
const fileName& fName const fileName& filename
) )
{ {
read(fName); read(filename);
} }
@ -281,13 +281,13 @@ Foam::fileFormats::STLsurfaceFormat<Face>::STLsurfaceFormat
template<class Face> template<class Face>
bool Foam::fileFormats::STLsurfaceFormat<Face>::read bool Foam::fileFormats::STLsurfaceFormat<Face>::read
( (
const fileName& fName const fileName& filename
) )
{ {
this->clear(); this->clear();
// read in the values // read in the values
STLsurfaceFormatCore reader(fName); STLsurfaceFormatCore reader(filename);
// transfer points // transfer points
this->storedPoints().transfer(reader.points()); this->storedPoints().transfer(reader.points());
@ -330,11 +330,11 @@ bool Foam::fileFormats::STLsurfaceFormat<Face>::read
if (names.size()) if (names.size())
{ {
this->addPatches(names, sizes); this->addPatches(sizes, names);
} }
else else
{ {
this->addPatches(names, sizes); this->addPatches(sizes);
} }
this->stitchFaces(SMALL); this->stitchFaces(SMALL);
@ -367,21 +367,21 @@ void Foam::fileFormats::STLsurfaceFormat<Face>::write
template<class Face> template<class Face>
void Foam::fileFormats::STLsurfaceFormat<Face>::write void Foam::fileFormats::STLsurfaceFormat<Face>::write
( (
const fileName& fName, const fileName& filename,
const UnsortedMeshedSurface<Face>& surf const UnsortedMeshedSurface<Face>& surf
) )
{ {
word ext = fName.ext(); word ext = filename.ext();
// handle 'stlb' as binary directly // handle 'stlb' as binary directly
if (ext == "stlb") if (ext == "stlb")
{ {
std::ofstream ofs(fName.c_str(), std::ios::binary); std::ofstream ofs(filename.c_str(), std::ios::binary);
writeBINARY(ofs, surf); writeBINARY(ofs, surf);
} }
else else
{ {
writeASCII(OFstream(fName)(), surf); writeASCII(OFstream(filename)(), surf);
} }
} }
@ -389,21 +389,21 @@ void Foam::fileFormats::STLsurfaceFormat<Face>::write
template<class Face> template<class Face>
void Foam::fileFormats::STLsurfaceFormat<Face>::write void Foam::fileFormats::STLsurfaceFormat<Face>::write
( (
const fileName& fName, const fileName& filename,
const MeshedSurface<Face>& surf const MeshedSurface<Face>& surf
) )
{ {
const word ext = fName.ext(); const word ext = filename.ext();
// handle 'stlb' as binary directly // handle 'stlb' as binary directly
if (ext == "stlb") if (ext == "stlb")
{ {
std::ofstream ofs(fName.c_str(), std::ios::binary); std::ofstream ofs(filename.c_str(), std::ios::binary);
writeBINARY(ofs, surf); writeBINARY(ofs, surf);
} }
else else
{ {
writeASCII(OFstream(fName)(), surf); writeASCII(OFstream(filename)(), surf);
} }
} }

View File

@ -111,14 +111,11 @@ public:
// Selectors // Selectors
//- Read file and return surface //- Read file and return surface
static autoPtr<MeshedSurface<Face> > New static autoPtr<MeshedSurface<Face> > New(const fileName& name)
(
const fileName& fName
)
{ {
return autoPtr<MeshedSurface<Face> > return autoPtr<MeshedSurface<Face> >
( (
new STLsurfaceFormat<Face>(fName) new STLsurfaceFormat<Face>(name)
); );
} }

View File

@ -42,12 +42,12 @@ License
// is detected ... this is not exactly what we want. // is detected ... this is not exactly what we want.
int Foam::fileFormats::STLsurfaceFormatCore::detectBINARY int Foam::fileFormats::STLsurfaceFormatCore::detectBINARY
( (
const fileName& fName const fileName& filename
) )
{ {
off_t fileSize = Foam::size(fName); off_t fileSize = Foam::size(filename);
IFstream ifs(fName, IOstream::BINARY); IFstream ifs(filename, IOstream::BINARY);
istream& is = ifs.stdStream(); istream& is = ifs.stdStream();
// Read the STL header // Read the STL header
@ -215,7 +215,7 @@ bool Foam::fileFormats::STLsurfaceFormatCore::readBINARY
Foam::fileFormats::STLsurfaceFormatCore::STLsurfaceFormatCore Foam::fileFormats::STLsurfaceFormatCore::STLsurfaceFormatCore
( (
const fileName& fName const fileName& filename
) )
: :
sorted_(true), sorted_(true),
@ -224,16 +224,16 @@ Foam::fileFormats::STLsurfaceFormatCore::STLsurfaceFormatCore
names_(0), names_(0),
sizes_(0) sizes_(0)
{ {
off_t fileSize = Foam::size(fName); off_t fileSize = Foam::size(filename);
// auto-detect ascii/binary // auto-detect ascii/binary
if (detectBINARY(fName)) if (detectBINARY(filename))
{ {
readBINARY(IFstream(fName, IOstream::BINARY)(), fileSize); readBINARY(IFstream(filename, IOstream::BINARY)(), fileSize);
} }
else else
{ {
readASCII(IFstream(fName)(), fileSize); readASCII(IFstream(filename)(), fileSize);
} }
} }

View File

@ -186,53 +186,53 @@ Foam::fileFormats::surfaceFormatsCore::sortedPatchRegions
// number of items, just do it ourselves // number of items, just do it ourselves
// step 1: get region sizes and store (regionId => patchI) // step 1: get region sizes and store (regionId => patchI)
Map<label> regionLookup; Map<label> lookup;
forAll(regionLst, faceI) forAll(regionLst, faceI)
{ {
const label regId = regionLst[faceI]; const label regId = regionLst[faceI];
Map<label>::iterator iter = regionLookup.find(regId); Map<label>::iterator fnd = lookup.find(regId);
if (iter == regionLookup.end()) if (fnd != lookup.end())
{ {
regionLookup.insert(regId, 1); fnd()++;
} }
else else
{ {
iter()++; lookup.insert(regId, 1);
} }
} }
// step 2: assign start/size (and name) to the newPatches // step 2: assign start/size (and name) to the newPatches
// re-use the lookup to map (regionId => patchI) // re-use the lookup to map (regionId => patchI)
surfGroupList patchLst(regionLookup.size()); surfGroupList patchLst(lookup.size());
label patchStart = 0; label start = 0;
label patchI = 0; label patchI = 0;
forAllIter(Map<label>, regionLookup, iter) forAllIter(Map<label>, lookup, iter)
{ {
label regId = iter.key(); label regId = iter.key();
word patchName; word name;
Map<word>::const_iterator iter2 = patchNames.find(regId); Map<word>::const_iterator fnd = patchNames.find(regId);
if (iter2 == patchNames.end()) if (fnd != patchNames.end())
{ {
patchName = word("patch") + ::Foam::name(patchI); name = fnd();
} }
else else
{ {
patchName = iter2(); name = word("patch") + ::Foam::name(patchI);
} }
patchLst[patchI] = surfGroup patchLst[patchI] = surfGroup
( (
patchName, name,
0, // initialize with zero size 0, // initialize with zero size
patchStart, start,
patchI patchI
); );
// increment the start for the next patch // increment the start for the next patch
// and save the (regionId => patchI) mapping // and save the (regionId => patchI) mapping
patchStart += iter(); start += iter();
iter() = patchI++; iter() = patchI++;
} }
@ -242,7 +242,7 @@ Foam::fileFormats::surfaceFormatsCore::sortedPatchRegions
forAll(regionLst, faceI) forAll(regionLst, faceI)
{ {
label patchI = regionLookup[regionLst[faceI]]; label patchI = lookup[regionLst[faceI]];
faceMap[faceI] = patchLst[patchI].start() + patchLst[patchI].size()++; faceMap[faceI] = patchLst[patchI].start() + patchLst[patchI].size()++;
} }
@ -260,7 +260,6 @@ Foam::fileFormats::surfaceFormatsCore::checkSupport
const word& functionName const word& functionName
) )
{ {
if (available.found(ext)) if (available.found(ext))
{ {
return true; return true;

View File

@ -64,10 +64,10 @@ inline void Foam::fileFormats::TRIsurfaceFormat<Face>::writeShell
template<class Face> template<class Face>
Foam::fileFormats::TRIsurfaceFormat<Face>::TRIsurfaceFormat Foam::fileFormats::TRIsurfaceFormat<Face>::TRIsurfaceFormat
( (
const fileName& fName const fileName& filename
) )
{ {
read(fName); read(filename);
} }
@ -76,13 +76,13 @@ Foam::fileFormats::TRIsurfaceFormat<Face>::TRIsurfaceFormat
template<class Face> template<class Face>
bool Foam::fileFormats::TRIsurfaceFormat<Face>::read bool Foam::fileFormats::TRIsurfaceFormat<Face>::read
( (
const fileName& fName const fileName& filename
) )
{ {
this->clear(); this->clear();
// read in the values // read in the values
TRIsurfaceFormatCore reader(fName); TRIsurfaceFormatCore reader(filename);
// transfer points // transfer points
this->storedPoints().transfer(reader.points()); this->storedPoints().transfer(reader.points());

View File

@ -88,14 +88,11 @@ public:
// Selectors // Selectors
//- Read file and return surface //- Read file and return surface
static autoPtr<MeshedSurface<Face> > New static autoPtr<MeshedSurface<Face> > New(const fileName& name)
(
const fileName& fName
)
{ {
return autoPtr<MeshedSurface<Face> > return autoPtr<MeshedSurface<Face> >
( (
new TRIsurfaceFormat<Face>(fName) new TRIsurfaceFormat<Face>(name)
); );
} }
@ -118,11 +115,11 @@ public:
//- Write MeshedSurface //- Write MeshedSurface
static void write static void write
( (
const fileName& fName, const fileName& name,
const MeshedSurface<Face>& surf const MeshedSurface<Face>& surf
) )
{ {
write(OFstream(fName)(), surf); write(OFstream(name)(), surf);
} }
//- Write UnsortedMeshedSurface //- Write UnsortedMeshedSurface
@ -137,11 +134,11 @@ public:
// By default, the output is not sorted by regions // By default, the output is not sorted by regions
static void write static void write
( (
const fileName& fName, const fileName& name,
const UnsortedMeshedSurface<Face>& surf const UnsortedMeshedSurface<Face>& surf
) )
{ {
write(OFstream(fName)(), surf); write(OFstream(name)(), surf);
} }
//- Write object //- Write object

View File

@ -38,7 +38,7 @@ License
Foam::fileFormats::TRIsurfaceFormatCore::TRIsurfaceFormatCore Foam::fileFormats::TRIsurfaceFormatCore::TRIsurfaceFormatCore
( (
const fileName& fName const fileName& filename
) )
: :
sorted_(true), sorted_(true),
@ -46,7 +46,7 @@ Foam::fileFormats::TRIsurfaceFormatCore::TRIsurfaceFormatCore
regions_(0), regions_(0),
sizes_(0) sizes_(0)
{ {
read(fName); read(filename);
} }
// * * * * * * * * * * * * * * * * Destructors * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Destructors * * * * * * * * * * * * * * * //
@ -59,20 +59,20 @@ Foam::fileFormats::TRIsurfaceFormatCore::~TRIsurfaceFormatCore()
bool Foam::fileFormats::TRIsurfaceFormatCore::read bool Foam::fileFormats::TRIsurfaceFormatCore::read
( (
const fileName& fName const fileName& filename
) )
{ {
this->clear(); this->clear();
sorted_ = true; sorted_ = true;
IFstream is(fName); IFstream is(filename);
if (!is.good()) if (!is.good())
{ {
FatalErrorIn FatalErrorIn
( (
"fileFormats::TRIsurfaceFormatCore::read(const fileName&)" "fileFormats::TRIsurfaceFormatCore::read(const fileName&)"
) )
<< "Cannot read file " << fName << "Cannot read file " << filename
<< exit(FatalError); << exit(FatalError);
} }
@ -161,19 +161,25 @@ bool Foam::fileFormats::TRIsurfaceFormatCore::read
dynSizes[regionI]++; dynSizes[regionI]++;
} }
// skip empty groups
label nPatch = 0;
forAll(dynSizes, patchI)
{
if (dynSizes[patchI])
{
if (nPatch != patchI)
{
dynSizes[nPatch] = dynSizes[patchI];
}
nPatch++;
}
}
dynSizes.setSize(nPatch);
// transfer to normal lists // transfer to normal lists
points_.transfer(dynPoints); points_.transfer(dynPoints);
regions_.transfer(dynRegions); regions_.transfer(dynRegions);
sizes_.transfer(dynSizes);
if (dynSizes[0] == 0)
{
// no ungrouped patches, copy sub-list
sizes_ = SubList<label>(dynSizes, dynSizes.size()-1, 1);
}
else
{
sizes_.transfer(dynSizes);
}
return true; return true;
} }

View File

@ -58,72 +58,6 @@ Foam::fileFormats::VTKsurfaceFormat<Face>::VTKsurfaceFormat()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Face>
void Foam::fileFormats::VTKsurfaceFormat<Face>::write
(
Ostream& os,
const UnsortedMeshedSurface<Face>& surf
)
{
const List<Face>& faceLst = surf.faces();
writeHeader(os, surf.points());
writeHeaderPolygons(os, faceLst);
bool doSort = false;
// a single region needs no sorting
if (surf.patches().size() == 1)
{
doSort = false;
}
if (doSort)
{
labelList faceMap;
List<surfGroup> patchLst = surf.sortedRegions(faceMap);
label faceIndex = 0;
forAll(patchLst, patchI)
{
forAll(patchLst[patchI], patchFaceI)
{
const Face& f = faceLst[faceMap[faceIndex++]];
os << f.size();
forAll(f, fp)
{
os << ' ' << f[fp];
}
os << ' ' << nl;
}
}
// Print region numbers
writeTail(os, patchLst);
}
else
{
labelList faceMap;
List<surfGroup> patchLst = surf.sortedRegions(faceMap);
forAll(faceLst, faceI)
{
const Face& f = faceLst[faceI];
os << f.size();
forAll(f, fp)
{
os << ' ' << f[fp];
}
os << ' ' << nl;
}
// Print region numbers
writeTail(os, surf.regions());
}
}
template<class Face> template<class Face>
void Foam::fileFormats::VTKsurfaceFormat<Face>::write void Foam::fileFormats::VTKsurfaceFormat<Face>::write
( (
@ -157,4 +91,34 @@ void Foam::fileFormats::VTKsurfaceFormat<Face>::write
writeTail(os, patchLst); writeTail(os, patchLst);
} }
template<class Face>
void Foam::fileFormats::VTKsurfaceFormat<Face>::write
(
Ostream& os,
const UnsortedMeshedSurface<Face>& surf
)
{
const List<Face>& faceLst = surf.faces();
writeHeader(os, surf.points());
writeHeaderPolygons(os, faceLst);
forAll(faceLst, faceI)
{
const Face& f = faceLst[faceI];
os << f.size();
forAll(f, fp)
{
os << ' ' << f[fp];
}
os << ' ' << nl;
}
// Print region numbers
writeTail(os, surf.regions());
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -27,6 +27,7 @@ Class
Description Description
Provide a means of writing VTK legacy format. Provide a means of writing VTK legacy format.
The output is never sorted by patch.
SourceFiles SourceFiles
VTKsurfaceFormat.C VTKsurfaceFormat.C
@ -56,7 +57,7 @@ namespace fileFormats
template<class Face> template<class Face>
class VTKsurfaceFormat class VTKsurfaceFormat
: :
public UnsortedMeshedSurface<Face>, public MeshedSurface<Face>,
public VTKsurfaceFormatCore public VTKsurfaceFormatCore
{ {
// Private Member Functions // Private Member Functions
@ -98,15 +99,15 @@ public:
//- Write MeshedSurface //- Write MeshedSurface
static void write static void write
( (
const fileName& fName, const fileName& name,
const MeshedSurface<Face>& surf const MeshedSurface<Face>& surf
) )
{ {
write(OFstream(fName)(), surf); write(OFstream(name)(), surf);
} }
//- Write UnsortedMeshedSurface //- Write UnsortedMeshedSurface
// By default, the output is not sorted by regions. // The output remains unsorted
static void write static void write
( (
Ostream&, Ostream&,
@ -114,14 +115,14 @@ public:
); );
//- Write UnsortedMeshedSurface //- Write UnsortedMeshedSurface
// By default, the output is not sorted by regions. // The output remains unsorted
static void write static void write
( (
const fileName& fName, const fileName& name,
const UnsortedMeshedSurface<Face>& surf const UnsortedMeshedSurface<Face>& surf
) )
{ {
write(OFstream(fName)(), surf); write(OFstream(name)(), surf);
} }
//- Write object //- Write object