Commit d026f908 authored by Mark Olesen's avatar Mark Olesen
Browse files

ENH: support writing of unsorted surface for AC3D format (issue #294)

- needed for triSurface output (when it comes)
parent b799b5d6
......@@ -24,10 +24,8 @@ License
\*---------------------------------------------------------------------------*/
#include "AC3DsurfaceFormat.H"
#include "clock.H"
#include "IStringStream.H"
#include "tensor.H"
#include "primitivePatch.H"
#include "PrimitivePatch.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
......@@ -254,6 +252,57 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
}
namespace Foam
{
// file-scope writing of a patch of faces
template
<
class Face,
template<class> class FaceList,
class PointField,
class PointType
>
static void writeZone
(
Ostream& os,
const PrimitivePatch<Face, FaceList, PointField, PointType>& patch,
const word& name,
const label zoneI
)
{
// An isolated surface region (patch).
os << "OBJECT poly" << nl
<< "name \"" << name << "\"" << nl;
os << "numvert " << patch.nPoints() << nl;
forAll(patch.localPoints(), pti)
{
const point& pt = patch.localPoints()[pti];
os << pt.x() << ' ' << pt.y() << ' ' << pt.z() << nl;
}
os << "numsurf " << patch.size() << nl;
forAll(patch.localFaces(), facei)
{
const Face& f = patch.localFaces()[facei];
os << "SURF 0x20" << nl // polygon
<< "mat " << zoneI << nl
<< "refs " << f.size() << nl;
forAll(f, fp)
{
os << f[fp] << " 0 0" << nl;
}
}
os << "kids 0" << endl;
}
}
template<class Face>
void Foam::fileFormats::AC3DsurfaceFormat<Face>::write
(
......@@ -273,14 +322,6 @@ void Foam::fileFormats::AC3DsurfaceFormat<Face>::write
const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1);
if (useFaceMap)
{
FatalErrorInFunction
<< "output with faceMap is not supported " << filename
<< exit(FatalError);
}
OFstream os(filename);
if (!os.good())
{
......@@ -291,52 +332,42 @@ void Foam::fileFormats::AC3DsurfaceFormat<Face>::write
writeHeader(os, zones);
forAll(zones, zoneI)
if (zones.size() == 1)
{
const surfZone& zone = zones[zoneI];
os << "OBJECT poly" << nl
<< "name \"" << zone.name() << "\"\n";
// Temporary PrimitivePatch to calculate compact points & faces
// use 'UList' to avoid allocations!
PrimitivePatch<Face, UList, const pointField&> patch
(
SubList<Face>
(
faceLst,
zone.size(),
zone.start()
),
pointLst
faceLst, pointLst
);
os << "numvert " << patch.nPoints() << endl;
writeZone(os, patch, zones[0].name(), 0);
return;
}
forAll(zones, zoneI)
{
const surfZone& zone = zones[zoneI];
forAll(patch.localPoints(), ptI)
if (useFaceMap)
{
const point& pt = patch.localPoints()[ptI];
SubList<label> zoneMap(surf.faceMap(), zone.size(), zone.start());
PrimitivePatch<Face, UIndirectList, const pointField&> patch
(
UIndirectList<Face>(faceLst, zoneMap),
pointLst
);
os << pt.x() << ' ' << pt.y() << ' ' << pt.z() << nl;
writeZone(os, patch, zone.name(), zoneI);
}
os << "numsurf " << patch.localFaces().size() << endl;
forAll(patch.localFaces(), localFacei)
else
{
const Face& f = patch.localFaces()[localFacei];
os << "SURF 0x20" << nl // polygon
<< "mat " << zoneI << nl
<< "refs " << f.size() << nl;
PrimitivePatch<Face, UList, const pointField&> patch
(
SubList<Face>(faceLst, zone.size(), zone.start()),
pointLst
);
forAll(f, fp)
{
os << f[fp] << " 0 0" << nl;
}
writeZone(os, patch, zone.name(), zoneI);
}
os << "kids 0" << endl;
}
}
......@@ -348,81 +379,44 @@ void Foam::fileFormats::AC3DsurfaceFormat<Face>::write
const UnsortedMeshedSurface<Face>& surf
)
{
OFstream os(filename);
if (!os.good())
{
FatalErrorInFunction
<< "Cannot open file for writing " << filename
<< exit(FatalError);
}
labelList faceMap;
List<surfZone> zoneLst = surf.sortedZones(faceMap);
if (zoneLst.size() <= 1)
{
write
const List<surfZone>& zones =
(
filename,
MeshedSurfaceProxy<Face>
(
surf.points(),
surf.surfFaces(),
zoneLst
)
zoneLst.size()
? zoneLst
: surfaceFormatsCore::oneZone(surf.surfFaces())
);
}
else
{
OFstream os(filename);
if (!os.good())
{
FatalErrorInFunction
<< "Cannot open file for writing " << filename
<< exit(FatalError);
}
writeHeader(os, zoneLst);
label faceIndex = 0;
forAll(zoneLst, zoneI)
{
const surfZone& zone = zoneLst[zoneI];
os << "OBJECT poly" << nl
<< "name \"" << zone.name() << "\"\n";
// Create zone with only zone faces included for ease of addressing
labelHashSet include(surf.size());
forAll(zone, localFacei)
{
const label facei = faceMap[faceIndex++];
include.insert(facei);
}
UnsortedMeshedSurface<Face> subm = surf.subsetMesh(include);
// Now we have isolated surface for this patch alone. Write it.
os << "numvert " << subm.nPoints() << endl;
forAll(subm.localPoints(), ptI)
{
const point& pt = subm.localPoints()[ptI];
os << pt.x() << ' ' << pt.y() << ' ' << pt.z() << endl;
}
os << "numsurf " << subm.localFaces().size() << endl;
forAll(subm.localFaces(), localFacei)
{
const Face& f = subm.localFaces()[localFacei];
writeHeader(os, zones);
writeZone(os, surf, zones[0].name(), 0);
return;
}
os << "SURF 0x20" << nl // polygon
<< "mat " << zoneI << nl
<< "refs " << f.size() << nl;
writeHeader(os, zoneLst);
forAll(zoneLst, zoneI)
{
const surfZone& zone = zoneLst[zoneI];
forAll(f, fp)
{
os << f[fp] << " 0 0" << nl;
}
}
SubList<label> zoneMap(faceMap, zone.size(), zone.start());
PrimitivePatch<Face, UIndirectList, const pointField&> patch
(
UIndirectList<Face>(surf.surfFaces(), zoneMap),
surf.points()
);
os << "kids 0" << endl;
}
writeZone(os, patch, zone.name(), zoneI);
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment