VTKsurfaceFormat.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) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2016-2021 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "VTKsurfaceFormat.H"
30 #include "vtkUnstructuredReader.H"
31 #include "labelIOField.H"
32 #include "scalarIOField.H"
33 #include "faceTraits.H"
34 #include <fstream>
35 
36 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
37 
38 template<class Face>
40 (
41  vtk::formatter& format,
42  const UList<Face>& faces
43 )
44 {
45  // connectivity count without additional storage (done internally)
46  label nConnectivity = 0;
47  for (const Face& f : faces)
48  {
49  nConnectivity += f.size();
50  }
51 
53  (
54  format.os(),
55  faces.size(),
56  nConnectivity
57  );
58 
59 
60  // legacy: size + connectivity together
61  // [nPts, id1, id2, ..., nPts, id1, id2, ...]
62 
63  for (const Face& f : faces)
64  {
65  format.write(f.size()); // The size prefix
67  }
68 
69  format.flush();
70 }
71 
72 
73 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
74 
75 template<class Face>
77 (
78  const fileName& filename
79 )
80 {
81  read(filename);
82 }
83 
84 
85 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
86 
87 template<class Face>
89 (
90  const fileName& filename
91 )
92 {
93  // Clear everything
94  this->clear();
95 
96  IFstream is(filename);
97  if (!is.good())
98  {
100  << "Cannot read file " << filename << nl
101  << exit(FatalError);
102  }
103 
104  // Assume groups are not intermixed
105  bool sorted = true;
106 
107 
108  // Use dummy Time for objectRegistry
109  autoPtr<Time> dummyTimePtr(Time::New());
110 
111  objectRegistry obr
112  (
113  IOobject
114  (
115  "vtk::surfaceFormat",
116  *dummyTimePtr,
117  IOobject::NO_READ,
118  IOobject::NO_WRITE,
119  false
120  )
121  );
122 
123  // Read all
124  vtkUnstructuredReader reader(obr, is);
125  const faceList& faces = reader.faces();
126 
127  // Assume all faces in zone0 unless a region field is present
128  labelList zones(faces.size(), Zero);
129 
130  for (auto fieldName : { "region", "STLSolidLabeling" })
131  {
132  const labelIOField* lptr =
133  reader.cellData().findObject<labelIOField>(fieldName);
134 
135  if (lptr)
136  {
137  label i = 0;
138  for (const auto& region : *lptr)
139  {
140  zones[i++] = label(region);
141  }
142  break;
143  }
144 
145  const scalarIOField* sptr =
146  reader.cellData().findObject<scalarIOField>(fieldName);
147 
148  if (sptr)
149  {
150  label i = 0;
151  for (const auto& region : *sptr)
152  {
153  zones[i++] = label(region);
154  }
155  break;
156  }
157  }
158 
159 
160  // Create zone names
161  const label nZones = max(zones)+1;
162  wordList zoneNames(nZones);
163  forAll(zoneNames, i)
164  {
165  zoneNames[i] = surfZone::defaultName(i);
166  }
167 
168 
169  // Check if it needs triangulation
170  label nTri = 0;
172  {
173  for (const face& f : faces)
174  {
175  nTri += f.nTriangles();
176  }
177  }
178 
179  DynamicList<label> dynElemId; // unused
180 
181  if (nTri > faces.size())
182  {
183  // We are here if the target surface needs triangles and
184  // the source surface has non-triangles
185 
186  DynamicList<Face> dynFaces(nTri);
187  DynamicList<label> dynZones(nTri);
188 
189  forAll(faces, facei)
190  {
191  const face& f = faces[facei];
192  for (label fp1 = 1; fp1 < f.size() - 1; fp1++)
193  {
194  const label fp2 = f.fcIndex(fp1);
195 
196  dynFaces.append(Face{f[0], f[fp1], f[fp2]});
197  dynZones.append(zones[facei]);
198  }
199  }
200  zones.clear();
201 
202  // Count
203  labelList zoneSizes(nZones, Zero);
204  for (const label zonei : dynZones)
205  {
206  zoneSizes[zonei]++;
207  }
208 
209  this->sortFacesAndStore(dynFaces, dynZones, dynElemId, sorted);
210 
211  // Add zones (retaining empty ones)
212  this->addZones(zoneSizes, zoneNames);
213  }
214  else
215  {
216  DynamicList<Face> dynFaces(faces.size());
217  DynamicList<label> dynZones(std::move(zones));
218 
219  for (const face& f : faces)
220  {
221  dynFaces.append(Face(f));
222  }
223 
224  // Count
225  labelList zoneSizes(nZones, Zero);
226  for (const label zonei : dynZones)
227  {
228  zoneSizes[zonei]++;
229  }
230 
231  this->sortFacesAndStore(dynFaces, dynZones, dynElemId, sorted);
232 
233  // Add zones (retaining empty ones)
234  this->addZones(zoneSizes, zoneNames);
235  }
236  this->addZonesToFaces(); // for labelledTri
237 
238  // transfer to normal lists
239  this->storedPoints().transfer(reader.points());
240 
241  return true;
242 }
243 
244 
245 template<class Face>
247 (
248  const fileName& filename,
249  const MeshedSurfaceProxy<Face>& surf,
251  const dictionary& options
252 )
253 {
254  const UList<point>& pointLst = surf.points();
255  const UList<Face>& faceLst = surf.surfFaces();
256  const UList<label>& faceMap = surf.faceMap();
257 
258  const surfZoneList zones =
259  (
260  surf.surfZones().empty()
261  ? surfaceFormatsCore::oneZone(faceLst)
262  : surf.surfZones()
263  );
264 
265  const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1);
266 
267  vtk::outputOptions opts = formatOptions(options);
268 
269  std::ofstream os(filename, std::ios::binary);
270 
272 
273  writeHeader(format(), pointLst);
274 
275  if (useFaceMap)
276  {
277  // connectivity count without additional storage (done internally)
278  label nConnectivity = 0;
279  for (const Face& f : faceLst)
280  {
281  nConnectivity += f.size();
282  }
283 
285  (
286  format().os(),
287  faceLst.size(),
288  nConnectivity
289  );
290 
291  label faceIndex = 0;
292  for (const surfZone& zone : zones)
293  {
294  forAll(zone, i)
295  {
296  const Face& f = faceLst[faceMap[faceIndex++]];
297 
298  format().write(f.size()); // The size prefix
299  vtk::writeList(format(), f);
300  }
301  }
302 
303  format().flush();
304  }
305  else
306  {
307  // Easy to write polys without a faceMap
308  writePolys(format(), faceLst);
309  }
310 
311  // Write regions (zones) as CellData
312  if (zones.size() > 1)
313  {
314  writeCellData(format(), zones);
315  }
316 }
317 
318 
319 template<class Face>
321 (
322  const fileName& filename,
323  const UnsortedMeshedSurface<Face>& surf,
325  const dictionary& options
326 )
327 {
328  vtk::outputOptions opts = formatOptions(options);
329 
330  std::ofstream os(filename, std::ios::binary);
331 
333 
334  writeHeader(format(), surf.points());
335 
336  // Easy to write polys without a faceMap
337  writePolys(format(), surf.surfFaces());
338 
339  // Write regions (zones) as CellData
340  writeCellData(format(), surf.zoneIds());
341 }
342 
343 
344 // ************************************************************************* //
Foam::vtk::outputOptions
Encapsulated combinations of output format options. This is primarily useful when defining the output...
Definition: foamVtkOutputOptions.H:59
nZones
label nZones
Definition: interpolatedFaces.H:24
Foam::vtkUnstructuredReader::points
const pointField & points() const noexcept
Points.
Definition: vtkUnstructuredReader.H:255
Foam::vtkUnstructuredReader::faces
const faceList & faces() const noexcept
2D cells (=faces)
Definition: vtkUnstructuredReader.H:282
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:169
Foam::faceMap
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
Definition: blockMeshMergeTopological.C:94
VTKsurfaceFormat.H
Foam::fileName
A class for handling file names.
Definition: fileName.H:73
Foam::IOField
A primitive field of type <T> with automated input and output.
Definition: foamVtkLagrangianWriter.H:61
Foam::MeshedSurfaceProxy::useFaceMap
bool useFaceMap() const
Can/should use faceMap?
Definition: MeshedSurfaceProxy.H:203
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::IFstream
Input from file stream, using an ISstream.
Definition: IFstream.H:53
Foam::DynamicList< label >
vtkUnstructuredReader.H
Foam::vtkUnstructuredReader
Reader for vtk UNSTRUCTURED_GRID legacy files. Supports single CELLS, POINTS etc. entry only.
Definition: vtkUnstructuredReader.H:67
Foam::zone
Base class for mesh zones.
Definition: zone.H:63
Foam::vtk::legacy::beginPolys
void beginPolys(std::ostream &os, label nPolys, label nConnectivity)
Emit header for POLYGONS (with trailing newline).
Definition: foamVtkOutputI.H:137
Foam::vtk::outputOptions::newFormatter
autoPtr< formatter > newFormatter(std::ostream &os) const
Return new formatter based on the selected output options.
Definition: foamVtkOutputOptionsI.H:63
Foam::MeshedSurfaceProxy::points
const pointField & points() const
Return const access to the points.
Definition: MeshedSurfaceProxy.H:171
Foam::fileFormats::VTKsurfaceFormat::VTKsurfaceFormat
VTKsurfaceFormat(const fileName &filename)
Construct from file name.
Definition: VTKsurfaceFormat.C:77
scalarIOField.H
Foam::writeHeader
static void writeHeader(Ostream &os, const word &fieldName)
Definition: rawSurfaceWriterImpl.C:66
Foam::MeshedSurfaceProxy
A proxy for writing MeshedSurface, UnsortedMeshedSurface and surfMesh to various file formats.
Definition: MeshedSurface.H:82
formatOptions
const dictionary formatOptions
Definition: createFields.H:26
Foam::MeshedSurfaceProxy::faceMap
const labelUList & faceMap() const
Const access to the faceMap, zero-sized when unused.
Definition: MeshedSurfaceProxy.H:191
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::IOstream::good
bool good() const noexcept
True if next operation might succeed.
Definition: IOstream.H:233
Foam::objectRegistry
Registry of regIOobjects.
Definition: objectRegistry.H:60
Foam::blockMeshTools::read
void read(Istream &, label &val, const dictionary &)
In-place read with dictionary lookup.
Definition: blockMeshTools.C:57
Foam::UnsortedMeshedSurface::zoneIds
virtual const labelList & zoneIds() const
Return const access to the zone ids.
Definition: UnsortedMeshedSurface.H:336
format
word format(conversionProperties.get< word >("format"))
Foam::faceTraits
Traits class for faces.
Definition: faceTraits.H:50
Foam::vtkUnstructuredReader::cellData
const objectRegistry & cellData() const noexcept
Cell based fields.
Definition: vtkUnstructuredReader.H:314
Foam::UnsortedMeshedSurface
A surface geometry mesh, in which the surface zone information is conveyed by the 'zoneId' associated...
Definition: MeshedSurface.H:83
Foam::DynamicList::append
DynamicList< T, SizeMin > & append(const T &val)
Append an element to the end of this list.
Definition: DynamicListI.H:511
Foam::fileFormats::VTKsurfaceFormat::read
virtual bool read(const fileName &filename)
Read from file.
Definition: VTKsurfaceFormat.C:89
Foam::IOstreamOption
The IOstreamOption is a simple container for options an IOstream can normally have.
Definition: IOstreamOption.H:63
Foam::vtk::writeList
void writeList(vtk::formatter &fmt, const UList< uint8_t > &values)
Write a list of uint8_t values.
Definition: foamVtkOutput.C:112
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
os
OBJstream os(runTime.globalPath()/outputName)
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
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
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:53
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::objectRegistry::findObject
const Type * findObject(const word &name, const bool recursive=false) const
Return const pointer to the object of the given Type.
Definition: objectRegistryTemplates.C:401
clear
patchWriters clear()
Foam::nl
constexpr char nl
Definition: Ostream.H:404
f
labelList f(nPoints)
Foam::List< face >
Foam::surfZone
A surface zone on a MeshedSurface.
Definition: surfZone.H:56
Foam::UList
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:103
Foam::fileFormats::VTKsurfaceFormat
Read/write VTK legacy format (ASCII) for surfaces.
Definition: VTKsurfaceFormat.H:83
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:72
Foam::MeshedSurfaceProxy::surfFaces
const UList< Face > & surfFaces() const
Return const access to the faces.
Definition: MeshedSurfaceProxy.H:177
faceTraits.H
Foam::fileFormats::VTKsurfaceFormat::write
static void write(const fileName &filename, const MeshedSurfaceProxy< Face > &surf, IOstreamOption=IOstreamOption(), const dictionary &options=dictionary::null)
Write surface mesh components by proxy.
Definition: VTKsurfaceFormat.C:247
labelIOField.H
Foam::MeshedSurfaceProxy::surfZones
const UList< surfZone > & surfZones() const
Const access to the surface zones.
Definition: MeshedSurfaceProxy.H:185