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