Enhance edgeMesh to support more formats.

Read only support:

  .bdf, .nas - NASTRAN format. Handles both CBEAM and CROD as lines.
  CROD is what Hypermesh happens to output.

Write only support:

  .vtk - VTK legacy format in ASCII

Read/write support:
  .eMesh - native format, which is simply a list of points, edges
      with an additional IOobject header that lets them be moved about
      easily to use as a featureEdgeMesh.

  .inp - STAR-CD inp/cel/vrt combination
       IOobject header)

  .obj - Alias waverfront format

Radically simplify surfaceFeatureConvert by using the new edgeMesh
functionality.
This commit is contained in:
Mark Olesen
2009-12-11 16:29:55 +01:00
parent 46a455ccea
commit d016db1bc6
27 changed files with 3074 additions and 337 deletions

View File

@ -21,7 +21,7 @@ surfaceFind
- Finds nearest vertex and face to given point.
surfaceMeshTriangulate
- Triangulate external facses of mesh and write as surface.
- Triangulate external faces of mesh and write as surface.
surfacePointMerge
- Explicit point merge of surface.

View File

@ -26,266 +26,85 @@ Application
surfaceFeatureConvert
Description
Extracts and writes surface features to file
Convert between edgeMesh formats
\*---------------------------------------------------------------------------*/
#include "featureEdgeMesh.H"
#include "argList.H"
#include "Time.H"
#include "IFstream.H"
#include "IStringStream.H"
#include "OFstream.H"
#include "Map.H"
#include "edgeMesh.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void readNASEdges
(
const fileName& inFileName,
pointField& allPoints,
edgeList& allEdges
)
{
IFstream is(inFileName);
if (!is.good())
{
FatalErrorIn("readNASEdges")
<< "Cannot read file " << inFileName
<< exit(FatalError);
}
// coordinates of point
DynamicList<point> points;
// Nastran index of point
DynamicList<label> pointIndices;
// beams
DynamicList<edge> edges;
DynamicList<label> edgeIndices;
while (is.good())
{
string line;
is.getLine(line);
if (line.empty() || line[0] == '$')
{
// Skip empty and comment
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 == "GRID")
{
label index;
lineStream >> index;
pointIndices.append(index);
scalar x = readScalar(IStringStream(line.substr(24, 8))());
scalar y = readScalar(IStringStream(line.substr(32, 8))());
scalar z = readScalar(IStringStream(line.substr(40, 8))());
points.append(point(x, y, z));
}
else if (cmd == "CBEAM")
{
// Read shell type since gives patchnames.
label index, group, v0, v1;
lineStream >> index >> group >> v0 >> v1;
edgeIndices.append(index);
edges.append(edge(v0, v1));
}
}
points.shrink();
pointIndices.shrink();
edges.shrink();
edgeIndices.shrink();
Pout<< "Read from " << inFileName
<< " edges:" << edges.size() << " points:" << points.size()
<< endl;
{
// Build inverse mapping (index to point)
Map<label> indexToPoint(2*pointIndices.size());
forAll(pointIndices, i)
{
indexToPoint.insert(pointIndices[i], i);
}
// Relabel edges
forAll(edges, i)
{
edge& e = edges[i];
e[0] = indexToPoint[e[0]];
e[1] = indexToPoint[e[1]];
}
}
allPoints.transfer(points);
allEdges.transfer(edges);
}
void write
(
const Time& runTime,
const fileName& inFileName,
const fileName& outFileName,
const edgeMesh& eMesh
)
{
if (outFileName.ext() == "eMesh")
{
featureEdgeMesh fem
(
IOobject
(
outFileName, // name
runTime.constant(), // instance
runTime, // registry
IOobject::NO_READ,
IOobject::AUTO_WRITE,
false
),
eMesh.points(),
eMesh.edges()
);
Pout<< "Writing feature edge mesh to " << fem.objectPath()
<< endl;
fem.write();
}
else if (outFileName.ext() == "vtk")
{
OFstream str(outFileName);
str << "# vtk DataFile Version 2.0" << nl
<< "featureEdgeMesh " << inFileName << nl
<< "ASCII" << nl
<< "DATASET POLYDATA" << nl;
str << "POINTS " << eMesh.points().size() << " float" << nl;
forAll(eMesh.points(), pointI)
{
const point& pt = eMesh.points()[pointI];
str << pt.x() << ' ' << pt.y() << ' ' << pt.z() << nl;
}
str << "LINES " << eMesh.edges().size() << ' '
<< 3*eMesh.edges().size() << nl;
forAll(eMesh.edges(), edgeI)
{
const edge& e = eMesh.edges()[edgeI];
str << "2 " << e[0] << ' ' << e[1] << nl;
}
}
else
{
FatalErrorIn("write")
<< "Supported output formats: .eMesh, .vtk"
<< exit(FatalError);
}
}
// Main program:
int main(int argc, char *argv[])
{
argList::addNote
(
"Convert between edgeMesh formats"
);
argList::noParallel();
argList::validArgs.append("input file");
argList::validArgs.append("output file");
# include "setRootCase.H"
# include "createTime.H"
argList::validArgs.append("inputFile");
argList::validArgs.append("outputFile");
argList::addOption
(
"scale",
"factor",
"specify a scaling factor for the points"
);
const fileName inFileName(args.additionalArgs()[0]);
const word outFileName(args.additionalArgs()[1]);
argList args(argc, argv);
Time runTime(args.rootPath(), args.caseName());
const stringList& params = args.additionalArgs();
Pout<< "Input features file : " << inFileName << nl
<< "Output features file : " << outFileName << nl
<< endl;
const fileName importName(params[0]);
const fileName exportName(params[1]);
// Read
// ~~~~
if (inFileName.ext() == "nas")
{
pointField points;
edgeList edges;
readNASEdges(inFileName, points, edges);
edgeMesh eMesh(points, edges);
write(runTime, inFileName, outFileName, eMesh);
}
else if (inFileName.ext() == "eMesh")
{
featureEdgeMesh fem
(
IOobject
(
inFileName, // name
runTime.constant(), // instance
runTime, // registry
IOobject::MUST_READ,
IOobject::AUTO_WRITE,
false
)
);
Pout<< "Read from " << inFileName
<< " edges:" << fem.edges().size()
<< " points:" << fem.points().size()
<< endl;
write(runTime, inFileName, outFileName, fem);
}
else
// disable inplace editing
if (importName == exportName)
{
FatalErrorIn(args.executable())
<< "Can only handle NASTRAN data formats (.nas extension)."
<< "Output file " << exportName << " would overwrite input file."
<< exit(FatalError);
}
Pout<< "End\n" << endl;
// check that reading/writing is supported
if
(
!edgeMesh::canReadType(importName.ext(), true)
|| !edgeMesh::canWriteType(exportName.ext(), true)
)
{
return 1;
}
edgeMesh mesh(importName);
Info<< "\nRead edgeMesh " << importName << nl;
mesh.writeStats(Info);
Info<< nl
<< "\nwriting " << exportName;
scalar scaleFactor = 0;
if (args.optionReadIfPresent("scale", scaleFactor) && scaleFactor > 0)
{
Info<< " with scaling " << scaleFactor << endl;
mesh.scalePoints(scaleFactor);
}
else
{
Info<< " without scaling" << endl;
}
mesh.write(exportName);
mesh.writeStats(Info);
Info<< endl;
Info<< "\nEnd\n" << endl;
return 0;
}