GTSsurfaceFormat.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 | Copyright (C) 2011 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 "GTSsurfaceFormat.H"
27 #include "surfaceFormatsCore.H"
28 #include "clock.H"
29 #include "IFstream.H"
30 #include "IStringStream.H"
31 #include "Ostream.H"
32 #include "OFstream.H"
33 
34 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
35 
36 template<class Face>
38 (
39  const fileName& filename
40 )
41 {
42  read(filename);
43 }
44 
45 
46 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
47 
48 template<class Face>
50 (
51  const fileName& filename
52 )
53 {
54  this->clear();
55 
56  IFstream is(filename);
57  if (!is.good())
58  {
60  (
61  "fileFormats::GTSsurfaceFormat::read(const fileName&)"
62  )
63  << "Cannot read file " << filename
64  << exit(FatalError);
65  }
66 
67  // Read header
68  string line = this->getLineNoComment(is);
69 
70  label nPoints, nEdges, nElems;
71  {
72  IStringStream lineStream(line);
73  lineStream
74  >> nPoints
75  >> nEdges
76  >> nElems;
77  }
78 
79 
80  // write directly into the lists:
81  pointField& pointLst = this->storedPoints();
82  List<Face>& faceLst = this->storedFaces();
83  List<label>& zoneIds = this->storedZoneIds();
84 
85  pointLst.setSize(nPoints);
86  faceLst.setSize(nElems);
87  zoneIds.setSize(nElems);
88 
89  // Read points
90  forAll(pointLst, pointI)
91  {
92  scalar x, y, z;
93  line = this->getLineNoComment(is);
94  {
95  IStringStream lineStream(line);
96  lineStream
97  >> x >> y >> z;
98  }
99 
100  pointLst[pointI] = point(x, y, z);
101  }
102 
103  // Read edges (Foam indexing)
104  edgeList edges(nEdges);
105  forAll(edges, edgei)
106  {
107  label beg, end;
108  line = this->getLineNoComment(is);
109  {
110  IStringStream lineStream(line);
111  lineStream
112  >> beg >> end;
113  }
114  edges[edgei] = edge(beg - 1, end - 1);
115  }
116 
117 
118  // Read triangles. Convert references to edges into pointlabels
119  label maxZone = 0;
120  forAll(faceLst, faceI)
121  {
122  label e0Label, e1Label, e2Label;
123  label zoneI = 0;
124 
125  line = this->getLineNoComment(is);
126  {
127  IStringStream lineStream(line);
128  lineStream
129  >> e0Label >> e1Label >> e2Label;
130 
131  // Optional zone number: read first, then check state on stream
132  if (lineStream)
133  {
134  label num;
135  lineStream >> num;
136  if (!lineStream.bad())
137  {
138  zoneI = num;
139  if (maxZone < zoneI)
140  {
141  maxZone = zoneI;
142  }
143  }
144  }
145  }
146 
147  // Determine ordering of edges e0, e1
148  // common: common vertex, shared by e0 and e1
149  // e0Far: vertex on e0 which is not common
150  // e1Far: vertex on e1 which is not common
151  const edge& e0 = edges[e0Label - 1];
152  const edge& e1 = edges[e1Label - 1];
153  const edge& e2 = edges[e2Label - 1];
154 
155  label common01 = e0.commonVertex(e1);
156  if (common01 == -1)
157  {
159  (
160  "fileFormats::GTSsurfaceFormat::read(const fileName&)"
161  )
162  << "Edges 0 and 1 of triangle " << faceI
163  << " do not share a point.\n"
164  << " edge0:" << e0 << nl
165  << " edge1:" << e1
166  << exit(FatalError);
167  }
168 
169  label e0Far = e0.otherVertex(common01);
170  label e1Far = e1.otherVertex(common01);
171 
172  label common12 = e1.commonVertex(e2);
173  if (common12 == -1)
174  {
176  (
177  "fileFormats::GTSsurfaceFormat::read(const fileName&)"
178  )
179  << "Edges 1 and 2 of triangle " << faceI
180  << " do not share a point.\n"
181  << " edge1:" << e1 << nl
182  << " edge2:" << e2
183  << exit(FatalError);
184  }
185  label e2Far = e2.otherVertex(common12);
186 
187  // Does edge2 sit between edge1 and 0?
188  if (common12 != e1Far || e2Far != e0Far)
189  {
191  (
192  "fileFormats::GTSsurfaceFormat::read(const fileName&)"
193  )
194  << "Edges of triangle " << faceI
195  << " reference more than three points.\n"
196  << " edge0:" << e0 << nl
197  << " edge1:" << e1 << nl
198  << " edge2:" << e2 << nl
199  << exit(FatalError);
200  }
201 
202  faceLst[faceI] = triFace(e0Far, common01, e1Far);
203  zoneIds[faceI] = zoneI;
204  }
205 
206 
207  List<surfZoneIdentifier> newZones(maxZone+1);
208  forAll(newZones, zoneI)
209  {
210  newZones[zoneI] = surfZoneIdentifier
211  (
212  "zone" + ::Foam::name(zoneI),
213  zoneI
214  );
215  }
216 
217  this->storedZoneToc().transfer(newZones);
218 
219  return true;
220 }
221 
222 
223 template<class Face>
225 (
226  const fileName& filename,
227  const MeshedSurface<Face>& surf
228 )
229 {
230  const pointField& pointLst = surf.points();
231  const List<Face>& faceLst = surf.faces();
232 
233  const List<surfZone>& zones =
234  (
235  surf.surfZones().size()
236  ? surf.surfZones()
237  : surfaceFormatsCore::oneZone(faceLst)
238  );
239 
240  // check if output triangulation would be required
241  // It is too annoying to triangulate on-the-fly
242  // just issue a warning and get out
244  {
245  label nNonTris = 0;
246  forAll(faceLst, faceI)
247  {
248  if (faceLst[faceI].size() != 3)
249  {
250  ++nNonTris;
251  }
252  }
253 
254  if (nNonTris)
255  {
257  (
258  "fileFormats::GTSsurfaceFormat::write"
259  "(const fileName&, const MeshedSurface<Face>&)"
260  )
261  << "Surface has " << nNonTris << "/" << faceLst.size()
262  << " non-triangulated faces - not writing!" << endl;
263  return;
264  }
265  }
266 
267 
268  OFstream os(filename);
269  if (!os.good())
270  {
272  (
273  "fileFormats::GTSsurfaceFormat::write"
274  "(const fileName&, const MeshedSurface<Face>&)"
275  )
276  << "Cannot open file for writing " << filename
277  << exit(FatalError);
278  }
279 
280 
281  // Write header, print zone names as comment
282  os << "# GTS file" << nl
283  << "# Zones:" << nl;
284 
285  forAll(zones, zoneI)
286  {
287  os << "# " << zoneI << " "
288  << zones[zoneI].name() << nl;
289  }
290  os << "#" << nl;
291 
292  os << "# nPoints nEdges nTriangles" << nl
293  << pointLst.size() << ' ' << surf.nEdges() << ' '
294  << surf.size() << endl;
295 
296 
297  // Write vertex coords
298  forAll(pointLst, pointI)
299  {
300  const point& pt = pointLst[pointI];
301 
302  os << pt.x() << ' ' << pt.y() << ' ' << pt.z() << nl;
303  }
304 
305 
306  // Write edges.
307  // Note: edges are in local point labels so convert
308  const edgeList& es = surf.edges();
309  const labelList& meshPts = surf.meshPoints();
310 
311  forAll(es, edgei)
312  {
313  os << meshPts[es[edgei].start()] + 1 << ' '
314  << meshPts[es[edgei].end()] + 1 << endl;
315  }
316 
317  // Write faces in terms of edges.
318  const labelListList& faceEs = surf.faceEdges();
319 
320  label faceIndex = 0;
321  forAll(zones, zoneI)
322  {
323  const surfZone& zone = zones[zoneI];
324 
325  forAll(zone, localFaceI)
326  {
327  const labelList& fEdges = faceEs[faceIndex++];
328 
329  os << fEdges[0] + 1 << ' '
330  << fEdges[1] + 1 << ' '
331  << fEdges[2] + 1 << ' '
332  << zoneI << endl;
333  }
334  }
335 }
336 
337 
338 template<class Face>
340 (
341  const fileName& filename,
342  const UnsortedMeshedSurface<Face>& surf
343 )
344 {
345  const pointField& pointLst = surf.points();
346  const List<Face>& faceLst = surf.faces();
347  const List<label>& zoneIds = surf.zoneIds();
348  const List<surfZoneIdentifier>& zoneToc = surf.zoneToc();
349 
350  // check if output triangulation would be required
351  // It is too annoying to triangulate on-the-fly
352  // just issue a warning and get out
354  {
355  label nNonTris = 0;
356  forAll(faceLst, faceI)
357  {
358  if (faceLst[faceI].size() != 3)
359  {
360  ++nNonTris;
361  }
362  }
363 
364  if (nNonTris)
365  {
367  (
368  "fileFormats::GTSsurfaceFormat::write"
369  "(const fileName&, const UnsortedMeshedSurfaces<Face>&)"
370  )
371  << "Surface has " << nNonTris << "/" << faceLst.size()
372  << " non-triangulated faces - not writing!" << endl;
373  return;
374  }
375  }
376 
377 
378  OFstream os(filename);
379  if (!os.good())
380  {
382  (
383  "fileFormats::GTSsurfaceFormat::write"
384  "(const fileName&, const UnsortedMeshedSurface<Face>&)"
385  )
386  << "Cannot open file for writing " << filename
387  << exit(FatalError);
388  }
389 
390 
391  // Write header, print zone names as comment
392  os << "# GTS file" << nl
393  << "# Zones:" << nl;
394 
395  forAll(zoneToc, zoneI)
396  {
397  os << "# " << zoneI << " "
398  << zoneToc[zoneI].name() << nl;
399  }
400  os << "#" << endl;
401 
402 
403  os << "# nPoints nEdges nTriangles" << nl
404  << pointLst.size() << ' ' << surf.nEdges() << ' '
405  << surf.size() << endl;
406 
407 
408  // Write vertex coords
409  forAll(pointLst, pointI)
410  {
411  os << pointLst[pointI].x() << ' '
412  << pointLst[pointI].y() << ' '
413  << pointLst[pointI].z() << endl;
414  }
415 
416 
417  // Write edges.
418  // Note: edges are in local point labels so convert
419  const edgeList& es = surf.edges();
420  const labelList& meshPts = surf.meshPoints();
421 
422  forAll(es, edgeI)
423  {
424  os << meshPts[es[edgeI].start()] + 1 << ' '
425  << meshPts[es[edgeI].end()] + 1 << endl;
426  }
427 
428 
429  // Write faces in terms of edges.
430  const labelListList& faceEs = surf.faceEdges();
431 
432  forAll(faceLst, faceI)
433  {
434  const labelList& fEdges = faceEs[faceI];
435 
436  os << fEdges[0] + 1 << ' '
437  << fEdges[1] + 1 << ' '
438  << fEdges[2] + 1 << ' '
439  << zoneIds[faceI] << endl;
440  }
441 }
442 
443 
444 // ************************************************************************* //
Input from memory buffer stream.
Definition: IStringStream.H:49
Output to file stream.
Definition: OFstream.H:81
iterator end()
Return an iterator to end traversing the UList.
Definition: UListI.H:237
const List< surfZoneIdentifier > & zoneToc() const
Return const access to the zone table-of-contents.
vector point
Point is a vector.
Definition: point.H:41
const List< surfZone > & surfZones() const
Const access to the surface zones.
label commonVertex(const edge &a) const
Return common vertex.
Definition: edgeI.H:121
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
bool bad() const
Return true if stream is corrupted.
Definition: IOstream.H:351
const List< label > & zoneIds() const
Return const access to the zone ids.
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
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:76
Provide a means of reading/writing GTS format. The output is never sorted by zone and is only written...
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
static void write(const fileName &, const MeshedSurface< Face > &)
Write MeshedSurface.
label size() const
The surface size is the number of faces.
face triFace(3)
Input from file stream.
Definition: IFstream.H:81
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:58
A line primitive.
Definition: line.H:56
An identifier for a surface zone on a meshed surface.
static const char nl
Definition: Ostream.H:260
void setSize(const label)
Reset size of List.
Definition: List.C:318
const Cmpt & y() const
Definition: VectorI.H:71
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
const List< Face > & faces() const
Return const access to the faces.
label size() const
The surface size is the number of faces.
Base class for zones.
Definition: zone.H:57
const labelList & meshPoints() const
Return labelList of mesh points in patch. They are constructed.
#define forAll(list, i)
Definition: UList.H:421
const edgeList & edges() const
Return list of edges, address into LOCAL point list.
bool good() const
Return true if next operation might succeed.
Definition: IOstream.H:333
label otherVertex(const label a) const
Given one vertex, return the other.
Definition: edgeI.H:103
const Cmpt & x() const
Definition: VectorI.H:65
const Cmpt & z() const
Definition: VectorI.H:77
A surface zone on a MeshedSurface.
Definition: surfZone.H:62
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
Definition: error.H:314
A surface geometry mesh, in which the surface zone information is conveyed by the &#39;zoneId&#39; associated...
Definition: MeshedSurface.H:74
error FatalError
scalar y
A class for handling file names.
Definition: fileName.H:69
const labelListList & faceEdges() const
Return face-edge addressing.
virtual bool read(const fileName &)
Read from file.
A surface geometry mesh with zone information, not to be confused with the similarly named surfaceMes...
Definition: MeshedSurface.H:72
bool read(const char *, int32_t &)
Definition: int32IO.C:87
label nEdges() const
Return number of edges in patch.
label nPoints
UEqn clear()
const Field< point > & points() const
Return reference to global points.