BUG: spurious empty surface zones added (fixes #706)

- problems were introduced by the change ee252307d3 (issue #686).
  Affected reading of OBJ files.

  The fallback zone (used to catch unnamed groups/zones), which was
  previously filtered away when not needed. Now handle more explicitly.

ENH: use stringOps::split and low-level read{Label,Scalar} for parsing OBJ file
This commit is contained in:
Mark Olesen
2018-01-16 13:20:58 +01:00
parent ff07ae1520
commit 82a9f2c949
6 changed files with 258 additions and 268 deletions

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2018 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -27,8 +27,55 @@ License
#include "clock.H" #include "clock.H"
#include "Fstream.H" #include "Fstream.H"
#include "Ostream.H" #include "Ostream.H"
#include "StringStream.H" #include "stringOps.H"
#include "ListOps.H"
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
{
// Token list with one of the following:
// f v1 v2 v3 ...
// f v1/vt1 v2/vt2 v3/vt3 ...
// l v1 v2 v3 ...
// l v1/vt1 v2/vt2 v3/vt3 ...
static label readObjVertices
(
const SubStrings<string>& tokens,
DynamicList<label>& verts
)
{
verts.clear();
bool first = true;
for (const auto& tok : tokens)
{
if (first)
{
// skip initial "f" or "l"
first = false;
continue;
}
const string vrtSpec(tok);
const auto slash = vrtSpec.find('/');
const label vertId =
(
slash != string::npos
? readLabel(vrtSpec.substr(0, slash))
: readLabel(vrtSpec)
);
verts.append(vertId - 1);
}
return verts.size();
}
} // End namespace Foam
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -43,56 +90,6 @@ Foam::fileFormats::OBJedgeFormat::OBJedgeFormat
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::fileFormats::OBJedgeFormat::readVertices
(
const string& line,
string::size_type& endNum,
DynamicList<label>& dynVertices
)
{
dynVertices.clear();
while (true)
{
string::size_type startNum =
line.find_first_not_of(' ', endNum);
if (startNum == string::npos)
{
break;
}
endNum = line.find(' ', startNum);
string vertexSpec;
if (endNum != 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::npos)
{
IStringStream intStream(vertexSpec.substr(0, slashPos));
intStream >> vertI;
}
else
{
IStringStream intStream(vertexSpec);
intStream >> vertI;
}
dynVertices.append(vertI - 1);
}
}
bool Foam::fileFormats::OBJedgeFormat::read(const fileName& filename) bool Foam::fileFormats::OBJedgeFormat::read(const fileName& filename)
{ {
clear(); clear();
@ -106,97 +103,97 @@ bool Foam::fileFormats::OBJedgeFormat::read(const fileName& filename)
} }
DynamicList<point> dynPoints; DynamicList<point> dynPoints;
DynamicList<label> dynVerts;
DynamicList<edge> dynEdges; DynamicList<edge> dynEdges;
DynamicList<label> dynUsedPoints; DynamicList<label> dynUsedPoints;
DynamicList<label> dynVertices;
while (is.good()) while (is.good())
{ {
string line = this->getLineNoComment(is); string line = this->getLineNoComment(is);
// Handle continuations // Line continuations
if (line.removeEnd("\\")) while (line.removeEnd("\\"))
{ {
line += this->getLineNoComment(is); line += this->getLineNoComment(is);
} }
// Read first word const SubStrings<string> tokens = stringOps::splitSpace(line);
IStringStream lineStream(line);
word cmd; // Require command and some arguments
lineStream >> cmd; if (tokens.size() < 2)
{
continue;
}
const word cmd = word::validate(tokens[0]);
if (cmd == "v") if (cmd == "v")
{ {
scalar x, y, z; // Vertex
lineStream >> x >> y >> z; // v x y z
dynPoints.append
(
point
(
readScalar(tokens[1]),
readScalar(tokens[2]),
readScalar(tokens[3])
)
);
dynPoints.append(point(x, y, z));
dynUsedPoints.append(-1); dynUsedPoints.append(-1);
} }
else if (cmd == "l") else if (cmd == "l")
{ {
// Assume 'l' is followed by space. // Line
string::size_type endNum = 1; // l v1 v2 v3 ...
// OR
// l v1/vt1 v2/vt2 v3/vt3 ...
readVertices readObjVertices(tokens, dynVerts);
(
line,
endNum,
dynVertices
);
for (label i = 1; i < dynVerts.size(); i++)
for (label i = 1; i < dynVertices.size(); i++)
{ {
edge edgeRead(dynVertices[i-1], dynVertices[i]); const edge e(dynVerts[i-1], dynVerts[i]);
dynEdges.append(e);
dynUsedPoints[edgeRead[0]] = edgeRead[0]; dynUsedPoints[e[0]] = e[0];
dynUsedPoints[edgeRead[1]] = edgeRead[1]; dynUsedPoints[e[1]] = e[1];
dynEdges.append(edgeRead);
} }
} }
else if (cmd == "f") else if (cmd == "f")
{ {
// Support for faces with 2 vertices // Face - support for faces with 2 vertices
// Assume 'f' is followed by space. // f v1 v2 v3 ...
string::size_type endNum = 1; // OR
// f v1/vt1 v2/vt2 v3/vt3 ...
readVertices if (readObjVertices(tokens, dynVerts) == 2)
(
line,
endNum,
dynVertices
);
if (dynVertices.size() == 2)
{ {
for (label i = 1; i < dynVertices.size(); i++) for (label i = 1; i < dynVerts.size(); i++)
{ {
edge edgeRead(dynVertices[i-1], dynVertices[i]); const edge e(dynVerts[i-1], dynVerts[i]);
dynEdges.append(e);
dynUsedPoints[edgeRead[0]] = edgeRead[0]; dynUsedPoints[e[0]] = e[0];
dynUsedPoints[edgeRead[1]] = edgeRead[1]; dynUsedPoints[e[1]] = e[1];
dynEdges.append(edgeRead);
} }
} }
} }
} }
// cull unused points // Cull unused points
label nUsed = 0; label nUsed = 0;
forAll(dynPoints, pointi) forAll(dynPoints, pointi)
{ {
if (dynUsedPoints[pointi] >= 0) if (dynUsedPoints[pointi] >= 0)
{ {
if (nUsed != pointi) if (nUsed != pointi)
{ {
dynPoints[nUsed] = dynPoints[pointi]; dynPoints[nUsed] = std::move(dynPoints[pointi]);
dynUsedPoints[pointi] = nUsed; // new position dynUsedPoints[pointi] = nUsed; // The new list location
} }
++nUsed; ++nUsed;
} }
@ -204,16 +201,14 @@ bool Foam::fileFormats::OBJedgeFormat::read(const fileName& filename)
dynPoints.setSize(nUsed); dynPoints.setSize(nUsed);
// transfer to normal lists // Transfer to normal lists
storedPoints().transfer(dynPoints); storedPoints().transfer(dynPoints);
// renumber edge vertices // Renumber edge vertices
if (nUsed != dynUsedPoints.size()) if (nUsed != dynUsedPoints.size())
{ {
forAll(dynEdges, edgeI) for (edge& e : dynEdges)
{ {
edge& e = dynEdges[edgeI];
e[0] = dynUsedPoints[e[0]]; e[0] = dynUsedPoints[e[0]];
e[1] = dynUsedPoints[e[1]]; e[1] = dynUsedPoints[e[1]];
} }
@ -252,10 +247,8 @@ void Foam::fileFormats::OBJedgeFormat::write
<< "# <points count=\"" << pointLst.size() << "\">" << nl; << "# <points count=\"" << pointLst.size() << "\">" << nl;
// Write vertex coords // Write vertex coords
forAll(pointLst, ptI) for (const point& p : pointLst)
{ {
const point& p = pointLst[ptI];
os << "v " << p.x() << ' ' << p.y() << ' ' << p.z() << nl; os << "v " << p.x() << ' ' << p.y() << ' ' << p.z() << nl;
} }
@ -264,10 +257,8 @@ void Foam::fileFormats::OBJedgeFormat::write
<< "# <edges count=\"" << edgeLst.size() << "\">" << endl; << "# <edges count=\"" << edgeLst.size() << "\">" << endl;
// Write line connectivity // Write line connectivity
forAll(edgeLst, edgeI) for (const edge& e : edgeLst)
{ {
const edge& e = edgeLst[edgeI];
os << "l " << (e[0] + 1) << " " << (e[1] + 1) << nl; os << "l " << (e[0] + 1) << " " << (e[1] + 1) << nl;
} }
os << "# </edges>" << endl; os << "# </edges>" << endl;

View File

@ -58,18 +58,11 @@ class OBJedgeFormat
{ {
// Private Member Functions // Private Member Functions
void readVertices
(
const string& line,
string::size_type& endNum,
DynamicList<label>& dynVertices
);
//- Disallow default bitwise copy construct //- Disallow default bitwise copy construct
OBJedgeFormat(const OBJedgeFormat&); OBJedgeFormat(const OBJedgeFormat&) = delete;
//- Disallow default bitwise assignment //- Disallow default bitwise assignment
void operator=(const OBJedgeFormat&); void operator=(const OBJedgeFormat&) = delete;
public: public:
@ -93,8 +86,7 @@ public:
//- Destructor //- Destructor
virtual ~OBJedgeFormat() virtual ~OBJedgeFormat() = default;
{}
// Member Functions // Member Functions

View File

@ -117,12 +117,12 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
DynamicList<Face> dynFaces; DynamicList<Face> dynFaces;
DynamicList<label> dynZones; DynamicList<label> dynZones;
DynamicList<label> dynSizes; DynamicList<label> dynSizes;
Map<label> zoneLookup; Map<label> zoneLookup;
// assume the types are not intermixed // Assume that the groups are not intermixed
// leave faces that didn't have a group in 0 label zoneId = 0;
bool sorted = true; bool sorted = true;
label zoneI = 0;
// Name for face group // Name for face group
Map<word> nameLookup; Map<word> nameLookup;
@ -139,7 +139,7 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
while (is.good()) while (is.good())
{ {
string::size_type linei = 0; // parsing position within current line string::size_type linei = 0; // Parsing position within current line
string line; string line;
is.getLine(line); is.getLine(line);
@ -221,74 +221,74 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
{ {
(void) nextNasField(line, linei, 8); // 8-16 (void) nextNasField(line, linei, 8); // 8-16
label groupId = readLabel(nextNasField(line, linei, 8)); // 16-24 label groupId = readLabel(nextNasField(line, linei, 8)); // 16-24
label a = readLabel(nextNasField(line, linei, 8)); // 24-32 const auto a = readLabel(nextNasField(line, linei, 8)); // 24-32
label b = readLabel(nextNasField(line, linei, 8)); // 32-40 const auto b = readLabel(nextNasField(line, linei, 8)); // 32-40
label c = readLabel(nextNasField(line, linei, 8)); // 40-48 const auto c = readLabel(nextNasField(line, linei, 8)); // 40-48
// Convert groupId into zoneId // Convert groupId into zoneId
const auto fnd = zoneLookup.cfind(groupId); const auto iterZone = zoneLookup.cfind(groupId);
if (fnd.found()) if (iterZone.found())
{ {
if (zoneI != fnd()) if (zoneId != *iterZone)
{ {
// pshell types are intermixed // pshell types are intermixed
sorted = false; sorted = false;
} }
zoneI = fnd(); zoneId = *iterZone;
} }
else else
{ {
zoneI = dynSizes.size(); zoneId = dynSizes.size();
zoneLookup.insert(groupId, zoneI); zoneLookup.insert(groupId, zoneId);
dynSizes.append(0); dynSizes.append(0);
// Info<< "zone" << zoneI << " => group " << groupId <<endl; // Info<< "zone" << zoneId << " => group " << groupId <<nl;
} }
dynFaces.append(Face{a, b, c}); dynFaces.append(Face{a, b, c});
dynZones.append(zoneI); dynZones.append(zoneId);
dynSizes[zoneI]++; dynSizes[zoneId]++;
} }
else if (cmd == "CQUAD4") else if (cmd == "CQUAD4")
{ {
(void) nextNasField(line, linei, 8); // 8-16 (void) nextNasField(line, linei, 8); // 8-16
label groupId = readLabel(nextNasField(line, linei, 8)); // 16-24 label groupId = readLabel(nextNasField(line, linei, 8)); // 16-24
label a = readLabel(nextNasField(line, linei, 8)); // 24-32 const auto a = readLabel(nextNasField(line, linei, 8)); // 24-32
label b = readLabel(nextNasField(line, linei, 8)); // 32-40 const auto b = readLabel(nextNasField(line, linei, 8)); // 32-40
label c = readLabel(nextNasField(line, linei, 8)); // 40-48 const auto c = readLabel(nextNasField(line, linei, 8)); // 40-48
label d = readLabel(nextNasField(line, linei, 8)); // 48-56 const auto d = readLabel(nextNasField(line, linei, 8)); // 48-56
// Convert groupID into zoneId // Convert groupId into zoneId
const auto fnd = zoneLookup.cfind(groupId); const auto iterZone = zoneLookup.cfind(groupId);
if (fnd.found()) if (iterZone.found())
{ {
if (zoneI != fnd()) if (zoneId != *iterZone)
{ {
// pshell types are intermixed // pshell types are intermixed
sorted = false; sorted = false;
} }
zoneI = fnd(); zoneId = *iterZone;
} }
else else
{ {
zoneI = dynSizes.size(); zoneId = dynSizes.size();
zoneLookup.insert(groupId, zoneI); zoneLookup.insert(groupId, zoneId);
dynSizes.append(0); dynSizes.append(0);
// Info<< "zone" << zoneI << " => group " << groupId <<endl; // Info<< "zone" << zoneId << " => group " << groupId <<nl;
} }
if (faceTraits<Face>::isTri()) if (faceTraits<Face>::isTri())
{ {
dynFaces.append(Face{a, b, c}); dynFaces.append(Face{a, b, c});
dynFaces.append(Face{c, d, a}); dynFaces.append(Face{c, d, a});
dynZones.append(zoneI); dynZones.append(zoneId);
dynZones.append(zoneI); dynZones.append(zoneId);
dynSizes[zoneI] += 2; dynSizes[zoneId] += 2;
} }
else else
{ {
dynFaces.append(Face{a,b,c,d}); dynFaces.append(Face{a,b,c,d});
dynZones.append(zoneI); dynZones.append(zoneId);
dynSizes[zoneI]++; dynSizes[zoneId]++;
} }
} }
else if (cmd == "GRID") else if (cmd == "GRID")
@ -388,10 +388,10 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
const label groupId = iter.key(); const label groupId = iter.key();
const label zoneId = iter.object(); const label zoneId = iter.object();
const auto fnd = nameLookup.cfind(groupId); const auto iterName = nameLookup.cfind(groupId);
if (fnd.found()) if (iterName.found())
{ {
names[zoneId] = fnd(); names[zoneId] = *iterName;
} }
else else
{ {

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd. \\/ M anipulation | Copyright (C) 2016-2018 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -26,8 +26,7 @@ License
#include "OBJsurfaceFormat.H" #include "OBJsurfaceFormat.H"
#include "clock.H" #include "clock.H"
#include "Fstream.H" #include "Fstream.H"
#include "StringStream.H" #include "stringOps.H"
#include "ListOps.H"
#include "faceTraits.H" #include "faceTraits.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -60,115 +59,123 @@ bool Foam::fileFormats::OBJsurfaceFormat<Face>::read
<< exit(FatalError); << exit(FatalError);
} }
// assume that the groups are not intermixed // Assume that the groups are not intermixed
// Place faces without a group in zone0.
// zoneId = -1 to signal uninitialized
label zoneId = -1;
bool sorted = true; bool sorted = true;
DynamicList<point> dynPoints; DynamicList<point> dynPoints;
DynamicList<label> dynVerts;
DynamicList<Face> dynFaces; DynamicList<Face> dynFaces;
DynamicList<label> dynZones;
DynamicList<word> dynNames;
DynamicList<label> dynSizes;
HashTable<label> lookup;
// place faces without a group in zone0 DynamicList<word> dynNames;
label zoneI = 0; DynamicList<label> dynZones;
lookup.insert("zone0", zoneI); DynamicList<label> dynSizes;
dynNames.append("zone0");
dynSizes.append(0); HashTable<label> groupLookup;
while (is.good()) while (is.good())
{ {
string line = this->getLineNoComment(is); string line = this->getLineNoComment(is);
// Handle continuations // Line continuations
if (line.removeEnd("\\")) while (line.removeEnd("\\"))
{ {
line += this->getLineNoComment(is); line += this->getLineNoComment(is);
} }
// Read first word const SubStrings<string> tokens = stringOps::splitSpace(line);
IStringStream lineStream(line);
word cmd; // Require command and some arguments
lineStream >> cmd; if (tokens.size() < 2)
{
continue;
}
const word cmd = word::validate(tokens[0]);
if (cmd == "v") if (cmd == "v")
{ {
scalar x, y, z; // Vertex
lineStream >> x >> y >> z; // v x y z
dynPoints.append(point(x, y, z));
dynPoints.append
(
point
(
readScalar(tokens[1]),
readScalar(tokens[2]),
readScalar(tokens[3])
)
);
} }
else if (cmd == "g") else if (cmd == "g")
{ {
word name; // Grouping
lineStream >> name; // g name
HashTable<label>::const_iterator fnd = lookup.find(name); const word groupName = word::validate(tokens[1]);
if (fnd != lookup.end()) const auto iterGroup = groupLookup.cfind(groupName);
if (iterGroup.found())
{ {
if (zoneI != fnd()) if (zoneId != *iterGroup)
{ {
// group appeared out of order sorted = false; // group appeared out of order
sorted = false;
} }
zoneI = fnd(); zoneId = *iterGroup;
} }
else else
{ {
zoneI = dynSizes.size(); zoneId = dynSizes.size();
lookup.insert(name, zoneI); groupLookup.insert(groupName, zoneId);
dynNames.append(name); dynNames.append(groupName);
dynSizes.append(0); dynSizes.append(0);
} }
} }
else if (cmd == "f") else if (cmd == "f")
{ {
DynamicList<label> dynVertices; // Face
// f v1 v2 v3 ...
// OR
// f v1/vt1 v2/vt2 v3/vt3 ...
// Assume 'f' is followed by space. // Ensure it has as valid grouping
string::size_type endNum = 1; if (zoneId < 0)
while (true)
{ {
string::size_type startNum = zoneId = 0;
line.find_first_not_of(' ', endNum); groupLookup.insert("zone0", 0);
dynNames.append("zone0");
if (startNum == string::npos) dynSizes.append(0);
{
break;
} }
endNum = line.find(' ', startNum); dynVerts.clear();
string vertexSpec; bool first = true;
if (endNum != string::npos) for (const auto& tok : tokens)
{ {
vertexSpec = line.substr(startNum, endNum-startNum); if (first)
}
else
{ {
vertexSpec = line.substr(startNum); // skip initial "f" or "l"
first = false;
continue;
} }
string::size_type slashPos = vertexSpec.find('/'); const string vrtSpec(tok);
const auto slash = vrtSpec.find('/');
label vertI = 0; const label vertId =
if (slashPos != string::npos) (
{ slash != string::npos
IStringStream intStream(vertexSpec.substr(0, slashPos)); ? readLabel(vrtSpec.substr(0, slash))
: readLabel(vrtSpec)
);
intStream >> vertI; dynVerts.append(vertId - 1);
} }
else
{
IStringStream intStream(vertexSpec);
intStream >> vertI; const labelUList& f = dynVerts;
}
dynVertices.append(vertI - 1);
}
dynVertices.shrink();
labelUList& f = static_cast<labelUList&>(dynVertices);
if (faceTraits<Face>::isTri() && f.size() > 3) if (faceTraits<Face>::isTri() && f.size() > 3)
{ {
@ -179,21 +186,21 @@ bool Foam::fileFormats::OBJsurfaceFormat<Face>::read
const label fp2 = f.fcIndex(fp1); const label fp2 = f.fcIndex(fp1);
dynFaces.append(Face{f[0], f[fp1], f[fp2]}); dynFaces.append(Face{f[0], f[fp1], f[fp2]});
dynZones.append(zoneI); dynZones.append(zoneId);
dynSizes[zoneI]++; dynSizes[zoneId]++;
} }
} }
else else if (f.size() >= 3)
{ {
dynFaces.append(Face(f)); dynFaces.append(Face(f));
dynZones.append(zoneI); dynZones.append(zoneId);
dynSizes[zoneI]++; dynSizes[zoneId]++;
} }
} }
} }
// transfer to normal lists // Transfer to normal lists
this->storedPoints().transfer(dynPoints); this->storedPoints().transfer(dynPoints);
this->sortFacesAndStore(dynFaces.xfer(), dynZones.xfer(), sorted); this->sortFacesAndStore(dynFaces.xfer(), dynZones.xfer(), sorted);
@ -282,9 +289,9 @@ void Foam::fileFormats::OBJsurfaceFormat<Face>::write
const Face& f = faceLst[faceMap[faceIndex++]]; const Face& f = faceLst[faceMap[faceIndex++]];
os << 'f'; os << 'f';
forAll(f, fp) for (const label verti : f)
{ {
os << ' ' << f[fp] + 1; os << ' ' << verti + 1;
} }
os << nl; os << nl;
} }
@ -296,9 +303,9 @@ void Foam::fileFormats::OBJsurfaceFormat<Face>::write
const Face& f = faceLst[faceIndex++]; const Face& f = faceLst[faceIndex++];
os << 'f'; os << 'f';
forAll(f, fp) for (const label verti : f)
{ {
os << ' ' << f[fp] + 1; os << ' ' << verti + 1;
} }
os << nl; os << nl;
} }

View File

@ -84,7 +84,7 @@ bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
fileName baseName = filename.lessExt(); fileName baseName = filename.lessExt();
// read cellTable names (if possible) // Read cellTable names (if possible)
Map<word> cellTableLookup = readInpCellTable Map<word> cellTableLookup = readInpCellTable
( (
IFstream(starFileName(baseName, STARCDCore::INP_FILE))() IFstream(starFileName(baseName, STARCDCore::INP_FILE))()
@ -111,7 +111,7 @@ bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
pointId.clear(); pointId.clear();
// read .cel file // Read .cel file
// ~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~
IFstream is(starFileName(baseName, STARCDCore::CEL_FILE)); IFstream is(starFileName(baseName, STARCDCore::CEL_FILE));
if (!is.good()) if (!is.good())
@ -131,7 +131,7 @@ bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
// assume the cellTableIds are not intermixed // assume the cellTableIds are not intermixed
bool sorted = true; bool sorted = true;
label zoneI = 0; label zoneId = 0;
label lineLabel, shapeId, nLabels, cellTableId, typeId; label lineLabel, shapeId, nLabels, cellTableId, typeId;
DynamicList<label> vertexLabels(64); DynamicList<label> vertexLabels(64);
@ -159,27 +159,27 @@ bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
if (typeId == starcdShellType) if (typeId == starcdShellType)
{ {
// Convert groupID into zoneID // Convert cellTableId to zoneId
const auto fnd = lookup.cfind(cellTableId); const auto iterGroup = lookup.cfind(cellTableId);
if (fnd.found()) if (iterGroup.found())
{ {
if (zoneI != fnd()) if (zoneId != *iterGroup)
{ {
// cellTableIds are intermixed // cellTableIds are intermixed
sorted = false; sorted = false;
} }
zoneI = fnd(); zoneId = *iterGroup;
} }
else else
{ {
zoneI = dynSizes.size(); zoneId = dynSizes.size();
lookup.insert(cellTableId, zoneI); lookup.insert(cellTableId, zoneId);
const auto tableNameIter = cellTableLookup.cfind(cellTableId); const auto iterTableName = cellTableLookup.cfind(cellTableId);
if (tableNameIter.found()) if (iterTableName.found())
{ {
dynNames.append(tableNameIter()); dynNames.append(*iterTableName);
} }
else else
{ {
@ -206,15 +206,15 @@ bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
{ {
// a triangular 'face', convert to 'triFace' etc // a triangular 'face', convert to 'triFace' etc
dynFaces.append(Face(tri)); dynFaces.append(Face(tri));
dynZones.append(zoneI); dynZones.append(zoneId);
dynSizes[zoneI]++; dynSizes[zoneId]++;
} }
} }
else else if (nLabels >= 3)
{ {
dynFaces.append(Face(vertices)); dynFaces.append(Face(vertices));
dynZones.append(zoneI); dynZones.append(zoneId);
dynSizes[zoneI]++; dynSizes[zoneId]++;
} }
} }
} }
@ -262,9 +262,9 @@ void Foam::fileFormats::STARCDsurfaceFormat<Face>::write
writeHeader(os, STARCDCore::HEADER_CEL); writeHeader(os, STARCDCore::HEADER_CEL);
label faceIndex = 0; label faceIndex = 0;
forAll(zones, zoneI) forAll(zones, zonei)
{ {
const surfZone& zone = zones[zoneI]; const surfZone& zone = zones[zonei];
const label nLocalFaces = zone.size(); const label nLocalFaces = zone.size();
if (useFaceMap) if (useFaceMap)
@ -272,7 +272,7 @@ void Foam::fileFormats::STARCDsurfaceFormat<Face>::write
for (label i=0; i<nLocalFaces; ++i) for (label i=0; i<nLocalFaces; ++i)
{ {
const Face& f = faceLst[faceMap[faceIndex++]]; const Face& f = faceLst[faceMap[faceIndex++]];
writeShell(os, f, faceIndex, zoneI + 1); writeShell(os, f, faceIndex, zonei + 1);
} }
} }
else else
@ -280,7 +280,7 @@ void Foam::fileFormats::STARCDsurfaceFormat<Face>::write
for (label i=0; i<nLocalFaces; ++i) for (label i=0; i<nLocalFaces; ++i)
{ {
const Face& f = faceLst[faceIndex++]; const Face& f = faceLst[faceIndex++];
writeShell(os, f, faceIndex, zoneI + 1); writeShell(os, f, faceIndex, zonei + 1);
} }
} }
} }

View File

@ -241,7 +241,7 @@ bool Foam::fileFormats::VTKsurfaceFormat<Face>::read
this->sortFacesAndStore(dynFaces.xfer(), zones.xfer(), sorted); this->sortFacesAndStore(dynFaces.xfer(), zones.xfer(), sorted);
// Add zones, retaining any empty ones // Add zones (retaining empty ones)
this->addZones(zoneSizes, zoneNames); this->addZones(zoneSizes, zoneNames);
} }
this->addZonesToFaces(); // for labelledTri this->addZonesToFaces(); // for labelledTri