From d026f908277bcae48fa06c21f1b930a95293843c Mon Sep 17 00:00:00 2001 From: Mark Olesen <Mark.Olesen@Germany> Date: Sun, 13 Nov 2016 23:05:43 +0100 Subject: [PATCH] ENH: support writing of unsorted surface for AC3D format (issue #294) - needed for triSurface output (when it comes) --- .../surfaceFormats/ac3d/AC3DsurfaceFormat.C | 212 +++++++++--------- 1 file changed, 103 insertions(+), 109 deletions(-) diff --git a/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.C b/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.C index 9bc86e0cf38..0c60b22ede2 100644 --- a/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.C +++ b/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.C @@ -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); } } -- GitLab