triSurfaceIO.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2017 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "triSurface.H"
29 #include "Fstream.H"
30 #include "Time.H"
31 #include "boundBox.H"
32 #include "bitSet.H"
33 #include "surfZoneList.H"
34 #include "surfaceFormatsCore.H"
35 #include "MeshedSurfaceProxy.H"
36 #include "MeshedSurface.H"
37 
38 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
39 
40 Foam::wordHashSet Foam::triSurface::readTypes_;
41 Foam::wordHashSet Foam::triSurface::writeTypes_;
42 
43 
44 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
45 
47 {
48  // Stop-gap measure until reading is handled more generally
49  if (readTypes_.empty())
50  {
51  readTypes_ = { "ftr", "stl", "stlb" };
54  }
55 
56  return readTypes_;
57 }
58 
59 
61 {
62  // Stop-gap measure until writing is handled more generally
63  if (writeTypes_.empty())
64  {
65  writeTypes_ = { "ftr", "stl", "stlb", "gts" };
67  }
68 
69  return writeTypes_;
70 }
71 
72 
73 bool Foam::triSurface::canReadType(const word& ext, const bool verbose)
74 {
76  (
77  readTypes(),
78  ext,
79  verbose,
80  "reading"
81  );
82 }
83 
84 
85 bool Foam::triSurface::canWriteType(const word& ext, const bool verbose)
86 {
88  (
89  writeTypes(),
90  ext,
91  verbose,
92  "writing"
93  );
94 }
95 
96 
97 bool Foam::triSurface::canRead(const fileName& name, const bool verbose)
98 {
99  word ext = name.ext();
100  if (ext == "gz")
101  {
102  ext = name.lessExt().ext();
103  }
104  return canReadType(ext, verbose);
105 }
106 
107 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
108 
109 void Foam::triSurface::printTriangle
110 (
111  Ostream& os,
112  const string& pre,
113  const labelledTri& f,
114  const pointField& points
115 )
116 {
117  os
118  << pre.c_str() << "vertex numbers:"
119  << f[0] << ' ' << f[1] << ' ' << f[2] << endl
120  << pre.c_str() << "vertex coords :"
121  << points[f[0]] << ' ' << points[f[1]] << ' ' << points[f[2]]
122  << pre.c_str() << "region :" << f.region() << endl
123  << endl;
124 }
125 
126 
127 bool Foam::triSurface::read(Istream& is)
128 {
129  // Read triangles, points from Istream
130  is >> patches_ >> storedPoints() >> storedFaces();
131 
132  return true;
133 }
134 
135 
136 bool Foam::triSurface::read
137 (
138  const fileName& name,
139  const word& ext,
140  const bool check
141 )
142 {
143  if (check && !exists(name))
144  {
146  << "Cannnot read " << name << exit(FatalError);
147  }
148 
149  if (ext == "gz")
150  {
151  fileName unzipName = name.lessExt();
152 
153  // Do not check for existence. Let IFstream do the unzipping.
154  return read(unzipName, unzipName.ext(), false);
155  }
156 
157  // Hard-coded readers
158  if (ext == "ftr")
159  {
160  return read(IFstream(name)());
161  }
162  else if (ext == "stl")
163  {
164  return readSTL(name); // ASCII
165  }
166  else if (ext == "stlb")
167  {
168  return readSTL(name, true); // Force BINARY
169  }
170 
171  // UnsortedMeshedSurface
172  {
173  using proxyType = UnsortedMeshedSurface<labelledTri>;
174  if (proxyType::readTypes().found(ext))
175  {
176  transfer(*(proxyType::New(name, ext)));
177  return true;
178  }
179  }
180 
181  // MeshedSurface
182  {
183  using proxyType = MeshedSurface<labelledTri>;
184  if (proxyType::readTypes().found(ext))
185  {
186  transfer(*(proxyType::New(name, ext)));
187  return true;
188  }
189  }
190 
191 
193  << "unknown file extension " << ext
194  << " for reading file " << name
195  << ". Supported extensions:" << nl
196  << " " << flatOutput(readTypes_.sortedToc()) << nl
197  << exit(FatalError);
198 
199  return false;
200 }
201 
202 
203 void Foam::triSurface::write
204 (
205  const fileName& name,
206  const word& ext,
207  const bool sort
208 ) const
209 {
210  // Hard-coded readers
211 
212  if (ext == "ftr")
213  {
214  OFstream os(name);
215  write(os);
216  }
217  else if (ext == "stl")
218  {
219  writeSTLASCII(name, sort);
220  }
221  else if (ext == "stlb")
222  {
223  writeSTLBINARY(name);
224  }
225  else if (ext == "gts")
226  {
227  writeGTS(name, sort);
228  }
230  {
232  List<surfZone> zoneLst = this->sortedZones(faceMap);
233 
234  MeshedSurfaceProxy<labelledTri> proxy
235  (
236  this->points(),
237  this->surfFaces(),
238  zoneLst,
239  faceMap
240  );
241 
242  proxy.write(name, ext);
243  }
244  else
245  {
247  << "unknown file extension " << ext
248  << " for writing file " << name
249  << ". Supported extensions:" << nl
250  << " " << flatOutput(writeTypes_.sortedToc()) << nl
251  << exit(FatalError);
252  }
253 }
254 
255 
256 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
257 
259 :
261  patches_(),
262  sortedEdgeFacesPtr_(nullptr),
263  edgeOwnerPtr_(nullptr)
264 {
265  read(is);
266 
267  setDefaultPatches();
268 }
269 
270 
272 :
274  patches_(),
275  sortedEdgeFacesPtr_(nullptr),
276  edgeOwnerPtr_(nullptr)
277 {
278  fileName foamFile(d.caseName() + ".ftr");
279 
280  fileName foamPath(d.path()/triSurfInstance(d)/typeName/foamFile);
281 
282  IFstream foamStream(foamPath);
283 
284  read(foamStream);
285 
286  setDefaultPatches();
287 }
288 
289 
290 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
291 
292 void Foam::triSurface::write
293 (
294  const fileName& name,
295  const bool sortByRegion
296 ) const
297 {
298  write(name, name.ext(), sortByRegion);
299 }
300 
301 
302 void Foam::triSurface::write(Ostream& os) const
303 {
304  os << patches() << nl;
305 
306  //Note: Write with global point numbering
307  os << points() << nl
308  << static_cast<const List<labelledTri>&>(*this) << nl;
309 
310  // Check state of Ostream
311  os.check(FUNCTION_NAME);
312 }
313 
314 
315 void Foam::triSurface::write(const Time& d) const
316 {
317  fileName foamFile(d.caseName() + ".ftr");
318 
319  fileName foamPath(d.path()/triSurfInstance(d)/typeName/foamFile);
320 
321  OFstream foamStream(foamPath);
322 
323  write(foamStream);
324 }
325 
326 
328 {
329  // Unfortunately nPoints constructs meshPoints() so do compact version
330  // ourselves.
331  bitSet pointIsUsed(points().size());
332 
333  label nPoints = 0;
335  labelHashSet regionsUsed;
336 
337  for (const triSurface::FaceType& f : *this)
338  {
339  regionsUsed.insert(f.region());
340 
341  forAll(f, fp)
342  {
343  const label pointi = f[fp];
344  if (pointIsUsed.set(pointi))
345  {
346  bb.add(points()[pointi]);
347  ++nPoints;
348  }
349  }
350  }
351 
352  os << "Triangles : " << size()
353  << " in " << regionsUsed.size() << " region(s)" << nl
354  << "Vertices : " << nPoints << nl
355  << "Bounding Box : " << bb << endl;
356 }
357 
358 
359 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
360 
362 {
363  sm.clearOut();
364  sm.read(is);
365  sm.setDefaultPatches();
366  return is;
367 }
368 
369 
371 {
372  sm.write(os);
373  return os;
374 }
375 
376 
377 // ************************************************************************* //
Foam::triSurface::writeStats
void writeStats(Ostream &os) const
Write some statistics.
Definition: triSurfaceIO.C:327
Foam::word::lessExt
word lessExt() const
Return word without extension (part before last .)
Definition: word.C:113
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:74
Foam::HashTable::size
label size() const noexcept
The number of elements in table.
Definition: HashTableI.H:52
MeshedSurfaceProxy.H
Foam::exists
bool exists(const fileName &name, const bool checkGzip=true, const bool followLink=true)
Does the name exist (as DIRECTORY or FILE) in the file system?
Definition: MSwindows.C:625
Foam::Time
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:73
Foam::faceMap
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
Definition: blockMeshMergeFast.C:94
Foam::triSurface::clearOut
void clearOut()
Definition: triSurface.C:542
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
Foam::bitSet
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:64
Foam::triSurface::writeTypes
static const wordHashSet & writeTypes()
Known writable file-types.
Definition: triSurfaceIO.C:60
Foam::IFstream
Input from file stream, using an ISstream.
Definition: IFstream.H:97
Foam::boundBox::invertedBox
static const boundBox invertedBox
A large inverted boundBox: min/max == +/- ROOTVGREAT.
Definition: boundBox.H:86
Foam::read
bool read(const char *buf, int32_t &val)
Same as readInt32.
Definition: int32.H:108
Foam::MeshedSurfaceProxy::canWriteType
static bool canWriteType(const word &ext, const bool verbose=false)
Can this file format type be written via MeshedSurfaceProxy?
Definition: MeshedSurfaceProxy.C:48
Foam::bitSet::set
void set(const bitSet &bitset)
Set specified bits from another bitset.
Definition: bitSetI.H:563
Foam::operator>>
Istream & operator>>(Istream &, directionInfo &)
Definition: directionInfo.C:228
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:337
Foam::word::ext
word ext() const
Return file name extension (part after last .)
Definition: word.C:126
triSurface.H
Foam::HashSet< word >
bitSet.H
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:290
nPoints
label nPoints
Definition: gmvOutputHeader.H:2
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:62
Foam::Field< vector >
Foam::triSurface
Triangulated surface description with patch information.
Definition: triSurface.H:70
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:61
Foam::name
word name(const complex &c)
Return string representation of complex.
Definition: complex.C:76
Foam::sort
void sort(UList< T > &a)
Definition: UList.C:241
Foam::triSurface::canWriteType
static bool canWriteType(const word &ext, const bool verbose=false)
Can we write this file format?
Definition: triSurfaceIO.C:85
Foam::triSurface::triSurface
triSurface()
Construct null.
Definition: triSurface.C:405
Foam::IOstream::check
virtual bool check(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:51
Foam::FatalError
error FatalError
Foam::MeshedSurface::readTypes
static wordHashSet readTypes()
Known readable file-types.
Definition: MeshedSurface.C:45
Foam::UnsortedMeshedSurface::readTypes
static wordHashSet readTypes()
Known readable file-types.
Definition: UnsortedMeshedSurface.C:41
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::OFstream
Output to file stream, using an OSstream.
Definition: OFstream.H:99
Foam::New
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tdf1, const word &name, const dimensionSet &dimensions)
Global function forwards to reuseTmpDimensionedField::New.
Definition: DimensionedFieldReuseFunctions.H:105
found
bool found
Definition: TABSMDCalcMethod2.H:32
boundBox.H
Time.H
Foam::MeshedSurfaceProxy::writeTypes
static wordHashSet writeTypes()
The file format types that can be written via MeshedSurfaceProxy.
Definition: MeshedSurfaceProxy.C:40
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:355
Foam::Time::caseName
const fileName & caseName() const
Return case name.
Definition: TimePathsI.H:54
Foam::nl
constexpr char nl
Definition: Ostream.H:372
Foam::Time::path
fileName path() const
Return path.
Definition: Time.H:303
Fstream.H
Input/output from file streams.
Foam::flatOutput
FlatOutput< Container > flatOutput(const Container &obj, label len=0)
Global flatOutput function.
Definition: FlatOutput.H:85
f
labelList f(nPoints)
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:102
points
const pointField & points
Definition: gmvOutputHeader.H:1
Foam::HashSet::insert
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
Definition: HashSet.H:182
patches
const polyBoundaryMesh & patches
Definition: convertProcessorPatches.H:65
FUNCTION_NAME
#define FUNCTION_NAME
Definition: messageStream.H:261
Foam::labelledTri
Triangle with additional region number.
Definition: labelledTri.H:58
Foam::vtk::write
void write(vtk::formatter &fmt, const Type &val, const label n=1)
Component-wise write of a value (N times)
Definition: foamVtkOutputTemplates.C:35
Foam::boundBox
A bounding box defined in terms of min/max extrema points.
Definition: boundBox.H:63
surfZoneList.H
Foam::triSurface::canReadType
static bool canReadType(const word &ext, const bool verbose=false)
Can we read this file format?
Definition: triSurfaceIO.C:73
Foam::triSurface::canRead
static bool canRead(const fileName &name, const bool verbose=false)
Can we read this file format?
Definition: triSurfaceIO.C:97
Foam::triSurface::readTypes
static const wordHashSet & readTypes()
Known readable file-types.
Definition: triSurfaceIO.C:46
Foam::HashTable::empty
bool empty() const noexcept
True if the hash table is empty.
Definition: HashTableI.H:59
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
surfaceFormatsCore.H
Foam::operator<<
Ostream & operator<<(Ostream &, const boundaryPatch &)
Definition: boundaryPatch.C:102
Foam::triSurface::triSurfInstance
static fileName triSurfInstance(const Time &)
Name of triSurface directory to use.
Definition: triSurface.C:46
Foam::fileFormats::surfaceFormatsCore::checkSupport
static bool checkSupport(const wordHashSet &available, const word &ext, const bool verbose, const word &functionName)
Helper function when checking if a file extension is supported.
Definition: surfaceFormatsCore.C:161
MeshedSurface.H
Foam::PrimitivePatch< labelledTri, ::Foam::List, pointField, point >
Foam::boundBox::add
void add(const boundBox &bb)
Extend to include the second box.
Definition: boundBoxI.H:191