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-2022 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 Member Functions * * * * * * * * * * * * //
39 
41 {
42  wordHashSet known
43  (
46  );
47 
48  // Additional hard-coded entry points, but do not need
49  // {"stl", "stlb"}
50  // since they are shadowed by *MeshedSurface
51 
52  known.insert("ftr");
53 
54  return known;
55 }
56 
57 
59 {
60  wordHashSet known
61  (
63  );
64 
65  // Additional hard-coded entry points, but do not need
66  // {"gts", "stl", "stlb"}
67  // since they are shadowed by MeshedSurfaceProxy
68 
69  known.insert("ftr");
70 
71  return known;
72 }
73 
74 
75 bool Foam::triSurface::canReadType(const word& fileType, bool verbose)
76 {
78  (
79  readTypes(),
80  fileType,
81  verbose,
82  "reading"
83  );
84 }
85 
86 
87 bool Foam::triSurface::canWriteType(const word& fileType, bool verbose)
88 {
90  (
91  writeTypes(),
92  fileType,
93  verbose,
94  "writing"
95  );
96 }
97 
98 
99 bool Foam::triSurface::canRead(const fileName& name, bool verbose)
100 {
101  const word ext =
102  (
103  name.has_ext("gz")
104  ? name.stem().ext()
105  : name.ext()
106  );
107 
108  return canReadType(ext, verbose);
109 }
110 
111 
113 (
114  const IOobject& io,
115  const fileName& f,
116  const bool isGlobal
117 )
118 {
120 }
121 
122 
124 (
125  const IOobject& io,
126  const bool isGlobal
127 )
128 {
130 }
131 
132 
134 (
135  const IOobject& io,
136  const dictionary& dict,
137  const bool isGlobal
138 )
139 {
141 }
142 
143 
145 (
146  const IOobject& io,
147  const bool isGlobal
148 )
149 {
151 }
152 
153 
155 (
156  const IOobject& io,
157  const dictionary& dict,
158  const bool isGlobal
159 )
160 {
162 }
163 
164 
165 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
166 
167 bool Foam::triSurface::readNative(Istream& is)
168 {
169  // Read triangles, points from Istream
170  is >> patches_ >> storedPoints() >> storedFaces();
171 
172  return true;
173 }
174 
175 
176 void Foam::triSurface::writeNative(Ostream& os) const
177 {
178  os << patches() << nl;
179 
180  //Note: Write with global point numbering
181  os << points() << nl
182  << static_cast<const List<labelledTri>&>(*this) << nl;
183 
185 }
186 
187 
188 bool Foam::triSurface::read
189 (
190  const fileName& name,
191  const word& fileType,
192  const bool check
193 )
194 {
195  if (check && !exists(name))
196  {
198  << "No such file " << name << nl
199  << exit(FatalError);
200  }
201 
202  this->clear();
203  transfer(*New(name, fileType));
204  return true;
205 }
206 
207 
209 (
210  const fileName& name,
211  const word& fileType,
212  const bool sortByRegion
213 ) const
214 {
215  if (fileType.empty())
216  {
217  // Handle empty/missing type
218 
219  const word ext(name.ext());
220 
221  if (ext.empty())
222  {
224  << "Cannot determine format from filename" << nl
225  << " " << name << nl
226  << exit(FatalError);
227  }
228 
229  write(name, ext, sortByRegion);
230  return;
231  }
232 
233 
234  // Hard-coded writers
235 
236  if (fileType == "ftr")
237  {
238  OFstream os(name);
239  writeNative(os);
240  }
241  else if (fileType == "stl")
242  {
243  writeSTLASCII(name, sortByRegion);
244  }
245  else if (fileType == "stlb")
246  {
247  writeSTLBINARY(name);
248  }
249  else if (fileType == "gts")
250  {
251  writeGTS(name, sortByRegion);
252  }
254  {
256  List<surfZone> zoneLst = this->sortedZones(faceMap);
257 
258  MeshedSurfaceProxy<labelledTri> proxy
259  (
260  this->points(),
261  this->surfFaces(),
262  zoneLst,
263  faceMap
264  );
265 
266  proxy.write(name, fileType);
267  }
268  else
269  {
271  << "Unknown surface format " << fileType
272  << " for writing file " << name << nl
273  << "Valid types:" << nl
274  << " " << flatOutput(writeTypes().sortedToc()) << nl
276  }
277 }
278 
279 
280 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
281 
282 Foam::triSurface::triSurface(Istream& is)
283 :
284  triSurface()
285 {
286  readNative(is);
287 
288  setDefaultPatches();
289 }
290 
291 
293 :
294  triSurface()
295 {
296  IFstream is
297  (
298  d.path()/triSurfInstance(d)/typeName/(d.caseName() + ".ftr")
299  );
300 
301  readNative(is);
302 
303  setDefaultPatches();
304 }
305 
306 
308 (
309  const IOobject& io,
310  const dictionary& dict,
311  const bool isGlobal
312 )
313 :
314  triSurface()
315 {
316  fileName fName(checkFile(io, dict, isGlobal));
317 
318  read(fName, dict.getOrDefault<word>("fileType", word::null));
319 
320  scalePoints(dict.getOrDefault<scalar>("scale", 0));
321 
322  setDefaultPatches();
323 }
324 
325 
326 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
327 
329 (
330  const fileName& name,
331  const bool sortByRegion
332 ) const
333 {
334  write(name, name.ext(), sortByRegion);
335 }
336 
339 {
340  writeNative(os);
341 }
342 
343 
344 void Foam::triSurface::write(const Time& d) const
345 {
346  OFstream os
347  (
348  d.path()/triSurfInstance(d)/typeName/(d.caseName() + ".ftr")
349  );
350 
351  writeNative(os);
352 }
353 
354 
356 {
357  // Unfortunately nPoints constructs meshPoints() so do compact version
358  // ourselves.
359 
360  bitSet pointIsUsed(points().size());
361 
362  boundBox bb;
363  labelHashSet regionsUsed;
364 
365  for (const auto& f : *this)
366  {
367  regionsUsed.insert(f.region());
368 
369  for (const label pointi : f)
370  {
371  if (pointIsUsed.set(pointi))
372  {
373  bb.add(points()[pointi]);
374  }
375  }
376  }
377 
378  os << "Triangles : " << size()
379  << " in " << regionsUsed.size() << " region(s)" << nl
380  << "Vertices : " << pointIsUsed.count() << nl
381  << "Bounding Box : " << bb << endl;
382 }
383 
384 
385 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
386 
387 Foam::Istream& Foam::operator>>(Istream& is, triSurface& s)
388 {
389  s.clearOut();
390  s.readNative(is);
391  s.setDefaultPatches();
392  return is;
393 }
394 
395 
396 Foam::Ostream& Foam::operator<<(Ostream& os, const triSurface& s)
397 {
398  s.writeNative(os);
399  return os;
400 }
401 
402 
403 // ************************************************************************* //
A surface geometry mesh, in which the surface zone information is conveyed by the &#39;zoneId&#39; associated...
Definition: MeshedSurface.H:76
dictionary dict
fileName path() const
Return path = rootPath/caseName. Same as TimePaths::path()
Definition: Time.H:503
A class for handling file names.
Definition: fileName.H:72
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
static fileName checkFile(const IOobject &io, const bool isGlobal=true)
Return fileName to load IOobject from.
Definition: triSurfaceIO.C:117
void writeStats(Ostream &os) const
Write some statistics.
Definition: triSurfaceIO.C:348
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
virtual bool check(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:45
A surface geometry mesh with zone information, not to be confused with the similarly named surfaceMes...
Output to file stream, using an OSstream.
Definition: OFstream.H:49
const fileName & caseName() const noexcept
Return case name.
Definition: TimePathsI.H:78
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tf1, const word &name, const dimensionSet &dimensions, const bool initCopy=false)
Global function forwards to reuseTmpDimensionedField::New.
A bounding box defined in terms of min/max extrema points.
Definition: boundBox.H:63
static bool canWriteType(const word &fileType, bool verbose=false)
Can we write this file format?
Definition: triSurfaceIO.C:80
static bool canWriteType(const word &fileType, bool verbose=false)
Can this file format type be written via MeshedSurfaceProxy?
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
Definition: HashSet.H:232
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:69
void write(Ostream &os) const
Write to Ostream in simple OpenFOAM format.
Definition: triSurfaceIO.C:331
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
static fileName checkFile(const IOobject &io, const bool isGlobal=true)
Return fileName to load IOobject from.
word ext() const
Return file name extension (part after last .)
Definition: wordI.H:171
label size() const noexcept
The number of elements in table.
Definition: HashTable.H:342
static fileName relativeFilePath(const IOobject &io, const fileName &f, const bool isGlobal=true)
Return fileName.
Definition: triSurfaceIO.C:106
void write(vtk::formatter &fmt, const Type &val, const label n=1)
Component-wise write of a value (N times)
void add(const boundBox &bb)
Extend to include the second box.
Definition: boundBoxI.H:323
static fileName triSurfInstance(const Time &)
Name of triSurface directory to use.
Definition: triSurface.C:66
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
const pointField & points
bool has_ext() const
Various checks for extensions.
Definition: stringI.H:43
static bool checkSupport(const wordHashSet &available, const word &fileType, const bool verbose=false, const char *functionName=nullptr)
Verbose checking of fileType in the list of available types.
A class for handling words, derived from Foam::string.
Definition: word.H:63
Istream & operator>>(Istream &, directionInfo &)
static const word null
An empty word.
Definition: word.H:84
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: POSIX.C:835
patchWriters clear()
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
static bool canReadType(const word &fileType, bool verbose=false)
Can we read this file format?
Definition: triSurfaceIO.C:68
OBJstream os(runTime.globalPath()/outputName)
#define FUNCTION_NAME
A proxy for writing MeshedSurface, UnsortedMeshedSurface and surfMesh to various file formats...
Definition: MeshedSurface.H:75
Input from file stream, using an ISstream.
Definition: IFstream.H:49
static void check(const int retVal, const char *what)
labelList f(nPoints)
static wordHashSet writeTypes()
Known writable file-types, including via friends or proxies.
Definition: triSurfaceIO.C:51
static fileName relativeFilePath(const IOobject &io, const fileName &f, const bool isGlobal=true)
Return fileName.
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces)
Definition: boundaryPatch.C:77
triSurface()
Default construct.
Definition: triSurface.C:425
static fileName findFile(const IOobject &io, const bool isGlobal=true)
Use IOobject information to resolve file to load from, or empty if the file does not exist...
Definition: triSurfaceIO.C:138
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:59
const polyBoundaryMesh & patches
List< label > sortedToc(const UList< bool > &bools)
Return the (sorted) values corresponding to &#39;true&#39; entries.
Definition: BitOps.C:195
virtual void scalePoints(const scalar scaleFactor)
Scale points. A non-positive factor is ignored.
Definition: triSurface.C:631
static bool canRead(const fileName &name, bool verbose=false)
Can we read this file format?
Definition: triSurfaceIO.C:92
List< label > labelList
A List of labels.
Definition: List.H:62
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, IOobject::NO_REGISTER)
Triangulated surface description with patch information.
Definition: triSurface.H:71
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
static wordHashSet readTypes()
Known readable file-types, including via friends or proxies.
Definition: triSurfaceIO.C:33
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:172
static fileName findFile(const IOobject &io, const bool isGlobal=true)
Use IOobject information to resolve file to load from, or empty if the file does not exist...
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition: FlatOutput.H:225