mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
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:
@ -99,14 +99,14 @@ bool Foam::MeshedSurface<Face>::canWriteType
|
||||
template<class Face>
|
||||
bool Foam::MeshedSurface<Face>::canRead
|
||||
(
|
||||
const fileName& fName,
|
||||
const fileName& name,
|
||||
const bool verbose
|
||||
)
|
||||
{
|
||||
word ext = fName.ext();
|
||||
word ext = name.ext();
|
||||
if (ext == "gz")
|
||||
{
|
||||
ext = fName.lessExt().ext();
|
||||
ext = name.lessExt().ext();
|
||||
}
|
||||
return canReadType(ext, verbose);
|
||||
}
|
||||
@ -115,7 +115,7 @@ bool Foam::MeshedSurface<Face>::canRead
|
||||
template<class Face>
|
||||
void Foam::MeshedSurface<Face>::write
|
||||
(
|
||||
const fileName& fName,
|
||||
const fileName& name,
|
||||
const MeshedSurface& surf
|
||||
)
|
||||
{
|
||||
@ -123,16 +123,16 @@ void Foam::MeshedSurface<Face>::write
|
||||
{
|
||||
Info<< "MeshedSurface::write"
|
||||
"(const fileName&, const MeshedSurface&) : "
|
||||
"writing to " << fName
|
||||
"writing to " << name
|
||||
<< endl;
|
||||
}
|
||||
|
||||
word ext = fName.ext();
|
||||
word ext = name.ext();
|
||||
|
||||
// handle 'native' format directly
|
||||
if (isNative(ext))
|
||||
{
|
||||
surf.write(OFstream(fName)());
|
||||
surf.write(OFstream(name)());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -150,7 +150,7 @@ void Foam::MeshedSurface<Face>::write
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
mfIter()(fName, surf);
|
||||
mfIter()(name, surf);
|
||||
}
|
||||
|
||||
|
||||
@ -180,100 +180,25 @@ Foam::MeshedSurface<Face>::MeshedSurface
|
||||
const xfer<pointField>& pointLst,
|
||||
const xfer<List<Face> >& faceLst,
|
||||
const UList<label>& patchSizes,
|
||||
const UList<word>& patchNames,
|
||||
const UList<word>& patchTypes
|
||||
const UList<word>& patchNames
|
||||
)
|
||||
:
|
||||
ParentType(pointLst, faceLst)
|
||||
{
|
||||
surfGroupList newPatches(patchSizes.size());
|
||||
|
||||
label start = 0;
|
||||
forAll(newPatches, patchI)
|
||||
if (&patchSizes)
|
||||
{
|
||||
newPatches[patchI] = surfGroup
|
||||
(
|
||||
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 (®ionIds && 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 (®ionIds && 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)
|
||||
if (&patchNames)
|
||||
{
|
||||
regionNames.insert(iter(), iter.key());
|
||||
addPatches(patchSizes, patchNames);
|
||||
}
|
||||
|
||||
sortFacesByRegion(regionIds, regionNames);
|
||||
else
|
||||
{
|
||||
addPatches(patchSizes);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
onePatch();
|
||||
}
|
||||
}
|
||||
|
||||
@ -430,18 +355,18 @@ Foam::MeshedSurface<Face>::MeshedSurface
|
||||
template<class Face>
|
||||
Foam::MeshedSurface<Face>::MeshedSurface
|
||||
(
|
||||
const fileName& fName,
|
||||
const fileName& name,
|
||||
const word& ext
|
||||
)
|
||||
{
|
||||
read(fName, ext);
|
||||
read(name, ext);
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
read(IFstream(findMeshName(d))());
|
||||
// setDefaultPatches();
|
||||
}
|
||||
|
||||
|
||||
@ -567,39 +491,40 @@ void Foam::MeshedSurface<Face>::checkPatches()
|
||||
|
||||
|
||||
template<class Face>
|
||||
void Foam::MeshedSurface<Face>::sortFacesByRegion
|
||||
void Foam::MeshedSurface<Face>::sortFacesAndStore
|
||||
(
|
||||
const UList<label>& regionIds,
|
||||
const Map<word>& regionNames
|
||||
const xfer<List<Face> >& unsortedFaces,
|
||||
const xfer<List<label> >& regionIds,
|
||||
const bool sorted
|
||||
)
|
||||
{
|
||||
const List<Face>& unsortedFaces = this->faces();
|
||||
List<Face> oldFaces(unsortedFaces);
|
||||
List<label> regions(regionIds);
|
||||
|
||||
if (!®ionNames || !®ionIds || regionIds.size() == 0)
|
||||
if (sorted)
|
||||
{
|
||||
onePatch();
|
||||
// already sorted - simply transfer faces
|
||||
this->storedFaces().transfer(oldFaces);
|
||||
}
|
||||
else if (regionIds.size() == unsortedFaces.size())
|
||||
else
|
||||
{
|
||||
labelList faceMap;
|
||||
surfGroupList newPatches = UnsortedMeshedSurface<Face>::sortedRegions
|
||||
(
|
||||
regionIds,
|
||||
regionNames,
|
||||
faceMap
|
||||
);
|
||||
patches_.transfer(newPatches);
|
||||
// unsorted - determine the sorted order:
|
||||
// avoid SortableList since we discard the main list anyhow
|
||||
List<label> faceMap;
|
||||
sortedOrder(regions, faceMap);
|
||||
regions.clear();
|
||||
|
||||
// this is somewhat like ListOps reorder and/or IndirectList
|
||||
List<Face> newFaces(unsortedFaces.size());
|
||||
forAll(newFaces, faceI)
|
||||
// sorted faces
|
||||
List<Face> newFaces(faceMap.size());
|
||||
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);
|
||||
|
||||
}
|
||||
regions.clear();
|
||||
}
|
||||
|
||||
|
||||
@ -634,8 +559,8 @@ void Foam::MeshedSurface<Face>::remapRegions(List<label>& faceMap)
|
||||
// adjust patch size
|
||||
p.size() = newFaceI - p.start();
|
||||
}
|
||||
faceMap.clear();
|
||||
}
|
||||
faceMap.clear();
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
@ -662,6 +587,7 @@ Foam::MeshedSurface<Face> Foam::MeshedSurface<Face>::subsetMesh
|
||||
const pointField& locPoints = this->localPoints();
|
||||
const List<Face>& locFaces = this->localFaces();
|
||||
|
||||
|
||||
// Fill pointMap, faceMap
|
||||
this->subsetMap(include, pointMap, faceMap);
|
||||
|
||||
@ -751,58 +677,83 @@ Foam::MeshedSurface<Face> Foam::MeshedSurface<Face>::subsetMesh
|
||||
template<class Face>
|
||||
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>
|
||||
void Foam::MeshedSurface<Face>::addPatches
|
||||
(
|
||||
const UList<label>& sizes,
|
||||
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)
|
||||
{
|
||||
patches_[patchI] = surfGroup
|
||||
(
|
||||
names[patchI],
|
||||
sizes[patchI],
|
||||
start,
|
||||
patchI
|
||||
);
|
||||
|
||||
start += sizes[patchI];
|
||||
if (sizes[patchI] || !cullEmpty)
|
||||
{
|
||||
patches_[nPatch] = surfGroup
|
||||
(
|
||||
names[patchI],
|
||||
sizes[patchI],
|
||||
start,
|
||||
nPatch
|
||||
);
|
||||
start += sizes[patchI];
|
||||
nPatch++;
|
||||
}
|
||||
}
|
||||
patches_.setSize(nPatch);
|
||||
}
|
||||
|
||||
|
||||
template<class Face>
|
||||
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)
|
||||
{
|
||||
patches_[patchI] = surfGroup
|
||||
(
|
||||
word("patch") + ::Foam::name(patchI),
|
||||
sizes[patchI],
|
||||
start,
|
||||
patchI
|
||||
);
|
||||
|
||||
start += sizes[patchI];
|
||||
if (sizes[patchI] || !cullEmpty)
|
||||
{
|
||||
patches_[nPatch] = surfGroup
|
||||
(
|
||||
word("patch") + ::Foam::name(nPatch),
|
||||
sizes[patchI],
|
||||
start,
|
||||
nPatch
|
||||
);
|
||||
start += sizes[patchI];
|
||||
nPatch++;
|
||||
}
|
||||
}
|
||||
patches_.setSize(nPatch);
|
||||
}
|
||||
|
||||
|
||||
@ -829,39 +780,35 @@ void Foam::MeshedSurface<Face>::transfer
|
||||
|
||||
labelList faceMap;
|
||||
surfGroupList patchLst = surf.sortedRegions(faceMap);
|
||||
List<Face>& oldFaces = surf.storedFaces();
|
||||
|
||||
const List<Face>& oldFaces = surf.faces();
|
||||
List<Face> newFaces(oldFaces.size());
|
||||
|
||||
// this is somewhat like ListOps reorder and/or IndirectList
|
||||
forAll(newFaces, faceI)
|
||||
List<Face> newFaces(faceMap.size());
|
||||
forAll(faceMap, faceI)
|
||||
{
|
||||
newFaces[faceI] = oldFaces[faceMap[faceI]];
|
||||
newFaces[faceI].transfer(oldFaces[faceMap[faceI]]);
|
||||
}
|
||||
faceMap.clear();
|
||||
|
||||
reset(xferMove(surf.storedPoints()), xferMove(newFaces));
|
||||
patches_.transfer(patchLst);
|
||||
|
||||
surf.regions_.clear();
|
||||
surf.patches_.clear();
|
||||
surf.clear();
|
||||
}
|
||||
|
||||
|
||||
// Read from file, determine format from extension
|
||||
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")
|
||||
{
|
||||
fileName unzipName = fName.lessExt();
|
||||
fileName unzipName = name.lessExt();
|
||||
return read(unzipName, unzipName.ext());
|
||||
}
|
||||
else
|
||||
{
|
||||
return read(fName, ext);
|
||||
return read(name, ext);
|
||||
}
|
||||
}
|
||||
|
||||
@ -870,19 +817,19 @@ bool Foam::MeshedSurface<Face>::read(const fileName& fName)
|
||||
template<class Face>
|
||||
bool Foam::MeshedSurface<Face>::read
|
||||
(
|
||||
const fileName& fName,
|
||||
const fileName& name,
|
||||
const word& ext
|
||||
)
|
||||
{
|
||||
// handle 'native' format directly
|
||||
if (isNative(ext))
|
||||
{
|
||||
return read(IFstream(fName)());
|
||||
return read(IFstream(name)());
|
||||
}
|
||||
else
|
||||
{
|
||||
// use selector mechanism
|
||||
transfer(New(fName, ext)());
|
||||
transfer(New(name, ext)());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -912,7 +859,6 @@ void Foam::MeshedSurface<Face>::operator=(const MeshedSurface& surf)
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#include "MeshedSurfaceCleanup.C"
|
||||
#include "MeshedSurfaceIO.C"
|
||||
#include "MeshedSurfaceNew.C"
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@ Class
|
||||
Description
|
||||
A surface geometry mesh with patch information, not to be confused
|
||||
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.
|
||||
- A set of points and faces without any patch information.
|
||||
@ -94,12 +94,6 @@ private:
|
||||
|
||||
// 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
|
||||
bool read(Istream&);
|
||||
|
||||
@ -107,12 +101,20 @@ protected:
|
||||
|
||||
// Protected Member functions
|
||||
|
||||
//- set a single patch
|
||||
void onePatch();
|
||||
|
||||
//- basic sanity check on patches
|
||||
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:
|
||||
|
||||
//- Runtime type information
|
||||
@ -137,8 +139,7 @@ public:
|
||||
//- Construct null
|
||||
MeshedSurface();
|
||||
|
||||
//- Construct by transferring components
|
||||
// (points, faces and patches).
|
||||
//- Construct by transferring components (points, faces, patches).
|
||||
MeshedSurface
|
||||
(
|
||||
const xfer<pointField>&,
|
||||
@ -146,35 +147,14 @@ public:
|
||||
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.
|
||||
// Sort faces according to regionIds with the names of the regions,
|
||||
// or jsut set a single default patch.
|
||||
// Use patch information, or set single default patch.
|
||||
MeshedSurface
|
||||
(
|
||||
const xfer<pointField>&,
|
||||
const xfer<List<Face> >&,
|
||||
const UList<label>& regionIds = UList<label>::null(),
|
||||
const Map<word>& regionNames = Map<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
|
||||
const UList<label>& patchSizes = UList<label>::null(),
|
||||
const UList<word>& patchNames = UList<word>::null()
|
||||
);
|
||||
|
||||
//- Construct from a boundary mesh with local points/faces
|
||||
@ -219,9 +199,9 @@ public:
|
||||
MeshedSurface,
|
||||
fileExtension,
|
||||
(
|
||||
const fileName& fName
|
||||
const fileName& name
|
||||
),
|
||||
(fName)
|
||||
(name)
|
||||
);
|
||||
|
||||
// Selectors
|
||||
@ -250,10 +230,10 @@ public:
|
||||
write,
|
||||
fileExtension,
|
||||
(
|
||||
const fileName& fName,
|
||||
const fileName& name,
|
||||
const MeshedSurface<Face>& surf
|
||||
),
|
||||
(fName, surf)
|
||||
(name, surf)
|
||||
);
|
||||
|
||||
//- Write to file
|
||||
@ -275,35 +255,36 @@ public:
|
||||
return patches_;
|
||||
}
|
||||
|
||||
void addPatches(const UList<surfGroup>&);
|
||||
|
||||
void addPatches(const UList<word>& names, const UList<label>& sizes);
|
||||
void addPatches(const UList<label>& sizes);
|
||||
//- set a single patch
|
||||
void onePatch();
|
||||
|
||||
//- 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
|
||||
|
||||
//- Clear all storage
|
||||
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.
|
||||
// Returns return pointMap, faceMap from subsetMeshMap
|
||||
MeshedSurface subsetMesh
|
||||
@ -341,9 +322,9 @@ public:
|
||||
virtual void write(Ostream&) const;
|
||||
|
||||
//- 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
|
||||
@ -365,15 +346,6 @@ public:
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
//- Specialization for holding triangulated information
|
||||
template<>
|
||||
inline label MeshedSurface<triFace>::triangulate()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -29,14 +29,10 @@ License
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
// all input is indirect via UnsortedMeshedSurface
|
||||
|
||||
template<class Face>
|
||||
Foam::autoPtr<Foam::MeshedSurface<Face> >
|
||||
Foam::MeshedSurface<Face>::New
|
||||
(
|
||||
const fileName& fName,
|
||||
const word& ext
|
||||
)
|
||||
Foam::MeshedSurface<Face>::New(const fileName& name, const word& ext)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
@ -56,7 +52,7 @@ Foam::MeshedSurface<Face>::New
|
||||
{
|
||||
// create indirectly
|
||||
autoPtr<MeshedSurface<Face> > surf(new MeshedSurface<Face>);
|
||||
surf().transfer(SiblingType::New(fName, ext)());
|
||||
surf().transfer(SiblingType::New(name, ext)());
|
||||
|
||||
return surf;
|
||||
}
|
||||
@ -67,8 +63,7 @@ Foam::MeshedSurface<Face>::New
|
||||
|
||||
FatalErrorIn
|
||||
(
|
||||
"MeshedSurface<Face>::New"
|
||||
"(const fileName&, const word&) : "
|
||||
"MeshedSurface<Face>::New(const fileName&, const word&) : "
|
||||
"constructing MeshedSurface"
|
||||
) << "Unknown file extension " << ext << nl << nl
|
||||
<< "Valid types are :" << nl
|
||||
@ -76,23 +71,20 @@ Foam::MeshedSurface<Face>::New
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
return autoPtr<MeshedSurface<Face> >(cstrIter()(fName));
|
||||
return autoPtr<MeshedSurface<Face> >(cstrIter()(name));
|
||||
}
|
||||
|
||||
|
||||
template<class Face>
|
||||
Foam::autoPtr<Foam::MeshedSurface<Face> >
|
||||
Foam::MeshedSurface<Face>::New
|
||||
(
|
||||
const fileName& fName
|
||||
)
|
||||
Foam::MeshedSurface<Face>::New(const fileName& name)
|
||||
{
|
||||
word ext = fName.ext();
|
||||
word ext = name.ext();
|
||||
if (ext == "gz")
|
||||
{
|
||||
ext = fName.lessExt().ext();
|
||||
ext = name.lessExt().ext();
|
||||
}
|
||||
return New(fName, ext);
|
||||
return New(name, ext);
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -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 * * * * * * * * * * * * * * //
|
||||
|
||||
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>
|
||||
bool Foam::PrimitiveMeshedSurface<Face>::stitchFaces
|
||||
(
|
||||
List<label>& faceMap,
|
||||
const scalar tol,
|
||||
const bool verbose
|
||||
)
|
||||
@ -218,10 +160,6 @@ bool Foam::PrimitiveMeshedSurface<Face>::stitchFaces
|
||||
|
||||
if (!hasMerged)
|
||||
{
|
||||
if (&faceMap)
|
||||
{
|
||||
faceMap.clear();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -236,13 +174,7 @@ bool Foam::PrimitiveMeshedSurface<Face>::stitchFaces
|
||||
|
||||
List<Face>& faceLst = this->storedFaces();
|
||||
|
||||
// local copy
|
||||
List<label> fMap;
|
||||
if (&faceMap)
|
||||
{
|
||||
fMap.transfer(faceMap);
|
||||
}
|
||||
fMap.setSize(faceLst.size());
|
||||
List<label> faceMap(faceLst.size());
|
||||
|
||||
// Reset the point labels to the unique points array
|
||||
label newFaceI = 0;
|
||||
@ -261,7 +193,7 @@ bool Foam::PrimitiveMeshedSurface<Face>::stitchFaces
|
||||
{
|
||||
faceLst[newFaceI] = f;
|
||||
}
|
||||
fMap[newFaceI] = faceI;
|
||||
faceMap[newFaceI] = faceI;
|
||||
newFaceI++;
|
||||
}
|
||||
else if (verbose)
|
||||
@ -282,18 +214,12 @@ bool Foam::PrimitiveMeshedSurface<Face>::stitchFaces
|
||||
<< " faces" << endl;
|
||||
}
|
||||
faceLst.setSize(newFaceI);
|
||||
if (&faceMap)
|
||||
{
|
||||
faceMap.transfer(fMap);
|
||||
faceMap.setSize(newFaceI);
|
||||
}
|
||||
remapRegions(faceMap);
|
||||
}
|
||||
fMap.clear();
|
||||
|
||||
faceMap.clear();
|
||||
|
||||
// Merging points might have changed geometric factors
|
||||
ParentType::clearOut();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -302,20 +228,13 @@ bool Foam::PrimitiveMeshedSurface<Face>::stitchFaces
|
||||
template<class Face>
|
||||
bool Foam::PrimitiveMeshedSurface<Face>::checkFaces
|
||||
(
|
||||
List<label>& faceMap,
|
||||
const bool verbose
|
||||
)
|
||||
{
|
||||
bool changed = false;
|
||||
List<Face>& faceLst = this->storedFaces();
|
||||
|
||||
// local copy
|
||||
List<label> fMap;
|
||||
if (&faceMap)
|
||||
{
|
||||
fMap.transfer(faceMap);
|
||||
}
|
||||
fMap.setSize(faceLst.size());
|
||||
List<label> faceMap(faceLst.size());
|
||||
|
||||
label newFaceI = 0;
|
||||
// Detect badly labelled faces and mark degenerate faces
|
||||
@ -339,13 +258,13 @@ bool Foam::PrimitiveMeshedSurface<Face>::checkFaces
|
||||
}
|
||||
}
|
||||
|
||||
fMap[faceI] = faceI;
|
||||
faceMap[faceI] = faceI;
|
||||
newFaceI++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// mark as bad face
|
||||
fMap[faceI] = -1;
|
||||
faceMap[faceI] = -1;
|
||||
|
||||
changed = true;
|
||||
if (verbose)
|
||||
@ -366,7 +285,7 @@ bool Foam::PrimitiveMeshedSurface<Face>::checkFaces
|
||||
forAll(faceLst, faceI)
|
||||
{
|
||||
// skip already collapsed faces:
|
||||
if (fMap[faceI] < 0)
|
||||
if (faceMap[faceI] < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -383,7 +302,7 @@ bool Foam::PrimitiveMeshedSurface<Face>::checkFaces
|
||||
{
|
||||
const label neiFaceI = neighbours[neighI];
|
||||
|
||||
if (neiFaceI <= faceI || fMap[neiFaceI] < 0)
|
||||
if (neiFaceI <= faceI || faceMap[neiFaceI] < 0)
|
||||
{
|
||||
// lower numbered faces already checked
|
||||
// skip neighbours that are themselves collapsed
|
||||
@ -414,12 +333,12 @@ bool Foam::PrimitiveMeshedSurface<Face>::checkFaces
|
||||
|
||||
if (okay)
|
||||
{
|
||||
fMap[faceI] = faceI;
|
||||
faceMap[faceI] = faceI;
|
||||
newFaceI++;
|
||||
}
|
||||
else
|
||||
{
|
||||
fMap[faceI] = -1;
|
||||
faceMap[faceI] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -443,33 +362,94 @@ bool Foam::PrimitiveMeshedSurface<Face>::checkFaces
|
||||
newFaceI = 0;
|
||||
forAll(faceLst, faceI)
|
||||
{
|
||||
if (fMap[faceI] >= 0)
|
||||
if (faceMap[faceI] >= 0)
|
||||
{
|
||||
if (newFaceI != faceI)
|
||||
{
|
||||
faceLst[newFaceI] = faceLst[faceI];
|
||||
}
|
||||
fMap[newFaceI] = faceI;
|
||||
faceMap[newFaceI] = faceI;
|
||||
newFaceI++;
|
||||
}
|
||||
}
|
||||
|
||||
faceLst.setSize(newFaceI);
|
||||
if (&faceMap)
|
||||
{
|
||||
faceMap.transfer(fMap);
|
||||
faceMap.setSize(newFaceI);
|
||||
}
|
||||
remapRegions(faceMap);
|
||||
}
|
||||
fMap.clear();
|
||||
faceMap.clear();
|
||||
|
||||
// Topology can change because of renumbering
|
||||
ParentType::clearOut();
|
||||
|
||||
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 * * * * * * * * * * * * * //
|
||||
|
||||
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
|
||||
|
||||
@ -84,6 +84,9 @@ protected:
|
||||
return static_cast<List<Face> &>(*this);
|
||||
}
|
||||
|
||||
//- Set new regions/patches from faceMap
|
||||
virtual void remapRegions(List<label>& faceMap);
|
||||
|
||||
public:
|
||||
|
||||
// Static
|
||||
@ -91,15 +94,6 @@ public:
|
||||
//- Face storage only handles triangulated faces
|
||||
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
|
||||
|
||||
//- Construct null
|
||||
@ -144,19 +138,24 @@ public:
|
||||
const xfer<List<Face> >&
|
||||
);
|
||||
|
||||
//- Remove invalid faces
|
||||
virtual void cleanup(const bool verbose);
|
||||
|
||||
virtual bool stitchFaces
|
||||
(
|
||||
List<label>& faceMap=const_cast<List<label>&>(List<label>::null()),
|
||||
const scalar tol=SMALL,
|
||||
const bool verbose=false
|
||||
);
|
||||
|
||||
virtual bool checkFaces
|
||||
(
|
||||
List<label>& faceMap=const_cast<List<label>&>(List<label>::null()),
|
||||
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;
|
||||
}
|
||||
|
||||
//- Specialization for holding triangulated information
|
||||
template<>
|
||||
inline label PrimitiveMeshedSurface<triFace>::triangulate()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
@ -95,14 +95,14 @@ bool Foam::UnsortedMeshedSurface<Face>::canWriteType
|
||||
template<class Face>
|
||||
bool Foam::UnsortedMeshedSurface<Face>::canRead
|
||||
(
|
||||
const fileName& fName,
|
||||
const fileName& name,
|
||||
const bool verbose
|
||||
)
|
||||
{
|
||||
word ext = fName.ext();
|
||||
word ext = name.ext();
|
||||
if (ext == "gz")
|
||||
{
|
||||
ext = fName.lessExt().ext();
|
||||
ext = name.lessExt().ext();
|
||||
}
|
||||
return canReadType(ext, verbose);
|
||||
}
|
||||
@ -111,7 +111,7 @@ bool Foam::UnsortedMeshedSurface<Face>::canRead
|
||||
template<class Face>
|
||||
void Foam::UnsortedMeshedSurface<Face>::write
|
||||
(
|
||||
const fileName& fName,
|
||||
const fileName& name,
|
||||
const UnsortedMeshedSurface<Face>& surf
|
||||
)
|
||||
{
|
||||
@ -119,16 +119,16 @@ void Foam::UnsortedMeshedSurface<Face>::write
|
||||
{
|
||||
Info<< "UnsortedMeshedSurface::write"
|
||||
"(const fileName&, const UnsortedMeshedSurface&) : "
|
||||
"writing to " << fName
|
||||
"writing to " << name
|
||||
<< endl;
|
||||
}
|
||||
|
||||
const word ext = fName.ext();
|
||||
const word ext = name.ext();
|
||||
|
||||
// handle 'native' format directly
|
||||
if (isNative(ext))
|
||||
{
|
||||
surf.write(OFstream(fName)());
|
||||
surf.write(OFstream(name)());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -147,7 +147,7 @@ void Foam::UnsortedMeshedSurface<Face>::write
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
mfIter()(fName, surf);
|
||||
mfIter()(name, surf);
|
||||
}
|
||||
|
||||
|
||||
@ -178,53 +178,27 @@ Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
|
||||
(
|
||||
const xfer<pointField>& pointLst,
|
||||
const xfer<List<Face> >& faceLst,
|
||||
const xfer<List<label> >& regionIds,
|
||||
const Map<word>& regionNames
|
||||
)
|
||||
:
|
||||
ParentType(pointLst, faceLst),
|
||||
regions_(regionIds)
|
||||
{
|
||||
if (®ionNames)
|
||||
{
|
||||
// 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
|
||||
const UList<label>& patchSizes,
|
||||
const UList<word>& patchNames
|
||||
)
|
||||
:
|
||||
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()))
|
||||
{
|
||||
const surfGroupList& patchLst = 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;
|
||||
}
|
||||
}
|
||||
setPatches(surf.patches());
|
||||
}
|
||||
|
||||
|
||||
template<class Face>
|
||||
Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
|
||||
(
|
||||
const fileName& fName,
|
||||
const fileName& name,
|
||||
const word& ext
|
||||
)
|
||||
{
|
||||
read(fName, ext);
|
||||
read(name, ext);
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
patches_.setSize(1);
|
||||
patches_[0] = PatchRegionType("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);
|
||||
patches_[0] = surfPatchIdentifier("patch0", 0);
|
||||
}
|
||||
|
||||
|
||||
template<class Face>
|
||||
void Foam::UnsortedMeshedSurface<Face>::setPatches
|
||||
(
|
||||
const Map<word>& regionNames,
|
||||
const label maxPatchHint
|
||||
const surfGroupList& patches
|
||||
)
|
||||
{
|
||||
label maxPatch = maxPatchHint;
|
||||
regions_.setSize(size());
|
||||
patches_.setSize(patches.size());
|
||||
|
||||
// determine max patch ID if required
|
||||
if (maxPatchHint < 0)
|
||||
forAll(patches, patchI)
|
||||
{
|
||||
maxPatch = 0;
|
||||
forAllConstIter(Map<word>, regionNames, iter)
|
||||
{
|
||||
if (maxPatch < iter.key())
|
||||
{
|
||||
maxPatch = iter.key();
|
||||
}
|
||||
}
|
||||
}
|
||||
const surfGroup& p = patches[patchI];
|
||||
|
||||
patches_[patchI] = p;
|
||||
|
||||
// Info<< "setPatches with maxPatch: " << maxPatch << endl;
|
||||
|
||||
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
|
||||
);
|
||||
SubList<label> subRegion(regions_, p.size(), p.start());
|
||||
subRegion = patchI;
|
||||
}
|
||||
}
|
||||
|
||||
@ -441,23 +336,49 @@ void Foam::UnsortedMeshedSurface<Face>::setPatches
|
||||
template<class Face>
|
||||
void Foam::UnsortedMeshedSurface<Face>::setPatches
|
||||
(
|
||||
const HashTable<label>& groupToPatch
|
||||
const UList<label>& sizes,
|
||||
const UList<word>& names
|
||||
)
|
||||
{
|
||||
// determine max patch Id
|
||||
label maxPatch = 0;
|
||||
Map<word> regionNames;
|
||||
regions_.setSize(size());
|
||||
patches_.setSize(sizes.size());
|
||||
|
||||
forAllConstIter(HashTable<label>, groupToPatch, iter)
|
||||
label start = 0;
|
||||
forAll(patches_, patchI)
|
||||
{
|
||||
regionNames.insert(iter(), iter.key());
|
||||
if (maxPatch < iter())
|
||||
{
|
||||
maxPatch = iter();
|
||||
}
|
||||
}
|
||||
patches_[patchI] = surfPatchIdentifier(names[patchI], patchI);
|
||||
|
||||
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);
|
||||
}
|
||||
faceMap.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class Face>
|
||||
@ -620,43 +541,25 @@ void Foam::UnsortedMeshedSurface<Face>::transfer
|
||||
MeshedSurface<Face>& surf
|
||||
)
|
||||
{
|
||||
surfGroupList& patchLst = surf.patches_;
|
||||
|
||||
reset(xferMove(surf.storedPoints()), xferMove(surf.storedFaces()));
|
||||
|
||||
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();
|
||||
setPatches(surf.patches());
|
||||
surf.clear();
|
||||
}
|
||||
|
||||
|
||||
// Read from file, determine format from extension
|
||||
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")
|
||||
{
|
||||
fileName unzipName = fName.lessExt();
|
||||
fileName unzipName = name.lessExt();
|
||||
return read(unzipName, unzipName.ext());
|
||||
}
|
||||
else
|
||||
{
|
||||
return read(fName, ext);
|
||||
return read(name, ext);
|
||||
}
|
||||
}
|
||||
|
||||
@ -665,19 +568,19 @@ bool Foam::UnsortedMeshedSurface<Face>::read(const fileName& fName)
|
||||
template<class Face>
|
||||
bool Foam::UnsortedMeshedSurface<Face>::read
|
||||
(
|
||||
const fileName& fName,
|
||||
const fileName& name,
|
||||
const word& ext
|
||||
)
|
||||
{
|
||||
// handle 'native' format directly
|
||||
if (isNative(ext))
|
||||
{
|
||||
return read(IFstream(fName)());
|
||||
return read(IFstream(name)());
|
||||
}
|
||||
else
|
||||
{
|
||||
// use selector mechanism
|
||||
transfer(New(fName, ext)());
|
||||
transfer(New(name, ext)());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -713,7 +616,6 @@ void Foam::UnsortedMeshedSurface<Face>::operator=
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#include "UnsortedMeshedSurfaceCleanup.C"
|
||||
#include "UnsortedMeshedSurfaceIO.C"
|
||||
#include "UnsortedMeshedSurfaceNew.C"
|
||||
|
||||
|
||||
@ -91,9 +91,6 @@ private:
|
||||
typedef PrimitiveMeshedSurface<Face> ParentType;
|
||||
typedef MeshedSurface<Face> SiblingType;
|
||||
|
||||
//- Typedef for type holding the region (patch) informationm
|
||||
typedef surfPatchIdentifier PatchRegionType;
|
||||
|
||||
// Private Member Data
|
||||
|
||||
//- The regions associated with the faces
|
||||
@ -101,7 +98,7 @@ private:
|
||||
|
||||
//- Patch information (face ordering nFaces/startFace only used
|
||||
// during reading and writing)
|
||||
List<PatchRegionType> patches_;
|
||||
List<surfPatchIdentifier> patches_;
|
||||
|
||||
// Private member functions
|
||||
|
||||
@ -111,38 +108,25 @@ private:
|
||||
//- Read OpenFOAM Surface format
|
||||
bool read(Istream&);
|
||||
|
||||
//- Set new regions from faceMap
|
||||
void remapRegions(List<label>& faceMap);
|
||||
|
||||
protected:
|
||||
|
||||
// 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
|
||||
List<label>& storedRegions()
|
||||
{
|
||||
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:
|
||||
|
||||
//- Runtime type information
|
||||
@ -177,32 +161,14 @@ public:
|
||||
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.
|
||||
// Set single default patch.
|
||||
// Use patch information, or set single default patch
|
||||
UnsortedMeshedSurface
|
||||
(
|
||||
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
|
||||
@ -244,9 +210,9 @@ public:
|
||||
UnsortedMeshedSurface,
|
||||
fileExtension,
|
||||
(
|
||||
const fileName& fName
|
||||
const fileName& name
|
||||
),
|
||||
(fName)
|
||||
(name)
|
||||
);
|
||||
|
||||
// Selectors
|
||||
@ -275,10 +241,10 @@ public:
|
||||
write,
|
||||
fileExtension,
|
||||
(
|
||||
const fileName& fName,
|
||||
const fileName& name,
|
||||
const UnsortedMeshedSurface<Face>& surf
|
||||
),
|
||||
(fName, surf)
|
||||
(name, surf)
|
||||
);
|
||||
|
||||
//- Write to file
|
||||
@ -314,29 +280,24 @@ public:
|
||||
// Returns patch list and sets faceMap to index within faces()
|
||||
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
|
||||
|
||||
//- Clear all storage
|
||||
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.
|
||||
// Returns return pointMap, faceMap from subsetMeshMap
|
||||
UnsortedMeshedSurface subsetMesh
|
||||
@ -382,9 +343,9 @@ public:
|
||||
virtual void write(Ostream&) const;
|
||||
|
||||
//- 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
|
||||
@ -408,15 +369,6 @@ public:
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
//- Specialization for holding triangulated information
|
||||
template<>
|
||||
inline label UnsortedMeshedSurface<triFace>::triangulate()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -31,16 +31,11 @@ License
|
||||
|
||||
template<class Face>
|
||||
Foam::autoPtr<Foam::UnsortedMeshedSurface<Face> >
|
||||
Foam::UnsortedMeshedSurface<Face>::New
|
||||
(
|
||||
const fileName& fName,
|
||||
const word& ext
|
||||
)
|
||||
Foam::UnsortedMeshedSurface<Face>::New(const fileName& name, const word& ext)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "UnsortedMeshedSurface<Face>::New"
|
||||
"(const fileName&, const word&) : "
|
||||
Info<< "UnsortedMeshedSurface::New(const fileName&, const word&) : "
|
||||
"constructing UnsortedMeshedSurface"
|
||||
<< endl;
|
||||
}
|
||||
@ -59,7 +54,7 @@ Foam::UnsortedMeshedSurface<Face>::New
|
||||
(
|
||||
new UnsortedMeshedSurface<Face>
|
||||
);
|
||||
surf().transfer(SiblingType::New(fName, ext)());
|
||||
surf().transfer(SiblingType::New(name, ext)());
|
||||
|
||||
return surf;
|
||||
}
|
||||
@ -79,24 +74,21 @@ Foam::UnsortedMeshedSurface<Face>::New
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
return autoPtr<UnsortedMeshedSurface<Face> >(cstrIter()(fName));
|
||||
return autoPtr<UnsortedMeshedSurface<Face> >(cstrIter()(name));
|
||||
}
|
||||
|
||||
|
||||
template<class Face>
|
||||
Foam::autoPtr<Foam::UnsortedMeshedSurface<Face> >
|
||||
Foam::UnsortedMeshedSurface<Face>::New
|
||||
(
|
||||
const fileName& fName
|
||||
)
|
||||
Foam::UnsortedMeshedSurface<Face>::New(const fileName& name)
|
||||
{
|
||||
word ext = fName.ext();
|
||||
word ext = name.ext();
|
||||
if (ext == "gz")
|
||||
{
|
||||
ext = fName.lessExt().ext();
|
||||
ext = name.lessExt().ext();
|
||||
}
|
||||
|
||||
return New(fName, ext);
|
||||
return New(name, ext);
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -41,10 +41,10 @@ License
|
||||
template<class Face>
|
||||
Foam::fileFormats::AC3DsurfaceFormat<Face>::AC3DsurfaceFormat
|
||||
(
|
||||
const fileName& fName
|
||||
const fileName& filename
|
||||
)
|
||||
{
|
||||
read(fName);
|
||||
read(filename);
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
@ -52,20 +52,20 @@ Foam::fileFormats::AC3DsurfaceFormat<Face>::AC3DsurfaceFormat
|
||||
template<class Face>
|
||||
bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
|
||||
(
|
||||
const fileName& fName
|
||||
const fileName& filename
|
||||
)
|
||||
{
|
||||
const bool mustTriangulate = this->isTri();
|
||||
this->clear();
|
||||
|
||||
IFstream is(fName);
|
||||
IFstream is(filename);
|
||||
if (!is.good())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"fileFormats::AC3DsurfaceFormat::read(const fileName&)"
|
||||
)
|
||||
<< "Cannot read file " << fName
|
||||
<< "Cannot read file " << filename
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
@ -81,7 +81,7 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
|
||||
(
|
||||
"fileFormats::AC3DsurfaceFormat::read(const fileName&)"
|
||||
)
|
||||
<< "When reading AC3D file " << fName
|
||||
<< "When reading AC3D file " << filename
|
||||
<< " read header " << line << " with version "
|
||||
<< version << endl
|
||||
<< "Only tested reading with version 'b'."
|
||||
@ -95,7 +95,7 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
|
||||
(
|
||||
"fileFormats::AC3DsurfaceFormat::read(const fileName&)"
|
||||
)
|
||||
<< "Cannot find \"OBJECT world\" in file " << fName
|
||||
<< "Cannot find \"OBJECT world\" in file " << filename
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
@ -108,13 +108,14 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
|
||||
|
||||
DynamicList<point> dynPoints;
|
||||
DynamicList<Face> dynFaces;
|
||||
List<label> sizes(nPatches, 0);
|
||||
List<word> names(nPatches);
|
||||
List<label> sizes(nPatches, 0);
|
||||
|
||||
for (label patchI = 0; patchI < nPatches; ++patchI)
|
||||
{
|
||||
word patchName = word("patch") + Foam::name(patchI);
|
||||
|
||||
args = cueToOrDie(is, "OBJECT", "while reading " + patchName);
|
||||
names[patchI] = word("patch") + Foam::name(patchI);
|
||||
|
||||
args = cueToOrDie(is, "OBJECT", "while reading " + names[patchI]);
|
||||
|
||||
// number of vertices for this patch
|
||||
label nPatchPoints = 0;
|
||||
@ -133,7 +134,7 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
|
||||
"fileFormats::AC3DsurfaceFormat::read(const fileName&)"
|
||||
)
|
||||
<< "Did not read up to \"kids 0\" while reading patch "
|
||||
<< patchI << " from file " << fName
|
||||
<< patchI << " from file " << filename
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
@ -143,7 +144,7 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
|
||||
string str = parse<string>(args);
|
||||
string::stripInvalid<word>(str);
|
||||
|
||||
patchName = str;
|
||||
names[patchI] = str;
|
||||
}
|
||||
else if (cmd == "rot")
|
||||
{
|
||||
@ -203,7 +204,7 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
|
||||
string(" while reading face ")
|
||||
+ Foam::name(faceI) + " on patch "
|
||||
+ Foam::name(patchI)
|
||||
+ " from file " + fName;
|
||||
+ " from file " + filename;
|
||||
|
||||
cueToOrDie(is, "SURF", errorMsg);
|
||||
cueToOrDie(is, "mat", errorMsg);
|
||||
@ -277,7 +278,8 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
|
||||
this->storedPoints().transfer(dynPoints);
|
||||
this->storedFaces().transfer(dynFaces);
|
||||
|
||||
this->addPatches(sizes);
|
||||
// add patches, culling empty groups
|
||||
this->addPatches(sizes, names, true);
|
||||
this->stitchFaces(SMALL);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -83,14 +83,11 @@ public:
|
||||
// Selectors
|
||||
|
||||
//- Read file and return surface
|
||||
static autoPtr<MeshedSurface<Face> > New
|
||||
(
|
||||
const fileName& fName
|
||||
)
|
||||
static autoPtr<MeshedSurface<Face> > New(const fileName& name)
|
||||
{
|
||||
return autoPtr<MeshedSurface<Face> >
|
||||
(
|
||||
new AC3DsurfaceFormat<Face>(fName)
|
||||
new AC3DsurfaceFormat<Face>(name)
|
||||
);
|
||||
}
|
||||
|
||||
@ -115,11 +112,11 @@ public:
|
||||
//- Write MeshedSurface
|
||||
static void write
|
||||
(
|
||||
const fileName& fName,
|
||||
const fileName& name,
|
||||
const MeshedSurface<Face>& surf
|
||||
)
|
||||
{
|
||||
write(OFstream(fName)(), surf);
|
||||
write(OFstream(name)(), surf);
|
||||
}
|
||||
|
||||
//- Write UnsortedMeshedSurface
|
||||
@ -134,11 +131,11 @@ public:
|
||||
// The output is always sorted by regions.
|
||||
static void write
|
||||
(
|
||||
const fileName& fName,
|
||||
const fileName& name,
|
||||
const UnsortedMeshedSurface<Face>& surf
|
||||
)
|
||||
{
|
||||
write(OFstream(fName)(), surf);
|
||||
write(OFstream(name)(), surf);
|
||||
}
|
||||
|
||||
//- Write object
|
||||
|
||||
@ -35,10 +35,10 @@ License
|
||||
template<class Face>
|
||||
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>
|
||||
bool Foam::fileFormats::FTRsurfaceFormat<Face>::read
|
||||
(
|
||||
const fileName& fName
|
||||
const fileName& filename
|
||||
)
|
||||
{
|
||||
this->clear();
|
||||
|
||||
IFstream is(fName);
|
||||
IFstream is(filename);
|
||||
if (!is.good())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"fileFormats::FTRsurfaceFormat::read(const fileName&)"
|
||||
)
|
||||
<< "Cannot read file " << fName
|
||||
<< "Cannot read file " << filename
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
@ -85,13 +85,18 @@ bool Foam::fileFormats::FTRsurfaceFormat<Face>::read
|
||||
this->storedFaces().transfer(faceLst);
|
||||
this->storedRegions().transfer(regionLst);
|
||||
|
||||
Map<word> regionNames;
|
||||
forAll(readPatches, patchI)
|
||||
// cast ftrPatch into new form
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@ -99,14 +99,11 @@ public:
|
||||
// Selectors
|
||||
|
||||
//- Read file and return surface
|
||||
static autoPtr<UnsortedMeshedSurface<Face> > New
|
||||
(
|
||||
const fileName& fName
|
||||
)
|
||||
static autoPtr<UnsortedMeshedSurface<Face> > New(const fileName& name)
|
||||
{
|
||||
return autoPtr<UnsortedMeshedSurface<Face> >
|
||||
(
|
||||
new FTRsurfaceFormat<Face>(fName)
|
||||
new FTRsurfaceFormat<Face>(name)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -38,10 +38,10 @@ License
|
||||
template<class Face>
|
||||
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>
|
||||
bool Foam::fileFormats::GTSsurfaceFormat<Face>::read
|
||||
(
|
||||
const fileName& fName
|
||||
const fileName& filename
|
||||
)
|
||||
{
|
||||
this->clear();
|
||||
|
||||
IFstream is(fName);
|
||||
IFstream is(filename);
|
||||
if (!is.good())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"fileFormats::GTSsurfaceFormat::read(const fileName&)"
|
||||
)
|
||||
<< "Cannot read file " << fName
|
||||
<< "Cannot read file " << filename
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
@ -205,111 +205,22 @@ bool Foam::fileFormats::GTSsurfaceFormat<Face>::read
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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>
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -27,6 +27,7 @@ Class
|
||||
|
||||
Description
|
||||
Provide a means of reading/writing GTS format.
|
||||
The output is never sorted by patch.
|
||||
|
||||
SourceFiles
|
||||
GTSsurfaceFormat.C
|
||||
@ -75,14 +76,11 @@ public:
|
||||
// Selectors
|
||||
|
||||
//- Read file and return surface
|
||||
static autoPtr<UnsortedMeshedSurface<Face> > New
|
||||
(
|
||||
const fileName& fName
|
||||
)
|
||||
static autoPtr<UnsortedMeshedSurface<Face> > New(const fileName& name)
|
||||
{
|
||||
return autoPtr<UnsortedMeshedSurface<Face> >
|
||||
(
|
||||
new GTSsurfaceFormat<Face>(fName)
|
||||
new GTSsurfaceFormat<Face>(name)
|
||||
);
|
||||
}
|
||||
|
||||
@ -105,15 +103,15 @@ public:
|
||||
//- Write MeshedSurface
|
||||
static void write
|
||||
(
|
||||
const fileName& fName,
|
||||
const fileName& name,
|
||||
const MeshedSurface<Face>& surf
|
||||
)
|
||||
{
|
||||
write(OFstream(fName)(), surf);
|
||||
write(OFstream(name)(), surf);
|
||||
}
|
||||
|
||||
//- Write UnsortedMeshedSurface
|
||||
// The output is sorted by regions
|
||||
// The output remains unsorted
|
||||
static void write
|
||||
(
|
||||
Ostream&,
|
||||
@ -121,14 +119,14 @@ public:
|
||||
);
|
||||
|
||||
//- Write UnsortedMeshedSurface
|
||||
// The output is sorted by regions
|
||||
// The output remains unsorted
|
||||
static void write
|
||||
(
|
||||
const fileName& fName,
|
||||
const fileName& name,
|
||||
const UnsortedMeshedSurface<Face>& surf
|
||||
)
|
||||
{
|
||||
write(OFstream(fName)(), surf);
|
||||
write(OFstream(name)(), surf);
|
||||
}
|
||||
|
||||
//- Write object
|
||||
|
||||
@ -38,10 +38,10 @@ License
|
||||
template<class Face>
|
||||
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>
|
||||
bool Foam::fileFormats::NASsurfaceFormat<Face>::read
|
||||
(
|
||||
const fileName& fName
|
||||
const fileName& filename
|
||||
)
|
||||
{
|
||||
const bool mustTriangulate = this->isTri();
|
||||
this->clear();
|
||||
|
||||
IFstream is(fName);
|
||||
IFstream is(filename);
|
||||
if (!is.good())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"fileFormats::NASsurfaceFormat::read(const fileName&)"
|
||||
)
|
||||
<< "Cannot read file " << fName
|
||||
<< "Cannot read file " << filename
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
DynamicList<point> pointLst;
|
||||
// Nastran index of points
|
||||
DynamicList<label> pointId;
|
||||
DynamicList<Face> faceLst;
|
||||
DynamicList<label> regionLst;
|
||||
HashTable<label> groupToPatch;
|
||||
DynamicList<point> dynPoints;
|
||||
DynamicList<Face> dynFaces;
|
||||
DynamicList<label> dynRegions;
|
||||
DynamicList<label> dynSizes;
|
||||
Map<label> lookup;
|
||||
|
||||
// From face groupId to patchId
|
||||
Map<label> groupIdToPatchId;
|
||||
label nPatches = 0;
|
||||
// assume the types are not intermixed
|
||||
bool sorted = true;
|
||||
label regionI = 0;
|
||||
|
||||
// Name for face group
|
||||
Map<word> groupIdToName;
|
||||
Map<word> nameLookup;
|
||||
|
||||
// Ansa tags. Denoted by $ANSA_NAME. These will appear just before the
|
||||
// first use of a type. We read them and store the pshell types which
|
||||
// are used to name the patches.
|
||||
// Ansa tags. Denoted by $ANSA_NAME.
|
||||
// These will appear just before the first use of a type.
|
||||
// We read them and store the PSHELL types which are used to name
|
||||
// the patches.
|
||||
label ansaId = -1;
|
||||
word ansaType;
|
||||
word ansaName;
|
||||
word ansaType, ansaName;
|
||||
|
||||
// leave faces that didn't have a group in 0
|
||||
// label groupID = 0;
|
||||
@ -134,7 +135,7 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
|
||||
string::stripInvalid<word>(rawName);
|
||||
ansaName = rawName;
|
||||
|
||||
// Info<< "ANSA tag for NastranID:" << ansaID
|
||||
// Info<< "ANSA tag for NastranID:" << ansaId
|
||||
// << " of type " << ansaType
|
||||
// << " name " << ansaName << endl;
|
||||
}
|
||||
@ -161,9 +162,9 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
|
||||
string::stripInvalid<word>(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;
|
||||
}
|
||||
|
||||
|
||||
// Check if character 72 is continuation
|
||||
if (line.size() > 72 && line[72] == '+')
|
||||
{
|
||||
@ -212,22 +212,27 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
|
||||
fTri[2] = readLabel(IStringStream(line.substr(40,8))());
|
||||
|
||||
// Convert groupID into patchID
|
||||
Map<label>::const_iterator iter = groupIdToPatchId.find(groupId);
|
||||
|
||||
label patchI;
|
||||
if (iter == groupIdToPatchId.end())
|
||||
Map<label>::const_iterator fnd = lookup.find(groupId);
|
||||
if (fnd != lookup.end())
|
||||
{
|
||||
patchI = nPatches++;
|
||||
groupIdToPatchId.insert(groupId, patchI);
|
||||
Info<< "patch " << patchI << " => group " << groupId << endl;
|
||||
if (regionI != fnd())
|
||||
{
|
||||
// pshell types are intermixed
|
||||
sorted = false;
|
||||
}
|
||||
regionI = fnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
patchI = iter();
|
||||
regionI = dynSizes.size();
|
||||
lookup.insert(groupId, regionI);
|
||||
dynSizes.append(0);
|
||||
// Info<< "patch" << regionI << " => group " << groupId <<endl;
|
||||
}
|
||||
|
||||
faceLst.append(fTri);
|
||||
regionLst.append(patchI);
|
||||
dynFaces.append(fTri);
|
||||
dynRegions.append(regionI);
|
||||
dynSizes[regionI]++;
|
||||
}
|
||||
else if (cmd == "CQUAD4")
|
||||
{
|
||||
@ -240,43 +245,39 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
|
||||
fQuad[2] = readLabel(IStringStream(line.substr(40,8))());
|
||||
fQuad[3] = readLabel(IStringStream(line.substr(48,8))());
|
||||
|
||||
// Convert group into patch
|
||||
Map<label>::const_iterator iter = groupIdToPatchId.find(groupId);
|
||||
|
||||
label patchI;
|
||||
if (iter == groupIdToPatchId.end())
|
||||
// Convert groupID into patchID
|
||||
Map<label>::const_iterator fnd = lookup.find(groupId);
|
||||
if (fnd != lookup.end())
|
||||
{
|
||||
patchI = nPatches++;
|
||||
groupIdToPatchId.insert(groupId, patchI);
|
||||
Info<< "patch " << patchI << " => group " << groupId << endl;
|
||||
if (regionI != fnd())
|
||||
{
|
||||
// pshell types are intermixed
|
||||
sorted = false;
|
||||
}
|
||||
regionI = fnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
patchI = iter();
|
||||
regionI = dynSizes.size();
|
||||
lookup.insert(groupId, regionI);
|
||||
dynSizes.append(0);
|
||||
// Info<< "patch" << regionI << " => group " << groupId <<endl;
|
||||
}
|
||||
|
||||
|
||||
if (mustTriangulate)
|
||||
{
|
||||
faceLst.append(triFace(f[0], f[1], f[2]));
|
||||
faceLst.append(triFace(f[0], f[2], f[3]));
|
||||
regionLst.append(patchI);
|
||||
regionLst.append(patchI);
|
||||
dynFaces.append(triFace(f[0], f[1], f[2]));
|
||||
dynFaces.append(triFace(f[0], f[2], f[3]));
|
||||
dynRegions.append(regionI);
|
||||
dynRegions.append(regionI);
|
||||
dynSizes[regionI] += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
faceLst.append(Face(f));
|
||||
regionLst.append(patchI);
|
||||
}
|
||||
}
|
||||
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;
|
||||
dynFaces.append(Face(f));
|
||||
dynRegions.append(regionI);
|
||||
dynSizes[regionI]++;
|
||||
}
|
||||
}
|
||||
else if (cmd == "GRID")
|
||||
@ -287,7 +288,7 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
|
||||
scalar z = parseNASCoord(line.substr(40, 8));
|
||||
|
||||
pointId.append(index);
|
||||
pointLst.append(point(x, y, z));
|
||||
dynPoints.append(point(x, y, z));
|
||||
}
|
||||
else if (cmd == "GRID*")
|
||||
{
|
||||
@ -309,76 +310,95 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
|
||||
"fileFormats::NASsurfaceFormat::read(const fileName&)"
|
||||
)
|
||||
<< "Expected continuation symbol '*' when reading GRID*"
|
||||
<< " (double precision coordinate) output" << nl
|
||||
<< " (double precision coordinate) format" << nl
|
||||
<< "Read:" << line << nl
|
||||
<< "File:" << is.name()
|
||||
<< " line:" << is.lineNumber()
|
||||
<< "File:" << is.name() << " line:" << is.lineNumber()
|
||||
<< exit(FatalError);
|
||||
}
|
||||
scalar z = parseNASCoord(line.substr(8, 16));
|
||||
|
||||
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))
|
||||
{
|
||||
Info<< "Unhandled Nastran command " << line << nl
|
||||
<< "File:" << is.name()
|
||||
<< " line:" << is.lineNumber()
|
||||
<< "File:" << is.name() << " line:" << is.lineNumber()
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
Info<< "Read faces:" << faceLst.size()
|
||||
<< " points:" << pointLst.size()
|
||||
<< endl;
|
||||
|
||||
// Info<< "Read faces:" << dynFaces.size()
|
||||
// << " points:" << dynPoints.size()
|
||||
// << endl;
|
||||
|
||||
// transfer to normal lists
|
||||
this->storedPoints().transfer(pointLst);
|
||||
this->storedRegions().transfer(regionLst);
|
||||
this->storedPoints().transfer(dynPoints);
|
||||
|
||||
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)
|
||||
Map<label> nasToFoamPoint(2*pointId.size());
|
||||
forAll(pointId, i)
|
||||
mapPointId.insert(pointId[i], 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
|
||||
forAll(faceLst, i)
|
||||
// create default patch names, or from ANSA/Hypermesh information
|
||||
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];
|
||||
forAll(f, fp)
|
||||
{
|
||||
f[fp] = nasToFoamPoint[f[fp]];
|
||||
}
|
||||
names[patchI] = fnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
names[patchI] = word("patch") + ::Foam::name(patchI);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// convert Nastran groupId => name to patchId => name
|
||||
Map<word> regionNames;
|
||||
forAllConstIter(Map<word>, groupIdToName, iter)
|
||||
{
|
||||
Map<label>::const_iterator iter2 = groupIdToPatchId.find(iter.key());
|
||||
sortFacesAndStore
|
||||
(
|
||||
xferMoveTo<List<Face> >(dynFaces),
|
||||
xferMoveTo<List<label> >(dynRegions),
|
||||
sorted
|
||||
);
|
||||
|
||||
if (iter2 != groupIdToPatchId.end())
|
||||
{
|
||||
regionNames.insert(iter2.key(), iter());
|
||||
}
|
||||
}
|
||||
// add patches, culling empty groups
|
||||
this->addPatches(dynSizes, names, true);
|
||||
|
||||
// transfer to normal lists
|
||||
this->storedFaces().transfer(faceLst);
|
||||
|
||||
this->setPatches(regionNames);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -58,13 +58,13 @@ namespace fileFormats
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class NASsurfaceFormat Declaration
|
||||
Class NASsurfaceFormat Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class Face>
|
||||
class NASsurfaceFormat
|
||||
:
|
||||
public UnsortedMeshedSurface<Face>,
|
||||
public MeshedSurface<Face>,
|
||||
public NASsurfaceFormatCore
|
||||
{
|
||||
// Private Member Functions
|
||||
@ -85,14 +85,11 @@ public:
|
||||
// Selectors
|
||||
|
||||
//- Read file and return surface
|
||||
static autoPtr<UnsortedMeshedSurface<Face> > New
|
||||
(
|
||||
const fileName& fName
|
||||
)
|
||||
static autoPtr<MeshedSurface<Face> > New(const fileName& name)
|
||||
{
|
||||
return autoPtr<UnsortedMeshedSurface<Face> >
|
||||
return autoPtr<MeshedSurface<Face> >
|
||||
(
|
||||
new NASsurfaceFormat<Face>(fName)
|
||||
new NASsurfaceFormat<Face>(name)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -37,9 +37,10 @@ namespace fileFormats
|
||||
{
|
||||
|
||||
// .bdf (Bulk Data Format)
|
||||
// .nas (Nastran)
|
||||
addNamedTemplatedToRunTimeSelectionTable
|
||||
(
|
||||
UnsortedMeshedSurface,
|
||||
MeshedSurface,
|
||||
NASsurfaceFormat,
|
||||
face,
|
||||
fileExtension,
|
||||
@ -47,25 +48,24 @@ addNamedTemplatedToRunTimeSelectionTable
|
||||
);
|
||||
addNamedTemplatedToRunTimeSelectionTable
|
||||
(
|
||||
UnsortedMeshedSurface,
|
||||
NASsurfaceFormat,
|
||||
triFace,
|
||||
fileExtension,
|
||||
bdf
|
||||
);
|
||||
|
||||
// .nas (Nastran)
|
||||
addNamedTemplatedToRunTimeSelectionTable
|
||||
(
|
||||
UnsortedMeshedSurface,
|
||||
MeshedSurface,
|
||||
NASsurfaceFormat,
|
||||
face,
|
||||
fileExtension,
|
||||
nas
|
||||
);
|
||||
|
||||
addNamedTemplatedToRunTimeSelectionTable
|
||||
(
|
||||
UnsortedMeshedSurface,
|
||||
MeshedSurface,
|
||||
NASsurfaceFormat,
|
||||
triFace,
|
||||
fileExtension,
|
||||
bdf
|
||||
);
|
||||
addNamedTemplatedToRunTimeSelectionTable
|
||||
(
|
||||
MeshedSurface,
|
||||
NASsurfaceFormat,
|
||||
triFace,
|
||||
fileExtension,
|
||||
|
||||
@ -27,6 +27,7 @@ License
|
||||
#include "OBJsurfaceFormat.H"
|
||||
#include "IFstream.H"
|
||||
#include "IStringStream.H"
|
||||
#include "ListOps.H"
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
@ -35,10 +36,10 @@ License
|
||||
template<class Face>
|
||||
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>
|
||||
bool Foam::fileFormats::OBJsurfaceFormat<Face>::read
|
||||
(
|
||||
const fileName& fName
|
||||
const fileName& filename
|
||||
)
|
||||
{
|
||||
const bool mustTriangulate = this->isTri();
|
||||
this->clear();
|
||||
|
||||
IFstream is(fName);
|
||||
IFstream is(filename);
|
||||
if (!is.good())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"fileFormats::OBJsurfaceFormat::read(const fileName&)"
|
||||
)
|
||||
<< "Cannot read file " << fName
|
||||
<< "Cannot read file " << filename
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
DynamicList<point> pointLst;
|
||||
DynamicList<Face> faceLst;
|
||||
DynamicList<label> regionLst;
|
||||
HashTable<label> groupToPatch;
|
||||
// assume that the groups are not intermixed
|
||||
bool sorted = true;
|
||||
|
||||
// leave faces that didn't have a group in 0
|
||||
label groupID = 0;
|
||||
label maxGroupID = -1;
|
||||
DynamicList<point> dynPoints;
|
||||
DynamicList<Face> dynFaces;
|
||||
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())
|
||||
{
|
||||
@ -93,30 +101,29 @@ bool Foam::fileFormats::OBJsurfaceFormat<Face>::read
|
||||
{
|
||||
scalar x, y, z;
|
||||
lineStream >> x >> y >> z;
|
||||
pointLst.append(point(x, y, z));
|
||||
dynPoints.append(point(x, y, z));
|
||||
}
|
||||
else if (cmd == "g")
|
||||
{
|
||||
word groupName;
|
||||
lineStream >> groupName;
|
||||
word name;
|
||||
lineStream >> name;
|
||||
|
||||
HashTable<label>::const_iterator findGroup =
|
||||
groupToPatch.find(groupName);
|
||||
|
||||
if (findGroup != groupToPatch.end())
|
||||
HashTable<label>::const_iterator fnd = lookup.find(name);
|
||||
if (fnd != lookup.end())
|
||||
{
|
||||
groupID = findGroup();
|
||||
if (regionI != fnd())
|
||||
{
|
||||
// group appeared out of order
|
||||
sorted = false;
|
||||
}
|
||||
regionI = fnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
// special treatment if any initial faces were not in a group
|
||||
if (maxGroupID == -1 && faceLst.size())
|
||||
{
|
||||
groupToPatch.insert("patch0", 0);
|
||||
maxGroupID = 0;
|
||||
}
|
||||
groupID = ++maxGroupID;
|
||||
groupToPatch.insert(groupName, groupID);
|
||||
regionI = dynSizes.size();
|
||||
lookup.insert(name, regionI);
|
||||
dynNames.append(name);
|
||||
dynSizes.append(0);
|
||||
}
|
||||
}
|
||||
else if (cmd == "f")
|
||||
@ -183,28 +190,72 @@ bool Foam::fileFormats::OBJsurfaceFormat<Face>::read
|
||||
fTri[1] = f[fp1];
|
||||
fTri[2] = f[fp2];
|
||||
|
||||
faceLst.append(fTri);
|
||||
regionLst.append(groupID);
|
||||
dynFaces.append(fTri);
|
||||
dynRegions.append(regionI);
|
||||
dynSizes[regionI]++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
faceLst.append(Face(f));
|
||||
regionLst.append(groupID);
|
||||
dynFaces.append(Face(f));
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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>
|
||||
void Foam::fileFormats::OBJsurfaceFormat<Face>::write
|
||||
(
|
||||
@ -243,39 +294,4 @@ void Foam::fileFormats::OBJsurfaceFormat<Face>::write
|
||||
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;
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -58,7 +58,7 @@ namespace fileFormats
|
||||
template<class Face>
|
||||
class OBJsurfaceFormat
|
||||
:
|
||||
public UnsortedMeshedSurface<Face>,
|
||||
public MeshedSurface<Face>,
|
||||
public OBJsurfaceFormatCore
|
||||
{
|
||||
// Private Member Functions
|
||||
@ -87,14 +87,11 @@ public:
|
||||
// Selectors
|
||||
|
||||
//- Read file and return surface
|
||||
static autoPtr<UnsortedMeshedSurface<Face> > New
|
||||
(
|
||||
const fileName& fName
|
||||
)
|
||||
static autoPtr<MeshedSurface<Face> > New(const fileName& name)
|
||||
{
|
||||
return autoPtr<UnsortedMeshedSurface<Face> >
|
||||
return autoPtr<MeshedSurface<Face> >
|
||||
(
|
||||
new OBJsurfaceFormat<Face>(fName)
|
||||
new OBJsurfaceFormat<Face>(name)
|
||||
);
|
||||
}
|
||||
|
||||
@ -119,11 +116,11 @@ public:
|
||||
//- Write MeshedSurface
|
||||
static void write
|
||||
(
|
||||
const fileName& fName,
|
||||
const fileName& name,
|
||||
const MeshedSurface<Face>& surf
|
||||
)
|
||||
{
|
||||
write(OFstream(fName)(), surf);
|
||||
write(OFstream(name)(), surf);
|
||||
}
|
||||
|
||||
//- Write UnsortedMeshedSurface
|
||||
@ -138,11 +135,11 @@ public:
|
||||
// The output is sorted by regions
|
||||
static void write
|
||||
(
|
||||
const fileName& fName,
|
||||
const fileName& name,
|
||||
const UnsortedMeshedSurface<Face>& surf
|
||||
)
|
||||
{
|
||||
write(OFstream(fName)(), surf);
|
||||
write(OFstream(name)(), surf);
|
||||
}
|
||||
|
||||
//- Write object
|
||||
|
||||
@ -38,7 +38,7 @@ namespace fileFormats
|
||||
|
||||
addNamedTemplatedToRunTimeSelectionTable
|
||||
(
|
||||
UnsortedMeshedSurface,
|
||||
MeshedSurface,
|
||||
OBJsurfaceFormat,
|
||||
face,
|
||||
fileExtension,
|
||||
@ -46,7 +46,7 @@ addNamedTemplatedToRunTimeSelectionTable
|
||||
);
|
||||
addNamedTemplatedToRunTimeSelectionTable
|
||||
(
|
||||
UnsortedMeshedSurface,
|
||||
MeshedSurface,
|
||||
OBJsurfaceFormat,
|
||||
triFace,
|
||||
fileExtension,
|
||||
|
||||
@ -37,10 +37,10 @@ License
|
||||
template<class Face>
|
||||
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>
|
||||
bool Foam::fileFormats::OFFsurfaceFormat<Face>::read
|
||||
(
|
||||
const fileName& fName
|
||||
const fileName& filename
|
||||
)
|
||||
{
|
||||
const bool mustTriangulate = this->isTri();
|
||||
this->clear();
|
||||
|
||||
IFstream is(fName);
|
||||
IFstream is(filename);
|
||||
if (!is.good())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"fileFormats::OFFsurfaceFormat<Face>::read(const fileName&)"
|
||||
)
|
||||
<< "Cannot read file " << fName
|
||||
<< "Cannot read file " << filename
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
@ -74,7 +74,7 @@ bool Foam::fileFormats::OFFsurfaceFormat<Face>::read
|
||||
(
|
||||
"fileFormats::OFFsurfaceFormat<Face>::read(const fileName&)"
|
||||
)
|
||||
<< "OFF file " << fName << " does not start with 'OFF'"
|
||||
<< "OFF file " << filename << " does not start with 'OFF'"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
@ -103,7 +103,7 @@ bool Foam::fileFormats::OFFsurfaceFormat<Face>::read
|
||||
|
||||
// Read faces - ignore optional region information
|
||||
// use a DynamicList for possible on-the-fly triangulation
|
||||
DynamicList<Face> faceLst(nElems);
|
||||
DynamicList<Face> dynFaces(nElems);
|
||||
|
||||
for (label faceI = 0; faceI < nElems; ++faceI)
|
||||
{
|
||||
@ -137,12 +137,12 @@ bool Foam::fileFormats::OFFsurfaceFormat<Face>::read
|
||||
fTri[1] = f[fp1];
|
||||
fTri[2] = f[fp2];
|
||||
|
||||
faceLst.append(fTri);
|
||||
dynFaces.append(fTri);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
faceLst.append(Face(f));
|
||||
dynFaces.append(Face(f));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -151,7 +151,7 @@ bool Foam::fileFormats::OFFsurfaceFormat<Face>::read
|
||||
reset
|
||||
(
|
||||
xferMove(pointLst),
|
||||
xferMoveTo<List<Face> >(faceLst)
|
||||
xferMoveTo<List<Face> >(dynFaces)
|
||||
);
|
||||
|
||||
// no region information
|
||||
|
||||
@ -95,14 +95,11 @@ public:
|
||||
// Selectors
|
||||
|
||||
//- Read file and return surface
|
||||
static autoPtr<MeshedSurface<Face> > New
|
||||
(
|
||||
const fileName& fName
|
||||
)
|
||||
static autoPtr<MeshedSurface<Face> > New(const fileName& name)
|
||||
{
|
||||
return autoPtr<MeshedSurface<Face> >
|
||||
(
|
||||
new OFFsurfaceFormat(fName)
|
||||
new OFFsurfaceFormat(name)
|
||||
);
|
||||
}
|
||||
|
||||
@ -125,11 +122,11 @@ public:
|
||||
//- Write MeshedSurface
|
||||
static void write
|
||||
(
|
||||
const fileName& fName,
|
||||
const fileName& name,
|
||||
const MeshedSurface<Face>& surf
|
||||
)
|
||||
{
|
||||
write(OFstream(fName)(), surf);
|
||||
write(OFstream(name)(), surf);
|
||||
}
|
||||
|
||||
//- Write UnsortedMeshedSurface
|
||||
@ -144,11 +141,11 @@ public:
|
||||
// The output is sorted by region.
|
||||
static void write
|
||||
(
|
||||
const fileName& fName,
|
||||
const fileName& name,
|
||||
const UnsortedMeshedSurface<Face>& surf
|
||||
)
|
||||
{
|
||||
write(OFstream(fName)(), surf);
|
||||
write(OFstream(name)(), surf);
|
||||
}
|
||||
|
||||
//- Write object
|
||||
|
||||
@ -38,6 +38,38 @@ Foam::fileFormats::SMESHsurfaceFormat<Face>::SMESHsurfaceFormat()
|
||||
|
||||
// * * * * * * * * * * * * * * * 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>
|
||||
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);
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -63,7 +63,7 @@ namespace fileFormats
|
||||
template<class Face>
|
||||
class SMESHsurfaceFormat
|
||||
:
|
||||
public UnsortedMeshedSurface<Face>,
|
||||
public MeshedSurface<Face>,
|
||||
public SMESHsurfaceFormatCore
|
||||
{
|
||||
// Private Member Functions
|
||||
@ -101,11 +101,11 @@ public:
|
||||
//- Write MeshedSurface
|
||||
static void write
|
||||
(
|
||||
const fileName& fName,
|
||||
const fileName& name,
|
||||
const MeshedSurface<Face>& surf
|
||||
)
|
||||
{
|
||||
write(OFstream(fName)(), surf);
|
||||
write(OFstream(name)(), surf);
|
||||
}
|
||||
|
||||
//- Write UnsortedMeshedSurface
|
||||
@ -120,11 +120,11 @@ public:
|
||||
// The output is sorted by region.
|
||||
static void write
|
||||
(
|
||||
const fileName& fName,
|
||||
const fileName& name,
|
||||
const UnsortedMeshedSurface<Face>& surf
|
||||
)
|
||||
{
|
||||
write(OFstream(fName)(), surf);
|
||||
write(OFstream(name)(), surf);
|
||||
}
|
||||
|
||||
//- Write object
|
||||
|
||||
@ -25,6 +25,7 @@ License
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "STARCDsurfaceFormat.H"
|
||||
#include "ListOps.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
@ -69,10 +70,10 @@ inline void Foam::fileFormats::STARCDsurfaceFormat<Face>::writeShell
|
||||
template<class Face>
|
||||
Foam::fileFormats::STARCDsurfaceFormat<Face>::STARCDsurfaceFormat
|
||||
(
|
||||
const fileName& fName
|
||||
const fileName& filename
|
||||
)
|
||||
{
|
||||
read(fName);
|
||||
read(filename);
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
@ -80,93 +81,65 @@ Foam::fileFormats::STARCDsurfaceFormat<Face>::STARCDsurfaceFormat
|
||||
template<class Face>
|
||||
bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
|
||||
(
|
||||
const fileName& fName
|
||||
const fileName& filename
|
||||
)
|
||||
{
|
||||
const bool mustTriangulate = this->isTri();
|
||||
this->clear();
|
||||
|
||||
fileName baseName = fName.lessExt();
|
||||
autoPtr<IFstream> isPtr;
|
||||
fileName baseName = filename.lessExt();
|
||||
|
||||
|
||||
DynamicList<point> pointLst;
|
||||
// STAR-CD index of points
|
||||
DynamicList<label> pointId;
|
||||
List<label> pointId;
|
||||
|
||||
//
|
||||
// read .vrt file
|
||||
// ~~~~~~~~~~~~~~
|
||||
isPtr.reset(new IFstream(baseName + ".vrt"));
|
||||
// read points from .vrt file
|
||||
readPoints
|
||||
(
|
||||
IFstream(baseName + ".vrt")(),
|
||||
this->storedPoints(),
|
||||
pointId
|
||||
);
|
||||
|
||||
if (!isPtr().good())
|
||||
{
|
||||
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());
|
||||
// Build inverse mapping (STAR-CD pointId -> index)
|
||||
Map<label> mapPointId(2*pointId.size());
|
||||
forAll(pointId, i)
|
||||
{
|
||||
mapToFoamPointId.insert(pointId[i], i);
|
||||
mapPointId.insert(pointId[i], i);
|
||||
}
|
||||
pointId.clear();
|
||||
|
||||
|
||||
DynamicList<Face> faceLst;
|
||||
DynamicList<label> regionLst;
|
||||
|
||||
// From face cellTableId to patchId
|
||||
Map<label> cellTableToPatchId;
|
||||
label nPatches = 0;
|
||||
|
||||
|
||||
//
|
||||
// read .cel file
|
||||
// ~~~~~~~~~~~~~~
|
||||
isPtr.reset(new IFstream(baseName + ".cel"));
|
||||
|
||||
if (!isPtr().good())
|
||||
IFstream is(baseName + ".cel");
|
||||
if (!is.good())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"fileFormats::STARCDsurfaceFormat::read(const fileName&)"
|
||||
)
|
||||
<< "Cannot read file " << (baseName + ".cel")
|
||||
<< "Cannot read file " << is.name()
|
||||
<< 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);
|
||||
|
||||
while ((isPtr() >> lineLabel).good())
|
||||
while ((is >> lineLabel).good())
|
||||
{
|
||||
isPtr() >> shapeId >> nLabels >> cellTableId >> typeId;
|
||||
is >> shapeId >> nLabels >> cellTableId >> typeId;
|
||||
|
||||
if (nLabels > starLabels.size())
|
||||
{
|
||||
@ -179,42 +152,43 @@ bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
|
||||
{
|
||||
if ((i % 8) == 0)
|
||||
{
|
||||
isPtr() >> lineLabel;
|
||||
is >> lineLabel;
|
||||
}
|
||||
isPtr() >> starLabels[i];
|
||||
is >> starLabels[i];
|
||||
}
|
||||
|
||||
if (typeId == starcdShellType_)
|
||||
{
|
||||
// Convert groupID into patchID
|
||||
Map<label>::const_iterator iter =
|
||||
cellTableToPatchId.find(cellTableId);
|
||||
|
||||
label patchI;
|
||||
if (iter == cellTableToPatchId.end())
|
||||
Map<label>::const_iterator fnd = lookup.find(cellTableId);
|
||||
if (fnd != lookup.end())
|
||||
{
|
||||
patchI = nPatches++;
|
||||
|
||||
cellTableToPatchId.insert(cellTableId, patchI);
|
||||
if (regionI != fnd())
|
||||
{
|
||||
// cellTableIds are intermixed
|
||||
sorted = false;
|
||||
}
|
||||
regionI = fnd();
|
||||
}
|
||||
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
|
||||
for (label i=0; i < nLabels; ++i)
|
||||
forAll(vertices, i)
|
||||
{
|
||||
starLabels[i] = mapToFoamPointId[starLabels[i]];
|
||||
vertices[i] = mapPointId[vertices[i]];
|
||||
}
|
||||
|
||||
if (mustTriangulate && nLabels > 3)
|
||||
{
|
||||
face f
|
||||
(
|
||||
SubList<label>(starLabels, nLabels)
|
||||
);
|
||||
face f(vertices);
|
||||
|
||||
faceList triFaces(f.nTriangles(this->points()));
|
||||
label nTri = 0;
|
||||
@ -222,47 +196,37 @@ bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
|
||||
|
||||
forAll(triFaces, faceI)
|
||||
{
|
||||
// a triangle, but not yet a triFace
|
||||
faceLst.append
|
||||
// a triangular face, but not yet a triFace
|
||||
dynFaces.append
|
||||
(
|
||||
triFace
|
||||
(
|
||||
static_cast<UList<label>&>(triFaces[faceI])
|
||||
)
|
||||
);
|
||||
regionLst.append(patchI);
|
||||
dynRegions.append(regionI);
|
||||
dynSizes[regionI]++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
faceLst.append
|
||||
(
|
||||
Face(SubList<label>(starLabels, nLabels))
|
||||
);
|
||||
regionLst.append(patchI);
|
||||
dynFaces.append(Face(vertices));
|
||||
dynRegions.append(regionI);
|
||||
dynSizes[regionI]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
mapPointId.clear();
|
||||
|
||||
mapToFoamPointId.clear();
|
||||
|
||||
// convert cellTable_N patchId => name
|
||||
Map<word> regionNames;
|
||||
forAllConstIter(Map<label>, cellTableToPatchId, iter)
|
||||
{
|
||||
regionNames.insert
|
||||
(
|
||||
iter(),
|
||||
"cellTable_" + Foam::name(iter.key())
|
||||
);
|
||||
}
|
||||
|
||||
// transfer to normal lists
|
||||
this->storedFaces().transfer(faceLst);
|
||||
this->storedRegions().transfer(regionLst);
|
||||
|
||||
this->setPatches(regionNames);
|
||||
sortFacesAndStore
|
||||
(
|
||||
xferMoveTo<List<Face> >(dynFaces),
|
||||
xferMoveTo<List<label> >(dynRegions),
|
||||
sorted
|
||||
);
|
||||
|
||||
// add patches, culling empty groups
|
||||
this->addPatches(dynSizes, dynNames, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -270,51 +234,11 @@ bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
|
||||
template<class Face>
|
||||
void Foam::fileFormats::STARCDsurfaceFormat<Face>::write
|
||||
(
|
||||
const fileName& fName,
|
||||
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 fileName& filename,
|
||||
const MeshedSurface<Face>& surf
|
||||
)
|
||||
{
|
||||
fileName baseName = fName.lessExt();
|
||||
fileName baseName = filename.lessExt();
|
||||
|
||||
writePoints(OFstream(baseName + ".vrt")(), surf.points());
|
||||
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
|
||||
);
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -62,7 +62,7 @@ namespace fileFormats
|
||||
template<class Face>
|
||||
class STARCDsurfaceFormat
|
||||
:
|
||||
public UnsortedMeshedSurface<Face>,
|
||||
public MeshedSurface<Face>,
|
||||
public STARCDsurfaceFormatCore
|
||||
{
|
||||
// Private Data
|
||||
@ -97,15 +97,12 @@ public:
|
||||
|
||||
// Selectors
|
||||
|
||||
//- Read file and return keyedSurface
|
||||
static autoPtr<UnsortedMeshedSurface<Face> > New
|
||||
(
|
||||
const fileName& fName
|
||||
)
|
||||
//- Read file and return surface
|
||||
static autoPtr<MeshedSurface<Face> > New(const fileName& name)
|
||||
{
|
||||
return autoPtr<UnsortedMeshedSurface<Face> >
|
||||
return autoPtr<MeshedSurface<Face> >
|
||||
(
|
||||
new STARCDsurfaceFormat<Face>(fName)
|
||||
new STARCDsurfaceFormat<Face>(name)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
(
|
||||
Ostream& os,
|
||||
|
||||
@ -61,6 +61,8 @@ protected:
|
||||
|
||||
static void writeHeader(Ostream&, const char* filetype);
|
||||
|
||||
static bool readPoints(IFstream&, pointField&, labelList& ids);
|
||||
|
||||
static void writePoints(Ostream&, const pointField&);
|
||||
|
||||
static void writeCase
|
||||
|
||||
@ -38,7 +38,7 @@ namespace fileFormats
|
||||
|
||||
addNamedTemplatedToRunTimeSelectionTable
|
||||
(
|
||||
UnsortedMeshedSurface,
|
||||
MeshedSurface,
|
||||
STARCDsurfaceFormat,
|
||||
face,
|
||||
fileExtension,
|
||||
@ -46,7 +46,7 @@ addNamedTemplatedToRunTimeSelectionTable
|
||||
);
|
||||
addNamedTemplatedToRunTimeSelectionTable
|
||||
(
|
||||
UnsortedMeshedSurface,
|
||||
MeshedSurface,
|
||||
STARCDsurfaceFormat,
|
||||
triFace,
|
||||
fileExtension,
|
||||
|
||||
@ -269,10 +269,10 @@ void Foam::fileFormats::STLsurfaceFormat<Face>::writeBINARY
|
||||
template<class Face>
|
||||
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>
|
||||
bool Foam::fileFormats::STLsurfaceFormat<Face>::read
|
||||
(
|
||||
const fileName& fName
|
||||
const fileName& filename
|
||||
)
|
||||
{
|
||||
this->clear();
|
||||
|
||||
// read in the values
|
||||
STLsurfaceFormatCore reader(fName);
|
||||
STLsurfaceFormatCore reader(filename);
|
||||
|
||||
// transfer points
|
||||
this->storedPoints().transfer(reader.points());
|
||||
@ -330,11 +330,11 @@ bool Foam::fileFormats::STLsurfaceFormat<Face>::read
|
||||
|
||||
if (names.size())
|
||||
{
|
||||
this->addPatches(names, sizes);
|
||||
this->addPatches(sizes, names);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->addPatches(names, sizes);
|
||||
this->addPatches(sizes);
|
||||
}
|
||||
|
||||
this->stitchFaces(SMALL);
|
||||
@ -367,21 +367,21 @@ void Foam::fileFormats::STLsurfaceFormat<Face>::write
|
||||
template<class Face>
|
||||
void Foam::fileFormats::STLsurfaceFormat<Face>::write
|
||||
(
|
||||
const fileName& fName,
|
||||
const fileName& filename,
|
||||
const UnsortedMeshedSurface<Face>& surf
|
||||
)
|
||||
{
|
||||
word ext = fName.ext();
|
||||
word ext = filename.ext();
|
||||
|
||||
// handle 'stlb' as binary directly
|
||||
if (ext == "stlb")
|
||||
{
|
||||
std::ofstream ofs(fName.c_str(), std::ios::binary);
|
||||
std::ofstream ofs(filename.c_str(), std::ios::binary);
|
||||
writeBINARY(ofs, surf);
|
||||
}
|
||||
else
|
||||
{
|
||||
writeASCII(OFstream(fName)(), surf);
|
||||
writeASCII(OFstream(filename)(), surf);
|
||||
}
|
||||
}
|
||||
|
||||
@ -389,21 +389,21 @@ void Foam::fileFormats::STLsurfaceFormat<Face>::write
|
||||
template<class Face>
|
||||
void Foam::fileFormats::STLsurfaceFormat<Face>::write
|
||||
(
|
||||
const fileName& fName,
|
||||
const fileName& filename,
|
||||
const MeshedSurface<Face>& surf
|
||||
)
|
||||
{
|
||||
const word ext = fName.ext();
|
||||
const word ext = filename.ext();
|
||||
|
||||
// handle 'stlb' as binary directly
|
||||
if (ext == "stlb")
|
||||
{
|
||||
std::ofstream ofs(fName.c_str(), std::ios::binary);
|
||||
std::ofstream ofs(filename.c_str(), std::ios::binary);
|
||||
writeBINARY(ofs, surf);
|
||||
}
|
||||
else
|
||||
{
|
||||
writeASCII(OFstream(fName)(), surf);
|
||||
writeASCII(OFstream(filename)(), surf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -111,14 +111,11 @@ public:
|
||||
// Selectors
|
||||
|
||||
//- Read file and return surface
|
||||
static autoPtr<MeshedSurface<Face> > New
|
||||
(
|
||||
const fileName& fName
|
||||
)
|
||||
static autoPtr<MeshedSurface<Face> > New(const fileName& name)
|
||||
{
|
||||
return autoPtr<MeshedSurface<Face> >
|
||||
(
|
||||
new STLsurfaceFormat<Face>(fName)
|
||||
new STLsurfaceFormat<Face>(name)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -42,12 +42,12 @@ License
|
||||
// is detected ... this is not exactly what we want.
|
||||
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();
|
||||
|
||||
// Read the STL header
|
||||
@ -215,7 +215,7 @@ bool Foam::fileFormats::STLsurfaceFormatCore::readBINARY
|
||||
|
||||
Foam::fileFormats::STLsurfaceFormatCore::STLsurfaceFormatCore
|
||||
(
|
||||
const fileName& fName
|
||||
const fileName& filename
|
||||
)
|
||||
:
|
||||
sorted_(true),
|
||||
@ -224,16 +224,16 @@ Foam::fileFormats::STLsurfaceFormatCore::STLsurfaceFormatCore
|
||||
names_(0),
|
||||
sizes_(0)
|
||||
{
|
||||
off_t fileSize = Foam::size(fName);
|
||||
off_t fileSize = Foam::size(filename);
|
||||
|
||||
// auto-detect ascii/binary
|
||||
if (detectBINARY(fName))
|
||||
if (detectBINARY(filename))
|
||||
{
|
||||
readBINARY(IFstream(fName, IOstream::BINARY)(), fileSize);
|
||||
readBINARY(IFstream(filename, IOstream::BINARY)(), fileSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
readASCII(IFstream(fName)(), fileSize);
|
||||
readASCII(IFstream(filename)(), fileSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -186,53 +186,53 @@ Foam::fileFormats::surfaceFormatsCore::sortedPatchRegions
|
||||
// number of items, just do it ourselves
|
||||
|
||||
// step 1: get region sizes and store (regionId => patchI)
|
||||
Map<label> regionLookup;
|
||||
Map<label> lookup;
|
||||
forAll(regionLst, faceI)
|
||||
{
|
||||
const label regId = regionLst[faceI];
|
||||
|
||||
Map<label>::iterator iter = regionLookup.find(regId);
|
||||
if (iter == regionLookup.end())
|
||||
Map<label>::iterator fnd = lookup.find(regId);
|
||||
if (fnd != lookup.end())
|
||||
{
|
||||
regionLookup.insert(regId, 1);
|
||||
fnd()++;
|
||||
}
|
||||
else
|
||||
{
|
||||
iter()++;
|
||||
lookup.insert(regId, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// step 2: assign start/size (and name) to the newPatches
|
||||
// re-use the lookup to map (regionId => patchI)
|
||||
surfGroupList patchLst(regionLookup.size());
|
||||
label patchStart = 0;
|
||||
surfGroupList patchLst(lookup.size());
|
||||
label start = 0;
|
||||
label patchI = 0;
|
||||
forAllIter(Map<label>, regionLookup, iter)
|
||||
forAllIter(Map<label>, lookup, iter)
|
||||
{
|
||||
label regId = iter.key();
|
||||
|
||||
word patchName;
|
||||
Map<word>::const_iterator iter2 = patchNames.find(regId);
|
||||
if (iter2 == patchNames.end())
|
||||
word name;
|
||||
Map<word>::const_iterator fnd = patchNames.find(regId);
|
||||
if (fnd != patchNames.end())
|
||||
{
|
||||
patchName = word("patch") + ::Foam::name(patchI);
|
||||
name = fnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
patchName = iter2();
|
||||
name = word("patch") + ::Foam::name(patchI);
|
||||
}
|
||||
|
||||
patchLst[patchI] = surfGroup
|
||||
(
|
||||
patchName,
|
||||
name,
|
||||
0, // initialize with zero size
|
||||
patchStart,
|
||||
start,
|
||||
patchI
|
||||
);
|
||||
|
||||
// increment the start for the next patch
|
||||
// and save the (regionId => patchI) mapping
|
||||
patchStart += iter();
|
||||
start += iter();
|
||||
iter() = patchI++;
|
||||
}
|
||||
|
||||
@ -242,7 +242,7 @@ Foam::fileFormats::surfaceFormatsCore::sortedPatchRegions
|
||||
|
||||
forAll(regionLst, faceI)
|
||||
{
|
||||
label patchI = regionLookup[regionLst[faceI]];
|
||||
label patchI = lookup[regionLst[faceI]];
|
||||
faceMap[faceI] = patchLst[patchI].start() + patchLst[patchI].size()++;
|
||||
}
|
||||
|
||||
@ -260,7 +260,6 @@ Foam::fileFormats::surfaceFormatsCore::checkSupport
|
||||
const word& functionName
|
||||
)
|
||||
{
|
||||
|
||||
if (available.found(ext))
|
||||
{
|
||||
return true;
|
||||
|
||||
@ -64,10 +64,10 @@ inline void Foam::fileFormats::TRIsurfaceFormat<Face>::writeShell
|
||||
template<class Face>
|
||||
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>
|
||||
bool Foam::fileFormats::TRIsurfaceFormat<Face>::read
|
||||
(
|
||||
const fileName& fName
|
||||
const fileName& filename
|
||||
)
|
||||
{
|
||||
this->clear();
|
||||
|
||||
// read in the values
|
||||
TRIsurfaceFormatCore reader(fName);
|
||||
TRIsurfaceFormatCore reader(filename);
|
||||
|
||||
// transfer points
|
||||
this->storedPoints().transfer(reader.points());
|
||||
|
||||
@ -88,14 +88,11 @@ public:
|
||||
// Selectors
|
||||
|
||||
//- Read file and return surface
|
||||
static autoPtr<MeshedSurface<Face> > New
|
||||
(
|
||||
const fileName& fName
|
||||
)
|
||||
static autoPtr<MeshedSurface<Face> > New(const fileName& name)
|
||||
{
|
||||
return autoPtr<MeshedSurface<Face> >
|
||||
(
|
||||
new TRIsurfaceFormat<Face>(fName)
|
||||
new TRIsurfaceFormat<Face>(name)
|
||||
);
|
||||
}
|
||||
|
||||
@ -118,11 +115,11 @@ public:
|
||||
//- Write MeshedSurface
|
||||
static void write
|
||||
(
|
||||
const fileName& fName,
|
||||
const fileName& name,
|
||||
const MeshedSurface<Face>& surf
|
||||
)
|
||||
{
|
||||
write(OFstream(fName)(), surf);
|
||||
write(OFstream(name)(), surf);
|
||||
}
|
||||
|
||||
//- Write UnsortedMeshedSurface
|
||||
@ -137,11 +134,11 @@ public:
|
||||
// By default, the output is not sorted by regions
|
||||
static void write
|
||||
(
|
||||
const fileName& fName,
|
||||
const fileName& name,
|
||||
const UnsortedMeshedSurface<Face>& surf
|
||||
)
|
||||
{
|
||||
write(OFstream(fName)(), surf);
|
||||
write(OFstream(name)(), surf);
|
||||
}
|
||||
|
||||
//- Write object
|
||||
|
||||
@ -38,7 +38,7 @@ License
|
||||
|
||||
Foam::fileFormats::TRIsurfaceFormatCore::TRIsurfaceFormatCore
|
||||
(
|
||||
const fileName& fName
|
||||
const fileName& filename
|
||||
)
|
||||
:
|
||||
sorted_(true),
|
||||
@ -46,7 +46,7 @@ Foam::fileFormats::TRIsurfaceFormatCore::TRIsurfaceFormatCore
|
||||
regions_(0),
|
||||
sizes_(0)
|
||||
{
|
||||
read(fName);
|
||||
read(filename);
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructors * * * * * * * * * * * * * * * //
|
||||
@ -59,20 +59,20 @@ Foam::fileFormats::TRIsurfaceFormatCore::~TRIsurfaceFormatCore()
|
||||
|
||||
bool Foam::fileFormats::TRIsurfaceFormatCore::read
|
||||
(
|
||||
const fileName& fName
|
||||
const fileName& filename
|
||||
)
|
||||
{
|
||||
this->clear();
|
||||
sorted_ = true;
|
||||
|
||||
IFstream is(fName);
|
||||
IFstream is(filename);
|
||||
if (!is.good())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"fileFormats::TRIsurfaceFormatCore::read(const fileName&)"
|
||||
)
|
||||
<< "Cannot read file " << fName
|
||||
<< "Cannot read file " << filename
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
@ -161,19 +161,25 @@ bool Foam::fileFormats::TRIsurfaceFormatCore::read
|
||||
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
|
||||
points_.transfer(dynPoints);
|
||||
regions_.transfer(dynRegions);
|
||||
|
||||
if (dynSizes[0] == 0)
|
||||
{
|
||||
// no ungrouped patches, copy sub-list
|
||||
sizes_ = SubList<label>(dynSizes, dynSizes.size()-1, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
sizes_.transfer(dynSizes);
|
||||
}
|
||||
sizes_.transfer(dynSizes);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -58,72 +58,6 @@ Foam::fileFormats::VTKsurfaceFormat<Face>::VTKsurfaceFormat()
|
||||
|
||||
// * * * * * * * * * * * * * * * 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>
|
||||
void Foam::fileFormats::VTKsurfaceFormat<Face>::write
|
||||
(
|
||||
@ -157,4 +91,34 @@ void Foam::fileFormats::VTKsurfaceFormat<Face>::write
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -27,6 +27,7 @@ Class
|
||||
|
||||
Description
|
||||
Provide a means of writing VTK legacy format.
|
||||
The output is never sorted by patch.
|
||||
|
||||
SourceFiles
|
||||
VTKsurfaceFormat.C
|
||||
@ -56,7 +57,7 @@ namespace fileFormats
|
||||
template<class Face>
|
||||
class VTKsurfaceFormat
|
||||
:
|
||||
public UnsortedMeshedSurface<Face>,
|
||||
public MeshedSurface<Face>,
|
||||
public VTKsurfaceFormatCore
|
||||
{
|
||||
// Private Member Functions
|
||||
@ -98,15 +99,15 @@ public:
|
||||
//- Write MeshedSurface
|
||||
static void write
|
||||
(
|
||||
const fileName& fName,
|
||||
const fileName& name,
|
||||
const MeshedSurface<Face>& surf
|
||||
)
|
||||
{
|
||||
write(OFstream(fName)(), surf);
|
||||
write(OFstream(name)(), surf);
|
||||
}
|
||||
|
||||
//- Write UnsortedMeshedSurface
|
||||
// By default, the output is not sorted by regions.
|
||||
// The output remains unsorted
|
||||
static void write
|
||||
(
|
||||
Ostream&,
|
||||
@ -114,14 +115,14 @@ public:
|
||||
);
|
||||
|
||||
//- Write UnsortedMeshedSurface
|
||||
// By default, the output is not sorted by regions.
|
||||
// The output remains unsorted
|
||||
static void write
|
||||
(
|
||||
const fileName& fName,
|
||||
const fileName& name,
|
||||
const UnsortedMeshedSurface<Face>& surf
|
||||
)
|
||||
{
|
||||
write(OFstream(fName)(), surf);
|
||||
write(OFstream(name)(), surf);
|
||||
}
|
||||
|
||||
//- Write object
|
||||
|
||||
Reference in New Issue
Block a user