VTKsurfaceFormat.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2019 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "VTKsurfaceFormat.H"
27 #include "vtkUnstructuredReader.H"
28 #include "scalarIOField.H"
29 
30 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
31 
32 template<class Face>
34 (
35  Ostream& os,
36  const UList<Face>& faceLst
37 )
38 {
39  label nNodes = 0;
40 
41  forAll(faceLst, facei)
42  {
43  nNodes += faceLst[facei].size();
44  }
45 
46  os << nl
47  << "POLYGONS " << faceLst.size() << ' '
48  << faceLst.size() + nNodes << nl;
49 }
50 
51 
52 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
53 
54 template<class Face>
56 (
57  const fileName& filename
58 )
59 {
60  read(filename);
61 }
62 
63 
64 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
65 
66 template<class Face>
68 (
69  const fileName& filename
70 )
71 {
72  const bool mustTriangulate = this->isTri();
73  this->clear();
74 
75  IFstream is(filename);
76  if (!is.good())
77  {
79  << "Cannot read file " << filename
80  << exit(FatalError);
81  }
82 
83  // assume that the groups are not intermixed
84  bool sorted = true;
85 
86 
87  // Construct dummy time so we have something to create an objectRegistry
88  // from
89  Time dummyTime
90  (
91  "dummyRoot",
92  "dummyCase",
93  "system",
94  "constant",
95  false // enableFunctionObjects
96  );
97 
98  // Make dummy object registry
99  objectRegistry obr
100  (
101  IOobject
102  (
103  "dummy",
104  dummyTime,
105  IOobject::NO_READ,
106  IOobject::NO_WRITE,
107  false
108  )
109  );
110 
111  // Read all
112  vtkUnstructuredReader reader(obr, is);
113  const faceList& faces = reader.faces();
114 
115  // Assume all faces in zone0 unless a region field is present
116  labelList zones(faces.size(), 0);
117  if (reader.cellData().foundObject<scalarIOField>("region"))
118  {
119  const scalarIOField& region =
121  (
122  "region"
123  );
124  forAll(region, i)
125  {
126  zones[i] = label(region[i]);
127  }
128  }
129  else if (reader.cellData().foundObject<scalarIOField>("STLSolidLabeling"))
130  {
131  const scalarIOField& region =
133  (
134  "STLSolidLabeling"
135  );
136  forAll(region, i)
137  {
138  zones[i] = label(region[i]);
139  }
140  }
141 
142  // Create zone names
143  const label nZones = max(zones)+1;
144  wordList zoneNames(nZones);
145  forAll(zoneNames, i)
146  {
147  zoneNames[i] = "zone" + Foam::name(i);
148  }
149 
150 
151  // See if needs triangulation
152  label nTri = 0;
153  if (mustTriangulate)
154  {
155  forAll(faces, facei)
156  {
157  nTri += faces[facei].size()-2;
158  }
159  }
160 
161  if (nTri > 0)
162  {
163  DynamicList<Face> dynFaces(nTri);
164  DynamicList<label> dynZones(nTri);
165  forAll(faces, facei)
166  {
167  const face& f = faces[facei];
168  for (label fp1 = 1; fp1 < f.size() - 1; fp1++)
169  {
170  label fp2 = f.fcIndex(fp1);
171 
172  dynFaces.append(triFace(f[0], f[fp1], f[fp2]));
173  dynZones.append(zones[facei]);
174  }
175  }
176 
177  // Count
178  labelList zoneSizes(nZones, 0);
179  forAll(dynZones, triI)
180  {
181  zoneSizes[dynZones[triI]]++;
182  }
183 
184  this->sortFacesAndStore(move(dynFaces), move(dynZones), sorted);
185 
186  // add zones, culling empty ones
187  this->addZones(zoneSizes, zoneNames, true);
188  }
189  else
190  {
191  DynamicList<Face> dynFaces(faces.size());
192  forAll(faces, facei)
193  {
194  const face& f = faces[facei];
195  dynFaces.append(Face(f));
196  }
197 
198  // Count
199  labelList zoneSizes(nZones, 0);
200  forAll(zones, facei)
201  {
202  zoneSizes[zones[facei]]++;
203  }
204 
205  this->sortFacesAndStore(move(dynFaces), move(zones), sorted);
206 
207  // add zones, culling empty ones
208  this->addZones(zoneSizes, zoneNames, true);
209  }
210 
211  // transfer to normal lists
212  this->storedPoints().transfer(reader.points());
213 
214  return true;
215 }
216 
217 
218 template<class Face>
220 (
221  const fileName& filename,
222  const MeshedSurfaceProxy<Face>& surf
223 )
224 {
225  const pointField& pointLst = surf.points();
226  const List<Face>& faceLst = surf.faces();
227  const List<label>& faceMap = surf.faceMap();
228 
229  const List<surfZone>& zones =
230  (
231  surf.surfZones().empty()
232  ? surfaceFormatsCore::oneZone(faceLst)
233  : surf.surfZones()
234  );
235 
236  const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1);
237 
238  OFstream os(filename);
239  if (!os.good())
240  {
242  << "Cannot open file for writing " << filename
243  << exit(FatalError);
244  }
245 
246 
247  writeHeader(os, pointLst);
248  writeHeaderPolygons(os, faceLst);
249 
250  label faceIndex = 0;
251  forAll(zones, zoneI)
252  {
253  const surfZone& zone = zones[zoneI];
254 
255  if (useFaceMap)
256  {
257  forAll(zone, localFacei)
258  {
259  const Face& f = faceLst[faceMap[faceIndex++]];
260 
261  os << f.size();
262  forAll(f, fp)
263  {
264  os << ' ' << f[fp];
265  }
266  os << ' ' << nl;
267  }
268  }
269  else
270  {
271  forAll(zone, localFacei)
272  {
273  const Face& f = faceLst[faceIndex++];
274 
275  os << f.size();
276  forAll(f, fp)
277  {
278  os << ' ' << f[fp];
279  }
280  os << ' ' << nl;
281  }
282  }
283  }
284 
285  writeTail(os, zones);
286 }
287 
288 
289 template<class Face>
291 (
292  const fileName& filename,
293  const UnsortedMeshedSurface<Face>& surf
294 )
295 {
296  OFstream os(filename);
297  if (!os.good())
298  {
300  << "Cannot open file for writing " << filename
301  << exit(FatalError);
302  }
303 
304 
305  const List<Face>& faceLst = surf.faces();
306 
307  writeHeader(os, surf.points());
308  writeHeaderPolygons(os, faceLst);
309 
310  forAll(faceLst, facei)
311  {
312  const Face& f = faceLst[facei];
313 
314  os << f.size();
315  forAll(f, fp)
316  {
317  os << ' ' << f[fp];
318  }
319  os << ' ' << nl;
320  }
321 
322  writeTail(os, surf.zoneIds());
323 }
324 
325 
326 // ************************************************************************* //
A surface geometry mesh, in which the surface zone information is conveyed by the &#39;zoneId&#39; associated...
Definition: MeshedSurface.H:74
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
tUEqn clear()
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:59
A class for handling file names.
Definition: fileName.H:79
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
error FatalError
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:323
const faceList & faces() const
2D cells (=faces)
Output to file stream.
Definition: OFstream.H:82
A surface zone on a MeshedSurface.
Definition: surfZone.H:62
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
label fcIndex(const label i) const
Return the forward circular index, i.e. the next index.
Definition: UListI.H:58
const List< label > & zoneIds() const
Return const access to the zone ids.
bool foundObject(const word &name) const
Is the named Type found?
Reader for vtk unstructured_grid legacy files. Supports single CELLS, POINTS etc. entry only...
void read(Istream &, label &, const dictionary &)
In-place read with dictionary lookup.
const Type & lookupObject(const word &name) const
Lookup and return the object of the given Type.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:68
bool good() const
Return true if next operation might succeed.
Definition: IOstream.H:330
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
Provide a means of reading/writing VTK legacy format. The output is never sorted by zone...
bool useFaceMap() const
Use faceMap?
void writeHeader(std::ostream &, const bool isBinary, const std::string &title)
Write header.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
Definition: DynamicList.H:56
Base class for zones.
Definition: zone.H:57
const List< Face > & faces() const
Return const access to the faces.
const objectRegistry & cellData() const
Cell based fields.
face triFace(3)
void append(const T &)
Append an element at the end of the list.
Definition: ListI.H:178
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Definition: DynamicListI.H:296
const Field< PointType > & points() const
Return reference to global points.
const List< surfZone > & surfZones() const
Const access to the surface zones.
static const char nl
Definition: Ostream.H:260
A proxy for writing MeshedSurface, UnsortedMeshedSurface and surfMesh to various file formats...
Definition: MeshedSurface.H:73
Input from file stream.
Definition: IFstream.H:81
labelList f(nPoints)
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
const List< Face > & faces() const
Return const access to the faces.
const pointField & points() const
Return const access to the points.
virtual bool read(const fileName &)
Read from file.
const List< label > & faceMap() const
Const access to the faceMap, zero-sized when unused.
static void write(const fileName &, const MeshedSurfaceProxy< Face > &)
Write surface mesh components by proxy.
Registry of regIOobjects.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:92
A primitive field of type <T> with automated input and output.
Definition: IOField.H:50
const pointField & points() const
Points.
VTKsurfaceFormat(const fileName &)
Construct from file name.