mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
checked in surfMesh library code
- keyedSurface is similar to triSurface, but uses faces - meshedSurface is sorted in regions and should be more memory efficient - surfMesh is the placeholder name for an OpenFOAM native surface format
This commit is contained in:
@ -1,40 +1,46 @@
|
||||
09/01/04
|
||||
2008-10-23
|
||||
|
||||
Contents:
|
||||
|
||||
surfaceAdd
|
||||
adds to surface files. (but does not intersect or anything)
|
||||
- adds to surface files. (but does not intersect or anything)
|
||||
|
||||
surfaceBooleanOp
|
||||
Boolean operations (add, or, xor) on closed surfaces. Probably not working.
|
||||
- Boolean operations (add, or, xor) on closed surfaces. Probably not working.
|
||||
|
||||
surfaceCheck
|
||||
checks surface for incorrect topology. Checks normals of neighbouring faces.
|
||||
- checks surface for incorrect topology. Checks normals of neighbouring faces.
|
||||
|
||||
surfaceCoarsen
|
||||
Stan Melax coarsening algorithm
|
||||
- Stan Melax coarsening algorithm
|
||||
|
||||
surfaceConvert
|
||||
Converts surfaces to/from various formats
|
||||
- Converts surfaces to/from various formats
|
||||
|
||||
surfaceFind
|
||||
Finds nearest vertex and face to given point.
|
||||
- Finds nearest vertex and face to given point.
|
||||
|
||||
surfaceMeshTriangulate
|
||||
Triangulate external facses of mesh and write as surface.
|
||||
- Triangulate external facses of mesh and write as surface.
|
||||
|
||||
surfacePointMerge
|
||||
Explicit point merge of surface.
|
||||
- Explicit point merge of surface.
|
||||
|
||||
surfaceSetOutside
|
||||
Orient normals on (closed) surface.
|
||||
- Orient normals on (closed) surface.
|
||||
|
||||
surfaceSmooth
|
||||
Laplacian smoothing on surface vertices
|
||||
- Laplacian smoothing on surface vertices
|
||||
|
||||
surfaceSubset
|
||||
Subsets surface
|
||||
- Subsets surface
|
||||
|
||||
surfaceToPatch
|
||||
Applies region information of surfaces to mesh. Each external face of mesh
|
||||
gets region number of nearest surface triangle.
|
||||
- Applies region information of surfaces to mesh.
|
||||
Each external face of mesh gets region number of nearest surface triangle.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
surfaceMeshConvert
|
||||
- Similar to surfaceConvert, but uses surfMesh library
|
||||
|
||||
|
||||
@ -0,0 +1,3 @@
|
||||
surfaceMeshConvert.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/surfaceMeshConvert
|
||||
@ -0,0 +1,5 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/triSurface/lnInclude \
|
||||
-I$(LIB_SRC)/surfMesh/lnInclude
|
||||
|
||||
EXE_LIBS = -lsurfMesh
|
||||
@ -0,0 +1,145 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
Application
|
||||
surfaceMeshConvert
|
||||
|
||||
Description
|
||||
Converts from one surface mesh format to another
|
||||
|
||||
Usage
|
||||
- surfaceMeshConvert inputFile outputFile [OPTION]
|
||||
|
||||
@param -clean \n
|
||||
Perform some surface checking/cleanup on the input surface
|
||||
|
||||
@param -scale \<scale\> \n
|
||||
Specify a scaling factor for writing the files
|
||||
|
||||
@param -triSurface \n
|
||||
Use triSurface library for input/output
|
||||
|
||||
Note
|
||||
The filename extensions are used to determine the file format type.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "timeSelector.H"
|
||||
#include "Time.H"
|
||||
#include "polyMesh.H"
|
||||
#include "meshedSurface.H"
|
||||
#include "triSurface.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
// Main program:
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noParallel();
|
||||
argList::validArgs.append("inputFile");
|
||||
argList::validArgs.append("outputFile");
|
||||
argList::validOptions.insert("scale", "scale");
|
||||
argList::validOptions.insert("clean", "");
|
||||
argList::validOptions.insert("triSurface", "");
|
||||
# include "setRootCase.H"
|
||||
const stringList& params = args.additionalArgs();
|
||||
|
||||
scalar scaleFactor = 0;
|
||||
if (args.options().found("scale"))
|
||||
{
|
||||
IStringStream(args.options()["scale"])() >> scaleFactor;
|
||||
}
|
||||
|
||||
fileName importName(params[0]);
|
||||
fileName exportName(params[1]);
|
||||
|
||||
if
|
||||
(
|
||||
!meshedSurface::canRead(importName.ext(), true)
|
||||
|| !meshedSurface::canWrite(exportName.ext(), true)
|
||||
)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (args.options().found("triSurface"))
|
||||
{
|
||||
// # include "createTime.H"
|
||||
// instantList timeDirs = timeSelector::select0(runTime, args);
|
||||
// # include "createPolyMesh.H"
|
||||
|
||||
triSurface surf(importName);
|
||||
|
||||
if (args.options().found("clean"))
|
||||
{
|
||||
surf.cleanup(true);
|
||||
surf.checkOrientation(true);
|
||||
}
|
||||
|
||||
Info << "writing " << exportName;
|
||||
if (scaleFactor <= 0)
|
||||
{
|
||||
Info<< " without scaling" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< " triSurface does not yet support scaling "
|
||||
<< scaleFactor << endl;
|
||||
// surf.scalePoints(scaleFactor);
|
||||
}
|
||||
surf.write(exportName);
|
||||
}
|
||||
else
|
||||
{
|
||||
meshedSurface surf(importName);
|
||||
|
||||
if (args.options().found("clean"))
|
||||
{
|
||||
surf.cleanup(true);
|
||||
surf.checkOrientation(true);
|
||||
}
|
||||
|
||||
surf.scalePoints(scaleFactor);
|
||||
|
||||
Info<< "writing " << exportName;
|
||||
if (scaleFactor <= 0)
|
||||
{
|
||||
Info<< " without scaling" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< " with scaling " << scaleFactor << endl;
|
||||
}
|
||||
surf.write(exportName);
|
||||
}
|
||||
|
||||
Info<< "\nEnd\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -13,6 +13,7 @@ wmake libso lagrangian/basic
|
||||
|
||||
wmake libso triSurface
|
||||
wmake libso edgeMesh
|
||||
wmake libso surfMesh
|
||||
wmake libso meshTools
|
||||
wmake libso finiteVolume
|
||||
|
||||
|
||||
@ -39,6 +39,7 @@ SourceFiles
|
||||
#define Keyed_H
|
||||
|
||||
#include "List.H"
|
||||
#include "xfer.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -48,6 +49,7 @@ namespace Foam
|
||||
// Forward declaration of friend functions and operators
|
||||
|
||||
template<class T> class Keyed;
|
||||
template<class T> class xfer;
|
||||
|
||||
template<class T> Istream& operator>>(Istream&, Keyed<T>&);
|
||||
template<class T> Ostream& operator<<(Ostream&, const Keyed<T>&);
|
||||
@ -92,6 +94,9 @@ public:
|
||||
//- Construct as a copy of item, with a key
|
||||
inline Keyed(const T& item, const label key=0);
|
||||
|
||||
//- Construct by transferring the item, with a key
|
||||
inline Keyed(const xfer<T>& item, const label key=0);
|
||||
|
||||
//- Construct from Istream
|
||||
inline Keyed(Istream&);
|
||||
|
||||
|
||||
@ -30,7 +30,6 @@ License
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
//- Construct null
|
||||
template<class T>
|
||||
inline Foam::Keyed<T>::Keyed()
|
||||
:
|
||||
@ -38,7 +37,6 @@ inline Foam::Keyed<T>::Keyed()
|
||||
{}
|
||||
|
||||
|
||||
//- Construct from components
|
||||
template<class T>
|
||||
inline Foam::Keyed<T>::Keyed(const T& item, const label key)
|
||||
:
|
||||
@ -47,6 +45,14 @@ inline Foam::Keyed<T>::Keyed(const T& item, const label key)
|
||||
{}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline Foam::Keyed<T>::Keyed(const xfer<T>& item, const label key)
|
||||
:
|
||||
T(item),
|
||||
key_(key)
|
||||
{}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline Foam::Keyed<T>::Keyed(Istream& is)
|
||||
{
|
||||
|
||||
23
src/surfMesh/Make/files
Normal file
23
src/surfMesh/Make/files
Normal file
@ -0,0 +1,23 @@
|
||||
keyedSurface/keyedSurface.C
|
||||
keyedSurface/keyedSurfaceCleanup.C
|
||||
keyedSurface/newKeyedSurface.C
|
||||
|
||||
meshedSurface/meshedSurface.C
|
||||
meshedSurface/meshedSurfaceCleanup.C
|
||||
meshedSurface/newMeshedSurface.C
|
||||
|
||||
fileFormats = keyedSurface/fileFormats
|
||||
$(fileFormats)/ac3d/AC3DfileFormat.C
|
||||
$(fileFormats)/gts/GTSfileFormat.C
|
||||
$(fileFormats)/nas/NASfileFormat.C
|
||||
$(fileFormats)/obj/OBJfileFormat.C
|
||||
$(fileFormats)/off/OFFfileFormat.C
|
||||
$(fileFormats)/smesh/SMESHfileFormat.C
|
||||
$(fileFormats)/starcd/STARCDfileFormat.C
|
||||
$(fileFormats)/stl/STLfileFormat.C
|
||||
$(fileFormats)/stl/STLfileFormatASCII.L
|
||||
$(fileFormats)/tri/TRIfileFormat.C
|
||||
$(fileFormats)/vtk/VTKfileFormat.C
|
||||
|
||||
LIB = $(FOAM_LIBBIN)/libsurfMesh
|
||||
|
||||
5
src/surfMesh/Make/options
Normal file
5
src/surfMesh/Make/options
Normal file
@ -0,0 +1,5 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/triSurface/lnInclude
|
||||
|
||||
LIB_LIBS = \
|
||||
-ltriSurface
|
||||
588
src/surfMesh/keyedSurface/fileFormats/ac3d/AC3DfileFormat.C
Normal file
588
src/surfMesh/keyedSurface/fileFormats/ac3d/AC3DfileFormat.C
Normal file
@ -0,0 +1,588 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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 "AC3DfileFormat.H"
|
||||
#include "clock.H"
|
||||
#include "IFstream.H"
|
||||
#include "IStringStream.H"
|
||||
#include "tensor.H"
|
||||
#include "primitivePatch.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
#include "addToMemberFunctionSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
namespace Foam
|
||||
{
|
||||
namespace fileFormats
|
||||
{
|
||||
|
||||
addNamedToRunTimeSelectionTable
|
||||
(
|
||||
keyedSurface,
|
||||
AC3DfileFormat,
|
||||
fileExtension,
|
||||
ac
|
||||
);
|
||||
|
||||
addNamedToMemberFunctionSelectionTable
|
||||
(
|
||||
keyedSurface,
|
||||
AC3DfileFormat,
|
||||
write,
|
||||
fileExtension,
|
||||
ac
|
||||
);
|
||||
|
||||
addNamedToMemberFunctionSelectionTable
|
||||
(
|
||||
meshedSurface,
|
||||
AC3DfileFormat,
|
||||
write,
|
||||
fileExtension,
|
||||
ac
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
Type Foam::fileFormats::AC3DfileFormat::parse(const string& str)
|
||||
{
|
||||
IStringStream ss(str);
|
||||
|
||||
Type t;
|
||||
ss >> t;
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::fileFormats::AC3DfileFormat::readCmd
|
||||
(
|
||||
IFstream& is,
|
||||
string& cmd,
|
||||
string& args
|
||||
)
|
||||
{
|
||||
if (is.good())
|
||||
{
|
||||
string line;
|
||||
is.getLine(line);
|
||||
|
||||
string::size_type space = line.find(' ');
|
||||
|
||||
if (space != string::npos)
|
||||
{
|
||||
cmd = line.substr(0, space);
|
||||
args = line.substr(space+1);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Read up to line starting with cmd. Sets args to rest of line.
|
||||
// Returns true if found, false if stream is not good anymore.
|
||||
bool Foam::fileFormats::AC3DfileFormat::cueTo
|
||||
(
|
||||
IFstream& is,
|
||||
const string& cmd,
|
||||
string& args
|
||||
)
|
||||
{
|
||||
while (is.good())
|
||||
{
|
||||
string line;
|
||||
is.getLine(line);
|
||||
|
||||
string::size_type space = line.find(' ');
|
||||
|
||||
if (space != string::npos)
|
||||
{
|
||||
if (line.substr(0, space) == cmd)
|
||||
{
|
||||
args = line.substr(space+1);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Similar to cueTo(), but throws error if cmd not found
|
||||
Foam::string Foam::fileFormats::AC3DfileFormat::cueToOrDie
|
||||
(
|
||||
IFstream& is,
|
||||
const string& cmd,
|
||||
const string& errorMsg
|
||||
)
|
||||
{
|
||||
string args;
|
||||
if (!cueTo(is, cmd, args))
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"fileFormats::AC3DfileFormat::AC3DfileFormat"
|
||||
"(const fileName&)"
|
||||
)
|
||||
<< "Cannot find command " << cmd
|
||||
<< " " << errorMsg
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::fileFormats::AC3DfileFormat::AC3DfileFormat()
|
||||
:
|
||||
Foam::keyedSurface()
|
||||
{}
|
||||
|
||||
|
||||
Foam::fileFormats::AC3DfileFormat::AC3DfileFormat
|
||||
(
|
||||
const fileName& fName,
|
||||
const bool triangulate
|
||||
)
|
||||
:
|
||||
Foam::keyedSurface()
|
||||
{
|
||||
IFstream is(fName);
|
||||
|
||||
if (!is.good())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"fileFormats::AC3DfileFormat::AC3DfileFormat"
|
||||
"(const fileName&)"
|
||||
)
|
||||
<< "Cannot read file " << fName
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
string line, cmd, args;
|
||||
|
||||
is.getLine(line);
|
||||
|
||||
string version = line.substr(4);
|
||||
|
||||
if (version != "b")
|
||||
{
|
||||
WarningIn
|
||||
(
|
||||
"fileFormats::AC3DfileFormat::AC3DfileFormat"
|
||||
"(const fileName&)"
|
||||
)
|
||||
<< "When reading AC3D file " << fName
|
||||
<< " read header " << line << " with version "
|
||||
<< version << endl
|
||||
<< "Only tested reading with version 'b'."
|
||||
<< " This might give problems" << endl;
|
||||
}
|
||||
|
||||
|
||||
if (!cueTo(is, "OBJECT", args) || (args != "world"))
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"fileFormats::AC3DfileFormat::AC3DfileFormat"
|
||||
"(const fileName&)"
|
||||
)
|
||||
<< "Cannot find \"OBJECT world\" in file " << fName
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
// # of kids is the # of patches
|
||||
args = cueToOrDie(is, "kids");
|
||||
label nPatches = parse<int>(args);
|
||||
|
||||
// Start of vertices for object/patch
|
||||
label patchVertOffset = 0;
|
||||
|
||||
DynamicList<point> pointLst;
|
||||
DynamicList<keyedFace> faceLst;
|
||||
|
||||
// patchId => patchName
|
||||
Map<word> regionNames;
|
||||
|
||||
for (label patchI = 0; patchI < nPatches; ++patchI)
|
||||
{
|
||||
word patchName = word("patch") + Foam::name(patchI);
|
||||
|
||||
args = cueToOrDie(is, "OBJECT", "while reading " + patchName);
|
||||
|
||||
// number of vertices for this patch
|
||||
label nPatchPoints = 0;
|
||||
vector location(pTraits<vector>::zero);
|
||||
// tensor rotation(I);
|
||||
|
||||
// Read all info for current patch
|
||||
while (is.good())
|
||||
{
|
||||
// Read line and get first word. If end of file break since
|
||||
// patch should always end with 'kids' command ?not sure.
|
||||
if (!readCmd(is, cmd, args))
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"fileFormats::AC3DfileFormat::AC3DfileFormat"
|
||||
"(const fileName&)"
|
||||
)
|
||||
<< "Did not read up to \"kids 0\" while reading patch "
|
||||
<< patchI << " from file " << fName
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
if (cmd == "name")
|
||||
{
|
||||
// name %s
|
||||
string str = parse<string>(args);
|
||||
string::stripInvalid<word>(str);
|
||||
|
||||
patchName = str;
|
||||
}
|
||||
else if (cmd == "rot")
|
||||
{
|
||||
// rot %f %f %f %f %f %f %f %f %f
|
||||
|
||||
// IStringStream lineStream(args);
|
||||
//
|
||||
// lineStream
|
||||
// >> rotation.xx() >> rotation.xy() >> rotation.xz()
|
||||
// >> rotation.yx() >> rotation.yy() >> rotation.yz()
|
||||
// >> rotation.zx() >> rotation.zy() >> rotation.zz();
|
||||
|
||||
WarningIn
|
||||
(
|
||||
"fileFormats::AC3DfileFormat::AC3DfileFormat"
|
||||
"(const fileName&)"
|
||||
)
|
||||
<< "rot (rotation tensor) command not implemented"
|
||||
<< "Line:" << cmd << ' ' << args << endl
|
||||
<< "while reading patch " << patchI << endl;
|
||||
}
|
||||
else if (cmd == "loc")
|
||||
{
|
||||
// loc %f %f %f
|
||||
IStringStream lineStream(args);
|
||||
|
||||
lineStream
|
||||
>> location.x()
|
||||
>> location.y()
|
||||
>> location.z();
|
||||
}
|
||||
else if (cmd == "numvert")
|
||||
{
|
||||
// numvert %d
|
||||
nPatchPoints = parse<int>(args);
|
||||
|
||||
for (label vertI = 0; vertI < nPatchPoints; ++vertI)
|
||||
{
|
||||
is.getLine(line);
|
||||
IStringStream lineStream(line);
|
||||
|
||||
point pt;
|
||||
lineStream
|
||||
>> pt.x() >> pt.y() >> pt.z();
|
||||
|
||||
// Offset with current translation vector
|
||||
pointLst.append(location + pt);
|
||||
}
|
||||
}
|
||||
else if (cmd == "numsurf")
|
||||
{
|
||||
label nFaces = parse<int>(args);
|
||||
|
||||
for (label faceI = 0; faceI < nFaces; ++faceI)
|
||||
{
|
||||
static string errorMsg =
|
||||
string(" while reading face ")
|
||||
+ Foam::name(faceI) + " on patch "
|
||||
+ Foam::name(patchI)
|
||||
+ " from file " + fName;
|
||||
|
||||
cueToOrDie(is, "SURF", errorMsg);
|
||||
cueToOrDie(is, "mat", errorMsg);
|
||||
args = cueToOrDie(is, "refs", errorMsg);
|
||||
|
||||
label nVert = parse<int>(args);
|
||||
|
||||
List<label> verts(nVert);
|
||||
forAll(verts, vertI)
|
||||
{
|
||||
is.getLine(line);
|
||||
verts[vertI] = parse<int>(line) + patchVertOffset;
|
||||
}
|
||||
|
||||
if (triangulate && verts.size() > 3)
|
||||
{
|
||||
face fTri(3);
|
||||
|
||||
// simple face triangulation about f[0].
|
||||
// cannot use face::triangulation
|
||||
// since points are incomplete
|
||||
fTri[0] = verts[0];
|
||||
for (label fp1 = 1; fp1 < verts.size() - 1; ++fp1)
|
||||
{
|
||||
label fp2 = (fp1 + 1) % verts.size();
|
||||
|
||||
fTri[1] = verts[fp1];
|
||||
fTri[2] = verts[fp2];
|
||||
|
||||
faceLst.append(keyedFace(fTri, patchI));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
faceLst.append(keyedFace(face(verts), patchI));
|
||||
}
|
||||
}
|
||||
|
||||
// Done the current patch.
|
||||
// Increment the offset vertices are stored at
|
||||
patchVertOffset += nPatchPoints;
|
||||
}
|
||||
else if (cmd == "kids")
|
||||
{
|
||||
// 'kids' denotes the end of the current patch.
|
||||
label nKids = parse<int>(args);
|
||||
|
||||
if (nKids != 0)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"fileFormats::AC3DfileFormat::AC3DfileFormat"
|
||||
"(const fileName&)"
|
||||
)
|
||||
<< "Can only read objects without kids."
|
||||
<< " Encountered " << nKids << " kids when"
|
||||
<< " reading patch " << patchI
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
// Done reading current patch
|
||||
regionNames.insert(patchI, patchName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// transfer to normal lists
|
||||
points().transfer(pointLst);
|
||||
faces().transfer(faceLst);
|
||||
setPatches(regionNames);
|
||||
stitchFaces(SMALL);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::fileFormats::AC3DfileFormat::writeHeader
|
||||
(
|
||||
Ostream& os,
|
||||
const List<surfacePatch>& patchLst
|
||||
)
|
||||
{
|
||||
// Write with patches as separate objects under "world" object.
|
||||
// Header is taken over from sample file.
|
||||
// Defines separate materials for all patches. Recycle colours.
|
||||
|
||||
// Define 8 standard colours as r,g,b components
|
||||
static scalar colourMap[] =
|
||||
{
|
||||
1, 1, 1,
|
||||
1, 0, 0,
|
||||
0, 1, 0,
|
||||
0, 0, 1,
|
||||
1, 1, 0,
|
||||
0, 1, 1,
|
||||
1, 0, 1,
|
||||
0.5, 0.5, 1
|
||||
};
|
||||
|
||||
// Write header. Define materials.
|
||||
os << "AC3Db" << nl;
|
||||
|
||||
forAll(patchLst, patchI)
|
||||
{
|
||||
const word& pName = patchLst[patchI].name();
|
||||
|
||||
label colourI = patchI % 8;
|
||||
label colourCompI = 3 * colourI;
|
||||
|
||||
os << "MATERIAL \"" << pName << "Mat\" rgb "
|
||||
<< colourMap[colourCompI] << ' ' << colourMap[colourCompI+1]
|
||||
<< ' ' << colourMap[colourCompI+2]
|
||||
<< " amb 0.2 0.2 0.2 emis 0 0 0 spec 0.5 0.5 0.5 shi 10"
|
||||
<< " trans 0"
|
||||
<< nl;
|
||||
}
|
||||
|
||||
os << "OBJECT world" << nl
|
||||
<< "kids " << patchLst.size() << endl;
|
||||
}
|
||||
|
||||
|
||||
void Foam::fileFormats::AC3DfileFormat::write
|
||||
(
|
||||
Ostream& os,
|
||||
const keyedSurface& surf
|
||||
)
|
||||
{
|
||||
labelList faceMap;
|
||||
List<surfacePatch> patchLst = surf.sortedRegions(faceMap);
|
||||
|
||||
writeHeader(os, patchLst);
|
||||
|
||||
label faceIndex = 0;
|
||||
forAll(patchLst, patchI)
|
||||
{
|
||||
const surfacePatch& sp = patchLst[patchI];
|
||||
|
||||
os << "OBJECT poly" << nl
|
||||
<< "name \"" << sp.name() << '"' << endl;
|
||||
|
||||
// Create patch with only patch faces included for ease of addressing
|
||||
boolList include(surf.size(), false);
|
||||
|
||||
forAll(sp, patchFaceI)
|
||||
{
|
||||
const label faceI = faceMap[faceIndex++];
|
||||
|
||||
include[faceI] = true;
|
||||
}
|
||||
|
||||
labelList pMap;
|
||||
labelList fMap;
|
||||
|
||||
keyedSurface patch = surf.subsetMesh
|
||||
(
|
||||
include, pMap, fMap
|
||||
);
|
||||
|
||||
// Now we have triSurface for this patch alone. Write it.
|
||||
os << "numvert " << patch.nPoints() << endl;
|
||||
|
||||
forAll(patch.localPoints(), ptI)
|
||||
{
|
||||
const point& pt = patch.localPoints()[ptI];
|
||||
|
||||
os << pt.x() << ' ' << pt.y() << ' ' << pt.z() << endl;
|
||||
}
|
||||
|
||||
os << "numsurf " << patch.localFaces().size() << endl;
|
||||
|
||||
forAll(patch.localFaces(), faceI)
|
||||
{
|
||||
const keyedFace& f = patch.localFaces()[faceI];
|
||||
|
||||
os << "SURF 0x20" << nl // polygon
|
||||
<< "mat " << patchI << nl
|
||||
<< "refs " << f.size() << nl;
|
||||
|
||||
forAll(f, fp)
|
||||
{
|
||||
os << f[fp] << " 0 0" << nl;
|
||||
}
|
||||
}
|
||||
|
||||
os << "kids 0" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::fileFormats::AC3DfileFormat::write
|
||||
(
|
||||
Ostream& os,
|
||||
const meshedSurface& surf
|
||||
)
|
||||
{
|
||||
const pointField& pointLst = surf.points();
|
||||
const List<face>& faceLst = surf.faces();
|
||||
const List<surfacePatch>& patchLst = surf.patches();
|
||||
|
||||
writeHeader(os, patchLst);
|
||||
|
||||
forAll(patchLst, patchI)
|
||||
{
|
||||
const surfacePatch& sp = patchLst[patchI];
|
||||
|
||||
os << "OBJECT poly" << nl
|
||||
<< "name \"" << sp.name() << '"' << endl;
|
||||
|
||||
// Temporary primitivePatch to calculate compact points & faces
|
||||
primitivePatch patch
|
||||
(
|
||||
SubList<face>
|
||||
(
|
||||
faceLst,
|
||||
sp.start(),
|
||||
sp.size()
|
||||
),
|
||||
pointLst
|
||||
);
|
||||
|
||||
os << "numvert " << patch.nPoints() << endl;
|
||||
|
||||
forAll(patch.localPoints(), ptI)
|
||||
{
|
||||
const point& pt = patch.localPoints()[ptI];
|
||||
|
||||
os << pt.x() << ' ' << pt.y() << ' ' << pt.z() << endl;
|
||||
}
|
||||
|
||||
os << "numsurf " << patch.localFaces().size() << endl;
|
||||
|
||||
forAll(patch.localFaces(), faceI)
|
||||
{
|
||||
const keyedFace& f = patch.localFaces()[faceI];
|
||||
|
||||
os << "SURF 0x20" << nl // polygon
|
||||
<< "mat " << patchI << nl
|
||||
<< "refs " << f.size() << nl;
|
||||
|
||||
forAll(f, fp)
|
||||
{
|
||||
os << f[fp] << " 0 0" << nl;
|
||||
}
|
||||
}
|
||||
|
||||
os << "kids 0" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
||||
167
src/surfMesh/keyedSurface/fileFormats/ac3d/AC3DfileFormat.H
Normal file
167
src/surfMesh/keyedSurface/fileFormats/ac3d/AC3DfileFormat.H
Normal file
@ -0,0 +1,167 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
Class
|
||||
Foam::fileFormats::AC3DfileFormat
|
||||
|
||||
Description
|
||||
Provide a means of reading/writing AC3D format.
|
||||
|
||||
http://www.inivis.com/ac3d/man/ac3dfileformat.html
|
||||
|
||||
Note
|
||||
Since the faces are already organized as patches, the reader could be
|
||||
optimized for this, but at expense of losing a common reading approach.
|
||||
|
||||
SourceFiles
|
||||
AC3DfileFormat.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef AC3DfileFormat_H
|
||||
#define AC3DfileFormat_H
|
||||
|
||||
#include "Ostream.H"
|
||||
#include "OFstream.H"
|
||||
#include "keyedSurface.H"
|
||||
#include "meshedSurface.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace fileFormats
|
||||
{
|
||||
|
||||
class AC3DfileFormat;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class AC3DfileFormat Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class AC3DfileFormat
|
||||
:
|
||||
public keyedSurface
|
||||
{
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Read a type via IStringStream
|
||||
template<class Type>
|
||||
static Type parse(const string&);
|
||||
|
||||
//- Read cmd, args from IFstream
|
||||
static bool readCmd(IFstream&, string& cmd, string& args);
|
||||
|
||||
//- Cue up to cmd, reading args
|
||||
static bool cueTo(IFstream&, const string& cmd, string& args);
|
||||
|
||||
//- Cue up to cmd, reading args or exit with a FatalError
|
||||
// returns the command args
|
||||
static string cueToOrDie
|
||||
(
|
||||
IFstream&,
|
||||
const string& cmd,
|
||||
const string& errorMsg=string::null
|
||||
);
|
||||
|
||||
//- Write header with materials
|
||||
static void writeHeader(Ostream&, const List<surfacePatch>&);
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
AC3DfileFormat(const AC3DfileFormat&);
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const AC3DfileFormat&);
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct null
|
||||
AC3DfileFormat();
|
||||
|
||||
//- Construct from file name
|
||||
AC3DfileFormat(const fileName&, const bool triangulate=false);
|
||||
|
||||
// Selectors
|
||||
|
||||
//- Read file and return keyedSurface
|
||||
static autoPtr<keyedSurface> New
|
||||
(
|
||||
const fileName& fName,
|
||||
const bool triangulate=false
|
||||
)
|
||||
{
|
||||
return autoPtr<keyedSurface>
|
||||
(
|
||||
new AC3DfileFormat(fName, triangulate)
|
||||
);
|
||||
}
|
||||
|
||||
// Destructor
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Write
|
||||
|
||||
//- Write keyedSurface
|
||||
static void write(Ostream&, const keyedSurface&);
|
||||
|
||||
//- Write keyedSurface
|
||||
static void write(const fileName& fName, const keyedSurface& surf)
|
||||
{
|
||||
write(OFstream(fName)(), surf);
|
||||
}
|
||||
|
||||
//- Write meshedSurface
|
||||
static void write(Ostream&, const meshedSurface&);
|
||||
|
||||
//- Write meshedSurface
|
||||
static void write(const fileName& fName, const meshedSurface& surf)
|
||||
{
|
||||
write(OFstream(fName)(), surf);
|
||||
}
|
||||
|
||||
//- Write object
|
||||
virtual void write(Ostream& os) const
|
||||
{
|
||||
write(os, *this);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace fileFormats
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
440
src/surfMesh/keyedSurface/fileFormats/gts/GTSfileFormat.C
Normal file
440
src/surfMesh/keyedSurface/fileFormats/gts/GTSfileFormat.C
Normal file
@ -0,0 +1,440 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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 "GTSfileFormat.H"
|
||||
#include "clock.H"
|
||||
#include "IFstream.H"
|
||||
#include "IStringStream.H"
|
||||
#include "tensor.H"
|
||||
#include "primitivePatch.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
#include "addToMemberFunctionSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
namespace Foam
|
||||
{
|
||||
namespace fileFormats
|
||||
{
|
||||
|
||||
addNamedToRunTimeSelectionTable
|
||||
(
|
||||
keyedSurface,
|
||||
GTSfileFormat,
|
||||
fileExtension,
|
||||
gts
|
||||
);
|
||||
|
||||
addNamedToMemberFunctionSelectionTable
|
||||
(
|
||||
keyedSurface,
|
||||
GTSfileFormat,
|
||||
write,
|
||||
fileExtension,
|
||||
gts
|
||||
);
|
||||
|
||||
addNamedToMemberFunctionSelectionTable
|
||||
(
|
||||
meshedSurface,
|
||||
GTSfileFormat,
|
||||
write,
|
||||
fileExtension,
|
||||
gts
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::fileFormats::GTSfileFormat::GTSfileFormat()
|
||||
:
|
||||
Foam::keyedSurface()
|
||||
{}
|
||||
|
||||
|
||||
Foam::fileFormats::GTSfileFormat::GTSfileFormat
|
||||
(
|
||||
const fileName& fName,
|
||||
const bool triangulate
|
||||
)
|
||||
:
|
||||
Foam::keyedSurface()
|
||||
{
|
||||
IFstream is(fName);
|
||||
|
||||
if (!is.good())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"fileFormats::GTSfileFormat::GTSfileFormat"
|
||||
"(const fileName&)"
|
||||
)
|
||||
<< "Cannot read file " << fName
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
// Read header
|
||||
string line = getLineNoComment(is);
|
||||
|
||||
label nPoints, nEdges, nElems;
|
||||
{
|
||||
IStringStream lineStream(line);
|
||||
lineStream
|
||||
>> nPoints
|
||||
>> nEdges
|
||||
>> nElems;
|
||||
}
|
||||
|
||||
pointField pointLst(nPoints);
|
||||
|
||||
// Read points
|
||||
forAll(pointLst, pointI)
|
||||
{
|
||||
scalar x, y, z;
|
||||
line = getLineNoComment(is);
|
||||
{
|
||||
IStringStream lineStream(line);
|
||||
lineStream
|
||||
>> x >> y >> z;
|
||||
}
|
||||
|
||||
pointLst[pointI] = point(x, y, z);
|
||||
}
|
||||
|
||||
// Read edges (Foam indexing)
|
||||
edgeList edges(nEdges);
|
||||
forAll(edges, edgei)
|
||||
{
|
||||
label beg, end;
|
||||
line = getLineNoComment(is);
|
||||
{
|
||||
IStringStream lineStream(line);
|
||||
lineStream
|
||||
>> beg >> end;
|
||||
}
|
||||
edges[edgei] = edge(beg - 1, end - 1);
|
||||
}
|
||||
|
||||
|
||||
// Read triangles. Convert references to edges into pointlabels
|
||||
List<keyedFace> faceLst(nElems);
|
||||
|
||||
label maxPatch = 0;
|
||||
|
||||
forAll(faceLst, faceI)
|
||||
{
|
||||
label e0Label, e1Label, e2Label;
|
||||
label region = 0;
|
||||
|
||||
line = getLineNoComment(is);
|
||||
{
|
||||
IStringStream lineStream(line);
|
||||
lineStream
|
||||
>> e0Label >> e1Label >> e2Label;
|
||||
|
||||
// Optional region number: read first, then check state on stream
|
||||
if (lineStream)
|
||||
{
|
||||
label num;
|
||||
lineStream >> num;
|
||||
if (!lineStream.bad())
|
||||
{
|
||||
region = num;
|
||||
if (maxPatch < region)
|
||||
{
|
||||
maxPatch = region;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Determine ordering of edges e0, e1
|
||||
// common: common vertex, shared by e0 and e1
|
||||
// e0Far: vertex on e0 which is not common
|
||||
// e1Far: vertex on e1 which is not common
|
||||
const edge& e0 = edges[e0Label - 1];
|
||||
const edge& e1 = edges[e1Label - 1];
|
||||
const edge& e2 = edges[e2Label - 1];
|
||||
|
||||
label common01 = e0.commonVertex(e1);
|
||||
if (common01 == -1)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"fileFormats::GTSfileFormat::GTSfileFormat"
|
||||
"(const fileName&)"
|
||||
)
|
||||
<< "Edges 0 and 1 of triangle " << faceI
|
||||
<< " do not share a point.\n"
|
||||
<< " edge0:" << e0 << nl
|
||||
<< " edge1:" << e1
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
label e0Far = e0.otherVertex(common01);
|
||||
label e1Far = e1.otherVertex(common01);
|
||||
|
||||
label common12 = e1.commonVertex(e2);
|
||||
if (common12 == -1)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"fileFormats::GTSfileFormat::GTSfileFormat"
|
||||
"(const fileName&)"
|
||||
)
|
||||
<< "Edges 1 and 2 of triangle " << faceI
|
||||
<< " do not share a point.\n"
|
||||
<< " edge1:" << e1 << nl
|
||||
<< " edge2:" << e2
|
||||
<< exit(FatalError);
|
||||
}
|
||||
label e2Far = e2.otherVertex(common12);
|
||||
|
||||
// Does edge2 sit between edge1 and 0?
|
||||
if (common12 != e1Far || e2Far != e0Far)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"fileFormats::GTSfileFormat::GTSfileFormat"
|
||||
"(const fileName&)"
|
||||
)
|
||||
<< "Edges of triangle " << faceI
|
||||
<< " reference more than three points.\n"
|
||||
<< " edge0:" << e0 << nl
|
||||
<< " edge1:" << e1 << nl
|
||||
<< " edge2:" << e2 << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
keyedFace lface(face(3), region);
|
||||
|
||||
lface[0] = e0Far;
|
||||
lface[1] = common01;
|
||||
lface[2] = e1Far;
|
||||
|
||||
faceLst[faceI] = lface;
|
||||
}
|
||||
|
||||
// transfer to normal lists
|
||||
points().transfer(pointLst);
|
||||
faces().transfer(faceLst);
|
||||
setPatches(maxPatch);
|
||||
// stitchFaces(SMALL);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::fileFormats::GTSfileFormat::write
|
||||
(
|
||||
Ostream& os,
|
||||
const keyedSurface& surf
|
||||
)
|
||||
{
|
||||
const pointField& pointLst = surf.points();
|
||||
const List<keyedFace>& faceLst = surf.faces();
|
||||
|
||||
// It is too annoying to triangulate on-the-fly
|
||||
// just issue a warning and get out
|
||||
label nNonTris = 0;
|
||||
forAll(faceLst, faceI)
|
||||
{
|
||||
if (faceLst[faceI].size() > 3)
|
||||
{
|
||||
++nNonTris;
|
||||
}
|
||||
}
|
||||
|
||||
if (nNonTris)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"fileFormats::GTSfileFormat::write"
|
||||
"(Ostream&, const keyedSurface&)"
|
||||
)
|
||||
<< "Surface has " << nNonTris << "/" << faceLst.size()
|
||||
<< " non-triangulated faces - not writing!" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
labelList faceMap;
|
||||
List<surfacePatch> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::fileFormats::GTSfileFormat::write
|
||||
(
|
||||
Ostream& os,
|
||||
const meshedSurface& surf
|
||||
)
|
||||
{
|
||||
const pointField& pointLst = surf.points();
|
||||
const List<surfacePatch>& patchLst = surf.patches();
|
||||
const List<face>& faceLst = surf.faces();
|
||||
|
||||
// It is too annoying to triangulate on-the-fly
|
||||
// just issue a warning and get out
|
||||
label nNonTris = 0;
|
||||
forAll(faceLst, faceI)
|
||||
{
|
||||
if (faceLst[faceI].size() > 3)
|
||||
{
|
||||
++nNonTris;
|
||||
}
|
||||
}
|
||||
|
||||
if (nNonTris)
|
||||
{
|
||||
WarningIn
|
||||
(
|
||||
"fileFormats::GTSfileFormat::write"
|
||||
"(Ostream&, const meshedSurface&)"
|
||||
)
|
||||
<< "Surface has " << nNonTris << "/" << faceLst.size()
|
||||
<< " non-triangulated faces - not writing!" << endl;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
const surfacePatch& patch = patchLst[patchI];
|
||||
|
||||
forAll(patch, patchFaceI)
|
||||
{
|
||||
const labelList& fEdges = faceEs[faceIndex++];
|
||||
|
||||
os << fEdges[0] + 1 << ' '
|
||||
<< fEdges[1] + 1 << ' '
|
||||
<< fEdges[2] + 1 << ' '
|
||||
<< patchI << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
||||
139
src/surfMesh/keyedSurface/fileFormats/gts/GTSfileFormat.H
Normal file
139
src/surfMesh/keyedSurface/fileFormats/gts/GTSfileFormat.H
Normal file
@ -0,0 +1,139 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
Class
|
||||
Foam::fileFormats::GTSfileFormat
|
||||
|
||||
Description
|
||||
Provide a means of reading/writing GTS format.
|
||||
|
||||
SourceFiles
|
||||
GTSfileFormat.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef GTSfileFormat_H
|
||||
#define GTSfileFormat_H
|
||||
|
||||
#include "Ostream.H"
|
||||
#include "OFstream.H"
|
||||
#include "keyedSurface.H"
|
||||
#include "meshedSurface.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace fileFormats
|
||||
{
|
||||
|
||||
class GTSfileFormat;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class GTSfileFormat Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class GTSfileFormat
|
||||
:
|
||||
public keyedSurface
|
||||
{
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
GTSfileFormat(const GTSfileFormat&);
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const GTSfileFormat&);
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct null
|
||||
GTSfileFormat();
|
||||
|
||||
//- Construct from file name
|
||||
GTSfileFormat(const fileName&, const bool triangulate=true);
|
||||
|
||||
// Selectors
|
||||
|
||||
//- Read file and return keyedSurface
|
||||
static autoPtr<keyedSurface> New
|
||||
(
|
||||
const fileName& fName,
|
||||
const bool triangulate=true
|
||||
)
|
||||
{
|
||||
return autoPtr<keyedSurface>
|
||||
(
|
||||
new GTSfileFormat(fName, triangulate)
|
||||
);
|
||||
}
|
||||
|
||||
// Destructor
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Write
|
||||
|
||||
//- Write keyedSurface
|
||||
static void write(Ostream&, const keyedSurface&);
|
||||
|
||||
//- Write keyedSurface
|
||||
static void write(const fileName& fName, const keyedSurface& surf)
|
||||
{
|
||||
write(OFstream(fName)(), surf);
|
||||
}
|
||||
|
||||
//- Write meshedSurface
|
||||
static void write(Ostream&, const meshedSurface&);
|
||||
|
||||
//- Write meshedSurface
|
||||
static void write(const fileName& fName, const meshedSurface& surf)
|
||||
{
|
||||
write(OFstream(fName)(), surf);
|
||||
}
|
||||
|
||||
//- Write object
|
||||
virtual void write(Ostream& os) const
|
||||
{
|
||||
write(os, *this);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace fileFormats
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
461
src/surfMesh/keyedSurface/fileFormats/nas/NASfileFormat.C
Normal file
461
src/surfMesh/keyedSurface/fileFormats/nas/NASfileFormat.C
Normal file
@ -0,0 +1,461 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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 "NASfileFormat.H"
|
||||
#include "clock.H"
|
||||
#include "IFstream.H"
|
||||
#include "IStringStream.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
#include "addToMemberFunctionSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
namespace Foam
|
||||
{
|
||||
namespace fileFormats
|
||||
{
|
||||
|
||||
// .bdf (Bulk Data Format)
|
||||
addNamedToRunTimeSelectionTable
|
||||
(
|
||||
keyedSurface,
|
||||
NASfileFormat,
|
||||
fileExtension,
|
||||
bdf
|
||||
);
|
||||
|
||||
// .nas (Nastran)
|
||||
addNamedToRunTimeSelectionTable
|
||||
(
|
||||
keyedSurface,
|
||||
NASfileFormat,
|
||||
fileExtension,
|
||||
nas
|
||||
);
|
||||
|
||||
// addNamedToMemberFunctionSelectionTable
|
||||
// (
|
||||
// keyedSurface,
|
||||
// NASfileFormat,
|
||||
// write,
|
||||
// fileExtension,
|
||||
// nas
|
||||
// );
|
||||
//
|
||||
// addNamedToMemberFunctionSelectionTable
|
||||
// (
|
||||
// meshedSurface,
|
||||
// NASfileFormat,
|
||||
// write,
|
||||
// fileExtension,
|
||||
// nas
|
||||
// );
|
||||
|
||||
}
|
||||
}
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
|
||||
// Do weird things to extract number
|
||||
Foam::scalar Foam::fileFormats::NASfileFormat::parseNASCoord(const string& s)
|
||||
{
|
||||
size_t expSign = s.find_last_of("+-");
|
||||
|
||||
if (expSign != string::npos && expSign > 0 && !isspace(s[expSign-1]))
|
||||
{
|
||||
scalar mantissa = readScalar(IStringStream(s.substr(0, expSign))());
|
||||
scalar exponent = readScalar(IStringStream(s.substr(expSign+1))());
|
||||
|
||||
if (s[expSign] == '-')
|
||||
{
|
||||
exponent = -exponent;
|
||||
}
|
||||
return mantissa*pow(10, exponent);
|
||||
}
|
||||
else
|
||||
{
|
||||
return readScalar(IStringStream(s)());
|
||||
}
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::fileFormats::NASfileFormat::NASfileFormat()
|
||||
:
|
||||
Foam::keyedSurface()
|
||||
{}
|
||||
|
||||
|
||||
Foam::fileFormats::NASfileFormat::NASfileFormat
|
||||
(
|
||||
const fileName& fName,
|
||||
const bool triangulate
|
||||
)
|
||||
:
|
||||
Foam::keyedSurface()
|
||||
{
|
||||
IFstream is(fName);
|
||||
|
||||
if (!is.good())
|
||||
{
|
||||
FatalErrorIn("fileFormats::NASfileFormat::NASfileFormat(const fileName&)")
|
||||
<< "Cannot read file " << fName
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
DynamicList<point> pointLst;
|
||||
// Nastran index of points
|
||||
DynamicList<label> pointId;
|
||||
DynamicList<keyedFace> faceLst;
|
||||
HashTable<label> groupToPatch;
|
||||
|
||||
// From face groupId to patchId
|
||||
Map<label> groupIdToPatchId;
|
||||
label nPatches = 0;
|
||||
|
||||
// Name for face group
|
||||
Map<word> groupIdToName;
|
||||
|
||||
// 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;
|
||||
|
||||
// leave faces that didn't have a group in 0
|
||||
// label groupID = 0;
|
||||
// label maxGroupID = -1;
|
||||
|
||||
// A single warning per unrecognized command
|
||||
HashSet<word> unhandledCmd;
|
||||
|
||||
while (is.good())
|
||||
{
|
||||
string line;
|
||||
is.getLine(line);
|
||||
|
||||
// Ansa extension
|
||||
if (line.substr(0, 10) == "$ANSA_NAME")
|
||||
{
|
||||
string::size_type sem0 = line.find (';', 0);
|
||||
string::size_type sem1 = line.find (';', sem0+1);
|
||||
string::size_type sem2 = line.find (';', sem1+1);
|
||||
|
||||
if
|
||||
(
|
||||
sem0 != string::npos
|
||||
&& sem1 != string::npos
|
||||
&& sem2 != string::npos
|
||||
)
|
||||
{
|
||||
ansaId = readLabel
|
||||
(
|
||||
IStringStream(line.substr(sem0+1, sem1-sem0-1))()
|
||||
);
|
||||
ansaType = line.substr(sem1+1, sem2-sem1-1);
|
||||
|
||||
string rawName;
|
||||
is.getLine(rawName);
|
||||
if (rawName[rawName.size()-1] == '\r')
|
||||
{
|
||||
rawName = rawName.substr(1, rawName.size()-2);
|
||||
}
|
||||
else
|
||||
{
|
||||
rawName = rawName.substr(1, rawName.size()-1);
|
||||
}
|
||||
|
||||
string::stripInvalid<word>(rawName);
|
||||
ansaName = rawName;
|
||||
|
||||
// Info<< "ANSA tag for NastranID:" << ansaID
|
||||
// << " of type " << ansaType
|
||||
// << " name " << ansaName << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Hypermesh extension
|
||||
// $HMNAME COMP 1"partName"
|
||||
if
|
||||
(
|
||||
line.substr(0, 12) == "$HMNAME COMP"
|
||||
&& line.find ('"') != string::npos
|
||||
)
|
||||
{
|
||||
label groupId = readLabel
|
||||
(
|
||||
IStringStream(line.substr(16, 16))()
|
||||
);
|
||||
|
||||
IStringStream lineStream(line.substr(32));
|
||||
|
||||
string rawName;
|
||||
lineStream >> rawName;
|
||||
string::stripInvalid<word>(rawName);
|
||||
|
||||
word groupName(rawName);
|
||||
groupIdToName.insert(groupId, groupName);
|
||||
|
||||
Info<< "group " << groupId << " => " << groupName << endl;
|
||||
}
|
||||
|
||||
|
||||
// Skip empty or comment
|
||||
if (line.size() == 0 || line[0] == '$')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// Check if character 72 is continuation
|
||||
if (line.size() > 72 && line[72] == '+')
|
||||
{
|
||||
line = line.substr(0, 72);
|
||||
|
||||
while (true)
|
||||
{
|
||||
string buf;
|
||||
is.getLine(buf);
|
||||
|
||||
if (buf.size() > 72 && buf[72] == '+')
|
||||
{
|
||||
line += buf.substr(8, 64);
|
||||
}
|
||||
else
|
||||
{
|
||||
line += buf.substr(8, buf.size()-8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Read first word
|
||||
IStringStream lineStream(line);
|
||||
word cmd;
|
||||
lineStream >> cmd;
|
||||
|
||||
if (cmd == "CTRIA3")
|
||||
{
|
||||
face fTri(3);
|
||||
|
||||
label groupId = readLabel(IStringStream(line.substr(16,8))());
|
||||
fTri[0] = readLabel(IStringStream(line.substr(24,8))());
|
||||
fTri[1] = readLabel(IStringStream(line.substr(32,8))());
|
||||
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())
|
||||
{
|
||||
patchI = nPatches++;
|
||||
groupIdToPatchId.insert(groupId, patchI);
|
||||
Info<< "patch " << patchI << " => group " << groupId << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
patchI = iter();
|
||||
}
|
||||
|
||||
faceLst.append(keyedFace(fTri, patchI));
|
||||
}
|
||||
else if (cmd == "CQUAD4")
|
||||
{
|
||||
face fQuad(4);
|
||||
|
||||
label groupId = readLabel(IStringStream(line.substr(16,8))());
|
||||
fQuad[0] = readLabel(IStringStream(line.substr(24,8))());
|
||||
fQuad[1] = readLabel(IStringStream(line.substr(32,8))());
|
||||
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())
|
||||
{
|
||||
patchI = nPatches++;
|
||||
groupIdToPatchId.insert(groupId, patchI);
|
||||
Info<< "patch " << patchI << " => group " << groupId << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
patchI = iter();
|
||||
}
|
||||
|
||||
if (triangulate)
|
||||
{
|
||||
face fTri(3);
|
||||
|
||||
// simple face triangulation about f[0].
|
||||
// cannot use face::triangulation since points are incomplete
|
||||
fTri[0] = fQuad[0];
|
||||
for (label fp1 = 1; fp1 < fQuad.size() - 1; fp1++)
|
||||
{
|
||||
label fp2 = (fp1 + 1) % fQuad.size();
|
||||
|
||||
fTri[1] = fQuad[fp1];
|
||||
fTri[2] = fQuad[fp2];
|
||||
|
||||
faceLst.append(keyedFace(fTri, patchI));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
faceLst.append(keyedFace(fQuad, 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;
|
||||
}
|
||||
}
|
||||
else if (cmd == "GRID")
|
||||
{
|
||||
label index = readLabel(IStringStream(line.substr(8,8))());
|
||||
scalar x = parseNASCoord(line.substr(24, 8));
|
||||
scalar y = parseNASCoord(line.substr(32, 8));
|
||||
scalar z = parseNASCoord(line.substr(40, 8));
|
||||
|
||||
pointId.append(index);
|
||||
pointLst.append(point(x, y, z));
|
||||
}
|
||||
else if (cmd == "GRID*")
|
||||
{
|
||||
// Long format is on two lines with '*' continuation symbol
|
||||
// on start of second line.
|
||||
// Typical line (spaces compacted)
|
||||
// GRID* 126 0 -5.55999875E+02 -5.68730474E+02
|
||||
// * 2.14897901E+02
|
||||
|
||||
label index = readLabel(IStringStream(line.substr(8,16))());
|
||||
scalar x = parseNASCoord(line.substr(40, 16));
|
||||
scalar y = parseNASCoord(line.substr(56, 16));
|
||||
|
||||
is.getLine(line);
|
||||
if (line[0] != '*')
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"fileFormats::NASfileFormat::NASfileFormat"
|
||||
"(const fileName&)"
|
||||
)
|
||||
<< "Expected continuation symbol '*' when reading GRID*"
|
||||
<< " (double precision coordinate) output" << nl
|
||||
<< "Read:" << line << nl
|
||||
<< "File:" << is.name()
|
||||
<< " line:" << is.lineNumber()
|
||||
<< exit(FatalError);
|
||||
}
|
||||
scalar z = parseNASCoord(line.substr(8, 16));
|
||||
|
||||
pointId.append(index);
|
||||
pointLst.append(point(x, y, z));
|
||||
}
|
||||
else if (unhandledCmd.insert(cmd))
|
||||
{
|
||||
Info<< "Unhandled Nastran command " << line << nl
|
||||
<< "File:" << is.name()
|
||||
<< " line:" << is.lineNumber()
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
Info<< "Read faces:" << faceLst.size()
|
||||
<< " points:" << pointLst.size()
|
||||
<< endl;
|
||||
|
||||
|
||||
// transfer to normal lists
|
||||
points().transfer(pointLst);
|
||||
|
||||
pointId.shrink();
|
||||
faceLst.shrink();
|
||||
|
||||
{
|
||||
// Build inverse mapping (index to point)
|
||||
Map<label> nasToFoamPoint(2*pointId.size());
|
||||
forAll(pointId, i)
|
||||
{
|
||||
nasToFoamPoint.insert(pointId[i], i);
|
||||
}
|
||||
pointId.clearStorage();
|
||||
|
||||
|
||||
// Relabel faces
|
||||
forAll(faceLst, i)
|
||||
{
|
||||
keyedFace& f = faceLst[i];
|
||||
forAll(f, fp)
|
||||
{
|
||||
f[fp] = nasToFoamPoint[f[fp]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// convert Nastran groupId => name to patchId => name
|
||||
Map<word> regionNames;
|
||||
forAllConstIter(Map<word>, groupIdToName, iter)
|
||||
{
|
||||
Map<label>::const_iterator iter2 = groupIdToPatchId.find(iter.key());
|
||||
|
||||
if (iter2 != groupIdToPatchId.end())
|
||||
{
|
||||
regionNames.insert(iter2.key(), iter());
|
||||
}
|
||||
}
|
||||
|
||||
// transfer to normal lists
|
||||
faces().transfer(faceLst);
|
||||
setPatches(regionNames);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// ************************************************************************* //
|
||||
122
src/surfMesh/keyedSurface/fileFormats/nas/NASfileFormat.H
Normal file
122
src/surfMesh/keyedSurface/fileFormats/nas/NASfileFormat.H
Normal file
@ -0,0 +1,122 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
Class
|
||||
Foam::fileFormats::NASfileFormat
|
||||
|
||||
Description
|
||||
Nastran surface reader.
|
||||
|
||||
- Uses the Ansa "$ANSA_NAME" or the Hypermesh "$HMNAME COMP" extensions
|
||||
to obtain patch names.
|
||||
- Handles Nastran short and long formats, but not free format.
|
||||
- Properly handles the Nastran compact floating point notation: \n
|
||||
@verbatim
|
||||
GRID 28 10.20269-.030265-2.358-8
|
||||
@endverbatim
|
||||
|
||||
SourceFiles
|
||||
NASfileFormat.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef NASfileFormat_H
|
||||
#define NASfileFormat_H
|
||||
|
||||
#include "Ostream.H"
|
||||
#include "OFstream.H"
|
||||
#include "keyedSurface.H"
|
||||
#include "meshedSurface.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace fileFormats
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class NASfileFormat Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class NASfileFormat
|
||||
:
|
||||
public keyedSurface
|
||||
{
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Do weird things to extract number
|
||||
static scalar parseNASCoord(const string&);
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
NASfileFormat(const NASfileFormat&);
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const NASfileFormat&);
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct null
|
||||
NASfileFormat();
|
||||
|
||||
//- Construct from file name
|
||||
NASfileFormat(const fileName&, const bool triangulate=false);
|
||||
|
||||
// Selectors
|
||||
|
||||
//- Read file and return keyedSurface
|
||||
static autoPtr<keyedSurface> New
|
||||
(
|
||||
const fileName& fName,
|
||||
const bool triangulate=false
|
||||
)
|
||||
{
|
||||
return autoPtr<keyedSurface>
|
||||
(
|
||||
new NASfileFormat(fName,triangulate)
|
||||
);
|
||||
}
|
||||
|
||||
// Destructor
|
||||
|
||||
// Member Functions
|
||||
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace fileFormats
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
371
src/surfMesh/keyedSurface/fileFormats/obj/OBJfileFormat.C
Normal file
371
src/surfMesh/keyedSurface/fileFormats/obj/OBJfileFormat.C
Normal file
@ -0,0 +1,371 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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 "OBJfileFormat.H"
|
||||
#include "clock.H"
|
||||
#include "IFstream.H"
|
||||
#include "IStringStream.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
#include "addToMemberFunctionSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
namespace Foam
|
||||
{
|
||||
namespace fileFormats
|
||||
{
|
||||
|
||||
addNamedToRunTimeSelectionTable
|
||||
(
|
||||
keyedSurface,
|
||||
OBJfileFormat,
|
||||
fileExtension,
|
||||
obj
|
||||
);
|
||||
|
||||
addNamedToMemberFunctionSelectionTable
|
||||
(
|
||||
keyedSurface,
|
||||
OBJfileFormat,
|
||||
write,
|
||||
fileExtension,
|
||||
obj
|
||||
);
|
||||
|
||||
addNamedToMemberFunctionSelectionTable
|
||||
(
|
||||
meshedSurface,
|
||||
OBJfileFormat,
|
||||
write,
|
||||
fileExtension,
|
||||
obj
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::fileFormats::OBJfileFormat::OBJfileFormat()
|
||||
:
|
||||
Foam::keyedSurface()
|
||||
{}
|
||||
|
||||
|
||||
Foam::fileFormats::OBJfileFormat::OBJfileFormat
|
||||
(
|
||||
const fileName& fName,
|
||||
const bool triangulate
|
||||
)
|
||||
:
|
||||
Foam::keyedSurface()
|
||||
{
|
||||
IFstream is(fName);
|
||||
|
||||
if (!is.good())
|
||||
{
|
||||
FatalErrorIn("fileFormats::OBJfileFormat::OBJfileFormat(const fileName&)")
|
||||
<< "Cannot read file " << fName
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
DynamicList<point> pointLst;
|
||||
DynamicList<keyedFace> faceLst;
|
||||
HashTable<label> groupToPatch;
|
||||
|
||||
// leave faces that didn't have a group in 0
|
||||
label groupID = 0;
|
||||
label maxGroupID = -1;
|
||||
|
||||
while (is.good())
|
||||
{
|
||||
string line = getLineNoComment(is);
|
||||
|
||||
// handle continuations
|
||||
if (line[line.size()-1] == '\\')
|
||||
{
|
||||
line.substr(0, line.size()-1);
|
||||
line += getLineNoComment(is);
|
||||
}
|
||||
|
||||
// Read first word
|
||||
IStringStream lineStream(line);
|
||||
word cmd;
|
||||
lineStream >> cmd;
|
||||
|
||||
if (cmd == "v")
|
||||
{
|
||||
scalar x, y, z;
|
||||
lineStream >> x >> y >> z;
|
||||
pointLst.append(point(x, y, z));
|
||||
}
|
||||
else if (cmd == "g")
|
||||
{
|
||||
word groupName;
|
||||
lineStream >> groupName;
|
||||
|
||||
HashTable<label>::const_iterator findGroup =
|
||||
groupToPatch.find(groupName);
|
||||
|
||||
if (findGroup != groupToPatch.end())
|
||||
{
|
||||
groupID = findGroup();
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
else if (cmd == "f")
|
||||
{
|
||||
DynamicList<label> verts;
|
||||
|
||||
// Assume 'f' is followed by space.
|
||||
string::size_type endNum = 1;
|
||||
|
||||
while (true)
|
||||
{
|
||||
string::size_type startNum = line.find_first_not_of(' ', endNum);
|
||||
|
||||
if (startNum == string::size_type(string::npos))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
endNum = line.find(' ', startNum);
|
||||
|
||||
string vertexSpec;
|
||||
if (endNum != string::size_type(string::npos))
|
||||
{
|
||||
vertexSpec = line.substr(startNum, endNum-startNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
vertexSpec = line.substr(startNum, line.size() - startNum);
|
||||
}
|
||||
|
||||
string::size_type slashPos = vertexSpec.find('/');
|
||||
|
||||
label vertI = 0;
|
||||
if (slashPos != string::size_type(string::npos))
|
||||
{
|
||||
IStringStream intStream(vertexSpec.substr(0, slashPos));
|
||||
|
||||
intStream >> vertI;
|
||||
}
|
||||
else
|
||||
{
|
||||
IStringStream intStream(vertexSpec);
|
||||
|
||||
intStream >> vertI;
|
||||
}
|
||||
verts.append(vertI - 1);
|
||||
}
|
||||
verts.shrink();
|
||||
|
||||
if (triangulate && verts.size() > 3)
|
||||
{
|
||||
face fTri(3);
|
||||
|
||||
// simple face triangulation about f[0].
|
||||
// Cannot use face::triangulation since points are incomplete
|
||||
fTri[0] = verts[0];
|
||||
for (label fp1 = 1; fp1 < verts.size() - 1; fp1++)
|
||||
{
|
||||
label fp2 = (fp1 + 1) % verts.size();
|
||||
|
||||
fTri[1] = verts[fp1];
|
||||
fTri[2] = verts[fp2];
|
||||
|
||||
faceLst.append(keyedFace(fTri, groupID));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
faceLst.append
|
||||
(
|
||||
keyedFace
|
||||
(
|
||||
face( xferMoveTo<labelList>(verts) ),
|
||||
groupID
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// transfer to normal lists
|
||||
points().transfer(pointLst);
|
||||
faces().transfer(faceLst);
|
||||
setPatches(groupToPatch);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::fileFormats::OBJfileFormat::write
|
||||
(
|
||||
Ostream& os,
|
||||
const keyedSurface& surf
|
||||
)
|
||||
{
|
||||
const pointField& pointLst = surf.points();
|
||||
const List<keyedFace>& faceLst = surf.faces();
|
||||
|
||||
labelList faceMap;
|
||||
List<surfacePatch> patchLst = surf.sortedRegions(faceMap);
|
||||
|
||||
os << "# Wavefront OBJ file written " << clock::dateTime().c_str() << nl
|
||||
<< "o " << os.name().lessExt().name() << nl
|
||||
<< nl
|
||||
<< "# points : " << pointLst.size() << nl
|
||||
<< "# faces : " << faceLst.size() << nl
|
||||
<< "# patches: " << patchLst.size() << nl;
|
||||
|
||||
// Print patch names as comment
|
||||
forAll(patchLst, patchI)
|
||||
{
|
||||
os << "# " << patchI << " " << patchLst[patchI].name()
|
||||
<< " (nFaces: " << patchLst[patchI].size() << ")" << nl;
|
||||
}
|
||||
|
||||
os << nl
|
||||
<< "# <points count=\"" << pointLst.size() << "\">" << endl;
|
||||
|
||||
// Write vertex coords
|
||||
forAll(pointLst, ptI)
|
||||
{
|
||||
os << "v " << pointLst[ptI].x()
|
||||
<< ' ' << pointLst[ptI].y()
|
||||
<< ' ' << pointLst[ptI].z() << nl;
|
||||
}
|
||||
|
||||
os << "# </points>" << nl
|
||||
<< nl
|
||||
<< "# <faces count=\"" << faceLst.size() << "\">" << endl;
|
||||
|
||||
label faceIndex = 0;
|
||||
forAll(patchLst, patchI)
|
||||
{
|
||||
// Print all faces belonging to this region
|
||||
const surfacePatch& patch = patchLst[patchI];
|
||||
|
||||
os << "g " << patch.name() << endl;
|
||||
|
||||
forAll(patch, patchFaceI)
|
||||
{
|
||||
const face& f = faceLst[faceMap[faceIndex++]];
|
||||
|
||||
os << 'f';
|
||||
forAll(f, fp)
|
||||
{
|
||||
os << ' ' << f[fp] + 1;
|
||||
}
|
||||
os << endl;
|
||||
}
|
||||
}
|
||||
|
||||
os << "# </faces>" << endl;
|
||||
}
|
||||
|
||||
|
||||
void Foam::fileFormats::OBJfileFormat::write
|
||||
(
|
||||
Ostream& os,
|
||||
const meshedSurface& surf
|
||||
)
|
||||
{
|
||||
const pointField& pointLst = surf.points();
|
||||
const List<face>& faceLst = surf.faces();
|
||||
const List<surfacePatch>& patchLst = surf.patches();
|
||||
|
||||
os << "# Wavefront OBJ file written " << clock::dateTime().c_str() << nl
|
||||
<< "o " << os.name().lessExt().name() << nl
|
||||
<< nl
|
||||
<< "# points : " << pointLst.size() << nl
|
||||
<< "# faces : " << faceLst.size() << nl
|
||||
<< "# patches: " << patchLst.size() << nl;
|
||||
|
||||
// Print patch names as comment
|
||||
forAll(patchLst, patchI)
|
||||
{
|
||||
os << "# " << patchI << " " << patchLst[patchI].name()
|
||||
<< " (nFaces: " << patchLst[patchI].size() << ")" << nl;
|
||||
}
|
||||
|
||||
os << nl
|
||||
<< "# <points count=\"" << pointLst.size() << "\">" << endl;
|
||||
|
||||
// Write vertex coords
|
||||
forAll(pointLst, ptI)
|
||||
{
|
||||
os << "v " << pointLst[ptI].x()
|
||||
<< ' ' << pointLst[ptI].y()
|
||||
<< ' ' << pointLst[ptI].z() << nl;
|
||||
}
|
||||
|
||||
os << "# </points>" << nl
|
||||
<< nl
|
||||
<< "# <faces count=\"" << faceLst.size() << "\">" << endl;
|
||||
|
||||
label faceIndex = 0;
|
||||
forAll(patchLst, patchI)
|
||||
{
|
||||
const surfacePatch& 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;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
|
||||
|
||||
// ************************************************************************* //
|
||||
139
src/surfMesh/keyedSurface/fileFormats/obj/OBJfileFormat.H
Normal file
139
src/surfMesh/keyedSurface/fileFormats/obj/OBJfileFormat.H
Normal file
@ -0,0 +1,139 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
Class
|
||||
Foam::fileFormats::OBJfileFormat
|
||||
|
||||
Description
|
||||
Provide a means of reading/writing Alias/Wavefront OBJ format.
|
||||
|
||||
Does not handle negative face indices.
|
||||
|
||||
SourceFiles
|
||||
OBJfileFormat.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef OBJfileFormat_H
|
||||
#define OBJfileFormat_H
|
||||
|
||||
#include "Ostream.H"
|
||||
#include "OFstream.H"
|
||||
#include "keyedSurface.H"
|
||||
#include "meshedSurface.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace fileFormats
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class OBJfileFormat Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class OBJfileFormat
|
||||
:
|
||||
public keyedSurface
|
||||
{
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
OBJfileFormat(const OBJfileFormat&);
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const OBJfileFormat&);
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct null
|
||||
OBJfileFormat();
|
||||
|
||||
//- Construct from file name
|
||||
OBJfileFormat(const fileName&, const bool triangulate=false);
|
||||
|
||||
// Selectors
|
||||
|
||||
//- Read file and return keyedSurface
|
||||
static autoPtr<keyedSurface> New
|
||||
(
|
||||
const fileName& fName,
|
||||
const bool triangulate = false
|
||||
)
|
||||
{
|
||||
return autoPtr<keyedSurface>
|
||||
(
|
||||
new OBJfileFormat(fName, triangulate)
|
||||
);
|
||||
}
|
||||
|
||||
// Destructor
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Write
|
||||
|
||||
//- Write keyedSurface
|
||||
static void write(Ostream&, const keyedSurface&);
|
||||
|
||||
//- Write keyedSurface
|
||||
static void write(const fileName& fName, const keyedSurface& surf)
|
||||
{
|
||||
write(OFstream(fName)(), surf);
|
||||
}
|
||||
|
||||
//- Write meshedSurface
|
||||
static void write(Ostream&, const meshedSurface&);
|
||||
|
||||
//- Write meshedSurface
|
||||
static void write(const fileName& fName, const meshedSurface& surf)
|
||||
{
|
||||
write(OFstream(fName)(), surf);
|
||||
}
|
||||
|
||||
//- Write object
|
||||
virtual void write(Ostream& os) const
|
||||
{
|
||||
write(os, *this);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace fileFormats
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
326
src/surfMesh/keyedSurface/fileFormats/off/OFFfileFormat.C
Normal file
326
src/surfMesh/keyedSurface/fileFormats/off/OFFfileFormat.C
Normal file
@ -0,0 +1,326 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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 "OFFfileFormat.H"
|
||||
#include "clock.H"
|
||||
#include "IFstream.H"
|
||||
#include "IStringStream.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
#include "addToMemberFunctionSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
namespace Foam
|
||||
{
|
||||
namespace fileFormats
|
||||
{
|
||||
|
||||
addNamedToRunTimeSelectionTable
|
||||
(
|
||||
keyedSurface,
|
||||
OFFfileFormat,
|
||||
fileExtension,
|
||||
off
|
||||
);
|
||||
|
||||
addNamedToMemberFunctionSelectionTable
|
||||
(
|
||||
keyedSurface,
|
||||
OFFfileFormat,
|
||||
write,
|
||||
fileExtension,
|
||||
off
|
||||
);
|
||||
|
||||
addNamedToMemberFunctionSelectionTable
|
||||
(
|
||||
meshedSurface,
|
||||
OFFfileFormat,
|
||||
write,
|
||||
fileExtension,
|
||||
off
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::fileFormats::OFFfileFormat::OFFfileFormat()
|
||||
:
|
||||
keyedSurface()
|
||||
{}
|
||||
|
||||
|
||||
Foam::fileFormats::OFFfileFormat::OFFfileFormat
|
||||
(
|
||||
const fileName& fName,
|
||||
const bool triangulate
|
||||
)
|
||||
:
|
||||
keyedSurface()
|
||||
{
|
||||
IFstream is(fName);
|
||||
|
||||
if (!is.good())
|
||||
{
|
||||
FatalErrorIn("fileFormats::OFFfileFormat(const fileName&)")
|
||||
<< "Cannot read file " << fName
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
// Read header
|
||||
string hdr = getLineNoComment(is);
|
||||
if (hdr != "OFF")
|
||||
{
|
||||
FatalErrorIn("fileFormats::OFFfileFormat(const fileName&)")
|
||||
<< "OFF file " << fName
|
||||
<< " does not start with 'OFF'"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
|
||||
// get dimensions
|
||||
label nPoints, nEdges, nElems;
|
||||
|
||||
string line = getLineNoComment(is);
|
||||
{
|
||||
IStringStream lineStream(line);
|
||||
lineStream >> nPoints >> nElems >> nEdges;
|
||||
}
|
||||
|
||||
// Read points
|
||||
pointField pointLst(nPoints);
|
||||
forAll(pointLst, pointI)
|
||||
{
|
||||
scalar x, y, z;
|
||||
line = getLineNoComment(is);
|
||||
{
|
||||
IStringStream lineStream(line);
|
||||
lineStream >> x >> y >> z;
|
||||
}
|
||||
pointLst[pointI] = point(x, y, z);
|
||||
}
|
||||
|
||||
// Read faces - ignore optional region information
|
||||
// use a DynamicList for possible on-the-fly triangulation
|
||||
DynamicList<keyedFace> faceLst(nElems);
|
||||
|
||||
forAll(faceLst, faceI)
|
||||
{
|
||||
line = getLineNoComment(is);
|
||||
{
|
||||
IStringStream lineStream(line);
|
||||
|
||||
label nVerts;
|
||||
lineStream >> nVerts;
|
||||
|
||||
face f(nVerts);
|
||||
|
||||
forAll(f, fp)
|
||||
{
|
||||
lineStream >> f[fp];
|
||||
}
|
||||
|
||||
if (triangulate && f.size() > 3)
|
||||
{
|
||||
face fTri(3);
|
||||
|
||||
// simple face triangulation about f[0].
|
||||
// cannot use face::triangulation since points are incomplete
|
||||
fTri[0] = f[0];
|
||||
for (label fp1 = 1; fp1 < f.size() - 1; fp1++)
|
||||
{
|
||||
label fp2 = (fp1 + 1) % f.size();
|
||||
|
||||
fTri[1] = f[fp1];
|
||||
fTri[2] = f[fp2];
|
||||
|
||||
faceLst.append(keyedFace(fTri, 0));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
faceLst.append(keyedFace(f, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// no region information
|
||||
points().transfer(pointLst);
|
||||
faces().transfer(faceLst);
|
||||
setPatches(0);
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
void Foam::fileFormats::OFFfileFormat::write
|
||||
(
|
||||
Ostream& os,
|
||||
const keyedSurface& surf
|
||||
)
|
||||
{
|
||||
const pointField& pointLst = surf.points();
|
||||
const List<keyedFace>& faceLst = surf.faces();
|
||||
|
||||
labelList faceMap;
|
||||
List<surfacePatch> patchLst = surf.sortedRegions(faceMap);
|
||||
|
||||
// Write header
|
||||
os << "OFF" << endl
|
||||
<< "# Geomview OFF file written " << clock::dateTime().c_str() << nl
|
||||
<< nl
|
||||
<< "# points : " << pointLst.size() << nl
|
||||
<< "# faces : " << faceLst.size() << nl
|
||||
<< "# patches: " << patchLst.size() << nl;
|
||||
|
||||
// Print patch names as comment
|
||||
forAll(patchLst, patchI)
|
||||
{
|
||||
os << "# " << patchI << " " << patchLst[patchI].name()
|
||||
<< " (nFaces: " << patchLst[patchI].size() << ")" << nl;
|
||||
}
|
||||
|
||||
os << nl
|
||||
<< "# nPoints nFaces nEdges" << nl
|
||||
<< pointLst.size() << ' ' << faceLst.size() << ' ' << 0 << nl;
|
||||
|
||||
os << nl
|
||||
<< "# <points count=\"" << pointLst.size() << "\">" << endl;
|
||||
|
||||
// Write vertex coords
|
||||
forAll(pointLst, ptI)
|
||||
{
|
||||
os << pointLst[ptI].x() << ' '
|
||||
<< pointLst[ptI].y() << ' '
|
||||
<< pointLst[ptI].z() << " #" << ptI << endl;
|
||||
}
|
||||
|
||||
os << "# </points>" << nl
|
||||
<< nl
|
||||
<< "# <faces count=\"" << faceLst.size() << "\">" << endl;
|
||||
|
||||
label faceIndex = 0;
|
||||
forAll(patchLst, patchI)
|
||||
{
|
||||
os << "# <patch name=\"" << patchLst[patchI].name() << "\">" << endl;
|
||||
|
||||
forAll(patchLst[patchI], patchFaceI)
|
||||
{
|
||||
const face& f = faceLst[faceMap[faceIndex++]];
|
||||
|
||||
os << f.size();
|
||||
forAll(f, fp)
|
||||
{
|
||||
os << ' ' << f[fp];
|
||||
}
|
||||
|
||||
// add optional region information
|
||||
os << ' ' << patchI << endl;
|
||||
}
|
||||
os << "# </patch>" << endl;
|
||||
}
|
||||
os << "# </faces>" << endl;
|
||||
}
|
||||
|
||||
|
||||
void Foam::fileFormats::OFFfileFormat::write
|
||||
(
|
||||
Ostream& os,
|
||||
const meshedSurface& surf
|
||||
)
|
||||
{
|
||||
const pointField& pointLst = surf.points();
|
||||
const List<face>& faceLst = surf.faces();
|
||||
const List<surfacePatch>& patchLst = surf.patches();
|
||||
|
||||
// Write header
|
||||
os << "OFF" << endl
|
||||
<< "# Geomview OFF file written " << clock::dateTime().c_str() << nl
|
||||
<< nl
|
||||
<< "# points : " << pointLst.size() << nl
|
||||
<< "# faces : " << faceLst.size() << nl
|
||||
<< "# patches: " << patchLst.size() << nl;
|
||||
|
||||
// Print patch names as comment
|
||||
forAll(patchLst, patchI)
|
||||
{
|
||||
os << "# " << patchI << " " << patchLst[patchI].name()
|
||||
<< " (nFaces: " << patchLst[patchI].size() << ")" << nl;
|
||||
}
|
||||
|
||||
os << nl
|
||||
<< "# nPoints nFaces nEdges" << nl
|
||||
<< pointLst.size() << ' ' << faceLst.size() << ' ' << 0 << nl;
|
||||
|
||||
os << nl
|
||||
<< "# <points count=\"" << pointLst.size() << "\">" << endl;
|
||||
|
||||
// Write vertex coords
|
||||
forAll(pointLst, ptI)
|
||||
{
|
||||
os << pointLst[ptI].x() << ' '
|
||||
<< pointLst[ptI].y() << ' '
|
||||
<< pointLst[ptI].z() << " #" << ptI << endl;
|
||||
}
|
||||
|
||||
os << "# </points>" << nl
|
||||
<< nl
|
||||
<< "# <faces count=\"" << faceLst.size() << "\">" << endl;
|
||||
|
||||
label faceIndex = 0;
|
||||
forAll(patchLst, patchI)
|
||||
{
|
||||
os << "# <patch name=\"" << patchLst[patchI].name() << "\">" << endl;
|
||||
|
||||
forAll(patchLst[patchI], patchFaceI)
|
||||
{
|
||||
const face& f = faceLst[faceIndex++];
|
||||
|
||||
os << f.size();
|
||||
forAll(f, fp)
|
||||
{
|
||||
os << ' ' << f[fp];
|
||||
}
|
||||
|
||||
// add optional region information
|
||||
os << ' ' << patchI << endl;
|
||||
}
|
||||
os << "# </patch>" << endl;
|
||||
}
|
||||
os << "# </faces>" << endl;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
|
||||
|
||||
// ************************************************************************* //
|
||||
146
src/surfMesh/keyedSurface/fileFormats/off/OFFfileFormat.H
Normal file
146
src/surfMesh/keyedSurface/fileFormats/off/OFFfileFormat.H
Normal file
@ -0,0 +1,146 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
Class
|
||||
Foam::fileFormats::OFFfileFormat
|
||||
|
||||
Description
|
||||
Provide a means of reading/writing Geomview OFF polyList format.
|
||||
|
||||
|
||||
See Also
|
||||
The <a href="http://www.geoview.org">Geoview</a>
|
||||
file format information:
|
||||
http://www.geomview.org/docs/html/OFF.html#OFF
|
||||
|
||||
Note
|
||||
When reading, the optional @a colorspec is ignored.
|
||||
When writing, it is set to the region number (integer).
|
||||
|
||||
SourceFiles
|
||||
OFFfileFormat.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef OFFfileFormat_H
|
||||
#define OFFfileFormat_H
|
||||
|
||||
#include "Ostream.H"
|
||||
#include "OFstream.H"
|
||||
#include "keyedSurface.H"
|
||||
#include "meshedSurface.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace fileFormats
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class OFFfileFormat Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class OFFfileFormat
|
||||
:
|
||||
public keyedSurface
|
||||
{
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
OFFfileFormat(const OFFfileFormat&);
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const OFFfileFormat&);
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct null
|
||||
OFFfileFormat();
|
||||
|
||||
//- Construct from file name
|
||||
OFFfileFormat(const fileName&, const bool triangulate=false);
|
||||
|
||||
// Selectors
|
||||
|
||||
//- Read file and return keyedSurface
|
||||
static autoPtr<keyedSurface> New
|
||||
(
|
||||
const fileName& fName,
|
||||
const bool triangulate=false
|
||||
)
|
||||
{
|
||||
return autoPtr<keyedSurface>
|
||||
(
|
||||
new OFFfileFormat(fName,triangulate)
|
||||
);
|
||||
}
|
||||
|
||||
// Destructor
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Write
|
||||
|
||||
//- Write keyedSurface
|
||||
static void write(Ostream&, const keyedSurface&);
|
||||
|
||||
//- Write keyedSurface
|
||||
static void write(const fileName& fName, const keyedSurface& surf)
|
||||
{
|
||||
write(OFstream(fName)(), surf);
|
||||
}
|
||||
|
||||
//- Write meshedSurface
|
||||
static void write(Ostream&, const meshedSurface&);
|
||||
|
||||
//- Write meshedSurface
|
||||
static void write(const fileName& fName, const meshedSurface& surf)
|
||||
{
|
||||
write(OFstream(fName)(), surf);
|
||||
}
|
||||
|
||||
//- Write object
|
||||
virtual void write(Ostream& os) const
|
||||
{
|
||||
write(os, *this);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace fileFormats
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
185
src/surfMesh/keyedSurface/fileFormats/smesh/SMESHfileFormat.C
Normal file
185
src/surfMesh/keyedSurface/fileFormats/smesh/SMESHfileFormat.C
Normal file
@ -0,0 +1,185 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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 "SMESHfileFormat.H"
|
||||
#include "clock.H"
|
||||
#include "IStringStream.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
#include "addToMemberFunctionSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
namespace Foam
|
||||
{
|
||||
namespace fileFormats
|
||||
{
|
||||
|
||||
addNamedToMemberFunctionSelectionTable
|
||||
(
|
||||
keyedSurface,
|
||||
SMESHfileFormat,
|
||||
write,
|
||||
fileExtension,
|
||||
smesh
|
||||
);
|
||||
|
||||
addNamedToMemberFunctionSelectionTable
|
||||
(
|
||||
meshedSurface,
|
||||
SMESHfileFormat,
|
||||
write,
|
||||
fileExtension,
|
||||
smesh
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
Foam::fileFormats::SMESHfileFormat::SMESHfileFormat()
|
||||
:
|
||||
keyedSurface()
|
||||
{}
|
||||
|
||||
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void
|
||||
Foam::fileFormats::SMESHfileFormat::write
|
||||
(
|
||||
Ostream& os,
|
||||
const keyedSurface& surf
|
||||
)
|
||||
{
|
||||
const pointField& pointLst= surf.points();
|
||||
const List<keyedFace>& faceLst = surf.faces();
|
||||
|
||||
labelList faceMap;
|
||||
List<surfacePatch> patchLst = surf.sortedRegions(faceMap);
|
||||
|
||||
os << "# tetgen .smesh file written " << clock::dateTime().c_str() << nl;
|
||||
os << "# <points count=\"" << pointLst.size() << "\">" << endl;
|
||||
os << pointLst.size() << " 3" << nl; // 3: dimensions
|
||||
|
||||
// Write vertex coords
|
||||
forAll(pointLst, ptI)
|
||||
{
|
||||
os << ptI
|
||||
<< ' ' << pointLst[ptI].x()
|
||||
<< ' ' << pointLst[ptI].y()
|
||||
<< ' ' << pointLst[ptI].z() << nl;
|
||||
}
|
||||
os << "# </points>" << nl
|
||||
<< nl
|
||||
<< "# <faces count=\"" << faceLst.size() << "\">" << endl;
|
||||
|
||||
os << faceLst.size() << " 1" << endl; // one attribute: region number
|
||||
|
||||
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 << ' ' << patchI << endl;
|
||||
}
|
||||
}
|
||||
|
||||
os << "# </faces>" << nl
|
||||
<< nl
|
||||
<< "# no holes or regions:" << nl
|
||||
<< '0' << nl // holes
|
||||
<< '0' << endl; // regions
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Foam::fileFormats::SMESHfileFormat::write
|
||||
(
|
||||
Ostream& os,
|
||||
const meshedSurface& surf
|
||||
)
|
||||
{
|
||||
const pointField& pointLst= surf.points();
|
||||
const List<face>& faceLst = surf.faces();
|
||||
const List<surfacePatch>& patchLst = surf.patches();
|
||||
|
||||
os << "# tetgen .smesh file written " << clock::dateTime().c_str() << nl;
|
||||
os << "# <points count=\"" << pointLst.size() << "\">" << endl;
|
||||
os << pointLst.size() << " 3" << nl; // 3: dimensions
|
||||
|
||||
// Write vertex coords
|
||||
forAll(pointLst, ptI)
|
||||
{
|
||||
os << ptI
|
||||
<< ' ' << pointLst[ptI].x()
|
||||
<< ' ' << pointLst[ptI].y()
|
||||
<< ' ' << pointLst[ptI].z() << nl;
|
||||
}
|
||||
os << "# </points>" << nl
|
||||
<< nl
|
||||
<< "# <faces count=\"" << faceLst.size() << "\">" << endl;
|
||||
|
||||
os << faceLst.size() << " 1" << endl; // one attribute: region number
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
os << "# </faces>" << nl
|
||||
<< nl
|
||||
<< "# no holes or regions:" << nl
|
||||
<< '0' << nl // holes
|
||||
<< '0' << endl; // regions
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
|
||||
|
||||
// ************************************************************************* //
|
||||
128
src/surfMesh/keyedSurface/fileFormats/smesh/SMESHfileFormat.H
Normal file
128
src/surfMesh/keyedSurface/fileFormats/smesh/SMESHfileFormat.H
Normal file
@ -0,0 +1,128 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
Class
|
||||
Foam::fileFormats::SMESHfileFormat
|
||||
|
||||
Description
|
||||
Provide a means of writing tetgen SMESH format.
|
||||
|
||||
Tetgen http://tetgen.berlios.de
|
||||
|
||||
See Also
|
||||
File format information:
|
||||
http://tetgen.berlios.de/fformats.smesh.html
|
||||
|
||||
SourceFiles
|
||||
SMESHfileFormat.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef SMESHfileFormat_H
|
||||
#define SMESHfileFormat_H
|
||||
|
||||
#include "IFstream.H"
|
||||
#include "OFstream.H"
|
||||
#include "Ostream.H"
|
||||
#include "keyedSurface.H"
|
||||
#include "meshedSurface.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace fileFormats
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class SMESHfileFormat Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class SMESHfileFormat
|
||||
:
|
||||
public keyedSurface
|
||||
{
|
||||
// Private data
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
SMESHfileFormat(const SMESHfileFormat&);
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const SMESHfileFormat&);
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct null
|
||||
SMESHfileFormat();
|
||||
|
||||
// Selectors
|
||||
|
||||
// Destructor
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Write keyedSurface
|
||||
static void write(Ostream&, const keyedSurface&);
|
||||
|
||||
//- Write meshedSurface
|
||||
static void write(Ostream&, const meshedSurface&);
|
||||
|
||||
//- Write keyedSurface
|
||||
static void write(const fileName& fName, const keyedSurface& surf)
|
||||
{
|
||||
write(OFstream(fName)(), surf);
|
||||
}
|
||||
|
||||
//- Write meshedSurface
|
||||
static void write(const fileName& fName, const meshedSurface& surf)
|
||||
{
|
||||
write(OFstream(fName)(), surf);
|
||||
}
|
||||
|
||||
|
||||
//- Write object
|
||||
virtual void write(Ostream& os) const
|
||||
{
|
||||
write(os, *this);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace fileFormats
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
478
src/surfMesh/keyedSurface/fileFormats/starcd/STARCDfileFormat.C
Normal file
478
src/surfMesh/keyedSurface/fileFormats/starcd/STARCDfileFormat.C
Normal file
@ -0,0 +1,478 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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 "STARCDfileFormat.H"
|
||||
#include "clock.H"
|
||||
#include "OSspecific.H"
|
||||
#include "IStringStream.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
#include "addToMemberFunctionSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
namespace Foam
|
||||
{
|
||||
namespace fileFormats
|
||||
{
|
||||
|
||||
addNamedToRunTimeSelectionTable
|
||||
(
|
||||
keyedSurface,
|
||||
STARCDfileFormat,
|
||||
fileExtension,
|
||||
inp
|
||||
);
|
||||
|
||||
addNamedToMemberFunctionSelectionTable
|
||||
(
|
||||
keyedSurface,
|
||||
STARCDfileFormat,
|
||||
write,
|
||||
fileExtension,
|
||||
inp
|
||||
);
|
||||
|
||||
addNamedToMemberFunctionSelectionTable
|
||||
(
|
||||
meshedSurface,
|
||||
STARCDfileFormat,
|
||||
write,
|
||||
fileExtension,
|
||||
inp
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//! @cond localScope
|
||||
const int starcdShellShape = 3;
|
||||
const int starcdShellType = 4;
|
||||
//! @endcond localScope
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
bool Foam::fileFormats::STARCDfileFormat::readHeader
|
||||
(
|
||||
IFstream& is,
|
||||
const word& signature
|
||||
)
|
||||
{
|
||||
if (!is.good())
|
||||
{
|
||||
FatalErrorIn("fileFormats::STARCDfileFormat::readHeader()")
|
||||
<< "cannot read " << signature << " " << is.name()
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
word header;
|
||||
label majorVersion;
|
||||
|
||||
string line;
|
||||
|
||||
is.getLine(line);
|
||||
IStringStream(line)() >> header;
|
||||
|
||||
is.getLine(line);
|
||||
IStringStream(line)() >> majorVersion;
|
||||
|
||||
// add other checks ...
|
||||
if (header != signature)
|
||||
{
|
||||
Info<< "header mismatch " << signature << " " << is.name()
|
||||
<< endl;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Foam::fileFormats::STARCDfileFormat::writeHeader
|
||||
(
|
||||
Ostream& os,
|
||||
const char* filetype
|
||||
)
|
||||
{
|
||||
os << "PROSTAR_" << filetype << nl
|
||||
<< 4000
|
||||
<< " " << 0
|
||||
<< " " << 0
|
||||
<< " " << 0
|
||||
<< " " << 0
|
||||
<< " " << 0
|
||||
<< " " << 0
|
||||
<< " " << 0
|
||||
<< endl;
|
||||
}
|
||||
|
||||
|
||||
void Foam::fileFormats::STARCDfileFormat::writePoints
|
||||
(
|
||||
Ostream& os,
|
||||
const pointField& pointLst
|
||||
)
|
||||
{
|
||||
writeHeader(os, "VERTEX");
|
||||
|
||||
// Set the precision of the points data to 10
|
||||
os.precision(10);
|
||||
|
||||
// force decimal point for Fortran input
|
||||
os.setf(std::ios::showpoint);
|
||||
|
||||
forAll(pointLst, ptI)
|
||||
{
|
||||
os
|
||||
<< ptI + 1 << " "
|
||||
<< pointLst[ptI].x() << " "
|
||||
<< pointLst[ptI].y() << " "
|
||||
<< pointLst[ptI].z() << nl;
|
||||
}
|
||||
os.flush();
|
||||
}
|
||||
|
||||
|
||||
inline void Foam::fileFormats::STARCDfileFormat::writeShell
|
||||
(
|
||||
Ostream& os,
|
||||
const face& f,
|
||||
const label cellId,
|
||||
const label cellTableId
|
||||
)
|
||||
{
|
||||
os
|
||||
<< cellId // includes 1 offset
|
||||
<< " " << starcdShellShape // 3(shell)
|
||||
<< " " << f.size()
|
||||
<< " " << cellTableId
|
||||
<< " " << starcdShellType; // 4(shell)
|
||||
|
||||
// primitives have <= 8 vertices, but prevent overrun anyhow
|
||||
// indent following lines for ease of reading
|
||||
label count = 0;
|
||||
forAll(f, fp)
|
||||
{
|
||||
if ((count % 8) == 0)
|
||||
{
|
||||
os
|
||||
<< nl
|
||||
<< " " << cellId;
|
||||
}
|
||||
os << " " << f[fp] + 1;
|
||||
count++;
|
||||
}
|
||||
os << endl;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::fileFormats::STARCDfileFormat::STARCDfileFormat()
|
||||
:
|
||||
Foam::keyedSurface()
|
||||
{}
|
||||
|
||||
|
||||
// .vrt file format:
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Line 1:
|
||||
PROSTAR_VERTEX [newline]
|
||||
|
||||
Line 2:
|
||||
<version> 0 0 0 0 0 0 0 [newline]
|
||||
|
||||
Body:
|
||||
<vertexId> <x> <y> <z> [newline]
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
Foam::fileFormats::STARCDfileFormat::STARCDfileFormat
|
||||
(
|
||||
const fileName& fName,
|
||||
const bool triangulation
|
||||
)
|
||||
:
|
||||
Foam::keyedSurface()
|
||||
{
|
||||
fileName baseName = fName.lessExt();
|
||||
autoPtr<IFstream> isPtr;
|
||||
|
||||
|
||||
DynamicList<point> pointLst;
|
||||
// STAR-CD index of points
|
||||
DynamicList<label> pointId;
|
||||
|
||||
//
|
||||
// read .vrt file
|
||||
//
|
||||
isPtr.reset(new IFstream(baseName + ".vrt"));
|
||||
|
||||
if (!isPtr().good())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"fileFormats::STARCDfileFormat::STARCDfileFormat(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
|
||||
points().transfer(pointLst);
|
||||
|
||||
// Build inverse mapping (index to point)
|
||||
pointId.shrink();
|
||||
Map<label> mapToFoamPointId(2*pointId.size());
|
||||
forAll(pointId, i)
|
||||
{
|
||||
mapToFoamPointId.insert(pointId[i], i);
|
||||
}
|
||||
pointId.clear();
|
||||
|
||||
|
||||
DynamicList<keyedFace> faceLst;
|
||||
|
||||
// From face cellTableId to patchId
|
||||
Map<label> cellTableToPatchId;
|
||||
label nPatches = 0;
|
||||
|
||||
|
||||
//
|
||||
// read .cel file
|
||||
//
|
||||
isPtr.reset(new IFstream(baseName + ".cel"));
|
||||
|
||||
if (!isPtr().good())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"fileFormats::STARCDfileFormat::STARCDfileFormat(const fileName&)"
|
||||
)
|
||||
<< "Cannot read file " << (baseName + ".cel")
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
readHeader(isPtr(), "PROSTAR_CELL");
|
||||
|
||||
label shapeId, nLabels, cellTableId, typeId;
|
||||
labelList starLabels(64);
|
||||
|
||||
while ((isPtr() >> lineLabel).good())
|
||||
{
|
||||
isPtr() >> shapeId >> nLabels >> cellTableId >> typeId;
|
||||
|
||||
if (nLabels > starLabels.size())
|
||||
{
|
||||
starLabels.setSize(nLabels);
|
||||
}
|
||||
starLabels = -1;
|
||||
|
||||
// read indices - max 8 per line
|
||||
for (label i = 0; i < nLabels; ++i)
|
||||
{
|
||||
if ((i % 8) == 0)
|
||||
{
|
||||
isPtr() >> lineLabel;
|
||||
}
|
||||
isPtr() >> starLabels[i];
|
||||
}
|
||||
|
||||
if (typeId == starcdShellType)
|
||||
{
|
||||
// Convert groupID into patchID
|
||||
Map<label>::const_iterator iter =
|
||||
cellTableToPatchId.find(cellTableId);
|
||||
|
||||
label patchI;
|
||||
if (iter == cellTableToPatchId.end())
|
||||
{
|
||||
patchI = nPatches++;
|
||||
|
||||
cellTableToPatchId.insert(cellTableId, patchI);
|
||||
}
|
||||
else
|
||||
{
|
||||
patchI = iter();
|
||||
}
|
||||
|
||||
|
||||
// convert orig vertex id to point label
|
||||
for (label i=0; i < nLabels; ++i)
|
||||
{
|
||||
starLabels[i] = mapToFoamPointId[starLabels[i]];
|
||||
}
|
||||
|
||||
if (triangulation && nLabels > 3)
|
||||
{
|
||||
face f
|
||||
(
|
||||
SubList<label>(starLabels, nLabels)
|
||||
);
|
||||
|
||||
faceList triFaces(f.nTriangles(points()));
|
||||
label nTri = 0;
|
||||
f.triangles(points(), nTri, triFaces);
|
||||
|
||||
forAll(triFaces, faceI)
|
||||
{
|
||||
faceLst.append
|
||||
(
|
||||
keyedFace
|
||||
(
|
||||
triFaces[faceI],
|
||||
patchI
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
faceLst.append
|
||||
(
|
||||
keyedFace
|
||||
(
|
||||
face(SubList<label>(starLabels, nLabels)),
|
||||
patchI
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
faces().transfer(faceLst);
|
||||
|
||||
setPatches(regionNames);
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
void Foam::fileFormats::STARCDfileFormat::write
|
||||
(
|
||||
const fileName& fName,
|
||||
const keyedSurface& surf
|
||||
)
|
||||
{
|
||||
const List<keyedFace>& faceLst = surf.faces();
|
||||
|
||||
fileName baseName = fName.lessExt();
|
||||
autoPtr<OFstream> osPtr;
|
||||
|
||||
osPtr.reset(new OFstream(baseName + ".vrt"));
|
||||
writePoints(osPtr(), surf.points());
|
||||
|
||||
|
||||
labelList faceMap;
|
||||
List<surfacePatch> patchLst = surf.sortedRegions(faceMap);
|
||||
|
||||
|
||||
osPtr.reset(new OFstream(baseName + ".cel"));
|
||||
writeHeader(osPtr(), "CELL");
|
||||
|
||||
label faceIndex = 0;
|
||||
forAll(patchLst, patchI)
|
||||
{
|
||||
const surfacePatch& patch = patchLst[patchI];
|
||||
|
||||
forAll(patch, patchFaceI)
|
||||
{
|
||||
const face& f = faceLst[faceMap[faceIndex++]];
|
||||
|
||||
writeShell(osPtr(), f, faceIndex, patchI + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Foam::fileFormats::STARCDfileFormat::write
|
||||
(
|
||||
const fileName& fName,
|
||||
const meshedSurface& surf
|
||||
)
|
||||
{
|
||||
const List<face>& faceLst = surf.faces();
|
||||
const List<surfacePatch>& patchLst = surf.patches();
|
||||
|
||||
|
||||
fileName baseName = fName.lessExt();
|
||||
autoPtr<OFstream> osPtr;
|
||||
|
||||
osPtr.reset(new OFstream(baseName + ".vrt"));
|
||||
writePoints(osPtr(), surf.points());
|
||||
|
||||
|
||||
osPtr.reset(new OFstream(baseName + ".cel"));
|
||||
writeHeader(osPtr(), "CELL");
|
||||
|
||||
label faceIndex = 0;
|
||||
forAll(patchLst, patchI)
|
||||
{
|
||||
const surfacePatch& patch = patchLst[patchI];
|
||||
|
||||
forAll(patch, patchFaceI)
|
||||
{
|
||||
const face& f = faceLst[faceIndex++];
|
||||
writeShell(osPtr(), f, faceIndex, patchI + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
|
||||
|
||||
// ************************************************************************* //
|
||||
149
src/surfMesh/keyedSurface/fileFormats/starcd/STARCDfileFormat.H
Normal file
149
src/surfMesh/keyedSurface/fileFormats/starcd/STARCDfileFormat.H
Normal file
@ -0,0 +1,149 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
Class
|
||||
Foam::fileFormats::STARCDfileFormat
|
||||
|
||||
Description
|
||||
Read/write the surface shells from pro-STAR vrt/cel files.
|
||||
|
||||
Note
|
||||
Uses the extension @a .inp (input) to denote the format.
|
||||
|
||||
See Also
|
||||
Foam::meshReaders::STARCD
|
||||
|
||||
SourceFiles
|
||||
STARCDfileFormat.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef STARCDfileFormat_H
|
||||
#define STARCDfileFormat_H
|
||||
|
||||
#include "STLtriangle.H"
|
||||
#include "IFstream.H"
|
||||
#include "Ostream.H"
|
||||
#include "OFstream.H"
|
||||
#include "keyedSurface.H"
|
||||
#include "meshedSurface.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace fileFormats
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class STARCDfileFormat Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class STARCDfileFormat
|
||||
:
|
||||
public keyedSurface
|
||||
{
|
||||
// Private data
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
STARCDfileFormat(const STARCDfileFormat&);
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const STARCDfileFormat&);
|
||||
|
||||
|
||||
static bool readHeader(IFstream&, const word&);
|
||||
|
||||
static void writeHeader(Ostream&, const char* filetype);
|
||||
|
||||
static void writePoints(Ostream&, const pointField&);
|
||||
|
||||
static inline void writeShell
|
||||
(
|
||||
Ostream&,
|
||||
const face&,
|
||||
const label cellId,
|
||||
const label cellTableId
|
||||
);
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct null
|
||||
STARCDfileFormat();
|
||||
|
||||
//- Construct from file name
|
||||
STARCDfileFormat(const fileName&, const bool triangulate=true);
|
||||
|
||||
// Selectors
|
||||
|
||||
//- Read file and return keyedSurface
|
||||
static autoPtr<keyedSurface> New
|
||||
(
|
||||
const fileName& fName,
|
||||
const bool triangulate=true
|
||||
)
|
||||
{
|
||||
return autoPtr<keyedSurface>
|
||||
(
|
||||
new STARCDfileFormat(fName, triangulate)
|
||||
);
|
||||
}
|
||||
|
||||
// Destructor
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Write
|
||||
|
||||
//- Write keyedSurface
|
||||
static void write(const fileName&, const keyedSurface&);
|
||||
|
||||
//- Write meshedSurface
|
||||
static void write(const fileName&, const meshedSurface&);
|
||||
|
||||
//- Write to Ostream as one large file - not really useful
|
||||
virtual void write(Ostream&) const
|
||||
{
|
||||
notImplemented("fileFormats::STARCDfileFormat::write(Ostream&)");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace fileFormats
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
590
src/surfMesh/keyedSurface/fileFormats/stl/STLfileFormat.C
Normal file
590
src/surfMesh/keyedSurface/fileFormats/stl/STLfileFormat.C
Normal file
@ -0,0 +1,590 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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 "STLfileFormat.H"
|
||||
#include "clock.H"
|
||||
#include "OSspecific.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
#include "addToMemberFunctionSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
namespace Foam
|
||||
{
|
||||
namespace fileFormats
|
||||
{
|
||||
|
||||
addNamedToRunTimeSelectionTable
|
||||
(
|
||||
keyedSurface,
|
||||
STLfileFormat,
|
||||
fileExtension,
|
||||
stl
|
||||
);
|
||||
|
||||
addNamedToRunTimeSelectionTable
|
||||
(
|
||||
keyedSurface,
|
||||
STLfileFormat,
|
||||
fileExtension,
|
||||
stlb
|
||||
);
|
||||
|
||||
addNamedToMemberFunctionSelectionTable
|
||||
(
|
||||
keyedSurface,
|
||||
STLfileFormat,
|
||||
write,
|
||||
fileExtension,
|
||||
stl
|
||||
);
|
||||
|
||||
addNamedToMemberFunctionSelectionTable
|
||||
(
|
||||
keyedSurface,
|
||||
STLfileFormat,
|
||||
write,
|
||||
fileExtension,
|
||||
stlb
|
||||
);
|
||||
|
||||
addNamedToMemberFunctionSelectionTable
|
||||
(
|
||||
meshedSurface,
|
||||
STLfileFormat,
|
||||
write,
|
||||
fileExtension,
|
||||
stl
|
||||
);
|
||||
|
||||
addNamedToMemberFunctionSelectionTable
|
||||
(
|
||||
meshedSurface,
|
||||
STLfileFormat,
|
||||
write,
|
||||
fileExtension,
|
||||
stlb
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
|
||||
// check binary by getting the header and number of facets
|
||||
// this seems to work better than the old token-based method
|
||||
// - some programs (eg, pro-STAR) have 'solid' as the first word in
|
||||
// the binary header.
|
||||
// - using wordToken can cause an abort if non-word (binary) content
|
||||
// is detected ... this is not exactly what we want.
|
||||
bool Foam::fileFormats::STLfileFormat::detectBINARY
|
||||
(
|
||||
const fileName& fName
|
||||
)
|
||||
{
|
||||
off_t fileSize = Foam::size(fName);
|
||||
|
||||
IFstream ifs(fName, IOstream::BINARY);
|
||||
istream& is = ifs.stdStream();
|
||||
|
||||
// Read the STL header
|
||||
char header[headerSize];
|
||||
is.read(header, headerSize);
|
||||
|
||||
// Check that stream is OK, if not this may be an ASCII file
|
||||
if (!is.good())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read the number of triangles in the STl file
|
||||
// (note: read as int so we can check whether >2^31)
|
||||
int nTris;
|
||||
is.read(reinterpret_cast<char*>(&nTris), sizeof(unsigned int));
|
||||
|
||||
// Check that stream is OK and number of triangles is positive,
|
||||
// if not this maybe an ASCII file
|
||||
//
|
||||
// Also compare the file size with that expected from the number of tris
|
||||
// If the comparison is not sensible then it may be an ASCII file
|
||||
if
|
||||
(
|
||||
!is
|
||||
|| nTris < 0
|
||||
|| nTris < (fileSize - headerSize)/50
|
||||
|| nTris > (fileSize - headerSize)/25
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// looks like it might be BINARY
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#undef DEBUG_STLBINARY
|
||||
|
||||
bool Foam::fileFormats::STLfileFormat::readBINARY
|
||||
(
|
||||
IFstream& ifs,
|
||||
const off_t fileSize
|
||||
)
|
||||
{
|
||||
istream& is = ifs.stdStream();
|
||||
|
||||
// Read the STL header
|
||||
char header[headerSize];
|
||||
is.read(header, headerSize);
|
||||
|
||||
// Check that stream is OK, if not this may be an ASCII file
|
||||
if (!is.good())
|
||||
{
|
||||
FatalErrorIn("fileFormats::STLfileFormat::readBINARY(Istream&)")
|
||||
<< "problem reading header, perhaps file is not binary "
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
// Read the number of triangles in the STl file
|
||||
// (note: read as int so we can check whether >2^31)
|
||||
int nTris;
|
||||
is.read(reinterpret_cast<char*>(&nTris), sizeof(unsigned int));
|
||||
|
||||
// Check that stream is OK and number of triangles is positive,
|
||||
// if not this maybe an ASCII file
|
||||
//
|
||||
// Also compare the file size with that expected from the number of tris
|
||||
// If the comparison is not sensible then it may be an ASCII file
|
||||
if
|
||||
(
|
||||
!is
|
||||
|| nTris < 0
|
||||
|| nTris < (fileSize - headerSize)/50
|
||||
|| nTris > (fileSize - headerSize)/25
|
||||
)
|
||||
{
|
||||
FatalErrorIn("fileFormats::STLfileFormat::readBINARY(Istream&)")
|
||||
<< "problem reading number of triangles, perhaps file is not binary"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_STLBINARY
|
||||
Info<< "# " << nTris << " facets" << endl;
|
||||
label prevRegion = -1;
|
||||
#endif
|
||||
|
||||
|
||||
pointField pointLst(3*nTris);
|
||||
List<keyedFace> faceLst(nTris);
|
||||
|
||||
label maxRegionId = 0;
|
||||
|
||||
label pointI = 0;
|
||||
forAll(faceLst, faceI)
|
||||
{
|
||||
// Read an STL triangle
|
||||
STLtriangle stlTri(is);
|
||||
|
||||
// Set the rawPoints to the vertices of the STL triangle
|
||||
// and set the point labels of the face
|
||||
face f(3);
|
||||
|
||||
pointLst[pointI] = stlTri.a();
|
||||
f[0] = pointI++;
|
||||
|
||||
pointLst[pointI] = stlTri.b();
|
||||
f[1] = pointI++;
|
||||
|
||||
pointLst[pointI] = stlTri.c();
|
||||
f[2] = pointI++;
|
||||
|
||||
if (maxRegionId < stlTri.region())
|
||||
{
|
||||
maxRegionId = stlTri.region();
|
||||
}
|
||||
|
||||
// interprete colour as a region
|
||||
faceLst[faceI] = keyedFace(f, stlTri.region());
|
||||
|
||||
#ifdef DEBUG_STLBINARY
|
||||
if
|
||||
(
|
||||
prevRegion != stlTri.region()
|
||||
)
|
||||
{
|
||||
if (prevRegion != -1)
|
||||
{
|
||||
Info<< "endsolid region" << prevRegion << nl;
|
||||
}
|
||||
prevRegion = stlTri.region();
|
||||
|
||||
Info<< "solid region" << prevRegion << nl;
|
||||
}
|
||||
|
||||
Info<< " facet normal " << stlTri.normal() << nl;
|
||||
Info<< " outer loop" << nl;
|
||||
Info<< " vertex " << stlTri.a() << nl;
|
||||
Info<< " vertex " << stlTri.b() << nl;
|
||||
Info<< " vertex " << stlTri.c() << nl;
|
||||
Info<< " outer loop" << nl;
|
||||
Info<< " endfacet" << endl;
|
||||
#endif
|
||||
}
|
||||
#ifdef DEBUG_STLBINARY
|
||||
Info<< "endsolid region" << prevRegion << nl;
|
||||
#endif
|
||||
|
||||
points().transfer(pointLst);
|
||||
faces().transfer(faceLst);
|
||||
setPatches(maxRegionId);
|
||||
stitchFaces(SMALL);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
inline void Foam::fileFormats::STLfileFormat::writeShell
|
||||
(
|
||||
Ostream& os,
|
||||
const pointField& pointLst,
|
||||
const face& f,
|
||||
const vector& norm
|
||||
)
|
||||
{
|
||||
// simple triangulation about f[0].
|
||||
// better triangulation should have been done before
|
||||
const point& p0 = pointLst[f[0]];
|
||||
for (label fp1 = 1; fp1 < f.size() - 1; ++fp1)
|
||||
{
|
||||
label fp2 = (fp1 + 1) % f.size();
|
||||
|
||||
const point& p1 = pointLst[f[fp1]];
|
||||
const point& p2 = pointLst[f[fp2]];
|
||||
|
||||
// write STL triangle
|
||||
os << " facet normal "
|
||||
<< norm.x() << ' ' << norm.y() << ' ' << norm.z() << nl
|
||||
<< " outer loop\n"
|
||||
<< " vertex "
|
||||
<< p0.x() << ' ' << p0.y() << ' ' << p0.z() << nl
|
||||
<< " vertex "
|
||||
<< p1.x() << ' ' << p1.y() << ' ' << p1.z() << nl
|
||||
<< " vertex "
|
||||
<< p2.x() << ' ' << p2.y() << ' ' << p2.z() << nl
|
||||
<< " endloop\n"
|
||||
<< " endfacet" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline void Foam::fileFormats::STLfileFormat::writeShell
|
||||
(
|
||||
ostream& os,
|
||||
const pointField& pointLst,
|
||||
const face& f,
|
||||
const vector& norm,
|
||||
const label patchI
|
||||
)
|
||||
{
|
||||
// simple triangulation about f[0].
|
||||
// better triangulation should have been done before
|
||||
const point& p0 = pointLst[f[0]];
|
||||
for (label fp1 = 1; fp1 < f.size() - 1; ++fp1)
|
||||
{
|
||||
label fp2 = (fp1 + 1) % f.size();
|
||||
|
||||
STLtriangle stlTri
|
||||
(
|
||||
norm,
|
||||
p0,
|
||||
pointLst[f[fp1]],
|
||||
pointLst[f[fp2]],
|
||||
patchI
|
||||
);
|
||||
|
||||
stlTri.write(os);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// write sorted:
|
||||
void Foam::fileFormats::STLfileFormat::writeASCII
|
||||
(
|
||||
Ostream& os,
|
||||
const keyedSurface& surf
|
||||
)
|
||||
{
|
||||
const pointField& pointLst = surf.points();
|
||||
const List<keyedFace>& faceLst = surf.faces();
|
||||
const vectorField& normLst = surf.faceNormals();
|
||||
|
||||
labelList faceMap;
|
||||
List<surfacePatch> patchLst = surf.sortedRegions(faceMap);
|
||||
|
||||
label faceIndex = 0;
|
||||
forAll(patchLst, patchI)
|
||||
{
|
||||
// Print all faces belonging to this region
|
||||
const surfacePatch& patch = patchLst[patchI];
|
||||
|
||||
os << "solid " << patch.name() << endl;
|
||||
|
||||
forAll(patch, patchFaceI)
|
||||
{
|
||||
const label faceI = faceMap[faceIndex++];
|
||||
writeShell(os, pointLst, faceLst[faceI], normLst[faceI]);
|
||||
}
|
||||
|
||||
os << "endsolid " << patch.name() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// write sorted:
|
||||
void Foam::fileFormats::STLfileFormat::writeASCII
|
||||
(
|
||||
Ostream& os,
|
||||
const meshedSurface& surf
|
||||
)
|
||||
{
|
||||
const pointField& pointLst = surf.points();
|
||||
const List<face>& faceLst = surf.faces();
|
||||
const List<surfacePatch>& patchLst = surf.patches();
|
||||
const vectorField& normLst = surf.faceNormals();
|
||||
|
||||
// force triangulation, but just do the cheapest form possible
|
||||
label faceIndex = 0;
|
||||
forAll(patchLst, patchI)
|
||||
{
|
||||
// Print all faces belonging to this region
|
||||
const surfacePatch& patch = patchLst[patchI];
|
||||
|
||||
os << "solid " << patch.name() << endl;
|
||||
|
||||
forAll(patch, patchFaceI)
|
||||
{
|
||||
const label faceI = faceIndex++;
|
||||
writeShell(os, pointLst, faceLst[faceI], normLst[faceI]);
|
||||
}
|
||||
|
||||
os << "endsolid " << patch.name() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// write unsorted:
|
||||
void Foam::fileFormats::STLfileFormat::writeBINARY
|
||||
(
|
||||
ostream& os,
|
||||
const keyedSurface& surf
|
||||
)
|
||||
{
|
||||
const pointField& pointLst = surf.points();
|
||||
const List<keyedFace>& faceLst = surf.faces();
|
||||
const vectorField& normLst = surf.faceNormals();
|
||||
|
||||
// Write the STL header
|
||||
string header("STL binary file", headerSize);
|
||||
|
||||
// clear possible trailing junk
|
||||
for (label i = header.size(); i < headerSize; ++i)
|
||||
{
|
||||
header[i] = 0;
|
||||
}
|
||||
os.write(header.c_str(), headerSize);
|
||||
|
||||
// force triangulation, but just do the cheapest form possible
|
||||
unsigned int nTris = 0;
|
||||
forAll(faceLst, faceI)
|
||||
{
|
||||
nTris += faceLst[faceI].size() - 2;
|
||||
}
|
||||
|
||||
os.write(reinterpret_cast<char*>(&nTris), sizeof(unsigned int));
|
||||
|
||||
forAll(faceLst, faceI)
|
||||
{
|
||||
writeShell
|
||||
(
|
||||
os,
|
||||
pointLst,
|
||||
faceLst[faceI],
|
||||
normLst[faceI],
|
||||
faceLst[faceI].key()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::fileFormats::STLfileFormat::writeBINARY
|
||||
(
|
||||
ostream& os,
|
||||
const meshedSurface& surf
|
||||
)
|
||||
{
|
||||
const pointField& pointLst = surf.points();
|
||||
const List<face>& faceLst = surf.faces();
|
||||
const surfacePatchList& patchLst = surf.patches();
|
||||
const vectorField& normLst = surf.faceNormals();
|
||||
|
||||
// Write the STL header
|
||||
string header("STL binary file", headerSize);
|
||||
os.write(header.c_str(), headerSize);
|
||||
|
||||
// force triangulation, but just do the cheapest form possible
|
||||
|
||||
unsigned int nTris = 0;
|
||||
forAll(faceLst, faceI)
|
||||
{
|
||||
nTris += faceLst[faceI].size() - 2;
|
||||
}
|
||||
|
||||
os.write(reinterpret_cast<char*>(&nTris), sizeof(unsigned int));
|
||||
|
||||
label faceIndex = 0;
|
||||
forAll(patchLst, patchI)
|
||||
{
|
||||
forAll(patchLst[patchI], patchFaceI)
|
||||
{
|
||||
writeShell
|
||||
(
|
||||
os,
|
||||
pointLst,
|
||||
faceLst[faceIndex],
|
||||
normLst[faceIndex],
|
||||
patchI
|
||||
);
|
||||
|
||||
++faceIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::fileFormats::STLfileFormat::STLfileFormat()
|
||||
:
|
||||
Foam::keyedSurface()
|
||||
{}
|
||||
|
||||
|
||||
Foam::fileFormats::STLfileFormat::STLfileFormat
|
||||
(
|
||||
const fileName& fName,
|
||||
const bool
|
||||
)
|
||||
:
|
||||
Foam::keyedSurface()
|
||||
{
|
||||
off_t fileSize = Foam::size(fName);
|
||||
|
||||
// auto-detect ascii/binary
|
||||
if (detectBINARY(fName))
|
||||
{
|
||||
readBINARY(IFstream(fName, IOstream::BINARY)(), fileSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
readASCII(IFstream(fName)(), fileSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
void Foam::fileFormats::STLfileFormat::write
|
||||
(
|
||||
Ostream& os,
|
||||
const keyedSurface& surf
|
||||
)
|
||||
{
|
||||
writeASCII(os, surf);
|
||||
}
|
||||
|
||||
|
||||
void Foam::fileFormats::STLfileFormat::write
|
||||
(
|
||||
Ostream& os,
|
||||
const meshedSurface& surf
|
||||
)
|
||||
{
|
||||
writeASCII(os, surf);
|
||||
}
|
||||
|
||||
|
||||
void Foam::fileFormats::STLfileFormat::write
|
||||
(
|
||||
const fileName& fName,
|
||||
const keyedSurface& surf
|
||||
)
|
||||
{
|
||||
const word ext = fName.ext();
|
||||
|
||||
// handle 'stlb' as binary directly
|
||||
if (ext == "stlb")
|
||||
{
|
||||
std::ofstream ofs(fName.c_str(), std::ios::binary);
|
||||
writeBINARY(ofs, surf);
|
||||
}
|
||||
else
|
||||
{
|
||||
writeASCII(OFstream(fName)(), surf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::fileFormats::STLfileFormat::write
|
||||
(
|
||||
const fileName& fName,
|
||||
const meshedSurface& surf
|
||||
)
|
||||
{
|
||||
const word ext = fName.ext();
|
||||
|
||||
// handle 'stlb' as binary directly
|
||||
if (ext == "stlb")
|
||||
{
|
||||
std::ofstream ofs(fName.c_str(), std::ios::binary);
|
||||
writeBINARY(ofs, surf);
|
||||
}
|
||||
else
|
||||
{
|
||||
writeASCII(OFstream(fName)(), surf);
|
||||
}
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
|
||||
|
||||
// ************************************************************************* //
|
||||
177
src/surfMesh/keyedSurface/fileFormats/stl/STLfileFormat.H
Normal file
177
src/surfMesh/keyedSurface/fileFormats/stl/STLfileFormat.H
Normal file
@ -0,0 +1,177 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
Class
|
||||
Foam::fileFormats::STLfileFormat
|
||||
|
||||
Description
|
||||
Provide a means of reading/writing STL files (ASCII and binary).
|
||||
|
||||
SourceFiles
|
||||
STLfileFormat.C
|
||||
STLfileFormatASCII.L
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef STLfileFormat_H
|
||||
#define STLfileFormat_H
|
||||
|
||||
#include "STLtriangle.H"
|
||||
#include "IFstream.H"
|
||||
#include "Ostream.H"
|
||||
#include "OFstream.H"
|
||||
#include "keyedSurface.H"
|
||||
#include "meshedSurface.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace fileFormats
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class STLfileFormat Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class STLfileFormat
|
||||
:
|
||||
public keyedSurface
|
||||
{
|
||||
// Private data
|
||||
|
||||
//- The number of bytes in the STL binary header
|
||||
static const int headerSize=80;
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
STLfileFormat(const STLfileFormat&);
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const STLfileFormat&);
|
||||
|
||||
bool detectBINARY(const fileName&);
|
||||
|
||||
bool readASCII(IFstream&, const off_t);
|
||||
bool readBINARY(IFstream&, const off_t);
|
||||
|
||||
//- write face in ASCII
|
||||
static inline void writeShell
|
||||
(
|
||||
Ostream&,
|
||||
const pointField&,
|
||||
const face&,
|
||||
const vector& norm
|
||||
);
|
||||
|
||||
//- write face in BINARY
|
||||
static inline void writeShell
|
||||
(
|
||||
ostream&,
|
||||
const pointField&,
|
||||
const face&,
|
||||
const vector&,
|
||||
const label patchI
|
||||
);
|
||||
|
||||
|
||||
//- Write keySurface
|
||||
static void writeASCII(Ostream&, const keyedSurface&);
|
||||
|
||||
//- Write keyedSurface
|
||||
static void writeBINARY(ostream&, const keyedSurface&);
|
||||
|
||||
//- Write meshedSurface
|
||||
static void writeASCII(Ostream&, const meshedSurface&);
|
||||
|
||||
//- Write meshedSurface
|
||||
static void writeBINARY(ostream&, const meshedSurface&);
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct null
|
||||
STLfileFormat();
|
||||
|
||||
//- Construct from file name
|
||||
STLfileFormat(const fileName&, const bool triangulate=true);
|
||||
|
||||
// Selectors
|
||||
|
||||
//- Read file and return keyedSurface
|
||||
static autoPtr<keyedSurface> New
|
||||
(
|
||||
const fileName& fName,
|
||||
const bool triangulate=true
|
||||
)
|
||||
{
|
||||
return autoPtr<keyedSurface>
|
||||
(
|
||||
new STLfileFormat(fName,triangulate)
|
||||
);
|
||||
}
|
||||
|
||||
// Destructor
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Write
|
||||
|
||||
//- Write keyedSurface
|
||||
// The ASCII output is sorted by patch, the binary output is unsorted
|
||||
static void write(Ostream&, const keyedSurface&);
|
||||
|
||||
//- Write keyedSurface
|
||||
// The ASCII output is sorted by patch, the binary output is unsorted
|
||||
static void write(const fileName&, const keyedSurface&);
|
||||
|
||||
//- Write meshedSurface
|
||||
static void write(Ostream&, const meshedSurface&);
|
||||
|
||||
//- Write meshedSurface
|
||||
static void write(const fileName&, const meshedSurface&);
|
||||
|
||||
//- Write object
|
||||
virtual void write(Ostream& os) const
|
||||
{
|
||||
write(os, *this);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace fileFormats
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
426
src/surfMesh/keyedSurface/fileFormats/stl/STLfileFormatASCII.L
Normal file
426
src/surfMesh/keyedSurface/fileFormats/stl/STLfileFormatASCII.L
Normal file
@ -0,0 +1,426 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
%{
|
||||
|
||||
#undef yyFlexLexer
|
||||
|
||||
/* ------------------------------------------------------------------------ *\
|
||||
------ local definitions
|
||||
\* ------------------------------------------------------------------------ */
|
||||
|
||||
#include "STLfileFormat.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// Dummy yyFlexLexer::yylex() to keep the linker happy. It is not called
|
||||
//! @cond dummy
|
||||
int yyFlexLexer::yylex()
|
||||
{
|
||||
FatalErrorIn("yyFlexLexer::yylex()")
|
||||
<< "Should not have called this function"
|
||||
<< abort(FatalError);
|
||||
return 0;
|
||||
}
|
||||
//! @endcond dummy
|
||||
|
||||
// Dummy yywrap to keep yylex happy at compile time.
|
||||
// It is called by yylex but is not used as the mechanism to change file.
|
||||
// See <<EOF>>
|
||||
//! @cond dummy
|
||||
#if YY_FLEX_SUBMINOR_VERSION < 34
|
||||
extern "C" int yywrap()
|
||||
#else
|
||||
int yyFlexLexer::yywrap()
|
||||
#endif
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
//! @endcond dummy
|
||||
|
||||
|
||||
//- A lexer for parsing STL ASCII files.
|
||||
// Returns DynamicList(s) of points and facets (regionIds).
|
||||
// Since the facets appear within a solid/endsolid grouping,
|
||||
// they are always within a region
|
||||
class STLASCIILexer
|
||||
:
|
||||
public yyFlexLexer
|
||||
{
|
||||
// Private data
|
||||
|
||||
short groupID_; // current region
|
||||
short maxGroupID_; // max region
|
||||
label lineNo_;
|
||||
word startError_;
|
||||
|
||||
DynamicList<point> points_;
|
||||
DynamicList<label> facets_;
|
||||
HashTable<label> groupToPatch_;
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- From input stream and the approximate number of vertices in the STL
|
||||
STLASCIILexer(istream* is, const label approxNpoints);
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- The lexer function itself
|
||||
int lex();
|
||||
|
||||
// Access
|
||||
|
||||
//- A list of points corresponding to a pointField
|
||||
DynamicList<point>& points()
|
||||
{
|
||||
return points_;
|
||||
}
|
||||
|
||||
//- A list of facet IDs (region IDs)
|
||||
// corresponds to the number of triangles
|
||||
DynamicList<label>& facets()
|
||||
{
|
||||
return facets_;
|
||||
}
|
||||
|
||||
//- region names
|
||||
const HashTable<label>& groupToPatch() const
|
||||
{
|
||||
return groupToPatch_;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
STLASCIILexer::STLASCIILexer(istream* is, const label approxNpoints)
|
||||
:
|
||||
yyFlexLexer(is),
|
||||
groupID_(-1),
|
||||
maxGroupID_(-1),
|
||||
lineNo_(1),
|
||||
points_(approxNpoints),
|
||||
facets_(approxNpoints)
|
||||
{}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------ *\
|
||||
------ cppLexer::yylex()
|
||||
\* ------------------------------------------------------------------------ */
|
||||
|
||||
#define YY_DECL int STLASCIILexer::lex()
|
||||
|
||||
%}
|
||||
|
||||
one_space [ \t\f\r]
|
||||
space {one_space}*
|
||||
some_space {one_space}+
|
||||
cspace ","{space}
|
||||
|
||||
alpha [_A-Za-z]
|
||||
digit [0-9]
|
||||
dec_digit [0-9]
|
||||
octal_digit [0-7]
|
||||
hex_digit [0-9a-fA-F]
|
||||
|
||||
identifier {alpha}({alpha}|{digit})*
|
||||
integer {dec_digit}+
|
||||
label [1-9]{dec_digit}*
|
||||
zeroLabel {digit}*
|
||||
signedInteger [-+]?{integer}
|
||||
|
||||
word ([[:alnum:]]|[[:punct:]])*
|
||||
string {word}({some_space}{word})*
|
||||
|
||||
exponent_part [eE][-+]?{digit}+
|
||||
fractional_constant [-+]?(({digit}*"."{digit}+)|({digit}+"."?))
|
||||
|
||||
double (({fractional_constant}{exponent_part}?)|({digit}+{exponent_part}))
|
||||
float {double}
|
||||
|
||||
x {float}
|
||||
y {float}
|
||||
z {float}
|
||||
|
||||
solid {space}("solid"|"SOLID"){space}
|
||||
color {space}("color"|"COLOR"){some_space}{float}{some_space}{float}{some_space}{float}{space}
|
||||
facet {space}("facet"|"FACET"){space}
|
||||
normal {space}("normal"|"NORMAL"){space}
|
||||
point {space}{x}{some_space}{y}{some_space}{z}{space}
|
||||
outerloop {space}("outer"{some_space}"loop")|("OUTER"{some_space}"LOOP"){space}
|
||||
vertex {space}("vertex"|"VERTEX"){space}
|
||||
endloop {space}("endloop"|"ENDLOOP"){space}
|
||||
endfacet {space}("endfacet"|"ENDFACET"){space}
|
||||
endsolid {space}("endsolid"|"ENDSOLID")({some_space}{word})*
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------ *\
|
||||
----- Exclusive start states -----
|
||||
\* ------------------------------------------------------------------------ */
|
||||
|
||||
%option stack
|
||||
|
||||
%x readSolidName
|
||||
%x readFacet
|
||||
%x readNormal
|
||||
%x readVertices
|
||||
%x readVertex
|
||||
%x stlError
|
||||
|
||||
%%
|
||||
|
||||
%{
|
||||
// End of read character pointer returned by strtof
|
||||
// char* endPtr;
|
||||
|
||||
STLpoint normal;
|
||||
STLpoint vertex;
|
||||
label cmpt = 0; // component index used for reading vertex
|
||||
|
||||
static const char* stateNames[7] =
|
||||
{
|
||||
"reading solid",
|
||||
"reading solid name",
|
||||
"reading facet",
|
||||
"reading normal",
|
||||
"reading vertices",
|
||||
"reading vertex",
|
||||
"error"
|
||||
};
|
||||
|
||||
static const char* stateExpects[7] =
|
||||
{
|
||||
"'solid', 'color', 'facet' or 'endsolid'",
|
||||
"<string>",
|
||||
"'normal', 'outer loop' or 'endfacet'",
|
||||
"<float> <float> <float>",
|
||||
"'vertex' or 'endloop'",
|
||||
"<float> <float> <float>",
|
||||
""
|
||||
};
|
||||
%}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------ *\
|
||||
------ Start Lexing ------
|
||||
\* ------------------------------------------------------------------------ */
|
||||
|
||||
/* ------ Reading control header ------ */
|
||||
|
||||
{solid} {
|
||||
BEGIN(readSolidName);
|
||||
}
|
||||
|
||||
<readSolidName>{string} {
|
||||
word group(Foam::string::validate<word>(YYText()));
|
||||
|
||||
HashTable<label>::const_iterator findGroup =
|
||||
groupToPatch_.find(group);
|
||||
|
||||
if (findGroup != groupToPatch_.end())
|
||||
{
|
||||
groupID_ = findGroup();
|
||||
}
|
||||
else
|
||||
{
|
||||
groupID_ = ++maxGroupID_;
|
||||
groupToPatch_.insert(group, groupID_);
|
||||
}
|
||||
BEGIN(INITIAL);
|
||||
}
|
||||
|
||||
<readSolidName>{space}\n {
|
||||
word group("solid");
|
||||
|
||||
HashTable<label>::const_iterator findGroup =
|
||||
groupToPatch_.find(group);
|
||||
|
||||
if (findGroup != groupToPatch_.end())
|
||||
{
|
||||
groupID_ = findGroup();
|
||||
}
|
||||
else
|
||||
{
|
||||
groupID_ = ++maxGroupID_;
|
||||
groupToPatch_.insert(group, groupID_);
|
||||
}
|
||||
|
||||
lineNo_++;
|
||||
BEGIN(INITIAL);
|
||||
}
|
||||
|
||||
{color} {
|
||||
}
|
||||
|
||||
{facet} {
|
||||
BEGIN(readFacet);
|
||||
}
|
||||
|
||||
<readFacet>{normal} {
|
||||
BEGIN(readNormal);
|
||||
}
|
||||
|
||||
<readNormal>{point} {
|
||||
/*
|
||||
skip reading normals:
|
||||
normal.x() = strtof(YYText(), &endPtr);
|
||||
normal.y() = strtof(endPtr, &endPtr);
|
||||
normal.z() = strtof(endPtr, &endPtr);
|
||||
normals_.append(normal);
|
||||
*/
|
||||
BEGIN(readFacet);
|
||||
}
|
||||
|
||||
<readFacet>{outerloop} {
|
||||
BEGIN(readVertices);
|
||||
}
|
||||
|
||||
<readVertices>{vertex} {
|
||||
BEGIN(readVertex);
|
||||
}
|
||||
|
||||
<readVertex>{space}{signedInteger}{space} {
|
||||
vertex[cmpt++] = atol(YYText());
|
||||
|
||||
if (cmpt == 3)
|
||||
{
|
||||
cmpt = 0;
|
||||
points_.append(vertex);
|
||||
BEGIN(readVertices);
|
||||
}
|
||||
}
|
||||
|
||||
<readVertex>{space}{float}{space} {
|
||||
vertex[cmpt++] = atof(YYText());
|
||||
|
||||
if (cmpt == 3)
|
||||
{
|
||||
cmpt = 0;
|
||||
points_.append(vertex);
|
||||
BEGIN(readVertices);
|
||||
}
|
||||
}
|
||||
|
||||
<readVertices>{endloop} {
|
||||
BEGIN(readFacet);
|
||||
}
|
||||
|
||||
<readFacet>{endfacet} {
|
||||
facets_.append(groupID_);
|
||||
BEGIN(INITIAL);
|
||||
}
|
||||
|
||||
{endsolid} {
|
||||
}
|
||||
|
||||
|
||||
/* ------------------ Ignore remaining space and \n s. -------------------- */
|
||||
|
||||
<*>{space} {}
|
||||
<*>\n { lineNo_++; }
|
||||
|
||||
|
||||
/* ------------------- Any other characters are errors -------------------- */
|
||||
|
||||
<*>. {
|
||||
startError_ = YYText();
|
||||
yy_push_state(stlError);
|
||||
}
|
||||
|
||||
|
||||
/* ---------------------------- Error handler ----------------------------- */
|
||||
|
||||
<stlError>.* {
|
||||
yy_pop_state();
|
||||
FatalErrorIn
|
||||
(
|
||||
"fileFormats::STLfileFormat::readASCII(const fileName& STLfileName)"
|
||||
) << "while " << stateNames[YY_START] << " on line " << lineNo_ << nl
|
||||
<< " expected " << stateExpects[YY_START]
|
||||
<< " but found '" << startError_.c_str() << YYText() << "'"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------ On EOF terminate ---------------------------- */
|
||||
|
||||
<<EOF>> {
|
||||
yyterminate();
|
||||
}
|
||||
%%
|
||||
|
||||
|
||||
//
|
||||
// member function
|
||||
//
|
||||
bool
|
||||
Foam::fileFormats::STLfileFormat::readASCII
|
||||
(
|
||||
IFstream& ifs,
|
||||
const off_t fileSize
|
||||
)
|
||||
{
|
||||
// Create the lexer with the approximate number of vertices in the STL
|
||||
// from the file size
|
||||
STLASCIILexer lexer(&ifs.stdStream(), fileSize/400);
|
||||
while (lexer.lex() != 0) {}
|
||||
|
||||
DynamicList<point>& pointLst = lexer.points();
|
||||
DynamicList<label>& facetsLst = lexer.facets();
|
||||
|
||||
// transfer to normal list
|
||||
points().transfer(pointLst);
|
||||
|
||||
// make our triangles
|
||||
facetsLst.shrink();
|
||||
List<keyedFace> faceLst(facetsLst.size());
|
||||
|
||||
face fTri(3);
|
||||
label ptI = 0;
|
||||
forAll(facetsLst, faceI)
|
||||
{
|
||||
fTri[0] = ptI++;
|
||||
fTri[1] = ptI++;
|
||||
fTri[2] = ptI++;
|
||||
|
||||
faceLst[faceI] = keyedFace(fTri, facetsLst[faceI]);
|
||||
}
|
||||
facetsLst.clearStorage();
|
||||
|
||||
// transfer to normal list
|
||||
faces().transfer(faceLst);
|
||||
setPatches(lexer.groupToPatch());
|
||||
stitchFaces(SMALL);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------ *\
|
||||
------ End of STLfileFormatASCII.L
|
||||
\* ------------------------------------------------------------------------ */
|
||||
93
src/surfMesh/keyedSurface/fileFormats/stl/STLpoint.H
Normal file
93
src/surfMesh/keyedSurface/fileFormats/stl/STLpoint.H
Normal file
@ -0,0 +1,93 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
Class
|
||||
Foam::STLpoint
|
||||
|
||||
Description
|
||||
A vertex point representation for STL files.
|
||||
|
||||
SourceFiles
|
||||
STLpointI.H
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef STLpoint_H
|
||||
#define STLpoint_H
|
||||
|
||||
#include "point.H"
|
||||
#include "Istream.H"
|
||||
#include "Ostream.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class STLpoint Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class STLpoint
|
||||
:
|
||||
public Vector<float>
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct null
|
||||
inline STLpoint();
|
||||
|
||||
//- Construct from components
|
||||
inline STLpoint(float x, float y, float z);
|
||||
|
||||
//- Construct from point
|
||||
inline STLpoint(const point&);
|
||||
|
||||
//- Construct from istream
|
||||
inline STLpoint(Istream&);
|
||||
|
||||
|
||||
// Member Operators
|
||||
|
||||
inline operator point() const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#include "STLpointI.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
60
src/surfMesh/keyedSurface/fileFormats/stl/STLpointI.H
Normal file
60
src/surfMesh/keyedSurface/fileFormats/stl/STLpointI.H
Normal file
@ -0,0 +1,60 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
inline Foam::STLpoint::STLpoint()
|
||||
{}
|
||||
|
||||
inline Foam::STLpoint::STLpoint(float x, float y, float z)
|
||||
:
|
||||
Vector<float>(x, y, z)
|
||||
{}
|
||||
|
||||
inline Foam::STLpoint::STLpoint(const point& pt)
|
||||
:
|
||||
Vector<float>(float(pt.x()), float(pt.y()), float(pt.z()))
|
||||
{}
|
||||
|
||||
inline Foam::STLpoint::STLpoint(Istream& is)
|
||||
:
|
||||
Vector<float>(is)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||
|
||||
inline Foam::STLpoint::operator point() const
|
||||
{
|
||||
return point(x(), y(), z());
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// ************************************************************************* //
|
||||
122
src/surfMesh/keyedSurface/fileFormats/stl/STLtriangle.H
Normal file
122
src/surfMesh/keyedSurface/fileFormats/stl/STLtriangle.H
Normal file
@ -0,0 +1,122 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
Class
|
||||
Foam::STLtriangle
|
||||
|
||||
Description
|
||||
A triangle representation for STL files.
|
||||
|
||||
SourceFiles
|
||||
STLtriangleI.H
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef STLtriangle_H
|
||||
#define STLtriangle_H
|
||||
|
||||
#include "STLpoint.H"
|
||||
#include "Istream.H"
|
||||
#include "Ostream.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class STLtriangle Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class STLtriangle
|
||||
{
|
||||
// Private data
|
||||
|
||||
typedef unsigned short STLregion;
|
||||
|
||||
STLpoint normal_, a_, b_, c_;
|
||||
|
||||
STLregion region_;
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct null
|
||||
inline STLtriangle();
|
||||
|
||||
//- Construct from components
|
||||
inline STLtriangle
|
||||
(
|
||||
const STLpoint& normal,
|
||||
const STLpoint& a,
|
||||
const STLpoint& b,
|
||||
const STLpoint& c,
|
||||
unsigned short region
|
||||
);
|
||||
|
||||
//- Construct from istream (read binary)
|
||||
inline STLtriangle(istream&);
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Access
|
||||
|
||||
inline const STLpoint& normal() const;
|
||||
inline const STLpoint& a() const;
|
||||
inline const STLpoint& b() const;
|
||||
inline const STLpoint& c() const;
|
||||
inline unsigned short region() const;
|
||||
|
||||
// Read
|
||||
|
||||
//- Read from istream (binary)
|
||||
inline void read(istream&);
|
||||
|
||||
// Write
|
||||
|
||||
//- Write to ostream (binary)
|
||||
inline void write(ostream&);
|
||||
|
||||
|
||||
// Ostream operator
|
||||
|
||||
inline friend Ostream& operator<<(Ostream&, const STLtriangle&);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#include "STLtriangleI.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
115
src/surfMesh/keyedSurface/fileFormats/stl/STLtriangleI.H
Normal file
115
src/surfMesh/keyedSurface/fileFormats/stl/STLtriangleI.H
Normal file
@ -0,0 +1,115 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
inline Foam::STLtriangle::STLtriangle()
|
||||
{}
|
||||
|
||||
|
||||
inline Foam::STLtriangle::STLtriangle
|
||||
(
|
||||
const STLpoint& normal,
|
||||
const STLpoint& a,
|
||||
const STLpoint& b,
|
||||
const STLpoint& c,
|
||||
unsigned short region
|
||||
)
|
||||
:
|
||||
normal_(normal),
|
||||
a_(a),
|
||||
b_(b),
|
||||
c_(c),
|
||||
region_(region)
|
||||
{}
|
||||
|
||||
|
||||
inline Foam::STLtriangle::STLtriangle(istream& is)
|
||||
{
|
||||
read(is);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
inline const Foam::STLpoint& Foam::STLtriangle::normal() const
|
||||
{
|
||||
return normal_;
|
||||
}
|
||||
|
||||
inline const Foam::STLpoint& Foam::STLtriangle::a() const
|
||||
{
|
||||
return a_;
|
||||
}
|
||||
|
||||
inline const Foam::STLpoint& Foam::STLtriangle::b() const
|
||||
{
|
||||
return b_;
|
||||
}
|
||||
|
||||
inline const Foam::STLpoint& Foam::STLtriangle::c() const
|
||||
{
|
||||
return c_;
|
||||
}
|
||||
|
||||
inline unsigned short Foam::STLtriangle::region() const
|
||||
{
|
||||
return region_;
|
||||
}
|
||||
|
||||
|
||||
inline void Foam::STLtriangle::read(istream& is)
|
||||
{
|
||||
is.read(reinterpret_cast<char*>(this), 4*sizeof(STLpoint));
|
||||
is.read(reinterpret_cast<char*>(®ion_), sizeof(STLregion));
|
||||
}
|
||||
|
||||
|
||||
inline void Foam::STLtriangle::write(ostream& os)
|
||||
{
|
||||
os.write(reinterpret_cast<char*>(this), 4*sizeof(STLpoint));
|
||||
os.write(reinterpret_cast<char*>(®ion_), sizeof(STLregion));
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
|
||||
|
||||
inline Foam::Ostream& Foam::operator<<(Ostream& os, const STLtriangle& t)
|
||||
{
|
||||
os << t.normal_ << token::SPACE
|
||||
<< t.a_ << token::SPACE
|
||||
<< t.b_ << token::SPACE
|
||||
<< t.c_ << token::SPACE
|
||||
<< t.region_;
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// ************************************************************************* //
|
||||
287
src/surfMesh/keyedSurface/fileFormats/tri/TRIfileFormat.C
Normal file
287
src/surfMesh/keyedSurface/fileFormats/tri/TRIfileFormat.C
Normal file
@ -0,0 +1,287 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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 "TRIfileFormat.H"
|
||||
#include "clock.H"
|
||||
#include "IFstream.H"
|
||||
#include "IOmanip.H"
|
||||
#include "IStringStream.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
#include "addToMemberFunctionSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
namespace Foam
|
||||
{
|
||||
namespace fileFormats
|
||||
{
|
||||
|
||||
addNamedToRunTimeSelectionTable
|
||||
(
|
||||
keyedSurface,
|
||||
TRIfileFormat,
|
||||
fileExtension,
|
||||
tri
|
||||
);
|
||||
|
||||
addNamedToMemberFunctionSelectionTable
|
||||
(
|
||||
keyedSurface,
|
||||
TRIfileFormat,
|
||||
write,
|
||||
fileExtension,
|
||||
tri
|
||||
);
|
||||
|
||||
addNamedToMemberFunctionSelectionTable
|
||||
(
|
||||
meshedSurface,
|
||||
TRIfileFormat,
|
||||
write,
|
||||
fileExtension,
|
||||
tri
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
inline void Foam::fileFormats::TRIfileFormat::writeShell
|
||||
(
|
||||
Ostream& os,
|
||||
const pointField& pointLst,
|
||||
const face& f,
|
||||
const label patchI
|
||||
)
|
||||
{
|
||||
// simple triangulation about f[0].
|
||||
// better triangulation should have been done before
|
||||
const point& p0 = pointLst[f[0]];
|
||||
for (label fp1 = 1; fp1 < f.size() - 1; ++fp1)
|
||||
{
|
||||
label fp2 = (fp1 + 1) % f.size();
|
||||
|
||||
const point& p1 = pointLst[f[fp1]];
|
||||
const point& p2 = pointLst[f[fp2]];
|
||||
|
||||
os << p0.x() << ' ' << p0.y() << ' ' << p0.z() << ' '
|
||||
<< p1.x() << ' ' << p1.y() << ' ' << p1.z() << ' '
|
||||
<< p2.x() << ' ' << p2.y() << ' ' << p2.z() << ' '
|
||||
// region as colour
|
||||
<< "0x" << hex << patchI << dec << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::fileFormats::TRIfileFormat::TRIfileFormat()
|
||||
:
|
||||
Foam::keyedSurface()
|
||||
{}
|
||||
|
||||
|
||||
Foam::fileFormats::TRIfileFormat::TRIfileFormat
|
||||
(
|
||||
const fileName& fName,
|
||||
const bool triangulate
|
||||
)
|
||||
:
|
||||
Foam::keyedSurface()
|
||||
{
|
||||
IFstream is(fName);
|
||||
|
||||
if (!is.good())
|
||||
{
|
||||
FatalErrorIn("fileFormats::TRIfileFormat(const fileName&)")
|
||||
<< "Cannot read file " << fName
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
// uses similar structure as STL, just some points
|
||||
DynamicList<point> pointLst;
|
||||
DynamicList<label> facetsLst;
|
||||
HashTable<label> groupToPatch;
|
||||
|
||||
// leave faces that didn't have a group in 0
|
||||
label nUngrouped = 0;
|
||||
label groupID = 0;
|
||||
label maxGroupID = -1;
|
||||
|
||||
while (is.good())
|
||||
{
|
||||
string line = getLineNoComment(is);
|
||||
|
||||
// handle continuations ?
|
||||
// if (line[line.size()-1] == '\\')
|
||||
// {
|
||||
// line.substr(0, line.size()-1);
|
||||
// line += getLineNoComment(is);
|
||||
// }
|
||||
|
||||
IStringStream lineStream(line);
|
||||
|
||||
point p
|
||||
(
|
||||
readScalar(lineStream),
|
||||
readScalar(lineStream),
|
||||
readScalar(lineStream)
|
||||
);
|
||||
|
||||
if (!lineStream) break;
|
||||
|
||||
pointLst.append(p);
|
||||
pointLst.append
|
||||
(
|
||||
point
|
||||
(
|
||||
readScalar(lineStream),
|
||||
readScalar(lineStream),
|
||||
readScalar(lineStream)
|
||||
)
|
||||
);
|
||||
pointLst.append
|
||||
(
|
||||
point
|
||||
(
|
||||
readScalar(lineStream),
|
||||
readScalar(lineStream),
|
||||
readScalar(lineStream)
|
||||
)
|
||||
);
|
||||
|
||||
// Region/colour in .tri file starts with 0x. Skip.
|
||||
// ie, instead of having 0xFF, skip 0 and leave xFF to
|
||||
// get read as a word and name it "patchFF"
|
||||
|
||||
char zero;
|
||||
lineStream >> zero;
|
||||
|
||||
word rawName(lineStream);
|
||||
word groupName("patch" + rawName(1, rawName.size()-1));
|
||||
|
||||
HashTable<label>::const_iterator findGroup =
|
||||
groupToPatch.find(groupName);
|
||||
|
||||
if (findGroup != groupToPatch.end())
|
||||
{
|
||||
groupID = findGroup();
|
||||
}
|
||||
else
|
||||
{
|
||||
// special treatment if any initial faces were not in a group
|
||||
if (maxGroupID == -1 && facetsLst.size())
|
||||
{
|
||||
groupToPatch.insert("patch0", 0);
|
||||
nUngrouped = facetsLst.size();
|
||||
maxGroupID = 0;
|
||||
}
|
||||
groupID = ++maxGroupID;
|
||||
groupToPatch.insert(groupName, groupID);
|
||||
}
|
||||
|
||||
facetsLst.append(groupID);
|
||||
}
|
||||
|
||||
// transfer to normal list
|
||||
points().transfer(pointLst);
|
||||
|
||||
// make our triangles
|
||||
facetsLst.shrink();
|
||||
List<keyedFace> faceLst(facetsLst.size());
|
||||
|
||||
face fTri(3);
|
||||
label ptI = 0;
|
||||
forAll(facetsLst, faceI)
|
||||
{
|
||||
fTri[0] = ptI++;
|
||||
fTri[1] = ptI++;
|
||||
fTri[2] = ptI++;
|
||||
|
||||
faceLst[faceI] = keyedFace(fTri, facetsLst[faceI]);
|
||||
}
|
||||
facetsLst.clearStorage();
|
||||
|
||||
faces().transfer(faceLst);
|
||||
setPatches(groupToPatch);
|
||||
stitchFaces(SMALL);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::fileFormats::TRIfileFormat::write
|
||||
(
|
||||
Ostream& os,
|
||||
const keyedSurface& surf
|
||||
)
|
||||
{
|
||||
const pointField& pointLst = surf.points();
|
||||
const List<keyedFace>& faceLst = surf.faces();
|
||||
|
||||
labelList faceMap;
|
||||
List<surfacePatch> patchLst = surf.sortedRegions(faceMap);
|
||||
|
||||
label faceIndex = 0;
|
||||
forAll(patchLst, patchI)
|
||||
{
|
||||
forAll(patchLst[patchI], patchFaceI)
|
||||
{
|
||||
const face& f = faceLst[faceMap[faceIndex++]];
|
||||
writeShell(os, pointLst, f, patchI);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::fileFormats::TRIfileFormat::write
|
||||
(
|
||||
Ostream& os,
|
||||
const meshedSurface& surf
|
||||
)
|
||||
{
|
||||
const pointField& pointLst = surf.points();
|
||||
const List<face>& faceLst = surf.faces();
|
||||
const List<surfacePatch>& patchLst = surf.patches();
|
||||
|
||||
label faceIndex = 0;
|
||||
forAll(patchLst, patchI)
|
||||
{
|
||||
forAll(patchLst[patchI], patchFaceI)
|
||||
{
|
||||
const face& f = faceLst[faceIndex++];
|
||||
writeShell(os, pointLst, f, patchI);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
|
||||
|
||||
// ************************************************************************* //
|
||||
145
src/surfMesh/keyedSurface/fileFormats/tri/TRIfileFormat.H
Normal file
145
src/surfMesh/keyedSurface/fileFormats/tri/TRIfileFormat.H
Normal file
@ -0,0 +1,145 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
Class
|
||||
Foam::fileFormats::TRIfileFormat
|
||||
|
||||
Description
|
||||
Provide a means of reading/writing .tri format.
|
||||
|
||||
SourceFiles
|
||||
TRIfileFormat.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef TRIfileFormat_H
|
||||
#define TRIfileFormat_H
|
||||
|
||||
#include "Ostream.H"
|
||||
#include "OFstream.H"
|
||||
#include "keyedSurface.H"
|
||||
#include "meshedSurface.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace fileFormats
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class TRIfileFormat Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class TRIfileFormat
|
||||
:
|
||||
public keyedSurface
|
||||
{
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
TRIfileFormat(const TRIfileFormat&);
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const TRIfileFormat&);
|
||||
|
||||
static inline void writeShell
|
||||
(
|
||||
Ostream&,
|
||||
const pointField&,
|
||||
const face&,
|
||||
const label patchI
|
||||
);
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct null
|
||||
TRIfileFormat();
|
||||
|
||||
//- Construct from file name
|
||||
TRIfileFormat(const fileName&, const bool triangulate=true);
|
||||
|
||||
// Selectors
|
||||
|
||||
//- Read file and return keyedSurface
|
||||
static autoPtr<keyedSurface> New
|
||||
(
|
||||
const fileName& fName,
|
||||
const bool triangulate=true
|
||||
)
|
||||
{
|
||||
return autoPtr<keyedSurface>
|
||||
(
|
||||
new TRIfileFormat(fName, triangulate)
|
||||
);
|
||||
}
|
||||
|
||||
// Destructor
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Write
|
||||
|
||||
//- Write keyedSurface
|
||||
static void write(Ostream&, const keyedSurface&);
|
||||
|
||||
//- Write keyedSurface
|
||||
static void write(const fileName& fName, const keyedSurface& surf)
|
||||
{
|
||||
write(OFstream(fName)(), surf);
|
||||
}
|
||||
|
||||
//- Write meshedSurface
|
||||
static void write(Ostream&, const meshedSurface&);
|
||||
|
||||
//- Write meshedSurface
|
||||
static void write(const fileName& fName, const meshedSurface& surf)
|
||||
{
|
||||
write(OFstream(fName)(), surf);
|
||||
}
|
||||
|
||||
//- Write object
|
||||
virtual void write(Ostream& os) const
|
||||
{
|
||||
write(os, *this);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace fileFormats
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
233
src/surfMesh/keyedSurface/fileFormats/vtk/VTKfileFormat.C
Normal file
233
src/surfMesh/keyedSurface/fileFormats/vtk/VTKfileFormat.C
Normal file
@ -0,0 +1,233 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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 "VTKfileFormat.H"
|
||||
#include "clock.H"
|
||||
#include "IFstream.H"
|
||||
#include "IStringStream.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
#include "addToMemberFunctionSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace fileFormats
|
||||
{
|
||||
|
||||
addNamedToMemberFunctionSelectionTable
|
||||
(
|
||||
keyedSurface,
|
||||
VTKfileFormat,
|
||||
write,
|
||||
fileExtension,
|
||||
vtk
|
||||
);
|
||||
|
||||
addNamedToMemberFunctionSelectionTable
|
||||
(
|
||||
meshedSurface,
|
||||
VTKfileFormat,
|
||||
write,
|
||||
fileExtension,
|
||||
vtk
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::fileFormats::VTKfileFormat::writeHead
|
||||
(
|
||||
Ostream& os,
|
||||
const pointField& pointLst
|
||||
)
|
||||
{
|
||||
// Write header
|
||||
os << "# vtk DataFile Version 2.0" << nl
|
||||
<< "surface written " << clock::dateTime().c_str() << nl
|
||||
<< "ASCII" << nl
|
||||
<< nl
|
||||
<< "DATASET POLYDATA" << nl;
|
||||
|
||||
// Write vertex coords
|
||||
os << "POINTS " << pointLst.size() << " float" << nl;
|
||||
forAll(pointLst, ptI)
|
||||
{
|
||||
os << pointLst[ptI].x() << ' '
|
||||
<< pointLst[ptI].y() << ' '
|
||||
<< pointLst[ptI].z() << nl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::fileFormats::VTKfileFormat::writeTail
|
||||
(
|
||||
Ostream& os,
|
||||
const List<surfacePatch>& patchLst
|
||||
)
|
||||
{
|
||||
label nFaces = 0;
|
||||
forAll(patchLst, patchI)
|
||||
{
|
||||
nFaces += patchLst[patchI].size();
|
||||
}
|
||||
|
||||
// Print region numbers
|
||||
os << nl
|
||||
<< "CELL_DATA " << nFaces << nl
|
||||
<< "FIELD attributes 1" << nl
|
||||
<< "region 1 " << nFaces << " float" << nl;
|
||||
|
||||
|
||||
forAll(patchLst, patchI)
|
||||
{
|
||||
forAll(patchLst[patchI], patchFaceI)
|
||||
{
|
||||
if (patchFaceI)
|
||||
{
|
||||
if ((patchFaceI % 20) == 0)
|
||||
{
|
||||
os << nl;
|
||||
}
|
||||
else
|
||||
{
|
||||
os << ' ';
|
||||
}
|
||||
}
|
||||
os << patchI + 1;
|
||||
}
|
||||
os << nl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::fileFormats::VTKfileFormat::VTKfileFormat()
|
||||
:
|
||||
Foam::keyedSurface()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::fileFormats::VTKfileFormat::write
|
||||
(
|
||||
Ostream& os,
|
||||
const keyedSurface& surf
|
||||
)
|
||||
{
|
||||
const pointField& pointLst = surf.points();
|
||||
const List<keyedFace>& faceLst = surf.faces();
|
||||
|
||||
labelList faceMap;
|
||||
List<surfacePatch> patchLst = surf.sortedRegions(faceMap);
|
||||
|
||||
writeHead(os, pointLst);
|
||||
|
||||
label nNodes = 0;
|
||||
forAll(faceLst, faceI)
|
||||
{
|
||||
nNodes += faceLst[faceI].size();
|
||||
}
|
||||
|
||||
os << nl
|
||||
<< "POLYGONS " << faceLst.size() << ' '
|
||||
<< faceLst.size() + nNodes << nl;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
void Foam::fileFormats::VTKfileFormat::write
|
||||
(
|
||||
Ostream& os,
|
||||
const meshedSurface& surf
|
||||
)
|
||||
{
|
||||
const pointField& pointLst = surf.points();
|
||||
const List<face>& faceLst = surf.faces();
|
||||
const List<surfacePatch>& patchLst = surf.patches();
|
||||
|
||||
writeHead(os, pointLst);
|
||||
|
||||
label nNodes = 0;
|
||||
forAll(faceLst, faceI)
|
||||
{
|
||||
nNodes += faceLst[faceI].size();
|
||||
}
|
||||
|
||||
os << nl
|
||||
<< "POLYGONS " << faceLst.size() << ' '
|
||||
<< faceLst.size() + nNodes << nl;
|
||||
|
||||
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 << ' ' << nl;
|
||||
}
|
||||
}
|
||||
|
||||
// Print region numbers
|
||||
writeTail(os, patchLst);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
|
||||
|
||||
// ************************************************************************* //
|
||||
124
src/surfMesh/keyedSurface/fileFormats/vtk/VTKfileFormat.H
Normal file
124
src/surfMesh/keyedSurface/fileFormats/vtk/VTKfileFormat.H
Normal file
@ -0,0 +1,124 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
Class
|
||||
Foam::fileFormats::VTKfileFormat
|
||||
|
||||
Description
|
||||
Provide a means of writing VTK legacy format.
|
||||
|
||||
SourceFiles
|
||||
VTKfileFormat.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef VTKfileFormat_H
|
||||
#define VTKfileFormat_H
|
||||
|
||||
#include "Ostream.H"
|
||||
#include "OFstream.H"
|
||||
#include "keyedSurface.H"
|
||||
#include "meshedSurface.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace fileFormats
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class VTKfileFormat Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class VTKfileFormat
|
||||
:
|
||||
public keyedSurface
|
||||
{
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
VTKfileFormat(const VTKfileFormat&);
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const VTKfileFormat&);
|
||||
|
||||
static void writeHead(Ostream&, const pointField&);
|
||||
static void writeTail(Ostream&, const List<surfacePatch>&);
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct null
|
||||
VTKfileFormat();
|
||||
|
||||
// Selectors
|
||||
|
||||
// Destructor
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Write
|
||||
|
||||
//- Write keyedSurface
|
||||
static void write(Ostream&, const keyedSurface&);
|
||||
|
||||
//- Write keyedSurface
|
||||
static void write(const fileName& fName, const keyedSurface& surf)
|
||||
{
|
||||
write(OFstream(fName)(), surf);
|
||||
}
|
||||
|
||||
//- Write meshedSurface
|
||||
static void write(Ostream&, const meshedSurface&);
|
||||
|
||||
//- Write meshedSurface
|
||||
static void write(const fileName& fName, const meshedSurface& surf)
|
||||
{
|
||||
write(OFstream(fName)(), surf);
|
||||
}
|
||||
|
||||
//- Write object
|
||||
virtual void write(Ostream& os) const
|
||||
{
|
||||
write(os, *this);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace fileFormats
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
1112
src/surfMesh/keyedSurface/keyedSurface.C
Normal file
1112
src/surfMesh/keyedSurface/keyedSurface.C
Normal file
File diff suppressed because it is too large
Load Diff
461
src/surfMesh/keyedSurface/keyedSurface.H
Normal file
461
src/surfMesh/keyedSurface/keyedSurface.H
Normal file
@ -0,0 +1,461 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
Class
|
||||
Foam::keyedSurface
|
||||
|
||||
Description
|
||||
A surface geometry mesh, in which the patch information is conveyed by
|
||||
the 'key' attached to each face.
|
||||
|
||||
This form of surface description is particularly useful for reading in
|
||||
surface meshes from third-party formats (eg, obj, stl, gts, etc.). It
|
||||
can also be particularly useful for situations in which the surface
|
||||
many be adjusted in an arbitrary manner without worrying about needed
|
||||
to adjust the patch information (eg, surface refinement).
|
||||
|
||||
See Also
|
||||
The Foam::meshedSurface - which is organized as a surface mesh, but
|
||||
with independent patch information.
|
||||
|
||||
SourceFiles
|
||||
keyedSurface.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef keyedSurface_H
|
||||
#define keyedSurface_H
|
||||
|
||||
#include "pointField.H"
|
||||
#include "PrimitivePatchExtra.H"
|
||||
#include "boolList.H"
|
||||
#include "geometricSurfacePatchList.H"
|
||||
#include "surfacePatchList.H"
|
||||
#include "face.H"
|
||||
#include "Keyed.H"
|
||||
#include "xfer.H"
|
||||
#include "runTimeSelectionTables.H"
|
||||
#include "memberFunctionSelectionTables.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
class Time;
|
||||
class IFstream;
|
||||
class meshedSurface;
|
||||
class polyBoundaryMesh;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class keyedSurface Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class keyedSurface
|
||||
:
|
||||
public PrimitivePatchExtra<Keyed<face>, ::Foam::List, pointField, point>
|
||||
{
|
||||
friend class meshedSurface;
|
||||
|
||||
protected:
|
||||
|
||||
// Protected Member Data
|
||||
|
||||
//- Typedef if this type has not already been defined
|
||||
typedef Keyed<face> keyedFace;
|
||||
|
||||
//- Typedef for similar code in keyedSurface and meshedSurface
|
||||
typedef keyedFace FaceType;
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Data
|
||||
|
||||
// Private typedefs
|
||||
|
||||
typedef PrimitivePatchExtra
|
||||
<
|
||||
FaceType,
|
||||
::Foam::List,
|
||||
pointField,
|
||||
point
|
||||
>
|
||||
MeshStorage;
|
||||
|
||||
// Private data
|
||||
|
||||
//- Patch information (face ordering nFaces/startFace only used
|
||||
// during reading and writing)
|
||||
geometricSurfacePatchList geoPatches_;
|
||||
|
||||
// Private member functions
|
||||
|
||||
//- Read in Foam format
|
||||
bool read(Istream&);
|
||||
|
||||
//- Generic read routine. Chooses reader based on extension.
|
||||
//? bool read(const fileName&, const word& ext);
|
||||
|
||||
protected:
|
||||
|
||||
// Static protected functions
|
||||
|
||||
//- Read non-comment line
|
||||
static string getLineNoComment(IFstream&);
|
||||
|
||||
// Protected Member functions
|
||||
|
||||
//- 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);
|
||||
|
||||
//- Join the faces by removing duplicate points.
|
||||
// Returns true if any points merged
|
||||
bool stitchFaces(const scalar tol=SMALL, const bool verbose=false);
|
||||
|
||||
|
||||
//- Return non-const access to global points
|
||||
pointField& points()
|
||||
{
|
||||
return const_cast<pointField&>(MeshStorage::points());
|
||||
}
|
||||
|
||||
//- Return non-const access to the faces
|
||||
List<FaceType>& faces()
|
||||
{
|
||||
return static_cast<List<FaceType> &>(*this);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
ClassName("keyedSurface");
|
||||
|
||||
//- Return the default geometric patch type (usually "empty")
|
||||
static word defaultGeometricType;
|
||||
|
||||
// Static
|
||||
|
||||
//- Name of keyedSurface directory to use.
|
||||
static fileName triSurfInstance(const Time&);
|
||||
|
||||
//- Name of keyedSurface directory to use.
|
||||
static fileName triSurfName(const Time&);
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct null
|
||||
keyedSurface();
|
||||
|
||||
//- Construct from components (points, labelled faces, patches).
|
||||
keyedSurface
|
||||
(
|
||||
const pointField&,
|
||||
const List<keyedFace>&,
|
||||
const geometricSurfacePatchList&
|
||||
);
|
||||
|
||||
//- Construct by transferring components
|
||||
// (points, labelled faces, patches.
|
||||
keyedSurface
|
||||
(
|
||||
const xfer<pointField>&,
|
||||
const xfer<List<keyedFace> >&,
|
||||
const xfer<geometricSurfacePatchList>&
|
||||
);
|
||||
|
||||
//- Construct by transferring points and labelled faces
|
||||
// With region names per map or set to default.
|
||||
keyedSurface
|
||||
(
|
||||
const xfer<pointField>&,
|
||||
const xfer<List<keyedFace> >&,
|
||||
const Map<word>& regionNames = Map<word>::null()
|
||||
);
|
||||
|
||||
//- Construct by transferring points and labelled faces
|
||||
// with patch-names from hash
|
||||
keyedSurface
|
||||
(
|
||||
const xfer<pointField>&,
|
||||
const xfer<List<keyedFace> >&,
|
||||
const HashTable<label>& labelToRegion
|
||||
);
|
||||
|
||||
//- Construct by transferring points, copying unlabelled faces.
|
||||
// Set single default patch.
|
||||
keyedSurface
|
||||
(
|
||||
const xfer<pointField>&,
|
||||
const List<face>&
|
||||
);
|
||||
|
||||
//- Construct from a boundary mesh with local points/faces
|
||||
keyedSurface
|
||||
(
|
||||
const polyBoundaryMesh&,
|
||||
const bool globalPoints=false
|
||||
);
|
||||
|
||||
//- Construct from a meshedSurface
|
||||
keyedSurface(const meshedSurface&);
|
||||
|
||||
//- Construct from file name (uses extension to determine type)
|
||||
keyedSurface
|
||||
(
|
||||
const fileName&,
|
||||
const bool triangulate=false
|
||||
);
|
||||
|
||||
//- Construct from file name (uses extension to determine type)
|
||||
keyedSurface
|
||||
(
|
||||
const fileName&,
|
||||
const word&,
|
||||
const bool triangulate=false
|
||||
);
|
||||
|
||||
//- Construct from Istream
|
||||
keyedSurface(Istream&);
|
||||
|
||||
//- Construct from objectRegistry
|
||||
keyedSurface(const Time&);
|
||||
|
||||
//- Construct as copy
|
||||
keyedSurface(const keyedSurface&);
|
||||
|
||||
//- Construct by transferring the contents from a keyedSurface
|
||||
keyedSurface(const xfer<keyedSurface>&);
|
||||
|
||||
//- Construct by transferring the contents from a meshedSurface
|
||||
keyedSurface(const xfer<meshedSurface>&);
|
||||
|
||||
|
||||
// Declare run-time constructor selection table
|
||||
|
||||
declareRunTimeSelectionTable
|
||||
(
|
||||
autoPtr,
|
||||
keyedSurface,
|
||||
fileExtension,
|
||||
(
|
||||
const fileName& fName,
|
||||
const bool triangulate
|
||||
),
|
||||
(fName, triangulate)
|
||||
);
|
||||
|
||||
// Selectors
|
||||
|
||||
//- Select constructed from filename (implicit extension)
|
||||
static autoPtr<keyedSurface> New
|
||||
(
|
||||
const fileName& fName,
|
||||
const bool triangulate=false
|
||||
);
|
||||
|
||||
//- Select constructed from filename (explicit extension)
|
||||
static autoPtr<keyedSurface> New
|
||||
(
|
||||
const fileName& fName,
|
||||
const word& ext,
|
||||
const bool triangulate=false
|
||||
);
|
||||
|
||||
// Destructor
|
||||
|
||||
~keyedSurface();
|
||||
|
||||
|
||||
// Member Function Selectors
|
||||
|
||||
declareMemberFunctionSelectionTable
|
||||
(
|
||||
void,
|
||||
keyedSurface,
|
||||
write,
|
||||
fileExtension,
|
||||
(
|
||||
const fileName& fName,
|
||||
const keyedSurface& surf
|
||||
),
|
||||
(fName, surf)
|
||||
);
|
||||
|
||||
//- Write to file
|
||||
static void write(const fileName&, const keyedSurface&);
|
||||
|
||||
//- Can we read this file format?
|
||||
static bool canRead(const word& ext, const bool verbose=false);
|
||||
|
||||
//- Can we write this file format?
|
||||
static bool canWrite(const word& ext, const bool verbose=false);
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Access
|
||||
|
||||
//- Return the number of points
|
||||
label nPoints() const
|
||||
{
|
||||
return points().size();
|
||||
}
|
||||
|
||||
//- Return the number of faces
|
||||
label nFaces() const
|
||||
{
|
||||
return faces().size();
|
||||
}
|
||||
|
||||
//- The surface size is the number of faces
|
||||
label size() const
|
||||
{
|
||||
return nFaces();
|
||||
}
|
||||
|
||||
//- Return const access to global points
|
||||
const pointField& points() const
|
||||
{
|
||||
return MeshStorage::points();
|
||||
}
|
||||
|
||||
//- Return const access to the faces
|
||||
const List<FaceType>& faces() const
|
||||
{
|
||||
return static_cast<const List<FaceType> &>(*this);
|
||||
}
|
||||
|
||||
const geometricSurfacePatchList& geoPatches() const
|
||||
{
|
||||
return geoPatches_;
|
||||
}
|
||||
|
||||
geometricSurfacePatchList& geoPatches()
|
||||
{
|
||||
return geoPatches_;
|
||||
}
|
||||
|
||||
//- Determine the sort order from the face regions.
|
||||
// Returns patch list and sets faceMap to index within faceLst
|
||||
static surfacePatchList sortedRegions
|
||||
(
|
||||
const List<keyedFace>& faceLst,
|
||||
const Map<word>& patchNames,
|
||||
labelList& faceMap
|
||||
);
|
||||
|
||||
//- Determine the sort order from the region list.
|
||||
// Returns patch list and sets faceMap to indices within faceLst
|
||||
static surfacePatchList sortedRegions
|
||||
(
|
||||
const List<label>& regionLst,
|
||||
const Map<word>& patchNames,
|
||||
labelList& faceMap
|
||||
);
|
||||
|
||||
//- Sort faces according to region.
|
||||
// Returns patch list and sets faceMap to index within faces()
|
||||
surfacePatchList sortedRegions(labelList& faceMap) const;
|
||||
|
||||
// Edit
|
||||
|
||||
//- Move points
|
||||
virtual void movePoints(const pointField&);
|
||||
|
||||
//- Scale points. A non-positive factor is ignored
|
||||
virtual void scalePoints(const scalar&);
|
||||
|
||||
void checkFaces(const bool verbose);
|
||||
|
||||
//- Remove invalid faces
|
||||
void cleanup(const bool verbose);
|
||||
|
||||
//- Return new surface. Returns pointMap, faceMap from
|
||||
// subsetMeshMap
|
||||
keyedSurface subsetMesh
|
||||
(
|
||||
const boolList& include,
|
||||
labelList& pointMap,
|
||||
labelList& faceMap
|
||||
) const;
|
||||
|
||||
//- Transfer the contents of the argument and annull the argument
|
||||
void transfer(keyedSurface&);
|
||||
|
||||
//- Transfer the contents of the argument and annull the argument
|
||||
void transfer(meshedSurface&);
|
||||
|
||||
// Write
|
||||
|
||||
//- Write to Ostream in simple FOAM format
|
||||
virtual void write(Ostream&) const;
|
||||
|
||||
//- Generic write routine. Chooses writer based on extension.
|
||||
virtual void write(const fileName& fName) const
|
||||
{
|
||||
write(fName, *this);
|
||||
}
|
||||
|
||||
//- Write to database
|
||||
void write(const Time&) const;
|
||||
|
||||
//- Write some statistics
|
||||
void writeStats(Ostream&) const;
|
||||
|
||||
// Friend Functions
|
||||
|
||||
// Member operators
|
||||
|
||||
void operator=(const keyedSurface&);
|
||||
|
||||
|
||||
// Ostream Operator
|
||||
|
||||
friend Ostream& operator<<(Ostream&, const keyedSurface&);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
235
src/surfMesh/keyedSurface/keyedSurfaceCleanup.C
Normal file
235
src/surfMesh/keyedSurface/keyedSurfaceCleanup.C
Normal file
@ -0,0 +1,235 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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 "keyedSurface.H"
|
||||
#include "mergePoints.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
// Remove badly degenerate faces, double faces.
|
||||
void Foam::keyedSurface::cleanup(const bool verbose)
|
||||
{
|
||||
// merge points (already done for STL, TRI)
|
||||
stitchFaces(SMALL, verbose);
|
||||
|
||||
checkFaces(verbose);
|
||||
checkEdges(verbose);
|
||||
}
|
||||
|
||||
|
||||
bool Foam::keyedSurface::stitchFaces(const scalar tol, const bool verbose)
|
||||
{
|
||||
pointField& pointLst = points();
|
||||
|
||||
// Merge points
|
||||
labelList pointMap(pointLst.size());
|
||||
pointField newPoints(pointLst.size());
|
||||
|
||||
bool hasMerged = mergePoints(pointLst, tol, verbose, pointMap, newPoints);
|
||||
|
||||
if (!hasMerged)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
Info<< "keyedSurface::stitchFaces : Renumbering all faces"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
// Set the coordinates to the merged ones
|
||||
pointLst.transfer(newPoints);
|
||||
|
||||
List<FaceType>& faceLst = faces();
|
||||
|
||||
// Reset the point labels to the unique points array
|
||||
label newFaceI = 0;
|
||||
forAll (faceLst, faceI)
|
||||
{
|
||||
FaceType& f = faceLst[faceI];
|
||||
forAll (f, fp)
|
||||
{
|
||||
f[fp] = pointMap[f[fp]];
|
||||
}
|
||||
|
||||
if (f.collapse() >= 3)
|
||||
{
|
||||
if (newFaceI != faceI)
|
||||
{
|
||||
faceLst[newFaceI] = f;
|
||||
}
|
||||
newFaceI++;
|
||||
}
|
||||
else if (verbose)
|
||||
{
|
||||
Pout<< "keyedSurface::stitchFaces : "
|
||||
<< "Removing collapsed face " << faceI << endl
|
||||
<< " vertices :" << f << endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (newFaceI != faceLst.size())
|
||||
{
|
||||
if (verbose)
|
||||
{
|
||||
Pout<< "keyedSurface::stitchFaces : "
|
||||
<< "Removed " << faceLst.size() - newFaceI
|
||||
<< " faces" << endl;
|
||||
}
|
||||
faceLst.setSize(newFaceI);
|
||||
}
|
||||
|
||||
// Merging points might have changed geometric factors
|
||||
clearOut();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Remove badly degenerate faces and double faces.
|
||||
void Foam::keyedSurface::checkFaces(const bool verbose)
|
||||
{
|
||||
// Simple check on indices ok.
|
||||
const label maxPointI = points().size() - 1;
|
||||
|
||||
List<FaceType>& faceLst = faces();
|
||||
|
||||
// Phase 0: detect badly labelled faces
|
||||
forAll (faceLst, faceI)
|
||||
{
|
||||
const FaceType& f = faceLst[faceI];
|
||||
|
||||
forAll (f, fp)
|
||||
{
|
||||
if (f[fp] < 0 || f[fp] > maxPointI)
|
||||
{
|
||||
FatalErrorIn("keyedSurface::checkFaces(bool)")
|
||||
<< "face " << f
|
||||
<< " uses point indices outside point range 0.."
|
||||
<< maxPointI
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Two phase process
|
||||
// 1. mark invalid faces
|
||||
// 2. pack
|
||||
// Done to keep numbering constant in phase 1
|
||||
const labelListList& fFaces = faceFaces();
|
||||
label newFaceI = 0;
|
||||
|
||||
forAll (faceLst, faceI)
|
||||
{
|
||||
FaceType& f = faceLst[faceI];
|
||||
|
||||
// avoid degenerate faces
|
||||
if (f.collapse() >= 3)
|
||||
{
|
||||
// duplicate face check
|
||||
bool okay = true;
|
||||
const labelList& neighbours = fFaces[faceI];
|
||||
|
||||
// Check if faceNeighbours use same points as this face.
|
||||
// Note: discards normal information - sides of baffle are merged.
|
||||
forAll (neighbours, neighI)
|
||||
{
|
||||
if (neighbours[neighI] <= faceI)
|
||||
{
|
||||
// lower numbered faces already checked
|
||||
continue;
|
||||
}
|
||||
|
||||
const face& nei = faceLst[neighbours[neighI]];
|
||||
|
||||
if (f == nei)
|
||||
{
|
||||
okay = false;
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
WarningIn
|
||||
(
|
||||
"keyedSurface::checkFaces(bool verbose)"
|
||||
) << "faces share the same vertices:\n"
|
||||
<< " face 1 :" << faceI << endl;
|
||||
// printFace(Warning, " ", f, points());
|
||||
|
||||
Warning
|
||||
<< endl
|
||||
<< " face 2 :"
|
||||
<< neighbours[neighI] << endl;
|
||||
// printFace(Warning, " ", nei, points());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (okay)
|
||||
{
|
||||
if (newFaceI != faceI)
|
||||
{
|
||||
faceLst[newFaceI] = f;
|
||||
}
|
||||
newFaceI++;
|
||||
}
|
||||
}
|
||||
else if (verbose)
|
||||
{
|
||||
WarningIn
|
||||
(
|
||||
"keyedSurface::checkFaces(bool verbose)"
|
||||
) << "face " << faceI
|
||||
<< " does not at least three unique vertices:\n";
|
||||
// printFace(Warning, " ", f, points());
|
||||
}
|
||||
}
|
||||
|
||||
if (newFaceI < faceLst.size())
|
||||
{
|
||||
if (verbose)
|
||||
{
|
||||
WarningIn
|
||||
(
|
||||
"keyedSurface::checkFaces(bool verbose)"
|
||||
) << "Removed " << faceLst.size() - newFaceI
|
||||
<< " illegal faces." << endl;
|
||||
}
|
||||
faceLst.setSize(newFaceI);
|
||||
|
||||
// Topology can change because of renumbering
|
||||
clearOut();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// ************************************************************************* //
|
||||
95
src/surfMesh/keyedSurface/newKeyedSurface.C
Normal file
95
src/surfMesh/keyedSurface/newKeyedSurface.C
Normal file
@ -0,0 +1,95 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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 "keyedSurface.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
Foam::autoPtr<Foam::keyedSurface>
|
||||
Foam::keyedSurface::New
|
||||
(
|
||||
const fileName& fName,
|
||||
const word& ext,
|
||||
const bool triangulate
|
||||
)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "keyedSurface::New"
|
||||
"(const fileName&, const word&, const bool) : "
|
||||
"constructing keyedSurface"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
fileExtensionConstructorTable::iterator cstrIter =
|
||||
fileExtensionConstructorTablePtr_->find(ext);
|
||||
|
||||
if (cstrIter == fileExtensionConstructorTablePtr_->end())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"keyedSurface::New(const fileName&, const word&, const bool) : "
|
||||
"constructing keyedSurface"
|
||||
) << "Unknown file extension " << ext << nl << nl
|
||||
<< "Valid types are :" << nl
|
||||
<< fileExtensionConstructorTablePtr_->toc()
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
return autoPtr<keyedSurface>(cstrIter()(fName, triangulate));
|
||||
}
|
||||
|
||||
|
||||
Foam::autoPtr<Foam::keyedSurface>
|
||||
Foam::keyedSurface::New
|
||||
(
|
||||
const fileName& fName,
|
||||
const bool triangulate
|
||||
)
|
||||
{
|
||||
const word ext = fName.ext();
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "keyedSurface::New(const fileName&, const bool) : "
|
||||
"constructing keyedSurface"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// if (ext == "gz")
|
||||
// {
|
||||
// fileName unzipName = fName.lessExt();
|
||||
//
|
||||
// return New(unzipName, unzipName.ext(), ext);
|
||||
// }
|
||||
|
||||
return New(fName, ext, triangulate);
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
||||
988
src/surfMesh/meshedSurface/meshedSurface.C
Normal file
988
src/surfMesh/meshedSurface/meshedSurface.C
Normal file
@ -0,0 +1,988 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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 "keyedSurface.H"
|
||||
#include "demandDrivenData.H"
|
||||
#include "IFstream.H"
|
||||
#include "OFstream.H"
|
||||
#include "Time.H"
|
||||
#include "boundBox.H"
|
||||
#include "SortableList.H"
|
||||
#include "ListOps.H"
|
||||
#include "polyBoundaryMesh.H"
|
||||
#include "polyMesh.H"
|
||||
// #include "surfMesh.H"
|
||||
#include "primitivePatch.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
defineTypeNameAndDebug(meshedSurface, 0);
|
||||
|
||||
defineMemberFunctionSelectionTable
|
||||
(
|
||||
meshedSurface,
|
||||
write,
|
||||
fileExtension
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
Foam::word Foam::meshedSurface::defaultGeometricType("empty");
|
||||
// File extension for 'native' raw format
|
||||
//! @cond localscope
|
||||
const char * const nativeExt = "ftr";
|
||||
//! @endcond localscope
|
||||
|
||||
// * * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * //
|
||||
|
||||
Foam::fileName Foam::meshedSurface::triSurfInstance(const Time& d)
|
||||
{
|
||||
fileName foamName(d.caseName() + "." + nativeExt);
|
||||
|
||||
// Search back through the time directories list to find the time
|
||||
// closest to and lower than current time
|
||||
|
||||
instantList ts = d.times();
|
||||
label i;
|
||||
|
||||
for (i=ts.size()-1; i>=0; i--)
|
||||
{
|
||||
if (ts[i].value() <= d.timeOutputValue())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Noting that the current directory has already been searched
|
||||
// for mesh data, start searching from the previously stored time directory
|
||||
|
||||
if (i>=0)
|
||||
{
|
||||
for (label j=i; j>=0; j--)
|
||||
{
|
||||
if (file(d.path()/ts[j].name()/typeName/foamName))
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Pout<< " meshedSurface::triSurfInstance(const Time& d)"
|
||||
<< "reading " << foamName
|
||||
<< " from " << ts[j].name()/typeName
|
||||
<< endl;
|
||||
}
|
||||
|
||||
return ts[j].name();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< " meshedSurface::triSurfInstance(const Time& d)"
|
||||
<< "reading " << foamName
|
||||
<< " from constant/" << endl;
|
||||
}
|
||||
|
||||
return "constant";
|
||||
}
|
||||
|
||||
|
||||
Foam::fileName Foam::meshedSurface::triSurfName(const Time& d)
|
||||
{
|
||||
fileName foamName(d.caseName() + "." + nativeExt);
|
||||
|
||||
// Search back through the time directories list to find the time
|
||||
// closest to and lower than current time
|
||||
|
||||
instantList ts = d.times();
|
||||
label i;
|
||||
|
||||
for (i=ts.size()-1; i>=0; i--)
|
||||
{
|
||||
if (ts[i].value() <= d.timeOutputValue())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Noting that the current directory has already been searched
|
||||
// for mesh data, start searching from the previously stored time directory
|
||||
|
||||
if (i>=0)
|
||||
{
|
||||
for (label j=i; j>=0; j--)
|
||||
{
|
||||
fileName testName(d.path()/ts[j].name()/typeName/foamName);
|
||||
|
||||
if (file(testName))
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Pout<< " meshedSurface::triSurfName(const Time& d)"
|
||||
<< "reading " << foamName
|
||||
<< " from " << ts[j].name()/typeName
|
||||
<< endl;
|
||||
}
|
||||
|
||||
return testName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< " meshedSurface::triSurfName(const Time& d)"
|
||||
<< "reading " << foamName
|
||||
<< " from constant/" << endl;
|
||||
}
|
||||
|
||||
return d.path()/"constant"/typeName/foamName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::meshedSurface::onePatch()
|
||||
{
|
||||
// set single default patch
|
||||
patches_.setSize(1);
|
||||
patches_[0] = surfacePatch
|
||||
(
|
||||
defaultGeometricType,
|
||||
"patch0",
|
||||
size(), // patch size
|
||||
0, // patch start
|
||||
0 // patch index
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void Foam::meshedSurface::checkPatches()
|
||||
{
|
||||
// extra safety, ensure we have at some patches,
|
||||
// and they cover all the faces
|
||||
// fix start silently
|
||||
if (patches_.size() > 1)
|
||||
{
|
||||
label count = 0;
|
||||
forAll(patches_, patchI)
|
||||
{
|
||||
patches_[patchI].start() = count;
|
||||
count += patches_[patchI].size();
|
||||
}
|
||||
|
||||
if (count < size())
|
||||
{
|
||||
WarningIn
|
||||
(
|
||||
"meshedSurface::checkPatches()\n"
|
||||
)
|
||||
<< "more nFaces " << size()
|
||||
<< " than patches " << count
|
||||
<< " ... extending final patch"
|
||||
<< endl;
|
||||
|
||||
patches_[patches_.size()-1].size() += count - size();
|
||||
}
|
||||
else if (count > size())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"meshedSurface::checkPatches()\n"
|
||||
)
|
||||
<< "more patches " << count
|
||||
<< " than nFaces " << size()
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
else if (patches_.size() == 1)
|
||||
{
|
||||
// like onePatch, but preserve the name
|
||||
patches_[0].start() = 0;
|
||||
patches_[0].size() = size();
|
||||
if (!patches_[0].name().size())
|
||||
{
|
||||
patches_[0].name() = "patch0";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
onePatch();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Read triangles, points from Istream
|
||||
bool Foam::meshedSurface::read(Istream& is)
|
||||
{
|
||||
is >> patches_ >> points() >> faces();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Read from file in given format
|
||||
bool Foam::meshedSurface::read(const fileName& name, const word& ext)
|
||||
{
|
||||
if (ext == "gz")
|
||||
{
|
||||
fileName unzipName = name.lessExt();
|
||||
|
||||
return read(unzipName, unzipName.ext());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::meshedSurface::meshedSurface()
|
||||
:
|
||||
MeshStorage(List<FaceType>(), pointField()),
|
||||
patches_()
|
||||
{}
|
||||
|
||||
|
||||
Foam::meshedSurface::meshedSurface
|
||||
(
|
||||
const pointField& pointLst,
|
||||
const List<FaceType>& faceLst,
|
||||
const surfacePatchList& patchLst
|
||||
)
|
||||
:
|
||||
MeshStorage(faceLst, pointLst),
|
||||
patches_(patchLst)
|
||||
{}
|
||||
|
||||
|
||||
Foam::meshedSurface::meshedSurface
|
||||
(
|
||||
const xfer<pointField>& pointLst,
|
||||
const xfer<List<FaceType> >& faceLst,
|
||||
const xfer<surfacePatchList>& patchLst
|
||||
)
|
||||
:
|
||||
MeshStorage(List<FaceType>(), pointField()),
|
||||
patches_(patchLst)
|
||||
{
|
||||
faces().transfer(faceLst());
|
||||
points().transfer(pointLst());
|
||||
}
|
||||
|
||||
|
||||
Foam::meshedSurface::meshedSurface
|
||||
(
|
||||
const xfer<pointField>& pointLst,
|
||||
const xfer<List<FaceType> >& faceLst,
|
||||
const List<label>& patchSizes,
|
||||
const List<word>& patchNames,
|
||||
const List<word>& patchTypes
|
||||
)
|
||||
:
|
||||
MeshStorage(List<FaceType>(), pointField()),
|
||||
patches_()
|
||||
{
|
||||
points().transfer(pointLst());
|
||||
faces().transfer(faceLst());
|
||||
|
||||
surfacePatchList newPatches(patchSizes.size());
|
||||
|
||||
label start = 0;
|
||||
forAll(newPatches, patchI)
|
||||
{
|
||||
newPatches[patchI] = surfacePatch
|
||||
(
|
||||
defaultGeometricType,
|
||||
patchNames[patchI],
|
||||
patchSizes[patchI],
|
||||
start,
|
||||
patchI
|
||||
);
|
||||
|
||||
start += patchSizes[patchI];
|
||||
}
|
||||
|
||||
patches_.transfer(newPatches);
|
||||
}
|
||||
|
||||
|
||||
Foam::meshedSurface::meshedSurface
|
||||
(
|
||||
const xfer<pointField>& pointLst,
|
||||
const xfer<List<FaceType> >& faceLst,
|
||||
const List<label>& regionLst,
|
||||
const Map<word>& regionNames
|
||||
)
|
||||
:
|
||||
MeshStorage(List<FaceType>(), pointField()),
|
||||
patches_()
|
||||
{
|
||||
points().transfer(pointLst());
|
||||
faces().transfer(faceLst());
|
||||
|
||||
const List<FaceType>& unsortedFaces = faces();
|
||||
|
||||
if (regionLst.size() == 0)
|
||||
{
|
||||
onePatch();
|
||||
}
|
||||
else if (regionLst.size() != unsortedFaces.size())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"meshedSurface::meshedSurface(\n"
|
||||
"(\n"
|
||||
" const pointField&,\n"
|
||||
" const List<FaceType>&,\n"
|
||||
" const List<label>& regionLst,\n"
|
||||
" const Map<word>& regionNames\n"
|
||||
" )\n"
|
||||
)
|
||||
<< "size mismatch : regionLst.size() != faceLst.size()"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
else
|
||||
{
|
||||
labelList faceMap;
|
||||
surfacePatchList newPatches = keyedSurface::sortedRegions
|
||||
(
|
||||
regionLst,
|
||||
regionNames,
|
||||
faceMap
|
||||
);
|
||||
patches_.transfer(newPatches);
|
||||
|
||||
// this is somewhat like ListOps reorder and/or IndirectList
|
||||
List<FaceType> newFaces(unsortedFaces.size());
|
||||
forAll(newFaces, faceI)
|
||||
{
|
||||
newFaces[faceI] = unsortedFaces[faceMap[faceI]];
|
||||
}
|
||||
faceMap.clear();
|
||||
|
||||
faces().transfer(newFaces);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::meshedSurface::meshedSurface
|
||||
(
|
||||
const xfer<pointField>& pointLst,
|
||||
const xfer<List<FaceType> >& faceLst
|
||||
)
|
||||
:
|
||||
MeshStorage(List<FaceType>(), pointField()),
|
||||
patches_()
|
||||
{
|
||||
faces().transfer(faceLst());
|
||||
points().transfer(pointLst());
|
||||
|
||||
onePatch();
|
||||
}
|
||||
|
||||
|
||||
Foam::meshedSurface::meshedSurface
|
||||
(
|
||||
const xfer<pointField>& pointLst,
|
||||
const List<keyedFace>& faceLst,
|
||||
const Map<word>& regionNames
|
||||
)
|
||||
:
|
||||
MeshStorage(List<FaceType>(), pointField()),
|
||||
patches_()
|
||||
{
|
||||
points().transfer(pointLst());
|
||||
|
||||
labelList faceMap;
|
||||
surfacePatchList newPatches = keyedSurface::sortedRegions
|
||||
(
|
||||
faceLst,
|
||||
regionNames,
|
||||
faceMap
|
||||
);
|
||||
patches_.transfer(newPatches);
|
||||
|
||||
// this is somewhat like ListOps reorder and/or IndirectList
|
||||
List<FaceType> newFaces(faceLst.size());
|
||||
forAll(newFaces, faceI)
|
||||
{
|
||||
newFaces[faceI] = faceLst[faceMap[faceI]];
|
||||
}
|
||||
|
||||
faces().transfer(newFaces);
|
||||
}
|
||||
|
||||
|
||||
Foam::meshedSurface::meshedSurface
|
||||
(
|
||||
const xfer<pointField>& pointLst,
|
||||
const List<keyedFace>& faceLst,
|
||||
const HashTable<label>& nameToRegionMapping
|
||||
)
|
||||
:
|
||||
MeshStorage(List<FaceType>(), pointField()),
|
||||
patches_()
|
||||
{
|
||||
points().transfer(pointLst());
|
||||
|
||||
Map<word> regionNames;
|
||||
forAllConstIter(HashTable<label>, nameToRegionMapping, iter)
|
||||
{
|
||||
regionNames.insert(iter(), iter.key());
|
||||
}
|
||||
|
||||
|
||||
labelList faceMap;
|
||||
surfacePatchList newPatches = keyedSurface::sortedRegions
|
||||
(
|
||||
faceLst,
|
||||
regionNames,
|
||||
faceMap
|
||||
);
|
||||
patches_.transfer(newPatches);
|
||||
|
||||
List<FaceType> newFaces(faceLst.size());
|
||||
|
||||
// this is somewhat like ListOps reorder and/or IndirectList
|
||||
forAll(newFaces, faceI)
|
||||
{
|
||||
newFaces[faceI] = faceLst[faceMap[faceI]];
|
||||
}
|
||||
|
||||
faces().transfer(newFaces);
|
||||
}
|
||||
|
||||
|
||||
Foam::meshedSurface::meshedSurface
|
||||
(
|
||||
const polyBoundaryMesh& bMesh,
|
||||
const bool useGlobalPoints
|
||||
)
|
||||
:
|
||||
MeshStorage(List<FaceType>(), pointField()),
|
||||
patches_()
|
||||
{
|
||||
const polyMesh& mesh = bMesh.mesh();
|
||||
const polyPatchList& bPatches = bMesh;
|
||||
const label nIntFaces = mesh.nInternalFaces();
|
||||
|
||||
// Get patch for all of outside
|
||||
primitivePatch allBoundary
|
||||
(
|
||||
SubList<FaceType>
|
||||
(
|
||||
mesh.faces(),
|
||||
mesh.nFaces() - nIntFaces,
|
||||
nIntFaces
|
||||
),
|
||||
mesh.points()
|
||||
);
|
||||
|
||||
if (useGlobalPoints)
|
||||
{
|
||||
// copy in the global points and the global face addressing
|
||||
points() = mesh.points();
|
||||
faces() = allBoundary;
|
||||
}
|
||||
else
|
||||
{
|
||||
// copy in the local points and the local face addressing
|
||||
points() = allBoundary.localPoints();
|
||||
faces() = allBoundary.localFaces();
|
||||
}
|
||||
|
||||
// create patch list
|
||||
surfacePatchList newPatches(bPatches.size());
|
||||
|
||||
label startFaceI = 0;
|
||||
forAll(bPatches, patchI)
|
||||
{
|
||||
const polyPatch& p = bPatches[patchI];
|
||||
|
||||
newPatches[patchI] = surfacePatch
|
||||
(
|
||||
defaultGeometricType,
|
||||
p.name(),
|
||||
p.size(),
|
||||
startFaceI,
|
||||
patchI
|
||||
);
|
||||
|
||||
startFaceI += p.size();
|
||||
}
|
||||
|
||||
patches_.transfer(newPatches);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
// in preparation
|
||||
Foam::meshedSurface::meshedSurface
|
||||
(
|
||||
const surfMesh& sMesh
|
||||
)
|
||||
:
|
||||
MeshStorage(List<FaceType>(sMesh.faces()), sMesh.points()),
|
||||
patches_()
|
||||
{
|
||||
const surfPatchList& sPatches = sMesh.boundaryMesh();
|
||||
|
||||
// create patch list
|
||||
surfacePatchList newPatches(sPatches.size());
|
||||
|
||||
label startFaceI = 0;
|
||||
forAll(sPatches, patchI)
|
||||
{
|
||||
const surfPatch& p = sPatches[patchI];
|
||||
|
||||
newPatches[patchI] = surfacePatch
|
||||
(
|
||||
defaultGeometricType,
|
||||
p.name(),
|
||||
p.size(),
|
||||
startFaceI,
|
||||
patchI
|
||||
);
|
||||
|
||||
startFaceI += p.size();
|
||||
}
|
||||
|
||||
patches_.transfer(newPatches);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Foam::meshedSurface::meshedSurface
|
||||
(
|
||||
const keyedSurface& surf
|
||||
)
|
||||
:
|
||||
MeshStorage(List<FaceType>(), surf.points()),
|
||||
patches_()
|
||||
{
|
||||
labelList faceMap;
|
||||
surfacePatchList newPatches = surf.sortedRegions(faceMap);
|
||||
patches_.transfer(newPatches);
|
||||
|
||||
const List<keyedFace>& origFaces = surf.faces();
|
||||
List<FaceType> newFaces(origFaces.size());
|
||||
|
||||
// this is somewhat like ListOps reorder and/or IndirectList
|
||||
forAll(newFaces, faceI)
|
||||
{
|
||||
newFaces[faceI] = origFaces[faceMap[faceI]];
|
||||
}
|
||||
|
||||
faces().transfer(newFaces);
|
||||
}
|
||||
|
||||
|
||||
Foam::meshedSurface::meshedSurface
|
||||
(
|
||||
const fileName& fName,
|
||||
const word& ext,
|
||||
const bool triangulate
|
||||
)
|
||||
:
|
||||
MeshStorage(List<FaceType>(), pointField()),
|
||||
patches_()
|
||||
{
|
||||
// use selector mechanism
|
||||
autoPtr<meshedSurface> surfPtr = New(fName, ext, triangulate);
|
||||
transfer(surfPtr());
|
||||
}
|
||||
|
||||
Foam::meshedSurface::meshedSurface
|
||||
(
|
||||
const fileName& fName,
|
||||
const bool triangulate
|
||||
)
|
||||
:
|
||||
MeshStorage(List<FaceType>(), pointField()),
|
||||
patches_()
|
||||
{
|
||||
// use selector mechanism
|
||||
autoPtr<meshedSurface> surfPtr = New(fName, triangulate);
|
||||
transfer(surfPtr());
|
||||
}
|
||||
|
||||
|
||||
Foam::meshedSurface::meshedSurface(Istream& is)
|
||||
:
|
||||
MeshStorage(List<FaceType>(), pointField()),
|
||||
patches_()
|
||||
{
|
||||
read(is);
|
||||
// setDefaultPatches();
|
||||
}
|
||||
|
||||
|
||||
Foam::meshedSurface::meshedSurface(const Time& d)
|
||||
:
|
||||
MeshStorage(List<FaceType>(), pointField()),
|
||||
patches_()
|
||||
{
|
||||
read(IFstream(triSurfName(d))());
|
||||
// setDefaultPatches();
|
||||
}
|
||||
|
||||
|
||||
Foam::meshedSurface::meshedSurface(const meshedSurface& surf)
|
||||
:
|
||||
MeshStorage(surf.faces(), surf.points()),
|
||||
patches_(surf.patches_)
|
||||
{}
|
||||
|
||||
|
||||
Foam::meshedSurface::meshedSurface(const xfer<keyedSurface>& surf)
|
||||
:
|
||||
MeshStorage(List<FaceType>(), pointField()),
|
||||
patches_()
|
||||
{
|
||||
transfer(surf());
|
||||
}
|
||||
|
||||
|
||||
Foam::meshedSurface::meshedSurface(const xfer<meshedSurface>& surf)
|
||||
:
|
||||
MeshStorage(List<FaceType>(), pointField()),
|
||||
patches_()
|
||||
{
|
||||
transfer(surf());
|
||||
}
|
||||
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::meshedSurface::~meshedSurface()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
//- Move points
|
||||
void Foam::meshedSurface::movePoints(const pointField& newPoints)
|
||||
{
|
||||
// Remove all geometry dependent data
|
||||
clearTopology();
|
||||
|
||||
// Adapt for new point position
|
||||
MeshStorage::movePoints(newPoints);
|
||||
|
||||
// Copy new points
|
||||
points() = newPoints;
|
||||
}
|
||||
|
||||
//- scale points
|
||||
void Foam::meshedSurface::scalePoints(const scalar& scaleFactor)
|
||||
{
|
||||
// avoid bad scaling
|
||||
if (scaleFactor > 0 && scaleFactor != 1.0)
|
||||
{
|
||||
// Remove all geometry dependent data
|
||||
clearTopology();
|
||||
|
||||
// Adapt for new point position
|
||||
MeshStorage::movePoints(pointField());
|
||||
|
||||
points() *= scaleFactor;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Foam::meshedSurface Foam::meshedSurface::subsetMesh
|
||||
(
|
||||
const boolList& include,
|
||||
labelList& pointMap,
|
||||
labelList& faceMap
|
||||
) const
|
||||
{
|
||||
const pointField& locPoints = localPoints();
|
||||
const List<FaceType>& locFaces = localFaces();
|
||||
|
||||
// Fill pointMap, faceMap
|
||||
subsetMap(include, pointMap, faceMap);
|
||||
|
||||
// Create compact coordinate list and forward mapping array
|
||||
pointField newPoints(pointMap.size());
|
||||
labelList oldToNew(locPoints.size());
|
||||
forAll(pointMap, pointI)
|
||||
{
|
||||
newPoints[pointI] = locPoints[pointMap[pointI]];
|
||||
oldToNew[pointMap[pointI]] = pointI;
|
||||
|
||||
}
|
||||
|
||||
// create a new patch list
|
||||
surfacePatchList newPatches(patches_);
|
||||
forAll(newPatches, patchI)
|
||||
{
|
||||
newPatches[patchI].size() = 0;
|
||||
}
|
||||
|
||||
// Renumber face node labels and compact
|
||||
List<FaceType> newFaces(faceMap.size());
|
||||
|
||||
forAll(faceMap, faceI)
|
||||
{
|
||||
// Get old vertex labels
|
||||
label origFaceI = faceMap[faceI];
|
||||
const FaceType& oldFace = locFaces[origFaceI];
|
||||
|
||||
newFaces[faceI] = FaceType(oldFace);
|
||||
|
||||
// Renumber labels for face
|
||||
FaceType& f = newFaces[faceI];
|
||||
forAll(f, fp)
|
||||
{
|
||||
f[fp] = oldToNew[oldFace[fp]];
|
||||
}
|
||||
|
||||
// adjust patch sizes
|
||||
forAllReverse (newPatches, patchI)
|
||||
{
|
||||
if
|
||||
(
|
||||
origFaceI >= patches_[patchI].start()
|
||||
&& patches_[patchI].size()
|
||||
)
|
||||
{
|
||||
newPatches[patchI].size()++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// adjust patch start
|
||||
label startFaceI = 0;
|
||||
forAll(newPatches, patchI)
|
||||
{
|
||||
newPatches[patchI].start() = startFaceI;
|
||||
startFaceI += newPatches[patchI].size();
|
||||
}
|
||||
|
||||
// Construct an empty subsurface and fill
|
||||
meshedSurface subSurf;
|
||||
|
||||
subSurf.patches_.transfer(newPatches);
|
||||
subSurf.points().transfer(newPoints);
|
||||
subSurf.faces().transfer(newFaces);
|
||||
|
||||
return subSurf;
|
||||
}
|
||||
|
||||
|
||||
void Foam::meshedSurface::transfer(meshedSurface& surf)
|
||||
{
|
||||
clearOut();
|
||||
faces().transfer(surf.faces());
|
||||
points().transfer(surf.points());
|
||||
patches_.transfer(surf.patches_);
|
||||
surf.clearOut();
|
||||
}
|
||||
|
||||
|
||||
void Foam::meshedSurface::transfer(keyedSurface& surf)
|
||||
{
|
||||
clearOut();
|
||||
points().transfer(surf.points());
|
||||
|
||||
labelList faceMap;
|
||||
surfacePatchList newPatches = surf.sortedRegions(faceMap);
|
||||
patches_.transfer(newPatches);
|
||||
|
||||
const List<keyedFace>& origFaces = surf.faces();
|
||||
List<FaceType> newFaces(origFaces.size());
|
||||
|
||||
// this is somewhat like ListOps reorder and/or IndirectList
|
||||
forAll(newFaces, faceI)
|
||||
{
|
||||
newFaces[faceI] = origFaces[faceMap[faceI]];
|
||||
}
|
||||
|
||||
faces().transfer(newFaces);
|
||||
surf.faces().clear();
|
||||
surf.clearOut();
|
||||
}
|
||||
|
||||
|
||||
bool Foam::meshedSurface::canRead(const word& ext, const bool verbose)
|
||||
{
|
||||
return keyedSurface::canRead(ext, verbose);
|
||||
}
|
||||
|
||||
|
||||
bool Foam::meshedSurface::canWrite(const word& ext, const bool verbose)
|
||||
{
|
||||
// perhaps we got sent an entire name
|
||||
word fExt(ext);
|
||||
|
||||
// FIXME: this looks horrible, but I don't have STL docs here
|
||||
string::size_type dot = ext.find_last_of(".");
|
||||
if (dot != string::npos)
|
||||
{
|
||||
fExt = ext.substr(dot+1);
|
||||
}
|
||||
|
||||
// handle 'native' format directly
|
||||
if (fExt == nativeExt)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
writefileExtensionMemberFunctionTable::iterator mfIter =
|
||||
writefileExtensionMemberFunctionTablePtr_->find(fExt);
|
||||
|
||||
if (mfIter == writefileExtensionMemberFunctionTablePtr_->end())
|
||||
{
|
||||
if (verbose)
|
||||
{
|
||||
const wordList& known =
|
||||
writefileExtensionMemberFunctionTablePtr_->toc();
|
||||
|
||||
Info<<"Unknown file extension for writing: " << fExt << nl;
|
||||
// compact output:
|
||||
Info<<"Valid types: ( " << nativeExt;
|
||||
forAll(known, i)
|
||||
{
|
||||
Info<<" " << known[i];
|
||||
}
|
||||
Info<<" )" << endl;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Foam::meshedSurface::write
|
||||
(
|
||||
const fileName& fName,
|
||||
const meshedSurface& surf
|
||||
)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "meshedSurface::write(const fileName&, const meshedSurface&) : "
|
||||
"writing meshedSurface to " << fName
|
||||
<< endl;
|
||||
}
|
||||
|
||||
const word ext = fName.ext();
|
||||
|
||||
// handle 'native' format directly
|
||||
if (ext == nativeExt)
|
||||
{
|
||||
surf.write(OFstream(fName)());
|
||||
}
|
||||
else
|
||||
{
|
||||
writefileExtensionMemberFunctionTable::iterator mfIter =
|
||||
writefileExtensionMemberFunctionTablePtr_->find(ext);
|
||||
|
||||
if (mfIter == writefileExtensionMemberFunctionTablePtr_->end())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"meshedSurface::write(const fileName&)"
|
||||
) << "Unknown file extension " << ext << nl << nl
|
||||
<< "Valid types are :" << endl
|
||||
<< writefileExtensionMemberFunctionTablePtr_->toc()
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
mfIter()(fName, surf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::meshedSurface::write(Ostream& os) const
|
||||
{
|
||||
// quick-hack
|
||||
os << patches_.size() << nl << token::BEGIN_LIST;
|
||||
forAll(patches_, patchI)
|
||||
{
|
||||
patches_[patchI].writeDict(os);
|
||||
}
|
||||
os << token::END_LIST;
|
||||
|
||||
// Note: Write with global point numbering
|
||||
os << points() << nl << faces() << endl;
|
||||
|
||||
// Check state of Ostream
|
||||
os.check("meshedSurface::write(Ostream&)");
|
||||
}
|
||||
|
||||
|
||||
void Foam::meshedSurface::write(const Time& d) const
|
||||
{
|
||||
write(OFstream(triSurfName(d))());
|
||||
}
|
||||
|
||||
|
||||
void Foam::meshedSurface::writeStats(Ostream& os) const
|
||||
{
|
||||
os << "Faces : " << size() << endl
|
||||
<< "Edges : " << nEdges() << endl
|
||||
<< "Vertices : " << nPoints() << endl
|
||||
<< "Bounding Box : " << boundBox(localPoints(), false) << endl;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::meshedSurface::operator=(const meshedSurface& surf)
|
||||
{
|
||||
clearOut();
|
||||
faces() = surf.faces();
|
||||
points() = surf.points();
|
||||
patches_ = surf.patches_;
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
|
||||
|
||||
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
|
||||
|
||||
Foam::Ostream& Foam::operator<<(Ostream& os, const meshedSurface& surf)
|
||||
{
|
||||
surf.write(os);
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// ************************************************************************* //
|
||||
437
src/surfMesh/meshedSurface/meshedSurface.H
Normal file
437
src/surfMesh/meshedSurface/meshedSurface.H
Normal file
@ -0,0 +1,437 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
Class
|
||||
Foam::meshedSurface
|
||||
|
||||
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 meshedSurface is intended to surfaces from a variety of sources.
|
||||
- A set of points and faces without any patch information.
|
||||
- A set of points and faces with randomly sorted patch information.
|
||||
This could arise, for example, from reading external file formats
|
||||
such as STL, etc.
|
||||
|
||||
SourceFiles
|
||||
meshedSurface.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef meshedSurface_H
|
||||
#define meshedSurface_H
|
||||
|
||||
#include "pointField.H"
|
||||
#include "PrimitivePatchExtra.H"
|
||||
#include "boolList.H"
|
||||
#include "geometricSurfacePatchList.H"
|
||||
#include "surfacePatchList.H"
|
||||
#include "face.H"
|
||||
#include "Keyed.H"
|
||||
#include "xfer.H"
|
||||
#include "runTimeSelectionTables.H"
|
||||
#include "memberFunctionSelectionTables.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
class Time;
|
||||
class keyedSurface;
|
||||
class polyBoundaryMesh;
|
||||
class surfMesh;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class meshedSurface Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class meshedSurface
|
||||
:
|
||||
public PrimitivePatchExtra<face, ::Foam::List, pointField, point>
|
||||
{
|
||||
friend class keyedSurface;
|
||||
|
||||
protected:
|
||||
|
||||
// Protected Member Data
|
||||
|
||||
//- Typedef if this type has not already been defined
|
||||
typedef Keyed<face> keyedFace;
|
||||
|
||||
//- Typedef for similar code in keyedSurface and meshedSurface
|
||||
typedef face FaceType;
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Data
|
||||
|
||||
// Private typedefs
|
||||
|
||||
typedef PrimitivePatchExtra
|
||||
<
|
||||
FaceType,
|
||||
::Foam::List,
|
||||
pointField,
|
||||
point
|
||||
>
|
||||
MeshStorage;
|
||||
|
||||
// Private data
|
||||
|
||||
//- Patch information (face ordering nFaces/startFace only used
|
||||
// during reading and writing)
|
||||
surfacePatchList patches_;
|
||||
|
||||
// Private member functions
|
||||
|
||||
//- set a single patch
|
||||
void onePatch();
|
||||
|
||||
//- basic sanity check on patches
|
||||
void checkPatches();
|
||||
|
||||
//- Read in Foam format
|
||||
bool read(Istream&);
|
||||
|
||||
|
||||
// Static private functions
|
||||
|
||||
public:
|
||||
|
||||
// Protected Member Data
|
||||
|
||||
// Protected Member functions
|
||||
|
||||
//- Return non-const access to global points
|
||||
pointField& points()
|
||||
{
|
||||
return const_cast<pointField&>(MeshStorage::points());
|
||||
}
|
||||
|
||||
//- Return non-const access to the faces
|
||||
List<FaceType>& faces()
|
||||
{
|
||||
return static_cast<List<FaceType> &>(*this);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
ClassName("meshedSurface");
|
||||
|
||||
//- Return the default geometric patch type (usually "empty")
|
||||
static word defaultGeometricType;
|
||||
|
||||
|
||||
// Static
|
||||
|
||||
//- Name of meshedSurface directory to use.
|
||||
static fileName triSurfInstance(const Time&);
|
||||
|
||||
//- Name of meshedSurface directory to use.
|
||||
static fileName triSurfName(const Time&);
|
||||
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct null
|
||||
meshedSurface();
|
||||
|
||||
//- Construct from components (points, faces and patches).
|
||||
meshedSurface
|
||||
(
|
||||
const pointField&,
|
||||
const List<face>&,
|
||||
const surfacePatchList&
|
||||
);
|
||||
|
||||
//- Construct by transferring components
|
||||
//- (points, faces and patches).
|
||||
meshedSurface
|
||||
(
|
||||
const xfer<pointField>&,
|
||||
const xfer<List<face> >&,
|
||||
const xfer<surfacePatchList>&
|
||||
);
|
||||
|
||||
//- Construct from points, faces, and patch information
|
||||
meshedSurface
|
||||
(
|
||||
const xfer<pointField>&,
|
||||
const xfer<List<face> >&,
|
||||
const List<label>& patchSizes,
|
||||
const List<word>& patchNames,
|
||||
const List<word>& patchTypes
|
||||
);
|
||||
|
||||
//- Construct from points, faces, a list of (unsorted) region Ids
|
||||
// and with the names of the regions.
|
||||
meshedSurface
|
||||
(
|
||||
const xfer<pointField>&,
|
||||
const xfer<List<face> >&,
|
||||
const List<label>& regionIds,
|
||||
const Map<word>& regionNames
|
||||
);
|
||||
|
||||
//- Construct by transferring points, faces
|
||||
// with a single default patch
|
||||
meshedSurface
|
||||
(
|
||||
const xfer<pointField>&,
|
||||
const xfer<List<face> >&
|
||||
);
|
||||
|
||||
//- Construct by transferring points and copying labelled faces
|
||||
// With region names per map or set to default.
|
||||
meshedSurface
|
||||
(
|
||||
const xfer<pointField>&,
|
||||
const List<keyedFace>&,
|
||||
const Map<word>& regionNames
|
||||
);
|
||||
|
||||
//- Construct by transferring points and labelled faces
|
||||
//- with patch-names from hash
|
||||
meshedSurface
|
||||
(
|
||||
const xfer<pointField>&,
|
||||
const List<keyedFace>&,
|
||||
const HashTable<label>& nameToRegionMapping
|
||||
);
|
||||
|
||||
//- Construct from a boundary mesh with local points/faces
|
||||
meshedSurface
|
||||
(
|
||||
const polyBoundaryMesh&,
|
||||
const bool globalPoints=false
|
||||
);
|
||||
|
||||
//- Construct from a keyedSurface
|
||||
meshedSurface(const keyedSurface&);
|
||||
|
||||
//- Construct from a surfMesh
|
||||
meshedSurface(const surfMesh&);
|
||||
|
||||
//- Construct by transferring the contents from a keyedSurface
|
||||
meshedSurface(const xfer<keyedSurface>&);
|
||||
|
||||
//- Construct by transferring the contents from a meshedSurface
|
||||
meshedSurface(const xfer<meshedSurface>&);
|
||||
|
||||
|
||||
//- Construct from file name (uses extension to determine type)
|
||||
meshedSurface
|
||||
(
|
||||
const fileName&,
|
||||
const bool triangulate=false
|
||||
);
|
||||
|
||||
//- Construct from file name (uses extension to determine type)
|
||||
meshedSurface
|
||||
(
|
||||
const fileName&,
|
||||
const word&,
|
||||
const bool triangulate=false
|
||||
);
|
||||
|
||||
//- Construct from Istream
|
||||
meshedSurface(Istream&);
|
||||
|
||||
//- Construct from objectRegistry
|
||||
meshedSurface(const Time&);
|
||||
|
||||
//- Construct as copy
|
||||
meshedSurface(const meshedSurface&);
|
||||
|
||||
// Selectors
|
||||
|
||||
//- Select constructed from filename (implicit extension)
|
||||
static autoPtr<meshedSurface> New
|
||||
(
|
||||
const fileName&,
|
||||
const bool triangulate=false
|
||||
);
|
||||
|
||||
//- Select constructed from filename (explicit extension)
|
||||
static autoPtr<meshedSurface> New
|
||||
(
|
||||
const fileName&,
|
||||
const word&,
|
||||
const bool triangulate=false
|
||||
);
|
||||
|
||||
|
||||
// Destructor
|
||||
|
||||
~meshedSurface();
|
||||
|
||||
|
||||
// Member Function Selectors
|
||||
|
||||
declareMemberFunctionSelectionTable
|
||||
(
|
||||
void,
|
||||
meshedSurface,
|
||||
write,
|
||||
fileExtension,
|
||||
(
|
||||
const fileName& fName,
|
||||
const meshedSurface& surf
|
||||
),
|
||||
(fName, surf)
|
||||
);
|
||||
|
||||
//- Write to file
|
||||
static void write(const fileName&, const meshedSurface&);
|
||||
|
||||
//- Can we read this file format?
|
||||
static bool canRead(const word& ext, const bool verbose=false);
|
||||
|
||||
//- Can we write this file format?
|
||||
static bool canWrite(const word& ext, const bool verbose=false);
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Access
|
||||
|
||||
//- Return the number of points
|
||||
label nPoints() const
|
||||
{
|
||||
return points().size();
|
||||
}
|
||||
|
||||
//- Return the number of faces
|
||||
label nFaces() const
|
||||
{
|
||||
return faces().size();
|
||||
}
|
||||
|
||||
//- The surface size is the number of faces
|
||||
label size() const
|
||||
{
|
||||
return nFaces();
|
||||
}
|
||||
|
||||
//- Return const access to global points
|
||||
const pointField& points() const
|
||||
{
|
||||
return MeshStorage::points();
|
||||
}
|
||||
|
||||
//- Return const access to the faces
|
||||
const List<FaceType>& faces() const
|
||||
{
|
||||
return static_cast<const List<FaceType> &>(*this);
|
||||
}
|
||||
|
||||
const surfacePatchList& patches() const
|
||||
{
|
||||
return patches_;
|
||||
}
|
||||
|
||||
surfacePatchList& patches()
|
||||
{
|
||||
return patches_;
|
||||
}
|
||||
|
||||
// Edit
|
||||
|
||||
//- Move points
|
||||
virtual void movePoints(const pointField&);
|
||||
|
||||
//- Scale points. A non-positive factor is ignored
|
||||
virtual void scalePoints(const scalar&);
|
||||
|
||||
//- Triangulate the surface, return the number of added faces.
|
||||
// The patch list will be adjusted accordingly.
|
||||
label triangulate();
|
||||
|
||||
//- Join the faces by removing duplicate points.
|
||||
// Returns true if any points merged
|
||||
bool stitchFaces(const scalar tol=SMALL, const bool verbose=false);
|
||||
|
||||
//- Check/fix duplicate/degenerate faces
|
||||
void checkFaces(const bool verbose);
|
||||
|
||||
//- Remove invalid faces
|
||||
void cleanup(const bool verbose);
|
||||
|
||||
//- Return new surface.
|
||||
// Returns pointMap, faceMap from subsetMeshMap
|
||||
meshedSurface subsetMesh
|
||||
(
|
||||
const boolList& include,
|
||||
labelList& pointMap,
|
||||
labelList& faceMap
|
||||
) const;
|
||||
|
||||
//- Transfer the contents of the argument and annull the argument
|
||||
void transfer(meshedSurface&);
|
||||
|
||||
//- Transfer the contents of the argument and annull the argument
|
||||
void transfer(keyedSurface&);
|
||||
|
||||
|
||||
// Write
|
||||
|
||||
//- Write to Ostream in simple FOAM format
|
||||
virtual void write(Ostream&) const;
|
||||
|
||||
//- Generic write routine. Chooses writer based on extension.
|
||||
virtual void write(const fileName& fName) const
|
||||
{
|
||||
write(fName, *this);
|
||||
}
|
||||
|
||||
//- Write to database
|
||||
void write(const Time&) const;
|
||||
|
||||
//- Write some statistics
|
||||
void writeStats(Ostream&) const;
|
||||
|
||||
|
||||
// Member operators
|
||||
|
||||
void operator=(const meshedSurface&);
|
||||
|
||||
// Ostream Operator
|
||||
|
||||
friend Ostream& operator<<(Ostream&, const meshedSurface&);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
330
src/surfMesh/meshedSurface/meshedSurfaceCleanup.C
Normal file
330
src/surfMesh/meshedSurface/meshedSurfaceCleanup.C
Normal file
@ -0,0 +1,330 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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.
|
||||
void Foam::meshedSurface::cleanup(const bool verbose)
|
||||
{
|
||||
// merge points (already done for STL, TRI)
|
||||
stitchFaces(SMALL, verbose);
|
||||
|
||||
checkFaces(verbose);
|
||||
checkEdges(verbose);
|
||||
}
|
||||
|
||||
|
||||
bool Foam::meshedSurface::stitchFaces(const scalar tol, const bool verbose)
|
||||
{
|
||||
pointField& pointLst = points();
|
||||
|
||||
// Merge points
|
||||
labelList pointMap(pointLst.size());
|
||||
pointField newPoints(pointLst.size());
|
||||
|
||||
bool hasMerged = mergePoints(pointLst, tol, verbose, pointMap, newPoints);
|
||||
|
||||
if (!hasMerged)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
Info<< "meshedSurface::stitchFaces : Renumbering all faces"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
// Set the coordinates to the merged ones
|
||||
pointLst.transfer(newPoints);
|
||||
|
||||
List<FaceType>& faceLst = faces();
|
||||
|
||||
// ensure we have at some patches, and they cover all the faces
|
||||
checkPatches();
|
||||
|
||||
// Reset the point labels to the unique points array
|
||||
label oldFaceI = 0;
|
||||
label newFaceI = 0;
|
||||
forAll (patches_, patchI)
|
||||
{
|
||||
surfacePatch& surfPatch = patches_[patchI];
|
||||
|
||||
// adjust patch start
|
||||
surfPatch.start() = newFaceI;
|
||||
|
||||
label patchEnd = oldFaceI + surfPatch.size();
|
||||
for (; oldFaceI < patchEnd; ++oldFaceI)
|
||||
{
|
||||
FaceType& f = faceLst[oldFaceI];
|
||||
forAll (f, fp)
|
||||
{
|
||||
f[fp] = pointMap[f[fp]];
|
||||
}
|
||||
|
||||
if (f.collapse() >= 3)
|
||||
{
|
||||
if (newFaceI != oldFaceI)
|
||||
{
|
||||
faceLst[newFaceI] = f;
|
||||
}
|
||||
newFaceI++;
|
||||
}
|
||||
else if (verbose)
|
||||
{
|
||||
Pout<< "meshedSurface::stitchFaces : "
|
||||
<< "Removing collapsed face " << oldFaceI << endl
|
||||
<< " vertices :" << f << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// adjust patch size
|
||||
surfPatch.size() = newFaceI - surfPatch.size();
|
||||
}
|
||||
|
||||
if (newFaceI != faceLst.size())
|
||||
{
|
||||
if (verbose)
|
||||
{
|
||||
Pout<< "meshedSurface::stitchFaces : "
|
||||
<< "Removed " << faceLst.size() - newFaceI
|
||||
<< " faces" << endl;
|
||||
}
|
||||
faceLst.setSize(newFaceI);
|
||||
}
|
||||
|
||||
|
||||
// Merging points might have changed geometric factors
|
||||
clearOut();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Remove badly degenerate faces and double faces.
|
||||
void Foam::meshedSurface::checkFaces(const bool verbose)
|
||||
{
|
||||
// Simple check on indices ok.
|
||||
const label maxPointI = points().size() - 1;
|
||||
|
||||
List<FaceType>& faceLst = faces();
|
||||
|
||||
// Phase 0: detect badly labelled faces
|
||||
forAll (faceLst, faceI)
|
||||
{
|
||||
const FaceType& f = faceLst[faceI];
|
||||
|
||||
forAll (f, fp)
|
||||
{
|
||||
if (f[fp] < 0 || f[fp] > maxPointI)
|
||||
{
|
||||
FatalErrorIn("meshedSurface::checkFaces(bool)")
|
||||
<< "face " << f
|
||||
<< " uses point indices outside point range 0.."
|
||||
<< maxPointI
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ensure we have patches, and they cover all the faces
|
||||
checkPatches();
|
||||
|
||||
// Phase 1: find and skip over invalid faces
|
||||
// Phase 2: pack
|
||||
const labelListList& fFaces = faceFaces();
|
||||
|
||||
label oldFaceI = 0;
|
||||
label newFaceI = 0;
|
||||
forAll (patches_, patchI)
|
||||
{
|
||||
surfacePatch& surfPatch = patches_[patchI];
|
||||
|
||||
// correct the patch start
|
||||
surfPatch.start() = newFaceI;
|
||||
|
||||
label patchEnd = oldFaceI + surfPatch.size();
|
||||
for (; oldFaceI < patchEnd; ++oldFaceI)
|
||||
{
|
||||
FaceType& f = faceLst[oldFaceI];
|
||||
|
||||
// 'degenerate' face check
|
||||
if (f.collapse() >= 3)
|
||||
{
|
||||
// duplicate face check
|
||||
bool okay = true;
|
||||
const labelList& neighbours = fFaces[oldFaceI];
|
||||
|
||||
// Check if faceNeighbours use same points as this face.
|
||||
// Note: discards normal information - sides of baffle are merged.
|
||||
forAll (neighbours, neighI)
|
||||
{
|
||||
if (neighbours[neighI] <= oldFaceI)
|
||||
{
|
||||
// lower numbered faces already checked
|
||||
continue;
|
||||
}
|
||||
|
||||
const face& nei = faceLst[neighbours[neighI]];
|
||||
|
||||
if (f == nei)
|
||||
{
|
||||
okay = false;
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
WarningIn
|
||||
(
|
||||
"meshedSurface::checkFaces(bool verbose)"
|
||||
) << "faces share the same vertices:\n"
|
||||
<< " face 1 :" << oldFaceI << endl;
|
||||
// printFace(Warning, " ", f, points());
|
||||
|
||||
Warning
|
||||
<< endl
|
||||
<< " face 2 :"
|
||||
<< neighbours[neighI] << endl;
|
||||
// printFace(Warning, " ", nei, points());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (okay)
|
||||
{
|
||||
if (newFaceI != oldFaceI)
|
||||
{
|
||||
faceLst[newFaceI] = f;
|
||||
}
|
||||
newFaceI++;
|
||||
}
|
||||
}
|
||||
else if (verbose)
|
||||
{
|
||||
WarningIn
|
||||
(
|
||||
"meshedSurface::checkFaces(bool verbose)"
|
||||
) << "face " << oldFaceI
|
||||
<< " has fewer than three unique vertices:\n";
|
||||
// printTriangle(Warning, " ", f, points());
|
||||
}
|
||||
}
|
||||
|
||||
// adjust patch size
|
||||
surfPatch.size() = newFaceI - surfPatch.start();
|
||||
}
|
||||
|
||||
if (newFaceI < faceLst.size())
|
||||
{
|
||||
if (verbose)
|
||||
{
|
||||
WarningIn
|
||||
(
|
||||
"meshedSurface::checkFaces(bool verbose)"
|
||||
) << "Removed " << faceLst.size() - newFaceI
|
||||
<< " illegal faces." << endl;
|
||||
}
|
||||
faceLst.setSize(newFaceI);
|
||||
|
||||
// Topology can change because of renumbering
|
||||
clearOut();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::label Foam::meshedSurface::triangulate()
|
||||
{
|
||||
label nTri = 0;
|
||||
|
||||
List<FaceType>& faceLst = faces();
|
||||
|
||||
// estimate how may triangles are needed
|
||||
forAll (faceLst, faceI)
|
||||
{
|
||||
nTri += faceLst[faceI].size() - 2;
|
||||
}
|
||||
|
||||
// nothing to do
|
||||
if (nTri <= faceLst.size())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
List<FaceType> newFaces(nTri);
|
||||
|
||||
// note the number of *additional* faces
|
||||
nTri -= faceLst.size();
|
||||
|
||||
// Reset the point labels to the unique points array
|
||||
label oldFaceI = 0;
|
||||
label newFaceI = 0;
|
||||
forAll (patches_, patchI)
|
||||
{
|
||||
surfacePatch& surfPatch = patches_[patchI];
|
||||
|
||||
// adjust patch start
|
||||
surfPatch.start() = newFaceI;
|
||||
|
||||
label patchEnd = oldFaceI + surfPatch.size();
|
||||
for (; oldFaceI < patchEnd; ++oldFaceI)
|
||||
{
|
||||
const FaceType& f = faceLst[oldFaceI];
|
||||
FaceType fTri(3);
|
||||
|
||||
// Do simple face triangulation around f[0].
|
||||
// we could also use face::triangulation
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// adjust patch size
|
||||
surfPatch.size() = newFaceI - surfPatch.start();
|
||||
}
|
||||
|
||||
faceLst.transfer(newFaces);
|
||||
|
||||
return nTri;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// ************************************************************************* //
|
||||
73
src/surfMesh/meshedSurface/newMeshedSurface.C
Normal file
73
src/surfMesh/meshedSurface/newMeshedSurface.C
Normal file
@ -0,0 +1,73 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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 "keyedSurface.H"
|
||||
#include "meshedSurface.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
// all input is indirect via keyedSurface
|
||||
Foam::autoPtr<Foam::meshedSurface>
|
||||
Foam::meshedSurface::New
|
||||
(
|
||||
const fileName& fName,
|
||||
const word& ext,
|
||||
const bool triangulate
|
||||
)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "meshedSurface::New(const fileName&, const word&, const bool) : "
|
||||
"constructing meshedSurface"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
// created indirectly via keyedSurface
|
||||
autoPtr<meshedSurface> surf(new meshedSurface);
|
||||
surf().transfer( keyedSurface::New(fName,ext,triangulate)() );
|
||||
|
||||
return surf;
|
||||
}
|
||||
|
||||
|
||||
Foam::autoPtr<Foam::meshedSurface>
|
||||
Foam::meshedSurface::New
|
||||
(
|
||||
const fileName& fName,
|
||||
const bool triangulate
|
||||
)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "meshedSurface::New(const fileName&, const bool) : "
|
||||
"constructing meshedSurface"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
return New(fName, fName.ext(), triangulate);
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
||||
Reference in New Issue
Block a user